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
+15 -6
View File
@@ -485,12 +485,21 @@ Tracker L1 OLED/e-ink, GAT562 30S). All on `feature/companion-repeater-presets`.
RX/TX counters (generic `Dispatcher::n_recv_by_type`/`n_sent_by_type`), uptime,
heap + stack (new `DeviceDiag` helper, nRF52 linker-symbol/`sbrk` heap +
FreeRTOS stack high-water), noise floor, RSSI/SNR, pool free, outbound queue,
and **Forwarded** (`Mesh::n_forwarded` — actual retransmits; backed out on
overhear cancel so it reflects what hits the air). Enter opens a confirm popup
to reset the cumulative counters (`resetStats` made virtual; `Mesh` override
also clears `n_forwarded`).
- Prefs persisted behind schema sentinels `0xC0DE000E` (four knobs) then
`0xC0DE000F` (suppress-dup), with stray-byte clamps for upgraders.
**Forwarded** (`Mesh::n_forwarded` — actual retransmits; backed out on overhear
cancel so it reflects what hits the air), and **Errors** (Dispatcher
`ERR_EVENT_*` flags decoded to F/C/R). Hold Enter opens a one-item "Reset
counters" menu (Back dismisses) — `resetStats` made virtual; `Mesh` override
also clears `n_forwarded`.
- **Radio settings locked while relaying** — a repeater must hear all traffic and
relay at consistent power, so duty-cycle RX ("Pwr save") and APC ("Auto pwr")
are forced off whenever `client_repeat` is on (effective `pref && !client_repeat`
via `applyPowerSave()` / `apcActive()`), applied at boot, on the on-device
toggle, and on the app's `CMD_SET_RADIO_PARAMS`; Settings shows `--` and blocks
the toggle, preserving the user's pref for when the repeater goes off. A
blinking `»` status-bar indicator (`ICON_REPEATER`) shows relaying at a glance.
- Prefs persisted behind schema sentinels `0xC0DE000E` (four knobs),
`0xC0DE000F` (suppress-dup), `0xC0DE0010` (radio profile), with stray-byte
clamps for upgraders.
- **Open question:** the app-side dedicated-band gate in `CMD_SET_RADIO_PARAMS`
was commented out (not deleted) to match the on-device toggle's any-frequency
behaviour — undecided whether that gate was UX-only or regulatory.