Regioninfo (#11056)

* advertise a superset of EU regional presets to client devices.

* trunk
This commit is contained in:
Tom
2026-07-19 06:22:39 -05:00
committed by GitHub
co-authored by GitHub
parent a4ea55f919
commit b8b5582943
3 changed files with 79 additions and 29 deletions
+36 -16
View File
@@ -55,6 +55,34 @@ static const meshtastic_Config_LoRaConfig_ModemPreset PRESETS_NARROW[] = {PRESET
static const meshtastic_Config_LoRaConfig_ModemPreset PRESETS_TINY[] = {PRESET(TINY_FAST), PRESET(TINY_SLOW), MODEM_PRESET_END};
// The EU_868/EU_866/EU_N_868 trio share the 868 band but own mutually exclusive preset
// profiles. Selecting a preset locked to a sibling swaps the region to that sibling (see
// regionSwapForPreset), so from any region in the trio every one of these presets is
// selectable. This union is what we advertise to clients as the trio's legal list. It is a
// display-only superset: on-device enforcement still uses each region's own disjoint
// profile->presets, so this must never be assigned to a RegionProfile (that would make
// supportsPreset() accept the preset in place and defeat the swap). Keep in sync with the
// EU_868/EU_866/EU_N_868 profile lists below. Sized to the 11-preset wire cap.
static const meshtastic_Config_LoRaConfig_ModemPreset PRESETS_EU_SUPERSET[] = {
PRESET(LONG_FAST), PRESET(LONG_SLOW), PRESET(MEDIUM_SLOW), PRESET(MEDIUM_FAST), PRESET(SHORT_SLOW), PRESET(SHORT_FAST),
PRESET(LONG_MODERATE), PRESET(LITE_FAST), PRESET(LITE_SLOW), PRESET(NARROW_FAST), PRESET(NARROW_SLOW), MODEM_PRESET_END};
// The EU_868/EU_866/EU_N_868 trio own mutually exclusive preset lists. Selecting a preset
// locked to a sibling means the user wants that sibling region, not the default preset.
static const meshtastic_Config_LoRaConfig_RegionCode SWAPPABLE_EU_REGIONS[] = {
meshtastic_Config_LoRaConfig_RegionCode_EU_868,
meshtastic_Config_LoRaConfig_RegionCode_EU_866,
meshtastic_Config_LoRaConfig_RegionCode_EU_N_868,
};
static bool isSwappableEuRegion(meshtastic_Config_LoRaConfig_RegionCode code)
{
for (auto c : SWAPPABLE_EU_REGIONS)
if (c == code)
return true;
return false;
}
// Region profiles: bundle preset list + regulatory parameters shared across regions
// presets, spacing, padding, audio, licensed, text throttle, position throttle, telemetry throttle
const RegionProfile PROFILE_STD = {PRESETS_STD, 0, 0, true, false, 0, 1, 1};
@@ -687,8 +715,13 @@ void getRegionPresetMap(meshtastic_LoRaRegionPresetMap &map)
grp.default_preset = r->getDefaultPreset();
grp.licensed_only = r->profile->licensedOnly;
grp.presets_count = 0;
for (size_t i = 0; r->profile->presets[i] != MODEM_PRESET_END && grp.presets_count < maxPresets; i++)
grp.presets[grp.presets_count++] = r->profile->presets[i];
// EU 86x siblings advertise the trio's superset - any of those presets is
// reachable from here via an automatic region swap. Every other region
// advertises exactly its own enforced profile list.
const meshtastic_Config_LoRaConfig_ModemPreset *advertised =
isSwappableEuRegion(r->code) ? PRESETS_EU_SUPERSET : r->profile->presets;
for (size_t i = 0; advertised[i] != MODEM_PRESET_END && grp.presets_count < maxPresets; i++)
grp.presets[grp.presets_count++] = advertised[i];
}
// Map this region to its group (capacity checked at the top of the loop).
@@ -963,14 +996,6 @@ static void sendErrorNotification(const char *msg, meshtastic_LogRecord_Level le
service->sendClientNotification(cn);
}
// The EU_868/EU_866/EU_N_868 trio own mutually exclusive preset lists. Selecting a preset
// locked to a sibling means the user wants that sibling region, not the default preset.
static const meshtastic_Config_LoRaConfig_RegionCode SWAPPABLE_EU_REGIONS[] = {
meshtastic_Config_LoRaConfig_RegionCode_EU_868,
meshtastic_Config_LoRaConfig_RegionCode_EU_866,
meshtastic_Config_LoRaConfig_RegionCode_EU_N_868,
};
/**
* If currentRegion is one of the swappable EU regions and preset belongs to a sibling in
* that trio, return the sibling region that owns the preset. Returns nullptr otherwise.
@@ -978,12 +1003,7 @@ static const meshtastic_Config_LoRaConfig_RegionCode SWAPPABLE_EU_REGIONS[] = {
const RegionInfo *RadioInterface::regionSwapForPreset(meshtastic_Config_LoRaConfig_RegionCode currentRegion,
meshtastic_Config_LoRaConfig_ModemPreset preset)
{
bool currentIsSwappable = false;
for (auto code : SWAPPABLE_EU_REGIONS) {
if (code == currentRegion)
currentIsSwappable = true;
}
if (!currentIsSwappable)
if (!isSwappableEuRegion(currentRegion))
return nullptr;
for (auto code : SWAPPABLE_EU_REGIONS) {