diff --git a/coap_io.c b/coap_io.c index 2dbdd359..81e79267 100644 --- a/coap_io.c +++ b/coap_io.c @@ -37,7 +37,6 @@ #include "mem.h" #include "coap_io.h" -#ifndef WITH_LWIP struct coap_packet_t { coap_if_handle_t hnd; /**< the interface handle */ coap_address_t src; /**< the packet's source address */ @@ -50,7 +49,6 @@ struct coap_packet_t { size_t length; /**< length of payload */ unsigned char payload[]; /**< payload */ }; -#endif #ifndef CUSTOM_COAP_NETWORK_ENDPOINT @@ -322,9 +320,6 @@ coap_free_packet(coap_packet_t *packet) { #ifdef WITH_CONTIKI /* FIXME: implement coap_malloc_packet and coap_free_packet */ #endif /* WITH_CONTIKI */ -#ifdef WITH_LWIP -/* FIXME: implement coap_malloc_packet and coap_free_packet */ -#endif /* WITH_LWIP */ static inline size_t coap_get_max_packetlength(const coap_packet_t *packet UNUSED_PARAM) { diff --git a/coap_io_lwip.c b/coap_io_lwip.c new file mode 100644 index 00000000..fa894d76 --- /dev/null +++ b/coap_io_lwip.c @@ -0,0 +1,87 @@ +/* coap_io_lwip.h -- Network I/O functions for libcoap on lwIP + * + * Copyright (C) 2012,2014 Olaf Bergmann + * 2014 chrysn + * + * This file is part of the CoAP library libcoap. Please see + * README for terms of use. + */ + +#include "config.h" +#include "mem.h" +#include "coap_io.h" + +void coap_packet_populate_endpoint(coap_packet_t *incoming, coap_endpoint_t *target) +{ + printf("FIXME no endpoint populated\n"); +} +void coap_packet_copy_source(coap_packet_t *incoming, coap_address_t *target) +{ + /** @FIXME types wtf */ + memcpy(target, ip_current_src_addr(), sizeof(coap_address_t)); +} +void coap_packet_get_memmapped(coap_packet_t *incoming, unsigned char **address, size_t *length) +{ + LWIP_ASSERT("Can only deal with contiguous PBUFs to read the initial details", incoming->pbuf->tot_len == incoming->pbuf->len); + *address = incoming->pbuf->payload; + *length = incoming->pbuf->tot_len; +} +void coap_free_packet(coap_packet_t *packet) +{ + pbuf_free(packet->pbuf); + coap_free_type(COAP_PACKET, packet); +} + +/** Callback from lwIP when a package was received. + * + * The current implemntation deals this to coap_handle_message immedately, but + * other mechanisms (as storing the package in a queue and later fetching it + * when coap_read is called) can be envisioned. + * + * It handles everything coap_read does on other implementations. + */ +static void coap_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + coap_endpoint_t *ep = (coap_endpoint_t*)arg; + coap_packet_t *packet = coap_malloc_type(COAP_PACKET, sizeof(coap_packet_t)); + /* this is fatal because due to the short life of the packet, never should there be more than one coap_packet_t required */ + LWIP_ASSERT("Insufficient coap_packet_t resources.", packet != NULL); + packet->pbuf = p; + + /** FIXME derive the context without changing endopint definition */ + coap_handle_message(ep->context, packet); + + coap_free_packet(packet); +} + +coap_endpoint_t *coap_new_endpoint(const coap_address_t *addr, int flags) { + coap_endpoint_t *result; + err_t err; + + LWIP_ASSERT("Flags not supported for LWIP endpoints", flags == COAP_ENDPOINT_NOSEC); + + result = coap_malloc_type(COAP_ENDPOINT, sizeof(coap_endpoint_t)); + if (!result) return NULL; + + result->pcb = udp_new(); + if (result->pcb == NULL) goto error; + + udp_recv(result->pcb, coap_recv, (void*)result); + err = udp_bind(result->pcb, &addr->addr, addr->port); + if (err) { + udp_remove(result->pcb); + goto error; + } + + return result; + +error: + coap_free_type(COAP_ENDPOINT, result); + return NULL; +} + +void coap_free_endpoint(coap_endpoint_t *ep) +{ + udp_remove(ep->pcb); + coap_free_type(COAP_ENDPOINT, ep); +}