RPL Classic: make sure no more than one probe gets in queue at any given time

This commit is contained in:
Simon Duquennoy 2018-05-09 14:39:14 -07:00
parent a2d9093cef
commit 72f558fb6e
4 changed files with 17 additions and 10 deletions

View File

@ -908,6 +908,8 @@ rpl_select_parent(rpl_dag_t *dag)
#if RPL_WITH_PROBING #if RPL_WITH_PROBING
if(rpl_parent_is_fresh(best)) { if(rpl_parent_is_fresh(best)) {
rpl_set_preferred_parent(dag, best); rpl_set_preferred_parent(dag, best);
/* Unschedule any already scheduled urgent probing */
dag->instance->urgent_probing_target = NULL;
} else { } else {
/* The best is not fresh. Look for the best fresh now. */ /* The best is not fresh. Look for the best fresh now. */
rpl_parent_t *best_fresh = best_parent(dag, 1); rpl_parent_t *best_fresh = best_parent(dag, 1);
@ -920,7 +922,7 @@ rpl_select_parent(rpl_dag_t *dag)
} }
/* Probe the best parent shortly in order to get a fresh estimate */ /* Probe the best parent shortly in order to get a fresh estimate */
dag->instance->urgent_probing_target = best; dag->instance->urgent_probing_target = best;
rpl_schedule_probing(dag->instance); rpl_schedule_probing_now(dag->instance);
} }
#else /* RPL_WITH_PROBING */ #else /* RPL_WITH_PROBING */
rpl_set_preferred_parent(dag, best); rpl_set_preferred_parent(dag, best);

View File

@ -341,6 +341,7 @@ void rpl_schedule_dao_immediately(rpl_instance_t *);
void rpl_schedule_unicast_dio_immediately(rpl_instance_t *instance); void rpl_schedule_unicast_dio_immediately(rpl_instance_t *instance);
void rpl_cancel_dao(rpl_instance_t *instance); void rpl_cancel_dao(rpl_instance_t *instance);
void rpl_schedule_probing(rpl_instance_t *instance); void rpl_schedule_probing(rpl_instance_t *instance);
void rpl_schedule_probing_now(rpl_instance_t *instance);
void rpl_reset_dio_timer(rpl_instance_t *); void rpl_reset_dio_timer(rpl_instance_t *);
void rpl_reset_periodic_timer(void); void rpl_reset_periodic_timer(void);

View File

@ -380,14 +380,7 @@ rpl_schedule_unicast_dio_immediately(rpl_instance_t *instance)
clock_time_t clock_time_t
get_probing_delay(rpl_dag_t *dag) get_probing_delay(rpl_dag_t *dag)
{ {
if(dag != NULL && dag->instance != NULL return ((RPL_PROBING_INTERVAL) / 2) + random_rand() % (RPL_PROBING_INTERVAL);
&& dag->instance->urgent_probing_target != NULL) {
/* Urgent probing needed (to find out if a neighbor may become preferred parent) */
return random_rand() % (CLOCK_SECOND * 10);
} else {
/* Else, use normal probing interval */
return ((RPL_PROBING_INTERVAL) / 2) + random_rand() % (RPL_PROBING_INTERVAL);
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
rpl_parent_t * rpl_parent_t *
@ -494,7 +487,6 @@ handle_probing_timer(void *ptr)
); );
/* Send probe, e.g. unicast DIO or DIS */ /* Send probe, e.g. unicast DIO or DIS */
RPL_PROBING_SEND_FUNC(instance, target_ipaddr); RPL_PROBING_SEND_FUNC(instance, target_ipaddr);
instance->urgent_probing_target = NULL;
} }
/* Schedule next probing */ /* Schedule next probing */
@ -511,5 +503,12 @@ rpl_schedule_probing(rpl_instance_t *instance)
ctimer_set(&instance->probing_timer, RPL_PROBING_DELAY_FUNC(instance->current_dag), ctimer_set(&instance->probing_timer, RPL_PROBING_DELAY_FUNC(instance->current_dag),
handle_probing_timer, instance); handle_probing_timer, instance);
} }
/*---------------------------------------------------------------------------*/
void
rpl_schedule_probing_now(rpl_instance_t *instance)
{
ctimer_set(&instance->probing_timer, random_rand() % (CLOCK_SECOND * 4),
handle_probing_timer, instance);
}
#endif /* RPL_WITH_PROBING */ #endif /* RPL_WITH_PROBING */
/** @}*/ /** @}*/

View File

@ -266,6 +266,11 @@ rpl_link_callback(const linkaddr_t *addr, int status, int numtx)
if(instance->used == 1 ) { if(instance->used == 1 ) {
parent = rpl_find_parent_any_dag(instance, &ipaddr); parent = rpl_find_parent_any_dag(instance, &ipaddr);
if(parent != NULL) { if(parent != NULL) {
/* If this is the neighbor we were probing urgently, mark urgent
probing as done */
if(instance->urgent_probing_target == parent) {
instance->urgent_probing_target = NULL;
}
/* Trigger DAG rank recalculation. */ /* Trigger DAG rank recalculation. */
PRINTF("RPL: rpl_link_callback triggering update\n"); PRINTF("RPL: rpl_link_callback triggering update\n");
parent->flags |= RPL_PARENT_FLAG_UPDATED; parent->flags |= RPL_PARENT_FLAG_UPDATED;