2026-03-17 00:03:08 +00:00

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 types
  • core/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 detection
  • core/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 cache
  • core/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 tracking
  • neode-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*
  • archipelago user must be in dialout group for serial access