- Python 99.3%
- Shell 0.7%
| bot | ||
| init_scripts | ||
| map | ||
| plugin | ||
| .gitignore | ||
| README.md | ||
rns-wardrive-tools
A collection of tools for wardriving LoRa coverage using the Reticulum Network Stack and Sideband.
To feed location data to the collector bot you can use either the Sideband plugin below or the dedicated Android app, rns-wardrive-app, which provides a live map, transmission log, and a bi-directional Probe mode for two-way RF link quality surveys.
Components
plugin/ — Sideband Plugin
A Sideband service plugin that runs on your mobile device and periodically sends your GPS location to the collector bot over RNS. If you'd rather use a standalone app instead of running it inside Sideband, see rns-wardrive-app.
Installation:
Copy wardrive_plugin.py and wardrive_config.json to your Sideband plugins directory (configured in Sideband settings under Plugins path).
Configuration (wardrive_config.json):
{
"announce_interval_secs": 30,
"announce_mode": "auto",
"send_mode": "packet",
"bot_hashes": ["<bot collector destination hash>"]
}
| Option | Values | Description |
|---|---|---|
announce_interval_secs |
integer (min 15) | How often to send location in auto mode |
announce_mode |
auto / manual |
auto: sends on interval; manual: sends when you press Sideband's announce button |
send_mode |
announce / packet |
announce: broadcasts on the network; packet: sends directly and privately to the bot |
bot_hashes |
list of hex strings | Collector destination hashes of bots to send to (packet mode only) |
In packet mode, location data is sent encrypted directly to each listed bot — it is not broadcast to the wider network. RSSI/SNR are still recorded on the receiving end.
In announce mode, location is broadcast as a wardrive.beacon announce visible to all nodes.
bot/ — Collector Bot
A server-side RNS daemon that listens for incoming location data, records RF signal statistics, and responds to LXMF commands.
Requirements: rns, lxmf, rnsd running
Installation:
Copy wardrive_bot.py to /opt/reticulum/bin/ (or any location on your $PATH).
Usage:
python3 wardrive_bot.py
The bot writes to ~/wardrive_bot.db (SQLite) and logs to /etc/reticulum/wardrive_bot_logfile.
LXMF commands (send via Sideband or any LXMF client):
| Command | Response |
|---|---|
ping |
Pong! [14:32:01, RSSI: -74dBm, SNR: 6.5dB] — RF stats included if message arrived over LoRa |
status |
Point count and timestamp of last received beacon |
nodes |
Count of discoverable nodes within the configured radius |
destinations |
Collector/probe destination hashes, plus the relay (aggregator) hash if this bot is the aggregator |
announce |
Reannounces all of the bot's destinations after a short randomized delay |
map/ — Coverage Map Server
A Flask web server that reads the bot's database and serves a live interactive coverage heatmap.
Requirements: flask, rns
Installation:
Copy map_server.py to /opt/reticulum/bin/ and wardrive_map.json to /etc/reticulum/.
Configuration (wardrive_map.json):
{
"db_path": "~/wardrive_bot.db",
"discovery_dir": "/etc/reticulum/storage/discovery/interfaces",
"listen_on": "0.0.0.0",
"port": 5000,
"page_title": "Wardrive Coverage Map",
"initial_lat": null,
"initial_lon": null,
"initial_zoom": null
}
Set initial_lat, initial_lon, and initial_zoom to pre-position the map on load; leave all three as null to auto-fit to recorded points.
Usage:
python3 map_server.py
Serves on http://0.0.0.0:5000 by default.
Features:
- Live heatmap of recorded coverage points, coloured by RSSI
- Live data stream panel showing incoming packets in real time (source, coordinates, RSSI/SNR/Q)
- Date range filter with day/week/month/year presets
- Light/dark UI theme with tileset selector (Dark, Voyager, Voyager no labels, Light, OSM)
- RNS infrastructure discovery panel — shows RNodes, Backbone, and I2P interfaces that have GPS coordinates, sourced from the local RNS discovery cache
- Toggleable node labels per interface type
init_scripts/ — Service Files
Systemd and OpenRC service files for both the bot and the map server.
OpenRC:
cp init_scripts/openrc/wardrive-bot /etc/init.d/
cp init_scripts/openrc/wardrive-map /etc/init.d/
chmod +x /etc/init.d/wardrive-bot /etc/init.d/wardrive-map
rc-update add wardrive-bot default
rc-update add wardrive-map default
Systemd:
cp init_scripts/systemd/wardrive-bot.service /etc/systemd/system/
cp init_scripts/systemd/wardrive-map.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now wardrive-bot wardrive-map
Data Flow
[Sideband + plugin]
|
| wardrive.beacon announce (announce mode, visible to all)
| wardrive.collector packet (packet mode, encrypted to bot only)
|
[wardrive_bot.py] ──── wardrive_bot.db ────[map_server.py]──── browser
|
LXMF replies (ping, status)