From cb9e24c010803269d3ce5b9f051b878a58bb0e2e Mon Sep 17 00:00:00 2001 From: Olaf Bergmann Date: Mon, 15 Sep 2014 11:05:56 +0200 Subject: [PATCH] Use coap_network_read() and coap_network_send() in Contiki --- coap_io.c | 88 ++++++++++++++++++++++++++++++++++--------------------- coap_io.h | 5 +++- net.c | 45 ++++++++++++---------------- net.h | 8 +++++ 4 files changed, 85 insertions(+), 61 deletions(-) diff --git a/coap_io.c b/coap_io.c index 3c1956b6..e909641b 100644 --- a/coap_io.c +++ b/coap_io.c @@ -40,45 +40,52 @@ #ifndef CUSTOM_COAP_NETWORK_ENDPOINT #ifdef WITH_CONTIKI -struct coap_contiki_endpoint_t { - int handle; - coap_address_t addr; - struct uip_udp_conn *conn; /**< uIP connection object */ -}; +static ep_initialized = 0; -static inline coap_contiki_endpoint_t * +static inline struct coap_endpoint_t * coap_malloc_contiki_endpoint() { - /* FIXME */ - return NULL; + static struct coap_endpoint_t ep; + + if (ep_initialized) { + return NULL; + } else { + ep_initialized = 1; + return &ep; + } } static inline void -coap_free_contiki_endpoint(coap_endpoint_t *ep) { - /* FIXME */ +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) { - static initialized = 0; - struct coap_contiki_endpoint_t ep; + struct coap_endpoint_t *ep = coap_malloc_contiki_endpoint(); - if (initialized) - return NULL; + if (ep) { + memset(ep, 0, sizeof(struct coap_contiki_endpoint_t)); + ep->handle.conn = udp_new(NULL, 0, NULL); - memset(&ep, 0, sizeof(struct coap_contiki_endpoint_t)); - ep.conn = udp_new(NULL, 0, NULL); + if (!ep->handle.conn) { + coap_free_endpoint(ep); + return NULL; + } - if (!ep.conn) - return NULL; - - memcpy(ep.addr, addr, sizeof(coap_address_t)); - udp_bind(ep.conn, addr->port); - return &ep; + memcpy(ep->addr, addr, sizeof(coap_address_t)); + udp_bind(ep->handle.conn, addr->port); + } + return ep; } void coap_free_endpoint(coap_endpoint_t *ep) { - /* FIXME */ + if (ep) { + if (ep->handle.conn) { + uip_udp_remove(ep->handle.conn); + } + coap_free_contiki_endpoint(ep); + } } #else /* WITH_CONTIKI */ @@ -139,7 +146,7 @@ coap_new_endpoint(const coap_address_t *addr, int flags) { } memset(ep, 0, sizeof(struct coap_endpoint_t)); - ep->handle = sockfd; + ep->handle.fd = sockfd; ep->flags = flags; memcpy(&ep->addr, addr, sizeof(coap_address_t)); @@ -164,8 +171,8 @@ coap_new_endpoint(const coap_address_t *addr, int flags) { void coap_free_endpoint(coap_endpoint_t *ep) { if(ep) { - if (ep->handle >= 0) - close(ep->handle); + if (ep->handle.fd >= 0) + close(ep->handle.fd); coap_free_posix_endpoint((struct coap_endpoint_t *)ep); } } @@ -270,7 +277,7 @@ coap_network_send(struct coap_context_t *context UNUSED_PARAM, return -1; } - return sendmsg(ep->handle, &mhdr, 0); + return sendmsg(ep->handle.fd, &mhdr, 0); #else /* WITH_CONTIKI */ /* FIXME: untested */ /* FIXME: is there a way to check if send was successful? */ @@ -355,7 +362,7 @@ coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) { mhdr.msg_controllen = sizeof(msg_control); assert(sizeof(msg_control) == CMSG_LEN(sizeof(struct sockaddr_storage))); - len = recvmsg(ep->handle, &mhdr, 0); + len = recvmsg(ep->handle.fd, &mhdr, 0); if (len < 0) { coap_log(LOG_WARNING, "coap_network_read: %s\n", strerror(errno)); @@ -364,11 +371,11 @@ coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) { } else { struct cmsghdr *cmsg; - coap_log(LOG_DEBUG, "received %d bytes on fd %d\n", (int)len, ep->handle); + coap_log(LOG_DEBUG, "received %d bytes on fd %d\n", (int)len, ep->handle.fd); /* use getsockname() to get the local port */ (*packet)->dst.size = sizeof((*packet)->dst.addr); - if (getsockname(ep->handle, &(*packet)->dst.addr.sa, &(*packet)->dst.size) < 0) { + if (getsockname(ep->handle.fd, &(*packet)->dst.addr.sa, &(*packet)->dst.size) < 0) { coap_log(LOG_DEBUG, "cannot determine local port\n"); return -1; } @@ -440,10 +447,25 @@ coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet) { } memcpy(buf, uip_appdata, len); - /* PRINTF("Server received %d bytes from [", (int)len); */ - /* PRINT6ADDR(&local->addr); */ - /* PRINTF("]:%d\n", uip_ntohs(local->port)); */ + PRINTF("Server received %d bytes from [", (int)len); + PRINT6ADDR(remote->addr); + PRINTF("]:%d\n", uip_ntohs(remote->port)); } + +#if 0 + if(uip_newdata()) { + uip_ipaddr_copy(&src.addr, &UIP_IP_BUF->srcipaddr); + src.port = UIP_UDP_BUF->srcport; + uip_ipaddr_copy(&dst.addr, &UIP_IP_BUF->destipaddr); + dst.port = UIP_UDP_BUF->destport; + + bytes_read = uip_datalen(); + ((char *)uip_appdata)[bytes_read] = 0; + PRINTF("Server received %d bytes from [", (int)bytes_read); + PRINT6ADDR(&src.addr); + PRINTF("]:%d\n", uip_ntohs(src.port)); + } +#endif #undef UIP_IP_BUF #undef UIP_UDP_BUF #endif /* WITH_CONTIKI */ diff --git a/coap_io.h b/coap_io.h index 6883f0ee..b0931558 100644 --- a/coap_io.h +++ b/coap_io.h @@ -54,7 +54,10 @@ struct coap_context_t; * this endpoint. */ typedef struct coap_endpoint_t { - int handle; /**< opaque handle to identify this endpoint */ + union { + int fd; /**< on POSIX systems */ + void *conn; /**< opaque connection (e.g. uip_conn in Contiki) */ + } handle; /**< opaque handle to identify this endpoint */ coap_address_t addr; /**< local interface address */ int ifindex; int flags; diff --git a/net.c b/net.c index 07479b38..26590e97 100644 --- a/net.c +++ b/net.c @@ -367,18 +367,13 @@ coap_new_context( } #ifdef WITH_POSIX c->sockfd = c->endpoint->handle; - - return c; - - onerror: - coap_free(c); - return NULL; - #endif /* WITH_POSIX */ + +#if defined(WITH_POSIX) || defined(WITH_CONTIKI) + c->network_send = coap_network_send; + c->network_read = coap_network_read; + #ifdef WITH_CONTIKI - c->conn = udp_new(NULL, 0, NULL); - udp_bind(c->conn, listen_addr->port); - process_start(&coap_retransmit_process, (char *)c); PROCESS_CONTEXT_BEGIN(&coap_retransmit_process); @@ -388,8 +383,15 @@ coap_new_context( /* the retransmit timer must be initialized to some large value */ etimer_set(&the_coap_context.retransmit_timer, 0xFFFF); PROCESS_CONTEXT_END(&coap_retransmit_process); - return c; #endif /* WITH_CONTIKI */ + + return c; + + onerror: + coap_free(c); + return NULL; + +#endif /* WITH_POSIX || WITH_CONTIKI */ #ifdef WITH_LWIP c->pcb = udp_new(); /* hard assert: this is not expected to fail dynamically */ @@ -551,7 +553,7 @@ coap_send_impl(coap_context_t *context, if ( !context || !dst || !pdu ) return id; - bytes_written = coap_network_send(context, local_interface, dst, + bytes_written = context->network_send(context, local_interface, dst, (unsigned char *)pdu->hdr, pdu->length); if (bytes_written >= 0) { @@ -809,7 +811,7 @@ void coap_dispatch(coap_context_t *context, coap_queue_t *rcvd); int coap_read( coap_context_t *ctx ) { -#if defined(WITH_LWIP) || defined(WITH_CONTIKI) +#if defined(WITH_LWIP) char *buf; #endif ssize_t bytes_read = -1; @@ -829,21 +831,10 @@ coap_read( coap_context_t *ctx ) { coap_address_init(&src); #ifdef WITH_POSIX - bytes_read = coap_network_read(ctx->endpoint, &packet); + bytes_read = ctx->network_read(ctx->endpoint, &packet); #endif /* WITH_POSIX */ #ifdef WITH_CONTIKI - if(uip_newdata()) { - uip_ipaddr_copy(&src.addr, &UIP_IP_BUF->srcipaddr); - src.port = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&dst.addr, &UIP_IP_BUF->destipaddr); - dst.port = UIP_UDP_BUF->destport; - - bytes_read = uip_datalen(); - ((char *)uip_appdata)[bytes_read] = 0; - PRINTF("Server received %d bytes from [", (int)bytes_read); - PRINT6ADDR(&src.addr); - PRINTF("]:%d\n", uip_ntohs(src.port)); - } + bytes_read = ctx->network_read(ctx->endpoint, &packet); #endif /* WITH_CONTIKI */ #ifdef WITH_LWIP /* FIXME: use lwip address operation functions */ @@ -869,7 +860,7 @@ coap_read( coap_context_t *ctx ) { (unsigned char *)ctx->pending_package bytes_read); #endif /* WITH_LWIP */ #ifdef WITH_CONTIKI - result = coap_handle_message(ctx, &src, uip_appdata, bytes_read); + result = coap_handle_message(ctx, ctx->endpoint, packet); #endif /* WITH_CONTIKI */ } diff --git a/net.h b/net.h index fdbcfeb0..a0035516 100644 --- a/net.h +++ b/net.h @@ -143,6 +143,14 @@ typedef struct coap_context_t { unsigned int observe; coap_response_handler_t response_handler; + + ssize_t (*network_send)(struct coap_context_t *context, + const coap_endpoint_t *local_interface, + const coap_address_t *dst, + unsigned char *data, size_t datalen); + + ssize_t (*network_read)(coap_endpoint_t *ep, coap_packet_t **packet); + } coap_context_t; /**