Commit Graph
106 Commits
Author SHA1 Message Date
liquidraver eb4e6583c7 linux native fixup #2 2026-06-02 14:50:31 +02:00
liquidraver eded1d7f04 linux native fixup #1 2026-06-01 22:29:53 +02:00
liquidraver e445e97fc3 fix(usb): release the interface on VBUS removal
A device-side cable yank often skips the DTR=0 line-state change, so the
companion stayed stuck on the USB interface and rejected every BLE
connection until reboot. Treat USBD_MSG_VBUS_REMOVED as a DTR drop.
2026-05-31 15:36:46 +02:00
liquidraver b26bd5eee4 fix(rng): hard-fail seed KDF on SHA-256 error
extract_via_aes_ctr used the void Utils::sha256, which silently zeroes
its output on PSA failure -> an all-zero AES key -> a constant,
device-shared Ed25519 identity that the degenerate check misses.
Re-inline psa_hash_compute with its status check so a failure reboots.
2026-05-31 15:36:25 +02:00
liquidraver 553b71c44a Make production the default build; decouple USB companion from CONFIG_LOG
Production (LOG=n, ASSERT=n, RTT=n, reboot-on-fatal) is now the prj.conf
default; debug.conf is the opt-in bundle. Removed prod.conf and the
logging.conf auto-include; relocated RTT/ASSERT out of the always-on
platform confs so they no longer override the prod defaults.

Add CONFIG_ZEPHCORE_COMPANION_USB so the USB CDC companion transport
compiles independently of logging (default-y on USB-capable companions,
opt-in on ESP32-S3 via esp32s3_usb.conf). Gate all USB sites behind one
ZEPHCORE_USB_STACK macro.

Rework BLE/USB interface arbitration to first-come-first-served: neither
transport evicts a live session. Make active_iface mutation thread-safe
(mutex + atomic claim) across the BLE callback thread and USB workqueue.

Share the ESP32-S3 USB OTG / console DTS via common dtsi includes; enable
uart0 (GPIO43/44) on station_g2 and xiao so the console reroute works.
2026-05-30 21:05:42 +02:00
liquidraver 7d7a64ff5a fix: airtime LDRO threshold must track driver (was BW-blind sf>=11)
getEstAirtimeFor() set LDRO from `sf >= 11`, correct only at BW125. Now
matches the driver's should_enable_ldro() (t_sym > 16.38 ms) so the
estimate's DE tracks hardware DE on every SF/BW. Also drop dead
calcRxDelay() + unused MAX_RX_DELAY_MILLIS.
2026-05-29 15:48:48 +02:00
liquidraver 5895d61211 adapters/ble: extract start_fast_adv() advertising helper 2026-05-29 15:09:33 +02:00
liquidraver 2b02966883 adapters/usb: drop dead write-only mesh-event statics 2026-05-29 15:01:23 +02:00
liquidraver 66fc25557d simplify LoRaRadioBase: merge configureRx/Tx into configure(bool) 2026-05-29 13:51:49 +02:00
liquidraver 799d694914 crypto: simplify entropy path after audit review
- Lift duplicated identity-gen block from main_companion.cpp +
  main_repeater.cpp into ZephyrRNG::generateFirstBootIdentity().
  Both mains shrink from ~40 lines to a 3-line helper call.
- Add LocalIdentity::fromSeed() so seed-derived keygen doesn't need
  a one-shot RNG wrapper; delete SeededRNG.
- Drop the per-byte ADC sampling loop: getBattMilliVolts() does an
  8-sample average + 10ms regulator settle internally, costing
  300-480ms of real wall-time and actively destroying the LSB jitter
  it was meant to harvest. Jitter mixer already dwarfs it.
- Centralize the printk + sys_reboot pattern as
  Utils::cryptoPanicReboot(); drop the 2000ms pre-reboot k_msleep
  (printk is synchronous, sleep just blocked the mesh thread on
  the ZephyrRNG::random() retry-failure path).
- Inline sample_cpu_jitter health check via online scalars instead
  of a 512-byte deltas[] array. Saves 1.5KB stack churn across boot
  and tracks every sample instead of only the first 128.
- extract_via_aes_ctr now uses Utils::sha256 instead of open-coding
  psa_hash_compute.
