Commit Graph
1945 Commits
Author SHA1 Message Date
mikecarper 1ad5423d7a Merge radio presets and Cardputer improvements from PR #28 2026-10-31 00:01:28 -07:00
mjgodatandClaude Opus 5.5 d10cc5658e Merge upstream keymindCascade (radio2 MQTT/USB log tagging, PR #27) into radio presets
Only test/fixtures/cli_reply_text.json conflicted; messages and profiles
identical, source token hashes regenerated for the merged sources.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:58:39 -07:00
mikecarper e8b2e3eee8 Keep contact safety checks within the Full Companion flash budget
Share contact scans and use the display driver shutdown hook for every panel. Preserve contact ordering, empty-key rejection, replay checks and all firmware features.
2026-10-30 18:05:49 -07:00
mikecarper 49d70fe0c6 Merge upstream dev fixes
Keep our radio transactions, notification defaults, display settings and pinned RadioLib release. Integrate contact and sensor safety fixes, saturated statistics and compatible board/display updates.
2026-10-30 17:43:40 -07:00
mikecarper 322e22a069 Merge pull request #27: tag radio2 traffic in MQTT and USB logs
Resolve the source fixture against the current branch, keep compact room logging unchanged, and run the new regressions in CI.
2026-10-30 17:19:01 -07:00
Claude 619c98d5a6 USB packet log: print the sent frame and radio2 marker ahead of TX lines
A TX line had no RAW of its own, so meshcoretomqtt published each
transmission with the last frame it had received, and a serial observer's
own radio2 transmissions never showed. The repeater and room server now
print the frame as sent (RAW), and RADIO: radio2 when it goes out on radio2,
just before the dispatcher's TX line, as they already do for RX.

The dispatcher calls mesh::usbLogTxFrame, a weak function only those two
roles define; Companion builds keep it undefined and pay a null test. RX/TX
lines and compact logging are unchanged.

Test: test_usb_log_radio2.py compiles both roles' real hook and runs the
lines through meshcoretomqtt's parsing: the TX now carries the sent frame,
tagged radio2 only when sent on radio2. cli_reply_text.json re-pinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011i5tJJtj95MB4oUgncCUe5
2026-10-30 11:45:17 -07:00
mjgodatandClaude Opus 5.5 d3ed59d485 Merge upstream keymindCascade (OTA relay/ACL updates) into radio presets
Only test/fixtures/cli_reply_text.json conflicted; messages and profiles
were identical, source token hashes regenerated for the merged sources.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:28:30 -07:00
mjgodatandClaude Opus 5.5 218359e9da feat(presets): lazy preset storage for RAM-tight images
MESH_RADIO_PRESETS_RESIDENT (default 1) selects where the preset table
lives. With 0, every preset command, loadSlot(), activeSlot() and table()
read /presets into a stack-local table, work on it, save and drop it.
Only the pending-revert mirror (slot, previous tuple), the countdown and
the timebase stay resident: RadioPresetCLI is 32 B on 32-bit targets
(static_assert <= 40 B) instead of ~220 B. Unrelated CLI lines never
touch /presets and plain reads never write flash.

Hooks are now a static function table plus a context pointer passed to
begin(), so the object keeps one pointer instead of seven. Replies,
revert/commit/retry and boot-revert behave the same in both modes; the
host tests run every harness in both modes and add read-only, unrelated
command and failed-seed-save cases. cli_reply_text hashes refreshed for
the begin() call sites.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 00:09:59 -07:00
mjgodatandClaude Opus 5.5 174b46c01e fix(presets): keep the STM32 image at its upstream size
isTempRadioActive() on CommonCLICallbacks is only needed by OTA and by
radio presets, so declare it under ENABLE_OTA || MESH_ENABLE_RADIO_PRESETS
again (no vtable slot or override thunk otherwise). The repeater's
login_full_admin flag is also preset-only. wio-e5-mini_repeater now links
byte-for-byte the same size as upstream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 17:38:00 -07:00
mikecarper 50db7d483e Unblock OTA login after its return path is sent 2026-10-29 17:00:15 -07:00
Liam Cottle 77d81d1f82 Merge pull request #3603 from A13xB0/companion-buzzer-cli
Add CLI command to toggle the buzzer for companions
2026-10-30 12:53:18 +13:00
mjgodatandClaude Opus 5.5 1f76b79fa4 feat(presets): MESH_ENABLE_RADIO_PRESETS build switch (off on STM32 and ESP-NOW-only)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:47:59 -07:00
mjgodatandClaude Opus 5.5 437a4dd5f3 Merge upstream keymindCascade into radio presets
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:14:34 -07:00
mjgodatandClaude Opus 5.5 94fb09a3dc fix(presets): start companion presets after prefs are loaded
/presets is shared with infrastructure roles, so a node reflashed to
Companion can carry a pending remote load. begin() reverts it through
applyAndSaveRadioParams, which saves _prefs; running it before loadPrefs
would overwrite the saved Companion prefs with constructor defaults. Start
it after loadPrefs, the HIL startup frequency and sanitising, just before
configureRadioFromPrefs(). Contract test asserts the ordering.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:44:34 -07:00
mjgodatandClaude Opus 5.5 a417ae6ef7 feat(presets): companion preset commands
Companions (T114, Cardputer) handle get/add/load/del preset from local
operators only: USB/TCP terminal, framed command 0x42, browser CLI and the
UI. An authorized LoRa CLI command (nonzero sender timestamp) is not
consumed, since companions have no revert path. Loads go through
applyAndSaveRadioParams with the same replies as "set radio". Exposes
loadRadioPreset/activeRadioPreset/radioPresetTable for the Cardputer UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:41:13 -07:00
mjgodatandClaude Opus 5.5 d0db89bbcd fix(presets): unguard preset file include, commit on room/sensor admin login, avoid NAME_MAX
- CommonCLI.cpp included RadioPresetFile.h only on nRF52/STM32; ESP32 and
  RP2040 builds could not see the file helpers. Include it unconditionally.
- Room server and sensor now commit a pending remote preset load on a
  successful strict-admin login, like the repeater; drop the doc caveat.
- Rename RadioPresetTable::NAME_MAX to MAX_NAME_LEN: newlib/ESP-IDF
  <limits.h> defines NAME_MAX as a macro. Host harnesses now predefine
  NAME_MAX so such collisions fail on host too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:33:51 -07:00
mjgodatandClaude Opus 5.5 6dea450861 feat(presets): repeater preset commands with login-confirmed switch
CommonCLI owns a RadioPresetCLI wired through static hook trampolines
(current/accepts/apply via the existing primary-radio save+apply path,
/presets storage via RadioPresetFile.h). begin() runs at the end of
loadPrefs, loop() next to the radio profiles, and dispatch precedes
radio profiles with remote = sender_timestamp != 0. A fresh strict-admin
repeater login (LoRa or ESP-NOW bridge) commits a pending remote load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:26:41 -07:00
Claude b2d6184bda USB packet log: print the radio2 marker from the repeater/room hooks
The marker in Dispatcher::logPacketLine cost the RAK4631 Full Companion 72
bytes it doesn't have (712776 of 712704). Companions aren't serial observers,
so print it where only repeaters and room servers pay for it: their logRxRaw,
right after the RAW line and before the RX line, using the radio's current
receive profile.

  12:34:56 - 29/10/2026 U RAW: 15A3…
  12:34:56 - 29/10/2026 U RADIO: radio2
  12:34:56 - 29/10/2026 U: RX, len=64 …

The shared dispatcher is back to upstream, so Companion images are unchanged.
Only receptions are marked in the USB log now; the MQTT bridge still tags
both directions.

test_usb_log_radio2.py compiles both roles' real logRxRaw and checks the
marker against meshcoretomqtt's patterns, and that the dispatcher and
Companion sources don't carry it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011i5tJJtj95MB4oUgncCUe5
2026-10-29 09:47:32 -07:00
fdlamotte 04d72b1049 Merge pull request #3687 from fdlamotte/display_prefs
ui: add some parameters to the cli (mostly regarding eink behaviour)
2026-10-29 08:35:36 -04:00
Florent 5d7100ae7d ui: add some parameters to the cli (mostly regarding eink behaviour) 2026-10-29 08:34:41 -04:00
Claude fef5ce0f17 MQTT radio2: keep repeater neighbours' radio2 in a small cache
Full ESP32 repeater builds keep up to 254 neighbours, and a 16-byte radio2
field on each pushed them past the DRAM check (checkprogsize). Instead:

- Radio2DiscoverTrailer is 8 bytes (bandwidth in 100 Hz steps, which is all
  the status format prints; sf/cr/state/mode/temporary in bitfields).
- The repeater keeps a 24-entry cache keyed by key prefix (288 bytes): a
  reply without a trailer changes nothing, a node's newer report replaces
  its older one, and a full cache keeps On (MediaMesh) reports over Off ones.
- The discovery snapshot reads from it; JSON output is unchanged.

The room server keeps its per-neighbour field (now 8 bytes).

Tests: test_radio2_neighbour_cache.py compiles the real cache functions;
the trailer test pins the 8-byte size; the lifecycle harness looks radio2 up
the same way the repeater does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011i5tJJtj95MB4oUgncCUe5
2026-10-29 02:59:01 -07:00
Claude 4aedbc8059 MQTT: tag radio2 (MediaMesh) packets, status and neighbors
Observers already publish radio2 packets, but nothing says they came over
radio2, so analyzers can't tell MediaMesh traffic or MediaMesh repeaters
apart. Add optional keys, all absent on the main radio, so existing
consumers see byte-identical messages:

- packets and raw: "rx_radio_id"/"tx_radio_id": "radio2" and
  "mediamesh": true, from the packet's own radio_profile (captured on
  receive, kept by outbound copies), not the radio's profile at publish
  time. rx_radio_id is CoreScope's multi-radio key (#1869).
