diff --git a/src/mesh/MeshRadio.h b/src/mesh/MeshRadio.h index e2c053a8b..659dc9691 100644 --- a/src/mesh/MeshRadio.h +++ b/src/mesh/MeshRadio.h @@ -15,7 +15,7 @@ static const meshtastic_Config_LoRaConfig_ModemPreset MODEM_PRESET_END = #define PRESET(name) meshtastic_Config_LoRaConfig_ModemPreset_##name -// Override slot magic numbers for RegionProfile.overrideSlot +// Override slot magic numbers for RegionInfo.overrideSlot #define OVERRIDE_SLOT_DEFAULT_CHANNEL_HASH 0 // Use hash of primary channel name #define OVERRIDE_SLOT_PRESET_HASH -1 // Use hash of preset name instead // Positive values (1-32767) are explicit slot numbers @@ -30,8 +30,6 @@ struct RegionProfile { int8_t textThrottle; // throttle for text - future expansion int8_t positionThrottle; // throttle for location data - future expansion int8_t telemetryThrottle; // throttle for telemetry - future expansion - int16_t overrideSlot; // a per-region override slot for if we need to fix it in place - // Magic values: 0 = use channel name hash, -1 = use preset name hash, >0 = explicit slot }; /** @@ -59,7 +57,9 @@ struct RegionInfo { bool wideLora; const RegionProfile *profile; meshtastic_Config_LoRaConfig_ModemPreset defaultPreset; - const char *name; // EU433 etc + int16_t overrideSlot; // per-region override slot for frequency selection + // Magic values: 0 = use channel name hash, -1 = use preset name hash, >0 = explicit slot + const char *name; // EU433 etc // Preset accessors (delegate through profile) meshtastic_Config_LoRaConfig_ModemPreset getDefaultPreset() const { return defaultPreset; } diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index d4eeed089..4493a58d9 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -50,17 +50,18 @@ static const meshtastic_Config_LoRaConfig_ModemPreset PRESETS_NARROW[] = {PRESET MODEM_PRESET_END}; // Region profiles: bundle preset list + regulatory parameters shared across regions -// presets, spacing, padding, audio, licensed, text throttle, position throttle, telemetry throttle, override slot -const RegionProfile PROFILE_STD = {PRESETS_STD, 0, 0, true, false, 0, 1, 1, 0}; -const RegionProfile PROFILE_EU868 = {PRESETS_EU_868, 0, 0, false, false, 0, 1, 1, 0}; -const RegionProfile PROFILE_UNDEF = {PRESETS_UNDEF, 0, 0, true, false, 0, 1, 1, 0}; -const RegionProfile PROFILE_LITE = {PRESETS_LITE, 0.4, 0.0375f, false, false, 0, 10, 10, 0}; -const RegionProfile PROFILE_NARROW = {PRESETS_NARROW, 0, 0.0104f, true, false, 0, 1, 1, 1}; +// presets, spacing, padding, audio, licensed, text throttle, position throttle, telemetry throttle +const RegionProfile PROFILE_STD = {PRESETS_STD, 0, 0, true, false, 0, 1, 1}; +const RegionProfile PROFILE_EU868 = {PRESETS_EU_868, 0, 0, false, false, 0, 1, 1}; +const RegionProfile PROFILE_UNDEF = {PRESETS_UNDEF, 0, 0, true, false, 0, 1, 1}; +const RegionProfile PROFILE_LITE = {PRESETS_LITE, 0.4, 0.0375f, false, false, 0, 10, 10}; +const RegionProfile PROFILE_NARROW = {PRESETS_NARROW, 0, 0.0104f, true, false, 0, 1, 1}; -#define RDEF(name, freq_start, freq_end, duty_cycle, power_limit, frequency_switching, wide_lora, profile_ptr, default_preset) \ +#define RDEF(name, freq_start, freq_end, duty_cycle, power_limit, frequency_switching, wide_lora, profile_ptr, default_preset, \ + override_slot) \ { \ meshtastic_Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, power_limit, frequency_switching, \ - wide_lora, &profile_ptr, default_preset, #name \ + wide_lora, &profile_ptr, default_preset, override_slot, #name \ } const RegionInfo regions[] = { @@ -68,7 +69,7 @@ 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)), + RDEF(US, 902.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* EN300220 ETSI V3.2.1 [Table B.1, Item H, p. 21] @@ -76,7 +77,7 @@ const RegionInfo regions[] = { https://www.etsi.org/deliver/etsi_en/300200_300299/30022002/03.02.01_60/en_30022002v030201p.pdf FIXME: https://github.com/meshtastic/firmware/issues/3371 */ - RDEF(EU_433, 433.0f, 434.0f, 10, 10, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(EU_433, 433.0f, 434.0f, 10, 10, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/ https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/ @@ -91,33 +92,33 @@ const RegionInfo regions[] = { AFA) to avoid a duty cycle. (Please refer to line P page 22 of this document.) https://www.etsi.org/deliver/etsi_en/300200_300299/30022002/03.01.01_60/en_30022002v030101p.pdf */ - RDEF(EU_868, 869.4f, 869.65f, 10, 27, false, false, PROFILE_EU868, PRESET(LONG_FAST)), + RDEF(EU_868, 869.4f, 869.65f, 10, 27, false, false, PROFILE_EU868, PRESET(LONG_FAST), 0), /* https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf */ - RDEF(CN, 470.0f, 510.0f, 100, 19, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(CN, 470.0f, 510.0f, 100, 19, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf https://www.arib.or.jp/english/html/overview/doc/5-STD-T108v1_5-E1.pdf https://qiita.com/ammo0613/items/d952154f1195b64dc29f */ - RDEF(JP, 920.5f, 923.5f, 100, 13, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(JP, 920.5f, 923.5f, 100, 13, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://www.iot.org.au/wp/wp-content/uploads/2016/12/IoTSpectrumFactSheet.pdf https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf Also used in Brazil. */ - RDEF(ANZ, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(ANZ, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* 433.05 - 434.79 MHz, 25mW EIRP max, No duty cycle restrictions AU Low Interference Potential https://www.acma.gov.au/licences/low-interference-potential-devices-lipd-class-licence NZ General User Radio Licence for Short Range Devices https://gazette.govt.nz/notice/id/2022-go3100 */ - RDEF(ANZ_433, 433.05f, 434.79f, 100, 14, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(ANZ_433, 433.05f, 434.79f, 100, 14, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf @@ -125,13 +126,13 @@ const RegionInfo regions[] = { Note: - We do LBT, so 100% is allowed. */ - RDEF(RU, 868.7f, 869.2f, 100, 20, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(RU, 868.7f, 869.2f, 100, 20, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://www.law.go.kr/LSW/admRulLsInfoP.do?admRulId=53943&efYd=0 https://resources.lora-alliance.org/technical-specifications/rp002-1-0-4-regional-parameters */ - RDEF(KR, 920.0f, 923.0f, 100, 23, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(KR, 920.0f, 923.0f, 100, 23, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Taiwan, 920-925Mhz, limited to 0.5W indoor or coastal, 1.0W outdoor. @@ -139,40 +140,40 @@ const RegionInfo regions[] = { https://www.ncc.gov.tw/english/files/23070/102_5190_230703_1_doc_C.PDF https://gazette.nat.gov.tw/egFront/e_detail.do?metaid=147283 */ - RDEF(TW, 920.0f, 925.0f, 100, 27, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(TW, 920.0f, 925.0f, 100, 27, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf */ - RDEF(IN, 865.0f, 867.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(IN, 865.0f, 867.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752 https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf */ - RDEF(NZ_865, 864.0f, 868.0f, 100, 36, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(NZ_865, 864.0f, 868.0f, 100, 36, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf https://standard.nbtc.go.th/getattachment/Standards/%E0%B8%A1%E0%B8%B2%E0%B8%95%E0%B8%A3%E0%B8%90%E0%B8%B2%E0%B8%99%E0%B8%97%E0%B8%B2%E0%B8%87%E0%B9%80%E0%B8%97%E0%B8%84%E0%B8%99%E0%B8%B4%E0%B8%84%E0%B8%82%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%84%E0%B8%A3%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B9%82%E0%B8%97%E0%B8%A3%E0%B8%84%E0%B8%A1%E0%B8%99%E0%B8%B2%E0%B8%84%E0%B8%A1/1033-2565.pdf.aspx?lang=th-TH Thailand 920–925 MHz set max TX power to 27 dBm and enforce 10% duty cycle, aligned with NBTC regulations. */ - RDEF(TH, 920.0f, 925.0f, 10, 27, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(TH, 920.0f, 925.0f, 10, 27, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* 433,05-434,7 Mhz 10 mW 868,0-868,6 Mhz 25 mW https://nkrzi.gov.ua/images/upload/256/5810/PDF_UUZ_19_01_2016.pdf */ - RDEF(UA_433, 433.0f, 434.7f, 10, 10, false, false, PROFILE_STD, PRESET(LONG_FAST)), - RDEF(UA_868, 868.0f, 868.6f, 1, 14, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(UA_433, 433.0f, 434.7f, 10, 10, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), + RDEF(UA_868, 868.0f, 868.6f, 1, 14, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Malaysia 433 - 435 MHz at 100mW, no restrictions. https://www.mcmc.gov.my/skmmgovmy/media/General/pdf/Short-Range-Devices-Specification.pdf */ - RDEF(MY_433, 433.0f, 435.0f, 100, 20, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(MY_433, 433.0f, 435.0f, 100, 20, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Malaysia @@ -181,14 +182,14 @@ const RegionInfo regions[] = { Frequency hopping is used for 919 - 923 MHz. https://www.mcmc.gov.my/skmmgovmy/media/General/pdf/Short-Range-Devices-Specification.pdf */ - RDEF(MY_919, 919.0f, 924.0f, 100, 27, true, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(MY_919, 919.0f, 924.0f, 100, 27, true, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Singapore SG_923 Band 30d: 917 - 925 MHz at 100mW, no restrictions. https://www.imda.gov.sg/-/media/imda/files/regulation-licensing-and-consultations/ict-standards/telecommunication-standards/radio-comms/imdatssrd.pdf */ - RDEF(SG_923, 917.0f, 925.0f, 100, 20, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(SG_923, 917.0f, 925.0f, 100, 20, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Philippines @@ -198,9 +199,9 @@ const RegionInfo regions[] = { https://github.com/meshtastic/firmware/issues/4948#issuecomment-2394926135 */ - RDEF(PH_433, 433.0f, 434.7f, 100, 10, false, false, PROFILE_STD, PRESET(LONG_FAST)), - RDEF(PH_868, 868.0f, 869.4f, 100, 14, false, false, PROFILE_STD, PRESET(LONG_FAST)), - RDEF(PH_915, 915.0f, 918.0f, 100, 24, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(PH_433, 433.0f, 434.7f, 100, 10, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), + RDEF(PH_868, 868.0f, 869.4f, 100, 14, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), + RDEF(PH_915, 915.0f, 918.0f, 100, 24, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Kazakhstan @@ -208,46 +209,46 @@ const RegionInfo regions[] = { 863 - 868 MHz <25 mW EIRP, 500kHz channels allowed, must not be used at airfields https://github.com/meshtastic/firmware/issues/7204 */ - RDEF(KZ_433, 433.075f, 434.775f, 100, 10, false, false, PROFILE_STD, PRESET(LONG_FAST)), - RDEF(KZ_863, 863.0f, 868.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(KZ_433, 433.075f, 434.775f, 100, 10, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), + RDEF(KZ_863, 863.0f, 868.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Nepal 865 MHz to 868 MHz frequency band for IoT (Internet of Things), M2M (Machine-to-Machine), and smart metering use, specifically in non-cellular mode. https://www.nta.gov.np/uploads/contents/Radio-Frequency-Policy-2080-English.pdf */ - RDEF(NP_865, 865.0f, 868.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(NP_865, 865.0f, 868.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* Brazil 902 - 907.5 MHz , 1W power limit, no duty cycle restrictions https://github.com/meshtastic/firmware/issues/3741 */ - RDEF(BR_902, 902.0f, 907.5f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(BR_902, 902.0f, 907.5f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* 2.4 GHZ WLAN Band equivalent. Only for SX128x chips. */ - RDEF(LORA_24, 2400.0f, 2483.5f, 100, 10, false, true, PROFILE_STD, PRESET(LONG_FAST)), + RDEF(LORA_24, 2400.0f, 2483.5f, 100, 10, false, true, PROFILE_STD, PRESET(LONG_FAST), 0), /* EU 866MHz band (Band no. 46b of 2006/771/EC and subsequent amendments) for Non-specific short-range devices (SRD) Gives 4 channels at 865.7/866.3/866.9/867.5 MHz, 400 kHz gap plus 37.5 kHz padding between channels, 27 dBm, duty cycle 2.5% (mobile) or 10% (fixed) https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:02006D0771(01)-20250123 */ - RDEF(EU_866, 865.6f, 867.6f, 2.5, 27, false, false, PROFILE_LITE, PRESET(LITE_FAST)), + RDEF(EU_866, 865.6f, 867.6f, 2.5, 27, false, false, PROFILE_LITE, PRESET(LITE_FAST), 0), /* EU 868MHz band: 3 channels at 869.410/869.4625/869.577 MHz Channel centres at 869.442/869.525/869.608 MHz, 10.4 kHz padding on channels, 27 dBm, duty cycle 10% */ - RDEF(EU_N_868, 869.4f, 869.65f, 10, 27, false, false, PROFILE_NARROW, PRESET(NARROW_SLOW)), + RDEF(EU_N_868, 869.4f, 869.65f, 10, 27, false, false, PROFILE_NARROW, PRESET(NARROW_SLOW), 1), /* This needs to be last. Same as US. */ - RDEF(UNSET, 902.0f, 928.0f, 100, 30, false, false, PROFILE_UNDEF, PRESET(LONG_FAST)), + RDEF(UNSET, 902.0f, 928.0f, 100, 30, false, false, PROFILE_UNDEF, PRESET(LONG_FAST), 0), }; @@ -932,11 +933,11 @@ bool RadioInterface::checkOrClampConfigLora(meshtastic_Config_LoRaConfig &loraCo // overrideSlot: 0 = channel hash, -1 = preset hash, >0 = explicit slot uses_default_frequency_slot = (loraConfig.channel_num == 0) || // user choice unset, no frequency override, so use default - (newRegion->profile->overrideSlot > 0 && - loraConfig.channel_num == newRegion->profile->overrideSlot) || // user setting matches explicit override slot - ((newRegion->profile->overrideSlot == OVERRIDE_SLOT_DEFAULT_CHANNEL_HASH) && + (newRegion->overrideSlot > 0 && + loraConfig.channel_num == newRegion->overrideSlot) || // user setting matches explicit override slot + ((newRegion->overrideSlot == OVERRIDE_SLOT_DEFAULT_CHANNEL_HASH) && ((uint32_t)(loraConfig.channel_num - 1) == channelNameHashSlot)) || // user setting matches channel name hash - ((newRegion->profile->overrideSlot == OVERRIDE_SLOT_PRESET_HASH) && + ((newRegion->overrideSlot == OVERRIDE_SLOT_PRESET_HASH) && ((uint32_t)(loraConfig.channel_num - 1) == presetNameHashSlot)); // user setting matches preset name hash // check if user setting different to preset name @@ -952,12 +953,11 @@ bool RadioInterface::checkOrClampConfigLora(meshtastic_Config_LoRaConfig &loraCo if (clamp) { if (uses_custom_channel_name) { // clamp to channel name hash loraConfig.channel_num = - channelNameHashSlot + 1; // channel_num is 1-based, but hash slot is 0-based, so add 1 - } else if (newRegion->profile->overrideSlot > 0) { // clamp to explicit override slot - loraConfig.channel_num = - newRegion->profile->overrideSlot; // use the explicit override slot specified by the region profile + channelNameHashSlot + 1; // channel_num is 1-based, but hash slot is 0-based, so add 1 + } else if (newRegion->overrideSlot > 0) { // clamp to explicit override slot + loraConfig.channel_num = newRegion->overrideSlot; // use the explicit override slot defined for this region uses_default_frequency_slot = true; - } else if (newRegion->profile->overrideSlot == OVERRIDE_SLOT_PRESET_HASH && loraConfig.use_preset) { + } else if (newRegion->overrideSlot == OVERRIDE_SLOT_PRESET_HASH && loraConfig.use_preset) { // clamp to preset name hash loraConfig.channel_num = presetNameHashSlot + 1; // channel_num is 1-based, but hash slot is 0-based, so add 1 uses_default_frequency_slot = true; @@ -1076,9 +1076,9 @@ void RadioInterface::applyModemConfig() // NB: channel_num is also know as frequency slot but it's too late to fix now. if (uses_default_frequency_slot) { // Handle three override slot cases: explicit slot (>0), preset hash (-1), or channel hash (0) - if (newRegion->profile->overrideSlot > 0) { - channel_num = newRegion->profile->overrideSlot - 1; // explicit override slot (1-based to 0-based) - } else if (newRegion->profile->overrideSlot == OVERRIDE_SLOT_PRESET_HASH) { + if (newRegion->overrideSlot > 0) { + channel_num = newRegion->overrideSlot - 1; // explicit override slot (1-based to 0-based) + } else if (newRegion->overrideSlot == OVERRIDE_SLOT_PRESET_HASH) { channel_num = presetNameHashSlot; // use preset name hash } else { channel_num = channelNameHashSlot; // use channel name hash (default case) @@ -1111,9 +1111,9 @@ void RadioInterface::applyModemConfig() LOG_INFO("newRegion->freqStart -> newRegion->freqEnd: %f -> %f (%f MHz)", newRegion->freqStart, newRegion->freqEnd, newRegion->freqEnd - newRegion->freqStart); LOG_INFO("numFreqSlots: %u x %.3fkHz", numFreqSlots, bw); - if (newRegion->profile->overrideSlot > 0) { - LOG_INFO("Using region explicit override slot: %d", newRegion->profile->overrideSlot); - } else if (newRegion->profile->overrideSlot == OVERRIDE_SLOT_PRESET_HASH) { + if (newRegion->overrideSlot > 0) { + LOG_INFO("Using region explicit override slot: %d", newRegion->overrideSlot); + } else if (newRegion->overrideSlot == OVERRIDE_SLOT_PRESET_HASH) { LOG_INFO("Using region preset name hash for slot selection"); } LOG_INFO("channel_num: %d", channel_num + 1); diff --git a/test/test_admin_radio/test_main.cpp b/test/test_admin_radio/test_main.cpp index 5e383d396..e370f26b9 100644 --- a/test/test_admin_radio/test_main.cpp +++ b/test/test_admin_radio/test_main.cpp @@ -138,7 +138,6 @@ static const RegionProfile TEST_PROFILE_SPACED = { /* textThrottle */ 0, /* positionThrottle */ 0, /* telemetryThrottle */ 0, - /* overrideSlot */ 0, }; // A licensed-only profile for testing access control @@ -151,7 +150,6 @@ static const RegionProfile TEST_PROFILE_LICENSED = { /* textThrottle */ 5, /* positionThrottle */ 10, /* telemetryThrottle */ 10, - /* overrideSlot */ 3, }; // Turbo-only profile @@ -164,7 +162,6 @@ static const RegionProfile TEST_PROFILE_TURBO = { /* textThrottle */ 0, /* positionThrottle */ 0, /* telemetryThrottle */ 0, - /* overrideSlot */ 0, }; // A preset list for the preset-hash override slot test (LONG_FAST + MEDIUM_FAST) @@ -185,7 +182,6 @@ static const RegionProfile TEST_PROFILE_PRESET_HASH = { /* textThrottle */ 0, /* positionThrottle */ 0, /* telemetryThrottle */ 0, - /* overrideSlot */ OVERRIDE_SLOT_PRESET_HASH, }; // Standalone test region using US frequencies (26 MHz span → 104 slots at 250 kHz BW) @@ -200,25 +196,26 @@ static const RegionInfo TEST_REGION_PRESET_HASH = { false, &TEST_PROFILE_PRESET_HASH, meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST, + OVERRIDE_SLOT_PRESET_HASH, "TEST_PRESET_HASH", }; static const RegionInfo testRegions[] = { // A wide US-like region with spacing + padding {meshtastic_Config_LoRaConfig_RegionCode_US, 902.0f, 928.0f, 100, 30, false, false, &TEST_PROFILE_SPACED, - meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST, "TEST_US_SPACED"}, + meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST, 0, "TEST_US_SPACED"}, // A narrow band simulating tight EU regulation {meshtastic_Config_LoRaConfig_RegionCode_EU_868, 869.4f, 869.65f, 10, 14, false, false, &TEST_PROFILE_LICENSED, - meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW, "TEST_EU_LICENSED"}, + meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW, 3, "TEST_EU_LICENSED"}, // A wide-LoRa region with turbo-only presets {meshtastic_Config_LoRaConfig_RegionCode_LORA_24, 2400.0f, 2483.5f, 100, 10, false, true, &TEST_PROFILE_TURBO, - meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO, "TEST_LORA24_TURBO"}, + meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO, 0, "TEST_LORA24_TURBO"}, // Sentinel — must be last {meshtastic_Config_LoRaConfig_RegionCode_UNSET, 902.0f, 928.0f, 100, 30, false, false, &TEST_PROFILE_SPACED, - meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST, "TEST_UNSET"}, + meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST, 0, "TEST_UNSET"}, }; static const RegionInfo *getTestRegion(meshtastic_Config_LoRaConfig_RegionCode code) @@ -256,7 +253,7 @@ static void test_shadowTable_licensedProfileFlagsCorrect() const RegionInfo *r = getTestRegion(meshtastic_Config_LoRaConfig_RegionCode_EU_868); TEST_ASSERT_TRUE(r->profile->licensedOnly); TEST_ASSERT_FALSE(r->profile->audioPermitted); - TEST_ASSERT_EQUAL(3, r->profile->overrideSlot); + TEST_ASSERT_EQUAL(3, r->overrideSlot); } static void test_shadowTable_presetCountMatchesExpected() @@ -319,8 +316,8 @@ static void test_shadowTable_unknownCodeFallsToSentinel() static void test_shadowTable_presetHashProfileHasCorrectOverrideSlot() { - TEST_ASSERT_EQUAL(OVERRIDE_SLOT_PRESET_HASH, TEST_PROFILE_PRESET_HASH.overrideSlot); - TEST_ASSERT_EQUAL(-1, TEST_PROFILE_PRESET_HASH.overrideSlot); + TEST_ASSERT_EQUAL(OVERRIDE_SLOT_PRESET_HASH, TEST_REGION_PRESET_HASH.overrideSlot); + TEST_ASSERT_EQUAL(-1, TEST_REGION_PRESET_HASH.overrideSlot); TEST_ASSERT_EQUAL(2, TEST_REGION_PRESET_HASH.getNumPresets()); }