48 #include "net/routing/rpl-lite/rpl.h" 49 #include "net/nbr-table.h" 50 #include "net/link-stats.h" 54 #define LOG_MODULE "RPL" 55 #define LOG_LEVEL LOG_LEVEL_RPL 72 #ifdef RPL_MRHOF_CONF_SQUARED_ETX 73 #define RPL_MRHOF_SQUARED_ETX RPL_MRHOF_CONF_SQUARED_ETX 75 #define RPL_MRHOF_SQUARED_ETX 0 80 #ifdef RPL_MRHOF_CONF_MAX_LINK_METRIC 81 #define MAX_LINK_METRIC RPL_MRHOF_CONF_MAX_LINK_METRIC 83 #define MAX_LINK_METRIC 512 87 #ifdef RPL_MRHOF_CONF_MAX_PATH_COST 88 #define MAX_PATH_COST RPL_MRHOF_CONF_MAX_PATH_COST 90 #define MAX_PATH_COST 32768 93 #if !RPL_MRHOF_SQUARED_ETX 96 #define RANK_THRESHOLD 192 98 #define RANK_THRESHOLD 384 104 #define TIME_THRESHOLD (10 * 60 * CLOCK_SECOND) 110 LOG_INFO(
"reset MRHOF\n");
117 return stats != NULL ? stats->etx : 0xffff;
121 link_metric_to_rank(uint16_t etx)
123 #if RPL_MRHOF_SQUARED_ETX 124 uint32_t squared_etx = ((uint32_t)etx * etx) / LINK_STATS_ETX_DIVISOR;
125 return (uint16_t)MIN(squared_etx, 0xffff);
142 switch(curr_instance.mc.type) {
144 base = nbr->mc.obj.etx;
146 case RPL_DAG_MC_ENERGY:
147 base = nbr->mc.obj.energy.energy_est << 8;
158 return MIN((uint32_t)base + link_metric_to_rank(nbr_link_metric(nbr)), 0xffff);
164 uint16_t min_hoprankinc;
168 return RPL_INFINITE_RANK;
171 min_hoprankinc = curr_instance.min_hoprankinc;
172 path_cost = nbr_path_cost(nbr);
175 return MAX(MIN((uint32_t)nbr->rank + min_hoprankinc, RPL_INFINITE_RANK), path_cost);
181 uint16_t link_metric = nbr_link_metric(nbr);
183 return link_metric <= MAX_LINK_METRIC;
189 uint16_t path_cost = nbr_path_cost(nbr);
191 return nbr_has_usable_link(nbr) && path_cost <= MAX_PATH_COST;
197 uint16_t path_cost = nbr_path_cost(nbr);
198 uint16_t parent_path_cost = nbr_path_cost(curr_instance.dag.preferred_parent);
200 int within_rank_hysteresis = path_cost + RANK_THRESHOLD > parent_path_cost;
201 int within_time_hysteresis = nbr->better_parent_since == 0
202 || (
clock_time() - nbr->better_parent_since) <= TIME_THRESHOLD;
206 return within_rank_hysteresis && within_time_hysteresis;
212 int nbr1_is_acceptable;
213 int nbr2_is_acceptable;
215 nbr1_is_acceptable = nbr1 != NULL && nbr_is_acceptable_parent(nbr1);
216 nbr2_is_acceptable = nbr2 != NULL && nbr_is_acceptable_parent(nbr2);
218 if(!nbr1_is_acceptable) {
219 return nbr2_is_acceptable ? nbr2 : NULL;
221 if(!nbr2_is_acceptable) {
222 return nbr1_is_acceptable ? nbr1 : NULL;
228 if(nbr1 == curr_instance.dag.preferred_parent && within_hysteresis(nbr2)) {
231 if(nbr2 == curr_instance.dag.preferred_parent && within_hysteresis(nbr1)) {
235 return nbr_path_cost(nbr1) < nbr_path_cost(nbr2) ? nbr1 : nbr2;
240 update_metric_container(
void)
242 curr_instance.mc.type = RPL_DAG_MC_NONE;
246 update_metric_container(
void)
251 if(!curr_instance.used) {
252 LOG_WARN(
"cannot update the metric container when not joined\n");
256 if(curr_instance.dag.rank ==
ROOT_RANK) {
258 curr_instance.mc.type = RPL_DAG_MC;
259 curr_instance.mc.flags = 0;
260 curr_instance.mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
261 curr_instance.mc.prec = 0;
262 path_cost = curr_instance.dag.rank;
264 path_cost = nbr_path_cost(curr_instance.dag.preferred_parent);
268 switch(curr_instance.mc.type) {
269 case RPL_DAG_MC_NONE:
272 curr_instance.mc.length =
sizeof(curr_instance.mc.obj.etx);
273 curr_instance.mc.obj.etx = path_cost;
275 case RPL_DAG_MC_ENERGY:
276 curr_instance.mc.length =
sizeof(curr_instance.mc.obj.energy);
277 if(curr_instance.dag.rank ==
ROOT_RANK) {
278 type = RPL_DAG_MC_ENERGY_TYPE_MAINS;
280 type = RPL_DAG_MC_ENERGY_TYPE_BATTERY;
282 curr_instance.mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE;
284 curr_instance.mc.obj.energy.energy_est = path_cost >> 8;
287 LOG_WARN(
"MRHOF, non-supported MC %u\n", curr_instance.mc.type);
297 nbr_is_acceptable_parent,
301 update_metric_container,
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
#define ROOT_RANK
Rank of a root node.
API for RPL objective functions (OF)
const struct link_stats * rpl_neighbor_get_link_stats(rpl_nbr_t *nbr)
Returns a neighbor's link statistics.
All information related to a RPL neighbor.
clock_time_t clock_time(void)
Get the current clock time.
Header file for the logging system