2026-05-29 07:58:54 +02:00
liquidraver b692ca72ed crypto: harden all crypto-sensitive memcmp + memset sites
Audit-driven sweep found additional compiler-optimization-sensitive
patterns beyond the login password compare just fixed:

P4.F3 (HIGH) — Utils::MACThenDecrypt verified packet MACs with
plain memcmp. Runs on EVERY encrypted-then-MAC'd packet in the
mesh; a timing oracle here lets attackers forge MACs byte-by-byte
across the whole mesh layer. Replaced with constantTimeEqual.

P4.F4 (MEDIUM) — Multiple memset(secret, 0, ...) calls on
stack-resident crypto buffers (Ed25519 seed, ADC noise pool, AES
key derived in extract_via_aes_ctr, HWINFO unique ID) were
subject to dead-store elimination under -Os. GCC/Clang routinely
elide these when the buffer is never read after; the wipe vanishes
and the secret persists on stack until next call overwrites.
Replaced with secureZeroize using volatile pointer writes.

P4.F5 (LOW) — Identity::validatePrivateKey boot self-test compared
shared secrets with plain memcmp. Boot-only, no attacker
observation channel, but hygiene matters and the fix is one line.
Also added secret-wipe for ss1/ss2 on all return paths.

Promoted the local ct_memeq() previously added to RepeaterMesh.cpp
into Utils::constantTimeEqual + Utils::secureZeroize (Utils.h/cpp)
so the login compare and MAC compare share the same audited helper.

Both helpers verified by Thumb-2 disassembly on rak3401_1watt:
- constantTimeEqual: loop branches on iterator, accumulator
  load-modify-stored to stack every iteration, final return uses
  CLZ+LSR (no conditional branch on result).
- secureZeroize: STRB.W to memory in a counted loop, not replaced
  with memset builtin and not eliminated.
