From 0345f2824ba2a7d021608aecc2201faa85101458 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Thu, 6 Nov 2014 22:30:36 +0100 Subject: [PATCH 01/90] sixlowapp: initial import of a 6LoWPAN example app --- sixlowapp/Makefile | 36 ++++++++++++ sixlowapp/README.md | 10 ++++ sixlowapp/helper.c | 52 +++++++++++++++++ sixlowapp/main.c | 72 +++++++++++++++++++++++ sixlowapp/monitor.c | 71 +++++++++++++++++++++++ sixlowapp/sixlowapp.h | 108 +++++++++++++++++++++++++++++++++++ sixlowapp/sixlowshell.c | 123 ++++++++++++++++++++++++++++++++++++++++ sixlowapp/udp.c | 107 ++++++++++++++++++++++++++++++++++ 8 files changed, 579 insertions(+) create mode 100644 sixlowapp/Makefile create mode 100644 sixlowapp/README.md create mode 100644 sixlowapp/helper.c create mode 100644 sixlowapp/main.c create mode 100644 sixlowapp/monitor.c create mode 100644 sixlowapp/sixlowapp.h create mode 100644 sixlowapp/sixlowshell.c create mode 100644 sixlowapp/udp.c diff --git a/sixlowapp/Makefile b/sixlowapp/Makefile new file mode 100644 index 0000000000..dd8966a639 --- /dev/null +++ b/sixlowapp/Makefile @@ -0,0 +1,36 @@ +# name of your application +APPLICATION = sixlowapp + +# 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)/../../RIOT + +# Uncomment this to enable scheduler statistics for ps: +#CFLAGS += -DSCHEDSTATISTICS + +# Uncomment this to enable 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: +export QUIET ?= 1 + +# Modules to include: +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += uart0 +USEMODULE += ps +USEMODULE += defaulttransceiver +USEMODULE += udp +ifneq (,$(filter iot-lab_M3,$(BOARD))) + USEMODULE += isl29020 + USEMODULE += lps331ap + USEMODULE += l3g4200d + USEMODULE += lsm303dlhc +endif + + +include $(RIOTBASE)/Makefile.include diff --git a/sixlowapp/README.md b/sixlowapp/README.md new file mode 100644 index 0000000000..691a27c96f --- /dev/null +++ b/sixlowapp/README.md @@ -0,0 +1,10 @@ +Usage of sixlowapp - 6LoWPAN example +==================================== +* set up two nodes + * for nativenet: + * run `${RIOTBASE}/cpu/native/tapsetup.sh create` + * run `PORT=tap0 make term` + * run `PORT=tap1 make term` (from another terminal) +* type `ifconfig` on both nodes +* type `ping ` on node 1, using the link local unicast address of node 2 as ` on node 1, using the link local unicast address of node 2 as diff --git a/sixlowapp/helper.c b/sixlowapp/helper.c new file mode 100644 index 0000000000..8123c44f12 --- /dev/null +++ b/sixlowapp/helper.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 INRIA + * + * This file is 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 + * @brief 6LoWPAN example application helper functions + * + * @author Oliver Hahm + */ + +#include "msg.h" +#include "sixlowpan/ip.h" + +#include "sixlowapp.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +void sixlowapp_ndp_workaround(ipv6_addr_t *dest) +{ + /* add the destination to the neighbor cache if is not already in it */ + if (!ndp_neighbor_cache_search(dest)) { + DEBUGF("XXX: Adding %s to neighbor cache.\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, dest)); + ndp_neighbor_cache_add(IF_ID, dest, &(dest->uint16[7]), 2, 0, + NDP_NCE_STATUS_REACHABLE, + NDP_NCE_TYPE_TENTATIVE, 0xffff); + } +} + +uint64_t sixlowapp_wait_for_msg_type(msg_t *m, timex_t timeout, uint16_t mtype) +{ + timex_t t1, t2, delta; + delta = timex_set(0, 0); + vtimer_now(&t1); + while (timex_cmp(delta, timeout) < 0) { + if (vtimer_msg_receive_timeout(m, timeout) < 0) { + return 0; + } + vtimer_now(&t2); + delta = timex_sub(t2, t1); + if (m->type == mtype) { + return timex_uint64(delta); + } + timeout = timex_sub(timeout, delta); + } + return 0; +} diff --git a/sixlowapp/main.c b/sixlowapp/main.c new file mode 100644 index 0000000000..5f47dacf15 --- /dev/null +++ b/sixlowapp/main.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 INRIA + * + * This file is 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 + * @brief 6LoWPAN example application - main function + * + * @author Oliver Hahm + */ + +#include + +#include "kernel.h" +#include "thread.h" +#include "net_if.h" +#include "posix_io.h" +#include "shell.h" +#include "shell_commands.h" +#include "board_uart0.h" + +#include "sixlowapp.h" + +kernel_pid_t sixlowapp_udp_server_pid = KERNEL_PID_UNDEF; + +char addr_str[IPV6_MAX_ADDR_STR_LEN]; +char monitor_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; +char udp_server_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; + +const shell_command_t shell_commands[] = { + {"ping", "Send an ICMPv6 echo request to another node", sixlowapp_send_ping}, + {"nc", "RIOT netcat - arbitrary UDP connections and listens", sixlowapp_netcat}, + {NULL, NULL, NULL} +}; + +int main(void) +{ + puts("RIOT 6LoWPAN example v"APP_VERSION); + + sixlowpan_lowpan_init_interface(IF_ID); + + /* start thread for monitor mode */ + kernel_pid_t monitor_pid = thread_create(monitor_stack_buffer, + sizeof(monitor_stack_buffer), + PRIORITY_MAIN - 2, + CREATE_STACKTEST, + sixlowapp_monitor, NULL, + "monitor"); + + ipv6_register_packet_handler(monitor_pid); + + /* Start the UDP server thread */ + sixlowapp_udp_server_pid = thread_create(udp_server_stack_buffer, + sizeof(udp_server_stack_buffer), + PRIORITY_MAIN, CREATE_STACKTEST, + sixlowapp_udp_server_loop, NULL, + "UDP receiver"); + + /* Open the UART0 for the shell */ + posix_open(uart0_handler_pid, 0); + /* initialize the shell */ + shell_t shell; + shell_init(&shell, shell_commands, UART0_BUFSIZE, uart0_readc, uart0_putc); + /* start the shell loop */ + shell_run(&shell); + + return 0; +} diff --git a/sixlowapp/monitor.c b/sixlowapp/monitor.c new file mode 100644 index 0000000000..4c5e2def2c --- /dev/null +++ b/sixlowapp/monitor.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 INRIA + * + * This file is 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 + * @brief 6LoWPAN example application IPv6 monitor + * + * @author Oliver Hahm + */ + +#include "msg.h" +#include "sixlowpan/ip.h" + +#include "sixlowapp.h" + +#define RCV_BUFFER_SIZE (32) + +#define IPV6_HDR_LEN (0x28) + +#define ENABLE_DEBUG (0) +#include "debug.h" + +msg_t msg_q[RCV_BUFFER_SIZE]; + +void *sixlowapp_monitor(void *unused) +{ + (void) unused; + + msg_t m; + ipv6_hdr_t *ipv6_buf; + + msg_init_queue(msg_q, RCV_BUFFER_SIZE); + + while (1) { + msg_receive(&m); + + if (m.type == IPV6_PACKET_RECEIVED) { + ipv6_buf = (ipv6_hdr_t *) m.content.ptr; + + if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) { + icmpv6_hdr_t *icmpv6_buf = (icmpv6_hdr_t *) &((uint8_t*)ipv6_buf)[(IPV6_HDR_LEN)]; + if (icmpv6_buf->type == ICMPV6_TYPE_ECHO_REPLY) { + if (sixlowapp_waiting_for_pong) { + msg_t m; + m.type = ICMP_ECHO_REPLY_RCVD; + sixlowapp_waiting_for_pong = 0; + msg_send(&m, sixlowapp_waiter_pid); + } + } + } + /* add the destination to the neighbor cache if is not already in it */ + if (!ndp_neighbor_cache_search(&(ipv6_buf->srcaddr))) { + ndp_neighbor_cache_add(IF_ID, &(ipv6_buf->srcaddr), + &(ipv6_buf->srcaddr.uint16[7]), 2, + 0, NDP_NCE_STATUS_REACHABLE, + NDP_NCE_TYPE_TENTATIVE, 0xffff); + } + DEBUGF("IPv6 datagram received (next header: %02X)", ipv6_buf->nextheader); + DEBUG(" from %s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, + &ipv6_buf->srcaddr)); + } + else { + printf("! Unknown message received, type %04X\n", m.type); + } + } +} diff --git a/sixlowapp/sixlowapp.h b/sixlowapp/sixlowapp.h new file mode 100644 index 0000000000..a7ca999304 --- /dev/null +++ b/sixlowapp/sixlowapp.h @@ -0,0 +1,108 @@ +#ifndef SIXLOWAPP_H +#define SIXLOWAPP_H + +#include "kernel.h" +#include "ipv6.h" + +/** + * @brief The application version number + */ +#define APP_VERSION "1.3" + +/** + * @brief Which interface should be used for 6LoWPAN + */ +#define IF_ID (0) + +/** + * @brief Define a IPC message type for ICMP echo reply handling + */ +#define ICMP_ECHO_REPLY_RCVD (4444) + +/** + * @brief PID for UDP server thread + */ +extern kernel_pid_t sixlowapp_udp_server_pid; + +/** + * @brief UDP port number that netcat uses to listen at + */ +extern uint16_t sixlowapp_netcat_listen_port; + +/** + * @brief Marker if we're waiting for an ICMP echo reply + */ +extern unsigned sixlowapp_waiting_for_pong; + +/** + * @brief The PID of the thread waiting for the ICMP echo reply + */ +extern kernel_pid_t sixlowapp_waiter_pid; + +/** + * @brief Helper variable for IP address printing + */ +extern char addr_str[IPV6_MAX_ADDR_STR_LEN]; + +/** + * @brief Shell command to send an ICMPv6 echo request + * + * @param[in] argc Number of arguments supplied to the function invocation. + * @param[in] argv The supplied argument list. + * + */ +void sixlowapp_send_ping(int argc, char **argv); + +/** + * @brief Shell command for netcat + * + * @param[in] argc Number of arguments supplied to the function invocation. + * @param[in] argv The supplied argument list. + */ +void sixlowapp_netcat(int argc, char **argv); + +/** + * @brief Wrapper function for sending data of UDP + * + * @param[in] dest Destination IPv6 address + * @param[in] port Destination UDP port + * @param[in] payload Data to send + * @param[in] len Size of data to send + */ +void sixlowapp_udp_send(ipv6_addr_t *dest, uint16_t port, char *payload, size_t len); + +/** + * @brief Monitoring thread + * + * @param[in] unused Obsolete + */ +void *sixlowapp_monitor(void *unused); + +/** + * @brief UDP server thread + * + * @param[in] arg Obsolete + */ +void *sixlowapp_udp_server_loop(void *arg); + +/** + * @brief Provides a workaround for currently broken 6LoWPAN ND + * + * @param[in] dest The IPv6 address to add to the neighbor cache + */ +void sixlowapp_ndp_workaround(ipv6_addr_t *dest); + +/** + * @brief Waits for a certain message type for a given time span + * + * @param[out] m Pointer to preallocated ``msg_t`` structure, must not + * be NULL + * @param[in] timeout The maximum interval to wait + * @param[in] mtype The message type to wait for + * + * @return 0 if no message of type @p mtype was received + * @return The number of microseconds before the message was received + */ +uint64_t sixlowapp_wait_for_msg_type(msg_t *m, timex_t timeout, uint16_t mtype); + +#endif /* SIXLOWAPP_H */ diff --git a/sixlowapp/sixlowshell.c b/sixlowapp/sixlowshell.c new file mode 100644 index 0000000000..358eaad800 --- /dev/null +++ b/sixlowapp/sixlowshell.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2014 INRIA + * + * This file is 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 + * @brief 6LoWPAN example application shell functions + * + * @author Oliver Hahm + */ + +#include +#include "msg.h" +#include "thread.h" +#include "sched.h" +#include "sixlowpan/ip.h" +#include "inet_pton.h" + +#include "sixlowapp.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define ICMP_DATA "RIOT" +#define ICMP_TIMEOUT (100) + +#define MAX_PAYLOAD_SIZE (32) + +extern uint8_t ipv6_ext_hdr_len; + +static char payload[MAX_PAYLOAD_SIZE]; + +unsigned sixlowapp_waiting_for_pong; +kernel_pid_t sixlowapp_waiter_pid; + +void sixlowapp_send_ping(int argc, char **argv) +{ + ipv6_addr_t dest; + const char *icmp_data = ICMP_DATA; + + if (argc != 2) { + puts("! Invalid number of parameters"); + printf(" usage: %s destination\n", argv[0]); + return; + } + + if (!inet_pton(AF_INET6, argv[1], &dest)) { + printf("! %s is not a valid IPv6 address\n", argv[1]); + return; + } + + sixlowapp_ndp_workaround(&dest); + + /* send an echo request */ + icmpv6_send_echo_request(&dest, 1, 1, (uint8_t *) icmp_data, sizeof(icmp_data)); + + sixlowapp_waiting_for_pong = 1; + sixlowapp_waiter_pid = sched_active_pid; + uint64_t rtt; + msg_t m; + m.type = 0; + rtt = sixlowapp_wait_for_msg_type(&m, timex_set(0, ICMP_TIMEOUT * 1000), ICMP_ECHO_REPLY_RCVD); + if (sixlowapp_waiting_for_pong == 0) { + char ts[TIMEX_MAX_STR_LEN]; + printf("Echo reply from %s received, rtt: %s\n", inet_ntop(AF_INET6, &dest, + addr_str, + IPV6_MAX_ADDR_STR_LEN), + timex_to_str(timex_from_uint64(rtt), ts)); + } + else { + printf("! Destination %s is unreachable\n", inet_ntop(AF_INET6, + &dest, + addr_str, + IPV6_MAX_ADDR_STR_LEN)); + } +} + +void sixlowapp_netcat(int argc, char **argv) +{ + ipv6_addr_t dest; + + if (argc < 3) { + puts("! Not enough parameters"); + puts(" usage: nc [-l] [destination] [port]"); + return; + } + + if (strlen(argv[1]) == 2) { + if (strncmp(argv[1], "-l", 2)) { + puts("! Invalid parameter"); + puts(" usage: nc [-l] [destination] [port]"); + return; + } + else { + sixlowapp_netcat_listen_port = atoi(argv[2]); + thread_wakeup(sixlowapp_udp_server_pid); + } + } + else if (!inet_pton(AF_INET6, argv[1], &dest)) { + printf("! %s is not a valid IPv6 address\n", argv[1]); + } + else { + sixlowapp_ndp_workaround(&dest); + size_t plen; + if (argc > 3 ) { + plen = (strlen(argv[3]) > MAX_PAYLOAD_SIZE) ? MAX_PAYLOAD_SIZE : strlen(argv[1]) + 1; + memcpy(payload, argv[3], plen); + payload[plen - 1] = 0; + } + else { + plen = 5; + strncpy(payload, "RIOT", plen); + + } + sixlowapp_udp_send(&dest, atoi(argv[2]), payload, plen); + } +} + + diff --git a/sixlowapp/udp.c b/sixlowapp/udp.c new file mode 100644 index 0000000000..0eff3505df --- /dev/null +++ b/sixlowapp/udp.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2013, 2014 INRIA + * + * 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. + */ + +/** + * @file + * + * @author Oliver Hahm + */ + +#include +#include +#include +#include +#include + +#include "thread.h" +#include "socket_base/socket.h" +#include "net_help.h" +#include "sixlowapp.h" + +#define UDP_BUFFER_SIZE (128) + +uint16_t sixlowapp_netcat_listen_port; + +/* UDP server thread */ +void *sixlowapp_udp_server_loop(void *arg) +{ + (void) arg; + + sockaddr6_t sa; + char buffer_main[UDP_BUFFER_SIZE]; + uint32_t fromlen; + int sock; + fromlen = sizeof(sa); + + while (1) { + while(!sixlowapp_netcat_listen_port) { + thread_sleep(); + } + + sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET; + sa.sin6_port = HTONS(sixlowapp_netcat_listen_port); + + if (-1 == socket_base_bind(sock, &sa, sizeof(sa))) { + printf("Error bind failed!\n"); + socket_base_close(sock); + sixlowapp_netcat_listen_port = 0; + continue; + } + + printf("Listening for incoming UDP connection at port %" PRIu16 "\n", sixlowapp_netcat_listen_port); + int32_t recsize = socket_base_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); + + socket_base_close(sock); + sixlowapp_netcat_listen_port = 0; + } + + return NULL; +} + +/* UDP send command */ +void sixlowapp_udp_send(ipv6_addr_t *dest, uint16_t port, char *payload, size_t len) +{ + int sock; + sockaddr6_t sa; + int bytes_sent; + + sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + if (-1 == sock) { + printf("Error Creating Socket!"); + return; + } + memset(&sa, 0, sizeof(sa)); + sa.sin6_family = AF_INET; + memcpy(&sa.sin6_addr, dest, 16); + sa.sin6_port = HTONS(port); + + printf("Trying to send %i bytes to %s:%" PRIu16 "\n", len, + ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, dest), port); + bytes_sent = socket_base_sendto(sock, payload, len, 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, IPV6_MAX_ADDR_STR_LEN, + dest)); + } + + socket_base_close(sock); +} From b921f573893f2853ad680d297d5bde81c9f557d0 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Fri, 7 Nov 2014 00:10:06 +0100 Subject: [PATCH 02/90] sixlowapp: fixed typo and complemented usage text --- sixlowapp/sixlowshell.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sixlowapp/sixlowshell.c b/sixlowapp/sixlowshell.c index 358eaad800..a4fbe2faac 100644 --- a/sixlowapp/sixlowshell.c +++ b/sixlowapp/sixlowshell.c @@ -85,14 +85,14 @@ void sixlowapp_netcat(int argc, char **argv) if (argc < 3) { puts("! Not enough parameters"); - puts(" usage: nc [-l] [destination] [port]"); + puts(" usage: nc [-l] [destination] [port] [text]"); return; } if (strlen(argv[1]) == 2) { if (strncmp(argv[1], "-l", 2)) { puts("! Invalid parameter"); - puts(" usage: nc [-l] [destination] [port]"); + puts(" usage: nc [-l] [destination] [port] [text]"); return; } else { @@ -107,7 +107,7 @@ void sixlowapp_netcat(int argc, char **argv) sixlowapp_ndp_workaround(&dest); size_t plen; if (argc > 3 ) { - plen = (strlen(argv[3]) > MAX_PAYLOAD_SIZE) ? MAX_PAYLOAD_SIZE : strlen(argv[1]) + 1; + plen = (strlen(argv[3]) > MAX_PAYLOAD_SIZE) ? MAX_PAYLOAD_SIZE : strlen(argv[3]) + 1; memcpy(payload, argv[3], plen); payload[plen - 1] = 0; } From 1744c6686db6c5f65ec876a0f7dab72cf740b7ce Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Fri, 7 Nov 2014 00:15:30 +0100 Subject: [PATCH 03/90] sixlowapp: updated README --- sixlowapp/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sixlowapp/README.md b/sixlowapp/README.md index 691a27c96f..367175dd44 100644 --- a/sixlowapp/README.md +++ b/sixlowapp/README.md @@ -6,5 +6,6 @@ Usage of sixlowapp - 6LoWPAN example * run `PORT=tap0 make term` * run `PORT=tap1 make term` (from another terminal) * type `ifconfig` on both nodes -* type `ping ` on node 1, using the link local unicast address of node 2 as ` on node 1, using the link local unicast address of node 2 as +* type `ping ` on node 1, using one of node 2's IPv6 addresses +* type `nc -l ` on of the nodes +* type `nc ` on the other node to send `` to the first node From 7bc5111e874916e97fae789aa0ad3262a46eee66 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Thu, 27 Nov 2014 11:58:39 +0100 Subject: [PATCH 04/90] sniffer: initial import Inspired by https://github.com/malvira/libmc1322x/wiki/wireshark --- sniffer/Makefile | 29 ++++++++ sniffer/main.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 sniffer/Makefile create mode 100644 sniffer/main.c diff --git a/sniffer/Makefile b/sniffer/Makefile new file mode 100644 index 0000000000..350a753f22 --- /dev/null +++ b/sniffer/Makefile @@ -0,0 +1,29 @@ +# Set the name of your application: +APPLICATION = sniffer + +# 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)/../../RIOT + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +# blacklist all boards without radio support +BOARD_BLACKLIST := arduino-due arduino-mega2560 mbed_lpc1768 msb-430 pttu \ + udoo qemu-i386 stm32f0discovery stm32f3discovery \ + stm32f4discovery pca10000 pca10005 msbiot samr21-xpro \ + yunjia-nrf51822 + +# Modules to include: + +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += uart0 +USEMODULE += ps +USEMODULE += vtimer +USEMODULE += auto_init +USEMODULE += defaulttransceiver + +include $(RIOTBASE)/Makefile.include diff --git a/sniffer/main.c b/sniffer/main.c new file mode 100644 index 0000000000..c0eb6463ed --- /dev/null +++ b/sniffer/main.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors to + * the MC1322x project (http://mc1322x.devl.org) + * Copyright (C) 2014 Oliver Hahm + * + * 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 main.c + * + * @brief Sniffer application for MSB-A2 and Wireshark + * + * @author Oliver Hahm + * @author Mariano Alvira + * + * @} + */ + +#include +#include + +#include "thread.h" +#include "posix_io.h" +#include "shell.h" +#include "shell_commands.h" +#include "board_uart0.h" +#include "hwtimer.h" +#include "transceiver.h" +#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X +#include "ieee802154_frame.h" +#endif + +#define RCV_BUFFER_SIZE (64) +#define RADIO_STACK_SIZE (KERNEL_CONF_STACKSIZE_MAIN) +#define PER_ROW (16) + +char radio_stack_buffer[RADIO_STACK_SIZE]; +msg_t msg_q[RCV_BUFFER_SIZE]; +transceiver_command_t tcmd; + +#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X +void print_packet(ieee802154_packet_t *p) +#else +void print_packet(radio_packet_t *p) +#endif +{ + volatile uint8_t i, j, k; + + if (p) { + printf("len 0x%02x lqi 0x%02x rx_time 0x%08lx", p->length, p->lqi, hwtimer_now()); + + for (j = 0, k = 0; j <= ((p->length) / PER_ROW); j++) { + printf("\n\r"); + + for (i = 0; i < PER_ROW; i++, k++) { + if (k >= p->length) { + printf("\n\r"); + return; + } + +#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X + printf("%02x ", p->frame.payload[j * PER_ROW + i]); +#else + printf("%02x ", p->data[j * PER_ROW + i]); +#endif + } + } + } + + printf("\n\r"); + return; +} + +void *radio(void *unused) +{ + (void) unused; + + msg_t m; +#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X + ieee802154_packet_t *p; +#else + radio_packet_t *p; +#endif + + msg_init_queue(msg_q, RCV_BUFFER_SIZE); + + while (1) { + msg_receive(&m); + + if (m.type == PKT_PENDING) { +#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X + p = (ieee802154_packet_t *) m.content.ptr; +#else + p = (radio_packet_t *) m.content.ptr; +#endif + printf("rftest-rx --- "); + print_packet(p); + p->processing--; + } + else if (m.type == ENOBUFFER) { + puts("Transceiver buffer full"); + } + else { + puts("Unknown packet received"); + } + } + + return NULL; +} + +void init_transceiver(void) +{ + kernel_pid_t radio_pid = thread_create( + radio_stack_buffer, + sizeof(radio_stack_buffer), + PRIORITY_MAIN - 2, + CREATE_STACKTEST, + radio, + NULL, + "radio"); + + uint16_t transceivers = TRANSCEIVER_DEFAULT; + + transceiver_init(transceivers); + transceiver_start(); + transceiver_register(transceivers, radio_pid); + + msg_t mesg; + mesg.type = SET_CHANNEL; + mesg.content.ptr = (char *) &tcmd; + + uint16_t c = 10; + + tcmd.transceivers = TRANSCEIVER_DEFAULT; + tcmd.data = &c; + printf("Set transceiver to channel %u\n", c); + msg_send(&mesg, transceiver_pid); + + mesg.type = SET_MONITOR; + mesg.content.ptr = (char *) &tcmd; + + uint16_t v = 1; + + tcmd.data = &v; + printf("Set transceiver into monitor mode\n"); + msg_send(&mesg, transceiver_pid); +} + +static int shell_readc(void) +{ + char c = 0; + posix_read(uart0_handler_pid, &c, 1); + return c; +} + +static void shell_putchar(int c) +{ + putchar(c); +} + +int main(void) +{ + shell_t shell; + posix_open(uart0_handler_pid, 0); + init_transceiver(); + + puts("Welcome to RIOT!"); + + shell_init(&shell, NULL, UART0_BUFSIZE, shell_readc, shell_putchar); + shell_run(&shell); + + return 0; +} From 7daa0c00f9f61a99dc4d220de4bc7c996fad354a Mon Sep 17 00:00:00 2001 From: Lotte Steenbrink Date: Wed, 4 Feb 2015 16:28:58 -0800 Subject: [PATCH 05/90] add microcoap example application --- microcoap/Makefile | 32 +++++++++ microcoap/README.md | 146 ++++++++++++++++++++++++++++++++++++++++++ microcoap/endpoints.c | 53 +++++++++++++++ microcoap/main.c | 143 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 374 insertions(+) create mode 100644 microcoap/Makefile create mode 100644 microcoap/README.md create mode 100644 microcoap/endpoints.c create mode 100644 microcoap/main.c diff --git a/microcoap/Makefile b/microcoap/Makefile new file mode 100644 index 0000000000..75b7527f88 --- /dev/null +++ b/microcoap/Makefile @@ -0,0 +1,32 @@ +# name of your application +APPLICATION = microcoap-example + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# if you try to compile this for anything but the boards specified, it will break. +# This application has not been verified to work with any other boards-- proceed with caution. +BOARD_WHITELIST := native + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../../RIOT + +# 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 += -DRIOT -DMICROCOAP_DEBUG + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +USEPKG=microcoap + +USEMODULE += config +USEMODULE += uart0 + +USEMODULE += nativenet + +USEMODULE += sixlowpan +USEMODULE += udp + +include $(RIOTBASE)/Makefile.include diff --git a/microcoap/README.md b/microcoap/README.md new file mode 100644 index 0000000000..ceab8b9ba5 --- /dev/null +++ b/microcoap/README.md @@ -0,0 +1,146 @@ +Microcoap example +============ + +This is a small microcoap example application. It provides a server which only +answers GET requests to the resource /foo/bar. + +## Setup + +You can use [marz](https://github.com/sgso/marz) to tunnel CoAP messages into the RIOT native thread. This is a bit tricky, so maybe this walkthrough will help: + +0. Build this application. +1. Install the copper plugin in your Firefox browser. +2. Run `sudo apt-get install bridge-utils` +3. In your RIOT directury, run + + ./cpu/native/tapsetup.sh create 2 + +This will set up two tap devices connected by a bridge. our RIOT application and +marz will each listen at one of these devices, and communicate over the bridge. + +3. Open two terminal windows. + +**In window #1**, start the microcoap-example application: + + cd applications/microcoap + sudo ./bin/native/microcoap-example.elf tap1 -i 1 + +*Make sure to bind it to ``tap1``, since marz will be bound to ``tap0`!* +``-i 1`` forces your RIOT instance to match its id to the one specified in marz.config. You should **only** specify this for the **one** RIOT that marz tunnels to. This is sufficient for this example; if you need help running more than one RIOT with marz, please contact the author of this example. + +You should see output similar to this. + + RIOT native uart0 initialized. + RIOT native interrupts/signals initialized. + LED_GREEN_OFF + LED_RED_ON + RIOT native board initialized. + RIOT native hardware initialization complete. + + kernel_init(): This is RIOT! (Version: 400e-microcoap) + kernel_init(): jumping into first task... + UART0 thread started. + uart0_init() [OK] + Initializing transport layer protocol: udp + Starting example microcoap server... + initializing 6LoWPAN... + initializing receive socket... + Ready to receive requests. + + Welcome to RIOT + + > + +**In window #2**, first install Python development headers by running + + sudo apt-get install python-dev + +Afterwards you can install and run marz: + + pip install --user Twisted && + pip install --user bidict && + git clone https://github.com/sgso/marz && + cd marz && + ./setup.sh + + ./marz.py + +You should see output similar to this. + + WARNING: No route found for IPv6 destination :: (no default route?) + Listening on UDP ports: [5683, 2222] + Listening on tap interface tap0 with MAC address 9a:80:a3:fc:93:18 + +## Testing + +The "Copper" firefox plugin is a convenient way to test CoAP endpoints. In the absence of a GUI you can also use Python to send test requests. + +### Using python(3) + +First, make sure Python 3 is installed, clone `aiocoap` into a directory of your choice and then change into it: + + git clone git@github.com:chrysn/aiocoap.git && + cd aiocoap + +Open the `clientGET.py` file and change the line that reads + + request.set_request_uri() + +to + + request.set_request_uri('coap://[::1]/foo/bar') + +Then run `clientGET.py`, which should print the following: + + $ ./clientGET.py + Result: 2.05 Content + b'1337' + + +### Using the Firefox Copper plugin + +Open Firefox and enter + + coap://[::1]:5683/foo/bar + +Into the browser window. Then, click the big gren ``GET`` button. This should +trigger a GET request to our microcoap-example application. Shortly after you've +clicked GET, **window #2** should read + + make new connection + [UDP6 5683] Received 14 data bytes from ('::1', 54685): Relaying through 54685 to RiotEndpoint(hwaddr=1, ipv6='fe80::ff:fe00:1', port=5683) + [TAP] Received 12 data bytes on port 54685: Relaying through 5683 to IP6Endpoint(ipv6='::1', port=54685) + +**window #1** should supply you with detailed information about the received +request and the reply our microcoap-example is sending: + + > Received packet: 40 01 0B EC B3 66 6F 6F 03 62 61 72 C1 02 + content: + Header: + ver 0x01 + t 0x01 + tkl 0x00 + code 0x01 + id 0x0BEC + Options: + 0x0B [ 66 6F 6F ] + 0x0B [ 62 61 72 ] + 0x17 [ 02 ] + Payload: + Sending packet: 60 45 0B EC C2 00 00 FF 31 33 33 37 + content: + Header: + ver 0x01 + t 0x01 + tkl 0x00 + code 0x45 + id 0x0BEC + Options: + 0x0C [ 00 00 ] + Payload: 31 33 33 37 + +And finally, the big grey ``Payload`` box in your Firefox window should read: + + 1337 + +If this all works, you're good to go! :) diff --git a/microcoap/endpoints.c b/microcoap/endpoints.c new file mode 100644 index 0000000000..ddf95700a6 --- /dev/null +++ b/microcoap/endpoints.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 HAW Hamburg + * + * 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. + */ + +/** + * @{ + * + * @file + * @brief microcoap example server endpoints + * + * @author Lotte Steenbrink + * + * @} + */ + +#include +#include +#include +#include "coap.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define MAX_RESPONSE_LEN 1500 +static uint8_t response[MAX_RESPONSE_LEN] = ""; + +static const coap_endpoint_path_t path = {2, {"foo", "bar"}}; + +void create_response_payload(const uint8_t *buffer) +{ + char *response = "1337"; + memcpy((void*)buffer, response, strlen(response)); +} + +/* The handler which handles the path /foo/bar */ +static int handle_get_response(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo) +{ + DEBUG("[endpoints] %s()\n", __func__); + create_response_payload(response); + /* NOTE: COAP_RSPCODE_CONTENT only works in a packet answering a GET. */ + return coap_make_response(scratch, outpkt, response, strlen((char*)response), + id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN); +} + +const coap_endpoint_t endpoints[] = +{ + {COAP_METHOD_GET, handle_get_response, &path, "ct=0"}, + {(coap_method_t)0, NULL, NULL, NULL} /* marks the end of the endpoints array */ +}; diff --git a/microcoap/main.c b/microcoap/main.c new file mode 100644 index 0000000000..782dc11ca6 --- /dev/null +++ b/microcoap/main.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2015 HAW Hamburg + * + * 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. + */ + +/** + * @{ + * + * @file + * @brief microcoap example server + * + * @author Lotte Steenbrink + * + * @} + */ + +#include + +#include "udp.h" +#include "net_help.h" +#include "net_if.h" +#include "periph/cpuid.h" +#include "board_uart0.h" +#include "thread.h" +#include "posix_io.h" +#include +#include "hashes.h" + +#define ENABLE_DEBUG (1) +#include "debug.h" + +#define PORT 5683 +#define BUFSZ 128 + +#define RCV_MSG_Q_SIZE (64) + +static void *_microcoap_server_thread(void *arg); + +msg_t msg_q[RCV_MSG_Q_SIZE]; +char _rcv_stack_buf[KERNEL_CONF_STACKSIZE_MAIN]; + +static ipv6_addr_t prefix; +int sock_rcv, if_id; +sockaddr6_t sa_rcv; +uint8_t buf[BUFSZ]; +uint8_t scratch_raw[BUFSZ]; +coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)}; + +static void _init_tlayer(void); +static uint16_t get_hw_addr(void); + +int main(void) +{ + + DEBUG("Starting example microcoap server...\n"); + + _init_tlayer(); + thread_create(_rcv_stack_buf, KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN, CREATE_STACKTEST, _microcoap_server_thread, NULL ,"_microcoap_server_thread"); + + DEBUG("Ready to receive requests.\n"); + + return 0; +} + +static uint16_t get_hw_addr(void) +{ + return sysconfig.id; +} + +/* init transport layer & routing stuff*/ +static void _init_tlayer(void) +{ + msg_init_queue(msg_q, RCV_MSG_Q_SIZE); + + net_if_set_hardware_address(0, get_hw_addr()); + DEBUG("set hawddr to: %d\n", get_hw_addr()); + + printf("initializing 6LoWPAN...\n"); + + ipv6_addr_init(&prefix, 0xABCD, 0xEF12, 0, 0, 0, 0, 0, 0); + if_id = 0; /* having more than one interface isn't supported anyway */ + + sixlowpan_lowpan_init_interface(if_id); +} + +static void *_microcoap_server_thread(void *arg) +{ + (void)arg; /* make the compiler shut up about unused variables */ + + printf("initializing receive socket...\n"); + + sa_rcv = (sockaddr6_t) { .sin6_family = AF_INET6, + .sin6_port = HTONS(PORT) }; + + sock_rcv = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + if (-1 == socket_base_bind(sock_rcv, &sa_rcv, sizeof(sa_rcv))) { + printf("Error: bind to receive socket failed!\n"); + socket_base_close(sock_rcv); + } + + printf("Ready to receive requests.\n"); + + while(1) + { + int n, rc; + socklen_t len = sizeof(sa_rcv); + coap_packet_t pkt; + + n = socket_base_recvfrom(sock_rcv, buf, sizeof(buf), 0, &sa_rcv, &len); + printf("Received packet: "); + coap_dump(buf, n, true); + printf("\n"); + + if (0 != (rc = coap_parse(&pkt, buf, n))) + printf("Bad packet rc=%d\n", rc); + else + { + size_t rsplen = sizeof(buf); + coap_packet_t rsppkt; + printf("content:\n"); + coap_dumpPacket(&pkt); + coap_handle_req(&scratch_buf, &pkt, &rsppkt); + + if (0 != (rc = coap_build(buf, &rsplen, &rsppkt))) + printf("coap_build failed rc=%d\n", rc); + else + { + printf("Sending packet: "); + coap_dump(buf, rsplen, true); + printf("\n"); + printf("content:\n"); + coap_dumpPacket(&rsppkt); + socket_base_sendto(sock_rcv, buf, rsplen, 0, &sa_rcv, sizeof(sa_rcv)); + } + } + } + + return NULL; +} From de18e754573bd9d3d64ed722752643d7346d1f61 Mon Sep 17 00:00:00 2001 From: Lotte Steenbrink Date: Sat, 21 Mar 2015 14:01:49 +0100 Subject: [PATCH 06/90] sixlowapp: fix small typo --- sixlowapp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sixlowapp/README.md b/sixlowapp/README.md index 367175dd44..6482369bd6 100644 --- a/sixlowapp/README.md +++ b/sixlowapp/README.md @@ -7,5 +7,5 @@ Usage of sixlowapp - 6LoWPAN example * run `PORT=tap1 make term` (from another terminal) * type `ifconfig` on both nodes * type `ping ` on node 1, using one of node 2's IPv6 addresses -* type `nc -l ` on of the nodes +* type `nc -l ` to start a UDP server listening on `` on of the nodes * type `nc ` on the other node to send `` to the first node From afc975834bddec3a4bd46e2db17074c638227bf4 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Thu, 9 Apr 2015 18:19:35 +0200 Subject: [PATCH 07/90] sixlowapp: adapted to new shell handler prototype --- sixlowapp/sixlowapp.h | 7 +++++-- sixlowapp/sixlowshell.c | 17 +++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/sixlowapp/sixlowapp.h b/sixlowapp/sixlowapp.h index a7ca999304..75e49944ae 100644 --- a/sixlowapp/sixlowapp.h +++ b/sixlowapp/sixlowapp.h @@ -50,16 +50,19 @@ extern char addr_str[IPV6_MAX_ADDR_STR_LEN]; * @param[in] argc Number of arguments supplied to the function invocation. * @param[in] argv The supplied argument list. * + * @returns 0 on success, error code on invalide parameters */ -void sixlowapp_send_ping(int argc, char **argv); +int sixlowapp_send_ping(int argc, char **argv); /** * @brief Shell command for netcat * * @param[in] argc Number of arguments supplied to the function invocation. * @param[in] argv The supplied argument list. + * + * @returns 0 on success, error code on invalide parameters */ -void sixlowapp_netcat(int argc, char **argv); +int sixlowapp_netcat(int argc, char **argv); /** * @brief Wrapper function for sending data of UDP diff --git a/sixlowapp/sixlowshell.c b/sixlowapp/sixlowshell.c index a4fbe2faac..3fc28cbbc1 100644 --- a/sixlowapp/sixlowshell.c +++ b/sixlowapp/sixlowshell.c @@ -14,6 +14,7 @@ */ #include +#include #include "msg.h" #include "thread.h" #include "sched.h" @@ -37,7 +38,7 @@ static char payload[MAX_PAYLOAD_SIZE]; unsigned sixlowapp_waiting_for_pong; kernel_pid_t sixlowapp_waiter_pid; -void sixlowapp_send_ping(int argc, char **argv) +int sixlowapp_send_ping(int argc, char **argv) { ipv6_addr_t dest; const char *icmp_data = ICMP_DATA; @@ -45,12 +46,12 @@ void sixlowapp_send_ping(int argc, char **argv) if (argc != 2) { puts("! Invalid number of parameters"); printf(" usage: %s destination\n", argv[0]); - return; + return EINVAL; } if (!inet_pton(AF_INET6, argv[1], &dest)) { printf("! %s is not a valid IPv6 address\n", argv[1]); - return; + return EFAULT; } sixlowapp_ndp_workaround(&dest); @@ -77,23 +78,25 @@ void sixlowapp_send_ping(int argc, char **argv) addr_str, IPV6_MAX_ADDR_STR_LEN)); } + + return 0; } -void sixlowapp_netcat(int argc, char **argv) +int sixlowapp_netcat(int argc, char **argv) { ipv6_addr_t dest; if (argc < 3) { puts("! Not enough parameters"); puts(" usage: nc [-l] [destination] [port] [text]"); - return; + return EINVAL; } if (strlen(argv[1]) == 2) { if (strncmp(argv[1], "-l", 2)) { puts("! Invalid parameter"); puts(" usage: nc [-l] [destination] [port] [text]"); - return; + return EINVAL; } else { sixlowapp_netcat_listen_port = atoi(argv[2]); @@ -118,6 +121,8 @@ void sixlowapp_netcat(int argc, char **argv) } sixlowapp_udp_send(&dest, atoi(argv[2]), payload, plen); } + + return 0; } From 47a6057bcd8f42ce70308fb35f65edeec8ce80dd Mon Sep 17 00:00:00 2001 From: haukepetersen Date: Tue, 21 Apr 2015 18:45:09 +0200 Subject: [PATCH 08/90] ng_sniffer: added ng version of sniffer application --- ng_sniffer/Makefile | 21 ++++++++ ng_sniffer/README.md | 12 +++++ ng_sniffer/main.c | 119 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 ng_sniffer/Makefile create mode 100644 ng_sniffer/README.md create mode 100644 ng_sniffer/main.c diff --git a/ng_sniffer/Makefile b/ng_sniffer/Makefile new file mode 100644 index 0000000000..2a75555e08 --- /dev/null +++ b/ng_sniffer/Makefile @@ -0,0 +1,21 @@ +# Set the name of your application: +APPLICATION = ng_sniffer + +# 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)/../../RIOT + +# Define modules that are used +USEMODULE += ng_netif +USEMODULE += auto_init_ng_netif +USEMODULE += uart0 +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/ng_sniffer/README.md b/ng_sniffer/README.md new file mode 100644 index 0000000000..db45fe4a78 --- /dev/null +++ b/ng_sniffer/README.md @@ -0,0 +1,12 @@ +About +===== + +This application is build to run together with the script `RIOTBASE/dist/tools/ng_sniffer/ng_sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. + + +Usage +===== + +Compile and flash this application to the board of your choice. You can check if everything on the RIOT side works by connecting to the board via UART and by checking with `ifconfig` if a network device is available. Further you can check with `ifconfig 4 promisc` if promiscuous mode is supported and with `ifconfig 4 raw` if raw mode is supported by the driver/network device. + +For further information on setting up the host part, see `RIOTBASE/dist/tools/ng_snifffer/README.md`. diff --git a/ng_sniffer/main.c b/ng_sniffer/main.c new file mode 100644 index 0000000000..6e82dc33be --- /dev/null +++ b/ng_sniffer/main.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * 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. + */ + +/** + * @defgroup app_sniffer + * @brief Sniffer application based on the new network stack + * @{ + * + * @file + * @brief Sniffer application for RIOT + * + * @author Hauke Petersen + * + * @} + */ + +#include + +#include "thread.h" +#include "hwtimer.h" +#include "shell.h" +#include "shell_commands.h" +#include "posix_io.h" +#include "board_uart0.h" +#include "net/ng_netbase.h" + +/** + * @brief Buffer size used by the shell + */ +#define SHELL_BUFSIZE (64U) + +/** + * @brief Priority of the RAW dump thread + */ +#define RAWDUMP_PRIO (THREAD_PRIORITY_MAIN - 1) + +/** + * @brief Stack for the raw dump thread + */ +static char rawdmp_stack[THREAD_STACKSIZE_MAIN]; + +/** + * @brief Make a raw dump of the given packet contents + */ +void dump_pkt(ng_pktsnip_t *pkt) +{ + ng_pktsnip_t *snip = pkt; + + printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n", + ng_pkt_len(pkt), 0, hwtimer_now()); + + while (snip) { + for (size_t i = 0; i < snip->size; i++) { + printf("0x%02x ", ((uint8_t *)(snip->data))[i]); + } + snip = snip->next; + } + puts("\n"); + + ng_pktbuf_release(pkt); +} + +/** + * @brief Event loop of the RAW dump thread + * + * @param[in] arg unused parameter + */ +void *rawdump(void *arg) +{ + (void)arg; + msg_t msg; + + while (1) { + msg_receive(&msg); + + switch (msg.type) { + case NG_NETAPI_MSG_TYPE_RCV: + dump_pkt((ng_pktsnip_t *)msg.content.ptr); + break; + default: + /* do nothing */ + break; + } + } + + /* never reached */ + return NULL; +} + +/** + * @brief Maybe you are a golfer?! + */ +int main(void) +{ + shell_t shell; + ng_netreg_entry_t dump; + + puts("RIOT sniffer application"); + + /* start and register rawdump thread */ + puts("Run the rawdump thread and register it"); + dump.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, + CREATE_STACKTEST, rawdump, NULL, "rawdump"); + dump.demux_ctx = NG_NETREG_DEMUX_CTX_ALL; + ng_netreg_register(NG_NETTYPE_UNDEF, &dump); + + /* start the shell */ + puts("All ok, starting the shell now"); + (void) posix_open(uart0_handler_pid, 0); + shell_init(&shell, NULL, SHELL_BUFSIZE, uart0_readc, uart0_putc); + shell_run(&shell); + + return 0; +} From e0ef049f78967bbbe7e7637928f9138c6bc4113c Mon Sep 17 00:00:00 2001 From: Philipp Borgers Date: Thu, 4 Jun 2015 09:30:48 +0200 Subject: [PATCH 09/90] sixlowapp: rename thread related constants The constants names changed in the past: https://github.com/RIOT-OS/RIOT/commit/426170b06439badf41818a58b37117aac26806a9 --- sixlowapp/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sixlowapp/main.c b/sixlowapp/main.c index 5f47dacf15..2b36c3087d 100644 --- a/sixlowapp/main.c +++ b/sixlowapp/main.c @@ -28,8 +28,8 @@ kernel_pid_t sixlowapp_udp_server_pid = KERNEL_PID_UNDEF; char addr_str[IPV6_MAX_ADDR_STR_LEN]; -char monitor_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; -char udp_server_stack_buffer[KERNEL_CONF_STACKSIZE_MAIN]; +char monitor_stack_buffer[THREAD_STACKSIZE_MAIN]; +char udp_server_stack_buffer[THREAD_STACKSIZE_MAIN]; const shell_command_t shell_commands[] = { {"ping", "Send an ICMPv6 echo request to another node", sixlowapp_send_ping}, @@ -46,7 +46,7 @@ int main(void) /* start thread for monitor mode */ kernel_pid_t monitor_pid = thread_create(monitor_stack_buffer, sizeof(monitor_stack_buffer), - PRIORITY_MAIN - 2, + THREAD_PRIORITY_MAIN - 2, CREATE_STACKTEST, sixlowapp_monitor, NULL, "monitor"); @@ -56,7 +56,7 @@ int main(void) /* Start the UDP server thread */ sixlowapp_udp_server_pid = thread_create(udp_server_stack_buffer, sizeof(udp_server_stack_buffer), - PRIORITY_MAIN, CREATE_STACKTEST, + THREAD_PRIORITY_MAIN, CREATE_STACKTEST, sixlowapp_udp_server_loop, NULL, "UDP receiver"); From c42da5ef22ec16a304d242824545da4891173932 Mon Sep 17 00:00:00 2001 From: haukepetersen Date: Tue, 2 Jun 2015 15:14:11 +0200 Subject: [PATCH 10/90] git: added .gitignore, copied from RIOT --- .gitignore | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..650d0caa32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Object files +*.o +# Built binaries +*bin +# Backup files +*~ +*.orig +.*.swp +cachegrind.out* +# Eclipse workspace files +.project +.cproject +.settings +.idea +# KDevelop4 project files +.kdev4 +*.kdev4 +# Codelite (among others) project files +*.project + +# Eclipse symbol file (output from make eclipsesym) +eclipsesym.xml +/toolchain From 3e1346d1d7f61d105a8ddb88f042a4df4de7bdd7 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Fri, 19 Dec 2014 07:27:32 +0100 Subject: [PATCH 11/90] add application for openwsn --- openwsn/Makefile | 33 ++++++++++++++++++++++++++ openwsn/main.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 openwsn/Makefile create mode 100644 openwsn/main.c diff --git a/openwsn/Makefile b/openwsn/Makefile new file mode 100644 index 0000000000..d52662ea8c --- /dev/null +++ b/openwsn/Makefile @@ -0,0 +1,33 @@ +APPLICATION = openwsn-app + +# If no BOARD is found in the environment, use this default: +BOARD ?= iot-lab_M3 + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../../RIOT + +# Uncomment this to enable scheduler statistics for ps: +#CFLAGS += -DSCHEDSTATISTICS + +# Uncomment this to enable 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: +export QUIET ?= 1 + +USEMODULE += ps +USEMODULE += vtimer +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += posix +USEMODULE += uart0 +USEMODULE += at86rf231 + +USEPKG += openwsn + +include $(RIOTBASE)/Makefile.include + +INCLUDES += -I$(RIOTBASE)/pkg/openwsn/openwsn/projects/common/03oos_openwsn \ + -I$(RIOTBASE)/pkg/openwsn/openwsn/bsp/boards/riot-adaption diff --git a/openwsn/main.c b/openwsn/main.c new file mode 100644 index 0000000000..31cac065e5 --- /dev/null +++ b/openwsn/main.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * 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 tests + * @{ + * + * @file + * @brief Test application for OpenWSN pkg + * + * @author Thomas Eichinger + * + * @} + */ + +#include + +#include "vtimer.h" +#include "shell.h" +#include "posix_io.h" +#include "03oos_openwsn.h" +#include "board_uart0.h" +#include "riot.h" + + +const shell_command_t shell_commands[] = { + {"owsn_init", "Start OpenWSN", openwsn_start_thread}, + {NULL, NULL, NULL} +}; + +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); + + puts("Welcome to RIOT!"); + + shell_init(&shell, shell_commands, UART0_BUFSIZE, shell_readc, shell_putchar); + + shell_run(&shell); + + return 0; +} \ No newline at end of file From e45424240bb0b8986076cbf083358f9fa6a97047 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Sat, 18 Jul 2015 00:37:33 +0200 Subject: [PATCH 12/90] openwsn: fix prototype for putchar --- openwsn/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openwsn/main.c b/openwsn/main.c index 31cac065e5..5dec79f8ed 100644 --- a/openwsn/main.c +++ b/openwsn/main.c @@ -40,9 +40,11 @@ static int shell_readc(void) return c; } -static void shell_putchar(int c) +static int shell_putchar(int c) { (void) putchar(c); + + return c; } int main(void) { @@ -57,4 +59,4 @@ int main(void) { shell_run(&shell); return 0; -} \ No newline at end of file +} From 367f3296badb2bb8aff1505819cdb2af29bc8a27 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Mon, 3 Aug 2015 19:02:12 +0200 Subject: [PATCH 13/90] ng_sniffer: added ng_netif_default This application was not adapted to https://github.com/RIOT-OS/RIOT/pull/3162 and https://github.com/RIOT-OS/RIOT/pull/3188 --- ng_sniffer/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ng_sniffer/Makefile b/ng_sniffer/Makefile index 2a75555e08..03499084cf 100644 --- a/ng_sniffer/Makefile +++ b/ng_sniffer/Makefile @@ -8,7 +8,7 @@ BOARD ?= native RIOTBASE ?= $(CURDIR)/../../RIOT # Define modules that are used -USEMODULE += ng_netif +USEMODULE += ng_netif_default USEMODULE += auto_init_ng_netif USEMODULE += uart0 USEMODULE += shell From 18965d53ce9de4a7f0991a90aadd17a0f4de4837 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Tue, 4 Aug 2015 18:23:32 +0200 Subject: [PATCH 14/90] ng_sniffer: use uart0 only for none newlib boards Related and dependent on https://github.com/RIOT-OS/RIOT/pull/3555 --- ng_sniffer/Makefile | 1 - ng_sniffer/main.c | 12 ++++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ng_sniffer/Makefile b/ng_sniffer/Makefile index 03499084cf..d6dff7c86a 100644 --- a/ng_sniffer/Makefile +++ b/ng_sniffer/Makefile @@ -10,7 +10,6 @@ RIOTBASE ?= $(CURDIR)/../../RIOT # Define modules that are used USEMODULE += ng_netif_default USEMODULE += auto_init_ng_netif -USEMODULE += uart0 USEMODULE += shell USEMODULE += shell_commands USEMODULE += ps diff --git a/ng_sniffer/main.c b/ng_sniffer/main.c index 6e82dc33be..339a750127 100644 --- a/ng_sniffer/main.c +++ b/ng_sniffer/main.c @@ -25,8 +25,12 @@ #include "hwtimer.h" #include "shell.h" #include "shell_commands.h" -#include "posix_io.h" -#include "board_uart0.h" +#ifdef MODULE_NEWLIB +# include "uart_stdio.h" +#else +# include "posix_io.h" +# include "board_uart0.h" +#endif #include "net/ng_netbase.h" /** @@ -111,8 +115,12 @@ int main(void) /* start the shell */ puts("All ok, starting the shell now"); +#ifndef MODULE_NEWLIB (void) posix_open(uart0_handler_pid, 0); shell_init(&shell, NULL, SHELL_BUFSIZE, uart0_readc, uart0_putc); +#else + shell_init(&shell, NULL, SHELL_BUFSIZE, getchar, putchar); +#endif shell_run(&shell); return 0; From bde91e0f75176a18958dba37a61be510d975475e Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Sun, 9 Aug 2015 21:09:29 +0200 Subject: [PATCH 15/90] sniffer: remove old application --- ng_sniffer/Makefile | 20 --- ng_sniffer/main.c | 127 ------------------ sniffer/Makefile | 23 +--- {ng_sniffer => sniffer}/README.md | 4 +- sniffer/main.c | 208 +++++++++++------------------- 5 files changed, 87 insertions(+), 295 deletions(-) delete mode 100644 ng_sniffer/Makefile delete mode 100644 ng_sniffer/main.c rename {ng_sniffer => sniffer}/README.md (53%) diff --git a/ng_sniffer/Makefile b/ng_sniffer/Makefile deleted file mode 100644 index d6dff7c86a..0000000000 --- a/ng_sniffer/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Set the name of your application: -APPLICATION = ng_sniffer - -# 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)/../../RIOT - -# Define modules that are used -USEMODULE += ng_netif_default -USEMODULE += auto_init_ng_netif -USEMODULE += shell -USEMODULE += shell_commands -USEMODULE += ps - -# Change this to 0 show compiler invocation lines by default: -QUIET ?= 1 - -include $(RIOTBASE)/Makefile.include diff --git a/ng_sniffer/main.c b/ng_sniffer/main.c deleted file mode 100644 index 339a750127..0000000000 --- a/ng_sniffer/main.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2015 Freie Universität Berlin - * - * 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. - */ - -/** - * @defgroup app_sniffer - * @brief Sniffer application based on the new network stack - * @{ - * - * @file - * @brief Sniffer application for RIOT - * - * @author Hauke Petersen - * - * @} - */ - -#include - -#include "thread.h" -#include "hwtimer.h" -#include "shell.h" -#include "shell_commands.h" -#ifdef MODULE_NEWLIB -# include "uart_stdio.h" -#else -# include "posix_io.h" -# include "board_uart0.h" -#endif -#include "net/ng_netbase.h" - -/** - * @brief Buffer size used by the shell - */ -#define SHELL_BUFSIZE (64U) - -/** - * @brief Priority of the RAW dump thread - */ -#define RAWDUMP_PRIO (THREAD_PRIORITY_MAIN - 1) - -/** - * @brief Stack for the raw dump thread - */ -static char rawdmp_stack[THREAD_STACKSIZE_MAIN]; - -/** - * @brief Make a raw dump of the given packet contents - */ -void dump_pkt(ng_pktsnip_t *pkt) -{ - ng_pktsnip_t *snip = pkt; - - printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n", - ng_pkt_len(pkt), 0, hwtimer_now()); - - while (snip) { - for (size_t i = 0; i < snip->size; i++) { - printf("0x%02x ", ((uint8_t *)(snip->data))[i]); - } - snip = snip->next; - } - puts("\n"); - - ng_pktbuf_release(pkt); -} - -/** - * @brief Event loop of the RAW dump thread - * - * @param[in] arg unused parameter - */ -void *rawdump(void *arg) -{ - (void)arg; - msg_t msg; - - while (1) { - msg_receive(&msg); - - switch (msg.type) { - case NG_NETAPI_MSG_TYPE_RCV: - dump_pkt((ng_pktsnip_t *)msg.content.ptr); - break; - default: - /* do nothing */ - break; - } - } - - /* never reached */ - return NULL; -} - -/** - * @brief Maybe you are a golfer?! - */ -int main(void) -{ - shell_t shell; - ng_netreg_entry_t dump; - - puts("RIOT sniffer application"); - - /* start and register rawdump thread */ - puts("Run the rawdump thread and register it"); - dump.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, - CREATE_STACKTEST, rawdump, NULL, "rawdump"); - dump.demux_ctx = NG_NETREG_DEMUX_CTX_ALL; - ng_netreg_register(NG_NETTYPE_UNDEF, &dump); - - /* start the shell */ - puts("All ok, starting the shell now"); -#ifndef MODULE_NEWLIB - (void) posix_open(uart0_handler_pid, 0); - shell_init(&shell, NULL, SHELL_BUFSIZE, uart0_readc, uart0_putc); -#else - shell_init(&shell, NULL, SHELL_BUFSIZE, getchar, putchar); -#endif - shell_run(&shell); - - return 0; -} diff --git a/sniffer/Makefile b/sniffer/Makefile index 350a753f22..eb04aa6ff7 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -7,23 +7,14 @@ BOARD ?= native # This has to be the absolute path to the RIOT base directory: RIOTBASE ?= $(CURDIR)/../../RIOT +# Define modules that are used +USEMODULE += ng_netif_default +USEMODULE += auto_init_ng_netif +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps + # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 -# blacklist all boards without radio support -BOARD_BLACKLIST := arduino-due arduino-mega2560 mbed_lpc1768 msb-430 pttu \ - udoo qemu-i386 stm32f0discovery stm32f3discovery \ - stm32f4discovery pca10000 pca10005 msbiot samr21-xpro \ - yunjia-nrf51822 - -# Modules to include: - -USEMODULE += shell -USEMODULE += shell_commands -USEMODULE += uart0 -USEMODULE += ps -USEMODULE += vtimer -USEMODULE += auto_init -USEMODULE += defaulttransceiver - include $(RIOTBASE)/Makefile.include diff --git a/ng_sniffer/README.md b/sniffer/README.md similarity index 53% rename from ng_sniffer/README.md rename to sniffer/README.md index db45fe4a78..6cd9794072 100644 --- a/ng_sniffer/README.md +++ b/sniffer/README.md @@ -1,7 +1,7 @@ About ===== -This application is build to run together with the script `RIOTBASE/dist/tools/ng_sniffer/ng_sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. +This application is build to run together with the script `RIOTBASE/dist/tools/sniffer/sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. Usage @@ -9,4 +9,4 @@ Usage Compile and flash this application to the board of your choice. You can check if everything on the RIOT side works by connecting to the board via UART and by checking with `ifconfig` if a network device is available. Further you can check with `ifconfig 4 promisc` if promiscuous mode is supported and with `ifconfig 4 raw` if raw mode is supported by the driver/network device. -For further information on setting up the host part, see `RIOTBASE/dist/tools/ng_snifffer/README.md`. +For further information on setting up the host part, see `RIOTBASE/dist/tools/sniffer/README.md`. diff --git a/sniffer/main.c b/sniffer/main.c index c0eb6463ed..339a750127 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -1,7 +1,5 @@ /* - * Copyright (c) 2010, Mariano Alvira and other contributors to - * the MC1322x project (http://mc1322x.devl.org) - * Copyright (C) 2014 Oliver Hahm + * Copyright (C) 2015 Freie Universität Berlin * * 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 @@ -9,170 +7,120 @@ */ /** - * @ingroup examples + * @defgroup app_sniffer + * @brief Sniffer application based on the new network stack * @{ * - * @file main.c + * @file + * @brief Sniffer application for RIOT * - * @brief Sniffer application for MSB-A2 and Wireshark - * - * @author Oliver Hahm - * @author Mariano Alvira + * @author Hauke Petersen * * @} */ #include -#include #include "thread.h" -#include "posix_io.h" +#include "hwtimer.h" #include "shell.h" #include "shell_commands.h" -#include "board_uart0.h" -#include "hwtimer.h" -#include "transceiver.h" -#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X -#include "ieee802154_frame.h" -#endif - -#define RCV_BUFFER_SIZE (64) -#define RADIO_STACK_SIZE (KERNEL_CONF_STACKSIZE_MAIN) -#define PER_ROW (16) - -char radio_stack_buffer[RADIO_STACK_SIZE]; -msg_t msg_q[RCV_BUFFER_SIZE]; -transceiver_command_t tcmd; - -#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X -void print_packet(ieee802154_packet_t *p) +#ifdef MODULE_NEWLIB +# include "uart_stdio.h" #else -void print_packet(radio_packet_t *p) +# include "posix_io.h" +# include "board_uart0.h" #endif +#include "net/ng_netbase.h" + +/** + * @brief Buffer size used by the shell + */ +#define SHELL_BUFSIZE (64U) + +/** + * @brief Priority of the RAW dump thread + */ +#define RAWDUMP_PRIO (THREAD_PRIORITY_MAIN - 1) + +/** + * @brief Stack for the raw dump thread + */ +static char rawdmp_stack[THREAD_STACKSIZE_MAIN]; + +/** + * @brief Make a raw dump of the given packet contents + */ +void dump_pkt(ng_pktsnip_t *pkt) { - volatile uint8_t i, j, k; + ng_pktsnip_t *snip = pkt; - if (p) { - printf("len 0x%02x lqi 0x%02x rx_time 0x%08lx", p->length, p->lqi, hwtimer_now()); + printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n", + ng_pkt_len(pkt), 0, hwtimer_now()); - for (j = 0, k = 0; j <= ((p->length) / PER_ROW); j++) { - printf("\n\r"); - - for (i = 0; i < PER_ROW; i++, k++) { - if (k >= p->length) { - printf("\n\r"); - return; - } - -#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X - printf("%02x ", p->frame.payload[j * PER_ROW + i]); -#else - printf("%02x ", p->data[j * PER_ROW + i]); -#endif - } + while (snip) { + for (size_t i = 0; i < snip->size; i++) { + printf("0x%02x ", ((uint8_t *)(snip->data))[i]); } + snip = snip->next; } + puts("\n"); - printf("\n\r"); - return; + ng_pktbuf_release(pkt); } -void *radio(void *unused) +/** + * @brief Event loop of the RAW dump thread + * + * @param[in] arg unused parameter + */ +void *rawdump(void *arg) { - (void) unused; - - msg_t m; -#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X - ieee802154_packet_t *p; -#else - radio_packet_t *p; -#endif - - msg_init_queue(msg_q, RCV_BUFFER_SIZE); + (void)arg; + msg_t msg; while (1) { - msg_receive(&m); + msg_receive(&msg); - if (m.type == PKT_PENDING) { -#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X - p = (ieee802154_packet_t *) m.content.ptr; -#else - p = (radio_packet_t *) m.content.ptr; -#endif - printf("rftest-rx --- "); - print_packet(p); - p->processing--; - } - else if (m.type == ENOBUFFER) { - puts("Transceiver buffer full"); - } - else { - puts("Unknown packet received"); + switch (msg.type) { + case NG_NETAPI_MSG_TYPE_RCV: + dump_pkt((ng_pktsnip_t *)msg.content.ptr); + break; + default: + /* do nothing */ + break; } } + /* never reached */ return NULL; } -void init_transceiver(void) -{ - kernel_pid_t radio_pid = thread_create( - radio_stack_buffer, - sizeof(radio_stack_buffer), - PRIORITY_MAIN - 2, - CREATE_STACKTEST, - radio, - NULL, - "radio"); - - uint16_t transceivers = TRANSCEIVER_DEFAULT; - - transceiver_init(transceivers); - transceiver_start(); - transceiver_register(transceivers, radio_pid); - - msg_t mesg; - mesg.type = SET_CHANNEL; - mesg.content.ptr = (char *) &tcmd; - - uint16_t c = 10; - - tcmd.transceivers = TRANSCEIVER_DEFAULT; - tcmd.data = &c; - printf("Set transceiver to channel %u\n", c); - msg_send(&mesg, transceiver_pid); - - mesg.type = SET_MONITOR; - mesg.content.ptr = (char *) &tcmd; - - uint16_t v = 1; - - tcmd.data = &v; - printf("Set transceiver into monitor mode\n"); - msg_send(&mesg, transceiver_pid); -} - -static int shell_readc(void) -{ - char c = 0; - posix_read(uart0_handler_pid, &c, 1); - return c; -} - -static void shell_putchar(int c) -{ - putchar(c); -} - +/** + * @brief Maybe you are a golfer?! + */ int main(void) { shell_t shell; - posix_open(uart0_handler_pid, 0); - init_transceiver(); + ng_netreg_entry_t dump; - puts("Welcome to RIOT!"); + puts("RIOT sniffer application"); - shell_init(&shell, NULL, UART0_BUFSIZE, shell_readc, shell_putchar); + /* start and register rawdump thread */ + puts("Run the rawdump thread and register it"); + dump.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, + CREATE_STACKTEST, rawdump, NULL, "rawdump"); + dump.demux_ctx = NG_NETREG_DEMUX_CTX_ALL; + ng_netreg_register(NG_NETTYPE_UNDEF, &dump); + + /* start the shell */ + puts("All ok, starting the shell now"); +#ifndef MODULE_NEWLIB + (void) posix_open(uart0_handler_pid, 0); + shell_init(&shell, NULL, SHELL_BUFSIZE, uart0_readc, uart0_putc); +#else + shell_init(&shell, NULL, SHELL_BUFSIZE, getchar, putchar); +#endif shell_run(&shell); return 0; From 017cbf190c24715045cb57d269264bf72fcd1a9c Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Sun, 23 Aug 2015 23:41:35 +0200 Subject: [PATCH 16/90] remove apps belonging to the old network stack --- sixlowapp/Makefile | 36 ----------- sixlowapp/README.md | 11 ---- sixlowapp/helper.c | 52 ---------------- sixlowapp/main.c | 72 ---------------------- sixlowapp/monitor.c | 71 ---------------------- sixlowapp/sixlowapp.h | 111 ---------------------------------- sixlowapp/sixlowshell.c | 128 ---------------------------------------- sixlowapp/udp.c | 107 --------------------------------- sniffer/Makefile | 20 ------- sniffer/README.md | 12 ---- sniffer/main.c | 127 --------------------------------------- 11 files changed, 747 deletions(-) delete mode 100644 sixlowapp/Makefile delete mode 100644 sixlowapp/README.md delete mode 100644 sixlowapp/helper.c delete mode 100644 sixlowapp/main.c delete mode 100644 sixlowapp/monitor.c delete mode 100644 sixlowapp/sixlowapp.h delete mode 100644 sixlowapp/sixlowshell.c delete mode 100644 sixlowapp/udp.c delete mode 100644 sniffer/Makefile delete mode 100644 sniffer/README.md delete mode 100644 sniffer/main.c diff --git a/sixlowapp/Makefile b/sixlowapp/Makefile deleted file mode 100644 index dd8966a639..0000000000 --- a/sixlowapp/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# name of your application -APPLICATION = sixlowapp - -# 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)/../../RIOT - -# Uncomment this to enable scheduler statistics for ps: -#CFLAGS += -DSCHEDSTATISTICS - -# Uncomment this to enable 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: -export QUIET ?= 1 - -# Modules to include: -USEMODULE += shell -USEMODULE += shell_commands -USEMODULE += uart0 -USEMODULE += ps -USEMODULE += defaulttransceiver -USEMODULE += udp -ifneq (,$(filter iot-lab_M3,$(BOARD))) - USEMODULE += isl29020 - USEMODULE += lps331ap - USEMODULE += l3g4200d - USEMODULE += lsm303dlhc -endif - - -include $(RIOTBASE)/Makefile.include diff --git a/sixlowapp/README.md b/sixlowapp/README.md deleted file mode 100644 index 6482369bd6..0000000000 --- a/sixlowapp/README.md +++ /dev/null @@ -1,11 +0,0 @@ -Usage of sixlowapp - 6LoWPAN example -==================================== -* set up two nodes - * for nativenet: - * run `${RIOTBASE}/cpu/native/tapsetup.sh create` - * run `PORT=tap0 make term` - * run `PORT=tap1 make term` (from another terminal) -* type `ifconfig` on both nodes -* type `ping ` on node 1, using one of node 2's IPv6 addresses -* type `nc -l ` to start a UDP server listening on `` on of the nodes -* type `nc ` on the other node to send `` to the first node diff --git a/sixlowapp/helper.c b/sixlowapp/helper.c deleted file mode 100644 index 8123c44f12..0000000000 --- a/sixlowapp/helper.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2014 INRIA - * - * This file is 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 - * @brief 6LoWPAN example application helper functions - * - * @author Oliver Hahm - */ - -#include "msg.h" -#include "sixlowpan/ip.h" - -#include "sixlowapp.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -void sixlowapp_ndp_workaround(ipv6_addr_t *dest) -{ - /* add the destination to the neighbor cache if is not already in it */ - if (!ndp_neighbor_cache_search(dest)) { - DEBUGF("XXX: Adding %s to neighbor cache.\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, dest)); - ndp_neighbor_cache_add(IF_ID, dest, &(dest->uint16[7]), 2, 0, - NDP_NCE_STATUS_REACHABLE, - NDP_NCE_TYPE_TENTATIVE, 0xffff); - } -} - -uint64_t sixlowapp_wait_for_msg_type(msg_t *m, timex_t timeout, uint16_t mtype) -{ - timex_t t1, t2, delta; - delta = timex_set(0, 0); - vtimer_now(&t1); - while (timex_cmp(delta, timeout) < 0) { - if (vtimer_msg_receive_timeout(m, timeout) < 0) { - return 0; - } - vtimer_now(&t2); - delta = timex_sub(t2, t1); - if (m->type == mtype) { - return timex_uint64(delta); - } - timeout = timex_sub(timeout, delta); - } - return 0; -} diff --git a/sixlowapp/main.c b/sixlowapp/main.c deleted file mode 100644 index 2b36c3087d..0000000000 --- a/sixlowapp/main.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2014 INRIA - * - * This file is 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 - * @brief 6LoWPAN example application - main function - * - * @author Oliver Hahm - */ - -#include - -#include "kernel.h" -#include "thread.h" -#include "net_if.h" -#include "posix_io.h" -#include "shell.h" -#include "shell_commands.h" -#include "board_uart0.h" - -#include "sixlowapp.h" - -kernel_pid_t sixlowapp_udp_server_pid = KERNEL_PID_UNDEF; - -char addr_str[IPV6_MAX_ADDR_STR_LEN]; -char monitor_stack_buffer[THREAD_STACKSIZE_MAIN]; -char udp_server_stack_buffer[THREAD_STACKSIZE_MAIN]; - -const shell_command_t shell_commands[] = { - {"ping", "Send an ICMPv6 echo request to another node", sixlowapp_send_ping}, - {"nc", "RIOT netcat - arbitrary UDP connections and listens", sixlowapp_netcat}, - {NULL, NULL, NULL} -}; - -int main(void) -{ - puts("RIOT 6LoWPAN example v"APP_VERSION); - - sixlowpan_lowpan_init_interface(IF_ID); - - /* start thread for monitor mode */ - kernel_pid_t monitor_pid = thread_create(monitor_stack_buffer, - sizeof(monitor_stack_buffer), - THREAD_PRIORITY_MAIN - 2, - CREATE_STACKTEST, - sixlowapp_monitor, NULL, - "monitor"); - - ipv6_register_packet_handler(monitor_pid); - - /* Start the UDP server thread */ - sixlowapp_udp_server_pid = thread_create(udp_server_stack_buffer, - sizeof(udp_server_stack_buffer), - THREAD_PRIORITY_MAIN, CREATE_STACKTEST, - sixlowapp_udp_server_loop, NULL, - "UDP receiver"); - - /* Open the UART0 for the shell */ - posix_open(uart0_handler_pid, 0); - /* initialize the shell */ - shell_t shell; - shell_init(&shell, shell_commands, UART0_BUFSIZE, uart0_readc, uart0_putc); - /* start the shell loop */ - shell_run(&shell); - - return 0; -} diff --git a/sixlowapp/monitor.c b/sixlowapp/monitor.c deleted file mode 100644 index 4c5e2def2c..0000000000 --- a/sixlowapp/monitor.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2014 INRIA - * - * This file is 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 - * @brief 6LoWPAN example application IPv6 monitor - * - * @author Oliver Hahm - */ - -#include "msg.h" -#include "sixlowpan/ip.h" - -#include "sixlowapp.h" - -#define RCV_BUFFER_SIZE (32) - -#define IPV6_HDR_LEN (0x28) - -#define ENABLE_DEBUG (0) -#include "debug.h" - -msg_t msg_q[RCV_BUFFER_SIZE]; - -void *sixlowapp_monitor(void *unused) -{ - (void) unused; - - msg_t m; - ipv6_hdr_t *ipv6_buf; - - msg_init_queue(msg_q, RCV_BUFFER_SIZE); - - while (1) { - msg_receive(&m); - - if (m.type == IPV6_PACKET_RECEIVED) { - ipv6_buf = (ipv6_hdr_t *) m.content.ptr; - - if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) { - icmpv6_hdr_t *icmpv6_buf = (icmpv6_hdr_t *) &((uint8_t*)ipv6_buf)[(IPV6_HDR_LEN)]; - if (icmpv6_buf->type == ICMPV6_TYPE_ECHO_REPLY) { - if (sixlowapp_waiting_for_pong) { - msg_t m; - m.type = ICMP_ECHO_REPLY_RCVD; - sixlowapp_waiting_for_pong = 0; - msg_send(&m, sixlowapp_waiter_pid); - } - } - } - /* add the destination to the neighbor cache if is not already in it */ - if (!ndp_neighbor_cache_search(&(ipv6_buf->srcaddr))) { - ndp_neighbor_cache_add(IF_ID, &(ipv6_buf->srcaddr), - &(ipv6_buf->srcaddr.uint16[7]), 2, - 0, NDP_NCE_STATUS_REACHABLE, - NDP_NCE_TYPE_TENTATIVE, 0xffff); - } - DEBUGF("IPv6 datagram received (next header: %02X)", ipv6_buf->nextheader); - DEBUG(" from %s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, - &ipv6_buf->srcaddr)); - } - else { - printf("! Unknown message received, type %04X\n", m.type); - } - } -} diff --git a/sixlowapp/sixlowapp.h b/sixlowapp/sixlowapp.h deleted file mode 100644 index 75e49944ae..0000000000 --- a/sixlowapp/sixlowapp.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef SIXLOWAPP_H -#define SIXLOWAPP_H - -#include "kernel.h" -#include "ipv6.h" - -/** - * @brief The application version number - */ -#define APP_VERSION "1.3" - -/** - * @brief Which interface should be used for 6LoWPAN - */ -#define IF_ID (0) - -/** - * @brief Define a IPC message type for ICMP echo reply handling - */ -#define ICMP_ECHO_REPLY_RCVD (4444) - -/** - * @brief PID for UDP server thread - */ -extern kernel_pid_t sixlowapp_udp_server_pid; - -/** - * @brief UDP port number that netcat uses to listen at - */ -extern uint16_t sixlowapp_netcat_listen_port; - -/** - * @brief Marker if we're waiting for an ICMP echo reply - */ -extern unsigned sixlowapp_waiting_for_pong; - -/** - * @brief The PID of the thread waiting for the ICMP echo reply - */ -extern kernel_pid_t sixlowapp_waiter_pid; - -/** - * @brief Helper variable for IP address printing - */ -extern char addr_str[IPV6_MAX_ADDR_STR_LEN]; - -/** - * @brief Shell command to send an ICMPv6 echo request - * - * @param[in] argc Number of arguments supplied to the function invocation. - * @param[in] argv The supplied argument list. - * - * @returns 0 on success, error code on invalide parameters - */ -int sixlowapp_send_ping(int argc, char **argv); - -/** - * @brief Shell command for netcat - * - * @param[in] argc Number of arguments supplied to the function invocation. - * @param[in] argv The supplied argument list. - * - * @returns 0 on success, error code on invalide parameters - */ -int sixlowapp_netcat(int argc, char **argv); - -/** - * @brief Wrapper function for sending data of UDP - * - * @param[in] dest Destination IPv6 address - * @param[in] port Destination UDP port - * @param[in] payload Data to send - * @param[in] len Size of data to send - */ -void sixlowapp_udp_send(ipv6_addr_t *dest, uint16_t port, char *payload, size_t len); - -/** - * @brief Monitoring thread - * - * @param[in] unused Obsolete - */ -void *sixlowapp_monitor(void *unused); - -/** - * @brief UDP server thread - * - * @param[in] arg Obsolete - */ -void *sixlowapp_udp_server_loop(void *arg); - -/** - * @brief Provides a workaround for currently broken 6LoWPAN ND - * - * @param[in] dest The IPv6 address to add to the neighbor cache - */ -void sixlowapp_ndp_workaround(ipv6_addr_t *dest); - -/** - * @brief Waits for a certain message type for a given time span - * - * @param[out] m Pointer to preallocated ``msg_t`` structure, must not - * be NULL - * @param[in] timeout The maximum interval to wait - * @param[in] mtype The message type to wait for - * - * @return 0 if no message of type @p mtype was received - * @return The number of microseconds before the message was received - */ -uint64_t sixlowapp_wait_for_msg_type(msg_t *m, timex_t timeout, uint16_t mtype); - -#endif /* SIXLOWAPP_H */ diff --git a/sixlowapp/sixlowshell.c b/sixlowapp/sixlowshell.c deleted file mode 100644 index 3fc28cbbc1..0000000000 --- a/sixlowapp/sixlowshell.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2014 INRIA - * - * This file is 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 - * @brief 6LoWPAN example application shell functions - * - * @author Oliver Hahm - */ - -#include -#include -#include "msg.h" -#include "thread.h" -#include "sched.h" -#include "sixlowpan/ip.h" -#include "inet_pton.h" - -#include "sixlowapp.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#define ICMP_DATA "RIOT" -#define ICMP_TIMEOUT (100) - -#define MAX_PAYLOAD_SIZE (32) - -extern uint8_t ipv6_ext_hdr_len; - -static char payload[MAX_PAYLOAD_SIZE]; - -unsigned sixlowapp_waiting_for_pong; -kernel_pid_t sixlowapp_waiter_pid; - -int sixlowapp_send_ping(int argc, char **argv) -{ - ipv6_addr_t dest; - const char *icmp_data = ICMP_DATA; - - if (argc != 2) { - puts("! Invalid number of parameters"); - printf(" usage: %s destination\n", argv[0]); - return EINVAL; - } - - if (!inet_pton(AF_INET6, argv[1], &dest)) { - printf("! %s is not a valid IPv6 address\n", argv[1]); - return EFAULT; - } - - sixlowapp_ndp_workaround(&dest); - - /* send an echo request */ - icmpv6_send_echo_request(&dest, 1, 1, (uint8_t *) icmp_data, sizeof(icmp_data)); - - sixlowapp_waiting_for_pong = 1; - sixlowapp_waiter_pid = sched_active_pid; - uint64_t rtt; - msg_t m; - m.type = 0; - rtt = sixlowapp_wait_for_msg_type(&m, timex_set(0, ICMP_TIMEOUT * 1000), ICMP_ECHO_REPLY_RCVD); - if (sixlowapp_waiting_for_pong == 0) { - char ts[TIMEX_MAX_STR_LEN]; - printf("Echo reply from %s received, rtt: %s\n", inet_ntop(AF_INET6, &dest, - addr_str, - IPV6_MAX_ADDR_STR_LEN), - timex_to_str(timex_from_uint64(rtt), ts)); - } - else { - printf("! Destination %s is unreachable\n", inet_ntop(AF_INET6, - &dest, - addr_str, - IPV6_MAX_ADDR_STR_LEN)); - } - - return 0; -} - -int sixlowapp_netcat(int argc, char **argv) -{ - ipv6_addr_t dest; - - if (argc < 3) { - puts("! Not enough parameters"); - puts(" usage: nc [-l] [destination] [port] [text]"); - return EINVAL; - } - - if (strlen(argv[1]) == 2) { - if (strncmp(argv[1], "-l", 2)) { - puts("! Invalid parameter"); - puts(" usage: nc [-l] [destination] [port] [text]"); - return EINVAL; - } - else { - sixlowapp_netcat_listen_port = atoi(argv[2]); - thread_wakeup(sixlowapp_udp_server_pid); - } - } - else if (!inet_pton(AF_INET6, argv[1], &dest)) { - printf("! %s is not a valid IPv6 address\n", argv[1]); - } - else { - sixlowapp_ndp_workaround(&dest); - size_t plen; - if (argc > 3 ) { - plen = (strlen(argv[3]) > MAX_PAYLOAD_SIZE) ? MAX_PAYLOAD_SIZE : strlen(argv[3]) + 1; - memcpy(payload, argv[3], plen); - payload[plen - 1] = 0; - } - else { - plen = 5; - strncpy(payload, "RIOT", plen); - - } - sixlowapp_udp_send(&dest, atoi(argv[2]), payload, plen); - } - - return 0; -} - - diff --git a/sixlowapp/udp.c b/sixlowapp/udp.c deleted file mode 100644 index 0eff3505df..0000000000 --- a/sixlowapp/udp.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2013, 2014 INRIA - * - * 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. - */ - -/** - * @file - * - * @author Oliver Hahm - */ - -#include -#include -#include -#include -#include - -#include "thread.h" -#include "socket_base/socket.h" -#include "net_help.h" -#include "sixlowapp.h" - -#define UDP_BUFFER_SIZE (128) - -uint16_t sixlowapp_netcat_listen_port; - -/* UDP server thread */ -void *sixlowapp_udp_server_loop(void *arg) -{ - (void) arg; - - sockaddr6_t sa; - char buffer_main[UDP_BUFFER_SIZE]; - uint32_t fromlen; - int sock; - fromlen = sizeof(sa); - - while (1) { - while(!sixlowapp_netcat_listen_port) { - thread_sleep(); - } - - sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET; - sa.sin6_port = HTONS(sixlowapp_netcat_listen_port); - - if (-1 == socket_base_bind(sock, &sa, sizeof(sa))) { - printf("Error bind failed!\n"); - socket_base_close(sock); - sixlowapp_netcat_listen_port = 0; - continue; - } - - printf("Listening for incoming UDP connection at port %" PRIu16 "\n", sixlowapp_netcat_listen_port); - int32_t recsize = socket_base_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); - - socket_base_close(sock); - sixlowapp_netcat_listen_port = 0; - } - - return NULL; -} - -/* UDP send command */ -void sixlowapp_udp_send(ipv6_addr_t *dest, uint16_t port, char *payload, size_t len) -{ - int sock; - sockaddr6_t sa; - int bytes_sent; - - sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - - if (-1 == sock) { - printf("Error Creating Socket!"); - return; - } - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET; - memcpy(&sa.sin6_addr, dest, 16); - sa.sin6_port = HTONS(port); - - printf("Trying to send %i bytes to %s:%" PRIu16 "\n", len, - ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, dest), port); - bytes_sent = socket_base_sendto(sock, payload, len, 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, IPV6_MAX_ADDR_STR_LEN, - dest)); - } - - socket_base_close(sock); -} diff --git a/sniffer/Makefile b/sniffer/Makefile deleted file mode 100644 index eb04aa6ff7..0000000000 --- a/sniffer/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Set the name of your application: -APPLICATION = sniffer - -# 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)/../../RIOT - -# Define modules that are used -USEMODULE += ng_netif_default -USEMODULE += auto_init_ng_netif -USEMODULE += shell -USEMODULE += shell_commands -USEMODULE += ps - -# Change this to 0 show compiler invocation lines by default: -QUIET ?= 1 - -include $(RIOTBASE)/Makefile.include diff --git a/sniffer/README.md b/sniffer/README.md deleted file mode 100644 index 6cd9794072..0000000000 --- a/sniffer/README.md +++ /dev/null @@ -1,12 +0,0 @@ -About -===== - -This application is build to run together with the script `RIOTBASE/dist/tools/sniffer/sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. - - -Usage -===== - -Compile and flash this application to the board of your choice. You can check if everything on the RIOT side works by connecting to the board via UART and by checking with `ifconfig` if a network device is available. Further you can check with `ifconfig 4 promisc` if promiscuous mode is supported and with `ifconfig 4 raw` if raw mode is supported by the driver/network device. - -For further information on setting up the host part, see `RIOTBASE/dist/tools/sniffer/README.md`. diff --git a/sniffer/main.c b/sniffer/main.c deleted file mode 100644 index 339a750127..0000000000 --- a/sniffer/main.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2015 Freie Universität Berlin - * - * 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. - */ - -/** - * @defgroup app_sniffer - * @brief Sniffer application based on the new network stack - * @{ - * - * @file - * @brief Sniffer application for RIOT - * - * @author Hauke Petersen - * - * @} - */ - -#include - -#include "thread.h" -#include "hwtimer.h" -#include "shell.h" -#include "shell_commands.h" -#ifdef MODULE_NEWLIB -# include "uart_stdio.h" -#else -# include "posix_io.h" -# include "board_uart0.h" -#endif -#include "net/ng_netbase.h" - -/** - * @brief Buffer size used by the shell - */ -#define SHELL_BUFSIZE (64U) - -/** - * @brief Priority of the RAW dump thread - */ -#define RAWDUMP_PRIO (THREAD_PRIORITY_MAIN - 1) - -/** - * @brief Stack for the raw dump thread - */ -static char rawdmp_stack[THREAD_STACKSIZE_MAIN]; - -/** - * @brief Make a raw dump of the given packet contents - */ -void dump_pkt(ng_pktsnip_t *pkt) -{ - ng_pktsnip_t *snip = pkt; - - printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n", - ng_pkt_len(pkt), 0, hwtimer_now()); - - while (snip) { - for (size_t i = 0; i < snip->size; i++) { - printf("0x%02x ", ((uint8_t *)(snip->data))[i]); - } - snip = snip->next; - } - puts("\n"); - - ng_pktbuf_release(pkt); -} - -/** - * @brief Event loop of the RAW dump thread - * - * @param[in] arg unused parameter - */ -void *rawdump(void *arg) -{ - (void)arg; - msg_t msg; - - while (1) { - msg_receive(&msg); - - switch (msg.type) { - case NG_NETAPI_MSG_TYPE_RCV: - dump_pkt((ng_pktsnip_t *)msg.content.ptr); - break; - default: - /* do nothing */ - break; - } - } - - /* never reached */ - return NULL; -} - -/** - * @brief Maybe you are a golfer?! - */ -int main(void) -{ - shell_t shell; - ng_netreg_entry_t dump; - - puts("RIOT sniffer application"); - - /* start and register rawdump thread */ - puts("Run the rawdump thread and register it"); - dump.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, - CREATE_STACKTEST, rawdump, NULL, "rawdump"); - dump.demux_ctx = NG_NETREG_DEMUX_CTX_ALL; - ng_netreg_register(NG_NETTYPE_UNDEF, &dump); - - /* start the shell */ - puts("All ok, starting the shell now"); -#ifndef MODULE_NEWLIB - (void) posix_open(uart0_handler_pid, 0); - shell_init(&shell, NULL, SHELL_BUFSIZE, uart0_readc, uart0_putc); -#else - shell_init(&shell, NULL, SHELL_BUFSIZE, getchar, putchar); -#endif - shell_run(&shell); - - return 0; -} From b425340ff1c747f2f827d64a882a9fb18f48c7db Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Thu, 10 Sep 2015 00:10:12 +0200 Subject: [PATCH 17/90] sniffer: re-add sniffer Was accidentally removed and is also updated to current gnrc. --- sniffer/Makefile | 20 ++++++++ sniffer/README.md | 12 +++++ sniffer/main.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 sniffer/Makefile create mode 100644 sniffer/README.md create mode 100644 sniffer/main.c diff --git a/sniffer/Makefile b/sniffer/Makefile new file mode 100644 index 0000000000..cc25dbe48c --- /dev/null +++ b/sniffer/Makefile @@ -0,0 +1,20 @@ +# Set the name of your application: +APPLICATION = sniffer + +# 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)/../../RIOT + +# Define modules that are used +USEMODULE += gnrc_netif_default +USEMODULE += auto_init_gnrc_netif +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/sniffer/README.md b/sniffer/README.md new file mode 100644 index 0000000000..6cd9794072 --- /dev/null +++ b/sniffer/README.md @@ -0,0 +1,12 @@ +About +===== + +This application is build to run together with the script `RIOTBASE/dist/tools/sniffer/sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. + + +Usage +===== + +Compile and flash this application to the board of your choice. You can check if everything on the RIOT side works by connecting to the board via UART and by checking with `ifconfig` if a network device is available. Further you can check with `ifconfig 4 promisc` if promiscuous mode is supported and with `ifconfig 4 raw` if raw mode is supported by the driver/network device. + +For further information on setting up the host part, see `RIOTBASE/dist/tools/sniffer/README.md`. diff --git a/sniffer/main.c b/sniffer/main.c new file mode 100644 index 0000000000..6cfd3e0b84 --- /dev/null +++ b/sniffer/main.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * 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. + */ + +/** + * @defgroup app_sniffer + * @brief Sniffer application based on the new network stack + * @{ + * + * @file + * @brief Sniffer application for RIOT + * + * @author Hauke Petersen + * + * @} + */ + +#include + +#include "thread.h" +#include "hwtimer.h" +#include "shell.h" +#include "shell_commands.h" +#ifdef MODULE_NEWLIB +# include "uart_stdio.h" +#else +# include "posix_io.h" +# include "board_uart0.h" +#endif +#include "net/gnrc.h" + +/** + * @brief Buffer size used by the shell + */ +#define SHELL_BUFSIZE (64U) + +/** + * @brief Priority of the RAW dump thread + */ +#define RAWDUMP_PRIO (THREAD_PRIORITY_MAIN - 1) + +/** + * @brief Stack for the raw dump thread + */ +static char rawdmp_stack[THREAD_STACKSIZE_MAIN]; + +/** + * @brief Make a raw dump of the given packet contents + */ +void dump_pkt(gnrc_pktsnip_t *pkt) +{ + gnrc_pktsnip_t *snip = pkt; + + printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n", + gnrc_pkt_len(pkt), 0, hwtimer_now()); + + while (snip) { + for (size_t i = 0; i < snip->size; i++) { + printf("0x%02x ", ((uint8_t *)(snip->data))[i]); + } + snip = snip->next; + } + puts("\n"); + + gnrc_pktbuf_release(pkt); +} + +/** + * @brief Event loop of the RAW dump thread + * + * @param[in] arg unused parameter + */ +void *rawdump(void *arg) +{ + (void)arg; + msg_t msg; + + while (1) { + msg_receive(&msg); + + switch (msg.type) { + case GNRC_NETAPI_MSG_TYPE_RCV: + dump_pkt((gnrc_pktsnip_t *)msg.content.ptr); + break; + default: + /* do nothing */ + break; + } + } + + /* never reached */ + return NULL; +} + +/** + * @brief Maybe you are a golfer?! + */ +int main(void) +{ + gnrc_netreg_entry_t dump; + + puts("RIOT sniffer application"); + + /* start and register rawdump thread */ + puts("Run the rawdump thread and register it"); + dump.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, + CREATE_STACKTEST, rawdump, NULL, "rawdump"); + dump.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL; + gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump); + + /* start the shell */ + puts("All ok, starting the shell now"); + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); + + return 0; +} From 4ecbc71502e1bf119726a7a0ca4d803a41b34308 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Tue, 15 Sep 2015 12:29:13 +0200 Subject: [PATCH 18/90] sniffer: update application to current RIOT master --- sniffer/Makefile | 1 + sniffer/main.c | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/sniffer/Makefile b/sniffer/Makefile index cc25dbe48c..8ac06b30c1 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -8,6 +8,7 @@ BOARD ?= native RIOTBASE ?= $(CURDIR)/../../RIOT # Define modules that are used +USEMODULE += gnrc USEMODULE += gnrc_netif_default USEMODULE += auto_init_gnrc_netif USEMODULE += shell diff --git a/sniffer/main.c b/sniffer/main.c index 6cfd3e0b84..9aa14ea71d 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -25,12 +25,6 @@ #include "hwtimer.h" #include "shell.h" #include "shell_commands.h" -#ifdef MODULE_NEWLIB -# include "uart_stdio.h" -#else -# include "posix_io.h" -# include "board_uart0.h" -#endif #include "net/gnrc.h" /** From f654c1e1a1ee38ee81555242b5aae5733596aecb Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Wed, 16 Sep 2015 03:41:25 +0200 Subject: [PATCH 19/90] sniffer: switch to xtimer --- sniffer/Makefile | 1 + sniffer/main.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sniffer/Makefile b/sniffer/Makefile index 8ac06b30c1..519bbb0d66 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -14,6 +14,7 @@ USEMODULE += auto_init_gnrc_netif USEMODULE += shell USEMODULE += shell_commands USEMODULE += ps +USEMODULE += xtimer # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 diff --git a/sniffer/main.c b/sniffer/main.c index 9aa14ea71d..4ae1ff1d05 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -22,7 +22,7 @@ #include #include "thread.h" -#include "hwtimer.h" +#include "xtimer.h" #include "shell.h" #include "shell_commands.h" #include "net/gnrc.h" @@ -49,8 +49,8 @@ void dump_pkt(gnrc_pktsnip_t *pkt) { gnrc_pktsnip_t *snip = pkt; - printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n", - gnrc_pkt_len(pkt), 0, hwtimer_now()); + printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08" PRIx64 "\n\n", + gnrc_pkt_len(pkt), 0, xtimer_now64()); while (snip) { for (size_t i = 0; i < snip->size; i++) { From 2424c6e555345f48e18e9002c1861389f04624ee Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 6 Jan 2016 16:54:08 +0100 Subject: [PATCH 20/90] sniffer: s/CREATE_STACKTEST/THREAD_CREATE_STACKTEST/ --- sniffer/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/main.c b/sniffer/main.c index 4ae1ff1d05..a54fb3374b 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -102,7 +102,7 @@ int main(void) /* start and register rawdump thread */ puts("Run the rawdump thread and register it"); dump.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, - CREATE_STACKTEST, rawdump, NULL, "rawdump"); + THREAD_CREATE_STACKTEST, rawdump, NULL, "rawdump"); dump.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL; gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump); From d737d8e612da8a3a10eeb41ad764df110d9ec7a5 Mon Sep 17 00:00:00 2001 From: Lotte Steenbrink Date: Tue, 26 Jan 2016 12:30:28 -0800 Subject: [PATCH 21/90] microcoap: rm stale example in favor of RIOT/examples/microcoap_server --- microcoap/Makefile | 32 --------- microcoap/README.md | 146 ------------------------------------------ microcoap/endpoints.c | 53 --------------- microcoap/main.c | 143 ----------------------------------------- 4 files changed, 374 deletions(-) delete mode 100644 microcoap/Makefile delete mode 100644 microcoap/README.md delete mode 100644 microcoap/endpoints.c delete mode 100644 microcoap/main.c diff --git a/microcoap/Makefile b/microcoap/Makefile deleted file mode 100644 index 75b7527f88..0000000000 --- a/microcoap/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# name of your application -APPLICATION = microcoap-example - -# If no BOARD is found in the environment, use this default: -BOARD ?= native - -# if you try to compile this for anything but the boards specified, it will break. -# This application has not been verified to work with any other boards-- proceed with caution. -BOARD_WHITELIST := native - -# This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../../RIOT - -# 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 += -DRIOT -DMICROCOAP_DEBUG - -# Change this to 0 show compiler invocation lines by default: -QUIET ?= 1 - -USEPKG=microcoap - -USEMODULE += config -USEMODULE += uart0 - -USEMODULE += nativenet - -USEMODULE += sixlowpan -USEMODULE += udp - -include $(RIOTBASE)/Makefile.include diff --git a/microcoap/README.md b/microcoap/README.md deleted file mode 100644 index ceab8b9ba5..0000000000 --- a/microcoap/README.md +++ /dev/null @@ -1,146 +0,0 @@ -Microcoap example -============ - -This is a small microcoap example application. It provides a server which only -answers GET requests to the resource /foo/bar. - -## Setup - -You can use [marz](https://github.com/sgso/marz) to tunnel CoAP messages into the RIOT native thread. This is a bit tricky, so maybe this walkthrough will help: - -0. Build this application. -1. Install the copper plugin in your Firefox browser. -2. Run `sudo apt-get install bridge-utils` -3. In your RIOT directury, run - - ./cpu/native/tapsetup.sh create 2 - -This will set up two tap devices connected by a bridge. our RIOT application and -marz will each listen at one of these devices, and communicate over the bridge. - -3. Open two terminal windows. - -**In window #1**, start the microcoap-example application: - - cd applications/microcoap - sudo ./bin/native/microcoap-example.elf tap1 -i 1 - -*Make sure to bind it to ``tap1``, since marz will be bound to ``tap0`!* -``-i 1`` forces your RIOT instance to match its id to the one specified in marz.config. You should **only** specify this for the **one** RIOT that marz tunnels to. This is sufficient for this example; if you need help running more than one RIOT with marz, please contact the author of this example. - -You should see output similar to this. - - RIOT native uart0 initialized. - RIOT native interrupts/signals initialized. - LED_GREEN_OFF - LED_RED_ON - RIOT native board initialized. - RIOT native hardware initialization complete. - - kernel_init(): This is RIOT! (Version: 400e-microcoap) - kernel_init(): jumping into first task... - UART0 thread started. - uart0_init() [OK] - Initializing transport layer protocol: udp - Starting example microcoap server... - initializing 6LoWPAN... - initializing receive socket... - Ready to receive requests. - - Welcome to RIOT - - > - -**In window #2**, first install Python development headers by running - - sudo apt-get install python-dev - -Afterwards you can install and run marz: - - pip install --user Twisted && - pip install --user bidict && - git clone https://github.com/sgso/marz && - cd marz && - ./setup.sh - - ./marz.py - -You should see output similar to this. - - WARNING: No route found for IPv6 destination :: (no default route?) - Listening on UDP ports: [5683, 2222] - Listening on tap interface tap0 with MAC address 9a:80:a3:fc:93:18 - -## Testing - -The "Copper" firefox plugin is a convenient way to test CoAP endpoints. In the absence of a GUI you can also use Python to send test requests. - -### Using python(3) - -First, make sure Python 3 is installed, clone `aiocoap` into a directory of your choice and then change into it: - - git clone git@github.com:chrysn/aiocoap.git && - cd aiocoap - -Open the `clientGET.py` file and change the line that reads - - request.set_request_uri() - -to - - request.set_request_uri('coap://[::1]/foo/bar') - -Then run `clientGET.py`, which should print the following: - - $ ./clientGET.py - Result: 2.05 Content - b'1337' - - -### Using the Firefox Copper plugin - -Open Firefox and enter - - coap://[::1]:5683/foo/bar - -Into the browser window. Then, click the big gren ``GET`` button. This should -trigger a GET request to our microcoap-example application. Shortly after you've -clicked GET, **window #2** should read - - make new connection - [UDP6 5683] Received 14 data bytes from ('::1', 54685): Relaying through 54685 to RiotEndpoint(hwaddr=1, ipv6='fe80::ff:fe00:1', port=5683) - [TAP] Received 12 data bytes on port 54685: Relaying through 5683 to IP6Endpoint(ipv6='::1', port=54685) - -**window #1** should supply you with detailed information about the received -request and the reply our microcoap-example is sending: - - > Received packet: 40 01 0B EC B3 66 6F 6F 03 62 61 72 C1 02 - content: - Header: - ver 0x01 - t 0x01 - tkl 0x00 - code 0x01 - id 0x0BEC - Options: - 0x0B [ 66 6F 6F ] - 0x0B [ 62 61 72 ] - 0x17 [ 02 ] - Payload: - Sending packet: 60 45 0B EC C2 00 00 FF 31 33 33 37 - content: - Header: - ver 0x01 - t 0x01 - tkl 0x00 - code 0x45 - id 0x0BEC - Options: - 0x0C [ 00 00 ] - Payload: 31 33 33 37 - -And finally, the big grey ``Payload`` box in your Firefox window should read: - - 1337 - -If this all works, you're good to go! :) diff --git a/microcoap/endpoints.c b/microcoap/endpoints.c deleted file mode 100644 index ddf95700a6..0000000000 --- a/microcoap/endpoints.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 HAW Hamburg - * - * 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. - */ - -/** - * @{ - * - * @file - * @brief microcoap example server endpoints - * - * @author Lotte Steenbrink - * - * @} - */ - -#include -#include -#include -#include "coap.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#define MAX_RESPONSE_LEN 1500 -static uint8_t response[MAX_RESPONSE_LEN] = ""; - -static const coap_endpoint_path_t path = {2, {"foo", "bar"}}; - -void create_response_payload(const uint8_t *buffer) -{ - char *response = "1337"; - memcpy((void*)buffer, response, strlen(response)); -} - -/* The handler which handles the path /foo/bar */ -static int handle_get_response(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo) -{ - DEBUG("[endpoints] %s()\n", __func__); - create_response_payload(response); - /* NOTE: COAP_RSPCODE_CONTENT only works in a packet answering a GET. */ - return coap_make_response(scratch, outpkt, response, strlen((char*)response), - id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN); -} - -const coap_endpoint_t endpoints[] = -{ - {COAP_METHOD_GET, handle_get_response, &path, "ct=0"}, - {(coap_method_t)0, NULL, NULL, NULL} /* marks the end of the endpoints array */ -}; diff --git a/microcoap/main.c b/microcoap/main.c deleted file mode 100644 index 782dc11ca6..0000000000 --- a/microcoap/main.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2015 HAW Hamburg - * - * 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. - */ - -/** - * @{ - * - * @file - * @brief microcoap example server - * - * @author Lotte Steenbrink - * - * @} - */ - -#include - -#include "udp.h" -#include "net_help.h" -#include "net_if.h" -#include "periph/cpuid.h" -#include "board_uart0.h" -#include "thread.h" -#include "posix_io.h" -#include -#include "hashes.h" - -#define ENABLE_DEBUG (1) -#include "debug.h" - -#define PORT 5683 -#define BUFSZ 128 - -#define RCV_MSG_Q_SIZE (64) - -static void *_microcoap_server_thread(void *arg); - -msg_t msg_q[RCV_MSG_Q_SIZE]; -char _rcv_stack_buf[KERNEL_CONF_STACKSIZE_MAIN]; - -static ipv6_addr_t prefix; -int sock_rcv, if_id; -sockaddr6_t sa_rcv; -uint8_t buf[BUFSZ]; -uint8_t scratch_raw[BUFSZ]; -coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)}; - -static void _init_tlayer(void); -static uint16_t get_hw_addr(void); - -int main(void) -{ - - DEBUG("Starting example microcoap server...\n"); - - _init_tlayer(); - thread_create(_rcv_stack_buf, KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN, CREATE_STACKTEST, _microcoap_server_thread, NULL ,"_microcoap_server_thread"); - - DEBUG("Ready to receive requests.\n"); - - return 0; -} - -static uint16_t get_hw_addr(void) -{ - return sysconfig.id; -} - -/* init transport layer & routing stuff*/ -static void _init_tlayer(void) -{ - msg_init_queue(msg_q, RCV_MSG_Q_SIZE); - - net_if_set_hardware_address(0, get_hw_addr()); - DEBUG("set hawddr to: %d\n", get_hw_addr()); - - printf("initializing 6LoWPAN...\n"); - - ipv6_addr_init(&prefix, 0xABCD, 0xEF12, 0, 0, 0, 0, 0, 0); - if_id = 0; /* having more than one interface isn't supported anyway */ - - sixlowpan_lowpan_init_interface(if_id); -} - -static void *_microcoap_server_thread(void *arg) -{ - (void)arg; /* make the compiler shut up about unused variables */ - - printf("initializing receive socket...\n"); - - sa_rcv = (sockaddr6_t) { .sin6_family = AF_INET6, - .sin6_port = HTONS(PORT) }; - - sock_rcv = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - - if (-1 == socket_base_bind(sock_rcv, &sa_rcv, sizeof(sa_rcv))) { - printf("Error: bind to receive socket failed!\n"); - socket_base_close(sock_rcv); - } - - printf("Ready to receive requests.\n"); - - while(1) - { - int n, rc; - socklen_t len = sizeof(sa_rcv); - coap_packet_t pkt; - - n = socket_base_recvfrom(sock_rcv, buf, sizeof(buf), 0, &sa_rcv, &len); - printf("Received packet: "); - coap_dump(buf, n, true); - printf("\n"); - - if (0 != (rc = coap_parse(&pkt, buf, n))) - printf("Bad packet rc=%d\n", rc); - else - { - size_t rsplen = sizeof(buf); - coap_packet_t rsppkt; - printf("content:\n"); - coap_dumpPacket(&pkt); - coap_handle_req(&scratch_buf, &pkt, &rsppkt); - - if (0 != (rc = coap_build(buf, &rsplen, &rsppkt))) - printf("coap_build failed rc=%d\n", rc); - else - { - printf("Sending packet: "); - coap_dump(buf, rsplen, true); - printf("\n"); - printf("content:\n"); - coap_dumpPacket(&rsppkt); - socket_base_sendto(sock_rcv, buf, rsplen, 0, &sa_rcv, sizeof(sa_rcv)); - } - } - } - - return NULL; -} From 34ec440a9314c621db62a9b84da4b1bec8970a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cenk=20G=C3=BCndo=C4=9Fan?= Date: Wed, 6 Apr 2016 13:42:03 +0200 Subject: [PATCH 22/90] openwsn: make: use correct name of iotlab-m3 --- openwsn/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openwsn/Makefile b/openwsn/Makefile index d52662ea8c..8c732404ec 100644 --- a/openwsn/Makefile +++ b/openwsn/Makefile @@ -1,7 +1,7 @@ APPLICATION = openwsn-app # If no BOARD is found in the environment, use this default: -BOARD ?= iot-lab_M3 +BOARD ?= iotlab-m3 # This has to be the absolute path to the RIOT base directory: RIOTBASE ?= $(CURDIR)/../../RIOT From b4f5cb6115453e97d8e1b3ae816397925ae95f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cenk=20G=C3=BCndo=C4=9Fan?= Date: Wed, 6 Apr 2016 13:58:24 +0200 Subject: [PATCH 23/90] openwsn: remove vtimer, use xtimer --- openwsn/Makefile | 2 +- openwsn/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openwsn/Makefile b/openwsn/Makefile index 8c732404ec..1e17df67be 100644 --- a/openwsn/Makefile +++ b/openwsn/Makefile @@ -18,7 +18,7 @@ CFLAGS += -DDEVELHELP export QUIET ?= 1 USEMODULE += ps -USEMODULE += vtimer +USEMODULE += xtimer USEMODULE += shell USEMODULE += shell_commands USEMODULE += posix diff --git a/openwsn/main.c b/openwsn/main.c index 5dec79f8ed..3ba7c212de 100644 --- a/openwsn/main.c +++ b/openwsn/main.c @@ -20,7 +20,7 @@ #include -#include "vtimer.h" +#include "xtimer.h" #include "shell.h" #include "posix_io.h" #include "03oos_openwsn.h" From 9651f8f90bd6e46f009718a187d14289a5eeeed8 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Fri, 8 Apr 2016 15:21:42 +0200 Subject: [PATCH 24/90] sniffer: update to RIOT master module name --- sniffer/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/Makefile b/sniffer/Makefile index 519bbb0d66..88c1a5c220 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -9,7 +9,7 @@ RIOTBASE ?= $(CURDIR)/../../RIOT # Define modules that are used USEMODULE += gnrc -USEMODULE += gnrc_netif_default +USEMODULE += gnrc_netdev_default USEMODULE += auto_init_gnrc_netif USEMODULE += shell USEMODULE += shell_commands From 0ef7e8e1a23f4abf69b1e3460acffcac1832149c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Thu, 10 Nov 2016 14:45:29 +0100 Subject: [PATCH 25/90] sniffer: Update to follow gnrc_netreg_entry_t API change --- sniffer/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/main.c b/sniffer/main.c index a54fb3374b..8628679e61 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -101,7 +101,7 @@ int main(void) /* start and register rawdump thread */ puts("Run the rawdump thread and register it"); - dump.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, + dump.target.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, THREAD_CREATE_STACKTEST, rawdump, NULL, "rawdump"); dump.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL; gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump); From 8c8de7cf66b833bd4139ff8a185b5142eac3fb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Sat, 3 Jun 2017 04:27:32 +0200 Subject: [PATCH 26/90] sniffer: Update xtimer_now64 usage after xtimer API change --- sniffer/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/main.c b/sniffer/main.c index 8628679e61..ece4fb2f7a 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -50,7 +50,7 @@ void dump_pkt(gnrc_pktsnip_t *pkt) gnrc_pktsnip_t *snip = pkt; printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08" PRIx64 "\n\n", - gnrc_pkt_len(pkt), 0, xtimer_now64()); + gnrc_pkt_len(pkt), 0, xtimer_usec_from_ticks64(xtimer_now64())); while (snip) { for (size_t i = 0; i < snip->size; i++) { From a455a00e01ebe9e9b85ec7edfcd3d4aa70d4a545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Sat, 3 Jun 2017 04:38:49 +0200 Subject: [PATCH 27/90] sniffer: Avoid relying on printf support for 64 bit numbers --- sniffer/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sniffer/main.c b/sniffer/main.c index ece4fb2f7a..602fb022e3 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -49,8 +49,10 @@ void dump_pkt(gnrc_pktsnip_t *pkt) { gnrc_pktsnip_t *snip = pkt; - printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08" PRIx64 "\n\n", - gnrc_pkt_len(pkt), 0, xtimer_usec_from_ticks64(xtimer_now64())); + uint64_t now_us = xtimer_usec_from_ticks64(xtimer_now64()); + + printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08" PRIx32 "%08" PRIx32 "\n\n", + gnrc_pkt_len(pkt), 0, (uint32_t)(now_us >> 32), (uint32_t)(now_us & 0xffffffff)); while (snip) { for (size_t i = 0; i < snip->size; i++) { From 03a53188b3ed66d7c42976e7a41ebe012c3f64d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Sat, 3 Jun 2017 13:00:21 +0200 Subject: [PATCH 28/90] spectrum-scanner: Application for radio ED scanning --- spectrum-scanner/Makefile | 20 ++++ spectrum-scanner/README.md | 36 +++++++ spectrum-scanner/main.c | 146 ++++++++++++++++++++++++++++ spectrum-scanner/tools/README.md | 40 ++++++++ spectrum-scanner/tools/example.png | Bin 0 -> 30859 bytes spectrum-scanner/tools/plot_rssi.py | 126 ++++++++++++++++++++++++ 6 files changed, 368 insertions(+) create mode 100644 spectrum-scanner/Makefile create mode 100644 spectrum-scanner/README.md create mode 100644 spectrum-scanner/main.c create mode 100644 spectrum-scanner/tools/README.md create mode 100644 spectrum-scanner/tools/example.png create mode 100755 spectrum-scanner/tools/plot_rssi.py diff --git a/spectrum-scanner/Makefile b/spectrum-scanner/Makefile new file mode 100644 index 0000000000..80c1eda49c --- /dev/null +++ b/spectrum-scanner/Makefile @@ -0,0 +1,20 @@ +# Set the name of your application: +APPLICATION = spectrum-scanner + +# If no BOARD is found in the environment, use this default: +BOARD ?= frdm-kw41z + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../../RIOT + +# Define modules that are used +USEMODULE += gnrc +USEMODULE += gnrc_netdev_default +USEMODULE += auto_init_gnrc_netif +USEMODULE += xtimer +USEMODULE += fmt + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/spectrum-scanner/README.md b/spectrum-scanner/README.md new file mode 100644 index 0000000000..39ec342a8a --- /dev/null +++ b/spectrum-scanner/README.md @@ -0,0 +1,36 @@ +About +===== + +This application is designed to run together with the script +`tools/plot_rssi.py` to monitor energy levels on all +available wireless channels. This application works with any board with a +network device that supports the gnrc network stack (or precisely the gnrc parts +up to the link-layer). Further, in order to get any measurements from the +device, the network device and its driver needs to support the netopt options +for executing a manual CCA and getting the last ED level +(NETOPT_IS_CHANNEL_CLR, and NETOPT_LAST_ED_LEVEL, respectively). Finally the +board needs to include auto-initialization code for the targeted network device. + +Usage +===== + +Compile and flash this application to the board of your choice. You can check if +everything on the RIOT side works by connecting to the board via UART and +looking at the output. + +Data format +=========== + +The format of the data on the UART is: + +``` +[interface_number, timestamp, count] channel: ed_level, channel: ed_level, ... +``` + +where interface_number is the interface number (in RIOT's `ifconfig`), timestamp +is the time since power on in microseconds, count is the number of measurements +that were averaged, channel is a channel number, ed_level is the average energy +level for that channel since the last update. + +For further information on setting up the host part, see +`tools/README.md`. diff --git a/spectrum-scanner/main.c b/spectrum-scanner/main.c new file mode 100644 index 0000000000..ad63a59f97 --- /dev/null +++ b/spectrum-scanner/main.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2017 Eistec AB + * + * 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. + */ + +/** + * @defgroup app_spectrum_scanner + * @brief Scanner application to find free channels + * @{ + * + * @file + * @brief Spectrum scanner application for RIOT + * + * @author Joakim Nohlgård + * + * @} + */ + +#include +#include + +#include "fmt.h" +#include "thread.h" +#include "xtimer.h" +#include "net/ieee802154.h" +#include "net/gnrc.h" + +/* Scanning interval */ +#define INTERVAL (500U * US_PER_MS) + +/** + * @brief Measure the radio energy spectrum and print on stdout + * + * Algorithm description: + * + * The process will repeat as many measurements as possible during the + * measurement interval, before the average power is computed. This reduces the + * noise in the measurement and will yield a better image of what the radio + * environment contains. + * + * Still, 122 measurements per second (frdm-kw41z) and 128 us per measurement + * will only give a time coverage of about 1.5%, but because the measurements are + * spread out over time they should still give a good representation of which + * channels are free. + * + * Note that because the ED values are given in decibels, the average radio + * power is not the same as the arithmetic mean of the ED measurements. To + * compute the average of the dB measurements this algorithm requires both + * logarithm and exponentiation, quite heavy operations on the kinds of CPUs + * that RIOT targets. Increasing the CPU clock frequency may therefore reduce + * the noise in the output, because of the more frequent energy measurements + * possible. + */ +void spectrum_scanner(unsigned long interval_us) +{ + kernel_pid_t ifs[GNRC_NETIF_NUMOF]; + size_t netif_numof = gnrc_netif_get(ifs); + + /* Using expf(x) (natural exponent) gives quicker computations on Cortex-M0+, + * compared to using powf(10, x). */ + /* + * This was optimized by testing different combinations of expf, powf, logf, log10f: + * + * functions used | measurement iterations per 0.5 s on reference system (frdm-kw41z) + * ------------------------------------------------------------------ + * expf, logf | 64 + * powf, log10f | 46 + * expf, log10f | 61 + * no-op (baseline) | 83 (but the measurements are useless) + */ + + while(1) { + /* Stack optimization, statically allocate this buffer */ + static float ed_average[GNRC_NETIF_NUMOF][IEEE802154_CHANNEL_MAX+1]; + + memset(ed_average, 0, sizeof(ed_average)); + + uint64_t last_wakeup = xtimer_now_usec64(); + uint64_t target = last_wakeup + interval_us; + /* We spin and try to do as many measurements as possible in the + * interval time */ + unsigned int count = 0; + do { + for (unsigned int k = 0; k < netif_numof; ++k) { + kernel_pid_t dev = ifs[k]; + for (unsigned int ch = IEEE802154_CHANNEL_MIN; ch <= IEEE802154_CHANNEL_MAX; ++ch) { + uint16_t tmp_ch = ch; + int res; + res = gnrc_netapi_set(dev, NETOPT_CHANNEL, 0, &tmp_ch, sizeof(uint16_t)); + if (res < 0) { + continue; + } + netopt_enable_t tmp; + /* Perform CCA to update ED level */ + res = gnrc_netapi_get(dev, NETOPT_IS_CHANNEL_CLR, 0, &tmp, sizeof(netopt_enable_t)); + if (res < 0) { + continue; + } + int8_t level = 0; + res = gnrc_netapi_get(dev, NETOPT_LAST_ED_LEVEL, 0, &level, sizeof(int8_t)); + if (res < 0) { + continue; + } + /* Convert dB to pseudo-energy before summing together the + * measurements. "Pseudo" because we use the natural + * exponential function e^x instead of computing 10^x which + * would be required if we needed the real measured energy. + * There is no need to know the real energy level because we + * will be converting back to dB again before printing. */ + ed_average[k][ch] += expf((float)level / 128.f); + } + } + ++count; + thread_yield(); + } while(xtimer_now_usec64() < target); + for (unsigned int k = 0; k < netif_numof; ++k) { + print("[", 1); + print_u32_dec(k); + print(", ", 2); + print_u64_dec(target); + print(", ", 2); + print_u32_dec(count); + print("] ", 2); + for (unsigned int ch = IEEE802154_CHANNEL_MIN; ch <= IEEE802154_CHANNEL_MAX; ++ch) { + /* Compute the average pseudo-energy and convert back to dB */ + ed_average[k][ch] = logf(ed_average[k][ch] / count) * 128.f; + print_u32_dec(ch); + print(": ", 2); + print_float(ed_average[k][ch], 4); + print(", ", 2); + } + print("\n", 1); + } + } +} + +int main(void) +{ + puts("RIOT scanner application"); + + spectrum_scanner(INTERVAL); + return 0; +} diff --git a/spectrum-scanner/tools/README.md b/spectrum-scanner/tools/README.md new file mode 100644 index 0000000000..1f1832e59e --- /dev/null +++ b/spectrum-scanner/tools/README.md @@ -0,0 +1,40 @@ +# RIOT Spectrum Scanner Application + +## About + +This script can be used to plot the radio signal spectrum when a connected node +is running the spectrum-scanner application application located in the parent +directory. +This node scans over the available radio channels performing CCA measurements +and outputting the measured ED level via a serial port. This output is then +parsed by the `plot_rssi.py` script included in this folder run on a host computer. + +## Dependencies + +The `plot_rssi.py` script requires [pyserial](https://pypi.python.org/pypi/pyserial) +for the serial port access, and [matplotlib](https://matplotlib.org) and +[numpy](http://www.numpy.org) for the plotting functionality. + +Installing the dependencies: + +#### Debian/Ubuntu + apt-get install python-serial python-matplotlib python-numpy + +#### PIP + pip install pyserial matplotlib numpy + +## Usage + +General usage: + +1. Flash a RIOT node with the spectrum-scanner application from +(https://github.com/RIOT-OS/applications/tree/master/spectrum-scanner) + +2. Run the `plot_rssi.py` script +``` +$ ./plot_rssi.py -b +``` + +### Examples + +![Example screenshot](https://github.com/RIOT-OS/applications/tree/master/spectrum-scanner/tools/example.png) diff --git a/spectrum-scanner/tools/example.png b/spectrum-scanner/tools/example.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c538ec03835c60fc4da2a392a6b0e1ab736d5c GIT binary patch literal 30859 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 SNjFXtruM08tEKO. + +import sys +import re +import time +import logging +import argparse +from serial import Serial +import numpy as np +import matplotlib.pylab as plt + +class rssi_plot(object): + + def plot_rssi(self, port): + self.count = 0 + self.dt = 0.5 + self.tlen = 120 + # Generate mesh for plotting + Y, X = np.mgrid[slice(0 - .5, 26 + 1.5, 1), slice(0 - self.dt / 2, self.tlen + 1 - self.dt / 2, self.dt)] + Z = np.zeros_like(X) + # X and Y are bounds, so Z should be the value *inside* those bounds. + # Therefore, remove the last value from the Z array. + Z = Z[:, :-1] + logging.debug("Creating figure") + fig = plt.figure() + pcm = plt.pcolormesh(X, Y, Z, vmin=-128, vmax=0, cmap=plt.cm.get_cmap('jet')) + plt.xlim([0, self.tlen]) + plt.ylim([0, 26]) + plt.colorbar(label="Measured signal level [dB]") + plt.ylabel("Channel number") + plt.xlabel("Time [s]") + plt.ion() + logging.debug("Show plot window") + plt.show() + ch_min = 26 + ch_max = 0 + last_update = time.time() + + logging.info("Begin collecting data from serial port") + while True: + line = port.readline().rstrip() + + pkt_data = re.match(r"\[([-+]?\d+),\s*([-+]?\d+),\s*([-+]?\d+)\]\s*(.*)", line.decode(errors='replace')) + if pkt_data: + now = time.time() + try: + iface_id = int(pkt_data.group(1)) + timestamp = int(pkt_data.group(2)) + count = int(pkt_data.group(3)) + tidx = int(timestamp / (self.dt * 1000000)) % (Z.shape[1]) + except ValueError: + continue + logging.debug("data: tidx=%d if=%d t=%d", tidx, iface_id, timestamp) + raw = pkt_data.group(4) + resize = False + for ch_ed in raw.split(","): + try: + pair = ch_ed.split(":") + ch = int(pair[0]) + ed = float(pair[1]) + if ch < ch_min: + ch_min = ch + resize = True + if ch > ch_max: + ch_max = ch + resize = True + Z[ch, tidx] = ed + except (ValueError, IndexError): + continue + #print("ch: %d ed: %d" % (ch, ed)) + if resize: + logging.debug("resize: %d %d" % (ch_min, ch_max)) + plt.ylim([ch_min - .5, ch_max + .5]) + if now > last_update + 1: + last_update = now + #pcm = plt.pcolormesh(X, Y, Z) + pcm.set_array(Z.ravel()) + pcm.autoscale() + pcm.changed() + plt.pause(0.01) + +def main(argv): + loglevels = [logging.CRITICAL, logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG] + parser = argparse.ArgumentParser(argv) + parser.add_argument('-v', '--verbosity', type=int, default=4, + help='set logging verbosity, 1=CRITICAL, 5=DEBUG') + parser.add_argument('tty', + help='Serial port device file name') + parser.add_argument('-b', '--baudrate', default=115200, type=int, + help='Serial port baudrate') + args = parser.parse_args() + # logging setup + logging.basicConfig(level=loglevels[args.verbosity-1]) + + # open serial port + try: + logging.debug("Open serial port %s, baud=%d", args.tty, args.baudrate) + port = Serial(args.tty, args.baudrate, dsrdtr=0, rtscts=0, timeout=0.3) + except IOError: + logging.critical("error opening serial port", file=sys.stderr) + sys.exit(2) + + try: + app = rssi_plot() + app.plot_rssi(port) + except KeyboardInterrupt: + port.close() + sys.exit(2) + +if __name__ == "__main__": + main(sys.argv) From 4f14d2a6d54b70e6bbb1403bbb4960936c9e05b1 Mon Sep 17 00:00:00 2001 From: smlng Date: Thu, 23 Nov 2017 10:44:32 +0100 Subject: [PATCH 29/90] sniffer: add script, moved from RIOT main repo --- sniffer/tools/README.md | 124 ++++++++++++++++++++++++++++ sniffer/tools/sniffer.py | 171 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 sniffer/tools/README.md create mode 100755 sniffer/tools/sniffer.py diff --git a/sniffer/tools/README.md b/sniffer/tools/README.md new file mode 100644 index 0000000000..4e858036b9 --- /dev/null +++ b/sniffer/tools/README.md @@ -0,0 +1,124 @@ +# RIOT Sniffer Application + + +## About + +This sniffer script can be used to monitor and capture network traffic using +a RIOT based node. It is primarily designed for sniffing wireless data traffic, +but can also well be used for wired network traffic, as long as used network +devices support promiscuous mode and output of raw data. + +The python script `sniffer.py` requires a RIOT node running the sniffer app, its +source code is located in this repository (see main folder). This node outputs +received network traffic via a serial port or a network socket in the common +Wireshark/libpcap (pcap) format. This output is then parsed by the `sniffer.py` +script included in this folder run on a host computer. + +The `sniffer.py` script is a modified version of [malvira's script](https://github.com/malvira/libmc1322x/blob/master/tools/rftestrx2pcap.py) +for the Redbee Ecotag (https://github.com/malvira/libmc1322x/wiki/wireshark). + +## Dependencies + +The `sniffer.py` script is written in Python and needs [pyserial](https://pypi.python.org/pypi/pyserial). + +Installing the dependencies: + + +#### Debuntu + apt-get install python-serial + +#### PIP + pip install pyserial + + +## Usage + +General usage: + +1. Flash an applicable RIOT node with the sniffer application (insert path to + RIOT source and board name), as follows: +``` +$ git clone https://github.com/RIOT-OS/applications/ +$ cd applications/sniffer +$ RIOTBASE= BOARD= make clean all flash +``` + +2. Run the `sniffer.py` script (change to subfolder `tools/`) as follows : + For serial port: +``` +$ ./sniffer.py serial [outfile] +``` +For network socket: +``` +$ ./sniffer.py socket [outfile] +``` + +The script has the following parameters: + +- **connType:** The type of connection to use. Either `serial` for serial ports or + `socket` for network sockets. +- **host:** The host if the `socket` connection type is in use. +- **port:** The port of the host if the `socket` connection type is in use. +- **tty:** The serial port the RIOT board is connected to. Under Linux, this is + typically something like /dev/ttyUSB0 or /dev/ttyACM0. Under Windows, + this is typically something like COM0 or COM1. This option is used + for the `serial` connection type. +- **baudrate:** The baudrate the serial port is configured to. The default in + RIOT is 115200, though this is defined per board and some boards + have some other value defined per default. NOTE: when sniffing + networks where the on-air bitrate is > baudrate, it makes sense + to increase the baudrate so no data is skipped when sniffing. + This option is used for the `serial` connection type. +- **channel:** The radio channel to use when sniffing. Possible values vary and + depend on the link-layer that is sniffed. This parameter is + ignored when sniffing wired networks. +- **[outfile]:** When this parameter is specified, the sniffer output is saved + into this file. See the examples below for alternatives to + specifying this parameter. (optional) + + +### Examples + +The following examples are made when using the sniffer application together with +an `iotlab-m3` node that is connected to `/dev/ttyUSB1`(or COM1) (`serial` connection type) +and runs per default with a baudrate of 500000. For the `socket` connection type port 20000 +is used. + +#### Linux (serial) + +Dump packets to a file: +``` +$ ./sniffer.py serial /dev/ttyUSB1 500000 17 > foo.pcap +``` + +This .pcap can then be opened in Wireshark. + +Alternatively for live captures, you can pipe directly into Wireshark with: +``` +$ ./sniffer.py serial /dev/ttyUSB1 500000 17 | wireshark -k -i - +``` + +#### Windows (serial) + +For windows you can use the optional third argument to output to a +.pcap: + +``` +$ ./sniffer.py serial COM1 500000 17 foo.pcap +``` + +#### IoT-Lab Testbed (socket) + +Start an experiment either via the website provided by the IoT-Lab testbed or +by using the RIOT specific iotlab Makefile with 3 neighboring `iotlab-m3` nodes, +where one of them runs the sniffer application and the others run the `gnrc_networking` application. + +Now you can bind the sniffer node to localhost: +ssh -L 20000:_node-id_:20000 _user_@_site_.iot-lab.info + +Then you can dump or observe the traffic generated by the other nodes running the `gnrc_networking` +application via one of the following commands: +``` +$ ./sniffer.py socket localhost 20000 26 > foo.pcap +$ ./sniffer.py socket localhost 20000 26 | wireshark -k -i - +``` diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py new file mode 100755 index 0000000000..612be817e5 --- /dev/null +++ b/sniffer/tools/sniffer.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +''' +(C) 2012, Mariano Alvira +(C) 2014, Oliver Hahm +(C) 2015, Hauke Petersen +(C) 2015, Martine Lenders +(C) 2015, Cenk Gündoğan + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the Institute nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. +''' + +from __future__ import print_function +import sys +import re +import socket +from time import sleep, time +from struct import pack +from serial import Serial + +# PCAP setup +MAGIC = 0xa1b2c3d4 +MAJOR = 2 +MINOR = 4 +ZONE = 0 +SIG = 0 +SNAPLEN = 0xffff +NETWORK = 230 # 802.15.4 no FCS + + +def configure_interface(port, channel): + line = "" + iface = 0 + port.write(b'ifconfig\n') + while True: + line = port.readline() + if line == '': + print("Application has no network interface defined", + file=sys.stderr) + sys.exit(2) + match = re.search(r'^Iface +(\d+)', line.decode()) + if match is not None: + iface = int(match.group(1)) + break + + # set channel, raw mode, and promiscuous mode + print('ifconfig %d set chan %d' % (iface, channel), file=sys.stderr) + print('ifconfig %d raw' % iface, file=sys.stderr) + print('ifconfig %d promisc' % iface, file=sys.stderr) + port.write(('ifconfig %d set chan %d\n' % (iface, channel)).encode()) + port.write(('ifconfig %d raw\n' % iface).encode()) + port.write(('ifconfig %d promisc\n' % iface).encode()) + + +def generate_pcap(port, out): + # count incoming packets + count = 0 + # output overall PCAP header + out.write(pack('? *rftest-rx --- len 0x(\w\w).*", + line.decode()) + if pkt_header: + now = time() + sec = int(now) + usec = int((now - sec) * 1000000) + length = int(pkt_header.group(1), 16) + out.write(pack(' (3,): + outfile = sys.stdout.buffer + else: + outfile = sys.stdout + + try: + generate_pcap(conn, outfile) + except KeyboardInterrupt: + conn.close() + print() + sys.exit(2) + + +if __name__ == "__main__": + main(sys.argv) From f9b3889e79e873b26893cf626d5562ad8abb13a9 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Mon, 18 Jun 2018 15:19:23 +0200 Subject: [PATCH 30/90] sniffer: remove gnrc_netif header; read LQI Since the device is in raw mode, we don't have any network layer modules included and we subscribe to `GNRC_NETTYPE_UNDEF` it is safe to assume that `pkt->next` in `dump_pkt()` is the `gnrc_netif` header. This only contains GNRC-internal information and should thus be removed from the dump (though Wireshark seems to be okay with the extra bytes, a reader of the raw data might be confused). Since this header however contains the LQI, which the sniffer claims to output but always returns 0, the LQI value in the `gnrc_netif` header is read and set before the deletion of that header. --- sniffer/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sniffer/main.c b/sniffer/main.c index 602fb022e3..f0f0924477 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -48,11 +48,14 @@ static char rawdmp_stack[THREAD_STACKSIZE_MAIN]; void dump_pkt(gnrc_pktsnip_t *pkt) { gnrc_pktsnip_t *snip = pkt; + gnrc_netif_hdr_t *netif_hdr = pkt->next->data; + uint8_t lqi = netif_hdr->lqi; + pkt = gnrc_pktbuf_remove_snip(pkt, pkt->next); uint64_t now_us = xtimer_usec_from_ticks64(xtimer_now64()); printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08" PRIx32 "%08" PRIx32 "\n\n", - gnrc_pkt_len(pkt), 0, (uint32_t)(now_us >> 32), (uint32_t)(now_us & 0xffffffff)); + gnrc_pkt_len(pkt), lqi, (uint32_t)(now_us >> 32), (uint32_t)(now_us & 0xffffffff)); while (snip) { for (size_t i = 0; i < snip->size; i++) { From 47aa717c786776515ba8475b96a0e55fda9a9cbc Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Mon, 18 Jun 2018 15:34:23 +0200 Subject: [PATCH 31/90] sniffer: add message queue for dumper thread Usually we have a message queue for threads handling GNRC netapi calls. Maybe the absence of one in this application contributes to the packet loss reported at various places. --- sniffer/main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sniffer/main.c b/sniffer/main.c index 602fb022e3..91d49983c2 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -37,6 +37,11 @@ */ #define RAWDUMP_PRIO (THREAD_PRIORITY_MAIN - 1) +/** + * @brief Message queue size of the RAW dump thread + */ +#define RAWDUMP_MSG_Q_SIZE (32U) + /** * @brief Stack for the raw dump thread */ @@ -72,12 +77,14 @@ void dump_pkt(gnrc_pktsnip_t *pkt) */ void *rawdump(void *arg) { + msg_t msg_q[RAWDUMP_MSG_Q_SIZE]; + (void)arg; - msg_t msg; - + msg_init_queue(msg_q, RAWDUMP_MSG_Q_SIZE); while (1) { - msg_receive(&msg); + msg_t msg; + msg_receive(&msg); switch (msg.type) { case GNRC_NETAPI_MSG_TYPE_RCV: dump_pkt((gnrc_pktsnip_t *)msg.content.ptr); From 3628f0dd5f3b4af6497eb94904c5a9de5b1efc2d Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 19 Jun 2018 09:51:18 +0200 Subject: [PATCH 32/90] sniffer: script: ignore non-ASCII characters on input The sniffer RIOT application doesn't generate non-ASCII characters so it is safe for the python PCAP-generating script to assume that those characters are garbage output (e.g. in initialization) and can be ignored. --- sniffer/tools/sniffer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 612be817e5..cb42ffa8d9 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -60,7 +60,7 @@ def configure_interface(port, channel): print("Application has no network interface defined", file=sys.stderr) sys.exit(2) - match = re.search(r'^Iface +(\d+)', line.decode()) + match = re.search(r'^Iface +(\d+)', line.decode(errors="ignore")) if match is not None: iface = int(match.group(1)) break @@ -85,7 +85,7 @@ def generate_pcap(port, out): line = port.readline().rstrip() pkt_header = re.match(r">? *rftest-rx --- len 0x(\w\w).*", - line.decode()) + line.decode(errors="ignore")) if pkt_header: now = time() sec = int(now) @@ -97,9 +97,9 @@ def generate_pcap(port, out): sys.stderr.write("RX: %i\r" % count) continue - pkt_data = re.match(r"(0x\w\w )+", line.decode()) + pkt_data = re.match(r"(0x\w\w )+", line.decode(errors="ignore")) if pkt_data: - for part in line.decode().split(' '): + for part in line.decode(errors="ignore").split(' '): byte = re.match(r"0x(\w\w)", part) if byte: out.write(pack(' Date: Fri, 22 Jun 2018 14:12:04 +0200 Subject: [PATCH 33/90] openwsn: remove deprecated application --- openwsn/Makefile | 33 -------------------------- openwsn/main.c | 62 ------------------------------------------------ 2 files changed, 95 deletions(-) delete mode 100644 openwsn/Makefile delete mode 100644 openwsn/main.c diff --git a/openwsn/Makefile b/openwsn/Makefile deleted file mode 100644 index 1e17df67be..0000000000 --- a/openwsn/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -APPLICATION = openwsn-app - -# If no BOARD is found in the environment, use this default: -BOARD ?= iotlab-m3 - -# This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../../RIOT - -# Uncomment this to enable scheduler statistics for ps: -#CFLAGS += -DSCHEDSTATISTICS - -# Uncomment this to enable 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: -export QUIET ?= 1 - -USEMODULE += ps -USEMODULE += xtimer -USEMODULE += shell -USEMODULE += shell_commands -USEMODULE += posix -USEMODULE += uart0 -USEMODULE += at86rf231 - -USEPKG += openwsn - -include $(RIOTBASE)/Makefile.include - -INCLUDES += -I$(RIOTBASE)/pkg/openwsn/openwsn/projects/common/03oos_openwsn \ - -I$(RIOTBASE)/pkg/openwsn/openwsn/bsp/boards/riot-adaption diff --git a/openwsn/main.c b/openwsn/main.c deleted file mode 100644 index 3ba7c212de..0000000000 --- a/openwsn/main.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * 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 tests - * @{ - * - * @file - * @brief Test application for OpenWSN pkg - * - * @author Thomas Eichinger - * - * @} - */ - -#include - -#include "xtimer.h" -#include "shell.h" -#include "posix_io.h" -#include "03oos_openwsn.h" -#include "board_uart0.h" -#include "riot.h" - - -const shell_command_t shell_commands[] = { - {"owsn_init", "Start OpenWSN", openwsn_start_thread}, - {NULL, NULL, NULL} -}; - -static int shell_readc(void) -{ - char c = 0; - (void) posix_read(uart0_handler_pid, &c, 1); - return c; -} - -static int shell_putchar(int c) -{ - (void) putchar(c); - - return c; -} - -int main(void) { - shell_t shell; - - (void) posix_open(uart0_handler_pid, 0); - - puts("Welcome to RIOT!"); - - shell_init(&shell, shell_commands, UART0_BUFSIZE, shell_readc, shell_putchar); - - shell_run(&shell); - - return 0; -} From b600dcf1f024c8f3f879fcb971f4bdef426f21a7 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 19 Jun 2018 11:42:18 +0200 Subject: [PATCH 34/90] sniffer: use argparse to parse script arguments This is mainly a preparation step to make some arguments (namely baudrate and the "serial/socket" argument) optional, to make it more usable like the old `rftest2pcap` script for the econotag. --- sniffer/tools/sniffer.py | 62 +++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 612be817e5..04ef801b45 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -33,6 +33,7 @@ SUCH DAMAGE. ''' from __future__ import print_function +import argparse import sys import re import socket @@ -106,21 +107,21 @@ def generate_pcap(port, out): out.flush() -def connect(argv): - connType = argv[1] +def connect(args): + connType = args.conn_type conn = None if connType == "serial": # open serial port try: - conn = Serial(argv[2], argv[3], dsrdtr=0, rtscts=0, + conn = Serial(args.tty, args.baudrate, dsrdtr=0, rtscts=0, timeout=1) except IOError: print("error opening serial port", file=sys.stderr) sys.exit(2) elif connType == "socket": - host = argv[2] - port = int(argv[3]) + host = args.host + port = args.port try: sock = socket.socket() @@ -135,32 +136,41 @@ def connect(argv): return conn -def main(argv): - if len(argv) < 5: - print("Usage: %s serial tty baudrate channel [outfile]\n" - " %s socket host port channel [outfile]" % (argv[0], argv[0]), - file=sys.stderr) - print(" channel = 11-26", file=sys.stderr) - sys.exit(2) +def main(): + if sys.version_info > (3,): + default_outfile = sys.stdout.buffer + else: + default_outfile = sys.stdout + p = argparse.ArgumentParser() + sp = p.add_subparsers(dest="conn_type") + serial_p = sp.add_parser("serial", + help="Parse output of sniffer application " + "connected via serial line") + serial_p.add_argument("tty", type=str, + help="Serial port to board with sniffer application") + serial_p.add_argument("baudrate", type=int, + help="Baudrate of the serial port") + socket_p = sp.add_parser("socket", + help="Parse output of a TCP-connected sniffer " + "application") + socket_p.add_argument("host", type=str, + help="Host of the TCP-based sniffer application") + socket_p.add_argument("port", type=int, + help="Port of the TCP-based sniffer application") + p.add_argument("channel", type=int, help="Channel to sniff on") + p.add_argument("outfile", type=argparse.FileType("w+b"), + default=default_outfile, nargs="?", + help="PCAP file to output to") + args = p.parse_args() - conn = connect(argv) + conn = connect(args) sleep(1) - configure_interface(conn, int(argv[4])) + configure_interface(conn, args.channel) sleep(1) - # figure out where to write try: - sys.stderr.write('trying to open file %s\n' % argv[5]) - outfile = open(argv[5], 'w+b') - except IndexError: - if sys.version_info > (3,): - outfile = sys.stdout.buffer - else: - outfile = sys.stdout - - try: - generate_pcap(conn, outfile) + generate_pcap(conn, args.outfile) except KeyboardInterrupt: conn.close() print() @@ -168,4 +178,4 @@ def main(argv): if __name__ == "__main__": - main(sys.argv) + main() From 1f77040fc099a22e35f56d00013bb575bc73b0de Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 19 Jun 2018 13:18:43 +0200 Subject: [PATCH 35/90] sniffer: make baudrate optional --- sniffer/tools/sniffer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 04ef801b45..588f66d453 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -148,8 +148,8 @@ def main(): "connected via serial line") serial_p.add_argument("tty", type=str, help="Serial port to board with sniffer application") - serial_p.add_argument("baudrate", type=int, - help="Baudrate of the serial port") + serial_p.add_argument("-b", "--baudrate", type=int, default=112500, + nargs="?", help="Baudrate of the serial port") socket_p = sp.add_parser("socket", help="Parse output of a TCP-connected sniffer " "application") From e4f73690abba33a07be29ba148c97cc680e196f4 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 19 Jun 2018 13:42:15 +0200 Subject: [PATCH 36/90] sniffer: get connection type from string format The KISS approach alternative to #38 (also includes #39, because...). Disadvantage: we loose backwards compatibility for this tool. --- sniffer/tools/sniffer.py | 46 ++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 588f66d453..58a55502df 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -108,21 +108,23 @@ def generate_pcap(port, out): def connect(args): - connType = args.conn_type - conn = None - if connType == "serial": + if args.conn.startswith("/dev/tty") or args.conn.startswith("COM"): # open serial port try: - conn = Serial(args.tty, args.baudrate, dsrdtr=0, rtscts=0, + conn = Serial(args.conn, args.baudrate, dsrdtr=0, rtscts=0, timeout=1) except IOError: - print("error opening serial port", file=sys.stderr) + print("error opening serial port %s" % args.conn, file=sys.stderr) + sys.exit(2) + else: + try: + port = args.conn.split(":")[-1] + host = args.conn[:-(len(port)+1)] + port = int(port) + except (IndexError, ValueError): + print("Can't parse host:port pair %s" % args.conn, file=sys.stderr) sys.exit(2) - elif connType == "socket": - host = args.host - port = args.port - try: sock = socket.socket() sock.connect((host, port)) @@ -130,33 +132,21 @@ def connect(args): except IOError: print("error connecting to %s:%s" % (host, port), file=sys.stderr) sys.exit(2) - else: - print("error: unsupported connection type. Use \"serial\" or \"socket\"") - sys.exit(2) - return conn + def main(): if sys.version_info > (3,): default_outfile = sys.stdout.buffer else: default_outfile = sys.stdout p = argparse.ArgumentParser() - sp = p.add_subparsers(dest="conn_type") - serial_p = sp.add_parser("serial", - help="Parse output of sniffer application " - "connected via serial line") - serial_p.add_argument("tty", type=str, - help="Serial port to board with sniffer application") - serial_p.add_argument("-b", "--baudrate", type=int, default=112500, - nargs="?", help="Baudrate of the serial port") - socket_p = sp.add_parser("socket", - help="Parse output of a TCP-connected sniffer " - "application") - socket_p.add_argument("host", type=str, - help="Host of the TCP-based sniffer application") - socket_p.add_argument("port", type=int, - help="Port of the TCP-based sniffer application") + p.add_argument("-b", "--baudrate", type=int, default=112500, + help="Baudrate of the serial port (only evaluated " + "for non TCP-terminal)") + p.add_argument("conn", metavar="tty/host:port", type=str, + help="Serial port or TCP (host, port) tuple to " + "terminal with sniffer application") p.add_argument("channel", type=int, help="Channel to sniff on") p.add_argument("outfile", type=argparse.FileType("w+b"), default=default_outfile, nargs="?", From 9204feb07b3f7f3c0c5a58d268a952c737ea26bc Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 19 Jun 2018 10:02:17 +0200 Subject: [PATCH 37/90] sniffer: use fmt instead of printf I was able to reduce stack usage by 2/3 on `samr21-xpro`. Additionally, I removed the leading `0x` for the hexadecimal numbers. The parsing script knows which numbers are hex (all of them) and they just waste time both on the node and in the parsing script --- sniffer/Makefile | 1 + sniffer/main.c | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/sniffer/Makefile b/sniffer/Makefile index 88c1a5c220..01e46cb67b 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -8,6 +8,7 @@ BOARD ?= native RIOTBASE ?= $(CURDIR)/../../RIOT # Define modules that are used +USEMODULE += fmt USEMODULE += gnrc USEMODULE += gnrc_netdev_default USEMODULE += auto_init_gnrc_netif diff --git a/sniffer/main.c b/sniffer/main.c index 8dd481fdbd..998a55b4aa 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Freie Universität Berlin + * Copyright (C) 2015-18 Freie Universität Berlin * * 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 @@ -15,12 +15,14 @@ * @brief Sniffer application for RIOT * * @author Hauke Petersen + * @author Martine Lenders * * @} */ #include +#include "fmt.h" #include "thread.h" #include "xtimer.h" #include "shell.h" @@ -59,16 +61,21 @@ void dump_pkt(gnrc_pktsnip_t *pkt) pkt = gnrc_pktbuf_remove_snip(pkt, pkt->next); uint64_t now_us = xtimer_usec_from_ticks64(xtimer_now64()); - printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08" PRIx32 "%08" PRIx32 "\n\n", - gnrc_pkt_len(pkt), lqi, (uint32_t)(now_us >> 32), (uint32_t)(now_us & 0xffffffff)); - + print_str("rftest-rx --- len "); + print_u32_hex((uint32_t)gnrc_pkt_len(pkt)); + print_str(" lqi "); + print_byte_hex(lqi); + print_str(" rx_time "); + print_u64_hex(now_us); + print_str("\n"); while (snip) { for (size_t i = 0; i < snip->size; i++) { - printf("0x%02x ", ((uint8_t *)(snip->data))[i]); + print_byte_hex(((uint8_t *)(snip->data))[i]); + print_str(" "); } snip = snip->next; } - puts("\n"); + print_str("\n\n"); gnrc_pktbuf_release(pkt); } From 3ef810ffd13790661f5d4f3657c57a6fdf1ace9b Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 19 Jun 2018 10:04:02 +0200 Subject: [PATCH 38/90] sniffer: adapt parsing script --- sniffer/tools/sniffer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 7d09d217bd..470520e810 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -85,7 +85,7 @@ def generate_pcap(port, out): while True: line = port.readline().rstrip() - pkt_header = re.match(r">? *rftest-rx --- len 0x(\w\w).*", + pkt_header = re.match(r">? *rftest-rx --- len (\w+).*", line.decode(errors="ignore")) if pkt_header: now = time() @@ -98,10 +98,10 @@ def generate_pcap(port, out): sys.stderr.write("RX: %i\r" % count) continue - pkt_data = re.match(r"(0x\w\w )+", line.decode(errors="ignore")) + pkt_data = re.match(r"(\w\w )+", line.decode(errors="ignore")) if pkt_data: for part in line.decode(errors="ignore").split(' '): - byte = re.match(r"0x(\w\w)", part) + byte = re.match(r"(\w\w)", part) if byte: out.write(pack(' Date: Tue, 19 Jun 2018 10:55:19 +0200 Subject: [PATCH 39/90] sniffer: reduce rawdump thread stack size --- sniffer/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/main.c b/sniffer/main.c index 998a55b4aa..3f78e71422 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -47,7 +47,7 @@ /** * @brief Stack for the raw dump thread */ -static char rawdmp_stack[THREAD_STACKSIZE_MAIN]; +static char rawdmp_stack[THREAD_STACKSIZE_SMALL]; /** * @brief Make a raw dump of the given packet contents From c32bd15ef50d74025bf37063efc912f68460d614 Mon Sep 17 00:00:00 2001 From: smlng Date: Tue, 2 Oct 2018 10:48:16 +0200 Subject: [PATCH 40/90] sniffer: fix default baudrate in script --- sniffer/tools/sniffer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 7d09d217bd..20a7fd280b 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -141,7 +141,7 @@ def main(): else: default_outfile = sys.stdout p = argparse.ArgumentParser() - p.add_argument("-b", "--baudrate", type=int, default=112500, + p.add_argument("-b", "--baudrate", type=int, default=115200, help="Baudrate of the serial port (only evaluated " "for non TCP-terminal)") p.add_argument("conn", metavar="tty/host:port", type=str, From ee613bda94436e871c32abda45bd322132b95b39 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 26 Sep 2018 20:19:52 +0200 Subject: [PATCH 41/90] sniffer: Update script path in README of sniffer application The script was moved from the main RIOT repository to the sniffer application's directory in 08b173b. This fixes the README of this application to reflect that. --- sniffer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/README.md b/sniffer/README.md index 6cd9794072..4bdd5d70f5 100644 --- a/sniffer/README.md +++ b/sniffer/README.md @@ -1,7 +1,7 @@ About ===== -This application is build to run together with the script `RIOTBASE/dist/tools/sniffer/sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. +This application is build to run together with the script `./tools/sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. Usage From 1216b9b7b68d56846b3625df0fd3b2713ecc1693 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 26 Sep 2018 20:28:43 +0200 Subject: [PATCH 42/90] sniffer.py: document default parameter values in help --- sniffer/tools/sniffer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 20a7fd280b..36110fb9f7 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -143,14 +143,14 @@ def main(): p = argparse.ArgumentParser() p.add_argument("-b", "--baudrate", type=int, default=115200, help="Baudrate of the serial port (only evaluated " - "for non TCP-terminal)") + "for non TCP-terminal, default: 112500)") p.add_argument("conn", metavar="tty/host:port", type=str, help="Serial port or TCP (host, port) tuple to " "terminal with sniffer application") p.add_argument("channel", type=int, help="Channel to sniff on") p.add_argument("outfile", type=argparse.FileType("w+b"), default=default_outfile, nargs="?", - help="PCAP file to output to") + help="PCAP file to output to (default: stdout)") args = p.parse_args() conn = connect(args) From 9f501941b05bbe68f20cd11e4ef32750df4869b7 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 26 Sep 2018 20:30:54 +0200 Subject: [PATCH 43/90] sniffer/tools: Update README to reflect use of argparse The sniffer script was ported to an `argparse`-based approach for its parameters in fb79b79, 5017bea, and 22516be. However, that change was missing an update to the README. This fixes that. --- sniffer/tools/README.md | 40 +++++++++++----------------------------- sniffer/tools/sniffer.py | 7 +++++-- 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/sniffer/tools/README.md b/sniffer/tools/README.md index 4e858036b9..6b51a21488 100644 --- a/sniffer/tools/README.md +++ b/sniffer/tools/README.md @@ -46,36 +46,18 @@ $ RIOTBASE= BOARD= make clean all flash 2. Run the `sniffer.py` script (change to subfolder `tools/`) as follows : For serial port: ``` -$ ./sniffer.py serial [outfile] +$ ./sniffer.py [-b baudrate] [outfile] ``` For network socket: ``` -$ ./sniffer.py socket [outfile] +$ ./sniffer.py : [outfile] ``` -The script has the following parameters: - -- **connType:** The type of connection to use. Either `serial` for serial ports or - `socket` for network sockets. -- **host:** The host if the `socket` connection type is in use. -- **port:** The port of the host if the `socket` connection type is in use. -- **tty:** The serial port the RIOT board is connected to. Under Linux, this is - typically something like /dev/ttyUSB0 or /dev/ttyACM0. Under Windows, - this is typically something like COM0 or COM1. This option is used - for the `serial` connection type. -- **baudrate:** The baudrate the serial port is configured to. The default in - RIOT is 115200, though this is defined per board and some boards - have some other value defined per default. NOTE: when sniffing - networks where the on-air bitrate is > baudrate, it makes sense - to increase the baudrate so no data is skipped when sniffing. - This option is used for the `serial` connection type. -- **channel:** The radio channel to use when sniffing. Possible values vary and - depend on the link-layer that is sniffed. This parameter is - ignored when sniffing wired networks. -- **[outfile]:** When this parameter is specified, the sniffer output is saved - into this file. See the examples below for alternatives to - specifying this parameter. (optional) +For detailed information on the parameters use the scripts on-line help: +``` +./sniffer.py -h +``` ### Examples @@ -88,14 +70,14 @@ is used. Dump packets to a file: ``` -$ ./sniffer.py serial /dev/ttyUSB1 500000 17 > foo.pcap +$ ./sniffer.py -b 500000 /dev/ttyUSB1 17 foo.pcap ``` This .pcap can then be opened in Wireshark. Alternatively for live captures, you can pipe directly into Wireshark with: ``` -$ ./sniffer.py serial /dev/ttyUSB1 500000 17 | wireshark -k -i - +$ ./sniffer.py -b 500000 /dev/ttyUSB1 17 | wireshark -k -i - ``` #### Windows (serial) @@ -104,7 +86,7 @@ For windows you can use the optional third argument to output to a .pcap: ``` -$ ./sniffer.py serial COM1 500000 17 foo.pcap +$ ./sniffer.py -b 500000 COM1 17 foo.pcap ``` #### IoT-Lab Testbed (socket) @@ -119,6 +101,6 @@ ssh -L 20000:_node-id_:20000 _user_@_site_.iot-lab.info Then you can dump or observe the traffic generated by the other nodes running the `gnrc_networking` application via one of the following commands: ``` -$ ./sniffer.py socket localhost 20000 26 > foo.pcap -$ ./sniffer.py socket localhost 20000 26 | wireshark -k -i - +$ ./sniffer.py localhost:20000 26 foo.pcap +$ ./sniffer.py localhost:20000 26 | wireshark -k -i - ``` diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 36110fb9f7..7ce6451308 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -50,6 +50,8 @@ SIG = 0 SNAPLEN = 0xffff NETWORK = 230 # 802.15.4 no FCS +DEFAULT_BAUDRATE = 115200 + def configure_interface(port, channel): line = "" @@ -141,9 +143,10 @@ def main(): else: default_outfile = sys.stdout p = argparse.ArgumentParser() - p.add_argument("-b", "--baudrate", type=int, default=115200, + p.add_argument("-b", "--baudrate", type=int, default=DEFAULT_BAUDRATE, help="Baudrate of the serial port (only evaluated " - "for non TCP-terminal, default: 112500)") + "for non TCP-terminal, default: %d)" % + DEFAULT_BAUDRATE) p.add_argument("conn", metavar="tty/host:port", type=str, help="Serial port or TCP (host, port) tuple to " "terminal with sniffer application") From f8fbc9a93e5dcf2fd7b32debd966836b937b5ec5 Mon Sep 17 00:00:00 2001 From: smlng Date: Tue, 2 Oct 2018 22:36:32 +0200 Subject: [PATCH 44/90] sniffer: uncrustify --- sniffer/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/main.c b/sniffer/main.c index 3f78e71422..189a660249 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -121,7 +121,7 @@ int main(void) /* start and register rawdump thread */ puts("Run the rawdump thread and register it"); dump.target.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO, - THREAD_CREATE_STACKTEST, rawdump, NULL, "rawdump"); + THREAD_CREATE_STACKTEST, rawdump, NULL, "rawdump"); dump.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL; gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump); From a62839b231477c438beee30d75a20be08355afc9 Mon Sep 17 00:00:00 2001 From: smlng Date: Tue, 2 Oct 2018 22:36:49 +0200 Subject: [PATCH 45/90] spectrum-scanner: uncrustify --- spectrum-scanner/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spectrum-scanner/main.c b/spectrum-scanner/main.c index ad63a59f97..72bdc184cc 100644 --- a/spectrum-scanner/main.c +++ b/spectrum-scanner/main.c @@ -72,9 +72,9 @@ void spectrum_scanner(unsigned long interval_us) * no-op (baseline) | 83 (but the measurements are useless) */ - while(1) { + while (1) { /* Stack optimization, statically allocate this buffer */ - static float ed_average[GNRC_NETIF_NUMOF][IEEE802154_CHANNEL_MAX+1]; + static float ed_average[GNRC_NETIF_NUMOF][IEEE802154_CHANNEL_MAX + 1]; memset(ed_average, 0, sizeof(ed_average)); @@ -115,7 +115,7 @@ void spectrum_scanner(unsigned long interval_us) } ++count; thread_yield(); - } while(xtimer_now_usec64() < target); + } while (xtimer_now_usec64() < target); for (unsigned int k = 0; k < netif_numof; ++k) { print("[", 1); print_u32_dec(k); From b0eae4bc821cc692bb8cde4ad9ea84f5ea61918d Mon Sep 17 00:00:00 2001 From: smlng Date: Thu, 4 Oct 2018 14:50:12 +0200 Subject: [PATCH 46/90] spektrum-scanner: adapt to new gnrc_netif calls Accessing and handling of network interfaces with gnrc_netif has changed and needs adaption to compile and work again. --- spectrum-scanner/main.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/spectrum-scanner/main.c b/spectrum-scanner/main.c index 72bdc184cc..412ccfd509 100644 --- a/spectrum-scanner/main.c +++ b/spectrum-scanner/main.c @@ -56,8 +56,7 @@ */ void spectrum_scanner(unsigned long interval_us) { - kernel_pid_t ifs[GNRC_NETIF_NUMOF]; - size_t netif_numof = gnrc_netif_get(ifs); + size_t netif_numof = gnrc_netif_numof(); /* Using expf(x) (natural exponent) gives quicker computations on Cortex-M0+, * compared to using powf(10, x). */ @@ -84,23 +83,23 @@ void spectrum_scanner(unsigned long interval_us) * interval time */ unsigned int count = 0; do { - for (unsigned int k = 0; k < netif_numof; ++k) { - kernel_pid_t dev = ifs[k]; + gnrc_netif_t *netif = NULL; + for (unsigned int k = 0; (netif = gnrc_netif_iter(netif)); k++) { for (unsigned int ch = IEEE802154_CHANNEL_MIN; ch <= IEEE802154_CHANNEL_MAX; ++ch) { uint16_t tmp_ch = ch; int res; - res = gnrc_netapi_set(dev, NETOPT_CHANNEL, 0, &tmp_ch, sizeof(uint16_t)); + res = gnrc_netapi_set(netif->pid, NETOPT_CHANNEL, 0, &tmp_ch, sizeof(uint16_t)); if (res < 0) { continue; } netopt_enable_t tmp; /* Perform CCA to update ED level */ - res = gnrc_netapi_get(dev, NETOPT_IS_CHANNEL_CLR, 0, &tmp, sizeof(netopt_enable_t)); + res = gnrc_netapi_get(netif->pid, NETOPT_IS_CHANNEL_CLR, 0, &tmp, sizeof(netopt_enable_t)); if (res < 0) { continue; } int8_t level = 0; - res = gnrc_netapi_get(dev, NETOPT_LAST_ED_LEVEL, 0, &level, sizeof(int8_t)); + res = gnrc_netapi_get(netif->pid, NETOPT_LAST_ED_LEVEL, 0, &level, sizeof(int8_t)); if (res < 0) { continue; } From 6838b92c4122ca6dc86b6945eb60344980e7e30c Mon Sep 17 00:00:00 2001 From: smlng Date: Thu, 4 Oct 2018 14:51:35 +0200 Subject: [PATCH 47/90] spektrum-scanner: set default board to samr21-xpro Currently only the at86rf2xx driver supports the required NETOPT to make the spektrum scanner work. --- spectrum-scanner/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spectrum-scanner/Makefile b/spectrum-scanner/Makefile index 80c1eda49c..f6b3db6754 100644 --- a/spectrum-scanner/Makefile +++ b/spectrum-scanner/Makefile @@ -2,7 +2,7 @@ APPLICATION = spectrum-scanner # If no BOARD is found in the environment, use this default: -BOARD ?= frdm-kw41z +BOARD ?= samr21-xpro # This has to be the absolute path to the RIOT base directory: RIOTBASE ?= $(CURDIR)/../../RIOT From b1cfc4844c223566e9a5f81203369452fcbd6722 Mon Sep 17 00:00:00 2001 From: smlng Date: Thu, 4 Oct 2018 14:11:50 +0200 Subject: [PATCH 48/90] spektrum-scanner: fix plot_rssi.py script Adapt python script to comply with python coding conventions, i.e. fixing error reported by flake8. --- spectrum-scanner/tools/plot_rssi.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spectrum-scanner/tools/plot_rssi.py b/spectrum-scanner/tools/plot_rssi.py index 1911a0562d..e03369801e 100755 --- a/spectrum-scanner/tools/plot_rssi.py +++ b/spectrum-scanner/tools/plot_rssi.py @@ -24,6 +24,7 @@ from serial import Serial import numpy as np import matplotlib.pylab as plt + class rssi_plot(object): def plot_rssi(self, port): @@ -37,7 +38,7 @@ class rssi_plot(object): # Therefore, remove the last value from the Z array. Z = Z[:, :-1] logging.debug("Creating figure") - fig = plt.figure() + plt.figure() pcm = plt.pcolormesh(X, Y, Z, vmin=-128, vmax=0, cmap=plt.cm.get_cmap('jet')) plt.xlim([0, self.tlen]) plt.ylim([0, 26]) @@ -65,7 +66,7 @@ class rssi_plot(object): tidx = int(timestamp / (self.dt * 1000000)) % (Z.shape[1]) except ValueError: continue - logging.debug("data: tidx=%d if=%d t=%d", tidx, iface_id, timestamp) + logging.debug("data: tidx=%d if=%d cnt=%d t=%d", tidx, iface_id, count, timestamp) raw = pkt_data.group(4) resize = False for ch_ed in raw.split(","): @@ -82,18 +83,17 @@ class rssi_plot(object): Z[ch, tidx] = ed except (ValueError, IndexError): continue - #print("ch: %d ed: %d" % (ch, ed)) if resize: logging.debug("resize: %d %d" % (ch_min, ch_max)) plt.ylim([ch_min - .5, ch_max + .5]) if now > last_update + 1: last_update = now - #pcm = plt.pcolormesh(X, Y, Z) pcm.set_array(Z.ravel()) pcm.autoscale() pcm.changed() plt.pause(0.01) + def main(argv): loglevels = [logging.CRITICAL, logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG] parser = argparse.ArgumentParser(argv) @@ -122,5 +122,6 @@ def main(argv): port.close() sys.exit(2) + if __name__ == "__main__": main(sys.argv) From 8869afda2cf01b23255a0203c9a18aa3b0a67e6b Mon Sep 17 00:00:00 2001 From: smlng Date: Tue, 28 Aug 2018 23:01:33 +0200 Subject: [PATCH 49/90] coap-chat: a simple chat application using gCoAP This application allows to send (small) messages via CoAP to any destination address. To chat locally you may use `ff02::1` to reach neighbouring nodes, or chat directly using unicast addresses. The application provides a distinct shell command `chat` but also brings standard shell commands like `ifconfig` to show a nodes IP addresses. --- coap-chat/Makefile | 29 ++++++++++ coap-chat/README.md | 36 +++++++++++++ coap-chat/coap.c | 127 ++++++++++++++++++++++++++++++++++++++++++++ coap-chat/main.c | 71 +++++++++++++++++++++++++ 4 files changed, 263 insertions(+) create mode 100644 coap-chat/Makefile create mode 100644 coap-chat/README.md create mode 100644 coap-chat/coap.c create mode 100644 coap-chat/main.c diff --git a/coap-chat/Makefile b/coap-chat/Makefile new file mode 100644 index 0000000000..900a1cfa90 --- /dev/null +++ b/coap-chat/Makefile @@ -0,0 +1,29 @@ +# name of your application +APPLICATION = coap_chat + +# 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)/../../RIOT + +USEMODULE += gnrc_netdev_default +USEMODULE += auto_init_gnrc_netif +# Specify the mandatory networking modules +USEMODULE += gnrc_ipv6_default +USEMODULE += gcoap +# Additional networking modules that can be dropped if not needed +USEMODULE += gnrc_icmpv6_echo +# Add also the shell, some shell commands +USEMODULE += shell +USEMODULE += shell_commands + +# 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: +DEVELHELP ?= 0 + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/coap-chat/README.md b/coap-chat/README.md new file mode 100644 index 0000000000..211d65cbcd --- /dev/null +++ b/coap-chat/README.md @@ -0,0 +1,36 @@ +## About + +This application provides a simple command line chat using (g)CoAP as transport. +It allows to send (short) messages to any (IPv6) address reachable by the node. +All messages are sent to and received for a CoAP resource with path `/chat`. + +## Usage + +To send messages use the `chat` shell command, it can be invoked as follows: + +``` +chat +``` + +- **destination:** a reachable IPv6 address, may even be multicast `ff02::1` +- **nickname:** your chat nickname, anything is allowed, but keep it short +- **message:** what ever text you want to share, be brief, size is limited + +The message format is plain text and will be send as *nickname: message*, the +maximum message size is 63 chars - so keep *nickname* and *message* short :) +Please be aware that all CoAP messages are sent as non-confirmable, hence there +is no retransmission in case of packet loss. + +## Notes + +The code base of this application aims for simplicity, thus it only provides +a minimalistic set of functions. An advanced CoAP application can be found in +the [RIOT examples](https://github.com/RIOT-OS/RIOT/tree/master/examples/gcoap). + +The application also ships with a number of standard shell commands, such as +`ifconfig` to allow for network interface configuration. Just type `help` in +the shell to see a full list and description of all available commands. + +By default this application is configured to run as an IPv6 node, i.e. it does +not include any routing or relaying functionality - such needs to be handled +by other nodes. diff --git a/coap-chat/coap.c b/coap-chat/coap.c new file mode 100644 index 0000000000..745ea36912 --- /dev/null +++ b/coap-chat/coap.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2018 HAW Hamburg + * + * 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 applications + * @{ + * + * @file + * @brief coap-chat - CoAP helper functions + * + * @author Sebastian Meiling + * + * @} + */ + +#include +#include +#include +#include + +#include "net/gcoap.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define COAP_CHAT_PATH "/chat" + +static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx); + +/* CoAP resources */ +static const coap_resource_t _resources[] = { + { COAP_CHAT_PATH, COAP_POST, _chat_handler, NULL }, +}; + +static gcoap_listener_t _listener = { + &_resources[0], + sizeof(_resources) / sizeof(_resources[0]), + NULL +}; + +static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) +{ + (void)ctx; + + if (pdu->payload_len > 0) { + printf("\n[ CHAT ] %.*s\n\n", pdu->payload_len, (char *)pdu->payload); + return gcoap_response(pdu, buf, len, COAP_CODE_CHANGED); + } + return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); +} + +static size_t _send(uint8_t *buf, size_t len, char *addr_str) +{ + ipv6_addr_t addr; + sock_udp_ep_t remote; + + remote.family = AF_INET6; + + /* parse for interface */ + int iface = ipv6_addr_split_iface(addr_str); + if (iface == -1) { + if (gnrc_netif_numof() == 1) { + /* assign the single interface found in gnrc_netif_numof() */ + remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid; + } + else { + remote.netif = SOCK_ADDR_ANY_NETIF; + } + } + else { + if (gnrc_netif_get_by_pid(iface) == NULL) { + DEBUG("[CoAP] interface not valid"); + return 0; + } + remote.netif = iface; + } + + /* parse destination address */ + if (ipv6_addr_from_str(&addr, addr_str) == NULL) { + DEBUG("[CoAP] unable to parse destination address"); + return 0; + } + if ((remote.netif == SOCK_ADDR_ANY_NETIF) && ipv6_addr_is_link_local(&addr)) { + DEBUG("[CoAP] must specify interface for link local target"); + return 0; + } + memcpy(&remote.addr.ipv6[0], &addr.u8[0], sizeof(addr.u8)); + + /* parse port */ + remote.port = GCOAP_PORT; + + return gcoap_req_send2(buf, len, &remote, NULL); +} + +int coap_post(char *addr, char *msgbuf, size_t msglen) +{ + assert(msglen < GCOAP_PDU_BUF_SIZE); + + coap_pkt_t pdu; + uint8_t buf[GCOAP_PDU_BUF_SIZE]; + size_t len = 0; + + gcoap_req_init(&pdu, buf, GCOAP_PDU_BUF_SIZE, COAP_POST, COAP_CHAT_PATH); + + memcpy(pdu.payload, msgbuf, msglen); + + len = gcoap_finish(&pdu, msglen, COAP_FORMAT_TEXT); + + DEBUG("[CoAP] coap_post: sending msg ID %u, %u bytes\n", + coap_get_id(&pdu), (unsigned) len); + + if (!_send(buf, len, addr)) { + puts("[CoAP] coap_post: msg send failed"); + return -1; + } + return len; +} + +void coap_init(void) +{ + gcoap_register_listener(&_listener); +} diff --git a/coap-chat/main.c b/coap-chat/main.c new file mode 100644 index 0000000000..b207c2ca8d --- /dev/null +++ b/coap-chat/main.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 HAW Hamburg + * + * 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 applications + * @{ + * + * @file + * @brief coap-chat - Main loop and shell handlers + * + * @author Sebastian Meiling + * + * @} + */ + +#include +#include "msg.h" + +#include "net/gcoap.h" +#include "kernel_types.h" +#include "shell.h" + +#define BUFLEN (64U) +#define MAIN_QUEUE_SIZE (4) + +static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; + +extern int coap_post(const char *addr, const char *buf, size_t buflen); +extern void coap_init(void); + +int chat(int argc, char **argv) +{ + if (argc < 4) { + puts("usage: chat "); + return 1; + } + + char buf[BUFLEN] = { 0 }; + size_t len = snprintf(buf, BUFLEN, "%s: %s", argv[2], argv[3]); + for (int i = 4; i < argc; ++i) { + len += snprintf(buf + len, BUFLEN - len, " %s", argv[i]); + } + coap_post(argv[1], buf, len); + + return 0; +} + +static const shell_command_t shell_commands[] = { + { "chat", "CoAP chat", chat }, + { NULL, NULL, NULL } +}; + +int main(void) +{ + /* for the thread running the shell */ + msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); + /* init coap listener */ + coap_init(); + /* start shell */ + puts("All up, running the shell now"); + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + + /* should never be reached */ + return 0; +} From 025e103c37640de72771011686e2f9093109c7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Tue, 16 Oct 2018 19:15:42 +0200 Subject: [PATCH 50/90] spectrum-scanner: Plotting rewrite --- spectrum-scanner/tools/plot_rssi.py | 120 ++++++++++++++++------------ 1 file changed, 67 insertions(+), 53 deletions(-) diff --git a/spectrum-scanner/tools/plot_rssi.py b/spectrum-scanner/tools/plot_rssi.py index e03369801e..83554d6833 100755 --- a/spectrum-scanner/tools/plot_rssi.py +++ b/spectrum-scanner/tools/plot_rssi.py @@ -20,78 +20,84 @@ import re import time import logging import argparse -from serial import Serial +import serial import numpy as np -import matplotlib.pylab as plt +import matplotlib.pyplot as plt +import matplotlib.animation as animation -class rssi_plot(object): +class SpectrumEmitter(object): - def plot_rssi(self, port): - self.count = 0 - self.dt = 0.5 - self.tlen = 120 - # Generate mesh for plotting - Y, X = np.mgrid[slice(0 - .5, 26 + 1.5, 1), slice(0 - self.dt / 2, self.tlen + 1 - self.dt / 2, self.dt)] - Z = np.zeros_like(X) - # X and Y are bounds, so Z should be the value *inside* those bounds. - # Therefore, remove the last value from the Z array. - Z = Z[:, :-1] - logging.debug("Creating figure") - plt.figure() - pcm = plt.pcolormesh(X, Y, Z, vmin=-128, vmax=0, cmap=plt.cm.get_cmap('jet')) - plt.xlim([0, self.tlen]) - plt.ylim([0, 26]) - plt.colorbar(label="Measured signal level [dB]") - plt.ylabel("Channel number") - plt.xlabel("Time [s]") - plt.ion() - logging.debug("Show plot window") - plt.show() - ch_min = 26 - ch_max = 0 - last_update = time.time() + def __init__(self, port): + self.port = port + def data_gen(self): logging.info("Begin collecting data from serial port") while True: - line = port.readline().rstrip() - + # Read one line from the spectrum device + line = self.port.readline().rstrip() pkt_data = re.match(r"\[([-+]?\d+),\s*([-+]?\d+),\s*([-+]?\d+)\]\s*(.*)", line.decode(errors='replace')) if pkt_data: - now = time.time() + ed = {} try: iface_id = int(pkt_data.group(1)) timestamp = int(pkt_data.group(2)) count = int(pkt_data.group(3)) - tidx = int(timestamp / (self.dt * 1000000)) % (Z.shape[1]) except ValueError: + # Incorrect data received, probably UART noise or debugging + # messages from the device, not much else we can do other + # than try again with the next line continue - logging.debug("data: tidx=%d if=%d cnt=%d t=%d", tidx, iface_id, count, timestamp) + logging.debug("data: if=%d cnt=%d t=%d", iface_id, count, timestamp) raw = pkt_data.group(4) - resize = False for ch_ed in raw.split(","): try: pair = ch_ed.split(":") ch = int(pair[0]) - ed = float(pair[1]) - if ch < ch_min: - ch_min = ch - resize = True - if ch > ch_max: - ch_max = ch - resize = True - Z[ch, tidx] = ed + ed[ch] = float(pair[1]) except (ValueError, IndexError): continue - if resize: - logging.debug("resize: %d %d" % (ch_min, ch_max)) - plt.ylim([ch_min - .5, ch_max + .5]) - if now > last_update + 1: - last_update = now - pcm.set_array(Z.ravel()) - pcm.autoscale() - pcm.changed() - plt.pause(0.01) + yield ed + +class RSSIPlot(object): + + def __init__(self, ax, *args, tlen=120, dt=0.5, nchannels=27): + self.ax = ax + self.count = 0 + self.dt = dt + self.tlen = tlen + # Generate mesh for plotting, this creates a grid of nchannel rows and + # (tlen / dt) columns + self.Y, self.X = np.mgrid[slice(0 - .5, nchannels + 0.5, 1), slice(-self.tlen - self.dt / 2, 0 + 1 - self.dt / 2, self.dt)] + Z = np.zeros_like(self.X) + # X and Y are the bounds, so Z should be the value *inside* those bounds. + # Therefore, remove the last row and column from the Z array. + self.Z = Z[:-1, :-1] + self.pcm = self.ax.pcolormesh(self.X, self.Y, self.Z, vmin=-128, vmax=0, cmap=plt.cm.get_cmap('jet')) + self.ax.get_figure().colorbar(self.pcm, label="Measured signal level [dB]") + self.ax.set_ylabel("Channel number") + self.ax.set_xlabel("Time [s]") + self.ch_min = nchannels + self.ch_max = 0 + + def update(self, ed): + resize = False + for ch in ed.keys(): + if ch < self.ch_min: + self.ch_min = ch + resize = True + if ch > self.ch_max: + self.ch_max = ch + resize = True + col = np.zeros((self.Z.shape[0], 1)) + for ch in ed.keys(): + col[ch, 0] = ed[ch] + self.Z = np.hstack((self.Z[:, 1:], col)) + if resize: + self.ax.set_ylim([self.ch_min - .5, self.ch_max + 0.5]) + self.ax.set_yticks(range(self.ch_min, self.ch_max + 1)) + self.pcm.set_array(self.Z.ravel()) + return self.pcm, def main(argv): @@ -110,14 +116,22 @@ def main(argv): # open serial port try: logging.debug("Open serial port %s, baud=%d", args.tty, args.baudrate) - port = Serial(args.tty, args.baudrate, dsrdtr=0, rtscts=0, timeout=0.3) + port = serial.Serial(port=args.tty, baudrate=9600, dsrdtr=0, rtscts=0, timeout=0.3) + # This baudrate reconfiguration is necessary for certain USB to serial + # adapters, the Linux cdc_acm driver will keep repeating stale buffer + # contents otherwise. No idea about the cause, but this fixes the symptom. + port.baudrate = args.baudrate except IOError: logging.critical("error opening serial port", file=sys.stderr) sys.exit(2) try: - app = rssi_plot() - app.plot_rssi(port) + logging.debug("Creating figure") + fig, ax = plt.subplots() + graph = RSSIPlot(ax) + emitter = SpectrumEmitter(port) + ani = animation.FuncAnimation(fig, graph.update, emitter.data_gen, interval=10, blit=True) + plt.show() except KeyboardInterrupt: port.close() sys.exit(2) From ead0b1ab8967fca865f77360da5514e79cbca1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Thu, 18 Oct 2018 09:06:34 +0200 Subject: [PATCH 51/90] spectrum-scanner: Shrink plot Z limits Make differences in ED level more visible. --- spectrum-scanner/tools/plot_rssi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spectrum-scanner/tools/plot_rssi.py b/spectrum-scanner/tools/plot_rssi.py index 83554d6833..6588bb0bd5 100755 --- a/spectrum-scanner/tools/plot_rssi.py +++ b/spectrum-scanner/tools/plot_rssi.py @@ -73,7 +73,7 @@ class RSSIPlot(object): # X and Y are the bounds, so Z should be the value *inside* those bounds. # Therefore, remove the last row and column from the Z array. self.Z = Z[:-1, :-1] - self.pcm = self.ax.pcolormesh(self.X, self.Y, self.Z, vmin=-128, vmax=0, cmap=plt.cm.get_cmap('jet')) + self.pcm = self.ax.pcolormesh(self.X, self.Y, self.Z, vmin=-100, vmax=-20, cmap=plt.cm.get_cmap('jet')) self.ax.get_figure().colorbar(self.pcm, label="Measured signal level [dB]") self.ax.set_ylabel("Channel number") self.ax.set_xlabel("Time [s]") From 4ab673ca746900ff9e38dcf066658072e997ceb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nohlg=C3=A5rd?= Date: Sat, 27 Oct 2018 00:00:38 +0200 Subject: [PATCH 52/90] sniffer: Check for missing netif header in dump_pkt Avoids a hard fault when using the latest RIOT master where raw mode does not provide a netif header. --- sniffer/main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sniffer/main.c b/sniffer/main.c index 189a660249..0846c9819b 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -55,10 +55,14 @@ static char rawdmp_stack[THREAD_STACKSIZE_SMALL]; void dump_pkt(gnrc_pktsnip_t *pkt) { gnrc_pktsnip_t *snip = pkt; - gnrc_netif_hdr_t *netif_hdr = pkt->next->data; - uint8_t lqi = netif_hdr->lqi; - - pkt = gnrc_pktbuf_remove_snip(pkt, pkt->next); + uint8_t lqi = 0; + if (pkt->next) { + if (pkt->next->type == GNRC_NETTYPE_NETIF) { + gnrc_netif_hdr_t *netif_hdr = pkt->next->data; + lqi = netif_hdr->lqi; + pkt = gnrc_pktbuf_remove_snip(pkt, pkt->next); + } + } uint64_t now_us = xtimer_usec_from_ticks64(xtimer_now64()); print_str("rftest-rx --- len "); From 2138b0145718d4cb1cf09b60a1aa0089dce89fa6 Mon Sep 17 00:00:00 2001 From: smlng Date: Tue, 2 Oct 2018 14:28:04 +0200 Subject: [PATCH 53/90] add RIOT as a submodule The RIOT submodule is intended to be fixed to lastest release, in this initial state that is 2018.10. The idea is to make sure all applications compile and run with that release and the submodule is later on updated by the RIOT release manager as part of the release process. --- .gitmodules | 3 +++ RIOT | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 RIOT diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..9048042c0a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "RIOT"] + path = RIOT + url = https://github.com/RIOT-OS/RIOT diff --git a/RIOT b/RIOT new file mode 160000 index 0000000000..6ab5f15466 --- /dev/null +++ b/RIOT @@ -0,0 +1 @@ +Subproject commit 6ab5f15466370b6f57e023afa31fca57598af4b8 From 71ab8470869216a296ebdffff6ded02785904b48 Mon Sep 17 00:00:00 2001 From: smlng Date: Tue, 2 Oct 2018 14:31:19 +0200 Subject: [PATCH 54/90] adapt RIOTBASE to use submodule path --- coap-chat/Makefile | 2 +- sniffer/Makefile | 2 +- spectrum-scanner/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coap-chat/Makefile b/coap-chat/Makefile index 900a1cfa90..5fb8fb137f 100644 --- a/coap-chat/Makefile +++ b/coap-chat/Makefile @@ -5,7 +5,7 @@ APPLICATION = coap_chat BOARD ?= native # This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../../RIOT +RIOTBASE ?= $(CURDIR)/../RIOT USEMODULE += gnrc_netdev_default USEMODULE += auto_init_gnrc_netif diff --git a/sniffer/Makefile b/sniffer/Makefile index 01e46cb67b..037df6f670 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -5,7 +5,7 @@ APPLICATION = sniffer BOARD ?= native # This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../../RIOT +RIOTBASE ?= $(CURDIR)/../RIOT # Define modules that are used USEMODULE += fmt diff --git a/spectrum-scanner/Makefile b/spectrum-scanner/Makefile index f6b3db6754..df7e61c575 100644 --- a/spectrum-scanner/Makefile +++ b/spectrum-scanner/Makefile @@ -5,7 +5,7 @@ APPLICATION = spectrum-scanner BOARD ?= samr21-xpro # This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../../RIOT +RIOTBASE ?= $(CURDIR)/../RIOT # Define modules that are used USEMODULE += gnrc From 0d6300037761cc677c3d622f01526f2659893545 Mon Sep 17 00:00:00 2001 From: smlng Date: Tue, 2 Oct 2018 14:32:41 +0200 Subject: [PATCH 55/90] initial travis.yml --- .travis.yml | 12 ++++++++++++ RIOT | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..e67e602c51 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +sudo: required + +language: minimal + +before_install: + - sudo apt-get install coreutils cppcheck pcregrep python3 python3-pip uncrustify + - sudo pip3 install flake8 + +script: + - ./RIOT/dist/tools/whitespacecheck/check.sh + - find . -path ./RIOT -prune -o -name *.py -exec python3 -m flake8 --config=./RIOT/dist/tools/flake8/flake8.cfg {} + + - find . -path ./RIOT -prune -o \( -name *.c -o -name *.h \) -exec cppcheck --std=c99 --enable=style --force --error-exitcode=2 --quiet -j 1 {} + diff --git a/RIOT b/RIOT index 6ab5f15466..bb6bedd708 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit 6ab5f15466370b6f57e023afa31fca57598af4b8 +Subproject commit bb6bedd708bbccc16d4a0cd9750f56efcd5f9244 From b2034520c5c0bcadd41c87f5c9ea3583c460215b Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 8 Jan 2019 10:17:51 +0100 Subject: [PATCH 56/90] Revert submodule change of #48 --- RIOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIOT b/RIOT index bb6bedd708..6ab5f15466 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit bb6bedd708bbccc16d4a0cd9750f56efcd5f9244 +Subproject commit 6ab5f15466370b6f57e023afa31fca57598af4b8 From 7a771c200c4ac9838bac40916e01b2696ceecfdc Mon Sep 17 00:00:00 2001 From: Sebastian Meiling Date: Wed, 9 Jan 2019 08:50:16 +0100 Subject: [PATCH 57/90] add missing LICENSE --- LICENSE | 504 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..8000a6faac --- /dev/null +++ b/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random + Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! From 53e91a13e360ac2426ffdf8b37602f83e240b9fb Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Fri, 15 Feb 2019 19:08:35 +0100 Subject: [PATCH 58/90] Update RIOT submodule to 2019.01 --- RIOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIOT b/RIOT index 6ab5f15466..9876e93b6b 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit 6ab5f15466370b6f57e023afa31fca57598af4b8 +Subproject commit 9876e93b6b601411e0bf40e68e109f67100a284c From 1ee703aa27e696f8f0b3dccca0268a133a548462 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 30 Apr 2019 11:59:37 +0200 Subject: [PATCH 59/90] RIOT: update submodule to 2019.04 --- RIOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIOT b/RIOT index 9876e93b6b..7a28e1c6d8 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit 9876e93b6b601411e0bf40e68e109f67100a284c +Subproject commit 7a28e1c6d8813606855ea5fb9943233c5bd3d568 From 96a894bacb65187708158497ed6edb9550b9f1d3 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 8 Jan 2019 10:41:34 +0100 Subject: [PATCH 60/90] Provide README --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..5909c83ddf --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +[![Build Status](https://travis-ci.org/RIOT-OS/applications.svg?branch=master)](https://travis-ci.org/RIOT-OS/applications) + +# RIOT Applications + +This repository provides more applications for the [RIOT operating system][riot-repo]. +Some of them are just useful tools for development work, others showcase +more extensive implementations of features of RIOT compared to the rather simple +[examples in the RIOT main codebase][riot-repo/examples]. + +## Usage + +To build and use them follow [the instructions in the RIOT repository][getting-started] +and the READMEs within the respective application directory. + +The RIOT main code is included as a submodule. This always points to the latest +release. To change the RIOT version to build against (e.g. current master), +clone the RIOT repository in a separate repository and point the `RIOTBASE` +environment variable there: + +```sh +# assuming you are in the working directory of your local clone of this repo +cd .. +git clone git@github.com:RIOT-OS/RIOT.git +cd applications +RIOTBASE="../RIOT" BOARD=samr21-xpro make -C sniffer flash +``` + +Alternatively, you can step into the submodule and check out the current master: + +```sh +cd RIOT +git checkout master +git pull +``` + +Note that there is no guarantee that it will build or work, since we only test +this repository against the latest release. + +[riot-repo]: https://github.com/RIOT-OS/RIOT +[riot-repo/examples]: https://github.com/RIOT-OS/RIOT/tree/master/examples +[getting-started]: https://github.com/RIOT-OS/RIOT/blob/master/README.md#getting-started From 4be4e20cbb35387b1c5e0f80db605df1c6e58b5b Mon Sep 17 00:00:00 2001 From: Ken Bannister Date: Tue, 24 Dec 2019 09:27:41 -0500 Subject: [PATCH 61/90] sniffer: remove obsolete reference to RIOTBASE --- sniffer/tools/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/tools/README.md b/sniffer/tools/README.md index 6b51a21488..56ca694485 100644 --- a/sniffer/tools/README.md +++ b/sniffer/tools/README.md @@ -40,7 +40,7 @@ General usage: ``` $ git clone https://github.com/RIOT-OS/applications/ $ cd applications/sniffer -$ RIOTBASE= BOARD= make clean all flash +$ BOARD= make clean all flash ``` 2. Run the `sniffer.py` script (change to subfolder `tools/`) as follows : From d78501d3052e331ac6b0ee57e8891a1c52eeab70 Mon Sep 17 00:00:00 2001 From: Sebastian Meiling Date: Thu, 28 Nov 2019 13:25:20 +0100 Subject: [PATCH 62/90] spectrum-scanner: fix flake8 issues --- spectrum-scanner/tools/plot_rssi.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spectrum-scanner/tools/plot_rssi.py b/spectrum-scanner/tools/plot_rssi.py index 6588bb0bd5..bf3fa2db9a 100755 --- a/spectrum-scanner/tools/plot_rssi.py +++ b/spectrum-scanner/tools/plot_rssi.py @@ -17,7 +17,6 @@ import sys import re -import time import logging import argparse import serial @@ -59,6 +58,7 @@ class SpectrumEmitter(object): continue yield ed + class RSSIPlot(object): def __init__(self, ax, *args, tlen=120, dt=0.5, nchannels=27): @@ -68,7 +68,8 @@ class RSSIPlot(object): self.tlen = tlen # Generate mesh for plotting, this creates a grid of nchannel rows and # (tlen / dt) columns - self.Y, self.X = np.mgrid[slice(0 - .5, nchannels + 0.5, 1), slice(-self.tlen - self.dt / 2, 0 + 1 - self.dt / 2, self.dt)] + self.Y, self.X = np.mgrid[slice(0 - .5, nchannels + 0.5, 1), + slice(-self.tlen - self.dt / 2, 0 + 1 - self.dt / 2, self.dt)] Z = np.zeros_like(self.X) # X and Y are the bounds, so Z should be the value *inside* those bounds. # Therefore, remove the last row and column from the Z array. @@ -130,7 +131,7 @@ def main(argv): fig, ax = plt.subplots() graph = RSSIPlot(ax) emitter = SpectrumEmitter(port) - ani = animation.FuncAnimation(fig, graph.update, emitter.data_gen, interval=10, blit=True) + animation.FuncAnimation(fig, graph.update, emitter.data_gen, interval=10, blit=True) plt.show() except KeyboardInterrupt: port.close() From 1b993970ed09aeb15cb582baff70e346fd10fa8d Mon Sep 17 00:00:00 2001 From: Ken Bannister Date: Tue, 24 Dec 2019 11:02:58 -0500 Subject: [PATCH 63/90] sniffer: add output example --- sniffer/tools/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sniffer/tools/README.md b/sniffer/tools/README.md index 56ca694485..7a8b2310f9 100644 --- a/sniffer/tools/README.md +++ b/sniffer/tools/README.md @@ -53,6 +53,14 @@ For network socket: $ ./sniffer.py : [outfile] ``` +You should see output like below: +``` +ifconfig 3 set chan 26 +ifconfig 3 raw +ifconfig 3 promisc +RX: 0 +``` + For detailed information on the parameters use the scripts on-line help: ``` From 6ca3a170cc58a7f46e78669aa6bcdb81af51e5ea Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Fri, 12 Apr 2019 11:40:39 +0200 Subject: [PATCH 64/90] travis: notify maintainers via mail about builds --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index e67e602c51..7b96e54911 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,13 @@ before_install: - sudo apt-get install coreutils cppcheck pcregrep python3 python3-pip uncrustify - sudo pip3 install flake8 +notifications: + email: + recipients: + - maintainer@riot-os.org + on_success: change + on_failure: always + script: - ./RIOT/dist/tools/whitespacecheck/check.sh - find . -path ./RIOT -prune -o -name *.py -exec python3 -m flake8 --config=./RIOT/dist/tools/flake8/flake8.cfg {} + From f31eb2f5b26305c90a195a4f5d4d960741a73545 Mon Sep 17 00:00:00 2001 From: Ken Bannister Date: Tue, 24 Dec 2019 09:31:41 -0500 Subject: [PATCH 65/90] sniffer: formatting and syntax updates --- sniffer/README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sniffer/README.md b/sniffer/README.md index 4bdd5d70f5..8a93f109b9 100644 --- a/sniffer/README.md +++ b/sniffer/README.md @@ -1,12 +1,22 @@ About ===== -This application is build to run together with the script `./tools/sniffer.py` as sniffer for (wireless) data traffic. This application works with any board with any network device that supports the gnrc network stack (or precisely the gnrc parts up to the link-layer). Further the network device (and it's driver) needs to support promiscuous and raw mode for usable output. Finally the board needs to include auto-initialization code for the targeted network device. +This application is built to run together with the script `./tools/sniffer.py` +as a sniffer for (wireless) data traffic. This application works with any board +with any network device that supports the gnrc network stack (or precisely the +gnrc parts up to the link-layer). Further the network device (and its driver) +needs to support promiscuous and raw mode for usable output. Finally the board +needs to include auto-initialization code for the targeted network device. Usage ===== -Compile and flash this application to the board of your choice. You can check if everything on the RIOT side works by connecting to the board via UART and by checking with `ifconfig` if a network device is available. Further you can check with `ifconfig 4 promisc` if promiscuous mode is supported and with `ifconfig 4 raw` if raw mode is supported by the driver/network device. +Compile and flash this application to the board of your choice. You can check +if everything on the RIOT side works by connecting to the board via UART and by +checking with `ifconfig` if a network device is available. Further you can +check with `ifconfig 4 promisc` if promiscuous mode is supported and with +`ifconfig 4 raw` if raw mode is supported by the driver/network device. -For further information on setting up the host part, see `RIOTBASE/dist/tools/sniffer/README.md`. +For further information on setting up the host part, see +`RIOTBASE/dist/tools/sniffer/README.md`. From 190e5924ed05065d1e75aba15d40dd1011f801c6 Mon Sep 17 00:00:00 2001 From: Ken Bannister Date: Tue, 24 Dec 2019 06:20:06 -0500 Subject: [PATCH 66/90] RIOT: update submodule to 2019.10 --- RIOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIOT b/RIOT index 7a28e1c6d8..1b9ec8eef7 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit 7a28e1c6d8813606855ea5fb9943233c5bd3d568 +Subproject commit 1b9ec8eef77af116b7c1b6aaf00b044a29345811 From 5955c6f2294ad519fd52f4dc7e0501a86928e752 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Wed, 5 Feb 2020 10:04:18 +0100 Subject: [PATCH 67/90] RIOT: bump version to 2020.01 --- RIOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIOT b/RIOT index 1b9ec8eef7..8735f8176a 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit 1b9ec8eef77af116b7c1b6aaf00b044a29345811 +Subproject commit 8735f8176a84446bc15a6df33331b5ee0129df1f From bb9aa60ece8d015d1073eb1b602ab800899ea9e7 Mon Sep 17 00:00:00 2001 From: Ken Bannister Date: Tue, 24 Dec 2019 09:33:53 -0500 Subject: [PATCH 68/90] sniffer: fix references to board network interface --- sniffer/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sniffer/README.md b/sniffer/README.md index 8a93f109b9..41e5e494d4 100644 --- a/sniffer/README.md +++ b/sniffer/README.md @@ -14,9 +14,10 @@ Usage Compile and flash this application to the board of your choice. You can check if everything on the RIOT side works by connecting to the board via UART and by -checking with `ifconfig` if a network device is available. Further you can -check with `ifconfig 4 promisc` if promiscuous mode is supported and with -`ifconfig 4 raw` if raw mode is supported by the driver/network device. +checking with `ifconfig` if a network device is available. Also note the +interface number for the following commands. Then you can check with +`ifconfig promisc` if promiscuous mode is supported and with +`ifconfig raw` if raw mode is supported by the driver/network device. For further information on setting up the host part, see `RIOTBASE/dist/tools/sniffer/README.md`. From 8dd36cf57a202125518028a43a344083e1aca852 Mon Sep 17 00:00:00 2001 From: Ken Bannister Date: Tue, 24 Dec 2019 09:04:22 -0500 Subject: [PATCH 69/90] coap-chat: update for gcoap change in 2019.10 release --- coap-chat/coap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coap-chat/coap.c b/coap-chat/coap.c index 745ea36912..f2b4729c14 100644 --- a/coap-chat/coap.c +++ b/coap-chat/coap.c @@ -40,6 +40,7 @@ static const coap_resource_t _resources[] = { static gcoap_listener_t _listener = { &_resources[0], sizeof(_resources) / sizeof(_resources[0]), + NULL, NULL }; From 5a0a37a29da2de78ed50ca7fed268b4c1e43bea5 Mon Sep 17 00:00:00 2001 From: Akshai M Date: Tue, 6 Sep 2022 10:11:10 +0200 Subject: [PATCH 70/90] RIOT-OS Submodule : Update to 2022.07 release --- RIOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIOT b/RIOT index 398a066552..81a01df5d9 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit 398a06655298a8c705f2bc35aab6703b2c50debd +Subproject commit 81a01df5d94729b8d8a2be7ce8e68f9fc7c7b95f From 33024b46b21c94b031dd3fd72ca9897b225ebbc0 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Mon, 27 Jul 2020 13:15:51 +0200 Subject: [PATCH 71/90] RIOT: update for 2020.07 --- RIOT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIOT b/RIOT index 8735f8176a..398a066552 160000 --- a/RIOT +++ b/RIOT @@ -1 +1 @@ -Subproject commit 8735f8176a84446bc15a6df33331b5ee0129df1f +Subproject commit 398a06655298a8c705f2bc35aab6703b2c50debd From e0e2e400df8e9e11fa4cc03afae13f3cee3f0e69 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Wed, 5 Feb 2020 10:04:35 +0100 Subject: [PATCH 72/90] README: fix submodule initialization --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5909c83ddf..e5c6ac6e92 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,15 @@ cd applications RIOTBASE="../RIOT" BOARD=samr21-xpro make -C sniffer flash ``` -Alternatively, you can step into the submodule and check out the current master: +Alternatively you can use RIOT as a submodule. To initialize the submodule, from the +root of the repository run: + +```sh +git submodule update --init --recursive +``` + +If you want to use master then simply step into the submodule and checkout master or +any other desired branch. ```sh cd RIOT From 818eb2d4e6fe2ed1ecfd74b3134316f7a520460e Mon Sep 17 00:00:00 2001 From: Ken Bannister Date: Tue, 24 Dec 2019 11:14:52 -0500 Subject: [PATCH 73/90] sniffer: fix reference to sniffer tool README --- sniffer/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sniffer/README.md b/sniffer/README.md index 41e5e494d4..14dbe0c9df 100644 --- a/sniffer/README.md +++ b/sniffer/README.md @@ -19,5 +19,4 @@ interface number for the following commands. Then you can check with `ifconfig promisc` if promiscuous mode is supported and with `ifconfig raw` if raw mode is supported by the driver/network device. -For further information on setting up the host part, see -`RIOTBASE/dist/tools/sniffer/README.md`. +For further information on setting up the host part, see `./tools/README.md`. From 8f8db4fb212c5db37df4adc732b7197d6987f305 Mon Sep 17 00:00:00 2001 From: chrysn Date: Fri, 16 Sep 2022 11:58:32 +0200 Subject: [PATCH 74/90] coap-chat: Update to 2022.07 release The signature changed; no need for changes in code as the context argument is discarded anyway. --- coap-chat/coap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coap-chat/coap.c b/coap-chat/coap.c index 20de02979e..a404eb8daa 100644 --- a/coap-chat/coap.c +++ b/coap-chat/coap.c @@ -30,7 +30,7 @@ #define COAP_CHAT_PATH "/chat" -static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx); +static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx); /* CoAP resources */ static const coap_resource_t _resources[] = { @@ -43,7 +43,7 @@ static gcoap_listener_t _listener = { .next = NULL, }; -static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) +static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx) { (void)ctx; From 5b050d8921b7680b9e6be64630328bcd37ca0103 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Mon, 27 Jul 2020 13:17:56 +0200 Subject: [PATCH 75/90] coap-chat: adapt for 2020.07 release --- coap-chat/coap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/coap-chat/coap.c b/coap-chat/coap.c index ac3af71199..ad18a41656 100644 --- a/coap-chat/coap.c +++ b/coap-chat/coap.c @@ -93,20 +93,21 @@ static size_t _send(uint8_t *buf, size_t len, char *addr_str) memcpy(&remote.addr.ipv6[0], &addr.u8[0], sizeof(addr.u8)); /* parse port */ - remote.port = GCOAP_PORT; + remote.port = CONFIG_GCOAP_PORT; return gcoap_req_send(buf, len, &remote, NULL, NULL); } int coap_post(char *addr, char *msgbuf, size_t msglen) { - assert(msglen < GCOAP_PDU_BUF_SIZE); + assert(msglen < CONFIG_GCOAP_PDU_BUF_SIZE); coap_pkt_t pdu; - uint8_t buf[GCOAP_PDU_BUF_SIZE]; + uint8_t buf[CONFIG_GCOAP_PDU_BUF_SIZE]; size_t len = 0; - gcoap_req_init(&pdu, buf, GCOAP_PDU_BUF_SIZE, COAP_POST, COAP_CHAT_PATH); + gcoap_req_init(&pdu, buf, CONFIG_GCOAP_PDU_BUF_SIZE, + COAP_POST, COAP_CHAT_PATH); memcpy(pdu.payload, msgbuf, msglen); From b0307a432dbb398b8abf8770c7f1df9e75e3e108 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Wed, 5 Feb 2020 10:12:07 +0100 Subject: [PATCH 76/90] coap-chat/coap.c: apply api changes --- coap-chat/coap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/coap-chat/coap.c b/coap-chat/coap.c index f2b4729c14..ac3af71199 100644 --- a/coap-chat/coap.c +++ b/coap-chat/coap.c @@ -63,8 +63,8 @@ static size_t _send(uint8_t *buf, size_t len, char *addr_str) remote.family = AF_INET6; /* parse for interface */ - int iface = ipv6_addr_split_iface(addr_str); - if (iface == -1) { + char *iface = ipv6_addr_split_iface(addr_str); + if (!iface) { if (gnrc_netif_numof() == 1) { /* assign the single interface found in gnrc_netif_numof() */ remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid; @@ -74,11 +74,11 @@ static size_t _send(uint8_t *buf, size_t len, char *addr_str) } } else { - if (gnrc_netif_get_by_pid(iface) == NULL) { + if (gnrc_netif_get_by_pid(atoi(iface)) == NULL) { DEBUG("[CoAP] interface not valid"); return 0; } - remote.netif = iface; + remote.netif = atoi(iface); } /* parse destination address */ @@ -95,7 +95,7 @@ static size_t _send(uint8_t *buf, size_t len, char *addr_str) /* parse port */ remote.port = GCOAP_PORT; - return gcoap_req_send2(buf, len, &remote, NULL); + return gcoap_req_send(buf, len, &remote, NULL, NULL); } int coap_post(char *addr, char *msgbuf, size_t msglen) From bc38fd40bc5e751b9528058a0ba0d19705c00ad6 Mon Sep 17 00:00:00 2001 From: chrysn Date: Fri, 16 Sep 2022 12:05:43 +0200 Subject: [PATCH 77/90] spectrum-scanner: Update to 2022.07 release The ztimer64_xtimer_compat module is not automatically enabled when ztimer provides xtimer compatibility. --- spectrum-scanner/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/spectrum-scanner/Makefile b/spectrum-scanner/Makefile index df7e61c575..37a3ddf3dd 100644 --- a/spectrum-scanner/Makefile +++ b/spectrum-scanner/Makefile @@ -12,6 +12,7 @@ USEMODULE += gnrc USEMODULE += gnrc_netdev_default USEMODULE += auto_init_gnrc_netif USEMODULE += xtimer +USEMODULE += ztimer64_xtimer_compat USEMODULE += fmt # Change this to 0 show compiler invocation lines by default: From 0fb6a17dd0e0d40fdb7ff00c25445bd5d8c7b5fa Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Mon, 27 Jul 2020 13:31:10 +0200 Subject: [PATCH 78/90] spectrum-scanner: adapt for 2020.07 release --- spectrum-scanner/main.c | 2 +- spectrum-scanner/tools/plot_rssi.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spectrum-scanner/main.c b/spectrum-scanner/main.c index 412ccfd509..c95cd8dc7a 100644 --- a/spectrum-scanner/main.c +++ b/spectrum-scanner/main.c @@ -73,7 +73,7 @@ void spectrum_scanner(unsigned long interval_us) while (1) { /* Stack optimization, statically allocate this buffer */ - static float ed_average[GNRC_NETIF_NUMOF][IEEE802154_CHANNEL_MAX + 1]; + float ed_average[netif_numof][IEEE802154_CHANNEL_MAX + 1]; memset(ed_average, 0, sizeof(ed_average)); diff --git a/spectrum-scanner/tools/plot_rssi.py b/spectrum-scanner/tools/plot_rssi.py index bf3fa2db9a..4850d580e2 100755 --- a/spectrum-scanner/tools/plot_rssi.py +++ b/spectrum-scanner/tools/plot_rssi.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2017 Eistec AB # From 25a5151dc4f4bfaee72c2bd0838dc7aebeb76b1f Mon Sep 17 00:00:00 2001 From: chrysn Date: Fri, 16 Sep 2022 12:26:34 +0200 Subject: [PATCH 79/90] sniffer: Update to 2022.07 release The ztimer64_xtimer_compat module is not automatically enabled when ztimer provides xtimer compatibility. It does not provide the xtimer_usec_from_ticks64 function, but that was not particularly used anyway. A header file became unavailable but was not needed. --- sniffer/Makefile | 1 + sniffer/main.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sniffer/Makefile b/sniffer/Makefile index 037df6f670..7c2e39ace4 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -16,6 +16,7 @@ USEMODULE += shell USEMODULE += shell_commands USEMODULE += ps USEMODULE += xtimer +USEMODULE += ztimer64_xtimer_compat # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 diff --git a/sniffer/main.c b/sniffer/main.c index 0846c9819b..3f48a3b63a 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -26,7 +26,6 @@ #include "thread.h" #include "xtimer.h" #include "shell.h" -#include "shell_commands.h" #include "net/gnrc.h" /** @@ -63,14 +62,14 @@ void dump_pkt(gnrc_pktsnip_t *pkt) pkt = gnrc_pktbuf_remove_snip(pkt, pkt->next); } } - uint64_t now_us = xtimer_usec_from_ticks64(xtimer_now64()); + uint64_t now = xtimer_now64(); print_str("rftest-rx --- len "); print_u32_hex((uint32_t)gnrc_pkt_len(pkt)); print_str(" lqi "); print_byte_hex(lqi); print_str(" rx_time "); - print_u64_hex(now_us); + print_u64_hex(now); print_str("\n"); while (snip) { for (size_t i = 0; i < snip->size; i++) { From 9d17a74df83bd7cd340652182bfed98f1c20eb56 Mon Sep 17 00:00:00 2001 From: Leandro Lanzieri Date: Thu, 4 Feb 2021 17:10:25 +0100 Subject: [PATCH 80/90] coap-chat: adapt to new gcoap API --- coap-chat/coap.c | 19 +++++++++++++------ coap-chat/main.c | 1 - 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/coap-chat/coap.c b/coap-chat/coap.c index ad18a41656..20de02979e 100644 --- a/coap-chat/coap.c +++ b/coap-chat/coap.c @@ -38,10 +38,9 @@ static const coap_resource_t _resources[] = { }; static gcoap_listener_t _listener = { - &_resources[0], - sizeof(_resources) / sizeof(_resources[0]), - NULL, - NULL + .resources = &_resources[0], + .resources_len = sizeof(_resources) / sizeof(_resources[0]), + .next = NULL, }; static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) @@ -109,9 +108,17 @@ int coap_post(char *addr, char *msgbuf, size_t msglen) gcoap_req_init(&pdu, buf, CONFIG_GCOAP_PDU_BUF_SIZE, COAP_POST, COAP_CHAT_PATH); - memcpy(pdu.payload, msgbuf, msglen); + coap_opt_add_format(&pdu, COAP_FORMAT_TEXT); + len = coap_opt_finish(&pdu, COAP_OPT_FINISH_PAYLOAD); - len = gcoap_finish(&pdu, msglen, COAP_FORMAT_TEXT); + if (pdu.payload_len >= msglen) { + memcpy(pdu.payload, msgbuf, msglen); + len += msglen; + } + else { + DEBUG("[CoAP] coap_post: ERROR. The message buffer is too small for the message\n"); + return -1; + } DEBUG("[CoAP] coap_post: sending msg ID %u, %u bytes\n", coap_get_id(&pdu), (unsigned) len); diff --git a/coap-chat/main.c b/coap-chat/main.c index b207c2ca8d..9aa3e24dee 100644 --- a/coap-chat/main.c +++ b/coap-chat/main.c @@ -22,7 +22,6 @@ #include "msg.h" #include "net/gcoap.h" -#include "kernel_types.h" #include "shell.h" #define BUFLEN (64U) From dda61ca78e2cc09ff924cdac6641d0b27b7764eb Mon Sep 17 00:00:00 2001 From: chrysn Date: Mon, 19 Sep 2022 14:46:58 +0200 Subject: [PATCH 81/90] dependencies: Replace deprecated module --- coap-chat/Makefile | 2 +- sniffer/Makefile | 2 +- spectrum-scanner/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coap-chat/Makefile b/coap-chat/Makefile index 5fb8fb137f..6ef5dd1421 100644 --- a/coap-chat/Makefile +++ b/coap-chat/Makefile @@ -7,7 +7,7 @@ BOARD ?= native # This has to be the absolute path to the RIOT base directory: RIOTBASE ?= $(CURDIR)/../RIOT -USEMODULE += gnrc_netdev_default +USEMODULE += netdev_default USEMODULE += auto_init_gnrc_netif # Specify the mandatory networking modules USEMODULE += gnrc_ipv6_default diff --git a/sniffer/Makefile b/sniffer/Makefile index 7c2e39ace4..a7f6d0e4de 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -10,7 +10,7 @@ RIOTBASE ?= $(CURDIR)/../RIOT # Define modules that are used USEMODULE += fmt USEMODULE += gnrc -USEMODULE += gnrc_netdev_default +USEMODULE += netdev_default USEMODULE += auto_init_gnrc_netif USEMODULE += shell USEMODULE += shell_commands diff --git a/spectrum-scanner/Makefile b/spectrum-scanner/Makefile index 37a3ddf3dd..ce598495eb 100644 --- a/spectrum-scanner/Makefile +++ b/spectrum-scanner/Makefile @@ -9,7 +9,7 @@ RIOTBASE ?= $(CURDIR)/../RIOT # Define modules that are used USEMODULE += gnrc -USEMODULE += gnrc_netdev_default +USEMODULE += netdev_default USEMODULE += auto_init_gnrc_netif USEMODULE += xtimer USEMODULE += ztimer64_xtimer_compat From b4f4173553974841182bdab1437a8e8ff8d22263 Mon Sep 17 00:00:00 2001 From: Akshai M Date: Mon, 22 Mar 2021 16:46:56 +0100 Subject: [PATCH 82/90] travis: Remove flak8 --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b96e54911..0c8adc3911 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ language: minimal before_install: - sudo apt-get install coreutils cppcheck pcregrep python3 python3-pip uncrustify - - sudo pip3 install flake8 notifications: email: @@ -15,5 +14,4 @@ notifications: script: - ./RIOT/dist/tools/whitespacecheck/check.sh - - find . -path ./RIOT -prune -o -name *.py -exec python3 -m flake8 --config=./RIOT/dist/tools/flake8/flake8.cfg {} + - find . -path ./RIOT -prune -o \( -name *.c -o -name *.h \) -exec cppcheck --std=c99 --enable=style --force --error-exitcode=2 --quiet -j 1 {} + From ef9b3a029d0f8156857ac9160b5d5748ddaf7026 Mon Sep 17 00:00:00 2001 From: chrysn Date: Mon, 19 Sep 2022 15:07:47 +0200 Subject: [PATCH 83/90] sniffer: Migrate to ztimer See-Also: https://github.com/RIOT-OS/applications/pull/78#pullrequestreview-1112206330 --- sniffer/Makefile | 3 +-- sniffer/main.c | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sniffer/Makefile b/sniffer/Makefile index a7f6d0e4de..3368b062bb 100644 --- a/sniffer/Makefile +++ b/sniffer/Makefile @@ -15,8 +15,7 @@ USEMODULE += auto_init_gnrc_netif USEMODULE += shell USEMODULE += shell_commands USEMODULE += ps -USEMODULE += xtimer -USEMODULE += ztimer64_xtimer_compat +USEMODULE += ztimer64_usec # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 diff --git a/sniffer/main.c b/sniffer/main.c index 3f48a3b63a..48314c406c 100644 --- a/sniffer/main.c +++ b/sniffer/main.c @@ -24,9 +24,9 @@ #include "fmt.h" #include "thread.h" -#include "xtimer.h" #include "shell.h" #include "net/gnrc.h" +#include "ztimer64.h" /** * @brief Buffer size used by the shell @@ -62,14 +62,14 @@ void dump_pkt(gnrc_pktsnip_t *pkt) pkt = gnrc_pktbuf_remove_snip(pkt, pkt->next); } } - uint64_t now = xtimer_now64(); + uint64_t now_us = ztimer64_now(ZTIMER64_USEC); print_str("rftest-rx --- len "); print_u32_hex((uint32_t)gnrc_pkt_len(pkt)); print_str(" lqi "); print_byte_hex(lqi); print_str(" rx_time "); - print_u64_hex(now); + print_u64_hex(now_us); print_str("\n"); while (snip) { for (size_t i = 0; i < snip->size; i++) { From 1c187bb82f2f56fa72a09110c4eb5938728b9b2c Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Mon, 19 Sep 2022 16:40:13 +0200 Subject: [PATCH 84/90] sniffer: correct handling of byte strings --- sniffer/tools/sniffer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 98b960017a..8f44868884 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -56,10 +56,10 @@ DEFAULT_BAUDRATE = 115200 def configure_interface(port, channel): line = "" iface = 0 - port.write(b'ifconfig\n') + port.write('ifconfig\n'.encode()) while True: line = port.readline() - if line == '': + if line == b'': print("Application has no network interface defined", file=sys.stderr) sys.exit(2) From eb0ec397cc573bb834b1273145ef1cf9c5e39adc Mon Sep 17 00:00:00 2001 From: chrysn Date: Mon, 19 Sep 2022 16:24:29 +0200 Subject: [PATCH 85/90] Remove "coap-chat" application --- coap-chat/Makefile | 29 ---------- coap-chat/README.md | 36 ------------ coap-chat/coap.c | 136 -------------------------------------------- coap-chat/main.c | 70 ----------------------- 4 files changed, 271 deletions(-) delete mode 100644 coap-chat/Makefile delete mode 100644 coap-chat/README.md delete mode 100644 coap-chat/coap.c delete mode 100644 coap-chat/main.c diff --git a/coap-chat/Makefile b/coap-chat/Makefile deleted file mode 100644 index 6ef5dd1421..0000000000 --- a/coap-chat/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# name of your application -APPLICATION = coap_chat - -# 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)/../RIOT - -USEMODULE += netdev_default -USEMODULE += auto_init_gnrc_netif -# Specify the mandatory networking modules -USEMODULE += gnrc_ipv6_default -USEMODULE += gcoap -# Additional networking modules that can be dropped if not needed -USEMODULE += gnrc_icmpv6_echo -# Add also the shell, some shell commands -USEMODULE += shell -USEMODULE += shell_commands - -# 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: -DEVELHELP ?= 0 - -# Change this to 0 show compiler invocation lines by default: -QUIET ?= 1 - -include $(RIOTBASE)/Makefile.include diff --git a/coap-chat/README.md b/coap-chat/README.md deleted file mode 100644 index 211d65cbcd..0000000000 --- a/coap-chat/README.md +++ /dev/null @@ -1,36 +0,0 @@ -## About - -This application provides a simple command line chat using (g)CoAP as transport. -It allows to send (short) messages to any (IPv6) address reachable by the node. -All messages are sent to and received for a CoAP resource with path `/chat`. - -## Usage - -To send messages use the `chat` shell command, it can be invoked as follows: - -``` -chat -``` - -- **destination:** a reachable IPv6 address, may even be multicast `ff02::1` -- **nickname:** your chat nickname, anything is allowed, but keep it short -- **message:** what ever text you want to share, be brief, size is limited - -The message format is plain text and will be send as *nickname: message*, the -maximum message size is 63 chars - so keep *nickname* and *message* short :) -Please be aware that all CoAP messages are sent as non-confirmable, hence there -is no retransmission in case of packet loss. - -## Notes - -The code base of this application aims for simplicity, thus it only provides -a minimalistic set of functions. An advanced CoAP application can be found in -the [RIOT examples](https://github.com/RIOT-OS/RIOT/tree/master/examples/gcoap). - -The application also ships with a number of standard shell commands, such as -`ifconfig` to allow for network interface configuration. Just type `help` in -the shell to see a full list and description of all available commands. - -By default this application is configured to run as an IPv6 node, i.e. it does -not include any routing or relaying functionality - such needs to be handled -by other nodes. diff --git a/coap-chat/coap.c b/coap-chat/coap.c deleted file mode 100644 index a404eb8daa..0000000000 --- a/coap-chat/coap.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2018 HAW Hamburg - * - * 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 applications - * @{ - * - * @file - * @brief coap-chat - CoAP helper functions - * - * @author Sebastian Meiling - * - * @} - */ - -#include -#include -#include -#include - -#include "net/gcoap.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#define COAP_CHAT_PATH "/chat" - -static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx); - -/* CoAP resources */ -static const coap_resource_t _resources[] = { - { COAP_CHAT_PATH, COAP_POST, _chat_handler, NULL }, -}; - -static gcoap_listener_t _listener = { - .resources = &_resources[0], - .resources_len = sizeof(_resources) / sizeof(_resources[0]), - .next = NULL, -}; - -static ssize_t _chat_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx) -{ - (void)ctx; - - if (pdu->payload_len > 0) { - printf("\n[ CHAT ] %.*s\n\n", pdu->payload_len, (char *)pdu->payload); - return gcoap_response(pdu, buf, len, COAP_CODE_CHANGED); - } - return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST); -} - -static size_t _send(uint8_t *buf, size_t len, char *addr_str) -{ - ipv6_addr_t addr; - sock_udp_ep_t remote; - - remote.family = AF_INET6; - - /* parse for interface */ - char *iface = ipv6_addr_split_iface(addr_str); - if (!iface) { - if (gnrc_netif_numof() == 1) { - /* assign the single interface found in gnrc_netif_numof() */ - remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid; - } - else { - remote.netif = SOCK_ADDR_ANY_NETIF; - } - } - else { - if (gnrc_netif_get_by_pid(atoi(iface)) == NULL) { - DEBUG("[CoAP] interface not valid"); - return 0; - } - remote.netif = atoi(iface); - } - - /* parse destination address */ - if (ipv6_addr_from_str(&addr, addr_str) == NULL) { - DEBUG("[CoAP] unable to parse destination address"); - return 0; - } - if ((remote.netif == SOCK_ADDR_ANY_NETIF) && ipv6_addr_is_link_local(&addr)) { - DEBUG("[CoAP] must specify interface for link local target"); - return 0; - } - memcpy(&remote.addr.ipv6[0], &addr.u8[0], sizeof(addr.u8)); - - /* parse port */ - remote.port = CONFIG_GCOAP_PORT; - - return gcoap_req_send(buf, len, &remote, NULL, NULL); -} - -int coap_post(char *addr, char *msgbuf, size_t msglen) -{ - assert(msglen < CONFIG_GCOAP_PDU_BUF_SIZE); - - coap_pkt_t pdu; - uint8_t buf[CONFIG_GCOAP_PDU_BUF_SIZE]; - size_t len = 0; - - gcoap_req_init(&pdu, buf, CONFIG_GCOAP_PDU_BUF_SIZE, - COAP_POST, COAP_CHAT_PATH); - - coap_opt_add_format(&pdu, COAP_FORMAT_TEXT); - len = coap_opt_finish(&pdu, COAP_OPT_FINISH_PAYLOAD); - - if (pdu.payload_len >= msglen) { - memcpy(pdu.payload, msgbuf, msglen); - len += msglen; - } - else { - DEBUG("[CoAP] coap_post: ERROR. The message buffer is too small for the message\n"); - return -1; - } - - DEBUG("[CoAP] coap_post: sending msg ID %u, %u bytes\n", - coap_get_id(&pdu), (unsigned) len); - - if (!_send(buf, len, addr)) { - puts("[CoAP] coap_post: msg send failed"); - return -1; - } - return len; -} - -void coap_init(void) -{ - gcoap_register_listener(&_listener); -} diff --git a/coap-chat/main.c b/coap-chat/main.c deleted file mode 100644 index 9aa3e24dee..0000000000 --- a/coap-chat/main.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2018 HAW Hamburg - * - * 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 applications - * @{ - * - * @file - * @brief coap-chat - Main loop and shell handlers - * - * @author Sebastian Meiling - * - * @} - */ - -#include -#include "msg.h" - -#include "net/gcoap.h" -#include "shell.h" - -#define BUFLEN (64U) -#define MAIN_QUEUE_SIZE (4) - -static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; - -extern int coap_post(const char *addr, const char *buf, size_t buflen); -extern void coap_init(void); - -int chat(int argc, char **argv) -{ - if (argc < 4) { - puts("usage: chat "); - return 1; - } - - char buf[BUFLEN] = { 0 }; - size_t len = snprintf(buf, BUFLEN, "%s: %s", argv[2], argv[3]); - for (int i = 4; i < argc; ++i) { - len += snprintf(buf + len, BUFLEN - len, " %s", argv[i]); - } - coap_post(argv[1], buf, len); - - return 0; -} - -static const shell_command_t shell_commands[] = { - { "chat", "CoAP chat", chat }, - { NULL, NULL, NULL } -}; - -int main(void) -{ - /* for the thread running the shell */ - msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); - /* init coap listener */ - coap_init(); - /* start shell */ - puts("All up, running the shell now"); - char line_buf[SHELL_DEFAULT_BUFSIZE]; - shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); - - /* should never be reached */ - return 0; -} From adf8ed117d2b085397c723d8ba4a4f0db9a47a47 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 20 Sep 2022 09:57:45 +0200 Subject: [PATCH 86/90] sniffer.py: enforce use of python3 --- sniffer/tools/sniffer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 8f44868884..9d29a51691 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' (C) 2012, Mariano Alvira From 646b37b2b34a57a050984e4dd953070c1714b2d3 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 20 Sep 2022 10:01:32 +0200 Subject: [PATCH 87/90] sniffer / spectrum-scanner: reformat using black --- sniffer/tools/sniffer.py | 82 ++++++++++++++++------------- spectrum-scanner/tools/plot_rssi.py | 56 +++++++++++++------- 2 files changed, 84 insertions(+), 54 deletions(-) diff --git a/sniffer/tools/sniffer.py b/sniffer/tools/sniffer.py index 9d29a51691..07ea50e013 100755 --- a/sniffer/tools/sniffer.py +++ b/sniffer/tools/sniffer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -''' +""" (C) 2012, Mariano Alvira (C) 2014, Oliver Hahm (C) 2015, Hauke Petersen @@ -30,7 +30,7 @@ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -''' +""" from __future__ import print_function import argparse @@ -42,13 +42,13 @@ from struct import pack from serial import Serial # PCAP setup -MAGIC = 0xa1b2c3d4 +MAGIC = 0xA1B2C3D4 MAJOR = 2 MINOR = 4 ZONE = 0 SIG = 0 -SNAPLEN = 0xffff -NETWORK = 230 # 802.15.4 no FCS +SNAPLEN = 0xFFFF +NETWORK = 230 # 802.15.4 no FCS DEFAULT_BAUDRATE = 115200 @@ -56,45 +56,44 @@ DEFAULT_BAUDRATE = 115200 def configure_interface(port, channel): line = "" iface = 0 - port.write('ifconfig\n'.encode()) + port.write("ifconfig\n".encode()) while True: line = port.readline() - if line == b'': - print("Application has no network interface defined", - file=sys.stderr) + if line == b"": + print("Application has no network interface defined", file=sys.stderr) sys.exit(2) - match = re.search(r'^Iface +(\d+)', line.decode(errors="ignore")) + match = re.search(r"^Iface +(\d+)", line.decode(errors="ignore")) if match is not None: iface = int(match.group(1)) break # set channel, raw mode, and promiscuous mode - print('ifconfig %d set chan %d' % (iface, channel), file=sys.stderr) - print('ifconfig %d raw' % iface, file=sys.stderr) - print('ifconfig %d promisc' % iface, file=sys.stderr) - port.write(('ifconfig %d set chan %d\n' % (iface, channel)).encode()) - port.write(('ifconfig %d raw\n' % iface).encode()) - port.write(('ifconfig %d promisc\n' % iface).encode()) + print("ifconfig %d set chan %d" % (iface, channel), file=sys.stderr) + print("ifconfig %d raw" % iface, file=sys.stderr) + print("ifconfig %d promisc" % iface, file=sys.stderr) + port.write(("ifconfig %d set chan %d\n" % (iface, channel)).encode()) + port.write(("ifconfig %d raw\n" % iface).encode()) + port.write(("ifconfig %d promisc\n" % iface).encode()) def generate_pcap(port, out): # count incoming packets count = 0 # output overall PCAP header - out.write(pack('? *rftest-rx --- len (\w+).*", - line.decode(errors="ignore")) + pkt_header = re.match( + r">? *rftest-rx --- len (\w+).*", line.decode(errors="ignore") + ) if pkt_header: now = time() sec = int(now) usec = int((now - sec) * 1000000) length = int(pkt_header.group(1), 16) - out.write(pack(' Date: Tue, 20 Sep 2022 11:47:59 +0200 Subject: [PATCH 88/90] Remove files from RIOT-applications that make no sense in RIOT examples --- .gitignore | 23 --- .gitmodules | 3 - .travis.yml | 17 -- LICENSE | 504 ---------------------------------------------------- README.md | 49 ----- RIOT | 1 - 6 files changed, 597 deletions(-) delete mode 100644 .gitignore delete mode 100644 .gitmodules delete mode 100644 .travis.yml delete mode 100644 LICENSE delete mode 100644 README.md delete mode 160000 RIOT diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 650d0caa32..0000000000 --- a/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# Object files -*.o -# Built binaries -*bin -# Backup files -*~ -*.orig -.*.swp -cachegrind.out* -# Eclipse workspace files -.project -.cproject -.settings -.idea -# KDevelop4 project files -.kdev4 -*.kdev4 -# Codelite (among others) project files -*.project - -# Eclipse symbol file (output from make eclipsesym) -eclipsesym.xml -/toolchain diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 9048042c0a..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "RIOT"] - path = RIOT - url = https://github.com/RIOT-OS/RIOT diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0c8adc3911..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -sudo: required - -language: minimal - -before_install: - - sudo apt-get install coreutils cppcheck pcregrep python3 python3-pip uncrustify - -notifications: - email: - recipients: - - maintainer@riot-os.org - on_success: change - on_failure: always - -script: - - ./RIOT/dist/tools/whitespacecheck/check.sh - - find . -path ./RIOT -prune -o \( -name *.c -o -name *.h \) -exec cppcheck --std=c99 --enable=style --force --error-exitcode=2 --quiet -j 1 {} + diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8000a6faac..0000000000 --- a/LICENSE +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random - Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/README.md b/README.md deleted file mode 100644 index e5c6ac6e92..0000000000 --- a/README.md +++ /dev/null @@ -1,49 +0,0 @@ -[![Build Status](https://travis-ci.org/RIOT-OS/applications.svg?branch=master)](https://travis-ci.org/RIOT-OS/applications) - -# RIOT Applications - -This repository provides more applications for the [RIOT operating system][riot-repo]. -Some of them are just useful tools for development work, others showcase -more extensive implementations of features of RIOT compared to the rather simple -[examples in the RIOT main codebase][riot-repo/examples]. - -## Usage - -To build and use them follow [the instructions in the RIOT repository][getting-started] -and the READMEs within the respective application directory. - -The RIOT main code is included as a submodule. This always points to the latest -release. To change the RIOT version to build against (e.g. current master), -clone the RIOT repository in a separate repository and point the `RIOTBASE` -environment variable there: - -```sh -# assuming you are in the working directory of your local clone of this repo -cd .. -git clone git@github.com:RIOT-OS/RIOT.git -cd applications -RIOTBASE="../RIOT" BOARD=samr21-xpro make -C sniffer flash -``` - -Alternatively you can use RIOT as a submodule. To initialize the submodule, from the -root of the repository run: - -```sh -git submodule update --init --recursive -``` - -If you want to use master then simply step into the submodule and checkout master or -any other desired branch. - -```sh -cd RIOT -git checkout master -git pull -``` - -Note that there is no guarantee that it will build or work, since we only test -this repository against the latest release. - -[riot-repo]: https://github.com/RIOT-OS/RIOT -[riot-repo/examples]: https://github.com/RIOT-OS/RIOT/tree/master/examples -[getting-started]: https://github.com/RIOT-OS/RIOT/blob/master/README.md#getting-started diff --git a/RIOT b/RIOT deleted file mode 160000 index 81a01df5d9..0000000000 --- a/RIOT +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 81a01df5d94729b8d8a2be7ce8e68f9fc7c7b95f From 17a042a06014cabf1b5a14ce3dada17616b6df39 Mon Sep 17 00:00:00 2001 From: chrysn Date: Tue, 20 Sep 2022 11:49:33 +0200 Subject: [PATCH 89/90] Move RIOT-applications into examples --- {sniffer => examples/sniffer}/Makefile | 0 {sniffer => examples/sniffer}/README.md | 0 {sniffer => examples/sniffer}/main.c | 0 {sniffer => examples/sniffer}/tools/README.md | 0 {sniffer => examples/sniffer}/tools/sniffer.py | 0 .../spectrum-scanner}/Makefile | 0 .../spectrum-scanner}/README.md | 0 .../spectrum-scanner}/main.c | 0 .../spectrum-scanner}/tools/README.md | 0 .../spectrum-scanner}/tools/example.png | Bin .../spectrum-scanner}/tools/plot_rssi.py | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename {sniffer => examples/sniffer}/Makefile (100%) rename {sniffer => examples/sniffer}/README.md (100%) rename {sniffer => examples/sniffer}/main.c (100%) rename {sniffer => examples/sniffer}/tools/README.md (100%) rename {sniffer => examples/sniffer}/tools/sniffer.py (100%) rename {spectrum-scanner => examples/spectrum-scanner}/Makefile (100%) rename {spectrum-scanner => examples/spectrum-scanner}/README.md (100%) rename {spectrum-scanner => examples/spectrum-scanner}/main.c (100%) rename {spectrum-scanner => examples/spectrum-scanner}/tools/README.md (100%) rename {spectrum-scanner => examples/spectrum-scanner}/tools/example.png (100%) rename {spectrum-scanner => examples/spectrum-scanner}/tools/plot_rssi.py (100%) diff --git a/sniffer/Makefile b/examples/sniffer/Makefile similarity index 100% rename from sniffer/Makefile rename to examples/sniffer/Makefile diff --git a/sniffer/README.md b/examples/sniffer/README.md similarity index 100% rename from sniffer/README.md rename to examples/sniffer/README.md diff --git a/sniffer/main.c b/examples/sniffer/main.c similarity index 100% rename from sniffer/main.c rename to examples/sniffer/main.c diff --git a/sniffer/tools/README.md b/examples/sniffer/tools/README.md similarity index 100% rename from sniffer/tools/README.md rename to examples/sniffer/tools/README.md diff --git a/sniffer/tools/sniffer.py b/examples/sniffer/tools/sniffer.py similarity index 100% rename from sniffer/tools/sniffer.py rename to examples/sniffer/tools/sniffer.py diff --git a/spectrum-scanner/Makefile b/examples/spectrum-scanner/Makefile similarity index 100% rename from spectrum-scanner/Makefile rename to examples/spectrum-scanner/Makefile diff --git a/spectrum-scanner/README.md b/examples/spectrum-scanner/README.md similarity index 100% rename from spectrum-scanner/README.md rename to examples/spectrum-scanner/README.md diff --git a/spectrum-scanner/main.c b/examples/spectrum-scanner/main.c similarity index 100% rename from spectrum-scanner/main.c rename to examples/spectrum-scanner/main.c diff --git a/spectrum-scanner/tools/README.md b/examples/spectrum-scanner/tools/README.md similarity index 100% rename from spectrum-scanner/tools/README.md rename to examples/spectrum-scanner/tools/README.md diff --git a/spectrum-scanner/tools/example.png b/examples/spectrum-scanner/tools/example.png similarity index 100% rename from spectrum-scanner/tools/example.png rename to examples/spectrum-scanner/tools/example.png diff --git a/spectrum-scanner/tools/plot_rssi.py b/examples/spectrum-scanner/tools/plot_rssi.py similarity index 100% rename from spectrum-scanner/tools/plot_rssi.py rename to examples/spectrum-scanner/tools/plot_rssi.py From ff3d3b5ba27341798bf480a01deeb9425d05e259 Mon Sep 17 00:00:00 2001 From: chrysn Date: Tue, 20 Sep 2022 11:49:56 +0200 Subject: [PATCH 90/90] makefiles: Adjust paths of RIOT-applications to run from examples --- examples/sniffer/Makefile | 2 +- examples/spectrum-scanner/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sniffer/Makefile b/examples/sniffer/Makefile index 3368b062bb..c5b26f562b 100644 --- a/examples/sniffer/Makefile +++ b/examples/sniffer/Makefile @@ -5,7 +5,7 @@ APPLICATION = sniffer BOARD ?= native # This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../RIOT +RIOTBASE ?= $(CURDIR)/../.. # Define modules that are used USEMODULE += fmt diff --git a/examples/spectrum-scanner/Makefile b/examples/spectrum-scanner/Makefile index ce598495eb..c59bd76b51 100644 --- a/examples/spectrum-scanner/Makefile +++ b/examples/spectrum-scanner/Makefile @@ -5,7 +5,7 @@ APPLICATION = spectrum-scanner BOARD ?= samr21-xpro # This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../RIOT +RIOTBASE ?= $(CURDIR)/../.. # Define modules that are used USEMODULE += gnrc