From be47673d404519a85084d2a3d36aa9189136a624 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 6 May 2015 11:32:29 +0200 Subject: [PATCH 1/8] Fix debug message --- core/net/rpl/rpl-dag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 7b1908cfe..ef64ec91c 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1329,7 +1329,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) PRINTF(", rank %u, min_rank %u, ", instance->current_dag->rank, instance->current_dag->min_rank); PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n", - p->rank, -1/*p->mc.obj.etx*/, p->link_metric, instance->mc.obj.etx); + p->rank, -1/*p->mc.obj.etx*/, rpl_get_nbr(p)->link_metric, instance->mc.obj.etx); /* We have allocated a candidate parent; process the DIO further. */ From 529376be7758eec8320e695c1efb5e416f2d8c1c Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 6 May 2015 11:34:52 +0200 Subject: [PATCH 2/8] Added rpl_print_neighbor_list function for RPL state monitoring --- core/net/rpl/rpl-dag.c | 25 +++++++++++++++++++++++++ core/net/rpl/rpl-timers.c | 4 ++++ core/net/rpl/rpl.h | 1 + 3 files changed, 30 insertions(+) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index ef64ec91c..e0ca1b11b 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -81,6 +81,28 @@ NBR_TABLE(rpl_parent_t, rpl_parents); rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t *default_instance; +/*---------------------------------------------------------------------------*/ +void +rpl_print_neighbor_list() +{ + if(default_instance != NULL && default_instance->current_dag != NULL && + default_instance->of != NULL && default_instance->of->calculate_rank != NULL) { + int curr_dio_interval = default_instance->dio_intcurrent; + int curr_rank = default_instance->current_dag->rank; + rpl_parent_t *p = nbr_table_head(rpl_parents); + + printf("RPL: rank %u dioint %u, %u nbr(s)\n", curr_rank, curr_dio_interval, uip_ds6_nbr_num()); + while(p != NULL) { + uip_ds6_nbr_t *nbr = rpl_get_nbr(p); + printf("RPL: nbr %3u %5u, %5u => %5u %c\n", + nbr_table_get_lladdr(rpl_parents, p)->u8[7], + p->rank, nbr ? nbr->link_metric : 0, default_instance->of->calculate_rank(p, 0), + p == default_instance->current_dag->preferred_parent ? '*' : ' '); + p = nbr_table_next(rpl_parents, p); + } + printf("RPL: end of list\n"); + } +} /*---------------------------------------------------------------------------*/ uip_ds6_nbr_t * rpl_get_nbr(rpl_parent_t *parent) @@ -729,6 +751,9 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) rpl_schedule_dao(instance); } rpl_reset_dio_timer(instance); +#if DEBUG + rpl_print_neighbor_list(); +#endif } else if(best_dag->rank != old_rank) { PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n", (unsigned)old_rank, best_dag->rank); diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index ea7bfe7f2..a849144cf 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -166,6 +166,10 @@ handle_dio_timer(void *ptr) } new_dio_interval(instance); } + +#if DEBUG + rpl_print_neighbor_list(); +#endif } /*---------------------------------------------------------------------------*/ void diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 512c1a8f0..e370d5d52 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -251,6 +251,7 @@ rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr); uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr); void rpl_dag_init(void); uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent); +void rpl_print_neighbor_list(); /** * RPL modes From 47ba4c0c4bd81fd429ba23557aa44ee75daa2b3a Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 6 May 2015 11:35:42 +0200 Subject: [PATCH 3/8] Implement RPL probing --- core/net/rpl/rpl-conf.h | 42 +++++++++++++++++++ core/net/rpl/rpl-dag.c | 17 ++++++-- core/net/rpl/rpl-icmp6.c | 8 +++- core/net/rpl/rpl-private.h | 1 + core/net/rpl/rpl-timers.c | 85 ++++++++++++++++++++++++++++++++++++++ core/net/rpl/rpl.c | 1 + core/net/rpl/rpl.h | 7 ++++ 7 files changed, 155 insertions(+), 6 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 95a05a499..d3749e033 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -207,4 +207,46 @@ #define RPL_INSERT_HBH_OPTION 1 #endif +/* + * RPL probing. When enabled, probes will be sent periodically to keep + * parent link estimates up to date. + * */ +#ifdef RPL_CONF_WITH_PROBING +#define RPL_WITH_PROBING RPL_CONF_WITH_PROBING +#else +#define RPL_WITH_PROBING 1 +#endif + +/* + * RPL probing interval. + * */ +#ifdef RPL_CONF_PROBING_INTERVAL +#define RPL_PROBING_INTERVAL RPL_CONF_PROBING_INTERVAL +#else +#define RPL_PROBING_INTERVAL (120 * CLOCK_SECOND) +#endif + +/* + * Function used to select the next parent to be probed. + * */ +#ifdef RPL_CONF_PROBING_SELECT_FUNC +#define RPL_PROBING_SELECT_FUNC RPL_CONF_PROBING_SELECT_FUNC +#else +#define RPL_PROBING_SELECT_FUNC(dag) get_probing_target((dag)) +#endif + +/* + * Function used to send RPL probes. + * To probe with DIO, use: + * #define RPL_CONF_PROBING_SEND_FUNC(instance, addr) dio_output((instance), (addr)) + * To probe with DIS, use: + * #define RPL_CONF_PROBING_SEND_FUNC(instance, addr) dis_output((addr)) + * Any other custom probing function is also acceptable. + * */ +#ifdef RPL_CONF_PROBING_SEND_FUNC +#define RPL_PROBING_SEND_FUNC RPL_CONF_PROBING_SEND_FUNC +#else +#define RPL_PROBING_SEND_FUNC(instance, addr) dio_output((instance), (addr)) +#endif + #endif /* RPL_CONF_H */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index e0ca1b11b..0bae981b3 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -75,7 +75,7 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF}; /*---------------------------------------------------------------------------*/ /* Per-parent RPL information */ -NBR_TABLE(rpl_parent_t, rpl_parents); +NBR_TABLE_GLOBAL(rpl_parent_t, rpl_parents); /*---------------------------------------------------------------------------*/ /* Allocate instance table. */ rpl_instance_t instance_table[RPL_MAX_INSTANCES]; @@ -90,14 +90,17 @@ rpl_print_neighbor_list() int curr_dio_interval = default_instance->dio_intcurrent; int curr_rank = default_instance->current_dag->rank; rpl_parent_t *p = nbr_table_head(rpl_parents); + clock_time_t now = clock_time(); printf("RPL: rank %u dioint %u, %u nbr(s)\n", curr_rank, curr_dio_interval, uip_ds6_nbr_num()); while(p != NULL) { uip_ds6_nbr_t *nbr = rpl_get_nbr(p); - printf("RPL: nbr %3u %5u, %5u => %5u %c\n", + printf("RPL: nbr %3u %5u, %5u => %5u %c (last tx %u min ago)\n", nbr_table_get_lladdr(rpl_parents, p)->u8[7], - p->rank, nbr ? nbr->link_metric : 0, default_instance->of->calculate_rank(p, 0), - p == default_instance->current_dag->preferred_parent ? '*' : ' '); + p->rank, nbr ? nbr->link_metric : 0, + default_instance->of->calculate_rank(p, 0), + p == default_instance->current_dag->preferred_parent ? '*' : ' ', + (now - p->last_tx_time) / (60 * CLOCK_SECOND)); p = nbr_table_next(rpl_parents, p); } printf("RPL: end of list\n"); @@ -496,6 +499,9 @@ rpl_alloc_instance(uint8_t instance_id) instance->instance_id = instance_id; instance->def_route = NULL; instance->used = 1; +#if RPL_WITH_PROBING + rpl_schedule_probing(instance); +#endif /* RPL_WITH_PROBING */ return instance; } } @@ -556,6 +562,9 @@ rpl_free_instance(rpl_instance_t *instance) 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); diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index c9890b706..66e311d51 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -466,8 +466,12 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr) buffer[pos++] = instance->dtsn_out; - /* always request new DAO to refresh route */ - RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); + if(uc_addr == NULL) { + /* Request new DAO to refresh route. We do not do this for unicast DIO + * in order to avoid DAO messages after a DIS-DIO update, + * or upon unicast DIO probing. */ + RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); + } /* reserved 2 bytes */ buffer[pos++] = 0; /* flags */ diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index a9ca3f375..ea4e34f90 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -313,6 +313,7 @@ rpl_of_t *rpl_find_of(rpl_ocp_t); void rpl_schedule_dao(rpl_instance_t *); void rpl_schedule_dao_immediately(rpl_instance_t *); void rpl_cancel_dao(rpl_instance_t *instance); +void rpl_schedule_probing(rpl_instance_t *instance); void rpl_reset_dio_timer(rpl_instance_t *); void rpl_reset_periodic_timer(void); diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index a849144cf..a5b0e0fc1 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -327,5 +327,90 @@ rpl_cancel_dao(rpl_instance_t *instance) ctimer_stop(&instance->dao_lifetime_timer); } /*---------------------------------------------------------------------------*/ +#if RPL_WITH_PROBING +static rpl_parent_t * +get_probing_target(rpl_dag_t *dag) +{ + /* Returns the next probing target. The current implementation looks for the + * best parent to which we have not transmitted since 2 * RPL_PROBING_INTERVAL. + * This will mostly select the preferred and second best parents. Probing the + * second best parent is important: if the link is good, RPL might choose to + * switch to it. If the link is bad, the second best parent will decrease in + * ranking, and another parent will be probed next time. */ + rpl_parent_t *p; + rpl_parent_t *probing_target; + rpl_rank_t probing_target_rank; + /* Look for a parent we have not sent to since 2 * RPL_PROBING_INTERVAL, + * e.g. with last_tx_time earlier than min_last_tx */ + clock_time_t min_last_tx = clock_time(); + min_last_tx = min_last_tx > 2 * RPL_PROBING_INTERVAL ? min_last_tx - 2 * RPL_PROBING_INTERVAL : 1; + + if(dag == NULL || + dag->instance == NULL || + dag->preferred_parent == NULL) { + return NULL; + } + + /* Our preferred parent needs probing */ + if(dag->preferred_parent->last_tx_time < min_last_tx) { + return dag->preferred_parent; + } + + /* Look for the best parent that needs probing. */ + probing_target = NULL; + probing_target_rank = INFINITE_RANK; + p = nbr_table_head(rpl_parents); + while(p != NULL) { + if(p->dag == dag && p->last_tx_time < min_last_tx) { + rpl_rank_t p_rank = dag->instance->of->calculate_rank(p, 0); + /* p is in our dag and needs probing */ + if(probing_target == NULL) { + probing_target = p; + probing_target_rank = p_rank; + } else { + if(p_rank < probing_target_rank) { + /* Found better candidate */ + probing_target = p; + probing_target_rank = p_rank; + } + } + } + p = nbr_table_next(rpl_parents, p); + } + + return probing_target; +} +/*---------------------------------------------------------------------------*/ +static void +handle_probing_timer(void *ptr) +{ + rpl_instance_t *instance = (rpl_instance_t *)ptr; + rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(instance->current_dag); + + /* Perform probing */ + if(probing_target != NULL && rpl_get_parent_ipaddr(probing_target) != NULL) { + PRINTF("RPL: probing %3u\n", + nbr_table_get_lladdr(rpl_parents, probing_target)->u8[7]); + /* Send probe, e.g. unicast DIO or DIS */ + RPL_PROBING_SEND_FUNC(instance, rpl_get_parent_ipaddr(probing_target)); + } + + /* Schedule next probing */ + rpl_schedule_probing(instance); + +#if DEBUG + rpl_print_neighbor_list(); +#endif +} +/*---------------------------------------------------------------------------*/ +void +rpl_schedule_probing(rpl_instance_t *instance) +{ + clock_time_t delay = (RPL_PROBING_INTERVAL / 2) + + random_rand() % (RPL_PROBING_INTERVAL / 2); + ctimer_set(&instance->probing_timer, delay, + handle_probing_timer, instance); +} +#endif /* RPL_WITH_PROBING */ /** @}*/ diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index f92d5f5f8..db5230611 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -263,6 +263,7 @@ rpl_link_neighbor_callback(const linkaddr_t *addr, int status, int numtx) parent->flags |= RPL_PARENT_FLAG_UPDATED; if(instance->of->neighbor_link_callback != NULL) { instance->of->neighbor_link_callback(parent, status, numtx); + parent->last_tx_time = clock_time(); } } } diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index e370d5d52..e6e385375 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -114,6 +114,7 @@ struct rpl_parent { rpl_metric_container_t mc; #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ rpl_rank_t rank; + clock_time_t last_tx_time; uint8_t dtsn; uint8_t flags; }; @@ -224,6 +225,9 @@ struct rpl_instance { uint16_t dio_totrecv; #endif /* RPL_CONF_STATS */ clock_time_t dio_next_delay; /* delay for completion of dio interval */ +#if RPL_WITH_PROBING + struct ctimer probing_timer; +#endif /* RPL_WITH_PROBING */ struct ctimer dio_timer; struct ctimer dao_timer; struct ctimer dao_lifetime_timer; @@ -253,6 +257,9 @@ void rpl_dag_init(void); uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent); void rpl_print_neighbor_list(); +/* Per-parent RPL information */ +NBR_TABLE_DECLARE(rpl_parents); + /** * RPL modes * From 2dd182f4a8a322867f90cdbc8f1a983b972ac7cd Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 8 May 2015 10:19:14 +0200 Subject: [PATCH 4/8] Modified the default RPL probing selection process. Will now probe the least recently updated parent from time to time --- core/net/rpl/rpl-timers.c | 57 ++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index a5b0e0fc1..7a7a7a2ef 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -331,18 +331,17 @@ rpl_cancel_dao(rpl_instance_t *instance) static rpl_parent_t * get_probing_target(rpl_dag_t *dag) { - /* Returns the next probing target. The current implementation looks for the - * best parent to which we have not transmitted since 2 * RPL_PROBING_INTERVAL. - * This will mostly select the preferred and second best parents. Probing the - * second best parent is important: if the link is good, RPL might choose to - * switch to it. If the link is bad, the second best parent will decrease in - * ranking, and another parent will be probed next time. */ + /* Returns the next probing target. The current implementation probes the current + * preferred parent if we have not updated its link for 2 * RPL_PROBING_INTERVAL. + * Otherwise, it picks at random between: + * (1) selecting the best parent not updated for 2 * RPL_PROBING_INTERVAL + * (2) selecting the least recently updated parent + */ rpl_parent_t *p; - rpl_parent_t *probing_target; - rpl_rank_t probing_target_rank; - /* Look for a parent we have not sent to since 2 * RPL_PROBING_INTERVAL, - * e.g. with last_tx_time earlier than min_last_tx */ + rpl_parent_t *probing_target = NULL; + rpl_rank_t probing_target_rank = INFINITE_RANK; + /* min_last_tx is the clock time (2 * RPL_PROBING_INTERVAL) in the past */ clock_time_t min_last_tx = clock_time(); min_last_tx = min_last_tx > 2 * RPL_PROBING_INTERVAL ? min_last_tx - 2 * RPL_PROBING_INTERVAL : 1; @@ -357,26 +356,34 @@ get_probing_target(rpl_dag_t *dag) return dag->preferred_parent; } - /* Look for the best parent that needs probing. */ - probing_target = NULL; - probing_target_rank = INFINITE_RANK; - p = nbr_table_head(rpl_parents); - while(p != NULL) { - if(p->dag == dag && p->last_tx_time < min_last_tx) { - rpl_rank_t p_rank = dag->instance->of->calculate_rank(p, 0); - /* p is in our dag and needs probing */ - if(probing_target == NULL) { - probing_target = p; - probing_target_rank = p_rank; - } else { - if(p_rank < probing_target_rank) { - /* Found better candidate */ + if((random_rand() % 2) == 0) { + /* With 1/2 probability: probe best parent not updated for 2 * RPL_PROBING_INTERVAL */ + p = nbr_table_head(rpl_parents); + while(p != NULL) { + if(p->dag == dag && p->last_tx_time < min_last_tx) { + /* p is in our dag and needs probing */ + rpl_rank_t p_rank = dag->instance->of->calculate_rank(p, 0); + if(probing_target == NULL + || p_rank < probing_target_rank) { probing_target = p; probing_target_rank = p_rank; } } + p = nbr_table_next(rpl_parents, p); } - p = nbr_table_next(rpl_parents, p); + } else { + /* With 1/2 probability: probe the least recently updated parent */ + p = nbr_table_head(rpl_parents); + while(p != NULL) { + if(p->dag == dag) { + if(probing_target == NULL + || p->last_tx_time < probing_target->last_tx_time) { + probing_target = p; + } + } + p = nbr_table_next(rpl_parents, p); + } + } return probing_target; From 6a5f238255a3a3450db2588cba7383d1be8529a0 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 8 May 2015 10:23:03 +0200 Subject: [PATCH 5/8] RPL probing: make delay function user-configurable --- core/net/rpl/rpl-conf.h | 10 ++++++++++ core/net/rpl/rpl-timers.c | 4 +--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index d3749e033..11d2cdbd0 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -249,4 +249,14 @@ #define RPL_PROBING_SEND_FUNC(instance, addr) dio_output((instance), (addr)) #endif +/* + * Function used to calculate next RPL probing interval + * */ +#ifdef RPL_CONF_PROBING_DELAY_FUNC +#define RPL_PROBING_DELAY_FUNC RPL_CONF_PROBING_DELAY_FUNC +#else +#define RPL_PROBING_DELAY_FUNC() ((RPL_PROBING_INTERVAL / 2) \ + + random_rand() % (RPL_PROBING_INTERVAL)) +#endif + #endif /* RPL_CONF_H */ diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index 7a7a7a2ef..fac19ee4f 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -414,9 +414,7 @@ handle_probing_timer(void *ptr) void rpl_schedule_probing(rpl_instance_t *instance) { - clock_time_t delay = (RPL_PROBING_INTERVAL / 2) + - random_rand() % (RPL_PROBING_INTERVAL / 2); - ctimer_set(&instance->probing_timer, delay, + ctimer_set(&instance->probing_timer, RPL_PROBING_DELAY_FUNC(), handle_probing_timer, instance); } #endif /* RPL_WITH_PROBING */ From d1ec31308156ddca14d39903a17087c4942373b1 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 8 May 2015 14:25:30 +0200 Subject: [PATCH 6/8] Add regression test for probing --- regression-tests/12-rpl/09-rpl-probing.csc | 258 +++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 regression-tests/12-rpl/09-rpl-probing.csc diff --git a/regression-tests/12-rpl/09-rpl-probing.csc b/regression-tests/12-rpl/09-rpl-probing.csc new file mode 100644 index 000000000..bc29029af --- /dev/null +++ b/regression-tests/12-rpl/09-rpl-probing.csc @@ -0,0 +1,258 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype190 + Sender + [CONTIKI_DIR]/regression-tests/12-rpl/code/sender-node.c + make clean TARGET=cooja +make sender-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype481 + RPL root + [CONTIKI_DIR]/regression-tests/12-rpl/code/root-node.c + make clean TARGET=cooja +make root-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype692 + Receiver + [CONTIKI_DIR]/regression-tests/12-rpl/code/receiver-node.c + make clean TARGET=cooja +make receiver-node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 8.0 + 2.0 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype481 + + + + org.contikios.cooja.interfaces.Position + -7.19071602882406 + 34.96668248624779 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype190 + + + + org.contikios.cooja.interfaces.Position + -17.870288882812428 + 4.581754854333804 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype692 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 2.494541140753371 0.0 0.0 2.494541140753371 168.25302383129448 116.2254386098645 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 597 + 0 + 428 + 402 + 162 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 904 + 4 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.ScriptRunner + + + true + + 605 + 1 + 684 + 604 + 14 + + + From 832a4d3e01349458a48a585e2e1af72ec6be0411 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sun, 10 May 2015 13:19:56 +0200 Subject: [PATCH 7/8] Make probing expiration time configurable --- core/net/rpl/rpl-conf.h | 9 +++++++++ core/net/rpl/rpl-timers.c | 11 ++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 11d2cdbd0..a2c0e6dd2 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -226,6 +226,15 @@ #define RPL_PROBING_INTERVAL (120 * CLOCK_SECOND) #endif +/* + * RPL probing expiration time. + * */ +#ifdef RPL_CONF_PROBING_EXPIRATION_TIME +#define RPL_PROBING_EXPIRATION_TIME RPL_CONF_PROBING_EXPIRATION_TIME +#else +#define RPL_PROBING_EXPIRATION_TIME (10 * 60 * CLOCK_SECOND) +#endif + /* * Function used to select the next parent to be probed. * */ diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index fac19ee4f..def1ff404 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -332,18 +332,19 @@ static rpl_parent_t * get_probing_target(rpl_dag_t *dag) { /* Returns the next probing target. The current implementation probes the current - * preferred parent if we have not updated its link for 2 * RPL_PROBING_INTERVAL. + * preferred parent if we have not updated its link for RPL_PROBING_EXPIRATION_TIME. * Otherwise, it picks at random between: - * (1) selecting the best parent not updated for 2 * RPL_PROBING_INTERVAL + * (1) selecting the best parent not updated for RPL_PROBING_EXPIRATION_TIME * (2) selecting the least recently updated parent */ rpl_parent_t *p; rpl_parent_t *probing_target = NULL; rpl_rank_t probing_target_rank = INFINITE_RANK; - /* min_last_tx is the clock time (2 * RPL_PROBING_INTERVAL) in the past */ + /* min_last_tx is the clock time RPL_PROBING_EXPIRATION_TIME in the past */ clock_time_t min_last_tx = clock_time(); - min_last_tx = min_last_tx > 2 * RPL_PROBING_INTERVAL ? min_last_tx - 2 * RPL_PROBING_INTERVAL : 1; + min_last_tx = min_last_tx > 2 * RPL_PROBING_EXPIRATION_TIME + ? min_last_tx - RPL_PROBING_EXPIRATION_TIME : 1; if(dag == NULL || dag->instance == NULL || @@ -357,7 +358,7 @@ get_probing_target(rpl_dag_t *dag) } if((random_rand() % 2) == 0) { - /* With 1/2 probability: probe best parent not updated for 2 * RPL_PROBING_INTERVAL */ + /* With 1/2 probability: probe best parent not updated for RPL_PROBING_EXPIRATION_TIME */ p = nbr_table_head(rpl_parents); while(p != NULL) { if(p->dag == dag && p->last_tx_time < min_last_tx) { From 9ced5b7bac2150f993ba0c6e602f279e7b27127f Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sun, 10 May 2015 13:28:00 +0200 Subject: [PATCH 8/8] RPL: when no probing target is found, probe least recently updated parent --- core/net/rpl/rpl-timers.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index def1ff404..27fff0ddf 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -354,11 +354,11 @@ get_probing_target(rpl_dag_t *dag) /* Our preferred parent needs probing */ if(dag->preferred_parent->last_tx_time < min_last_tx) { - return dag->preferred_parent; + probing_target = dag->preferred_parent; } - if((random_rand() % 2) == 0) { - /* With 1/2 probability: probe best parent not updated for RPL_PROBING_EXPIRATION_TIME */ + /* With 50% probability: probe best parent not updated for RPL_PROBING_EXPIRATION_TIME */ + if(probing_target == NULL && (random_rand() % 2) == 0) { p = nbr_table_head(rpl_parents); while(p != NULL) { if(p->dag == dag && p->last_tx_time < min_last_tx) { @@ -372,8 +372,10 @@ get_probing_target(rpl_dag_t *dag) } p = nbr_table_next(rpl_parents, p); } - } else { - /* With 1/2 probability: probe the least recently updated parent */ + } + + /* The default probing target is the least recently updated parent */ + if(probing_target == NULL) { p = nbr_table_head(rpl_parents); while(p != NULL) { if(p->dag == dag) { @@ -384,7 +386,6 @@ get_probing_target(rpl_dag_t *dag) } p = nbr_table_next(rpl_parents, p); } - } return probing_target;