# archy-messh — Architecture & Design Space Target hardware (locked in): **Heltec WiFi LoRa 32 V3** — ESP32-S3FN8, 8MB flash, 512KB SRAM, **no PSRAM**, single SX1262 LoRa radio, dual-core LX7. This doc synthesizes research into Meshtastic, MeshCore, and Reticulum/RNode firmware architecture, identifies the hard constraints the Heltec V3 imposes, and lays out a phased plan toward a single device that can speak to and repeat between all three networks. --- ## 1. The three protocols, side by side | | Meshtastic | MeshCore | Reticulum (RNS + RNode) | |---|---|---|---| | **Default LoRa PHY** (EU) | 869.525 MHz, BW 250 kHz (or 812.5 wide), CR 4:5, **SF 11** | Compiled default identical: `869.525,250,11,5` — but community has since moved to **narrowband SF7-8 / BW 62.5 kHz** (Oct 2025) | No fixed preset — operator-configured freq/BW/SF/CR per deployment | | **Sync word** | Custom `0x2b` (not LoRaWAN's public `0x34`) | Unconfirmed — needs direct check (RadioLib default vs custom) | Whatever the operator configures; not protocol-mandated | | **Frequency selection** | Hashed per channel-name within region plan (hops, not fixed) | Single fixed frequency, no hopping found | Fixed, operator-set | | **Radio chips** | SX126x/SX127x/SX128x/LR11x0/STM32WLE5JC, via RadioLib | Same chip families, also via a RadioLib-based wrapper | SX127x/SX126x/SX128x, custom firmware (not RadioLib) | | **On-air routing** | Pure managed flood: hop_limit/hop_start (3-bit), SNR-weighted CSMA-style contention-window rebroadcast delay, optional learned next-hop since v2.5 | Flood-to-discover path, then **source-routed** reply using a recorded path (path bytes embedded in packet); dedup by content hash (path-independent), 160-entry ring buffer | Host-side `Transport`: announce-based path tables, store-and-forward, no on-device routing at all — RNode is a dumb modem | | **Encryption** | AES-CTR (no auth tag), PSK = literal channel key bytes; **default "LongFast" key is hardcoded/public in source** | Public-channel PSK also a known default; DMs use per-contact ECDH (Ed25519→X25519) secret; **routing metadata (hashes/path) is cleartext, payload only is encrypted** — repeaters relay without decrypting | Ed25519 (signing) + X25519 (ECDH, per-packet *and* per-link) + AES-256-CBC + HMAC-SHA256; destination = truncated SHA-256 hash, not directly tied to a readable identity | | **Node identity** | NodeNum from device MAC | Self-generated Ed25519 keypair, persisted to flash | Identity = Ed25519+X25519 keypair; Destination = hash derived from identity + app name | | **Firmware structure** | One monolithic Arduino/PlatformIO app; maintainers confirm extracting just the mesh layer "would be a lot of refactoring" — RadioLib is the only cleanly reusable piece | `src/` is a genuine shared library (radio HAL, routing, crypto, identity) used by all role binaries (`examples/{companion_radio,simple_repeater,...}`) — more modular than Meshtastic | RNode firmware (device) is a thin modem; all protocol logic lives in host-side RNS (Python) or the C++ port **microReticulum** (ESP32/nRF52, PlatformIO) | | **Documented host-bridge API** | ToRadio/FromRadio protobuf stream over Serial/BLE/TCP ("Client API") — official Python/JS/Android/iOS clients all use this | Companion Radio protocol over BLE (Nordic UART-style) / USB serial, official JS (`meshcore.js`) + Python (`meshcore_py`) clients | KISS-framed serial protocol (FEND/FESC escaping, command opcodes for freq/BW/SF/CR/TX/RX), same approach archy's existing `reticulum.rs` already validated against canonical source | | **Reference ESP32 boards** | Heltec V3, T-Beam (Supreme), Station G2 | Same boards — Heltec V3, T-Beam, Station G2, XIAO+Wio-SX1262 | Same boards again — T-Beam, Heltec V3 all RNode-flashable | **Open items still unconfirmed** (verify in source before relying on them): exact MeshCore sync word / RadioLib default; MeshCore's exact AES cipher mode (sources disagree: AES-128 vs AES-128-ECB vs AES+HMAC); whether any two protocols' *current* real-world default configs ever overlap enough for one static radio config to receive both. --- ## 2. The central constraint: one radio, three networks The Heltec V3 has **exactly one SX1262**. A LoRa radio only demodulates a packet if it's currently configured with the matching frequency, bandwidth, spreading factor, and sync word. Since Meshtastic, MeshCore, and Reticulum each use independently-configured (and, per the table above, currently non-overlapping) PHY parameters, **one radio cannot simultaneously listen to all three networks**. This is true regardless of how clever the software is — it's a property of the radio hardware, not the firmware. That leaves two real options for a single-board device: **A. Time-multiplexed single radio.** Rotate the SX1262 through three PHY configs on a schedule (e.g. 1-2s dwell per network), queueing outbound traffic between windows. Pros: works on a stock, unmodified Heltec V3. Cons: it's a *probabilistic* repeater, not an always-on one — it will miss packets transmitted by other nodes while parked on a different network's config, and rebroadcast latency goes up on all three networks. Network participants assume their peers are always listening; a node that's only half the time will look unreliable to them (more so on networks like Meshtastic where missed CSMA windows + flood timing matter). **B. Add cheap radio breakouts.** The ESP32-S3 has multiple SPI-capable GPIO pairs; 1-2 additional SX1262 breakout modules (~$5-10 each) wired to spare CS/IRQ/RESET lines turn the single Heltec V3 board into a host MCU with **one dedicated radio per network**, each always listening, no time- sharing. This keeps "one device" but is no longer a stock/unmodified board — it requires soldering/wiring. RAM (512KB, no PSRAM) is the harder limit here: running three protocols' framing/routing/crypto state concurrently as FreeRTOS tasks, lean builds will be required regardless (drop WiFi entirely, likely BLE too, cap NodeDB/path-table sizes). **Recommendation: start with A as the v1 proof of concept** (cheapest, zero extra hardware, validates the bridging/translation logic), and treat B as the v2 hardware revision once the time-multiplexed version proves the software design is sound and someone decides duty-cycled coverage isn't good enough. --- ## 3. Recommended phased plan **Phase 0 — De-risk the bridge logic, not the hardware squeeze.** Before fighting RAM and single-radio limits at all, build the message-translation/repeater logic across **three separate official-firmware boards** (e.g. 3 spare ESP32 LoRa boards, one flashed stock Meshtastic, one stock MeshCore companion-radio, one RNode), each talking its own documented serial/BLE client API to a host (a Pi or PC). This validates "can we correctly receive a message on network A and re-originate/repeat it on networks B and C" without touching firmware internals or memory limits at all — pure host-side bridge code against three already-working radios. **Phase 1 — Single Heltec V3, time-multiplexed (Option A).** Port the host-side bridge logic from Phase 0 onto the Heltec V3 itself, replacing "three separate official boards" with "one onboard SX1262 re-tuned on a schedule." This is where Meshtastic/MeshCore/RNode-equivalent framing+crypto needs to be reimplemented in lean, embeddable form (most realistic source for that: MeshCore's `src/` since it's already a reusable library; microReticulum for the Reticulum side; for Meshtastic, RadioLib directly plus a minimal from-scratch reimplementation of just the 16-byte header/AES-CTR/dedup logic documented in ARCHITECTURE — not the full Meshtastic app). **Phase 2 — Multi-radio hardware revision (Option B), if duty-cycled coverage proves insufficient.** Add dedicated radio breakouts so each network gets always-on reception; revisit RAM budget with leaner per- protocol implementations informed by what Phase 1 actually needed. --- ## 4. Why this is more tractable than "reimplement three mesh protocols" All three ecosystems independently converged on the same pattern: **don't reimplement the radio/routing stack — run the real firmware (or a real library) and talk to it over a documented protocol.** That's the basis for Phase 0, and de-risks the project considerably versus a from-scratch clean- room implementation of three different mesh routing algorithms. The harder, protocol-native reimplementation work (needed for Phase 1's single-radio squeeze, since there's no separate module to "talk to" — it's all one firmware image) is least risky for MeshCore (genuinely modular `src/`) and Reticulum (microReticulum already exists as a C++ port, though missing Link/Resource/Channel), and highest risk for Meshtastic (monolithic firmware, no officially separable mesh library — would mean reimplementing the 16-byte header / AES-CTR / PacketHistory dedup / SNR-weighted CSMA rebroadcast logic from spec, documented above, rather than reusing existing code). --- ## 5. Next steps - [ ] Confirm MeshCore's actual sync word / cipher mode against `src/Utils.cpp` and the RadioLib config (open item from §1) - [ ] Phase 0 prototype: pick 3 spare boards, flash stock firmware each, write host-side bridge translating one test message across all three - [ ] Decide on a minimal common internal message format for the bridge (sender id, origin network, payload, hop/path metadata) that all three protocol adapters translate to/from - [ ] Revisit RAM budget once Phase 1's actual per-protocol footprint is known