- status: "radios": [{id: "radio2", radio, mode, mediamesh, temporary}]
  while radio2 is on with the MeshCore protocol; "radio" stays the main
  radio.
- neighbors (repeater and room server): the refresh's DISCOVER_REQ sets
  the radio2 flag (0x02, docs/radio_profiles.md); each neighbour's trailer
  is kept and published as "radio2" {mode, radio, temporary}, with
  "self.radio2" for this node. No trailer leaves the key out (unknown,
  never off).

Radio2DiscoverTrailer parses the trailer (host-tested). publishRaw now
takes the direction. MQTT_IMPLEMENTATION.md documents the keys.

Tests: new payload-builder cases (golden prefix, rx/tx/raw tags, status
radios, neighbors radio2, measurements), trailer parsing, and the
neighbor lifecycle fixture now checks radio2 end to end for both roles.
Harnesses updated for the new field and the publishRaw signature.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011i5tJJtj95MB4oUgncCUe5
2026-10-29 02:09:41 -07:00
mikecarper 5d45d8a270 Fix CI radio harnesses and constrained firmware builds 2026-10-28 19:24:16 -07:00
mikecarper c95d227c83 Keep displays awake for two minutes on first installation 2026-10-28 18:31:01 -07:00
mikecarper d270cd611a Add split RX and TX repeater modes with source-based bridge routing 2026-10-28 15:34:42 -07:00
mikecarper 2fa1b63e14 Allow bridge ingress to target radio2 without primary fallback 2026-10-28 15:10:17 -07:00
mikecarper 67009e0d1e Add ESP32 app slot selection to the CLI 2026-10-28 14:03:31 -07:00
mikecarper 1d09ea4bde Expose board-aware setting capabilities and saved primary preamble 2026-10-28 12:52:48 -07:00
mikecarper f6034e1f02 Shorten RAK Bluetooth startup diagnostics 2026-10-28 10:00:54 -07:00
mikecarper 8c2ddc9ac7 Coalesce repeater clock and radio schedule runtime fields 2026-10-28 05:03:29 -07:00
mikecarper acacf548ef Group runtime timers and flags to recover nRF52 repeater RAM 2026-10-28 04:57:03 -07:00
mikecarper 8f20fe5d83 Trim remaining validation wording in small Companion profiles 2026-10-28 04:44:06 -07:00
mikecarper 8a51a54fd7 Use concise validation replies in constrained Companion builds 2026-10-28 04:22:07 -07:00
mikecarper cea654cb47 Use shorter CLI validation replies on the constrained Mini 2026-10-28 04:15:04 -07:00
mikecarper c778abceab Shorten Companion help descriptions while retaining every command 2026-10-28 03:52:08 -07:00
mikecarper f0bcb10ff0 Handle USB mode queries in the existing getter paths 2026-10-28 03:21:36 -07:00
mikecarper 411144f69c Keep local Companion control parsing in a cold function 2026-10-28 03:15:49 -07:00
mikecarper 3385f2acaa Avoid repeated channel alias parsing in constrained companions 2026-10-28 03:03:48 -07:00
mikecarper 4261889095 Recover constrained firmware flash and update USB dispatch fixtures 2026-10-28 02:51:56 -07:00
mikecarper dfef59331c Merge remote-tracking branch 'origin/keymindCascade' into keymindCascade 2026-10-28 02:33:24 -07:00
mikecarper b18ba8288a Report the running firmware USB mode without disturbing logging 2026-10-28 02:14:11 -07:00
mikecarper 0c7dec9f19 Add an hourly emergency battery sleep schedule for infrastructure nodes 2026-10-28 02:06:58 -07:00
mikecarper 744692fb93 Configure MediaMesh radio2 presets when joining Companion channels 2026-10-28 00:05:10 -07:00
mikecarper 1e22f6326d Fix Cardputer history, notifications and hardware lifecycle 2026-10-27 23:45:06 -07:00
ripplebiz 42ded8da64 Merge pull request #3688 from Blake-Latchford/fix/stats-dup-count-wrap
Saturate duplicate packet stats instead of wrapping
2026-10-28 17:06:21 +11:00
mikecarper 9a2211e85a Fix Cardputer delivery, live settings and power management
Keep selected chats bound to full contact keys and route keyboard channel sends through the active transport. Deliver accepted plain, room and Meshtext messages to local history and notifications once; disarm rejected sends and retries.

