/*---------------------------------------------------------------------------*/ void rpl_purge_dags(void) { rpl_instance_t *instance; rpl_instance_t *end; int i; for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { if(instance->used) { for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) { if(instance->dag_table[i].used) { if(instance->dag_table[i].lifetime == 0) { if(!instance->dag_table[i].joined) { PRINTF("Removing dag "); PRINT6ADDR(&instance->dag_table[i].dag_id); PRINTF("\n"); rpl_free_dag(&instance->dag_table[i]); } } else { instance->dag_table[i].lifetime--; } } } } } }
/*---------------------------------------------------------------------------*/ void rpl_free_instance(rpl_instance_t *instance) { rpl_dag_t *dag; rpl_dag_t *end; PRINTF("RPL: Leaving the instance %u\n", instance->instance_id); /* Remove any DAG inside this instance */ for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { if(dag->used) { rpl_free_dag(dag); } } rpl_set_default_route(instance, NULL); #if RPL_WITH_PROBING ctimer_stop(&instance->probing_timer); #endif /* RPL_WITH_PROBING */ ctimer_stop(&instance->dio_timer); ctimer_stop(&instance->dao_timer); ctimer_stop(&instance->dao_lifetime_timer); if(default_instance == instance) { default_instance = NULL; } instance->used = 0; }
rpl_dag_t * rpl_set_root(uip_ipaddr_t *dag_id) { rpl_dag_t *dag; int version; version = -1; dag = rpl_get_dag(RPL_DEFAULT_INSTANCE); if(dag != NULL) { PRINTF("RPL: Dropping a joined DAG when setting this node as root"); version = dag->version; rpl_free_dag(dag); } dag = rpl_alloc_dag(RPL_DEFAULT_INSTANCE); if(dag == NULL) { PRINTF("RPL: Failed to allocate a DAG\n"); return NULL; } dag->joined = 1; dag->version = version + 1; dag->grounded = RPL_GROUNDED; dag->mop = RPL_MOP_DEFAULT; dag->of = &RPL_OF; dag->preferred_parent = NULL; dag->dtsn_out = 1; /* Trigger DAOs from the beginning. */ memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id)); dag->dio_intdoubl = DEFAULT_DIO_INTERVAL_DOUBLINGS; dag->dio_intmin = DEFAULT_DIO_INTERVAL_MIN; dag->dio_redundancy = DEFAULT_DIO_REDUNDANCY; dag->max_rankinc = DEFAULT_MAX_RANKINC; dag->min_hoprankinc = DEFAULT_MIN_HOPRANKINC; dag->default_lifetime = RPL_DEFAULT_LIFETIME; dag->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT; dag->rank = ROOT_RANK(dag); dag->of->update_metric_container(dag); PRINTF("RPL: Node set to be a DAG root with DAG ID "); PRINT6ADDR(&dag->dag_id); PRINTF("\n"); ANNOTATE("#A root=%u\n",dag->dag_id.u8[sizeof(dag->dag_id) - 1]); rpl_reset_dio_timer(dag, 1); return dag; }
void cetic_6lbr_end_dodag_root(rpl_instance_t *instance) { if(is_dodag_root()) { LOG6LBR_INFO("Leaving DODAG root\n"); rpl_local_repair(instance); dio_output(instance, NULL); rpl_free_dag(instance->current_dag); rpl_free_instance(instance); if(!rpl_fast_startup) { //Restart DODAG creation check ctimer_set(&create_dodag_root_timer, CLOCK_SECOND, check_dodag_creation, NULL); } } }
/*---------------------------------------------------------------------------*/ rpl_dag_t * rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) { rpl_dag_t *dag; rpl_instance_t *instance; uint8_t version; int i; #if CETIC_6LBR version = nvm_data.rpl_version_id; RPL_LOLLIPOP_INCREMENT(version); nvm_data.rpl_version_id = version; store_nvm_config(); #else version = RPL_LOLLIPOP_INIT; #endif instance = rpl_get_instance(instance_id); if(instance != NULL) { for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; ++i) { dag = &instance->dag_table[i]; if(dag->used) { if(uip_ipaddr_cmp(&dag->dag_id, dag_id)) { version = dag->version; RPL_LOLLIPOP_INCREMENT(version); #if CETIC_6LBR nvm_data.rpl_version_id = version; store_nvm_config(); #endif } if(dag == dag->instance->current_dag) { PRINTF("RPL: Dropping a joined DAG when setting this node as root"); rpl_set_default_route(instance, NULL); dag->instance->current_dag = NULL; } else { PRINTF("RPL: Dropping a DAG when setting this node as root"); } rpl_free_dag(dag); } } } dag = rpl_alloc_dag(instance_id, dag_id); if(dag == NULL) { PRINTF("RPL: Failed to allocate a DAG\n"); return NULL; } instance = dag->instance; dag->version = version; dag->joined = 1; dag->grounded = RPL_GROUNDED; dag->preference = RPL_PREFERENCE; instance->mop = RPL_MOP_DEFAULT; instance->of = &RPL_OF; rpl_set_preferred_parent(dag, NULL); memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id)); instance->dio_intdoubl = RPL_DIO_INTERVAL_DOUBLINGS; instance->dio_intmin = RPL_DIO_INTERVAL_MIN; /* The current interval must differ from the minimum interval in order to trigger a DIO timer reset. */ instance->dio_intcurrent = RPL_DIO_INTERVAL_MIN + RPL_DIO_INTERVAL_DOUBLINGS; instance->dio_redundancy = RPL_DIO_REDUNDANCY; instance->max_rankinc = RPL_MAX_RANKINC; instance->min_hoprankinc = RPL_MIN_HOPRANKINC; instance->default_lifetime = RPL_DEFAULT_LIFETIME; instance->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT; dag->rank = ROOT_RANK(instance); if(instance->current_dag != dag && instance->current_dag != NULL) { /* Remove routes installed by DAOs. */ rpl_remove_routes(instance->current_dag); instance->current_dag->joined = 0; } instance->current_dag = dag; instance->dtsn_out = RPL_LOLLIPOP_INIT; instance->of->update_metric_container(instance); default_instance = instance; PRINTF("RPL: Node set to be a DAG root with DAG ID "); PRINT6ADDR(&dag->dag_id); PRINTF("\n"); ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]); rpl_reset_dio_timer(instance); return dag; }