Add Phase 0 host-bridge: relay text across Meshtastic, MeshCore, Reticulum
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# host-bridge (Phase 0)
|
||||
|
||||
A host-side Python bridge that connects to one radio per network —
|
||||
Meshtastic, MeshCore, and Reticulum (via an RNode-flashed board) — over
|
||||
each project's **official** client protocol, and relays text messages
|
||||
between all three. See `../docs/ARCHITECTURE.md` for why this is Phase 0
|
||||
(prove the cross-network translation logic on 3 separate boards, no
|
||||
custom firmware) rather than Phase 1 (one time-multiplexed radio on a
|
||||
single Heltec V3).
|
||||
|
||||
## Status
|
||||
|
||||
**Written, not yet hardware-tested.** Every library call has been checked
|
||||
against the upstream project's actual source/docs (see comments in each
|
||||
`adapters/*.py` file for what was verified and how), and all four
|
||||
dependencies (`meshtastic`, `meshcore`, `rns`, `lxmf`) install and import
|
||||
cleanly. What's unverified is the actual on-air behavior once real radios
|
||||
are attached — that requires the three boards described below.
|
||||
|
||||
## What you need to test this for real
|
||||
|
||||
- A Meshtastic-flashed board (e.g. Heltec V3) connected via USB serial or reachable over TCP (ESP32 WiFi build)
|
||||
- A MeshCore companion-radio-flashed board, serial or TCP
|
||||
- An RNode-flashed board (any RNode-compatible LoRa board) reachable via RNS's serial interface — configure this the same way archy's own `core/archipelago/src/mesh/reticulum.rs` KISS interface does, since this bridge uses the standard `rns`/`lxmf` Python packages, not a custom implementation
|
||||
- All three radios need actual antennas/RF range to each other's respective real-world networks to see any traffic worth relaying — this is not simulatable without a radio in the loop
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
python3 main.py \
|
||||
--meshtastic-port /dev/ttyUSB0 \
|
||||
--meshcore-port /dev/ttyUSB1 \
|
||||
--reticulum-storage ./rns-storage
|
||||
```
|
||||
|
||||
Use `--meshtastic-host`/`--meshcore-host` instead of the `-port` flags if a
|
||||
board is reachable over TCP (e.g. an ESP32 WiFi build) instead of USB
|
||||
serial. Run `python3 main.py --help` for the full flag list.
|
||||
|
||||
## How relaying works
|
||||
|
||||
Each adapter pushes received text onto a shared, thread-safe queue
|
||||
(`bridge_core.MessageBus`). A single dispatcher loop in `main.py` pulls
|
||||
each message off, tags it with its origin network + sender, and re-sends
|
||||
it on the other two networks — never back onto the network it came from.
|
||||
|
||||
Content-hash dedup (`MessageBus.is_duplicate`, 5-minute TTL by default)
|
||||
stops the obvious relay loop (the bridge re-hearing its own relayed
|
||||
copy). This is a known-simple v0 approach — it can't distinguish two
|
||||
different messages that happen to have identical text within the TTL
|
||||
window, and it doesn't help if there are *multiple* archy-messh bridges
|
||||
active near each other. Good enough to prove the concept; revisit once
|
||||
Phase 1 needs something more robust.
|
||||
|
||||
## Known gaps (by design, for v0)
|
||||
|
||||
- **Reticulum has no broadcast-channel primitive.** Meshtastic has channel
|
||||
PSKs, MeshCore has public channel indices — Reticulum/LXMF messaging is
|
||||
point-to-point between Destinations. `ReticulumAdapter` fakes broadcast
|
||||
by tracking a roster of peer delivery-destinations learned from their
|
||||
LXMF announces and fanning out to all of them individually. A shared
|
||||
symmetric-key Reticulum `GROUP` destination would be a closer analog to
|
||||
a real channel — noted as a follow-up, not implemented here.
|
||||
- **MeshCore channel messages carry no sender identity at the protocol
|
||||
level** (verified against `meshcore/reader.py` — `CHANNEL_MSG_RECV` has
|
||||
no pubkey/name field). MeshCore apps convey sender identity by
|
||||
convention inside the message text itself; this bridge doesn't attempt
|
||||
to parse that out, so messages relayed *from* MeshCore show `?` as the
|
||||
sender.
|
||||
Reference in New Issue
Block a user