Fixes and features from upstream: MACThenDecrypt / command buffer
overflow fixes, ACK forwarding delay, transport code 0 as unscoped,
hidden nodes don't answer DISCOVER, LR2021/LR1121 fixes, GPS cold-start
detection and waitFor()/drain(), NMEA fix-age counters, ESP32 RTC after a
crash, remote CLI by text message (TXT_TYPE_CLI_COMMAND),
PUSH_CODE_BINARY_RESPONSE, board.loop(), new boards (Wio Tracker L1 1W,
ThinkNode M4/M8, Muzi Base, Waveshare LR1121, Pico W).
Kept ours: NodePrefs, main.cpp, every UI, GxEPDDisplay. The companion CLI
stays MyMeshCli.h's handleCliCommand(); upstream's handleCommand() calls
it. The board's FEM gains go through attachDynamicPrefs() with an adapter
over our NodePrefs fields. Upstream's JSON prefs and MultiSerialInterface
come as their own stages.
Also: the display defaults were inside RADIO_FEM_TXGAIN's #else (a
missing #endif).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gat562_30s_mesh_kit has an always-on external PA rated at +30dBm, but the
firmware wrote tx_power_dbm straight to the SX1262 register (capped at 22),
so the app/CLI/UI never matched the real radiated power and couldn't ask
for more than 22 even though the hardware supports it.
Add a generic, macro-gated PA gain-curve resolution in
RadioLibWrapper::setTxPower() (the single choke point every TX-power path
already funnels through), reusable by any future board with a similar PA.
For this board, reuse the vendor-measured 869MHz curve from the open
upstream Meshtastic PR that added it for the same physical module
(meshtastic/firmware#11212): pick the lowest SX1262 setting whose measured
output reaches the requested dBm, clamped at the PA's saturation knee.
Bump LORA_TX_POWER/MAX_LORA_TX_POWER to 30 for this variant only -- the
other three GAT562 boards use the SX1262's own PA_BOOST (22dBm, no
external PA) and are unaffected.
Since a request below the PA's floor gain (14dBm) still radiates at that
floor, also make CommonCLICallbacks::setTxPower() return what was actually
applied, and have every setter (BLE CMD_SET_RADIO_TX_POWER, CLI "tx",
simple_repeater/room_server/sensor) persist and report that value instead
of the raw request -- so tx_power_dbm never silently disagrees with the
physical output in either direction.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The serial command buffers must stay NUL-terminated within their
bounds: if they ever aren't, strlen() can return >= sizeof(command)
and the read loop would index past the buffer. Additionally, a full
buffer now becomes a completed line (end-of-line marker placed
inside the buffer, NUL terminator kept) instead of overwriting the
terminator and silently corrupting the buffer for the next pass.
Applies to the serial CLI readers of the repeater, room server,
sensor and secure chat examples, and to the CLI rescue reader of
the companion example.
Mirrors the simple_repeater sim port exactly: headless (no DISPLAY_CLASS,
UITask.cpp excluded from the build), new sim_simple_room_server native env
plus build_wasm_room_server.sh, own SimFS root ./sim_data_room so its
identity storage can't collide with the companion or repeater instances on
the same page/cwd.
Verified beyond "it compiles": ran the native binary and confirmed a real
_main.id identity file gets persisted through the actual SimFS/IdentityStore
path, same as the other two sim targets.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adopts hardware Channel Activity Detection (wired into
RadioLibWrapper::isChannelActive() alongside our RSSI-threshold check
and RX duty-cycle power-save), MCU temperature telemetry, LR2021
standby workaround, DISPLAY_SCALE/FLIP overrides, NRF52Board
shutdownPeripherals() refactor, and misc upstream fixes.
Declines upstream's ConfigSerializer-based NodePrefs rewrite,
MultiSerialInterface/interface_manager, and UIColor palette system —
each would have broken large parts of the Solo-specific feature set
(NodePrefs fields, per-variant single serial_interface, enum-based
DisplayDriver::Color). Flagged as candidate follow-up migrations, not
permanent no's.
Also fixes several pre-existing bugs surfaced while chasing silent
merge breaks (stale newMsg() override signature in ui-tiny/ui-orig,
dead UIEventType::newContactMessage case, missing ContactsIterator
init), bumps FIRMWARE_VERSION/MESHCORE_VERSION to 1.17, and fixes a
missing <cstdlib> include that broke the native ConfigSerializer unit
tests.
Verified via 13+ pio run builds across ESP32/nRF52, all 3 companion UI
variants, and 7 display drivers, plus the full native unit test suite
(33/33 passing).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The room server never supported RX boosted gain, while the repeater
does. Three consequences on SX1262/SX1268 boards:
- boosted gain was never applied to the radio at boot, so a room server
ran in power-saving RX mode while an identical repeater ran boosted -
a real receive-sensitivity difference with nothing pointing at it
- _prefs.rx_boosted_gain was never initialised (the prefs are memset to
0 before defaults are set), so it defaulted to off
- 'set radio.rxgain on' replied "Error: unsupported" but CommonCLI had
already written the value to prefs and saved them, so a stale setting
survived reboot and was never applied
Mirror the repeater's implementation: initialise the pref default under
the same USE_SX1262/USE_SX1268 and SX126X_RX_BOOSTED_GAIN guards, apply
it during radio init, and override setRxBoostedGain() so the CLI reports
success and takes effect.
Built Heltec_v3_room_server (SX1262) and LilyGo_T3S3_sx1276_room_server
(guards compile out cleanly).
The `recv_pkt_region` is set when processing a flood packet in `filterRecvFloodPacket`
but direct/non-flood packets would never pass through that function, so the pointer was
not cleared for them.
`sendFloodReply` would then later use it blindly, which meant that the response would
either inherit the region from the last flood packet, or refer to a non-initialised pointer
if no region floods had been received yet.
Before this commit, there was no way to set a different max hop count
for unscoped messages.
Now with this change, by defaul it tracks the flood.max setting, until
a user provides a flood.max.unscoped value, which tax precidence for
packets if ROUTE_TYPE_FLOOD is true.
Framework for upcoming variant-specific PRs that add LED feedback during boot. The hook gives users visual cues that the device is busy and
shouldn't be interacted with until startup completes.