diff --git a/examples/posix_sockets/Makefile b/examples/posix_sockets/Makefile new file mode 100644 index 0000000000000..33644300c13c2 --- /dev/null +++ b/examples/posix_sockets/Makefile @@ -0,0 +1,42 @@ +# name of your application +APPLICATION = posix_sockets + +# 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)/../.. + +# TODO: select stack according to size of available memory (or by user?) + +BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \ + nrf6310 nucleo-f334 pca10000 pca10005 \ + stm32f0discovery telosb wsn430-v1_3b wsn430-v1_4 \ + yunjia-nrf51822 z1 + +BOARD_BLACKLIST := arduino-mega2560 spark-core +# arduino-mega2560: unknown error types (e.g. -EBADMSG) + +# Include packages that pull up and auto-init the link layer. +# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present +USEMODULE += gnrc_netif_default +USEMODULE += auto_init_gnrc_netif +# Specify the mandatory networking modules for socket communication via UDP +USEMODULE += gnrc_ipv6_default +USEMODULE += gnrc_udp +USEMODULE += gnrc_conn_udp +USEMODULE += posix_sockets +# Add also the shell, some shell commands +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +CFLAGS += -DDEVELHELP + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/examples/posix_sockets/README.md b/examples/posix_sockets/README.md new file mode 100644 index 0000000000000..9bb113a0efbf3 --- /dev/null +++ b/examples/posix_sockets/README.md @@ -0,0 +1,58 @@ +examples/posix_sockets +====================== +This application is a showcase for RIOT's POSIX socket support. To +keep things simple this application has only one-hop support and +no routing capabilities. + +Usage +===== + +Build, flash and start the application: +``` +export BOARD=your_board +make +make flash +make term +``` + +The `term` make target starts a terminal emulator for your board. It +connects to a default port so you can interact with the shell, usually +that is `/dev/ttyUSB0`. If your port is named differently, the +`PORT=/dev/yourport` variable can be used to override this. + + +Example output +============== + +The shell commands come with online help. Call `help` to see which commands +exist and what they do. + +Running the `help` command on an iotlab-m3: +``` +2014-05-06 13:14:38,508 - INFO # > help +``` + +Running the `ps` command on an iotlab-m3: + +``` +2014-05-09 17:38:33,388 - INFO # > ps +``` + +Start a UDP server: + +``` +> udp server start +``` + +Stop a UDP server: + +``` +> udp server start +``` + + +Send a UDP package: + +``` +> udp send +``` diff --git a/examples/posix_sockets/udp.c b/examples/posix_sockets/udp.c new file mode 100644 index 0000000000000..8149c39cae527 --- /dev/null +++ b/examples/posix_sockets/udp.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Demonstrating the sending and receiving of UDP data over POSIX sockets. + * + * @author Martine Lenders + * + * @} + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static int server_socket = 0; + +static void udp_send(char *addr_str, char *port_str, char *data, unsigned int num, + unsigned int delay) +{ + struct sockaddr_in6 dst; + size_t data_len = strlen(data); + uint16_t port; + int s; + /* parse destination address */ + if (inet_pton(AF_INET6, addr_str, &dst.sin6_addr) != 1) { + puts("Error: unable to parse destination address"); + return; + } + /* parse port */ + port = (uint16_t)atoi(port_str); + dst.sin6_port = htons(port); + s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + for (unsigned int i = 0; i < num; i++) { + sendto(s, data, data_len, 0, (struct sockaddr *)&dst, sizeof(dst)); + printf("Success: send %u byte to %s:%u\n", (unsigned)data_len, addr_str, port); + usleep(delay); + } + close(s); +} + +static void udp_start_server(char *port_str) +{ + struct sockaddr_in6 dst; + size_t data_len = strlen(data); + uint16_t port; + + /* check if server is already running */ + if (server_socket != 0) { + puts("Error: server already running"); + return; + } + /* parse port */ + port = (uint16_t)atoi(port_str); + if (port == 0) { + puts("Error: invalid port specified"); + return; + } + memset(&dst.sin6_addr, 0, sizeof(dst.sin6_addr)); + dst.sin6_port = htons(port); + /* start server (which means registering pktdump for the chosen port) */ + server_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + /* TODO: start server thread, if not running */ + printf("Success: started UDP server on port %" PRIu16 "\n", port); +} + +static void udp_stop_server(void) +{ + /* check if server is running at all */ + if (server_socket == 0) { + printf("Error: server was not running\n"); + return; + } + /* stop server */ + /* TODO: send stop command to server thread */ + close(server_socket); + server_socket = 0; + puts("Success: stopped UDP server"); +} + +int udp_cmd(int argc, char **argv) +{ + if (argc < 2) { + printf("usage: %s [send|server]\n", argv[0]); + return 1; + } + + if (strcmp(argv[1], "send") == 0) { + uint32_t num = 1; + uint32_t delay = 1000000; + if (argc < 5) { + printf("usage: %s send [ []]\n", + argv[0]); + return 1; + } + if (argc > 5) { + num = (uint32_t)atoi(argv[5]); + } + if (argc > 6) { + delay = (uint32_t)atoi(argv[6]); + } + udp_send(argv[2], argv[3], argv[4], num, delay); + } + else if (strcmp(argv[1], "server") == 0) { + if (argc < 3) { + printf("usage: %s server [start|stop]\n", argv[0]); + return 1; + } + if (strcmp(argv[2], "start") == 0) { + if (argc < 4) { + printf("usage %s server start \n", argv[0]); + return 1; + } + udp_start_server(argv[3]); + } + else if (strcmp(argv[2], "stop") == 0) { + udp_stop_server(); + } + else { + puts("error: invalid command"); + } + } + else { + puts("error: invalid command"); + } + return 0; +} + +/** @} */