diff --git a/core/contiki-default-conf.h b/core/contiki-default-conf.h index ed82c73ac..36bf6afe1 100644 --- a/core/contiki-default-conf.h +++ b/core/contiki-default-conf.h @@ -220,14 +220,6 @@ * on the target platform, and are therefore platform-specific. */ -/* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS specifies how many times the - MAC layer should resend packets if no link-layer ACK was - received. This only makes sense with the csma_driver - NETSTACK_CONF_MAC. */ -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 4 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ - /* SICSLOWPAN_CONF_FRAG specifies if 6lowpan fragmentation should be used or not. Fragmentation is on by default. */ #ifndef SICSLOWPAN_CONF_FRAG diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index de9d78181..942acd13b 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -92,12 +92,6 @@ void uip_log(char *msg); #define UIP_LOG(m) #endif /* UIP_LOGGING == 1 */ -#ifdef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#else -#define SICSLOWPAN_MAX_MAC_TRANSMISSIONS 4 -#endif - #ifndef SICSLOWPAN_COMPRESSION #ifdef SICSLOWPAN_CONF_COMPRESSION #define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION @@ -1290,9 +1284,6 @@ output(const uip_lladdr_t *localdest) packetbuf_clear(); packetbuf_ptr = packetbuf_dataptr(); - packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, - SICSLOWPAN_MAX_MAC_TRANSMISSIONS); - if(callback) { /* call the attribution when the callback comes, but set attributes here ! */ diff --git a/core/net/mac/csma.c b/core/net/mac/csma.c index e6f79b066..eea86b4e8 100644 --- a/core/net/mac/csma.c +++ b/core/net/mac/csma.c @@ -63,26 +63,35 @@ #define PRINTF(...) #endif /* DEBUG */ -#ifndef CSMA_MAX_BACKOFF_EXPONENT -#ifdef CSMA_CONF_MAX_BACKOFF_EXPONENT -#define CSMA_MAX_BACKOFF_EXPONENT CSMA_CONF_MAX_BACKOFF_EXPONENT -#else -#define CSMA_MAX_BACKOFF_EXPONENT 3 -#endif /* CSMA_CONF_MAX_BACKOFF_EXPONENT */ -#endif /* CSMA_MAX_BACKOFF_EXPONENT */ +/* Constants of the IEEE 802.15.4 standard */ -#ifndef CSMA_MAX_MAC_TRANSMISSIONS -#ifdef CSMA_CONF_MAX_MAC_TRANSMISSIONS -#define CSMA_MAX_MAC_TRANSMISSIONS CSMA_CONF_MAX_MAC_TRANSMISSIONS +/* macMinBE: Initial backoff exponent. Range 0--CSMA_MAX_BE */ +#ifdef CSMA_CONF_MIN_BE +#define CSMA_MIN_BE CSMA_CONF_MIN_BE #else -#define CSMA_MAX_MAC_TRANSMISSIONS 3 -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS */ -#endif /* CSMA_MAX_MAC_TRANSMISSIONS */ +#define CSMA_MIN_BE 0 +#endif -#if CSMA_MAX_MAC_TRANSMISSIONS < 1 -#error CSMA_CONF_MAX_MAC_TRANSMISSIONS must be at least 1. -#error Change CSMA_CONF_MAX_MAC_TRANSMISSIONS in contiki-conf.h or in your Makefile. -#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS < 1 */ +/* macMaxBE: Maximum backoff exponent. Range 3--8 */ +#ifdef CSMA_CONF_MAX_BE +#define CSMA_MAX_BE CSMA_CONF_MAX_BE +#else +#define CSMA_MAX_BE 4 +#endif + +/* macMaxCSMABackoffs: Maximum number of backoffs in case of channel busy/collision. Range 0--5 */ +#ifdef CSMA_CONF_MAX_BACKOFF +#define CSMA_MAX_BACKOFF CSMA_CONF_MAX_BACKOFF +#else +#define CSMA_MAX_BACKOFF 5 +#endif + +/* macMaxFrameRetries: Maximum number of re-transmissions attampts. Range 0--7 */ +#ifdef CSMA_CONF_MAX_FRAME_RETRIES +#define CSMA_MAX_MAX_FRAME_RETRIES CSMA_CONF_MAX_FRAME_RETRIES +#else +#define CSMA_MAX_MAX_FRAME_RETRIES 7 +#endif /* Packet metadata */ struct qbuf_metadata { @@ -97,7 +106,7 @@ struct neighbor_queue { linkaddr_t addr; struct ctimer transmit_timer; uint8_t transmissions; - uint8_t collisions, deferrals; + uint8_t collisions; LIST_STRUCT(queued_packet_list); }; @@ -138,18 +147,18 @@ neighbor_queue_from_addr(const linkaddr_t *addr) } /*---------------------------------------------------------------------------*/ static clock_time_t -default_timebase(void) +backoff_period(void) { clock_time_t time; /* The retransmission time must be proportional to the channel check interval of the underlying radio duty cycling layer. */ time = NETSTACK_RDC.channel_check_interval(); - /* If the radio duty cycle has no channel check interval (i.e., it - does not turn the radio off), we make the retransmission time - proportional to the configured MAC channel check rate. */ + /* If the radio duty cycle has no channel check interval, we use + * the default in IEEE 802.15.4: aUnitBackoffPeriod which is + * 20 symbols i.e. 320 usec. That is, 1/3125 second. */ if(time == 0) { - time = (CLOCK_SECOND / 3125) ? (CLOCK_SECOND / 3125) : 1; + time = MAX(CLOCK_SECOND / 3125, 1); } return time; } @@ -170,10 +179,28 @@ transmit_packet_list(void *ptr) } /*---------------------------------------------------------------------------*/ static void +schedule_transmission(struct neighbor_queue *n) +{ + clock_time_t delay; + int backoff_exponent; /* BE in IEEE 802.15.4 */ + + backoff_exponent = MIN(n->collisions, CSMA_MAX_BE); + + /* Compute max delay as per IEEE 802.15.4: 2^BE-1 backoff periods */ + delay = ((1 << backoff_exponent) - 1) * backoff_period(); + if(delay > 0) { + /* Pick a time for next transmission */ + delay = random_rand() % delay; + } + + PRINTF("csma: scheduling transmission in %u ticks, NB=%u, BE=%u\n", + (unsigned)delay, n->collisions, backoff_exponent); + ctimer_set(&n->transmit_timer, delay, transmit_packet_list, n); +} +/*---------------------------------------------------------------------------*/ +static void free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status) { - clock_time_t tx_delay; - if(p != NULL) { /* Remove packet from list and deallocate */ list_remove(n->queued_packet_list, p); @@ -186,11 +213,9 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status) if(list_head(n->queued_packet_list) != NULL) { /* There is a next packet. We reset current tx information */ n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; - /* Set a timer for next transmissions */ - tx_delay = (status == MAC_TX_OK) ? 0 : default_timebase(); - ctimer_set(&n->transmit_timer, tx_delay, transmit_packet_list, n); + n->collisions = CSMA_MIN_BE; + /* Schedule next transmissions */ + schedule_transmission(n); } else { /* This was the last packet in the queue, we free the neighbor */ ctimer_stop(&n->transmit_timer); @@ -232,22 +257,7 @@ tx_done(int status, struct rdc_buf_list *q, struct neighbor_queue *n) static void rexmit(struct rdc_buf_list *q, struct neighbor_queue *n) { - clock_time_t time; - int backoff_exponent; - int backoff_transmissions; - - time = default_timebase(); - backoff_exponent = n->collisions; - - /* Proceed to exponentiation. */ - backoff_transmissions = 1 << backoff_exponent; - - /* Pick a time for next transmission, within the interval: - * [time, time + 2^backoff_exponent * time[ */ - time = time + (random_rand() % (backoff_transmissions * time)); - - PRINTF("csma: retransmitting with time %lu %p\n", time, q); - ctimer_set(&n->transmit_timer, time, transmit_packet_list, n); + schedule_transmission(n); /* This is needed to correctly attribute energy that we spent transmitting this packet. */ queuebuf_update_attr_from_packetbuf(q->buf); @@ -263,9 +273,10 @@ collision(struct rdc_buf_list *q, struct neighbor_queue *n, n->collisions += num_transmissions; - if(n->collisions > CSMA_MAX_BACKOFF_EXPONENT) { - n->collisions = 0; - n->transmissions += num_transmissions; + if(n->collisions > CSMA_MAX_BACKOFF) { + n->collisions = CSMA_MIN_BE; + /* Increment to indicate a next retry */ + n->transmissions++; } if(n->transmissions >= metadata->max_transmissions) { @@ -283,8 +294,8 @@ noack(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) metadata = (struct qbuf_metadata *)q->ptr; + n->collisions = CSMA_MIN_BE; n->transmissions += num_transmissions; - n->collisions = 0; if(n->transmissions >= metadata->max_transmissions) { tx_done(MAC_TX_NOACK, q, n); @@ -297,6 +308,7 @@ noack(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) static void tx_ok(struct rdc_buf_list *q, struct neighbor_queue *n, int num_transmissions) { + n->collisions = CSMA_MIN_BE; n->transmissions += num_transmissions; tx_done(MAC_TX_OK, q, n); } @@ -341,7 +353,6 @@ packet_sent(void *ptr, int status, int num_transmissions) collision(q, n, num_transmissions); break; case MAC_TX_DEFERRED: - n->deferrals += num_transmissions; break; default: tx_done(status, q, n); @@ -380,8 +391,7 @@ send_packet(mac_callback_t sent, void *ptr) /* Init neighbor entry */ linkaddr_copy(&n->addr, addr); n->transmissions = 0; - n->collisions = 0; - n->deferrals = 0; + n->collisions = CSMA_MIN_BE; /* Init packet list for this neighbor */ LIST_STRUCT_INIT(n, queued_packet_list); /* Add neighbor to the list */ @@ -402,7 +412,7 @@ send_packet(mac_callback_t sent, void *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; + metadata->max_transmissions = CSMA_MAX_MAX_FRAME_RETRIES + 1; } else { metadata->max_transmissions = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS); @@ -423,7 +433,7 @@ send_packet(mac_callback_t sent, void *ptr) list_length(n->queued_packet_list), memb_numfree(&packet_memb)); /* 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); + schedule_transmission(n); } return; } diff --git a/platform/cooja/contiki-conf.h b/platform/cooja/contiki-conf.h index 04f1c4d43..dba7e9553 100644 --- a/platform/cooja/contiki-conf.h +++ b/platform/cooja/contiki-conf.h @@ -168,9 +168,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 8 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #endif /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/platform/exp5438/contiki-conf.h b/platform/exp5438/contiki-conf.h index bb7a5fcdd..9220ba890 100644 --- a/platform/exp5438/contiki-conf.h +++ b/platform/exp5438/contiki-conf.h @@ -174,9 +174,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 diff --git a/platform/jn516x/contiki-conf.h b/platform/jn516x/contiki-conf.h index 8b702a56e..1a326f62b 100644 --- a/platform/jn516x/contiki-conf.h +++ b/platform/jn516x/contiki-conf.h @@ -154,9 +154,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #define UIP_CONF_ICMP_DEST_UNREACH 1 #define UIP_CONF_DHCP_LIGHT diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index e011bff96..03eacbbde 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -110,9 +110,6 @@ typedef unsigned short uip_stats_t; #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_QUEUE_PKT 1 diff --git a/platform/sky/contiki-conf.h b/platform/sky/contiki-conf.h index ff4ad8578..39d8bc882 100644 --- a/platform/sky/contiki-conf.h +++ b/platform/sky/contiki-conf.h @@ -179,9 +179,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108 diff --git a/platform/stm32nucleo-spirit1/contiki-conf.h b/platform/stm32nucleo-spirit1/contiki-conf.h index 14baa8d97..9a97ab355 100644 --- a/platform/stm32nucleo-spirit1/contiki-conf.h +++ b/platform/stm32nucleo-spirit1/contiki-conf.h @@ -106,10 +106,6 @@ #define SICSLOWPAN_CONF_MAXAGE 4 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ - #define UIP_CONF_ICMP_DEST_UNREACH 1 #define UIP_CONF_DHCP_LIGHT diff --git a/platform/wismote/contiki-conf.h b/platform/wismote/contiki-conf.h index bcc6c10ca..f7150c5ff 100644 --- a/platform/wismote/contiki-conf.h +++ b/platform/wismote/contiki-conf.h @@ -157,9 +157,6 @@ #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 -#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS -#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 -#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ #else /* NETSTACK_CONF_WITH_IPV6 */ #define UIP_CONF_IP_FORWARD 1 #define UIP_CONF_BUFFER_SIZE 108