From ef25cc6c58341e538e74a4bdbbe6e33ab0b108bb Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 10:50:28 +0100 Subject: [PATCH 1/8] Rimestats bugfix: only compile the rimestats printout if rimestats are enabled --- core/lib/print-stats.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/lib/print-stats.c b/core/lib/print-stats.c index 37cf442d6..6354cf7e3 100644 --- a/core/lib/print-stats.c +++ b/core/lib/print-stats.c @@ -55,6 +55,7 @@ void print_stats(void) { +#if RIMESTATS_CONF_ENABLED PRINTA("S %d.%d clock %lu tx %lu rx %lu rtx %lu rrx %lu rexmit %lu acktx %lu noacktx %lu ackrx %lu timedout %lu badackrx %lu toolong %lu tooshort %lu badsynch %lu badcrc %lu contentiondrop %lu sendingdrop %lu lltx %lu llrx %lu\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], clock_seconds(), @@ -66,6 +67,7 @@ print_stats(void) rimestats.badsynch, rimestats.badcrc, rimestats.contentiondrop, rimestats.sendingdrop, rimestats.lltx, rimestats.llrx); +#endif /* RIMESTATS_CONF_ENABLED */ #if ENERGEST_CONF_ON PRINTA("E %d.%d clock %lu cpu %lu lpm %lu irq %lu gled %lu yled %lu rled %lu tx %lu listen %lu sensors %lu serial %lu\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], From 0670a8e1e277044f5d3c96649b4131badd593997 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 23:29:58 +0100 Subject: [PATCH 2/8] Minor code style fixes to the contikimac and nullrdc code --- core/net/mac/contikimac.c | 69 +++++++++++++++++++++------------------ core/net/mac/csma.c | 5 +-- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/core/net/mac/contikimac.c b/core/net/mac/contikimac.c index 06998c42c..fa6f14e96 100644 --- a/core/net/mac/contikimac.c +++ b/core/net/mac/contikimac.c @@ -377,16 +377,17 @@ powercycle(struct rtimer *t, void *ptr) static uint8_t count; #if SYNC_CYCLE_STARTS - /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple of CHANNEL_CHECK_RATE */ - if (sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) { - sync_cycle_phase = 0; - sync_cycle_start += RTIMER_ARCH_SECOND; - cycle_start = sync_cycle_start; + /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple + of CHANNEL_CHECK_RATE */ + if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) { + sync_cycle_phase = 0; + sync_cycle_start += RTIMER_ARCH_SECOND; + cycle_start = sync_cycle_start; } else { #if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535 - cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE; + cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE; #else - cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE; + cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE; #endif } #else @@ -475,12 +476,13 @@ powercycle(struct rtimer *t, void *ptr) } if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) { - /* Schedule the next powercycle interrupt, or sleep the mcu until then. - Sleeping will not exit from this interrupt, so ensure an occasional wake cycle - or foreground processing will be blocked until a packet is detected */ + /* Schedule the next powercycle interrupt, or sleep the mcu + until then. Sleeping will not exit from this interrupt, so + ensure an occasional wake cycle or foreground processing will + be blocked until a packet is detected */ #if RDC_CONF_MCU_SLEEP static uint8_t sleepcycle; - if ((sleepcycle++<16) && !we_are_sending && !radio_is_on) { + if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) { rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start)); } else { sleepcycle = 0; @@ -519,7 +521,9 @@ broadcast_rate_drop(void) } /*---------------------------------------------------------------------------*/ static int -send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_list *buf_list) +send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, + struct rdc_buf_list *buf_list, + int is_receiver_awake) { rtimer_clock_t t0; rtimer_clock_t encounter_time = 0; @@ -538,8 +542,8 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ struct hdr *chdr; #endif /* WITH_CONTIKIMAC_HEADER */ - /* Exit if RDC and radio were explicitly turned off */ - if (!contikimac_is_on && !contikimac_keep_radio_on) { + /* Exit if RDC and radio were explicitly turned off */ + if(!contikimac_is_on && !contikimac_keep_radio_on) { PRINTF("contikimac: radio is turned off\n"); return MAC_TX_ERR_FATAL; } @@ -609,7 +613,6 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ } #endif - /* Make sure that the packet is longer or equal to the shortest packet length. */ transmit_len = packetbuf_totlen(); @@ -691,7 +694,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ /* Check if there are any transmissions by others. */ /* TODO: why does this give collisions before sending with the mc1322x? */ if(is_receiver_awake == 0) { - int i; + int i; for(i = 0; i < CCA_COUNT_MAX_TX; ++i) { t0 = RTIMER_NOW(); on(); @@ -720,8 +723,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ #if !RDC_CONF_HARDWARE_ACK if(!is_broadcast) { - /* Turn radio on to receive expected unicast ack. - Not necessary with hardware ack detection, and may trigger an unnecessary cca or rx cycle */ + /* Turn radio on to receive expected unicast ack. Not necessary + with hardware ack detection, and may trigger an unnecessary cca + or rx cycle */ on(); } #endif @@ -735,14 +739,14 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ watchdog_periodic(); - if((is_receiver_awake || is_known_receiver) && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { + if(!is_broadcast && (is_receiver_awake || is_known_receiver) && + !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]); break; } len = 0; - { rtimer_clock_t wt; rtimer_clock_t txtime; @@ -752,7 +756,8 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ ret = NETSTACK_RADIO.transmit(transmit_len); #if RDC_CONF_HARDWARE_ACK - /* For radios that block in the transmit routine and detect the ACK in hardware */ + /* For radios that block in the transmit routine and detect the + ACK in hardware */ if(ret == RADIO_TX_OK) { if(!is_broadcast) { got_strobe_ack = 1; @@ -764,9 +769,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ PRINTF("contikimac: collisions while sending\n"); collisions++; } - wt = RTIMER_NOW(); + wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } -#else +#else /* RDC_CONF_HARDWARE_ACK */ /* Wait for the ACK packet */ wt = RTIMER_NOW(); while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } @@ -779,7 +784,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { } len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); - if(len == ACK_LEN && seqno == ackbuf[ACK_LEN-1]) { + if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) { got_strobe_ack = 1; encounter_time = txtime; break; @@ -829,16 +834,16 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ } #if WITH_PHASE_OPTIMIZATION - if(is_known_receiver && got_strobe_ack) { - PRINTF("no miss %d wake-ups %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], + PRINTF("no miss %d wake-ups %d\n", + packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], strobes); } if(!is_broadcast) { if(collisions == 0 && is_receiver_awake == 0) { - phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time, - ret); + phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), + encounter_time, ret); } } #endif /* WITH_PHASE_OPTIMIZATION */ @@ -903,8 +908,9 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) is_receiver_awake = 0; } /*---------------------------------------------------------------------------*/ -/* Timer callback triggered when receiving a burst, after having waited for a next - packet for a too long time. Turns the radio off and leaves burst reception mode */ +/* Timer callback triggered when receiving a burst, after having + waited for a next packet for a too long time. Turns the radio off + and leaves burst reception mode */ static void recv_burst_off(void *ptr) { @@ -952,7 +958,8 @@ input_packet(void) we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING); if(we_are_receiving_burst) { on(); - /* Set a timer to turn the radio off in case we do not receive a next packet */ + /* Set a timer to turn the radio off in case we do not receive + a next packet */ ctimer_set(&ct, INTER_PACKET_DEADLINE, recv_burst_off, NULL); } else { off(); diff --git a/core/net/mac/csma.c b/core/net/mac/csma.c index 157032ace..cb0430341 100644 --- a/core/net/mac/csma.c +++ b/core/net/mac/csma.c @@ -110,8 +110,9 @@ static void packet_sent(void *ptr, int status, int num_transmissions); static void transmit_packet_list(void *ptr); /*---------------------------------------------------------------------------*/ -static struct -neighbor_queue *neighbor_queue_from_addr(const rimeaddr_t *addr) { +static struct neighbor_queue * +neighbor_queue_from_addr(const rimeaddr_t *addr) +{ struct neighbor_queue *n = list_head(neighbor_list); while(n != NULL) { if(rimeaddr_cmp(&n->addr, addr)) { From 82b755c0175ddf69d6fd20115b6922c6019fbc33 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 23:35:39 +0100 Subject: [PATCH 3/8] Bugfix: keep track of receiver being awake as a local variable rather than a global, as it may have changed between invokations --- core/net/mac/contikimac.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/net/mac/contikimac.c b/core/net/mac/contikimac.c index fa6f14e96..716d47882 100644 --- a/core/net/mac/contikimac.c +++ b/core/net/mac/contikimac.c @@ -116,8 +116,6 @@ struct hdr { /* Are we currently receiving a burst? */ static int we_are_receiving_burst = 0; -/* Has the receiver been awoken by a burst we're sending? */ -static int is_receiver_awake = 0; /* BURST_RECV_TIME is the maximum time a receiver waits for the next packet of a burst when FRAME_PENDING is set. */ @@ -854,7 +852,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, static void qsend_packet(mac_callback_t sent, void *ptr) { - int ret = send_packet(sent, ptr, NULL); + int ret = send_packet(sent, ptr, NULL, 0); if(ret != MAC_TX_DEFERRED) { mac_call_sent_callback(sent, ptr, ret, 1); } @@ -866,6 +864,8 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) struct rdc_buf_list *curr = buf_list; struct rdc_buf_list *next; int ret; + int is_receiver_awake; + if(curr == NULL) { return; } @@ -889,7 +889,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) } /* Send the current packet */ - ret = send_packet(sent, ptr, curr); + ret = send_packet(sent, ptr, curr, is_receiver_awake); if(ret != MAC_TX_DEFERRED) { mac_call_sent_callback(sent, ptr, ret, 1); } @@ -905,7 +905,6 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) next = NULL; } } while(next != NULL); - is_receiver_awake = 0; } /*---------------------------------------------------------------------------*/ /* Timer callback triggered when receiving a burst, after having From f2fbb4b49d212239beaea6075bce7de8222a73b9 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 23:38:14 +0100 Subject: [PATCH 4/8] Defensive programming: make sure that we don't fail completely if we get a callback for a NULL pointer --- core/net/mac/csma.c | 269 ++++++++++++++++++++++---------------------- 1 file changed, 135 insertions(+), 134 deletions(-) diff --git a/core/net/mac/csma.c b/core/net/mac/csma.c index cb0430341..37d8f4998 100644 --- a/core/net/mac/csma.c +++ b/core/net/mac/csma.c @@ -186,15 +186,19 @@ free_first_packet(struct neighbor_queue *n) static void packet_sent(void *ptr, int status, int num_transmissions) { - struct neighbor_queue *n = ptr; - struct rdc_buf_list *q = list_head(n->queued_packet_list); - struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; + struct neighbor_queue *n; + struct rdc_buf_list *q; + struct qbuf_metadata *metadata; clock_time_t time = 0; mac_callback_t sent; void *cptr; int num_tx; int backoff_transmissions; + n = ptr; + if(n == NULL) { + return; + } switch(status) { case MAC_TX_OK: case MAC_TX_NOACK: @@ -208,66 +212,72 @@ packet_sent(void *ptr, int status, int num_transmissions) break; } - sent = metadata->sent; - cptr = metadata->cptr; - num_tx = n->transmissions; + q = list_head(n->queued_packet_list); + if(q != NULL) { + metadata = (struct qbuf_metadata *)q->ptr; - if(status == MAC_TX_COLLISION || - status == MAC_TX_NOACK) { + if(metadata != NULL) { + sent = metadata->sent; + cptr = metadata->cptr; + num_tx = n->transmissions; + if(status == MAC_TX_COLLISION || + status == MAC_TX_NOACK) { - /* If the transmission was not performed because of a collision or - noack, we must retransmit the packet. */ - - switch(status) { - case MAC_TX_COLLISION: - PRINTF("csma: rexmit collision %d\n", n->transmissions); - break; - case MAC_TX_NOACK: - PRINTF("csma: rexmit noack %d\n", n->transmissions); - break; - default: - PRINTF("csma: rexmit err %d, %d\n", status, n->transmissions); + /* If the transmission was not performed because of a + collision or noack, we must retransmit the packet. */ + + switch(status) { + case MAC_TX_COLLISION: + PRINTF("csma: rexmit collision %d\n", n->transmissions); + break; + case MAC_TX_NOACK: + PRINTF("csma: rexmit noack %d\n", n->transmissions); + break; + default: + PRINTF("csma: rexmit err %d, %d\n", status, n->transmissions); + } + + /* The retransmission time must be proportional to the channel + check interval of the underlying radio duty cycling layer. */ + time = default_timebase(); + + /* The retransmission time uses a linear backoff so that the + interval between the transmissions increase with each + retransmit. */ + backoff_transmissions = n->transmissions + 1; + + /* Clamp the number of backoffs so that we don't get a too long + timeout here, since that will delay all packets in the + queue. */ + if(backoff_transmissions > 3) { + backoff_transmissions = 3; + } + + time = time + (random_rand() % (backoff_transmissions * time)); + + if(n->transmissions < metadata->max_transmissions) { + PRINTF("csma: retransmitting with time %lu %p\n", time, q); + ctimer_set(&n->transmit_timer, time, + transmit_packet_list, n); + /* This is needed to correctly attribute energy that we spent + transmitting this packet. */ + queuebuf_update_attr_from_packetbuf(q->buf); + } else { + PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", + status, n->transmissions, n->collisions); + free_first_packet(n); + mac_call_sent_callback(sent, cptr, status, num_tx); + } + } else { + if(status == MAC_TX_OK) { + PRINTF("csma: rexmit ok %d\n", n->transmissions); + } else { + PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); + } + free_first_packet(n); + mac_call_sent_callback(sent, cptr, status, num_tx); + } } - - /* The retransmission time must be proportional to the channel - check interval of the underlying radio duty cycling layer. */ - time = default_timebase(); - - /* The retransmission time uses a linear backoff so that the - interval between the transmissions increase with each - retransmit. */ - backoff_transmissions = n->transmissions + 1; - - /* Clamp the number of backoffs so that we don't get a too long - timeout here, since that will delay all packets in the - queue. */ - if(backoff_transmissions > 3) { - backoff_transmissions = 3; - } - - time = time + (random_rand() % (backoff_transmissions * time)); - - if(n->transmissions < metadata->max_transmissions) { - PRINTF("csma: retransmitting with time %lu %p\n", time, q); - ctimer_set(&n->transmit_timer, time, - transmit_packet_list, n); - /* This is needed to correctly attribute energy that we spent - transmitting this packet. */ - queuebuf_update_attr_from_packetbuf(q->buf); - } else { - PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", - status, n->transmissions, n->collisions); - free_first_packet(n); - mac_call_sent_callback(sent, cptr, status, num_tx); - } - } else { - if(status == MAC_TX_OK) { - PRINTF("csma: rexmit ok %d\n", n->transmissions); - } else { - PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); - } - free_first_packet(n); - mac_call_sent_callback(sent, cptr, status, num_tx); } } /*---------------------------------------------------------------------------*/ @@ -277,86 +287,77 @@ send_packet(mac_callback_t sent, void *ptr) struct rdc_buf_list *q; struct neighbor_queue *n; static uint16_t seqno; + const rimeaddr_t *addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, seqno++); - - /* If the packet is a broadcast, do not allocate a queue - entry. Instead, just send it out. */ - if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), - &rimeaddr_null)) { - const rimeaddr_t *addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); - - /* Look for the neighbor entry */ - n = neighbor_queue_from_addr(addr); - if(n == NULL) { - /* Allocate a new neighbor entry */ - n = memb_alloc(&neighbor_memb); - if(n != NULL) { - /* Init neighbor entry */ - rimeaddr_copy(&n->addr, addr); - n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; - /* Init packet list for this neighbor */ - LIST_STRUCT_INIT(n, queued_packet_list); - /* Add neighbor to the list */ - list_add(neighbor_list, n); - } - } + /* Look for the neighbor entry */ + n = neighbor_queue_from_addr(addr); + if(n == NULL) { + /* Allocate a new neighbor entry */ + n = memb_alloc(&neighbor_memb); if(n != NULL) { - /* Add packet to the neighbor's queue */ - q = memb_alloc(&packet_memb); - if(q != NULL) { - q->ptr = memb_alloc(&metadata_memb); - if(q->ptr != NULL) { - q->buf = queuebuf_new_from_packetbuf(); - if(q->buf != NULL) { - struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; - /* Neighbor and packet successfully allocated */ - if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) { - /* Use default configuration for max transmissions */ - metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS; - } else { - metadata->max_transmissions = - packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); - } - metadata->sent = sent; - metadata->cptr = ptr; - - if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == - PACKETBUF_ATTR_PACKET_TYPE_ACK) { - list_push(n->queued_packet_list, q); - } else { - list_add(n->queued_packet_list, q); - } - - /* If q is the first packet in the neighbor's queue, send asap */ - if(list_head(n->queued_packet_list) == q) { - ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n); - } - return; - } - memb_free(&metadata_memb, q->ptr); - PRINTF("csma: could not allocate queuebuf, dropping packet\n"); - } - memb_free(&packet_memb, q); - PRINTF("csma: could not allocate queuebuf, dropping packet\n"); - } - /* The packet allocation failed. Remove and free neighbor entry if empty. */ - if(list_length(n->queued_packet_list) == 0) { - list_remove(neighbor_list, n); - memb_free(&neighbor_memb, n); - } - PRINTF("csma: could not allocate packet, dropping packet\n"); - } else { - PRINTF("csma: could not allocate neighbor, dropping packet\n"); + /* Init neighbor entry */ + rimeaddr_copy(&n->addr, addr); + n->transmissions = 0; + n->collisions = 0; + n->deferrals = 0; + /* Init packet list for this neighbor */ + LIST_STRUCT_INIT(n, queued_packet_list); + /* Add neighbor to the list */ + list_add(neighbor_list, n); } - mac_call_sent_callback(sent, ptr, MAC_TX_ERR, 1); - } else { - PRINTF("csma: send broadcast\n"); - NETSTACK_RDC.send(sent, ptr); } + + if(n != NULL) { + /* Add packet to the neighbor's queue */ + q = memb_alloc(&packet_memb); + if(q != NULL) { + q->ptr = memb_alloc(&metadata_memb); + if(q->ptr != NULL) { + q->buf = queuebuf_new_from_packetbuf(); + if(q->buf != NULL) { + struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr; + /* Neighbor and packet successfully allocated */ + if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) { + /* Use default configuration for max transmissions */ + metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS; + } else { + metadata->max_transmissions = + packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); + } + metadata->sent = sent; + metadata->cptr = ptr; + + if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == + PACKETBUF_ATTR_PACKET_TYPE_ACK) { + list_push(n->queued_packet_list, q); + } else { + list_add(n->queued_packet_list, q); + } + + /* If q is the first packet in the neighbor's queue, send asap */ + if(list_head(n->queued_packet_list) == q) { + ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n); + } + return; + } + memb_free(&metadata_memb, q->ptr); + PRINTF("csma: could not allocate queuebuf, dropping packet\n"); + } + memb_free(&packet_memb, q); + PRINTF("csma: could not allocate queuebuf, dropping packet\n"); + } + /* The packet allocation failed. Remove and free neighbor entry if empty. */ + if(list_length(n->queued_packet_list) == 0) { + list_remove(neighbor_list, n); + memb_free(&neighbor_memb, n); + } + PRINTF("csma: could not allocate packet, dropping packet\n"); + } else { + PRINTF("csma: could not allocate neighbor, dropping packet\n"); + } + mac_call_sent_callback(sent, ptr, MAC_TX_ERR, 1); } /*---------------------------------------------------------------------------*/ static void From 4efd570cf93627a21d2df1b49c88dd00b541504c Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 23:43:03 +0100 Subject: [PATCH 5/8] Minor bugfix: explicitly cast pointer argument in debug printf --- core/net/mac/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/mac/mac.c b/core/net/mac/mac.c index c79b75665..bdb7b6f2f 100644 --- a/core/net/mac/mac.c +++ b/core/net/mac/mac.c @@ -45,7 +45,7 @@ void mac_call_sent_callback(mac_callback_t sent, void *ptr, int status, int num_tx) { PRINTF("mac_callback_t %p ptr %p status %d num_tx %d\n", - sent, ptr, status, num_tx); + (void *)sent, ptr, status, num_tx); switch(status) { case MAC_TX_COLLISION: PRINTF("mac: collision after %d tx\n", num_tx); From 843d2361dcc0247309eac4be430ccc814599ae28 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 23:53:46 +0100 Subject: [PATCH 6/8] Include the rimestats variable only if rimestats are enabled by the configuration --- core/net/rime/rimestats.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/net/rime/rimestats.h b/core/net/rime/rimestats.h index 3fd9b06b7..607aa78ad 100644 --- a/core/net/rime/rimestats.h +++ b/core/net/rime/rimestats.h @@ -55,8 +55,11 @@ struct rimestats { unsigned long lltx, llrx; }; +#if RIMESTATS_CONF_ENABLED extern struct rimestats rimestats; - #define RIMESTATS_ADD(x) rimestats.x++ +#else /* RIMESTATS_CONF_ENABLED */ +#define RIMESTATS_ADD(x) +#endif /* RIMESTATS_CONF_ENABLED */ #endif /* __RIMESTATS_H__ */ From 2ba293a53864232b302b63e5971d3982157dee7d Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 23:56:55 +0100 Subject: [PATCH 7/8] Bugfix: check the size of the outgoing packet to avoid overflowing the output buffer --- core/net/uip-udp-packet.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/net/uip-udp-packet.c b/core/net/uip-udp-packet.c index 8e9369ab7..96423bfcb 100644 --- a/core/net/uip-udp-packet.c +++ b/core/net/uip-udp-packet.c @@ -54,7 +54,8 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len) uip_udp_conn = c; uip_slen = len; memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, - len > UIP_BUFSIZE? UIP_BUFSIZE: len); + len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? + UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len); uip_process(UIP_UDP_SEND_CONN); #if UIP_CONF_IPV6 tcpip_ipv6_output(); From 7742b05d8cc5976c27c365c517699b403944b3b1 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 17 Mar 2013 23:49:32 +0100 Subject: [PATCH 8/8] Major bugfix: when nullrdc is asked to send a list of packets, send the list of packets and not just the first packet - this is essential for retransmissions of fragmented IP packets to work --- core/net/mac/nullrdc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/net/mac/nullrdc.c b/core/net/mac/nullrdc.c index 1ba5d939b..9321c3ede 100644 --- a/core/net/mac/nullrdc.c +++ b/core/net/mac/nullrdc.c @@ -208,9 +208,10 @@ send_packet(mac_callback_t sent, void *ptr) static void send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) { - if(buf_list != NULL) { + while(buf_list != NULL) { queuebuf_to_packetbuf(buf_list->buf); send_packet(sent, ptr); + buf_list = buf_list->next; } } /*---------------------------------------------------------------------------*/