From 8e4798ecc56254939ddd4b5aa6e8b6503e5ca4ff Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Wed, 25 Feb 2015 18:15:37 +0100 Subject: [PATCH 1/7] examples/watrli_rpl_udp: initial commit --- examples/watrli_rpl_udp/Makefile | 23 ++++ examples/watrli_rpl_udp/main.c | 230 +++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 examples/watrli_rpl_udp/Makefile create mode 100644 examples/watrli_rpl_udp/main.c diff --git a/examples/watrli_rpl_udp/Makefile b/examples/watrli_rpl_udp/Makefile new file mode 100644 index 000000000000..ff4d10f6a3b5 --- /dev/null +++ b/examples/watrli_rpl_udp/Makefile @@ -0,0 +1,23 @@ +# name of your application +APPLICATION = watrli_rpl_udp + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +CFLAGS += -DDEVELHELP + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +# Modules to include +USEMODULE += defaulttransceiver +USEMODULE += rpl +USEMODULE += udp + +include $(RIOTBASE)/Makefile.include diff --git a/examples/watrli_rpl_udp/main.c b/examples/watrli_rpl_udp/main.c new file mode 100644 index 000000000000..d0629233fb33 --- /dev/null +++ b/examples/watrli_rpl_udp/main.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2015 + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief watr.li rpl udp application + * + * @author + * + * @} + */ + +#include +#include +#include "udp.h" +#include "rpl.h" + +#define WATR_LI_CHANNEL (21) /**< The used channel */ +#define WATR_LI_PAN (0x03e9) /**< The used PAN ID */ +#define WATR_LI_IFACE (0) /**< The used Trasmssion device */ +#define WATR_LI_UDP_PORT (12345) /**< The UDP port to listen */ +#define WATR_LI_UDP_BUFFER_SIZE (1024) /**< The buffer size for receiving UDPs */ + +/** The UDP server thread stack */ +char udp_server_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; + +/** +* @brief the sample UDP server that expects receiving strings +* @param[in] arg unused parameter pointer +*/ +static void *watr_li_udp_server(void *arg) +{ + (void) arg; + + sockaddr6_t sa; + char buffer_main[WATR_LI_UDP_BUFFER_SIZE]; + uint32_t fromlen; + int sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + memset(&sa, 0, sizeof(sa)); + + sa.sin6_family = AF_INET; + sa.sin6_port = HTONS(WATR_LI_UDP_PORT); + + fromlen = sizeof(sa); + + if (-1 == socket_base_bind(sock, &sa, sizeof(sa))) { + puts("[watr_li_udp_server] Error bind failed!"); + socket_base_close(sock); + return NULL; + } + + while (1) { + int32_t recsize = socket_base_recvfrom(sock, (void *)buffer_main, + WATR_LI_UDP_BUFFER_SIZE, 0, + &sa, &fromlen); + + if (recsize < 0) { + puts("[watr_li_udp_server] ERROR: recsize < 0!"); + } + + printf("UDP packet received, payload: %s\n", buffer_main); + } + + socket_base_close(sock); + + return NULL; +} + +static void watr_li_udp_send(void) +{ + int sock; + sockaddr6_t sa; + int bytes_sent; + sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + char text[] = "watr.li node text"; + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + + if (-1 == sock) { + puts("[watr_li_udp_send] Error Creating Socket!"); + return; + } + rpl_dodag_t *mydodag = rpl_get_my_dodag(); + + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET; + memcpy(&sa.sin6_addr, &(mydodag->dodag_id), 16); + sa.sin6_port = HTONS(WATR_LI_UDP_PORT); + bytes_sent = socket_base_sendto(sock, (char *)text, + strlen(text) + 1, 0, &sa, + sizeof(sa)); + + if (bytes_sent < 0) { + puts("[watr_li_udp_send] Error sending packet!"); + } + + printf("[watr_li_udp_send] Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", + bytes_sent, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, + &(sa.sin6_addr))); + + socket_base_close(sock); +} + +/** +* @brief setup the readio interface +* @retrun radio_address_t of the set interface +*/ +static radio_address_t set_watr_li_if(void) +{ + net_if_set_src_address_mode(WATR_LI_IFACE, NET_IF_TRANS_ADDR_M_SHORT); + radio_address_t iface_id = net_if_get_hardware_address(WATR_LI_IFACE); + return iface_id; +} + +/** +* @brief set the channel for this watr.li node +* @param[in] chan the channel to use +* @return 0 on success +*/ +static int set_watr_li_channel(int32_t chan) +{ + transceiver_command_t tcmd; + msg_t m; + + tcmd.transceivers = TRANSCEIVER_DEFAULT; + tcmd.data = &chan; + m.type = SET_CHANNEL; + m.content.ptr = (void *) &tcmd; + + msg_send_receive(&m, &m, transceiver_pid); + return 0; +} + +/** +* @brief set the PAN ID for this watr.li node +* @param[in] pan the PAN ID to use +* @return 0 on success +*/ +static int set_watr_li_pan(int32_t pan) +{ + transceiver_command_t tcmd; + msg_t m; + + tcmd.transceivers = TRANSCEIVER_DEFAULT; + tcmd.data = &pan; + m.type = SET_PAN; + m.content.ptr = (void *) &tcmd; + + msg_send_receive(&m, &m, transceiver_pid); + return 0; +} + +/** +* @brief set a desire address for this watr.li node +* @return 0 on success +*/ +static int set_watr_li_address(ipv6_addr_t* node_addr) +{ + ipv6_net_if_add_addr(WATR_LI_IFACE, node_addr, NDP_ADDR_STATE_PREFERRED, 0, 0, 0); + return 0; +} + +/** +* @brief prepares this node to join the watr.li DODAG +* @return 0 on success +*/ +static int watr_li_setup_node(void) +{ + radio_address_t iface_id = 0xffff; + ipv6_addr_t myaddr, rpl_addr; + + set_watr_li_channel(WATR_LI_CHANNEL); + set_watr_li_pan(WATR_LI_PAN); + iface_id = set_watr_li_if(); + + /* choose addresses */ + ipv6_addr_init(&myaddr, 0x2015, 0x1, 0x28, 0x1111, 0x0, 0x0, 0x0, iface_id); + ipv6_addr_init(&rpl_addr, 0xff02, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a); + /* and set them */ + set_watr_li_address(&myaddr); + set_watr_li_address(&rpl_addr); + + return 0; +} + +/** +* @brief initialize RPL on this watr.li node +* @return 0 on success +*/ +static int watr_li_init_rpl(void) +{ + rpl_init(WATR_LI_IFACE); + ipv6_iface_set_routing_provider(rpl_get_next_hop); + return 0; +} + +static void watr_li_start_udp_server(void) +{ + thread_create(udp_server_stack_buffer,sizeof(udp_server_stack_buffer), + PRIORITY_MAIN, CREATE_STACKTEST, watr_li_udp_server, NULL, + "watr.li udp_server"); +} + +int main(void) +{ + puts("Hello watr.li!"); + + printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); + printf("This board features a(n) %s MCU.\n", RIOT_MCU); + + watr_li_setup_node(); + watr_li_init_rpl(); + watr_li_start_udp_server(); + + sleep(30); + watr_li_udp_send(); + while(1){ + thread_yield(); + } + + return 0; +} From 8331cd1805ebbd8538176ad78613e7ead411a4de Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Wed, 18 Mar 2015 08:43:59 +0100 Subject: [PATCH 2/7] [SQUASH ME] removed unnecessary address binding --- examples/watrli_rpl_udp/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/watrli_rpl_udp/main.c b/examples/watrli_rpl_udp/main.c index d0629233fb33..e1920e57a204 100644 --- a/examples/watrli_rpl_udp/main.c +++ b/examples/watrli_rpl_udp/main.c @@ -175,7 +175,7 @@ static int set_watr_li_address(ipv6_addr_t* node_addr) static int watr_li_setup_node(void) { radio_address_t iface_id = 0xffff; - ipv6_addr_t myaddr, rpl_addr; + ipv6_addr_t myaddr; set_watr_li_channel(WATR_LI_CHANNEL); set_watr_li_pan(WATR_LI_PAN); @@ -183,10 +183,9 @@ static int watr_li_setup_node(void) /* choose addresses */ ipv6_addr_init(&myaddr, 0x2015, 0x1, 0x28, 0x1111, 0x0, 0x0, 0x0, iface_id); - ipv6_addr_init(&rpl_addr, 0xff02, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a); - /* and set them */ + + /* and set it */ set_watr_li_address(&myaddr); - set_watr_li_address(&rpl_addr); return 0; } From ba7de3e33dfea2fe3f9c3cbaeb117bf962a4ac3e Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Wed, 18 Mar 2015 15:01:58 +0100 Subject: [PATCH 3/7] [SQUASH ME] made it less error prone --- examples/watrli_rpl_udp/main.c | 71 ++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/examples/watrli_rpl_udp/main.c b/examples/watrli_rpl_udp/main.c index e1920e57a204..791a9a2e85e0 100644 --- a/examples/watrli_rpl_udp/main.c +++ b/examples/watrli_rpl_udp/main.c @@ -23,7 +23,7 @@ #include "udp.h" #include "rpl.h" -#define WATR_LI_CHANNEL (21) /**< The used channel */ +#define WATR_LI_CHANNEL (26) /**< The used channel */ #define WATR_LI_PAN (0x03e9) /**< The used PAN ID */ #define WATR_LI_IFACE (0) /**< The used Trasmssion device */ #define WATR_LI_UDP_PORT (12345) /**< The UDP port to listen */ @@ -65,9 +65,26 @@ static void *watr_li_udp_server(void *arg) if (recsize < 0) { puts("[watr_li_udp_server] ERROR: recsize < 0!"); + } else { + /* if we received a string print it */ + if (buffer_main[recsize-1] == '\0' ) { + printf("UDP packet received, payload:\n%s\n", buffer_main); + } else { + /* print the buffer bytes in hex */ + printf("UDP packet received, payload (%d bytes):\n", (int)recsize); + for(int i = 0; i < recsize; ++i) { + + if ( (i%8) == 0 ) { + /* newline after 8 bytes */ + puts(""); + } + + printf("%02x ", buffer_main[i]); + } + puts(""); + } } - printf("UDP packet received, payload: %s\n", buffer_main); } socket_base_close(sock); @@ -75,13 +92,17 @@ static void *watr_li_udp_server(void *arg) return NULL; } -static void watr_li_udp_send(void) +/** +* @brief sends a packet to the DODAG ID (should be the root node IPv6 address) +* @param[in] payload pointer to the payload to be sent +* @param[in] size number of bytes of the payload +*/ +static void watr_li_udp_send(char* payload, size_t payload_size) { int sock; sockaddr6_t sa; int bytes_sent; sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - char text[] = "watr.li node text"; char addr_str[IPV6_MAX_ADDR_STR_LEN]; if (-1 == sock) { @@ -90,22 +111,27 @@ static void watr_li_udp_send(void) } rpl_dodag_t *mydodag = rpl_get_my_dodag(); - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET; - memcpy(&sa.sin6_addr, &(mydodag->dodag_id), 16); - sa.sin6_port = HTONS(WATR_LI_UDP_PORT); - bytes_sent = socket_base_sendto(sock, (char *)text, - strlen(text) + 1, 0, &sa, - sizeof(sa)); + if(mydodag != NULL) { + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET; + memcpy(&sa.sin6_addr, &(mydodag->dodag_id), 16); + sa.sin6_port = HTONS(WATR_LI_UDP_PORT); - if (bytes_sent < 0) { - puts("[watr_li_udp_send] Error sending packet!"); - } + bytes_sent = socket_base_sendto(sock, + payload, + payload_size, + 0, &sa, sizeof(sa)); - printf("[watr_li_udp_send] Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", - bytes_sent, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, - &(sa.sin6_addr))); + if (bytes_sent < 0) { + puts("[watr_li_udp_send] Error sending packet!"); + } + printf("[watr_li_udp_send] Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", + bytes_sent, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, + &(sa.sin6_addr))); + } else { + puts("[watr_li_udp_send] not joined a DODAG (yet), so payload will not be sent."); + } socket_base_close(sock); } @@ -182,7 +208,7 @@ static int watr_li_setup_node(void) iface_id = set_watr_li_if(); /* choose addresses */ - ipv6_addr_init(&myaddr, 0x2015, 0x1, 0x28, 0x1111, 0x0, 0x0, 0x0, iface_id); + ipv6_addr_init(&myaddr, 0x2015, 0x3, 0x18, 0x1111, 0x0, 0x0, 0x0, iface_id); /* and set it */ set_watr_li_address(&myaddr); @@ -201,6 +227,9 @@ static int watr_li_init_rpl(void) return 0; } +/** +* @brief create a thread to receive UDP messages +*/ static void watr_li_start_udp_server(void) { thread_create(udp_server_stack_buffer,sizeof(udp_server_stack_buffer), @@ -215,13 +244,15 @@ int main(void) printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); printf("This board features a(n) %s MCU.\n", RIOT_MCU); + char payload[] = "watr.li node textX"; + watr_li_setup_node(); watr_li_init_rpl(); watr_li_start_udp_server(); - sleep(30); - watr_li_udp_send(); while(1){ + sleep(30); + watr_li_udp_send(payload, (strlen(payload) + 1)); thread_yield(); } From daa439f068e931ccdf80a9f062d60ae9a53b69fd Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Wed, 18 Mar 2015 15:30:14 +0100 Subject: [PATCH 4/7] [SQUASH ME] made payload more dynamic --- examples/watrli_rpl_udp/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/watrli_rpl_udp/main.c b/examples/watrli_rpl_udp/main.c index 791a9a2e85e0..17af3d0547b6 100644 --- a/examples/watrli_rpl_udp/main.c +++ b/examples/watrli_rpl_udp/main.c @@ -31,6 +31,8 @@ /** The UDP server thread stack */ char udp_server_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; +/** The node IPv6 address */ +ipv6_addr_t myaddr; /** * @brief the sample UDP server that expects receiving strings @@ -201,7 +203,6 @@ static int set_watr_li_address(ipv6_addr_t* node_addr) static int watr_li_setup_node(void) { radio_address_t iface_id = 0xffff; - ipv6_addr_t myaddr; set_watr_li_channel(WATR_LI_CHANNEL); set_watr_li_pan(WATR_LI_PAN); @@ -244,14 +245,17 @@ int main(void) printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); printf("This board features a(n) %s MCU.\n", RIOT_MCU); - char payload[] = "watr.li node textX"; + char payload[80]; + int msgnum = 0; watr_li_setup_node(); watr_li_init_rpl(); watr_li_start_udp_server(); + while(1){ sleep(30); + snprintf(payload, 80, "watr.li node(%x) msg: %d", HTONS(myaddr.uint16[7]), msgnum++); watr_li_udp_send(payload, (strlen(payload) + 1)); thread_yield(); } From fc23b256071abd396d28f7c43134bb0619858e4e Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Fri, 27 Mar 2015 18:27:05 +0100 Subject: [PATCH 5/7] [SQUASH ME] adjusted `rpl_init()` call to the API change providing the desired global address --- examples/watrli_rpl_udp/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/watrli_rpl_udp/main.c b/examples/watrli_rpl_udp/main.c index 17af3d0547b6..f6bf38025d39 100644 --- a/examples/watrli_rpl_udp/main.c +++ b/examples/watrli_rpl_udp/main.c @@ -212,7 +212,7 @@ static int watr_li_setup_node(void) ipv6_addr_init(&myaddr, 0x2015, 0x3, 0x18, 0x1111, 0x0, 0x0, 0x0, iface_id); /* and set it */ - set_watr_li_address(&myaddr); + //set_watr_li_address(&myaddr); return 0; } @@ -223,7 +223,7 @@ static int watr_li_setup_node(void) */ static int watr_li_init_rpl(void) { - rpl_init(WATR_LI_IFACE); + rpl_init(WATR_LI_IFACE, &myaddr); ipv6_iface_set_routing_provider(rpl_get_next_hop); return 0; } From 6d82ec10ad3a62f75d315964e08888fe7d764b64 Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Mon, 30 Mar 2015 08:02:47 +0200 Subject: [PATCH 6/7] [SQUASH ME] added comment pointing the API change --- examples/watrli_rpl_udp/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/watrli_rpl_udp/main.c b/examples/watrli_rpl_udp/main.c index f6bf38025d39..48ef041d1061 100644 --- a/examples/watrli_rpl_udp/main.c +++ b/examples/watrli_rpl_udp/main.c @@ -212,7 +212,7 @@ static int watr_li_setup_node(void) ipv6_addr_init(&myaddr, 0x2015, 0x3, 0x18, 0x1111, 0x0, 0x0, 0x0, iface_id); /* and set it */ - //set_watr_li_address(&myaddr); + /* set_watr_li_address(&myaddr); // this is done by RPL now automatically */ return 0; } From df3c31a9279f4d88a7ba06f5078fe658df45c434 Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Mon, 11 May 2015 13:50:44 +0200 Subject: [PATCH 7/7] [SQUASH ME] added option to let the node act as RPL root --- examples/watrli_rpl_udp/main.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/examples/watrli_rpl_udp/main.c b/examples/watrli_rpl_udp/main.c index 48ef041d1061..0d5da3e453a8 100644 --- a/examples/watrli_rpl_udp/main.c +++ b/examples/watrli_rpl_udp/main.c @@ -221,9 +221,25 @@ static int watr_li_setup_node(void) * @brief initialize RPL on this watr.li node * @return 0 on success */ -static int watr_li_init_rpl(void) +static int watr_li_init_rpl(bool is_root) { + /* use specific global address */ rpl_init(WATR_LI_IFACE, &myaddr); + + if(is_root) { + ipv6_addr_t prefix; + ipv6_addr_init(&prefix, 0x2015, 0x3, 0x18, 0x1111, 0x0, 0x0, 0x0, 0x0); + + rpl_options_t rpl_opts = { + .instance_id = 0, + .prefix = prefix, + .prefix_len = 64, + .prefix_flags = RPL_PREFIX_INFO_AUTO_ADDR_CONF, + /* autonomous address-configuration */ + }; + rpl_init_root(&rpl_opts); + } + ipv6_iface_set_routing_provider(rpl_get_next_hop); return 0; } @@ -247,15 +263,25 @@ int main(void) char payload[80]; int msgnum = 0; + bool is_root = false; watr_li_setup_node(); - watr_li_init_rpl(); + watr_li_init_rpl(is_root); watr_li_start_udp_server(); + if(is_root) { + puts("I'am the RPL root."); + } else { + puts("I'am a RPL node."); + } while(1){ sleep(30); - snprintf(payload, 80, "watr.li node(%x) msg: %d", HTONS(myaddr.uint16[7]), msgnum++); + if(is_root) { + snprintf(payload, 80, "watr.li root(%x) msg: %d", HTONS(myaddr.uint16[7]), msgnum++); + } else { + snprintf(payload, 80, "watr.li node(%x) msg: %d", HTONS(myaddr.uint16[7]), msgnum++); + } watr_li_udp_send(payload, (strlen(payload) + 1)); thread_yield(); }