mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-10-09 19:26:40 +00:00
fix(radio): disable Pwr save (RX duty-cycle) — unsafe across mixed firmware
Field report: a user on the stock SF8 "EU/UK (Narrow)" preset saw reception drop from ~1-5 msg/min to ~1/3h with Pwr save on, unaffected by a better antenna. Root cause, confirmed against the SX1262 datasheet and RadioLib's own maintainers (jgromes/RadioLib#1597, closed as inherent chip behaviour): the SX126x's duty-cycle preamble detection needs the sender's actual preamble to closely match what we've configured our receiver to expect. A mismatch — e.g. a repeater still on pre-v1.16 firmware sending 16 symbols against our 32 — doesn't cost a little sensitivity, it silently drops every packet from that sender regardless of signal strength. There's no local parameter fix: shortening minSymbols to tolerate shorter preambles directly shortens the wake-window's correlator dwell time, trading the preamble mismatch failure mode for a marginal-signal one instead. Checked whether IoTThinks' MeshCore fork solved this differently — it doesn't hit the problem at all, because its "power saving" only light-sleeps the MCU on the radio's own GPIO interrupt and never touches RX duty-cycle. examples/companion_radio/MyMesh.h now defines FEAT_RX_POWERSAVE 0, gating out the Settings row, the Diagnostics RXPS watchdog row, and every call site that would apply rx_powersave to the radio or CAD auto-enable — including forcing setPowerSaving(false) unconditionally so a stale rx_powersave=1 byte from before this change can't do anything either. The real duty-cycle implementation in RadioLibWrapper/CustomSX1262Wrapper is left in place, unneutered, for if a network-wide compatibility mechanism (e.g. the still-unused ADV_FEAT1/FEAT2 advert bits) is ever built to make it safe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -287,7 +287,14 @@ bool MyMesh::getCADEnabled() const {
|
||||
// _prefs.cad_enabled itself has no UI/CLI exposure yet on companion_radio
|
||||
// (unlike simple_repeater's CommonCLI `cad` command) — it's wired and
|
||||
// persisted for a future manual override, but always 0 today.
|
||||
// rx_powersave is never actually applied to the radio while FEAT_RX_POWERSAVE
|
||||
// is 0 (see MyMesh.h) -- don't let a stale persisted byte from before that
|
||||
// still auto-enable CAD here for a duty-cycle mode that isn't running.
|
||||
#if FEAT_RX_POWERSAVE
|
||||
return _prefs.cad_enabled || (_prefs.rx_powersave && !_prefs.client_repeat);
|
||||
#else
|
||||
return _prefs.cad_enabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
int MyMesh::calcRxDelay(float score, uint32_t air_time) const {
|
||||
@@ -1991,7 +1998,11 @@ void MyMesh::begin(bool has_display) {
|
||||
applyRepeaterRadio(); // companion params, or the repeater profile if relaying with one set
|
||||
applyApc(); // sets TX power to the ceiling and arms APC if enabled
|
||||
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
||||
#if FEAT_RX_POWERSAVE
|
||||
radio_driver.setPowerSaving(_prefs.rx_powersave && !_prefs.client_repeat); // duty-cycle RX off while repeating (must hear all traffic)
|
||||
#else
|
||||
radio_driver.setPowerSaving(false); // see MyMesh.h FEAT_RX_POWERSAVE -- ignore any stale persisted rx_powersave byte
|
||||
#endif
|
||||
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
|
||||
board.setLoRaFemPaGainEnabled(_prefs.radio_fem_txgain);
|
||||
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
||||
@@ -2482,7 +2493,11 @@ void MyMesh::handleCmdFrame(size_t len) {
|
||||
// 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).
|
||||
#if FEAT_RX_POWERSAVE
|
||||
radio_driver.setPowerSaving(_prefs.rx_powersave && !_prefs.client_repeat);
|
||||
#else
|
||||
radio_driver.setPowerSaving(false); // see MyMesh.h FEAT_RX_POWERSAVE -- ignore any stale persisted rx_powersave byte
|
||||
#endif
|
||||
applyApc(); // pins power to the ceiling; apcActive() keeps it there while repeating
|
||||
MESH_DEBUG_PRINTLN("OK: CMD_SET_RADIO_PARAMS: f=%d, bw=%d, sf=%d, cr=%d", freq, bw, (uint32_t)sf,
|
||||
(uint32_t)cr);
|
||||
|
||||
Reference in New Issue
Block a user