diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 6dd26cc09f81473b2b6ec10c1f7ee36ba178a827..0a28aafefa53431119de04924ccd367a3dec7379 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -55,6 +55,13 @@ endif ifneq (,$(filter lsm303dlhc,$(USEMODULE))) SRC += sc_lsm303dlhc.c endif +ifneq (,$(filter ng_netif,$(USEMODULE))) + ifneq (,$(filter ng_netapi,$(USEMODULE))) + ifneq (,$(filter ng_pktbuf,$(USEMODULE))) + SRC += sc_netif.c + endif + endif +endif # TODO # Conditional building not possible at the moment due to diff --git a/sys/shell/commands/sc_netif.c b/sys/shell/commands/sc_netif.c new file mode 100644 index 0000000000000000000000000000000000000000..39d51af228dec5d3eae533c861865b14ef62c9f7 --- /dev/null +++ b/sys/shell/commands/sc_netif.c @@ -0,0 +1,251 @@ +/* + * 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. + */ + +/** + * @ingroup sys_shell_commands + * @{ + * + * @file + * @brief Shell commands for interacting with network devices + * + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> + */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "thread.h" +#include "net/ng_netif.h" +#include "net/ng_netapi.h" +#include "net/ng_netconf.h" +#include "net/ng_pktbuf.h" +#include "net/ng_netif/hdr.h" + +/** + * @brief The maximal expected link layer address length in byte + */ +#define MAX_ADDR_LEN (16U) + + +/* utility functions */ +uint8_t _parse_addr(char *str, uint8_t *addr) +{ + char *tok = strtok(str, ":"); + uint8_t res = 0; + + while (tok != NULL) { + if (res >= MAX_ADDR_LEN) { + return 0; + } + uint16_t tmp = (uint16_t)strtol(tok, NULL, 16); + if (tmp <= 0xff) { + addr[res++] = (uint8_t)tmp; + } + else { + return 0; + } + tok = strtok(NULL, ":"); + } + return res; +} + +void _print_addr(uint8_t *addr, uint8_t addr_len) +{ + for (uint8_t i = 0; i < addr_len; i++) { + printf("%02x", addr[i]); + if (i != (addr_len - 1)) { + printf(":"); + } + } +} + +/* shell commands */ +void _netif_list(int argc, char **argv) +{ + (void)argc; + (void)argv; + kernel_pid_t *ifs; + size_t numof; + + /* read available interfaces */ + ifs = ng_netif_get(&numof); + + /* print information about each interface */ + for (size_t i = 0; i < numof; i++) { + /* TODO: print more information about the devices */ + printf("%3i - \n", ifs[i]); + } +} + +void _netif_send(int argc, char **argv) +{ + kernel_pid_t dev; + uint8_t addr[MAX_ADDR_LEN]; + uint8_t addr_len; + ng_pktsnip_t *pkt; + ng_netif_hdr_t *nethdr; + + + if (argc < 4) { + printf("usage: %s IF ADDR DATA\n", argv[0]); + return; + } + /* parse interface */ + dev = (kernel_pid_t)atoi(argv[1]); + if (thread_get(dev) == NULL) { + puts("error: invalid interface given"); + return; + } + /* parse address */ + addr_len = _parse_addr(argv[2], addr); + if (addr_len == 0) { + puts("error: invalid address given"); + return; + } + /* put packet together */ + pkt = ng_pktbuf_add(NULL, argv[3], strlen(argv[3]), NG_NETTYPE_UNDEF); + pkt = ng_pktbuf_add(pkt, NULL, sizeof(ng_netif_hdr_t) + addr_len, + NG_NETTYPE_UNDEF); + nethdr = (ng_netif_hdr_t *)pkt->data; + ng_netif_hdr_init(nethdr, 0, addr_len); + ng_netif_hdr_set_dst_addr(nethdr, addr, addr_len); + /* and send it */ + ng_netapi_send(dev, pkt); +} + +void _netif_addr(int argc, char **argv) +{ + kernel_pid_t dev; + uint8_t addr[MAX_ADDR_LEN]; + size_t addr_len; + int res; + + if (argc < 2) { + printf("usage: %s IF [ADDR]\n", argv[0]); + return; + } + /* parse interface */ + dev = (kernel_pid_t)atoi(argv[1]); + if (thread_get(dev) == NULL) { + puts("error: invalid interface given"); + return; + } + /* if address was given, parse and set it */ + if (argc >= 3) { + addr_len = _parse_addr(argv[2], addr); + if (addr_len == 0) { + puts("error: unable to parse address"); + } + else { + res = ng_netapi_set(dev, NETCONF_OPT_ADDRESS, 0, + addr, addr_len); + if (res > 0) { + printf("success: address of interface %i set to ", dev); + _print_addr(addr, addr_len); + puts(""); + } + else { + puts("error: could not set address\n"); + } + } + } + /* otherwise read it */ + else { + res = ng_netapi_get(dev, NETCONF_OPT_ADDRESS, 0, addr, MAX_ADDR_LEN); + if (res > 0) { + addr_len = (size_t)res; + printf("address of interface %i is ", dev); + _print_addr(addr, addr_len); + puts(""); + } + else { + puts("error: unable to read address"); + } + } +} + +void _netif_chan(int argc, char **argv) +{ + kernel_pid_t dev; + uint16_t chan; + int res; + + if (argc < 2) { + printf("usage: %s IF [CHAN]\n", argv[0]); + return; + } + /* parse interface */ + dev = (kernel_pid_t)atoi(argv[1]); + if (thread_get(dev) == NULL) { + puts("error: invalid interface given"); + return; + } + /* if channel was given, parse and set it */ + if (argc >= 3) { + chan = (uint16_t)atoi(argv[2]); + res = ng_netapi_set(dev, NETCONF_OPT_CHANNEL, 0, &chan, 2); + if (res > 0) { + printf("success: channel of interface %i set to %u\n", dev, chan); + } + else { + puts("error: could not set channel\n"); + } + } + /* otherwise read it */ + else { + res = ng_netapi_get(dev, NETCONF_OPT_CHANNEL, 0, &chan, 2); + if (res > 0) { + printf("channel of interface %i is %u\n", dev, chan); + } + else { + puts("error: unable to read channel"); + } + } +} + +void _netif_pan(int argc, char **argv) +{ + kernel_pid_t dev; + uint16_t pan; + int res; + + if (argc < 2) { + printf("usage: %s IF [CHAN]\n", argv[0]); + return; + } + /* parse interface */ + dev = (kernel_pid_t)atoi(argv[1]); + if (thread_get(dev) == NULL) { + puts("error: invalid interface given"); + return; + } + /* if PAN was given, parse and set it */ + if (argc >= 3) { + pan = (uint16_t)atoi(argv[2]); + res = ng_netapi_set(dev, NETCONF_OPT_NID, 0, &pan, 2); + if (res > 0) { + printf("success: PAN of interface %i set to %u\n", dev, pan); + } + else { + puts("error: could not set PAN\n"); + } + } + /* otherwise read it */ + else { + res = ng_netapi_get(dev, NETCONF_OPT_NID, 0, &pan, 2); + if (res > 0) { + printf("PAN of interface %i is %u\n", dev, pan); + } + else { + puts("error: unable to read PAN"); + } + } + +} diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index 7b131d88f941095b4b6ac05d6fba575886bd24c6..6021ac25ce7498951abd6dc82adf4af7856b9996 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -150,6 +150,14 @@ extern void _mersenne_init(int argc, char **argv); extern void _mersenne_get(int argc, char **argv); #endif +#if defined(MODULE_NG_NETIF) && defined(MODULE_NG_NETAPI) && defined(MODULE_NG_PKTBUF) +void _netif_list(int argc, char **argv); +void _netif_send(int argc, char **argv); +void _netif_addr(int argc, char **argv); +void _netif_chan(int argc, char **argv); +void _netif_pan(int argc, char **argv); +#endif + const shell_command_t _shell_command_list[] = { {"reboot", "Reboot the node", _reboot_handler}, #ifdef MODULE_CONFIG @@ -242,6 +250,13 @@ const shell_command_t _shell_command_list[] = { #endif #ifdef CPU_X86 {"lspci", "Lists PCI devices", _x86_lspci}, +#endif +#if defined(MODULE_NG_NETIF) && defined(MODULE_NG_NETAPI) && defined(MODULE_NG_PKTBUF) + {"netif_list", "list network devices", _netif_list }, + {"netif_send", "send raw data", _netif_send }, + {"netif_addr", "get/set link layer address", _netif_addr }, + {"netif_chan", "get/set channel (for radio devices)", _netif_chan }, + {"netif_pan", "get/set PAN (for some radios)", _netif_pan }, #endif {NULL, NULL, NULL} };