From defcc639cef1c27c8bf6a37499c2cda2e7661372 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 1 Jul 2013 18:00:21 +0200 Subject: [PATCH] Use no metric container when having MRHOF with ETX, as specified in RFC6719. Renamed rpl-of-etx to rpl-mrhof. --- core/net/rpl/Makefile.rpl | 2 +- core/net/rpl/rpl-conf.h | 8 +++-- core/net/rpl/rpl-dag.c | 4 +++ core/net/rpl/rpl-icmp6.c | 4 ++- core/net/rpl/{rpl-of-etx.c => rpl-mrhof.c} | 34 +++++++++++++++------ core/net/rpl/rpl.h | 2 ++ platform/avr-ravenusb/Makefile.avr-ravenusb | 2 +- platform/cc2530dk/contiki-conf.h | 2 +- platform/cc2538dk/contiki-conf.h | 2 +- platform/sensinode/contiki-conf.h | 2 +- 10 files changed, 43 insertions(+), 19 deletions(-) rename core/net/rpl/{rpl-of-etx.c => rpl-mrhof.c} (87%) diff --git a/core/net/rpl/Makefile.rpl b/core/net/rpl/Makefile.rpl index 88d5c4775..f5852e13b 100644 --- a/core/net/rpl/Makefile.rpl +++ b/core/net/rpl/Makefile.rpl @@ -1,2 +1,2 @@ CONTIKI_SOURCEFILES += rpl.c rpl-dag.c rpl-icmp6.c rpl-timers.c \ - rpl-of-etx.c rpl-ext-header.c + rpl-mrhof.c rpl-ext-header.c diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index 7d3662474..2810bd6d3 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -49,23 +49,25 @@ * Select routing metric supported at runtime. This must be a valid * DAG Metric Container Object Type (see below). Currently, we only * support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY. + * When MRHOF (RFC6719) is used with ETX, no metric container must + * be used; instead the rank carries ETX directly. */ #ifdef RPL_CONF_DAG_MC #define RPL_DAG_MC RPL_CONF_DAG_MC #else -#define RPL_DAG_MC RPL_DAG_MC_ETX +#define RPL_DAG_MC RPL_DAG_MC_NONE #endif /* RPL_CONF_DAG_MC */ /* * The objective function used by RPL is configurable through the * RPL_CONF_OF parameter. This should be defined to be the name of an - * rpl_of_t object linked into the system image, e.g., rpl_of0. + * rpl_of object linked into the system image, e.g., rpl_of0. */ #ifdef RPL_CONF_OF #define RPL_OF RPL_CONF_OF #else /* ETX is the default objective function. */ -#define RPL_OF rpl_of_etx +#define RPL_OF rpl_mrhof #endif /* RPL_CONF_OF */ /* This value decides which DAG instance we should participate in by default. */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index baad9946b..bada01437 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -518,7 +518,9 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) p->rank = dio->rank; p->dtsn = dio->dtsn; p->link_metric = RPL_INIT_LINK_METRIC; +#if RPL_DAG_MC != RPL_DAG_MC_NONE memcpy(&p->mc, &dio->mc, sizeof(p->mc)); +#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ list_add(dag->parents, p); return p; } @@ -1238,7 +1240,9 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) /* We have allocated a candidate parent; process the DIO further. */ +#if RPL_DAG_MC != RPL_DAG_MC_NONE memcpy(&p->mc, &dio->mc, sizeof(p->mc)); +#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ if(rpl_process_parent_event(instance, p) == 0) { PRINTF("RPL: The candidate parent is rejected\n"); return; diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 11c414222..73408211b 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -311,7 +311,9 @@ dio_input(void) dio.mc.prec = buffer[i + 4] & 0xf; dio.mc.length = buffer[i + 5]; - if(dio.mc.type == RPL_DAG_MC_ETX) { + if(dio.mc.type == RPL_DAG_MC_NONE) { + /* No metric container: do nothing */ + } else if(dio.mc.type == RPL_DAG_MC_ETX) { dio.mc.obj.etx = get16(buffer, i + 6); PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n", diff --git a/core/net/rpl/rpl-of-etx.c b/core/net/rpl/rpl-mrhof.c similarity index 87% rename from core/net/rpl/rpl-of-etx.c rename to core/net/rpl/rpl-mrhof.c index abbc229b7..567977c70 100644 --- a/core/net/rpl/rpl-of-etx.c +++ b/core/net/rpl/rpl-mrhof.c @@ -35,10 +35,11 @@ */ /** * \file - * The minrank-hysteresis objective function (OCP 1). + * The Minimum Rank with Hysteresis Objective Function (MRHOF) * * This implementation uses the estimated number of - * transmissions (ETX) as the additive routing metric. + * transmissions (ETX) as the additive routing metric, + * and also provides stubs for the energy metric. * * \author Joakim Eriksson , Nicolas Tsiftes */ @@ -56,7 +57,7 @@ static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); static void update_metric_container(rpl_instance_t *); -rpl_of_t rpl_of_etx = { +rpl_of_t rpl_mrhof = { reset, parent_state_callback, best_parent, @@ -83,12 +84,18 @@ typedef uint16_t rpl_path_metric_t; static rpl_path_metric_t calculate_path_metric(rpl_parent_t *p) { - if(p == NULL || (p->mc.obj.etx == 0 && p->rank > ROOT_RANK(p->dag->instance))) { + if(p == NULL) { return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; } else { - long etx = p->link_metric; - etx = (etx * RPL_DAG_MC_ETX_DIVISOR) / NEIGHBOR_INFO_ETX_DIVISOR; - return p->mc.obj.etx + (uint16_t) etx; + long link_metric = p->link_metric; + link_metric = (link_metric * RPL_DAG_MC_ETX_DIVISOR) / NEIGHBOR_INFO_ETX_DIVISOR; +#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 */ } } @@ -181,12 +188,17 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2) static void update_metric_container(rpl_instance_t *instance) { + instance->mc.type = RPL_DAG_MC; + +#if RPL_DAG_MC != RPL_DAG_MC_NONE + rpl_path_metric_t path_metric; rpl_dag_t *dag; #if RPL_DAG_MC == RPL_DAG_MC_ENERGY uint8_t type; #endif + instance->mc.type = RPL_DAG_MC; instance->mc.flags = RPL_DAG_MC_FLAG_P; instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE; instance->mc.prec = 0; @@ -204,9 +216,12 @@ update_metric_container(rpl_instance_t *instance) path_metric = calculate_path_metric(dag->preferred_parent); } -#if RPL_DAG_MC == RPL_DAG_MC_ETX +#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 - instance->mc.type = RPL_DAG_MC_ETX; instance->mc.length = sizeof(instance->mc.obj.etx); instance->mc.obj.etx = path_metric; @@ -216,7 +231,6 @@ update_metric_container(rpl_instance_t *instance) #elif RPL_DAG_MC == RPL_DAG_MC_ENERGY - instance->mc.type = RPL_DAG_MC_ENERGY; instance->mc.length = sizeof(instance->mc.obj.energy); if(dag->rank == ROOT_RANK(instance)) { diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index d1f66bf83..8e770ddd8 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -110,7 +110,9 @@ struct rpl_dag; struct rpl_parent { struct rpl_parent *next; struct rpl_dag *dag; +#if RPL_DAG_MC != RPL_DAG_MC_NONE rpl_metric_container_t mc; +#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ uip_ipaddr_t addr; rpl_rank_t rank; uint8_t link_metric; diff --git a/platform/avr-ravenusb/Makefile.avr-ravenusb b/platform/avr-ravenusb/Makefile.avr-ravenusb index 1641baded..23e3b6f6b 100644 --- a/platform/avr-ravenusb/Makefile.avr-ravenusb +++ b/platform/avr-ravenusb/Makefile.avr-ravenusb @@ -22,7 +22,7 @@ USB += scsi_decoder.c ctrl_access.c storage_task.c avr_flash.c #As of September 2010 the following are needed for rpl. They need explicit inclusion if CONTIKI_NO_NET=1 #If CONTIKI_NO_NET=1 the tcpip_input routine in tcpip.c must be commented out; it expects a tcpip process and conflicts with the one in fakeuip.c -#RPL = rpl.c rpl-dag.c rpl-icmp6.c rpl-timers.c rpl-of-etx.c uip-ds6.c uip-icmp6.c uip-nd6.c uip6.c neighbor-info.c neighbor-attr.c tcpip.c uip-split.c psock.c +#RPL = rpl.c rpl-dag.c rpl-icmp6.c rpl-timers.c rpl-mrhof.c uip-ds6.c uip-icmp6.c uip-nd6.c uip6.c neighbor-info.c neighbor-attr.c tcpip.c uip-split.c psock.c CONTIKI_TARGET_SOURCEFILES += cfs-eeprom.c eeprom.c random.c \ mmem.c contiki-raven-default-init-lowlevel.c \ diff --git a/platform/cc2530dk/contiki-conf.h b/platform/cc2530dk/contiki-conf.h index 4b51a0928..ae7a9641a 100644 --- a/platform/cc2530dk/contiki-conf.h +++ b/platform/cc2530dk/contiki-conf.h @@ -208,7 +208,7 @@ #define RPL_CONF_STATS 0 #define RPL_CONF_MAX_DAG_ENTRIES 1 #ifndef RPL_CONF_OF -#define RPL_CONF_OF rpl_of_etx +#define RPL_CONF_OF rpl_mrhof #endif #define UIP_CONF_ND6_REACHABLE_TIME 600000 diff --git a/platform/cc2538dk/contiki-conf.h b/platform/cc2538dk/contiki-conf.h index b38fccec6..d7ca928cd 100644 --- a/platform/cc2538dk/contiki-conf.h +++ b/platform/cc2538dk/contiki-conf.h @@ -335,7 +335,7 @@ typedef uint32_t rtimer_clock_t; #define RPL_CONF_STATS 0 #define RPL_CONF_MAX_DAG_ENTRIES 1 #ifndef RPL_CONF_OF -#define RPL_CONF_OF rpl_of_etx +#define RPL_CONF_OF rpl_mrhof #endif #define UIP_CONF_ND6_REACHABLE_TIME 600000 diff --git a/platform/sensinode/contiki-conf.h b/platform/sensinode/contiki-conf.h index 335efb0f4..21ae8f655 100644 --- a/platform/sensinode/contiki-conf.h +++ b/platform/sensinode/contiki-conf.h @@ -214,7 +214,7 @@ #define RPL_CONF_STATS 0 #define RPL_CONF_MAX_DAG_ENTRIES 1 #ifndef RPL_CONF_OF -#define RPL_CONF_OF rpl_of_etx +#define RPL_CONF_OF rpl_mrhof #endif #define UIP_CONF_ND6_REACHABLE_TIME 600000