Files
giglez/signatures/t-embed-rf/SUBGHZ_WIGLE_WARDRIVING.md
Trilltechnician 04bd80b25b GPS Auto-Extraction + First Successful Upload Complete
Major milestone: GPS coordinates now auto-extract from filenames and
uploads appear on map with full end-to-end workflow functional!

 GPS Auto-Extraction Features:
- JavaScript GPS extractor class matching Python patterns
- Supports 3 filename formats:
  * N/S/E/W: 34.0478N_118.2349W_filename.sub
  * lat/lon prefix: lat34.0478lon-118.2348_filename.sub
  * Signed decimal: -34.0478_118.2348_filename.sub
- Auto-populates latitude/longitude form fields on file drop
- Green notification toast shows detected coordinates
- File list shows GPS badge for files with coordinates

🗺️ Web Interface Improvements:
- Upload endpoint now stores captures in-memory
- Query endpoint returns uploaded captures for map display
- Stats endpoint shows real-time upload counts
- Map displays uploaded captures as markers
- Color-coded by frequency band

📁 Updated Files:
- static/js/upload.js: GPS extraction + auto-population
- src/api/main_simple.py: In-memory storage + endpoints
- src/parser/gps_extractor.py: Backend GPS extraction (Python)
- scripts/test_gps_extraction.py: Python test suite
- test_gps_extraction.html: Browser test suite

📊 T-Embed Files Updated:
- 34.0478N_118.2348W_1637_raw_8.sub: 315 MHz Princeton
- 34.0478N_118.2349W_1351_raw_10.sub: 433.92 MHz Princeton
- 34.0478N_118.2349W_1650_test_raw.sub: 433.92 MHz RAW
- All now have proper Flipper SubGhz headers

 Tested Features:
- GPS extraction from filename: 34.0478N_118.2349W → 34.0478, -118.2349
- Auto-population of GPS fields in upload form
- File upload with GPS validation
- Capture appears on map after upload
- Statistics update in real-time
- Frequency distribution calculated correctly

🎯 End-to-End Flow Working:
1. User drops .sub file with GPS in filename
2. GPS auto-detected and form fields populate
3. User clicks Upload
4. Server parses RF data + GPS coordinates
5. Capture stored in memory
6. Map refreshes and displays new marker
7. Stats update with new counts

🚀 Demo: http://localhost:8000
Upload 34.0478N_118.2349W_1351_raw_10.sub and watch it appear on map!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 18:37:13 -08:00

13 KiB

SubGHz Wigle-Like Wardriving System

Complete GPS+RF Capture and Export System

Overview

This system creates a Wigle-like wardriving platform for sub-GHz RF signals, pairing GPS coordinates with Bruce T-Embed RF captures in a standardized format similar to Wigle WiFi wardriving.

Architecture:

┌──────────────────────────────────────────────────────────┐
│ GPS Sources (termux-location)                            │
└─────────────────┬────────────────────────────────────────┘
                  │
                  ▼
┌──────────────────────────────────────────────────────────┐
│ Bruce T-Embed RF Captures (.sub files)                   │
│ - Frequency, Protocol, Preset                            │
│ - RAW data, Key data                                     │
└─────────────────┬────────────────────────────────────────┘
                  │
                  ▼
┌──────────────────────────────────────────────────────────┐
│ SubGHz Wardriving Database (~/logs/subghz_wardriving.db) │
│ ├─ wardriving_sessions                                   │
│ ├─ gps_track (GPS breadcrumbs)                           │
│ └─ subghz_signals (RF+GPS pairs)                         │
└─────────────────┬────────────────────────────────────────┘
                  │
                  ▼
┌──────────────────────────────────────────────────────────┐
│ Export Formats                                           │
│ ├─ JSON (detailed)                                       │
│ ├─ CSV (standard wardriving)                             │
│ ├─ Wigle CSV (standardized for sharing)                  │
│ └─ SQLite (database backup)                              │
└──────────────────────────────────────────────────────────┘

Quick Start

1. Capture GPS + Associate with RF File

# Capture current GPS and pair with Bruce .sub file
python3 ~/python/subghz_wardriving/quick_capture.py \
    ~/projects/device-integration/bruce/data/captures/raw10.sub

# With custom session name
python3 ~/python/subghz_wardriving/quick_capture.py \
    raw10.sub downtown_survey

Latest GPS:

  • Coordinates: 34.07362505, -118.35955673
  • Accuracy: 24.5m
  • Timestamp: 2026-01-13T11:17:51-08:00
  • Provider: GPS

2. Export to Wigle Format

# Export all data to Wigle CSV
gps wigle-export

# Export specific session
gps wigle-export --session downtown_survey

