-
Notifications
You must be signed in to change notification settings - Fork 6
Wardriving

CYM integrates passive WiFi scanning, BLE enumeration, and GPS logging into a single wardriving pipeline with direct export to WiGLE and WDG Wars.
- Attach a GPS module to the LP-UART header (TX→GPIO5, RX→GPIO4)
- Start Wardrive from the main menu
- CYM hops WiFi channels using the D-UCB bandit algorithm, logging every AP and BLE device with GPS coordinates
- Every record is timestamped (GPS-synced clock), geotagged, and written to
/sdcard/lab/wardrives/ - Upload directly to WiGLE or WDG Wars over WiFi from the Wardrive → Manage Data screen
| Type | Fields |
|---|---|
| WiFi AP | SSID, BSSID, RSSI, channel, band, encryption, lat, lon, altitude, accuracy, timestamp |
| BLE device | MAC, name, RSSI, lat, lon, altitude, accuracy, timestamp |
Output format: WiGLE CSV 1.6 — accepted directly by WiGLE and WDG Wars without conversion.
CYM uses a Discounted Upper-Confidence Bound (D-UCB) bandit to allocate dwell time across WiFi channels. The reward signal is new networks discovered per dwell — the bandit spends more time on channels where it keeps finding APs and less time on channels that are quiet.
- All non-DFS 5 GHz channels always receive full weight in all capture profiles
- The 19 DFS channels (100–144) are tier-weighted: full dwell when stationary or walking, reduced to 1-in-10 sweeps while driving
- Band filtering (2.4 GHz / 5 GHz / Both) is respected — filtered channels are never considered
- The green D-UCB box in the dashboard shows the channel currently being dwelled on
With Speed Adaptive Mode enabled (default), dwell time and DFS channel policy follow live GPS speed automatically:
| Profile | Trigger | Dwell | DFS policy |
|---|---|---|---|
| Stationary | < 5 km/h | 500 ms | Full weight |
| Walking | 5–20 km/h | 300 ms | Full weight |
| Driving | > 20 km/h | 150 ms | 1 in 10 sweeps |
Profile transitions use hysteresis to prevent oscillation at speed boundaries. The active profile and live speed appear in the dashboard footer. A green border means adaptive mode; red means a manual override is set.
With Speed Adaptive off, the Manual Mode dropdown lets you fix a profile for the entire session.
Field observation (@birolt29, two city drives): Mode transitions visible in data; 5 GHz maintained at 35–38% of observations (650–700 unique 5 GHz APs); DFS down to 12–19% of sweeps while driving; zero zero-fix rows.
Any UART GPS module outputting standard NMEA sentences ($GPRMC, $GPGGA) works. Recommended: Teyleten Robot ATGM336H GPS+BDS (CASIC chipset) — 3.3 V UART, onboard ceramic patch antenna.
Wiring: TX→GPIO5 (ESP→GPS), RX→GPIO4 (GPS→ESP).
| Setting | Fix rate | Notes |
|---|---|---|
| 9600 baud (default) | 1 Hz | Works with all modules |
| 115200 baud (opt-in) | 5 Hz | ATGM336H verified; 5.2 fix/s measured under full wardrive load |
At 65 km/h: 1 Hz = ~18 m between fixes; 5 Hz = ~3.6 m between fixes. At road speed this is the single largest improvement to WiGLE data quality — closer stamps mean APs are placed nearer where they were actually heard.
Boot-time baud auto-detect: The ATGM336H (and most GPS modules) store baud in battery-backed RAM and keep it across power cycles. CYM now probes the real baud at boot instead of assuming 9600. If a previous session left the module at 115200, the next boot picks it up automatically.
Switching to 115200: Goes through an opt-in consent popup in Options → GPS Baud. CYM sends the baud command to all supported chipset families ($PCAS01 for CASIC, $PMTK251 for MTK, UBX-CFG-PRT for u-blox), then listens 1.3 s at the target baud. If the module doesn't respond, the UART is put back at the original baud — the setting is not written and GPS continues normally. This prevents the module being left in a mute state.
GPS status icon: A satellite icon appears in the top bar of every screen. Green = valid fix; grey with red slash = no fix. Costs one glyph; eliminates "is GPS actually locked?" guessing while navigating.
- Live fix active → wardrive starts immediately
- No fix, but last-known position in NVS → wardrive starts immediately with 150 m accuracy
- No fix, no last-known → firmware waits; set a manual position via Settings → GPS Info → Set Position to skip
Wardrive continues using the last-known coordinates and reports 150 m in AccuracyMeters. Scanning only pauses if there is truly no position at all. When signal returns, live coordinates and accuracy resume automatically.
Wardrive mode uses hardware radio coexistence (CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y / CONFIG_SOC_COEX_HW_PTI=y) to run WiFi promiscuous scanning and BLE discovery concurrently on the shared radio. BLE operates at a 12.5% duty cycle (320 ms interval / 40 ms window) to leave WiFi throughput unimpeded. BLE is always active during a wardrive — the separate BLE toggle was removed in v2.13.x.
BLE device discovery uses an active scan to solicit SCAN_RSP packets, where most devices advertise their name. Discovered devices are deduplicated by MAC; names are backfilled when SCAN_RSP arrives after the initial advertisement.
BLE rows share the same WD_Wifi_<stamp>-NNN.csv file as WiFi rows. Both types upload to WiGLE and WDG Wars together.
BLE-only mode was broken (collecting 0 devices) for an extended period. Root cause: esp_wifi_stop() does not free the WiFi driver's DMA pool. NimBLE then fails to allocate advertising memory (0x207 BLE_ERR_MEM_CAPACITY). The fix calls esp_wifi_deinit() before NimBLE starts, freeing the WiFi DMA pool. The WiFi driver is re-initialized cleanly when wardrive stops.
Results after fix (field-tested @birolt29): 33–48 devices per run, CSV valid, uploaded to WiGLE and WDG successfully.
The BLE-only dashboard uses a dedicated layout: B | MAC | Name | RSSI table with a "BLE / SCAN" box (not the WiFi channel display). Output file: WD_BLE_<stamp>-NNN.csv.
BLE device cap: 2000 (PSRAM). Previous cap was 200 — a single city session was hitting the limit and stopping collection.
WiGLE CSV 1.6:
WigleWifi-1.6,appRelease=v2.13.23,model=NM-CYD-C5,...
MAC,SSID,AuthMode,FirstSeen,Channel,Frequency,RSSI,CurrentLatitude,CurrentLongitude,AltitudeMeters,AccuracyMeters,RCOIs,MfgrId,Type
AA:BB:CC:DD:EE:FF,"MyNetwork",[WPA2_PSK],2026-08-03 14:15:23,6,2437,-65,37.123456,-122.456789,42.0,8.40,,,WIFI
11:22:33:44:55:66,"BLE Device",[BLE],2026-08-03 14:15:30,37,2402,-72,37.123456,-122.456789,42.0,8.40,,,BLE
| Column | Source |
|---|---|
FirstSeen |
GPS-synced clock at moment of first detection |
AltitudeMeters |
GPS altitude at detection time |
AccuracyMeters |
HDOP × 4 from live fix; 150.00 from last-known fallback |
Power-cut safe (v2.12.0): CYM calls fsync() after writing the CSV header and after each periodic flush. Power-cut verified at 10 s, 20 s, and 30 s — all rows survive, no truncation, no need to stop cleanly before pulling power.
Auto-rotation: When a file reaches the size threshold, it is closed and a new part is opened with the next sequential suffix. All parts of the same journey share the same date/time stamp prefix:
WD_Wifi_20260803_141500-001.csv ← first part
WD_Wifi_20260803_141500-002.csv ← rotated when -001 fills
WD_Wifi_20260803_141500-003.csv ← and so on
This solves the 8 MiB single-buffer upload ceiling that long drives hit with the previous single-file approach. Each part can be uploaded independently.
Note: A previous build had a self-deadlock bug in the rotation path — the rotate block sat inside a critical section that already held
sd_spi_mutex(a non-recursive mutex), then tried to take the same mutex again withportMAX_DELAY. The device froze silently with no crash and no log, because the display and SD share the same bus lock. Fixed in v2.12.0.
Lists all wardrive CSV files in /sdcard/lab/wardrives/. Row colours:
| Color | Meaning |
|---|---|
| Green | Uploaded to all selected services |
| Amber | Partial (e.g. WiGLE OK, WDG failed) |
| White | Not yet uploaded |
Tap a row to see options (Upload, Delete). Upload status persists in /sdcard/lab/wardrives/upload_log.csv.
Network mapping during mobile assessments Drive or walk the perimeter of a facility. The resulting map shows every AP broadcasting from inside the building. With 5 Hz GPS at road speed, each AP is stamped within ~3.6 m of where it was heard — giving the client accurate signal reach evidence, not smeared blobs.
Rogue AP geolocation A rogue broadcasting a corporate SSID appears in the wardrive log with GPS position accurate to a few metres. Cross-reference the BSSID against WiGLE to find when it first appeared and who else has seen it.
BSSID / MAC geolocation for OSINT BSSIDs uploaded to WiGLE are cross-referenced against the global database. An AP's historical GPS positions reveal where a device has been.
BLE device geolocation BLE devices with static MACs appear repeatedly in the log as you move. Clustering by MAC gives physical locations of fixed beacons, asset tags, and IoT sensors. Be aware: a large fraction of BLE MACs are rotating random addresses and are not stable between sessions.
WiGLE community contributions WiGLE is the largest public database of wireless networks. CYM's dual-band coverage and high-rate GPS produce accurate, well-geotagged contributions — especially for 5 GHz networks that most wardriving setups miss entirely.
Wardrive radio mode (2.4 GHz only / 5 GHz only / Both) is now persisted to NVS across reboots. The mode selected in the last wardrive session is automatically restored when wardrive starts again -- no need to reconfigure after a power cycle.
This was particularly important for users on 5 GHz-only scans or 2.4-only surveys: previously every power cycle reset to the default Both mode, requiring a manual change before each run.
A GPS debug log toggle is available at Settings → GPS Info → GPS Debug Log.
When enabled, every raw NMEA sentence received from the GPS module is logged to the serial monitor as [GPSDBG] $GPRMC,... prefixed lines. This is useful for:
- Diagnosing GPS module wiring issues (no sentences at all = wiring/baud problem)
- Verifying the correct baud rate was negotiated at boot
- Watching for sentence quality during fix acquisition
- Debugging fix loss mid-wardrive
The toggle only affects serial output -- all normal wardrive GPS behavior is unchanged. Disable it after debugging to reduce serial noise.
/sdcard/lab/wardrives/
WD_Wifi_20260803_141500-001.csv
WD_Wifi_20260803_141500-002.csv
WD_BLE_20260803_153000-001.csv
upload_log.csv
wd000001_marks.gpx (GPS waypoints, older format)