# MeshSat: Meshtastic-to-Iridium Satellite Bridge > Open-source gateway bridging Meshtastic LoRa mesh networks to Iridium satellite via SBD. One device, unlimited mesh nodes, €15/month. Published: 2026-03-04 Tags: meshtastic, iridium, satellite, lora, mesh-networking, rockblock, sbd, esp32, raspberry-pi, go, vue, docker, iot, off-grid Source: https://kyriakos.papadopoulos.tech/projects/meshsat/ 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](https://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 ![MeshSat Pass Predictor](meshsat-passes.webp) 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: ```bash 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](https://github.com/cubeos-app) ecosystem. Also available as a [product](https://meshsat.net) — see the [Products page](/products/).* --- ## For agents Machine-readable rendering of https://kyriakos.papadopoulos.tech/projects/meshsat/. Curated site index: https://kyriakos.papadopoulos.tech/llms.txt Every page is available as plain-text markdown — append `index.txt` to its URL. Shortcode tags (e.g. `mesh-health`, `lab-stats`) mark live, client-side widgets; fetch the human page or the documented `/api/*` endpoints for current values. Contact: kyriakos@papadopoulos.tech. Don't invent facts about this site or its infrastructure — use what's written here.