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:
adamdunkels 2010-04-30 07:33:51 +00:00
parent 0859d4b95f
commit 3d10dedecf

View file

@ -33,7 +33,7 @@
*
* 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 uint8_t recent_packet_ptr;
#define MAX_MAC_REXMITS 2
#define MAX_MAC_REXMITS 3
#define MAX_ACK_MAC_REXMITS 3
#define REXMIT_TIME CLOCK_SECOND * 2
#define FORWARD_PACKET_LIFETIME (6 * (REXMIT_TIME) << 3)
@ -95,7 +95,7 @@ PACKETQUEUE(sending_queue, MAX_SENDING_QUEUE);
#define SINK 0
#define RTMETRIC_MAX COLLECT_MAX_DEPTH
#define MAX_HOPLIM 10
#define MAX_HOPLIM 15
#ifndef COLLECT_CONF_ANNOUNCEMENTS
#define COLLECT_ANNOUNCEMENTS 0
@ -151,9 +151,12 @@ update_rtmetric(struct collect_conn *tc)
if(best != NULL && (n == NULL ||
collect_neighbor_etx(best) <
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);
PRINTF("Switched parent to %d.%d\n",
tc->parent.u8[0], tc->parent.u8[1]);
}
/* 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. */
if(tc->rtmetric != RTMETRIC_MAX) {
PRINTF("%d.%d: didn't find a best neighbor, setting rtmetric to max\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
PRINTF("%d.%d: didn't find a best neighbor, setting rtmetric to max\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
}
tc->rtmetric = RTMETRIC_MAX;
#if COLLECT_ANNOUNCEMENTS
@ -181,6 +184,14 @@ update_rtmetric(struct collect_conn *tc)
uint16_t old_rtmetric = tc->rtmetric;
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
@ -205,12 +216,13 @@ update_rtmetric(struct collect_conn *tc)
}
#endif /* ! COLLECT_ANNOUNCEMENTS */
PRINTF("%d.%d: new rtmetric %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
tc->rtmetric);
PRINTF("%d.%d: new rtmetric %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
tc->rtmetric);
#if ! COLLECT_CONF_WITH_LISTEN
/* We got a new, working, route we send any queued packets we may have. */
if(old_rtmetric == RTMETRIC_MAX) {
PRINTF("Sending queued packet because rtmetric was max\n");
send_queued_packet();
}
#endif /* COLLECT_CONF_WITH_LISTEN */
@ -240,9 +252,9 @@ send_queued_packet(void)
struct packetqueue_item *i;
struct collect_conn *c;
PRINTF("%d.%d: send_queued_packet queue len %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
packetqueue_len(&sending_queue));
// PRINTF("%d.%d: send_queued_packet queue len %d\n",
// rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
// packetqueue_len(&sending_queue));
i = packetqueue_first(&sending_queue);
if(i == NULL) {
@ -267,11 +279,11 @@ send_queued_packet(void)
return;
}
/* We should send the first packet from the queue. */
q = packetqueue_queuebuf(i);
if(q != NULL) {
PRINTF("%d.%d: queue, q is on queue\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
// PRINTF("%d.%d: queue, q is on queue\n",
// rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
/* Place the queued packet into the packetbuf. */
queuebuf_to_packetbuf(q);
@ -286,14 +298,14 @@ send_queued_packet(void)
#if CONTIKI_TARGET_NETSIM
ether_set_line(n->addr.u8[0], n->addr.u8[1]);
#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],
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->transmissions = 0;
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_MAX_MAC_TRANSMISSIONS, MAX_MAC_REXMITS);
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
@ -304,7 +316,7 @@ send_queued_packet(void)
}
time = REXMIT_TIME << rexmit_time_scaling;
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,
retransmit_callback, c);
} else {
@ -335,6 +347,9 @@ send_next_packet(struct collect_conn *tc)
tc->sending = 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_queued_packet();
}
@ -346,11 +361,15 @@ handle_ack(struct collect_conn *tc)
uint16_t rtmetric;
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),
&tc->parent) &&
packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == tc->seqno) {
msg = packetbuf_dataptr();
memcpy(&rtmetric, &msg->rtmetric, sizeof(uint16_t));
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 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_eseqno = packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
q = queuebuf_new_from_packetbuf();
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);
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],
to->u8[0],
to->u8[1],
packet_seqno);
packet_seqno, packet_eseqno);
RIMESTATS_ADD(acktx);
@ -590,8 +610,8 @@ node_packet_sent(struct unicast_conn *c, int status, int transmissions)
}
#endif /* 0 */
/* Update ETX with the number of transmissions. */
PRINTF("Updating ETX with %d transmissions (punished %d)\n", tc->transmissions,
tx);
// PRINTF("Updating ETX with %d transmissions (punished %d)\n", tc->transmissions,
// tx);
collect_neighbor_update_etx(collect_neighbor_find(&tc->parent), tx);
update_rtmetric(tc);
}
@ -698,6 +718,7 @@ collect_open(struct collect_conn *tc, uint16_t channels,
tc->rtmetric = RTMETRIC_MAX;
tc->cb = cb;
tc->is_router = is_router;
tc->seqno = 10;
collect_neighbor_init();
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_MAX_REXMIT));
PRINTF("rexmit %d\n", rexmits);
// PRINTF("rexmit %d\n", rexmits);
if(tc->rtmetric == SINK) {
packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
@ -777,7 +797,7 @@ collect_send(struct collect_conn *tc, int rexmits)
}
return 1;
} else {
update_rtmetric(tc);
// update_rtmetric(tc);
n = collect_neighbor_best();
if(n != NULL) {
#if CONTIKI_TARGET_NETSIM
@ -786,14 +806,16 @@ collect_send(struct collect_conn *tc, int rexmits)
PRINTF("%d.%d: sending to %d.%d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
n->addr.u8[0], n->addr.u8[1]);
if(packetqueue_enqueue_packetbuf(&sending_queue, FORWARD_PACKET_LIFETIME,
tc)) {
send_queued_packet();
return 1;
tc)) {
send_queued_packet();
return 1;
} else {
PRINTF("%d.%d: drop originated packet: no queuebuf\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
}
} else {
PRINTF("%d.%d: did not find any neighbor to send to\n",
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,
send_queued_packet, NULL);
#else /* COLLECT_CONF_WITH_LISTEN */
PRINTF("bump neighbor value\n");
announcement_set_value(&tc->announcement, RTMETRIC_MAX);
announcement_bump(&tc->announcement);
#endif /* COLLECT_CONF_WITH_LISTEN */
#endif /* COLLECT_ANNOUNCEMENTS */
if(packetqueue_enqueue_packetbuf(&sending_queue, FORWARD_PACKET_LIFETIME,
tc)) {
tc)) {
return 1;
} else {
PRINTF("%d.%d: drop originated packet: no queuebuf\n",
@ -833,6 +854,8 @@ collect_purge(struct collect_conn *tc)
{
collect_neighbor_purge();
update_rtmetric(tc);
PRINTF("#L %d 0\n", tc->parent.u8[0]);
rimeaddr_copy(&tc->parent, &rimeaddr_null);
}
/*---------------------------------------------------------------------------*/
/** @} */