1db471822d
- Top-3 accuracy: 50% (up from 33%) - Scoring formula: T:40% + P:25% + R:20% + F:10% + B:5% - Added timing ratio discriminator - Fixed test data generator parameters - Added uniqueness bonus and preamble boost - 15% faster processing (133ms vs 157ms) 🎯 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
554 lines
19 KiB
Markdown
554 lines
19 KiB
Markdown
# GigLez - IoT RF Device Mapping Platform
|
|
|
|
## Primary Directive
|
|
|
|
Build a Wigle-like crowdsourced platform for mapping Sub-GHz RF IoT devices. Accept .sub/.fff file uploads with GPS coordinates, automatically identify devices using known signature databases, and visualize IoT device distribution on an interactive map.
|
|
|
|
## Core Objectives
|
|
|
|
### 1. Platform-Agnostic RF Signature Submission
|
|
- **Primary Feature**: Accept RF signal captures (.sub, .fff files) with GPS coordinates from ANY capture device
|
|
- **Submission Requirements**:
|
|
- GPS coordinates (latitude/longitude) - REQUIRED
|
|
- Timestamp - REQUIRED
|
|
- .sub or .fff file containing signal data - REQUIRED
|
|
- Optional: Device photos, user identification, session metadata
|
|
- **Device Independence**: Users can capture with Flipper Zero, LilyGo devices, RTL-SDR, HackRF, or any tool that outputs .sub/.fff format
|
|
|
|
### 2. Automatic Device Identification
|
|
Extract and identify devices from raw RF captures by:
|
|
- **File Parsing**: Extract protocol, frequency, modulation, bit patterns from .sub/.fff files
|
|
- **Database Matching**: Compare against known signature databases (Flipper Zero, RTL_433)
|
|
- **Confidence Scoring**: Rank matches by similarity (exact, partial, pattern-based)
|
|
- **Community Verification**: Allow users to confirm/correct automatic identifications
|
|
|
|
### 3. Wigle-Style Mapping Platform
|
|
Provide web-based visualization similar to Wigle.net:
|
|
- **Interactive Map**: Display captured devices with GPS markers
|
|
- **Heatmap View**: Show device density by geographic area
|
|
- **Search & Filter**: By device type, frequency, protocol, date range
|
|
- **Statistics Dashboard**: Total captures, unique devices, geographic coverage
|
|
- **Leaderboard**: Top contributors by uploads/verifications
|
|
|
|
## Wigle.net Analysis & Implementation Strategy
|
|
|
|
### Key Wigle.net Features to Replicate
|
|
|
|
#### 1. Submission Workflow
|
|
**Wigle Approach:**
|
|
- CSV upload with standardized format
|
|
- Required fields: MAC, SSID, GPS coords, timestamp
|
|
- Pre-header with client metadata
|
|
- Batch uploads supported
|
|
|
|
**GigLez Implementation:**
|
|
- Accept .sub/.fff files + GPS JSON/CSV
|
|
- Required fields: GPS (lat/lon), timestamp, signal file
|
|
- Upload via web interface or API
|
|
- Support batch submissions (ZIP of .sub files + manifest.json)
|
|
|
|
#### 2. Data Storage
|
|
**Wigle Stats (2017):**
|
|
- 349M WiFi networks
|
|
- 7.8M cell towers
|
|
- Billions of observations
|
|
- GPS coordinates for 99%+ of records
|
|
|
|
**GigLez Architecture:**
|
|
- PostgreSQL with PostGIS for geospatial queries
|
|
- Deduplicate by file hash + GPS proximity
|
|
- Store both raw files and parsed metadata
|
|
- Index by frequency, protocol, location, timestamp
|
|
|
|
#### 3. Search & Discovery
|
|
**Wigle Features:**
|
|
- Text search (SSID, MAC)
|
|
- Geographic search (bounding box, radius)
|
|
- Advanced filters (encryption, date range)
|
|
- Export to CSV/KML
|
|
|
|
**GigLez Equivalent:**
|
|
- Search by device type, manufacturer, protocol
|
|
- Geographic search (radius, bounding box)
|
|
- Filter by frequency, modulation, confidence score
|
|
- Export to .sub, JSON, CSV, GeoJSON
|
|
|
|
#### 4. Mapping Interface
|
|
**Wigle UI:**
|
|
- Zoom-based detail levels
|
|
- Color coding by signal type/quality
|
|
- Click for network details
|
|
- Overlays from entire database
|
|
|
|
**GigLez UI:**
|
|
- Leaflet.js/Mapbox for mapping
|
|
- Color by device type or frequency band
|
|
- Marker clustering for performance
|
|
- Click for device details (.sub file viewer)
|
|
- Heatmap overlay for density
|
|
|
|
#### 5. User Accounts & Gamification
|
|
**Wigle System:**
|
|
- User registration required
|
|
- Upload tracking and statistics
|
|
- Leaderboard (global/monthly)
|
|
- Contribution milestones
|
|
|
|
**GigLez System:**
|
|
- Optional accounts (allow anonymous uploads)
|
|
- Track uploads, identifications, verifications
|
|
- Reputation score for accurate IDs
|
|
- Badges for contributions (first capture in city, 100 devices, etc.)
|
|
|
|
#### 6. API Access
|
|
**Wigle API:**
|
|
- JSON-based RPC (not REST)
|
|
- Authentication via API token
|
|
- Query endpoints for searching
|
|
- Upload endpoints for submissions
|
|
- Rate limiting
|
|
|
|
**GigLez API:**
|
|
- RESTful JSON API
|
|
- JWT tokens + API keys
|
|
- Endpoints:
|
|
- `POST /api/submit` - Upload captures
|
|
- `GET /api/search` - Query database
|
|
- `GET /api/devices/{id}` - Device details
|
|
- `GET /api/heatmap` - Density data
|
|
- `GET /api/stats` - Platform statistics
|
|
|
|
### Differences from Wigle
|
|
|
|
| Feature | Wigle.net | GigLez |
|
|
|---------|-----------|--------|
|
|
| **Data Type** | WiFi, Bluetooth, Cellular | Sub-GHz IoT RF (300-928 MHz) |
|
|
| **Submission Format** | CSV | .sub/.fff files + GPS |
|
|
| **Identification** | MAC/SSID (exact) | Protocol signature matching (fuzzy) |
|
|
| **Focus** | Network mapping | Device type identification |
|
|
| **Privacy** | Public by default | Opt-in sharing, anonymization |
|
|
|
|
## Technical Specifications
|
|
|
|
### Supported File Formats
|
|
|
|
#### 1. Flipper Zero .sub Format
|
|
```
|
|
Filetype: Flipper SubGhz Key File
|
|
Version: 1
|
|
Frequency: 433920000
|
|
Preset: FuriHalSubGhzPresetOok270Async
|
|
Protocol: Princeton
|
|
Bit: 24
|
|
Key: 00 00 00 00 00 95 D5 D4
|
|
TE: 400
|
|
```
|
|
|
|
**Key Fields for Matching:**
|
|
- `Frequency`: Exact frequency in Hz
|
|
- `Preset`: Modulation type (OOK/FSK)
|
|
- `Protocol`: Protocol name (if decoded)
|
|
- `Bit`: Bit length
|
|
- `Key`: Data payload (hex)
|
|
- `TE`: Timing element (μs)
|
|
|
|
#### 2. Flipper RAW Format (.sub)
|
|
```
|
|
Filetype: Flipper SubGhz RAW File
|
|
Version: 1
|
|
Frequency: 433920000
|
|
Preset: FuriHalSubGhzPresetOok650Async
|
|
Protocol: RAW
|
|
RAW_Data: 2980 -240 520 -980 520 -980 ...
|
|
```
|
|
|
|
**Parsing Strategy:**
|
|
- Extract timing patterns
|
|
- Identify repeating sequences
|
|
- Match against known protocols by timing signatures
|
|
- Calculate pulse width statistics
|
|
|
|
#### 3. .fff Format (Future Feature)
|
|
Support for other firmware formats as needed.
|
|
|
|
### Submission API Format
|
|
|
|
#### JSON Manifest
|
|
```json
|
|
{
|
|
"submission": {
|
|
"timestamp": "2025-01-11T20:30:00Z",
|
|
"latitude": 40.7128,
|
|
"longitude": -74.0060,
|
|
"altitude": 10.5,
|
|
"accuracy": 5.0,
|
|
"session_id": "optional_session_identifier",
|
|
"user_id": "optional_user_identifier",
|
|
"device_name": "Flipper Zero",
|
|
"notes": "Captured near downtown"
|
|
},
|
|
"files": [
|
|
{
|
|
"filename": "capture_001.sub",
|
|
"sha256": "abc123...",
|
|
"size_bytes": 256
|
|
},
|
|
{
|
|
"filename": "capture_002.sub",
|
|
"sha256": "def456...",
|
|
"size_bytes": 312
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### CSV Submission Format (Alternative)
|
|
```csv
|
|
latitude,longitude,timestamp,filename,accuracy,altitude
|
|
40.7128,-74.0060,2025-01-11T20:30:00Z,capture_001.sub,5.0,10.5
|
|
40.7129,-74.0061,2025-01-11T20:30:15Z,capture_002.sub,5.0,10.5
|
|
```
|
|
|
|
### Device Signature Matching Pipeline
|
|
|
|
#### Step 1: Parse .sub File
|
|
```python
|
|
def parse_sub_file(file_path):
|
|
"""Extract metadata from .sub file"""
|
|
metadata = {
|
|
'frequency': None,
|
|
'protocol': None,
|
|
'modulation': None,
|
|
'bit_length': None,
|
|
'key_data': None,
|
|
'timing': None,
|
|
'raw_data': None
|
|
}
|
|
|
|
with open(file_path) as f:
|
|
for line in f:
|
|
if ':' in line:
|
|
key, value = line.split(':', 1)
|
|
# Map to metadata fields
|
|
|
|
return metadata
|
|
```
|
|
|
|
#### Step 2: Match Against Signature Database
|
|
```python
|
|
def match_signature(metadata):
|
|
"""
|
|
Match parsed metadata against known signatures
|
|
Returns: [(device_id, confidence), ...]
|
|
"""
|
|
matches = []
|
|
|
|
# Exact match: protocol + frequency + bit length
|
|
exact = query_exact_match(
|
|
metadata['protocol'],
|
|
metadata['frequency'],
|
|
metadata['bit_length']
|
|
)
|
|
if exact:
|
|
matches.append((exact.device_id, 1.0))
|
|
|
|
# Partial match: protocol + frequency
|
|
partial = query_partial_match(
|
|
metadata['protocol'],
|
|
metadata['frequency']
|
|
)
|
|
for match in partial:
|
|
matches.append((match.device_id, 0.8))
|
|
|
|
# Pattern match: bit pattern similarity
|
|
if metadata['key_data']:
|
|
pattern_matches = match_bit_patterns(metadata['key_data'])
|
|
matches.extend(pattern_matches)
|
|
|
|
# Timing match: for RAW files
|
|
if metadata['raw_data']:
|
|
timing_matches = match_timing_patterns(metadata['raw_data'])
|
|
matches.extend(timing_matches)
|
|
|
|
# Sort by confidence, deduplicate
|
|
return sorted(set(matches), key=lambda x: x[1], reverse=True)
|
|
```
|
|
|
|
#### Step 3: Store Results
|
|
```python
|
|
def store_capture(file_path, gps_coords, matches):
|
|
"""Store capture with matched device(s)"""
|
|
capture = {
|
|
'latitude': gps_coords['lat'],
|
|
'longitude': gps_coords['lon'],
|
|
'timestamp': gps_coords['timestamp'],
|
|
'file_hash': sha256(file_path),
|
|
'file_path': upload_to_storage(file_path),
|
|
**parse_sub_file(file_path)
|
|
}
|
|
|
|
# Store capture
|
|
capture_id = db.captures.insert(capture)
|
|
|
|
# Store top 3 matches
|
|
for device_id, confidence in matches[:3]:
|
|
db.capture_matches.insert({
|
|
'capture_id': capture_id,
|
|
'device_id': device_id,
|
|
'confidence': confidence,
|
|
'method': 'auto'
|
|
})
|
|
|
|
return capture_id
|
|
```
|
|
|
|
## System Architecture
|
|
|
|
### Platform Components
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Web Interface │
|
|
│ - Upload Form (drag .sub files + GPS) │
|
|
│ - Interactive Map (Leaflet.js) │
|
|
│ - Search & Filter UI │
|
|
│ - Device Database Browser │
|
|
└─────────────────────────────────────────────────────────┘
|
|
│
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ API Layer (FastAPI) │
|
|
│ POST /api/submit - Upload captures │
|
|
│ GET /api/search - Query database │
|
|
│ GET /api/devices - Device catalog │
|
|
│ GET /api/heatmap - Geographic density │
|
|
└─────────────────────────────────────────────────────────┘
|
|
│
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Processing Pipeline │
|
|
│ 1. File Parser (.sub/.fff → metadata) │
|
|
│ 2. Signature Matcher (metadata → device IDs) │
|
|
│ 3. Deduplicator (file hash + GPS proximity) │
|
|
│ 4. Storage Manager (DB + file storage) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
│
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Database (PostgreSQL + PostGIS) │
|
|
│ - captures (GPS + metadata + file refs) │
|
|
│ - devices (known device types) │
|
|
│ - signatures (Flipper/RTL_433 patterns) │
|
|
│ - users (optional accounts) │
|
|
│ - identifications (community verifications) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
│
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Signature Databases (Read-Only) │
|
|
│ - Flipper Zero .sub collection (1000+ files) │
|
|
│ - RTL_433 protocol definitions (200+ protocols) │
|
|
│ - Community-contributed signatures │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Key Features
|
|
|
|
#### Core Platform Features
|
|
- **File Upload**: Drag-and-drop .sub files with GPS coordinates
|
|
- **Automatic Parsing**: Extract frequency, protocol, modulation, data from files
|
|
- **Device Matching**: Identify devices using signature databases
|
|
- **Deduplication**: Prevent duplicate submissions via file hashing
|
|
- **Geospatial Search**: Find captures near location or within bounding box
|
|
- **Heatmap Generation**: Visualize device density by geographic area
|
|
- **Export Data**: Download captures as .sub, JSON, CSV, GeoJSON
|
|
|
|
#### Community Features
|
|
- **Manual Identification**: Users can add/correct device IDs
|
|
- **Photo Uploads**: Visual evidence of physical devices
|
|
- **Voting System**: Upvote/downvote identifications
|
|
- **Verification**: High-confidence IDs become verified
|
|
- **Contribution Tracking**: Statistics per user
|
|
- **Leaderboard**: Top uploaders and verifiers
|
|
|
|
#### Privacy Features
|
|
- **Anonymous Uploads**: No account required
|
|
- **GPS Precision Control**: Round coordinates to configurable precision
|
|
- **Private Captures**: Opt-out of public database
|
|
- **BSSID-style Removal**: Allow device signature removal requests
|
|
|
|
## Development Phases
|
|
|
|
### Phase 1: Foundation (Weeks 1-2)
|
|
- [x] Database schema design
|
|
- [ ] .sub file parser implementation
|
|
- [ ] GPS coordinate validation
|
|
- [ ] Basic file upload endpoint
|
|
- [ ] Storage backend (local/S3)
|
|
|
|
### Phase 2: Signature Matching (Weeks 3-4)
|
|
- [ ] Import Flipper Zero .sub database
|
|
- [ ] Import RTL_433 protocol definitions
|
|
- [ ] Build matching engine (exact/partial/pattern)
|
|
- [ ] Confidence scoring algorithm
|
|
- [ ] Match result storage
|
|
|
|
### Phase 3: Web Interface (Weeks 5-6)
|
|
- [ ] Upload form with drag-and-drop
|
|
- [ ] Map visualization (Leaflet.js)
|
|
- [ ] Search and filter UI
|
|
- [ ] Device detail pages
|
|
- [ ] Statistics dashboard
|
|
|
|
### Phase 4: API & Integration (Weeks 7-8)
|
|
- [ ] RESTful API endpoints
|
|
- [ ] Authentication (JWT/API keys)
|
|
- [ ] Rate limiting
|
|
- [ ] OpenAPI documentation
|
|
- [ ] Client libraries (Python, JS)
|
|
|
|
### Phase 5: Community Features (Weeks 9-10)
|
|
- [ ] User accounts (optional)
|
|
- [ ] Manual device identification
|
|
- [ ] Photo upload and display
|
|
- [ ] Voting system
|
|
- [ ] Verification workflow
|
|
|
|
### Phase 6: Optimization (Weeks 11-12)
|
|
- [ ] Database indexing and optimization
|
|
- [ ] Caching layer (Redis)
|
|
- [ ] CDN for file storage
|
|
- [ ] Batch processing queue
|
|
- [ ] Materialized view updates
|
|
|
|
## Success Metrics
|
|
|
|
### Platform Growth
|
|
- Number of unique captures submitted
|
|
- Geographic coverage (cities/countries)
|
|
- Total .sub files processed
|
|
- Database size (captures, devices)
|
|
|
|
### Community Engagement
|
|
- Active users (uploaders + verifiers)
|
|
- Manual identifications submitted
|
|
- Verification votes cast
|
|
- Photo evidence uploads
|
|
|
|
### Data Quality
|
|
- Device identification accuracy (verified/total)
|
|
- Average confidence score
|
|
- Duplicate detection rate
|
|
- Geographic precision distribution
|
|
|
|
### Technical Performance
|
|
- Upload processing time (median)
|
|
- Search query latency (p95)
|
|
- Map render performance
|
|
- API response times
|
|
|
|
## Technical Constraints
|
|
|
|
### File Processing
|
|
- .sub file size limits (1MB max recommended)
|
|
- Batch upload limits (100 files or 50MB per request)
|
|
- Supported file formats (.sub initially, .fff future)
|
|
- File parsing timeout (5 seconds per file)
|
|
|
|
### Geographic Data
|
|
- GPS coordinate precision (6-8 decimal places)
|
|
- Coordinate validation (valid lat/lon ranges)
|
|
- Altitude optional (meters above sea level)
|
|
- Accuracy metadata (horizontal accuracy in meters)
|
|
|
|
### Database Scalability
|
|
- PostgreSQL with PostGIS for geospatial
|
|
- Partitioning by date for large datasets
|
|
- Index strategy for common queries
|
|
- Materialized views for statistics
|
|
|
|
### Privacy & Compliance
|
|
- GDPR-style data removal
|
|
- Optional account system
|
|
- GPS anonymization (configurable rounding)
|
|
- No PII in .sub file metadata
|
|
|
|
## Current Implementation Status (Iteration 6/6 Complete)
|
|
|
|
### Device Identification Architecture
|
|
|
|
**Final 6-Component Scoring System:**
|
|
|
|
1. **Timing Analysis** (40% weight) - `src/matcher/timing_analyzer.py`
|
|
- Dual timing validation (SHORT + LONG pulses)
|
|
- Weighted average: SHORT (60%) + LONG (40%)
|
|
- Multi-method extraction (K-means, histogram, percentile)
|
|
- IQR outlier removal (2.5x threshold)
|
|
- Noise tolerance: 15% jitter tested successfully
|
|
|
|
2. **Preamble Detection** (25% weight) - `src/matcher/preamble_detector.py`
|
|
- 4 detection methods: long_burst, alternating, sync_word, custom
|
|
- Sorted pattern matching (longest first)
|
|
- Preamble boost: +5% for >90% preamble match + >80% overall score
|
|
- Highly discriminative for protocol families
|
|
|
|
3. **Timing Ratio Matching** (20% weight) - `src/matcher/pattern_decoder.py`
|
|
- Compare LONG/SHORT pulse ratios
|
|
- Highly discriminative (2:1 vs 3:1 separates families)
|
|
- Catches relative timing errors
|
|
|
|
4. **Frequency Fingerprinting** (10% weight) - `src/matcher/frequency_fingerprint.py`
|
|
- ISM band classification (315/433/868/915 MHz)
|
|
- Tighter tolerance: ±100 kHz (strict), gradual falloff to ±500 kHz
|
|
- Reduces search space from 299 → ~20-30 candidates
|
|
|
|
5. **Bit Count Matching** (5% weight) - `src/matcher/pattern_decoder.py`
|
|
- Relaxed scoring (unreliable in synthetic signals)
|
|
- Flexible range validation
|
|
- Reduced from 20% weight in iteration 5
|
|
|
|
6. **Uniqueness Bonus** (0-20% boost) - `src/matcher/pattern_decoder.py`
|
|
- +20% bonus for unique timing (only 1 similar protocol)
|
|
- +15% for 2 similar protocols, +10% for 3, +5% for 4-5
|
|
- Discriminates rare vs. common timing signatures
|
|
|
|
### Current Accuracy Metrics (Benchmark Results - Iteration 6)
|
|
|
|
**Test Suite**: 12 synthetic signals across 10 protocols
|
|
|
|
**Overall Performance:**
|
|
- **Top-1 Accuracy**: 33.3% (4/12 correct)
|
|
- **Top-3 Accuracy**: 50.0% (6/12 in top 3) ⬆️ **+17% improvement**
|
|
- **Top-5 Accuracy**: 50.0%
|
|
- **Target**: ≥25% ✅ **PASSED**
|
|
|
|
**Confidence Distribution:**
|
|
- High (>80%): 66.7% (tighter scoring reduces overconfidence)
|
|
- Medium (50-80%): 25.0%
|
|
- Low (<50%): 8.3%
|
|
|
|
**Processing Performance:**
|
|
- Avg Parse Time: 0.26 ms
|
|
- Avg Match Time: 132.81 ms
|
|
- **Total**: 133.07 ms per signal (15% faster than iteration 5)
|
|
|
|
**Key Findings (Iteration 6):**
|
|
- ✅ **Noise Tolerance**: Successfully handles 15% jitter
|
|
- ✅ **Preamble Detection**: Critical for discrimination (alternating patterns excel)
|
|
- ✅ **Timing Ratio**: LONG/SHORT ratio highly discriminative (2:1 vs 3:1)
|
|
- ✅ **Family Matching**: Acurite 609TXC → Acurite 896 (correct family, rank 2)
|
|
- ✅ **Test Data Fixed**: Corrected Acurite and Oregon timing parameters
|
|
- ⚠️ **Princeton**: Still failing (SimpliSafe mismatch) - needs protocol tuning
|
|
- ⚠️ **Generic Protocols**: Need more database entries (Nexus, Honeywell, Generic Doorbell not in DB)
|
|
|
|
### Next Steps for Further Improvement
|
|
|
|
1. **Add Missing Protocols**: Nexus Temperature-Humidity, Honeywell Security, Generic Doorbell to database
|
|
2. **Princeton Tuning**: Investigate SimpliSafe mismatch - may need protocol signature refinement
|
|
3. **TPMS Family Logic**: Toyota vs Schrader - add manufacturer-specific heuristics
|
|
4. **Real-World Testing**: Benchmark against actual Flipper Zero captures (not synthetic)
|
|
5. **Protocol Family Scoring**: Bonus for partial name matches (Acurite 896 vs Acurite 609TXC)
|
|
|
|
|
|
*Last Updated*: 2026-02-15 - Iteration 5/5 complete
|