Commit Graph

187 Commits

Author SHA1 Message Date
Smittix 60d3cff5e7 Fix SDR device lock-up from unreleased device registry on process crash
Stream threads for sensor, pager, acars, rtlamr, dmr, and dsc modes
never called release_sdr_device() when their SDR process crashed,
leaving devices permanently locked in the registry. Also fixes orphaned
companion processes (rtl_fm, rtl_tcp) not being killed on crash, start
path failures leaking processes, DMR stop handler missing lock, and
listening post/audio websocket pkill nuking all system-wide rtl_fm
processes. Wires up register_process()/unregister_process() so the
atexit/signal cleanup safety net actually works, and adds rtl_tcp,
rtl_power, rtlamr, ffmpeg to the killall endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:18:15 +00:00
Smittix 3b191dccd6 Remove raw output display and filter DSD startup banner lines
The dmrRawOutput div was rendering garbled box-drawing characters from
the dsd-fme ASCII art banner below the signal activity canvas. Remove
the div and filter banner lines (box-drawing chars, version info) in
the parser so they never become events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:52:59 +00:00
Smittix c0eda84644 Fix signal activity panel dying after DSD startup banner
The stream thread used a blocking readline() with no timeout, so once
DSD finished outputting its startup banner there were no more events
until actual signal activity. The frontend decayed to zero and appeared
dead. If DSD crashed, the synthesizer state never transitioned to
'stopped' so there was no visual or textual indication of failure.

- Use select() with 1s timeout on DSD stderr to avoid indefinite block
- Send heartbeat events every 3s while decoder is alive but idle
- Detect DSD crashes: capture exit code and remaining stderr, send as
  'crashed' status with details and show notification to user
- Frontend properly transitions synthesizer to 'stopped' on process
  death (was only happening on user-initiated stop)
- Increase idle breathing amplitude so LISTENING state is clearly
  visible (0.12 +/- 0.06 vs old 0.05 +/- 0.035)
- Release device reservation on crash, not just user stop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:49:35 +00:00
Smittix 19f382a31a Add device reservation to DMR mode and improve USB busy error message
DMR was missing checkDeviceAvailability/reserveDevice/releaseDevice
calls that other modes (SSTV, listening post) use, so the device
dropdown showed device 0 as available even when another process held
it. Also detect USB claim errors from rtl_fm and surface a clear
message telling the user to pick a different device.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:44:47 +00:00
Smittix 3b205db329 Fix DMR decoder signal activity and parsing for dsd-fme compatibility
The DSD stderr parser had regex ordering bugs that swallowed voice and
call events as bare slot events, and only matched classic dsd output
format (not dsd-fme). Unmatched lines were silently dropped, leaving
the signal activity panel with nothing to display.

- Reorder regex checks: TG/Src before voice before slot
- Support dsd-fme comma-separated format (TG: x, Src: y)
- Make bare slot regex strict (only standalone "Slot N" lines)
- Forward unmatched DSD lines as raw events for diagnostics
- Add LISTENING state to signal activity panel for raw output
- Show raw decoder output text below synthesizer canvas
- Fix test mocks for find_dsd() tuple return value

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:41:15 +00:00
Smittix d8c5491200 Fix APRS start crash from calling nonexistent reserve_sdr_device
The APRS route called app_module.reserve_sdr_device() which does not
exist, causing an AttributeError that Flask returned as an HTML error
page. The frontend then failed to parse it as JSON, showing
"Unexpected token '<'" to the user. Fixed to use claim_sdr_device()
which is the correct function used by all other modes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:31:48 +00:00
Smittix b9c8b1c730 Register SSTV mode with SDR device registry for device state panel
SSTV was not claiming/releasing SDR devices through the centralized
registry, so the device state panel always showed the device as idle
during SSTV use. Added claim_sdr_device/release_sdr_device on the
backend and reserveDevice/releaseDevice on the frontend, matching the
pattern used by all other modes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:28:37 +00:00
Smittix 684f17f507 Add delete and download functionality to SSTV image gallery
Users can now manage decoded SSTV images with download and delete actions
accessible from hover overlays on gallery cards, the full-size image modal
toolbar, and a "Clear All" button in the gallery header. Both ISS and
General SSTV modes are supported.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:12:26 +00:00
Smittix ef7d8cca9f Replace broken slowrx dependency with pure Python SSTV decoder
slowrx is a GTK GUI app that doesn't support CLI usage, so the SSTV
decoder was silently failing. This replaces it with a pure Python
implementation using numpy and Pillow that supports Robot36/72,
Martin1/2, Scottie1/2, and PD120/180 modes via VIS header auto-detection.

