mirror of
https://github.com/meshtastic/firmware
synced 2026-08-07 20:32:18 -04:00
* fix(serial): validate serial module config on every platform
AdminModule guarded the serial config validation by architecture but not the
assignment beneath it:
#if ARCH_ESP32 || ARCH_NRF52 || ARCH_RP2040
if (!SerialModule::isValidConfig(...)) return false;
disableBluetooth();
#endif
moduleConfig.serial = c.payload_variant.serial;
So on every other platform an admin "set module config: serial" stored a config
the firmware rejects on ESP32. override_console_serial_port combined with
DEFAULT, SIMPLE, TEXTMSG or PROTO is accepted and persisted today.
Two families are affected, for different reasons:
- portduino/meshtasticd, where the validation did not exist at all:
isValidConfig was a static member of SerialModule, and that class is inside
the same architecture guard, so `nm` finds no such symbol in the native
object.
- STM32WL (rak3172, wio-e5, CDEBYTE_E77-MBL, russell), where it existed and
was never called: the class guard includes ARCH_STM32WL and the AdminModule
call site did not.
Validation is pure config logic with no serial hardware behind it, so it moves
out of the class and out of the guard as a free serialConfigIsValid(). Its only
external references - clientNotificationPool, service, getValidTime - are
already unguarded elsewhere, so it links on every target. AdminModule's include
of SerialModule.h is unguarded for the same reason; the class itself stays
guarded inside the header. Only disableBluetooth() remains architecture-specific.
This changes what meshtasticd and the STM32WL targets accept: a host relying on
the unvalidated path (override_console_serial_port with a mode other than NMEA,
CalTopo or MS_CONFIG) is now rejected, as it already is on ESP32.
test/test_serial has asserted nothing since it was added in 28aeb0f09e
(2025-07-26): its body is behind the same guard, so on portduino it logged a
warning and ran zero assertions while counting as one of the canonical suites.
Enabling it showed the code did not even compile - its designated initializers
list .override_console_serial_port before .mode, which is not declaration order,
and C++ requires that. PlatformIO only builds test/ for the native env, so no
build had ever compiled these lines. Reordered; all nine now run and pass.
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* I'd say gimme 5 bees for a dollar. That's what we called a nickel, because they had bees on em.
* style: wrap over-long warning string to the 120-col limit
* Cover MS_CONFIG override and correct the validator comment
serialConfigIsValid() accepts MS_CONFIG alongside NMEA and CALTOPO when
override_console_serial_port is set, but only the first two had a valid-case
test. Add the missing one.
The declaration comment described the function as pure config logic; it also
logs and, in non-test builds, sends a client notification on rejection.
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
146 lines
5.4 KiB
C++
146 lines
5.4 KiB
C++
#include "DebugConfiguration.h"
|
|
#include "TestUtil.h"
|
|
#include <unity.h>
|
|
|
|
#ifdef ARCH_PORTDUINO
|
|
#include "configuration.h"
|
|
|
|
#include "modules/SerialModule.h"
|
|
|
|
// Test that empty configuration is valid.
|
|
void test_serialConfigEmptyIsValid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {};
|
|
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that basic enabled configuration is valid.
|
|
void test_serialConfigEnabledIsValid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {.enabled = true};
|
|
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that configuration with override_console_serial_port and NMEA mode is valid.
|
|
void test_serialConfigWithOverrideConsoleNmeaModeIsValid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {
|
|
.enabled = true, .mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA, .override_console_serial_port = true};
|
|
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that configuration with override_console_serial_port and CalTopo mode is valid.
|
|
void test_serialConfigWithOverrideConsoleCalTopoModeIsValid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {
|
|
.enabled = true, .mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO, .override_console_serial_port = true};
|
|
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that configuration with override_console_serial_port and MS Config mode is valid.
|
|
void test_serialConfigWithOverrideConsoleMsConfigModeIsValid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {.enabled = true,
|
|
.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MS_CONFIG,
|
|
.override_console_serial_port = true};
|
|
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that configuration with override_console_serial_port and DEFAULT mode is invalid.
|
|
void test_serialConfigWithOverrideConsoleDefaultModeIsInvalid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {
|
|
.enabled = true, .mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT, .override_console_serial_port = true};
|
|
|
|
TEST_ASSERT_FALSE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that configuration with override_console_serial_port and SIMPLE mode is invalid.
|
|
void test_serialConfigWithOverrideConsoleSimpleModeIsInvalid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {
|
|
.enabled = true, .mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE, .override_console_serial_port = true};
|
|
|
|
TEST_ASSERT_FALSE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that configuration with override_console_serial_port and TEXTMSG mode is invalid.
|
|
void test_serialConfigWithOverrideConsoleTextMsgModeIsInvalid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {
|
|
.enabled = true, .mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG, .override_console_serial_port = true};
|
|
|
|
TEST_ASSERT_FALSE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that configuration with override_console_serial_port and PROTO mode is invalid.
|
|
void test_serialConfigWithOverrideConsoleProtoModeIsInvalid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {
|
|
.enabled = true, .mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO, .override_console_serial_port = true};
|
|
|
|
TEST_ASSERT_FALSE(serialConfigIsValid(config));
|
|
}
|
|
|
|
// Test that various modes work without override_console_serial_port.
|
|
void test_serialConfigVariousModesWithoutOverrideAreValid(void)
|
|
{
|
|
meshtastic_ModuleConfig_SerialConfig config = {.enabled = true, .override_console_serial_port = false};
|
|
|
|
// Test DEFAULT mode
|
|
config.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT;
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
|
|
// Test SIMPLE mode
|
|
config.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE;
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
|
|
// Test TEXTMSG mode
|
|
config.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG;
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
|
|
// Test PROTO mode
|
|
config.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO;
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
|
|
// Test NMEA mode
|
|
config.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA;
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
|
|
// Test CALTOPO mode
|
|
config.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO;
|
|
TEST_ASSERT_TRUE(serialConfigIsValid(config));
|
|
}
|
|
|
|
void setup()
|
|
{
|
|
initializeTestEnvironment();
|
|
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_serialConfigEmptyIsValid);
|
|
RUN_TEST(test_serialConfigEnabledIsValid);
|
|
RUN_TEST(test_serialConfigWithOverrideConsoleNmeaModeIsValid);
|
|
RUN_TEST(test_serialConfigWithOverrideConsoleCalTopoModeIsValid);
|
|
RUN_TEST(test_serialConfigWithOverrideConsoleMsConfigModeIsValid);
|
|
RUN_TEST(test_serialConfigWithOverrideConsoleDefaultModeIsInvalid);
|
|
RUN_TEST(test_serialConfigWithOverrideConsoleSimpleModeIsInvalid);
|
|
RUN_TEST(test_serialConfigWithOverrideConsoleTextMsgModeIsInvalid);
|
|
RUN_TEST(test_serialConfigWithOverrideConsoleProtoModeIsInvalid);
|
|
RUN_TEST(test_serialConfigVariousModesWithoutOverrideAreValid);
|
|
exit(UNITY_END());
|
|
}
|
|
#else
|
|
void setup()
|
|
{
|
|
initializeTestEnvironment();
|
|
LOG_WARN("This test requires the ARCH_PORTDUINO variant");
|
|
UNITY_BEGIN();
|
|
exit(UNITY_END());
|
|
}
|
|
#endif
|
|
void loop() {}
|