From 3f9cd2e4e0a3b2fd3bcf5fbdbab65bdb842c98ad Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 14 Jun 2026 18:47:20 -0500 Subject: [PATCH] Update US LoRa modem preset to region defaults for compliance --- src/mesh/Channels.cpp | 2 +- src/mesh/NodeDB.cpp | 5 ++++- src/mesh/RadioInterface.cpp | 7 ++++++- test/test_admin_radio/test_main.cpp | 24 ++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index be75e3d42..90bca6c40 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -82,7 +82,7 @@ void Channels::initDefaultLoraConfig() { meshtastic_Config_LoRaConfig &loraConfig = config.lora; - loraConfig.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast + loraConfig.modem_preset = getRegion(loraConfig.region)->getDefaultPreset(); // region default (US: LONG_TURBO for FCC) loraConfig.use_preset = true; loraConfig.tx_power = 0; // default loraConfig.channel_num = 0; diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 2481eb8ca..ea22ae175 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -834,7 +834,10 @@ void NodeDB::installDefaultConfig(bool preserveKey = false) #ifdef USERPREFS_LORACONFIG_MODEM_PRESET config.lora.modem_preset = USERPREFS_LORACONFIG_MODEM_PRESET; #else - config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST; + // Default to the region's own default preset (US is LONG_TURBO for FCC §15.247; every other region + // is LONG_FAST). region is set just above, so a region-locked board is born on the compliant default + // without any runtime "upgrade" step. + config.lora.modem_preset = getRegion(config.lora.region)->getDefaultPreset(); #endif #ifdef USERPREFS_LORACONFIG_USE_PRESET config.lora.use_preset = USERPREFS_LORACONFIG_USE_PRESET; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 0d973e2e2..858803cd2 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -77,7 +77,12 @@ const RegionInfo regions[] = { https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/ */ - RDEF(US, 902.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), + // FCC §15.247 requires >=500 kHz of 6 dB bandwidth for digital (non-frequency-hopping) + // modulation in the 902-928 MHz band, so the US region's default preset is LONG_TURBO (500 kHz) + // rather than the 250 kHz LONG_FAST. A fresh US board adopts this as its factory default via + // getDefaultPreset() (see installDefaultConfig); LONG_FAST and the other presets stay available + // for users who opt in. + RDEF(US, 902.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_TURBO), 0), /* EN300220 ETSI V3.2.1 [Table B.1, Item H, p. 21] diff --git a/test/test_admin_radio/test_main.cpp b/test/test_admin_radio/test_main.cpp index d905cc8a0..b110e7ebb 100644 --- a/test/test_admin_radio/test_main.cpp +++ b/test/test_admin_radio/test_main.cpp @@ -1112,6 +1112,26 @@ void tearDown(void) testAdmin = nullptr; } +// ----------------------------------------------------------------------- +// US region factory default preset (LONG_TURBO for FCC §15.247). A fresh board adopts its region's +// default via getDefaultPreset() in installDefaultConfig() — there is no runtime "upgrade" path. +// ----------------------------------------------------------------------- + +static void test_usRegionDefaultPresetIsLongTurbo() +{ + // FCC §15.247: the US region's default preset is the 500 kHz LONG_TURBO, so a fresh US board is + // born compliant. + TEST_ASSERT_EQUAL(meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO, + getRegion(meshtastic_Config_LoRaConfig_RegionCode_US)->getDefaultPreset()); +} + +static void test_nonUsRegionDefaultPresetUnchanged() +{ + // Only US changed: every other region still defaults to LONG_FAST. + TEST_ASSERT_EQUAL(meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST, + getRegion(meshtastic_Config_LoRaConfig_RegionCode_EU_868)->getDefaultPreset()); +} + void setup() { delay(10); @@ -1180,6 +1200,10 @@ void setup() RUN_TEST(test_regionFieldsAreSane); RUN_TEST(test_onlyLORA24HasWideLora); + // US region factory default preset + RUN_TEST(test_usRegionDefaultPresetIsLongTurbo); + RUN_TEST(test_nonUsRegionDefaultPresetUnchanged); + // OVERRIDE_SLOT_PRESET_HASH (-1) slot formula tests RUN_TEST(test_overrideSlotPresetHash_longFast_customChannelMatchesDefaultNameSlot); RUN_TEST(test_overrideSlotPresetHash_mediumFast_customChannelMatchesDefaultNameSlot);