# Direct export
python3 -c "
from subghz_wardriving.exporter import SubGHzExporter, ExportConfig
exporter = SubGHzExporter()
config = ExportConfig(format='wigle', compress=False)
result = exporter.export_session(config)
print(f'Exported to: {result[\"output_file\"]}')
"

Output Location: ~/exports/subghz_wardriving/

Database Schema

Table: subghz_signals

Stores RF captures paired with GPS coordinates:

Column Type Description
id INTEGER Primary key
session_id TEXT Wardriving session ID
capture_id TEXT Unique capture identifier
timestamp TEXT ISO 8601 timestamp
bruce_filename TEXT Original .sub filename
bruce_file_path TEXT Full path to .sub file
file_size_bytes INTEGER File size
frequency_hz INTEGER RF frequency in Hz
protocol TEXT Protocol (RAW, Princeton, etc.)
gps_latitude REAL Latitude (decimal degrees)
gps_longitude REAL Longitude (decimal degrees)
gps_accuracy_meters REAL GPS accuracy
interpolated BOOLEAN GPS interpolated?
interpolation_confidence REAL Confidence score (0-1)
time_gap_seconds REAL Time since last capture
distance_traveled_meters REAL Distance from last capture
estimated_speed_mps REAL Speed in m/s
file_hash_md5 TEXT MD5 hash of file
notes TEXT Additional notes

Table: gps_track

GPS breadcrumb trail:

Column Type Description
id INTEGER Primary key
session_id TEXT Session identifier
timestamp TEXT ISO 8601 timestamp
latitude REAL Latitude
longitude REAL Longitude
altitude REAL Altitude (meters)
accuracy REAL Horizontal accuracy (meters)
speed REAL Speed (m/s)
provider TEXT GPS provider (gps/network/passive)

Table: wardriving_sessions

Session metadata:

Column Type Description
session_id TEXT Primary key
start_time TEXT Session start time
end_time TEXT Session end time
total_signals INTEGER Number of signals captured
total_distance_km REAL Total distance traveled
device_info TEXT Device information
notes TEXT Session notes

Wigle CSV Format

Header Format

WigleWifi-1.4,appRelease=SubGHz-Wardrive-1.0,model=BruceT-Embed,release=Android,device=Phone,display=SubGHzWardrive,board=termux,brand=custom
SignalHash,Frequency(MHz),Protocol,RSSI(dBm),Latitude,Longitude,Altitude,Accuracy,FirstSeen,LastSeen,CaptureCount,Interpolated,Confidence,BruceFile,SessionID

Columns

Column Description
SignalHash SHA256 hash of frequency+protocol (16 chars)
Frequency(MHz) Frequency in MHz (e.g., 433.92)
Protocol Protocol name (RAW, Princeton, etc.)
RSSI(dBm) Signal strength (not available from .sub files)
Latitude Decimal degrees
Longitude Decimal degrees
Altitude Meters above sea level
Accuracy GPS accuracy in meters
FirstSeen ISO 8601 timestamp of first capture
LastSeen ISO 8601 timestamp of last capture
CaptureCount Number of times signal was seen
Interpolated true/false - was GPS interpolated?
Confidence Interpolation confidence (0-1)
BruceFile Original .sub filename
SessionID Wardriving session ID

Signal Aggregation

Signals are grouped by hash (frequency + protocol), similar to how Wigle groups WiFi by BSSID. Multiple captures of the same signal show:

  • First and last seen timestamps
  • Total capture count
  • Location from first capture

Usage Examples

Example 1: Quick Capture

# Capture GPS now with Bruce file
python3 ~/python/subghz_wardriving/quick_capture.py raw10.sub

Output:

📡 SubGHz GPS Capture
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Bruce File: raw10.sub
Session: quick_20260113_112045

🛰️  Getting GPS location...
✓ GPS Location: 34.073625, -118.359557
  Accuracy: 24.5m

📻 Parsing RF file...
✓ Frequency: 433920000 Hz (433.920 MHz)
  Protocol: RAW
  Preset: FCC_433

💾 Storing to database...
✓ Stored signal: quick_20260113_112045_raw10_1736789645

✅ Capture paired successfully!
   Database: ~/logs/subghz_wardriving.db

Example 2: Export Session

# Export to Wigle CSV
gps wigle-export --session downtown_survey

Output File: ~/exports/subghz_wardriving/downtown_survey_20260113_112130_wigle.csv

Content:

