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:
parent
a4d9d6651b
commit
0eade2886c
|
@ -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
|
||||||
|
@ -195,8 +200,18 @@ 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_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);
|
neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
|
||||||
#else
|
} 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 */
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue