Fixed bug with link-layer ACKs. Refactored the ACK reception code.

This commit is contained in:
adamdunkels 2010-11-25 08:44:34 +00:00
parent 2f66db3ded
commit 6d556d5c13

View file

@ -28,7 +28,7 @@
* *
* This file is part of the Contiki operating system. * 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 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 the code. To ensure that OFF_TIME is greater than zero, we use the
construct below. */ construct below. */
#if OFF_TIME == 0 #if OFF_TIME < 2
#undef OFF_TIME #undef OFF_TIME
#define OFF_TIME 1 #define OFF_TIME 2
#endif #endif
struct announcement_data { struct announcement_data {
@ -643,7 +643,7 @@ send_packet(mac_callback_t sent, void *ptr)
packetbuf_compact(); packetbuf_compact();
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
{ {
int hdrlen = NETSTACK_FRAMER.create(); int hdrlen = NETSTACK_FRAMER.create();
if(hdrlen == 0) { 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 * Read a packet from the underlying radio driver. If the incoming
* packet is a probe packet and the sender of the probe matches the * 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 neighbors, and are dequeued by the dutycycling function
instead, after the appropriate time. */ instead, after the appropriate time. */
if(!rimeaddr_cmp(receiver, &rimeaddr_null)) { if(!rimeaddr_cmp(receiver, &rimeaddr_null)) {
#define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000 if(detect_ack()) {
#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) {
remove_queued_packet(i, 1); remove_queued_packet(i, 1);
} else { } else {
remove_queued_packet(i, 0); remove_queued_packet(i, 0);