2015-08-17 15:41:29 +02:00
|
|
|
|
/*
|
2017-11-30 21:23:44 +01:00
|
|
|
|
* Copyright (C) 2018 HAW Hamburg
|
|
|
|
|
* Copyright (C) 2015–2017 Cenk Gündoğan <cenk.guendogan@haw-hamburg.de>
|
2015-08-17 15:41:29 +02:00
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @{
|
|
|
|
|
*
|
|
|
|
|
* @file
|
|
|
|
|
*
|
2017-11-30 21:23:44 +01:00
|
|
|
|
* @author Cenk Gündoğan <cenk.guendogan@haw-hamburg.de>
|
2015-08-17 15:41:29 +02:00
|
|
|
|
*/
|
|
|
|
|
|
2020-10-21 15:58:33 +02:00
|
|
|
|
#include <assert.h>
|
2018-07-21 10:13:00 +02:00
|
|
|
|
#include <string.h>
|
2020-04-23 11:15:45 +02:00
|
|
|
|
#include "kernel_defines.h"
|
2018-07-21 10:13:00 +02:00
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
#include "net/icmpv6.h"
|
|
|
|
|
#include "net/ipv6.h"
|
2017-11-16 18:06:46 +01:00
|
|
|
|
#include "net/gnrc/netif/internal.h"
|
2015-08-17 15:41:29 +02:00
|
|
|
|
#include "net/gnrc.h"
|
2015-08-23 18:07:49 +02:00
|
|
|
|
#include "mutex.h"
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#include "evtimer.h"
|
|
|
|
|
#include "random.h"
|
|
|
|
|
#include "gnrc_rpl_internal/globals.h"
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
|
|
|
|
#include "net/gnrc/rpl.h"
|
2015-08-23 14:25:39 +02:00
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
|
|
|
|
#include "net/gnrc/rpl/p2p.h"
|
|
|
|
|
#include "net/gnrc/rpl/p2p_dodag.h"
|
|
|
|
|
#endif
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
|
|
|
|
#define ENABLE_DEBUG (0)
|
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
|
|
static char _stack[GNRC_RPL_STACK_SIZE];
|
|
|
|
|
kernel_pid_t gnrc_rpl_pid = KERNEL_PID_UNDEF;
|
2016-03-22 10:17:32 +01:00
|
|
|
|
const ipv6_addr_t ipv6_addr_all_rpl_nodes = GNRC_RPL_ALL_NODES_ADDR;
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
2017-01-17 16:44:05 +01:00
|
|
|
|
static uint32_t _lt_time = GNRC_RPL_LIFETIME_UPDATE_STEP * US_PER_SEC;
|
2015-09-04 13:19:19 +02:00
|
|
|
|
static xtimer_t _lt_timer;
|
|
|
|
|
static msg_t _lt_msg = { .type = GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE };
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#endif
|
2020-05-15 10:18:56 +02:00
|
|
|
|
static msg_t _msg_q[GNRC_RPL_MSG_QUEUE_SIZE];
|
2015-08-17 15:41:29 +02:00
|
|
|
|
static gnrc_netreg_entry_t _me_reg;
|
2015-08-23 18:07:49 +02:00
|
|
|
|
static mutex_t _inst_id_mutex = MUTEX_INIT;
|
|
|
|
|
static uint8_t _instance_id;
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
|
|
|
|
gnrc_rpl_instance_t gnrc_rpl_instances[GNRC_RPL_INSTANCES_NUMOF];
|
|
|
|
|
gnrc_rpl_parent_t gnrc_rpl_parents[GNRC_RPL_PARENTS_NUMOF];
|
|
|
|
|
|
2016-06-01 14:04:28 +02:00
|
|
|
|
#ifdef MODULE_NETSTATS_RPL
|
|
|
|
|
netstats_rpl_t gnrc_rpl_netstats;
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
2015-08-17 15:41:29 +02:00
|
|
|
|
static void _update_lifetime(void);
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#endif
|
2015-08-17 15:41:29 +02:00
|
|
|
|
static void _dao_handle_send(gnrc_rpl_dodag_t *dodag);
|
|
|
|
|
static void _receive(gnrc_pktsnip_t *pkt);
|
|
|
|
|
static void *_event_loop(void *args);
|
|
|
|
|
|
2017-11-30 21:23:26 +01:00
|
|
|
|
evtimer_msg_t gnrc_rpl_evtimer;
|
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid)
|
|
|
|
|
{
|
|
|
|
|
/* check if RPL was initialized before */
|
|
|
|
|
if (gnrc_rpl_pid == KERNEL_PID_UNDEF) {
|
2020-10-12 10:03:02 +02:00
|
|
|
|
mutex_t eventloop_startup = MUTEX_INIT_LOCKED;
|
|
|
|
|
|
2015-08-23 18:07:49 +02:00
|
|
|
|
_instance_id = 0;
|
2015-08-17 15:41:29 +02:00
|
|
|
|
/* start the event loop */
|
2015-12-02 12:00:19 +01:00
|
|
|
|
gnrc_rpl_pid = thread_create(_stack, sizeof(_stack), GNRC_RPL_PRIO,
|
|
|
|
|
THREAD_CREATE_STACKTEST,
|
2020-10-12 10:03:02 +02:00
|
|
|
|
_event_loop, (void*)&eventloop_startup,
|
|
|
|
|
"RPL");
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
|
|
|
|
if (gnrc_rpl_pid == KERNEL_PID_UNDEF) {
|
|
|
|
|
DEBUG("RPL: could not start the event loop\n");
|
|
|
|
|
return KERNEL_PID_UNDEF;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-12 10:03:02 +02:00
|
|
|
|
/* Wait for the event loop to indicate that it set up its message
|
|
|
|
|
* queue, and registration with netreg can commence. */
|
|
|
|
|
mutex_lock(&eventloop_startup);
|
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
_me_reg.demux_ctx = ICMPV6_RPL_CTRL;
|
2016-08-11 15:13:50 +02:00
|
|
|
|
_me_reg.target.pid = gnrc_rpl_pid;
|
2015-08-17 15:41:29 +02:00
|
|
|
|
/* register interest in all ICMPv6 packets */
|
|
|
|
|
gnrc_netreg_register(GNRC_NETTYPE_ICMPV6, &_me_reg);
|
|
|
|
|
|
|
|
|
|
gnrc_rpl_of_manager_init();
|
2017-11-30 21:23:26 +01:00
|
|
|
|
evtimer_init_msg(&gnrc_rpl_evtimer);
|
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
2015-09-04 13:19:19 +02:00
|
|
|
|
xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid);
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#endif
|
2016-06-01 14:04:28 +02:00
|
|
|
|
|
|
|
|
|
#ifdef MODULE_NETSTATS_RPL
|
|
|
|
|
memset(&gnrc_rpl_netstats, 0, sizeof(gnrc_rpl_netstats));
|
|
|
|
|
#endif
|
2015-08-17 15:41:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* register all_RPL_nodes multicast address */
|
2017-12-13 13:40:40 +01:00
|
|
|
|
gnrc_netif_ipv6_group_join_internal(gnrc_netif_get_by_pid(if_pid),
|
|
|
|
|
&ipv6_addr_all_rpl_nodes);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
2017-04-18 09:52:34 +02:00
|
|
|
|
gnrc_rpl_send_DIS(NULL, (ipv6_addr_t *) &ipv6_addr_all_rpl_nodes, NULL, 0);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
return gnrc_rpl_pid;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-27 22:29:08 +02:00
|
|
|
|
gnrc_rpl_instance_t *gnrc_rpl_root_init(uint8_t instance_id, ipv6_addr_t *dodag_id,
|
|
|
|
|
bool gen_inst_id, bool local_inst_id)
|
2015-08-17 15:41:29 +02:00
|
|
|
|
{
|
2015-08-23 18:07:49 +02:00
|
|
|
|
if (gen_inst_id) {
|
|
|
|
|
instance_id = gnrc_rpl_gen_instance_id(local_inst_id);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-27 22:29:08 +02:00
|
|
|
|
gnrc_rpl_dodag_t *dodag = NULL;
|
|
|
|
|
gnrc_rpl_instance_t *inst = gnrc_rpl_root_instance_init(instance_id, dodag_id,
|
2016-03-22 17:35:14 +01:00
|
|
|
|
GNRC_RPL_DEFAULT_MOP);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
2015-08-27 22:29:08 +02:00
|
|
|
|
if (!inst) {
|
2015-08-17 15:41:29 +02:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-27 22:29:08 +02:00
|
|
|
|
dodag = &inst->dodag;
|
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
dodag->dtsn = 1;
|
|
|
|
|
dodag->prf = 0;
|
2020-04-17 16:51:25 +02:00
|
|
|
|
dodag->dio_interval_doubl = CONFIG_GNRC_RPL_DEFAULT_DIO_INTERVAL_DOUBLINGS;
|
2020-04-17 16:57:47 +02:00
|
|
|
|
dodag->dio_min = CONFIG_GNRC_RPL_DEFAULT_DIO_INTERVAL_MIN;
|
2020-04-23 10:21:17 +02:00
|
|
|
|
dodag->dio_redun = CONFIG_GNRC_RPL_DEFAULT_DIO_REDUNDANCY_CONSTANT;
|
2020-04-23 10:22:45 +02:00
|
|
|
|
dodag->default_lifetime = CONFIG_GNRC_RPL_DEFAULT_LIFETIME;
|
2020-04-23 10:24:02 +02:00
|
|
|
|
dodag->lifetime_unit = CONFIG_GNRC_RPL_LIFETIME_UNIT;
|
2015-08-17 15:41:29 +02:00
|
|
|
|
dodag->version = GNRC_RPL_COUNTER_INIT;
|
|
|
|
|
dodag->grounded = GNRC_RPL_GROUNDED;
|
|
|
|
|
dodag->node_status = GNRC_RPL_ROOT_NODE;
|
|
|
|
|
dodag->my_rank = GNRC_RPL_ROOT_RANK;
|
2016-03-15 15:17:46 +01:00
|
|
|
|
dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_DODAG_CONF;
|
2020-04-23 11:15:45 +02:00
|
|
|
|
|
|
|
|
|
if (!IS_ACTIVE(CONFIG_GNRC_RPL_WITHOUT_PIO)) {
|
|
|
|
|
dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_PREFIX_INFO;
|
|
|
|
|
}
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
2017-06-08 21:39:33 +02:00
|
|
|
|
trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG,
|
|
|
|
|
(1 << dodag->dio_min), dodag->dio_interval_doubl,
|
|
|
|
|
dodag->dio_redun);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
2015-08-27 22:29:08 +02:00
|
|
|
|
return inst;
|
2015-08-17 15:41:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void _receive(gnrc_pktsnip_t *icmpv6)
|
|
|
|
|
{
|
2016-03-22 14:58:23 +01:00
|
|
|
|
gnrc_pktsnip_t *ipv6, *netif;
|
|
|
|
|
ipv6_hdr_t *ipv6_hdr;
|
|
|
|
|
icmpv6_hdr_t *icmpv6_hdr;
|
|
|
|
|
kernel_pid_t iface = KERNEL_PID_UNDEF;
|
|
|
|
|
|
|
|
|
|
assert(icmpv6 != NULL);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
2016-02-11 00:48:06 +01:00
|
|
|
|
ipv6 = gnrc_pktsnip_search_type(icmpv6, GNRC_NETTYPE_IPV6);
|
2016-03-22 14:58:23 +01:00
|
|
|
|
netif = gnrc_pktsnip_search_type(icmpv6, GNRC_NETTYPE_NETIF);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
|
|
|
|
assert(ipv6 != NULL);
|
|
|
|
|
|
2016-03-22 14:58:23 +01:00
|
|
|
|
if (netif) {
|
|
|
|
|
iface = ((gnrc_netif_hdr_t *)netif->data)->if_pid;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
ipv6_hdr = (ipv6_hdr_t *)ipv6->data;
|
|
|
|
|
|
|
|
|
|
icmpv6_hdr = (icmpv6_hdr_t *)icmpv6->data;
|
|
|
|
|
switch (icmpv6_hdr->code) {
|
|
|
|
|
case GNRC_RPL_ICMPV6_CODE_DIS:
|
|
|
|
|
DEBUG("RPL: DIS received\n");
|
2016-03-22 14:58:23 +01:00
|
|
|
|
gnrc_rpl_recv_DIS((gnrc_rpl_dis_t *)(icmpv6_hdr + 1), iface, &ipv6_hdr->src,
|
|
|
|
|
&ipv6_hdr->dst, byteorder_ntohs(ipv6_hdr->len));
|
2015-08-17 15:41:29 +02:00
|
|
|
|
break;
|
|
|
|
|
case GNRC_RPL_ICMPV6_CODE_DIO:
|
|
|
|
|
DEBUG("RPL: DIO received\n");
|
2016-03-22 14:58:23 +01:00
|
|
|
|
gnrc_rpl_recv_DIO((gnrc_rpl_dio_t *)(icmpv6_hdr + 1), iface, &ipv6_hdr->src,
|
2016-06-01 14:04:28 +02:00
|
|
|
|
&ipv6_hdr->dst, byteorder_ntohs(ipv6_hdr->len));
|
2015-08-17 15:41:29 +02:00
|
|
|
|
break;
|
|
|
|
|
case GNRC_RPL_ICMPV6_CODE_DAO:
|
|
|
|
|
DEBUG("RPL: DAO received\n");
|
2016-03-22 14:58:23 +01:00
|
|
|
|
gnrc_rpl_recv_DAO((gnrc_rpl_dao_t *)(icmpv6_hdr + 1), iface, &ipv6_hdr->src,
|
2016-06-01 14:04:28 +02:00
|
|
|
|
&ipv6_hdr->dst, byteorder_ntohs(ipv6_hdr->len));
|
2015-08-17 15:41:29 +02:00
|
|
|
|
break;
|
|
|
|
|
case GNRC_RPL_ICMPV6_CODE_DAO_ACK:
|
|
|
|
|
DEBUG("RPL: DAO-ACK received\n");
|
2016-06-01 14:04:28 +02:00
|
|
|
|
gnrc_rpl_recv_DAO_ACK((gnrc_rpl_dao_ack_t *)(icmpv6_hdr + 1), iface, &ipv6_hdr->src,
|
|
|
|
|
&ipv6_hdr->dst, byteorder_ntohs(ipv6_hdr->len));
|
2015-08-17 15:41:29 +02:00
|
|
|
|
break;
|
2015-08-23 14:25:39 +02:00
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
|
|
|
|
case GNRC_RPL_P2P_ICMPV6_CODE_DRO:
|
|
|
|
|
DEBUG("RPL: P2P DRO received\n");
|
|
|
|
|
gnrc_pktsnip_t *icmpv6_snip = gnrc_pktbuf_add(NULL, NULL, icmpv6->size,
|
|
|
|
|
GNRC_NETTYPE_ICMPV6);
|
|
|
|
|
if (icmpv6_snip == NULL) {
|
|
|
|
|
DEBUG("RPL-P2P: cannot copy ICMPv6 packet\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(icmpv6_snip->data, icmpv6->data, icmpv6->size);
|
|
|
|
|
|
|
|
|
|
gnrc_rpl_p2p_recv_DRO(icmpv6_snip, &ipv6_hdr->src);
|
|
|
|
|
break;
|
|
|
|
|
case GNRC_RPL_P2P_ICMPV6_CODE_DRO_ACK:
|
|
|
|
|
DEBUG("RPL: P2P DRO-ACK received\n");
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
2015-08-17 15:41:29 +02:00
|
|
|
|
default:
|
|
|
|
|
DEBUG("RPL: Unknown ICMPV6 code received\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gnrc_pktbuf_release(icmpv6);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-30 21:23:26 +01:00
|
|
|
|
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++;
|
2017-04-18 09:52:34 +02:00
|
|
|
|
gnrc_rpl_send_DIS(parent->dodag->instance, &parent->addr, NULL, 0);
|
2017-11-30 21:23:26 +01:00
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
static void *_event_loop(void *args)
|
|
|
|
|
{
|
|
|
|
|
msg_t msg, reply;
|
|
|
|
|
|
2020-10-12 10:03:02 +02:00
|
|
|
|
{
|
|
|
|
|
mutex_t *eventloop_startup = (mutex_t*)args;
|
|
|
|
|
|
|
|
|
|
msg_init_queue(_msg_q, GNRC_RPL_MSG_QUEUE_SIZE);
|
|
|
|
|
|
|
|
|
|
/* Message queue is initialized, gnrc_rpl_init can continue and will
|
|
|
|
|
* pop the underlying mutex off its stack. */
|
|
|
|
|
mutex_unlock(eventloop_startup);
|
|
|
|
|
}
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
|
|
|
|
/* preinitialize ACK */
|
|
|
|
|
reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
|
|
|
|
|
|
|
|
|
|
trickle_t *trickle;
|
2017-11-30 21:23:26 +01:00
|
|
|
|
gnrc_rpl_parent_t *parent;
|
|
|
|
|
gnrc_rpl_instance_t *instance;
|
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
/* start event loop */
|
|
|
|
|
while (1) {
|
|
|
|
|
DEBUG("RPL: waiting for incoming message.\n");
|
|
|
|
|
msg_receive(&msg);
|
|
|
|
|
|
|
|
|
|
switch (msg.type) {
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
2015-08-17 15:41:29 +02:00
|
|
|
|
case GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE:
|
|
|
|
|
DEBUG("RPL: GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE received\n");
|
|
|
|
|
_update_lifetime();
|
|
|
|
|
break;
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#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;
|
2017-06-08 21:39:33 +02:00
|
|
|
|
case GNRC_RPL_MSG_TYPE_TRICKLE_MSG:
|
|
|
|
|
DEBUG("RPL: GNRC_RPL_MSG_TYPE_TRICKLE_MSG received\n");
|
2016-06-02 20:40:15 +02:00
|
|
|
|
trickle = msg.content.ptr;
|
2015-08-17 15:41:29 +02:00
|
|
|
|
if (trickle && (trickle->callback.func != NULL)) {
|
|
|
|
|
trickle_callback(trickle);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case GNRC_NETAPI_MSG_TYPE_RCV:
|
|
|
|
|
DEBUG("RPL: GNRC_NETAPI_MSG_TYPE_RCV received\n");
|
2016-06-02 20:40:15 +02:00
|
|
|
|
_receive(msg.content.ptr);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
break;
|
|
|
|
|
case GNRC_NETAPI_MSG_TYPE_SND:
|
2015-12-05 15:56:21 +01:00
|
|
|
|
break;
|
2015-08-17 15:41:29 +02:00
|
|
|
|
case GNRC_NETAPI_MSG_TYPE_GET:
|
|
|
|
|
case GNRC_NETAPI_MSG_TYPE_SET:
|
2015-12-05 15:56:21 +01:00
|
|
|
|
DEBUG("RPL: reply to unsupported get/set\n");
|
2015-08-17 15:41:29 +02:00
|
|
|
|
reply.content.value = -ENOTSUP;
|
|
|
|
|
msg_reply(&msg, &reply);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
2015-08-17 15:41:29 +02:00
|
|
|
|
void _update_lifetime(void)
|
|
|
|
|
{
|
2015-08-23 14:25:39 +02:00
|
|
|
|
gnrc_rpl_p2p_update();
|
|
|
|
|
|
2015-09-04 13:19:19 +02:00
|
|
|
|
xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
}
|
2017-11-30 21:23:26 +01:00
|
|
|
|
#endif
|
2015-08-17 15:41:29 +02:00
|
|
|
|
|
|
|
|
|
void gnrc_rpl_delay_dao(gnrc_rpl_dodag_t *dodag)
|
|
|
|
|
{
|
2017-11-30 21:23:26 +01:00
|
|
|
|
evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->dao_event);
|
|
|
|
|
((evtimer_event_t *)&(dodag->dao_event))->offset = random_uint32_range(
|
2020-04-23 10:30:41 +02:00
|
|
|
|
CONFIG_GNRC_RPL_DAO_DELAY_DEFAULT,
|
2020-04-23 10:34:30 +02:00
|
|
|
|
CONFIG_GNRC_RPL_DAO_DELAY_DEFAULT + CONFIG_GNRC_RPL_DAO_DELAY_JITTER
|
2017-11-30 21:23:26 +01:00
|
|
|
|
);
|
|
|
|
|
evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->dao_event, gnrc_rpl_pid);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
dodag->dao_counter = 0;
|
|
|
|
|
dodag->dao_ack_received = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void gnrc_rpl_long_delay_dao(gnrc_rpl_dodag_t *dodag)
|
|
|
|
|
{
|
2017-11-30 21:23:26 +01:00
|
|
|
|
evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->dao_event);
|
|
|
|
|
((evtimer_event_t *)&(dodag->dao_event))->offset = random_uint32_range(
|
2020-04-23 10:29:19 +02:00
|
|
|
|
CONFIG_GNRC_RPL_DAO_DELAY_LONG,
|
2020-04-23 10:34:30 +02:00
|
|
|
|
CONFIG_GNRC_RPL_DAO_DELAY_LONG + CONFIG_GNRC_RPL_DAO_DELAY_JITTER
|
2017-11-30 21:23:26 +01:00
|
|
|
|
);
|
|
|
|
|
evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->dao_event, gnrc_rpl_pid);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
dodag->dao_counter = 0;
|
|
|
|
|
dodag->dao_ack_received = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _dao_handle_send(gnrc_rpl_dodag_t *dodag)
|
|
|
|
|
{
|
2017-11-30 21:23:26 +01:00
|
|
|
|
if (dodag->node_status == GNRC_RPL_ROOT_NODE) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2015-08-23 14:25:39 +02:00
|
|
|
|
#ifdef MODULE_GNRC_RPL_P2P
|
|
|
|
|
if (dodag->instance->mop == GNRC_RPL_P2P_MOP) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2020-04-23 10:25:18 +02:00
|
|
|
|
if ((dodag->dao_ack_received == false) &&
|
|
|
|
|
(dodag->dao_counter < CONFIG_GNRC_RPL_DAO_SEND_RETRIES)) {
|
2015-08-17 15:41:29 +02:00
|
|
|
|
dodag->dao_counter++;
|
2015-08-27 22:29:08 +02:00
|
|
|
|
gnrc_rpl_send_DAO(dodag->instance, NULL, dodag->default_lifetime);
|
2017-11-30 21:23:26 +01:00
|
|
|
|
evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->dao_event);
|
2020-04-23 10:28:02 +02:00
|
|
|
|
((evtimer_event_t *)&(dodag->dao_event))->offset = CONFIG_GNRC_RPL_DAO_ACK_DELAY;
|
2017-11-30 21:23:26 +01:00
|
|
|
|
evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->dao_event, gnrc_rpl_pid);
|
2015-08-17 15:41:29 +02:00
|
|
|
|
}
|
|
|
|
|
else if (dodag->dao_ack_received == false) {
|
|
|
|
|
gnrc_rpl_long_delay_dao(dodag);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-23 18:07:49 +02:00
|
|
|
|
uint8_t gnrc_rpl_gen_instance_id(bool local)
|
|
|
|
|
{
|
|
|
|
|
mutex_lock(&_inst_id_mutex);
|
2020-04-24 13:15:23 +02:00
|
|
|
|
uint8_t instance_id = CONFIG_GNRC_RPL_DEFAULT_INSTANCE;
|
2015-08-23 18:07:49 +02:00
|
|
|
|
|
|
|
|
|
if (local) {
|
|
|
|
|
instance_id = ((_instance_id++) | GNRC_RPL_INSTANCE_ID_MSB);
|
|
|
|
|
mutex_unlock(&_inst_id_mutex);
|
|
|
|
|
return instance_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instance_id = ((_instance_id++) & GNRC_RPL_GLOBAL_INSTANCE_MASK);
|
|
|
|
|
mutex_unlock(&_inst_id_mutex);
|
|
|
|
|
return instance_id;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-17 15:41:29 +02:00
|
|
|
|
/**
|
|
|
|
|
* @}
|
|
|
|
|
*/
|