Use shared live radio settings, GPS acquisition and power-saving policy, screen timers and red night palette. Report save failures, preserve verified custom preferences, and guard display controls and shutdown.

Add executable sanitizer regressions for routing, retries, selection, storage faults, UI lifecycle and GPS. Both Companion builds and the shared T-Deck regression pass; no physical Cardputer testing performed.
2026-10-27 22:59:26 -07:00
mikecarper 64a068506b Merge PR #26: add M5Stack Cardputer-Adv support
Integrate mjgodat's keyboard/display Companion, USB Companion, Repeater and
Room Server support for Cardputer-Adv with Cap LoRa-1262.

Fix UI retry dispatch and ACK ownership, packet/storage bounds, numeric
input validation, sparse channel selection, optional-display shutdown,
keyboard layout limits, reserved GPIOs and Windows cross-drive includes.
Retain all 350 contacts and queue capacity using the existing contact cache;
account for the custom UI's runtime allocations in the RAM admission gate.
Carry the MultiMote and DejaVu notices with firmware packages and add CI
coverage for all four board roles plus the shared T-Deck Companion.

Validation: all four Cardputer roles and the T-Deck BLE Companion build;
Cardputer sanitizer, UI, layout, ownership, licensing and storage tests;
65 RAM-policy tests and 14 contact-cache tests. PlatformIO ran serially.

PR: https://github.com/mikecarper/MeshCore/pull/26
2026-10-27 22:25:35 -07:00
mikecarper 80bfa754d1 Keep the continuous logging help entry within USB output bounds 2026-10-27 18:50:28 -07:00
mikecarper 05679aa741 Add a saved override to keep USB packet logging continuous 2026-10-27 18:47:05 -07:00
mikecarper b3df8bfd3f Quiet USB packet logs for five minutes after console commands 2026-10-27 18:19:19 -07:00