Commit Graph
22 Commits
Author SHA1 Message Date
swaitsandClaude Opus 4.6 86d35bf80a feat(examples): add SNR-based packet filtering to LoRa bridge
Drop INVALID and UNRELIABLE packets per PROTOCOL.md quality grading
to avoid retransmitting likely-corrupt data. MARGINAL packets are
forwarded with a warning tag. All RX log lines now include SNR.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:33:56 -06:00
swaits 9ffa5c10d6 docs: add cd examples, mux usage, and Linux device permissions to READMEs 2026-04-03 10:43:28 -06:00
swaits 89c2d51693 chore: massive repo reorganization 2026-04-03 10:28:38 -06:00
swaitsandClaude Opus 4.6 405f4f2f13 chore: tooling improvements
- Add cargo-binutils to mise.toml (needed for `just size`)
- Remove jj from mise.toml (optional, not a build dependency)
- Silence `mise install` output when tools are current (--quiet)
- Add `just outdated` recipe with embassy-executor exclusion
  (esp-rtos 0.2 pins embassy-executor ^0.9; 0.10 renamed arch-*
  features to platform-*, which crashes cargo-outdated)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:57:44 -06:00
swaitsandClaude Opus 4.6 d01de9d14d fix: MeshCore spec compliance audit and packet quality warnings
Audited against meshcore-spec and fixed all compliance gaps:

- Fix trace hash size encoding: use 1<<(flags&3) not (flags&3)+1
- Reject reserved path hash_size_code 3 per spec Section 3
- Minimum packet size 3 bytes (was 2)
- Add MAX_PACKET_PAYLOAD (184) and min payload (1) validation
- Tighten payload minimums: ANON_REQ≥51, encrypted≥20, group≥19,
  multipart≥2
- Add node_type 0 ("none") to NODE_TYPES
- Fix node_type fallback display (was "node=type=14", now "node=0x0e")

Add packet quality warnings for likely-corrupt frames:
- decode_meshcore_packet returns (str, list[str]) with quality warnings
- ADVERT: flag bad node_type, bad UTF-8 in name, future/bad timestamps
- Combine content warnings with low-SNR signal at display layer
- Warnings stack: one flag = maybe, multiple = high confidence corrupt

Update test corpus and generators for tightened validation rules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:57:32 -06:00
swaitsandClaude Opus 4.6 d551095f3f chore: stop tracking generated corpus and pycache
These paths are already in .gitignore but were committed before the
ignore rules existed. Remove them from the index so they stay local.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:57:14 -06:00
swaits 83a76d4b48 chore: update tooling (mise, justfile, examples)
Add mise.toml for tool version management, rename Justfile to justfile,
add examples/justfile for running Python examples, and update docs.
2026-03-31 17:31:47 -06:00
swaits dd3b7c195f feat: add #nodeops, #weekly-net, #net, #repeater-ops channels 2026-03-30 17:40:23 -06:00
swaits 228a0cbf65 fix: clean up meshcore_rx.py output to match themed styling
Replace raw dict dumps and debug-style prints with consistent
themed output using >>> / <<< markers and formatted responses.
Quiet TxDone noise, dim status messages, and align all output
with the 2-space indent used by RX packet lines.
2026-03-30 16:21:45 -06:00
swaits 02dfa4844a chore: change display timeout in meshcore_rx example to 90s 2026-03-30 11:33:24 -06:00
swaits 1fbbf110bc feat: GetMac command + MacAddress response
New protocol command (tag 8): GetMac returns the board's 6-byte hardware
address. Useful when multiple dongles are connected to one host.

Response (tag 6): MacAddress containing 6 raw bytes.

Updated: PROTOCOL.md, CHANGELOG, donglora.py decoder, all_commands.py.
2026-03-30 09:08:59 -06:00
swaits 9cdacc51f5 feat: lora_bridge.py — two-way LoRa bridge over TCP (Tailscale, WireGuard, etc.) 2026-03-30 08:51:15 -06:00
swaits 583bfb72e2 feat: auto-off display after 60s idle in meshcore_rx.py, wake on RX activity 2026-03-30 08:47:24 -06:00
swaits f54579bfde feat: decode Config response in donglora.py, add all_commands.py example
Config response (GetConfig) now returns decoded RadioConfig fields instead
of raw hex. New all_commands.py exercises all 8 protocol commands in
sequence — Ping, SetConfig, GetConfig, StartRx, StopRx, Transmit,
DisplayOff, DisplayOn.
2026-03-29 22:24:46 -06:00
swaits 9a13c4b951 fix: handle SerialException gracefully in all example scripts
All examples now catch serial.SerialException instead of crashing with
a traceback. This covers port contention (multiple processes), device
disconnect, and USB errors. meshcore_rx.py already had this.
2026-03-29 22:01:20 -06:00
swaits 4e221486ee fix: remove stale postcard/serde references from README, DESIGN.md, CHANGELOG, donglora.py 2026-03-29 21:47:03 -06:00
swaits 7a947a1a05 refactor: update Python examples for fixed-size LE wire format
Remove all varint/zigzag encoding. Every field is now struct.pack/unpack
with fixed-size little-endian format strings. RadioConfig is a single
struct.pack('<IBBBHB', ...) call. Response decoding uses struct.unpack_from
with known offsets. No encoding helpers needed beyond struct.
2026-03-29 20:42:59 -06:00
swaits ebe9197d04 feat: per-board TX power range, TX_POWER_MAX sentinel (-128)
- Each board exports TX_POWER_RANGE constant (min, max dBm)
- RadioConfig::validate() uses the board's range, not hardcoded limits
- TX_POWER_MAX sentinel (-128 on the wire) means "use board's maximum"
  — resolved to the actual max before storing config
- GetConfig returns the resolved actual power, not the sentinel
- Default configs in examples use TX_POWER_MAX
- Protocol docs updated
2026-03-29 20:42:58 -06:00
swaits 0b4eb04591 fix: correct postcard encoding for u8/i8 fields (was using varint/zigzag)
ROOT CAUSE: postcard encodes u8 and i8 as raw bytes, NOT varint/zigzag.
The Python encoders used varint() for u8 and zigzag() for i8. For small
values this was silently correct (varint(7) == raw byte 7), but for
tx_power_dbm: zigzag(14) = 28, which the new validation correctly
rejected as out of range (-9..22). This was a pre-existing bug masked
by the absence of validation.

Fix all RadioConfig field encoders in both donglora.py and meshcore_rx.py.
Fix docs/PROTOCOL.md to correctly document i8 as raw byte, not zigzag.
Restore full config validation.
2026-03-29 20:42:58 -06:00
swaits 8a5d8c419e refactor: relocate MeshCore tools to examples/meshcore/
MeshCore is a protocol implementation ON TOP of DongLoRa, not part of the
dongle itself. Moving it to examples/ makes the separation clear while
keeping it accessible as a real-world usage example.
2026-03-29 20:42:58 -06:00
swaits 8790ebfd7b feat: example scripts (simple_rx, simple_tx, ping_pong) with shared donglora.py helper 2026-03-29 20:42:58 -06:00
swaits eab42e9ad8 fix: invert only RX/TX letters, not surrounding spaces in display 2026-03-29 20:42:56 -06:00