net: contiki: move neighbor_list to struct l2_buf

When using the CSMA MAC driver, a new packet can be queued before
all the fragments of the previous one were sent. The transmit_packet_list()
function will start sending the old fragments with the new net_buf context.

Keep a per-context neighbor_list to avoid that

Change-Id: I9d41a923c48f597cc95a8f8c9f67884c5caac02c
Signed-off-by: Vlad Lungu <vlad.lungu@windriver.com>
This commit is contained in:
Vlad Lungu 2016-03-16 15:52:08 +02:00 committed by Gerrit Code Review
commit 0667c0fe0e
3 changed files with 17 additions and 7 deletions

View file

@ -34,6 +34,7 @@
#include "contiki/ip/uipopt.h" #include "contiki/ip/uipopt.h"
#include "contiki/ip/uip.h" #include "contiki/ip/uip.h"
#include "contiki/packetbuf.h" #include "contiki/packetbuf.h"
#include "contiki/os/lib/list.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -66,6 +67,9 @@ struct l2_buf {
int packetbuf_payload_len; int packetbuf_payload_len;
uint8_t uncomp_hdr_len; uint8_t uncomp_hdr_len;
int last_tx_status; int last_tx_status;
#if defined(CONFIG_NETWORKING_WITH_15_4)
LIST_STRUCT(neighbor_list);
#endif
struct packetbuf_attr pkt_packetbuf_attrs[PACKETBUF_NUM_ATTRS]; struct packetbuf_attr pkt_packetbuf_attrs[PACKETBUF_NUM_ATTRS];
struct packetbuf_addr pkt_packetbuf_addrs[PACKETBUF_NUM_ADDRS]; struct packetbuf_addr pkt_packetbuf_addrs[PACKETBUF_NUM_ADDRS];
@ -86,6 +90,10 @@ struct l2_buf {
(((struct l2_buf *)net_buf_user_data((buf)))->uncomp_hdr_len) (((struct l2_buf *)net_buf_user_data((buf)))->uncomp_hdr_len)
#define uip_last_tx_status(buf) \ #define uip_last_tx_status(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->last_tx_status) (((struct l2_buf *)net_buf_user_data((buf)))->last_tx_status)
#if defined(CONFIG_NETWORKING_WITH_15_4)
#define uip_neighbor_list(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->neighbor_list)
#endif
#define uip_pkt_buflen(buf) \ #define uip_pkt_buflen(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_buflen) (((struct l2_buf *)net_buf_user_data((buf)))->pkt_buflen)
#define uip_pkt_bufptr(buf) \ #define uip_pkt_bufptr(buf) \

View file

@ -132,16 +132,15 @@ struct neighbor_queue {
MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES); MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES);
MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS); MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS);
MEMB(metadata_memb, struct qbuf_metadata, MAX_QUEUED_PACKETS); MEMB(metadata_memb, struct qbuf_metadata, MAX_QUEUED_PACKETS);
LIST(neighbor_list);
static void packet_sent(struct net_buf *buf, void *ptr, int status, int num_transmissions); static void packet_sent(struct net_buf *buf, void *ptr, int status, int num_transmissions);
static void transmit_packet_list(struct net_buf *buf, void *ptr); static void transmit_packet_list(struct net_buf *buf, void *ptr);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static struct neighbor_queue * static struct neighbor_queue *
neighbor_queue_from_addr(const linkaddr_t *addr) neighbor_queue_from_addr(struct net_buf *buf, const linkaddr_t *addr)
{ {
struct neighbor_queue *n = list_head(neighbor_list); struct neighbor_queue *n = list_head(uip_neighbor_list(buf));
while(n != NULL) { while(n != NULL) {
if(linkaddr_cmp(&n->addr, addr)) { if(linkaddr_cmp(&n->addr, addr)) {
return n; return n;
@ -188,7 +187,7 @@ free_packet(struct net_buf *buf, struct neighbor_queue *n, struct rdc_buf_list *
transmit_packet_list(buf, n); transmit_packet_list(buf, n);
} else { } else {
/* This was the last packet in the queue, we free the neighbor */ /* This was the last packet in the queue, we free the neighbor */
list_remove(neighbor_list, n); list_remove(uip_neighbor_list(buf), n);
memb_free(&neighbor_memb, n); memb_free(&neighbor_memb, n);
l2_buf_unref(buf); l2_buf_unref(buf);
} }
@ -354,7 +353,7 @@ send_packet(struct net_buf *buf, mac_callback_t sent, bool last_fragment, void *
packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_SEQNO, seqno++); packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_SEQNO, seqno++);
/* Look for the neighbor entry */ /* Look for the neighbor entry */
n = neighbor_queue_from_addr(addr); n = neighbor_queue_from_addr(buf, addr);
if(n == NULL) { if(n == NULL) {
/* Allocate a new neighbor entry */ /* Allocate a new neighbor entry */
n = memb_alloc(&neighbor_memb); n = memb_alloc(&neighbor_memb);
@ -367,7 +366,7 @@ send_packet(struct net_buf *buf, mac_callback_t sent, bool last_fragment, void *
/* Init packet list for this neighbor */ /* Init packet list for this neighbor */
LIST_STRUCT_INIT(n, queued_packet_list); LIST_STRUCT_INIT(n, queued_packet_list);
/* Add neighbor to the list */ /* Add neighbor to the list */
list_add(neighbor_list, n); list_add(uip_neighbor_list(buf), n);
} }
} }
@ -416,7 +415,7 @@ send_packet(struct net_buf *buf, mac_callback_t sent, bool last_fragment, void *
} }
/* The packet allocation failed. Remove and free neighbor entry if empty. */ /* The packet allocation failed. Remove and free neighbor entry if empty. */
if(list_length(n->queued_packet_list) == 0) { if(list_length(n->queued_packet_list) == 0) {
list_remove(neighbor_list, n); list_remove(uip_neighbor_list(buf), n);
memb_free(&neighbor_memb, n); memb_free(&neighbor_memb, n);
} }
} else { } else {

View file

@ -131,6 +131,9 @@ struct net_buf *l2_buf_get_reserve(uint16_t reserve_head)
#endif #endif
packetbuf_clear(buf); packetbuf_clear(buf);
#if defined(CONFIG_NETWORKING_WITH_15_4)
LIST_STRUCT_INIT(((struct l2_buf *)net_buf_user_data((buf))), neighbor_list);
#endif
return buf; return buf;
} }