From 1b1ca336f80a7901e8554fe91f75ce4c55f539de Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Mon, 6 Jan 2014 10:10:47 +0100 Subject: [PATCH] created examples folder with six apps --- examples/ccn-lite-client/HOWTO | 55 +++++ examples/ccn-lite-client/Makefile | 49 +++++ examples/ccn-lite-client/main.c | 354 ++++++++++++++++++++++++++++++ examples/ccn-lite-relay/Makefile | 46 ++++ examples/ccn-lite-relay/main.c | 83 +++++++ examples/default/Makefile | 68 ++++++ examples/default/main.c | 133 +++++++++++ examples/hello-world/Makefile | 14 ++ examples/hello-world/main.c | 8 + examples/ipc_pingpong/Makefile | 12 + examples/ipc_pingpong/main.c | 34 +++ examples/rpl_udp/Makefile | 35 +++ examples/rpl_udp/demo.h | 64 ++++++ examples/rpl_udp/helper.c | 119 ++++++++++ examples/rpl_udp/main.c | 37 ++++ examples/rpl_udp/rpl.c | 186 ++++++++++++++++ examples/rpl_udp/udp.c | 108 +++++++++ 17 files changed, 1405 insertions(+) create mode 100644 examples/ccn-lite-client/HOWTO create mode 100644 examples/ccn-lite-client/Makefile create mode 100644 examples/ccn-lite-client/main.c create mode 100644 examples/ccn-lite-relay/Makefile create mode 100644 examples/ccn-lite-relay/main.c create mode 100644 examples/default/Makefile create mode 100644 examples/default/main.c create mode 100644 examples/hello-world/Makefile create mode 100644 examples/hello-world/main.c create mode 100644 examples/ipc_pingpong/Makefile create mode 100644 examples/ipc_pingpong/main.c create mode 100644 examples/rpl_udp/Makefile create mode 100644 examples/rpl_udp/demo.h create mode 100644 examples/rpl_udp/helper.c create mode 100644 examples/rpl_udp/main.c create mode 100644 examples/rpl_udp/rpl.c create mode 100644 examples/rpl_udp/udp.c diff --git a/examples/ccn-lite-client/HOWTO b/examples/ccn-lite-client/HOWTO new file mode 100644 index 0000000000..f9b74e99cf --- /dev/null +++ b/examples/ccn-lite-client/HOWTO @@ -0,0 +1,55 @@ +simple appserver (all in one shell) +==================================================== + +0. create tap devices: *./cpu/native/tapsetup.sh create 3* +1. build ccn-lite-client: *CFLAGS="-DHAVE_VALGRIND_VALGRIND_H" make -B clean all* +2. start: *./bin/ccn-lite-client.elf tap0* (valgrind support included) +3. start ccn thread: *ccn* [enter] (this starts the ccn relay network stack) +4. start appserver thread: *appserver* [enter] (this starts the userland appserver, which registers for "/riot/appserver/" +5. request content: *interest /riot/appserver/test* [enter] (ask the relay for this "file", userland code splits this up in +chunks and requests them from the relay. In the relay the name "/riot/appserver" is registered to the RIOT MSG face with +thread of the appserver. Interest is forwarded to appserver which replies with content.... +6. tear down ccn network stack: *haltccn* [enter] +7. now you can hit *ctrl+c* to stop the RIOT process [in valgrind you can notice that there is no leak] + +simple forward (needs two shells) +==================================================== + +SHELL 1 | SHELL 2 +-------------------------------------------------------------------------------------------------------------- +0. create tap devices: *./cpu/native/tapsetup.sh create 3* | +1. build ccn-lite-client: *make -B clean all* | build ccn-lite: *make clean all* +2. start: *./bin/ccn-lite-client.elf tap0* | start: *./bin/ccn-lite-relay.elf tap1* +3. start ccn thread: *ccn* [enter] | [it starts ccn automaticly] +4. set address: *addr 1* [enter] | [it picks address 42 automaticly] +5. register prefix the ccn-lite stack: *prefix /riot/ newTRANSface 42* [enter] | [it populates the cache automaticly] +6. request content: *interest /riot/text* [enter] | +7. tear down ccn network stack: *haltccn* [enter] + +advanced forward (needs three [four] shells) +==================================================== + +SHELL 1 | SHELL 2 | SHELL 3 | SHELL 4 (currently a bug in the native port on heavy traffic) +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +0. create tap devices: *./cpu/native/tapsetup.sh create 3* | | | +1. build ccn-lite-client: *make -B clean all* | | build ccn-lite: make clean all | ping -Itapbr0 8.8.8.8 +2. start: *./bin/ccn-lite-client.elf tap0* | start: *./bin/ccn-lite-client.elf tap1* | start: ./bin/ccn-lite-relay.elf tap2 | +3. start ccn thread: *ccn* [enter] | start ccn thread: *ccn* [enter] | [it starts ccn automaticly] | +4. set address: *addr 1* [enter] | set address: *addr 2* [enter] | [it picks address 42 automaticly] | +5. *prefix /riot/ newTRANSface 2* [enter] | *prefix /riot/ newTRANSface 42* [enter] | [it populates the cache automaticly] | +6. request content: *interest /riot/text* [enter] | | | + + +overdosed forward (needs three [four] shells) +==================================================== + +SHELL 1 | SHELL 2 | SHELL 3 | SHELL 4 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +0. create tap devices: *./cpu/native/tapsetup.sh create 3* | | | +1. build ccn-lite-client: *make -B clean all* | | | ping -Itapbr0 8.8.8.8 +2. start: *./bin/ccn-lite-client.elf tap0* | start: *./bin/ccn-lite-client.elf tap1* | start: *./bin/ccn-lite-client.elf tap2* | +3. start ccn thread: *ccn* [enter] | start ccn thread: *ccn* [enter] | start ccn thread: *ccn* [enter] | +4. set address: *addr 1* [enter] | set address: *addr 2* [enter] | set address: *addr 3* [enter] | +5. | | start appserver: *appserver* [enter] | +6. *prefix /riot/ newTRANSface 2* [enter] | *prefix /riot/ newTRANSface 3* [enter] | | +7. request content: *interest /riot/appserver/test* [enter] | | | diff --git a/examples/ccn-lite-client/Makefile b/examples/ccn-lite-client/Makefile new file mode 100644 index 0000000000..b006331443 --- /dev/null +++ b/examples/ccn-lite-client/Makefile @@ -0,0 +1,49 @@ +# name of your project +export PROJECT = ccn-lite-client + +# for easy switching of boards +ifeq ($(strip $(BOARD)),) + export BOARD = native +endif + +# this has to be the absolute path of the RIOT-base dir +export RIOTBASE = $(CURDIR)/../.. + +# uncomment this to enable scheduler statistics for ps +#CFLAGS += -DSCHEDSTATISTICS + +# If you want to use valgrind, you should recompile native with either +# HAVE_VALGRIND_H or HAVE_VALGRIND_VALGRIND_H depending on the location +# of the valgrind header (i.e. or ) +# For more information about the valgrind support of RIOT read: +# RIOT/cpu/native/README +#CFLAGS += -DHAVE_VALGRIND_VALGRIND_H +#CFLAGS += -DHAVE_VALGRIND_H + +## Modules to include. + +USEMODULE += config +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += uart0 +USEMODULE += posix +USEMODULE += ps +USEMODULE += auto_init +USEMODULE += hwtimer +USEMODULE += ltc4150 + +USEMODULE += transceiver +ifeq ($(BOARD),msba2) + USEMODULE += cc110x_ng +else ifeq ($(BOARD),native) + USEMODULE += nativenet +endif + +USEMODULE += rtc +USEMODULE += crypto_sha256 +USEMODULE += ccn_lite +USEMODULE += ccn_lite_client + +export INCLUDES = -I$(RIOTBASE)/drivers/cc110x_ng/include/ -I$(RIOTBASE)/sys/net/include + +include $(RIOTBASE)/Makefile.include diff --git a/examples/ccn-lite-client/main.c b/examples/ccn-lite-client/main.c new file mode 100644 index 0000000000..baa406ee77 --- /dev/null +++ b/examples/ccn-lite-client/main.c @@ -0,0 +1,354 @@ +/** + * RIOT CCN SHELL + * + * Copyright (C) 2013 Freie Universität Berlin + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * \{ + * \file riot_ccn.c + * \author Christian Mehlis + * \} + */ + +#include +#include +#include +#include + +#include "msg.h" +#include "thread.h" +#include "posix_io.h" +#include "shell.h" +#include "board_uart0.h" +#include "transceiver.h" +#include "rtc.h" +#include "ps.h" +#include "ltc4150.h" + +#define ENABLE_DEBUG (1) +#include "debug.h" + +#include "ccn_lite/ccnl-riot.h" +#include "ccn_lite/util/ccnl-riot-client.h" + +#define RIOT_CCN_APPSERVER (1) +#define RIOT_CCN_TESTS (0) +#define CCNL_DEFAULT_MAX_CACHE_ENTRIES 0 // means: no content caching +#define CCNL_DEFAULT_THRESHOLD_PREFIX 1 +#define CCNL_DEFAULT_THRESHOLD_AGGREGATE 2 + +char relay_stack[KERNEL_CONF_STACKSIZE_PRINTF]; + +#if RIOT_CCN_APPSERVER +char appserver_stack[KERNEL_CONF_STACKSIZE_PRINTF]; +#endif +int relay_pid, appserver_pid; + +int shell_max_cache_entries, shell_threshold_prefix, shell_threshold_aggregate; + +#define SHELL_MSG_BUFFER_SIZE (64) +msg_t msg_buffer_shell[SHELL_MSG_BUFFER_SIZE]; + +shell_t shell; + +unsigned char big_buf[3 * 1024]; +char small_buf[PAYLOAD_SIZE]; + +#if RIOT_CCN_APPSERVER +static void appserver_thread(void) +{ + ccnl_riot_appserver_start(relay_pid); +} + +static void riot_ccn_appserver(char *str) +{ + (void) str; /* unused */ + + if (appserver_pid) { + /* already running */ + return; + } + + appserver_pid = thread_create(appserver_stack, KERNEL_CONF_STACKSIZE_PRINTF, PRIORITY_MAIN - 1, CREATE_STACKTEST, appserver_thread, "appserver"); + DEBUG("ccn-lite appserver on thread_id %d...\n", appserver_pid); +} +#endif + +static void riot_ccn_express_interest(char *str) +{ + char *given_interest = strtok(str, " "); /* str=interest, skip that */ + given_interest = strtok(NULL, " "); + static const char *default_interest = "/ccnx/0.7.1/doc/technical/CanonicalOrder.txt"; + + if (!given_interest) { + strncpy(small_buf, default_interest, 100); // null terminated + } + else { + strncpy(small_buf, given_interest, 100); + } + + DEBUG("in='%s'\n", small_buf); + + ltc4150_start(); + int content_len = ccnl_riot_client_get(relay_pid, small_buf, (char *) big_buf); // small_buf=name to request + ltc4150_stop(); + printf("mAh=%f\n", ltc4150_get_total_mAh()); + + if (content_len == 0) { + puts("riot_get returned 0 bytes...aborting!"); + return; + } + + puts("####################################################"); + big_buf[content_len] = '\0'; + printf("data='%s'\n", big_buf); + puts("####################################################"); + puts("done"); +} + +static void riot_ccn_register_prefix(char *str) +{ + char *given_prefix = strtok(str, " "); + given_prefix = strtok(NULL, " "); + static const char *default_prefix = "/ccnx/0.7.1/doc/technical"; + + if (!given_prefix) { + strncpy(small_buf, default_prefix, 100); + } + else { + strncpy(small_buf, given_prefix, 100); + } + + DEBUG("prefix='%s'\n", small_buf); + + char *type = strtok(NULL, " "); + + if (!type) { + puts("enter: prefix /path/to/abc faceid"); + return; + } + + char *faceid = strtok(NULL, " ");//"2"; // 0=trans;1=msg + + if (!faceid) { + puts("enter: prefix /path/to/abc faceid"); + return; + } + + int content_len = ccnl_riot_client_publish(relay_pid, small_buf, faceid, type, big_buf); + + DEBUG("shell received: '%s'\n", big_buf); + DEBUG("received %d bytes.\n", content_len); + puts("done"); +} + +static void relay_thread(void) +{ + ccnl_riot_relay_start(shell_max_cache_entries, shell_threshold_prefix, shell_threshold_aggregate); +} + +static void riot_ccn_relay_start(char *str) +{ + if (relay_pid) { + /* already running */ + return; + } + + char *toc_str = strtok(str, " "); + + toc_str = strtok(NULL, " "); + if (!toc_str) { + shell_max_cache_entries = CCNL_DEFAULT_MAX_CACHE_ENTRIES; + } else { + shell_max_cache_entries = atoi(toc_str); + } + + toc_str = strtok(NULL, " "); + if (!toc_str) { + shell_threshold_prefix = CCNL_DEFAULT_THRESHOLD_PREFIX; + } else { + shell_threshold_prefix = atoi(toc_str); + } + + toc_str = strtok(NULL, " "); + if (!toc_str) { + shell_threshold_aggregate = CCNL_DEFAULT_THRESHOLD_AGGREGATE; + } else { + shell_threshold_aggregate = atoi(toc_str); + } + + relay_pid = thread_create(relay_stack, KERNEL_CONF_STACKSIZE_PRINTF, PRIORITY_MAIN - 2, CREATE_STACKTEST, relay_thread, "relay"); + DEBUG("ccn-lite relay on thread_id %d...\n", relay_pid); +} + +static void riot_ccn_relay_stop(char *str) +{ + (void) str; /* unused */ + + msg_t m; + m.content.value = 0; + m.type = CCNL_RIOT_HALT; + msg_send(&m, relay_pid, 1); + + /* mark relay as not running */ + relay_pid = 0; +} + +#if RIOT_CCN_TESTS +static void riot_ccn_pit_test(char *str) +{ + (void) str; /* unused */ + + char name[] = "/riot/test"; + + char *prefix[CCNL_MAX_NAME_COMP]; + char *cp = strtok(name, "/"); + int i = 0; + + while (i < (CCNL_MAX_NAME_COMP - 1) && cp) { + prefix[i++] = cp; + cp = strtok(NULL, "/"); + } + + //prefix[i] = 0; //segment to request + prefix[i + 1] = 0; + + msg_t m; + riot_ccnl_msg_t rmsg; + char segment_string[16]; //max=999\0 + struct timeval now; + + int segment; + + for (segment = 0; segment < 200; segment++) { + memset(segment_string, 0, 16); + snprintf(segment_string, 16, "%d", segment); + prefix[i] = segment_string; + int interest_len = mkInterest(prefix, NULL, (unsigned char *) small_buf); + + rmsg.payload = &small_buf; + rmsg.size = interest_len; + m.content.ptr = (char *) &rmsg; + m.type = CCNL_RIOT_MSG; + + msg_send(&m, relay_pid, 1); + + if ((segment % 50) == 0) { + rtc_time(&now); + printf("done: %d - %ld.%ld\n", segment, now.tv_sec, now.tv_usec); + } + } + + printf("done: tried to send %d interests\n", segment); +} + +static void riot_ccn_fib_test(char *str) +{ + (void) str; /* unused */ + + char type[] = "newTRANSface"; + char faceid[] = "42"; + + riot_new_face(relay_pid, type, faceid, big_buf); + + struct timeval now; + int i = -1; + + do { + i++; + snprintf(small_buf, sizeof(small_buf), "/riot/test/fib/%d/", i); + riot_register_prefix(relay_pid, small_buf, faceid, big_buf); + + if (i % 50 == 0) { + rtc_time(&now); + printf("done: %d - %ld.%ld\n", i, now.tv_sec, now.tv_usec); + } + } + while (0 == strcmp((const char *) big_buf, "prefixreg cmd worked")); + + DEBUG("%d: '%s'\n", i, big_buf); + printf("done: %d\n", i - 1); +} +#endif + +static void riot_ccn_populate(char *str) +{ + (void) str; /* unused */ + + msg_t m; + m.content.value = 0; + m.type = CCNL_RIOT_POPULATE; + msg_send(&m, relay_pid, 1); +} + +static void riot_ccn_stat(char *str) +{ + (void) str; /* unused */ + + msg_t m; + m.content.value = 0; + m.type = CCNL_RIOT_PRINT_STAT; + msg_send(&m, relay_pid, 1); +} + +static void riot_ccn_columb(char *str) +{ + (void) str; /* unused */ + + ltc4150_start(); +} + +static void riot_ccn_columb_stop(char *str) +{ + (void) str; /* unused */ + + ltc4150_stop(); + printf("mAh=%lf\n", ltc4150_get_total_mAh()); +} + +static const shell_command_t sc[] = { + { "ccn", "starts ccn relay", riot_ccn_relay_start }, + { "haltccn", "stops ccn relay", riot_ccn_relay_stop }, + { "interest", "express an interest", riot_ccn_express_interest }, + { "populate", "populate the cache of the relay with data", riot_ccn_populate }, + { "prefix", "registers a prefix to a face", riot_ccn_register_prefix }, + { "stat", "prints out forwarding statistics", riot_ccn_stat }, + { "columb", "starts the columb counter", riot_ccn_columb }, + { "columbstop", "stops the columb counter", riot_ccn_columb_stop }, +#if RIOT_CCN_APPSERVER + { "appserver", "starts an application server to reply to interests", riot_ccn_appserver }, +#endif +#if RIOT_CCN_TESTS + { "pittest", "starts a test for the size and speed of pit operations", riot_ccn_pit_test }, + { "fibtest", "starts a test for the size and speed of fib operations", riot_ccn_fib_test }, +#endif + { NULL, NULL, NULL } +}; + +void riot_ccn_runner(void) +{ + if (msg_init_queue(msg_buffer_shell, SHELL_MSG_BUFFER_SIZE) != 0) { + DEBUG("msg init queue failed...abording\n"); + return; + } + + puts("posix open"); + posix_open(uart0_handler_pid, 0); + puts("shell init"); + shell_init(&shell, sc, UART0_BUFSIZE, uart0_readc, uart0_putc); + puts("shell run"); + shell_run(&shell); +} + +int main(void) +{ + puts("CCN!"); + + puts("starting shell..."); + riot_ccn_runner(); + + return 0; +} diff --git a/examples/ccn-lite-relay/Makefile b/examples/ccn-lite-relay/Makefile new file mode 100644 index 0000000000..cc1c700895 --- /dev/null +++ b/examples/ccn-lite-relay/Makefile @@ -0,0 +1,46 @@ +# name of your project +export PROJECT = ccn-lite-relay + +# for easy switching of boards +ifeq ($(strip $(BOARD)),) + export BOARD = native +endif + +# this has to be the absolute path of the RIOT-base dir +export RIOTBASE = $(CURDIR)/../.. + +# uncomment this to enable scheduler statistics for ps +#CFLAGS += -DSCHEDSTATISTICS + +# If you want to use valgrind, you should recompile native with either +# HAVE_VALGRIND_H or HAVE_VALGRIND_VALGRIND_H depending on the location +# of the valgrind header (i.e. or ) +# For more information about the valgrind support of RIOT read: +# RIOT/cpu/native/README +#CFLAGS += -DHAVE_VALGRIND_VALGRIND_H +#CFLAGS += -DHAVE_VALGRIND_H + +## Modules to include. + +USEMODULE += config +USEMODULE += uart0 +USEMODULE += posix +USEMODULE += auto_init +USEMODULE += hwtimer + +USEMODULE += auto_init + +USEMODULE += transceiver +ifeq ($(BOARD),msba2) + USEMODULE += cc110x_ng +else ifeq ($(BOARD),native) + USEMODULE += nativenet +endif + +USEMODULE += rtc +USEMODULE += crypto_sha256 +USEMODULE += ccn_lite + +export INCLUDES = -I$(RIOTBASE)/drivers/cc110x_ng/include/ -I$(RIOTBASE)/sys/net/include/ + +include $(RIOTBASE)/Makefile.include diff --git a/examples/ccn-lite-relay/main.c b/examples/ccn-lite-relay/main.c new file mode 100644 index 0000000000..76d66bc52f --- /dev/null +++ b/examples/ccn-lite-relay/main.c @@ -0,0 +1,83 @@ +/** + * RIOT CCN MAIN APP + * + * Copyright (C) 2013 Freie Universität Berlin + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * \{ + * \file main.c + * \author Christian Mehlis + * \} + */ + +// system +#include +#include +#include +#include + +// riot +#include "thread.h" +#include "rtc.h" + +// ccn +#include "ccn_lite/ccnl-riot.h" + +int relay_pid; + +char t2_stack[KERNEL_CONF_STACKSIZE_PRINTF]; + +#define CCNL_DEFAULT_MAX_CACHE_ENTRIES 1 +#define CCNL_DEFAULT_THRESHOLD_PREFIX 1 +#define CCNL_DEFAULT_THRESHOLD_AGGREGATE 2 + +void set_address_handler(uint16_t a) +{ + msg_t mesg; + transceiver_command_t tcmd; + + tcmd.transceivers = transceiver_ids; + tcmd.data = &a; + mesg.content.ptr = (char *) &tcmd; + + printf("trying to set address %"PRIu16"\n", a); + mesg.type = SET_ADDRESS; + + printf("transceiver_pid=%d\n", transceiver_pid); + + msg_send_receive(&mesg, &mesg, transceiver_pid); + printf("got address: %"PRIu16"\n", a); +} + +void populate_cache(void) +{ + msg_t m; + m.content.value = 0; + m.type = CCNL_RIOT_POPULATE; + msg_send(&m, relay_pid, 1); +} + +void second_thread(void) +{ + set_address_handler(42); + populate_cache(); +} + +int main(void) +{ + printf("CCN!\n"); + + relay_pid = thread_getpid(); + + thread_create(t2_stack, KERNEL_CONF_STACKSIZE_PRINTF, PRIORITY_MAIN + 1, CREATE_STACKTEST, second_thread, "helper thread"); + + printf("starting ccn-lite relay...\n"); + ccnl_riot_relay_start(CCNL_DEFAULT_MAX_CACHE_ENTRIES, + CCNL_DEFAULT_THRESHOLD_PREFIX, + CCNL_DEFAULT_THRESHOLD_AGGREGATE); + + return 0; +} diff --git a/examples/default/Makefile b/examples/default/Makefile new file mode 100644 index 0000000000..1059db4777 --- /dev/null +++ b/examples/default/Makefile @@ -0,0 +1,68 @@ +# name of your project +export PROJECT = default + +# for easy switching of boards +ifeq ($(strip $(BOARD)),) + export BOARD = native +endif + +# this has to be the absolute path of the RIOT-base dir +export RIOTBASE = $(CURDIR)/../.. + +# uncomment this to enable scheduler statistics for ps +#CFLAGS += -DSCHEDSTATISTICS + +# If you want to use valgrind, you should recompile native with either +# HAVE_VALGRIND_H or HAVE_VALGRIND_VALGRIND_H depending on the location +# of the valgrind header (i.e. or ) +# For more information about the valgrind support of RIOT read: +# RIOT/cpu/native/README +#CFLAGS += -DHAVE_VALGRIND_VALGRIND_H +#CFLAGS += -DHAVE_VALGRIND_H + +USEMODULE += posix +USEMODULE += uart0 +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps +USEMODULE += vtimer +USEMODULE += auto_init +ifneq (,$(findstring msb-430,$(BOARD))) + USEMODULE += sht11 +endif +ifneq (,$(findstring chronos,$(BOARD))) + USEMODULE += cc110x_ng + export INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include +endif +ifneq (,$(findstring wsn430-v1_3b,$(BOARD))) + USEMODULE += cc110x_ng + export INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include +endif +ifneq (,$(findstring wsn430-v1_4,$(BOARD))) + USEMODULE += cc2420 + export INCLUDES += -I$(RIOTBASE)/drivers/cc2420/include +endif +ifneq (,$(findstring msb-430h,$(BOARD))) + USEMODULE += cc110x_ng + export INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include +endif +ifneq (,$(findstring msba2,$(BOARD))) + USEMODULE += sht11 + USEMODULE += ltc4150 + USEMODULE += rtc + USEMODULE += mci + USEMODULE += cc110x_ng + USEMODULE += config + export INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include +endif +ifneq (,$(findstring native,$(BOARD))) + USEMODULE += ltc4150 + USEMODULE += rtc + USEMODULE += nativenet + USEMODULE += transceiver + USEMODULE += config +endif + +export INCLUDES += -I${RIOTBASE}/core/include/ -I${RIOTBASE}/sys/include/ -I${RIOTBASE}/drivers/include/ + +include $(RIOTBASE)/Makefile.include diff --git a/examples/default/main.c b/examples/default/main.c new file mode 100644 index 0000000000..2384718038 --- /dev/null +++ b/examples/default/main.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2008, 2009, 2010 Kaspar Schleiser + * Copyright (C) 2013 Ludwig Ortmann + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include +#include + +#include "thread.h" +#include "posix_io.h" +#include "shell.h" +#include "shell_commands.h" +#include "board_uart0.h" + +#ifdef MODULE_LTC4150 +#include +#endif + +#ifdef MODULE_TRANSCEIVER +#include +#endif + +#define SND_BUFFER_SIZE (100) +#define RCV_BUFFER_SIZE (64) +#define RADIO_STACK_SIZE (KERNEL_CONF_STACKSIZE_DEFAULT) + +#ifdef MODULE_TRANSCEIVER + +char radio_stack_buffer[RADIO_STACK_SIZE]; +msg_t msg_q[RCV_BUFFER_SIZE]; + +void radio(void) { + msg_t m; + radio_packet_t *p; + radio_packet_length_t i; + + msg_init_queue(msg_q, RCV_BUFFER_SIZE); + + while (1) { + msg_receive(&m); + if (m.type == PKT_PENDING) { + p = (radio_packet_t*) m.content.ptr; + printf("Got radio packet:\n"); + printf("\tLength:\t%u\n", p->length); + printf("\tSrc:\t%u\n", p->src); + printf("\tDst:\t%u\n", p->dst); + printf("\tLQI:\t%u\n", p->lqi); + printf("\tRSSI:\t%u\n", p->rssi); + + for (i = 0; i < p->length; i++) { + printf("%02X ", p->data[i]); + } + p->processing--; + puts("\n"); + } + else if (m.type == ENOBUFFER) { + puts("Transceiver buffer full"); + } + else { + puts("Unknown packet received"); + } + } +} + +void init_transceiver(void) +{ + int radio_pid = thread_create( + radio_stack_buffer, + RADIO_STACK_SIZE, + PRIORITY_MAIN-2, + CREATE_STACKTEST, + radio, + "radio"); + + uint16_t transceivers = 0; +#ifdef MODULE_CC110X + transceivers |= TRANSCEIVER_CC1100; +#endif +#ifdef MODULE_CC110X_NG + transceivers |= TRANSCEIVER_CC1100; +#endif +#ifdef MODULE_CC2420 + transceivers |= TRANSCEIVER_CC2420; +#endif +#ifdef MODULE_NATIVENET + transceivers |= TRANSCEIVER_NATIVE; +#endif +#ifdef MODULE_AT86RF231 + transceivers |= TRANSCEIVER_AT86RF231; +#endif +#ifdef MODULE_MC1322X + transceivers |= TRANSCEIVER_MC1322X; +#endif + + transceiver_init(transceivers); + (void) transceiver_start(); + transceiver_register(transceivers, radio_pid); +} +#endif /* MODULE_TRANSCEIVER */ + +static int shell_readc(void) { + char c = 0; + (void) posix_read(uart0_handler_pid, &c, 1); + return c; +} + +static void shell_putchar(int c) { + (void) putchar(c); +} + +int main(void) { + shell_t shell; + (void) posix_open(uart0_handler_pid, 0); + +#ifdef MODULE_LTC4150 + ltc4150_start(); +#endif + +#ifdef MODULE_TRANSCEIVER + init_transceiver(); +#endif + + (void) puts("Welcome to RIOT!"); + + shell_init(&shell, NULL, UART0_BUFSIZE, shell_readc, shell_putchar); + + shell_run(&shell); + return 0; +} diff --git a/examples/hello-world/Makefile b/examples/hello-world/Makefile new file mode 100644 index 0000000000..79c42307a6 --- /dev/null +++ b/examples/hello-world/Makefile @@ -0,0 +1,14 @@ +# name of your project +export PROJECT = hello-world + +# for easy switching of boards +ifeq ($(strip $(BOARD)),) + export BOARD = native +endif + +# this has to be the absolute path of the RIOT-base dir +export RIOTBASE = $(CURDIR)/../.. + +export QUIET := 1 + +include $(RIOTBASE)/Makefile.include diff --git a/examples/hello-world/main.c b/examples/hello-world/main.c new file mode 100644 index 0000000000..52f2a787d7 --- /dev/null +++ b/examples/hello-world/main.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + puts("Hello World!\n"); + + while(1); +} diff --git a/examples/ipc_pingpong/Makefile b/examples/ipc_pingpong/Makefile new file mode 100644 index 0000000000..a65c53e7ef --- /dev/null +++ b/examples/ipc_pingpong/Makefile @@ -0,0 +1,12 @@ +# name of your project +export PROJECT = ipc_pingpong + +# for easy switching of boards +ifeq ($(strip $(BOARD)),) + export BOARD = native +endif + +# this has to be the absolute path of the RIOT-base dir +export RIOTBASE = $(CURDIR)/../.. + +include $(RIOTBASE)/Makefile.include diff --git a/examples/ipc_pingpong/main.c b/examples/ipc_pingpong/main.c new file mode 100644 index 0000000000..b269ab34f1 --- /dev/null +++ b/examples/ipc_pingpong/main.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +void second_thread(void) { + printf("second_thread starting.\n"); + msg_t m; + + while(1) { + msg_receive(&m); + printf("2nd: got msg from %i\n", m.sender_pid); + m.content.value++; + msg_reply(&m, &m); + } +} + +char second_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; + +int main(void) +{ + printf("Hello world!\n"); + + msg_t m; + + int pid = thread_create(second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong"); + + m.content.value = 1; + + while(1) { + msg_send_receive(&m, &m, pid); + printf("Got msg with content %u\n", m.content.value); + } +} diff --git a/examples/rpl_udp/Makefile b/examples/rpl_udp/Makefile new file mode 100644 index 0000000000..1040d5b781 --- /dev/null +++ b/examples/rpl_udp/Makefile @@ -0,0 +1,35 @@ +# name of your project +export PROJECT = rpl_udp + +# for easy switching of boards +ifeq ($(strip $(BOARD)),) + export BOARD = native +endif + +# get rid of the mandatory RPL warning +CFLAGS += "-Wno-cpp" + +# this has to be the absolute path of the RIOT-base dir +export RIOTBASE =$(CURDIR)/../.. + +## Modules to include. + +USEMODULE += auto_init +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += uart0 +USEMODULE += posix +USEMODULE += ps +USEMODULE += vtimer +ifeq ($(strip $(BOARD)),native) + USEMODULE += nativenet +else + USEMODULE += cc110x +endif +USEMODULE += sixlowpan +USEMODULE += rpl +USEMODULE += destiny + +export INCLUDES += -I$(RIOTBASE)/sys/net/include -I$(RIOTBASE)/sys/net/routing/rpl -I$(RIOTBASE)/drivers/cc110x + +include $(RIOTBASE)/Makefile.include diff --git a/examples/rpl_udp/demo.h b/examples/rpl_udp/demo.h new file mode 100644 index 0000000000..dff1e93e2d --- /dev/null +++ b/examples/rpl_udp/demo.h @@ -0,0 +1,64 @@ +#ifndef DEMO_H +#define DEMO_H + +#include "kernel.h" + +#define APP_VERSION "1.1" + +#define RADIO_CHANNEL (10) + +#define MONITOR_STACK_SIZE (KERNEL_CONF_STACKSIZE_MAIN) +#define RCV_BUFFER_SIZE (32) + +/* RPL shell command handlers */ +/** + * @brief Shell command to initializes RPL and Destiny + * + * @param[in] str Shell input + */ +void init(char *str); + +/** + * @brief Shell command to set node's ID + * + * @param[in] str Shell input + */ +void set_id(char *id); + +/** + * @brief Loops through the routing table + * + * @param[in] unused Guess what + */ +void loop(char *unused); + +/** + * @brief Shows the routing table + * + * @param[in] unused Guess what + */ +void table(char *unused); + +/** + * @brief Shows the dodag + * + * @param[in] unused Guess what + */ +void dodag(char *unused); + +/* UDP shell command handlers */ +void udp_server(char *unused); +void udp_send(char *str); + +/* helper command handlers */ +void ip(char *unused); + +void ignore(char *addr); + +/* monitoring thread */ +void monitor(void); + +extern radio_address_t id; +extern ipv6_addr_t std_addr; +extern char addr_str[IPV6_MAX_ADDR_STR_LEN]; +#endif /* DEMO_H */ diff --git a/examples/rpl_udp/helper.c b/examples/rpl_udp/helper.c new file mode 100644 index 0000000000..e055c2abc8 --- /dev/null +++ b/examples/rpl_udp/helper.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include "msg.h" +#include "sixlowpan/ip.h" +#include "transceiver.h" +#include "ieee802154_frame.h" +#include "rpl_structs.h" + +#include "demo.h" + +#define ENABLE_DEBUG (1) +#include "debug.h" + +#define LL_HDR_LEN (0x4) +#define IPV6_HDR_LEN (0x28) + +extern uint8_t ipv6_ext_hdr_len; + +msg_t msg_q[RCV_BUFFER_SIZE]; + +/* prints current IPv6 adresses */ +void ip(char *unused) +{ + (void) unused; + ipv6_iface_print_addrs(); +} + +void set_id(char *id_str) +{ + int res = sscanf(id_str, "set %hu", &id); + + if (res < 1) { + printf("Usage: init address\n"); + printf("\taddress must be an 8 bit integer\n"); + printf("\n\t(Current address is %u)\n", id); + return; + } + + printf("Set node ID to %u\n", id); +} + +void monitor(void) +{ + msg_t m; + radio_packet_t *p; + ipv6_hdr_t *ipv6_buf; + uint8_t icmp_type, icmp_code; + icmpv6_hdr_t *icmpv6_buf = NULL; + + msg_init_queue(msg_q, RCV_BUFFER_SIZE); + + while (1) { + msg_receive(&m); + if (m.type == PKT_PENDING) { + p = (radio_packet_t*) m.content.ptr; + + DEBUG("Received packet from ID %u\n", p->src); + DEBUG("\tLength:\t%u\n", p->length); + DEBUG("\tSrc:\t%u\n", p->src); + DEBUG("\tDst:\t%u\n", p->dst); + DEBUG("\tLQI:\t%u\n", p->lqi); + DEBUG("\tRSSI:\t%i\n", (int8_t) p->rssi); + + for (uint8_t i = 0; i < p->length; i++) { + DEBUG("%02X ", p->data[i]); + } + p->processing--; + DEBUG("\n"); + } + else if (m.type == IPV6_PACKET_RECEIVED) { + ipv6_buf = (ipv6_hdr_t*) m.content.ptr; + printf("IPv& datagram received (next header: %02X)", ipv6_buf->nextheader); + printf(" from %s ", ipv6_addr_to_str(addr_str, &ipv6_buf->srcaddr)); + if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) { + icmpv6_buf = (icmpv6_hdr_t*) &ipv6_buf[(LL_HDR_LEN + IPV6_HDR_LEN) + ipv6_ext_hdr_len]; + icmp_type = icmpv6_buf->type; + icmp_code = icmpv6_buf->code; + } + + if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) { + DEBUG("\t ICMP type: %02X ", icmp_type); + DEBUG("\t ICMP code: %02X ", icmp_code); + } + printf("\n"); + } + else if (m.type == ENOBUFFER) { + puts("Transceiver buffer full"); + } + else { + printf("Unknown packet received, type %04X\n", m.type); + } + } +} + +transceiver_command_t tcmd; + +void ignore(char *addr) { + uint16_t a; + if (transceiver_pid < 0) { + puts("Transceiver not runnning."); + return; + } + + msg_t mesg; + mesg.type = DBG_IGN; + mesg.content.ptr = (char*) &tcmd; + + tcmd.transceivers = TRANSCEIVER_CC1100; + tcmd.data = &a; + a = atoi(addr + strlen("ign ")); + if (strlen(addr) > strlen("ign ")) { + printf("sending to transceiver (%u): %u\n", transceiver_pid, (*(uint8_t*)tcmd.data)); + msg_send(&mesg, transceiver_pid, 1); + } + else { + puts("Usage:\tign "); + } +} diff --git a/examples/rpl_udp/main.c b/examples/rpl_udp/main.c new file mode 100644 index 0000000000..641abd6942 --- /dev/null +++ b/examples/rpl_udp/main.c @@ -0,0 +1,37 @@ +#include + +#include "posix_io.h" +#include "shell.h" +#include "shell_commands.h" +#include "board_uart0.h" +#include "destiny.h" +#include "kernel.h" + +#include "demo.h" + +const shell_command_t shell_commands[] = { + {"init", "Initialize network", init}, + {"set", "Set ID", set_id}, + {"table", "", table}, + {"dodag", "", dodag}, + {"loop", "", loop}, + {"server", "Starts a UDP server", udp_server}, + {"send", "Send a UDP datagram", udp_send}, + {"ip", "Print all assigned IP addresses", ip}, + {"ign", "ignore node", ignore}, + {NULL, NULL, NULL} +}; + +int main(void) +{ + puts("RPL router v"APP_VERSION); + + /* start shell */ + posix_open(uart0_handler_pid, 0); + + shell_t shell; + shell_init(&shell, shell_commands, UART0_BUFSIZE, uart0_readc, uart0_putc); + + shell_run(&shell); + return 0; +} diff --git a/examples/rpl_udp/rpl.c b/examples/rpl_udp/rpl.c new file mode 100644 index 0000000000..4a7a48f6f5 --- /dev/null +++ b/examples/rpl_udp/rpl.c @@ -0,0 +1,186 @@ +#include +#include +#include "vtimer.h" +#include "thread.h" +#include "sixlowpan.h" +#include "destiny.h" +#include "rpl.h" +#include "rpl_dodag.h" +#include "demo.h" + +#ifdef MODULE_NATIVENET +#define TRANSCEIVER TRANSCEIVER_NATIVE +#else +#define TRANSCEIVER TRANSCEIVER_CC1100 +#endif + +char monitor_stack_buffer[MONITOR_STACK_SIZE]; +radio_address_t id; +ipv6_addr_t std_addr; + +uint8_t is_root = 0; + +void init(char *str) +{ + transceiver_command_t tcmd; + msg_t m; + uint8_t chan = RADIO_CHANNEL; + + char command; + + int res = sscanf(str, "init %c", &command); + + if (res < 1) { + printf("Usage: init (r|n)\n"); + printf("\tr\tinitialize as root\n"); + printf("\tn\tinitialize as node router\n"); + } + + uint8_t state; + + if ((command == 'n') || (command == 'r')) { + printf("INFO: Initialize as %s on address %d\n", ((command == 'n') ? "node" : "root"), id); + if (!id || (id > 255)) { + printf("ERROR: address not a valid 8 bit integer\n"); + return; + } + + state = rpl_init(TRANSCEIVER, id); + + if (state != SIXLOWERROR_SUCCESS) { + printf("Error initializing RPL\n"); + } + else { + puts("6LoWPAN and RPL initialized."); + } + + if (command == 'r') { + rpl_init_root(); + is_root = 1; + } + else { + ipv6_iface_set_routing_provider(rpl_get_next_hop); + } + int monitor_pid = thread_create(monitor_stack_buffer, MONITOR_STACK_SIZE, PRIORITY_MAIN-2, CREATE_STACKTEST, monitor, "monitor"); + transceiver_register(TRANSCEIVER, monitor_pid); + ipv6_register_packet_handler(monitor_pid); + //sixlowpan_lowpan_register(monitor_pid); + } + else { + printf("ERROR: Unknown command '%c'\n", command); + return; + } + + /* TODO: check if this works as intended */ + ipv6_addr_t prefix, tmp; + ipv6_addr_init(&std_addr, 0xABCD, 0xEF12, 0, 0, 0x1034, 0x00FF, 0xFE00, id); + ipv6_addr_init_prefix(&prefix, &std_addr, 64); + plist_add(&prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE, 0, 1, ICMPV6_NDP_OPT_PI_FLAG_AUTONOM); + ipv6_init_iface_as_router(); + /* add global address */ + ipv6_addr_set_by_eui64(&tmp, &std_addr); + ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_GLOBAL, NDP_ADDR_STATE_PREFERRED, 0, 0); + + /* set channel to 10 */ + tcmd.transceivers = TRANSCEIVER; + tcmd.data = &chan; + m.type = SET_CHANNEL; + m.content.ptr = (void *) &tcmd; + + msg_send_receive(&m, &m, transceiver_pid); + printf("Channel set to %u\n", RADIO_CHANNEL); + + destiny_init_transport_layer(); + puts("Destiny initialized"); + /* start transceiver watchdog */ +} + +void loop(char *unused) +{ + (void) unused; + + rpl_routing_entry_t *rtable; + + rtable = rpl_get_routing_table(); + rpl_dodag_t *mydodag = rpl_get_my_dodag(); + + if (mydodag == NULL) { + return; + } + + printf("---------------------------\n"); + printf("OUTPUT\n"); + printf("my rank: %d\n", mydodag->my_rank); + if (!is_root) { + printf("my preferred parent:\n"); + printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->my_preferred_parent->addr))); + printf("parent lifetime: %d\n", mydodag->my_preferred_parent->lifetime); + } + printf("---------------------------$\n"); + + for (int i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) { + if (rtable[i].used) { + printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].address))); + puts("next hop"); + printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].next_hop))); + printf("entry %d lifetime %d\n", i, rtable[i].lifetime); + + if (!rpl_equal_id(&rtable[i].address, &rtable[i].next_hop)) { + puts("multi-hop"); + } + + printf("---------------------------$\n"); + } + } + + printf("########################\n"); +} + +void table(char *unused) +{ + (void) unused; + + rpl_routing_entry_t *rtable; + rtable = rpl_get_routing_table(); + printf("---------------------------\n"); + printf("OUTPUT\n"); + printf("---------------------------\n"); + + for (int i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) { + if (rtable[i].used) { + printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].address))); + printf("entry %d lifetime %d\n", i, rtable[i].lifetime); + + if (!rpl_equal_id(&rtable[i].address, &rtable[i].next_hop)) { + puts("multi-hop"); + } + + printf("--------------\n"); + } + } + + printf("$\n"); +} + +void dodag(char *unused) +{ + (void) unused; + + printf("---------------------------\n"); + rpl_dodag_t *mydodag = rpl_get_my_dodag(); + + if (mydodag == NULL) { + printf("Not part of a dodag\n"); + printf("---------------------------$\n"); + return; + } + + printf("Part of Dodag:\n"); + printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->dodag_id))); + printf("my rank: %d\n", mydodag->my_rank); + if (!is_root) { + printf("my preferred parent:\n"); + printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->my_preferred_parent->addr))); + } + printf("---------------------------$\n"); +} diff --git a/examples/rpl_udp/udp.c b/examples/rpl_udp/udp.c new file mode 100644 index 0000000000..c6f9bb4bfb --- /dev/null +++ b/examples/rpl_udp/udp.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +#include "kernel.h" +#include "thread.h" + +#include "destiny/socket.h" + +#include "net_help.h" + +#include "demo.h" + +#define UDP_BUFFER_SIZE (128) +#define SERVER_PORT (0xFF01) + +char udp_server_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; +char addr_str[IPV6_MAX_ADDR_STR_LEN]; + +void init_udp_server(void); + +/* UDP server thread */ +void udp_server(char *unused) +{ + (void) unused; + int udp_server_thread_pid = thread_create(udp_server_stack_buffer, KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN, CREATE_STACKTEST, init_udp_server, "init_udp_server"); + printf("UDP SERVER THREAD PID: %i\n", udp_server_thread_pid); +} + +void init_udp_server(void) +{ + sockaddr6_t sa; + char buffer_main[UDP_BUFFER_SIZE]; + int32_t recsize; + uint32_t fromlen; + int sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + memset(&sa, 0, sizeof(sa)); + + sa.sin6_family = AF_INET; + sa.sin6_port = HTONS(SERVER_PORT); + + fromlen = sizeof(sa); + + if (-1 == destiny_socket_bind(sock, &sa, sizeof(sa))) { + printf("Error bind failed!\n"); + destiny_socket_close(sock); + } + + for(;;) { + recsize = destiny_socket_recvfrom(sock, (void *)buffer_main, UDP_BUFFER_SIZE, 0, + &sa, &fromlen); + + if(recsize < 0) { + printf("ERROR: recsize < 0!\n"); + } + + printf("UDP packet received, payload: %s\n", buffer_main); + } + + destiny_socket_close(sock); +} + +/* UDP send command */ +void udp_send(char *str) +{ + int sock; + sockaddr6_t sa; + ipv6_addr_t ipaddr; + int bytes_sent; + int address; + char text[5]; + if (sscanf(str, "send %i %s", &address, text) < 2) { + printf("usage: send \n"); + return; + } + + sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + if(-1 == sock) { + printf("Error Creating Socket!"); + return; + } + + memset(&sa, 0, sizeof sa); + + ipv6_addr_init(&ipaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, (uint16_t)address); + + sa.sin6_family = AF_INET; + memcpy(&sa.sin6_addr, &ipaddr, 16); + sa.sin6_port = HTONS(SERVER_PORT); + + bytes_sent = destiny_socket_sendto(sock, (char *)text, + strlen(text) + 1, 0, &sa, + sizeof sa); + + if(bytes_sent < 0) { + printf("Error sending packet!\n"); + } + else { + printf("Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", bytes_sent, ipv6_addr_to_str(addr_str, &ipaddr)); + } + + destiny_socket_close(sock); +} + +