diff --git a/sys/include/net/gnrc/rpl.h b/sys/include/net/gnrc/rpl.h index 30062b175d57d82bb1e25dda24a7a87489ddacf8..c49be36c71bd968b72cbc6b215f5a6fafeda4770 100644 --- a/sys/include/net/gnrc/rpl.h +++ b/sys/include/net/gnrc/rpl.h @@ -31,6 +31,7 @@ #include <string.h> #include <stdint.h> +#include "net/gnrc.h" #include "net/ipv6/addr.h" #include "net/gnrc/nettype.h" #include "net/gnrc/rpl/structs.h" @@ -342,7 +343,7 @@ extern kernel_pid_t gnrc_rpl_pid; kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid); /** - * @brief Initialization of a RPL DODAG as root node. Creates a new instance if necessary. + * @brief Initialization of a node as root. * * @param[in] instance_id Id of the instance * @param[in] dodag_id Id of the DODAG @@ -434,6 +435,28 @@ void gnrc_rpl_delay_dao(gnrc_rpl_dodag_t *dodag); * @param[in] dodag The DODAG of the DAO */ void gnrc_rpl_long_delay_dao(gnrc_rpl_dodag_t *dodag); + +/** + * @brief Creation of a RPL DODAG as root. Creates a new instance if necessary. + * + * @param[in] instance_id Id of the instance + * @param[in] dodag_id Id of the DODAG + * @param[in] mop Mode of Operation + * + * @return Pointer to the new DODAG, on success. + * @return NULL, otherwise. + */ +gnrc_rpl_dodag_t *gnrc_rpl_root_dodag_init(uint8_t instance_id, ipv6_addr_t *dodag_id, uint8_t mop); + +/** + * @brief Send a control message + * + * @param[in] pkt gnrc_pktnsip_t to send + * @param[in] src Source address of the packet + * @param[in] dst Destination address of the packet + * @param[in] dodag_id Id of the DODAG + */ +void gnrc_rpl_send(gnrc_pktsnip_t *pkt, ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *dodag_id); #ifdef __cplusplus } #endif diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl.c b/sys/net/gnrc/routing/rpl/gnrc_rpl.c index 69caacdae8540791374922fd384ca04314fe28f8..83abaa3bc572850da08401b94a9eb8411e2c67af 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl.c @@ -43,7 +43,6 @@ static void _update_lifetime(void); static void _dao_handle_send(gnrc_rpl_dodag_t *dodag); static void _receive(gnrc_pktsnip_t *pkt); static void *_event_loop(void *args); -static gnrc_rpl_dodag_t *_root_dodag_init(uint8_t instance_id, ipv6_addr_t *dodag_id, uint8_t mop); kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid) { @@ -78,7 +77,7 @@ kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid) gnrc_rpl_dodag_t *gnrc_rpl_root_init(uint8_t instance_id, ipv6_addr_t *dodag_id) { - gnrc_rpl_dodag_t *dodag = _root_dodag_init(instance_id, dodag_id, GNRC_RPL_DEFAULT_MOP); + gnrc_rpl_dodag_t *dodag = gnrc_rpl_root_dodag_init(instance_id, dodag_id, GNRC_RPL_DEFAULT_MOP); if (!dodag) { return NULL; @@ -103,63 +102,6 @@ gnrc_rpl_dodag_t *gnrc_rpl_root_init(uint8_t instance_id, ipv6_addr_t *dodag_id) return dodag; } -static gnrc_rpl_dodag_t *_root_dodag_init(uint8_t instance_id, ipv6_addr_t *dodag_id, uint8_t mop) -{ - if (gnrc_rpl_pid == KERNEL_PID_UNDEF) { - DEBUG("RPL: RPL thread not started\n"); - return NULL; - } - - ipv6_addr_t *configured_addr; - gnrc_ipv6_netif_addr_t *netif_addr = NULL; - gnrc_rpl_instance_t *inst = NULL; - gnrc_rpl_dodag_t *dodag = NULL; - - if (instance_id == 0) { - DEBUG("RPL: instance id (%d) must be a positive number greater than zero\n", instance_id); - return NULL; - } - - if (gnrc_ipv6_netif_find_by_addr(&configured_addr, dodag_id) == KERNEL_PID_UNDEF) { - DEBUG("RPL: no IPv6 address configured to match the given dodag id: %s\n", - ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str))); - return NULL; - } - - if ((netif_addr = gnrc_ipv6_netif_addr_get(configured_addr)) == NULL) { - DEBUG("RPL: no netif address found for %s\n", ipv6_addr_to_str(addr_str, configured_addr, - sizeof(addr_str))); - return NULL; - } - - if (gnrc_rpl_instance_add(instance_id, &inst)) { - inst->of = (gnrc_rpl_of_t *) gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP); - inst->mop = mop; - inst->min_hop_rank_inc = GNRC_RPL_DEFAULT_MIN_HOP_RANK_INCREASE; - inst->max_rank_inc = GNRC_RPL_DEFAULT_MAX_RANK_INCREASE; - } - else if (inst == NULL) { - DEBUG("RPL: could not allocate memory for a new instance with id %d", instance_id); - return NULL; - } - else if (inst->mop != mop) { - DEBUG("RPL: instance (%d) exists with another MOP", instance_id); - return NULL; - } - - if (!gnrc_rpl_dodag_add(inst, dodag_id, &dodag)) { - DEBUG("RPL: DODAG with id %s exists or no memory left for a new DODAG", - ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str))); - return NULL; - } - - dodag->prefix_len = netif_addr->prefix_len; - dodag->addr_preferred = netif_addr->preferred; - dodag->addr_valid = netif_addr->valid; - - return dodag; -} - static void _receive(gnrc_pktsnip_t *icmpv6) { gnrc_pktsnip_t *ipv6 = NULL; diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index 34f4c4ce119643cdd8664ac7f74e437cea14253c..7b22b4ddcf83dddfc552182cc90669c53f64528b 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -43,8 +43,7 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN]; #define GNRC_RPL_DAO_K_BIT (1 << 7) #define GNRC_RPL_DAO_ACK_D_BIT (1 << 7) -void _gnrc_rpl_send(gnrc_pktsnip_t *pkt, ipv6_addr_t *src, ipv6_addr_t *dst, - ipv6_addr_t *dodag_id) +void gnrc_rpl_send(gnrc_pktsnip_t *pkt, ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *dodag_id) { gnrc_pktsnip_t *hdr; ipv6_addr_t all_RPL_nodes = GNRC_RPL_ALL_NODES_ADDR, ll_addr; @@ -166,7 +165,7 @@ void gnrc_rpl_send_DIO(gnrc_rpl_dodag_t *dodag, ipv6_addr_t *destination) } dodag->dodag_conf_counter++; - _gnrc_rpl_send(pkt, NULL, destination, &dodag->dodag_id); + gnrc_rpl_send(pkt, NULL, destination, &dodag->dodag_id); } void gnrc_rpl_send_DIS(gnrc_rpl_dodag_t *dodag, ipv6_addr_t *destination) @@ -192,7 +191,7 @@ void gnrc_rpl_send_DIS(gnrc_rpl_dodag_t *dodag, ipv6_addr_t *destination) /* TODO: see above TODO */ memset((dis + 1), 0, 4); - _gnrc_rpl_send(pkt, NULL, destination, (dodag ? &dodag->dodag_id : NULL)); + gnrc_rpl_send(pkt, NULL, destination, (dodag ? &dodag->dodag_id : NULL)); } void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, ipv6_addr_t *src, ipv6_addr_t *dst, uint16_t len) @@ -584,7 +583,7 @@ void gnrc_rpl_send_DAO(gnrc_rpl_dodag_t *dodag, ipv6_addr_t *destination, uint8_ transit->path_sequence = 0; transit->path_lifetime = lifetime; - _gnrc_rpl_send(pkt, NULL, destination, &dodag->dodag_id); + gnrc_rpl_send(pkt, NULL, destination, &dodag->dodag_id); GNRC_RPL_COUNTER_INCREMENT(dodag->dao_seq); } @@ -627,7 +626,7 @@ void gnrc_rpl_send_DAO_ACK(gnrc_rpl_dodag_t *dodag, ipv6_addr_t *destination, ui dao_ack->dao_sequence = seq; dao_ack->status = 0; - _gnrc_rpl_send(pkt, NULL, destination, &dodag->dodag_id); + gnrc_rpl_send(pkt, NULL, destination, &dodag->dodag_id); } void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, ipv6_addr_t *src, uint16_t len) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c index 185f1d12815436c6daeffed172c31987e23b5164..5c4126b824e64d24d186b603c5adb2249dc6f60a 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c @@ -423,6 +423,63 @@ static gnrc_rpl_parent_t *_gnrc_rpl_find_preferred_parent(gnrc_rpl_dodag_t *doda return dodag->parents; } +gnrc_rpl_dodag_t *gnrc_rpl_root_dodag_init(uint8_t instance_id, ipv6_addr_t *dodag_id, uint8_t mop) +{ + if (gnrc_rpl_pid == KERNEL_PID_UNDEF) { + DEBUG("RPL: RPL thread not started\n"); + return NULL; + } + + ipv6_addr_t *configured_addr; + gnrc_ipv6_netif_addr_t *netif_addr = NULL; + gnrc_rpl_instance_t *inst = NULL; + gnrc_rpl_dodag_t *dodag = NULL; + + if (instance_id == 0) { + DEBUG("RPL: instance id (%d) must be a positive number greater than zero\n", instance_id); + return NULL; + } + + if (gnrc_ipv6_netif_find_by_addr(&configured_addr, dodag_id) == KERNEL_PID_UNDEF) { + DEBUG("RPL: no IPv6 address configured to match the given dodag id: %s\n", + ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str))); + return NULL; + } + + if ((netif_addr = gnrc_ipv6_netif_addr_get(configured_addr)) == NULL) { + DEBUG("RPL: no netif address found for %s\n", ipv6_addr_to_str(addr_str, configured_addr, + sizeof(addr_str))); + return NULL; + } + + if (gnrc_rpl_instance_add(instance_id, &inst)) { + inst->of = (gnrc_rpl_of_t *) gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP); + inst->mop = mop; + inst->min_hop_rank_inc = GNRC_RPL_DEFAULT_MIN_HOP_RANK_INCREASE; + inst->max_rank_inc = GNRC_RPL_DEFAULT_MAX_RANK_INCREASE; + } + else if (inst == NULL) { + DEBUG("RPL: could not allocate memory for a new instance with id %d", instance_id); + return NULL; + } + else if (inst->mop != mop) { + DEBUG("RPL: instance (%d) exists with another MOP", instance_id); + return NULL; + } + + if (!gnrc_rpl_dodag_add(inst, dodag_id, &dodag)) { + DEBUG("RPL: DODAG with id %s exists or no memory left for a new DODAG", + ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str))); + return NULL; + } + + dodag->prefix_len = netif_addr->prefix_len; + dodag->addr_preferred = netif_addr->preferred; + dodag->addr_valid = netif_addr->valid; + + return dodag; +} + /** * @} */