sample: net: RPL mesh sample over QEMU

Create a net sample to setup a multi-node RPL mesh network using QMEU.
To enable this, it was necessary implement a hw filter on IEEE 802.15.4
UART Pipe driver and create a QEMU pipe management on cmake.

This sample use a tool developed on zephyr net-tools repository called
virtual-hub.

Signed-off-by: Pedro Martucci <pedropaulomartucci@gmail.com>
This commit is contained in:
Pedro Martucci 2018-02-14 11:17:56 -02:00 committed by Jukka Rissanen
commit a495b31ee0
9 changed files with 368 additions and 2 deletions

2
.gitignore vendored
View file

@ -8,6 +8,7 @@
*.swo *.swo
*~ *~
build build
build-*
cscope.* cscope.*
.dir .dir
outdir outdir
@ -37,3 +38,4 @@ tags
.cproject .cproject
.xxproject .xxproject
.envrc .envrc
.vscode

View file

@ -66,7 +66,49 @@ if(CONFIG_NETWORKING)
endif() endif()
endif() endif()
if(QEMU_NET_STACK) # TO create independent pipes for each QEMU application set QEMU_PIPE_STACK
if(QEMU_PIPE_STACK)
list(APPEND qemu_targets
node
)
if(NOT QEMU_PIPE_ID)
set(QEMU_PIPE_ID 1)
endif()
list(APPEND QEMU_FLAGS
-serial none
)
list(APPEND MORE_FLAGS_FOR_node
-serial pipe:/tmp/hub/ip-stack-node${QEMU_PIPE_ID}
-pidfile qemu-node${QEMU_PIPE_ID}.pid
)
set(PIPE_NODE_IN /tmp/hub/ip-stack-node${QEMU_PIPE_ID}.in)
set(PIPE_NODE_OUT /tmp/hub/ip-stack-node${QEMU_PIPE_ID}.out)
set(pipes
${PIPE_NODE_IN}
${PIPE_NODE_OUT}
)
set(destroy_pipe_commands
COMMAND ${CMAKE_COMMAND} -E remove -f ${pipes}
)
set(create_pipe_commands
COMMAND ${CMAKE_COMMAND} -E make_directory /tmp/hub
COMMAND mkfifo ${PIPE_NODE_IN}
COMMAND mkfifo ${PIPE_NODE_OUT}
)
set(PRE_QEMU_COMMANDS_FOR_node
${destroy_pipe_commands}
${create_pipe_commands}
)
elseif(QEMU_NET_STACK)
list(APPEND qemu_targets list(APPEND qemu_targets
client client
server server
@ -153,7 +195,7 @@ if(QEMU_NET_STACK)
# TODO: Support cleanup of the monitor_15_4 process # TODO: Support cleanup of the monitor_15_4 process
) )
endif() endif()
endif(QEMU_NET_STACK) endif(QEMU_PIPE_STACK)
if(CONFIG_X86_IAMCU) if(CONFIG_X86_IAMCU)
list(APPEND PRE_QEMU_COMMANDS list(APPEND PRE_QEMU_COMMANDS

View file

@ -0,0 +1,77 @@
# RPL Mesh Network over QEMU
Overview
********
This sample uses virtual-hub tool from zephyrproject-rtos/net-tools
to setup a multi-node RPL network on top of QEMU. This way, is possible
to validate different network topologies in virtualized environment.
In this sample, we will build a three node graph connected like a row:
root <-> node1 <-> node2
Requirements
************
First of all, we must clone net-tools repository, and build virtual-hub:
```
cd virtual-hub
mkdir build && cd build
cmake ..
make
```
Building and Running
********************
1. Build and run the RPL root application:
```
cd root
mkdir build && cd build
cmake -DQEMU_PIPE_ID=1 ..
make
make node
```
2. Build and run the first RPL node application:
```
cd node
mkdir build-1 && cd build-1
cmake -DQEMU_PIPE_ID=2 ..
make
make node
```
3. Build and run the second RPL node application:
```
cd node
mkdir build-2 && cd build-2
cmake -DQEMU_PIPE_ID=3 ..
make
make node
```
4. Now we should run the virtual-hub, which will connect
all the pipes according to the csv file:
```
cd virtual-hub/build
./hub ../input.csv
```
5. Wait until the network is fine, you can check it
using net shell on root application:
```
select net
route
```
You should see two routes pointing to both clients application.
Virtual-Hub Notes
*****************
When trying to reboot/drop a node from network you must
also reboot the virtual-hub to keep it working properly.
For more details about how to customize the network, follow the
README instructions from virtual-hub repository.

View file

@ -0,0 +1,9 @@
set(BOARD qemu_cortex_m3)
set(CONF_FILE prj_qemu.conf)
set(QEMU_PIPE_STACK 1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,60 @@
#### Initial Configuration ############################
# Enable basic networking
CONFIG_NETWORKING=y
# 802.15.4 requires random generator
CONFIG_TEST_RANDOM_GENERATOR=y
# Network Interface Buffer Size
CONFIG_NET_PKT_RX_COUNT=40
CONFIG_NET_PKT_TX_COUNT=40
#### Logging Configuration ############################
CONFIG_SYS_LOG=y
CONFIG_NET_LOG=y
CONFIG_SYS_LOG_NET_LEVEL=4
CONFIG_SYS_LOG_SHOW_COLOR=y
#### Network Stack Configuration ######################
# RPL (Routing)
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_PROBING=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1
# IPv6 (L3)
CONFIG_NET_IPV6=y
CONFIG_NET_DEBUG_IPV6=n
CONFIG_NET_IPV6_ND=n
CONFIG_NET_IPV6_DAD=y
CONFIG_NET_IPV6_MLD=n
# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y
CONFIG_NET_DEBUG_6LO=n
# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_DEBUG_L2_IEEE802154=n
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=n
# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=2
#### Additional Configuration #########################
# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y
CONFIG_NET_APP_IEEE802154_DEV_NAME="IEEE802154_UPIPE"
# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n
# Application Settings
CONFIG_NET_APP_SETTINGS=y

View file

@ -0,0 +1,13 @@
/*
* Copyright (c) 2017 CPqD Foundation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <misc/printk.h>
void main(void)
{
printk("RPL node running\n");
}

View file

@ -0,0 +1,11 @@
set(BOARD qemu_cortex_m3)
set(CONF_FILE prj_qemu.conf)
set(QEMU_PIPE_STACK 1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)
target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/subsys/net/ip)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,69 @@
#### Initial Configuration ############################
# Enable basic networking
CONFIG_NETWORKING=y
# 802.15.4 requires random generator
CONFIG_TEST_RANDOM_GENERATOR=y
# Network Interface Buffer Size
CONFIG_NET_PKT_RX_COUNT=40
CONFIG_NET_PKT_TX_COUNT=40
#### Logging Configuration ############################
CONFIG_SYS_LOG=y
CONFIG_NET_LOG=y
CONFIG_SYS_LOG_NET_LEVEL=4
CONFIG_SYS_LOG_SHOW_COLOR=y
#### Network Stack Configuration ######################
# RPL (Routing)
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_GROUNDED=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1
CONFIG_NET_RPL_PREFIX="2001:db8::1/64"
# IPv6 (L3)
CONFIG_NET_IPV6=y
CONFIG_NET_DEBUG_IPV6=n
CONFIG_NET_IPV6_ND=n
CONFIG_NET_IPV6_DAD=y
CONFIG_NET_IPV6_MLD=n
# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y
CONFIG_NET_DEBUG_6LO=n
# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_DEBUG_L2_IEEE802154=n
CONFIG_NET_L2_IEEE802154_FRAGMENT=y
CONFIG_NET_DEBUG_L2_IEEE802154_FRAGMENT=n
# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y
CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL=2
#### Additional Configuration #########################
# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y
# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n
# Application Settings
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
CONFIG_NET_APP_IEEE802154_DEV_NAME="IEEE802154_UPIPE"
# MAC Setup
CONFIG_IEEE802154_UPIPE_RANDOM_MAC=n
CONFIG_IEEE802154_UPIPE_MAC4=0xAA
CONFIG_IEEE802154_UPIPE_MAC5=0xAA
CONFIG_IEEE802154_UPIPE_MAC6=0xAA
CONFIG_IEEE802154_UPIPE_MAC7=0xAA

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2017 CPqD Foundation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <misc/printk.h>
#include <stdlib.h>
#include "rpl.h"
#define CURRENT_VERSION 0
void main(void)
{
u8_t init_version = CURRENT_VERSION;
char prefix_str[NET_IPV6_ADDR_LEN + 1];
struct in6_addr prefix;
u8_t prefix_len;
printk("RPL border router starting\n");
struct net_if *iface = net_if_get_default();
if (!iface) {
printk("Interface is NULL\n");
printk("Failed to setup RPL root node\n");
return;
}
/* Read prefix from KConfig and parse it */
memset(prefix_str, 0, sizeof(prefix_str));
memcpy(prefix_str, CONFIG_NET_RPL_PREFIX,
min(strlen(CONFIG_NET_RPL_PREFIX), NET_IPV6_ADDR_LEN));
char *slash = strstr(prefix_str, "/");
if (!slash) {
prefix_len = 64;
} else {
*slash = '\0';
prefix_len = atoi(slash + 1);
}
if (prefix_len == 0) {
printk("Invalid prefix length %s", slash + 1);
return;
}
if (net_addr_pton(AF_INET6, prefix_str, &prefix) < 0) {
printk("Invalid IPv6 prefix %s", prefix_str);
return;
}
/* Check the current version */
if (CURRENT_VERSION == 0) {
/* case 0 - call init */
init_version = net_rpl_lollipop_init();
} else if (CURRENT_VERSION > 0) {
/* case > 0 - increment */
net_rpl_lollipop_increment(&init_version);
} else {
printk("CURRENT_VERSION should be greater or eqaul to 0");
return;
}
/* Setup the root node */
struct net_rpl_dag *dag = net_rpl_set_root_with_version(
iface, CONFIG_NET_RPL_DEFAULT_INSTANCE, &prefix, init_version);
if (!dag) {
printk("Cannot set root node");
return;
}
bool ret = net_rpl_set_prefix(iface, dag, &prefix, prefix_len);
if (!ret) {
printk("Cannot set prefix %s/%d", prefix_str, prefix_len);
return;
}
}