fix(repeater): close radio-profile bypass paths, dedupe preset/BW logic

CMD_SET_RADIO_PARAMS and the on-device Settings radio editors
(Freq/SF/BW/CR/Preset) called radio_driver.setParams() directly instead
of applyRepeaterRadio(), so editing the companion's own radio params
while relaying on a dedicated profile silently retuned the live radio
off that profile. Both now route through applyRepeaterRadio(), the
single decision point already used at boot and by the on-device
repeater toggle.

Also: overhear-suppression matched queued packets by payload hash
alone, so it could cancel a queued direct-route retransmit that
happened to share a hash with an overheard flood packet — now scoped
to flood-queued entries only. repeaterProfileValid()'s frequency floor
(100 MHz) is raised to 150 MHz to match the radio's actual validated
range. RepeaterScreen's preset-name lookup now uses the same
epsilon-tolerant float comparison as Settings instead of exact ==,
avoiding inconsistent "Custom" labeling between the two screens.

Dedupe: the BW-options table, the value-column x-offset math, and the
default-profile-seeding block had each drifted into two or three
independent copies (RepeaterScreen vs Settings, MyMesh constructor vs
DataStore.cpp upgrade path); factored into shared helpers in
RadioPresets.h / NodePrefs.h.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-06-20 01:50:21 +02:00
co-authored by Claude Sonnet 4.6
parent afe7b8a0ca
commit 4999620fba
9 changed files with 63 additions and 50 deletions
+3 -7
View File
@@ -1309,12 +1309,8 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
_prefs.tx_power_dbm = LORA_TX_POWER;
// Repeater profile default for a true first boot (no prefs file yet, so
// loadPrefs() below is a no-op) — same band-matched seed as the upgrade
// path in DataStore.cpp, kept in sync rather than left at memset's 0/Current.
_prefs.repeater_use_profile = 1;
_prefs.repeater_freq = defaultRepeaterFreqForBand(_prefs.freq);
_prefs.repeater_bw = LORA_BW;
_prefs.repeater_sf = LORA_SF;
_prefs.repeater_cr = LORA_CR;
// path in DataStore.cpp.
seedDefaultRepeaterProfile(_prefs);
_prefs.gps_enabled = 0; // GPS disabled by default
_prefs.gps_interval = 0; // No automatic GPS updates by default
_prefs.display_brightness = 2; // medium brightness by default
@@ -1868,7 +1864,7 @@ void MyMesh::handleCmdFrame(size_t len) {
_prefs.client_repeat = repeat;
savePrefs();
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
applyRepeaterRadio(); // companion params, or the repeater profile if relaying with one set
// Keep the "repeating ⇒ continuous RX, full TX power" invariants when repeat
// is toggled via the app, mirroring the on-device path (a repeater must hear
// all traffic and relay at consistent power).