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;