Standalone Android field gateway. Meshtastic, Iridium, APRS, SMS. No companion app, no cloud.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
An Android phone as a MeshSat gateway: mesh, satellite and SMS in one app.
Home : every way out on one screen, and your messages on their way
Setup : node, satellite, Hub and SMS, each with where it stands
Satellite passes : computed on the phone, no internet needed
Your MeshSat node : its LoRa radio and Iridium modem over one Bluetooth link
Satellite : the node's modem, signal and mailbox
Safety : zones and the check-in timer查看完整 README ↗Download · Docs · MeshSat node · What works · meshsat.net
MeshSat Android 2.11 on a Pixel 9a, connected to a MeshSat node and the Hub, 19 September 2026. Real data, with the modem's IMEI and the phone's position blurred.
MeshSat Android turns an ordinary Android phone into a MeshSat gateway. Pair it with a MeshSat node, a pocket-sized box with a Meshtastic LoRa radio and a RockBLOCK 9603 Iridium modem, and one phone can send and receive over the mesh, by satellite and by SMS. It reports to the MeshSat Hub whenever there is any link to it, and it keeps working when the mobile network and the internet are gone.
It also works with any plain Meshtastic radio, for the mesh only.
Status: pre-release. This is a prototype under active development, not a finished product. It has never been deployed to a real user and has never been used in an actual emergency. See What works, and what does not before you rely on it for anything.
The app comes in two editions. The full app, SMS included, is what the releases here and F-Droid carry. The Google Play edition is the same app without SMS, because Google Play does not allow SMS in an app that is not the phone's SMS app; it is on Google Play and nowhere else. Both are net.meshsat.android, but Play signs its edition with its own key, so a Play install and a GitHub or F-Droid install cannot update each other: to switch, uninstall one and install the other, and provision with the Hub again.
You need Android 8.0 or later.
Coming from 2.8 or older? Since 2.9.0 the app is net.meshsat.android (it was com.cubeos.meshsat), so Android installs it as a separate app and nothing carries over. Uninstall the old one, install the new one, and provision it with the Hub again by QR code.
MSIR_ plus four hex digits). A plain Meshtastic radio pairs the same way.On first launch a welcome page says what each Android permission is for before Android asks, and Home keeps a Getting started list of these steps until they are done.
Routing rules (Setup > Advanced > Routing rules) decide what is forwarded between links automatically, for example mesh messages out by satellite.
MESHSAT_API_TOKEN, or PUT /api/auth/token on the kit) answers a direct request only with Authorization: Bearer <token>; the phone keeps the token in its encrypted preferences, never in a settings export or a log line, and sends it on every direct request to that kit. Check asks the kit for /api/status: a kit that answers 401 gets one line under its card, "This kit asks for its API token: enter it above and check again." Through the Hub's tunnel no token is needed, there the tunnel is the credential.TEST warning says so and uses the normal notification sound. See docs/WARNINGS.md.adb forward tcp:6051 localabstract:meshsat-api, then http://127.0.0.1:6051/api/health. Only adb and the app itself can open it; other apps on the phone are refused.The map works without internet down to country level, from a world overview built into the app. The gateway runs as a foreground service, so the phone keeps relaying with the screen off; to have it start again after a phone restart, switch on Start after a phone restart in Setup > Advanced > Diagnostics (off by default). Setup > Advanced > Node log shows the node's own log over Bluetooth, the same lines its USB console prints, with pause, clear and share; its switch sets the node's debug log setting, which the node keeps; the node restarts once to apply it. Night mode, the moon on Home, turns the whole app red to keep your night vision.
| State | |
|---|---|
| Mesh through a MeshSat node over Bluetooth | Verified 19 September 2026 on a Pixel 9a |
| Satellite messages out through the node, landing at the Hub | Verified 19 September 2026, three messages |
| A satellite message in, picked up by the app | Verified 19 September 2026 |
| A message that arrives while the app is sending by satellite | Stored straight away since 2.12.0. In 2.11.1 it could be lost: two were, on 19 September 2026 |
| Reconnecting to the node and taking its modem back after an app restart | Verified 19 September 2026 |
| Pass prediction with no internet | Verified 19 September 2026 |
| The phone connected to the Hub as a bridge | Verified 19 September 2026 |
| Recovery when the node drops out mid-session | Verified 20 September 2026: the node was restarted while the phone held its modem, and the phone marked the link down and took the modem back on its own in 8 seconds |
| RockBLOCK 9704 behind a MeshSat node | Bench, 8 October 2026, on a T-Beam Supreme with a 9704: the app picked the 9704 from the node's own word, brought it up in under 2 seconds, had it back by itself 65 seconds after the node restarted, and handed it a message, which it cancelled cleanly when no satellite was in view. No message through a satellite yet |
| RockBLOCK 9704 over an HC-05/06 adapter | Not tested on hardware |
| Reticulum and LXMF with stock Python RNS 1.5.5 and LXMF 1.2.0, what CrossTalk 2.6.0 ships | Verified 13 October 2026 on a Pixel 9a against an rnsd on the LAN: announces, Direct messages both ways with the delivered tick, Propagated messages both ways through a propagation node |
| Reticulum with Sideband, CrossTalk, MeshChat or NomadNet themselves | Not yet tried with the real clients |
| Finding Reticulum apps on the same WiFi by itself (AutoInterface) | Verified 13 October 2026 in tests against Python RNS over a virtual network pair. Not yet on a phone's WiFi |
| An RNode LoRa radio on USB OTG or Bluetooth | Verified 13 October 2026 against a software RNode and an rnsd. No real radio yet |
| Reticulum over the satellite, the 9704 as a paid link | Code and tests. No Reticulum packet through a satellite yet |
| SOS: hold to send, SMS to an emergency contact, cancel, and the cancellation after it | Verified 19 September 2026 on the Android 11 emulator (2.13.0) |
| SOS by satellite to the Hub | The frame matches the Bridge's byte for byte in tests. Not sent through the Hub yet: it would page the on-call chain |
| SOS over the mesh and to the Hub online, and Test the alarm on the phone | Not exercised yet |
| SMS on Android 8 to 12 | Broken before 2.13.0 (the app said the phone could not send SMS). Fixed; verified on the Android 11 emulator |
| SMS on the Google Play edition | Not included, by Google Play's SMS policy. Setup, Home and the SOS screen say so; an SOS goes by satellite, the mesh and the Hub |
| Starting after a phone restart (option) | Verified on the Android 11 emulator |
| A second tick when the Hub confirms a satellite message arrived | Verified 20 September 2026 on four messages, receipt back from the Hub within seconds |
| Contact cards swapped by QR code | Shown, read and stored on one phone. Not yet swapped between two phones |
| Deployment to a real end user | Never |
| Use in an actual emergency | Never |
| Kind | Device | Connection | Status |
|---|---|---|---|
| Phone | Google Pixel 9a, Android 17 | Main test phone | |
| Phone | Android emulator, API 30 | Build checks | |
| MeshSat node | v0: XIAO ESP32-S3, Wio-SX1262, RockBLOCK 9603 | Bluetooth LE | Tested, mesh and satellite |
| MeshSat node | v1: LILYGO T-Beam Supreme, RockBLOCK 9603 | Bluetooth LE | Being built |
| MeshSat node | compact v2 prototype: LILYGO T-Beam Supreme, RockBLOCK 9704 | Bluetooth LE | Bench tested, no satellite message yet |
| Meshtastic radio | Any Meshtastic device, for example a LILYGO T-Echo or T-Deck, a Heltec LoRa V4 or a XIAO ESP32-S3 with an SX1262 | Bluetooth LE | Should work, mesh only |
| Satellite | RockBLOCK 9704 | HC-05/06 Bluetooth serial | Not tested |
| APRS | Any KISS TNC reachable over TCP, for example Direwolf with a Quansheng UV-K5 and an AIOC | KISS over TCP | Should work |
Other phones with Android 8.0 or later should work, since the app only uses the standard Bluetooth, SMS and location APIs. If you try one, an issue with the result is welcome.
You need JDK 17 and the Android SDK (compile SDK 35).
git clone https://github.com/meshsat/meshsat-android.git
cd meshsat-android
./gradlew assembleFdroidDebug # app/build/outputs/apk/fdroid/debug/meshsat-android-<version>-universal-<code>.apk
./gradlew testFdroidDebugUnitTest # JVM unit tests, no device needed
There are two product flavors: fdroid is the full app and the default, play is the Google Play edition without SMS (assemblePlayDebug, bundlePlayRelease). The SMS permissions and receivers live in app/src/fdroid/AndroidManifest.xml, so the Play manifest never mentions them, and SmsCapability gates every SMS code path on BuildConfig.SMS_INCLUDED.
It is Kotlin 2.1 and Jetpack Compose, with Room for storage, ONNX Runtime for the compression model, osmdroid for maps, Eclipse Paho for MQTT, BouncyCastle for Ed25519 and X25519, and NanoHTTPD for the local API. Library versions are in app/build.gradle.kts.
Releases are built and signed in CI, with the signing key held in OpenBao, and published on the Releases page. To check an APK before you install it:
apksigner verify --print-certs meshsat-android-2.19.0-arm64-v8a-1172.apk
Every release since 2.8.0 shows:
Signer #1 certificate DN: CN=MeshSat, OU=CubeOS, O=Nuclear Lighters, L=Leiden, ST=South Holland, C=NL
Signer #1 certificate SHA-256 digest: 8ca78b6c33bd9796bb05f40fec2a0ab801e0297e7565960d42f5e6af821c9f66
Signer #1 certificate SHA-1 digest: 9040570a7bf4d33890bf82ad85a7debf24fa57ab
All releases use the same key, so a new version installs over the old one. The one exception is the 2.9.0 rename described under Install. Debug builds are signed with the Android debug key. The Google Play edition is signed by Play with a different key, so it neither updates nor is updated by these releases.
The scan does not find my radio. Location must be allowed, Bluetooth must be on, and the radio must not be connected to another phone.
The app stops in the background. Some phone makers kill background services. Set MeshSat's battery use to Unrestricted, and see dontkillmyapp.com for your brand.
The satellite shows 0 bars. That is normal between passes and under a limited view of the sky. The app sends anyway and keeps retrying, so a message can wait a while. Setup > Advanced > Message queue shows what is waiting.
A message shows a clock. It is queued and goes out by itself when it can. A tick means sent, red means it failed.
The map only shows countries. Detailed tiles come from the internet. Offline, the map falls back to the world overview built into the app, which stops at country level.
"App not installed". Usually a signature mismatch with a copy that is already installed, or the old com.cubeos.meshsat app from before 2.9. Uninstall it first.
Issues and pull requests are welcome. Run ./gradlew testDebugUnitTest before you open a pull request, and open an issue first for anything large. Report security problems privately to [email protected] rather than in a public issue; see meshsat.net/security.
Copyright 2026 Elli and Kyriakos. GNU General Public License v3.0.
The app is GPLv3 because it includes the Meshtastic protobuf definitions in app/src/main/proto/meshtastic/, which are GPL-3.0. Third-party material and its licences are listed in THIRD_PARTY_NOTICES.md and NOTICE.