From 33cfd9247500c19265c4faa9344098e057f79bb8 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 29 Apr 2014 16:25:16 +0200 Subject: [PATCH] RPL MRHOF with ETX: bypass weighted moving average when setting a parent's link metric for the first time --- core/net/rpl/rpl-dag.c | 4 ++-- core/net/rpl/rpl-icmp6.c | 4 ++-- core/net/rpl/rpl-mrhof.c | 12 ++++++++++-- core/net/rpl/rpl.c | 4 ++-- core/net/rpl/rpl.h | 5 ++++- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 08178d5ad..d79a7f465 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1082,8 +1082,8 @@ rpl_recalculate_ranks(void) */ p = nbr_table_head(rpl_parents); while(p != NULL) { - if(p->dag != NULL && p->dag->instance && p->updated) { - p->updated = 0; + if(p->dag != NULL && p->dag->instance && (p->flags & RPL_PARENT_FLAG_UPDATED)) { + p->flags &= ~RPL_PARENT_FLAG_UPDATED; PRINTF("RPL: rpl_process_parent_event recalculate_ranks\n"); if(!rpl_process_parent_event(p->dag->instance, p)) { PRINTF("RPL: A parent was dropped\n"); diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index b744f4dc8..34ad696d5 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -652,7 +652,7 @@ dao_input(void) PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n", DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance)); parent->rank = INFINITE_RANK; - parent->updated = 1; + parent->flags |= RPL_PARENT_FLAG_UPDATED; return; } @@ -660,7 +660,7 @@ dao_input(void) if(parent != NULL && parent == dag->preferred_parent) { PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n"); parent->rank = INFINITE_RANK; - parent->updated = 1; + parent->flags |= RPL_PARENT_FLAG_UPDATED; return; } } diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c index 634bec763..508d66f1d 100644 --- a/core/net/rpl/rpl-mrhof.c +++ b/core/net/rpl/rpl-mrhof.c @@ -122,8 +122,16 @@ neighbor_link_callback(rpl_parent_t *p, int status, int numtx) packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; } - new_etx = ((uint32_t)recorded_etx * ETX_ALPHA + - (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE; + if(p->flags & RPL_PARENT_FLAG_LINK_METRIC_VALID) { + /* We already have a valid link metric, use weighted moving average to update it */ + new_etx = ((uint32_t)recorded_etx * ETX_ALPHA + + (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE; + } else { + /* We don't have a valid link metric, set it to the current packet's ETX */ + new_etx = packet_etx; + /* Set link metric as valid */ + p->flags |= RPL_PARENT_FLAG_LINK_METRIC_VALID; + } PRINTF("RPL: ETX changed from %u to %u (packet ETX = %u)\n", (unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR), diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index fd532c4c6..860131a10 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -260,7 +260,7 @@ rpl_link_neighbor_callback(const linkaddr_t *addr, int status, int numtx) if(parent != NULL) { /* Trigger DAG rank recalculation. */ PRINTF("RPL: rpl_link_neighbor_callback triggering update\n"); - parent->updated = 1; + parent->flags |= RPL_PARENT_FLAG_UPDATED; if(instance->of->neighbor_link_callback != NULL) { instance->of->neighbor_link_callback(parent, status, numtx); } @@ -286,7 +286,7 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) p->rank = INFINITE_RANK; /* Trigger DAG rank recalculation. */ PRINTF("RPL: rpl_ipv6_neighbor_callback infinite rank\n"); - p->updated = 1; + p->flags |= RPL_PARENT_FLAG_UPDATED; } } } diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 76134e44e..c5e89c61b 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -104,6 +104,9 @@ typedef struct rpl_metric_container rpl_metric_container_t; struct rpl_instance; struct rpl_dag; /*---------------------------------------------------------------------------*/ +#define RPL_PARENT_FLAG_UPDATED 0x1 +#define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2 + struct rpl_parent { struct rpl_parent *next; struct rpl_dag *dag; @@ -113,7 +116,7 @@ struct rpl_parent { rpl_rank_t rank; uint16_t link_metric; uint8_t dtsn; - uint8_t updated; + uint8_t flags; }; typedef struct rpl_parent rpl_parent_t; /*---------------------------------------------------------------------------*/