Generalized MRHOF and added partial support for energy objects in DAG metric containers.
This commit is contained in:
parent
d9b5bac953
commit
4739143126
@ -250,9 +250,10 @@ dio_input(void)
|
||||
dio.mc.aggr = buffer[i + 4] >> 4;
|
||||
dio.mc.prec = buffer[i + 4] & 0xf;
|
||||
dio.mc.length = buffer[i + 5];
|
||||
|
||||
if(dio.mc.type == RPL_DAG_MC_ETX) {
|
||||
dio.mc.etx.etx = buffer[i + 6] << 8;
|
||||
dio.mc.etx.etx |= buffer[i + 7];
|
||||
dio.mc.obj.etx = buffer[i + 6] << 8;
|
||||
dio.mc.obj.etx |= buffer[i + 7];
|
||||
|
||||
PRINTF("RPL: DAG MC: type %u, flags %u, aggr %u, prec %u, length %u, ETX %u\n",
|
||||
(unsigned)dio.mc.type,
|
||||
@ -260,7 +261,10 @@ dio_input(void)
|
||||
(unsigned)dio.mc.aggr,
|
||||
(unsigned)dio.mc.prec,
|
||||
(unsigned)dio.mc.length,
|
||||
(unsigned)dio.mc.etx.etx);
|
||||
(unsigned)dio.mc.obj.etx);
|
||||
} else if(dio.mc.type == RPL_DAG_MC_ENERGY) {
|
||||
dio.mc.obj.energy.flags = buffer[i + 6];
|
||||
dio.mc.obj.energy.energy_est = buffer[i + 7];
|
||||
} else {
|
||||
PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type);
|
||||
return;
|
||||
@ -380,8 +384,12 @@ dio_output(rpl_dag_t *dag, uip_ipaddr_t *uc_addr)
|
||||
buffer[pos++] |= dag->mc.prec;
|
||||
if(dag->mc.type == RPL_DAG_MC_ETX) {
|
||||
buffer[pos++] = 2;
|
||||
buffer[pos++] = dag->mc.etx.etx >> 8;
|
||||
buffer[pos++] = dag->mc.etx.etx & 0xff;
|
||||
buffer[pos++] = dag->mc.obj.etx >> 8;
|
||||
buffer[pos++] = dag->mc.obj.etx & 0xff;
|
||||
} else if(dag->mc.type == RPL_DAG_MC_ENERGY) {
|
||||
buffer[pos++] = 2;
|
||||
buffer[pos++] = dag->mc.obj.energy.flags;
|
||||
buffer[pos++] = dag->mc.obj.energy.energy_est;
|
||||
} else {
|
||||
PRINTF("RPL: Unable to send DIO because of unhandled DAG MC type %u\n",
|
||||
(unsigned)dag->mc.type);
|
||||
|
@ -66,7 +66,7 @@ rpl_of_t rpl_of_etx = {
|
||||
|
||||
#define NI_ETX_TO_RPL_ETX(etx) \
|
||||
((etx) * (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
|
||||
#define RPL_ETX_TO_NI_ETX(etx) \
|
||||
#define rpl_path_metric_tO_NI_ETX(etx) \
|
||||
((etx) / (RPL_DAG_MC_ETX_DIVISOR / NEIGHBOR_INFO_ETX_DIVISOR))
|
||||
|
||||
/* Reject parents that have a higher link metric than the following. */
|
||||
@ -84,13 +84,12 @@ rpl_of_t rpl_of_etx = {
|
||||
*/
|
||||
#define PARENT_SWITCH_THRESHOLD_DIV 2
|
||||
|
||||
typedef uint16_t rpl_etx_t;
|
||||
#define MAX_ETX 65535
|
||||
typedef uint16_t rpl_path_metric_t;
|
||||
|
||||
static uint16_t
|
||||
calculate_etx(rpl_parent_t *p)
|
||||
calculate_path_metric(rpl_parent_t *p)
|
||||
{
|
||||
return p->mc.etx.etx + NI_ETX_TO_RPL_ETX(p->etx);
|
||||
return p->mc.obj.etx + NI_ETX_TO_RPL_ETX(p->etx);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -140,48 +139,64 @@ static rpl_parent_t *
|
||||
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||
{
|
||||
rpl_dag_t *dag;
|
||||
rpl_etx_t min_diff;
|
||||
rpl_etx_t p1_etx;
|
||||
rpl_etx_t p2_etx;
|
||||
rpl_path_metric_t min_diff;
|
||||
rpl_path_metric_t p1_metric;
|
||||
rpl_path_metric_t p2_metric;
|
||||
|
||||
dag = p1->dag; /* Both parents must be in the same DAG. */
|
||||
|
||||
min_diff = RPL_DAG_MC_ETX_DIVISOR /
|
||||
PARENT_SWITCH_THRESHOLD_DIV;
|
||||
|
||||
p1_etx = calculate_etx(p1);
|
||||
p2_etx = calculate_etx(p2);
|
||||
p1_metric = calculate_path_metric(p1);
|
||||
p2_metric = calculate_path_metric(p2);
|
||||
|
||||
/* Maintain stability of the preferred parent in case of similar ranks. */
|
||||
if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
|
||||
if(p1_etx < p2_etx + min_diff &&
|
||||
p1_etx > p2_etx - min_diff) {
|
||||
if(p1_metric < p2_metric + min_diff &&
|
||||
p1_metric > p2_metric - min_diff) {
|
||||
PRINTF("RPL: MRHOF hysteresis: %u <= %u <= %u\n",
|
||||
p2_etx - min_diff,
|
||||
p1_etx,
|
||||
p2_etx + min_diff);
|
||||
p2_metric - min_diff,
|
||||
p1_metric,
|
||||
p2_metric + min_diff);
|
||||
return dag->preferred_parent;
|
||||
}
|
||||
}
|
||||
|
||||
return p1_etx < p2_etx ? p1 : p2;
|
||||
return p1_metric < p2_metric ? p1 : p2;
|
||||
}
|
||||
|
||||
static void
|
||||
update_metric_container(rpl_dag_t *dag)
|
||||
{
|
||||
#if RPL_DAG_MC == RPL_DAG_MC_ETX
|
||||
dag->mc.type = RPL_DAG_MC_ETX;
|
||||
dag->mc.flags = RPL_DAG_MC_FLAG_P;
|
||||
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
|
||||
dag->mc.prec = 0;
|
||||
dag->mc.length = sizeof(dag->mc.etx.etx);
|
||||
dag->mc.length = sizeof(dag->mc.obj.etx);
|
||||
if(dag->rank == ROOT_RANK(dag)) {
|
||||
dag->mc.etx.etx = 0;
|
||||
dag->mc.obj.etx = 0;
|
||||
} else {
|
||||
dag->mc.etx.etx = calculate_etx(dag->preferred_parent);
|
||||
dag->mc.obj.etx = calculate_path_metric(dag->preferred_parent);
|
||||
}
|
||||
#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
|
||||
dag->mc.type = RPL_DAG_MC_ENERGY;
|
||||
dag->mc.flags = RPL_DAG_MC_FLAG_P;
|
||||
dag->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
|
||||
dag->mc.prec = 0;
|
||||
dag->mc.length = sizeof(dag->mc.obj.energy);
|
||||
if(dag->rank == ROOT_RANK(dag)) {
|
||||
dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_MAINS << RPL_DAG_MC_ENERGY_TYPE;
|
||||
} else {
|
||||
dag->mc.obj.energy.flags = RPL_DAG_MC_ENERGY_TYPE_BATTERY << RPL_DAG_MC_ENERGY_TYPE;
|
||||
}
|
||||
dag->mc.obj.energy.energy_est = calculate_path_metric(dag->preferred_parent);
|
||||
#else
|
||||
#error "Unsupported RPL_DAG_MC configured. See rpl.h."
|
||||
#endif /* RPL_DAG_MC */
|
||||
|
||||
PRINTF("RPL: My path ETX to the root is %u.%u\n",
|
||||
dag->mc.etx.etx / RPL_DAG_MC_ETX_DIVISOR,
|
||||
(dag->mc.etx.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR);
|
||||
dag->mc.obj.etx / RPL_DAG_MC_ETX_DIVISOR,
|
||||
(dag->mc.obj.etx % RPL_DAG_MC_ETX_DIVISOR * 100) / RPL_DAG_MC_ETX_DIVISOR);
|
||||
}
|
||||
|
@ -49,6 +49,17 @@
|
||||
#define RPL_CONF_STATS 0
|
||||
#endif /* RPL_CONF_STATS */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifdef RPL_CONF_DAG_MC
|
||||
#define RPL_DAG_MC RPL_CONF_DAG_MC
|
||||
#else
|
||||
#define RPL_DAG_MC RPL_DAG_MC_ETX
|
||||
#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
|
||||
@ -78,8 +89,8 @@ typedef uint16_t rpl_ocp_t;
|
||||
/* DAG Metric Container Object Types, to be confirmed by IANA. */
|
||||
#define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */
|
||||
#define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
|
||||
#define RPL_DAG_MC_NE 2 /* Node Energy */
|
||||
#define RPL_DAG_MC_HC 3 /* Hop Count */
|
||||
#define RPL_DAG_MC_ENERGY 2 /* Node Energy */
|
||||
#define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */
|
||||
#define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
|
||||
#define RPL_DAG_MC_LATENCY 5 /* Latency */
|
||||
#define RPL_DAG_MC_LQL 6 /* Link Quality Level */
|
||||
@ -99,9 +110,19 @@ typedef uint16_t rpl_ocp_t;
|
||||
#define RPL_DAG_MC_AGGR_MINIMUM 2
|
||||
#define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
|
||||
|
||||
/* Logical representation of an ETX object in a DAG Metric Container. */
|
||||
struct rpl_metric_object_etx {
|
||||
uint16_t etx;
|
||||
/* The bit index within the flags field of
|
||||
the rpl_metric_object_energy structure. */
|
||||
#define RPL_DAG_MC_ENERGY_INCLUDED 3
|
||||
#define RPL_DAG_MC_ENERGY_TYPE 1
|
||||
#define RPL_DAG_MC_ENERGY_ESTIMATION 0
|
||||
|
||||
#define RPL_DAG_MC_ENERGY_TYPE_MAINS 0
|
||||
#define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1
|
||||
#define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2
|
||||
|
||||
struct rpl_metric_object_energy {
|
||||
uint8_t flags;
|
||||
uint8_t energy_est;
|
||||
};
|
||||
|
||||
/* Logical representation of a DAG Metric Container. */
|
||||
@ -111,9 +132,10 @@ struct rpl_metric_container {
|
||||
uint8_t aggr;
|
||||
uint8_t prec;
|
||||
uint8_t length;
|
||||
/* Once we support more objects, the etx field will be replaced by a
|
||||
union of those. */
|
||||
struct rpl_metric_object_etx etx;
|
||||
union metric_object {
|
||||
struct rpl_metric_object_energy energy;
|
||||
uint16_t etx;
|
||||
} obj;
|
||||
};
|
||||
typedef struct rpl_metric_container rpl_metric_container_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
Loading…
Reference in New Issue
Block a user