From 3c44f7e0bcd7b5213c8f8fa10fba46f99340383f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 16 Feb 2016 17:57:47 +0200 Subject: [PATCH] net: contiki: Enable packet queueing Currently the packet is dropped if some other packet needs to be sent instead. This does not make much sense in Zephyr so activate packet queueing where the saved packet is sent later. The queueing can happen e.g., with neighbor discovery where the packet to be sent requires ND to be done before the actual application packet is being sent. Change-Id: Ia321d641eec5acfbc9f8f581de712801a483e32d Signed-off-by: Jukka Rissanen --- net/ip/contiki/contiki-conf.h | 5 ++++ net/ip/contiki/ip/tcpip.c | 37 +++++++++++++++++++++++++---- net/ip/contiki/ip/uip-packetqueue.c | 9 ++----- net/ip/contiki/ipv6/uip-nd6.c | 4 ++-- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/net/ip/contiki/contiki-conf.h b/net/ip/contiki/contiki-conf.h index 3d3165fca7d..396a2595ef9 100644 --- a/net/ip/contiki/contiki-conf.h +++ b/net/ip/contiki/contiki-conf.h @@ -49,6 +49,11 @@ typedef unsigned int uip_stats_t; */ #define QUEUEBUF_CONF_NUM (13 + 5) +/* Do not just drop packets because of some other packet is sent. + * So queue the packet and send it later. + */ +#define UIP_CONF_IPV6_QUEUE_PKT 1 + #ifdef SICSLOWPAN_CONF_ENABLE /* Min and Max compressible UDP ports */ #define SICSLOWPAN_UDP_PORT_MIN 0xF0B0 diff --git a/net/ip/contiki/ip/tcpip.c b/net/ip/contiki/ip/tcpip.c index 38497b9d79e..7fe46f8596a 100644 --- a/net/ip/contiki/ip/tcpip.c +++ b/net/ip/contiki/ip/tcpip.c @@ -671,7 +671,7 @@ tcpip_ipv6_output(struct net_buf *buf) } else { #if UIP_CONF_IPV6_QUEUE_PKT /* Copy outgoing pkt in the queuing buffer for later transmit. */ - if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) { + if(uip_packetqueue_alloc(buf, &nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) { memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF(buf), uip_len(buf)); uip_packetqueue_set_buflen(&nbr->packethandle, uip_len(buf)); } @@ -706,9 +706,12 @@ tcpip_ipv6_output(struct net_buf *buf) #if UIP_CONF_IPV6_QUEUE_PKT /* Copy outgoing pkt in the queuing buffer for later transmit and set the destination nbr to nbr. */ - if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) { + if(uip_packetqueue_alloc(buf, &nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) { memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF(buf), uip_len(buf)); uip_packetqueue_set_buflen(&nbr->packethandle, uip_len(buf)); + } else { + PRINTF("IP packet buf %p len %d discarded because no space " + "in the queue\n", buf, uip_len(buf)); } #else PRINTF("IP packet buf %p len %d discarded because neighbor info is " @@ -738,11 +741,35 @@ tcpip_ipv6_output(struct net_buf *buf) * to STALE, and you must both send a NA and the queued packet. */ if(uip_packetqueue_buflen(&nbr->packethandle) != 0) { - uip_len(buf) = uip_packetqueue_buflen(&nbr->packethandle); - memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&nbr->packethandle), uip_len(buf)); + bool allocated_here = false; + if (ret != 0) { + /* The IP buf was freed because the send succeed so we need to + * allocate a new one here. + */ + buf = ip_buf_get_reserve_tx(0); + if (!buf) { + PRINTF("%s(): Cannot send queued packet, no net buffers\n", __FUNCTION__); + uip_packetqueue_free(&nbr->packethandle); + goto no_buf; + } + allocated_here = true; + } + + uip_len(buf) = buf->len = uip_packetqueue_buflen(&nbr->packethandle); + memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&nbr->packethandle), + uip_len(buf)); uip_packetqueue_free(&nbr->packethandle); - ret = tcpip_output(uip_ds6_nbr_get_ll(nbr)); + ret = tcpip_output(buf, uip_ds6_nbr_get_ll(nbr)); + if (allocated_here && !ret) { + /* There was a sending error and the buffer was not released. + * We cannot return the buffer to upper layers so just release + * it here. + */ + ip_buf_unref(buf); + ret = 1; /* This will tell caller that buf is released. */ + } } + no_buf: #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ if (ret == 0) { diff --git a/net/ip/contiki/ip/uip-packetqueue.c b/net/ip/contiki/ip/uip-packetqueue.c index 5634bb649ac..7cd0647166a 100644 --- a/net/ip/contiki/ip/uip-packetqueue.c +++ b/net/ip/contiki/ip/uip-packetqueue.c @@ -9,13 +9,8 @@ #define MAX_NUM_QUEUED_PACKETS 2 MEMB(packets_memb, struct uip_packetqueue_packet, MAX_NUM_QUEUED_PACKETS); -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif +#define DEBUG DEBUG_NONE +#include "contiki/ip/uip-debug.h" /*---------------------------------------------------------------------------*/ static void diff --git a/net/ip/contiki/ipv6/uip-nd6.c b/net/ip/contiki/ipv6/uip-nd6.c index d60a31bcef7..7b51e5a4baf 100644 --- a/net/ip/contiki/ipv6/uip-nd6.c +++ b/net/ip/contiki/ipv6/uip-nd6.c @@ -575,7 +575,7 @@ na_input(struct net_buf *buf) return; }*/ if(uip_packetqueue_buflen(&uip_nbr(buf)->packethandle) != 0) { - uip_len(buf) = uip_packetqueue_buflen(&uip_nbr(buf)->packethandle); + uip_len(buf) = buf->len = uip_packetqueue_buflen(&uip_nbr(buf)->packethandle); memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&uip_nbr(buf)->packethandle), uip_len(buf)); uip_packetqueue_free(&uip_nbr(buf)->packethandle); return; @@ -1093,7 +1093,7 @@ ra_input(struct net_buf *buf) return; }*/ if(uip_nbr(buf) != NULL && uip_packetqueue_buflen(&uip_nbr(buf)->packethandle) != 0) { - uip_len(buf) = uip_packetqueue_buflen(&uip_nbr(buf)->packethandle); + uip_len(buf) = buf->len = uip_packetqueue_buflen(&uip_nbr(buf)->packethandle); memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&uip_nbr(buf)->packethandle), uip_len(buf)); uip_packetqueue_free(&uip_nbr(buf)->packethandle); return;