diff --git a/Makefile.dep b/Makefile.dep index 0895d9992bf9f6286c26cea7fe76e846231cb775..6fbd8a1e6f60a5a89715808faffeafb6ef84ebdb 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -127,6 +127,7 @@ ifneq (,$(filter gnrc_rpl,$(USEMODULE))) USEMODULE += gnrc_ipv6_nib USEMODULE += trickle USEMODULE += xtimer + USEMODULE += evtimer endif ifneq (,$(filter trickle,$(USEMODULE))) diff --git a/sys/include/net/gnrc/rpl.h b/sys/include/net/gnrc/rpl.h index ef0d62ccaf50fa30bcc3106ea724e14f2f5b7753..7242b67b6acbb6fdcae925aa1fa7fcba28864037 100644 --- a/sys/include/net/gnrc/rpl.h +++ b/sys/include/net/gnrc/rpl.h @@ -326,23 +326,37 @@ static inline bool GNRC_RPL_COUNTER_GREATER_THAN(uint8_t A, uint8_t B) * @{ */ #ifndef GNRC_RPL_DAO_SEND_RETRIES -#define GNRC_RPL_DAO_SEND_RETRIES (4) +#define GNRC_RPL_DAO_SEND_RETRIES (4) #endif -#ifndef GNRC_RPL_DEFAULT_WAIT_FOR_DAO_ACK -#define GNRC_RPL_DEFAULT_WAIT_FOR_DAO_ACK (3) +#ifndef GNRC_RPL_DAO_ACK_DELAY +#define GNRC_RPL_DAO_ACK_DELAY (3000UL) #endif -#ifndef GNRC_RPL_REGULAR_DAO_INTERVAL -#define GNRC_RPL_REGULAR_DAO_INTERVAL (60) +#ifndef GNRC_RPL_DAO_DELAY_LONG +/** + * @brief Long delay for DAOs in milli seconds + */ +#define GNRC_RPL_DAO_DELAY_LONG (60000UL) +#endif +#ifndef GNRC_RPL_DAO_DELAY_DEFAULT +/** + * @brief Default delay for DAOs in milli seconds + */ +#define GNRC_RPL_DAO_DELAY_DEFAULT (1000UL) #endif -#ifndef GNRC_RPL_DEFAULT_DAO_DELAY -#define GNRC_RPL_DEFAULT_DAO_DELAY (1) +#ifndef GNRC_RPL_DAO_DELAY_JITTER +/** + * @brief Jitter for DAOs in milli seconds + */ +#define GNRC_RPL_DAO_DELAY_JITTER (1000UL) #endif /** @} */ /** - * @brief Cleanup timeout in seconds + * @brief Cleanup interval in milliseconds. */ -#define GNRC_RPL_CLEANUP_TIME (5) +#ifndef GNRC_RPL_CLEANUP_TIME +#define GNRC_RPL_CLEANUP_TIME (5 * MS_PER_SEC) +#endif /** * @name Node Status @@ -453,6 +467,13 @@ extern const ipv6_addr_t ipv6_addr_all_rpl_nodes; extern netstats_rpl_t gnrc_rpl_netstats; #endif +/** + * @brief Number of DIS retries before parent times out + */ +#ifndef GNRC_RPL_PARENT_TIMEOUT_DIS_RETRIES +#define GNRC_RPL_PARENT_TIMEOUT_DIS_RETRIES (3) +#endif + /** * @brief Initialization of the RPL thread. * diff --git a/sys/include/net/gnrc/rpl/structs.h b/sys/include/net/gnrc/rpl/structs.h index 6abfca39ad051106bf59d3e949ca841f02dab4b7..3a208f780b19304209849365e6635354c2caee70 100644 --- a/sys/include/net/gnrc/rpl/structs.h +++ b/sys/include/net/gnrc/rpl/structs.h @@ -30,7 +30,8 @@ extern "C" { #include "byteorder.h" #include "net/ipv6/addr.h" -#include "xtimer.h" +#include "evtimer.h" +#include "evtimer_msg.h" #include "trickle.h" /** @@ -222,14 +223,17 @@ typedef struct gnrc_rpl_instance gnrc_rpl_instance_t; * @cond INTERNAL */ struct gnrc_rpl_parent { gnrc_rpl_parent_t *next; /**< pointer to the next parent */ - uint8_t state; /**< 0 for unsued, 1 for used */ + uint8_t state; /**< see @ref gnrc_rpl_parent_states */ ipv6_addr_t addr; /**< link-local IPv6 address of this parent */ uint8_t dtsn; /**< last seen dtsn of this parent */ uint16_t rank; /**< rank of the parent */ gnrc_rpl_dodag_t *dodag; /**< DODAG the parent belongs to */ - uint32_t lifetime; /**< lifetime of this parent in seconds */ - double link_metric; /**< metric of the link */ + double link_metric; /**< metric of the link */ uint8_t link_metric_type; /**< type of the metric */ + /** + * @brief Parent timeout events (see @ref GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT) + */ + evtimer_msg_event_t timeout_event; }; /** * @endcond @@ -290,7 +294,7 @@ struct gnrc_rpl_dodag { bool dao_ack_received; /**< flag to check for DAO-ACK */ uint8_t dio_opts; /**< options in the next DIO (see @ref GNRC_RPL_REQ_DIO_OPTS "DIO Options") */ - uint8_t dao_time; /**< time to schedule a DAO in seconds */ + evtimer_msg_event_t dao_event; /**< DAO TX events (see @ref GNRC_RPL_MSG_TYPE_DODAG_DAO_TX) */ trickle_t trickle; /**< trickle representation */ }; @@ -302,7 +306,10 @@ struct gnrc_rpl_instance { gnrc_rpl_of_t *of; /**< configured Objective Function */ uint16_t min_hop_rank_inc; /**< minimum hop rank increase */ uint16_t max_rank_inc; /**< max increase in the rank */ - int8_t cleanup; /**< cleanup time in seconds */ + /** + * @brief Instance cleanup events (see @ref GNRC_RPL_MSG_TYPE_INSTANCE_CLEANUP) + */ + evtimer_msg_event_t cleanup_event; }; /** * @endcond diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl.c b/sys/net/gnrc/routing/rpl/gnrc_rpl.c index 991f7314d868bb114cc5c1f878cdbd175c2b1e4a..dbd734ffe8642cffcb19473f19de3c7eb380f40a 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl.c @@ -20,6 +20,9 @@ #include "net/gnrc/netif/internal.h" #include "net/gnrc.h" #include "mutex.h" +#include "evtimer.h" +#include "random.h" +#include "gnrc_rpl_internal/globals.h" #include "net/gnrc/rpl.h" #ifdef MODULE_GNRC_RPL_P2P @@ -33,9 +36,11 @@ static char _stack[GNRC_RPL_STACK_SIZE]; kernel_pid_t gnrc_rpl_pid = KERNEL_PID_UNDEF; const ipv6_addr_t ipv6_addr_all_rpl_nodes = GNRC_RPL_ALL_NODES_ADDR; +#ifdef MODULE_GNRC_RPL_P2P static uint32_t _lt_time = GNRC_RPL_LIFETIME_UPDATE_STEP * US_PER_SEC; static xtimer_t _lt_timer; static msg_t _lt_msg = { .type = GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE }; +#endif static msg_t _msg_q[GNRC_RPL_MSG_QUEUE_SIZE]; static gnrc_netreg_entry_t _me_reg; static mutex_t _inst_id_mutex = MUTEX_INIT; @@ -48,11 +53,15 @@ gnrc_rpl_parent_t gnrc_rpl_parents[GNRC_RPL_PARENTS_NUMOF]; netstats_rpl_t gnrc_rpl_netstats; #endif +#ifdef MODULE_GNRC_RPL_P2P static void _update_lifetime(void); +#endif static void _dao_handle_send(gnrc_rpl_dodag_t *dodag); static void _receive(gnrc_pktsnip_t *pkt); static void *_event_loop(void *args); +evtimer_msg_t gnrc_rpl_evtimer; + kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid) { /* check if RPL was initialized before */ @@ -74,7 +83,10 @@ kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid) gnrc_netreg_register(GNRC_NETTYPE_ICMPV6, &_me_reg); gnrc_rpl_of_manager_init(); + evtimer_init_msg(&gnrc_rpl_evtimer); +#ifdef MODULE_GNRC_RPL_P2P xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid); +#endif #ifdef MODULE_NETSTATS_RPL memset(&gnrc_rpl_netstats, 0, sizeof(gnrc_rpl_netstats)); @@ -197,6 +209,35 @@ static void _receive(gnrc_pktsnip_t *icmpv6) gnrc_pktbuf_release(icmpv6); } +static void _parent_timeout(gnrc_rpl_parent_t *parent) +{ + if (!parent || (parent->state == GNRC_RPL_PARENT_UNUSED)) { + return; + } + + evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&parent->timeout_event); + + if (parent->state == GNRC_RPL_PARENT_ACTIVE) { + parent->state = GNRC_RPL_PARENT_STALE; + } + + if ((parent->state >= GNRC_RPL_PARENT_STALE) && + (parent->state < GNRC_RPL_PARENT_TIMEOUT)) { + parent->state++; + gnrc_rpl_send_DIS(parent->dodag->instance, &parent->addr); + } + else { + gnrc_rpl_dodag_t *dodag = parent->dodag; + gnrc_rpl_parent_remove(parent); + gnrc_rpl_parent_update(dodag, NULL); + return; + } + + ((evtimer_event_t *)&(parent->timeout_event))->offset = GNRC_RPL_PARENT_PROBE_INTERVAL; + parent->timeout_event.msg.type = GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT; + evtimer_add_msg(&gnrc_rpl_evtimer, &parent->timeout_event, gnrc_rpl_pid); +} + static void *_event_loop(void *args) { msg_t msg, reply; @@ -208,16 +249,38 @@ static void *_event_loop(void *args) reply.type = GNRC_NETAPI_MSG_TYPE_ACK; trickle_t *trickle; + gnrc_rpl_parent_t *parent; + gnrc_rpl_instance_t *instance; + /* start event loop */ while (1) { DEBUG("RPL: waiting for incoming message.\n"); msg_receive(&msg); switch (msg.type) { +#ifdef MODULE_GNRC_RPL_P2P case GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE: DEBUG("RPL: GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE received\n"); _update_lifetime(); break; +#endif + case GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT: + DEBUG("RPL: GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT received\n"); + parent = msg.content.ptr; + _parent_timeout(parent); + break; + case GNRC_RPL_MSG_TYPE_DODAG_DAO_TX: + DEBUG("RPL: GNRC_RPL_MSG_TYPE_DODAG_DAO_TX received\n"); + instance = msg.content.ptr; + _dao_handle_send(&instance->dodag); + break; + case GNRC_RPL_MSG_TYPE_INSTANCE_CLEANUP: + DEBUG("RPL: GNRC_RPL_MSG_TYPE_INSTANCE_CLEANUP received\n"); + instance = msg.content.ptr; + if (instance->dodag.parents == NULL) { + gnrc_rpl_instance_remove(instance); + } + break; case GNRC_RPL_MSG_TYPE_TRICKLE_MSG: DEBUG("RPL: GNRC_RPL_MSG_TYPE_TRICKLE_MSG received\n"); trickle = msg.content.ptr; @@ -245,73 +308,44 @@ static void *_event_loop(void *args) return NULL; } +#ifdef MODULE_GNRC_RPL_P2P void _update_lifetime(void) { - gnrc_rpl_parent_t *parent; - gnrc_rpl_instance_t *inst; - - for (uint8_t i = 0; i < GNRC_RPL_PARENTS_NUMOF; ++i) { - parent = &gnrc_rpl_parents[i]; - if (parent->state != 0) { - if (parent->lifetime > GNRC_RPL_LIFETIME_UPDATE_STEP) { - if (parent->lifetime <= (2 * GNRC_RPL_LIFETIME_UPDATE_STEP)) { - gnrc_rpl_send_DIS(parent->dodag->instance, &parent->addr); - } - parent->lifetime -= GNRC_RPL_LIFETIME_UPDATE_STEP; - } - else { - gnrc_rpl_dodag_t *dodag = parent->dodag; - gnrc_rpl_parent_remove(parent); - gnrc_rpl_parent_update(dodag, NULL); - } - } - } - - for (int i = 0; i < GNRC_RPL_INSTANCES_NUMOF; ++i) { - inst = &gnrc_rpl_instances[i]; - if (inst->state != 0) { - if ((inst->cleanup > 0) && (inst->dodag.parents == NULL) && - (inst->dodag.my_rank == GNRC_RPL_INFINITE_RANK)) { - inst->cleanup -= GNRC_RPL_LIFETIME_UPDATE_STEP; - if (inst->cleanup <= 0) { - /* no parents - delete this instance and DODAG */ - gnrc_rpl_instance_remove(inst); - continue; - } - } - - if (inst->dodag.dao_time > GNRC_RPL_LIFETIME_UPDATE_STEP) { - inst->dodag.dao_time -= GNRC_RPL_LIFETIME_UPDATE_STEP; - } - else { - _dao_handle_send(&inst->dodag); - } - } - } - -#ifdef MODULE_GNRC_RPL_P2P gnrc_rpl_p2p_update(); -#endif xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid); } +#endif void gnrc_rpl_delay_dao(gnrc_rpl_dodag_t *dodag) { - dodag->dao_time = GNRC_RPL_DEFAULT_DAO_DELAY; + evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->dao_event); + ((evtimer_event_t *)&(dodag->dao_event))->offset = random_uint32_range( + GNRC_RPL_DAO_DELAY_DEFAULT, + GNRC_RPL_DAO_DELAY_DEFAULT + GNRC_RPL_DAO_DELAY_JITTER + ); + evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->dao_event, gnrc_rpl_pid); dodag->dao_counter = 0; dodag->dao_ack_received = false; } void gnrc_rpl_long_delay_dao(gnrc_rpl_dodag_t *dodag) { - dodag->dao_time = GNRC_RPL_REGULAR_DAO_INTERVAL; + evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->dao_event); + ((evtimer_event_t *)&(dodag->dao_event))->offset = random_uint32_range( + GNRC_RPL_DAO_DELAY_LONG, + GNRC_RPL_DAO_DELAY_LONG + GNRC_RPL_DAO_DELAY_JITTER + ); + evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->dao_event, gnrc_rpl_pid); dodag->dao_counter = 0; dodag->dao_ack_received = false; } void _dao_handle_send(gnrc_rpl_dodag_t *dodag) { + if (dodag->node_status == GNRC_RPL_ROOT_NODE) { + return; + } #ifdef MODULE_GNRC_RPL_P2P if (dodag->instance->mop == GNRC_RPL_P2P_MOP) { return; @@ -320,7 +354,9 @@ void _dao_handle_send(gnrc_rpl_dodag_t *dodag) if ((dodag->dao_ack_received == false) && (dodag->dao_counter < GNRC_RPL_DAO_SEND_RETRIES)) { dodag->dao_counter++; gnrc_rpl_send_DAO(dodag->instance, NULL, dodag->default_lifetime); - dodag->dao_time = GNRC_RPL_DEFAULT_WAIT_FOR_DAO_ACK; + evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->dao_event); + ((evtimer_event_t *)&(dodag->dao_event))->offset = GNRC_RPL_DAO_ACK_DELAY; + evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->dao_event, gnrc_rpl_pid); } else if (dodag->dao_ack_received == false) { gnrc_rpl_long_delay_dao(dodag); 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 9e467ff3c7fc2fe9b32a03155003f98a502c81dc..34436329e42850d33c306829a2df2d88e68f666a 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -24,6 +24,7 @@ #include "net/gnrc/netif/internal.h" #include "net/gnrc.h" #include "net/eui64.h" +#include "gnrc_rpl_internal/globals.h" #ifdef MODULE_NETSTATS_RPL #include "gnrc_rpl_internal/netstats.h" @@ -688,7 +689,7 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src /* sender of incoming DIO is not a parent of mine (anymore) and has an INFINITE rank and I have a rank != INFINITE_RANK */ - if (parent->state == 0) { + if (parent->state == GNRC_RPL_PARENT_UNUSED) { if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) && (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) { trickle_reset_timer(&dodag->trickle); diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c index 1fb5cf3efc9a4d297f96b1beb4e1db705d4624d4..c989ca5656242a8b5cc177ad8d22a99612aa231e 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c @@ -22,6 +22,7 @@ #include "net/gnrc/netif/internal.h" #include "net/gnrc/rpl/dodag.h" #include "net/gnrc/rpl/structs.h" +#include "gnrc_rpl_internal/globals.h" #include "utlist.h" #include "net/gnrc/rpl.h" @@ -87,6 +88,7 @@ bool gnrc_rpl_instance_add(uint8_t instance_id, gnrc_rpl_instance_t **inst) (*inst)->max_rank_inc = GNRC_RPL_DEFAULT_MAX_RANK_INCREASE; (*inst)->min_hop_rank_inc = GNRC_RPL_DEFAULT_MIN_HOP_RANK_INCREASE; (*inst)->dodag.parents = NULL; + (*inst)->cleanup_event.msg.content.ptr = (*inst); return true; } @@ -151,6 +153,8 @@ bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, k dodag->dao_counter = 0; dodag->instance = instance; dodag->iface = iface; + dodag->dao_event.msg.content.ptr = instance; + dodag->dao_event.msg.type = GNRC_RPL_MSG_TYPE_DODAG_DAO_TX; if ((netif != NULL) && !(netif->flags & GNRC_NETIF_FLAGS_IPV6_FORWARDING)) { gnrc_rpl_leaf_operation(dodag); @@ -199,8 +203,13 @@ bool gnrc_rpl_parent_add_by_addr(gnrc_rpl_dodag_t *dodag, ipv6_addr_t *addr, if (*parent != NULL) { (*parent)->dodag = dodag; LL_APPEND(dodag->parents, *parent); - (*parent)->state = 1; + (*parent)->state = GNRC_RPL_PARENT_ACTIVE; (*parent)->addr = *addr; + (*parent)->rank = GNRC_RPL_INFINITE_RANK; + evtimer_del((evtimer_t *)(&gnrc_rpl_evtimer), (evtimer_event_t *)(&(*parent)->timeout_event)); + ((evtimer_event_t *)(&(*parent)->timeout_event))->next = NULL; + (*parent)->timeout_event.msg.type = GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT; + (*parent)->timeout_event.msg.content.ptr = (*parent); return true; } @@ -221,13 +230,13 @@ bool gnrc_rpl_parent_remove(gnrc_rpl_parent_t *parent) /* set the default route to the next parent for now */ if (parent->next) { - uint32_t now = xtimer_now_usec() / US_PER_SEC; gnrc_ipv6_nib_ft_add(NULL, 0, &parent->next->addr, dodag->iface, - (parent->next->lifetime - now)); + dodag->default_lifetime * dodag->lifetime_unit * MS_PER_SEC); } } LL_DELETE(dodag->parents, parent); + evtimer_del((evtimer_t *)(&gnrc_rpl_evtimer), (evtimer_event_t *)&parent->timeout_event); memset(parent, 0, sizeof(gnrc_rpl_parent_t)); return true; } @@ -246,15 +255,22 @@ void gnrc_rpl_local_repair(gnrc_rpl_dodag_t *dodag) if (dodag->my_rank != GNRC_RPL_INFINITE_RANK) { dodag->my_rank = GNRC_RPL_INFINITE_RANK; trickle_reset_timer(&dodag->trickle); - dodag->instance->cleanup = GNRC_RPL_CLEANUP_TIME; + evtimer_del((evtimer_t *)(&gnrc_rpl_evtimer), (evtimer_event_t *)&dodag->instance->cleanup_event); + ((evtimer_event_t *)&(dodag->instance->cleanup_event))->offset = GNRC_RPL_CLEANUP_TIME; + dodag->instance->cleanup_event.msg.type = GNRC_RPL_MSG_TYPE_INSTANCE_CLEANUP; + evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->instance->cleanup_event, gnrc_rpl_pid); } } void gnrc_rpl_parent_update(gnrc_rpl_dodag_t *dodag, gnrc_rpl_parent_t *parent) { /* update Parent lifetime */ - if (parent != NULL) { - parent->lifetime = dodag->default_lifetime * dodag->lifetime_unit; + if ((parent != NULL) && (parent->state != GNRC_RPL_PARENT_UNUSED)) { + parent->state = GNRC_RPL_PARENT_ACTIVE; + evtimer_del((evtimer_t *)(&gnrc_rpl_evtimer), (evtimer_event_t *)&parent->timeout_event); + ((evtimer_event_t *)&(parent->timeout_event))->offset = dodag->default_lifetime * dodag->lifetime_unit * MS_PER_SEC; + parent->timeout_event.msg.type = GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT; + evtimer_add_msg(&gnrc_rpl_evtimer, &parent->timeout_event, gnrc_rpl_pid); #ifdef MODULE_GNRC_RPL_P2P if (dodag->instance->mop != GNRC_RPL_P2P_MOP) { #endif diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_internal/globals.h b/sys/net/gnrc/routing/rpl/gnrc_rpl_internal/globals.h new file mode 100644 index 0000000000000000000000000000000000000000..43bbf482529cb9f9edb0f05cb088d7eb7663abf8 --- /dev/null +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_internal/globals.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2017 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup net_gnrc_rpl + * @{ + * + * @file + * @brief Internal globals for RPL + * + * @author Cenk Gündoğan <mail-github@cgundogan.de> + */ + +#ifndef GLOBALS_H +#define GLOBALS_H + +#include "evtimer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Event queue for msg events. + */ +extern evtimer_msg_t gnrc_rpl_evtimer; + +/** + * @defgroup gnrc_rpl_events RPL events + * Events for RPL. + * @{ + */ +/** + * @brief Message type for parent timeouts. + */ +#define GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT (0x0904) +/** + * @brief Message type for instance cleanup. + */ +#define GNRC_RPL_MSG_TYPE_INSTANCE_CLEANUP (0x0905) +/** + * @brief Message type for DAO transmissions. + */ +#define GNRC_RPL_MSG_TYPE_DODAG_DAO_TX (0x0906) +/** @} */ + +/** + * @brief Interval in milliseconds to probe a parent with DIS messages. + */ +#define GNRC_RPL_PARENT_PROBE_INTERVAL (2 * MS_PER_SEC) + +/** + * @defgroup gnrc_rpl_parent_states Parent states + * State of a RPL parent + * @{ + */ +/** + * @brief Parent is unused. + */ +#define GNRC_RPL_PARENT_UNUSED (0) +/** + * @brief Parent is active. + */ +#define GNRC_RPL_PARENT_ACTIVE (1) +/** + * @brief Parent is stale. + */ +#define GNRC_RPL_PARENT_STALE (2) +/** + * @brief Parent has timed out. + */ +#define GNRC_RPL_PARENT_TIMEOUT (GNRC_RPL_PARENT_STALE + GNRC_RPL_PARENT_TIMEOUT_DIS_RETRIES) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* GLOBALS_H */ +/** @} */