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" 54 #define DEBUG DEBUG_NONE 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 78 #if !RPL_MRHOF_SQUARED_ETX 81 #define MAX_LINK_METRIC 1024 86 #define PARENT_SWITCH_THRESHOLD 96 88 #define MAX_LINK_METRIC 2048 89 #define PARENT_SWITCH_THRESHOLD 160 94 #define MAX_PATH_COST 32768 100 PRINTF(
"RPL: Reset MRHOF\n");
105 dao_ack_callback(rpl_parent_t *p,
int status)
107 if(status == RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT) {
111 PRINTF(
"RPL: MRHOF - DAO ACK received with status: %d\n", status);
112 if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) {
114 link_stats_packet_sent(rpl_get_parent_lladdr(p),
MAC_TX_OK, 10);
115 }
else if(status == RPL_DAO_ACK_TIMEOUT) {
117 link_stats_packet_sent(rpl_get_parent_lladdr(p),
MAC_TX_OK, 10);
123 parent_link_metric(rpl_parent_t *p)
125 const struct link_stats *stats = rpl_get_parent_link_stats(p);
127 #if RPL_MRHOF_SQUARED_ETX 128 uint32_t squared_etx = ((uint32_t)stats->etx * stats->etx) / LINK_STATS_ETX_DIVISOR;
129 return (uint16_t)MIN(squared_etx, 0xffff);
138 parent_path_cost(rpl_parent_t *p)
142 if(p == NULL || p->dag == NULL || p->dag->instance == NULL) {
148 switch(p->dag->instance->mc.type) {
150 base = p->mc.obj.etx;
152 case RPL_DAG_MC_ENERGY:
153 base = p->mc.obj.energy.energy_est << 8;
164 return MIN((uint32_t)base + parent_link_metric(p), 0xffff);
168 rank_via_parent(rpl_parent_t *p)
170 uint16_t min_hoprankinc;
173 if(p == NULL || p->dag == NULL || p->dag->instance == NULL) {
174 return RPL_INFINITE_RANK;
177 min_hoprankinc = p->dag->instance->min_hoprankinc;
178 path_cost = parent_path_cost(p);
181 return MAX(MIN((uint32_t)p->rank + min_hoprankinc, 0xffff), path_cost);
185 parent_is_acceptable(rpl_parent_t *p)
187 uint16_t link_metric = parent_link_metric(p);
188 uint16_t path_cost = parent_path_cost(p);
190 return link_metric <= MAX_LINK_METRIC && path_cost <= MAX_PATH_COST;
194 parent_has_usable_link(rpl_parent_t *p)
196 uint16_t link_metric = parent_link_metric(p);
198 return link_metric <= MAX_LINK_METRIC;
201 static rpl_parent_t *
202 best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
207 int p1_is_acceptable;
208 int p2_is_acceptable;
210 p1_is_acceptable = p1 != NULL && parent_is_acceptable(p1);
211 p2_is_acceptable = p2 != NULL && parent_is_acceptable(p2);
213 if(!p1_is_acceptable) {
214 return p2_is_acceptable ? p2 : NULL;
216 if(!p2_is_acceptable) {
217 return p1_is_acceptable ? p1 : NULL;
221 p1_cost = parent_path_cost(p1);
222 p2_cost = parent_path_cost(p2);
225 if(p1 == dag->preferred_parent || p2 == dag->preferred_parent) {
226 if(p1_cost < p2_cost + PARENT_SWITCH_THRESHOLD &&
227 p1_cost > p2_cost - PARENT_SWITCH_THRESHOLD) {
228 return dag->preferred_parent;
232 return p1_cost < p2_cost ? p1 : p2;
238 if(d1->grounded != d2->grounded) {
239 return d1->grounded ? d1 : d2;
242 if(d1->preference != d2->preference) {
243 return d1->preference > d2->preference ? d1 : d2;
246 return d1->rank < d2->rank ? d1 : d2;
253 instance->mc.type = RPL_DAG_MC_NONE;
263 dag = instance->current_dag;
264 if(dag == NULL || !dag->joined) {
265 PRINTF(
"RPL: Cannot update the metric container when not joined\n");
271 instance->mc.type = RPL_DAG_MC;
272 instance->mc.flags = 0;
273 instance->mc.aggr = RPL_DAG_MC_AGGR_ADDITIVE;
274 instance->mc.prec = 0;
275 path_cost = dag->rank;
277 path_cost = parent_path_cost(dag->preferred_parent);
281 switch(instance->mc.type) {
282 case RPL_DAG_MC_NONE:
285 instance->mc.length =
sizeof(instance->mc.obj.etx);
286 instance->mc.obj.etx = path_cost;
288 case RPL_DAG_MC_ENERGY:
289 instance->mc.length =
sizeof(instance->mc.obj.energy);
291 type = RPL_DAG_MC_ENERGY_TYPE_MAINS;
293 type = RPL_DAG_MC_ENERGY_TYPE_BATTERY;
295 instance->mc.obj.energy.flags = type << RPL_DAG_MC_ENERGY_TYPE;
297 instance->mc.obj.energy.energy_est = path_cost >> 8;
300 PRINTF(
"RPL: MRHOF, non-supported MC %u\n", instance->mc.type);
312 parent_has_usable_link,
317 update_metric_container,
#define ROOT_RANK
Rank of a root node.
A set of debugging macros for the IP stack
The MAC layer transmission was OK.
API for RPL objective functions (OF)