Better loop handling: when a loop is detected, the neighbor to which the packet was originally sent gets an inflated ETX; made sure that collect without announcments work; increased timeouts, to work nicer in larger networks

This commit is contained in:
adamdunkels 2010-02-23 18:35:23 +00:00
parent a4d9d6651b
commit 0eade2886c
2 changed files with 49 additions and 13 deletions

View File

@ -36,7 +36,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: collect.c,v 1.32 2010/02/08 21:59:49 adamdunkels Exp $ * $Id: collect.c,v 1.33 2010/02/23 18:35:23 adamdunkels Exp $
*/ */
/** /**
@ -70,10 +70,11 @@ static const struct packetbuf_attrlist attributes[] =
PACKETBUF_ATTR_LAST PACKETBUF_ATTR_LAST
}; };
#define NUM_RECENT_PACKETS 2 #define NUM_RECENT_PACKETS 8
struct recent_packet { struct recent_packet {
rimeaddr_t originator; rimeaddr_t originator;
rimeaddr_t sent_to;
uint8_t seqno; uint8_t seqno;
}; };
@ -90,7 +91,7 @@ PACKETQUEUE(forwarding_queue, MAX_FORWARDING_QUEUE);
#define MAX_HOPLIM 10 #define MAX_HOPLIM 10
#ifndef COLLECT_CONF_ANNOUNCEMENTS #ifndef COLLECT_CONF_ANNOUNCEMENTS
#define COLLECT_ANNOUNCEMENTS 1 #define COLLECT_ANNOUNCEMENTS 0
#else #else
#define COLLECT_ANNOUNCEMENTS COLLECT_CONF_ANNOUNCEMENTS #define COLLECT_ANNOUNCEMENTS COLLECT_CONF_ANNOUNCEMENTS
#endif /* COLLECT_CONF_ANNOUNCEMENTS */ #endif /* COLLECT_CONF_ANNOUNCEMENTS */
@ -184,7 +185,11 @@ update_rtmetric(struct collect_conn *tc)
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
} }
tc->rtmetric = RTMETRIC_MAX; tc->rtmetric = RTMETRIC_MAX;
#if COLLECT_ANNOUNCEMENTS
announcement_set_value(&tc->announcement, tc->rtmetric); announcement_set_value(&tc->announcement, tc->rtmetric);
#else /* COLLECT_ANNOUNCEMENTS */
neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
#endif /* COLLECT_ANNOUNCEMENTS */
} else { } else {
/* We set our rtmetric to the rtmetric of our best neighbor plus /* We set our rtmetric to the rtmetric of our best neighbor plus
@ -194,11 +199,21 @@ update_rtmetric(struct collect_conn *tc)
tc->rtmetric = n->rtmetric + neighbor_etx(n); tc->rtmetric = n->rtmetric + neighbor_etx(n);
#if !COLLECT_ANNOUNCEMENTS #if ! COLLECT_ANNOUNCEMENTS
neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
#else /* neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);*/
/* If we get a significantly better rtmetric than we had
before, we call neighbor_discovery_start to start a new
period. */
if(old_rtmetric >= tc->rtmetric + NEIGHBOR_ETX_SCALE + NEIGHBOR_ETX_SCALE / 2) {
neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
} else {
neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
}
#else /* ! COLLECT_ANNOUNCEMENTS */
announcement_set_value(&tc->announcement, tc->rtmetric); announcement_set_value(&tc->announcement, tc->rtmetric);
#endif /* !COLLECT_ANNOUNCEMENTS */ #endif /* ! COLLECT_ANNOUNCEMENTS */
PRINTF("%d.%d: new rtmetric %d\n", PRINTF("%d.%d: new rtmetric %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
@ -233,10 +248,12 @@ node_packet_received(struct runicast_conn *c, const rimeaddr_t *from,
struct collect_conn *tc = (struct collect_conn *) struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(struct collect_conn, runicast_conn)); ((char *)c - offsetof(struct collect_conn, runicast_conn));
int i; int i;
struct neighbor *n;
/* To protect against forwarding duplicate packets, we keep a list /* To protect against forwarding duplicate packets, we keep a list
of recently forwarded packet seqnos. If the seqno of the current of recently forwarded packet seqnos. If the seqno of the current
packet exists in the list, we drop the packet. */ packet exists in the list, we drop the packet and increase the
ETX of the neighbor we sent it to in the first place. */
for(i = 0; i < NUM_RECENT_PACKETS; i++) { for(i = 0; i < NUM_RECENT_PACKETS; i++) {
if(recent_packets[i].seqno == packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID) && if(recent_packets[i].seqno == packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID) &&
@ -246,6 +263,10 @@ node_packet_received(struct runicast_conn *c, const rimeaddr_t *from,
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
recent_packets[i].originator.u8[0], recent_packets[i].originator.u8[1], recent_packets[i].originator.u8[0], recent_packets[i].originator.u8[1],
packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID)); packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
n = neighbor_find(&recent_packets[i].sent_to);
if(n != NULL) {
neighbor_update_etx(n, neighbor_etx(n) + NEIGHBOR_ETX_SCALE * 4);
}
/* Drop the packet. */ /* Drop the packet. */
return; return;
} }
@ -253,6 +274,10 @@ node_packet_received(struct runicast_conn *c, const rimeaddr_t *from,
recent_packets[recent_packet_ptr].seqno = packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID); recent_packets[recent_packet_ptr].seqno = packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
rimeaddr_copy(&recent_packets[recent_packet_ptr].originator, rimeaddr_copy(&recent_packets[recent_packet_ptr].originator,
packetbuf_addr(PACKETBUF_ADDR_ESENDER)); packetbuf_addr(PACKETBUF_ADDR_ESENDER));
n = neighbor_best();
rimeaddr_copy(&recent_packets[recent_packet_ptr].sent_to,
&n->addr);
recent_packet_ptr = (recent_packet_ptr + 1) % NUM_RECENT_PACKETS; recent_packet_ptr = (recent_packet_ptr + 1) % NUM_RECENT_PACKETS;
if(tc->rtmetric == SINK) { if(tc->rtmetric == SINK) {
@ -293,6 +318,10 @@ node_packet_received(struct runicast_conn *c, const rimeaddr_t *from,
PRINTF("%d.%d: packet dropped: no queue buffer available\n", PRINTF("%d.%d: packet dropped: no queue buffer available\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
} }
} else if(packetbuf_attr(PACKETBUF_ATTR_TTL) <= 1) {
PRINTF("%d.%d: packet dropped: ttl %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
packetbuf_attr(PACKETBUF_ATTR_TTL));
} }
return; return;
@ -406,9 +435,9 @@ collect_open(struct collect_conn *tc, uint16_t channels,
{ {
#if !COLLECT_ANNOUNCEMENTS #if !COLLECT_ANNOUNCEMENTS
neighbor_discovery_open(&tc->neighbor_discovery_conn, channels, neighbor_discovery_open(&tc->neighbor_discovery_conn, channels,
CLOCK_SECOND * 2, CLOCK_SECOND * 8,
CLOCK_SECOND * 10, CLOCK_SECOND * 32,
CLOCK_SECOND * 60, CLOCK_SECOND * 600,
&neighbor_discovery_callbacks); &neighbor_discovery_callbacks);
#endif /* !COLLECT_ANNOUNCEMENTS */ #endif /* !COLLECT_ANNOUNCEMENTS */
runicast_open(&tc->runicast_conn, channels + 1, &runicast_callbacks); runicast_open(&tc->runicast_conn, channels + 1, &runicast_callbacks);
@ -493,7 +522,9 @@ collect_send(struct collect_conn *tc, int rexmits)
/* printf("Didn't find any neighbor\n");*/ /* printf("Didn't find any neighbor\n");*/
PRINTF("%d.%d: did not find any neighbor to send to\n", PRINTF("%d.%d: did not find any neighbor to send to\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
#if COLLECT_ANNOUNCEMENTS
announcement_listen(1); announcement_listen(1);
#endif /* COLLECT_ANNOUNCEMENTS */
if(packetqueue_enqueue_packetbuf(&forwarding_queue, FORWARD_PACKET_LIFETIME, if(packetqueue_enqueue_packetbuf(&forwarding_queue, FORWARD_PACKET_LIFETIME,
tc)) { tc)) {
return 1; return 1;

View File

@ -47,7 +47,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: collect.h,v 1.11 2009/04/29 20:48:57 adamdunkels Exp $ * $Id: collect.h,v 1.12 2010/02/23 18:35:23 adamdunkels Exp $
*/ */
/** /**
@ -62,6 +62,7 @@
#include "net/rime/announcement.h" #include "net/rime/announcement.h"
#include "net/rime/runicast.h" #include "net/rime/runicast.h"
#include "net/rime/neighbor-discovery.h"
#define COLLECT_ATTRIBUTES { PACKETBUF_ADDR_ESENDER, PACKETBUF_ADDRSIZE }, \ #define COLLECT_ATTRIBUTES { PACKETBUF_ADDR_ESENDER, PACKETBUF_ADDRSIZE }, \
{ PACKETBUF_ATTR_EPACKET_ID, PACKETBUF_ATTR_BIT * 4 }, \ { PACKETBUF_ATTR_EPACKET_ID, PACKETBUF_ATTR_BIT * 4 }, \
@ -77,7 +78,11 @@ struct collect_callbacks {
struct collect_conn { struct collect_conn {
struct runicast_conn runicast_conn; struct runicast_conn runicast_conn;
#if ! COLLECT_CONF_ANNOUNCEMENTS
struct neighbor_discovery_conn neighbor_discovery_conn;
#else /* ! COLLECT_CONF_ANNOUNCEMENTS */
struct announcement announcement; struct announcement announcement;
#endif /* COLLECT_CONF_ANNOUNCEMENTS */
const struct collect_callbacks *cb; const struct collect_callbacks *cb;
struct ctimer t; struct ctimer t;
uint16_t rtmetric; uint16_t rtmetric;
@ -86,7 +91,7 @@ struct collect_conn {
}; };
void collect_open(struct collect_conn *c, uint16_t channels, void collect_open(struct collect_conn *c, uint16_t channels,
const struct collect_callbacks *callbacks); const struct collect_callbacks *callbacks);
void collect_close(struct collect_conn *c); void collect_close(struct collect_conn *c);
int collect_send(struct collect_conn *c, int rexmits); int collect_send(struct collect_conn *c, int rexmits);