Commit Graph
140 Commits
Author SHA1 Message Date
mikecarper 633e2ce832 Add opt-in nRF52 Bluetooth event diagnostics and USB capture 2026-10-01 02:19:45 -07:00
mikecarper a834882836 Keep Companion get radio compatible with upstream CSV 2026-09-30 23:48:47 -07:00
mikecarper c7dcbd4c31 Distinguish BLE link loss from firmware watchdog evidence 2026-09-30 23:39:25 -07:00
mikecarper 70e8c98567 Merge remote-tracking branch 'origin/keymindCascade' into keymindCascade 2026-09-30 23:38:05 -07:00
mikecarper fa9f7dd538 Add legacy RAK3401 OTA route and relay reboot recovery 2026-09-30 23:30:08 -07:00
mikecarper bb58b40d9c Persist Full Companion BLE subscriptions across reboot 2026-09-30 23:20:14 -07:00
mikecarper 72982fa55f Preserve SoftDevice memory side effects under nRF52 LTO 2026-09-30 23:01:37 -07:00
mikecarper 0feffaa3ab Fix WebConfig bootstrap for legacy Android Chrome
Physical LG Android 5.1.1 testing found Chrome 43 could decode gzip but failed on the bootstrap's arrow syntax. Use ES5 functions and Promises while preserving retries, version refresh, and optional abort handling. Keep Google Zopfli gzip compression at 1,000 iterations.

Verified the flashed V4.3 through its WiFi link using the real Android browser: bootstrap and main page gzip responses completed, settings loaded at 910.525 MHz, and no JavaScript or transfer errors were reported. Add a loader syntax regression and document legacy browser support.
2026-09-30 19:20:12 -07:00
mikecarper 02b8935794 Merge PR #13 with gzip-only WebConfig assets
Keep the graceful final-ACK TCP close and optional FEM control guards from
pixitha's browser compatibility fixes. Replace Brotli negotiation and duplicate
page assets with one gzip representation compressed by Google Zopfli 0.4.3
using 1,000 iterations. Compress the bootstrap, captive success, compact OTA,
and static WiFi setup pages with the same validated build cache.

Honor gzip quality values and wildcard precedence. Validate compressed OTA
page evidence in the firmware capability gate, and add native and Python
regressions plus CI coverage. Remove the unused Brotli build dependency.

