diff --git a/Makefile.am b/Makefile.am index da4574f0..ab553fb4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,6 +44,9 @@ libcoap_@LIBCOAP_API_VERSION@_la_CFLAGS = \ -fPIE \ $(AM_CFLAGS) +## Platform-specific sources are located in platform_src +platform_src = src/platform/@PLATFORM@ + ## Define the source file list for the "libcoap.la" target. ## Note that it is not necessary to list header files which are already listed ## elsewhere in a _HEADERS variable assignment. @@ -51,7 +54,6 @@ libcoap_@LIBCOAP_API_VERSION@_la_SOURCES = \ src/address.c \ src/async.c \ src/block.c \ - src/platform/@PLATFORM@/coap_io.c \ src/coap_time.c \ src/debug.c \ src/encode.c \ @@ -64,7 +66,8 @@ libcoap_@LIBCOAP_API_VERSION@_la_SOURCES = \ src/str.c \ src/subscribe.c \ src/uri.c \ - src/platform/@PLATFORM@/prng.c + $(platform_src)/coap_io.c \ + $(platform_src)/prng.c ## Define the list of public header files and their install location. ## The list defined here will be used within the include/Makefile.am diff --git a/include/coap/coap_io.h b/include/coap/coap_io.h index 0263ef9b..69c302cb 100644 --- a/include/coap/coap_io.h +++ b/include/coap/coap_io.h @@ -37,6 +37,7 @@ struct coap_context_t; * tuple (handle, addr) must uniquely identify this endpoint. */ typedef struct coap_endpoint_t { + struct coap_endpoint_t *next; #if defined(WITH_POSIX) || defined(WITH_CONTIKI) union { int fd; /**< on POSIX systems */ @@ -46,10 +47,8 @@ typedef struct coap_endpoint_t { #ifdef WITH_LWIP struct udp_pcb *pcb; - /**< @FIXME --chrysn - * this was added in a hurry, not sure it confirms to the overall model */ - struct coap_context_t *context; #endif /* WITH_LWIP */ + struct coap_context_t *context; coap_address_t addr; /**< local interface address */ int ifindex; diff --git a/include/coap/net.h b/include/coap/net.h index 014b4903..4c8e595f 100644 --- a/include/coap/net.h +++ b/include/coap/net.h @@ -90,10 +90,6 @@ typedef struct coap_context_t { coap_queue_t *sendqueue; coap_endpoint_t *endpoint; /**< the endpoint used for listening */ -#ifdef WITH_POSIX - int sockfd; /**< send/receive socket */ -#endif /* WITH_POSIX */ - #ifdef WITH_CONTIKI struct uip_udp_conn *conn; /**< uIP connection object */ struct etimer retransmit_timer; /**< fires when the next packet must be sent */ diff --git a/src/net.c b/src/net.c index 98173113..b4ae16c1 100644 --- a/src/net.c +++ b/src/net.c @@ -1,6 +1,6 @@ /* net.c -- CoAP network interface * - * Copyright (C) 2010--2015 Olaf Bergmann + * Copyright (C) 2010--2016 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see * README for terms of use. @@ -36,6 +36,7 @@ #include #endif +#include "utlist.h" #include "debug.h" #include "mem.h" #include "str.h" @@ -329,6 +330,21 @@ is_wkc(coap_key_t k) { } #endif +void +coap_detach_endpoint(coap_endpoint_t *endpoint) { + if (endpoint->context != NULL) { + LL_DELETE(endpoint->context->endpoint, endpoint); + endpoint->context = NULL; + } +} + +void +coap_attach_endpoint(coap_context_t *ctx, coap_endpoint_t *endpoint) { + coap_detach_endpoint(endpoint); + endpoint->context = ctx; + LL_PREPEND(ctx->endpoint, endpoint); +} + coap_context_t * coap_new_context( const coap_address_t *listen_addr) { @@ -376,18 +392,11 @@ coap_new_context( /* initialize message id */ coap_prng((unsigned char *)&c->message_id, sizeof(unsigned short)); - c->endpoint = coap_new_endpoint(listen_addr, COAP_ENDPOINT_NOSEC); -#ifdef WITH_LWIP - c->endpoint->context = c; -#endif + coap_attach_endpoint(c, coap_new_endpoint(listen_addr, COAP_ENDPOINT_NOSEC)); if (c->endpoint == NULL) { goto onerror; } -#ifdef WITH_POSIX - c->sockfd = c->endpoint->handle.fd; -#endif /* WITH_POSIX */ - #if defined(WITH_POSIX) || defined(WITH_CONTIKI) c->network_send = coap_network_send; c->network_read = coap_network_read; diff --git a/src/platform/posix/coap_io.c b/src/platform/posix/coap_io.c index cbf2263d..ea4349ca 100644 --- a/src/platform/posix/coap_io.c +++ b/src/platform/posix/coap_io.c @@ -1,6 +1,6 @@ -/* coap_io.h -- Default network I/O functions for libcoap +/* coap_io.c -- Default network I/O functions for libcoap * - * Copyright (C) 2012,2014 Olaf Bergmann + * Copyright (C) 2012,2014,2016 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see * README for terms of use. @@ -29,15 +29,10 @@ #endif #include -#ifdef WITH_CONTIKI -# include "uip.h" -#endif - #include "debug.h" #include "mem.h" #include "coap_io.h" -#ifdef WITH_POSIX struct coap_packet_t { coap_if_handle_t hnd; /**< the interface handle */ coap_address_t src; /**< the packet's source address */ @@ -50,62 +45,9 @@ struct coap_packet_t { size_t length; /**< length of payload */ unsigned char payload[]; /**< payload */ }; -#endif #ifndef CUSTOM_COAP_NETWORK_ENDPOINT -#ifdef WITH_CONTIKI -static int ep_initialized = 0; - -static inline struct coap_endpoint_t * -coap_malloc_contiki_endpoint() { - static struct coap_endpoint_t ep; - - if (ep_initialized) { - return NULL; - } else { - ep_initialized = 1; - return &ep; - } -} - -static inline void -coap_free_contiki_endpoint(struct coap_endpoint_t *ep) { - ep_initialized = 0; -} - -coap_endpoint_t * -coap_new_endpoint(const coap_address_t *addr, int flags) { - struct coap_endpoint_t *ep = coap_malloc_contiki_endpoint(); - - if (ep) { - memset(ep, 0, sizeof(struct coap_endpoint_t)); - ep->handle.conn = udp_new(NULL, 0, NULL); - - if (!ep->handle.conn) { - coap_free_endpoint(ep); - return NULL; - } - - coap_address_init(&ep->addr); - uip_ipaddr_copy(&ep->addr.addr, &addr->addr); - ep->addr.port = addr->port; - udp_bind((struct uip_udp_conn *)ep->handle.conn, addr->port); - } - return ep; -} - -void -coap_free_endpoint(coap_endpoint_t *ep) { - if (ep) { - if (ep->handle.conn) { - uip_udp_remove((struct uip_udp_conn *)ep->handle.conn); - } - coap_free_contiki_endpoint(ep); - } -} - -#else /* WITH_CONTIKI */ static inline struct coap_endpoint_t * coap_malloc_posix_endpoint(void) { return (struct coap_endpoint_t *)coap_malloc(sizeof(struct coap_endpoint_t)); @@ -200,12 +142,11 @@ coap_free_endpoint(coap_endpoint_t *ep) { } } -#endif /* WITH_CONTIKI */ #endif /* CUSTOM_COAP_NETWORK_ENDPOINT */ #ifndef CUSTOM_COAP_NETWORK_SEND -#if defined(WITH_POSIX) != defined(HAVE_NETINET_IN_H) +#ifndef HAVE_NETINET_IN_H /* define struct in6_pktinfo and struct in_pktinfo if not available FIXME: check with configure */ @@ -219,7 +160,7 @@ struct in_pktinfo { struct in_addr ipi_spec_dst; struct in_addr ipi_addr; }; -#endif +#endif /* HAVE_NETINET_IN_H */ #if defined(WITH_POSIX) && !defined(SOL_IP) /* Solaris expects level IPPROTO_IP for ancillary data. */ @@ -242,7 +183,6 @@ coap_network_send(struct coap_context_t *context UNUSED_PARAM, struct coap_endpoint_t *ep = (struct coap_endpoint_t *)local_interface; -#ifndef WITH_CONTIKI /* a buffer large enough to hold all protocol address types */ char buf[CMSG_LEN(sizeof(struct sockaddr_storage))]; struct msghdr mhdr; @@ -325,13 +265,6 @@ coap_network_send(struct coap_context_t *context UNUSED_PARAM, } return sendmsg(ep->handle.fd, &mhdr, 0); -#else /* WITH_CONTIKI */ - /* FIXME: untested */ - /* FIXME: is there a way to check if send was successful? */ - uip_udp_packet_sendto((struct uip_udp_conn *)ep->handle.conn, data, datalen, - &dst->addr, dst->port); - return datalen; -#endif /* WITH_CONTIKI */ } #endif /* CUSTOM_COAP_NETWORK_SEND */ @@ -340,7 +273,6 @@ coap_network_send(struct coap_context_t *context UNUSED_PARAM, #define SIN6(A) ((struct sockaddr_in6 *)(A)) -#ifdef WITH_POSIX static coap_packet_t * coap_malloc_packet(void) { coap_packet_t *packet; @@ -357,18 +289,6 @@ void coap_free_packet(coap_packet_t *packet) { coap_free(packet); } -#endif /* WITH_POSIX */ -#ifdef WITH_CONTIKI -static inline coap_packet_t * -coap_malloc_packet(void) { - return (coap_packet_t *)coap_malloc_type(COAP_PACKET, 0); -} - -void -coap_free_packet(coap_packet_t *packet) { - coap_free_type(COAP_PACKET, packet); -} -#endif /* WITH_CONTIKI */ static inline size_t coap_get_max_packetlength(const coap_packet_t *packet UNUSED_PARAM) { @@ -376,23 +296,20 @@ coap_get_max_packetlength(const coap_packet_t *packet UNUSED_PARAM) { } void -coap_packet_populate_endpoint(coap_packet_t *packet, coap_endpoint_t *target) -{ +coap_packet_populate_endpoint(coap_packet_t *packet, coap_endpoint_t *target) { target->handle = packet->interface->handle; memcpy(&target->addr, &packet->dst, sizeof(target->addr)); target->ifindex = packet->ifindex; target->flags = 0; /* FIXME */ } void -coap_packet_copy_source(coap_packet_t *packet, coap_address_t *target) -{ +coap_packet_copy_source(coap_packet_t *packet, coap_address_t *target) { memcpy(target, &packet->src, sizeof(coap_address_t)); } void -coap_packet_get_memmapped(coap_packet_t *packet, unsigned char **address, size_t *length) -{ - *address = packet->payload; - *length = packet->length; +coap_packet_get_memmapped(coap_packet_t *packet, unsigned char **address, size_t *length) { + *address = packet->payload; + *length = packet->length; } /** @@ -410,11 +327,9 @@ ssize_t coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) { ssize_t len = -1; -#ifdef WITH_POSIX char msg_control[CMSG_LEN(sizeof(struct sockaddr_storage))]; struct msghdr mhdr; struct iovec iov[1]; -#endif /* WITH_POSIX */ assert(ep); assert(packet); @@ -429,7 +344,6 @@ coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) { coap_address_init(&(*packet)->dst); /* the local interface address */ coap_address_init(&(*packet)->src); /* the remote peer */ -#ifdef WITH_POSIX iov[0].iov_base = (*packet)->payload; iov[0].iov_len = coap_get_max_packetlength(*packet); @@ -515,55 +429,6 @@ coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) { goto error; } } -#endif /* WITH_POSIX */ -#ifdef WITH_CONTIKI - /* FIXME: untested, make this work */ -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) - - if(uip_newdata()) { - uip_ipaddr_copy(&(*packet)->src.addr, &UIP_IP_BUF->srcipaddr); - (*packet)->src.port = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&(*packet)->dst.addr, &UIP_IP_BUF->destipaddr); - (*packet)->dst.port = UIP_UDP_BUF->destport; - - if (!is_local_if(&ep->addr, &(*packet)->dst)) { - coap_log(LOG_DEBUG, "packet received on wrong interface, dropped\n"); - goto error; - } - - len = uip_datalen(); - - if (len > coap_get_max_packetlength(*packet)) { - /* FIXME: we might want to send back a response */ - warn("discarded oversized packet\n"); - return -1; - } - - ((char *)uip_appdata)[len] = 0; -#ifndef NDEBUG - if (LOG_DEBUG <= coap_get_log_level()) { -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 40 -#endif - unsigned char addr_str[INET6_ADDRSTRLEN+8]; - - if (coap_print_addr(&(*packet)->src, addr_str, INET6_ADDRSTRLEN+8)) { - debug("received %zd bytes from %s\n", len, addr_str); - } - } -#endif /* NDEBUG */ - - (*packet)->length = len; - memcpy(&(*packet)->payload, uip_appdata, len); - } - -#undef UIP_IP_BUF -#undef UIP_UDP_BUF -#endif /* WITH_CONTIKI */ -#ifdef WITH_LWIP -#error "coap_network_read() not implemented on this platform" -#endif (*packet)->interface = ep;