Key implementation details:
- Generalized Goertzel (DTFT) for exact-frequency tone detection
- Vectorized batch Goertzel for real-time pixel decoding performance
- Overlapping analysis windows for short-window frequency estimation
- VIS header detection state machine with parity validation
- Per-line sync re-synchronization for drift tolerance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:47:02 +00:00
Smittix 3e453a7b6d Capture rtl_fm stderr for pipeline error diagnostics
rtl_fm stderr was sent to DEVNULL, hiding the actual failure reason
(rc=1). Now captured and surfaced in the error response. Also drains
rtl_fm stderr during normal operation to prevent pipe blocking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:41:49 +00:00
Smittix fbbf20d820 Fix dsd-fme audio output flag and add pipeline error diagnostics
Use -o - (stdout) instead of -o /dev/null for audio output, as
dsd-fme expects specific output targets. Remove -N flag which may
cause issues in headless mode. Add stderr capture on pipeline
failure for better error messages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:02:29 +00:00
Smittix 765404fdc2 Fix dsd-fme support with correct protocol flags and ncurses disable
dsd-fme uses different protocol flags than classic dsd (e.g. -fs for
DMR instead of -fd, -f1 for P25 instead of -fp). Add -N flag to
disable ncurses terminal which is required when reading from stdin pipe.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:52:48 +00:00
Smittix 67fa196a28 Fix DSD voice decoder detection for dsd-fme and PulseAudio error
Check for dsd-fme binary (common fork) before falling back to dsd.
Disable audio output with -o /dev/null to prevent PulseAudio
connection failures when running under sudo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:44:31 +00:00
Smittix 4e3f0ad800 Add DMR digital voice, WebSDR, and listening post enhancements
- DMR/P25 digital voice decoder mode with DSD-FME integration
- WebSDR mode with KiwiSDR audio proxy and websocket-client support
- Listening post waterfall/spectrogram visualization and audio streaming
- Dockerfile updates for mbelib and DSD-FME build dependencies
- New tests for DMR, WebSDR, KiwiSDR, waterfall, and signal guess API
- Chart.js date adapter for time-scale axes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:38:08 +00:00
Smittix 4c67307951 Add terrestrial HF SSTV mode with predefined frequencies and modulation support
Adds a general-purpose SSTV decoder alongside the existing ISS SSTV mode,
supporting USB/LSB/FM modulation on common amateur radio HF/VHF/UHF
frequencies (14.230 MHz USB, 3.845 MHz LSB, etc.) with auto-detection
of modulation from preset frequency table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:36:41 +00:00
Smittix 8fca54e523 Fix APRS rtl_fm startup failure and SDR device conflicts (#122)
Add SDR device reservation to prevent conflicts with other modes, and
capture rtl_fm stderr so actual error messages are reported to the user
instead of a generic exit code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 13:50:09 +00:00
Smittix b4742f205a Update listening post handling 2026-02-06 09:50:49 +00:00
Smittix 337c25f66b Use WiFi scanner singleton for TSCM device availability check
Replace fragile platform-specific WiFi detection with the same
scanner._detect_interfaces() used by the actual scanning code,
eliminating false "No wireless interfaces found" warnings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:12:44 +00:00
Smittix eabb6b2951 Fix TSCM WiFi detection, SDR capabilities, layout, and correlation/cluster emission
- Use networksetup instead of deprecated airport utility for macOS WiFi detection
- Fix SDRDevice attribute access (use getattr instead of dict .get())
- Move Detected Threats panel next to RF Signals in 2-column grid
- Always run correlation/identity analysis at sweep end, even if stopped by user

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 16:41:10 +00:00
Smittix 5d4b19aef2 Fix TSCM sweep scan resilience and add per-device error isolation
The sweep loop's WiFi/BT/RF scan processing had unprotected
timeline_manager.add_observation() calls that could crash an entire
scan iteration, silently preventing all device events from reaching
the frontend. Additionally, scan interval timestamps were only updated
at the end of processing, causing tight retry loops on persistent errors.

- Wrap timeline observation calls in try/except for all three protocols
- Move last_*_scan timestamp updates immediately after scan completes
- Add per-device try/except so one bad device doesn't block others
- Emit sweep_progress after WiFi scan for real-time status visibility
- Log warning when WiFi scan returns 0 networks for easier diagnosis
- Add known_device and score_modifier fields to correlation engine
- Add TSCM scheduling, cases, known devices, and advanced WiFi indicators

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 16:07:34 +00:00
Smittix 11941bedad Swap ISS position API priority to avoid timeout delays
Open Notify API (api.open-notify.org) is frequently unreliable,
causing 5-second timeout delays on every ISS position request.
Promote wheretheiss.at as the primary API in both satellite.py
and sstv.py, demoting Open Notify to fallback.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 12:50:07 +00:00
Smittix c5bd13ea52 Filter WiFi connected clients by selected access point
The /wifi/v2/clients endpoint was returning all clients regardless
of query parameters, because a duplicate route in wifi.py took
precedence over the filtered one in wifi_v2.py. Added bssid,
associated, and min_rssi filtering to the active route.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:31:54 +00:00
Smittix 9ecad43f76 Fix USB device contention when starting audio pipeline
Add retry mechanism (3 attempts) for usb_claim_interface errors when
the SDR device hasn't been fully released by a previous process. Also
kill rtl_power alongside rtl_fm during cleanup and increase the USB
release delay.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:13:22 +00:00
Smittix 953e94da44 Add SNR column to signal hits table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:01:20 +00:00
Smittix 805fc69281 Set cyan-tinted map tiles as default 2026-02-04 22:31:02 +00:00
Smittix 1b04b52509 Sync scanner range from backend updates 2026-02-04 13:25:14 +00:00
Smittix fec38adc78 Stabilize scanner progress tracking 2026-02-04 12:42:30 +00:00
Smittix 993a7d2626 Stabilize sweep display and lower SNR default 2026-02-04 12:30:13 +00:00
Smittix dbe09411ac Stabilize sweep progress updates 2026-02-04 12:20:38 +00:00
Smittix 4862b285a8 Order sweep updates to avoid progress jitter 2026-02-04 12:14:46 +00:00
Smittix 41dd1555d7 Emit sweep progress and clear scanner queue 2026-02-04 12:11:50 +00:00
Smittix 0cf3a25ac6 Ensure scanner releases SDR before listening 2026-02-04 12:07:30 +00:00
Smittix 3674b6e2d6 Stop rtl_power when starting listen 2026-02-04 12:04:50 +00:00
Smittix 4c9bcb00c3 Improve rtl_power line parsing 2026-02-04 12:03:01 +00:00
Smittix 2067d0bf84 Default squelch to zero and track SDR usage 2026-02-04 11:59:06 +00:00
Smittix c0fa59d10e Add SNR threshold control for power scan 2026-02-04 11:54:56 +00:00
Smittix 37add84d59 Switch scanner to rtl_power sweep 2026-02-04 11:52:39 +00:00
Smittix c23019b8c0 Advance scanner after dwell on signal 2026-02-04 11:44:19 +00:00
Smittix b4edd35f5f Tighten listening signal detection thresholds 2026-02-04 11:41:30 +00:00
Smittix 82ad784fcb Restart audio pipeline for fresh stream header 2026-02-04 11:04:43 +00:00
Smittix 4bd7077d64 Add listening audio probe diagnostics 2026-02-04 11:02:00 +00:00
Smittix 0742647571 Stream listening audio as WAV 2026-02-04 10:56:57 +00:00
Smittix 33090419df Timeout audio stream if no first chunk 2026-02-04 10:53:03 +00:00
Smittix d3a0b41fba Flush ffmpeg audio stream packets 2026-02-04 10:06:45 +00:00
Smittix 2fefea5618 Add listening audio debug endpoint 2026-02-04 10:03:47 +00:00
Smittix b1e92326b6 Fix multiple UI bugs and improve error handling
Issues fixed:
- #113: Display RTL-SDR serial numbers in device selector
- #112: Kill all processes now stops Bluetooth scans
- #111: BLE device list no longer overflows container bounds
- #109: WiFi scanner panels maintain minimum width (no more "imploding")
- #108: Radar device hover no longer causes violent shaking
- #106: "Use GPS" button now uses gpsd for USB GPS devices
- #105: Meter trend text no longer overlaps adjacent columns
- #104: dump1090 errors now provide specific troubleshooting guidance

Changes:
- app.py: Add Bluetooth cleanup to /killall endpoint
- routes/adsb.py: Parse dump1090 stderr for specific error messages
- templates/index.html: Show SDR serial numbers in device dropdown
- static/css/index.css: Fix WiFi/BT panel layouts with proper min-width
- static/css/components/signal-cards.css: Fix meter grid overflow
- static/css/components/proximity-viz.css: Fix radar hover transform
- static/css/settings.css: Add GPS detection spinner
- static/js/components/proximity-radar.js: Add invisible hit areas
- static/js/core/settings-manager.js: Use gpsd before browser geolocation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 21:45:40 +00:00
Smittix 9ac63bd75f Add application restart endpoint for post-update restarts
Adds POST /updater/restart endpoint that gracefully restarts the
application using os.execv. Cleans up all decoder processes and
global state before replacing the process with a fresh instance.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:28:32 +00:00
Smittix f795180c7d Release v2.12.1
Bug fixes and improvements.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:16:12 +00:00
Smittix a76dfde02d Add SDR device registry to prevent decoder conflicts
Implements centralized tracking of SDR device allocation to prevent
multiple decoders from trying to use the same device simultaneously.

- Add sdr_device_registry with claim/release/status functions in app.py
- Update all SDR-based routes to claim devices on start and release on stop
- Return HTTP 409 with DEVICE_BUSY error when device is already in use
- Clear registry on /killall
- Skip device claims for remote connections (rtl_tcp, remote SBS)

Fixes #100
Fixes #101

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:05:21 +00:00
cemaxecuter 7182f7803a Auto-refresh agent capabilities after monitor mode toggle
When monitor mode is toggled on a remote agent, the controller now
automatically refreshes the agent's capabilities and updates the
database. This keeps the UI interface list in sync without requiring
a manual refresh.
2026-01-31 08:48:32 -05:00