diff --git a/.gitignore b/.gitignore index ac73c5a530d..4c78c46e559 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ *.swo *~ build +build-* cscope.* .dir outdir @@ -37,3 +38,4 @@ tags .cproject .xxproject .envrc +.vscode diff --git a/cmake/emu/qemu.cmake b/cmake/emu/qemu.cmake index 2c40625719e..257298f2933 100644 --- a/cmake/emu/qemu.cmake +++ b/cmake/emu/qemu.cmake @@ -66,7 +66,49 @@ if(CONFIG_NETWORKING) 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 client server @@ -153,7 +195,7 @@ if(QEMU_NET_STACK) # TODO: Support cleanup of the monitor_15_4 process ) endif() -endif(QEMU_NET_STACK) +endif(QEMU_PIPE_STACK) if(CONFIG_X86_IAMCU) list(APPEND PRE_QEMU_COMMANDS diff --git a/samples/net/rpl-mesh-qemu/README.md b/samples/net/rpl-mesh-qemu/README.md new file mode 100644 index 00000000000..12c4bd3e092 --- /dev/null +++ b/samples/net/rpl-mesh-qemu/README.md @@ -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. \ No newline at end of file diff --git a/samples/net/rpl-mesh-qemu/node/CMakeLists.txt b/samples/net/rpl-mesh-qemu/node/CMakeLists.txt new file mode 100644 index 00000000000..87428f3f364 --- /dev/null +++ b/samples/net/rpl-mesh-qemu/node/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/samples/net/rpl-mesh-qemu/node/prj_qemu.conf b/samples/net/rpl-mesh-qemu/node/prj_qemu.conf new file mode 100644 index 00000000000..73c5c9e2a77 --- /dev/null +++ b/samples/net/rpl-mesh-qemu/node/prj_qemu.conf @@ -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 \ No newline at end of file diff --git a/samples/net/rpl-mesh-qemu/node/src/main.c b/samples/net/rpl-mesh-qemu/node/src/main.c new file mode 100644 index 00000000000..d21a4b49afb --- /dev/null +++ b/samples/net/rpl-mesh-qemu/node/src/main.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2017 CPqD Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +void main(void) +{ + printk("RPL node running\n"); +} diff --git a/samples/net/rpl-mesh-qemu/root/CMakeLists.txt b/samples/net/rpl-mesh-qemu/root/CMakeLists.txt new file mode 100644 index 00000000000..f2e2ddfc0a5 --- /dev/null +++ b/samples/net/rpl-mesh-qemu/root/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/samples/net/rpl-mesh-qemu/root/prj_qemu.conf b/samples/net/rpl-mesh-qemu/root/prj_qemu.conf new file mode 100644 index 00000000000..210296ee870 --- /dev/null +++ b/samples/net/rpl-mesh-qemu/root/prj_qemu.conf @@ -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 \ No newline at end of file diff --git a/samples/net/rpl-mesh-qemu/root/src/main.c b/samples/net/rpl-mesh-qemu/root/src/main.c new file mode 100644 index 00000000000..124808f1321 --- /dev/null +++ b/samples/net/rpl-mesh-qemu/root/src/main.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017 CPqD Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#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; + } +}