
Bluetooth Low Energy (BLE) scanner with Resolvable Private Address (RPA) resolution using Identity Resolving Keys (IRKs)
A Bluetooth Low Energy (BLE) scanner with advanced Resolvable Private Address (RPA) resolution. Discover nearby BLE devices, track a specific device by MAC address, or resolve privacy-randomized addresses using an Identity Resolving Key (IRK).
Written by: David Kennedy (@HackingDave) Company: TrustedSec
-o -)GPS location stamping requires the gpsd daemon running with a connected GPS receiver. If gpsd is not running, btrpa-scan continues normally without GPS.
| Platform | Install | Start |
|---|---|---|
| macOS | brew install gpsd | gpsd -n /dev/tty.usbserial-* |
| Debian/Ubuntu | sudo apt install gpsd gpsd-clients | sudo systemctl start gpsd |
| Fedora/RHEL | sudo dnf install gpsd gpsd-clients | sudo systemctl start gpsd |
| Arch | sudo pacman -S gpsd | sudo systemctl start gpsd |
| Windows | Use gpsd via WSL or MSYS2 | See WSL instructions above |
To verify gpsd is working:
# Check that gpsd is listening
gpspipe -w -n 5
# Or use the curses monitor
cgps
| Platform | Notes |
|---|---|
| macOS | Uses CoreBluetooth. IRK mode leverages an undocumented API to retrieve real Bluetooth addresses instead of UUIDs. --active has no effect — CoreBluetooth always scans actively. |
| Linux | May require root or CAP_NET_ADMIN capability for scanning. |
| Windows | Native WinRT Bluetooth API — real MAC addresses available natively. TUI requires pip install windows-curses. |
This project uses pyproject.toml (PEP 621), the modern Python packaging standard. It defines the project as an installable package with a registered CLI command — no need to run .py files directly.
uvx btrpa-scan --all
uvx --from git+https://github.com/hackingdave/btrpa-scan.git btrpa-scan --all
uv tool install btrpa-scan
Or directly from GitHub:
uv tool install git+https://github.com/hackingdave/btrpa-scan.git
pip install btrpa-scan
For GUI support (Flask-based radar interface):
pip install btrpa-scan[gui]
git clone https://github.com/hackingdave/btrpa-scan.git
cd btrpa-scan
pip install .
usage: btrpa-scan [-h] [-a] [--irk HEX] [--irk-file PATH] [-t TIMEOUT]
[--output {csv,json,jsonl}] [-o FILE] [--log FILE]
[-v | -q] [--min-rssi DBM] [--rssi-window N] [--active]
[--environment {free_space,indoor,outdoor}]
[--ref-rssi DBM] [--name-filter PATTERN]
[--alert-within METERS] [--tui] [--gui] [--gui-port PORT]
[--no-gps] [--adapters LIST] [mac]
BLE Scanner — discover all devices or hunt for a specific one
positional arguments:
mac Target MAC address to search for (omit to scan all)
optional arguments:
-h, --help show this help message and exit
-a, --all Scan for all broadcasting devices
--irk HEX Resolve RPAs using this Identity Resolving Key (32 hex chars)
--irk-file PATH Read IRK(s) from a file (one per line, hex format)
-t, --timeout TIMEOUT Scan timeout in seconds (default: 30, or infinite for --irk)
--output {csv,json,jsonl}
Batch output format written at end of scan
-o, --output-file FILE
Output file path (default: btrpa-scan-results.<format>;
use - for stdout)
--log FILE Stream detections to a CSV file in real time
-v, --verbose Verbose mode — show additional details
-q, --quiet Quiet mode — suppress per-device output, show summary only
--min-rssi DBM Minimum RSSI threshold (e.g. -70) — ignore weaker signals
--rssi-window N RSSI sliding window size for averaging (default: 1 = no averaging)
--active Use active scanning (sends SCAN_REQ for additional data)
--environment {free_space,indoor,outdoor}
Distance estimation path-loss model (default: free_space)
--ref-rssi DBM Calibrated RSSI at 1 metre for distance estimation
--name-filter PATTERN Filter devices by name (case-insensitive substring match)
--alert-within METERS Proximity alert when device is within this distance
--tui Live-updating terminal table instead of scrolling output
--gui Launch web-based radar interface in the browser
--gui-port PORT Port for GUI web server (default: 5000)
--no-gps Disable GPS location stamping (GPS is on by default via gpsd)
--adapters LIST Comma-separated Bluetooth adapter names (e.g. hci0,hci1)
Scan for all broadcasting BLE devices (default 30-second timeout):
btrpa-scan --all
With a custom timeout:
btrpa-scan --all -t 60
Search for a specific device by MAC address:
btrpa-scan AA:BB:CC:DD:EE:FF
Resolve Resolvable Private Addresses using an Identity Resolving Key. This mode runs indefinitely by default until stopped with Ctrl+C:
btrpa-scan --irk 0123456789ABCDEF0123456789ABCDEF
The IRK can be provided in several formats: