/*---------------------------------------------------------------------------*/ static void handle_dao_timer(void *ptr) { rpl_instance_t *instance; instance = (rpl_instance_t *)ptr; if(!dio_send_ok && uip_ds6_get_link_local(ADDR_PREFERRED) == NULL) { PRINTF("RPL: Postpone DAO transmission\n"); ctimer_set(&instance->dao_timer, CLOCK_SECOND, handle_dao_timer, instance); return; } /* Send the DAO to the DAO parent set -- the preferred parent in our case. */ if(instance->current_dag->preferred_parent != NULL) { PRINTF("RPL: handle_dao_timer - sending DAO\n"); /* Set the route lifetime to the default value. */ dao_output(instance->current_dag->preferred_parent, instance->default_lifetime); } else { PRINTF("RPL: No suitable DAO parent\n"); } ctimer_stop(&instance->dao_timer); if(etimer_expired(&instance->dao_lifetime_timer.etimer)) { set_dao_lifetime_timer(instance); } }
/*---------------------------------------------------------------------------*/ static void schedule_dao(rpl_instance_t *instance, clock_time_t latency) { clock_time_t expiration_time; if(rpl_get_mode() == RPL_MODE_FEATHER) { return; } expiration_time = etimer_expiration_time(&instance->dao_timer.etimer); if(!etimer_expired(&instance->dao_timer.etimer)) { PRINTF("RPL: DAO timer already scheduled\n\r"); } else { if(latency != 0) { expiration_time = latency / 2 + (random_rand() % (latency)); } else { expiration_time = 0; } PRINTF("RPL: Scheduling DAO timer %u ticks in the future\n\r", (unsigned)expiration_time); ctimer_set(&instance->dao_timer, expiration_time, handle_dao_timer, instance); set_dao_lifetime_timer(instance); } }
/*---------------------------------------------------------------------------*/ static void handle_dao_timer(struct net_buf *not_used, void *ptr) { rpl_instance_t *instance; #if RPL_CONF_MULTICAST uip_mcast6_route_t *mcast_route; uint8_t i; #endif instance = (rpl_instance_t *)ptr; if(!dio_send_ok && uip_ds6_get_link_local(ADDR_PREFERRED) == NULL) { PRINTF("RPL: Postpone DAO transmission\n"); ctimer_set(NULL, &instance->dao_timer, CLOCK_SECOND, handle_dao_timer, instance); return; } /* Send the DAO to the DAO parent set -- the preferred parent in our case. */ if(instance->current_dag->preferred_parent != NULL) { PRINTF("RPL: handle_dao_timer - sending DAO\n"); /* Set the route lifetime to the default value. */ dao_output(instance->current_dag->preferred_parent, instance->default_lifetime); #if RPL_CONF_MULTICAST /* Send DAOs for multicast prefixes only if the instance is in MOP 3 */ if(instance->mop == RPL_MOP_STORING_MULTICAST) { /* Send a DAO for own multicast addresses */ for(i = 0; i < UIP_DS6_MADDR_NB; i++) { if(uip_ds6_if.maddr_list[i].isused && uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) { dao_output_target(instance->current_dag->preferred_parent, &uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME); } } /* Iterate over multicast routes and send DAOs */ mcast_route = uip_mcast6_route_list_head(); while(mcast_route != NULL) { /* Don't send if it's also our own address, done that already */ if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) { dao_output_target(instance->current_dag->preferred_parent, &mcast_route->group, RPL_MCAST_LIFETIME); } mcast_route = list_item_next(mcast_route); } } #endif } else { PRINTF("RPL: No suitable DAO parent\n"); } ctimer_stop(&instance->dao_timer); if(etimer_expired(&instance->dao_lifetime_timer.etimer)) { set_dao_lifetime_timer(instance); } }