Added a safety measure against a problem where a node in rare situations would turn itself into a sink. Not entirely sure why this happens, but the safety measure should at least avoid the results of the problem. Added more debug messages.
This commit is contained in:
parent
0859d4b95f
commit
3d10dedecf
|
@ -33,7 +33,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*
|
*
|
||||||
* $Id: collect.c,v 1.46 2010/04/01 11:08:36 fros4943 Exp $
|
* $Id: collect.c,v 1.47 2010/04/30 07:33:51 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +85,7 @@ struct ack_msg {
|
||||||
static struct recent_packet recent_packets[NUM_RECENT_PACKETS];
|
static struct recent_packet recent_packets[NUM_RECENT_PACKETS];
|
||||||
static uint8_t recent_packet_ptr;
|
static uint8_t recent_packet_ptr;
|
||||||
|
|
||||||
#define MAX_MAC_REXMITS 2
|
#define MAX_MAC_REXMITS 3
|
||||||
#define MAX_ACK_MAC_REXMITS 3
|
#define MAX_ACK_MAC_REXMITS 3
|
||||||
#define REXMIT_TIME CLOCK_SECOND * 2
|
#define REXMIT_TIME CLOCK_SECOND * 2
|
||||||
#define FORWARD_PACKET_LIFETIME (6 * (REXMIT_TIME) << 3)
|
#define FORWARD_PACKET_LIFETIME (6 * (REXMIT_TIME) << 3)
|
||||||
|
@ -95,7 +95,7 @@ PACKETQUEUE(sending_queue, MAX_SENDING_QUEUE);
|
||||||
#define SINK 0
|
#define SINK 0
|
||||||
#define RTMETRIC_MAX COLLECT_MAX_DEPTH
|
#define RTMETRIC_MAX COLLECT_MAX_DEPTH
|
||||||
|
|
||||||
#define MAX_HOPLIM 10
|
#define MAX_HOPLIM 15
|
||||||
|
|
||||||
#ifndef COLLECT_CONF_ANNOUNCEMENTS
|
#ifndef COLLECT_CONF_ANNOUNCEMENTS
|
||||||
#define COLLECT_ANNOUNCEMENTS 0
|
#define COLLECT_ANNOUNCEMENTS 0
|
||||||
|
@ -151,9 +151,12 @@ update_rtmetric(struct collect_conn *tc)
|
||||||
if(best != NULL && (n == NULL ||
|
if(best != NULL && (n == NULL ||
|
||||||
collect_neighbor_etx(best) <
|
collect_neighbor_etx(best) <
|
||||||
collect_neighbor_etx(n) - COLLECT_NEIGHBOR_ETX_SCALE)) {
|
collect_neighbor_etx(n) - COLLECT_NEIGHBOR_ETX_SCALE)) {
|
||||||
|
PRINTF("Switched parent from %d.%d to %d.%d\n",
|
||||||
|
tc->parent.u8[0], tc->parent.u8[1],
|
||||||
|
best->addr.u8[0], best->addr.u8[1]);
|
||||||
|
PRINTF("#L %d 0\n", tc->parent.u8[0]);
|
||||||
|
PRINTF("#L %d 1\n", best->addr.u8[0]);
|
||||||
rimeaddr_copy(&tc->parent, &best->addr);
|
rimeaddr_copy(&tc->parent, &best->addr);
|
||||||
PRINTF("Switched parent to %d.%d\n",
|
|
||||||
tc->parent.u8[0], tc->parent.u8[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If n is NULL, we have no best neighbor. */
|
/* If n is NULL, we have no best neighbor. */
|
||||||
|
@ -163,8 +166,8 @@ update_rtmetric(struct collect_conn *tc)
|
||||||
the maximum value to indicate that we do not have a route. */
|
the maximum value to indicate that we do not have a route. */
|
||||||
|
|
||||||
if(tc->rtmetric != RTMETRIC_MAX) {
|
if(tc->rtmetric != RTMETRIC_MAX) {
|
||||||
PRINTF("%d.%d: didn't find a best neighbor, setting rtmetric to max\n",
|
PRINTF("%d.%d: didn't find a best neighbor, setting rtmetric to max\n",
|
||||||
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
|
#if COLLECT_ANNOUNCEMENTS
|
||||||
|
@ -181,6 +184,14 @@ update_rtmetric(struct collect_conn *tc)
|
||||||
uint16_t old_rtmetric = tc->rtmetric;
|
uint16_t old_rtmetric = tc->rtmetric;
|
||||||
|
|
||||||
tc->rtmetric = n->rtmetric + collect_neighbor_etx(n);
|
tc->rtmetric = n->rtmetric + collect_neighbor_etx(n);
|
||||||
|
if(tc->rtmetric == SINK) {
|
||||||
|
/* Something strange happened - ETX to this neighbors is zero! */
|
||||||
|
printf("Error: n->rtmetric %d, collect_neighbor_etx(n) %d\n",
|
||||||
|
n->rtmetric, collect_neighbor_etx(n));
|
||||||
|
|
||||||
|
/* Fix the problem by setting ETX to one. */
|
||||||
|
tc->rtmetric = COLLECT_NEIGHBOR_ETX_SCALE;
|
||||||
|
}
|
||||||
|
|
||||||
#if ! COLLECT_ANNOUNCEMENTS
|
#if ! COLLECT_ANNOUNCEMENTS
|
||||||
|
|
||||||
|
@ -205,12 +216,13 @@ update_rtmetric(struct collect_conn *tc)
|
||||||
}
|
}
|
||||||
#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],
|
||||||
tc->rtmetric);
|
tc->rtmetric);
|
||||||
#if ! COLLECT_CONF_WITH_LISTEN
|
#if ! COLLECT_CONF_WITH_LISTEN
|
||||||
/* We got a new, working, route we send any queued packets we may have. */
|
/* We got a new, working, route we send any queued packets we may have. */
|
||||||
if(old_rtmetric == RTMETRIC_MAX) {
|
if(old_rtmetric == RTMETRIC_MAX) {
|
||||||
|
PRINTF("Sending queued packet because rtmetric was max\n");
|
||||||
send_queued_packet();
|
send_queued_packet();
|
||||||
}
|
}
|
||||||
#endif /* COLLECT_CONF_WITH_LISTEN */
|
#endif /* COLLECT_CONF_WITH_LISTEN */
|
||||||
|
@ -240,9 +252,9 @@ send_queued_packet(void)
|
||||||
struct packetqueue_item *i;
|
struct packetqueue_item *i;
|
||||||
struct collect_conn *c;
|
struct collect_conn *c;
|
||||||
|
|
||||||
PRINTF("%d.%d: send_queued_packet queue len %d\n",
|
// PRINTF("%d.%d: send_queued_packet queue len %d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
// rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
packetqueue_len(&sending_queue));
|
// packetqueue_len(&sending_queue));
|
||||||
|
|
||||||
i = packetqueue_first(&sending_queue);
|
i = packetqueue_first(&sending_queue);
|
||||||
if(i == NULL) {
|
if(i == NULL) {
|
||||||
|
@ -267,11 +279,11 @@ send_queued_packet(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We should send the first packet from the queue. */
|
||||||
q = packetqueue_queuebuf(i);
|
q = packetqueue_queuebuf(i);
|
||||||
if(q != NULL) {
|
if(q != NULL) {
|
||||||
|
// PRINTF("%d.%d: queue, q is on queue\n",
|
||||||
PRINTF("%d.%d: queue, q is on queue\n",
|
// rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
|
||||||
|
|
||||||
/* Place the queued packet into the packetbuf. */
|
/* Place the queued packet into the packetbuf. */
|
||||||
queuebuf_to_packetbuf(q);
|
queuebuf_to_packetbuf(q);
|
||||||
|
@ -286,14 +298,14 @@ send_queued_packet(void)
|
||||||
#if CONTIKI_TARGET_NETSIM
|
#if CONTIKI_TARGET_NETSIM
|
||||||
ether_set_line(n->addr.u8[0], n->addr.u8[1]);
|
ether_set_line(n->addr.u8[0], n->addr.u8[1]);
|
||||||
#endif /* CONTIKI_TARGET_NETSIM */
|
#endif /* CONTIKI_TARGET_NETSIM */
|
||||||
PRINTF("%d.%d: sending packet to %d.%d\n",
|
PRINTF("%d.%d: sending packet to %d.%d with eseqno %d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
n->addr.u8[0], n->addr.u8[1]);
|
n->addr.u8[0], n->addr.u8[1],
|
||||||
|
packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
|
||||||
|
|
||||||
c->sending = 1;
|
c->sending = 1;
|
||||||
c->transmissions = 0;
|
c->transmissions = 0;
|
||||||
c->max_rexmits = packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT);
|
c->max_rexmits = packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT);
|
||||||
PRINTF("max_rexmits %d\n", c->max_rexmits);
|
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
|
packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_MAC_REXMITS);
|
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_MAC_REXMITS);
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
|
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
|
||||||
|
@ -304,7 +316,7 @@ send_queued_packet(void)
|
||||||
}
|
}
|
||||||
time = REXMIT_TIME << rexmit_time_scaling;
|
time = REXMIT_TIME << rexmit_time_scaling;
|
||||||
time = time / 2 + random_rand() % (time / 2);
|
time = time / 2 + random_rand() % (time / 2);
|
||||||
PRINTF("retransmission time %lu\n", time);
|
// PRINTF("retransmission time %lu\n", time);
|
||||||
ctimer_set(&c->retransmission_timer, time,
|
ctimer_set(&c->retransmission_timer, time,
|
||||||
retransmit_callback, c);
|
retransmit_callback, c);
|
||||||
} else {
|
} else {
|
||||||
|
@ -335,6 +347,9 @@ send_next_packet(struct collect_conn *tc)
|
||||||
tc->sending = 0;
|
tc->sending = 0;
|
||||||
tc->transmissions = 0;
|
tc->transmissions = 0;
|
||||||
|
|
||||||
|
PRINTF("sending next packet, seqno %d, queue len %d\n",
|
||||||
|
tc->seqno, packetqueue_len(&sending_queue));
|
||||||
|
|
||||||
/* Send the next packet in the queue, if any. */
|
/* Send the next packet in the queue, if any. */
|
||||||
send_queued_packet();
|
send_queued_packet();
|
||||||
}
|
}
|
||||||
|
@ -346,11 +361,15 @@ handle_ack(struct collect_conn *tc)
|
||||||
uint16_t rtmetric;
|
uint16_t rtmetric;
|
||||||
struct collect_neighbor *n;
|
struct collect_neighbor *n;
|
||||||
|
|
||||||
|
PRINTF("handle_ack: sender %d.%d parent %d.%d, id %d seqno %d\n",
|
||||||
|
packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
|
||||||
|
packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
|
||||||
|
tc->parent.u8[0], tc->parent.u8[1],
|
||||||
|
packetbuf_attr(PACKETBUF_ATTR_PACKET_ID), tc->seqno);
|
||||||
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||||
&tc->parent) &&
|
&tc->parent) &&
|
||||||
packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == tc->seqno) {
|
packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == tc->seqno) {
|
||||||
|
|
||||||
|
|
||||||
msg = packetbuf_dataptr();
|
msg = packetbuf_dataptr();
|
||||||
memcpy(&rtmetric, &msg->rtmetric, sizeof(uint16_t));
|
memcpy(&rtmetric, &msg->rtmetric, sizeof(uint16_t));
|
||||||
n = collect_neighbor_find(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
n = collect_neighbor_find(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
@ -376,12 +395,13 @@ send_ack(struct collect_conn *tc, const rimeaddr_t *to, int congestion, int drop
|
||||||
{
|
{
|
||||||
struct ack_msg *ack;
|
struct ack_msg *ack;
|
||||||
struct queuebuf *q;
|
struct queuebuf *q;
|
||||||
uint16_t packet_seqno;
|
uint16_t packet_seqno, packet_eseqno;
|
||||||
|
|
||||||
|
|
||||||
PRINTF("send_ack\n");
|
// PRINTF("send_ack\n");
|
||||||
|
|
||||||
packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
|
packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
|
||||||
|
packet_eseqno = packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
|
||||||
|
|
||||||
q = queuebuf_new_from_packetbuf();
|
q = queuebuf_new_from_packetbuf();
|
||||||
if(q != NULL) {
|
if(q != NULL) {
|
||||||
|
@ -403,11 +423,11 @@ send_ack(struct collect_conn *tc, const rimeaddr_t *to, int congestion, int drop
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_ACK_MAC_REXMITS);
|
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_ACK_MAC_REXMITS);
|
||||||
unicast_send(&tc->unicast_conn, to);
|
unicast_send(&tc->unicast_conn, to);
|
||||||
|
|
||||||
PRINTF("%d.%d: collect: Sending ACK to %d.%d for %d\n",
|
PRINTF("%d.%d: collect: Sending ACK to %d.%d for %d (epacket_id %d)\n",
|
||||||
rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
|
||||||
to->u8[0],
|
to->u8[0],
|
||||||
to->u8[1],
|
to->u8[1],
|
||||||
packet_seqno);
|
packet_seqno, packet_eseqno);
|
||||||
|
|
||||||
RIMESTATS_ADD(acktx);
|
RIMESTATS_ADD(acktx);
|
||||||
|
|
||||||
|
@ -590,8 +610,8 @@ node_packet_sent(struct unicast_conn *c, int status, int transmissions)
|
||||||
}
|
}
|
||||||
#endif /* 0 */
|
#endif /* 0 */
|
||||||
/* Update ETX with the number of transmissions. */
|
/* Update ETX with the number of transmissions. */
|
||||||
PRINTF("Updating ETX with %d transmissions (punished %d)\n", tc->transmissions,
|
// PRINTF("Updating ETX with %d transmissions (punished %d)\n", tc->transmissions,
|
||||||
tx);
|
// tx);
|
||||||
collect_neighbor_update_etx(collect_neighbor_find(&tc->parent), tx);
|
collect_neighbor_update_etx(collect_neighbor_find(&tc->parent), tx);
|
||||||
update_rtmetric(tc);
|
update_rtmetric(tc);
|
||||||
}
|
}
|
||||||
|
@ -698,6 +718,7 @@ collect_open(struct collect_conn *tc, uint16_t channels,
|
||||||
tc->rtmetric = RTMETRIC_MAX;
|
tc->rtmetric = RTMETRIC_MAX;
|
||||||
tc->cb = cb;
|
tc->cb = cb;
|
||||||
tc->is_router = is_router;
|
tc->is_router = is_router;
|
||||||
|
tc->seqno = 10;
|
||||||
collect_neighbor_init();
|
collect_neighbor_init();
|
||||||
packetqueue_init(&sending_queue);
|
packetqueue_init(&sending_queue);
|
||||||
|
|
||||||
|
@ -765,8 +786,7 @@ collect_send(struct collect_conn *tc, int rexmits)
|
||||||
packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
|
packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
|
||||||
packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
|
packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
|
||||||
|
|
||||||
|
// PRINTF("rexmit %d\n", rexmits);
|
||||||
PRINTF("rexmit %d\n", rexmits);
|
|
||||||
|
|
||||||
if(tc->rtmetric == SINK) {
|
if(tc->rtmetric == SINK) {
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
|
packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
|
||||||
|
@ -777,7 +797,7 @@ collect_send(struct collect_conn *tc, int rexmits)
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
update_rtmetric(tc);
|
// update_rtmetric(tc);
|
||||||
n = collect_neighbor_best();
|
n = collect_neighbor_best();
|
||||||
if(n != NULL) {
|
if(n != NULL) {
|
||||||
#if CONTIKI_TARGET_NETSIM
|
#if CONTIKI_TARGET_NETSIM
|
||||||
|
@ -786,14 +806,16 @@ collect_send(struct collect_conn *tc, int rexmits)
|
||||||
PRINTF("%d.%d: sending to %d.%d\n",
|
PRINTF("%d.%d: sending to %d.%d\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
|
||||||
n->addr.u8[0], n->addr.u8[1]);
|
n->addr.u8[0], n->addr.u8[1]);
|
||||||
|
|
||||||
if(packetqueue_enqueue_packetbuf(&sending_queue, FORWARD_PACKET_LIFETIME,
|
if(packetqueue_enqueue_packetbuf(&sending_queue, FORWARD_PACKET_LIFETIME,
|
||||||
tc)) {
|
tc)) {
|
||||||
send_queued_packet();
|
send_queued_packet();
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
PRINTF("%d.%d: drop originated packet: no queuebuf\n",
|
PRINTF("%d.%d: drop originated packet: no queuebuf\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
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]);
|
||||||
|
@ -804,14 +826,13 @@ collect_send(struct collect_conn *tc, int rexmits)
|
||||||
ctimer_set(&tc->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
|
ctimer_set(&tc->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
|
||||||
send_queued_packet, NULL);
|
send_queued_packet, NULL);
|
||||||
#else /* COLLECT_CONF_WITH_LISTEN */
|
#else /* COLLECT_CONF_WITH_LISTEN */
|
||||||
PRINTF("bump neighbor value\n");
|
|
||||||
announcement_set_value(&tc->announcement, RTMETRIC_MAX);
|
announcement_set_value(&tc->announcement, RTMETRIC_MAX);
|
||||||
announcement_bump(&tc->announcement);
|
announcement_bump(&tc->announcement);
|
||||||
#endif /* COLLECT_CONF_WITH_LISTEN */
|
#endif /* COLLECT_CONF_WITH_LISTEN */
|
||||||
#endif /* COLLECT_ANNOUNCEMENTS */
|
#endif /* COLLECT_ANNOUNCEMENTS */
|
||||||
|
|
||||||
if(packetqueue_enqueue_packetbuf(&sending_queue, FORWARD_PACKET_LIFETIME,
|
if(packetqueue_enqueue_packetbuf(&sending_queue, FORWARD_PACKET_LIFETIME,
|
||||||
tc)) {
|
tc)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
PRINTF("%d.%d: drop originated packet: no queuebuf\n",
|
PRINTF("%d.%d: drop originated packet: no queuebuf\n",
|
||||||
|
@ -833,6 +854,8 @@ collect_purge(struct collect_conn *tc)
|
||||||
{
|
{
|
||||||
collect_neighbor_purge();
|
collect_neighbor_purge();
|
||||||
update_rtmetric(tc);
|
update_rtmetric(tc);
|
||||||
|
PRINTF("#L %d 0\n", tc->parent.u8[0]);
|
||||||
|
rimeaddr_copy(&tc->parent, &rimeaddr_null);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
Loading…
Reference in a new issue