Open surveillance detection toolkit: a portable Rust library, standardized signature format, and documented companion event protocol for WiFi and BLE surveillance device detection. ESP32 firmware provides a ready-to-flash reference implementation; the same library and formats support Linux daemons, Kismet integrations, and any tool that adopts the schemas.
Surveillance cameras, ALPR systems, and related RF devices are proliferating in public spaces. Several community projects have built tools to detect them (see Related Projects below), each combining scanning, analysis, alerting, and UI into a single firmware.
AirHound takes a different approach: separation of concerns, built around three portable deliverables:
- Signature database — the most complete open-source collection of surveillance device identifiers (MAC OUI, SSID, BLE name/UUID/manufacturer), in a standard JSON format any tool can import (#11)
- Companion event protocol — a documented NDJSON wire format with JSON Schemas for detection events and host commands, transport-agnostic (#9)
- Detection library — portable Rust crate (
no_std, no platform dependencies) that connects signatures to scan data, testable on any host
Each layer is independently useful. The ESP32 firmware wires all three together with real radio hardware, but a Linux daemon (#13), Kismet companion (#12), or any other tool can consume the same signatures and speak the same protocol. Analysis, scoring, GPS tagging, and storage live in companion apps — the detection layer stays thin and focused. See #17 for the full architecture vision.
The goal is a community-maintained signature database and open standards that work across multiple tools, hardware platforms, and companion apps (#16).
AirHound builds on work by the surveillance detection community. These projects pioneered the techniques and published the device signatures that AirHound's signature database draws from:
| Project | Platform | WiFi | BLE | Output | Notes |
|---|---|---|---|---|---|
| Flock-You | ESP32-S3 | — | Scan | Web UI, JSON/CSV/KML | Largest community, GPS via browser |
| OUI-Spy | ESP32-S3 (custom PCB) | — | Scan | Web UI | Multi-mode: surveillance, drone, proximity |
| FlockSquawk | ESP32 (5 variants) | Promisc | Scan | Serial JSON, audio | First dual WiFi+BLE detection |
| FlockBack | Linux (Python) | Monitor | Scan | CLI | No dedicated hardware needed |
| ESP32Marauder | ESP32 (many) | Promisc | Scan | Serial, WiGLE CSV | Flock detection within broader toolkit |
| DeFlock | iOS | — | — | — | Companion app |
AirHound's approach is complementary: a portable detection library and standardized formats that separate scanning from analysis. The ESP32 firmware uses BLE GATT relay so the phone keeps its own connectivity; a Linux daemon or Kismet companion can use the same library with different radios. AirHound's signature database builds on research from these projects — the goal is a shared, community-maintained signature format that benefits everyone (#11).
- Standard formats — Surveillance device signatures, detection events, and host commands all have formal JSON Schemas. Any tool can validate, import, or produce conforming data without depending on AirHound's code.
- Library-first — Core detection logic in a portable
no_stdRust library with no platform dependencies. Platform code (ESP32 firmware, Linux daemon, Kismet companion) is a thin consumer layer. - App-agnostic — Open NDJSON companion protocol over any transport (BLE GATT, serial, TCP). Sensors and companion apps are interchangeable.
- Multi-platform — ESP32 firmware today. Linux daemon (#13) and Kismet companion (#12) planned, sharing the same library and formats.
- Community signatures — The signature database is designed to grow through contributions and be shared across projects (#11, #16). See Contributing.
Data:
- Signature — an atomic, stateless matching criterion (MAC OUI, SSID pattern, BLE name, raw byte pattern, etc.). Evaluated against a single frame in isolation.
- Rule — a named device detection that composes signatures with boolean logic (
anyOf/allOf/not). Still stateless — combines per-frame signature matches, not temporal patterns. - Signature database — portable JSON file of signatures and rules (
signatures.v1.schema.json).
Processing:
- Scan event — a parsed WiFi frame or BLE advertisement, before any evaluation.
- Filter engine — stateless code that evaluates scan events against signatures.
- Match — positive result: a scan event matched one or more signatures. Contains match reasons.
- Match reason — a single explanation: which signature type triggered and a human-readable detail.
Communication:
- Device message — NDJSON output from sensor (WiFi match, BLE match, or status).
- Host command — NDJSON input to sensor (start, stop, configure).
- Companion event protocol — the transport-agnostic NDJSON wire format for device messages and host commands.
WIDS (planned, #32):
- Fingerprint alert — single-frame security anomaly detection (e.g., malformed IE, zero WPA NONCE).
- Behavioral alert — multi-frame temporal detection (e.g., deauth flood, evil twin). Implemented as code modules with configurable thresholds, not declarative rules.
AirHound defines three JSON Schemas (draft 2020-12) in the schemas/ directory. These are designed for cross-tool use — any surveillance detection project can adopt them independently of AirHound's Rust code.
| Schema | Description | Used by |
|---|---|---|
signatures.v1.schema.json |
Portable signature database: MAC OUI prefixes, SSID patterns, BLE names/UUIDs/manufacturer IDs, with boolean rule composition (anyOf/allOf/not) |
Signature contributors, tool importers, runtime loaders (#14) |
device-message.v1.schema.json |
Detection events emitted by sensors: WiFi matches, BLE matches, status reports | Companion apps, log analysis, data pipelines |
host-command.v1.schema.json |
Commands sent to sensors: start/stop scanning, set RSSI threshold, configure buzzer | Companion apps, CLI tools |
An example signature file demonstrates the format with Flock Safety, Raven, and AirTag signatures.
| Board | Chip | Target | Feature Flag | Extras |
|---|---|---|---|---|
| Seeed XIAO ESP32-S3 | ESP32-S3 | xtensa-esp32s3-none-elf |
xiao |
PSRAM, GPS header |
| M5StickC Plus2 | ESP32 (PICO-V3) | xtensa-esp32-none-elf |
m5stickc |
TFT display, buzzer |
- 135x240 TFT display (ST7789V2) — status screen with match counts, uptime, and last detection
- Passive buzzer (GPIO2) — short alert beep on surveillance device match, togglable via BLE command
Pre-built binaries are available on the Releases page. To flash:
# 1. Install espflash
cargo install espflash --locked
# 2. Connect your board via USB and flash
espflash flash --chip esp32s3 airhound-xiao.bin # XIAO ESP32-S3
espflash flash --chip esp32 airhound-m5stickc.bin # M5StickC Plus2
# 3. Connect from a companion app over BLE, or monitor serial output
espflash monitor --speed 115200AirHound starts scanning immediately on boot. Matched devices appear as NDJSON on both BLE GATT notifications and serial.
No local ESP toolchain needed. Requires Docker and just.
cargo install just
just docker-build # Both targets
just docker-build-xiao # XIAO ESP32-S3 only
just docker-build-m5stickc # M5StickC Plus2 only
just docker-clean # Clean (required after dependency changes)Requires the ESP Rust toolchain (espup install) and espflash.
# Install toolchain
cargo install espup --locked && espup install
cargo install espflash --locked
. ~/export-esp.sh
# Build
just build-xiao
just build-m5stickc# Flash pre-built binaries (espflash auto-detects serial port)
espflash flash --chip esp32s3 target/xtensa-esp32s3-none-elf/release/airhound
espflash flash --chip esp32 target/xtensa-esp32-none-elf/release/airhound
# Or build + flash + monitor in one step (native only)
just flash-xiao
just flash-m5stickcAirHound uses newline-delimited JSON (NDJSON) for all communication. The format is transport-agnostic — the same messages work over BLE GATT, serial, TCP, or any stream transport. Full JSON Schemas are in schemas/.
WiFi scan result:
{"type":"wifi","mac":"B4:1E:52:XX:XX:XX","ssid":"Flock-A1B2C3","rssi":-65,"ch":6,"frame":"beacon","match":[{"type":"mac_oui","detail":"Flock Safety"},{"type":"ssid_pattern","detail":"Flock Safety camera WiFi"}],"ts":12345}BLE scan result:
{"type":"ble","mac":"58:8E:81:XX:XX:XX","name":"FS Ext Battery","rssi":-72,"mfr":2504,"match":[{"type":"ble_name","detail":"FS Ext Battery"},{"type":"ble_mfr","detail":"Known manufacturer ID"}],"ts":12346}Status report:
{"type":"status","scanning":true,"uptime":3600,"heap_free":45000,"ble_clients":1,"board":"xiao_esp32s3","version":"0.1.0"}{"cmd":"start"}
{"cmd":"stop"}
{"cmd":"status"}
{"cmd":"set_rssi","min_rssi":-80}
{"cmd":"set_buzzer","enabled":false}| Attribute | UUID | Properties |
|---|---|---|
| Service | 4a690001-1c4a-4e3c-b5d8-f47b2e1c0a9d |
-- |
| TX (results) | 4a690002-1c4a-4e3c-b5d8-f47b2e1c0a9d |
Notify |
| RX (commands) | 4a690003-1c4a-4e3c-b5d8-f47b2e1c0a9d |
Write |
AirHound's value lives in three separable, portable layers (#17):
| Layer | Description | Status |
|---|---|---|
| Signature Database | Portable JSON format for surveillance device signatures | v1 schema committed (signatures.v1.schema.json) |
| Companion Event Protocol | NDJSON wire format for detection events and host commands | v1 schema committed (device-message.v1, host-command.v1) |
| Detection Library | Rust crate: parsing, filtering, protocol types | Implemented (src/lib.rs, no_std) |
The library is organized in two code layers. Layer 1 is implemented; Layer 2 modules are planned.
┌──────────────────────────────────┐
│ Platform Binaries │
├───────────┬───────────┬───────────┤
│ ESP32 │ Linux │ Kismet │
│ Firmware │ Daemon │ Companion │
│ │ (#13) │ (#12) │
└─────┬─────┴─────┬─────┴─────┬─────┘
│ │ │
┌─────────────────────────┴───────────┴───────────┴──────┐
│ Layer 2 (Planned) — feature-gated modules │
│ gps · tracker · channel · export · wids │
│ (#28) (#29) (#30) (#31) (#32) │
├────────────────────────────────────────────────────────┤
│ Layer 1 (Implemented) — no_std, no dependencies │
│ scanner · filter · defaults · protocol · comm · board │
└────────────────────────────────────────────────────────┘
┌─────────────────┐ ┌──────────────────┐
│ WiFi Sniffer │ │ BLE Scanner │
│ (13-ch hop) │ │ (periodic scan) │
└────────┬────────┘ └────────┬─────────┘
│ ScanEvent │ ScanEvent
└──────────┬───────────┘
▼
┌─────────────────┐
│ Filter Engine │
│ MAC/SSID/BLE/UUID│
└────────┬────────┘
│ NDJSON
┌─────────┼─────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ BLE GATT │ │ Serial │ │ Display/Buzz │
│ (notify) │ │ (115200) │ │ (M5StickC) │
└──────────┘ └──────────┘ └──────────────┘
The signature database is defined by a formal JSON Schema and designed for cross-tool sharing (#11). The current default signatures include data merged from multiple open-source surveillance detection projects:
- 115 MAC OUI prefixes — Flock Safety, Silicon Labs, Axis, Hanwha, FLIR, Mobotix, and other surveillance vendors
- SSID patterns —
Flock-XXXXXX,Penguin-XXXXXXXXXX,FS Ext Battery - BLE name patterns — Flock, Penguin, FS Ext Battery, Pigvision
- Raven BLE service UUIDs — 0x3100-0x3500 (custom), 0x180A/0x1809/0x1819 (standard)
- Manufacturer IDs — 0x09C8 (XUNTONG / Flock Safety)
The schema supports boolean rule composition (anyOf/allOf/not) for complex device detections. See the example signature file for the format, and the signature contribution guide to add new devices.
Directions, not promises. See #17 for the full architecture vision.
| Module | Feature Gate | Description | Issue |
|---|---|---|---|
gps.rs |
gps |
NMEA parsing, position types, geofence helpers | #28 |
tracker.rs |
tracker |
Device history, re-identification, follow detection | #29 |
channel.rs |
channel |
WiFi channel scheduling, dwell optimization | #30 |
export.rs |
std |
WiGLE CSV, KML, pcapng export | #31 |
wids.rs |
wids |
Rogue AP detection, deauth monitoring | #32 |
| Platform | Status | Issue |
|---|---|---|
| ESP32 firmware (XIAO, M5StickC) | Implemented | — |
| Flipper Zero companion app | Planned | #34 |
| Linux daemon (Raspberry Pi / laptop) | Planned | #13 |
| Kismet companion process | Planned | #12 |
- Cargo workspace extraction for multi-platform library reuse (#33)
- Flipper Zero BLE serial relay (upstream
flipperzero-rscontribution) - Runtime signature loading and updates (#14)
- GPS enrichment for boards with GPS modules (#15)
- Protocol v2 — versioning and expanded command set (#9)
- Cross-tool interoperability with OUI-Spy, FlockSquawk, Flock-You, and others (#16)
- More ESP32 variants (C3, C6 RISC-V) and other MCU families
Contributions are welcome — especially new device signatures. See CONTRIBUTING.md for guidelines on submitting signatures, adding board support, and development setup.
MIT