- Kotlin 100%
Location tracking was hardcoded to FusedLocationProviderClient, which silently delivers no fixes on devices without Google Play Services (e.g. GrapheneOS without the sandboxed compatibility layer) since the failed Task was never observed. WardriveLocationTrackerFactory now picks Fused when available and falls back to the native LocationManager (GPS/NETWORK provider) otherwise, so tracking keeps working either way. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| app | ||
| gradle | ||
| .gitignore | ||
| app-logo.png | ||
| build.gradle.kts | ||
| Columba_RPC_Setup.md | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| LICENSE | ||
| README.md | ||
| settings.gradle.kts | ||
RNS Wardrive
An Android wardriving app that broadcasts GPS location over the Reticulum Network Stack (RNS) via a shared instance.
What it does
- Runs a persistent foreground service that tracks your GPS position and periodically sends it to a wardrive collector bot over RNS
- Supports three operating modes: Announce (broadcast), Packet (direct unicast to bot), and Probe (bi-directional unicast that exchanges RSSI/SNR link telemetry in both directions for link quality mapping)
- Displays your live position on an interactive MapLibre map with a trail of sent beacons
- Shows a transmission log with per-entry acknowledgement status (for Probe mode)
- Smart Updates: skip transmissions if you haven't moved more than a configurable distance threshold
Requirements
- Android 10+ (API 29)
- An RNS shared instance accessible from the device — provided by an app such as Columba or Sideband running on the same device
rns-wardrive-toolsrunning server-side — provides the collector bot that receives your beacons and does the actual wardrive tracking. The app discovers reachable bots from their RNS announces.
Download & Install
Download the latest APK from the releases page and install it on your device.
Prefer to build it yourself? See Building at the bottom.
Setup
-
Install and open the app. Grant location permissions when prompted (including "Allow all the time" for background tracking).
-
Set up the collector bot. Your beacons need somewhere to go — install and run
rns-wardrive-tools, which provides the wardrive collector bot/server. Note the bot's RNS destination hash; you'll need it below. -
Start Columba (or another RNS shared instance) on your device. The app connects to it on port
37428by default. -
Open Settings in the app and configure:
- Bot hash — the RNS destination hash of your wardrive collector bot (hex string)
- Send interval — how often to transmit (default: 30 seconds)
- Operating mode — Announce, Packet, or Probe
- Shared instance port — change if Columba is on a non-default port
- Smart updates — minimum distance (meters) you must move before a new beacon is sent
- Map style URL — any MapLibre-compatible tile URL (default: OpenFreeMap Liberty)
-
Tap Start on the map screen. The status bubble shows RNS connection state and points sent.
Operating Modes
| Mode | Description |
|---|---|
| Announce | Broadcasts your position as an RNS announce. Works without a path to the bot. Lowest latency, no delivery confirmation. |
| Packet | Sends a direct encrypted packet to the collector bot. Falls back to Announce if no path is known yet. |
| Probe | Bi-directional. Like Packet, but each beacon carries the downlink RSSI/SNR measured from the bot's previous reply, and the bot echoes back the uplink RSSI/SNR it measured for your packet. This captures link quality in both directions — useful for two-way RF link quality surveys. Real downlink values require a working RPC connection to the shared instance — see Probe mode setup. |
Probe mode setup
Probe mode's real downlink RSSI/SNR (the signal quality of the bot's reply as heard by your
device) requires a working RPC connection to your RNS shared instance — the app reads that
physical-layer stat from the instance over Reticulum's authenticated RPC channel, using the
instance's rpc_key.
To turn it on, put the shared instance's rpc_key into Settings → RPC Key (leave RPC port
at its default, 37429):
- Sideband — Connectivity tab → Copy RPC Config To Clipboard, then paste into the field.
- Columba — the key isn't exposed in its UI; it has to be derived from Columba's transport identity file (requires root). See Columba RPC key setup.
Permissions
| Permission | Reason |
|---|---|
ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION |
GPS position |
ACCESS_BACKGROUND_LOCATION |
Continue tracking when the screen is off |
FOREGROUND_SERVICE / FOREGROUND_SERVICE_LOCATION |
Persistent service |
INTERNET |
RNS TCP transport / map tiles |
POST_NOTIFICATIONS |
Foreground service notification |
WAKE_LOCK |
Prevent CPU sleep during active tracking |
Architecture
ui/
map/ MapScreen + MapViewModel — live map, status overlays, start/stop
log/ LogScreen + LogViewModel — beacon transmission log
settings/ SettingsScreen + SettingsViewModel
rns/
WardrivRnsManager — RNS lifecycle, beacon sending, probe/ping logic
WardrivLxmfManager — LXMF messaging (bot responses)
service/
WardriveForegroundService — location loop, wakelock, notification
data/
SettingsRepository — DataStore-backed settings persistence
model/ — WardrivSettings, LocationPoint, LogEntry
The app uses Hilt for DI, Jetpack Compose + Material3 for UI, and Kotlin coroutines/Flow throughout.
Building
Prerequisites
- Android Studio Meerkat or later
- JDK 17
- Gradle 8.x (managed by the wrapper — no separate install needed)
The app depends on reticulum-kt and LXMF-kt, published to JitPack. No additional setup is needed — Gradle resolves them automatically.
Clone and build
git clone https://git.rns.moscow/deuxyeux/rns-wardrive-app.git
cd rns-wardrive-app
./gradlew assembleDebug
The APK will be at app/build/outputs/apk/debug/app-debug.apk.
For a release build:
./gradlew assembleRelease
You will need to configure a signing keystore in app/build.gradle.kts or via Android Studio before a release build will install on a device.
Install via ADB
adb install app/build/outputs/apk/debug/app-debug.apk
License
Released under the MIT License. See LICENSE.