49 #include "net/routing/rpl-classic/rpl.h" 50 #include "net/routing/rpl-classic/rpl-private.h" 51 #include "net/nbr-table.h" 52 #include "net/link-stats.h" 56 #define LOG_MODULE "RPL" 57 #define LOG_LEVEL LOG_LEVEL_RPL 74 #ifdef RPL_MRHOF_CONF_SQUARED_ETX 75 #define RPL_MRHOF_SQUARED_ETX RPL_MRHOF_CONF_SQUARED_ETX 77 #define RPL_MRHOF_SQUARED_ETX 0 80 #if !RPL_MRHOF_SQUARED_ETX 83 #define MAX_LINK_METRIC 1024 88 #define PARENT_SWITCH_THRESHOLD 96 90 #define MAX_LINK_METRIC 2048 91 #define PARENT_SWITCH_THRESHOLD 160 96 #define MAX_PATH_COST 32768 102 LOG_INFO(
"Reset MRHOF\n");
107 dao_ack_callback(rpl_parent_t *p,
int status)
109 if(status == RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT) {
113 LOG_DBG(
"MRHOF - DAO ACK received with status: %d\n", status);
114 if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) {
116 link_stats_packet_sent(rpl_get_parent_lladdr(p),
MAC_TX_OK, 10);
117 }
else if(status == RPL_DAO_ACK_TIMEOUT) {
119 link_stats_packet_sent(rpl_get_parent_lladdr(p),
MAC_TX_OK, 10);
125 parent_link_metric(rpl_parent_t *p)
127 const struct link_stats *stats = rpl_get_parent_link_stats(p);
129 #if RPL_MRHOF_SQUARED_ETX 130 uint32_t squared_etx = ((uint32_t)stats->etx * stats->etx) / LINK_STATS_ETX_DIVISOR;
131 return (uint16_t)MIN(squared_etx, 0xffff);
140 parent_path_cost(rpl_parent_t *p)
144 if(p == NULL || p->dag == NULL || p->dag->instance == NULL) {
150 switch(p->dag->instance->mc.type) {
152 base = p->mc.obj.etx;
154 case RPL_DAG_MC_ENERGY:
155 base = p->mc.obj.energy.energy_est << 8;
166 return MIN((uint32_t)base + parent_link_metric(p), 0xffff);
170 rank_via_parent(rpl_parent_t *p)
172 uint16_t min_hoprankinc;
175 if(p == NULL || p->dag == NULL || p->dag->instance == NULL) {
176 return RPL_INFINITE_RANK;
179 min_hoprankinc = p->dag->instance->min_hoprankinc;
180 path_cost = parent_path_cost(p);
183 return MAX(MIN((uint32_t)p->rank + min_hoprankinc, 0xffff), path_cost);
187 parent_is_acceptable(rpl_parent_t *p)
189 uint16_t link_metric = parent_link_metric(p);
190 uint16_t path_cost = parent_path_cost(p);
192 return link_metric <= MAX_LINK_METRIC && path_cost <= MAX_PATH_COST;
196 parent_has_usable_link(rpl_parent_t *p)
198 uint16_t link_metric = parent_link_metric(p);
200 return link_metric <= MAX_LINK_METRIC;
203 static rpl_parent_t *
204 best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
209 int p1_is_acceptable;
210 int p2_is_acceptable;
212 p1_is_acceptable = p1 != NULL && parent_is_acceptable(p1);
213 p2_is_acceptable = p2 != NULL && parent_is_acceptable(p2);
215 if(!p1_is_acceptable) {
216 return p2_is_acceptable ? p2 : NULL;
218 if(!p2_is_acceptable) {
219 return p1_is_acceptable ? p1 : NULL;
223 p1_cost = parent_path_cost(p1);
224 p2_cost = parent_path_cost(p2);
227 if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
228 if(p1_cost < p2_cost + PARENT_SWITCH_THRESHOLD &&
229 p1_cost > p2_cost - PARENT_SWITCH_THRESHOLD) {
230 return dag->preferred_parent;
234 return p1_cost < p2_cost ? p1 : p2;
240 if(d1->grounded != d2->grounded) {
241 return d1->grounded ? d1 : d2;
244 if(d1->preference != d2->preference) {
245 return d1->preference > d2->preference ? d1 : d2;
248 return d1->rank < d2->rank ? d1 : d2;
255 instance->mc.type = RPL_DAG_MC_NONE;
265 dag = instance->current_dag;
266 if(dag == NULL || !dag->joined) {
267 LOG_WARN(
"Cannot update the metric container when not joined\n");
273 instance->mc.type = RPL_DAG_MC;
274 instance->mc.flags = 0;
275 instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
276 instance->mc.prec = 0;
277 path_cost = dag->rank;
279 path_cost = parent_path_cost(dag->preferred_parent);
283 switch(instance->mc.type) {
284 case RPL_DAG_MC_NONE:
287 instance->mc.length =
sizeof(instance->mc.obj.etx);
288 instance->mc.obj.etx = path_cost;
290 case RPL_DAG_MC_ENERGY:
291 instance->mc.length =
sizeof(instance->mc.obj.energy);
293 type = RPL_DAG_MC_ENERGY_TYPE_MAINS;
295 type = RPL_DAG_MC_ENERGY_TYPE_BATTERY;
297 instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE;
299 instance->mc.obj.energy.energy_est = path_cost >> 8;
302 LOG_WARN(
"MRHOF, non-supported MC %u\n", instance->mc.type);
314 parent_has_usable_link,
319 update_metric_container,
#define ROOT_RANK
Rank of a root node.
API for RPL objective functions (OF)
The MAC layer transmission was OK.
Header file for the logging system