From 4a088a1259ff69f96d8ec6c6f5cb2e1c337a723e Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 10 Aug 2016 16:38:57 +0300 Subject: [PATCH] net: apps: Example app for Trickle algorithm This is only meant for Contiki based IP stack. Change-Id: I53cbcb7da0bd13ad87243fd70974cec0bd31072e Signed-off-by: Jukka Rissanen --- samples/net/trickle-legacy/Makefile | 32 ++++ samples/net/trickle-legacy/prj.mdef | 5 + samples/net/trickle-legacy/prj_802154.conf | 14 ++ samples/net/trickle-legacy/prj_bt.conf | 19 ++ samples/net/trickle-legacy/prj_ethernet.conf | 13 ++ samples/net/trickle-legacy/prj_qemu.conf | 10 + samples/net/trickle-legacy/prj_slip.conf | 14 ++ samples/net/trickle-legacy/src/Makefile | 13 ++ samples/net/trickle-legacy/src/main.c | 192 +++++++++++++++++++ 9 files changed, 312 insertions(+) create mode 100644 samples/net/trickle-legacy/Makefile create mode 100644 samples/net/trickle-legacy/prj.mdef create mode 100644 samples/net/trickle-legacy/prj_802154.conf create mode 100644 samples/net/trickle-legacy/prj_bt.conf create mode 100644 samples/net/trickle-legacy/prj_ethernet.conf create mode 100644 samples/net/trickle-legacy/prj_qemu.conf create mode 100644 samples/net/trickle-legacy/prj_slip.conf create mode 100644 samples/net/trickle-legacy/src/Makefile create mode 100644 samples/net/trickle-legacy/src/main.c diff --git a/samples/net/trickle-legacy/Makefile b/samples/net/trickle-legacy/Makefile new file mode 100644 index 00000000000..096d52b1cc2 --- /dev/null +++ b/samples/net/trickle-legacy/Makefile @@ -0,0 +1,32 @@ +# Makefile - Example trickle application running in Contiki based +# legacy IP stack + +# +# Copyright (c) 2016 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +NET_IFACE ?= slip +MDEF_FILE = prj.mdef +KERNEL_TYPE ?= nano +BOARD ?= qemu_x86 +CONF_FILE ?= prj_$(NET_IFACE).conf + +include $(ZEPHYR_BASE)/Makefile.inc + +ifeq ($(CONFIG_NETWORKING_WITH_BT), y) + QEMU_EXTRA_FLAGS = -serial unix:/tmp/bt-server-bredr +else + include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack +endif diff --git a/samples/net/trickle-legacy/prj.mdef b/samples/net/trickle-legacy/prj.mdef new file mode 100644 index 00000000000..b431140bd02 --- /dev/null +++ b/samples/net/trickle-legacy/prj.mdef @@ -0,0 +1,5 @@ +% Application : trickle demo app + +% TASK NAME PRIO ENTRY STACK GROUPS +% ================================== + TASK MAIN 7 main 2048 [EXE] diff --git a/samples/net/trickle-legacy/prj_802154.conf b/samples/net/trickle-legacy/prj_802154.conf new file mode 100644 index 00000000000..778203801e8 --- /dev/null +++ b/samples/net/trickle-legacy/prj_802154.conf @@ -0,0 +1,14 @@ +CONFIG_NETWORKING=y +CONFIG_NETWORKING_WITH_LOGGING=y +CONFIG_IP_BUF_RX_SIZE=3 +CONFIG_IP_BUF_TX_SIZE=2 +CONFIG_NANO_TIMEOUTS=y +CONFIG_NETWORKING_WITH_15_4=y +CONFIG_NETWORKING_WITH_15_4_TI_CC2520=y +CONFIG_SYS_LOG_TI_CC2520_LEVEL=4 +CONFIG_NETWORKING_WITH_6LOWPAN=y +CONFIG_6LOWPAN_COMPRESSION_IPHC=y +CONFIG_NANO_WORKQUEUE=y +CONFIG_NETWORKING_STATISTICS=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_bt.conf b/samples/net/trickle-legacy/prj_bt.conf new file mode 100644 index 00000000000..09e1c77a66f --- /dev/null +++ b/samples/net/trickle-legacy/prj_bt.conf @@ -0,0 +1,19 @@ +CONFIG_BLUETOOTH=y +CONFIG_BLUETOOTH_LE=y +CONFIG_BLUETOOTH_DEBUG_LOG=y +CONFIG_BLUETOOTH_DEBUG_L2CAP=y +CONFIG_BLUETOOTH_SMP=y +CONFIG_BLUETOOTH_SIGNING=y +CONFIG_BLUETOOTH_PERIPHERAL=y +CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL=y +CONFIG_NETWORKING=y +CONFIG_NETWORKING_WITH_LOGGING=y +CONFIG_NETWORKING_WITH_6LOWPAN=y +CONFIG_6LOWPAN_COMPRESSION_IPHC=y +CONFIG_NETWORKING_WITH_BT=y +CONFIG_IP_BUF_RX_SIZE=5 +CONFIG_IP_BUF_TX_SIZE=3 +CONFIG_NANO_WORKQUEUE=y +CONFIG_NETWORKING_STATISTICS=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_ethernet.conf b/samples/net/trickle-legacy/prj_ethernet.conf new file mode 100644 index 00000000000..b0d193953e8 --- /dev/null +++ b/samples/net/trickle-legacy/prj_ethernet.conf @@ -0,0 +1,13 @@ +CONFIG_INIT_STACKS=y +CONFIG_NETWORKING=y +CONFIG_NETWORKING_WITH_LOGGING=y +CONFIG_IP_BUF_RX_SIZE=3 +CONFIG_IP_BUF_TX_SIZE=2 +CONFIG_NANO_TIMEOUTS=y +CONFIG_ETHERNET=y +CONFIG_ETH_DW=y +CONFIG_ETHERNET_DEBUG=y +CONFIG_NANO_WORKQUEUE=y +CONFIG_NETWORKING_STATISTICS=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_qemu.conf b/samples/net/trickle-legacy/prj_qemu.conf new file mode 100644 index 00000000000..b3e065a5280 --- /dev/null +++ b/samples/net/trickle-legacy/prj_qemu.conf @@ -0,0 +1,10 @@ +CONFIG_NETWORKING_IPV6_NO_ND=y +CONFIG_NETWORKING=y +CONFIG_NETWORKING_WITH_LOGGING=y +CONFIG_IP_BUF_RX_SIZE=3 +CONFIG_IP_BUF_TX_SIZE=2 +CONFIG_NANO_TIMEOUTS=y +CONFIG_NANO_WORKQUEUE=y +CONFIG_NETWORKING_STATISTICS=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/prj_slip.conf b/samples/net/trickle-legacy/prj_slip.conf new file mode 100644 index 00000000000..0fb24f9bf65 --- /dev/null +++ b/samples/net/trickle-legacy/prj_slip.conf @@ -0,0 +1,14 @@ +CONFIG_NET_TESTING=y +CONFIG_NETWORKING_IPV6_NO_ND=y +CONFIG_NETWORKING=y +CONFIG_NETWORKING_WITH_LOGGING=y +CONFIG_NETWORKING_WITH_LOOPBACK=y +CONFIG_NETWORKING_UART=y +CONFIG_NETWORKING_DEBUG_UART=y +CONFIG_IP_BUF_RX_SIZE=3 +CONFIG_IP_BUF_TX_SIZE=2 +CONFIG_NANO_TIMEOUTS=y +CONFIG_NANO_WORKQUEUE=y +CONFIG_NETWORKING_STATISTICS=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NETWORKING_WITH_TRICKLE=y diff --git a/samples/net/trickle-legacy/src/Makefile b/samples/net/trickle-legacy/src/Makefile new file mode 100644 index 00000000000..60d9ec7b16f --- /dev/null +++ b/samples/net/trickle-legacy/src/Makefile @@ -0,0 +1,13 @@ +ccflags-y +=-I${ZEPHYR_BASE}/net/ip +ccflags-y +=-I${ZEPHYR_BASE}/samples/bluetooth/ + +ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki +ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib +ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os +ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/trickle + +obj-y = main.o + +ifeq ($(CONFIG_NETWORKING_WITH_BT), y) + obj-y += ../../../bluetooth/gatt/ipss.o +endif diff --git a/samples/net/trickle-legacy/src/main.c b/samples/net/trickle-legacy/src/main.c new file mode 100644 index 00000000000..80c74b4ae81 --- /dev/null +++ b/samples/net/trickle-legacy/src/main.c @@ -0,0 +1,192 @@ +/* main.c - Trickle sample app for legacy IP stack */ + +/* + * Copyright (c) 2015 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(CONFIG_STDOUT_CONSOLE) +#include +#define PRINT printf +#else +#include +#define PRINT printk +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#define MY_IPADDR { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0x1 } } } +#define MY_PREFIX_LEN 64 + +static const struct in6_addr in6addr_my = MY_IPADDR; +#define MY_PORT 30001 + +#if defined(CONFIG_NANOKERNEL) +#define STACKSIZE 2000 +char __noinit __stack fiberStack[STACKSIZE]; +#endif + +static struct nano_delayed_work token_lifetime; +static uint32_t timeout = SECONDS(5); + +static struct trickle_timer tt; +static uint8_t token; + +#define IMIN 16 /* ticks */ +#define IMAX 10 /* doublings */ +#define REDUNDANCY_CONST 2 + +static void trickle_tx(void *user_data, uint8_t suppress) +{ + struct trickle_timer *t = (struct trickle_timer *)user_data; + + if (suppress == TRICKLE_TIMER_TX_SUPPRESS) { + return; + } + + PRINT("At %lu (I=%lu, c=%u): token 0x%02x\n", + sys_tick_get_32(), (unsigned long)t->i_cur, + t->c, token); + + /* FIXME: Send token .... */ +} + +static inline void init_app(void) +{ + PRINT("%s: run trickle demo\n", __func__); + + token = 0; + + trickle_timer_config(&tt, IMIN, IMAX, REDUNDANCY_CONST); + trickle_timer_set(&tt, trickle_tx, &tt); + + uip_ds6_prefix_add((uip_ipaddr_t *)&in6addr_my, MY_PREFIX_LEN, 0); +} + +/* How many tics to wait for a network packet */ +#define WAIT_TIME 1 +#define WAIT_TICKS (WAIT_TIME * sys_clock_ticks_per_sec) + +struct nano_fifo *net_context_get_queue(struct net_context *context); +static inline void receive_and_reply(const char *name, + struct net_context *udp_recv) +{ + struct net_buf *buf; + + buf = net_receive(udp_recv, WAIT_TICKS); + if (buf) { + } + + fiber_sleep(50); +} + +static inline bool get_context(struct net_context **udp_recv) +{ + static struct net_addr any_addr; + static struct net_addr my_addr; + static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; + + any_addr.in6_addr = in6addr_any; + any_addr.family = AF_INET6; + + my_addr.in6_addr = in6addr_my; + my_addr.family = AF_INET6; + + *udp_recv = net_context_get(IPPROTO_UDP, + &any_addr, 0, + &my_addr, MY_PORT); + if (!*udp_recv) { + PRINT("%s: Cannot get network context\n", __func__); + return false; + } + + return true; +} + +static inline void token_expired(struct nano_work *work) +{ + PRINT("Generate a new token value %d\n", token); + + /* Periodically (and randomly) generate a new token. + * This will trigger a trickle inconsistency + */ + if (!(sys_rand32_get() % 2)) { + token++; + + PRINT("Generating a new token 0x%02x\n", token); + + trickle_timer_reset_event(&tt); + } + + nano_delayed_work_submit(&token_lifetime, timeout); +} + +void receive(void) +{ + static struct net_context *udp_recv; + + if (!get_context(&udp_recv)) { + PRINT("%s: Cannot get network contexts\n", __func__); + return; + } + + /* + * Trickle is now started and is running the first interval. + * All nodes agree that token is 0 initially. This will then + * change when one node randomly decides to generate a new one token. + */ + nano_delayed_work_init(&token_lifetime, token_expired); + nano_delayed_work_submit(&token_lifetime, timeout); + + while (1) { + receive_and_reply(__func__, udp_recv); + } +} + +void main(void) +{ + net_init(); + + init_app(); + +#if defined(CONFIG_NETWORKING_WITH_BT) + if (bt_enable(NULL)) { + PRINT("Bluetooth init failed\n"); + return; + } + ipss_init(); + ipss_advertise(); +#endif + +#if defined(CONFIG_MICROKERNEL) + receive(); +#else + task_fiber_start (&fiberStack[0], STACKSIZE, + (nano_fiber_entry_t)receive, 0, 0, 7, 0); +#endif +}