Commit Graph
369 Commits
Author SHA1 Message Date
mikecarper fe7f2ef05b Keep BLE-only sleep checks lean and exercise role deadlines 2026-10-21 17:53:57 -07:00
mikecarper 61eecbd971 Enable reversible ESP32 BLE shutdown and bounded radio2 CPU sleep 2026-10-21 17:53:57 -07:00
mikecarper a3d77a9a76 Clean project references and separate optional bench tooling
Remove unrelated ecosystem comparisons and software citations while retaining hardware links, measured model names, and required license notices.

Preserve stock-peer runners and tests in a verified local validation package. Keep shared Companion USB transport in the firmware repository for the raw-radio sweep and OTA seeder, with focused CI coverage. Restore missing hosted documentation links.
2026-10-21 17:35:37 -07:00
mikecarper 6c3bf00691 Fix unit test fixtures and fit constrained firmware builds 2026-10-21 14:09:51 -07:00
mikecarper f68d4ca544 Add recent repeater login history with short key prefixes 2026-10-21 13:31:03 -07:00
mikecarper c433b40e51 Default repeater guest login off and expose guest sessions 2026-10-21 11:11:07 -07:00
mikecarper db1c4704e0 Fix firmware budget regressions and flood alias delimiters
Share nRF52 checked-record reads and command-family lookups without changing
storage formats, error protection, fleet authorization, or delegated scopes.
Use the existing bounded Merkle proof workspace for qualified ESP32 repeaters
while retaining source capacity, wire format, and every enabled feature.
Restore advert tab/CRLF delimiters and expose nested qualification build logs.

Validation: all 1932 native CI test cases; exact canonical RAK4631 Full,
Wio-E5 Mini, Station G3 Full MQTT, and Wireless Tracker Full wrappers;
linked RAK crypto/workspace checks and retained Reader code equivalence;
focused persistence, authorization, source-proof, and RAM policy regressions.
2026-10-21 03:02:46 -07:00
mikecarper 953ad6defb Extend forwarding filters and save moderation rules atomically 2026-10-21 01:10:12 -07:00
mikecarper 300b889bca Add saved OLED controller selection on RAK boards
Allow Auto, SSD1306 or SH1106 through display.controller on display-enabled RAK4631 and RAK3401 roles. Persist the choice before restart without changing the active screen policy, and let saved Auto override legacy build defaults.

Share checked settings I/O and the existing atomic writer to keep Full Companion within its flash boundary while retaining features and existing record formats. Cover save failures, backup recovery, startup selection and ambiguous OLED replies.

Validation: 35 targeted host tests passed. RAK4631 Full Companion and RAK3401 unified LoRa OTA repeater build and package checks passed with release-length version strings.
2026-10-20 21:14:49 -07:00
mikecarper 265b71d77a feat: set Morse receive floor and add bounded RSSI diagnostics 2026-10-20 17:44:29 -07:00
mikecarper 4e27d5108b fix: preserve HWCDC logging lease across transient USB status 2026-10-20 17:32:12 -07:00
mikecarper 099c5a851a fix: keep adaptive Morse receive within the full RAK image limit 2026-10-20 16:39:18 -07:00
mikecarper 805dd2cbdf fix: keep feature-complete release builds within flash limits 2026-10-20 11:19:27 -07:00
mikecarper bc1176c7f4 Merge remote-tracking branch 'origin/keymindCascade' into keymindCascade 2026-10-20 10:42:48 -07:00
mikecarper d58bedd8ca fix(nrf52): align external QSPI DMA buffers 2026-10-20 10:35:07 -07:00
mikecarper d5a6df6283 Detect SSD1306 and SH1106 screens on RAK boards
Use repeated status reads at screen initialization and preserve SSD1306 for ambiguous responses. Share the existing framebuffer, drawing, rotation and power handling; use SH1106 page transfers when detected.

