From d58311ce3c246086a47ba1f5e8618e8082f645e1 Mon Sep 17 00:00:00 2001 From: "Valentin V. Bartenev" Date: Sun, 7 Jun 2026 14:51:02 +0300 Subject: [PATCH] Revert on-disk layout to the one before 1.16.0 merge When "flood_max_unscoped" and "flood_max_advert" were inserted at offsets 291-292 in a previous commit, they displaced "fan_mode" and "fan_timeout_secs" from their established positions. On upgrade, devices with existing saved prefs would load the old "fan_mode" byte (0, 1, or 2) into "flood_max_unscoped" and the low byte of "fan_timeout_secs" into "flood_max_advert", both yielding values of 0 or 1. A "flood_max_unscoped" or "flood_max_advert" of 0 or 1 effectively silences the repeater, causing it to drop nearly all unscoped flood and advert packets. Additionally, "rx_boosted_gain" was displaced to offset 291 in the new layout, causing it to read 0 (gain disabled) on devices whose prefs were saved before the layout change. Restore a correct, upgrade-safe layout: 290: reserved_290 (placeholder; preserves the byte that held rx_boosted_gain in the layout before this series) 291: rx_boosted_gain 292: fan_mode 293-294: fan_timeout_secs (uint16_t) 295: flood_max_unscoped 296: flood_max_advert "flood_max_unscoped" and "flood_max_advert" are moved to the end so that existing saved prefs with "fan_mode"/"fan_timeout_secs" at 291-294 are read correctly on upgrade, and the repeater resumes normal flood forwarding behaviour. Also fix a copy-paste bug in loadPrefsInt where the availability checks for "flood_max_unscoped" and "flood_max_advert" both used sizeof(rx_boosted_gain) instead of their own field sizes. --- src/helpers/CommonCLI.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index add08149..baa5f6a1 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -88,22 +88,25 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 - if (file.available() >= (int)sizeof(_prefs->rx_boosted_gain)) { - file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290 + if (file.available() >= (int)sizeof(_prefs->reserved_290)) { + file.read((uint8_t *)&_prefs->reserved_290, sizeof(_prefs->reserved_290)); // 290 reserved } if (file.available() >= (int)sizeof(_prefs->rx_boosted_gain)) { - file.read((uint8_t *)&_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 291 - } - if (file.available() >= (int)sizeof(_prefs->rx_boosted_gain)) { - file.read((uint8_t *)&_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 292 + file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 291 } if (file.available() >= (int)sizeof(_prefs->fan_mode)) { - file.read((uint8_t *)&_prefs->fan_mode, sizeof(_prefs->fan_mode)); // 293 + file.read((uint8_t *)&_prefs->fan_mode, sizeof(_prefs->fan_mode)); // 292 } if (file.available() >= (int)sizeof(_prefs->fan_timeout_secs)) { - file.read((uint8_t *)&_prefs->fan_timeout_secs, sizeof(_prefs->fan_timeout_secs)); // 294 + file.read((uint8_t *)&_prefs->fan_timeout_secs, sizeof(_prefs->fan_timeout_secs)); // 293 } - // next: 296 + if (file.available() >= (int)sizeof(_prefs->flood_max_unscoped)) { + file.read((uint8_t *)&_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 295 + } + if (file.available() >= (int)sizeof(_prefs->flood_max_advert)) { + file.read((uint8_t *)&_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 296 + } + // next: 297 // sanitise bad pref values _prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); @@ -195,12 +198,13 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 - file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290 - file.write((uint8_t *)&_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 291 - file.write((uint8_t *)&_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 292 - file.write((uint8_t *)&_prefs->fan_mode, sizeof(_prefs->fan_mode)); // 293 - file.write((uint8_t *)&_prefs->fan_timeout_secs, sizeof(_prefs->fan_timeout_secs)); // 294 - // next: 296 + file.write((uint8_t *)&_prefs->reserved_290, sizeof(_prefs->reserved_290)); // 290 reserved + file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 291 + file.write((uint8_t *)&_prefs->fan_mode, sizeof(_prefs->fan_mode)); // 292 + file.write((uint8_t *)&_prefs->fan_timeout_secs, sizeof(_prefs->fan_timeout_secs)); // 293 + file.write((uint8_t *)&_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 295 + file.write((uint8_t *)&_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 296 + // next: 297 file.close(); }