void uip_ds6_send_rs(uip_ds6_defrt_t *defrt) { u8_t unicast_rs = 0; if (!timer_expired(&uip_ds6_timer_rs)) { return; } locdefrt = NULL; /* First check whether we can unicast the RS to a specific router rather than * multicasting it. */ if ((defrt != NULL) && (defrt->isused)){ /* Mark this router as "sending_rs" in case it wasn't marked already */ defrt->sending_rs = 1; locdefrt = defrt; unicast_rs = 1; } else { for(locdefrt = uip_ds6_defrt_list; locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { if((locdefrt->isused) && (locdefrt->sending_rs)) { unicast_rs = 1; break; } } } if (unicast_rs) { if (locdefrt->rscount < UIP_ND6_MAX_RTR_SOLICITATIONS) { /* Unicast RS and update count and timer */ uip_nd6_rs_output(&locdefrt->ipaddr); locdefrt->rscount = locdefrt->rscount > 10 ? locdefrt->rscount : locdefrt->rscount + 1; timer_set(&uip_ds6_timer_rs, rs_rtx_time(locdefrt->rscount) * CLOCK_SECOND); return; } else { /* Switch to multicast */ locdefrt->sending_rs = 0; rscount = locdefrt->rscount; locdefrt->rscount = 0; } } /* Multicast RS and update RS count and timer */ uip_nd6_rs_output(NULL); if(uip_ds6_defrt_choose() == NULL) { rscount = rscount > 10 ? rscount : rscount + 1; } else { rscount = 0; } /* Make sure we do not send rs more frequently than UIP_ND6_RTR_SOLICITATION_INTERVAL */ timer_set(&uip_ds6_timer_rs, rs_rtx_time(rscount) * CLOCK_SECOND); }
/*---------------------------------------------------------------------------*/ static void handle_periodic_timer(void *ptr) { rpl_purge_routes(); rpl_recalculate_ranks(); /* handle DIS */ #if UIP_ND6_ENGINE != UIP_ND6_ENGINE_RPL #if RPL_DIS_SEND next_dis++; if(rpl_get_any_dag() == NULL && next_dis >= RPL_DIS_INTERVAL) { next_dis = 0; dis_output(NULL); } #endif #else if(rpl_get_any_dag() == NULL && stimer_expired(&uip_ds6_timer_dis)) { discount++; dis_output(NULL); stimer_set(&uip_ds6_timer_dis, rs_rtx_time(discount)); } #endif ctimer_reset(&periodic_timer); }