Enable this for RAK4631 and RAK3401, including WisMesh Pocket v2/v3. Add controller overrides, protocol tests and CI coverage. Addresses meshcore-dev/MeshCore#3296.
2026-10-20 09:43:25 -07:00
mikecarperandR0ck f57dffa2be Add saved Companion sound and vibration controls
Default fresh settings to sound off and vibration on, and keep existing saved choices. Apply changes immediately across all three UIs and make custom notification patterns respect the same mute controls.

Keep the Wio Mini Companion within its existing flash boundary by storing its LED switch in a reserved preference byte and shortening CLI help without removing commands. Add coverage for live output changes, persistence, and storage failures.

Adapted from https://github.com/meshcore-dev/MeshCore/pull/3603.

Co-authored-by: R0ck <develop@hectospark.co.uk>
2026-10-20 09:33:43 -07:00
mikecarper 8e35f477c0 Repair failed profile retunes before receiving packets 2026-10-19 18:54:14 -07:00
mikecarper 8038715ffe Extend nRF52 radio profile timing across RTC wraps 2026-10-19 18:53:33 -07:00
mikecarper ca67494f8c Correct chip-specific radio profile validation and airtime
Retain supported LR2021 bandwidths and reject frequency gaps. Enable LR1121 high-band bandwidth selection and account for its forced LDRO in profile and beacon airtime.

Cover all eight chip families with production-method regression tests.
2026-10-19 18:49:15 -07:00
mikecarper 25299a77b3 Invalidate LR1110 profile cache on packet changes
Revoke fast-RX ownership before CRC, header and IQ setters, including failed writes. Cover normal RX rebuilds and unchanged defaults with production-method tests.
2026-10-19 18:43:11 -07:00
mikecarper 40a4161782 fix: keep unavailable radios out of identity and settings recovery 2026-10-19 17:44:48 -07:00
mikecarper 61dc5ca3f1 Wake XIAO QSPI flash and preserve access after failed resets 2026-10-19 13:25:04 -07:00
mikecarper c557d96bf0 Fix nRF52 console mocks and cover framework logging in CI 2026-10-19 12:54:05 -07:00
mikecarper d34d84460b Warn on radio2 spectral overlap and suggest a clear center 2026-10-19 10:44:39 -07:00
mikecarper a3f858f6f0 Fit V3 Full with NimBLE and bounded OTA source proofs 2026-10-19 02:47:13 -07:00
mikecarper 036661e7e4 Reduce contact RAM across boards and compact Full firmware 2026-10-19 01:55:25 -07:00
mikecarper 0e70110640 Fix Bluefruit role dispatch after disconnect frees connection 2026-10-19 00:06:03 -07:00
mikecarper f7b5c40c3b Fit RAK4631 Full OTA image by reusing regulator recovery code 2026-10-18 23:48:07 -07:00
mikecarper e8d1e537e4 Record T-Deck radio2 hardware timing and regression coverage
Add receive-only same-image display, SPI, modem/IQ-cache and scoped-priority experiments with checkpointed collectors. Keep rejected clock-phase correction and elevated-priority experiments out of production.

Publish sanitized timing data, Full Companion/Bluetooth/USB checks and redraw measurements with their limits. Wire the new behavioral checks into CI.
2026-10-18 23:20:50 -07:00
mikecarper a782cc8413 Speed up T-Deck radio2 retunes with guarded command reuse
Reuse the confirmed LoRa modem only inside acknowledged warm continuous-RX hops and revoke that capability before modem initialization or after failures.

Opt the tested T-Deck into IQ workaround reuse and an exact 8,888,888 Hz SPI setting. Keep the existing BUSY, packet-ownership and recovery checks; other boards retain their modem-cache default.
2026-10-18 23:20:50 -07:00
mikecarper a944b1779d Keep T-Deck radio2 scanning active during screen redraws
Render into a PSRAM canvas and release the shared SPI bus between bounded TFT strips. Service only the radio driver at cooperative checkpoints and use the buffered radio HAL, preserving packet and transmit guards.

