1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-28 23:09:46 +01:00
18459: makefiles/suit: make it possible to accept multiple SUIT keys r=miri64 a=benpicco



18724: nanocoap_sock: implement DTLS socket r=miri64 a=benpicco



19081: sys/stdio_udp: add stdio over UDP r=benpicco a=benpicco



19082: core/init: add early_init() r=benpicco a=benpicco



19136: CI: re-add "synchronize" event to check-labels r=miri64 a=kaspar030



Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
Co-authored-by: Benjamin Valentin <benjamin.valentin@bht-berlin.de>
Co-authored-by: Kaspar Schleiser <kaspar@schleiser.de>
This commit is contained in:
bors[bot] 2023-01-13 13:50:55 +00:00 committed by GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 838 additions and 145 deletions

View File

@ -1,7 +1,7 @@
name: check-labels
on:
pull_request:
types: [opened, reopened, labeled, unlabeled]
types: [opened, reopened, labeled, unlabeled, synchronize]
pull_request_review:
types: [submitted, dismissed]
jobs:

View File

@ -56,6 +56,15 @@ void kernel_init(void);
*/
void board_init(void);
/**
* @brief Initialize debug LEDs and stdio
*/
#ifdef MODULE_CORE_INIT
void early_init(void);
#else
static inline void early_init(void) {}
#endif
#ifdef __cplusplus
}
#endif

View File

@ -29,6 +29,11 @@
#include "log.h"
#include "periph/pm.h"
#include "thread.h"
#include "stdio_base.h"
#if IS_USED(MODULE_VFS)
#include "vfs.h"
#endif
#define ENABLE_DEBUG 0
#include "debug.h"
@ -102,3 +107,18 @@ void kernel_init(void)
cpu_switch_context_exit();
}
void early_init(void)
{
/* initialize leds */
if (IS_USED(MODULE_PERIPH_INIT_LEDS)) {
extern void led_init(void);
led_init();
}
stdio_init();
#if MODULE_VFS
vfs_bind_stdio();
#endif
}

View File

@ -21,6 +21,7 @@
#include <stdio.h>
#include <avr/io.h>
#include "kernel_init.h"
#include "stdio_uart.h"
static int _uart_putchar(char c, FILE *stream);
@ -45,7 +46,7 @@ static int _uart_getchar(FILE *stream)
void avr8_stdio_init(void)
{
stdio_init();
early_init();
stdout = &_uart_stdout;
stdin = &_uart_stdin;

View File

@ -20,6 +20,7 @@
#include "stdio_base.h"
#include "cpu.h"
#include "kernel_init.h"
#include "periph/init.h"
#include "periph_conf.h"
@ -37,7 +38,7 @@ void cpu_init(void)
/* initialize the clock system */
cpu_clock_init();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();
}

View File

@ -18,6 +18,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph_conf.h"
#include "periph/init.h"
#include "stdio_base.h"
@ -46,7 +47,7 @@ void cpu_init(void)
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -19,6 +19,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph_conf.h"
#include "periph/init.h"
#include "stdio_base.h"
@ -37,7 +38,7 @@ void cpu_init(void)
setup_trim_device();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -22,6 +22,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph_conf.h"
#include "periph/init.h"
#include "stdio_base.h"
@ -231,7 +232,7 @@ void cpu_init(void)
pm_init();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -6,6 +6,21 @@
* directory for more details.
*/
/**
* @defgroup stdio_usb_serial_jtag STDIO over ESP32 Debug Serial/JTAG
* @ingroup sys_stdio
* @brief STDIO via the USB Serial/JTAG debug interface found on some ESP32 SoCs
*
* Some members of the ESP32 family (ESP32-C3, ESP32-S3, ESP32-H2) provide a on-chip
* debug interface that provides a serial console and JTAG via USB.
*
* To route STDIO to this debug console, enable this module.
*
* USEMODULE += stdio_usb_serial_jtag
*
* @see cpu_esp32
*/
/**
@defgroup cpu_esp32 ESP32 SoC Series
@ingroup cpu

View File

@ -149,7 +149,7 @@ static NORETURN void IRAM system_startup_cpu0(void)
/* initialize stdio */
esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
stdio_init();
early_init();
RESET_REASON reset_reason = rtc_get_reset_reason(PRO_CPU_NUM);

View File

@ -106,7 +106,7 @@ void esp_riot_init(void)
/* initialize stdio*/
extern int stdio_is_initialized;
stdio_init();
early_init();
stdio_is_initialized = 1;
/* trigger static peripheral initialization */

View File

@ -19,6 +19,7 @@
#include "clk.h"
#include "cpu.h"
#include "kernel_init.h"
#include "periph/init.h"
#include "periph_conf.h"
@ -108,7 +109,7 @@ void cpu_init(void)
riscv_init();
/* Initialize stdio */
stdio_init();
early_init();
/* Initialize static peripheral */
periph_init();

View File

@ -14,6 +14,7 @@
*
* @author Koen Zandberg <koen@bergzand.net>
*/
#include "kernel_init.h"
#include "stdio_uart.h"
#include "periph/init.h"
#include "irq_arch.h"
@ -30,6 +31,6 @@ void cpu_init(void)
gd32vf103_clock_init();
/* Common RISC-V initialization */
riscv_init();
stdio_init();
early_init();
periph_init();
}

View File

@ -18,6 +18,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph/init.h"
#include "stdio_base.h"
#ifdef MODULE_PERIPH_MCG
@ -44,7 +45,7 @@ void cpu_init(void)
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -18,6 +18,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "irq.h"
#include "sched.h"
#include "thread.h"
@ -38,7 +39,7 @@ void cpu_init(void)
cpu_clock_init(CLOCK_SOURCE);
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -18,6 +18,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph/init.h"
#include "stdio_base.h"
@ -29,7 +30,7 @@ void cpu_init(void)
/* initialize the Cortex-M core */
cortexm_init();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();
}

View File

@ -13,6 +13,7 @@
#include <stdint.h>
#include "cpu.h"
#include "kernel_init.h"
#include "irq.h"
#include "VIC.h"
@ -130,7 +131,7 @@ void cpu_init(void)
board_init();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -9,6 +9,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "irq.h"
#include "sched.h"
#include "thread.h"

View File

@ -51,7 +51,7 @@ __attribute__((constructor)) static void startup(void)
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();
/* continue with kernel initialization */

View File

@ -10,6 +10,17 @@
* Native CPU internal declarations
*/
/**
* @defgroup cpu_native_stdio STDIO for native
* @ingroup sys_stdio
* @brief Standard input/output backend for native
*
* This will hook up RIOT's stdio to the host's stdio fds. It is the default
* stdio implementation of the board `native`.
*
* @see cpu_native
*/
/**
* @ingroup cpu_native
* @{

View File

@ -466,7 +466,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e
{
_native_init_syscalls();
/* initialize stdio as early as possible */
stdio_init();
early_init();
_native_argv = argv;
_progname = argv[0];

