diff --git a/os/net/routing/rpl-lite/rpl-conf.h b/os/net/routing/rpl-lite/rpl-conf.h index a3693f8b9..8d2f4b7b9 100644 --- a/os/net/routing/rpl-lite/rpl-conf.h +++ b/os/net/routing/rpl-lite/rpl-conf.h @@ -185,10 +185,10 @@ * This value decides if this node must stay as a leaf or not * as allowed by draft-ietf-roll-rpl-19#section-8.5 */ -#ifdef RPL_CONF_LEAF_ONLY -#define RPL_LEAF_ONLY RPL_CONF_LEAF_ONLY +#ifdef RPL_CONF_DEFAULT_LEAF_ONLY +#define RPL_DEFAULT_LEAF_ONLY RPL_CONF_DEFAULT_LEAF_ONLY #else -#define RPL_LEAF_ONLY 0 +#define RPL_DEFAULT_LEAF_ONLY 0 #endif /******************************************************************************/ diff --git a/os/net/routing/rpl-lite/rpl-icmp6.c b/os/net/routing/rpl-lite/rpl-icmp6.c index 1e4a50423..be5ea2948 100644 --- a/os/net/routing/rpl-lite/rpl-icmp6.c +++ b/os/net/routing/rpl-lite/rpl-icmp6.c @@ -342,14 +342,14 @@ rpl_icmp6_dio_output(uip_ipaddr_t *uc_addr) /* Make sure we're up-to-date before sending data out */ rpl_dag_update_state(); -#if RPL_LEAF_ONLY - /* In leaf mode, we only send DIO messages as unicasts in response to - unicast DIS messages. */ - if(uc_addr == NULL) { - /* Do not send multicast DIO in leaf mode */ - return; + if(rpl_get_leaf_only()) { + /* In leaf mode, we only send DIO messages as unicasts in response to + unicast DIS messages. */ + if(uc_addr == NULL) { + /* Do not send multicast DIO in leaf mode */ + return; + } } -#endif /* RPL_LEAF_ONLY */ /* DAG Information Object */ pos = 0; @@ -358,11 +358,11 @@ rpl_icmp6_dio_output(uip_ipaddr_t *uc_addr) buffer[pos++] = curr_instance.instance_id; buffer[pos++] = curr_instance.dag.version; -#if RPL_LEAF_ONLY - set16(buffer, pos, RPL_INFINITE_RANK); -#else /* RPL_LEAF_ONLY */ - set16(buffer, pos, curr_instance.dag.rank); -#endif /* RPL_LEAF_ONLY */ + if(rpl_get_leaf_only()) { + set16(buffer, pos, RPL_INFINITE_RANK); + } else { + set16(buffer, pos, curr_instance.dag.rank); + } pos += 2; buffer[pos] = 0; @@ -383,29 +383,29 @@ rpl_icmp6_dio_output(uip_ipaddr_t *uc_addr) memcpy(buffer + pos, &curr_instance.dag.dag_id, sizeof(curr_instance.dag.dag_id)); pos += 16; -#if !RPL_LEAF_ONLY - if(curr_instance.mc.type != RPL_DAG_MC_NONE) { - buffer[pos++] = RPL_OPTION_DAG_METRIC_CONTAINER; - buffer[pos++] = 6; - buffer[pos++] = curr_instance.mc.type; - buffer[pos++] = curr_instance.mc.flags >> 1; - buffer[pos] = (curr_instance.mc.flags & 1) << 7; - buffer[pos++] |= (curr_instance.mc.aggr << 4) | curr_instance.mc.prec; - if(curr_instance.mc.type == RPL_DAG_MC_ETX) { - buffer[pos++] = 2; - set16(buffer, pos, curr_instance.mc.obj.etx); - pos += 2; - } else if(curr_instance.mc.type == RPL_DAG_MC_ENERGY) { - buffer[pos++] = 2; - buffer[pos++] = curr_instance.mc.obj.energy.flags; - buffer[pos++] = curr_instance.mc.obj.energy.energy_est; - } else { - LOG_ERR("unable to send DIO because of unsupported DAG MC type %u\n", - (unsigned)curr_instance.mc.type); - return; + if(!rpl_get_leaf_only()) { + if(curr_instance.mc.type != RPL_DAG_MC_NONE) { + buffer[pos++] = RPL_OPTION_DAG_METRIC_CONTAINER; + buffer[pos++] = 6; + buffer[pos++] = curr_instance.mc.type; + buffer[pos++] = curr_instance.mc.flags >> 1; + buffer[pos] = (curr_instance.mc.flags & 1) << 7; + buffer[pos++] |= (curr_instance.mc.aggr << 4) | curr_instance.mc.prec; + if(curr_instance.mc.type == RPL_DAG_MC_ETX) { + buffer[pos++] = 2; + set16(buffer, pos, curr_instance.mc.obj.etx); + pos += 2; + } else if(curr_instance.mc.type == RPL_DAG_MC_ENERGY) { + buffer[pos++] = 2; + buffer[pos++] = curr_instance.mc.obj.energy.flags; + buffer[pos++] = curr_instance.mc.obj.energy.energy_est; + } else { + LOG_ERR("unable to send DIO because of unsupported DAG MC type %u\n", + (unsigned)curr_instance.mc.type); + return; + } } } -#endif /* !RPL_LEAF_ONLY */ /* Always add a DAG configuration option. */ buffer[pos++] = RPL_OPTION_DAG_CONF; @@ -442,9 +442,9 @@ rpl_icmp6_dio_output(uip_ipaddr_t *uc_addr) pos += 16; } -#if !RPL_LEAF_ONLY - addr = addr != NULL ? addr : &rpl_multicast_addr; -#endif /* RPL_LEAF_ONLY */ + if(!rpl_get_leaf_only()) { + addr = addr != NULL ? addr : &rpl_multicast_addr; + } LOG_INFO("sending a %s-DIO with rank %u to ", uc_addr != NULL ? "unicast" : "multicast", diff --git a/os/net/routing/rpl-lite/rpl-timers.c b/os/net/routing/rpl-lite/rpl-timers.c index f7a50b858..80a24fe66 100644 --- a/os/net/routing/rpl-lite/rpl-timers.c +++ b/os/net/routing/rpl-lite/rpl-timers.c @@ -150,11 +150,11 @@ rpl_timers_dio_reset(const char *str) { if(rpl_dag_ready_to_advertise()) { LOG_INFO("reset DIO timer (%s)\n", str); -#if !RPL_LEAF_ONLY - curr_instance.dag.dio_counter = 0; - curr_instance.dag.dio_intcurrent = curr_instance.dio_intmin; - new_dio_interval(); -#endif /* RPL_LEAF_ONLY */ + if(!rpl_get_leaf_only()) { + curr_instance.dag.dio_counter = 0; + curr_instance.dag.dio_intcurrent = curr_instance.dio_intmin; + new_dio_interval(); + } } } /*---------------------------------------------------------------------------*/ diff --git a/os/net/routing/rpl-lite/rpl.c b/os/net/routing/rpl-lite/rpl.c index acfe94c37..fd93b40e8 100644 --- a/os/net/routing/rpl-lite/rpl.c +++ b/os/net/routing/rpl-lite/rpl.c @@ -50,6 +50,7 @@ #define LOG_LEVEL LOG_LEVEL_RPL uip_ipaddr_t rpl_multicast_addr; +static uint8_t rpl_leaf_only = RPL_DEFAULT_LEAF_ONLY; /*---------------------------------------------------------------------------*/ int @@ -223,6 +224,18 @@ drop_route(uip_ds6_route_t *route) /* Do nothing. RPL-lite only supports non-storing mode, i.e. no routes */ } /*---------------------------------------------------------------------------*/ +void +rpl_set_leaf_only(uint8_t value) +{ + rpl_leaf_only = value; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rpl_get_leaf_only(void) +{ + return rpl_leaf_only; +} +/*---------------------------------------------------------------------------*/ const struct routing_driver rpl_lite_driver = { "RPL Lite", init, diff --git a/os/net/routing/rpl-lite/rpl.h b/os/net/routing/rpl-lite/rpl.h index 25ac3863e..e39c825c4 100644 --- a/os/net/routing/rpl-lite/rpl.h +++ b/os/net/routing/rpl-lite/rpl.h @@ -133,6 +133,20 @@ int rpl_lollipop_greater_than(int a, int b); */ void rpl_refresh_routes(const char *str); +/** + * Changes the value of the rpl_leaf_only flag, which determines if a node acts + * only as a leaf in the network + * + * \param value the value to set: 0-disable, 1-enable + */ +void rpl_set_leaf_only(uint8_t value); + +/** + * Get the value of the rpl_leaf_only flag + * + * \return The value of the rpl_leaf_only flag + */ +uint8_t rpl_get_leaf_only(void); /** @} */ #endif /* RPL_H */