- Rebrand to RTC (Reticulum / meshTastic / meshCore); Meshtastic row = T.
- On-chip Meshtastic decode (mbedtls AES-128-CTR + protobuf) surfacing text
and node short-names, mirroring firmware/tools/meshtastic_decode.py.
- Device identity 'Reticutasticore' / 'RTC' (DEVICE_NAME) baked in for all
three networks; boot splash shows it.
- Trippy OLED: acid smiley with a periodic spinning-striped freak-out
(googly eyes + gaping mouth), punk 'bubble' RTC header, three live network
rows (counts + RX blips), last-decoded line.
- Hardware-confirmed: Meshtastic + MeshCore both received (0x12 MeshCore
sync word guess validated); Reticulum still placeholder.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AES-128-CTR (public LongFast key) + minimal protobuf walk. Verified against
packets our scanner captured on-air: decoded a live NodeInfo (longName
'Arch Optiplex', shortName 'ARCH') and POSITION packets. Serves as the
reference for the on-chip C++ port in src/main.cpp.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add SSD1306 UI to the Phase 1 scanner: an animated acid smiley inside
expanding psychedelic rings, an 'RMC' (Reticulum/Meshtastic/meshCore)
strobe header, and three live network rows with per-network packet counts
and RX activity blips. Scan loop made non-blocking (millis-based dwell) so
the display animates smoothly (~20fps) while the radio rotates.
Honest note in-code: the single SX1262 is time-sliced across the three
PHYs (ARCHITECTURE.md §2); the UI shows all three armed but true concurrent
RX needs added radios (Phase 2). Pins U8g2 2.36.18.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First Phase 1 increment toward the single-device 3-in-1: one Heltec V3
(ESP32-S3 + single SX1262) rotating the radio through the Meshtastic /
MeshCore / Reticulum PHY presets, logging every raw packet it demodulates
per dwell window. No framing/crypto/bridge yet — proves the RX loop first.
Validated on hardware: radio.begin() clean, all three presets cycle, and
the Meshtastic window received live broadcast packets (-36..-41 dBm). The
single-radio time-multiplex premise (ARCHITECTURE.md §2) holds.
MeshCore sync word and Reticulum PHY are flagged placeholders in CONFIGS[].
Deps pinned (espressif32 7.0.1, RadioLib 7.7.1). Adds venv/pycache/storage
to .gitignore.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dispatcher deduped on inbound text but relayed a prefixed copy
("[net/sender] text"), so a re-heard relayed message hashed differently
and was re-relayed, stacking another prefix each hop — an unbounded loop,
exactly what the dedup was meant to prevent.
Add MessageBus.mark_seen() and record the on-air relayed string before
sending, so the bridge recognises and drops its own relayed copies.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
close() stopped the asyncio loop without disconnecting first, leaving the
EventDispatcher._process_events() task and the serial transport pending
("Task was destroyed but it is pending!" / "Event loop is closed").
Now await MeshCore.disconnect() and let the transport's connection_lost
callback settle before stopping the loop, then join the thread.
Found by running the adapter against a live MeshCore-flashed Heltec V3.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>