Skip to content

Expose companion repeat mode and stop radio-parameter updates clearing it - #363

Open
garrett-livefront wants to merge 2 commits into
jkingsman:mainfrom
garrett-livefront:feat/companion-repeat-toggle
Open

garrett-livefront wants to merge 2 commits into
jkingsman:mainfrom
garrett-livefront:feat/companion-repeat-toggle

Conversation

@garrett-livefront

@garrett-livefront garrett-livefront commented Sep 23, 2026 •

Copy link
Copy Markdown

Fixes #362.

The problem

MeshCore companions carry a "repeat" flag (the repeater-mode checkbox in the official app). The firmware sets it from the trailing byte of CMD_SET_RADIO_PARAMS and treats a missing byte as repeat = 0, then persists it. apply_radio_config_update called set_radio(freq, bw, sf, cr) without that byte, so every frequency / bandwidth / SF / CR change made through RemoteTerm silently turned repeat mode off on a node that had it enabled. There was also no way to see or set the flag from RemoteTerm.

The change

Two commits: backend + tests, then frontend + tests.

Backend

  • RadioManager caches repeat_enabled, repeat_supported and allowed_repeat_freqs alongside the other device-query fields. They're read from the DEVICE_INFO reply (payload["repeat"], fw ver ≥ 9; raw-frame fallback at byte 80), and the allowed list from get_allowed_repeat_freq() in the same connect-time pass. A failed allowed-frequency query logs at debug and leaves the list empty; it never blocks connect.
  • GET /api/radio/config returns repeat_enabled, repeat_supported and allowed_repeat_freqs (min/max MHz ranges). PATCH accepts repeat_enabled.
  • apply_radio_config_update now always passes repeat= to set_radio when the firmware supports it: the requested value if given, otherwise the node's current value. This is the bug fix, and it applies to existing users who never touch the new checkbox. A repeat-only PATCH reuses the current freq/bw/sf/cr from self_info.
  • The set_radio result is now checked. A firmware ERR (e.g. repeat requested on a frequency outside the compiled-in allowed list) becomes a 422 that quotes the node's own allowed list: Firmware rejected the radio settings (ERR_CODE_ILLEGAL_ARG). Repeat mode is only allowed on: 918.000 MHz. Sending repeat_enabled to firmware that doesn't report repeat returns 400, mirroring path_hash_mode.
  • No new dependency; meshcore 2.3.7 already has set_radio(..., repeat=), the repeat parse, and get_allowed_repeat_freq().

Frontend

  • "Repeater Mode" checkbox at the end of the Radio Parameters section, shown only when repeat_supported, with one line of help text. Diffed into the PATCH only when changed; included in config export/import like the other flags.
  • A Compatibility Warning box (same style as the Path Hash Mode one) lists the firmware's allowed repeat frequencies and notes the list is compiled into the firmware and can't be changed from RemoteTerm.
  • The checkbox is disabled when it's unticked and the entered frequency is outside every allowed range, so repeat can't be enabled somewhere the firmware will reject. It can always be unticked. If repeat is already on and the frequency is moved off-list, saving fails loudly with the 422 above rather than silently dropping repeat; that's deliberate.

Docs: the /radio/config rows in AGENTS.md, app/AGENTS.md and frontend/AGENTS.md are updated.

New radio setting UI
image

Error upon attempting to save radio settings with repeater mode enabled for an unsupported frequency
image

Testing

  • ./scripts/quality/all_quality.sh green (pyright 0 errors, pytest + vitest passing, frontend build).
  • New unit tests: repeat preserved on a param-only update; repeat-only update reuses self_info params; ERR → 422 quoting the cached allowed list; unsupported-firmware → 400; allowed list cached from payload and empty on ERR; checkbox shown/hidden, gated by entered frequency, always un-tickable.
  • Hardware: tested over TCP against a companion on firmware v1.16.0 (companion protocol 13) whose build allows repeat only on 910.525 MHz. Confirmed: checkbox reflects the node; changing SF with repeat on keeps repeat on (previously cleared it, verified via DEVICE_QUERY byte 80); allowed list renders; off-list frequency with repeat on returns the 422 and leaves the radio unchanged; unticking at an off-list frequency saves the frequency change with repeat off.

Notes for the maintainer

Written with AI assistance per CONTRIBUTING.md; every change was reviewed and hardware-tested by me. AGENTS.md says agents never commit — the two commits here were produced by an agent on my fork and reviewed by me before opening this. Happy to squash or re-author if you'd prefer.

garrett-livefront and others added 2 commits September 23, 2026 12:38
…ring it

Firmware CMD_SET_RADIO_PARAMS persists repeat=0 when the trailing repeat
byte is absent, so every freq/bw/sf/cr change silently turned repeat mode
off. Cache the repeat flag from DEVICE_INFO (fw ver >= 9), resend it on
every set_radio, and expose it as repeat_enabled / repeat_supported on
/api/radio/config. A repeat-only PATCH reuses the current radio params.

Also query the firmware's compiled-in allowed repeat frequencies at
connect (best-effort) and expose them as allowed_repeat_freqs.
set_radio results are now checked; a firmware ERR returns 422, quoting
the node's allowed frequencies when known.

Refs: jkingsman#362

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Show a "Repeater Mode" checkbox in the Radio Parameters section when the
firmware reports repeat_supported, send repeat_enabled only when it
changes, and carry it through config export/import. When the node
reports its allowed repeat frequencies, list them in a compatibility
warning and disable the checkbox while the entered frequency is outside
them.

Refs: jkingsman#362

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Radio-parameter updates silently disable companion repeat mode (no way to see or set it)

1 participant