Cover pixel parity, transaction boundaries, allocation failure, partial updates and sleep/wake behavior with native tests.
2026-10-18 23:18:55 -07:00
mikecarper a43604c577 Check linked Reader text and stack use alongside crypto 2026-10-18 21:36:56 -07:00
mikecarper c4a1d485ff Add saved regulator modes and battery-gated crash recovery 2026-10-18 21:10:58 -07:00
mikecarper 5df3e4ae53 Verify RP2040 capabilities against matching UF2 application 2026-10-18 20:40:06 -07:00
mikecarper 9c78ccde57 Unify optional hardware variants and add runtime R8 TFT rotation 2026-10-18 20:25:13 -07:00
mikecarper 4f746d1e3b Detect manufacturer-supported optional screens on RC32, Tracker V1 and V4 R8 2026-10-18 18:55:38 -07:00
mikecarper 1ce3f0cdd7 Make T114 screen detection the default firmware and picker choice 2026-10-18 16:20:27 -07:00
mikecarper 22ab02caf7 Fix G3 gain transitions, slot commands and radio restore 2026-10-18 14:29:19 -07:00
mikecarper cd02e55824 Share the saved admin password across ESP32 management services
Use the committed node credential for setup WiFi, WebConfig and browser OTA. Add persistent ESP32 WiFi Companion management credentials without changing preferences layouts, revoke stale browser sessions on rotation, retain scoped save receipts, and coordinate credential changes with flash uploads. Keep external-service credentials and trusted TCP protocol compatibility independent. Update live join QR codes, failure handling and documentation.

Validated 51 native cases, 158 related host and browser methods, and serial Full V4 Companion, Station G3 Repeater, ESP32-C6 Room Server and V4 Sensor firmware builds.
2026-10-18 13:09:48 -07:00
mikecarper 7088096abf Merge upstream dev through 428a95c64
Integrate fractional Companion timezones and conditional Bluetooth pages while preserving the existing preference byte layout, transactional saves, and Full transport selector. Add migration, rollback, invalid-value, and UI profile regressions.
2026-10-18 08:30:50 -07:00
mikecarper 89dcd82089 Add guarded hardware acceptance and restoration tools 2026-10-18 00:24:03 -07:00
mikecarper 80023f79e0 Fix ESP32-C6 GPIO hold capability and add cross-platform smoke builds 2026-10-17 21:41:47 -07:00
mikecarper 040182e8ec Merge remote-tracking branch 'origin/pr-21' into codex/integrate-open-prs-17-21 2026-10-17 21:13:27 -07:00
mikecarper 9a5331eecd Merge remote-tracking branch 'origin/pr-19' into codex/integrate-open-prs-17-21 2026-10-17 21:13:27 -07:00
mikecarper 24653842e8 Merge remote-tracking branch 'origin/pr-18' into codex/integrate-open-prs-17-21 2026-10-17 21:13:27 -07:00
nullrouten0andClaude Opus 5.5 618c18d385 Keep whole contact records ahead of a partial trailing record
Upstream MeshCore, and this fork up to v1.17.1.6 except ESP32 Full
builds, rewrote /contacts3 in place, one record after another. A reset
or a full volume during that save leaves whole records followed by part
of the next one. Upstream reads such a file up to the short read. Here
readableContactFile() treats any size that is not a multiple of 152
bytes as unreadable, and since 2311160a9 the bounded recovery then
deletes /contacts3. On the first boot after an upgrade, three whole
records plus one stray byte became zero contacts.

Invariant: on ESP32, RP2040 and STM32, when /contacts3 holds at least
one whole record followed by part of one, and /contacts3.bak does not
exist, the whole records load and nothing is written or deleted at
boot. The next ordinary save publishes only whole records through the
existing transaction. Unchanged: whole-record images; a backup still
wins over an incomplete primary, including a backup that is unreadable
or of unknown presence at boot, which keeps its retry at the recovery
boundary; read errors keep the bounded recovery; a file with no whole
record is still discarded; nRF52 is not touched.

selectContactFile() makes this check only after the strict checks of
both names fail, through a new partial_tail mode of
readableContactFile(). loadContacts() drops its own size check; its
whole-record loop bound already stops before the tail.