Validation: 54 native tests, 56 Python/browser checks, full V4.3 build and
verified application flash. Actual V4 WiFi responses matched the generated
gzip assets; 30 repeat downloads completed without reboot. Chromium loaded
the setup and settings pages without script or transfer errors. Physical
Android testing is pending because the Pi detects no phone over USB or mDNS.
2026-09-30 18:55:17 -07:00
Kyle Duren 22aa62e7d6 Use gzip fallback for WebConfig clients 2026-09-30 17:07:59 -04:00
Kyle Duren 70d183a3ae Fix WebConfig browser compatibility 2026-09-30 16:58:36 -04:00
mikecarper bf04fbb2e8 Offer exact latest bootloader files only for selected nRF52 hardware 2026-09-29 17:00:19 -07:00
mikecarper fd7b93c52d Link ESP32 picker to exact partition expansion packages 2026-09-27 21:13:25 -07:00
mikecarper 4db7780ba7 Prepare 1.17.1.7 Cascade release catalogs and STM32WL USB images 2026-09-27 10:20:43 -07:00
mikecarper 709a6fa735 Precompute ESP32 release partition lookup table 2026-09-26 19:58:28 -07:00
mikecarper f46368226e Publish one ordinary ESP32 Full image per board role 2026-09-26 09:29:18 -07:00
mikecarper 4bd31358fc Keep G2 migration Full images out of ordinary release matrix 2026-09-26 08:59:29 -07:00
mikecarper 7bbb7947ba Replay initial nRF52 USB READY after application handoff 2026-09-25 17:44:15 -07:00
mikecarper bea50fc451 Correct merged RAK bootloader target to OTAFIX 2.4.8 2026-09-25 10:50:29 -07:00
mikecarper b84da21417 Describe local adaptive OTAFIX requirement in release metadata 2026-09-25 10:37:10 -07:00
mikecarper fca10471c3 Unify RAK repeater storage firmware and bootloader handoff 2026-09-25 10:35:04 -07:00
mikecarper 0500cb3720 Stabilize nRF52 Bluefruit startup for buttonless DFU 2026-09-25 08:33:54 -07:00
mikecarper 4362acf00b Bound nRF52 UF2 images and reduce repeater BLE DFU memory 2026-09-25 08:09:38 -07:00
mikecarper d34efccc64 Align WSL3 migration identity with firmware hardware tag 2026-09-25 05:51:57 -07:00
mikecarper 7a31f33abd Add local complete firmware release build entry point 2026-09-25 01:36:44 -07:00
mikecarper 51ed608951 Fix logging matrix firmware build failures 2026-09-25 00:37:38 -07:00
mikecarper 40a9843c24 Merge branch 'keymindCascade' of github.com:mikecarper/MeshCore into keymindCascade
# Conflicts:
#	test/test_nrf52_ble_startup.py
2026-09-24 17:36:09 -07:00
mikecarper 307e7bec02 Complete ESP32 partition expander and adaptive LoRa OTA pacing 2026-09-24 17:13:22 -07:00
mikecarper 640facd5a2 Safely hand off expanded ESP32 LoRa bridge without resume record 2026-09-24 12:17:49 -07:00
mikecarper c0ef07a968 Add LoRa partition migration recipes for ESP32 infrastructure boards 2026-09-24 10:40:32 -07:00
mikecarper e7f6d529a0 Expand ESP32 OTA partition migration across infrastructure roles 2026-09-24 10:01:14 -07:00
mikecarper d68601b358 Add ESP32 migration build menu and verified release bundle 2026-09-24 08:02:31 -07:00
mikecarper 1e8ef78a2e Merge observer firmware branch into keymindCascade
Integrate compatible observer board, preset, WebConfig, display, CI, and policy updates. Preserve the checkout's newer MQTT binary preferences and WiFi bridge runtime where the forked implementations conflict. Keep ThinkNode observer networking WiFi-based until the Ethernet transport is wired into that runtime.
2026-09-24 01:20:56 -07:00
mikecarper b5a34939a4 Normalize Windows checkout status in ESP32 recipe 2026-09-24 00:29:03 -07:00
mikecarper 8d4716be5b Add repeatable ESP32 partition migration build recipe 2026-09-24 00:26:46 -07:00
mikecarper 63b97cb1d4 Package migration tables from saved merged images 2026-09-23 23:53:59 -07:00
mikecarper 1bc900c33e Select registered OTA slots and verify LoRa staging geometry 2026-09-23 23:33:29 -07:00
mikecarper c55022b001 Add in-place ESP32 Wi-Fi and LoRa partition migration packages 2026-09-23 22:12:45 -07:00
mikecarper 5c4394edd8 Keep nRF52 Full Companion BLE subscriptions across reconnects 2026-09-23 03:19:58 -07:00
mikecarper af86517059 fix(nrf52): avoid CCCD flash reset on Full Companion 2026-09-23 01:29:14 -07:00
mikecarper 47af95b4b2 Harden nRF52 filesystem recovery and flash writes 2026-09-22 15:17:39 -07:00
mikecarper 6a75e2a861 Apply nRF52 flash completion fix to every build target 2026-09-22 09:53:58 -07:00
mikecarper 7e1f87dfbc Fix nRF52 flash completion and preserve recoverable ExtraFS 2026-09-22 09:29:05 -07:00
mikecarper c1571077a5 docs(picker): publish verified runtime capabilities 2026-09-21 19:58:46 -07:00
agessaman fdf299c3d0 fix(webconfig): publish the board probe safely and test the gap
Codex review of the previous commit found two real problems.

