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.
*
* $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);