Implement RPL non-storing mode
This commit is contained in:
parent
d14b76d869
commit
b3e31e1456
17 changed files with 1149 additions and 278 deletions
211
core/net/rpl/rpl-ns.c
Normal file
211
core/net/rpl/rpl-ns.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Inria.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* RPL non-storing mode specific functions. Includes support for
|
||||
* source routing.
|
||||
*
|
||||
* \author Simon Duquennoy <simon.duquennoy@inria.fr>
|
||||
*/
|
||||
|
||||
#include "net/rpl/rpl-conf.h"
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ip/tcpip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/rpl/rpl-private.h"
|
||||
#include "net/rpl/rpl-ns.h"
|
||||
#include "lib/list.h"
|
||||
#include "lib/memb.h"
|
||||
|
||||
#if RPL_WITH_NON_STORING
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ip/uip-debug.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Total number of nodes */
|
||||
static int num_nodes;
|
||||
|
||||
/* Every known node in the network */
|
||||
LIST(nodelist);
|
||||
MEMB(nodememb, rpl_ns_node_t, RPL_NS_LINK_NUM);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ns_num_nodes()
|
||||
{
|
||||
return num_nodes;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
node_matches_address(const rpl_dag_t *dag, const rpl_ns_node_t *node, const uip_ipaddr_t *addr)
|
||||
{
|
||||
return addr != NULL
|
||||
&& node != NULL
|
||||
&& dag != NULL
|
||||
&& dag == node->dag
|
||||
&& !memcmp(addr, &node->dag->dag_id, 8)
|
||||
&& !memcmp(((const unsigned char *)addr) + 8, node->link_identifier, 8);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_ns_node_t *
|
||||
rpl_ns_get_node(const rpl_dag_t *dag, const uip_ipaddr_t *addr)
|
||||
{
|
||||
rpl_ns_node_t *l;
|
||||
for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) {
|
||||
/* Compare prefix and node identifier */
|
||||
if(node_matches_address(dag, l, addr)) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ns_is_node_reachable(const rpl_dag_t *dag, const uip_ipaddr_t *addr)
|
||||
{
|
||||
int max_depth = RPL_NS_LINK_NUM;
|
||||
rpl_ns_node_t *node = rpl_ns_get_node(dag, addr);
|
||||
rpl_ns_node_t *root_node = rpl_ns_get_node(dag, dag != NULL ? &dag->dag_id : NULL);
|
||||
while(node != NULL && node != root_node && max_depth > 0) {
|
||||
node = node->parent;
|
||||
max_depth--;
|
||||
}
|
||||
return node != NULL && node == root_node;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_ns_expire_parent(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent)
|
||||
{
|
||||
rpl_ns_node_t *l = rpl_ns_get_node(dag, child);
|
||||
/* Check if parent matches */
|
||||
if(l != NULL && node_matches_address(dag, l->parent, parent)) {
|
||||
l->lifetime = RPL_NOPATH_REMOVAL_DELAY;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_ns_node_t *
|
||||
rpl_ns_update_node(rpl_dag_t *dag, const uip_ipaddr_t *child, const uip_ipaddr_t *parent, uint32_t lifetime)
|
||||
{
|
||||
rpl_ns_node_t *child_node = rpl_ns_get_node(dag, child);
|
||||
rpl_ns_node_t *parent_node = rpl_ns_get_node(dag, parent);
|
||||
|
||||
if(parent != NULL) {
|
||||
/* No node for the parent, add one with infinite lifetime */
|
||||
if(parent_node == NULL) {
|
||||
parent_node = rpl_ns_update_node(dag, parent, NULL, 0xffffffff);
|
||||
if(parent_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No node for this child, add one */
|
||||
if(child_node == NULL) {
|
||||
child_node = memb_alloc(&nodememb);
|
||||
/* No space left, abort */
|
||||
if(child_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
list_add(nodelist, child_node);
|
||||
num_nodes++;
|
||||
}
|
||||
|
||||
/* Initialize node */
|
||||
child_node->dag = dag;
|
||||
child_node->lifetime = lifetime;
|
||||
child_node->parent = parent_node;
|
||||
memcpy(child_node->link_identifier, ((const unsigned char *)child) + 8, 8);
|
||||
|
||||
return child_node;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_ns_init()
|
||||
{
|
||||
num_nodes = 0;
|
||||
memb_init(&nodememb);
|
||||
list_init(nodelist);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_ns_node_t *rpl_ns_node_head()
|
||||
{
|
||||
return list_head(nodelist);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_ns_node_t *rpl_ns_node_next(rpl_ns_node_t *item)
|
||||
{
|
||||
return list_item_next(item);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_ns_get_node_global_addr(uip_ipaddr_t *addr, rpl_ns_node_t *node)
|
||||
{
|
||||
if(addr != NULL && node != NULL && node->dag != NULL) {
|
||||
memcpy(addr, &node->dag->dag_id, 8);
|
||||
memcpy(((unsigned char *)addr) + 8, &node->link_identifier, 8);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_ns_periodic()
|
||||
{
|
||||
rpl_ns_node_t *l;
|
||||
/* First pass, decrement lifetime for all nodes with non-infinite lifetime */
|
||||
for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) {
|
||||
/* Don't touch infinite lifetime nodes */
|
||||
if(l->lifetime != 0xffffffff && l->lifetime > 0) {
|
||||
l->lifetime--;
|
||||
}
|
||||
}
|
||||
/* Second pass, for all expire nodes, deallocate them iff no child points to them */
|
||||
for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) {
|
||||
if(l->lifetime == 0) {
|
||||
rpl_ns_node_t *l2;
|
||||
for(l2 = list_head(nodelist); l2 != NULL; l2 = list_item_next(l2)) {
|
||||
if(l2->parent == l) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* No child found, deallocate node */
|
||||
list_remove(nodelist, l);
|
||||
memb_free(&nodememb, l);
|
||||
num_nodes--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RPL_WITH_NON_STORING */
|
Loading…
Add table
Add a link
Reference in a new issue