Add test_companion_contact_partial_tail.py, which runs the real load,
recovery and save paths on the uncached ESP32, RP2040 and STM32
harness and on the ESP32 Full cache harness under ASan/UBSan. On the
old code all four fail with zero contacts and /contacts3 deleted. It
catches 14 of 15 mutations of this change, including a full revert;
the other drops a guard whose value is read only when the file handle
is valid. Two cases in the uncached storage fixture used a one-byte
truncation as their unreadable image; they now use a file shorter than
one record, so they still exercise the discard path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:57:09 +00:00
nullrouten0andClaude Opus 5.5 ef1e4a70cb Lock WebConfig logins per client address with a shared failure cap
/api/login locked every client for 30 s after five failures from anyone.
Anyone who could reach the login page could keep the owner locked out by
failing on purpose. If no login succeeded after a lockout, the lock also
returned from 2^31 to 2^32 ms (about 24.9 to 49.7 days) later, because the
deadline was never cleared and was compared as a signed difference.

Count failures per remote address instead. Five failures lock that address
for 30 s, as before. A shared budget caps failures from all addresses
together, so changing address does not add guesses: it holds six failures
and refills one every 6 s, the old global rate, so one failing address can
never empty it on its own. While it is empty every client waits, as before.
Lock times are measured as elapsed time.

The policy is a pure header, WebConfigLoginThrottle.h.
test_webconfig_login_throttle.py runs it directly (isolation, boundaries,
one-hour rate bounds, millis() half-wrap, saturation, eviction) and runs the
real handleLogin with ArduinoJson under ASan/UBSan. Putting every client on
one key, as the old code did, fails the handler test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:57:09 +00:00
nullrouten0andClaude Opus 5.5 09435b049d Use the node's admin password for the migration bridge AP
The Wi-Fi, LoRa first-stage and Partition Expander bridges serve an
unauthenticated /update behind an AP whose password was fixed and published,
so anyone in range during a migration could upload firmware while the private
key is staged. Use the old node's saved admin password as the WPA2
passphrase, read from /com_prefs or /node_prefs at offset 56 as the firmware
loads it. The operator already used that password to start the old updater.

Fall back to the published password, with a serial warning, when the saved
admin password is missing, unreadable, shorter than 8 characters or not
printable ASCII, so no node becomes unreachable. The legacy filesystem is
mounted without formatting and the password is never printed. Migration
admission, flash sequencing, /update gating and the USB bridge are unchanged.
Update both guides and the package README.

Add a sanitizer-backed host test that compiles the bridge's actual Wi-Fi
block against fake SPIFFS and WiFi: both boots, file precedence, WPA2 length
and terminator bounds, printable characters, stock 1.10/1.11 file sizes,
truncated fields, and mount, seek and partial-read failures. It fails 8 of 8
on the previous code and catches 27 of 27 code mutations. Verified 13 related
host test files and the esp32_s3_4mb_partition_migrator build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:57:09 +00:00
nullrouten0andClaude Opus 5.5 6b61e28404 Keep guest-password room logins out of the durable replay store
On a room server the guest password grants Read/Write, which the login
replay store treats as a role that needs a durable record. Every new
guest-password identity therefore took one of the 128 permanent slots,
and once they were used up the store failed closed for every new
identity, including a new administrator device, until the filesystem was
erased. Rooms often publish the guest password.

A guest-password Read/Write session (one without explicitly assigned
permissions) now uses the policy public readers already use: it must
beat its in-boot timestamp and any record the identity already has,
which is still advanced, but it never creates a new record.
Administrator logins and explicitly assigned roles keep the durable
reservation and still fail closed on a full store.

Tests: test_room_login_replay_capacity.py runs the real room login
handler against the real ClientACL replay store with ASan/UBSan: guest
churn cannot lock out a new admin or assigned writer, a former admin's
record still binds guest-password logins, and a store full of privileged
records still refuses a new admin. It fails 2 of 3 on the previous code.
Two expectations in test_room_login_integration.py and the login profile
contract follow the new policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:57:09 +00:00