From 0997932bcb357c80336e0294ca38568c5ce2d514 Mon Sep 17 00:00:00 2001 From: Toshio Ito Date: Tue, 23 Oct 2018 16:31:34 +0900 Subject: [PATCH] tsch: skip resynchronization when time source has been already changed. See #712 Plus, now `resynchronize` is a separate function. --- os/net/mac/tsch/tsch.c | 62 +++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/os/net/mac/tsch/tsch.c b/os/net/mac/tsch/tsch.c index 25b565809..60638eaaf 100644 --- a/os/net/mac/tsch/tsch.c +++ b/os/net/mac/tsch/tsch.c @@ -243,11 +243,49 @@ tsch_reset(void) } /* 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(¤t_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(¤t_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 */ static void keepalive_packet_sent(void *ptr, int status, int transmissions) { + int schedule_next_keepalive = 1; /* Update neighbor link statistics */ link_stats_packet_sent(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), status, transmissions); /* 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_(", 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(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(); - } - } 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; - } + schedule_next_keepalive = !resynchronize(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } - tsch_schedule_keepalive(); + if(schedule_next_keepalive) { + tsch_schedule_keepalive(); + } } /*---------------------------------------------------------------------------*/ /* Prepare and send a keepalive message */