From faff1c2a7e59e24b528cb38b263669b470149543 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Wed, 20 Nov 2013 14:10:39 +0100 Subject: [PATCH] Preliminary support for RPL node types. This change allows a node to be in any of three given types: * Mesh: this is the normal case. Nodes route data on behalf of others and the node can be reached via a DAO route. * Leaf: the node does not route data on behalf of others, but others can route data to the node (it has a RPL DAO route). * Feather: this is a new type of node. A feather node routes data on behalf of others, but does not install DAO routes in the network. Feather nodes allow having a larger number of nodes than the RPL network can sustain in terms of routing tables. This commit introduces the RPL node types and the feather mode, but does not add support for the leaf node type. --- core/net/rpl/rpl-icmp6.c | 5 +++++ core/net/rpl/rpl-timers.c | 4 ++++ core/net/rpl/rpl.c | 41 +++++++++++++++++++++++++++++++++++++++ core/net/rpl/rpl.h | 33 +++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+) 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 */