View File

@ -15,15 +15,11 @@
#include "kernel_defines.h"
#include "native_internal.h"
#include "vfs.h"
#include "stdio_base.h"
void stdio_init(void)
{
if (IS_USED(MODULE_VFS)) {
vfs_bind_stdio();
}
}
ssize_t stdio_read(void* buffer, size_t max_len)

View File

@ -18,6 +18,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "nrf_clock.h"
#include "nrfx_riot.h"
#include "periph_conf.h"
@ -36,7 +37,7 @@ void cpu_init(void)
/* setup the HF clock */
clock_init_hf();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();
}

View File

@ -23,6 +23,7 @@
#define DONT_OVERRIDE_NVIC
#include "cpu.h"
#include "kernel_init.h"
#include "nrfx_riot.h"
#include "nrf_clock.h"
#include "periph_conf.h"
@ -75,7 +76,7 @@ void cpu_init(void)
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -19,6 +19,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "nrf_clock.h"
#include "periph_conf.h"
#include "periph/init.h"
@ -44,7 +45,7 @@ void cpu_init(void)
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -18,6 +18,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph/init.h"
#include "stdio_base.h"
@ -51,7 +52,7 @@ void cpu_init(void)
cpu_clock_init();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();
}

View File

@ -19,6 +19,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "macros/units.h"
#include "periph/init.h"
#include "periph_cpu.h"
@ -87,7 +88,7 @@ void cpu_init(void)
_cpu_reset();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
DEBUG_PUTS("[rpx0xx] GPOUT0 (GPIO pin 21) is clocked from XOSC (typically 12 MHz)");

View File

@ -18,6 +18,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph_conf.h"
#include "periph/init.h"
#include "stdio_base.h"
@ -104,7 +105,7 @@ void cpu_init(void)
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -19,6 +19,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph_conf.h"
#include "periph/init.h"
#include "stdio_base.h"
@ -281,7 +282,7 @@ void cpu_init(void)
dma_init();
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();
}

View File

@ -20,6 +20,7 @@
#include <assert.h>
#include "cpu.h"
#include "kernel_init.h"
#include "macros/units.h"
#include "periph_conf.h"
#include "periph/init.h"
@ -383,7 +384,7 @@ void cpu_init(void)
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -19,6 +19,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "periph/init.h"
#include "periph_conf.h"
#include "board.h"
@ -183,7 +184,7 @@ void cpu_init(void)
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -21,6 +21,7 @@
#include <assert.h>
#include "cpu.h"
#include "kernel_init.h"
#include "periph/init.h"
#include "periph_conf.h"
#include "stdio_base.h"
@ -312,7 +313,7 @@ void cpu_init(void)
dma_init();
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
/* trigger static peripheral initialization */
periph_init();

View File

@ -33,6 +33,7 @@
*/
#include "cpu.h"
#include "kernel_init.h"
#include "stdio_base.h"
#include "stmclk.h"
#include "periph_cpu.h"
@ -359,7 +360,7 @@ void cpu_init(void)
dma_init();
#endif
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init();
early_init();
#ifdef STM32F1_DISABLE_JTAG
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;

View File

@ -49,11 +49,11 @@ def to_header(pk):
if isinstance(pk, ed25519.Ed25519PrivateKey):
public_bytes = pk.public_key().public_bytes(ks.Encoding.Raw,
ks.PublicFormat.Raw)
public_c_def = ['const uint8_t public_key[] = {'] + textwrap.wrap(
public_c_def = ['{'] + textwrap.wrap(
', '.join(['{:0=#4x}'.format(x) for x in public_bytes]),
76
)
return str.encode('\n '.join(public_c_def) + '\n};\n')
return str.encode('\n '.join(public_c_def) + '\n},\n')
OutputFormaters = {

View File

@ -24,9 +24,6 @@
#include "ethos.h"
#include "isrpipe.h"
#include "stdio_uart.h"
#if IS_USED(MODULE_VFS)
#include "vfs.h"
#endif
extern ethos_t ethos;
@ -41,10 +38,6 @@ static void _isrpipe_write(void *arg, uint8_t data)
void stdio_init(void)
{
uart_init(ETHOS_UART, ETHOS_BAUDRATE, _isrpipe_write, &ethos_stdio_isrpipe);
#if MODULE_VFS
vfs_bind_stdio();
#endif
}
extern unsigned ethos_unstuff_readbyte(uint8_t *buf, uint8_t byte,

View File

@ -6,6 +6,21 @@
* details.
*/
/**
* @defgroup drivers_ethos_stdio STDIO via ethos
* @ingroup sys_stdio
* @brief Standard input/output backend multiplexed via ethernet-over-serial
*
* This will multiplex STDIO via ethos.
* The shell can be accessed via the `ethos` tool.
*
* To enable this stdio implementation, select
*
* USEMODULE += stdio_ethos
*
* @see drivers_ethos
*/
/**
* @defgroup drivers_ethos Ethernet-over-serial driver
* @ingroup drivers_netdev

View File

@ -6,6 +6,21 @@
* directory for more details.
*/
/**
* @defgroup drivers_slipdev_stdio STDIO via SLIP
* @ingroup sys_stdio
* @brief Standard input/output backend multiplexed via SLIP
*
* This will multiplex STDIO via the Serial Line Internet Protocol.
* The shell can be accessed via the `sliptty` tool.
*
* To enable this stdio implementation, select
*
* USEMODULE += slipdev_stdio
*
* @see drivers_slipdev
*/
/**
* @defgroup drivers_slipdev SLIP network device
* @ingroup drivers_netdev

View File

@ -58,11 +58,6 @@
void periph_init(void)
{
#ifdef MODULE_PERIPH_INIT
/* initialize leds */
if (IS_USED(MODULE_PERIPH_INIT_LEDS)) {
extern void led_init(void);
led_init();
}
/* initialize buttonss */
if (IS_USED(MODULE_PERIPH_INIT_BUTTONS)) {
extern void button_init(void);

View File

@ -80,4 +80,17 @@ else
"don't run this on public networks!$(COLOR_RESET)" 1>&2)
endif
endif
# Warn about STDIO UDP
ifneq (,$(filter stdio_udp,$(USEMODULE)))
ifneq (1,$(I_UNDERSTAND_THAT_STDIO_UDP_IS_INSECURE))
$(shell $(COLOR_ECHO) "$(COLOR_RED)stdio via UDP will be started automatically,"\
"make sure you understand why this almost certainly"\
"is a REALLY BAD idea before proceeding!$(COLOR_RESET)" 1>&2)
$(error I_UNDERSTAND_THAT_STDIO_UDP_IS_INSECURE must be set to 1 to proceed)
else
$(shell $(COLOR_ECHO) "$(COLOR_YELLOW)stdio via UDP will be started automatically,"\
"don't run this on public networks!$(COLOR_RESET)" 1>&2)
endif
endif
endif

View File

@ -8,6 +8,7 @@ STDIO_MODULES = \
stdio_rtt \
stdio_semihosting \
stdio_uart \
stdio_udp \
stdio_telnet \
stdio_tinyusb_cdc_acm \
stdio_usb_serial_jtag \
@ -75,6 +76,10 @@ ifneq (,$(filter stdio_telnet,$(USEMODULE)))
USEMODULE += telnet
endif
ifneq (,$(filter stdio_udp,$(USEMODULE)))
USEMODULE += sock_udp
endif
# enable stdout buffering for modules that benefit from sending out buffers in larger chunks
ifneq (,$(filter picolibc,$(USEMODULE)))
ifneq (,$(filter stdio_cdc_acm stdio_ethos slipdev_stdio stdio_semihosting,$(USEMODULE)))

View File

@ -18,13 +18,11 @@ else
SUIT_KEY_DIR ?= $(XDG_DATA_HOME)/RIOT/keys
endif
# Enable user to encrypt private key with a password
ifneq (,$(SUIT_SEC_PASSWORD))
SUIT_TOOL_ARGS += -p $(SUIT_SEC_PASSWORD)
endif
SUIT_SEC ?= $(SUIT_KEY_DIR)/$(SUIT_KEY).pem
# Multiple keys can be specified with "key0:pw0 key1:pw1 …" (pw may be empty)
SUIT_SECS ?= $(SUIT_SEC):$(SUIT_SEC_PASSWORD)
SUIT_PUB_HDR = $(BINDIR)/riotbuild/public_key.h
SUIT_PUB_HDR_DIR = $(dir $(SUIT_PUB_HDR))
CFLAGS += -I$(SUIT_PUB_HDR_DIR)
@ -40,7 +38,21 @@ $(SUIT_SEC): | $(CLEAN)
# key's mtime is too far back).
$(SUIT_PUB_HDR): $(SUIT_SEC) FORCE | $(CLEAN)
$(Q)mkdir -p $(SUIT_PUB_HDR_DIR)
$(Q)$(SUIT_TOOL) pubkey $(SUIT_TOOL_ARGS) -f header -k $(SUIT_SEC) \
| '$(LAZYSPONGE)' $(LAZYSPONGE_FLAGS) '$@'
$(Q)( \
echo "const uint8_t public_key[][32] = {"; \
for i in $(SUIT_SECS); do \
key=$${i%:*}; \
pw=$${i#*:}; \
if [ "$$key" = "$$pw" ]; then \
unset pw; \
fi; \
if [ -z "$$pw" ]; then \
$(SUIT_TOOL) pubkey -f header -k $$key; \
else \
$(SUIT_TOOL) pubkey -f header -k $$key -p $$pw; \
fi \
done; \
echo "};" \
) | '$(LAZYSPONGE)' $(LAZYSPONGE_FLAGS) '$@'
suit/genkey: $(SUIT_SEC)

View File

@ -814,6 +814,71 @@ ssize_t sock_dtls_recv_aux(sock_dtls_t *sock, sock_dtls_session_t *remote,
}
}
ssize_t sock_dtls_recv_buf_aux(sock_dtls_t *sock, sock_dtls_session_t *remote,
void **data, void **buf_ctx, uint32_t timeout,
sock_dtls_aux_rx_t *aux)
{
assert(sock);
assert(data);
assert(buf_ctx);
assert(remote);
sock_udp_ep_t ep;
/* 2nd call to the function (with ctx set) will free the data */
if (*buf_ctx) {
int res = sock_udp_recv_buf_aux(sock->udp_sock, data, buf_ctx,
timeout, &ep, (sock_udp_aux_rx_t *)aux);
assert(res == 0);
return res;
}
/* loop breaks when timeout or application data read */
while (1) {
ssize_t res;
uint32_t start_recv = ztimer_now(ZTIMER_USEC);
msg_t msg;
if (sock->buffer.data != NULL) {
*data = sock->buffer.data;
sock->buffer.data = NULL;
_copy_session(sock, remote);
return sock->buffer.datalen;
}
else if (mbox_try_get(&sock->mbox, &msg) &&
msg.type == DTLS_EVENT_CONNECTED) {
return _complete_handshake(sock, remote, msg.content.ptr);
}
/* Crude way to somewhat test that `sock_dtls_aux_rx_t` and
* `sock_udp_aux_rx_t` remain compatible: */
static_assert(sizeof(sock_dtls_aux_rx_t) == sizeof(sock_udp_aux_rx_t),
"sock_dtls_aux_rx_t became incompatible with "
"sock_udp_aux_rx_t");
res = sock_udp_recv_buf_aux(sock->udp_sock, data, buf_ctx,
timeout, &ep, (sock_udp_aux_rx_t *)aux);
if (res == 0) {
continue;
}
if (res < 0) {
DEBUG("sock_dtls: error receiving UDP packet: %d\n", (int)res);
return res;
}
_ep_to_session(&ep, &remote->dtls_session);
res = dtls_handle_message(sock->dtls_ctx, &remote->dtls_session,
*data, res);
if ((timeout != SOCK_NO_TIMEOUT) && (timeout != 0)) {
timeout = _update_timeout(start_recv, timeout);
}
if (timeout == 0) {
DEBUG("sock_dtls: timed out while decrypting message\n");
return -ETIMEDOUT;
}
}
}
void sock_dtls_close(sock_dtls_t *sock)
{
dtls_free_context(sock->dtls_ctx);

View File

@ -28,18 +28,10 @@
#include "tusb.h"
#include "tinyusb.h"
#if MODULE_VFS
#include "vfs.h"
#endif
static mutex_t data_lock = MUTEX_INIT_LOCKED;
void stdio_init(void)
{
/* Initialize this side of the CDC ACM pipe */
#if MODULE_VFS
vfs_bind_stdio();
#endif
}
#if IS_USED(MODULE_STDIO_AVAILABLE)

View File

@ -129,3 +129,14 @@
* [tinyUSB documentation](https://docs.tinyusb.org/en/latest/reference/getting_started.html)
* for details.
*/
/**
* @defgroup pkg_tinyusb_stdio_cdc_acm STDIO over USB CDC-ACM (tinyUSB)
* @ingroup sys_stdio
* @brief Standard input/output backend using tinyUSB CDC ACM
* @see pkg_tinyusb
*
* To enable this, select the `tinyusb_stdio_cdc_acm` module:
*
* USEMODULE += stdio_tinyusb_cdc_acm
*/

View File

@ -713,6 +713,11 @@ ifneq (,$(filter luid,$(USEMODULE)))
FEATURES_OPTIONAL += periph_cpuid
endif
ifneq (,$(filter nanocoap_dtls,$(USEMODULE)))
USEMODULE += sock_dtls
USEPKG += tinydtls
endif
ifneq (,$(filter nanocoap_sock,$(USEMODULE)))
USEMODULE += sock_udp
USEMODULE += sock_util

View File

@ -31,6 +31,11 @@ extern "C" {
*/
#define COAP_PORT (5683)
/**
* @brief Default CoAP DTLS port
*/
#define COAPS_PORT (5684)
#define COAP_V1 (1) /**< Identifier for CoAP version 1 (RFC 7252) */
/**

View File

@ -135,16 +135,58 @@
#include "net/nanocoap.h"
#include "net/sock/udp.h"
#include "net/sock/util.h"
#if IS_USED(MODULE_NANOCOAP_DTLS)
#include "net/credman.h"
#include "net/sock/dtls.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief nanocoap socket type
*
* @brief Timeout for CoAP over DTLS queries in milliseconds
*/
typedef sock_udp_t nanocoap_sock_t;
#ifndef CONFIG_NANOCOAP_SOCK_DTLS_TIMEOUT_MS
#define CONFIG_NANOCOAP_SOCK_DTLS_TIMEOUT_MS (1000U)
#endif
/**
* @brief Number of CoAP over DTLS handshake retries
*/
#ifndef CONFIG_NANOCOAP_SOCK_DTLS_RETRIES
#define CONFIG_NANOCOAP_SOCK_DTLS_RETRIES (2)
#endif
/**
* @brief Credman tag used for NanoCoAP
* Tag together with the credential type (PSK) needs to be unique
*/
#ifndef CONFIG_NANOCOAP_SOCK_DTLS_TAG
#define CONFIG_NANOCOAP_SOCK_DTLS_TAG (0xc0ab)
#endif
/**
* @brief NanoCoAP socket types
*/
typedef enum {
COAP_SOCKET_TYPE_UDP, /**< transport is plain UDP */
COAP_SOCKET_TYPE_DTLS, /**< transport is DTLS */
} nanocoap_socket_type_t;
/**
* @brief NanoCoAP socket struct
*/
typedef struct {
sock_udp_t udp; /**< UDP socket */
#if IS_USED(MODULE_NANOCOAP_DTLS) || defined(DOXYGEN)
sock_dtls_t dtls; /**< DTLS socket */
sock_dtls_session_t dtls_session; /**< Session object for the stored socket.
Used for exchanging a session between
functions. */
nanocoap_socket_type_t type; /**< Socket type (UDP, DTLS) */
#endif
} nanocoap_sock_t;
/**
* @brief Blockwise request helper struct
@ -185,9 +227,30 @@ static inline int nanocoap_sock_connect(nanocoap_sock_t *sock,
const sock_udp_ep_t *local,
const sock_udp_ep_t *remote)
{
return sock_udp_create(sock, local, remote, 0);
#if IS_USED(MODULE_NANOCOAP_DTLS)
sock->type = COAP_SOCKET_TYPE_UDP;
#endif
return sock_udp_create(&sock->udp, local, remote, 0);
}
#if IS_USED(MODULE_NANOCOAP_DTLS) || DOXYGEN
/**
* @brief Create a DTLS secured CoAP client socket
*
* @param[out] sock CoAP UDP socket
* @param[in] local Local UDP endpoint, may be NULL
* @param[in] remote remote UDP endpoint
* @param[in] tag Tag of the PSK credential to use
* Has to be added with @ref credman_add
*
* @returns 0 on success
* @returns <0 on error
*/
int nanocoap_sock_dtls_connect(nanocoap_sock_t *sock, sock_udp_ep_t *local,
const sock_udp_ep_t *remote, credman_tag_t tag);
#endif
/**
* @brief Create a CoAP client socket by URL
*
@ -206,7 +269,13 @@ int nanocoap_sock_url_connect(const char *url, nanocoap_sock_t *sock);
*/
static inline void nanocoap_sock_close(nanocoap_sock_t *sock)
{
sock_udp_close(sock);
#if IS_USED(MODULE_NANOCOAP_DTLS)
if (sock->type == COAP_SOCKET_TYPE_DTLS) {
sock_dtls_session_destroy(&sock->dtls, &sock->dtls_session);
sock_dtls_close(&sock->dtls);
}
#endif
sock_udp_close(&sock->udp);
}
/**
@ -441,7 +510,7 @@ ssize_t nanocoap_sock_request(nanocoap_sock_t *sock, coap_pkt_t *pkt, size_t len
* @returns length of response on success
* @returns <0 on error
*/
ssize_t nanocoap_sock_request_cb(sock_udp_t *sock, coap_pkt_t *pkt,
ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,
coap_request_cb_t cb, void *arg);
/**

View File

@ -6,6 +6,26 @@
* directory for more details.
*/
/**
* @defgroup net_telnet_stdio STDIO over telnet
* @ingroup sys_stdio
* @brief Standard input/output via telnet
*
* This will make RIOT's stdio available over telnet.
*
* To enable it, add
*
* USEMODULE += stdio_telnet
*
* to your application.
* You will also have to set `I_UNDERSTAND_THAT_TELNET_IS_INSECURE = 1` to
* acknowledge that you will only use this for debugging in an isolated network.
*
* You can then use any standard `telnet` client to connect to your node.
*
* @see net_telnet
*/
/**
* @defgroup net_telnet basic Telnet server implementation
* @ingroup net_ipv6

View File

@ -8,7 +8,11 @@
/**
* @defgroup sys_stdio_nimble STDIO over NimBLE
* @ingroup sys
* @ingroup sys_stdio
*
* To enable stdio over nimBLE, add the module `stdio_nimble`:
*
* USEMODULE += stdio_nimble
*
* @experimental This feature is experimental as some use-cases, such as examples/twr_aloha, show
* unexpected behaviour.

View File

@ -9,10 +9,17 @@
/**
* @defgroup sys_stdio_rtt STDIO over SEGGER RTT
* @ingroup sys
* @ingroup sys_stdio
*
* @brief STDIO mapping for running the STDIO over SEGGER's RTT interface
*
* To enable stdio over SEGGER's RTT, enable the module `stdio_rtt`:
*
* USEMODULE += stdio_rtt
*
* @note Currently, `stdio_rtt` is only supported when OpenOCD or J-Link is
* used as programmer.
*
* @{
* @file
*

View File

@ -8,7 +8,7 @@
/**
* @defgroup sys_stdio_semihosting STDIO over Semihosting
* @ingroup sys
* @ingroup sys_stdio
*
* @brief Standard input/output backend using ARM Semihosting
*

View File

@ -9,10 +9,17 @@
/**
* @defgroup sys_stdio_uart STDIO over UART
* @ingroup sys
* @ingroup sys_stdio
*
* @brief Standard input/output backend using UART
*
* To enable stdio over UART, enable the `stdio_uart` module:
*
* USEMODULE += stdio_uart
*
* @note For many board, `stdio_uart` is already the default stdio backend
* and therefore already enabled.
*
* ## Input
*
* @warning Standard input is disabled by default on UART. To enable it, load

View File

@ -6,6 +6,19 @@
* more details.
*/
/**
* @defgroup usbus_cdc_acm_stdio STDIO over CDC ACM (usbus)
* @ingroup sys_stdio
* @brief Standard input/output backend using usbus CDC ACM.
*
* This will provide STDIO via a virtual COM port over USB.
* It can be enabled with
*
* USEMODULE += stdio_cdc_acm
*
* @see usbus_cdc_acm
*/
/**
* @defgroup usbus_cdc_acm USBUS CDC ACM - USBUS CDC abstract control model
* @ingroup usb

View File

@ -776,6 +776,19 @@ void ztimer_set_wakeup(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
void ztimer_set_timeout_flag(ztimer_clock_t *clock, ztimer_t *timer,
uint32_t timeout);
/**
* @brief Unlock mutex after @p timeout
*
* This function will unlock the given mutex after the timeout has passed.
*
* @param[in] clock ztimer clock to operate on
* @param[in] timer timer struct to use
* @param[in] timeout timeout in ztimer_clock's ticks
* @param[in] mutex mutex to unlock after timeout
*/
void ztimer_mutex_unlock(ztimer_clock_t *clock, ztimer_t *timer,
uint32_t timeout, mutex_t *mutex);
/**
* @brief Try to lock the given mutex, but give up after @p timeout
*

View File

@ -26,9 +26,11 @@
#include <stdio.h>
#include "atomic_utils.h"
#include "net/credman.h"
#include "net/nanocoap_sock.h"
#include "net/sock/util.h"
#include "net/sock/udp.h"
#include "net/iana/portrange.h"
#include "random.h"
#include "sys/uio.h"
#include "timex.h"
@ -37,6 +39,17 @@
#define ENABLE_DEBUG 0
#include "debug.h"
/**
* @brief Size of the buffer used for the DTLS handshake
*
* This size was found suitable for DTLS using a simple PSK in mode AES_128_CCM_8.
* DTLS places no restriction on its handshake package size therefore this might need change,
* 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)
#endif
enum {
STATE_REQUEST_SEND, /**< request was just sent or will be sent again */
STATE_RESPONSE_RCVD, /**< response received but might be invalid */
@ -56,6 +69,93 @@ static uint16_t _get_id(void)
return atomic_fetch_add_u16(&id, 1);
}
#if IS_USED(MODULE_NANOCOAP_DTLS)
int nanocoap_sock_dtls_connect(nanocoap_sock_t *sock, sock_udp_ep_t *local,
const sock_udp_ep_t *remote, credman_tag_t tag)
{
int res;
uint32_t timeout_ms = CONFIG_NANOCOAP_SOCK_DTLS_TIMEOUT_MS;
uint8_t retries = CONFIG_NANOCOAP_SOCK_DTLS_RETRIES;
bool auto_port = local->port == 0;
do {
if (auto_port) {
/* choose random ephemeral port, since DTLS requires a local port */
local->port = random_uint32_range(IANA_DYNAMIC_PORTRANGE_MIN,
IANA_DYNAMIC_PORTRANGE_MAX);
}
/* connect UDP socket */
res = nanocoap_sock_connect(sock, local, remote);
} while (auto_port && (res == -EADDRINUSE));
if (res < 0) {
return res;
}
/* create DTLS socket on to of UDP socket */
res = sock_dtls_create(&sock->dtls, &sock->udp, tag,
SOCK_DTLS_1_2, SOCK_DTLS_CLIENT);
if (res < 0) {
DEBUG("Unable to create DTLS sock: %s\n", strerror(-res));
nanocoap_sock_close(sock);
return res;
}
sock->type = COAP_SOCKET_TYPE_DTLS;
while (1) {
uint8_t buf[CONFIG_NANOCOAP_DTLS_HANDSHAKE_BUF_SIZE];
mutex_t lock = MUTEX_INIT_LOCKED;
ztimer_t timeout;
/* unlock lock after timeout */
ztimer_mutex_unlock(ZTIMER_MSEC, &timeout, timeout_ms, &lock);
/* create DTLS session */
res = sock_dtls_session_init(&sock->dtls, remote, &sock->dtls_session);
if (res >= 0) {
/* handle handshake */
res = sock_dtls_recv(&sock->dtls, &sock->dtls_session, buf,
sizeof(buf), timeout_ms * US_PER_MS);
if (res == -SOCK_DTLS_HANDSHAKE) {
DEBUG("DTLS handshake successful\n");
ztimer_remove(ZTIMER_MSEC, &timeout);
return 0;
}
DEBUG("Unable to establish DTLS handshake: %s\n", strerror(-res));
} else {
DEBUG("Unable to initialize DTLS session: %s\n", strerror(-res));
}
sock_dtls_session_destroy(&sock->dtls, &sock->dtls_session);
if (retries--) {
/* wait for timeout to expire */
mutex_lock(&lock);
} else {
ztimer_remove(ZTIMER_MSEC, &timeout);
break;
}
/* see https://datatracker.ietf.org/doc/html/rfc6347#section-4.2.4.1 */
timeout_ms *= 2U;
}
nanocoap_sock_close(sock);
return res;
}
#else
int nanocoap_sock_dtls_connect(nanocoap_sock_t *sock, const sock_udp_ep_t *local,
const sock_udp_ep_t *remote, credman_tag_t tag)
{
(void)sock;
(void)local;
(void)remote;
(void)tag;
return -ENOTSUP;
}
#endif
static int _get_error(const coap_pkt_t *pkt)
{
switch (coap_get_code_class(pkt)) {
@ -68,15 +168,61 @@ static int _get_error(const coap_pkt_t *pkt)
}
}
static inline nanocoap_socket_type_t _get_type(nanocoap_sock_t *sock)
{
#if IS_USED(MODULE_NANOCOAP_DTLS)
return sock->type;
#else
(void)sock;
return COAP_SOCKET_TYPE_UDP;
#endif
}
static int _sock_sendv(nanocoap_sock_t *sock, const iolist_t *snips)
{
switch (_get_type(sock)) {
case COAP_SOCKET_TYPE_UDP:
return sock_udp_sendv(&sock->udp, snips, NULL);
#if IS_USED(MODULE_NANOCOAP_DTLS)
case COAP_SOCKET_TYPE_DTLS:
return sock_dtls_sendv(&sock->dtls, &sock->dtls_session, snips,
CONFIG_NANOCOAP_SOCK_DTLS_TIMEOUT_MS);
#endif
default:
assert(0);
return -EINVAL;
}
}
static int _sock_recv_buf(nanocoap_sock_t *sock, void **data, void **ctx, uint32_t timeout)
{
switch (_get_type(sock)) {
case COAP_SOCKET_TYPE_UDP:
return sock_udp_recv_buf(&sock->udp, data, ctx, timeout, NULL);
#if IS_USED(MODULE_NANOCOAP_DTLS)
case COAP_SOCKET_TYPE_DTLS:
return sock_dtls_recv_buf(&sock->dtls, &sock->dtls_session, data, ctx, timeout);
#endif
default:
assert(0);
return -EINVAL;
}
}
static int _send_ack(nanocoap_sock_t *sock, coap_pkt_t *pkt)
{
coap_hdr_t ack;
unsigned tkl = coap_get_token_len(pkt);
const iolist_t snip = {
.iol_base = &ack,
.iol_len = sizeof(ack),
};
coap_build_hdr(&ack, COAP_TYPE_ACK, coap_get_token(pkt), tkl,
COAP_CODE_EMPTY, ntohs(pkt->hdr->id));
return sock_udp_send(sock, &ack, sizeof(ack), NULL);
return _sock_sendv(sock, &snip);
}
static bool _id_or_token_missmatch(const coap_pkt_t *pkt, unsigned id,
@ -149,7 +295,7 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,
DEBUG("nanocoap: send %u bytes (%u tries left)\n",
(unsigned)iolist_size(&head), tries_left);
res = sock_udp_sendv(sock, &head, NULL);
res = _sock_sendv(sock, &head);
if (res <= 0) {
DEBUG("nanocoap: error sending coap request, %d\n", (int)res);
return res;
@ -170,7 +316,7 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,
_deadline_left_us(deadline));
}
const void *old_ctx = ctx;
tmp = sock_udp_recv_buf(sock, &payload, &ctx, _deadline_left_us(deadline), NULL);
tmp = _sock_recv_buf(sock, &payload, &ctx, _deadline_left_us(deadline));
/* sock_udp_recv_buf() is supposed to return multiple packet fragments
* when called multiple times with the same context.
* In practise, this is not implemented and it will always return a pointer
@ -271,7 +417,7 @@ static int _request_cb(void *arg, coap_pkt_t *pkt)
return pkt_len;
}
ssize_t nanocoap_sock_request(sock_udp_t *sock, coap_pkt_t *pkt, size_t len)
ssize_t nanocoap_sock_request(nanocoap_sock_t *sock, coap_pkt_t *pkt, size_t len)
{
struct iovec buf = {
.iov_base = pkt->hdr,
@ -611,7 +757,14 @@ int nanocoap_sock_url_connect(const char *url, nanocoap_sock_t *sock)
char hostport[CONFIG_SOCK_HOSTPORT_MAXLEN];
sock_udp_ep_t remote;
if (strncmp(url, "coap://", 7)) {
bool is_coaps = false;
if (IS_USED(MODULE_NANOCOAP_DTLS) && !strncmp(url, "coaps://", 8)) {
DEBUG("nanocoap: CoAPS URL detected\n");
is_coaps = true;
}
if (!is_coaps && strncmp(url, "coap://", 7)) {
DEBUG("nanocoap: URL doesn't start with \"coap://\"\n");
return -EINVAL;
}
@ -627,10 +780,26 @@ int nanocoap_sock_url_connect(const char *url, nanocoap_sock_t *sock)
}
if (!remote.port) {
remote.port = COAP_PORT;
remote.port = is_coaps ? COAPS_PORT : COAP_PORT;
}
return nanocoap_sock_connect(sock, NULL, &remote);
if (is_coaps) {
/* tinydtls wants the interface to match */
if (!remote.netif &&
ipv6_addr_is_link_local((ipv6_addr_t *)remote.addr.ipv6)) {
netif_t *iface = netif_iter(NULL);
if (iface == NULL) {
return -ENODEV;
}
remote.netif = netif_get_id(iface);
}
sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
return nanocoap_sock_dtls_connect(sock, &local, &remote, CONFIG_NANOCOAP_SOCK_DTLS_TAG);
} else {
return nanocoap_sock_connect(sock, NULL, &remote);
}
}
int nanocoap_get_blockwise_url(const char *url,
@ -693,13 +862,13 @@ int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize)
local->port = COAP_PORT;
}
ssize_t res = sock_udp_create(&sock, local, NULL, 0);
ssize_t res = sock_udp_create(&sock.udp, local, NULL, 0);
if (res != 0) {
return -1;
}
while (1) {
res = sock_udp_recv(&sock, buf, bufsize, -1, &remote);
res = sock_udp_recv(&sock.udp, buf, bufsize, -1, &remote);
if (res < 0) {
DEBUG("error receiving UDP packet %d\n", (int)res);
}
@ -710,7 +879,7 @@ int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize)
continue;
}
if ((res = coap_handle_req(&pkt, buf, bufsize, &ctx)) > 0) {
sock_udp_send(&sock, buf, res, &remote);
sock_udp_send(&sock.udp, buf, res, &remote);
}
else {
DEBUG("error handling request %d\n", (int)res);

View File

@ -7,7 +7,8 @@
*/
/**
* @ingroup sys
* @defgroup net_telnet_stdio STDIO via telnet
* @ingroup sys_stdio
* @{
*
* @file
@ -29,9 +30,6 @@
#include "stdio_uart.h"
#include "periph/uart.h"
#endif
#if IS_USED(MODULE_VFS)
#include "vfs.h"
#endif
#ifdef CPU_NATIVE
#include "native_internal.h"
#endif
@ -62,10 +60,6 @@ static inline int _write_fallback(const void* buffer, size_t len)
void stdio_init(void)
{
_init_fallback();
#if IS_USED(MODULE_VFS)
vfs_bind_stdio();
#endif
}
ssize_t stdio_read(void* buffer, size_t count)

View File

@ -39,10 +39,6 @@
#include "periph/uart.h"
#endif /* IS_USED(MODULE_STDIO_NIMBLE_DEBUG) */
#if IS_USED(MODULE_VFS)
#include "vfs.h"
#endif
#include "tsrb.h"
#include "isrpipe.h"
#include "stdio_nimble.h"
@ -312,10 +308,6 @@ static int gatt_svr_chr_access_stdin(
void stdio_init(void)
{
#if IS_USED(MODULE_VFS)
vfs_bind_stdio();
#endif
#if IS_USED(MODULE_STDIO_NIMBLE_DEBUG)
uart_init(STDIO_UART_DEV, STDIO_UART_BAUDRATE, NULL, NULL);
#endif

21
sys/stdio_null/doc.txt Normal file
View File

@ -0,0 +1,21 @@
/*
* Copyright (C) 2019 Bas Stottelaar <basstottelaar@gmail.com>
*
* 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 sys_stdio_null STDIO null driver
* @ingroup sys_stdio
*
* @brief Dummy implementation of the stdio interface.
*
* This provides a null driver for STDIO that does not depend on anything.
* It is a mock implementation that will never output / read anything.
*
* To enable it use
*
* USEMODULE += stdio_null
*/

View File

@ -7,7 +7,7 @@
*/
/**
* @ingroup sys
* @ingroup sys_stdio_null
* @{
*
* @file
@ -22,18 +22,11 @@
#include "stdio_base.h"
#if MODULE_VFS
#include "vfs.h"
#endif
#define ENABLE_DEBUG 0
#include "debug.h"
void stdio_init(void)
{
#if MODULE_VFS
vfs_bind_stdio();
#endif
}
ssize_t stdio_read(void* buffer, size_t count)

View File

@ -82,10 +82,6 @@
#include "thread.h"
#include "ztimer.h"
#if MODULE_VFS
#include "vfs.h"
#endif
/* This parameter affects the bandwidth of both input and output. Decreasing
it will significantly improve bandwidth at the cost of CPU time. */
#ifndef STDIO_POLL_INTERVAL_MS
@ -282,10 +278,6 @@ void stdio_init(void) {
blocking_stdout = 1;
#endif
#if MODULE_VFS
vfs_bind_stdio();
#endif
/* the mutex should start locked */
mutex_lock(&_rx_mutex);
}

View File

@ -27,10 +27,6 @@
#include "stdio_semihosting.h"
#include "ztimer.h"
#if MODULE_VFS
#include "vfs.h"
#endif
/**
* @brief Rate at which the stdin read polls (breaks) the debugger for input
* data in milliseconds
@ -149,9 +145,6 @@ static ssize_t _semihosting_read(uint8_t *buffer, size_t len)
void stdio_init(void)
{
#if MODULE_VFS
vfs_bind_stdio();
#endif
}
ssize_t stdio_read(void* buffer, size_t count)

View File

@ -36,10 +36,6 @@
#include "periph/uart.h"
#include "stdio_uart.h"
#if MODULE_VFS
#include "vfs.h"
#endif
#define ENABLE_DEBUG 0
#include "debug.h"
@ -62,10 +58,6 @@ void stdio_init(void)
}
uart_init(STDIO_UART_DEV, STDIO_UART_BAUDRATE, cb, arg);
#if MODULE_VFS
vfs_bind_stdio();
#endif
}
#if IS_USED(MODULE_STDIO_AVAILABLE)

1
sys/stdio_udp/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

29
sys/stdio_udp/doc.txt Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2023 ML!PA Consulting GmbH
*
* 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 sys_stdio_udp STDIO over UDP
* @ingroup sys_stdio
* @brief STDIO over UDP implementation
*
* This file implements STDIO via a UDP that can be used with e.g. netcat:
*
* nc -u fe80::7837:fcff:fe7d:1aaf%tapbr0 2323
*
* It can be enabled with
*
* USEMODULE += stdio_udp
*
* and will listen on `CONFIG_STDIO_UDP_PORT` for incoming connections.
*
* You will also have to set `I_UNDERSTAND_THAT_STDIO_UDP_IS_INSECURE = 1` to
* acknowledge that you will only use this for debugging in an isolated network.
*
* @warning This is entirely unsecured, only use this for debugging in
* an isolated network!
*/

85
sys/stdio_udp/stdio_udp.c Normal file
View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2023 ML!PA Consulting GmbH
*
* 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_stdio_udp
* @{
*
* @file
* @brief STDIO over UDP implementation
*
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*
* @}
*/
#include <errno.h>
#include "macros/utils.h"
#include "net/sock/udp.h"
#ifndef CONFIG_STDIO_UDP_PORT
#define CONFIG_STDIO_UDP_PORT 2323
#endif
#ifndef CONFIG_STDIO_UDP_RX_BUF_LEN
#define CONFIG_STDIO_UDP_RX_BUF_LEN 64
#endif
static sock_udp_t sock;
static sock_udp_ep_t remote;
void stdio_init(void)
{
const sock_udp_ep_t local = {
.family = AF_INET6,
.netif = SOCK_ADDR_ANY_NETIF,
.port = CONFIG_STDIO_UDP_PORT,
};
sock_udp_create(&sock, &local, NULL, 0);
}
ssize_t stdio_read(void* buffer, size_t count)
{
static uint8_t rx_buf[CONFIG_STDIO_UDP_RX_BUF_LEN];
static uint8_t *pos;
static size_t left;
/* shell will only read one byte at a time, so we buffer the input */
if (left == 0) {
int res = sock_udp_recv(&sock, rx_buf, sizeof(rx_buf),
SOCK_NO_TIMEOUT, &remote);
if (res > 0) {
left = res;
pos = rx_buf;
} else {
return res;
}
}
count = MIN(left, count);
memcpy(buffer, pos, count);
left -= count;
pos += count;
return count;
}
ssize_t stdio_write(const void* buffer, size_t len)
{
if (remote.port == 0) {
return -ENOTCONN;
}
if (len == 0) {
return 0;
}
return sock_udp_send(&sock, buffer, len, &remote);
}

View File

@ -438,7 +438,8 @@ static int _dtv_fetch(suit_manifest_t *manifest, int key,
if (0) {}
#ifdef MODULE_SUIT_TRANSPORT_COAP
else if (strncmp(manifest->urlbuf, "coap://", 7) == 0) {
else if ((strncmp(manifest->urlbuf, "coap://", 7) == 0) ||
(IS_USED(MODULE_NANOCOAP_DTLS) && strncmp(manifest->urlbuf, "coaps://", 8) == 0)) {
res = nanocoap_get_blockwise_url(manifest->urlbuf, CONFIG_SUIT_COAP_BLOCKSIZE,
_storage_helper,
manifest);

View File

@ -32,17 +32,18 @@
#include "suit/handlers.h"
#include "suit.h"
static int _auth_handler(suit_manifest_t *manifest, int key,
nanocbor_value_t *it)
static int _verify_with_key(suit_manifest_t *manifest, const nanocbor_value_t *it,
const void *key)
{
(void)key;
cose_sign_dec_t verify;
const uint8_t *cose_buf;
const uint8_t *auth_container;
size_t auth_container_len;
size_t cose_len = 0;
nanocbor_value_t tmp = *it;
/* It is a list of cose signatures */
if (nanocbor_get_bstr(it, &auth_container, &auth_container_len) < 0) {
if (nanocbor_get_bstr(&tmp, &auth_container, &auth_container_len) < 0) {
LOG_INFO("Unable to get auth container\n");
return SUIT_ERR_INVALID_MANIFEST;
}
@ -51,7 +52,7 @@ static int _auth_handler(suit_manifest_t *manifest, int key,
cose_key_t pkey;
cose_key_init(&pkey);
cose_key_set_keys(&pkey, COSE_EC_CURVE_ED25519, COSE_ALGO_EDDSA,
(uint8_t *)public_key, NULL, NULL);
(void *)key, NULL, NULL);
nanocbor_value_t _cont, arr;
nanocbor_decoder_init(&_cont, auth_container, auth_container_len);
@ -96,6 +97,7 @@ static int _auth_handler(suit_manifest_t *manifest, int key,
}
else {
LOG_INFO("Unable to validate signature: %d\n", verification);
res = SUIT_ERR_SIGNATURE;
}
}
}
@ -103,6 +105,23 @@ static int _auth_handler(suit_manifest_t *manifest, int key,
return res;
}
static int _auth_handler(suit_manifest_t *manifest, int key,
nanocbor_value_t *it)
{
(void)key;
int res = 0;
for (unsigned i = 0; i < ARRAY_SIZE(public_key); ++i) {
res = _verify_with_key(manifest, it, public_key[i]);
if (res != SUIT_ERR_SIGNATURE) {
break;
}
}
return res;
}
static int _manifest_handler(suit_manifest_t *manifest, int key,
nanocbor_value_t *it)
{

View File

@ -87,7 +87,8 @@ int suit_handle_url(const char *url)
if (0) {}
#ifdef MODULE_SUIT_TRANSPORT_COAP
else if (strncmp(url, "coap://", 7) == 0) {
else if ((strncmp(url, "coap://", 7) == 0) ||
(IS_USED(MODULE_NANOCOAP_DTLS) && strncmp(url, "coaps://", 8) == 0)) {
size = nanocoap_get_blockwise_url_to_buf(url,
CONFIG_SUIT_COAP_BLOCKSIZE,
_manifest_buf,

View File

@ -30,10 +30,6 @@
#include "usb/usbus.h"
#include "usb/usbus/cdc/acm.h"
#if MODULE_VFS
#include "vfs.h"
#endif
static usbus_cdcacm_device_t cdcacm;
static uint8_t _cdc_tx_buf_mem[CONFIG_USBUS_CDC_ACM_STDIO_BUF_SIZE];
static uint8_t _cdc_rx_buf_mem[CONFIG_USBUS_CDC_ACM_STDIO_BUF_SIZE];
@ -41,10 +37,6 @@ static isrpipe_t _cdc_stdio_isrpipe = ISRPIPE_INIT(_cdc_rx_buf_mem);
void stdio_init(void)
{
/* Initialize this side of the CDC ACM pipe */
#if MODULE_VFS
vfs_bind_stdio();
#endif
}
#if IS_USED(MODULE_STDIO_AVAILABLE)

View File

@ -144,6 +144,18 @@ void ztimer_set_timeout_flag(ztimer_clock_t *clock, ztimer_t *t,
}
#endif
void ztimer_mutex_unlock(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
mutex_t *mutex)
{
unsigned state = irq_disable();
timer->callback = _callback_unlock_mutex;
timer->arg = (void *)mutex;
irq_restore(state);
ztimer_set(clock, timer, offset);
}
static void _callback_wakeup(void *arg)
{
thread_wakeup((kernel_pid_t)((intptr_t)arg));

View File

@ -22,22 +22,27 @@ LOW_MEMORY_BOARDS := \
blackpill-stm32f103c8 \
bluepill-stm32f103c8 \
derfmega128 \
im880b \
nucleo-f302r8 \
saml10-xpro \
saml11-xpro \
spark-core \
stm32f7508-dk \
stm32mp157c-dk2 \
#
# Don't enable VFS functions on small boards
# Don't enable VFS, DTLS functions on small boards
ifeq (,$(filter $(BOARD),$(LOW_MEMORY_BOARDS)))
USEMODULE += nanocoap_dtls
USEMODULE += prng_sha256prng
USEMODULE += nanocoap_vfs
USEMODULE += vfs_default
# USEMODULE += vfs_auto_format
USEMODULE += shell_cmds_default
# VFS operations require more stack on the main thread
CFLAGS += -DTHREAD_STACKSIZE_MAIN=THREAD_STACKSIZE_LARGE
# DTLS and VFS operations require more stack on the main thread
CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(3*THREAD_STACKSIZE_DEFAULT\)
# always enable auto-format for native
ifeq ($(BOARD),native)

View File

@ -21,6 +21,7 @@
#include <stdio.h>
#include "msg.h"
#include "net/nanocoap_sock.h"
#include "net/gnrc/netif.h"
#include "net/ipv6/addr.h"
#include "shell.h"
@ -28,6 +29,25 @@
#define MAIN_QUEUE_SIZE (4)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
#if IS_USED(MODULE_NANOCOAP_DTLS)
#include "net/credman.h"
#include "net/dsm.h"
#include "tinydtls_keys.h"
static const uint8_t psk_id_0[] = PSK_DEFAULT_IDENTITY;
static const uint8_t psk_key_0[] = PSK_DEFAULT_KEY;
static const credman_credential_t credential = {
.type = CREDMAN_TYPE_PSK,
.tag = CONFIG_NANOCOAP_SOCK_DTLS_TAG,
.params = {
.psk = {
.key = { .s = psk_key_0, .len = sizeof(psk_key_0) - 1, },
.id = { .s = psk_id_0, .len = sizeof(psk_id_0) - 1, },
}
},
};
#endif
extern int nanotest_client_cmd(int argc, char **argv);
extern int nanotest_client_url_cmd(int argc, char **argv);
extern int nanotest_server_cmd(int argc, char **argv);
@ -121,6 +141,14 @@ int main(void)
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("nanocoap test app");
#if IS_USED(MODULE_NANOCOAP_DTLS)
int res = credman_add(&credential);
if (res < 0 && res != CREDMAN_EXIST) {
printf("nanocoap: cannot add credential to system: %d\n", res);
return res;
}
#endif
/* start shell */
puts("All up, running the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2018 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.
*/
/**
* @ingroup examples
* @{
*
* @file
* @brief PSK and RPK keys for the dtls-sock example.
*
* @author Raul Fuentes <raul.fuentes-samaniego@inria.fr>
*
* @}
*/
#ifndef TINYDTLS_KEYS_H
#define TINYDTLS_KEYS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Default keys examples for tinyDTLS (for RIOT, Linux and Contiki)
*/
#define PSK_DEFAULT_IDENTITY "Client_identity"
#define PSK_DEFAULT_KEY "secretPSK"
#define PSK_OPTIONS "i:k:"
#define PSK_ID_MAXLEN 32
#define PSK_MAXLEN 32
#ifdef __cplusplus
}
#endif
#endif /* TINYDTLS_KEYS_H */