blob: 8bd8756c664036a9d13dc26cf5bdb065e74fe9df [file] [log] [blame]
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#if 1
#define SYS_LOG_DOMAIN "rpl-br/rpl"
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif
#include <zephyr.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/net_ip.h>
#include "../../../subsys/net/ip/rpl.h"
#include "config.h"
static struct {
struct in6_addr dag_id;
u8_t dag_init_version;
bool dag_has_version;
struct in6_addr prefix;
u8_t prefix_len;
} rpl;
static bool br_join_dag(struct net_rpl_dio *dio)
{
static u8_t last_version;
if (net_ipv6_addr_cmp(&dio->dag_id, &rpl.dag_id)) {
if (rpl.dag_init_version != dio->version &&
last_version != dio->version) {
NET_DBG("Me root, DIO version %d instance %d",
dio->version, dio->instance_id);
last_version = dio->version;
}
if (dio->version > NET_RPL_LOLLIPOP_CIRCULAR_REGION) {
rpl.dag_init_version = dio->version;
rpl.dag_has_version = true;
}
#if CONFIG_SYS_LOG_NET_LEVEL > 3
} else {
char me[NET_IPV6_ADDR_LEN];
char other[NET_IPV6_ADDR_LEN];
net_addr_ntop(AF_INET6, &dio->dag_id, other,
NET_IPV6_ADDR_LEN);
net_addr_ntop(AF_INET6, &rpl.dag_id, me, NET_IPV6_ADDR_LEN);
NET_DBG("Other root %s, me %s, DIO version %d instance %d",
other, me, dio->version, dio->instance_id);
#endif
}
return 0;
}
bool setup_rpl(struct net_if *iface, const char *addr_prefix)
{
char prefix[NET_IPV6_ADDR_LEN + 1];
struct net_rpl_dag *dag;
char *slash;
bool ret;
/* As the addr_prefix is Kconfig option we need to copy it to temporary
* buffer in order to be able to manipulate it.
*/
memset(prefix, 0, sizeof(prefix));
memcpy(prefix, addr_prefix, min(strlen(addr_prefix),
NET_IPV6_ADDR_LEN));
slash = strstr(prefix, "/");
if (!slash) {
rpl.prefix_len = 64;
} else {
*slash = '\0';
rpl.prefix_len = atoi(slash + 1);
}
if (rpl.prefix_len == 0) {
NET_ERR("Invalid prefix length %s", slash + 1);
return false;
}
if (net_addr_pton(AF_INET6, prefix, &rpl.prefix) < 0) {
NET_ERR("Invalid IPv6 prefix %s", prefix);
return false;
}
net_rpl_set_join_callback(br_join_dag);
if (rpl.dag_has_version) {
net_rpl_lollipop_increment(&rpl.dag_init_version);
dag = net_rpl_set_root_with_version(iface,
CONFIG_NET_RPL_DEFAULT_INSTANCE, &rpl.dag_id,
rpl.dag_init_version);
} else {
dag = net_rpl_set_root(iface, CONFIG_NET_RPL_DEFAULT_INSTANCE,
&rpl.prefix);
}
if (!dag) {
NET_ERR("Cannot set root node");
return false;
}
net_rpl_dag_set_grounded_status(dag, 1);
ret = net_rpl_set_prefix(iface, dag, &rpl.prefix, rpl.prefix_len);
if (!ret) {
NET_ERR("Cannot set prefix %s/%d", prefix, rpl.prefix_len);
return false;
}
#if CONFIG_SYS_LOG_NET_LEVEL > 3
{
char out[NET_IPV6_ADDR_LEN];
if (net_addr_ntop(AF_INET6, &rpl.prefix, out,
NET_IPV6_ADDR_LEN)) {
if (rpl.dag_has_version) {
NET_DBG("New RPL dag %s/%d version %u created",
out, rpl.prefix_len,
rpl.dag_init_version);
} else {
NET_DBG("New RPL dag %s/%d created", out,
rpl.prefix_len);
}
}
}
#endif
return true;
}