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:
parent
ede5b8ffc3
commit
a495b31ee0
9 changed files with 368 additions and 2 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
77
samples/net/rpl-mesh-qemu/README.md
Normal file
77
samples/net/rpl-mesh-qemu/README.md
Normal 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.
|
9
samples/net/rpl-mesh-qemu/node/CMakeLists.txt
Normal file
9
samples/net/rpl-mesh-qemu/node/CMakeLists.txt
Normal 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)
|
60
samples/net/rpl-mesh-qemu/node/prj_qemu.conf
Normal file
60
samples/net/rpl-mesh-qemu/node/prj_qemu.conf
Normal 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
|
13
samples/net/rpl-mesh-qemu/node/src/main.c
Normal file
13
samples/net/rpl-mesh-qemu/node/src/main.c
Normal 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");
|
||||||
|
}
|
11
samples/net/rpl-mesh-qemu/root/CMakeLists.txt
Normal file
11
samples/net/rpl-mesh-qemu/root/CMakeLists.txt
Normal 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)
|
69
samples/net/rpl-mesh-qemu/root/prj_qemu.conf
Normal file
69
samples/net/rpl-mesh-qemu/root/prj_qemu.conf
Normal 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
|
83
samples/net/rpl-mesh-qemu/root/src/main.c
Normal file
83
samples/net/rpl-mesh-qemu/root/src/main.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue