From 43b5425493a23d9774c9a73468ec889107c23873 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Fri, 20 Sep 2013 15:44:18 +0200 Subject: [PATCH] Cleaned up various fragments and fixed a compilation error that occured when switching metric container. Fixed a wrapping problem in the ETX EWMA calculation. Corrected the multiplier of the link metric, and simplified the configuration so that the user does not need to specify the multiplier. --- core/net/rpl/rpl-conf.h | 2 +- core/net/rpl/rpl-dag.c | 2 +- core/net/rpl/rpl-mrhof.c | 78 ++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 197c5abbe..ad3cb1861 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -162,7 +162,7 @@ * Initial metric attributed to a link when the ETX is unknown */ #ifndef RPL_CONF_INIT_LINK_METRIC -#define RPL_INIT_LINK_METRIC 5 * RPL_MIN_HOPRANKINC +#define RPL_INIT_LINK_METRIC 5 #else #define RPL_INIT_LINK_METRIC RPL_CONF_INIT_LINK_METRIC #endif diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 5719c811f..4bc4c1790 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -548,7 +548,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) p->dag = dag; p->rank = dio->rank; p->dtsn = dio->dtsn; - p->link_metric = RPL_INIT_LINK_METRIC; + p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; #if RPL_DAG_MC != RPL_DAG_MC_NONE memcpy(&p->mc, &dio->mc, sizeof(p->mc)); #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c index 9fdc82f05..8154c5b62 100644 --- a/core/net/rpl/rpl-mrhof.c +++ b/core/net/rpl/rpl-mrhof.c @@ -90,46 +90,46 @@ calculate_path_metric(rpl_parent_t *p) { if(p == NULL) { return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; - } else { - long link_metric = p->link_metric; -#if RPL_DAG_MC == RPL_DAG_MC_NONE - return p->rank + (uint16_t)link_metric; -#elif RPL_DAG_MC == RPL_DAG_MC_ETX - return p->mc.obj.etx + (uint16_t)link_metric; -#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY - return p->mc.obj.energy.energy_test + (uint16_t)link_metric; -#endif /* RPL_DAG_MC */ } + +#if RPL_DAG_MC == RPL_DAG_MC_NONE + return p->rank + (uint16_t)p->link_metric; +#elif RPL_DAG_MC == RPL_DAG_MC_ETX + return p->mc.obj.etx + (uint16_t)p->link_metric; +#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY + return p->mc.obj.energy.energy_est + (uint16_t)p->link_metric; +#else +#error "Unsupported RPL_DAG_MC configured. See rpl.h." +#endif /* RPL_DAG_MC */ } static void reset(rpl_dag_t *sag) { + PRINTF("RPL: Reset MRHOF\n"); } static void neighbor_link_callback(rpl_parent_t *p, int status, int numtx) { + uint16_t recorded_etx = p->link_metric; + uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR; + uint16_t new_etx; + /* Do not penalize the ETX when collisions or transmission errors occur. */ if(status == MAC_TX_OK || status == MAC_TX_NOACK) { - int recorded_etx = p->link_metric; - int packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR; - int new_etx; - if(status == MAC_TX_NOACK) { packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; } - new_etx = ((uint16_t)recorded_etx * ETX_ALPHA + - (uint16_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE; + new_etx = ((uint32_t)recorded_etx * ETX_ALPHA + + (uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE; - PRINTF("RPL: ETX changed from %d to %d (packet ETX = %d) %d\n", - recorded_etx / p->dag->instance->min_hoprankinc, - new_etx / p->dag->instance->min_hoprankinc, - packet_etx / p->dag->instance->min_hoprankinc, - dest->u8[7]); + PRINTF("RPL: ETX changed from %u to %u (packet ETX = %u)\n", + (unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR), + (unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR), + (unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR)); p->link_metric = new_etx; - } } @@ -143,9 +143,8 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank) if(base_rank == 0) { return INFINITE_RANK; } - rank_increase = RPL_INIT_LINK_METRIC; + rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; } else { - /* multiply first, then scale down to avoid truncation effects */ rank_increase = p->link_metric; if(base_rank == 0) { base_rank = p->rank; @@ -186,7 +185,7 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2) rpl_path_metric_t p1_metric; rpl_path_metric_t p2_metric; - dag = p1->dag; /* Both parents must be in the same DAG. */ + dag = p1->dag; /* Both parents are in the same DAG. */ min_diff = RPL_DAG_MC_ETX_DIVISOR / PARENT_SWITCH_THRESHOLD_DIV; @@ -209,13 +208,16 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2) return p1_metric < p2_metric ? p1 : p2; } +#if RPL_DAG_MC == RPL_DAG_MC_NONE static void update_metric_container(rpl_instance_t *instance) { instance->mc.type = RPL_DAG_MC; - -#if RPL_DAG_MC != RPL_DAG_MC_NONE - +} +#else +static void +update_metric_container(rpl_instance_t *instance) +{ rpl_path_metric_t path_metric; rpl_dag_t *dag; #if RPL_DAG_MC == RPL_DAG_MC_ENERGY @@ -230,7 +232,7 @@ update_metric_container(rpl_instance_t *instance) dag = instance->current_dag; if (!dag->joined) { - /* We should probably do something here */ + PRINTF("RPL: Cannot update the metric container when not joined\n"); return; } @@ -240,21 +242,15 @@ update_metric_container(rpl_instance_t *instance) path_metric = calculate_path_metric(dag->preferred_parent); } -#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ - -#if RPL_DAG_MC == RPL_DAG_MC_NONE - /* Do nothing more */ -#elif RPL_DAG_MC == RPL_DAG_MC_ETX - +#if RPL_DAG_MC == RPL_DAG_MC_ETX instance->mc.length = sizeof(instance->mc.obj.etx); instance->mc.obj.etx = path_metric; PRINTF("RPL: My path ETX to the root is %u.%u\n", instance->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR, - (instance->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR); - + (instance->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / + RPL_DAG_MC_ETX_DIVISOR); #elif RPL_DAG_MC == RPL_DAG_MC_ENERGY - instance->mc.length = sizeof(instance->mc.obj.energy); if(dag->rank == ROOT_RANK(instance)) { @@ -265,10 +261,6 @@ update_metric_container(rpl_instance_t *instance) instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE; instance->mc.obj.energy.energy_est = path_metric; - -#else - -#error "Unsupported RPL_DAG_MC configured. See rpl.h." - -#endif /* RPL_DAG_MC */ +#endif /* RPL_DAG_MC == RPL_DAG_MC_ETX */ } +#endif /* RPL_DAG_MC == RPL_DAG_MC_NONE */