Add full telemetry display in node popups including device metrics
(voltage, channel utilization, air TX) and environment sensors
(temperature, humidity, barometric pressure).
Add traceroute functionality with interactive visualization showing
hop paths and SNR values. Includes API endpoints for sending traceroutes
and retrieving results, plus a modal UI for displaying route information.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When multiple serial ports are detected (e.g., /dev/ttyACM0 and /dev/ttyUSB0),
the Meshtastic SDK's auto-detect fails. This adds a /meshtastic/ports endpoint
to list available ports and populates the device dropdown, auto-selecting the
first port when multiple exist.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New Features:
- Meshtastic LoRa mesh network integration
- Real-time message streaming via SSE
- Channel configuration with encryption
- Node information with RSSI/SNR metrics
- Ubertooth One BLE scanner backend
- Passive capture across all 40 BLE channels
- Raw advertising payload access
- Offline mode with bundled assets
- Local Leaflet, Chart.js, and fonts
- Multiple map tile providers
- Settings modal for configuration
Technical Changes:
- New routes: meshtastic.py, offline.py
- New utils: ubertooth_scanner.py, meshtastic.py
- New CSS/JS for meshtastic and settings
- Updated dashboard templates with conditional asset loading
- Added context processor for offline settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for connecting to Meshtastic LoRa mesh devices via USB/Serial.
Includes routes for device connection, channel configuration with encryption,
and SSE streaming of received messages.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ACARS (f00b4r0/DragonOS compatibility):
- Use --output json:file (not json:file:-) for stdout
- Use --rtlsdr instead of -r for device selection
- Use -m 256 for 3.2 MS/s sample rate (wider bandwidth for NA freqs)
- Properly detects fork by checking for --output in help
The f00b4r0 fork (used by DragonOS) has different CLI syntax than
TLeconte's original. Key differences:
- TLeconte: -j -r <device>
- f00b4r0: --output json:file -m 256 --rtlsdr <device>
ADS-B stop fix:
- Add Content-Type header to stop fetch request
- Flask's request.json requires application/json content type
- Without this header, stop returns HTTP 415 and dump1090 keeps running
- Agent TSCM uses same ThreatDetector and CorrelationEngine as local mode
- Added baseline_id parameter support using get_tscm_baseline()
- Fixed RF scan stop_check to allow agent-specific stop events
- Fixed 'undefined MHz' display for WiFi devices (added essid fallback and null check)
- Fixed signal strength type conversion (string to int) for correlation engine
- Agent threat detection matches local mode behavior:
- No baseline: detects anomaly/hidden_camera threats only
- With baseline: also detects new_device threats
Health Monitoring:
- Add /controller/agents/health endpoint for efficient bulk health checks
- Check all agents in one call with response time tracking
- Update agent status in real-time (30s interval)
- Show latency next to agent status in UI
- Add collapsible "All Agents Health" panel in sidebar
- Log console notifications when agents go online/offline
Response Utilities:
- Add unwrapAgentResponse() to consistently handle controller proxy format
- Add isAgentMode() and getCurrentAgentName() helpers
- Standardize error handling for agent responses
UI Improvements:
- Show response latency (ms) in agent selector dropdown
- Health panel shows status + running modes for each agent
- Better visual feedback for agent status changes
Agent improvements:
- Add process verification (0.5s delay + poll check) for sensor, pager, APRS, DSC modes
- Prevents silent failures when SDR is busy or tools fail to start
- Returns clear error messages when subprocess exits immediately
Frontend agent integration:
- Add agent routing to all SDR modes (pager, sensor, RTLAMR, APRS, listening post, TSCM)
- Add agent routing to WiFi and Bluetooth modes with polling fallback
- Add agent routing to AIS and DSC dashboards
- Implement "Show All Agents" toggle for Bluetooth mode
- Add agent badges to device/network lists
- Handle controller proxy response format (nested 'result' field)
Controller enhancements:
- Add running_modes_detail endpoint showing device info per mode
- Support SDR conflict detection across modes
Documentation:
- Expand DISTRIBUTED_AGENTS.md with complete API reference
- Add troubleshooting guide and security considerations
- Document all supported modes with tools and data formats
UI/CSS:
- Add agent badge styling for remote vs local sources
- Add WiFi and Bluetooth table agent columns
Features:
- Standalone agent server (intercept_agent.py) for remote sensor nodes
- Controller API blueprint for agent management and data aggregation
- Push mechanism for agents to send data to controller
- Pull mechanism for controller to proxy requests to agents
- Multi-agent SSE stream for combined data view
- Agent management page at /controller/manage
- Agent selector dropdown in main UI
- GPS integration for location tagging
- API key authentication for secure agent communication
- Integration with Intercept's dependency checking system
New files:
- intercept_agent.py: Remote agent HTTP server
- intercept_agent.cfg: Agent configuration template
- routes/controller.py: Controller API endpoints
- utils/agent_client.py: HTTP client for agents
- utils/trilateration.py: Multi-agent position calculation
- static/js/core/agents.js: Frontend agent management
- templates/agents.html: Agent management page
- docs/DISTRIBUTED_AGENTS.md: System documentation
Modified:
- app.py: Register controller blueprint
- utils/database.py: Add agents and push_payloads tables
- templates/index.html: Add agent selector section
When a monitor mode interface (e.g., wlan0mon) is detected, automatically
use airodump-ng deep scan instead of quick scan which doesn't work with
monitor mode interfaces.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement reliable tracker detection for AirTag, Tile, Samsung SmartTag,
and other BLE trackers based on manufacturer data patterns, service UUIDs,
and advertising payload analysis.
Key changes:
- Add TrackerSignatureEngine with signatures for major tracker brands
- Device fingerprinting to track devices across MAC randomization
- Suspicious presence heuristics (persistence, following patterns)
- New API endpoints: /api/bluetooth/trackers, /diagnostics
- UI updates with tracker badges, confidence, and evidence display
- TSCM integration updated to use v2 tracker detection data
- Unit tests and smoke test scripts for validation
Detection is heuristic-based with confidence scoring (high/medium/low)
and evidence transparency. Backwards compatible with existing APIs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add v2 capabilities, quick scan, deep scan, and status endpoints
- Add v2 networks, clients, probes, and channels endpoints
- Add v2 SSE stream, export (CSV/JSON), and baseline management
- Add recommendation_rank field to ChannelRecommendation model
The frontend was already wired up to call these v2 endpoints but they
were missing from the backend. This completes the WiFi module v2 API.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- New utils/wifi/ package with models, scanner, parsers, channel analyzer
- Quick Scan mode using system tools (nmcli, iw, iwlist, airport)
- Deep Scan mode using airodump-ng with monitor mode
- Hidden SSID correlation engine
- Channel utilization analysis with recommendations
- v2 API endpoints at /wifi/v2/* with SSE streaming
- TSCM integration updated to use new scanner (backwards compatible)
Frontend:
- WiFi mode controller (wifi.js) with dual-mode support
- Channel utilization chart component (channel-chart.js)
- Updated wifi.html template with scan mode tabs and export
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix Signal Timeline not receiving events by using SignalTimeline.create()
for TSCM mode to maintain backward compatibility with addEvent() calls
- Lower RF detection thresholds for RTL-SDR compatibility (6dB margin,
-90dBm floor instead of 10dB/-70dBm)
- Reduce RF scan interval from 60s to 30s for quicker feedback
- Enable RF/SDR checkbox by default to match WiFi and Bluetooth
- Update status message when no signals detected
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The unified get_tscm_bluetooth_snapshot() no longer accepts a bt_interface
parameter as it handles interface selection internally.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add device_key.py for stable device identification (identity > public MAC > fingerprint)
- Add distance.py with DistanceEstimator class (path-loss formula, EMA smoothing, confidence scoring)
- Add ring_buffer.py for time-windowed RSSI observation storage
- Extend BTDeviceAggregate with proximity_band, estimated_distance_m, distance_confidence, rssi_ema
- Add new API endpoints: /proximity/snapshot, /heatmap/data, /devices/<key>/timeseries
- Update TSCM integration to include new proximity fields
Frontend:
- Add proximity-radar.js: SVG radar with concentric rings, device dots positioned by distance
- Add timeline-heatmap.js: RSSI history grid with time buckets and color-coded signal strength
- Update bluetooth.js to initialize and feed data to new components
- Replace zone counters with radar visualization and zone summary
- Add proximity-viz.css for component styling
Tests:
- Add test_bluetooth_proximity.py with unit tests for device key stability, EMA smoothing,
distance estimation, band classification, and ring buffer functionality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The SSE stream was sending events without proper event names.
Frontend uses addEventListener('device_update', ...) which only
works with named events. Now maps internal event types to proper
SSE event names:
- device -> device_update
- status/started -> scan_started
- status/stopped -> scan_stopped
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major changes:
- Add utils/bluetooth/ package with DBus scanner, fallback scanners
(bleak, hcitool, bluetoothctl), device aggregation, and heuristics
- New unified API at /api/bluetooth/ with REST endpoints and SSE streaming
- Device observation aggregation with RSSI statistics and range bands
- Behavioral heuristics: new, persistent, beacon-like, strong+stable
- Frontend components: DeviceCard, MessageCard, RSSISparkline
- TSCM integration via get_tscm_bluetooth_snapshot() helper
- Unit tests for aggregator, heuristics, and API endpoints
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Set min-height: 300px on main grid
- Set min-height: 120px on individual panels
- Set min-height: 80px on panel content
- Change dashboard from height: 100% to min-height: 100%
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add verbose_results flag to store full device details in sweep results
- Add non-interactive mode (--non-interactive) to setup.sh
- Add ask_yes_no helper for interactive prompts with TTY detection
- Update reports.py to handle new results structure with fallbacks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added rtlamr mode for decoding utility meters (water, gas, electric)
- Starts rtl_tcp server first, then connects rtlamr to it
- Supports multiple message types: SCM, SCM+, IDM, NetIDM, R900, R900 BCD
- Added frequency presets for 912 MHz (NA) and 868 MHz (EU)
- Includes meter ID filtering and unique message options
- Updated setup.sh to check and install rtlamr and rtl_tcp
- Added UI components: navigation button, mode template, JavaScript functions
- Integrated into SDR/RF dropdown menu with lightning bolt icon
- Updates mode indicator with frequency when listening
- Added help documentation and requirements section
The previous detection logic incorrectly matched '-o' in help text for
version 4.x, causing startup failures. Now properly detects version:
- Version 4.0+: uses -j for JSON stdout
- Version 3.x: uses -o 4 for JSON stdout
Parses version from acarsdec output (e.g., "Acarsdec v4.3.1" or
"Acarsdec/acarsserv 3.7") to determine the correct flag.
Fixes: "invalid option -- 'o'" error on modern acarsdec builds
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The get_acarsdec_json_flag() function was defaulting to the obsolete '-o'
flag when detection failed, causing "invalid option -- 'o'" errors with
modern acarsdec builds from TLeconte repository.
Changes:
- Try both -h and --help flags for better compatibility
- Improve -j flag detection patterns
- Default to -j (modern standard) instead of -o
- Only use -o if explicitly documented in help text
This fixes ACARS decoder startup failures on systems where acarsdec was
built from source using setup.sh.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Change /tscm/playbooks to return array instead of dict
- Add id, name, category fields to each playbook for JS compatibility
- Fix tscmViewPlaybook JS to use correct field names (action/details/safety_note)
- Display when_to_escalate and documentation_required sections
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement 9 major TSCM feature enhancements:
1. Capability & Coverage Reality Panel - Exposes what sweeps can/cannot
detect based on OS, privileges, adapters, and SDR limits
2. Baseline Diff & Health - Shows changes vs baseline with health scoring
(healthy/noisy/stale) based on age and device churn
3. Per-Device Timelines - Time-bucketed observations with RSSI stability,
movement patterns, and meeting correlation
4. Whitelist/Known-Good Registry + Case Grouping - Global and per-location
device registry with case management for sweeps/threats/notes
5. Meeting-Window Summary Enhancements - Tracks devices first seen during
meetings with scoring modifiers
6. Client-Ready PDF Report + Technical Annex - Executive summary, findings
by risk tier, JSON/CSV annex export
7. WiFi Advanced Indicators - Evil twin detection, probe request tracking,
deauth burst detection (auto-disables without monitor mode)
8. Bluetooth Risk Explainability - Proximity estimates, tracker brand
explanations, human-readable risk descriptions
9. Operator Playbooks - Procedural guidance by risk level with steps,
safety notes, and documentation requirements
All features include mandatory disclaimers, preserve existing architecture,
and follow TSCM best practices (no packet capture, no surveillance claims).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Objects (;) and items ()) were identified but position data was never
extracted, causing them to appear without location on the map. Added
parse_object() and parse_item() functions to properly extract name,
status, and coordinates.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Return 503 instead of 500 when grgsm_scanner not found
- Show clearer error message in UI when gr-gsm unavailable
- Update status display to show "Not Available" state
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add spectrum monitoring via rtl_power with configurable presets
- Add OpenCelliD tower integration with Leaflet map display
- Add grgsm_scanner integration for passive GSM cell detection (alpha)
- Add rules engine for anomaly detection and findings
- Add baseline recording and comparison system
- Add setup.sh support for gr-gsm installation on Debian/Ubuntu
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix emergency alerts triggering for non-emergency squawk codes (VFR 1200/7000, etc.)
by checking squawkInfo.type === 'emergency' before alerting
- Fix emergency filter to only show actual emergency squawk codes
- Add acarsdec version detection to support both -j (newer) and -o 4 (older) JSON flags
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add propagate=False to prevent child loggers from duplicating
messages through parent handler
- Only log SBS connection errors once until successful reconnect
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Capture local reference to audio_process at generator start to prevent
'NoneType' object has no attribute 'stdout' error when stop is called
concurrently from another request.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problems fixed:
1. Added start_new_session=True to dump1090 Popen - creates proper process
group for clean shutdown
2. Use os.killpg() to kill entire process group when stopping ADS-B -
ensures child processes are terminated and device is released
3. Track active device index in adsb_active_device for debugging
4. Add device info to /adsb/status endpoint
5. Add logging when starting/stopping ADS-B with device info
These changes ensure the RTL-SDR device is properly released when ADS-B
stops, allowing another process (e.g., airband) to use a different device.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend changes (routes/aprs.py):
- Remove -q h flag from direwolf to enable audio level output
- Add parse_audio_level() to extract levels from direwolf output
- Add rate-limiting (max 10 updates/sec, min 2-level change)
- Push meter events to SSE queue as type='meter'
Frontend changes:
- Add signal meter widget to APRS sidebar
- Horizontal bar gauge with gradient (green->cyan->yellow->red)
- Numeric level display (0-100)
- "BURST" indicator for levels >70
- Status text (weak/moderate/strong signal)
- "No RF activity" state after 5 seconds of silence
- CSS styles in static/css/modes/aprs.css
Also added UK region to dropdown (same freq as Europe: 144.800)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major improvements to APRS decoding reliability:
Process piping fixes (prevent deadlocks):
- rtl_fm stderr -> DEVNULL (was blocking on unbuffered stderr)
- decoder stderr -> STDOUT (merged, single stream to read)
- decoder uses text=True, bufsize=1 for line-buffered reading
- Proper EOF detection in stream thread
rtl_fm command improvements:
- Use -M nfm (narrowband FM) for APRS
- Add -E dc (DC blocking filter) for cleaner audio
- Add -A fast (fast AGC) for packet bursts
- Sample rate 22050 Hz matches direwolf -r 22050
Parsing robustness:
- Strip direwolf bracket prefixes like "[0.4] " before parsing
- Handle multimon-ng "AFSK1200:" prefix
- Better error handling for early process exit
New /aprs/spectrum endpoint:
- Runs rtl_power to scan around APRS frequency
- Returns peak detection, noise floor, signal analysis
- Provides advice for antenna/signal debugging
- Supports region selection and custom frequency
Also added UK to region list (same freq as Europe: 144.800 MHz)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Direwolf requires a config file to run. Create a minimal receive-only
config at startup that configures stdin input with AFSK1200 modem.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>