6.3 KiB
6.3 KiB
name, description
| name | description |
|---|---|
| mesh | Mesh networking development for Archipelago — protocol, crypto, serial driver, transport abstraction, and LoRa chat. Use when working on mesh radio, Meshcore protocol, LoRa messaging, transport layers, peer discovery, or off-grid communication features. |
Mesh Networking Skill
Architecture
The mesh subsystem enables offline peer discovery and end-to-end encrypted messaging between Archipelago nodes via Meshcore LoRa radio devices (Heltec V3, T-Beam, RAK WisBlock).
USB Meshcore Device (115200 baud)
↕ serial2-tokio
core/archipelago/src/mesh/
├── mod.rs — MeshService: lifecycle, config, public API
├── types.rs — MeshPeer, MeshMessage, MeshStatus, MeshEvent
├── protocol.rs — Meshcore binary frame protocol (encode/decode)
├── serial.rs — MeshcoreDevice: async serial driver
├── crypto.rs — X25519 ECDH + ChaCha20-Poly1305 encryption
└── listener.rs — Background tokio task: serial reader + dispatcher
↕ RPC
core/archipelago/src/api/rpc/mesh.rs — 6 endpoints
↕ HTTP
neode-ui/src/stores/mesh.ts — Pinia store
neode-ui/src/views/Mesh.vue — Two-column chat UI
Key Files
Backend (Rust)
core/archipelago/src/mesh/mod.rs— MeshService (start/stop/status/peers/messages/send/configure)core/archipelago/src/mesh/types.rs— All shared typescore/archipelago/src/mesh/protocol.rs— Binary frame format, command builders, response parsers (12 unit tests)core/archipelago/src/mesh/serial.rs— USB serial driver, handshake, device detectioncore/archipelago/src/mesh/crypto.rs— X25519 key agreement + ChaCha20-Poly1305 (7 unit tests)core/archipelago/src/mesh/listener.rs— Background event loop, auto-reconnect, peer cachecore/archipelago/src/api/rpc/mesh.rs— RPC handlers (mesh.status/peers/messages/send/broadcast/configure)core/archipelago/src/server.rs— MeshService initialization (non-blocking)core/archipelago/src/identity.rs— Ed25519 keypair, DID, X25519 derivation
Frontend (Vue 3 + TypeScript)
neode-ui/src/stores/mesh.ts— Pinia store with unread trackingneode-ui/src/views/Mesh.vue— Full chat UI (~1000 lines)neode-ui/src/router/index.ts— Route:/dashboard/mesh
Mock Backend
neode-ui/mock-backend.js— Dev mode mesh RPC responses (mesh.status/peers/messages/send/broadcast/configure)
Protocol Reference
Meshcore Frame Format
- Outbound:
<(0x3C) + 2-byte LE length + data - Inbound:
>(0x3E) + 2-byte LE length + data - Max LoRa payload: 160 bytes
- Baud: 115200, 8N1
Key Commands
| Byte | Command | Description |
|---|---|---|
| 0x01 | APP_START | Init session with version negotiation |
| 0x02 | SEND_TXT_MSG | Direct message (6-byte pubkey prefix) |
| 0x03 | SEND_CHANNEL_TXT_MSG | Broadcast on channel |
| 0x04 | GET_CONTACTS | Fetch contact list |
| 0x06 | SET_DEVICE_TIME | Sync device clock |
| 0x07 | SEND_SELF_ADVERT | Broadcast identity |
| 0x0A | SYNC_NEXT_MESSAGE | Retrieve queued messages |
Identity Wire Format
ARCHY:2:{ed25519_hex_64}:{x25519_hex_64} (137 bytes, fits 160)
Encryption
- X25519 Diffie-Hellman from Ed25519 keys (RFC 7748 clamping)
- ChaCha20-Poly1305 AEAD with random 12-byte nonce
- Wire:
[nonce 12B] + [ciphertext + tag 16B]— max 132B plaintext
RPC Endpoints
| Method | Params | Returns |
|---|---|---|
mesh.status |
— | MeshStatus |
mesh.peers |
— | {peers, count} |
mesh.messages |
{limit?} |
{messages, count} |
mesh.send |
{contact_id, message} |
{sent, message_id, encrypted} |
mesh.broadcast |
— | {broadcast} |
mesh.configure |
{enabled?, device_path?, channel_name?, broadcast_identity?, advert_name?} |
{configured} |
Development Workflow
Building & Testing (on dev server, NOT macOS)
# Deploy mesh changes
./scripts/deploy-to-target.sh --live
# Run mesh unit tests on server
ssh -i ~/.ssh/archipelago-deploy archipelago@192.168.1.228 \
'cd ~/archy/core && cargo test --all-features -- mesh'
# Check device is detected
ssh -i ~/.ssh/archipelago-deploy archipelago@192.168.1.228 \
'ls -la /dev/ttyUSB* /dev/ttyACM* 2>/dev/null'
# Watch mesh logs
ssh -i ~/.ssh/archipelago-deploy archipelago@192.168.1.228 \
'sudo journalctl -u archipelago -f | grep -i mesh'
Frontend Dev (local, mock backend)
cd neode-ui && npm start
# Mesh mock data at http://localhost:8100/dashboard/mesh
Roadmap Phases
Phase 1: Core Implementation (COMPLETE)
- Meshcore binary protocol, serial driver, crypto, listener, RPC, Vue UI
Phase 2: Mesh as Federation Transport
- NodeTransport trait abstraction (mesh/tor/lan backends)
- Transport priority: Mesh (1) > LAN/mDNS (2) > Tor (3)
- Chunked message protocol for >160B payloads (Reed-Solomon FEC)
- CBOR delta sync instead of full JSON state
- Transport indicator per peer in federation UI
- "Mesh only" off-grid mode
- Dependencies:
ciborium(CBOR),reed-solomon-erasure(FEC),mdns-sd(LAN discovery)
Phase 3: Encrypted Mesh Messaging
- Double Ratchet (Signal protocol) over LoRa
- X3DH key agreement using existing Ed25519/X25519
- Store-and-forward relay for offline peers (24h TTL)
- Message types: TEXT, ALERT, INVOICE (bolt11), PSBT_HASH, COORDINATE
- Per-peer chat threads, delivery status, offline indicators
Phase 4: Off-Grid Bitcoin Operations
- Compact block headers over mesh (SPV verification)
- Transaction relay via internet-connected mesh peer
- Lightning payment coordination over mesh
- Emergency alert system (signed alerts, GPS, dead man's switch)
Phase 5: Mesh Network Intelligence
- Adaptive routing, signal strength mapping, spreading factor adjustment
- Multi-path routing for reliability
- Steganographic modes
- Additional hardware: T-Beam, RAK WisBlock, WiFi mesh (802.11s), BLE, Blockstream Satellite
Conventions
- All crypto uses existing identity infrastructure (Ed25519 signing key → X25519 derivation)
- Mesh init is non-blocking — errors logged but don't crash server
- Config persists to
{data_dir}/mesh-config.json - Message buffer: circular, max 100 messages
- Never build Rust on macOS — always deploy to server
- USB device paths:
/dev/ttyUSB*and/dev/ttyACM* archipelagouser must be indialoutgroup for serial access