grgsm_scanner (like many GNU Radio tools) writes scan results to
stderr, not stdout. The stderr reader was only logging at debug
level and discarding lines. Now feeds stderr into the parse queue.
Also added info-level logging for all scanner output lines to aid
debugging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parser expected pipe-delimited table rows but grgsm_scanner outputs
comma-separated key-value pairs like:
ARFCN: 975, Freq: 925.2M, CID: 13522, LAC: 38722, MCC: 262, MNC: 1, Pwr: -58
This was the root cause of no data appearing in GSM Spy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
stop_scanner() cleared gsm_spy_active_device without calling
release_sdr_device(), so the device stayed claimed in the registry.
The scanner thread's finally block then saw None and skipped release.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GSM Spy was failing with FileNotFoundError because grgsm_scanner
wasn't installed. These tools are now installed automatically by
setup.sh (both Debian and macOS) and included in the Dockerfile,
matching how other tools like multimon-ng and ffmpeg are handled.
- setup.sh: Remove ask_yes_no prompts for gr-gsm and tshark, install
unconditionally; add check_recommended tier for final summary
- Dockerfile: Add tshark to apt layer, add gr-gsm RUN layer with
apt-then-source-build fallback, preseed debconf for tshark
- gsm_spy.py: Add shutil.which pre-check in start_scanner route,
catch FileNotFoundError in scanner_thread to stop retry loop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- kill_all() now resets gsm_spy_scanner_running and related state so
the scanner thread stops after killall
- scanner_thread sets flag to False instead of None on exit
- Restore alert_rules, alert_events, recording_sessions tables and
wifi_clients column removed by PR in database.py
- Escape all server-sourced values in analysis modals with escapeHtml()
- Reset gsm_towers_found/gsm_devices_tracked on stop to prevent
counter drift across sessions
- Replace raw terminate/kill with safe_terminate() in scanner_thread
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>