Rewrote proactive link estimator to be invoked randomly instead of triggered by an empty queue; this makes network bootups because nodes are not synchronized
This commit is contained in:
parent
f9d5815e19
commit
677575fc8c
2 changed files with 66 additions and 46 deletions
|
@ -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.64 2010/10/25 12:25:39 adamdunkels Exp $
|
* $Id: collect.c,v 1.65 2010/10/28 15:36:02 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,12 +154,12 @@ MEMB(send_queue_memb, struct packetqueue_item, MAX_SENDING_QUEUE);
|
||||||
#define MAX_HOPLIM 15
|
#define MAX_HOPLIM 15
|
||||||
|
|
||||||
|
|
||||||
/* Experimental mechanism: when there are no packets in the send
|
/* Proactive probing: when there are no packets in the send
|
||||||
queue, the system periodically sends a dummy packet to potential
|
queue, the system periodically sends a dummy packet to potential
|
||||||
parents, i.e., neighbors with a lower rtmetric than we have but for
|
parents, i.e., neighbors with a lower rtmetric than we have but for
|
||||||
which we do not yet have a link quality estimate. */
|
which we do not yet have a link quality estimate. */
|
||||||
#define PROACTIVE_MAINTENANCE_INTERVAL CLOCK_SECOND * 30
|
#define PROACTIVE_PROBING_INTERVAL (random_rand() % CLOCK_SECOND * 60)
|
||||||
#define PROACTIVE_MAINTENANCE_REXMITS 15
|
#define PROACTIVE_PROBING_REXMITS 15
|
||||||
|
|
||||||
/* COLLECT_CONF_ANNOUNCEMENTS defines if the Collect implementation
|
/* COLLECT_CONF_ANNOUNCEMENTS defines if the Collect implementation
|
||||||
should use Contiki's announcement primitive to announce its routes
|
should use Contiki's announcement primitive to announce its routes
|
||||||
|
@ -502,6 +502,55 @@ send_packet(struct collect_conn *c, struct collect_neighbor *n)
|
||||||
retransmit_not_sent_callback, c);
|
retransmit_not_sent_callback, c);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
proactive_probing_callback(void *ptr)
|
||||||
|
{
|
||||||
|
struct collect_conn *c = ptr;
|
||||||
|
struct packetqueue_item *i;
|
||||||
|
|
||||||
|
ctimer_set(&c->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
|
||||||
|
proactive_probing_callback, ptr);
|
||||||
|
|
||||||
|
/* Only do proactive link probing if we are not the sink and if we
|
||||||
|
have a route. */
|
||||||
|
if(c->rtmetric != RTMETRIC_SINK && c->rtmetric != RTMETRIC_MAX) {
|
||||||
|
/* Grab the first packet on the send queue to see if the queue is
|
||||||
|
empty or not. */
|
||||||
|
i = packetqueue_first(&c->send_queue);
|
||||||
|
if(i == NULL) {
|
||||||
|
/* If there are no packets to send, we go through the list of
|
||||||
|
neighbors to find a potential parent for which we do not have a
|
||||||
|
link estimate and send a dummy packet to it. This allows us to
|
||||||
|
quickly gauge the link quality of neighbors that we do not
|
||||||
|
currently use as parents. */
|
||||||
|
struct collect_neighbor *n;
|
||||||
|
|
||||||
|
/* Find the neighbor with the lowest number of estimates. */
|
||||||
|
for(n = list_head(collect_neighbor_list(&c->neighbor_list));
|
||||||
|
n != NULL; n = list_item_next(n)) {
|
||||||
|
if(n->rtmetric + COLLECT_LINK_ESTIMATE_UNIT < c->rtmetric &&
|
||||||
|
collect_link_estimate_num_estimates(&n->le) == 0) {
|
||||||
|
rimeaddr_t current_parent;
|
||||||
|
|
||||||
|
PRINTF("proactive_probing_callback: found neighbor with no link estimate, %d.%d\n",
|
||||||
|
n->addr.u8[RIMEADDR_SIZE - 2], n->addr.u8[RIMEADDR_SIZE - 1]);
|
||||||
|
|
||||||
|
rimeaddr_copy(¤t_parent, &c->parent);
|
||||||
|
rimeaddr_copy(&c->parent, &n->addr);
|
||||||
|
if(enqueue_dummy_packet(c, PROACTIVE_PROBING_REXMITS)) {
|
||||||
|
send_queued_packet(c);
|
||||||
|
}
|
||||||
|
rimeaddr_copy(&c->parent, ¤t_parent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PRINTF("%d.%d: nothing on queue\n",
|
||||||
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* This function is called when a queued packet should be sent
|
* This function is called when a queued packet should be sent
|
||||||
* out. The function takes the first packet on the output queue, adds
|
* out. The function takes the first packet on the output queue, adds
|
||||||
|
@ -533,38 +582,6 @@ send_queued_packet(struct collect_conn *c)
|
||||||
PRINTF("%d.%d: nothing on queue\n",
|
PRINTF("%d.%d: nothing on queue\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
||||||
|
|
||||||
/* If there are no packets to send, we go through the list of
|
|
||||||
neighbors to find a potential parent for which we do not have a
|
|
||||||
link estimate and send a dummy packet to it. This allows us to
|
|
||||||
quickly gauge the link quality of neighbors that we do not
|
|
||||||
currently use as parents. */
|
|
||||||
if(c->rtmetric != RTMETRIC_SINK &&
|
|
||||||
timer_expired(&c->proactive_maintenence_timer)) {
|
|
||||||
struct collect_neighbor *n;
|
|
||||||
|
|
||||||
timer_set(&c->proactive_maintenence_timer,
|
|
||||||
PROACTIVE_MAINTENANCE_INTERVAL);
|
|
||||||
|
|
||||||
/* Find the neighbor with the lowest number of estimates. */
|
|
||||||
for(n = list_head(collect_neighbor_list(&c->neighbor_list));
|
|
||||||
n != NULL; n = list_item_next(n)) {
|
|
||||||
if(n->rtmetric + COLLECT_LINK_ESTIMATE_UNIT < c->rtmetric &&
|
|
||||||
collect_link_estimate_num_estimates(&n->le) == 0) {
|
|
||||||
rimeaddr_t current_parent;
|
|
||||||
|
|
||||||
PRINTF("proactive maintenance: found neighbor with no link estimate, %d.%d\n",
|
|
||||||
n->addr.u8[0], n->addr.u8[1]);
|
|
||||||
|
|
||||||
rimeaddr_copy(¤t_parent, &c->parent);
|
|
||||||
rimeaddr_copy(&c->parent, &n->addr);
|
|
||||||
if(enqueue_dummy_packet(c, PROACTIVE_MAINTENANCE_REXMITS)) {
|
|
||||||
send_queued_packet(c);
|
|
||||||
}
|
|
||||||
rimeaddr_copy(&c->parent, ¤t_parent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,8 +1041,8 @@ node_packet_received(struct unicast_conn *c, const rimeaddr_t *from)
|
||||||
} else {
|
} else {
|
||||||
send_ack(tc, &ack_to,
|
send_ack(tc, &ack_to,
|
||||||
ackflags | ACK_FLAGS_DROPPED | ACK_FLAGS_CONGESTED);
|
ackflags | ACK_FLAGS_DROPPED | ACK_FLAGS_CONGESTED);
|
||||||
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]);*/
|
||||||
stats.qdrop++;
|
stats.qdrop++;
|
||||||
}
|
}
|
||||||
} else if(packetbuf_attr(PACKETBUF_ATTR_TTL) <= 1) {
|
} else if(packetbuf_attr(PACKETBUF_ATTR_TTL) <= 1) {
|
||||||
|
@ -1056,10 +1073,10 @@ static void
|
||||||
timedout(struct collect_conn *tc)
|
timedout(struct collect_conn *tc)
|
||||||
{
|
{
|
||||||
struct collect_neighbor *n;
|
struct collect_neighbor *n;
|
||||||
printf("%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
|
/* printf("%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], tc->transmissions,
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], tc->transmissions,
|
||||||
tc->current_parent.u8[0], tc->current_parent.u8[1],
|
tc->current_parent.u8[0], tc->current_parent.u8[1],
|
||||||
tc->max_rexmits);
|
tc->max_rexmits);*/
|
||||||
|
|
||||||
tc->sending = 0;
|
tc->sending = 0;
|
||||||
n = collect_neighbor_list_find(&tc->neighbor_list,
|
n = collect_neighbor_list_find(&tc->neighbor_list,
|
||||||
|
@ -1270,6 +1287,9 @@ collect_open(struct collect_conn *tc, uint16_t channels,
|
||||||
announcement_set_value(&tc->announcement, RTMETRIC_MAX);
|
announcement_set_value(&tc->announcement, RTMETRIC_MAX);
|
||||||
#endif /* COLLECT_CONF_WITH_LISTEN */
|
#endif /* COLLECT_CONF_WITH_LISTEN */
|
||||||
#endif /* !COLLECT_ANNOUNCEMENTS */
|
#endif /* !COLLECT_ANNOUNCEMENTS */
|
||||||
|
|
||||||
|
ctimer_set(&tc->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
|
||||||
|
proactive_probing_callback, tc);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
@ -1413,8 +1433,8 @@ collect_send(struct collect_conn *tc, int rexmits)
|
||||||
send_queued_packet(tc);
|
send_queued_packet(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",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1438,8 +1458,8 @@ collect_send(struct collect_conn *tc, int rexmits)
|
||||||
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",
|
||||||
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
|
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[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.22 2010/10/03 20:08:44 adamdunkels Exp $
|
* $Id: collect.h,v 1.23 2010/10/28 15:36:02 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,7 +101,7 @@ struct collect_conn {
|
||||||
struct ctimer keepalive_timer;
|
struct ctimer keepalive_timer;
|
||||||
clock_time_t keepalive_period;
|
clock_time_t keepalive_period;
|
||||||
|
|
||||||
struct timer proactive_maintenence_timer;
|
struct ctimer proactive_probing_timer;
|
||||||
|
|
||||||
rimeaddr_t parent, current_parent;
|
rimeaddr_t parent, current_parent;
|
||||||
uint16_t rtmetric;
|
uint16_t rtmetric;
|
||||||
|
|
Loading…
Reference in a new issue