diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index cc4839ec0..a749a65c4 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -793,6 +793,11 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) /* Destination Advertisement Object */ + /* If we are in feather mode, we should not send any DAOs */ + if(rpl_get_mode() == RPL_MODE_FEATHER) { + return; + } + if(parent == NULL) { PRINTF("RPL dao_output_target error parent NULL\n"); return; diff --git a/core/net/rpl/rpl-timers.c b/core/net/rpl/rpl-timers.c index 02c3e00ba..acc1badf0 100644 --- a/core/net/rpl/rpl-timers.c +++ b/core/net/rpl/rpl-timers.c @@ -250,6 +250,10 @@ schedule_dao(rpl_instance_t *instance, clock_time_t latency) { clock_time_t expiration_time; + if(rpl_get_mode() == RPL_MODE_FEATHER) { + return; + } + expiration_time = etimer_expiration_time(&instance->dao_timer.etimer); if(!etimer_expired(&instance->dao_timer.etimer)) { diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index 4ff9b1c6a..7e3111d65 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -57,6 +57,47 @@ rpl_stats_t rpl_stats; #endif +static enum rpl_mode mode = RPL_MODE_MESH; +/*---------------------------------------------------------------------------*/ +enum rpl_mode +rpl_get_mode(void) +{ + return mode; +} +/*---------------------------------------------------------------------------*/ +enum rpl_mode +rpl_set_mode(enum rpl_mode m) +{ + enum rpl_mode oldmode = mode; + + /* We need to do different things depending on what mode we are + switching to. */ + if(m == RPL_MODE_MESH) { + + /* If we switcht to mesh mode, we should send out a DAO message to + inform our parent that we now are reachable. Before we do this, + we must set the mode variable, since DAOs will not be send if + we are in feather mode. */ + PRINTF("RPL: switching to mesh mode\n"); + mode = m; + + if(default_instance != NULL) { + rpl_schedule_dao_immediately(default_instance); + } + } else if(m == RPL_MODE_FEATHER) { + + PRINTF("RPL: switching to feather mode\n"); + mode = m; + if(default_instance != NULL) { + rpl_cancel_dao(default_instance); + } + + } else { + mode = m; + } + + return oldmode; +} /*---------------------------------------------------------------------------*/ void rpl_purge_routes(void) diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 8488a0f1f..7d2a5ee70 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -244,5 +244,38 @@ uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr); rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr); uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr); void rpl_dag_init(void); + + +/** + * RPL modes + * + * The RPL module can be in either of three modes: mesh mode + * (RPL_MODE_MESH), feater mode (RPL_MODE_FEATHER), and leaf mode + * (RPL_MODE_LEAF). In mesh mode, nodes forward data for other nodes, + * and are reachable by others. In feather mode, nodes can forward + * data for other nodes, but are not reachable themselves. In leaf + * mode, nodes do not forward data for others, but are reachable by + * others. */ +enum rpl_mode { + RPL_MODE_MESH = 0, + RPL_MODE_FEATHER = 1, + RPL_MODE_LEAF = 2, +}; + +/** + * Set the RPL mode + * + * \param mode The new RPL mode + * \retval The previous RPL mode + */ +enum rpl_mode rpl_set_mode(enum rpl_mode mode); + +/** + * Get the RPL mode + * + * \retval The RPL mode + */ +enum rpl_mode rpl_get_mode(void); + /*---------------------------------------------------------------------------*/ #endif /* RPL_H */