Commit Graph
65 Commits
Author SHA1 Message Date
liquidraver e36d9b33a3 companion: scope joystick-only state to joystick builds
- #ifdef-gate _pending_joystick_{ping,admin}_tag fields + setters
  under CONFIG_ZEPHCORE_UI_DESIGN_JOYSTICK (saves 8 bytes per
  CompanionMesh instance on button-UI builds)
- gate logTx ui_notify_packet_sent() to joystick builds only;
  was firing on every TX for any UI variant (dead code on button UI)
- drop redundant _pending_login manual set in CMD_SEND_LOGIN;
  BaseChatMesh::sendLogin's onLoginSent hook owns it now, just
  clear the other pending fields explicitly
2026-05-21 09:06:55 +02:00
Steve Calvário 56b10f70a1 Init 2026-05-20 20:40:58 +01:00
liquidraver 0ba2721b40 refactor(companion): tighten Phase 2F polish — error codes, length checks, build assert
Three small correctness/polish improvements from BLE audit Phase 2F:

1. Five handlers (CMD_APP_START, CMD_GET_CHANNEL, CMD_SET_CHANNEL,
   CMD_DEVICE_QUERY, CMD_SEND_CHANNEL_TXT_MSG) previously responded
   with ERR_UNSUPPORTED on short-frame validation failure (because
   they fell through to the dispatcher's default break, which the
   caller converts to "unknown command"). They now explicitly
   sendPacketError(ERR_ILLEGAL_ARG) — the semantically correct code
   for "known cmd, bad frame".

2. CMD_SET_TUNING_PARAMS previously returned PACKET_OK on short
   frames without applying any change. Now sends ERR_ILLEGAL_ARG so
   the phone learns the change didn't take.

3. Added static_assert that CONFIG_ZEPHCORE_BOARD_NAME fits in 40
   bytes including its null terminator, so a future too-long board
   name fails at build time instead of producing an unterminated
   wire-format response.
2026-05-20 15:54:20 +02:00
liquidraver b39483add3 fix(companion): null-terminate contact name in CMD_ADD_UPDATE_CONTACT
The wire format reserves a 32-byte name field; if the phone sends 32
non-null bytes, ContactInfo::name has no terminator. Subsequent
LOG_INF/LOG_DBG sites using %s with contact.name then read past the
field into adjacent struct bytes (type, flags, out_path_len, ...)
until the first null. No memory corruption — serializeContact uses
StrHelper::strzcpy which is length-bounded — but log output gets
garbage and a paired peer could probe a few bytes of the struct
through log capture.

Sibling handler CMD_SET_CHANNEL at :1593-1594 already does this
defensively. Match the pattern.
2026-05-20 15:40:18 +02:00
liquidraver 988b438ec3 refactor(companion): harden telemetry buffer sizing and custom-vars snprintf
Two polish items from BLE audit Phase 2B:

1. CMD_SEND_TELEMETRY_REQ self-response buffer was uint8_t rsp[96]
   with a comment claiming 70 B worst case. Actual worst case at
   POWER_MAX_CHANNELS=4 is 82 B; if the channel cap ever grew the
   buffer would silently overflow. Replaced with a sizeof-style
   expression that tracks POWER_MAX_CHANNELS, plus an 8-byte safety
   pad. No size change today (90 vs. 96) but the upper bound auto-
   tracks any future bump.

2. CMD_GET_CUSTOM_VARS used `dp += snprintf(dp, 20, ...)` which
   advances by the would-be-written length, not bytes actually
   written. Currently safe only because gps_interval is capped
   ≤86400, but if either cap drifted or a new key was added the
   length passed to writeFrame would include uninitialized stack
   bytes between the truncation point and the (over-advanced) dp.
   Now tracks rsp_end, computes remaining per snprintf, and only
   advances dp on real progress.

