An open-source gateway that bridges Meshtastic LoRa mesh networks to the Iridium satellite constellation via Short Burst Data (SBD). One gateway device provides satellite backhaul for an unlimited number of mesh nodes — instead of paying per device like Garmin and ACR charge.
Overview
| Aspect | Details |
|---|---|
| Function | Bidirectional Meshtastic ↔ Iridium SBD bridge |
| Hardware | Raspberry Pi 5, Lilygo T-Echo, RockBLOCK 9603 |
| Backend | Go 1.24 (chi router, SQLite) |
| Frontend | Vue.js 3 (SSE, Leaflet maps) |
| Deployment | Docker multi-arch (ARM64 + x86_64) |
| License | GPLv3 |
| Repository | github.com/cubeos-app/meshsat |
Why MeshSat
Consumer satellite communicators like Garmin inReach and ACR Bivy Stick MESH charge per person or cap at 12 devices. A 20-person expedition pays €300/month for individual Garmin subscriptions. MeshSat replaces that with a single €15/month satellite link shared across the entire mesh network.
| Garmin inReach | ACR Bivy MESH | MeshSat | |
|---|---|---|---|
| Mesh support | None | 12 devices max | Unlimited nodes |
| Monthly cost (20 users) | €300+ | €240+ | €15 + credits |
| Custom data | Text only | Text only | Any payload |
| Open source | No | No | Yes |
| Vendor lock-in | Yes | Yes | No |
Architecture
┌──────────────────────────────────────────────────────────────┐
│ Meshtastic Mesh Network │
│ T-Echo / T-Deck / Heltec V4 / RAK nodes │
└──────────────────────────┬───────────────────────────────────┘
│ LoRa 868/915 MHz
▼
┌──────────────────────────────────────────────────────────────┐
│ MeshSat Gateway │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ Meshtastic │ │ Processor │ │ Iridium SBD │ │
│ │ Transport │──│ Bridge Rules│──│ Transport │ │
│ │ (protobuf) │ │ SOS Engine │ │ (AT commands) │ │
│ └─────────────┘ └──────────────┘ └────────────────────┘ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ Pass │ │ SQLite DB │ │ Vue.js Dashboard │ │
│ │ Predictor │ │ DLQ + Queue │ │ (SSE real-time) │ │
│ │ (SGP4/TLE) │ │ │ │ │ │
│ └─────────────┘ └──────────────┘ └────────────────────┘ │
└──────────────────────────┬───────────────────────────────────┘
│ 1.6 GHz L-band
▼
┌──────────────────────────────────────────────────────────────┐
│ Iridium Satellite Constellation │
│ 66 LEO satellites, 780 km altitude │
└──────────────────────────────────────────────────────────────┘
Key Features
Bidirectional Message Bridge
Configurable bridge rules filter which messages cross to satellite — by node ID, channel, or message type. Prevents position beacons and telemetry from burning credits while ensuring important messages get through. Dead-letter queue with automatic retry handles failed transmissions.
SGP4 Satellite Pass Prediction

Predicts Iridium satellite passes using CelesTrak TLE data and SGP4 orbital propagation. The dashboard overlays predicted pass windows with actual signal strength history, showing correlation between high-elevation passes and successful transmissions. Enables modem sleep/wake scheduling based on when satellites are actually overhead, instead of blind retry against a mountain.
Multi-Source Positioning
Three GPS sources with graceful degradation: primary GPS (Heltec V4 or USB dongle, ~2-5m accuracy) → Iridium geolocation (free with every SBD transmission, ~1-100km accuracy) → custom fallback. The Iridium geolocation is accurate enough for pass prediction, allowing GPS-free operation after the first satellite exchange.
Emergency SOS
Dedicated ARM/SEND controls with immediate Iridium transmission path. SOS bypasses all filtering and queuing — when the button is pressed, the message goes to satellite immediately.
Zero-Dependency Hardware Access
Hand-rolled protobuf codec and AT command engine for direct serial communication. USB auto-detection via sysfs VID:PID matching — plug in hardware and MeshSat finds it. No manual port configuration, no external libraries for hardware access.
Technical Implementation
Direct Serial Transport (~2,100 lines)
Five Go source files implementing full protocol handling:
- proto.go — Hand-rolled protobuf primitives (varint, length-delimited, tag parsing)
- serial.go — Shared serial layer with Meshtastic framing (0x94 0xC3 header) and AT command engine
- meshtastic_proto.go — Full Meshtastic protocol: parsers for FromRadio, MeshPacket, NodeInfo, Position, DeviceMetrics; builders for text messages, admin commands, traceroute, waypoints
- direct_mesh.go — DirectMeshTransport: auto-detection (7 VID:PIDs), wake sequence, config handshake, background reader with heartbeat, node DB, message ring buffer
- direct_sat.go — DirectSatTransport: AT probe with GPS/Meshtastic exclusion, SBDIX with rate limiting, ring alert monitor, signal poller, binary SBD with checksum
Challenges Solved
Serial mutex starvation: SBDIX sessions hold the serial port for 11-62 seconds. Combined with aggressive polling, the mutex was permanently held — signal reads returned 0, outbound sends blocked. Redesigned with context-aware rate limiting and mid-sleep mutex release.
SBD piggybacking: Mobile-Terminated messages delivered during outbound SBDIX were silently lost across 4 separate code paths (HAL response fields, MeshSat parser, forward/DLQ/drain checks). Traced and fixed all 4.
Obstructed environments: Built satellite pass predictor correlating predicted passes with actual signal history. Enables intelligent sleep/wake scheduling instead of blind retry against mountain walls.
Tested Hardware
| Device | Model | Interface |
|---|---|---|
| Meshtastic radio | Lilygo T-Echo (nRF52840 + SX1262) | USB Serial |
| Satellite modem | Iridium 9600 SBD Transceiver (RockBLOCK 9603) | USB Serial (FTDI) |
| Host | Raspberry Pi 5 | Docker / CubeOS |
Deployment
Docker one-liner:
docker run -d --privileged \
-v /dev:/dev -v /sys:/sys \
-p 8080:8080 \
ghcr.io/cubeos-app/meshsat:latest
Also runs as a managed CubeOS application via HAL (Hardware Abstraction Layer), or standalone on any Linux machine with USB ports.
Technology Stack
| Layer | Technology |
|---|---|
| Backend | Go 1.24, chi router, SQLite |
| Frontend | Vue.js 3, Leaflet maps, SSE |
| Protocols | Meshtastic protobuf, Iridium SBD AT commands |
| Prediction | SGP4 orbital propagation, CelesTrak TLE |
| Deployment | Docker multi-arch, GHCR |
| Integration | CubeOS HAL (optional) |
| License | GPLv3 |
Current State
Bidirectional satellite bridge working end-to-end on Raspberry Pi 5. Messages flow both ways through the Iridium constellation. The dashboard shows mesh nodes, satellite signal, SBD queue depth, and predicted pass windows in real time.
Part of the CubeOS ecosystem. Also available as a product — see the Products page .
