From 6d556d5c13399cb0cc2b4c96f319db5138dc35ad Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 25 Nov 2010 08:44:34 +0000 Subject: [PATCH] Fixed bug with link-layer ACKs. Refactored the ACK reception code. --- core/net/mac/lpp.c | 65 +++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/core/net/mac/lpp.c b/core/net/mac/lpp.c index d7dbc8c34..32584e7b4 100644 --- a/core/net/mac/lpp.c +++ b/core/net/mac/lpp.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: lpp.c,v 1.38 2010/10/20 15:23:43 adamdunkels Exp $ + * $Id: lpp.c,v 1.39 2010/11/25 08:44:34 adamdunkels Exp $ */ /** @@ -104,9 +104,9 @@ is 0 which will make compilation fail due to a modulo operation in the code. To ensure that OFF_TIME is greater than zero, we use the construct below. */ -#if OFF_TIME == 0 +#if OFF_TIME < 2 #undef OFF_TIME -#define OFF_TIME 1 +#define OFF_TIME 2 #endif struct announcement_data { @@ -643,7 +643,7 @@ send_packet(mac_callback_t sent, void *ptr) packetbuf_compact(); packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); - + { int hdrlen = NETSTACK_FRAMER.create(); if(hdrlen == 0) { @@ -721,6 +721,40 @@ send_packet(mac_callback_t sent, void *ptr) } } /*---------------------------------------------------------------------------*/ +static int +detect_ack(void) +{ +#define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000 +#define ACK_LEN 3 +#define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1000 + rtimer_clock_t wt; + uint8_t ack_received = 0; + + wt = RTIMER_NOW(); + leds_on(LEDS_GREEN); + while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } + leds_off(LEDS_GREEN); + /* Check for incoming ACK. */ + if((NETSTACK_RADIO.receiving_packet() || + NETSTACK_RADIO.pending_packet() || + NETSTACK_RADIO.channel_clear() == 0)) { + int len; + uint8_t ackbuf[ACK_LEN + 2]; + + wt = RTIMER_NOW(); + while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { } + + len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); + if(len == ACK_LEN) { + ack_received = 1; + } + } + if(ack_received) { + leds_toggle(LEDS_RED); + } + return ack_received; +} +/*---------------------------------------------------------------------------*/ /** * Read a packet from the underlying radio driver. If the incoming * packet is a probe packet and the sender of the probe matches the @@ -830,28 +864,7 @@ input_packet(void) neighbors, and are dequeued by the dutycycling function instead, after the appropriate time. */ if(!rimeaddr_cmp(receiver, &rimeaddr_null)) { -#define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000 -#define ACK_LEN 3 -#define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1000 - rtimer_clock_t wt; - uint8_t ack_received = 0; - - wt = RTIMER_NOW(); - while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } - /* Check for incoming ACK. */ - if((NETSTACK_RADIO.receiving_packet() || - NETSTACK_RADIO.pending_packet() || - NETSTACK_RADIO.channel_clear() == 0)) { - int len; - uint8_t ackbuf[ACK_LEN]; - - wt = RTIMER_NOW(); - while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { } - - len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); - - } - if(ack_received) { + if(detect_ack()) { remove_queued_packet(i, 1); } else { remove_queued_packet(i, 0);