tsch: skip resynchronization when time source has been already changed.

See #712

Plus, now `resynchronize` is a separate function.
This commit is contained in:
Toshio Ito 2018-10-23 16:31:34 +09:00
parent cc6398dd3c
commit 0997932bcb

View File

@ -243,11 +243,49 @@ tsch_reset(void)
} }
/* TSCH keep-alive functions */ /* TSCH keep-alive functions */
/*---------------------------------------------------------------------------*/
/* Resynchronize to last_eb_nbr.
* Return non-zero if this function schedules the next keepalive.
* Return zero otherwise.
*/
static int
resynchronize(const linkaddr_t *original_time_source_addr)
{
const struct tsch_neighbor *current_time_source = tsch_queue_get_time_source();
if(current_time_source && !linkaddr_cmp(&current_time_source->addr, original_time_source_addr)) {
/* Time source has already been changed (e.g. by RPL). Let's see if it works. */
LOG_INFO("time source has been changed to ");
LOG_INFO_LLADDR(&current_time_source->addr);
LOG_INFO_("\n");
return 0;
}
/* Switch time source to the last neighbor we received an EB from */
if(linkaddr_cmp(&last_eb_nbr_addr, &linkaddr_null)) {
LOG_WARN("not able to re-synchronize, received no EB from other neighbors\n");
if(sync_count == 0) {
/* We got no synchronization at all in this session, leave the network */
tsch_disassociate();
}
return 0;
} else {
LOG_WARN("re-synchronizing on ");
LOG_WARN_LLADDR(&last_eb_nbr_addr);
LOG_WARN_("\n");
/* We simply pick the last neighbor we receiver sync information from */
tsch_queue_update_time_source(&last_eb_nbr_addr);
tsch_join_priority = last_eb_nbr_jp + 1;
/* Try to get in sync ASAP */
tsch_schedule_keepalive_immediately();
return 1;
}
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Tx callback for keepalive messages */ /* Tx callback for keepalive messages */
static void static void
keepalive_packet_sent(void *ptr, int status, int transmissions) keepalive_packet_sent(void *ptr, int status, int transmissions)
{ {
int schedule_next_keepalive = 1;
/* Update neighbor link statistics */ /* Update neighbor link statistics */
link_stats_packet_sent(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), status, transmissions); link_stats_packet_sent(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), status, transmissions);
/* Call RPL callback if RPL is enabled */ /* Call RPL callback if RPL is enabled */
@ -258,28 +296,14 @@ keepalive_packet_sent(void *ptr, int status, int transmissions)
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
LOG_INFO_(", st %d-%d\n", status, transmissions); LOG_INFO_(", st %d-%d\n", status, transmissions);
/* We got no ack, try to recover by switching to the last neighbor we received an EB from */ /* We got no ack, try to resynchronize */
if(status == MAC_TX_NOACK) { if(status == MAC_TX_NOACK) {
if(linkaddr_cmp(&last_eb_nbr_addr, &linkaddr_null)) { schedule_next_keepalive = !resynchronize(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
LOG_WARN("not able to re-synchronize, received no EB from other neighbors\n");
if(sync_count == 0) {
/* We got no synchronization at all in this session, leave the network */
tsch_disassociate();
}
} else {
LOG_WARN("re-synchronizing on ");
LOG_WARN_LLADDR(&last_eb_nbr_addr);
LOG_WARN_("\n");
/* We simply pick the last neighbor we receiver sync information from */
tsch_queue_update_time_source(&last_eb_nbr_addr);
tsch_join_priority = last_eb_nbr_jp + 1;
/* Try to get in sync ASAP */
tsch_schedule_keepalive_immediately();
return;
}
} }
tsch_schedule_keepalive(); if(schedule_next_keepalive) {
tsch_schedule_keepalive();
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Prepare and send a keepalive message */ /* Prepare and send a keepalive message */