2026-05-28 13:26:20 +02:00
liquidraver 515f3610e1 crypto: harden first-boot identity entropy + 3 RNG fixes
Adds a layered entropy mixer for first-boot identity Ed25519 keygen,
primarily to address ESP32 where the hardware TRNG (WDEV_RND_REG) is
only fed real entropy once the internal WiFi/BT radio is enabled —
but identity gen runs before that on companion and indefinitely
before that on a bare repeater. ESP-IDF's bootloader_random_enable()
is not compiled by Zephyr-Espressif HAL, ruling out that workaround.
Design reviewed with nextgens (author of upstream meshcore-dev/
MeshCore#2280 which fixes the same issue via BT/WiFi init/pull/deinit).

ZephyrRNG::random — retry sys_csrand_get up to 4x with k_msleep
backoff; cold-reboot on persistent failure. Previously fell back
silently to sys_rand_get (xoshiro PRNG), which would have produced
a weak Ed25519 seed on CSPRNG error. BUILD_ASSERT enforces
CONFIG_CSPRNG_ENABLED.

ZephyrRNG::mixIdentitySeed — layered entropy mixer for one-shot
identity keygen. Combines sys_csrand_get (early + late),
HWINFO unique device ID, caller-supplied ADC LSB noise, 200ms of
CPU cycle-counter jitter (NIST SP 800-90B class source), and
50ms more jitter in an independent timing window. Conditioned via
AES-256-CTR (NIST SP 800-108 KDF-in-Counter-Mode): SHA-256 of the
pool extracts a 32-byte AES key; AES-256-ECB on an incrementing
128-bit counter expands to the requested output length. Uses PSA
crypto already enabled in zephcore_common.conf. NIST-style
repetition-count + variance health check on jitter samples;
reboot on degenerate output. ~280ms one-time cost at first boot.
LoRa radio TRNG was considered as an additional source but rejected
on expert advice — radio sources are attacker-influenceable
(jamming/spoofing).

ui-joystick BLE passkey — switch from sys_rand32_get (non-crypto
xoshiro) to sys_csrand_get. The 6-digit passkey is the MITM
protection the rest of the BLE config enforces; predictable PINs
weaken it.

Identity reserved-prefix loop — replace the silent 10-attempt cap
(which committed whatever it had on fall-through) with a
bounded-retry-then-reboot pattern.

Also: fix a pre-existing scope bug at main_companion.cpp:357 in
the MESH_EVENT_PREFS_DIRTY handler — data_store was referenced
inside mesh_event_loop() but declared 50+ lines later. Moved the
call into a forward-declared helper defined after the statics.
Unrelated to crypto work but uncovered during build verification;
every companion build was broken.
2026-05-28 09:34:43 +02:00
liquidraver 57b971fc2c remove redundant main thread wakeups 2026-05-27 09:46:48 +02:00
liquidraver f06c472e87 usb: unify companion + repeater CDC ACM init, drop boot waits
Single ZephyrUSBCDC module owns the usbd context, 1200-baud DFU
detection, and DTR transitions for both roles. The boot banner
now blocks on a k_event signalled by the usbd_msg_callback when
DTR transitions high — host attached → wakes immediately; no host
→ bounded timeout (2 s repeater, 1 s companion). Replaces the
fixed k_sleep delays in both mains.

Deletes the companion's 10 s DTR-polling work — line state changes
arrive as events now, same callback handles disconnect (resets V3
parser, flips active_iface) and DFU touch (reboots to bootloader).

Side effect: prod companion no longer enumerates a phantom CDC ACM
port (CONFIG_LOG=n skips the whole stack instead of auto-initing
an unused device).
2026-05-27 09:04:32 +02:00
liquidraver 051adef93e native linux initial commit 2026-05-24 20:06:49 +02:00
Steve Calvário 5caf53a496 Add GPS altitude support, add channel “reply to” targeting, fix snake wall collisions, fix unread navigation incorrectly returning to home, and fix BLE continuing to advertise after being disabled 2026-05-21 17:09:13 +01:00
Steve Calvário 56b10f70a1 Init 2026-05-20 20:40:58 +01:00
liquidraver d7e420bf2f fix(ble,usb): three bugs from BLE audit
1. USB takeover opcode mismatch
   ZephyrCompanionUSB.cpp checked payload[0] == 0x03 with a comment
   claiming CMD_APP_START, but CMD_APP_START is 0x01 (0x03 is
   CMD_SEND_CHANNEL_TXT_MSG). The USB handshake silently dropped the
   companion app's first frame on every connection; the app appeared
   broken over USB until the user happened to send a channel message.

2. CMD_SET_ADVERT_NAME didn't propagate to BLE adv data
   Name changes were persisted to prefs but the advertising payload
   and GATT device name kept the old value until reboot. Added
   zephcore_ble_update_name() and called it from the handler.

3. No advertising-health watchdog
   If bt_le_adv_start() ever failed transiently (HCI timeout,
   controller pacing), the device would silently stop advertising
   and stay undiscoverable until reboot. Added an adv_running flag
   and a 5s watchdog in the companion housekeeping handler that
   nudges adv back on if it stops outside a connection. Tracks
   Arduino nrf52's equivalent 10s watchdog.
2026-05-20 11:09:45 +02:00
liquidraver 78f0c1c840 fix(ble): don't clobber overflow frame on congestion 2026-05-20 10:49:55 +02:00
liquidraver f0c29a612f ble cleanup 2026-05-20 10:27:42 +02:00
liquidraver 3441caf8b0 new rx busy latch 2026-05-14 22:24:48 +02:00
liquidraver 1bb04dd968 refactor atomicwrites, add atomic contacts save to QSPI capable devices 2026-05-11 13:02:55 +02:00
liquidraver 6919c3511c rx_boost state is undefined at boot (minor fix)
every LBT-retried flood packet loses its priority (fixed)
witching between LBT and non-LBT mode (or any cad.mode change) could silently skip full reconfiguration and leave the radio in the wrong mode (fixed)
2026-05-08 09:50:52 +02:00
liquidraver 2a8cc88262 fix fast path LBT CAD mode 2026-05-07 11:37:09 +02:00
liquidraver 65f31ced7d no permanent gps disable on repeaters 2026-05-06 10:11:09 +02:00
liquidraverandClaude Opus 4.7 5e7adfb130 normalize source-file line endings to LF
Add .gitattributes rules so .c/.h/.cpp/.hpp are always stored as LF
(prevents EOL drift from editors with autocrlf-true defaults), and
renormalize the 30 source files that had drifted to CRLF in the index.

Pure mechanical change — `git diff --ignore-cr-at-eol` is empty.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:56:44 +02:00
liquidraver e8f14442bf ramp time to 800us and duty cycle to 13/3 2026-05-05 14:52:05 +02:00
liquidraver ee2990fd16 hwconfig failsafe and duty cycle 10/6->10/4 (tests showed better reception) 2026-05-05 10:46:58 +02:00
liquidraver 9a1569c511 make rx duty cycle tuning more easy 2026-05-04 15:09:26 +02:00
liquidraver 1a956aa86a remove hot path RX, re-done the math, solves nothing, eats battery 2026-05-02 12:13:29 +02:00
liquidraver 9282ac8c9c stay in full RX after TX for 3 seconds
agc reset on every lora_recv_duty_cycle entry
2026-05-01 20:46:12 +02:00
liquidraver 624fc3306c tune duty cycling 2026-05-01 08:58:55 +02:00
liquidraver a81f27aea4 implement "isradioready" for early returns in rx duty cycling 2026-04-30 21:54:59 +02:00
liquidraver 7c31045bd4 fix hang near noisefloorcalibrate 2026-04-30 21:35:06 +02:00
liquidraver f947b6b5b1 increase preamble like vanilla 2026-04-30 12:58:33 +02:00
liquidraver b84830b3b3 (greatly) improve our BLE 2026-04-29 12:09:21 +02:00
liquidraver 067e53b474 fix RX duty cycling logic 2026-04-28 15:31:03 +02:00
liquidraver 1092c49a7d port vanilla duty cycling logic 2026-04-28 14:43:12 +02:00
liquidraver c9b6d6bded disable GPS cycle until reboot if no GNSS messages present 2026-04-28 13:49:08 +02:00
liquidraver d5f260c1c9 Fix ESP OTA functions 2026-04-25 14:52:45 +02:00
liquidraver 57aab5f522 GPS start fix when requesting telemetry
APC disabled by default, but compiled in
2026-04-24 22:32:05 +02:00
liquidraver 37eb87efd6 repeater housekeeping bugfix 2026-04-24 14:30:07 +02:00
liquidraver a5e5fcbb74 fix 0,0 lat/lon save to prefs as valid position, sorry people on a boat off the coast of Ghana with a very precise GPS hardware 2026-04-23 08:23:01 +02:00
liquidraver d03deda313 port adc.multiplier command 2026-04-22 10:49:41 +02:00
liquidraver de4bcd9a52 clear first_fix_acquired on gps off, increase timeout to 120 sec 2026-04-21 14:41:56 +02:00
liquidraver a3244e2dc2 Three driver fixes for RX duty cycle, all applied to the existing patch
stolen from Zephyr main:

  1. Issue StopTimerOnPreamble=1 before SetRxDutyCycle so the chip's
     timer is not reset on every preamble detect (per §13.1 of the
     datasheet). Without this, duty cycle effectively never sleeps in
     noisy RF and current draw spikes.
  2. On IRQ_RX_TX_TIMEOUT during duty-cycle RX, re-arm via
     sx126x_restart_rx() instead of falling through to set_sleep().
     The old path silently killed duty cycle after the first preamble
     false-positive.
  3. On recv_duty_cycle(NULL) cancel, wake the radio before issuing
     SetStandby — BUSY stays asserted during the sleep phase and the
     standby command was being dropped.

Also adds a dc_timeout_restarts atomic counter incremented on the Fix 2
path, exposed end-to-end: sx126x_ext.h accessors → LoRaRadioBase vtable
→ SX126xRadio override → CommonCLICallbacks → RepeaterMesh. Query via
`get dc.restarts` on the repeater CLI; cleared by `clear stats`. High
values indicate a noisy environment or a too-loose preamble threshold.

(+increase ESP BT stack because future zephyr pin advance will trip that mine)
2026-04-20 13:36:45 +02:00
liquidraver d2cec84100 sync with vanilla dev 2026-04-17 13:21:30 +02:00
liquidraver e71c3894a2 enable bluetooth privacy on esp32 to counter ios/esp bug
android on official app needs a manual BT bond
2026-04-16 13:02:12 +02:00
liquidraver 54eebee9e8 remove unnecessary writes on nRF 2026-04-16 11:10:07 +02:00
liquidraver 66b064ab02 I HATE BLUETOOTH 2026-04-16 10:31:11 +02:00