WigleWifi-1.4,appRelease=SubGHz-Wardrive-1.0,model=BruceT-Embed,release=Android,device=Phone,display=SubGHzWardrive,board=termux,brand=custom
SignalHash,Frequency(MHz),Protocol,RSSI(dBm),Latitude,Longitude,Altitude,Accuracy,FirstSeen,LastSeen,CaptureCount,Interpolated,Confidence,BruceFile,SessionID
8a3f2d1c4e5b6a7f,433.920,RAW,,34.073625,-118.359557,,24.5,2026-01-13T19:17:51Z,2026-01-13T19:17:51Z,1,false,1.0,raw10.sub,downtown_survey

Example 3: Wardriving Session

# Start GPS logging
gps on --session wardrive_session1 --interval 158.4

# Bruce captures RF signals to /BruceRF/*.sub files
# (Manually on Bruce device)

# After session, run batch import
for subfile in ~/projects/device-integration/bruce/data/captures/*.sub; do
    python3 ~/python/subghz_wardriving/quick_capture.py "$subfile" wardrive_session1
done

# Stop GPS logging
gps off

# Export to Wigle format
gps wigle-export --session wardrive_session1

File Locations

Component Path
Database ~/logs/subghz_wardriving.db
GPS Quick Log ~/logs/gps_quick.jsonl
GPS Correlations ~/logs/gps_correlations.db (legacy)
Exports ~/exports/subghz_wardriving/
Bruce Captures ~/projects/device-integration/bruce/data/captures/
Quick Capture Script ~/python/subghz_wardriving/quick_capture.py
Exporter Module ~/python/subghz_wardriving/exporter.py
Database Module ~/python/subghz_wardriving/database.py

Integration with Existing GPS Infrastructure

This system integrates with your existing GPS wardriving infrastructure:

Existing Systems

  1. gps command - CLI tool for GPS operations
  2. gps_service.py - Background GPS logging (158.4s interval)
  3. smart_gps_detector.py - Auto-detection and file renaming
  4. realtime_gps_attribution.py - Real-time GPS attribution

New Additions

  1. quick_capture.py - Quick GPS+RF pairing
  2. Wigle export format - Added to exporter.py
  3. gps wigle-export - New command in gps script
  4. Standardized database - Uses existing subghz_wardriving.db

Advanced Features

GPS Interpolation

When RF captures occur between GPS readings, the system interpolates GPS coordinates based on:

  • Time gap between captures
  • Distance traveled
  • Estimated speed
  • Interpolation confidence score

Session Management

from subghz_wardriving.database import SubGHzWardrivingDB

db = SubGHzWardrivingDB()

# Create session
db.create_session("my_session", device_info="Bruce T-Embed", notes="Downtown survey")

# End session (calculates statistics)
db.end_session("my_session")

# Get summary
summary = db.get_session_summary("my_session")
print(f"Signals: {summary['session']['total_signals']}")
print(f"Distance: {summary['session']['total_distance_km']} km")

Filtering Exports

from subghz_wardriving.exporter import SubGHzExporter, ExportConfig

exporter = SubGHzExporter()

# Export only 433 MHz signals
config = ExportConfig(
    format='wigle',
    frequency_filter=(433_000_000, 434_000_000),  # 433-434 MHz
    confidence_threshold=0.8,  # High confidence only
    protocol_filter='RAW'
)

result = exporter.export_session(config)

Comparison to WiFi Wigle

Feature WiFi Wigle SubGHz Wigle
Signal ID BSSID (MAC address) SignalHash (freq+protocol)
Signal Name SSID Protocol name
Frequency WiFi channels (2.4/5 GHz) SubGHz (300-928 MHz)
Strength RSSI (dBm) Not available from .sub
Device WiFi adapter Bruce T-Embed CC1101
Format CSV CSV (Wigle-compatible)
Location GPS GPS
Aggregation By BSSID By SignalHash

Future Enhancements

  1. RSSI Integration - If Bruce firmware provides signal strength
  2. Real-time Export - Live streaming to Wigle format
  3. Map Visualization - Plot signals on map
  4. Protocol Decoding - Decode known protocols (garage doors, car keys, etc.)
  5. Community Database - Share SubGHz signal maps
  6. Cross-device Correlation - Combine with Pineapple WiFi wardriving

Troubleshooting

No GPS Fix

# Check GPS status
gps status

# Try network provider
termux-location -p network

# Use test coordinates
# Edit gps script to add test coordinate option

Database Locked

# Check for running processes
ps aux | grep python | grep subghz

# Close database connections
pkill -f subghz_wardriving

Export Fails

# Check database exists
ls -lh ~/logs/subghz_wardriving.db

# Check export directory
mkdir -p ~/exports/subghz_wardriving

# Test export directly
python3 -m subghz_wardriving.exporter

Resources


Created: 2026-01-13 System Version: 1.0 Database: ~/logs/subghz_wardriving.db Latest GPS: 34.07362505, -118.35955673 (24.5m accuracy)