Both are correctness polish, not exploitable today.
2026-05-20 11:57:37 +02:00
liquidraver bd1e022e88 fix(security): close OOB read in path-decoding callers (BLE + LoRa-anon)
Both mesh::Packet::writePath and ::copyPath did a raw memcpy of the
decoded hash_count*hash_size bytes from src to dest with no bound on
src. Two call sites used phone-supplied or LoRa-anon-supplied buffers
where the path_len byte was attacker-controlled:

  - CompanionMesh CMD_SEND_CHANNEL_DATA accepted len>=4 and called
    writePath with no src bound; a paired phone could leak up to ~65
    bytes of syswq stack into the outgoing LoRa channel-data frame.

  - RepeaterMesh handleAnonRegionsReq / handleAnonOwnerReq /
    handleAnonClockReq read reply_path_len from an unauthenticated
    LoRa anon-request payload and called copyPath without any src
    bound. Any LoRa neighbor could leak repeater stack into the
    reply path.

Hardened the API: both functions now require an explicit src_len
and reject (return 0) when the decoded byte count exceeds it.
Updated all 14 call sites across Packet/Mesh/Dispatcher/BaseChatMesh/
CompanionMesh/RepeaterMesh. Trusted callers (internal MAX_PATH_SIZE
buffers) pass MAX_PATH_SIZE; untrusted callers pass real remaining
length. Added len-5 plumbing through the anon-handler signatures.

CMD_SEND_CHANNEL_DATA also gained a local len>=5 + path_bytes
sanity check for early rejection.
2026-05-20 11:52:39 +02: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 a6d095bc16 edit default prefs 2026-05-12 22:07:02 +02:00
liquidraver 2ee0fffa69 sync with vanilla 2026-05-08 10:13:42 +02:00
liquidraver 147ac462b3 fix deleting public channel could wipe all other channels on reboot 2026-05-07 21:43:48 +02:00
liquidraver 6bc3ba7405 disable default duty cycling + SX driver fixes 2026-05-05 21:56:00 +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 28e12c7eef initial companion jitter lowering 2026-05-05 14:52:12 +02:00
liquidraver 62232bf609 small ble fixes 2026-04-30 09:23:56 +02:00
liquidraver 5dc07d78ba force unscoped send on magic scope word: "none" even if there is a default scope 2026-04-29 13:17:04 +02:00
liquidraver b84830b3b3 (greatly) improve our BLE 2026-04-29 12:09:21 +02:00
liquidraver 1092c49a7d port vanilla duty cycling logic 2026-04-28 14:43:12 +02:00
liquidraver b57df41753 micro-tweak: skip APC math when APC is off 2026-04-28 14:18:10 +02:00
liquidraver e18d017b2c refactor repeater prefs changes 2026-04-28 13:49:08 +02:00
liquidraver bf9ad0ef40 tune delay knobs 2026-04-28 13:49:08 +02:00
liquidraver 7ecf647af8 runtime guard agc reset if rx duty cycle is enabled 2026-04-28 13:49:08 +02:00
liquidraver e7219893c6 fix repeater prefs saving 2026-04-27 10:15:37 +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 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 78561036d0 bump version to match vanilla 2026-04-19 10:16:59 +02:00
liquidraver 7876ae79c3 make CAD retry jittery, sync prefs load to companion-style 2026-04-18 22:21:57 +02:00
liquidraver d2cec84100 sync with vanilla dev 2026-04-17 13:21:30 +02:00
liquidraver ba4b86752d acw: airtime-scale jitter caps, companion surroundings awareness
- flood retransmit jitter now capped at min(2000ms, 6·airtime) instead of
  fixed 2000ms — spreads tighter at SF7, unchanged at SF8
- reactive per-dupe backoff cap now min(2000ms, 12·airtime), keeps
  semantic of "push past ~12 relay slots"
