Replaced invalid attempt to switch preferred parent when its DS6 neighbor entry got purged.

This commit is contained in:
nvt-se 2010-06-08 15:40:50 +00:00
parent f51e3a4f1e
commit b8848f29eb

View file

@ -32,7 +32,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: rpl-dag.c,v 1.22 2010/06/07 14:01:22 nvt-se Exp $ * $Id: rpl-dag.c,v 1.23 2010/06/08 15:40:50 nvt-se Exp $
*/ */
/** /**
* \file * \file
@ -318,6 +318,8 @@ rpl_preferred_parent(rpl_dag_t *dag)
if(dag->best_parent != best) { if(dag->best_parent != best) {
dag->best_parent = best; /* Cache the value. */ dag->best_parent = best; /* Cache the value. */
rpl_set_default_route(dag, &best->addr); rpl_set_default_route(dag, &best->addr);
/* The DAO parent set changed - schedule a DAO transmission. */
rpl_schedule_dao(dag);
} }
return best; return best;
} }
@ -618,7 +620,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
return; return;
} }
PRINTF("RPL: New parent with rank %hu ", p->rank); PRINTF("RPL: New parent with rank %hu: ", p->rank);
PRINT6ADDR(from); PRINT6ADDR(from);
PRINTF("\n"); PRINTF("\n");
new_parent = 1; new_parent = 1;
@ -663,13 +665,16 @@ rpl_ds6_neighbor_callback(uip_ds6_nbr_t *nbr)
{ {
rpl_dag_t *dag; rpl_dag_t *dag;
rpl_parent_t *p; rpl_parent_t *p;
rpl_parent_t *new_p;
if(nbr->isused) { if(nbr->isused) {
PRINTF("RPL: Neighbor state %u: ", nbr->state); PRINTF("RPL: Neighbor state %u: ", nbr->state);
PRINT6ADDR(&nbr->ipaddr); PRINT6ADDR(&nbr->ipaddr);
PRINTF("\n"); PRINTF("\n");
} else { return;
PRINTF("RPL: Removed neighbor "); }
PRINTF("RPL: Removing neighbor ");
PRINT6ADDR(&nbr->ipaddr); PRINT6ADDR(&nbr->ipaddr);
PRINTF("\n"); PRINTF("\n");
@ -680,32 +685,31 @@ rpl_ds6_neighbor_callback(uip_ds6_nbr_t *nbr)
p = rpl_find_parent(dag, &nbr->ipaddr); p = rpl_find_parent(dag, &nbr->ipaddr);
if(p != NULL) { if(p != NULL) {
rpl_remove_parent(dag, p); if(p == dag->best_parent) {
} /* Try to select a new preferred parent. */
new_p = rpl_preferred_parent(dag);
if(dag->def_route != NULL && if(new_p == NULL) {
uip_ipaddr_cmp(&dag->def_route->ipaddr, &p->addr)) {
p = rpl_preferred_parent(dag);
if(p == NULL) {
rpl_free_dag(dag); rpl_free_dag(dag);
return; return;
} }
if(acceptable_rank_increase(dag, p)) { if(acceptable_rank_increase(dag, new_p)) {
dag->rank = dag->of->increment_rank(p->rank, p); dag->rank = dag->of->increment_rank(new_p->rank, new_p);
if(dag->rank < dag->min_rank) { if(dag->rank < dag->min_rank) {
dag->min_rank = dag->rank; dag->min_rank = dag->rank;
} }
PRINTF("RPL: New rank is %hu, max is %hu\n", PRINTF("RPL: New rank is %hu, max is %hu\n",
dag->rank, dag->min_rank + dag->max_rankinc); dag->rank, dag->min_rank + dag->max_rankinc);
rpl_set_default_route(dag, &p->addr); rpl_set_default_route(dag, &new_p->addr);
} else { } else {
PRINTF("RPL: Cannot select the preferred parent\n"); PRINTF("RPL: Cannot select the preferred parent\n");
/* do local repair - jump down the DAG */ /* do local repair - jump down the DAG */
rpl_set_default_route(dag, NULL);
remove_parents(dag, NULL, POISON_ROUTES); remove_parents(dag, NULL, POISON_ROUTES);
dag->rank = INFINITE_RANK; dag->rank = INFINITE_RANK;
rpl_reset_dio_timer(dag, 1); rpl_reset_dio_timer(dag, 1);
} }
} }
rpl_remove_parent(dag, p);
} }
} }