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:
commit
54f2109134
|
@ -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
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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)) {
|
|
@ -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;
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue