From 25826ef1325fc7f6fd7f69a063bb8504a87bbcf2 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Fri, 21 Nov 2025 20:56:32 +0100 Subject: [PATCH 01/14] drivers/slipmux: Rework slipdev driver and renaming --- CODEOWNERS | 1 - Makefile.dep | 2 +- boards/seeedstudio-xiao-esp32c3/Makefile.dep | 2 +- dist/tools/doccheck/exclude_simple | 7 - drivers/Makefile.dep | 4 +- drivers/include/slipdev.h | 191 ------- drivers/include/slipmux.h | 175 ++++++ drivers/slipdev/Kconfig | 22 - drivers/slipdev/Makefile.include | 2 - drivers/slipdev/include/slipdev_internal.h | 93 ---- drivers/slipdev/include/slipdev_params.h | 74 --- drivers/slipdev/slipdev.c | 500 ------------------ drivers/slipdev/stdio.c | 54 -- drivers/{slipdev => slipmux}/Makefile | 2 +- drivers/{slipdev => slipmux}/Makefile.dep | 14 +- drivers/slipmux/Makefile.include | 7 + drivers/slipmux/coap.c | 129 +++++ drivers/slipmux/include/slipmux_internal.h | 202 +++++++ drivers/slipmux/include/slipmux_params.h | 86 +++ drivers/slipmux/net.c | 237 +++++++++ drivers/slipmux/slipmux.c | 255 +++++++++ drivers/slipmux/stdio.c | 50 ++ examples/networking/coap/gcoap/Makefile.slip | 7 +- examples/networking/coap/gcoap/README-slip.md | 3 +- .../networking/coap/gcoap_dtls/Makefile.slip | 6 +- .../gnrc/border_router/Makefile.board.dep | 2 +- .../gnrc/border_router/Makefile.slip.conf | 6 +- .../networking/gnrc/border_router/README.md | 2 +- .../gnrc/networking_subnets/README.md | 4 +- makefiles/pseudomodules.inc.mk | 3 - makefiles/stdio.inc.mk | 4 +- pkg/lwip/contrib/netdev/lwip_netdev.c | 8 +- ...uto_init_slipdev.c => auto_init_slipmux.c} | 15 +- sys/include/net/gnrc/netif/conf.h | 2 +- sys/net/gnrc/Makefile.dep | 2 +- sys/net/gnrc/netif/gnrc_netif.c | 4 +- sys/net/gnrc/netif/gnrc_netif_device_type.c | 2 +- sys/net/link_layer/l2util/l2util.c | 10 +- sys/shell/cmds/gnrc_netif.c | 2 +- tests/net/slip/Makefile | 8 +- 40 files changed, 1205 insertions(+), 994 deletions(-) delete mode 100644 drivers/include/slipdev.h create mode 100644 drivers/include/slipmux.h delete mode 100644 drivers/slipdev/Kconfig delete mode 100644 drivers/slipdev/Makefile.include delete mode 100644 drivers/slipdev/include/slipdev_internal.h delete mode 100644 drivers/slipdev/include/slipdev_params.h delete mode 100644 drivers/slipdev/slipdev.c delete mode 100644 drivers/slipdev/stdio.c rename drivers/{slipdev => slipmux}/Makefile (69%) rename drivers/{slipdev => slipmux}/Makefile.dep (50%) create mode 100644 drivers/slipmux/Makefile.include create mode 100644 drivers/slipmux/coap.c create mode 100644 drivers/slipmux/include/slipmux_internal.h create mode 100644 drivers/slipmux/include/slipmux_params.h create mode 100644 drivers/slipmux/net.c create mode 100644 drivers/slipmux/slipmux.c create mode 100644 drivers/slipmux/stdio.c rename pkg/lwip/init_devs/{auto_init_slipdev.c => auto_init_slipmux.c} (67%) diff --git a/CODEOWNERS b/CODEOWNERS index 2d2ef0506a6d..18ca5a12f128 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -83,7 +83,6 @@ Cargo.* @chrysn /drivers/pca9685/ @gschorcht /drivers/sht3x/ @gschorcht /drivers/si70xx/ @basilfx -/drivers/slipdev/ @miri64 /drivers/sx127x/ @aabadie @jia200x /drivers/ws281x/ @maribu /drivers/xbee/ @miri64 diff --git a/Makefile.dep b/Makefile.dep index 17b6abba8523..ca279ba91d6e 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -3,7 +3,7 @@ -include $(APPDIR)/Makefile.$(TOOLCHAIN).dep # select default stdio provider if no other is selected -ifeq (,$(filter stdio_% slipdev_stdio,$(USEMODULE))) +ifeq (,$(filter stdio_% slipmux_stdio,$(USEMODULE))) USEMODULE += stdio_default endif diff --git a/boards/seeedstudio-xiao-esp32c3/Makefile.dep b/boards/seeedstudio-xiao-esp32c3/Makefile.dep index 0e4c6e045cc3..3b2332b47e26 100644 --- a/boards/seeedstudio-xiao-esp32c3/Makefile.dep +++ b/boards/seeedstudio-xiao-esp32c3/Makefile.dep @@ -13,7 +13,7 @@ ifeq (,$(filter info-% generate-%,$(MAKECMDGOALS))) endif endif -ifeq (,$(filter stdio_% slipdev_stdio,$(USEMODULE))) +ifeq (,$(filter stdio_% slipmux_stdio,$(USEMODULE))) USEMODULE += stdio_usb_serial_jtag endif diff --git a/dist/tools/doccheck/exclude_simple b/dist/tools/doccheck/exclude_simple index a080967d11a5..2ff4b60c0dbe 100644 --- a/dist/tools/doccheck/exclude_simple +++ b/dist/tools/doccheck/exclude_simple @@ -6399,13 +6399,6 @@ warning: Member SIXLOWPAN_ND_OPT_6CTX_LEN_MAX (macro definition) of group net_si warning: Member SIXLOWPAN_ND_OPT_6CTX_LEN_MIN (macro definition) of group net_sixlowpan_nd is not documented. warning: Member SIXLOWPAN_ND_OPT_ABR_LEN (macro definition) of group net_sixlowpan_nd is not documented. warning: Member SIXLOWPAN_ND_OPT_AR_LEN (macro definition) of group net_sixlowpan_nd is not documented. -warning: Member SLIPDEV_END_ESC (macro definition) of file slipdev_internal.h is not documented. -warning: Member SLIPDEV_END (macro definition) of file slipdev_internal.h is not documented. -warning: Member SLIPDEV_ESC_ESC (macro definition) of file slipdev_internal.h is not documented. -warning: Member SLIPDEV_ESC (macro definition) of file slipdev_internal.h is not documented. -warning: Member SLIPDEV_PARAM_BAUDRATE (macro definition) of file slipdev_params.h is not documented. -warning: Member SLIPDEV_PARAMS (macro definition) of file slipdev_params.h is not documented. -warning: Member SLIPDEV_PARAM_UART (macro definition) of file slipdev_params.h is not documented. warning: Member SLOTDURATION (macro definition) of file board_info.h is not documented. warning: Member SM_PWM_01C_PARAMS_DEFAULT (macro definition) of file sm_pwm_01c_params.h is not documented. warning: Member SM_PWM_01C_SAUL_INFO (macro definition) of file sm_pwm_01c_params.h is not documented. diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index ef2e8ec6ed19..b247c06b0835 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -238,8 +238,8 @@ ifneq (,$(filter si70%,$(USEMODULE))) USEMODULE += si70xx endif -ifneq (,$(filter slipdev_%,$(USEMODULE))) - USEMODULE += slipdev +ifneq (,$(filter slipmux_%,$(USEMODULE))) + USEMODULE += slipmux endif ifneq (,$(filter stmpe811_%,$(USEMODULE))) diff --git a/drivers/include/slipdev.h b/drivers/include/slipdev.h deleted file mode 100644 index 675f65dc8d7c..000000000000 --- a/drivers/include/slipdev.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2015-17 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. - */ - -#pragma once - -/** - * @defgroup drivers_slipdev_stdio STDIO via SLIP - * @ingroup sys_stdio - * @brief Standard input/output backend multiplexed via SLIP - * @see [draft-bormann-t2trg-slipmux-03](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03) - * - * This extension is part of the [Slipmux draft](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03). - * @warning This module is under development for optimizations and module names might change! - * - * 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_configuration CoAP via SLIP - * @ingroup drivers_slipdev - * @brief Exchange CoAP requests and responses via SLIP - * @see [draft-bormann-t2trg-slipmux-03](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03) - * - * This extension is part of the [Slipmux draft](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03). - * @warning This module is under development for optimizations and module names might change! - * - * This will multiplex CoAP messages via the Serial Line Internet Protocol. - * It spawns an extra thread as a CoAP server. The incoming requests are handled with `nanocoap` - * according to any `NANOCOAP_RESOURCE`s present in the binary. See @ref net_nanocoap for more. - * - * To enable this implementation, select - * - * USEMODULE += slipdev_config - * - * @see drivers_slipdev - */ - -/** - * @defgroup drivers_slipdev SLIP network device - * @ingroup drivers_netdev - * @brief SLIP network device over @ref drivers_periph_uart - * @see [RFC 1055](https://datatracker.ietf.org/doc/html/rfc1055) - * - * @{ - * - * @file - * @brief SLIP device definitions - * - * @author Martine Lenders - */ - -#include - -#include "cib.h" -#include "net/netdev.h" -#include "periph/uart.h" -#include "chunked_ringbuffer.h" -#include "sched.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup drivers_slipdev_config SLIP Network driver compile configuration - * @ingroup config_drivers_netdev - * @{ - */ -/** - * @brief UART buffer size used for TX and RX buffers - * - * Reduce this value if your expected traffic does not include full IPv6 MTU - * sized packets. - */ -#ifdef CONFIG_SLIPDEV_BUFSIZE_EXP -#define CONFIG_SLIPDEV_BUFSIZE (1< + +#include "cib.h" +#include "event.h" +#include "net/netdev.h" +#include "periph/uart.h" +#include "chunked_ringbuffer.h" +#include "sched.h" + +/** + * @defgroup drivers_slipmux Serial Line Internet Protocol Multiplexing + * @brief Provides de-/encoding for SLIPMUX + * @see [draft-bormann-t2trg-slipmux-03](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03) + * + * This is the base module, see @ref drivers_slipmux_net, @ref drivers_slipmux_coap and + * @ref drivers_slipmux_stdio for more information. + * + * @{ + * + * @file + * @brief SLIPMUX definitions + * + * @author Martine Lenders + * @author Bennet Hattesen + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup drivers_slipmux_stdio STDIO via SLIPMUX + * @ingroup sys_stdio + * @brief Standard input/output backend multiplexed via SLIPMUX + * @see [draft-bormann-t2trg-slipmux-03](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03) + * + * This extension is part of the [Slipmux draft](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03). + * @warning This module is under development for optimizations and module names might change! + * + * This multiplexes STDIO together with the Serial Line Internet Protocol via SLIPMUX. + * The shell can be accessed via the `sliptty` tool. + * + * To enable this stdio implementation, select + * + * USEMODULE += slipmux_stdio + * + * @see drivers_slipmux + */ + +/** + * @defgroup drivers_slipmux_coap CoAP via SLIP + * @ingroup drivers_slipmux + * @brief Exchange CoAP requests and responses via SLIPMUX + * @see [draft-bormann-t2trg-slipmux-03](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03) + * + * This extension is part of the [Slipmux draft](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03). + * @warning This module is under development for optimizations and module names might change! + * + * This will multiplex CoAP messages together with the Serial Line Internet Protocol via SLIPMUX. + * It spawns an extra thread as a CoAP server. The incoming requests are handled with `nanocoap` + * according to any `NANOCOAP_RESOURCE`s present in the binary. See @ref net_nanocoap for more. + * + * To enable this implementation, select + * + * USEMODULE += slipmux_coap + * + * @see drivers_slipmux + * @{ + */ + +/** + * @brief UART buffer size used for TX and RX buffers + * + * Reduce this value if your expected traffic does not include full IPv6 MTU + * sized packets. + */ +#ifndef CONFIG_SLIPMUX_COAP_BUFSIZE +# define CONFIG_SLIPMUX_COAP_BUFSIZE (512U) +#endif +/** @} */ + + +/** + * @defgroup drivers_slipmux_net SLIP network device + * @ingroup drivers_netdev + * @brief SLIP network device over @ref drivers_periph_uart + * @see [RFC 1055](https://datatracker.ietf.org/doc/html/rfc1055) + * + * This extension is part of the [Slipmux draft](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03). + * @warning This module is under development for optimizations and module names might change! + * + * This will offer the traditional Serial Line Internet Protocol as a network interface + * using GNRC. + * + * To enable this implementation, select + * + * USEMODULE += slipmux_net + * + * @see drivers_slipmux + * + * @{ + */ + +/** + * @brief Buffer size used for TX and RX buffers + * + * Reduce this value if your expected traffic does not include full IPv6 MTU + * sized packets. + */ +#ifdef CONFIG_SLIPMUX_NET_BUFSIZE_EXP +# define CONFIG_SLIPMUX_NET_BUFSIZE (1< - */ - -#include -#include - -#include "isrpipe.h" -#include "periph/uart.h" -#include "mutex.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @name SLIP marker bytes - * @see [RFC 1055](https://tools.ietf.org/html/rfc1055) - * @{ - */ -#define SLIPDEV_END (0xc0U) -#define SLIPDEV_ESC (0xdbU) -#define SLIPDEV_END_ESC (0xdcU) -#define SLIPDEV_ESC_ESC (0xddU) - -/** - * @brief Marker byte for beginning of stdio - * @see taken from diagnostic transfer from - * [SLIPMUX](https://tools.ietf.org/html/draft-bormann-t2trg-slipmux-03#section-4) - */ -#define SLIPDEV_STDIO_START (0x0aU) - -/** - * @brief Marker byte for beginning of configuration/CoAP - * @see taken from configuration from - * [SLIPMUX](https://tools.ietf.org/html/draft-bormann-t2trg-slipmux-03#section-5) - */ -#define SLIPDEV_CONFIG_START (0xa9U) -/** @} */ - -/** - * @brief ISR pipe to hand read bytes to stdin - */ -extern isrpipe_t slipdev_stdio_isrpipe; - -/** - * @brief Mutex to synchronize write operations to the UART between stdio - * sub-module and normal SLIP. - */ -extern mutex_t slipdev_mutex; - -/** - * @brief Writes one byte to UART - * - * @param[in] uart The UART device to write to. - * @param[in] byte The byte to write to @p uart. - */ -static inline void slipdev_write_byte(uart_t uart, uint8_t byte) -{ - uart_write(uart, &byte, 1U); -} - -/** - * @brief Write multiple bytes SLIP-escaped to UART - * - * @param[in] uart The UART device to write to. - * @param[in] data The bytes to write SLIP-escaped to @p uart. - * @param[in] len Number of bytes in @p data. - */ -void slipdev_write_bytes(uart_t uart, const uint8_t *data, size_t len); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/drivers/slipdev/include/slipdev_params.h b/drivers/slipdev/include/slipdev_params.h deleted file mode 100644 index f4601e6a873d..000000000000 --- a/drivers/slipdev/include/slipdev_params.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2018-2020 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. - */ - -#pragma once - -/** - * @ingroup drivers_slipdev - * @{ - * - * @file - * @brief Default configuration for the SLIP device driver - * - * @author Martine Lenders - */ - -#include "board.h" -#include "slipdev.h" -#ifdef MODULE_SLIPDEV_STDIO -#include "stdio_uart.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @name Set default configuration parameters for slipdev driver - * @{ - */ -#ifndef SLIPDEV_PARAM_UART -# ifndef MODULE_SLIPDEV_STDIO -# ifdef MODULE_USBUS_CDC_ACM -# define SLIPDEV_PARAM_UART UART_DEV(0) -# else -# define SLIPDEV_PARAM_UART UART_DEV(1) -# endif -# else /* MODULE_SLIPDEV_STDIO */ -# define SLIPDEV_PARAM_UART STDIO_UART_DEV -# endif /* MODULE_SLIPDEV_STDIO */ -#endif /* SLIPDEV_PARAM_UART */ -#ifndef SLIPDEV_PARAM_BAUDRATE -# ifndef MODULE_SLIPDEV_STDIO -# define SLIPDEV_PARAM_BAUDRATE (115200U) -# else /* MODULE_SLIPDEV_STDIO */ -# define SLIPDEV_PARAM_BAUDRATE (STDIO_UART_BAUDRATE) -# endif /* MODULE_SLIPDEV_STDIO */ -#endif /* SLIPDEV_PARAM_BAUDRATE */ - -#ifndef SLIPDEV_PARAMS -#define SLIPDEV_PARAMS { .uart = SLIPDEV_PARAM_UART, \ - .baudrate = SLIPDEV_PARAM_BAUDRATE } -#endif -/** @} */ - -/** - * @brief slipdev configuration - * - * The first element in this array will be used to multiplex stdio if - * `slipdev_stdio` is included. - */ -static const slipdev_params_t slipdev_params[] = { - SLIPDEV_PARAMS -}; - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/drivers/slipdev/slipdev.c b/drivers/slipdev/slipdev.c deleted file mode 100644 index 97bed93c0b1a..000000000000 --- a/drivers/slipdev/slipdev.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -/** - * @{ - * - * @file - * @author Martine Lenders - * @author Benjamin Valentin - * @author Bennet Hattesen - */ - -#include -#include -#include -#include - -#include "log.h" -#include "slipdev.h" -#include "slipdev_internal.h" -#include "net/eui_provider.h" - -/* XXX: BE CAREFUL ABOUT USING OUTPUT WITH MODULE_SLIPDEV_STDIO IN SENDING - * FUNCTIONALITY! MIGHT CAUSE DEADLOCK!!!1!! */ -#define ENABLE_DEBUG 0 -#include "debug.h" - -#include "isrpipe.h" -#include "mutex.h" -#if IS_USED(MODULE_SLIPDEV_CONFIG) -#include "checksum/crc16_ccitt.h" -#include "net/nanocoap.h" -#endif -#include "stdio_uart.h" - -#if (IS_USED(MODULE_SLIPDEV_STDIO) || IS_USED(MODULE_SLIPDEV_CONFIG)) -/* For synchronization with stdio/config threads */ -mutex_t slipdev_mutex = MUTEX_INIT; -#endif - -#if IS_USED(MODULE_SLIPDEV_CONFIG) -/* The special init is the result of normal fcs init combined with slipmux config start (0xa9) */ -#define SPECIAL_INIT_FCS (0x374cU) -#define COAP_STACKSIZE (1024) - -static char coap_stack[COAP_STACKSIZE]; -#endif /* IS_USED(MODULE_SLIPDEV_CONFIG) */ - -static int _check_state(slipdev_t *dev); - -static inline void slipdev_lock(void) -{ - if (IS_USED(MODULE_SLIPDEV_STDIO) || IS_USED(MODULE_SLIPDEV_CONFIG)) { - mutex_lock(&slipdev_mutex); - } -} - -static inline void slipdev_unlock(void) -{ - if (IS_USED(MODULE_SLIPDEV_STDIO) || IS_USED(MODULE_SLIPDEV_CONFIG)) { - mutex_unlock(&slipdev_mutex); - } -} - -static void _slip_rx_cb(void *arg, uint8_t byte) -{ - slipdev_t *dev = arg; - - switch (dev->state) { - case SLIPDEV_STATE_STDIN: - switch (byte) { - case SLIPDEV_ESC: - dev->state = SLIPDEV_STATE_STDIN_ESC; - break; - case SLIPDEV_END: - dev->state = SLIPDEV_STATE_NONE; - break; - default: -#if IS_USED(MODULE_SLIPDEV_STDIO) - if (dev->config.uart == STDIO_UART_DEV) { - isrpipe_write_one(&stdin_isrpipe, byte); - } -#endif - break; - } - return; - case SLIPDEV_STATE_STDIN_ESC: - switch (byte) { - case SLIPDEV_END_ESC: - byte = SLIPDEV_END; - break; - case SLIPDEV_ESC_ESC: - byte = SLIPDEV_ESC; - break; - } - dev->state = SLIPDEV_STATE_STDIN; -#if IS_USED(MODULE_SLIPDEV_STDIO) - if (dev->config.uart == STDIO_UART_DEV) { - isrpipe_write_one(&stdin_isrpipe, byte); - } -#endif - return; - case SLIPDEV_STATE_CONFIG: - switch (byte) { - case SLIPDEV_ESC: - dev->state = SLIPDEV_STATE_CONFIG_ESC; - break; - case SLIPDEV_END: - dev->state = SLIPDEV_STATE_NONE; -#if IS_USED(MODULE_SLIPDEV_CONFIG) - crb_end_chunk(&dev->rb_config, true); - thread_flags_set(thread_get(dev->coap_server_pid), 1); -#endif - break; - default: -#if IS_USED(MODULE_SLIPDEV_CONFIG) - /* discard frame if byte can't be added */ - if (!crb_add_byte(&dev->rb_config, byte)) { - DEBUG("slipdev: rx buffer full, drop frame\n"); - crb_end_chunk(&dev->rb_config, false); - dev->state = SLIPDEV_STATE_NONE; - return; - } -#endif - break; - } - return; - case SLIPDEV_STATE_CONFIG_ESC: - switch (byte) { - case SLIPDEV_END_ESC: - byte = SLIPDEV_END; - break; - case SLIPDEV_ESC_ESC: - byte = SLIPDEV_ESC; - break; - } -#if IS_USED(MODULE_SLIPDEV_CONFIG) - /* discard frame if byte can't be added */ - if (!crb_add_byte(&dev->rb_config, byte)) { - DEBUG("slipdev: rx buffer full, drop frame\n"); - crb_end_chunk(&dev->rb_config, false); - dev->state = SLIPDEV_STATE_NONE; - return; - } -#endif - dev->state = SLIPDEV_STATE_CONFIG; - return; - case SLIPDEV_STATE_NONE: - /* is diagnostic frame? */ - if (byte == SLIPDEV_STDIO_START) { - dev->state = SLIPDEV_STATE_STDIN; - return; - } - - if (byte == SLIPDEV_CONFIG_START) { -#if IS_USED(MODULE_SLIPDEV_CONFIG) - /* try to create new frame */ - if (!crb_start_chunk(&dev->rb_config)) { - return; - } -#endif - dev->state = SLIPDEV_STATE_CONFIG; - return; - } - - /* ignore empty frame */ - if (byte == SLIPDEV_END) { - return; - } - - /* try to create new ip frame */ - if (!crb_start_chunk(&dev->rb)) { - return; - } - dev->state = SLIPDEV_STATE_NET; - /* fall-through */ - case SLIPDEV_STATE_NET: - switch (byte) { - case SLIPDEV_ESC: - dev->state = SLIPDEV_STATE_NET_ESC; - return; - case SLIPDEV_END: - crb_end_chunk(&dev->rb, true); - netdev_trigger_event_isr(&dev->netdev); - dev->state = SLIPDEV_STATE_NONE; - return; - } - break; - /* escaped byte received */ - case SLIPDEV_STATE_NET_ESC: - switch (byte) { - case SLIPDEV_END_ESC: - byte = SLIPDEV_END; - break; - case SLIPDEV_ESC_ESC: - byte = SLIPDEV_ESC; - break; - } - dev->state = SLIPDEV_STATE_NET; - break; - } - - assert(dev->state == SLIPDEV_STATE_NET); - - /* discard frame if byte can't be added */ - if (!crb_add_byte(&dev->rb, byte)) { - DEBUG("slipdev: rx buffer full, drop frame\n"); - crb_end_chunk(&dev->rb, false); - dev->state = SLIPDEV_STATE_NONE; - return; - } -} - -static void _poweron(slipdev_t *dev) -{ - if ((dev->state != SLIPDEV_STATE_STANDBY) && - (dev->state != SLIPDEV_STATE_SLEEP)) { - return; - } - - dev->state = 0; - uart_init(dev->config.uart, dev->config.baudrate, _slip_rx_cb, dev); -} - -static inline void _poweroff(slipdev_t *dev, uint8_t state) -{ - uart_poweroff(dev->config.uart); - dev->state = state; -} - -static int _init(netdev_t *netdev) -{ - slipdev_t *dev = (slipdev_t *)netdev; - - DEBUG("slipdev: initializing device %p on UART %i with baudrate %" PRIu32 "\n", - (void *)dev, dev->config.uart, dev->config.baudrate); - /* initialize buffers */ - crb_init(&dev->rb, dev->rxmem, sizeof(dev->rxmem)); - if (uart_init(dev->config.uart, dev->config.baudrate, _slip_rx_cb, - dev) != UART_OK) { - LOG_ERROR("slipdev: error initializing UART %i with baudrate %" PRIu32 "\n", - dev->config.uart, dev->config.baudrate); - return -ENODEV; - } - - /* signal link UP */ - netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP); - - return 0; -} - -void slipdev_write_bytes(uart_t uart, const uint8_t *data, size_t len) -{ - for (unsigned j = 0; j < len; j++, data++) { - switch (*data) { - case SLIPDEV_END: - /* escaping END byte*/ - slipdev_write_byte(uart, SLIPDEV_ESC); - slipdev_write_byte(uart, SLIPDEV_END_ESC); - break; - case SLIPDEV_ESC: - /* escaping ESC byte*/ - slipdev_write_byte(uart, SLIPDEV_ESC); - slipdev_write_byte(uart, SLIPDEV_ESC_ESC); - break; - default: - slipdev_write_byte(uart, *data); - } - } -} - -static int _check_state(slipdev_t *dev) -{ - /* power states not supported when multiplexing stdio / configuration */ - if (IS_USED(MODULE_SLIPDEV_STDIO) || IS_USED(MODULE_SLIPDEV_CONFIG)) { - return 0; - } - - /* discard data when interface is in SLEEP mode */ - if (dev->state == SLIPDEV_STATE_SLEEP) { - return -ENETDOWN; - } - - /* sending data wakes the interface from STANDBY */ - if (dev->state == SLIPDEV_STATE_STANDBY) { - _poweron(dev); - } - - return 0; -} - -static int _send(netdev_t *netdev, const iolist_t *iolist) -{ - slipdev_t *dev = (slipdev_t *)netdev; - int bytes = _check_state(dev); - if (bytes) { - return bytes; - } - - DEBUG("slipdev: sending iolist\n"); - slipdev_lock(); - for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { - uint8_t *data = iol->iol_base; - slipdev_write_bytes(dev->config.uart, data, iol->iol_len); - bytes += iol->iol_len; - } - slipdev_write_byte(dev->config.uart, SLIPDEV_END); - slipdev_unlock(); - - return bytes; -} - -static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) -{ - slipdev_t *dev = (slipdev_t *)netdev; - size_t res = 0; - - (void)info; - if (buf == NULL) { - if (len > 0) { - /* remove data */ - crb_consume_chunk(&dev->rb, NULL, len); - } else { - /* the user was warned not to use a buffer size > `INT_MAX` ;-) */ - crb_get_chunk_size(&dev->rb, &res); - } - } - else { - crb_consume_chunk(&dev->rb, buf, len); - res = len; - } - return res; -} - -static void _isr(netdev_t *netdev) -{ - slipdev_t *dev = (slipdev_t *)netdev; - - DEBUG("slipdev: handling ISR event\n"); - - size_t len; - while (crb_get_chunk_size(&dev->rb, &len)) { - DEBUG("slipdev: event handler set, issuing RX_COMPLETE event\n"); - netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); - } -} - -#if !(IS_USED(MODULE_SLIPDEV_STDIO) || IS_USED(MODULE_SLIPDEV_CONFIG)) -static int _set_state(slipdev_t *dev, netopt_state_t state) -{ - if (IS_USED(MODULE_SLIPDEV_STDIO)) { - return -ENOTSUP; - } - - switch (state) { - case NETOPT_STATE_STANDBY: - _poweroff(dev, SLIPDEV_STATE_STANDBY); - break; - case NETOPT_STATE_SLEEP: - _poweroff(dev, SLIPDEV_STATE_SLEEP); - break; - case NETOPT_STATE_IDLE: - _poweron(dev); - break; - default: - return -ENOTSUP; - } - - return sizeof(netopt_state_t); -} - -static int _set(netdev_t *netdev, netopt_t opt, const void *value, size_t max_len) -{ - (void)max_len; - - slipdev_t *dev = (slipdev_t *)netdev; - switch (opt) { - case NETOPT_STATE: - assert(max_len <= sizeof(netopt_state_t)); - return _set_state(dev, *((const netopt_state_t *)value)); - default: - return -ENOTSUP; - } -} -#endif /* !(MODULE_SLIPDEV_STDIO || MODULE_SLIPDEV_CONFIG) */ - -static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len) -{ - (void)netdev; - (void)value; - (void)max_len; - switch (opt) { - case NETOPT_IS_WIRED: - return 1; - case NETOPT_DEVICE_TYPE: - assert(max_len == sizeof(uint16_t)); - *((uint16_t *)value) = NETDEV_TYPE_SLIP; - return sizeof(uint16_t); -#if IS_USED(MODULE_SLIPDEV_L2ADDR) - case NETOPT_ADDRESS_LONG: - assert(max_len == sizeof(eui64_t)); - netdev_eui64_get(netdev, value); - return sizeof(eui64_t); -#endif - default: - return -ENOTSUP; - } -} - -static int _confirm_send(netdev_t *netdev, void *info) -{ - (void)netdev; - (void)info; - return -EOPNOTSUPP; -} - -static const netdev_driver_t slip_driver = { - .send = _send, - .recv = _recv, - .init = _init, - .isr = _isr, - .get = _get, - .confirm_send = _confirm_send, -#if (IS_USED(MODULE_SLIPDEV_STDIO) || IS_USED(MODULE_SLIPDEV_CONFIG)) - .set = netdev_set_notsup, -#else - .set = _set, -#endif -}; - -#if IS_USED(MODULE_SLIPDEV_CONFIG) -static void *_coap_server_thread(void *arg) -{ - static uint8_t buf[512]; - slipdev_t *dev = arg; - while (1) { - thread_flags_wait_any(1); - size_t len; - while (crb_get_chunk_size(&dev->rb_config, &len)) { - crb_consume_chunk(&dev->rb_config, buf, len); - - /* Is the crc correct via residue(=0xF0B8) test */ - if (crc16_ccitt_fcs_update(SPECIAL_INIT_FCS, buf, len) != 0xF0B8) { - break; - } - - /* cut off the FCS checksum at the end */ - size_t pktlen = len - 2; - - coap_pkt_t pkt; - sock_udp_ep_t remote; - coap_request_ctx_t ctx = { - .remote = &remote, - }; - if (coap_parse(&pkt, buf, pktlen) < 0) { - break; - } - unsigned int res = 0; - if ((res = coap_handle_req(&pkt, buf, sizeof(buf), &ctx)) <= 0) { - break; - } - - uint16_t fcs_sum = crc16_ccitt_fcs_finish(SPECIAL_INIT_FCS, buf, res); - - slipdev_lock(); - slipdev_write_byte(dev->config.uart, SLIPDEV_CONFIG_START); - slipdev_write_bytes(dev->config.uart, buf, res); - slipdev_write_bytes(dev->config.uart, (uint8_t *) &fcs_sum, 2); - slipdev_write_byte(dev->config.uart, SLIPDEV_END); - slipdev_unlock(); - } - } - - return NULL; -} -#endif /* MODULE_SLIPDEV_CONFIG */ - -void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params, uint8_t index) -{ -#if IS_USED(MODULE_SLIPDEV_CONFIG) - crb_init(&dev->rb_config, dev->rxmem_config, sizeof(dev->rxmem_config)); - - dev->coap_server_pid = thread_create(coap_stack, sizeof(coap_stack), THREAD_PRIORITY_MAIN - 1, - THREAD_CREATE_STACKTEST, _coap_server_thread, - (void *)dev, "Slipmux CoAP server"); -#endif - /* set device descriptor fields */ - dev->config = *params; - dev->state = 0; - dev->netdev.driver = &slip_driver; - - netdev_register(&dev->netdev, NETDEV_SLIPDEV, index); -} - -/** @} */ diff --git a/drivers/slipdev/stdio.c b/drivers/slipdev/stdio.c deleted file mode 100644 index 833e26e41b86..000000000000 --- a/drivers/slipdev/stdio.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -/** - * @{ - * - * @file - * @author Martine Lenders - */ - -#include "board.h" -#include "isrpipe.h" -#include "periph/uart.h" - -#include "slipdev.h" -#include "slipdev_internal.h" -#include "slipdev_params.h" - -#include "stdio_base.h" -#include "stdio_uart.h" - -static void _isrpipe_write(void *arg, uint8_t data) -{ - isrpipe_write_one(arg, (char)data); -} - -static void _init(void) -{ - /* intentionally overwritten in netdev init so we have stdio before - * the network device is initialized */ - uart_init(slipdev_params[0].uart, slipdev_params[0].baudrate, - _isrpipe_write, &stdin_isrpipe); - - slipdev_write_byte(slipdev_params[0].uart, SLIPDEV_END); -} - -static ssize_t _write(const void *buffer, size_t len) -{ - mutex_lock(&slipdev_mutex); - slipdev_write_byte(slipdev_params[0].uart, SLIPDEV_STDIO_START); - slipdev_write_bytes(slipdev_params[0].uart, buffer, len); - slipdev_write_byte(slipdev_params[0].uart, SLIPDEV_END); - mutex_unlock(&slipdev_mutex); - return len; -} - -STDIO_PROVIDER(STDIO_SLIP, _init, NULL, _write) - -/** @} */ diff --git a/drivers/slipdev/Makefile b/drivers/slipmux/Makefile similarity index 69% rename from drivers/slipdev/Makefile rename to drivers/slipmux/Makefile index 7c6f250804f4..fd394c384896 100644 --- a/drivers/slipdev/Makefile +++ b/drivers/slipmux/Makefile @@ -1,5 +1,5 @@ # exclude submodule sources from *.c wildcard source selection -SRC := $(filter-out stdio.c,$(wildcard *.c)) +SRC := $(filter-out stdio.c coap.c net.c,$(wildcard *.c)) # enable submodules SUBMODULES := 1 diff --git a/drivers/slipdev/Makefile.dep b/drivers/slipmux/Makefile.dep similarity index 50% rename from drivers/slipdev/Makefile.dep rename to drivers/slipmux/Makefile.dep index f738e8b96057..88f5592c79dc 100644 --- a/drivers/slipdev/Makefile.dep +++ b/drivers/slipmux/Makefile.dep @@ -1,13 +1,23 @@ +ifneq (,$(filter slipmux_net_l2addr,$(USEMODULE))) + USEMODULE += slipmux_net +endif + +ifeq (,$(filter slipmux_%,$(USEMODULE))) + USEMODULE += slipmux_stdio + USEMODULE += slipmux_coap + USEMODULE += slipmux_net +endif + USEMODULE += chunked_ringbuffer USEMODULE += eui_provider USEMODULE += netdev_new_api USEMODULE += netdev_register FEATURES_REQUIRED += periph_uart -ifneq (,$(filter slipdev_stdio,$(USEMODULE))) +ifneq (,$(filter slipmux_stdio,$(USEMODULE))) USEMODULE += isrpipe endif -ifneq (,$(filter slipdev_config,$(USEMODULE))) +ifneq (,$(filter slipmux_coap,$(USEMODULE))) USEMODULE += checksum USEMODULE += sock_udp USEMODULE += gnrc_ipv6 diff --git a/drivers/slipmux/Makefile.include b/drivers/slipmux/Makefile.include new file mode 100644 index 000000000000..1ca1eef0d613 --- /dev/null +++ b/drivers/slipmux/Makefile.include @@ -0,0 +1,7 @@ +PSEUDOMODULES += slipmux_stdio +PSEUDOMODULES += slipmux_coap +PSEUDOMODULES += slipmux_net +PSEUDOMODULES += slipmux_net_l2addr + +USEMODULE_INCLUDES_slipmux := $(LAST_MAKEFILEDIR)/include +USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_slipmux) diff --git a/drivers/slipmux/coap.c b/drivers/slipmux/coap.c new file mode 100644 index 000000000000..0a77f30f0b22 --- /dev/null +++ b/drivers/slipmux/coap.c @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @{ + * + * @file + * @author Bennet Hattesen + */ + +#include "chunked_ringbuffer.h" +#include "checksum/crc16_ccitt.h" +#include "event.h" +#include "net/nanocoap.h" + +#include "slipmux_internal.h" +#include "slipmux.h" + +/* The special init is the result of normal fcs init combined with slipmux config start (0xa9) */ +#define SPECIAL_INIT_FCS (0x374cU) + +#define COAP_STACKSIZE (1024) +static char coap_stack[COAP_STACKSIZE]; + +static event_queue_t queue; + +static uint8_t buf[CONFIG_SLIPMUX_COAP_BUFSIZE]; + +/* called in ISR context */ +void slipmux_coap_notify(slipmux_t *dev) +{ + if (queue.waiter) { + event_post(&queue, &dev->event); + } +} + +void slipmux_coap_send(uint8_t *buf, size_t len, slipmux_t *dev) +{ + uint16_t fcs_sum = crc16_ccitt_fcs_finish(SPECIAL_INIT_FCS, buf, len); + + slipmux_lock(dev); + slipmux_write_byte(dev->config.uart, SLIPMUX_COAP_START); + slipmux_write_bytes(dev->config.uart, buf, len); + slipmux_write_bytes(dev->config.uart, (uint8_t *) &fcs_sum, 2); + slipmux_write_byte(dev->config.uart, SLIPMUX_END); + slipmux_unlock(dev); +} + +int slipmux_coap_recv(uint8_t *buf, size_t buf_size, slipmux_t *dev) +{ + size_t len; + if (crb_get_chunk_size(&dev->coap_rb, &len)) { + if ((len > buf_size) || (len <= 2)) { + return -1; + } + + crb_consume_chunk(&dev->coap_rb, buf, len); + + /* Is the CRC correct via residue(=0xF0B8) test */ + if (crc16_ccitt_fcs_update(SPECIAL_INIT_FCS, buf, len) != 0xF0B8) { + return -1; + } + + /* cut off the FCS checksum at the end */ + size_t pktlen = len - 2; + + return pktlen; + } + return 0; +} + +void slipmux_recv_handler(event_t * event) +{ + slipmux_t *dev = container_of(event, slipmux_t, event); + + while (1) { + ssize_t len = slipmux_coap_recv(buf, sizeof(buf), dev); + if (len <= 0) { + return; + } + + coap_pkt_t pkt; + sock_udp_ep_t remote; + coap_request_ctx_t ctx = { + .remote = &remote, + }; + if (coap_parse(&pkt, buf, len) < 0) { + break; + } + + unsigned int res = 0; + if ((res = coap_handle_req(&pkt, buf, sizeof(buf), &ctx)) <= 0) { + break; + } + + slipmux_coap_send(buf, res, dev); + } +} + +static void *_coap_server_thread(void *arg) +{ + (void) arg; + event_queue_claim(&queue); + while (1) { + event_t *event = event_wait(&queue); + event->handler(event); + } + + return NULL; +} + +void slipmux_coap_init(slipmux_t *dev, unsigned index) +{ + (void) index; + dev->event.handler = slipmux_recv_handler; + crb_init(&dev->coap_rb, dev->coap_rx, sizeof(dev->coap_rx)); + + if (!queue.waiter) { + event_queue_init_detached(&queue); + dev->coap_server_pid = thread_create(coap_stack, sizeof(coap_stack), + THREAD_PRIORITY_MAIN - 1, + THREAD_CREATE_STACKTEST, _coap_server_thread, + (void *)dev, "Slipmux CoAP server"); + } +} + +/** @} */ diff --git a/drivers/slipmux/include/slipmux_internal.h b/drivers/slipmux/include/slipmux_internal.h new file mode 100644 index 000000000000..8d7732469776 --- /dev/null +++ b/drivers/slipmux/include/slipmux_internal.h @@ -0,0 +1,202 @@ +/* + * SPDX-FileCopyrightText: 2018 Freie Universität Berlin + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup drivers_slipmux + * @{ + * + * @file + * @internal + * @brief Internal SLIPMUX device definitions + * + * @author Martine Lenders + * @author Bennet Hattesen + */ + +#include +#include + +#include "periph/uart.h" +#include "mutex.h" + +#include "slipmux_params.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Number of slipmux devices, Parameters and array defined in slipmux_params.h + */ +#define SLIPMUX_DEV_NUM ARRAY_SIZE(slipmux_params) + +/** + * @brief List of slipmux devices. + */ +extern slipmux_t slipmux_devs[SLIPMUX_DEV_NUM]; + +/** + * @name SLIP marker bytes + * @see [RFC 1055](https://tools.ietf.org/html/rfc1055) + * @{ + */ +/** + * @brief Ends a frame + */ +#define SLIPMUX_END (0xc0U) +/** + * @brief Initiates escape sequence + */ +#define SLIPMUX_ESC (0xdbU) +/** + * @brief Ends escape sequence, next byte is END + */ +#define SLIPMUX_END_ESC (0xdcU) +/** + * @brief Ends escape sequence, next byte is ESC + */ +#define SLIPMUX_ESC_ESC (0xddU) +/** @} */ + +/** + * @name SLIPMUX marker bytes + * @see [SLIPMUX](https://tools.ietf.org/html/draft-bormann-t2trg-slipmux-03#section-4) + * @{ + */ +/** + * @brief Starts a diagnostic frame + */ +#define SLIPMUX_STDIO_START (0x0aU) +/** + * @brief Starts a configuration frame + */ +#define SLIPMUX_COAP_START (0xa9U) +/** + * @brief Starts a IP packet frame + */ +#define SLIPMUX_NET_START(byte) (\ + /* is it an IPv4 packet? */ \ + (byte >= 0x45 && byte <= 0x4f) || \ + /* or is it an IPv6 packet? */ \ + (byte >= 0x60 && byte <= 0x6f) \ + ) +/** @} */ + +/** + * @brief Decoder internal state + */ +enum { + /* Device is in no mode (currently did not receiving any data frame) */ + SLIPMUX_STATE_NONE = 0, + /* Device writes handles data as network device */ + SLIPMUX_STATE_NET, + /* Device writes handles data as network device, next byte is escaped */ + SLIPMUX_STATE_NET_ESC, + /* Device writes received data to stdin */ + SLIPMUX_STATE_STDIN, + /* Device writes received data to stdin, next byte is escaped */ + SLIPMUX_STATE_STDIN_ESC, + /* Device writes received data as CoAP message */ + SLIPMUX_STATE_COAP, + /* Device writes received data as CoAP message, next byte is escaped */ + SLIPMUX_STATE_COAP_ESC, + /* Device is in standby, will wake up when sending data */ + SLIPMUX_STATE_STANDBY, + /* Device is in sleep mode */ + SLIPMUX_STATE_SLEEP, +}; + +/** + * @brief Callback for the UART on receiving data + */ +void slipmux_rx_cb(void *arg, uint8_t byte); + +/** + * @brief Writes one byte to UART + * + * @param[in] uart The UART device to write to. + * @param[in] byte The byte to write to @p uart. + */ +static inline void slipmux_write_byte(uart_t uart, uint8_t byte) +{ + uart_write(uart, &byte, 1U); +} + +/** + * @brief Write multiple bytes SLIPMUX-escaped to UART + * + * @param[in] uart The UART device to write to. + * @param[in] data The bytes to write SLIPMUX-escaped to @p uart. + * @param[in] len Number of bytes in @p data. + */ +void slipmux_write_bytes(uart_t uart, const uint8_t *data, size_t len); + +/** + * @brief Acquire exclusive access for writing + * Guarded for _stdio or _coap, the idea being that if only _net is + * used, you are most likely to care about performance. + */ +static inline void slipmux_lock(slipmux_t *dev) +{ + (void) dev; +#if IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP) + mutex_lock(&dev->mutex); +#endif +} + +/** + * @brief Release the exclusive access + */ +static inline void slipmux_unlock(slipmux_t *dev) +{ + (void) dev; +#if IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP) + mutex_unlock(&dev->mutex); +#endif +} + +#if IS_USED(MODULE_SLIPMUX_COAP) +/** + * @brief Initialise the CoAP handling + * + * @param[in] dev The Slipmux device to initialise. + * @param[in] index Device number. + */ +void slipmux_coap_init(slipmux_t *dev, unsigned index); + +/** + * @brief Inform the CoAP server there is new work to do. + * Called in ISR context! + * + * @param[in] dev The Slipmux device to notify. + */ +void slipmux_coap_notify(slipmux_t *dev); +#endif +#if IS_USED(MODULE_SLIPMUX_NET) +/** + * @brief Initialise the network handling + * + * @param[in] dev The Slipmux device to initialise. + * @param[in] index Device number. + */ +void slipmux_net_init(slipmux_t *dev, unsigned index); + +/** + * @brief Inform the Network interface there is new work to do. + * Called in ISR context! + * + * @param[in] dev The Slipmux device to notify. + */ +void slipmux_net_notify(slipmux_t *dev); +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/drivers/slipmux/include/slipmux_params.h b/drivers/slipmux/include/slipmux_params.h new file mode 100644 index 000000000000..88f9adaee829 --- /dev/null +++ b/drivers/slipmux/include/slipmux_params.h @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2018 Freie Universität Berlin + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup drivers_slipmux + * @{ + * + * @file + * @brief Default configuration for the SLIPMUX device driver + * + * @author Martine Lenders + */ + +#include "board.h" +#include "slipmux.h" +#ifdef MODULE_SLIPMUX_STDIO +# include "stdio_uart.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Set default configuration parameters for slipmux driver + * @{ + */ +#if DOXYGEN +/** + * @brief Default UART to use + */ +#define SLIPMUX_PARAM_UART UART_DEV(0) +/** + * @brief Default baudrate to use + */ +#define SLIPMUX_PARAM_BAUDRATE (115200U) +#endif /* DOXYGEN */ + +#ifndef SLIPMUX_PARAM_UART +# ifndef MODULE_SLIPMUX_STDIO +# ifdef MODULE_USBUS_CDC_ACM +# define SLIPMUX_PARAM_UART UART_DEV(0) +# else +# define SLIPMUX_PARAM_UART UART_DEV(1) +# endif +# else /* MODULE_SLIPMUX_STDIO */ +# define SLIPMUX_PARAM_UART STDIO_UART_DEV +# endif /* MODULE_SLIPMUX_STDIO */ +#endif /* SLIPMUX_PARAM_UART */ +#ifndef SLIPMUX_PARAM_BAUDRATE +# ifndef MODULE_SLIPMUX_STDIO +# define SLIPMUX_PARAM_BAUDRATE (115200U) +# else /* MODULE_SLIPMUX_STDIO */ +# define SLIPMUX_PARAM_BAUDRATE (STDIO_UART_BAUDRATE) +# endif /* MODULE_SLIPMUX_STDIO */ +#endif /* SLIPMUX_PARAM_BAUDRATE */ + +#ifndef SLIPMUX_PARAMS +/** + * @brief Default UART parameters for SLIPMUX + */ +#define SLIPMUX_PARAMS { .uart = SLIPMUX_PARAM_UART, \ + .baudrate = SLIPMUX_PARAM_BAUDRATE } +#endif +/** @} */ + +/** + * @brief slipmux configuration + * + * The first element in this array will be used to multiplex stdio if + * `slipmux_stdio` is included. + */ +static const slipmux_params_t slipmux_params[] = { + SLIPMUX_PARAMS, +}; + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/drivers/slipmux/net.c b/drivers/slipmux/net.c new file mode 100644 index 000000000000..2b21ee4a2a0e --- /dev/null +++ b/drivers/slipmux/net.c @@ -0,0 +1,237 @@ +/* + * SPDX-FileCopyrightText: 2017 Freie Universität Berlin + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @{ + * + * @file + * @author Benjamin Valentin + * @author Bennet Hattesen + */ + +#include + +#include "chunked_ringbuffer.h" +#include "slipmux_internal.h" +#include "slipmux.h" + +#include "net/eui_provider.h" +#include "net/gnrc/netif/raw.h" +#include "net/gnrc.h" + +/** + * @brief Define stack parameters for the MAC layer thread + * @{ + */ +#define SLIPDEV_STACKSIZE (THREAD_STACKSIZE_DEFAULT - 128) +#ifndef SLIPDEV_PRIO +# define SLIPDEV_PRIO (GNRC_NETIF_PRIO) +#endif +/** @} */ + +#if IS_USED(MODULE_GNRC) +static char _slipdev_stacks[SLIPMUX_DEV_NUM][SLIPDEV_STACKSIZE]; +static gnrc_netif_t _netif[SLIPMUX_DEV_NUM]; +#endif + +static void _poweron(slipmux_t *dev) +{ + if ((dev->state != SLIPMUX_STATE_STANDBY) && + (dev->state != SLIPMUX_STATE_SLEEP)) { + return; + } + + dev->state = 0; + uart_init(dev->config.uart, dev->config.baudrate, slipmux_rx_cb, dev); +} + +static inline void _poweroff(slipmux_t *dev, uint8_t state) +{ + uart_poweroff(dev->config.uart); + dev->state = state; +} + +static int _init(netdev_t *netdev) +{ + /* signal link UP */ + netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP); + + return 0; +} + +static int _check_state(slipmux_t *dev) +{ + /* power states not supported when multiplexing stdio / configuration */ + if (IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) { + return 0; + } + + /* discard data when interface is in SLEEP mode */ + if (dev->state == SLIPMUX_STATE_SLEEP) { + return -ENETDOWN; + } + + /* sending data wakes the interface from STANDBY */ + if (dev->state == SLIPMUX_STATE_STANDBY) { + _poweron(dev); + } + + return 0; +} + +static int _send(netdev_t *netdev, const iolist_t *iolist) +{ + slipmux_t *dev = container_of(netdev, slipmux_t, netdev); + int bytes = _check_state(dev); + if (bytes) { + return bytes; + } + + slipmux_lock(dev); + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + uint8_t *data = iol->iol_base; + slipmux_write_bytes(dev->config.uart, data, iol->iol_len); + bytes += iol->iol_len; + } + slipmux_write_byte(dev->config.uart, SLIPMUX_END); + slipmux_unlock(dev); + return bytes; +} + +static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) +{ + slipmux_t *dev = container_of(netdev, slipmux_t, netdev); + size_t res = 0; + + (void)info; + if (buf == NULL) { + if (len > 0) { + /* remove data */ + crb_consume_chunk(&dev->net_rb, NULL, len); + } else { + /* the user was warned not to use a buffer size > `INT_MAX` ;-) */ + crb_get_chunk_size(&dev->net_rb, &res); + } + } + else { + crb_consume_chunk(&dev->net_rb, buf, len); + res = len; + } + return res; +} + +static void _isr(netdev_t *netdev) +{ + slipmux_t *dev = container_of(netdev, slipmux_t, netdev); + + size_t len; + while (crb_get_chunk_size(&dev->net_rb, &len)) { + netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); + } +} + +#if !(IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) +static int _set_state(slipmux_t *dev, netopt_state_t state) +{ + if (IS_USED(MODULE_SLIPMUX_STDIO)) { + return -ENOTSUP; + } + + switch (state) { + case NETOPT_STATE_STANDBY: + _poweroff(dev, SLIPMUX_STATE_STANDBY); + break; + case NETOPT_STATE_SLEEP: + _poweroff(dev, SLIPMUX_STATE_SLEEP); + break; + case NETOPT_STATE_IDLE: + _poweron(dev); + break; + default: + return -ENOTSUP; + } + + return sizeof(netopt_state_t); +} + +static int _set(netdev_t *netdev, netopt_t opt, const void *value, size_t max_len) +{ + (void)max_len; + + slipmux_t *dev = container_of(netdev, slipmux_t, netdev); + switch (opt) { + case NETOPT_STATE: + assert(max_len <= sizeof(netopt_state_t)); + return _set_state(dev, *((const netopt_state_t *)value)); + default: + return -ENOTSUP; + } +} +#endif /* !(MODULE_SLIPMUX_STDIO || MODULE_SLIPMUX_COAP) */ + +static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len) +{ + (void)netdev; + (void)value; + (void)max_len; + switch (opt) { + case NETOPT_IS_WIRED: + return 1; + case NETOPT_DEVICE_TYPE: + assert(max_len == sizeof(uint16_t)); + *((uint16_t *)value) = NETDEV_TYPE_SLIP; + return sizeof(uint16_t); +#if IS_USED(MODULE_SLIPMUX_NET_L2ADDR) + case NETOPT_ADDRESS_LONG: + assert(max_len == sizeof(eui64_t)); + netdev_eui64_get(netdev, value); + return sizeof(eui64_t); +#endif + default: + return -ENOTSUP; + } +} + +static int _confirm_send(netdev_t *netdev, void *info) +{ + (void)netdev; + (void)info; + return -EOPNOTSUPP; +} + +static const netdev_driver_t slip_driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .confirm_send = _confirm_send, +#if (IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) + .set = netdev_set_notsup, +#else + .set = _set, +#endif +}; + +void slipmux_net_notify(slipmux_t *dev) +{ + netdev_trigger_event_isr(&dev->netdev); +} + +void slipmux_net_init(slipmux_t * dev, unsigned index) +{ + dev->netdev.driver = &slip_driver; + crb_init(&dev->net_rb, dev->net_rx, sizeof(dev->net_rx)); + netdev_register(&dev->netdev, NETDEV_SLIPDEV, index); + +#if IS_USED(MODULE_GNRC) + gnrc_netif_raw_create(&_netif[index], _slipdev_stacks[index], SLIPDEV_STACKSIZE, + SLIPDEV_PRIO, "slipdev", + &dev->netdev); +#endif +} + +/** @} */ diff --git a/drivers/slipmux/slipmux.c b/drivers/slipmux/slipmux.c new file mode 100644 index 000000000000..301bed57de1b --- /dev/null +++ b/drivers/slipmux/slipmux.c @@ -0,0 +1,255 @@ +/* + * SPDX-FileCopyrightText: 2017 Freie Universität Berlin + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @{ + * + * @file + * @author Martine Lenders + * @author Benjamin Valentin + * @author Bennet Hattesen + */ + +/* XXX: BE CAREFUL ABOUT USING OUTPUT WITH MODULE_SLIPMUX_STDIO IN SENDING + * FUNCTIONALITY! MIGHT CAUSE DEADLOCK!!!1!! */ +#define ENABLE_DEBUG 0 +#include "debug.h" + +#include "auto_init_utils.h" +#include "chunked_ringbuffer.h" +#include "isrpipe.h" +#include "mutex.h" +#include "periph/uart.h" + +#include "slipmux_internal.h" +#include "slipmux_params.h" + +#if (IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) +/* For synchronization with stdio/config threads */ +mutex_t slipmux_mutex = MUTEX_INIT; +#endif + +slipmux_t slipmux_devs[SLIPMUX_DEV_NUM]; + +void slipmux_rx_cb(void *arg, uint8_t byte) +{ + slipmux_t *dev = arg; + + switch (dev->state) { + case SLIPMUX_STATE_STDIN: + switch (byte) { + case SLIPMUX_ESC: + dev->state = SLIPMUX_STATE_STDIN_ESC; + break; + case SLIPMUX_END: + dev->state = SLIPMUX_STATE_NONE; + break; + default: +#if IS_USED(MODULE_SLIPMUX_STDIO) + if (dev->config.uart == STDIO_UART_DEV) { + isrpipe_write_one(&stdin_isrpipe, byte); + } +#endif + break; + } + return; + case SLIPMUX_STATE_STDIN_ESC: + switch (byte) { + case SLIPMUX_END_ESC: + byte = SLIPMUX_END; + break; + case SLIPMUX_ESC_ESC: + byte = SLIPMUX_ESC; + break; + } + dev->state = SLIPMUX_STATE_STDIN; +#if IS_USED(MODULE_SLIPMUX_STDIO) + if (dev->config.uart == STDIO_UART_DEV) { + isrpipe_write_one(&stdin_isrpipe, byte); + } +#endif + return; + case SLIPMUX_STATE_COAP: + switch (byte) { + case SLIPMUX_ESC: + dev->state = SLIPMUX_STATE_COAP_ESC; + break; + case SLIPMUX_END: + dev->state = SLIPMUX_STATE_NONE; +#if IS_USED(MODULE_SLIPMUX_COAP) + crb_end_chunk(&dev->coap_rb, true); + slipmux_coap_notify(dev); +#endif + break; + default: +#if IS_USED(MODULE_SLIPMUX_COAP) + /* discard frame if byte can't be added */ + if (!crb_add_byte(&dev->coap_rb, byte)) { + DEBUG("slipmux: coap rx buffer full, drop frame\n"); + crb_end_chunk(&dev->coap_rb, false); + dev->state = SLIPMUX_STATE_NONE; + return; + } +#endif + break; + } + return; + case SLIPMUX_STATE_COAP_ESC: + switch (byte) { + case SLIPMUX_END_ESC: + byte = SLIPMUX_END; + break; + case SLIPMUX_ESC_ESC: + byte = SLIPMUX_ESC; + break; + } +#if IS_USED(MODULE_SLIPMUX_COAP) + /* discard frame if byte can't be added */ + if (!crb_add_byte(&dev->coap_rb, byte)) { + DEBUG("slipmux: coap rx buffer full, drop frame\n"); + crb_end_chunk(&dev->coap_rb, false); + dev->state = SLIPMUX_STATE_NONE; + return; + } +#endif + dev->state = SLIPMUX_STATE_COAP; + return; + case SLIPMUX_STATE_NET: + switch (byte) { + case SLIPMUX_ESC: + dev->state = SLIPMUX_STATE_NET_ESC; + return; + case SLIPMUX_END: +#if IS_USED(MODULE_SLIPMUX_NET) + crb_end_chunk(&dev->net_rb, true); + slipmux_net_notify(dev); +#endif + dev->state = SLIPMUX_STATE_NONE; + return; + } +#if IS_USED(MODULE_SLIPMUX_NET) + /* discard frame if byte can't be added */ + if (!crb_add_byte(&dev->net_rb, byte)) { + DEBUG("slipmux: net rx buffer full, drop frame\n"); + crb_end_chunk(&dev->net_rb, false); + dev->state = SLIPMUX_STATE_NONE; + } +#endif + return; + /* escaped byte received */ + case SLIPMUX_STATE_NET_ESC: + switch (byte) { + case SLIPMUX_END_ESC: + byte = SLIPMUX_END; + break; + case SLIPMUX_ESC_ESC: + byte = SLIPMUX_ESC; + break; + } +#if IS_USED(MODULE_SLIPMUX_NET) + /* discard frame if byte can't be added */ + if (!crb_add_byte(&dev->net_rb, byte)) { + DEBUG("slipmux: net rx buffer full, drop frame\n"); + crb_end_chunk(&dev->net_rb, false); + dev->state = SLIPMUX_STATE_NONE; + return; + } +#endif + dev->state = SLIPMUX_STATE_NET; + return; + + case SLIPMUX_STATE_NONE: + /* is diagnostic frame? */ + if (byte == SLIPMUX_STDIO_START) { + dev->state = SLIPMUX_STATE_STDIN; + return; + } + + if (byte == SLIPMUX_COAP_START) { +#if IS_USED(MODULE_SLIPMUX_COAP) + /* try to create new configuration / CoAP frame */ + if (!crb_start_chunk(&dev->coap_rb)) { + return; + } +#endif + dev->state = SLIPMUX_STATE_COAP; + return; + } + + if (SLIPMUX_NET_START(byte)) { +#if IS_USED(MODULE_SLIPMUX_NET) + /* try to create new ip frame */ + if (!crb_start_chunk(&dev->net_rb)) { + DEBUG("slipmux: can't start new net frame, drop frame\n"); + return; + } + if (!crb_add_byte(&dev->net_rb, byte)) { + DEBUG("slipmux: net rx buffer full, drop frame\n"); + crb_end_chunk(&dev->net_rb, false); + dev->state = SLIPMUX_STATE_NONE; + return; + } +#endif + dev->state = SLIPMUX_STATE_NET; + return; + } + + /* ignore empty frame */ + if (byte == SLIPMUX_END) { + return; + } + + DEBUG("slipmux: Unknown start byte %b ignored\n", byte); + // todo: Own parser category for unknown packet + } +} + +void slipmux_write_bytes(uart_t uart, const uint8_t *data, size_t len) +{ + for (unsigned j = 0; j < len; j++, data++) { + switch (*data) { + case SLIPMUX_END: + /* escaping END byte*/ + slipmux_write_byte(uart, SLIPMUX_ESC); + slipmux_write_byte(uart, SLIPMUX_END_ESC); + break; + case SLIPMUX_ESC: + /* escaping ESC byte*/ + slipmux_write_byte(uart, SLIPMUX_ESC); + slipmux_write_byte(uart, SLIPMUX_ESC_ESC); + break; + default: + slipmux_write_byte(uart, *data); + } + } +} + +void slipmux_init(void) +{ + for (unsigned i = 0; i < SLIPMUX_DEV_NUM; i++) { + slipmux_t *dev = &slipmux_devs[i]; + dev->config = slipmux_params[i]; + + if (uart_init(dev->config.uart, dev->config.baudrate, slipmux_rx_cb, + dev) != UART_OK) { + DEBUG("slipmux: error initializing UART %i with baudrate %" PRIu32 "\n", + dev->config.uart, dev->config.baudrate); + return; + } + DEBUG("slipmux: initialized device %p on UART %i with baudrate %" PRIu32 "\n", + (void *)dev, dev->config.uart, dev->config.baudrate); + +#if IS_USED(MODULE_SLIPMUX_COAP) + slipmux_coap_init(dev, i); +#endif +#if IS_USED(MODULE_SLIPMUX_NET) + slipmux_net_init(dev, i); +#endif + } +} + +AUTO_INIT(slipmux_init, 0); +/** @} */ diff --git a/drivers/slipmux/stdio.c b/drivers/slipmux/stdio.c new file mode 100644 index 000000000000..d235e3fcecef --- /dev/null +++ b/drivers/slipmux/stdio.c @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2018 Freie Universität Berlin + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @{ + * + * @file + * @author Martine Lenders + */ + +#include "board.h" +#include "isrpipe.h" +#include "periph/uart.h" + +#include "slipmux_internal.h" +#include "slipmux_params.h" + +#include "stdio_base.h" +#include "stdio_uart.h" + +static void _isrpipe_write(void *arg, uint8_t data) +{ + isrpipe_write_one(arg, (char)data); +} + +static void _init(void) +{ + /* intentionally overwritten in slipmux init so we have stdio before + * the network device is initialized */ + uart_init(slipmux_params[0].uart, slipmux_params[0].baudrate, + _isrpipe_write, &stdin_isrpipe); + + slipmux_write_byte(slipmux_params[0].uart, SLIPMUX_END); +} + +static ssize_t _write(const void *buffer, size_t len) +{ + slipmux_lock(&slipmux_devs[0]); + slipmux_write_byte(slipmux_params[0].uart, SLIPMUX_STDIO_START); + slipmux_write_bytes(slipmux_params[0].uart, buffer, len); + slipmux_write_byte(slipmux_params[0].uart, SLIPMUX_END); + slipmux_unlock(&slipmux_devs[0]); + return len; +} + +STDIO_PROVIDER(STDIO_SLIPMUX, _init, NULL, _write) + +/** @} */ diff --git a/examples/networking/coap/gcoap/Makefile.slip b/examples/networking/coap/gcoap/Makefile.slip index 010581fbc6f5..06c5a3f6dd2d 100644 --- a/examples/networking/coap/gcoap/Makefile.slip +++ b/examples/networking/coap/gcoap/Makefile.slip @@ -28,8 +28,8 @@ ifeq (,$(SLIP_BAUDRATE)) SLIP_BAUDRATE=115200 endif -CFLAGS += -DSLIPDEV_PARAM_UART=$(SLIP_UART) -CFLAGS += -DSLIPDEV_PARAM_BAUDRATE=$(SLIP_BAUDRATE) +CFLAGS += -DSLIPMUX_PARAM_UART=$(SLIP_UART) +CFLAGS += -DSLIPMUX_PARAM_BAUDRATE=$(SLIP_BAUDRATE) # Include packages that pull up and auto-init the link layer. # NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present @@ -42,7 +42,7 @@ USEMODULE += gnrc_rpl # Border router requirements # Include SLIP package for IP over Serial communication -USEMODULE += slipdev +USEMODULE += slipmux_net # Specify the mandatory networking modules for 6LoWPAN border router USEMODULE += gnrc_sixlowpan_border_router_default # Additional networking modules that can be dropped if not needed @@ -54,6 +54,7 @@ USEMODULE += fmt # Add also the shell, some shell commands USEMODULE += shell USEMODULE += shell_cmds_default +USEMODULE += uri_parser USEMODULE += ps # Comment this out to disable code in RIOT that does safety checking diff --git a/examples/networking/coap/gcoap/README-slip.md b/examples/networking/coap/gcoap/README-slip.md index 5f051c99d480..fcc1f57f56b8 100644 --- a/examples/networking/coap/gcoap/README-slip.md +++ b/examples/networking/coap/gcoap/README-slip.md @@ -33,7 +33,8 @@ We include two approaches to configuration below, automated via RPL, and manual First, define a TUN interface on an Ubuntu host with tunslip, in the `dist/tools/tunslip` directory. In the example below, the tun interface is host 1. - cd ../../dist/tools/tunslip/ + cd ../../../../dist/tools/tunslip/ + make sudo ./tunslip6 -s ttyUSB0 -t tun0 bbbb::1/64 sudo ip -6 route add aaaa::/64 dev tun0 diff --git a/examples/networking/coap/gcoap_dtls/Makefile.slip b/examples/networking/coap/gcoap_dtls/Makefile.slip index 010581fbc6f5..9c3fec001529 100644 --- a/examples/networking/coap/gcoap_dtls/Makefile.slip +++ b/examples/networking/coap/gcoap_dtls/Makefile.slip @@ -28,8 +28,8 @@ ifeq (,$(SLIP_BAUDRATE)) SLIP_BAUDRATE=115200 endif -CFLAGS += -DSLIPDEV_PARAM_UART=$(SLIP_UART) -CFLAGS += -DSLIPDEV_PARAM_BAUDRATE=$(SLIP_BAUDRATE) +CFLAGS += -DSLIPMUX_PARAM_UART=$(SLIP_UART) +CFLAGS += -DSLIPMUX_PARAM_BAUDRATE=$(SLIP_BAUDRATE) # Include packages that pull up and auto-init the link layer. # NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present @@ -42,7 +42,7 @@ USEMODULE += gnrc_rpl # Border router requirements # Include SLIP package for IP over Serial communication -USEMODULE += slipdev +USEMODULE += slipmux_net # Specify the mandatory networking modules for 6LoWPAN border router USEMODULE += gnrc_sixlowpan_border_router_default # Additional networking modules that can be dropped if not needed diff --git a/examples/networking/gnrc/border_router/Makefile.board.dep b/examples/networking/gnrc/border_router/Makefile.board.dep index d4654ed8d41f..35695292f68e 100644 --- a/examples/networking/gnrc/border_router/Makefile.board.dep +++ b/examples/networking/gnrc/border_router/Makefile.board.dep @@ -1,7 +1,7 @@ # Put board specific dependencies here ifeq (,$(filter native native32 native64,$(BOARD))) ifeq (slip,$(UPLINK)) - USEMODULE += slipdev_stdio + USEMODULE += slipmux_stdio else ifeq (ethos,$(UPLINK)) USEMODULE += stdio_ethos else ifeq (wifi,$(UPLINK)) diff --git a/examples/networking/gnrc/border_router/Makefile.slip.conf b/examples/networking/gnrc/border_router/Makefile.slip.conf index bf36fdb80dff..fc0b9153b278 100644 --- a/examples/networking/gnrc/border_router/Makefile.slip.conf +++ b/examples/networking/gnrc/border_router/Makefile.slip.conf @@ -1,14 +1,16 @@ INCLUDES += -I$(CURDIR) -CFLAGS += -DSLIPDEV_PARAM_BAUDRATE=$(SLIP_BAUDRATE) +CFLAGS += -DSLIPMUX_PARAM_BAUDRATE=$(SLIP_BAUDRATE) STATIC_ROUTES ?= 1 +USEMODULE += slipmux_net + ifeq (dhcpv6,$(PREFIX_CONF)) FLAGS_EXTRAS=-d else ifeq (auto_subnets,$(PREFIX_CONF)) FLAGS_EXTRAS=-r - USEMODULE += slipdev_l2addr + USEMODULE += slipmux_net_l2addr endif # Configure terminal parameters diff --git a/examples/networking/gnrc/border_router/README.md b/examples/networking/gnrc/border_router/README.md index 9f9aa4ab9029..0cdef7b3eaa3 100644 --- a/examples/networking/gnrc/border_router/README.md +++ b/examples/networking/gnrc/border_router/README.md @@ -118,7 +118,7 @@ interface and configure the BR. Notice that this will also configure `2001:db8::/64` as a prefix. This prefix should be announced to other motes through the wireless interface. -As said previously, `ethos` and `slipdev` allow to send IP packets and shell commands. +As said previously, `ethos` and `slipmux` allow to send IP packets and shell commands. This is done through the same serial interface. By typing `help` you will get the list of available shell commands. diff --git a/examples/networking/gnrc/networking_subnets/README.md b/examples/networking/gnrc/networking_subnets/README.md index aec9a74a4b35..bf55b6757acd 100644 --- a/examples/networking/gnrc/networking_subnets/README.md +++ b/examples/networking/gnrc/networking_subnets/README.md @@ -54,9 +54,9 @@ It is also possible to connect non-routing leaf nodes with a single interface: On physical hardware the setup will be the same. Routing nodes need at least two interfaces between which they can route. -For a simple setup, you can use `ethos` or `slipdev` to turn any UART into +For a simple setup, you can use `ethos` or `slipmux_net` to turn any UART into a network interface. (If you need to use DHCPv6 IA_PD for obtaining a prefix, -use `slipdev_l2addr` instead of plain `slipdev`) +use `slipmux_net_l2addr` instead of plain `slipmux_net`) ### Obtaining the prefix diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 82be1d001222..d41cd5cc1985 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -453,9 +453,6 @@ PSEUDOMODULES += shell_lock_auto_locking PSEUDOMODULES += shield_llcc68 PSEUDOMODULES += shield_sx1262 PSEUDOMODULES += shield_w5100 -PSEUDOMODULES += slipdev_stdio -PSEUDOMODULES += slipdev_config -PSEUDOMODULES += slipdev_l2addr PSEUDOMODULES += sock PSEUDOMODULES += sock_async PSEUDOMODULES += sock_aux_local diff --git a/makefiles/stdio.inc.mk b/makefiles/stdio.inc.mk index df0221ddd0e0..beacfff29ad1 100644 --- a/makefiles/stdio.inc.mk +++ b/makefiles/stdio.inc.mk @@ -1,5 +1,5 @@ STDIO_MODULES = \ - slipdev_stdio \ + slipmux_stdio \ stdio_cdc_acm \ stdio_ethos \ stdio_native \ @@ -101,7 +101,7 @@ 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 stdio_tinyusb_cdc_acm,$(USEMODULE))) + ifneq (,$(filter stdio_cdc_acm stdio_ethos slipmux_stdio stdio_semihosting stdio_tinyusb_cdc_acm,$(USEMODULE))) USEMODULE += picolibc_stdout_buffered endif endif diff --git a/pkg/lwip/contrib/netdev/lwip_netdev.c b/pkg/lwip/contrib/netdev/lwip_netdev.c index c4d0deef6bb2..4325b548bfc4 100644 --- a/pkg/lwip/contrib/netdev/lwip_netdev.c +++ b/pkg/lwip/contrib/netdev/lwip_netdev.c @@ -67,7 +67,7 @@ static err_t _eth_link_output(struct netif *netif, struct pbuf *p); #ifdef MODULE_LWIP_SIXLOWPAN static err_t _ieee802154_link_output(struct netif *netif, struct pbuf *p); #endif -#ifdef MODULE_SLIPDEV +#ifdef MODULE_SLIPMUX_NET static err_t _slip_link_output(struct netif *netif, struct pbuf *p); #if LWIP_IPV4 static err_t slip_output4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); @@ -209,7 +209,7 @@ err_t lwip_netdev_init(struct netif *netif) break; } #endif -#ifdef MODULE_SLIPDEV +#ifdef MODULE_SLIPMUX_NET case NETDEV_TYPE_SLIP: netif->name[0] = 'S'; netif->name[1] = 'L'; @@ -223,7 +223,7 @@ err_t lwip_netdev_init(struct netif *netif) #if LWIP_IPV6 netif->output_ip6 = slip_output6; - if (IS_USED(MODULE_SLIPDEV_L2ADDR)) { + if (IS_USED(MODULE_SLIPMUX_L2ADDR)) { netif->hwaddr_len = (u8_t)netdev->driver->get(netdev, NETOPT_ADDRESS_LONG, netif->hwaddr, sizeof(netif->hwaddr)); @@ -384,7 +384,7 @@ static err_t _ieee802154_link_output(struct netif *netif, struct pbuf *p) } #endif -#ifdef MODULE_SLIPDEV +#ifdef MODULE_SLIPMUX_NET #if LWIP_IPV4 static err_t slip_output4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) { diff --git a/pkg/lwip/init_devs/auto_init_slipdev.c b/pkg/lwip/init_devs/auto_init_slipmux.c similarity index 67% rename from pkg/lwip/init_devs/auto_init_slipdev.c rename to pkg/lwip/init_devs/auto_init_slipmux.c index 6eb65e64b33d..48d79a513734 100644 --- a/pkg/lwip/init_devs/auto_init_slipdev.c +++ b/pkg/lwip/init_devs/auto_init_slipmux.c @@ -11,29 +11,29 @@ * @{ * * @file - * @brief Auto initialization for the SLIP module + * @brief Auto initialization for the SLIPMUX module * * @author Benjamin Valentin */ -#include "slipdev.h" -#include "slipdev_params.h" +#include "slipmux.h" +#include "slipmux_internal.h" +#include "slipmux_params.h" #include "lwip_init_devs.h" #define ENABLE_DEBUG 0 #include "debug.h" -#define NETIF_SLIPDEV_NUMOF ARRAY_SIZE(slipdev_params) +#define NETIF_SLIPDEV_NUMOF ARRAY_SIZE(slipmux_params) static lwip_netif_t netif[NETIF_SLIPDEV_NUMOF]; -static slipdev_t slipdev_devs[NETIF_SLIPDEV_NUMOF]; static void auto_init_slipdev(void) { for (unsigned i = 0; i < NETIF_SLIPDEV_NUMOF; i++) { - slipdev_setup(&slipdev_devs[i], &slipdev_params[i], i); - if (lwip_add_ethernet(&netif[i], &slipdev_devs[i].netdev) == NULL) { + LWIP_ASSERT("slipmux_init() must run first!", slipmux_devs[i].netdev.driver != NULL); + if (lwip_add_ethernet(&netif[i], &slipmux_devs[i].netdev) == NULL) { DEBUG("Could not add slipdev device\n"); return; } @@ -41,4 +41,5 @@ static void auto_init_slipdev(void) } LWIP_INIT_ETH_NETIF(auto_init_slipdev); + /** @} */ diff --git a/sys/include/net/gnrc/netif/conf.h b/sys/include/net/gnrc/netif/conf.h index d8adde9fadbe..189ceb182e52 100644 --- a/sys/include/net/gnrc/netif/conf.h +++ b/sys/include/net/gnrc/netif/conf.h @@ -146,7 +146,7 @@ extern "C" { * address types are included */ #ifndef GNRC_NETIF_L2ADDR_MAXLEN -#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) || defined(MODULE_SLIPDEV_L2ADDR) +#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) || defined(MODULE_SLIPMUX_L2ADDR) #define GNRC_NETIF_L2ADDR_MAXLEN (IEEE802154_LONG_ADDRESS_LEN) #elif MODULE_NETDEV_ETH #define GNRC_NETIF_L2ADDR_MAXLEN (ETHERNET_ADDR_LEN) diff --git a/sys/net/gnrc/Makefile.dep b/sys/net/gnrc/Makefile.dep index 09c4fccbdde9..6de742818396 100644 --- a/sys/net/gnrc/Makefile.dep +++ b/sys/net/gnrc/Makefile.dep @@ -143,7 +143,7 @@ ifneq (,$(filter gnrc_netif_bus,$(USEMODULE))) USEMODULE += core_msg_bus endif -ifneq (,$(filter netdev_eth slipdev, $(USEMODULE))) +ifneq (,$(filter netdev_eth slipmux_net, $(USEMODULE))) ifeq (,$(filter gnrc_sixloenc, $(USEMODULE))) ifneq (,$(filter gnrc_ipv6, $(USEMODULE))) USEMODULE += gnrc_ipv6_classic diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index eee3b722d140..d09730325835 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -1621,11 +1621,11 @@ static void _test_options(gnrc_netif_t *netif) assert(netif->l2addr_len >= 3U && netif->l2addr_len <= 5U); break; case NETDEV_TYPE_SLIP: -#if IS_USED(MODULE_SLIPDEV_L2ADDR) +#if IS_USED(MODULE_SLIPMUX_L2ADDR) assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR); assert(8U == netif->l2addr_len); break; -#endif /* IS_USED(MODULE_SLIPDEV_L2ADDR) */ +#endif /* IS_USED(MODULE_SLIPMUX_L2ADDR) */ case NETDEV_TYPE_LORA: /* LoRa doesn't provide L2 ADDR */ assert(!(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR)); assert(0U == netif->l2addr_len); diff --git a/sys/net/gnrc/netif/gnrc_netif_device_type.c b/sys/net/gnrc/netif/gnrc_netif_device_type.c index 654ed31b5843..44d86bcd9ebd 100644 --- a/sys/net/gnrc/netif/gnrc_netif_device_type.c +++ b/sys/net/gnrc/netif/gnrc_netif_device_type.c @@ -57,7 +57,7 @@ netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif) } break; #endif -#if defined(MODULE_SLIPDEV_L2ADDR) +#if defined(MODULE_SLIPMUX_L2ADDR) case NETDEV_TYPE_SLIP: res = NETOPT_ADDRESS_LONG; break; diff --git a/sys/net/link_layer/l2util/l2util.c b/sys/net/link_layer/l2util/l2util.c index c1437d75ffb7..4c3d46623d93 100644 --- a/sys/net/link_layer/l2util/l2util.c +++ b/sys/net/link_layer/l2util/l2util.c @@ -123,11 +123,11 @@ int l2util_eui64_from_addr(int dev_type, const uint8_t *addr, size_t addr_len, return -EINVAL; } #endif /* defined (MODULE_NRF24L01P_NG) */ -#if defined(MODULE_SLIPDEV_L2ADDR) +#if defined(MODULE_SLIPMUX_L2ADDR) case NETDEV_TYPE_SLIP: memcpy(eui64, addr, addr_len); return sizeof(eui64_t); -#endif /* defined(MODULE_SLIPDEV_L2ADDR) */ +#endif /* defined(MODULE_SLIPMUX_L2ADDR) */ default: (void)addr; (void)addr_len; @@ -235,7 +235,7 @@ int l2util_ipv6_iid_to_addr(int dev_type, const eui64_t *iid, uint8_t *addr) memcpy(&addr[addr_len - 3], &iid->uint8[5], 3); return addr_len; #endif /* defined(MODULE_NRF24L01P_NG) */ -#if defined(MODULE_SLIPDEV_L2ADDR) +#if defined(MODULE_SLIPMUX_L2ADDR) case NETDEV_TYPE_SLIP: memcpy(addr, iid, sizeof(eui64_t)); return sizeof(eui64_t); @@ -298,10 +298,10 @@ int l2util_ndp_addr_len_from_l2ao(int dev_type, (void)opt; return 5; /* maximum length */ #endif /* defined(MODULE_NRF24L01P_NG) */ -#if defined(MODULE_SLIPDEV_L2ADDR) +#if defined(MODULE_SLIPMUX_L2ADDR) case NETDEV_TYPE_SLIP: return sizeof(eui64_t); -#endif /* defined(MODULE_SLIPDEV_L2ADDR) */ +#endif /* defined(MODULE_SLIPMUX_L2ADDR) */ default: (void)opt; #ifdef DEVELHELP diff --git a/sys/shell/cmds/gnrc_netif.c b/sys/shell/cmds/gnrc_netif.c index f3f262797561..7d901fc0a5ac 100644 --- a/sys/shell/cmds/gnrc_netif.c +++ b/sys/shell/cmds/gnrc_netif.c @@ -1765,7 +1765,7 @@ static int _netif_add(char *cmd_name, netif_t *iface, int argc, char **argv) (void)iface; (void)argc; (void)argv; - printf("error: unable to add IPv6 address.\n"); + printf("error: IPv6 module not enabled.\n"); return 1; #endif diff --git a/tests/net/slip/Makefile b/tests/net/slip/Makefile index 3ad0c888232c..5bc534786f5c 100644 --- a/tests/net/slip/Makefile +++ b/tests/net/slip/Makefile @@ -2,9 +2,11 @@ include ../Makefile.net_common USEMODULE += auto_init_gnrc_netif USEMODULE += gnrc +USEMODULE += gnrc_ipv6 +USEMODULE += gnrc_icmpv6_echo USEMODULE += gnrc_pktdump USEMODULE += gnrc_txtsnd -USEMODULE += slipdev +USEMODULE += slipmux_net USEMODULE += shell USEMODULE += shell_cmds_default @@ -13,8 +15,8 @@ SLIP_UART ?= "UART_NUMOF-1" SLIP_BAUDRATE ?= 115200 # export slip parameters -CFLAGS += -DSLIPDEV_PARAM_UART="UART_DEV($(SLIP_UART))" -CFLAGS += -DSLIPDEV_PARAM_BAUDRATE=$(SLIP_BAUDRATE) +CFLAGS += -DSLIPMUX_PARAM_UART="UART_DEV($(SLIP_UART))" +CFLAGS += -DSLIPMUX_PARAM_BAUDRATE=$(SLIP_BAUDRATE) # add current directory to the include path. Putting it in CFLAGS will make # it go to the beginning, before the standard includes. From 4f56cb50ce5329cbcc47f9bb21a2db423ab61c3c Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 10:56:20 +0100 Subject: [PATCH 02/14] remove nolonger needed mutex --- drivers/slipmux/slipmux.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/slipmux/slipmux.c b/drivers/slipmux/slipmux.c index 301bed57de1b..34319a45a239 100644 --- a/drivers/slipmux/slipmux.c +++ b/drivers/slipmux/slipmux.c @@ -27,11 +27,6 @@ #include "slipmux_internal.h" #include "slipmux_params.h" -#if (IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) -/* For synchronization with stdio/config threads */ -mutex_t slipmux_mutex = MUTEX_INIT; -#endif - slipmux_t slipmux_devs[SLIPMUX_DEV_NUM]; void slipmux_rx_cb(void *arg, uint8_t byte) From 9a5b785cb0e38098af944dab8070d37d4c25ed3b Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 11:33:56 +0100 Subject: [PATCH 03/14] review: fix doc issues in headers --- drivers/include/slipmux.h | 22 +++++++-------- drivers/slipmux/include/slipmux_internal.h | 31 +++++++++++----------- drivers/slipmux/include/slipmux_params.h | 14 +++++++--- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/drivers/include/slipmux.h b/drivers/include/slipmux.h index 4e72555d72e6..30502f09bc4b 100644 --- a/drivers/include/slipmux.h +++ b/drivers/include/slipmux.h @@ -82,7 +82,7 @@ extern "C" { * Reduce this value if your expected traffic does not include full IPv6 MTU * sized packets. */ -#ifndef CONFIG_SLIPMUX_COAP_BUFSIZE +#if !defined(CONFIG_SLIPMUX_COAP_BUFSIZE) || defined(DOXYGEN) # define CONFIG_SLIPMUX_COAP_BUFSIZE (512U) #endif /** @} */ @@ -115,12 +115,12 @@ extern "C" { * Reduce this value if your expected traffic does not include full IPv6 MTU * sized packets. */ -#ifdef CONFIG_SLIPMUX_NET_BUFSIZE_EXP -# define CONFIG_SLIPMUX_NET_BUFSIZE (1<= 0x45 && byte <= 0x4f) || \ /* or is it an IPv6 packet? */ \ @@ -93,17 +93,17 @@ extern slipmux_t slipmux_devs[SLIPMUX_DEV_NUM]; enum { /* Device is in no mode (currently did not receiving any data frame) */ SLIPMUX_STATE_NONE = 0, - /* Device writes handles data as network device */ + /* Device handles data as network device */ SLIPMUX_STATE_NET, - /* Device writes handles data as network device, next byte is escaped */ + /* Device handles data as network device, next byte is escaped */ SLIPMUX_STATE_NET_ESC, - /* Device writes received data to stdin */ + /* Device handles received data to stdin */ SLIPMUX_STATE_STDIN, - /* Device writes received data to stdin, next byte is escaped */ + /* Device handles received data to stdin, next byte is escaped */ SLIPMUX_STATE_STDIN_ESC, - /* Device writes received data as CoAP message */ + /* Device handles received data as CoAP message */ SLIPMUX_STATE_COAP, - /* Device writes received data as CoAP message, next byte is escaped */ + /* Device handles received data as CoAP message, next byte is escaped */ SLIPMUX_STATE_COAP_ESC, /* Device is in standby, will wake up when sending data */ SLIPMUX_STATE_STANDBY, @@ -117,7 +117,7 @@ enum { void slipmux_rx_cb(void *arg, uint8_t byte); /** - * @brief Writes one byte to UART + * @brief Writes one byte to UART without escaping * * @param[in] uart The UART device to write to. * @param[in] byte The byte to write to @p uart. @@ -160,7 +160,7 @@ static inline void slipmux_unlock(slipmux_t *dev) #endif } -#if IS_USED(MODULE_SLIPMUX_COAP) +#if IS_USED(MODULE_SLIPMUX_COAP) || defined(DOXYGEN) /** * @brief Initialise the CoAP handling * @@ -176,8 +176,9 @@ void slipmux_coap_init(slipmux_t *dev, unsigned index); * @param[in] dev The Slipmux device to notify. */ void slipmux_coap_notify(slipmux_t *dev); -#endif -#if IS_USED(MODULE_SLIPMUX_NET) +#endif /* MODULE_SLIPMUX_COAP */ + +#if IS_USED(MODULE_SLIPMUX_NET) || defined(DOXYGEN) /** * @brief Initialise the network handling * @@ -193,7 +194,7 @@ void slipmux_net_init(slipmux_t *dev, unsigned index); * @param[in] dev The Slipmux device to notify. */ void slipmux_net_notify(slipmux_t *dev); -#endif +#endif /* MODULE_SLIPMUX_NET */ #ifdef __cplusplus } diff --git a/drivers/slipmux/include/slipmux_params.h b/drivers/slipmux/include/slipmux_params.h index 88f9adaee829..e2b31d825ed6 100644 --- a/drivers/slipmux/include/slipmux_params.h +++ b/drivers/slipmux/include/slipmux_params.h @@ -34,11 +34,11 @@ extern "C" { /** * @brief Default UART to use */ -#define SLIPMUX_PARAM_UART UART_DEV(0) +# define SLIPMUX_PARAM_UART UART_DEV(0) /** * @brief Default baudrate to use */ -#define SLIPMUX_PARAM_BAUDRATE (115200U) +# define SLIPMUX_PARAM_BAUDRATE (115200U) #endif /* DOXYGEN */ #ifndef SLIPMUX_PARAM_UART @@ -52,19 +52,25 @@ extern "C" { # define SLIPMUX_PARAM_UART STDIO_UART_DEV # endif /* MODULE_SLIPMUX_STDIO */ #endif /* SLIPMUX_PARAM_UART */ + +/* if the user hasn't defined their own specific baudrate... */ #ifndef SLIPMUX_PARAM_BAUDRATE +/* ... and we are not using the STDIO module... */ # ifndef MODULE_SLIPMUX_STDIO +/* ... we default to this baudrate */ # define SLIPMUX_PARAM_BAUDRATE (115200U) +/* ... but if we are using the STDIO module... */ # else /* MODULE_SLIPMUX_STDIO */ +/* ... we use the default STDIO baudrate */ # define SLIPMUX_PARAM_BAUDRATE (STDIO_UART_BAUDRATE) # endif /* MODULE_SLIPMUX_STDIO */ #endif /* SLIPMUX_PARAM_BAUDRATE */ -#ifndef SLIPMUX_PARAMS +#if !defined(SLIPMUX_PARAMS) || DOXYGEN /** * @brief Default UART parameters for SLIPMUX */ -#define SLIPMUX_PARAMS { .uart = SLIPMUX_PARAM_UART, \ +# define SLIPMUX_PARAMS { .uart = SLIPMUX_PARAM_UART, \ .baudrate = SLIPMUX_PARAM_BAUDRATE } #endif /** @} */ From 8c5e46a98f0bed19c28ed1ff2afcbac31e77a511 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 12:01:07 +0100 Subject: [PATCH 04/14] doc fixes --- drivers/include/slipmux.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/include/slipmux.h b/drivers/include/slipmux.h index 30502f09bc4b..a3cf3f66c4d7 100644 --- a/drivers/include/slipmux.h +++ b/drivers/include/slipmux.h @@ -22,7 +22,12 @@ * * This is the base module, see @ref drivers_slipmux_net, @ref drivers_slipmux_coap and * @ref drivers_slipmux_stdio for more information. - * + * + * For example, to use STDIO and also provide a network interface over SLIPMUX select: + * + * USEMODULE += slipmux_stdio + * USEMODULE += slipmux_net + * * @{ * * @file @@ -56,7 +61,7 @@ extern "C" { */ /** - * @defgroup drivers_slipmux_coap CoAP via SLIP + * @defgroup drivers_slipmux_coap CoAP via SLIPMUX * @ingroup drivers_slipmux * @brief Exchange CoAP requests and responses via SLIPMUX * @see [draft-bormann-t2trg-slipmux-03](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03) @@ -79,8 +84,6 @@ extern "C" { /** * @brief UART buffer size used for TX and RX buffers * - * Reduce this value if your expected traffic does not include full IPv6 MTU - * sized packets. */ #if !defined(CONFIG_SLIPMUX_COAP_BUFSIZE) || defined(DOXYGEN) # define CONFIG_SLIPMUX_COAP_BUFSIZE (512U) @@ -89,7 +92,7 @@ extern "C" { /** - * @defgroup drivers_slipmux_net SLIP network device + * @defgroup drivers_slipmux_net IP via SLIPMUX / SLIP network device * @ingroup drivers_netdev * @brief SLIP network device over @ref drivers_periph_uart * @see [RFC 1055](https://datatracker.ietf.org/doc/html/rfc1055) @@ -97,8 +100,8 @@ extern "C" { * This extension is part of the [Slipmux draft](https://datatracker.ietf.org/doc/html/draft-bormann-t2trg-slipmux-03). * @warning This module is under development for optimizations and module names might change! * - * This will offer the traditional Serial Line Internet Protocol as a network interface - * using GNRC. + * This will offer the traditional Serial Line Internet Protocol as a network interface. + * Uses GNRC by default, can also be used with LWIP. * * To enable this implementation, select * From f22fbf14b829d0120fad218aaf2816d2feeeae3e Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 12:11:08 +0100 Subject: [PATCH 05/14] add docs for _net_l2addr --- drivers/include/slipmux.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/include/slipmux.h b/drivers/include/slipmux.h index a3cf3f66c4d7..5024c0bae4a5 100644 --- a/drivers/include/slipmux.h +++ b/drivers/include/slipmux.h @@ -106,6 +106,10 @@ extern "C" { * To enable this implementation, select * * USEMODULE += slipmux_net + * + * To add link-layer addresses to the SLIPMUX network interfaces, select + * + * USEMODULE += slipmux_net_l2addr * * @see drivers_slipmux * From 6aa2df2df62414d07073ab33928f680f080d636f Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 12:20:05 +0100 Subject: [PATCH 06/14] fix wrong module name --- pkg/lwip/contrib/netdev/lwip_netdev.c | 2 +- sys/include/net/gnrc/netif/conf.h | 2 +- sys/net/gnrc/netif/gnrc_netif.c | 4 ++-- sys/net/gnrc/netif/gnrc_netif_device_type.c | 2 +- sys/net/link_layer/l2util/l2util.c | 12 ++++++------ 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/lwip/contrib/netdev/lwip_netdev.c b/pkg/lwip/contrib/netdev/lwip_netdev.c index 4325b548bfc4..70c79778ab4c 100644 --- a/pkg/lwip/contrib/netdev/lwip_netdev.c +++ b/pkg/lwip/contrib/netdev/lwip_netdev.c @@ -223,7 +223,7 @@ err_t lwip_netdev_init(struct netif *netif) #if LWIP_IPV6 netif->output_ip6 = slip_output6; - if (IS_USED(MODULE_SLIPMUX_L2ADDR)) { + if (IS_USED(MODULE_SLIPMUX_NET_L2ADDR)) { netif->hwaddr_len = (u8_t)netdev->driver->get(netdev, NETOPT_ADDRESS_LONG, netif->hwaddr, sizeof(netif->hwaddr)); diff --git a/sys/include/net/gnrc/netif/conf.h b/sys/include/net/gnrc/netif/conf.h index 189ceb182e52..3d75595bd64b 100644 --- a/sys/include/net/gnrc/netif/conf.h +++ b/sys/include/net/gnrc/netif/conf.h @@ -146,7 +146,7 @@ extern "C" { * address types are included */ #ifndef GNRC_NETIF_L2ADDR_MAXLEN -#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) || defined(MODULE_SLIPMUX_L2ADDR) +#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) || defined(MODULE_SLIPMUX_NET_L2ADDR) #define GNRC_NETIF_L2ADDR_MAXLEN (IEEE802154_LONG_ADDRESS_LEN) #elif MODULE_NETDEV_ETH #define GNRC_NETIF_L2ADDR_MAXLEN (ETHERNET_ADDR_LEN) diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index d09730325835..ec64c225839f 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -1621,11 +1621,11 @@ static void _test_options(gnrc_netif_t *netif) assert(netif->l2addr_len >= 3U && netif->l2addr_len <= 5U); break; case NETDEV_TYPE_SLIP: -#if IS_USED(MODULE_SLIPMUX_L2ADDR) +#if IS_USED(MODULE_SLIPMUX_NET_L2ADDR) assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR); assert(8U == netif->l2addr_len); break; -#endif /* IS_USED(MODULE_SLIPMUX_L2ADDR) */ +#endif /* IS_USED(MODULE_SLIPMUX_NET_L2ADDR) */ case NETDEV_TYPE_LORA: /* LoRa doesn't provide L2 ADDR */ assert(!(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR)); assert(0U == netif->l2addr_len); diff --git a/sys/net/gnrc/netif/gnrc_netif_device_type.c b/sys/net/gnrc/netif/gnrc_netif_device_type.c index 44d86bcd9ebd..ae066c33e266 100644 --- a/sys/net/gnrc/netif/gnrc_netif_device_type.c +++ b/sys/net/gnrc/netif/gnrc_netif_device_type.c @@ -57,7 +57,7 @@ netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif) } break; #endif -#if defined(MODULE_SLIPMUX_L2ADDR) +#if defined(MODULE_SLIPMUX_NET_L2ADDR) case NETDEV_TYPE_SLIP: res = NETOPT_ADDRESS_LONG; break; diff --git a/sys/net/link_layer/l2util/l2util.c b/sys/net/link_layer/l2util/l2util.c index 4c3d46623d93..83e5120361e5 100644 --- a/sys/net/link_layer/l2util/l2util.c +++ b/sys/net/link_layer/l2util/l2util.c @@ -123,11 +123,11 @@ int l2util_eui64_from_addr(int dev_type, const uint8_t *addr, size_t addr_len, return -EINVAL; } #endif /* defined (MODULE_NRF24L01P_NG) */ -#if defined(MODULE_SLIPMUX_L2ADDR) +#if defined(MODULE_SLIPMUX_NET_L2ADDR) case NETDEV_TYPE_SLIP: memcpy(eui64, addr, addr_len); return sizeof(eui64_t); -#endif /* defined(MODULE_SLIPMUX_L2ADDR) */ +#endif /* defined(MODULE_SLIPMUX_NET_L2ADDR) */ default: (void)addr; (void)addr_len; @@ -235,11 +235,11 @@ int l2util_ipv6_iid_to_addr(int dev_type, const eui64_t *iid, uint8_t *addr) memcpy(&addr[addr_len - 3], &iid->uint8[5], 3); return addr_len; #endif /* defined(MODULE_NRF24L01P_NG) */ -#if defined(MODULE_SLIPMUX_L2ADDR) +#if defined(MODULE_SLIPMUX_NET_L2ADDR) case NETDEV_TYPE_SLIP: memcpy(addr, iid, sizeof(eui64_t)); return sizeof(eui64_t); -#endif /* defined(MODULE_SLIP) */ +#endif /* defined(MODULE_SLIPMUX_NET_L2ADDR) */ default: (void)iid; (void)addr; @@ -298,10 +298,10 @@ int l2util_ndp_addr_len_from_l2ao(int dev_type, (void)opt; return 5; /* maximum length */ #endif /* defined(MODULE_NRF24L01P_NG) */ -#if defined(MODULE_SLIPMUX_L2ADDR) +#if defined(MODULE_SLIPMUX_NET_L2ADDR) case NETDEV_TYPE_SLIP: return sizeof(eui64_t); -#endif /* defined(MODULE_SLIPMUX_L2ADDR) */ +#endif /* defined(MODULE_SLIPMUX_NET_L2ADDR) */ default: (void)opt; #ifdef DEVELHELP From dcd6f154f712ea0b101b0e6b2029ec52c59302be Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 12:31:07 +0100 Subject: [PATCH 07/14] remove slipdev debris --- dist/tools/tunslip/README.md | 10 ++-- .../gnrc/netif/init_devs/auto_init_slipdev.c | 58 ------------------- sys/net/gnrc/netif/init_devs/init.c | 5 -- 3 files changed, 5 insertions(+), 68 deletions(-) delete mode 100644 sys/net/gnrc/netif/init_devs/auto_init_slipdev.c diff --git a/dist/tools/tunslip/README.md b/dist/tools/tunslip/README.md index ddfb8689be3e..a4d11e1fba8b 100644 --- a/dist/tools/tunslip/README.md +++ b/dist/tools/tunslip/README.md @@ -1,10 +1,10 @@ # Creating a SLIP network interface -The module `slipdev` (Serial line IP) enables the RIOT network stack to -send and receive IP packets over a serial interface. This collection of -tools originally from Contiki [1] enables Linux to interpret this data. -Though there is a tool for such operations on Linux (`slattach`) it is -only able to handle IPv4 packages and is unnecessarily complicated. +The module `slipmux_net` (Serial line IP Multiplexing) enables the RIOT network +stack to send and receive IP packets over a serial interface. This collection +of tools originally from Contiki [1] enables Linux to interpret this data. +Though there is a tool for such operations on Linux (`slattach`) it is only +able to handle IPv4 packages and is unnecessarily complicated. ## Installation diff --git a/sys/net/gnrc/netif/init_devs/auto_init_slipdev.c b/sys/net/gnrc/netif/init_devs/auto_init_slipdev.c deleted file mode 100644 index d6f953e3d146..000000000000 --- a/sys/net/gnrc/netif/init_devs/auto_init_slipdev.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2015 Kaspar Schleiser - * - * 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_auto_init_gnrc_netif - * @{ - * - * @file - * @brief Auto initialization for XBee network interfaces - * - * @author Kaspar Schleiser - */ - -#include "log.h" -#include "board.h" -#include "net/gnrc/netif/raw.h" -#include "net/gnrc.h" -#include "include/init_devs.h" - -#include "slipdev.h" -#include "slipdev_params.h" - -#define SLIPDEV_NUM ARRAY_SIZE(slipdev_params) - -/** - * @brief Define stack parameters for the MAC layer thread - * @{ - */ -#define SLIPDEV_STACKSIZE (GNRC_NETIF_STACKSIZE_DEFAULT) -#ifndef SLIPDEV_PRIO -#define SLIPDEV_PRIO (GNRC_NETIF_PRIO) -#endif - -static slipdev_t slipdevs[SLIPDEV_NUM]; -static char _slipdev_stacks[SLIPDEV_NUM][SLIPDEV_STACKSIZE]; - -static gnrc_netif_t _netif[SLIPDEV_NUM]; - -void auto_init_slipdev(void) -{ - for (unsigned i = 0; i < SLIPDEV_NUM; i++) { - const slipdev_params_t *p = &slipdev_params[i]; - - LOG_DEBUG("[auto_init_netif] initializing slip #%u\n", i); - - slipdev_setup(&slipdevs[i], p, i); - gnrc_netif_raw_create(&_netif[i], _slipdev_stacks[i], SLIPDEV_STACKSIZE, - SLIPDEV_PRIO, "slipdev", - &slipdevs[i].netdev); - } -} -/** @} */ diff --git a/sys/net/gnrc/netif/init_devs/init.c b/sys/net/gnrc/netif/init_devs/init.c index 23b7adb885ec..3dd5af5c15b5 100644 --- a/sys/net/gnrc/netif/init_devs/init.c +++ b/sys/net/gnrc/netif/init_devs/init.c @@ -109,11 +109,6 @@ void gnrc_netif_init_devs(void) auto_init_sam0_eth(); } - if (IS_USED(MODULE_SLIPDEV)) { - extern void auto_init_slipdev(void); - auto_init_slipdev(); - } - if (IS_USED(MODULE_CC2538_RF)) { extern void auto_init_cc2538_rf(void); auto_init_cc2538_rf(); From 848ab3db780e1e017e260721772d14291ad6ca9d Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 12:39:15 +0100 Subject: [PATCH 08/14] review: adjust net.c --- drivers/slipmux/net.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/slipmux/net.c b/drivers/slipmux/net.c index 2b21ee4a2a0e..dd25316dcd90 100644 --- a/drivers/slipmux/net.c +++ b/drivers/slipmux/net.c @@ -44,7 +44,7 @@ static void _poweron(slipmux_t *dev) return; } - dev->state = 0; + dev->state = SLIPMUX_STATE_NONE; uart_init(dev->config.uart, dev->config.baudrate, slipmux_rx_cb, dev); } @@ -125,7 +125,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) static void _isr(netdev_t *netdev) { - slipmux_t *dev = container_of(netdev, slipmux_t, netdev); + slipmux_t *dev = container_of(netdev, slipmux_t, netdev); size_t len; while (crb_get_chunk_size(&dev->net_rb, &len)) { @@ -136,10 +136,6 @@ static void _isr(netdev_t *netdev) #if !(IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) static int _set_state(slipmux_t *dev, netopt_state_t state) { - if (IS_USED(MODULE_SLIPMUX_STDIO)) { - return -ENOTSUP; - } - switch (state) { case NETOPT_STATE_STANDBY: _poweroff(dev, SLIPMUX_STATE_STANDBY); @@ -209,10 +205,10 @@ static const netdev_driver_t slip_driver = { .isr = _isr, .get = _get, .confirm_send = _confirm_send, -#if (IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) - .set = netdev_set_notsup, -#else +#if !(IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP)) .set = _set, +#else + .set = netdev_set_notsup, #endif }; From b7711054ebfac02e65610cd01fe503d38098de84 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 12:48:40 +0100 Subject: [PATCH 09/14] lol forgot to commit, use new state names --- drivers/slipmux/coap.c | 2 +- drivers/slipmux/slipmux.c | 6 +++--- drivers/slipmux/stdio.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/slipmux/coap.c b/drivers/slipmux/coap.c index 0a77f30f0b22..88daef2dc986 100644 --- a/drivers/slipmux/coap.c +++ b/drivers/slipmux/coap.c @@ -41,7 +41,7 @@ void slipmux_coap_send(uint8_t *buf, size_t len, slipmux_t *dev) uint16_t fcs_sum = crc16_ccitt_fcs_finish(SPECIAL_INIT_FCS, buf, len); slipmux_lock(dev); - slipmux_write_byte(dev->config.uart, SLIPMUX_COAP_START); + slipmux_write_byte(dev->config.uart, SLIPMUX_START_COAP); slipmux_write_bytes(dev->config.uart, buf, len); slipmux_write_bytes(dev->config.uart, (uint8_t *) &fcs_sum, 2); slipmux_write_byte(dev->config.uart, SLIPMUX_END); diff --git a/drivers/slipmux/slipmux.c b/drivers/slipmux/slipmux.c index 34319a45a239..dc74b93f81fa 100644 --- a/drivers/slipmux/slipmux.c +++ b/drivers/slipmux/slipmux.c @@ -158,12 +158,12 @@ void slipmux_rx_cb(void *arg, uint8_t byte) case SLIPMUX_STATE_NONE: /* is diagnostic frame? */ - if (byte == SLIPMUX_STDIO_START) { + if (byte == SLIPMUX_START_STDIO) { dev->state = SLIPMUX_STATE_STDIN; return; } - if (byte == SLIPMUX_COAP_START) { + if (byte == SLIPMUX_START_COAP) { #if IS_USED(MODULE_SLIPMUX_COAP) /* try to create new configuration / CoAP frame */ if (!crb_start_chunk(&dev->coap_rb)) { @@ -174,7 +174,7 @@ void slipmux_rx_cb(void *arg, uint8_t byte) return; } - if (SLIPMUX_NET_START(byte)) { + if (SLIPMUX_START_NET(byte)) { #if IS_USED(MODULE_SLIPMUX_NET) /* try to create new ip frame */ if (!crb_start_chunk(&dev->net_rb)) { diff --git a/drivers/slipmux/stdio.c b/drivers/slipmux/stdio.c index d235e3fcecef..7e516a918f07 100644 --- a/drivers/slipmux/stdio.c +++ b/drivers/slipmux/stdio.c @@ -38,7 +38,7 @@ static void _init(void) static ssize_t _write(const void *buffer, size_t len) { slipmux_lock(&slipmux_devs[0]); - slipmux_write_byte(slipmux_params[0].uart, SLIPMUX_STDIO_START); + slipmux_write_byte(slipmux_params[0].uart, SLIPMUX_START_STDIO); slipmux_write_bytes(slipmux_params[0].uart, buffer, len); slipmux_write_byte(slipmux_params[0].uart, SLIPMUX_END); slipmux_unlock(&slipmux_devs[0]); From 690c9c3953fb99e148219ebb4ee5e62cf1362e2e Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 12:59:23 +0100 Subject: [PATCH 10/14] typedef the state --- drivers/include/slipmux.h | 26 +++++++++++++++++++++- drivers/slipmux/include/slipmux_internal.h | 24 -------------------- drivers/slipmux/slipmux.c | 7 ++++++ 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/include/slipmux.h b/drivers/include/slipmux.h index 5024c0bae4a5..ffefa48db967 100644 --- a/drivers/include/slipmux.h +++ b/drivers/include/slipmux.h @@ -139,6 +139,30 @@ typedef struct { uint32_t baudrate; /**< baudrate for the UART interface */ } slipmux_params_t; +/** + * @brief Decoder internal state + */ +typedef enum { + /* Device is in no mode (currently did not receiving any data frame) */ + SLIPMUX_STATE_NONE = 0, + /* Device handles data as network device */ + SLIPMUX_STATE_NET, + /* Device handles data as network device, next byte is escaped */ + SLIPMUX_STATE_NET_ESC, + /* Device handles received data to stdin */ + SLIPMUX_STATE_STDIN, + /* Device handles received data to stdin, next byte is escaped */ + SLIPMUX_STATE_STDIN_ESC, + /* Device handles received data as CoAP message */ + SLIPMUX_STATE_COAP, + /* Device handles received data as CoAP message, next byte is escaped */ + SLIPMUX_STATE_COAP_ESC, + /* Device is in standby, will wake up when sending data */ + SLIPMUX_STATE_STANDBY, + /* Device is in sleep mode */ + SLIPMUX_STATE_SLEEP, +} slipmux_state_t; + /** * @brief Device descriptor for slipmux */ @@ -163,7 +187,7 @@ typedef struct { /** * @brief Device state (decoder-, powerstate) */ - uint8_t state; + slipmux_state_t state; #if IS_USED(MODULE_SLIPMUX_STDIO) || IS_USED(MODULE_SLIPMUX_COAP) /** * @brief Mutex to synchronize write operations to the UART between stdio, diff --git a/drivers/slipmux/include/slipmux_internal.h b/drivers/slipmux/include/slipmux_internal.h index 43f155c4cb4f..e96432a958c9 100644 --- a/drivers/slipmux/include/slipmux_internal.h +++ b/drivers/slipmux/include/slipmux_internal.h @@ -87,30 +87,6 @@ extern slipmux_t slipmux_devs[SLIPMUX_DEV_NUM]; ) /** @} */ -/** - * @brief Decoder internal state - */ -enum { - /* Device is in no mode (currently did not receiving any data frame) */ - SLIPMUX_STATE_NONE = 0, - /* Device handles data as network device */ - SLIPMUX_STATE_NET, - /* Device handles data as network device, next byte is escaped */ - SLIPMUX_STATE_NET_ESC, - /* Device handles received data to stdin */ - SLIPMUX_STATE_STDIN, - /* Device handles received data to stdin, next byte is escaped */ - SLIPMUX_STATE_STDIN_ESC, - /* Device handles received data as CoAP message */ - SLIPMUX_STATE_COAP, - /* Device handles received data as CoAP message, next byte is escaped */ - SLIPMUX_STATE_COAP_ESC, - /* Device is in standby, will wake up when sending data */ - SLIPMUX_STATE_STANDBY, - /* Device is in sleep mode */ - SLIPMUX_STATE_SLEEP, -}; - /** * @brief Callback for the UART on receiving data */ diff --git a/drivers/slipmux/slipmux.c b/drivers/slipmux/slipmux.c index dc74b93f81fa..2179e94a682b 100644 --- a/drivers/slipmux/slipmux.c +++ b/drivers/slipmux/slipmux.c @@ -34,6 +34,13 @@ void slipmux_rx_cb(void *arg, uint8_t byte) slipmux_t *dev = arg; switch (dev->state) { + case SLIPMUX_STATE_STANDBY: + /* fall through */ + case SLIPMUX_STATE_SLEEP: + /* do nothing if we are supposed to sleep */ + /* and we should usually not be able to hit this case anyways */ + assert(0); + break; case SLIPMUX_STATE_STDIN: switch (byte) { case SLIPMUX_ESC: From 71ad6d49a3e6699cbb2e55d1c068f3f4aa455591 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 13:28:30 +0100 Subject: [PATCH 11/14] add unknown frame type --- drivers/include/slipmux.h | 2 ++ drivers/slipmux/slipmux.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/include/slipmux.h b/drivers/include/slipmux.h index ffefa48db967..0747a1ec81c2 100644 --- a/drivers/include/slipmux.h +++ b/drivers/include/slipmux.h @@ -145,6 +145,8 @@ typedef struct { typedef enum { /* Device is in no mode (currently did not receiving any data frame) */ SLIPMUX_STATE_NONE = 0, + /* Device discards incoming data until next frame begins */ + SLIPMUX_STATE_UNKNOWN, /* Device handles data as network device */ SLIPMUX_STATE_NET, /* Device handles data as network device, next byte is escaped */ diff --git a/drivers/slipmux/slipmux.c b/drivers/slipmux/slipmux.c index 2179e94a682b..1bf34a5a2933 100644 --- a/drivers/slipmux/slipmux.c +++ b/drivers/slipmux/slipmux.c @@ -92,7 +92,7 @@ void slipmux_rx_cb(void *arg, uint8_t byte) if (!crb_add_byte(&dev->coap_rb, byte)) { DEBUG("slipmux: coap rx buffer full, drop frame\n"); crb_end_chunk(&dev->coap_rb, false); - dev->state = SLIPMUX_STATE_NONE; + dev->state = SLIPMUX_STATE_UNKNOWN; return; } #endif @@ -113,7 +113,7 @@ void slipmux_rx_cb(void *arg, uint8_t byte) if (!crb_add_byte(&dev->coap_rb, byte)) { DEBUG("slipmux: coap rx buffer full, drop frame\n"); crb_end_chunk(&dev->coap_rb, false); - dev->state = SLIPMUX_STATE_NONE; + dev->state = SLIPMUX_STATE_UNKNOWN; return; } #endif @@ -137,7 +137,7 @@ void slipmux_rx_cb(void *arg, uint8_t byte) if (!crb_add_byte(&dev->net_rb, byte)) { DEBUG("slipmux: net rx buffer full, drop frame\n"); crb_end_chunk(&dev->net_rb, false); - dev->state = SLIPMUX_STATE_NONE; + dev->state = SLIPMUX_STATE_UNKNOWN; } #endif return; @@ -156,13 +156,17 @@ void slipmux_rx_cb(void *arg, uint8_t byte) if (!crb_add_byte(&dev->net_rb, byte)) { DEBUG("slipmux: net rx buffer full, drop frame\n"); crb_end_chunk(&dev->net_rb, false); - dev->state = SLIPMUX_STATE_NONE; + dev->state = SLIPMUX_STATE_UNKNOWN; return; } #endif dev->state = SLIPMUX_STATE_NET; return; - + case SLIPMUX_STATE_UNKNOWN: + if (byte == SLIPMUX_END) { + dev->state = SLIPMUX_STATE_NONE; + } + return; case SLIPMUX_STATE_NONE: /* is diagnostic frame? */ if (byte == SLIPMUX_START_STDIO) { @@ -174,6 +178,7 @@ void slipmux_rx_cb(void *arg, uint8_t byte) #if IS_USED(MODULE_SLIPMUX_COAP) /* try to create new configuration / CoAP frame */ if (!crb_start_chunk(&dev->coap_rb)) { + dev->state = SLIPMUX_STATE_UNKNOWN; return; } #endif @@ -186,12 +191,13 @@ void slipmux_rx_cb(void *arg, uint8_t byte) /* try to create new ip frame */ if (!crb_start_chunk(&dev->net_rb)) { DEBUG("slipmux: can't start new net frame, drop frame\n"); + dev->state = SLIPMUX_STATE_UNKNOWN; return; } if (!crb_add_byte(&dev->net_rb, byte)) { DEBUG("slipmux: net rx buffer full, drop frame\n"); crb_end_chunk(&dev->net_rb, false); - dev->state = SLIPMUX_STATE_NONE; + dev->state = SLIPMUX_STATE_UNKNOWN; return; } #endif @@ -204,8 +210,8 @@ void slipmux_rx_cb(void *arg, uint8_t byte) return; } + dev->state = SLIPMUX_STATE_UNKNOWN; DEBUG("slipmux: Unknown start byte %b ignored\n", byte); - // todo: Own parser category for unknown packet } } From 69f3d50f0bbd4643586bb74ca0a6db3d4575d795 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 13:55:12 +0100 Subject: [PATCH 12/14] remove trailing whitespace --- drivers/include/slipmux.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/include/slipmux.h b/drivers/include/slipmux.h index 0747a1ec81c2..e00bc671ebd7 100644 --- a/drivers/include/slipmux.h +++ b/drivers/include/slipmux.h @@ -22,12 +22,12 @@ * * This is the base module, see @ref drivers_slipmux_net, @ref drivers_slipmux_coap and * @ref drivers_slipmux_stdio for more information. - * + * * For example, to use STDIO and also provide a network interface over SLIPMUX select: - * + * * USEMODULE += slipmux_stdio * USEMODULE += slipmux_net - * + * * @{ * * @file @@ -106,7 +106,7 @@ extern "C" { * To enable this implementation, select * * USEMODULE += slipmux_net - * + * * To add link-layer addresses to the SLIPMUX network interfaces, select * * USEMODULE += slipmux_net_l2addr From 27af9a1c90a836e13a70743561753489be4e7933 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Nov 2025 13:58:11 +0100 Subject: [PATCH 13/14] unfinished Kconf --- drivers/Kconfig.net | 2 +- drivers/slipmux/Kconfig | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 drivers/slipmux/Kconfig diff --git a/drivers/Kconfig.net b/drivers/Kconfig.net index 5e1af3d239f8..d527706495c6 100644 --- a/drivers/Kconfig.net +++ b/drivers/Kconfig.net @@ -15,5 +15,5 @@ rsource "dose/Kconfig" rsource "mrf24j40/Kconfig" rsource "pn532/Kconfig" rsource "rn2xx3/Kconfig" -rsource "slipdev/Kconfig" +rsource "slipmux/Kconfig" endmenu # Network Device Drivers diff --git a/drivers/slipmux/Kconfig b/drivers/slipmux/Kconfig new file mode 100644 index 000000000000..29dac8e883c7 --- /dev/null +++ b/drivers/slipmux/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2020 Freie Universitaet Berlin +# 2021 HAW Hamburg +# 2025 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. +# + +menu "SLIPMUX driver" + depends on USEMODULE_SLIPMUX + +# todo + +endmenu # SLIPMUX driver From 95a343ae8652eef662c6fcd72ff124f3bb67d202 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Wed, 3 Dec 2025 18:59:46 +0100 Subject: [PATCH 14/14] Rename module to slipmux_dev, fix dependency handling --- Makefile.dep | 2 +- drivers/Kconfig.net | 2 +- drivers/Makefile.dep | 4 +- drivers/slipmux/Kconfig | 15 ----- drivers/slipmux/Makefile | 7 -- drivers/slipmux/Makefile.dep | 26 ------- drivers/slipmux_dev/Kconfig | 27 ++++++++ drivers/slipmux_dev/Makefile | 13 ++++ drivers/slipmux_dev/Makefile.dep | 67 +++++++++++++++++++ .../{slipmux => slipmux_dev}/Makefile.include | 1 + drivers/{slipmux => slipmux_dev}/coap.c | 0 .../include/slipmux_internal.h | 0 .../include/slipmux_params.h | 0 drivers/{slipmux => slipmux_dev}/net.c | 0 drivers/{slipmux => slipmux_dev}/slipmux.c | 0 drivers/{slipmux => slipmux_dev}/stdio.c | 0 makefiles/stdio.inc.mk | 3 +- 17 files changed, 114 insertions(+), 53 deletions(-) delete mode 100644 drivers/slipmux/Kconfig delete mode 100644 drivers/slipmux/Makefile delete mode 100644 drivers/slipmux/Makefile.dep create mode 100644 drivers/slipmux_dev/Kconfig create mode 100644 drivers/slipmux_dev/Makefile create mode 100644 drivers/slipmux_dev/Makefile.dep rename drivers/{slipmux => slipmux_dev}/Makefile.include (90%) rename drivers/{slipmux => slipmux_dev}/coap.c (100%) rename drivers/{slipmux => slipmux_dev}/include/slipmux_internal.h (100%) rename drivers/{slipmux => slipmux_dev}/include/slipmux_params.h (100%) rename drivers/{slipmux => slipmux_dev}/net.c (100%) rename drivers/{slipmux => slipmux_dev}/slipmux.c (100%) rename drivers/{slipmux => slipmux_dev}/stdio.c (100%) diff --git a/Makefile.dep b/Makefile.dep index ca279ba91d6e..5eb38989c827 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -3,7 +3,7 @@ -include $(APPDIR)/Makefile.$(TOOLCHAIN).dep # select default stdio provider if no other is selected -ifeq (,$(filter stdio_% slipmux_stdio,$(USEMODULE))) +ifeq (,$(filter stdio_% slipmux_stdio slipmux,$(USEMODULE))) USEMODULE += stdio_default endif diff --git a/drivers/Kconfig.net b/drivers/Kconfig.net index d527706495c6..076112844941 100644 --- a/drivers/Kconfig.net +++ b/drivers/Kconfig.net @@ -15,5 +15,5 @@ rsource "dose/Kconfig" rsource "mrf24j40/Kconfig" rsource "pn532/Kconfig" rsource "rn2xx3/Kconfig" -rsource "slipmux/Kconfig" +rsource "slipmux_dev/Kconfig" endmenu # Network Device Drivers diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index b247c06b0835..f7169a6b5399 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -238,8 +238,8 @@ ifneq (,$(filter si70%,$(USEMODULE))) USEMODULE += si70xx endif -ifneq (,$(filter slipmux_%,$(USEMODULE))) - USEMODULE += slipmux +ifneq (,$(filter slipmux%,$(USEMODULE))) + USEMODULE += slipmux_dev endif ifneq (,$(filter stmpe811_%,$(USEMODULE))) diff --git a/drivers/slipmux/Kconfig b/drivers/slipmux/Kconfig deleted file mode 100644 index 29dac8e883c7..000000000000 --- a/drivers/slipmux/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2020 Freie Universitaet Berlin -# 2021 HAW Hamburg -# 2025 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. -# - -menu "SLIPMUX driver" - depends on USEMODULE_SLIPMUX - -# todo - -endmenu # SLIPMUX driver diff --git a/drivers/slipmux/Makefile b/drivers/slipmux/Makefile deleted file mode 100644 index fd394c384896..000000000000 --- a/drivers/slipmux/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# exclude submodule sources from *.c wildcard source selection -SRC := $(filter-out stdio.c coap.c net.c,$(wildcard *.c)) - -# enable submodules -SUBMODULES := 1 - -include $(RIOTBASE)/Makefile.base diff --git a/drivers/slipmux/Makefile.dep b/drivers/slipmux/Makefile.dep deleted file mode 100644 index 88f5592c79dc..000000000000 --- a/drivers/slipmux/Makefile.dep +++ /dev/null @@ -1,26 +0,0 @@ -ifneq (,$(filter slipmux_net_l2addr,$(USEMODULE))) - USEMODULE += slipmux_net -endif - -ifeq (,$(filter slipmux_%,$(USEMODULE))) - USEMODULE += slipmux_stdio - USEMODULE += slipmux_coap - USEMODULE += slipmux_net -endif - -USEMODULE += chunked_ringbuffer -USEMODULE += eui_provider -USEMODULE += netdev_new_api -USEMODULE += netdev_register -FEATURES_REQUIRED += periph_uart - -ifneq (,$(filter slipmux_stdio,$(USEMODULE))) - USEMODULE += isrpipe -endif -ifneq (,$(filter slipmux_coap,$(USEMODULE))) - USEMODULE += checksum - USEMODULE += sock_udp - USEMODULE += gnrc_ipv6 - USEMODULE += nanocoap_sock - USEMODULE += nanocoap_resources -endif diff --git a/drivers/slipmux_dev/Kconfig b/drivers/slipmux_dev/Kconfig new file mode 100644 index 000000000000..e1992325a785 --- /dev/null +++ b/drivers/slipmux_dev/Kconfig @@ -0,0 +1,27 @@ +# 2025 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. +# + +menu "SLIPMUX driver" + depends on USEMODULE_SLIPMUX_DEV + + config SLIPMUX_COAP_BUFSIZE + depends on USEMODULE_SLIPMUX_COAP + int "CoAP TX/RX buffer size, in bytes" + range 0 9999999 + default 512 + help + Size of the CoAP request / response buffer + + config SLIPMUX_NET_BUFSIZE + depends on USEMODULE_SLIPMUX_NET + int "IP packet TX/RX buffer size, in bytes" + range 0 9999999 + default 2048 + help + Size of the IP network interface TX/RX buffer. Reduce this value if your expected traffic does not include full IPv6 MTU sized packets. + +endmenu # SLIPMUX driver diff --git a/drivers/slipmux_dev/Makefile b/drivers/slipmux_dev/Makefile new file mode 100644 index 000000000000..fa67ef48f874 --- /dev/null +++ b/drivers/slipmux_dev/Makefile @@ -0,0 +1,13 @@ +SRC = slipmux.c + +ifneq (,$(filter slipmux_coap,$(USEMODULE))) + SRC += coap.c +endif +ifneq (,$(filter slipmux_stdio,$(USEMODULE))) + SRC += stdio.c +endif +ifneq (,$(filter slipmux_net,$(USEMODULE))) + SRC += net.c +endif + +include $(RIOTBASE)/Makefile.base diff --git a/drivers/slipmux_dev/Makefile.dep b/drivers/slipmux_dev/Makefile.dep new file mode 100644 index 000000000000..8c0d1e68ad49 --- /dev/null +++ b/drivers/slipmux_dev/Makefile.dep @@ -0,0 +1,67 @@ +# This variable ensures the warning is printed only once +_SLIPMUX_OVERSELECTED_MODULES ?= 0 +ifeq (0, $(_SLIPMUX_OVERSELECTED_MODULES)) + ifneq (,$(filter slipmux,$(USEMODULE))) + _SUBMODS = $(filter slipmux_stdio slipmux_coap slipmux_net,$(USEMODULE)) + # any submodules at all? + ifneq (,$(_SUBMODS)) + # but less then three? Because if we use all three submodules the behaviour is identical + # to using the base module. Same result, no confusion or unexpected behaviour for the user. + # So we don't warn. This works because the `word` filter returns either the third word + # from submods (-> we have three modules defined) or nothing at all -> one or two moduels in use + ifeq (,$(word 3,$(_SUBMODS))) + # an undefined variable can be used to trick make into allowing leading whitespace + # we don't even have to define the variable itself, see, it is commented out! + # _give_space = + $(info $(COLOR_YELLOW)Warning in slipmux_dev:) + $(info $(_give_space) You selected the submodule(s) `$(_SUBMODS)` manually in USEMODULE together with the module `slipmux`.) + $(info $(_give_space) The module `slipmux` enables all submodules by default.) + $(info $(_give_space) If you want to use only the submodule that you selected and want to disable the others:) + $(info $(_give_space) Remove the `slipmux` module from your USEMODULE.) + $(info $(_give_space) If you want to enable all submodules and get rid of this warning:) + $(info $(_give_space) Remove the `$(_SUBMODS)` submodule(s) from your USEMODULE. Keep `slipmux` only.) + $(info $(_give_space) If you want to enable all submodules and keep this warning:) + $(info $(_give_space) Do nothing.$(COLOR_RESET)) + _SLIPMUX_OVERSELECTED_MODULES = 1 + endif + endif + endif +endif + +# If the pseudomodule `slipmux` is used, enable all frame types +ifneq (,$(filter slipmux,$(USEMODULE))) + USEMODULE += slipmux_stdio + USEMODULE += slipmux_coap + USEMODULE += slipmux_net +endif + +# If the _net suboption is used, ensure _net is enabled +ifneq (,$(filter slipmux_net_l2addr,$(USEMODULE))) + USEMODULE += slipmux_net +endif + +# Both the modules need the ringbuffer +ifneq (,$(filter slipmux_coap slipmux_net,$(USEMODULE))) + USEMODULE += chunked_ringbuffer +endif + +ifneq (,$(filter slipmux_net,$(USEMODULE))) + USEMODULE += eui_provider + USEMODULE += netdev_new_api + USEMODULE += netdev_register +endif + +ifneq (,$(filter slipmux_stdio,$(USEMODULE))) + USEMODULE += isrpipe +endif + +ifneq (,$(filter slipmux_coap,$(USEMODULE))) + USEMODULE += checksum + USEMODULE += sock_udp + USEMODULE += gnrc_ipv6 + USEMODULE += nanocoap_sock + USEMODULE += nanocoap_resources +endif + +# We always require a uart +FEATURES_REQUIRED += periph_uart \ No newline at end of file diff --git a/drivers/slipmux/Makefile.include b/drivers/slipmux_dev/Makefile.include similarity index 90% rename from drivers/slipmux/Makefile.include rename to drivers/slipmux_dev/Makefile.include index 1ca1eef0d613..af80005fb616 100644 --- a/drivers/slipmux/Makefile.include +++ b/drivers/slipmux_dev/Makefile.include @@ -1,3 +1,4 @@ +PSEUDOMODULES += slipmux PSEUDOMODULES += slipmux_stdio PSEUDOMODULES += slipmux_coap PSEUDOMODULES += slipmux_net diff --git a/drivers/slipmux/coap.c b/drivers/slipmux_dev/coap.c similarity index 100% rename from drivers/slipmux/coap.c rename to drivers/slipmux_dev/coap.c diff --git a/drivers/slipmux/include/slipmux_internal.h b/drivers/slipmux_dev/include/slipmux_internal.h similarity index 100% rename from drivers/slipmux/include/slipmux_internal.h rename to drivers/slipmux_dev/include/slipmux_internal.h diff --git a/drivers/slipmux/include/slipmux_params.h b/drivers/slipmux_dev/include/slipmux_params.h similarity index 100% rename from drivers/slipmux/include/slipmux_params.h rename to drivers/slipmux_dev/include/slipmux_params.h diff --git a/drivers/slipmux/net.c b/drivers/slipmux_dev/net.c similarity index 100% rename from drivers/slipmux/net.c rename to drivers/slipmux_dev/net.c diff --git a/drivers/slipmux/slipmux.c b/drivers/slipmux_dev/slipmux.c similarity index 100% rename from drivers/slipmux/slipmux.c rename to drivers/slipmux_dev/slipmux.c diff --git a/drivers/slipmux/stdio.c b/drivers/slipmux_dev/stdio.c similarity index 100% rename from drivers/slipmux/stdio.c rename to drivers/slipmux_dev/stdio.c diff --git a/makefiles/stdio.inc.mk b/makefiles/stdio.inc.mk index beacfff29ad1..51ca785b106c 100644 --- a/makefiles/stdio.inc.mk +++ b/makefiles/stdio.inc.mk @@ -1,5 +1,6 @@ STDIO_MODULES = \ slipmux_stdio \ + slipmux \ stdio_cdc_acm \ stdio_ethos \ stdio_native \ @@ -101,7 +102,7 @@ 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 slipmux_stdio stdio_semihosting stdio_tinyusb_cdc_acm,$(USEMODULE))) + ifneq (,$(filter stdio_cdc_acm stdio_ethos slipmux slipmux_stdio stdio_semihosting stdio_tinyusb_cdc_acm,$(USEMODULE))) USEMODULE += picolibc_stdout_buffered endif endif