From ba6bf7dd6b250b2f2735d54ff23d393a34cc47e6 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Fri, 11 Feb 2011 14:17:26 +0100 Subject: [PATCH 1/2] Rewrote the parent selection to favour parents with a low ETX and a good rank. The old parent selection would always favour parents with a lower rank, regardless of their ETX, which in some cases lead to suboptimal parent selections. Also, the old code was buggy in that it would always pick the worst parent (the one with the highest ETX). --- core/net/rpl/rpl-of0.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/core/net/rpl/rpl-of0.c b/core/net/rpl/rpl-of0.c index 8c907a18c..5d7e3c729 100644 --- a/core/net/rpl/rpl-of0.c +++ b/core/net/rpl/rpl-of0.c @@ -46,6 +46,8 @@ #define DEBUG DEBUG_ANNOTATE #include "net/uip-debug.h" +#include "net/neighbor-info.h" + static void reset(void *); static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); @@ -82,6 +84,7 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) return INFINITE_RANK; } return base_rank + DEFAULT_RANK_INCREMENT; + } static rpl_parent_t * @@ -90,22 +93,39 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2) PRINTF("RPL: Comparing parent "); PRINT6ADDR(&p1->addr); PRINTF(" (confidence %d, rank %d) with parent ", - p1->local_confidence, p1->rank); + p1->etx, p1->rank); PRINT6ADDR(&p2->addr); PRINTF(" (confidence %d, rank %d)\n", - p2->local_confidence, p2->rank); + p2->etx, p2->rank); + + /* Compare two parents by looking both and their rank and at the ETX + for that parent. We choose the parent that has the most + favourable combination. */ + if(DAG_RANK(p1->rank, (rpl_dag_t *)p1->dag) * ETX_DIVISOR + p1->etx < + DAG_RANK(p2->rank, (rpl_dag_t *)p1->dag) * ETX_DIVISOR + p2->etx) { + return p1; + } else { + return p2; + } + + /* This is the old code, which isn't used now, but left here in case + we would like to use it later (if the above code turns out to not + work as well as we expect it to. The old code first favoured the + parent with a lower rank, then used the ETX to compare two + parents with the same rank. This is not ideal since you may have + a parent with a low rank on the edge of your range that will have + a very bad ETX. But the code below would nevertheless pick that + one. */ if(p1->rank < p2->rank) { return p1; } else if(p2->rank < p1->rank) { return p2; } - if(p1->local_confidence > p2->local_confidence) { + if(p1->etx < p2->etx) { return p1; - } else if(p2->local_confidence > p1->local_confidence) { + } else { return p2; } - - return p2; } From 706045120fcd0388e8325d5c9782a8910e031f1b Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Fri, 11 Feb 2011 14:18:57 +0100 Subject: [PATCH 2/2] Changed the variable name local_confidence to etx to better reflect what it was used for --- core/net/rpl/rpl-dag.c | 9 +++++++-- core/net/rpl/rpl-of-etx.c | 6 +++--- core/net/rpl/rpl.c | 4 ++-- core/net/rpl/rpl.h | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 58af7501c..7429b9681 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -56,6 +56,8 @@ #define DEBUG DEBUG_NONE #include "net/uip-debug.h" +#include "net/neighbor-info.h" + /************************************************************************/ extern rpl_of_t RPL_OF; static rpl_of_t * const objective_functions[] = {&RPL_OF}; @@ -92,6 +94,9 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF}; #else #define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS #endif /* !RPL_CONF_DIO_INTERVAL_DOUBLINGS */ + +#define INITIAL_ETX ETX_DIVISOR * 5 + /************************************************************************/ /* Allocate parents from the same static MEMB chunk to reduce memory waste. */ MEMB(parent_memb, struct rpl_parent, RPL_MAX_PARENTS); @@ -277,7 +282,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->local_confidence = 0; + p->etx = INITIAL_ETX; p->dtsn = 0; list_add(dag->parents, p); @@ -423,7 +428,7 @@ join_dag(uip_ipaddr_t *from, rpl_dio_t *dio) } PRINTF("succeeded\n"); - p->local_confidence = 0; /* The lowest confidence for new parents. */ + p->etx = INITIAL_ETX; /* The lowest confidence for new parents. */ /* Determine the objective function by using the objective code point of the DIO. */ diff --git a/core/net/rpl/rpl-of-etx.c b/core/net/rpl/rpl-of-etx.c index 7c416b9e1..d6404b35b 100644 --- a/core/net/rpl/rpl-of-etx.c +++ b/core/net/rpl/rpl-of-etx.c @@ -118,10 +118,10 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) rank_increase = INITIAL_LINK_METRIC * DEFAULT_MIN_HOPRANKINC; } else { dag = (rpl_dag_t *)p->dag; - if(p->local_confidence == 0) { - p->local_confidence = INITIAL_LINK_METRIC * ETX_DIVISOR; + if(p->etx == 0) { + p->etx = INITIAL_LINK_METRIC * ETX_DIVISOR; } - rank_increase = (p->local_confidence * dag->min_hoprankinc) / ETX_DIVISOR; + rank_increase = (p->etx * dag->min_hoprankinc) / ETX_DIVISOR; if(base_rank == 0) { base_rank = p->rank; } diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index 5cd6f7b6d..4b05793f3 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -150,11 +150,11 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx) return; } - if(etx != parent->local_confidence) { + if(etx != parent->etx) { /* Trigger DAG rank recalculation. */ parent->updated = 1; } - parent->local_confidence = etx; + parent->etx = etx; if(dag->of->parent_state_callback != NULL) { dag->of->parent_state_callback(parent, known, etx); diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 4c992bcb0..ed4277adc 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -207,7 +207,7 @@ struct rpl_parent { void *dag; uip_ipaddr_t addr; rpl_rank_t rank; - uint8_t local_confidence; + uint8_t etx; uint8_t dtsn; uint8_t updated; };