diff --git a/.mailmap b/.mailmap index 5d795abab2ca..aba19f1453cd 100644 --- a/.mailmap +++ b/.mailmap @@ -26,4 +26,6 @@ Peter Kietzmann René Kijewski René Kijewski Sebastian Meiling +Marian Buschsieweke Marian Buschsieweke +Marian Buschsieweke diff --git a/LOSTANDFOUND.md b/LOSTANDFOUND.md index 1132f1398fc6..b2df5cab655a 100644 --- a/LOSTANDFOUND.md +++ b/LOSTANDFOUND.md @@ -302,6 +302,18 @@ therefore, have no interest in supporting this board. As result, none of the RIOT core contributors has access to the hardware, preventing us from doing the necessary testing for maintaining this board. +### boards/nrf6310 [4953ba8e6759d2b1a1a1ea497a4ad1e71489195a] +Author(s): +- Christian Kühling +- Timo Ziegler +- Hauke Petersen + +Reason for removal: +- this was an early development board by Nordic which was discontinued + (successor: `nrf51dk`) +- also for a `BLE DEVKIT.N` board from Mommosoft, which was discontinued as well +- no hardware available anymore for testing, many exclusions from CI + [6cad5d24771ba6199228351a11b5062cd2e9b36d]: https://github.com/RIOT-OS/RIOT/commit/6cad5d24771ba6199228351a11b5062cd2e9b36d [d83d08f0995a88f399e70a7d07b44dd780082436]: https://github.com/RIOT-OS/RIOT/commit/d83d08f0995a88f399e70a7d07b44dd780082436 [cdc252ab7bd4161cc046bf93a3e55995704b24d4]: https://github.com/RIOT-OS/RIOT/commit/cdc252ab7bd4161cc046bf93a3e55995704b24d4 @@ -334,3 +346,4 @@ necessary testing for maintaining this board. [fe941ac9fe3f81c0f08ff3b8564cf439639abcda]: https://github.com/RIOT-OS/RIOT/commit/fe941ac9fe3f81c0f08ff3b8564cf439639abcda [81458c8eed8949c686d5ded652dbee10748e860b]: https://github.com/RIOT-OS/RIOT/commit/81458c8eed8949c686d5ded652dbee10748e860b [2b8a0d48940517f7df4e78c7a0b16024f46a8694]: https://github.com/RIOT-OS/RIOT/commit/2b8a0d48940517f7df4e78c7a0b16024f46a8694 +[4953ba8e6759d2b1a1a1ea497a4ad1e71489195a]: https://github.com/RIOT-OS/RIOT/commit/4953ba8e6759d2b1a1a1ea497a4ad1e71489195a diff --git a/boards/nrf6310/Kconfig b/boards/nrf6310/Kconfig deleted file mode 100644 index 53d1696153ba..000000000000 --- a/boards/nrf6310/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2020 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. - -config BOARD - default "nrf6310" if BOARD_NRF6310 - -config BOARD_NRF6310 - bool - default y - select BOARD_COMMON_NRF51 - select CPU_MODEL_NRF51X22XXAA - -source "$(RIOTBOARD)/common/nrf51/Kconfig" diff --git a/boards/nrf6310/Makefile b/boards/nrf6310/Makefile deleted file mode 100644 index f8fcbb53a065..000000000000 --- a/boards/nrf6310/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE = board - -include $(RIOTBASE)/Makefile.base diff --git a/boards/nrf6310/Makefile.dep b/boards/nrf6310/Makefile.dep deleted file mode 100644 index babcd96228ac..000000000000 --- a/boards/nrf6310/Makefile.dep +++ /dev/null @@ -1 +0,0 @@ -include $(RIOTBOARD)/common/nrf51/Makefile.dep diff --git a/boards/nrf6310/Makefile.features b/boards/nrf6310/Makefile.features deleted file mode 100644 index 46b201fafbf4..000000000000 --- a/boards/nrf6310/Makefile.features +++ /dev/null @@ -1,8 +0,0 @@ -CPU_MODEL = nrf51x22xxaa - -# Put defined MCU peripherals here (in alphabetical order) -FEATURES_PROVIDED += periph_spi -FEATURES_PROVIDED += periph_uart - -# include common nrf51 based boards features -include $(RIOTBOARD)/common/nrf51/Makefile.features diff --git a/boards/nrf6310/Makefile.include b/boards/nrf6310/Makefile.include deleted file mode 100644 index 35c541b38c23..000000000000 --- a/boards/nrf6310/Makefile.include +++ /dev/null @@ -1,12 +0,0 @@ -# set default port depending on operating system -PORT_LINUX ?= /dev/ttyUSB0 -PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.SLAB_USBtoUART*))) - -# use jlink to program this board -PROGRAMMER ?= jlink - -# set required debug adapter for openocd if it's used -OPENOCD_DEBUG_ADAPTER = jlink - -# include nrf51 boards common configuration -include $(RIOTBOARD)/common/nrf51/Makefile.include diff --git a/boards/nrf6310/board.c b/boards/nrf6310/board.c deleted file mode 100644 index b909139fef21..000000000000 --- a/boards/nrf6310/board.c +++ /dev/null @@ -1,31 +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 boards_nrf6310 - * @{ - * - * @file board.c - * @brief Board specific implementations for the NRF6310 board - * - * @author Christian Kühling - * @author Timo Ziegler - * @author Hauke Petersen - * - * @} - */ - -#include "board.h" -#include "cpu.h" - -void led_init(void) -{ - /* initialize and turn off on-board LEDs */ - NRF_GPIO->DIRSET = LED0_MASK | LED1_MASK | LED2_MASK; - NRF_GPIO->OUTSET = LED0_MASK | LED1_MASK | LED2_MASK; -} diff --git a/boards/nrf6310/doc.txt b/boards/nrf6310/doc.txt deleted file mode 100644 index 856a406d8256..000000000000 --- a/boards/nrf6310/doc.txt +++ /dev/null @@ -1,5 +0,0 @@ -/** -@defgroup boards_nrf6310 NRF6310 (Nordic NRF Hardware Development Kit) -@ingroup boards -@brief Support for the nRF51 boards: nrf6310 or MOMMOSOFT BLE DEVKIT.N - */ diff --git a/boards/nrf6310/include/board.h b/boards/nrf6310/include/board.h deleted file mode 100644 index c02add33edbf..000000000000 --- a/boards/nrf6310/include/board.h +++ /dev/null @@ -1,60 +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 boards_nrf6310 - * @{ - * - * @file - * @brief Board specific definitions for the nRF51 evaluation board nrf6310 - * - * @author Christian Kühling - * @author Timo Ziegler - * @author Frank Holtz - */ - -#ifndef BOARD_H -#define BOARD_H - -#include "cpu.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @name LED pin definitions and handlers - * @{ - */ -#define LED0_PIN GPIO_PIN(0, 8) -#define LED1_PIN GPIO_PIN(0, 9) -#define LED2_PIN GPIO_PIN(0, 10) - -#define LED0_MASK (1 << 8) -#define LED1_MASK (1 << 9) -#define LED2_MASK (1 << 10) - -#define LED0_ON (NRF_GPIO->OUTCLR = LED0_MASK) -#define LED0_OFF (NRF_GPIO->OUTSET = LED0_MASK) -#define LED0_TOGGLE (NRF_GPIO->OUT ^= LED0_MASK) - -#define LED1_ON (NRF_GPIO->OUTCLR = LED1_MASK) -#define LED1_OFF (NRF_GPIO->OUTSET = LED1_MASK) -#define LED1_TOGGLE (NRF_GPIO->OUT ^= LED1_MASK) - -#define LED2_ON (NRF_GPIO->OUTCLR = LED2_MASK) -#define LED2_OFF (NRF_GPIO->OUTSET = LED2_MASK) -#define LED2_TOGGLE (NRF_GPIO->OUT ^= LED2_MASK) -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* BOARD_H */ -/** @} */ diff --git a/boards/nrf6310/include/periph_conf.h b/boards/nrf6310/include/periph_conf.h deleted file mode 100644 index bbe0d27efef4..000000000000 --- a/boards/nrf6310/include/periph_conf.h +++ /dev/null @@ -1,82 +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 boards_nrf6310 - * @{ - * - * @file - * @brief Peripheral MCU configuration for the nRF51 board nrf6310 - * - * @author Christian Kühling - * @author Timo Ziegler - * @author Hauke Petersen - * @author Frank Holtz - */ - -#ifndef PERIPH_CONF_H -#define PERIPH_CONF_H - -#include "periph_cpu.h" -#include "cfg_clock_16_1.h" -#include "cfg_timer_012.h" -#include "cfg_rtt_default.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @name UART configuration - * @{ - */ -static const uart_conf_t uart_config[] = { - { - .dev = NRF_UART0, - .rx_pin = GPIO_PIN(0, 16), - .tx_pin = GPIO_PIN(0, 17), -#ifdef MODULE_PERIPH_UART_HW_FC - .rts_pin = GPIO_PIN(0, 19), - .cts_pin = GPIO_PIN(0, 18), -#endif - .irqn = UART0_IRQn, - }, -}; - -#define UART_NUMOF ARRAY_SIZE(uart_config) -#define UART_0_ISR isr_uart0 -/** @} */ - -/** - * @name SPI configuration - * @{ - */ -static const spi_conf_t spi_config[] = { - { - .dev = NRF_SPI0, - .sclk = 23, - .mosi = 22, - .miso = 20 - }, - { - .dev = NRF_SPI1, - .sclk = 16, - .mosi = 17, - .miso = 18 - } -}; - -#define SPI_NUMOF ARRAY_SIZE(spi_config) -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* PERIPH_CONF_H */ -/** @} */ diff --git a/cpu/nrf52/radio/nrf802154/nrf802154_radio.c b/cpu/nrf52/radio/nrf802154/nrf802154_radio.c index 37fcba3fab87..404a6e676650 100644 --- a/cpu/nrf52/radio/nrf802154/nrf802154_radio.c +++ b/cpu/nrf52/radio/nrf802154/nrf802154_radio.c @@ -119,14 +119,22 @@ static void _power_off(void) static bool _l2filter(uint8_t *mhr) { uint8_t dst_addr[IEEE802154_LONG_ADDRESS_LEN]; + uint8_t src_addr[IEEE802154_LONG_ADDRESS_LEN]; le_uint16_t dst_pan; + le_uint16_t src_pan; uint8_t pan_bcast[] = IEEE802154_PANID_BCAST; - int addr_len = ieee802154_get_dst(mhr, dst_addr, &dst_pan); + int dst_addr_len = ieee802154_get_dst(mhr, dst_addr, &dst_pan); + + int src_addr_len = ieee802154_get_src(mhr, src_addr, &src_pan); if ((mhr[0] & IEEE802154_FCF_TYPE_MASK) == IEEE802154_FCF_TYPE_BEACON) { - if ((memcmp(&nrf802154_pan_id, pan_bcast, 2) == 0)) { - return true; + if (src_addr_len == IEEE802154_SHORT_ADDRESS_LEN || + src_addr_len == IEEE802154_LONG_ADDRESS_LEN){ + if ((memcmp(&nrf802154_pan_id, src_pan.u8, 2) == 0) || + (memcmp(&nrf802154_pan_id, pan_bcast, 2) == 0)) { + return true; + } } } /* filter PAN ID */ @@ -138,11 +146,11 @@ static bool _l2filter(uint8_t *mhr) } /* check destination address */ - if (((addr_len == IEEE802154_SHORT_ADDRESS_LEN) && - (memcmp(nrf802154_short_addr, dst_addr, addr_len) == 0 || - memcmp(ieee802154_addr_bcast, dst_addr, addr_len) == 0)) || - ((addr_len == IEEE802154_LONG_ADDRESS_LEN) && - (memcmp(nrf802154_long_addr, dst_addr, addr_len) == 0))) { + if (((dst_addr_len == IEEE802154_SHORT_ADDRESS_LEN) && + (memcmp(nrf802154_short_addr, dst_addr, dst_addr_len) == 0 || + memcmp(ieee802154_addr_bcast, dst_addr, dst_addr_len) == 0)) || + ((dst_addr_len == IEEE802154_LONG_ADDRESS_LEN) && + (memcmp(nrf802154_long_addr, dst_addr, dst_addr_len) == 0))) { return true; } diff --git a/cpu/sam3/periph/rtt.c b/cpu/sam3/periph/rtt.c index 2da87e712c3a..7cefa4f210f3 100644 --- a/cpu/sam3/periph/rtt.c +++ b/cpu/sam3/periph/rtt.c @@ -88,12 +88,12 @@ void rtt_clear_alarm(void) void rtt_poweron(void) { - PMC->PMC_PCER0 |= (1 << ID_RTT); + PMC->PMC_PCER0 = (1 << ID_RTT); } void rtt_poweroff(void) { - PMC->PMC_PCER0 &= ~(1 << ID_RTT); + PMC->PMC_PCDR0 = (1 << ID_RTT); } void isr_rtt(void) diff --git a/cpu/sam3/periph/spi.c b/cpu/sam3/periph/spi.c index e542519dabbd..f7c56afd8003 100644 --- a/cpu/sam3/periph/spi.c +++ b/cpu/sam3/periph/spi.c @@ -71,7 +71,7 @@ void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk) /* lock bus */ mutex_lock(&locks[bus]); /* enable SPI device clock */ - PMC->PMC_PCER0 |= (1 << spi_config[bus].id); + PMC->PMC_PCER0 = (1 << spi_config[bus].id); /* set mode and speed */ dev(bus)->SPI_CSR[0] = (SPI_CSR_SCBR(CLOCK_CORECLOCK / clk) | mode); dev(bus)->SPI_MR = (SPI_MR_MSTR | SPI_MR_MODFDIS); @@ -82,7 +82,7 @@ void spi_release(spi_t bus) { /* disable device and turn off clock signal */ dev(bus)->SPI_CR = 0; - PMC->PMC_PCER0 &= ~(1 << spi_config[bus].id); + PMC->PMC_PCDR0 = (1 << spi_config[bus].id); /* release device lock */ mutex_unlock(&locks[bus]); } diff --git a/cpu/sam3/periph/uart.c b/cpu/sam3/periph/uart.c index 206e457a429a..8cb8723ed068 100644 --- a/cpu/sam3/periph/uart.c +++ b/cpu/sam3/periph/uart.c @@ -89,12 +89,12 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len) void uart_poweron(uart_t uart) { - PMC->PMC_PCER0 |= (1 << uart_config[uart].pmc_id); + PMC->PMC_PCER0 = (1 << uart_config[uart].pmc_id); } void uart_poweroff(uart_t uart) { - PMC->PMC_PCER0 &= ~(1 << uart_config[uart].pmc_id); + PMC->PMC_PCDR0 = (1 << uart_config[uart].pmc_id); } static inline void isr_handler(int num) diff --git a/doc.txt b/doc.txt index 78dca2c18873..94cd317455bf 100644 --- a/doc.txt +++ b/doc.txt @@ -59,6 +59,32 @@ # define DEVELHELP #endif +/** + * @def RIOT_FILE_RELATIVE + * @brief Provides the current filename relative to the RIOT base directory (RIOTBASE) + * @warning This only works within `*.c` and `*.cpp` files. For `*.h`/`*.hpp` files the + * source compiles, however, the including `*.c`/`*.cpp` file will be + * substituted. + * @see `__FILE__` for absolute filenames that also work with *.h files + * @see @ref RIOT_FILE_NOPATH + */ +#if DOXYGEN +# define RIOT_FILE_RELATIVE +#endif + +/** + * @def RIOT_FILE_NOPATH + * @brief Provides the current filename without the parent directory path + * @warning This only works within `*.c` and `*.cpp` files. For `*.h`/`*.hpp` files the + * source compiles, however, the including `*.c`/`*.cpp` file will be + * substituted. + * @see `__FILE__` for absolute filenames that also work with *.h files + * @see @ref RIOT_FILE_RELATIVE + */ +#if DOXYGEN +# define RIOT_FILE_NOPATH +#endif + /** * @def CONFIG_THREAD_NAMES * @brief This global macro enable storage of thread names to help developers. diff --git a/doc/doxygen/riot.doxyfile b/doc/doxygen/riot.doxyfile index 5df85353f2b6..00a214d116b5 100644 --- a/doc/doxygen/riot.doxyfile +++ b/doc/doxygen/riot.doxyfile @@ -2304,8 +2304,7 @@ PREDEFINED = DOXYGEN \ MODULE_GNRC_SIXLOWPAN \ MODULE_GNRC_SIXLOWPAN_ND_ROUTER \ MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER \ - MODULE_GNRC_UDP \ - RIOT_FILE_RELATIVE + MODULE_GNRC_UDP # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/drivers/include/periph/uart.h b/drivers/include/periph/uart.h index 87bbc965c1d6..b57e4ea55864 100644 --- a/drivers/include/periph/uart.h +++ b/drivers/include/periph/uart.h @@ -177,7 +177,7 @@ typedef enum { #endif /** - * @brief Initialize a given UART device + * @brief Initialize and acquire a given UART device * * The UART device will be initialized with the following configuration: * - 8 data bits @@ -188,6 +188,14 @@ typedef enum { * If no callback parameter is given (rx_cb := NULL), the UART will be * initialized in TX only mode. * + * @pre The caller is not calling `uart_init()` twice without a call of + * to @ref uart_poweroff in between. + * + * @note This may block if the UART is already acquired until it is released. + * This allows sharing the underlying peripheral to provide other + * serial interfaces (e.g. if the peripheral can also provide SPI, I2C, + * etc.) + * * @param[in] uart UART device to initialize * @param[in] baud desired symbol rate in baud * @param[in] rx_cb receive callback, executed in interrupt context once @@ -401,14 +409,17 @@ int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, void uart_write(uart_t uart, const uint8_t *data, size_t len); /** - * @brief Power on the given UART device + * @brief Power on and acquire the given UART device + * + * The UART will resume with the configuration it was most recently configured + * with. * * @param[in] uart the UART device to power on */ void uart_poweron(uart_t uart); /** - * @brief Power off the given UART device + * @brief Power off and release the given UART device * * @param[in] uart the UART device to power off */ diff --git a/examples/asymcute_mqttsn/Makefile.ci b/examples/asymcute_mqttsn/Makefile.ci index 681d67cc4d13..de5192c86364 100644 --- a/examples/asymcute_mqttsn/Makefile.ci +++ b/examples/asymcute_mqttsn/Makefile.ci @@ -20,7 +20,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430h \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/dtls-echo/Makefile.ci b/examples/dtls-echo/Makefile.ci index 1feb84512501..5cb8c7725a6b 100644 --- a/examples/dtls-echo/Makefile.ci +++ b/examples/dtls-echo/Makefile.ci @@ -27,7 +27,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/dtls-sock/Makefile.ci b/examples/dtls-sock/Makefile.ci index 58a2c5f5cc5a..4f9d7736600b 100644 --- a/examples/dtls-sock/Makefile.ci +++ b/examples/dtls-sock/Makefile.ci @@ -30,7 +30,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/dtls-wolfssl/Makefile.ci b/examples/dtls-wolfssl/Makefile.ci index 64f98b634940..a7b33c2ac94d 100644 --- a/examples/dtls-wolfssl/Makefile.ci +++ b/examples/dtls-wolfssl/Makefile.ci @@ -17,7 +17,6 @@ BOARD_INSUFFICIENT_MEMORY := \ maple-mini \ microbit \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/gcoap_dtls/Makefile.ci b/examples/gcoap_dtls/Makefile.ci index 2a2d882e9895..29799600d300 100644 --- a/examples/gcoap_dtls/Makefile.ci +++ b/examples/gcoap_dtls/Makefile.ci @@ -31,7 +31,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/gnrc_border_router/Makefile b/examples/gnrc_border_router/Makefile index c52d31ce92bf..8a4b9bdb33df 100644 --- a/examples/gnrc_border_router/Makefile +++ b/examples/gnrc_border_router/Makefile @@ -10,6 +10,14 @@ RIOTBASE ?= $(CURDIR)/../.. # Default to using ethos for providing the uplink when not on native UPLINK ?= ethos +# If enabled will configure a default DNS resolver and propagate it via the +# RDNSS option to the hosts +ENABLE_DNS ?= 1 +# If the above setting is active this setting will also enable DNS caching, +# consequently dedicating some more memory space in order to reduce DNS +# requests +ENABLE_DNS_CACHING ?= 1 + # Check if the selected Uplink is valid ifeq (,$(filter ethos slip cdc-ecm wifi ethernet,$(UPLINK))) $(error Supported uplinks are `ethos`, `slip`, `cdc-ecm`, `ethernet` and `wifi`) @@ -39,8 +47,14 @@ USEMODULE += ps # Optionally include DNS support. This includes resolution of names at an # upstream DNS server and the handling of RDNSS options in Router Advertisements # to auto-configure that upstream DNS server. -#USEMODULE += sock_dns # include DNS client -#USEMODULE += gnrc_ipv6_nib_dns # include RDNSS option handling +ifneq (0,$(ENABLE_DNS)) + USEMODULE += sock_dns # include DNS client + USEMODULE += gnrc_ipv6_nib_dns # include RDNSS option handling + USEMODULE += auto_init_sock_dns # configure default DNS resolver + ifneq (0,$(ENABLE_DNS_CACHING)) + USEMODULE += dns_cache # cache DNS responses + endif +endif # When using a regular network uplink we should use DHCPv6 ifneq (,$(filter cdc-ecm wifi ethernet,$(UPLINK))$(REUSE_TAP)) diff --git a/examples/gnrc_border_router/Makefile.ci b/examples/gnrc_border_router/Makefile.ci index fcbe41c2a3d9..f8e68ac08ad7 100644 --- a/examples/gnrc_border_router/Makefile.ci +++ b/examples/gnrc_border_router/Makefile.ci @@ -34,7 +34,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430h \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/javascript/Makefile.ci b/examples/javascript/Makefile.ci index 961056a015dc..64f84cf62210 100644 --- a/examples/javascript/Makefile.ci +++ b/examples/javascript/Makefile.ci @@ -23,7 +23,6 @@ BOARD_INSUFFICIENT_MEMORY := \ microbit \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/lua_REPL/Makefile.ci b/examples/lua_REPL/Makefile.ci index 1bccc4ef64d5..41d40d2fb8aa 100644 --- a/examples/lua_REPL/Makefile.ci +++ b/examples/lua_REPL/Makefile.ci @@ -40,7 +40,6 @@ BOARD_INSUFFICIENT_MEMORY := \ microbit \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/lwm2m/Makefile.ci b/examples/lwm2m/Makefile.ci index bab3493af59e..a33f2aa1cafe 100644 --- a/examples/lwm2m/Makefile.ci +++ b/examples/lwm2m/Makefile.ci @@ -30,7 +30,6 @@ BOARD_INSUFFICIENT_MEMORY := \ maple-mini \ microbit \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/nanocoap_server/Makefile b/examples/nanocoap_server/Makefile index 2b418732cbdf..b944748b8464 100644 --- a/examples/nanocoap_server/Makefile +++ b/examples/nanocoap_server/Makefile @@ -20,7 +20,7 @@ USEMODULE += gnrc_icmpv6_echo USEMODULE += nanocoap_sock USEMODULE += nanocoap_resources -USEMODULE += xtimer +USEMODULE += ztimer_msec # include this for nicely formatting the returned internal value USEMODULE += fmt @@ -48,10 +48,12 @@ HIGH_MEMORY_BOARDS := native native64 same54-xpro mcb2388 ifneq (,$(filter $(BOARD),$(HIGH_MEMORY_BOARDS))) # enable separate response - USEMODULE += nanocoap_server_separate USEMODULE += event_callback + USEMODULE += event_periodic USEMODULE += event_thread USEMODULE += event_timeout_ztimer + USEMODULE += nanocoap_server_observe + USEMODULE += nanocoap_server_separate # enable fileserver USEMODULE += nanocoap_fileserver diff --git a/examples/nanocoap_server/coap_handler.c b/examples/nanocoap_server/coap_handler.c index f40a425362c2..86dd39993997 100644 --- a/examples/nanocoap_server/coap_handler.c +++ b/examples/nanocoap_server/coap_handler.c @@ -11,13 +11,13 @@ #include #include "event/callback.h" -#include "event/timeout.h" +#include "event/periodic.h" #include "event/thread.h" +#include "event/timeout.h" #include "fmt.h" #include "net/nanocoap.h" #include "net/nanocoap_sock.h" #include "hashes/sha256.h" -#include "kernel_defines.h" /* internal value that can be read/written via CoAP */ static uint8_t internal_value = 0; @@ -59,7 +59,7 @@ static ssize_t _riot_block2_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, c bufpos += coap_put_option_ct(bufpos, 0, COAP_FORMAT_TEXT); bufpos += coap_opt_put_block2(bufpos, COAP_OPT_CONTENT_FORMAT, &slicer, 1); - *bufpos++ = 0xff; + *bufpos++ = COAP_PAYLOAD_MARKER; /* Add actual content */ bufpos += coap_blockwise_put_bytes(&slicer, bufpos, block2_intro, sizeof(block2_intro)-1); @@ -196,7 +196,7 @@ static void _send_response(void *ctx) puts("_separate_handler(): send delayed response"); nanocoap_server_send_separate(ctx, COAP_CODE_CONTENT, COAP_TYPE_NON, - response, sizeof(response)); + response, sizeof(response)); } static ssize_t _separate_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context) @@ -204,7 +204,12 @@ static ssize_t _separate_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap static event_timeout_t event_timeout; static event_callback_t event_timed = EVENT_CALLBACK_INIT(_send_response, &_separate_ctx); - if (event_timeout_is_pending(&event_timeout) && !sock_udp_ep_equal(context->remote, &_separate_ctx.remote)) { + if (event_timeout_is_pending(&event_timeout)) { + if (nanocoap_server_is_remote_in_response_ctx(&_separate_ctx, context)) { + /* duplicate of the request a separate response is already scheduled + * for --> resending the ACK */ + return coap_build_empty_ack(pkt, (void *)buf); + } puts("_separate_handler(): response already scheduled"); return coap_build_reply(pkt, COAP_CODE_SERVICE_UNAVAILABLE, buf, len, 0); } @@ -229,6 +234,107 @@ NANOCOAP_RESOURCE(separate) { }; #endif /* MODULE_EVENT_THREAD */ +#ifdef MODULE_NANOCOAP_SERVER_OBSERVE +static ssize_t _time_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context) +{ + uint32_t obs; + bool registered = false; + if (coap_opt_get_uint(pkt, COAP_OPT_OBSERVE, &obs)) { + /* No (valid) observe option present */ + obs = UINT32_MAX; + } + + uint32_t now = ztimer_now(ZTIMER_MSEC); + + switch (obs) { + case 0: + /* register */ + if (nanocoap_register_observer(context, pkt) == 0) { + registered = true; + } + break; + case 1: + /* unregister */ + nanocoap_unregister_observer(context, pkt); + break; + default: + /* No (valid) observe option present --> ignore observe and handle + * as regular GET */ + break; + } + + const size_t estimated_data_len = + 4 /* Max Observe Option size */ + + 1 /* payload marker */ + + 10 /* strlen("4294967295"), 4294967295 == UINT32_MAX */ + + 1; /* '\n' */ + ssize_t hdr_len = coap_build_reply(pkt, COAP_CODE_CONTENT, buf, len, estimated_data_len); + + if (hdr_len < 0) { + /* we undo any potential registration if we cannot reply */ + nanocoap_unregister_observer(context, pkt); + return len; + } + + if (hdr_len == 0) { + /* no response required, probably because of no-response option matching + * the response class */ + return 0; + } + + /* coap_build_reply() is a bit goofy: It returns the size of the written + * header + `estiamted_data_len`, so we have to subtract it again to obtain + * the size of data written. */ + uint8_t *pos = buf + hdr_len - estimated_data_len; + + if (registered) { + uint16_t last_opt = 0; + pos += coap_opt_put_observe(pos, last_opt, now); + } + *pos++ = COAP_PAYLOAD_MARKER; + pos += fmt_u32_dec((void *)pos, now); + *pos++ = '\n'; + + return (uintptr_t)pos - (uintptr_t)buf; +} + +NANOCOAP_RESOURCE(time) { + .path = "/time", .methods = COAP_GET, .handler = _time_handler, +}; + +static void _notify_observer_handler(event_t *ev) +{ + (void)ev; + uint32_t now = ztimer_now(ZTIMER_MSEC); + uint8_t buf[32]; + uint8_t *pos = buf; + uint16_t last_opt = 0; + pos += coap_opt_put_observe(pos, last_opt, now); + *pos++ = COAP_PAYLOAD_MARKER; + pos += fmt_u32_dec((void *)pos, now); + *pos++ = '\n'; + iolist_t data = { + .iol_base = buf, + .iol_len = (uintptr_t)pos - (uintptr_t)buf, + }; + + /* `NANOCOAP_RESOURCE(time)` expends to XFA magic adding an entry named + * `coap_resource_time`. */ + nanocoap_notify_observers(&coap_resource_time, &data); +} + +void setup_observe_event(void) +{ + static event_t ev = { + .handler = _notify_observer_handler + }; + static event_periodic_t pev; + + event_periodic_init(&pev, ZTIMER_MSEC, EVENT_PRIO_MEDIUM, &ev); + event_periodic_start(&pev, MS_PER_SEC); +} +#endif /* MODULE_NANOCOAP_SERVER_OBSERVE */ + /* we can also include the fileserver module */ #ifdef MODULE_NANOCOAP_FILESERVER #include "net/nanocoap/fileserver.h" diff --git a/examples/nanocoap_server/main.c b/examples/nanocoap_server/main.c index 739a63e3d96f..72dba3209f49 100644 --- a/examples/nanocoap_server/main.c +++ b/examples/nanocoap_server/main.c @@ -20,13 +20,15 @@ #include #include "net/nanocoap_sock.h" -#include "xtimer.h" +#include "ztimer.h" #define COAP_INBUF_SIZE (256U) #define MAIN_QUEUE_SIZE (8) static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; +extern void setup_observe_event(void); + int main(void) { puts("RIOT nanocoap example application"); @@ -35,7 +37,11 @@ int main(void) msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); puts("Waiting for address autoconfiguration..."); - xtimer_sleep(3); + ztimer_sleep(ZTIMER_MSEC, 3 * MS_PER_SEC); + + if (IS_USED(MODULE_NANOCOAP_SERVER_OBSERVE)) { + setup_observe_event(); + } /* print network addresses */ printf("{\"IPv6 addresses\": [\""); diff --git a/examples/paho-mqtt/Makefile.ci b/examples/paho-mqtt/Makefile.ci index bf491e5b51bb..478563df14aa 100644 --- a/examples/paho-mqtt/Makefile.ci +++ b/examples/paho-mqtt/Makefile.ci @@ -26,7 +26,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/posix_sockets/Makefile.ci b/examples/posix_sockets/Makefile.ci index 8a8fa6637c96..7ec03bcde535 100644 --- a/examples/posix_sockets/Makefile.ci +++ b/examples/posix_sockets/Makefile.ci @@ -16,7 +16,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430h \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/examples/rust-gcoap/Makefile.ci b/examples/rust-gcoap/Makefile.ci index cf8d98ffa9e5..65bdec1a8cfa 100644 --- a/examples/rust-gcoap/Makefile.ci +++ b/examples/rust-gcoap/Makefile.ci @@ -24,7 +24,6 @@ BOARD_INSUFFICIENT_MEMORY := \ maple-mini \ microbit \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/sys/Makefile.dep b/sys/Makefile.dep index 00afb08a25ee..db8cef9c2a27 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -529,6 +529,10 @@ ifneq (,$(filter nanocoap_server_auto_init,$(USEMODULE))) USEMODULE += nanocoap_server endif +ifneq (,$(filter nanocoap_server_observe,$(USEMODULE))) + USEMODULE += nanocoap_server_separate +endif + ifneq (,$(filter nanocoap_server_separate,$(USEMODULE))) USEMODULE += nanocoap_server USEMODULE += sock_aux_local diff --git a/sys/include/net/coap.h b/sys/include/net/coap.h index 275510463d51..797d4d7f8a73 100644 --- a/sys/include/net/coap.h +++ b/sys/include/net/coap.h @@ -519,6 +519,7 @@ typedef enum { */ #define COAP_OBS_REGISTER (0) #define COAP_OBS_DEREGISTER (1) +#define COAP_OBS_MAX_VALUE_MASK (0xffffff) /**< observe value is 24 bits */ /** @} */ /** diff --git a/sys/include/net/nanocoap.h b/sys/include/net/nanocoap.h index 45fc28ed2660..4ae8107736e3 100644 --- a/sys/include/net/nanocoap.h +++ b/sys/include/net/nanocoap.h @@ -1790,6 +1790,22 @@ static inline size_t coap_opt_put_block2_control(uint8_t *buf, uint16_t lastonum (block->blknum << 4) | block->szx); } +/** + * @brief Insert an CoAP Observe Option into the buffer + * + * @param[out] buf Buffer to write to + * @param[in] lastonum last option number (must be < 6) + * @param[in] obs observe number to write + * + * @returns amount of bytes written to @p buf + */ +static inline size_t coap_opt_put_observe(uint8_t *buf, uint16_t lastonum, + uint32_t obs) +{ + obs &= COAP_OBS_MAX_VALUE_MASK; /* trim obs down to 24 bit */ + return coap_opt_put_uint(buf, lastonum, COAP_OPT_OBSERVE, obs); +} + /** * @brief Encode the given string as multi-part option into buffer * diff --git a/sys/include/net/nanocoap_sock.h b/sys/include/net/nanocoap_sock.h index 9bdf41ce2f6c..d74c629e046e 100644 --- a/sys/include/net/nanocoap_sock.h +++ b/sys/include/net/nanocoap_sock.h @@ -261,7 +261,20 @@ int nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx, coap_pkt_t *pkt, const coap_request_ctx_t *req); /** - * @brief Send a separate response to a CoAP request + * @brief Check if a given separate response context was prepared for the + * remote endpoint of a given request + * + * @param[in] ctx Separate response context to check + * @param[in] req Request from the remote to check for + * + * @retval true The remote endpoint given by @p req is in @p ctx + * @retval false @p ctx was prepared for a different remote endpoint + */ +bool nanocoap_server_is_remote_in_response_ctx(const nanocoap_server_response_ctx_t *ctx, + const coap_request_ctx_t *req); + +/** + * @brief Build and send a separate response to a CoAP request * * This sends a response to a CoAP request outside the CoAP handler * @@ -279,12 +292,159 @@ int nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx, * @param[in] payload Response payload * @param[in] len Payload length * - * @returns 0 on success - * negative error (see @ref sock_udp_sendv_aux) + * @retval 0 Success + * @retval -ECANCELED Request contained no-response option that did match the given @p code + * @retval <0 Negative errno code indicating the error */ int nanocoap_server_send_separate(const nanocoap_server_response_ctx_t *ctx, unsigned code, unsigned type, const void *payload, size_t len); + +/** + * @brief Build a separate response header to a CoAP request + * + * This builds the response packet header. You may add CoAP Options, a payload + * marker and a payload as needed after the header. + * + * @pre @ref nanocoap_server_prepare_separate has been called on @p ctx + * inside the CoAP handler + * @pre Synchronization between calls of this function and calls of + * @ref nanocoap_server_prepare_separate is ensured + * + * @warning This function is only available when using the module + * `nanocoap_server_separate` + * + * @param[in] ctx Context information for the CoAP response + * @param[out] buf Buffer to write the header to + * @param[in] buf_len Length of @p buf in bytes + * @param[in] code CoAP response code + * @param[in] type Response type, may be `COAP_TYPE_NON` + * @param[in] msg_id Message ID to send + * + * @return Length of the header build in bytes + * @retval -ECANCELED Request contained no-response option that did match the given @p code + * @retval <0 Negative errno code indicating the error + */ +ssize_t nanocoap_server_build_separate(const nanocoap_server_response_ctx_t *ctx, + void *buf, size_t buf_len, + unsigned code, unsigned type, + uint16_t msg_id); + +/** + * @brief Send an already build separate response + * + * @pre @ref nanocoap_server_prepare_separate has been called on @p ctx + * inside the CoAP handler + * @pre Synchronization between calls of this function and calls of + * @ref nanocoap_server_prepare_separate is ensured + * @pre @ref nanocoap_server_build_separate has been used to build the + * header in @p msg + * + * @warning This function is only available when using the module + * `nanocoap_server_separate` + * + * @param[in] ctx Context information for the CoAP response + * @param[in] reply I/O list containing the reply to send + * + * @retval 0 Success + * @retval <0 negative errno code indicating the error + */ +int nanocoap_server_sendv_separate(const nanocoap_server_response_ctx_t *ctx, + const iolist_t *reply); + +/** + * @brief Register an observer + * @param[in] req_ctx Request context belonging to @p req_pkt + * @param[in,out] req_pkt Request that contained the observe registration request + * + * @warning This depends on module `nanocoap_server_observe` + * + * @note If the same endpoint already was registered on the same resource, + * it will just update the token and keep the existing entry. This + * way duplicate detection is not needed and we eagerly can reclaim + * resources when a client lost state. + * + * @warning Preventing the same endpoint to registers more than once (using + * different tokens) to the same resource deviates from RFC 7641. + * + * The deviation here is intentional. A server can receive a second registration + * from the same endpoint for the same resource for one of the following + * reasons: + * + * 1. Reaffirming the registration by using the same token again. + * 2. Losing state on the client side. + * 3. A malicious client trying to exhaust resources. + * 4. The same resource has different representations depending on the + * request. (E.g. `/.well-known/core` can yield a wildly different response + * depending on filters provided via URI-Query Options.) + * + * For case 1 updating the registration is matching what the spec mandates. + * For two the old registration will not be of value for the client, and + * overwriting it makes more efficient use of network bandwidth and RAM. + * For 3 the deviation forces the adversary to send observe requests from + * different ports to exhaust resources, which is a very minor improvement. + * For 4 the deviation is a problem. However, the observe API does not allow to + * send out different notification messages for the same resource anyway, so + * case 4 cannot occur here. + * + * @retval 0 Success + * @retval -ENOMEM Not enough resources to register another observer + * @retval <0 Negative errno code indicating error + */ +int nanocoap_register_observer(const coap_request_ctx_t *req_ctx, coap_pkt_t *req_pkt); + +/** + * @brief Unregister an observer + * @param req_ctx Request context belonging to @p req_pkt + * @param req_pkt Received request for unregistration + * + * @warning This depends on module `nanocoap_server_observe` + * + * @note It is safe to call this multiple times, e.g. duplicate detection + * is not needed for this. + */ +void nanocoap_unregister_observer(const coap_request_ctx_t *req_ctx, + const coap_pkt_t *req_pkt); + +/** + * @brief Unregister a stale observation due to a reset message received + * @param[in] ep Endpoint to wipe from the observer list + * @param[in] msg_id Message ID of the notification send. + */ +void nanocoap_unregister_observer_due_to_reset(const sock_udp_ep_t *ep, + uint16_t msg_id); + +/** + * @brief Notify all currently registered observers of the given resource + * + * @param[in] res Resource to send updates for + * @param[in] iol I/O list containing the CoAP Options, payload marker, + * and payload of the update to send up + * + * @pre @p iol contains everything but the CoAP header needed to send out. + * This will at least be a CoAP observe option, a payload marker, + * and a payload + * + * @post For each registered observer a CoAP packet header is generated and + * the concatenation of that header and the provided list is sent + */ +void nanocoap_notify_observers(const coap_resource_t *res, const iolist_t *iol); + +/** + * @brief Build and send notification to observers registered to a specific + * resource. + * + * @note Use @ref nanocoap_notify_observers for more control (such + * as adding custom options) over the notification(s) to send. + * + * @param[in] res Resource to send updates for + * @param[in] obs 24-bit number to add as observe option + * @param[in] payload Payload to send out + * @param[in] payload_len Length of @p payload in bytes + */ +void nanocoap_notify_observers_simple(const coap_resource_t *res, uint32_t obs, + const void *payload, size_t payload_len); + /** * @brief Get next consecutive message ID for use when building a new * CoAP request. diff --git a/sys/net/application_layer/nanocoap/nanocoap.c b/sys/net/application_layer/nanocoap/nanocoap.c index 5f6a6e8f0d29..3a5f4f5d08a4 100644 --- a/sys/net/application_layer/nanocoap/nanocoap.c +++ b/sys/net/application_layer/nanocoap/nanocoap.c @@ -28,6 +28,7 @@ #include "bitarithm.h" #include "net/nanocoap.h" +#include "net/nanocoap_sock.h" #define ENABLE_DEBUG 0 #include "debug.h" @@ -494,16 +495,45 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le { assert(ctx); + if (IS_USED(MODULE_NANOCOAP_SERVER_OBSERVE) && (coap_get_type(pkt) == COAP_TYPE_RST)) { + nanocoap_unregister_observer_due_to_reset(coap_request_ctx_get_remote_udp(ctx), + coap_get_id(pkt)); + } + + switch (coap_get_type(pkt)) { + case COAP_TYPE_CON: + case COAP_TYPE_NON: + /* could be a request ==> proceed */ + break; + default: + DEBUG_PUTS("coap_handle_req(): ignoring RST/ACK"); + return -EBADMSG; + } + if (coap_get_code_class(pkt) != COAP_REQ) { - DEBUG("coap_handle_req(): not a request.\n"); + DEBUG_PUTS("coap_handle_req(): not a request --> ignore"); return -EBADMSG; } - if (pkt->hdr->code == 0) { - return coap_build_reply(pkt, COAP_CODE_EMPTY, resp_buf, resp_buf_len, 0); + if (coap_get_code_raw(pkt) == COAP_CODE_EMPTY) { + /* we are not able to process a CON/NON message with an empty code, + * so we reply with a RST, unless we got a multicast message */ + if (!sock_udp_ep_is_multicast(coap_request_ctx_get_local_udp(ctx))) { + return coap_build_reply(pkt, COAP_CODE_EMPTY, resp_buf, resp_buf_len, 0); + } } - return coap_tree_handler(pkt, resp_buf, resp_buf_len, ctx, - coap_resources, coap_resources_numof); + + ssize_t retval = coap_tree_handler(pkt, resp_buf, resp_buf_len, ctx, + coap_resources, coap_resources_numof); + if (retval < 0) { + /* handlers were not able to process this, so we reply with a RST, + * unless we got a multicast message */ + if (!sock_udp_ep_is_multicast(coap_request_ctx_get_local_udp(ctx))) { + return coap_build_reply(pkt, COAP_CODE_EMPTY, resp_buf, resp_buf_len, 0); + } + } + + return retval; } ssize_t coap_subtree_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, diff --git a/sys/net/application_layer/nanocoap/sock.c b/sys/net/application_layer/nanocoap/sock.c index 0b3db123b777..06a852a3188c 100644 --- a/sys/net/application_layer/nanocoap/sock.c +++ b/sys/net/application_layer/nanocoap/sock.c @@ -25,16 +25,14 @@ #include #include -#include "atomic_utils.h" +#include "container.h" #include "net/credman.h" #include "net/nanocoap.h" #include "net/nanocoap_sock.h" -#include "net/sock/util.h" #include "net/sock/udp.h" -#include "net/iana/portrange.h" +#include "net/sock/util.h" #include "random.h" -#include "sys/uio.h" -#include "timex.h" +#include "sys/uio.h" /* IWYU pragma: keep (exports struct iovec) */ #include "ztimer.h" #define ENABLE_DEBUG 0 @@ -48,7 +46,11 @@ * if mode or key-size change especially if certificates instead of PSK are used. */ #ifndef CONFIG_NANOCOAP_DTLS_HANDSHAKE_BUF_SIZE -#define CONFIG_NANOCOAP_DTLS_HANDSHAKE_BUF_SIZE (160) +# define CONFIG_NANOCOAP_DTLS_HANDSHAKE_BUF_SIZE (160) +#endif + +#ifndef CONFIG_NANOCOAP_MAX_OBSERVERS +# define CONFIG_NANOCOAP_MAX_OBSERVERS 4 #endif enum { @@ -67,6 +69,35 @@ typedef struct { #endif } _block_ctx_t; +/** + * @brief Structure to track the state of an observation + */ +typedef struct { + /** + * @brief Context needed to build notifications (e.g. Token, endpoint + * to send to) + * + * @details To safe ROM, we reuse the separate response code to also + * send notifications, as the functionality is almost identical. + */ + nanocoap_server_response_ctx_t response; + /** + * @brief The resource the client has subscribed to + * + * @details This is `NULL` when the slot is free + */ + const coap_resource_t *resource; + /** + * @brief Message ID used in the last notification + */ + uint16_t msg_id; +} _observer_t; + +#if MODULE_NANOCOAP_SERVER_OBSERVE +static _observer_t _observer_pool[CONFIG_NANOCOAP_MAX_OBSERVERS]; +static mutex_t _observer_pool_lock; +#endif + int nanocoap_sock_dtls_connect(nanocoap_sock_t *sock, sock_udp_ep_t *local, const sock_udp_ep_t *remote, credman_tag_t tag) { @@ -1111,13 +1142,22 @@ int nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx, return 0; } -int nanocoap_server_send_separate(const nanocoap_server_response_ctx_t *ctx, - unsigned code, unsigned type, - const void *payload, size_t len) +bool nanocoap_server_is_remote_in_response_ctx(const nanocoap_server_response_ctx_t *ctx, + const coap_request_ctx_t *req) +{ + return sock_udp_ep_equal(&ctx->remote, req->remote); +} + +ssize_t nanocoap_server_build_separate(const nanocoap_server_response_ctx_t *ctx, + void *buf, size_t buf_len, + unsigned code, unsigned type, + uint16_t msg_id) { - uint8_t rbuf[sizeof(coap_hdr_t) + COAP_TOKEN_LENGTH_MAX + 1]; assert(type != COAP_TYPE_ACK); assert(type != COAP_TYPE_CON); /* TODO: add support */ + if ((sizeof(coap_hdr_t) + COAP_TOKEN_LENGTH_MAX + 1) > buf_len) { + return -EOVERFLOW; + } const uint8_t no_response_index = (code >> 5) - 1; /* If the handler code misbehaved here, we'd face UB otherwise */ @@ -1125,7 +1165,49 @@ int nanocoap_server_send_separate(const nanocoap_server_response_ctx_t *ctx, const uint8_t mask = 1 << no_response_index; if (ctx->no_response & mask) { - return 0; + return -ECANCELED; + } + + return coap_build_hdr(buf, type, ctx->token, ctx->tkl, code, msg_id); +} + +int nanocoap_server_sendv_separate(const nanocoap_server_response_ctx_t *ctx, + const iolist_t *reply) +{ + sock_udp_aux_tx_t *aux_out_ptr = NULL; + /* make sure we reply with the same address that the request was + * destined for -- except in the multicast case */ + sock_udp_aux_tx_t aux_out = { + .flags = SOCK_AUX_SET_LOCAL, + .local = ctx->local, + }; + if (!sock_udp_ep_is_multicast(&ctx->local)) { + aux_out_ptr = &aux_out; + } + ssize_t retval = sock_udp_sendv_aux(NULL, reply, &ctx->remote, aux_out_ptr); + + if (retval < 0) { + return retval; + } + + return 0; +} + +int nanocoap_server_send_separate(const nanocoap_server_response_ctx_t *ctx, + unsigned code, unsigned type, + const void *payload, size_t len) +{ + uint8_t rbuf[sizeof(coap_hdr_t) + COAP_TOKEN_LENGTH_MAX + 1]; + + ssize_t hdr_len = nanocoap_server_build_separate(ctx, rbuf, sizeof(rbuf), + code, type, random_uint32()); + if (hdr_len < 0) { + return hdr_len; + } + + /* add payload marker if needed */ + if (len) { + rbuf[hdr_len++] = 0xFF; } iolist_t data = { @@ -1136,24 +1218,126 @@ int nanocoap_server_send_separate(const nanocoap_server_response_ctx_t *ctx, iolist_t head = { .iol_next = &data, .iol_base = rbuf, + .iol_len = hdr_len, }; - head.iol_len = coap_build_hdr((coap_hdr_t *)rbuf, type, - ctx->token, ctx->tkl, - code, random_uint32()); - if (len) { - rbuf[head.iol_len++] = 0xFF; + + return nanocoap_server_sendv_separate(ctx, &head); +} +#endif + +#if MODULE_NANOCOAP_SERVER_OBSERVE +int nanocoap_register_observer(const coap_request_ctx_t *req_ctx, coap_pkt_t *req_pkt) +{ + mutex_lock(&_observer_pool_lock); + + _observer_t *free = NULL; + const coap_resource_t *resource = req_ctx->resource; + + for (size_t i = 0; i < CONFIG_NANOCOAP_MAX_OBSERVERS; i++) { + if (_observer_pool[i].resource == NULL) { + free = &_observer_pool[i]; + } + if ((_observer_pool[i].resource == resource) + && sock_udp_ep_equal(&_observer_pool[i].response.remote, + coap_request_ctx_get_remote_udp(req_ctx))) + { + /* Deviation from the standard: Subscribing twice makes no + * sense with our CoAP implementation, so either this is a + * reaffirmation of an existing subscription (same token) or the + * client lost state (different token). We just update the + * subscription in either case */ + DEBUG("nanocoap: observe slot %" PRIuSIZE " reused\n", i); + uint8_t tkl = coap_get_token_len(req_pkt); + _observer_pool[i].response.tkl = tkl; + memcpy(_observer_pool[i].response.token, coap_get_token(req_pkt), tkl); + mutex_unlock(&_observer_pool_lock); + return 0; + } } - sock_udp_aux_tx_t *aux_out_ptr = NULL; - /* make sure we reply with the same address that the request was - * destined for -- except in the multicast case */ - sock_udp_aux_tx_t aux_out = { - .flags = SOCK_AUX_SET_LOCAL, - .local = ctx->local, - }; - if (!sock_udp_ep_is_multicast(&ctx->local)) { - aux_out_ptr = &aux_out; + if (!free) { + DEBUG_PUTS("nanocoap: observe registration failed, no free slot"); + mutex_unlock(&_observer_pool_lock); + return -ENOMEM; + } + + int retval = nanocoap_server_prepare_separate(&free->response, req_pkt, req_ctx); + if (retval) { + DEBUG("nanocoap: observe registration failed: %d\n", retval); + mutex_unlock(&_observer_pool_lock); + return retval; + } + free->resource = req_ctx->resource; + free->msg_id = random_uint32(); + mutex_unlock(&_observer_pool_lock); + DEBUG("nanocoap: new observe registration at slot %" PRIuSIZE "\n", + index_of(_observer_pool, free)); + return 0; +} + +void nanocoap_unregister_observer(const coap_request_ctx_t *req_ctx, + const coap_pkt_t *req_pkt) +{ + mutex_lock(&_observer_pool_lock); + for (size_t i = 0; i < CONFIG_NANOCOAP_MAX_OBSERVERS; i++) { + if ((_observer_pool[i].resource == req_ctx->resource) + && (_observer_pool[i].response.tkl == coap_get_token_len(req_pkt)) + && !memcmp(_observer_pool[i].response.token, coap_get_token(req_pkt), + _observer_pool[i].response.tkl) + && sock_udp_ep_equal(&_observer_pool[i].response.remote, coap_request_ctx_get_remote_udp(req_ctx))) { + DEBUG("nanocoap: observer at index %" PRIuSIZE " unregistered\n", i); + _observer_pool[i].resource = NULL; + } + } + mutex_unlock(&_observer_pool_lock); +} + +void nanocoap_unregister_observer_due_to_reset(const sock_udp_ep_t *ep, + uint16_t msg_id) +{ + mutex_lock(&_observer_pool_lock); + for (size_t i = 0; i < CONFIG_NANOCOAP_MAX_OBSERVERS; i++) { + if ((_observer_pool[i].resource != NULL) + && (_observer_pool[i].msg_id == msg_id) + && sock_udp_ep_equal(&_observer_pool[i].response.remote, ep)) { + DEBUG("nanocoap: observer at index %" PRIuSIZE " unregistered due to RST\n", i); + _observer_pool[i].resource = NULL; + return; + } + } + mutex_unlock(&_observer_pool_lock); +} + +void nanocoap_notify_observers(const coap_resource_t *res, const iolist_t *iol) +{ + mutex_lock(&_observer_pool_lock); + for (size_t i = 0; i < CONFIG_NANOCOAP_MAX_OBSERVERS; i++) { + if (_observer_pool[i].resource == res) { + uint8_t rbuf[sizeof(coap_hdr_t) + COAP_TOKEN_LENGTH_MAX + 1]; + + ssize_t hdr_len = nanocoap_server_build_separate(&_observer_pool[i].response, rbuf, sizeof(rbuf), + COAP_CODE_CONTENT, COAP_TYPE_NON, + ++_observer_pool[i].msg_id); + if (hdr_len < 0) { + /* no need to keep the observer in the pool, if we cannot + * send anyway */ + _observer_pool[i].resource = NULL; + continue; + } + + const iolist_t msg = { + .iol_base = rbuf, + .iol_len = hdr_len, + .iol_next = (iolist_t *)iol + }; + + if (nanocoap_server_sendv_separate(&_observer_pool[i].response, &msg)) { + /* no need to keep the observer in the pool, if we cannot + * send anyway */ + _observer_pool[i].resource = NULL; + } + } } - return sock_udp_sendv_aux(NULL, &head, &ctx->remote, aux_out_ptr); + mutex_unlock(&_observer_pool_lock); } #endif diff --git a/sys/tiny_strerror/tiny_strerror.c b/sys/tiny_strerror/tiny_strerror.c index 77732f4d7864..386d1686d2fc 100644 --- a/sys/tiny_strerror/tiny_strerror.c +++ b/sys/tiny_strerror/tiny_strerror.c @@ -48,7 +48,9 @@ static FLASH_ATTR const char _edquot[] = "-EDQUOT"; static FLASH_ATTR const char _eexist[] = "-EEXIST"; static FLASH_ATTR const char _efault[] = "-EFAULT"; static FLASH_ATTR const char _efbig[] = "-EFBIG"; +#ifdef EHOSTDOWN /* not part of POSIX and not universally available */ static FLASH_ATTR const char _ehostdown[] = "-EHOSTDOWN"; +#endif static FLASH_ATTR const char _ehostunreach[] = "-EHOSTUNREACH"; static FLASH_ATTR const char _eidrm[] = "-EIDRM"; static FLASH_ATTR const char _eilseq[] = "-EILSEQ"; @@ -93,7 +95,9 @@ static FLASH_ATTR const char _enxio[] = "-ENXIO"; static FLASH_ATTR const char _eoverflow[] = "-EOVERFLOW"; static FLASH_ATTR const char _eownerdead[] = "-EOWNERDEAD"; static FLASH_ATTR const char _eperm[] = "-EPERM"; +#ifdef EPFNOSUPPORT /* not part of POSIX and not universally available */ static FLASH_ATTR const char _epfnosupport[] = "-EPFNOSUPPORT"; +#endif static FLASH_ATTR const char _epipe[] = "-EPIPE"; static FLASH_ATTR const char _eprotonosupport[] = "-EPROTONOSUPPORT"; static FLASH_ATTR const char _eprototype[] = "-EPROTOTYPE"; @@ -105,7 +109,9 @@ static FLASH_ATTR const char _esrch[] = "-ESRCH"; static FLASH_ATTR const char _estale[] = "-ESTALE"; static FLASH_ATTR const char _etimedout[] = "-ETIMEDOUT"; static FLASH_ATTR const char _etime[] = "-ETIME"; +#ifdef ETOOMANYREFS /* not part of POSIX and not universally available */ static FLASH_ATTR const char _etoomanyrefs[] = "-ETOOMANYREFS"; +#endif static FLASH_ATTR const char _etxtbsy[] = "-ETXTBSY"; static FLASH_ATTR const char _exdev[] = "-EXDEV"; /* EAGAIN and EWOULDBLOCK have the exact same meaning and consequently may @@ -143,7 +149,9 @@ static FLASH_ATTR const char * FLASH_ATTR const lookup[] = { [EEXIST] = _eexist, [EFAULT] = _efault, [EFBIG] = _efbig, +#ifdef EHOSTDOWN /* not part of POSIX and not universally available */ [EHOSTDOWN] = _ehostdown, +#endif [EHOSTUNREACH] = _ehostunreach, [EIDRM] = _eidrm, [EILSEQ] = _eilseq, @@ -188,7 +196,9 @@ static FLASH_ATTR const char * FLASH_ATTR const lookup[] = { [EOVERFLOW] = _eoverflow, [EOWNERDEAD ] = _eownerdead, [EPERM] = _eperm, +#ifdef EPFNOSUPPORT /* not part of POSIX and not universally available */ [EPFNOSUPPORT] = _epfnosupport, +#endif [EPIPE] = _epipe, [EPROTONOSUPPORT] = _eprotonosupport, [EPROTOTYPE] = _eprototype, @@ -200,7 +210,9 @@ static FLASH_ATTR const char * FLASH_ATTR const lookup[] = { [ESTALE] = _estale, [ETIMEDOUT] = _etimedout, [ETIME] = _etime, +#ifdef ETOOMANYREFS /* not part of POSIX and not universally available */ [ETOOMANYREFS] = _etoomanyrefs, +#endif [ETXTBSY] = _etxtbsy, [EXDEV] = _exdev, #if EAGAIN != EWOULDBLOCK diff --git a/tests/bench/xtimer/Makefile b/tests/bench/xtimer/Makefile index 0de2634d33c8..c07f5fecb664 100644 --- a/tests/bench/xtimer/Makefile +++ b/tests/bench/xtimer/Makefile @@ -42,7 +42,6 @@ LOW_MEMORY_BOARDS += \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-f030r8 \ nucleo-f042k6 \ nucleo-f070rb \ diff --git a/tests/bench/ztimer/Makefile b/tests/bench/ztimer/Makefile index 57b12aea2c88..6a77b15e3369 100644 --- a/tests/bench/ztimer/Makefile +++ b/tests/bench/ztimer/Makefile @@ -42,7 +42,6 @@ LOW_MEMORY_BOARDS += \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-f030r8 \ nucleo-f042k6 \ nucleo-f070rb \ diff --git a/tests/core/thread_float/Makefile.ci b/tests/core/thread_float/Makefile.ci index 53bfe5b5a6d7..67f931300a89 100644 --- a/tests/core/thread_float/Makefile.ci +++ b/tests/core/thread_float/Makefile.ci @@ -13,7 +13,6 @@ BOARD_INSUFFICIENT_MEMORY := \ mbed_lpc1768 \ microbit \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f031k6 \ nucleo-f042k6 \ diff --git a/tests/drivers/nrf802154/README.md b/tests/drivers/nrf802154/README.md index 6d0620ccaca2..28e0664b0f10 100644 --- a/tests/drivers/nrf802154/README.md +++ b/tests/drivers/nrf802154/README.md @@ -1,6 +1,11 @@ # About This is a manual test application for the NRF802154 radio driver. +Supported boards must have an nRF52-series chip that has an IEEE 802.15.4 radio (e.g. nrf52840dk). # Usage For testing the radio driver you can use the ifconfig and txtsnd shell commands that are included in this application. + +For testing beacon frame acceptance you can flash this test onto two nRF52 devices +and use the beaconsend command to send an IEEE 802.15.4 beacon frame. +The opponent should print the received frame details. \ No newline at end of file diff --git a/tests/drivers/nrf802154/main.c b/tests/drivers/nrf802154/main.c index 32a3f4f9c8ce..3ce0ae635863 100644 --- a/tests/drivers/nrf802154/main.c +++ b/tests/drivers/nrf802154/main.c @@ -52,6 +52,77 @@ int netdev_ieee802154_minimal_init_devs(netdev_event_cb_t cb) { return 0; } +void send_beacon_usage(char *cmd_name) +{ + printf("usage: %s [<16 bit hex source PAN ID>] (uses device PAN ID by default)\n", cmd_name); +} + +int cmd_send_beacon(int argc, char **argv) +{ + uint16_t pan_id; + /* evaluating if argument is present */ + switch (argc) { + case 1: + pan_id = nrf802154.dev.pan; + puts("using device PAN ID as source"); + break; + case 2: + if (strlen(argv[1]) != 4) { + puts("send: Error parsing PAN ID"); + send_beacon_usage(argv[0]); + return 1; + } + pan_id = strtoul(argv[1], NULL, 16); + break; + default: + send_beacon_usage(argv[0]); + return 1; + } + + printf("PAN ID: %x\n", pan_id); + + /* preparing the mac header */ + uint8_t mhr[IEEE802154_MAX_HDR_LEN]; + memset(mhr, 0, IEEE802154_MAX_HDR_LEN*sizeof(uint8_t)); + le_uint16_t src_pan = byteorder_btols(byteorder_htons(pan_id)); + le_uint16_t dst_pan = byteorder_htols(0); + size_t src_len = 2, dst_len = 0; + uint8_t *src = nrf802154.dev.short_addr, *dst = NULL; + uint8_t flags = IEEE802154_FCF_TYPE_BEACON; + + int res = ieee802154_set_frame_hdr(mhr, src, src_len, + dst, dst_len, + src_pan, dst_pan, + flags, nrf802154.dev.seq++); + if (res < 0) { + puts("send: Error preparing frame"); + send_beacon_usage(argv[0]); + return 1; + } + /* preparing packet to send */ + iolist_t iol = { + .iol_base = mhr, + .iol_len = (size_t)res, + .iol_next = NULL, + }; + + puts("Sending Beacon Frame"); + + res = netdev_ieee802154_minimal_send(&nrf802154.dev.netdev, &iol); + + if (res < 0) { + puts("send: Error on sending"); + send_beacon_usage(argv[0]); + return 1; + } + return 0; +} + +static const shell_command_t shell_commands[] = { + { "beaconsend", "Send an IEEE 802.15.4 beacon frame", cmd_send_beacon}, + {NULL, NULL, NULL} +}; + int main(void) { puts("Test application for NRF802154 IEEE 802.15.4 device driver"); @@ -66,7 +137,7 @@ int main(void) puts("Initialization successful - starting the shell now"); char line_buf[SHELL_DEFAULT_BUFSIZE]; - shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); return 0; } diff --git a/tests/net/emcute/Makefile.ci b/tests/net/emcute/Makefile.ci index e5f52901fd5c..621b90a35ae5 100644 --- a/tests/net/emcute/Makefile.ci +++ b/tests/net/emcute/Makefile.ci @@ -32,7 +32,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/net/gcoap_dns/Makefile.ci b/tests/net/gcoap_dns/Makefile.ci index 9345fcf9bd08..1b380b3cf988 100644 --- a/tests/net/gcoap_dns/Makefile.ci +++ b/tests/net/gcoap_dns/Makefile.ci @@ -27,7 +27,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/net/gcoap_forward_proxy/Makefile.ci b/tests/net/gcoap_forward_proxy/Makefile.ci index a690f42ba7f3..d3841a237454 100644 --- a/tests/net/gcoap_forward_proxy/Makefile.ci +++ b/tests/net/gcoap_forward_proxy/Makefile.ci @@ -25,7 +25,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/net/gnrc_dhcpv6_client_6lbr/Makefile.ci b/tests/net/gnrc_dhcpv6_client_6lbr/Makefile.ci index 29cc1722c05b..47da52310736 100644 --- a/tests/net/gnrc_dhcpv6_client_6lbr/Makefile.ci +++ b/tests/net/gnrc_dhcpv6_client_6lbr/Makefile.ci @@ -35,7 +35,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/net/gnrc_dhcpv6_client_stateless/Makefile.ci b/tests/net/gnrc_dhcpv6_client_stateless/Makefile.ci index f6eff6ae22dd..05d00f92c319 100644 --- a/tests/net/gnrc_dhcpv6_client_stateless/Makefile.ci +++ b/tests/net/gnrc_dhcpv6_client_stateless/Makefile.ci @@ -23,7 +23,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/net/gnrc_netif/Makefile.ci b/tests/net/gnrc_netif/Makefile.ci index a66475848ac6..00d55166d338 100644 --- a/tests/net/gnrc_netif/Makefile.ci +++ b/tests/net/gnrc_netif/Makefile.ci @@ -36,7 +36,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430h \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/net/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile.ci b/tests/net/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile.ci index 99e38a371fad..7980875d5d4e 100644 --- a/tests/net/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile.ci +++ b/tests/net/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile.ci @@ -27,7 +27,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/net/gnrc_udp/Makefile.ci b/tests/net/gnrc_udp/Makefile.ci index 0308a88f80df..51104b119ef8 100644 --- a/tests/net/gnrc_udp/Makefile.ci +++ b/tests/net/gnrc_udp/Makefile.ci @@ -23,7 +23,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/periph/uart/Makefile b/tests/periph/uart/Makefile index b60500e81f0e..c8ec516c0fd3 100644 --- a/tests/periph/uart/Makefile +++ b/tests/periph/uart/Makefile @@ -6,6 +6,7 @@ FEATURES_OPTIONAL += periph_uart_collision FEATURES_OPTIONAL += periph_uart_modecfg FEATURES_OPTIONAL += periph_uart_rxstart_irq +USEMODULE += bitfield USEMODULE += shell USEMODULE += ztimer_msec diff --git a/tests/periph/uart/main.c b/tests/periph/uart/main.c index 6c5a17a6eacb..b7b36f597650 100644 --- a/tests/periph/uart/main.c +++ b/tests/periph/uart/main.c @@ -22,11 +22,12 @@ #include #include -#include "shell.h" -#include "thread.h" +#include "bitfield.h" #include "msg.h" -#include "ringbuffer.h" #include "periph/uart.h" +#include "ringbuffer.h" +#include "shell.h" +#include "thread.h" #include "ztimer.h" #ifdef MODULE_STDIO_UART @@ -86,6 +87,8 @@ static uart_stop_bits_t stop_bits_lut[] = { UART_STOP_BITS_1, UART_STOP_BITS_2 } static int stop_bits_lut_len = ARRAY_SIZE(stop_bits_lut); #endif +static BITFIELD(uarts_initialized_mask, UART_NUMOF); + static int parse_dev(char *arg) { unsigned dev = atoi(arg); @@ -180,6 +183,9 @@ static int _self_test(uart_t dev, unsigned baud) uart_collision_detect_disable(dev); #endif + uart_poweroff(UART_DEV(dev)); + + test_mode = false; return 0; failure: @@ -248,6 +254,11 @@ static int cmd_init(int argc, char **argv) } baud = strtol(argv[2], NULL, 0); + if (bf_isset(uarts_initialized_mask, dev)) { + uart_poweroff(UART_DEV(dev)); + bf_unset(uarts_initialized_mask, dev); + } + /* initialize UART */ res = uart_init(UART_DEV(dev), baud, rx_cb, (void *)(intptr_t)dev); if (res == UART_NOBAUD) { @@ -260,6 +271,8 @@ static int cmd_init(int argc, char **argv) } printf("Success: Initialized UART_DEV(%i) at BAUD %"PRIu32"\n", dev, baud); + bf_set(uarts_initialized_mask, dev); + /* also test if poweron() and poweroff() work (or at least don't break * anything) */ sleep_test(dev, UART_DEV(dev)); @@ -396,6 +409,11 @@ static int cmd_test(int argc, char **argv) puts("[START]"); + if (bf_isset(uarts_initialized_mask, dev)) { + uart_poweroff(UART_DEV(dev)); + bf_unset(uarts_initialized_mask, dev); + } + /* run self test with different baud rates */ test_mode = true; for (unsigned i = 1; i <= 12; ++i) { diff --git a/tests/pkg/cmsis-dsp/Makefile b/tests/pkg/cmsis-dsp/Makefile index 75d308d8d603..8616b92e5318 100644 --- a/tests/pkg/cmsis-dsp/Makefile +++ b/tests/pkg/cmsis-dsp/Makefile @@ -34,7 +34,6 @@ BOARD_WHITELIST := \ stm32f4discovery \ udoo \ yunjia-nrf51822 \ - nrf6310 \ # include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg/edhoc_c/Makefile.ci b/tests/pkg/edhoc_c/Makefile.ci index 89ef9b6b2a82..2906674e8204 100644 --- a/tests/pkg/edhoc_c/Makefile.ci +++ b/tests/pkg/edhoc_c/Makefile.ci @@ -19,7 +19,6 @@ BOARD_INSUFFICIENT_MEMORY := \ microbit \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-f030r8 \ nucleo-f031k6 \ nucleo-f042k6 \ diff --git a/tests/pkg/lwip/Makefile.ci b/tests/pkg/lwip/Makefile.ci index bca4d0c08d00..81b37f75782c 100644 --- a/tests/pkg/lwip/Makefile.ci +++ b/tests/pkg/lwip/Makefile.ci @@ -4,7 +4,6 @@ BOARD_INSUFFICIENT_MEMORY := \ bluepill-stm32f030c8 \ bluepill-stm32f103c8 \ i-nucleo-lrwan1 \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/pkg/lz4/Makefile.ci b/tests/pkg/lz4/Makefile.ci index c4b1317f3c4a..33a3a5743f8d 100644 --- a/tests/pkg/lz4/Makefile.ci +++ b/tests/pkg/lz4/Makefile.ci @@ -19,7 +19,6 @@ BOARD_INSUFFICIENT_MEMORY := \ im880b \ microbit \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/pkg/nimble_ext_adv/Makefile.ci b/tests/pkg/nimble_ext_adv/Makefile.ci index b0a9d107df38..44a3e94f66b8 100644 --- a/tests/pkg/nimble_ext_adv/Makefile.ci +++ b/tests/pkg/nimble_ext_adv/Makefile.ci @@ -3,6 +3,5 @@ BOARD_INSUFFICIENT_MEMORY := \ calliope-mini \ microbit \ nrf51dongle \ - nrf6310 \ yunjia-nrf51822 \ # diff --git a/tests/pkg/nimble_l2cap_server/nimble.inc.mk b/tests/pkg/nimble_l2cap_server/nimble.inc.mk index e00afed23b26..ec3020c81fd4 100644 --- a/tests/pkg/nimble_l2cap_server/nimble.inc.mk +++ b/tests/pkg/nimble_l2cap_server/nimble.inc.mk @@ -3,7 +3,7 @@ # Note: as the CPU variable is not set at this point, we manually 'whitelist' # all supported nrf51-boards here BOARDS_NRF51 := airfy-beacon calliope-mini microbit nrf51dk nrf51dongle \ - nrf6310 yunjia-nrf51822 + yunjia-nrf51822 ifneq (,$(filter $(BOARDS_NRF51),$(BOARD))) APP_MTU ?= 250 MSYS_CNT ?= 6 diff --git a/tests/pkg/tinydtls_sock_async/Makefile.ci b/tests/pkg/tinydtls_sock_async/Makefile.ci index 29cc1722c05b..47da52310736 100644 --- a/tests/pkg/tinydtls_sock_async/Makefile.ci +++ b/tests/pkg/tinydtls_sock_async/Makefile.ci @@ -35,7 +35,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msb-430 \ msb-430h \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/sys/conn_can/Makefile.ci b/tests/sys/conn_can/Makefile.ci index 878ed9073928..1f2135f204de 100644 --- a/tests/sys/conn_can/Makefile.ci +++ b/tests/sys/conn_can/Makefile.ci @@ -5,7 +5,6 @@ BOARD_INSUFFICIENT_MEMORY := \ im880b \ microbit \ nrf51dongle \ - nrf6310 \ nucleo-f030r8 \ nucleo-f031k6 \ nucleo-f042k6 \ diff --git a/tests/sys/posix_semaphore/Makefile.ci b/tests/sys/posix_semaphore/Makefile.ci index 02ec9f8f6bbc..4c0357f2c392 100644 --- a/tests/sys/posix_semaphore/Makefile.ci +++ b/tests/sys/posix_semaphore/Makefile.ci @@ -11,7 +11,6 @@ BOARD_INSUFFICIENT_MEMORY := \ mbed_lpc1768 \ msb-430 \ msb-430h \ - nrf6310 \ nucleo-f030r8 \ nucleo-f031k6 \ nucleo-f042k6 \ diff --git a/tests/unittests/Makefile.ci b/tests/unittests/Makefile.ci index cda190820678..34908417976a 100644 --- a/tests/unittests/Makefile.ci +++ b/tests/unittests/Makefile.ci @@ -44,7 +44,6 @@ BOARD_INSUFFICIENT_MEMORY := \ msba2 \ nrf51dk \ nrf51dongle \ - nrf6310 \ nucleo-c031c6 \ nucleo-f030r8 \ nucleo-f031k6 \ diff --git a/tests/unittests/tests-nanocoap/tests-nanocoap.c b/tests/unittests/tests-nanocoap/tests-nanocoap.c index b6493b7b762c..5b04de848398 100644 --- a/tests/unittests/tests-nanocoap/tests-nanocoap.c +++ b/tests/unittests/tests-nanocoap/tests-nanocoap.c @@ -1227,6 +1227,29 @@ static void test_nanocoap___rst_message(void) TEST_ASSERT_EQUAL_INT(0x55, buf[sizeof(rst_expected)]); } +/* + * Test that invalid encoding of CoAP option is caught early, so that + * later access to CoAP option does indeed not need to perform bound + * checking. + */ +static void test_nanocoap__out_of_bounds_option(void) +{ + uint8_t invalid_msg[] = { + (COAP_V1 << 6) | (COAP_TYPE_CON << 4) | 3, /* version = 1, type = CON, Token Len = 3 */ + COAP_METHOD_GET, + 0x13, 0x37, /* Message ID = 0x1337 */ + 0xca, 0xfe, 0x42, /* Token = 0xcafe42 */ + /* Option Delta: 11 (11 + 0 = 11 = URI-Path) + * Option Length: 8 */ + (COAP_OPT_URI_PATH << 4) | (8), + 0x13, 0x37, 0x42, 0x42 /* 4 bytes Option Data */ + /* End of packet - 4 bytes before the claimed end of option */ + }; + + coap_pkt_t pkt; + TEST_ASSERT_EQUAL_INT(-EBADMSG, coap_parse(&pkt, invalid_msg, sizeof(invalid_msg))); +} + Test *tests_nanocoap_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { @@ -1266,6 +1289,7 @@ Test *tests_nanocoap_tests(void) new_TestFixture(test_nanocoap__token_length_ext_16), new_TestFixture(test_nanocoap__token_length_ext_269), new_TestFixture(test_nanocoap___rst_message), + new_TestFixture(test_nanocoap__out_of_bounds_option), }; EMB_UNIT_TESTCALLER(nanocoap_tests, NULL, NULL, fixtures); diff --git a/tests/unittests/tests-rtc/tests-rtc.c b/tests/unittests/tests-rtc/tests-rtc.c index 281c868b9638..8669aa6513b7 100644 --- a/tests/unittests/tests-rtc/tests-rtc.c +++ b/tests/unittests/tests-rtc/tests-rtc.c @@ -224,6 +224,39 @@ static void test_rtc_mktime(void) TEST_ASSERT_EQUAL_INT(98197931, rtc_mktime(&t)); } +static void test_mktime(void) +{ + /* second 1 of 1970 is defined 1 second of unixtime */ + struct tm t = { + .tm_sec = 1, + .tm_min = 0, + .tm_hour = 0, + .tm_mday = 1, + .tm_mon = 0, + .tm_year = 70, + .tm_wday = 0, + .tm_yday = 1, + }; + /* This test will fail if mktime is applying timezone information + * that is not 0 seconds offset from UTC (GMT) and therefore returning unixtime. + * A usual reason for failure might be that nativ is run in a local not "UTC" timezone, + * a "Fix" for this failure is setting the environment variable TZ to "UTC" */ + TEST_ASSERT_EQUAL_INT(1, mktime(&t)); + + t = (struct tm){ + .tm_sec = 11, + .tm_min = 12, + .tm_hour = 13, + .tm_mday = 1, + .tm_mon = 0, + .tm_year = 120, + .tm_wday = 0, + .tm_yday = 1, + }; + + TEST_ASSERT_EQUAL_INT(1577884331, mktime(&t)); +} + static void test_rtc_localtime(void) { struct tm t; @@ -287,6 +320,7 @@ Test *tests_rtc_tests(void) new_TestFixture(test_rtc_year), new_TestFixture(test_rtc_compare), new_TestFixture(test_rtc_mktime), + new_TestFixture(test_mktime), new_TestFixture(test_rtc_localtime), };