Skip to content

Wardriving

JimGat edited this page Sep 7, 2026 · 5 revisions

Wardriving & Geolocation

Wardriving Screen

CYM integrates passive WiFi scanning, BLE enumeration, and GPS logging into a single wardriving pipeline with direct export to WiGLE and WDG Wars.


How It Works

  1. Attach a GPS module to the LP-UART header (TX→GPIO5, RX→GPIO4)
  2. Start Wardrive from the main menu
  3. CYM hops WiFi channels using the D-UCB bandit algorithm, logging every AP and BLE device with GPS coordinates
  4. Every record is timestamped (GPS-synced clock), geotagged, and written to /sdcard/lab/wardrives/
  5. Upload directly to WiGLE or WDG Wars over WiFi from the Wardrive → Manage Data screen

What gets logged

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.


D-UCB Channel Scheduler

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

Adaptive Speed-Based Capture

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.


GPS Integration

Supported modules

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).

Baud and fix rate (v2.13.x)

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.

GPS at wardrive start-up

  • 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

GPS loss mid-session

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.


BLE Wardriving

Concurrent BLE (hardware coexistence)

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 wardrive (v2.12.0 — fixed)

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.


File Format

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

CSV Durability & Rotation

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 with portMAX_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.


Manage Data

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.


Research Use Cases

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.


Radio Mode NVS Persistence (v2.12.1)

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.


GPS Serial Debug Toggle (v2.13.5)

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.


SD Card Layout

/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)

Clone this wiki locally