Merge pull request #290 from simonduq/rpl-mrhof-etx-nomc

Update of RPL MRHOF (use no metric container with ETX [RFC6719])
This commit is contained in:
Adam Dunkels 2013-07-29 00:56:25 -07:00
commit 54f2109134
10 changed files with 43 additions and 19 deletions

View file

@ -1,2 +1,2 @@
CONTIKI_SOURCEFILES += rpl.c rpl-dag.c rpl-icmp6.c rpl-timers.c \ 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

View file

@ -49,23 +49,25 @@
* Select routing metric supported at runtime. This must be a valid * Select routing metric supported at runtime. This must be a valid
* DAG Metric Container Object Type (see below). Currently, we only * DAG Metric Container Object Type (see below). Currently, we only
* support RPL_DAG_MC_ETX and RPL_DAG_MC_ENERGY. * 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 #ifdef RPL_CONF_DAG_MC
#define RPL_DAG_MC RPL_CONF_DAG_MC #define RPL_DAG_MC RPL_CONF_DAG_MC
#else #else
#define RPL_DAG_MC RPL_DAG_MC_ETX #define RPL_DAG_MC RPL_DAG_MC_NONE
#endif /* RPL_CONF_DAG_MC */ #endif /* RPL_CONF_DAG_MC */
/* /*
* The objective function used by RPL is configurable through the * 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_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 #ifdef RPL_CONF_OF
#define RPL_OF RPL_CONF_OF #define RPL_OF RPL_CONF_OF
#else #else
/* ETX is the default objective function. */ /* ETX is the default objective function. */
#define RPL_OF rpl_of_etx #define RPL_OF rpl_mrhof
#endif /* RPL_CONF_OF */ #endif /* RPL_CONF_OF */
/* This value decides which DAG instance we should participate in by default. */ /* This value decides which DAG instance we should participate in by default. */

View file