The routes go live in startLanMode()/startSetupMode(), one tick before
probeBoardCommands() first runs, so a status request can land in between.
That made _board_cmds a genuine cross-task race despite the comment
claiming otherwise, and — worse — let /api/status answer "no board
commands" before the board had been asked. The page reads status once,
so a browser that loaded in that window hid working FEM controls for the
whole session.

The probe result is now published and read under _mux, and /api/status
OMITS board_cmds until the probe has run, which is not the same as
reporting an empty list. The page treats the absent field as "not known
yet" and re-polls with backoff; the audit waits for it the same way,
rather than auditing a board it only half knows.

Probing from the start path instead would close the window, but
Callbacks::execCommand is documented as loop-task-only and `start
webconfig` is itself mid-handleCommand, so that trades a race for
re-entrancy.

The audit never executed fan.lo or fan.hi, which have no getter and so no
round-trip: they were only ever matched as strings. They now run for real,
including the four rejection paths, and the mock grew --probe-delay so the
retry path is exercised rather than assumed.
2026-09-19 21:08:54 -07:00
agessaman a1f3e2c3d3 feat(webconfig): let the portal discover board-specific CLI commands
The FEM commands moved out of CommonCLI into Board::handleCommand(), and
the T-Beam 1W fan control was added there too, but the portal never caught
up: `radio.fem.txgain` and the fan commands were missing from the terminal
table entirely, while `radio.fem.rxgain` was offered on every board even
though a board with no hook now answers "??:" rather than "unsupported".

Whether a node answers these is a property of the board, not of the build,
so the page cannot know from the firmware version. Ask the board instead:
probeBoardCommands() runs each candidate getter once on the loop task at
startup and keeps the ones that answer, which needs no per-variant list
because Board::handleCommand() already reports whether it handled a
command. /api/status names the survivors and the page hides everything
else, so adding a command to a variant means one entry in WC_BOARD_CMDS
rather than an edit per board.

The two FEM keys also become Radio-panel toggles, gated the same way;
their `set` reaches the board hook through the existing config batch, so
only the allowlist and /api/config needed to grow.

webconfig_cli_audit.py now scans variants/*/*Board.cpp for the boards that
actually build the portal, checks set-only keys in the reverse direction,
and verifies every gate is a command some board answers; the mock gained
--board-cmds so both shapes of board are testable. `stop ota` joins
NOT_OFFERED: `start ota` cannot run from the portal, so it has nothing to
stop.
2026-09-19 20:51:25 -07:00
mikecarper 66b605a49d Add Wi-Fi OTA partition migration support 2026-09-19 20:14:37 -07:00
mikecarper 2d6e546ba4 Maximize Zopfli mOTA transport compression 2026-09-19 20:12:37 -07:00
agessaman 7af901a576 build(mqtt): make the preset table byte-identical across channels
The preset table is fleet state, not a build detail. A slot's preset is stored
in /mqtt.json by name, and firmware that does not know a name does not merely
ignore it: MQTTPrefsSerializer repairs it to "none" and CommonCLI writes the
repaired file back to flash. A node that rolls back to a channel missing a
preset therefore loses that slot permanently, and re-upgrading does not bring
it back.

The parity gate compared preset names only, deliberately allowing URL, CA and
credential drift. It now requires src/helpers/MQTTPresets.h to be byte-identical
between the channels, which also catches that drift — the two channels are meant
to dial the same brokers.

That is only workable if the file holds no channel-specific code, so
mqttPresetEnforcesTokenExp() moves to the new MQTTPresetPolicy.h. It was the
sole difference between the two channels' copies, and with it moved they match
exactly today. Policy keyed off the table belongs there from now on; the table
itself stays pure data.

The older name-only comparison stays available without --exact for ad-hoc use,
and the checker's self-test now covers both modes, including that --exact
rejects a config-only change the name check waves through.
2026-09-19 16:46:55 -07:00
mikecarper 8d8c7e5885 Use Brotli and Zopfli for compressed assets 2026-09-18 12:37:46 -07:00