feat(repeater): suppress Adaptive Power Control while relaying

A repeater wants full, consistent TX power for relay reach, and APC's feedback
(own ACKs / own flood echoes) never fires on forwarded traffic — so leaving APC
on would relay at whatever reduced power it last trimmed to, or sit inert on a
dedicated repeater network. Force it off whenever client_repeat is on, mirroring
the power-save lock:

- apcActive() = tx_apc && !client_repeat gates every APC control site
  (sample/failure/track).
- applyApc() pins power to the tx_power_dbm ceiling; called at boot, on the
  on-device repeater toggle, and on the app's CMD_SET_RADIO_PARAMS.
- Settings "Auto pwr" shows "--" and blocks the toggle while repeating; the
  user's pref is preserved and restored when the repeater is switched off.

Also refreshes the FEATURES repeater entry (Hold-Enter reset, Errors row, schema
0x10, the radio-setting locks and status indicator).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-06-19 14:45:34 +02:00
co-authored by Claude Sonnet 4.6
parent 84a76adcf1
commit 885662beae
7 changed files with 36 additions and 16 deletions
+5
View File
@@ -156,6 +156,11 @@ protected:
// Overhear suppression only makes sense while repeating; gated behind its own
// opt-in pref (Settings > Radio > Suppress dup).
bool wantsOverhearSuppress() const override { return _prefs.client_repeat && _prefs.repeat_suppress_dup; }
// Adaptive Power Control is suppressed while repeating: a repeater wants full,
// consistent TX power for relay reach, and its feedback sources (own ACKs /
// own flood echoes) don't fire on forwarded traffic anyway. applyApc() then
// pins power to the ceiling.
bool apcActive() const { return _prefs.tx_apc && !_prefs.client_repeat; }
void sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint32_t delay_millis);
void sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis=0) override;