From 65366d10c10453299d2da5d036b8c3e09ac96eda Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Wed, 16 Mar 2011 13:29:01 +0100 Subject: [PATCH] Update the metric container correctly. Use only one ETX initializer. --- core/net/rpl/rpl-dag.c | 11 ++++------- core/net/rpl/rpl-of-etx.c | 25 +++++++++++-------------- core/net/rpl/rpl-private.h | 2 ++ core/net/rpl/rpl.c | 10 ++++------ core/net/rpl/rpl.h | 2 +- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 1806810cc..64201ca50 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -94,8 +94,6 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF}; #define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS #endif /* !RPL_CONF_DIO_INTERVAL_DOUBLINGS */ -#define INITIAL_ETX NEIGHBOR_INFO_ETX_DIVISOR * 5 - /************************************************************************/ /* Allocate parents from the same static MEMB chunk to reduce memory waste. */ MEMB(parent_memb, struct rpl_parent, RPL_MAX_PARENTS); @@ -309,7 +307,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) memcpy(&p->addr, addr, sizeof(p->addr)); p->dag = dag; p->rank = dio->rank; - p->etx = INITIAL_ETX; + p->link_metric = INITIAL_LINK_METRIC; p->dtsn = 0; memcpy(&p->mc, &dio->mc, sizeof(p->mc)); @@ -459,8 +457,6 @@ join_dag(uip_ipaddr_t *from, rpl_dio_t *dio) } PRINTF("succeeded\n"); - p->etx = INITIAL_ETX; /* The lowest confidence for new parents. */ - /* Determine the objective function by using the objective code point of the DIO. */ of = rpl_find_of(dio->ocp); @@ -733,7 +729,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) PRINTF(")\n"); return; } - + PRINTF("RPL: New candidate parent with rank %u: ", (unsigned)p->rank); PRINT6ADDR(from); PRINTF("\n"); @@ -743,7 +739,8 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } /* We have allocated a candidate parent; process the DIO further. */ - + + memcpy(&p->mc, &dio->mc, sizeof(p->mc)); p->rank = dio->rank; if(rpl_process_parent_event(dag, p) == 0) { /* The candidate parent no longer exists. */ diff --git a/core/net/rpl/rpl-of-etx.c b/core/net/rpl/rpl-of-etx.c index 0b6265311..9d3748174 100644 --- a/core/net/rpl/rpl-of-etx.c +++ b/core/net/rpl/rpl-of-etx.c @@ -66,7 +66,7 @@ rpl_of_t rpl_of_etx = { #define NI_ETX_TO_RPL_ETX(etx) \ ((etx) * (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR)) -#define rpl_path_metric_tO_NI_ETX(etx) \ +#define RPL_ETX_TO_NI_ETX(etx) \ ((etx) / (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR)) /* Reject parents that have a higher link metric than the following. */ @@ -75,9 +75,6 @@ rpl_of_t rpl_of_etx = { /* Reject parents that have a higher path cost than the following. */ #define MAX_PATH_COST 100 -/* An initial guess of the link metric. */ -#define INITIAL_LINK_METRIC 3 - /* * The rank must differ more than 1/PARENT_SWITCH_THRESHOLD_DIV in order * to switch preferred parent. @@ -89,7 +86,10 @@ typedef uint16_t rpl_path_metric_t; static uint16_t calculate_path_metric(rpl_parent_t *p) { - return p->mc.obj.etx + NI_ETX_TO_RPL_ETX(p->etx); + if(p->mc.obj.etx == 0 && p->rank > ROOT_RANK(p->dag)) { + return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; + } + return p->mc.obj.etx + NI_ETX_TO_RPL_ETX(p->link_metric); } static void @@ -112,12 +112,9 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) if(base_rank == 0) { return INFINITE_RANK; } - rank_increase = INITIAL_LINK_METRIC * DEFAULT_MIN_HOPRANKINC; + rank_increase = NEIGHBOR_INFO_FIX2ETX(INITIAL_LINK_METRIC) * DEFAULT_MIN_HOPRANKINC; } else { - if(p->etx == 0) { - p->etx = INITIAL_LINK_METRIC * NEIGHBOR_INFO_ETX_DIVISOR; - } - rank_increase = (p->etx * p->dag->min_hoprankinc) / NEIGHBOR_INFO_ETX_DIVISOR; + rank_increase = NEIGHBOR_INFO_FIX2ETX(p->link_metric) * p->dag->min_hoprankinc; if(base_rank == 0) { base_rank = p->rank; } @@ -180,6 +177,10 @@ update_metric_container(rpl_dag_t *dag) } else { dag->mc.obj.etx = calculate_path_metric(dag->preferred_parent); } + + PRINTF("RPL: My path ETX to the root is %u.%u\n", + dag->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR, + (dag->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR); #elif RPL_DAG_MC == RPL_DAG_MC_ENERGY dag->mc.type = RPL_DAG_MC_ENERGY; dag->mc.flags = RPL_DAG_MC_FLAG_P; @@ -195,8 +196,4 @@ update_metric_container(rpl_dag_t *dag) #else #error "Unsupported RPL_DAG_MC configured. See rpl.h." #endif /* RPL_DAG_MC */ - - PRINTF("RPL: My path ETX to the root is %u.%u\n", - dag->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR, - (dag->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR); } diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index 9bde3dcfb..764ed940a 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -127,6 +127,8 @@ #define INFINITE_RANK 0xffff +#define INITIAL_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(5) + /* Represents 2^n ms. */ /* Default value according to the specification is 3 which means 8 milliseconds, but that is an unreasonable value if diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index fa7ad7be6..b41fbeea7 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -148,11 +148,10 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx) return; } - if(etx != parent->etx) { - /* Trigger DAG rank recalculation. */ - parent->updated = 1; - } - parent->etx = etx; + /* Trigger DAG rank recalculation. */ + parent->updated = 1; + + parent->link_metric = etx; if(dag->of->parent_state_callback != NULL) { dag->of->parent_state_callback(parent, known, etx); @@ -163,7 +162,6 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx) PRINT6ADDR(&parent->addr); PRINTF(" because of bad connectivity (ETX %d)\n", etx); parent->rank = INFINITE_RANK; - parent->updated = 1; } } /************************************************************************/ diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 5676ccd31..c55ee6cd0 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -147,7 +147,7 @@ struct rpl_parent { rpl_metric_container_t mc; uip_ipaddr_t addr; rpl_rank_t rank; - uint8_t etx; + uint8_t link_metric; uint8_t dtsn; uint8_t updated; };