@ -518,7 +518,9 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
p->rank = dio->rank; p->rank = dio->rank;
p->dtsn = dio->dtsn; p->dtsn = dio->dtsn;
p->link_metric = RPL_INIT_LINK_METRIC; p->link_metric = RPL_INIT_LINK_METRIC;
#if RPL_DAG_MC != RPL_DAG_MC_NONE
memcpy(&p->mc, &dio->mc, sizeof(p->mc)); memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
list_add(dag->parents, p); list_add(dag->parents, p);
return p; return p;
} }
@ -1235,7 +1237,9 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
/* We have allocated a candidate parent; process the DIO further. */ /* 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)); memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
if(rpl_process_parent_event(instance, p) == 0) { if(rpl_process_parent_event(instance, p) == 0) {
PRINTF("RPL: The candidate parent is rejected\n"); PRINTF("RPL: The candidate parent is rejected\n");
return; return;

View file

@ -311,7 +311,9 @@ dio_input(void)
dio.mc.prec = buffer[i + 4] & 0xf; dio.mc.prec = buffer[i + 4] & 0xf;
dio.mc.length = buffer[i + 5]; 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); 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", PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n",

View file

@ -35,10 +35,11 @@
*/ */
/** /**
* \file * \file
* The minrank-hysteresis objective function (OCP 1). * The Minimum Rank with Hysteresis Objective Function (MRHOF)
* *
* This implementation uses the estimated number of * 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 <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se> * \author Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
*/ */
@ -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 rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
static void update_metric_container(rpl_instance_t *); static void update_metric_container(rpl_instance_t *);
rpl_of_t rpl_of_etx = { rpl_of_t rpl_mrhof = {
reset, reset,
parent_state_callback, parent_state_callback,
best_parent, best_parent,
@ -83,12 +84,18 @@ typedef uint16_t rpl_path_metric_t;
static rpl_path_metric_t static rpl_path_metric_t
calculate_path_metric(rpl_parent_t *p) 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; return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
} else { } else {
long etx = p->link_metric; long link_metric = p->link_metric;
etx = (etx * RPL_DAG_MC_ETX_DIVISOR) / NEIGHBOR_INFO_ETX_DIVISOR; link_metric = (link_metric * RPL_DAG_MC_ETX_DIVISOR) / NEIGHBOR_INFO_ETX_DIVISOR;
return p->mc.obj.etx + (uint16_t) etx; #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 static void
update_metric_container(rpl_instance_t *instance) 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_path_metric_t path_metric;
rpl_dag_t *dag; rpl_dag_t *dag;
#if RPL_DAG_MC == RPL_DAG_MC_ENERGY #if RPL_DAG_MC == RPL_DAG_MC_ENERGY
uint8_t type; uint8_t type;
#endif #endif
instance->mc.type = RPL_DAG_MC;
instance->mc.flags = RPL_DAG_MC_FLAG_P; instance->mc.flags = RPL_DAG_MC_FLAG_P;
instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE; instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
instance->mc.prec = 0; instance->mc.prec = 0;
@ -204,9 +216,12 @@ update_metric_container(rpl_instance_t *instance)
path_metric = calculate_path_metric(dag->preferred_parent); 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.length = sizeof(instance->mc.obj.etx);
instance->mc.obj.etx = path_metric; 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 #elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
instance->mc.type = RPL_DAG_MC_ENERGY;
instance->mc.length = sizeof(instance->mc.obj.energy); instance->mc.length = sizeof(instance->mc.obj.energy);
if(dag->rank == ROOT_RANK(instance)) { if(dag->rank == ROOT_RANK(instance)) {

View file

@ -110,7 +110,9 @@ struct rpl_dag;
struct rpl_parent { struct rpl_parent {
struct rpl_parent *next; struct rpl_parent *next;
struct rpl_dag *dag; struct rpl_dag *dag;
#if RPL_DAG_MC != RPL_DAG_MC_NONE
rpl_metric_container_t mc; rpl_metric_container_t mc;
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
uip_ipaddr_t addr; uip_ipaddr_t addr;
rpl_rank_t rank; rpl_rank_t rank;
uint8_t link_metric; uint8_t link_metric;

View file

@ -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 #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 #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 \ CONTIKI_TARGET_SOURCEFILES += cfs-eeprom.c eeprom.c random.c \
mmem.c contiki-raven-default-init-lowlevel.c \ mmem.c contiki-raven-default-init-lowlevel.c \

View file

@ -208,7 +208,7 @@
#define RPL_CONF_STATS 0 #define RPL_CONF_STATS 0
#define RPL_CONF_MAX_DAG_ENTRIES 1 #define RPL_CONF_MAX_DAG_ENTRIES 1
#ifndef RPL_CONF_OF #ifndef RPL_CONF_OF
#define RPL_CONF_OF rpl_of_etx #define RPL_CONF_OF rpl_mrhof
#endif #endif
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000

View file

@ -335,7 +335,7 @@ typedef uint32_t rtimer_clock_t;
#define RPL_CONF_STATS 0 #define RPL_CONF_STATS 0
#define RPL_CONF_MAX_DAG_ENTRIES 1 #define RPL_CONF_MAX_DAG_ENTRIES 1
#ifndef RPL_CONF_OF #ifndef RPL_CONF_OF
#define RPL_CONF_OF rpl_of_etx #define RPL_CONF_OF rpl_mrhof
#endif #endif
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000

View file

@ -214,7 +214,7 @@
#define RPL_CONF_STATS 0 #define RPL_CONF_STATS 0
#define RPL_CONF_MAX_DAG_ENTRIES 1 #define RPL_CONF_MAX_DAG_ENTRIES 1
#ifndef RPL_CONF_OF #ifndef RPL_CONF_OF
#define RPL_CONF_OF rpl_of_etx #define RPL_CONF_OF rpl_mrhof
#endif #endif
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000