- contention ring 16 → 24 for 50-neighbor hilltops
- companions passively track heard floods (warms EMA without forwarding)
  and spread their own TX by up to min(1000ms, 3·airtime), hopefully
  fixing repeaters missing companion's first transmission

config cleanup:
- move BLE TX buffer bumps (ACL_TX=12 etc.) from zephcore_common.conf to
  esp32_common.conf — the Espressif blob needs them, nRF doesn't, and
  the bumps were overflowing nRF52840 RAM
- remove CONFIG_ZEPHCORE_MAX_CONTACTS=510 overrides from 5 nRF52840
  companion boards; Kconfig default of 350 fits with comfortable margin
  (wio prod: 91% → 79% RAM)
2026-04-17 10:24:12 +02:00
liquidraver e1c04113ca update default prefs 2026-04-14 12:07:52 +02:00
liquidraver 5c3df69621 atomic write (temp + sync + rename) for identity, prefs, and channels 2026-04-13 21:52:40 +02:00
liquidraver a716d2478f port seeed solar p1 + gps command fixes 2026-04-13 11:48:34 +02:00
liquidraver 4f6b0cca27 fix repeater-observer hybrid freezing 2026-04-09 12:23:27 +02:00
liquidraver 0898699c33 patch file CLRF fixup and repeater-observer hybrid first implementation 2026-04-09 11:02:58 +02:00
Rastislav Vysoky da22b127c3 sx1276 2026-04-07 19:05:32 +02:00
liquidraver 7998b5eae3 observer self-advert on mqtt when lat/lon and custom name is set 2026-04-05 17:21:37 +02:00
liquidraver 875e6554d4 Implement MQTT Observer role 2026-04-05 14:34:06 +02:00
liquidraver e115f24b31 buzzer and led queued offline message indicator
- buzzer was bugged when message received
- green led: hearthbeat, blue led: message received indicator (when not connected to app)
- if only one led blinks: hearthbeat 20msec, message received 200msec
2026-04-02 21:06:28 +02:00
liquidraver a1dddbea75 Repeater GPS: separate advert vs telemetry position, persist last fix
GPS fixes no longer overwrite prefs lat/lon — adverts use only
manually-set coordinates (via gps setloc or companion app)

Precise GPS position served via telemetry requests only
getNodeLat()/getNodeLon() returns live GPS fix

Last good fix persisted to /lfs/gps_pos — survives reboots

| Command | Description |
|---------|-------------|
| `gps` | Show GPS status (`on` or `off`) |
| `gps on` | Enable GPS module |
| `gps off` | Disable GPS module |
| `gps setloc` | Update stored latitude/longitude from current GPS fix |
| `gps advert` | Show current location advertising policy |
| `gps advert none` | Do not include location in advertisements |
| `gps advert share` | Include live GPS location in advertisements |
| `gps advert prefs` | Include stored lat/lon from prefs in advertisements |
2026-04-01 11:06:09 +02:00
liquidraver 2051e1b51a telemetry bugfix and "healthcheck" conf for debug logging 2026-03-31 20:35:39 +02:00
liquidraver 0e5e71563c logging cleanup 2026-03-29 09:51:53 +02:00
liquidraver 33fa19a7f5 comment overhaul 2026-03-28 20:53:59 +01:00
liquidraver 8dd6f149f8 sync with arduino/dev 2026-03-24 20:36:36 +01:00
liquidraver e2f13e2292 MSG ui display fix 2026-03-24 14:32:03 +01:00
liquidraver c9013d85d4 update zephyr 2026-03-23 08:56:21 +01:00
liquidraver d794b57e31 APC second test
This reverts commit 4bd84ddf7e.
2026-03-14 21:15:57 +01:00
liquidraver 4bd84ddf7e APC first test 2026-03-14 14:01:10 +01:00
liquidraver d45fbf7027 reactive collision avoidance 2026-03-11 12:08:48 +01:00
liquidraver 98bf9e0eb6 west update 2026-03-09 13:45:22 +01:00