mirror of
https://github.com/smittix/intercept.git
synced 2026-07-08 01:28:13 -07:00
Default squelch to zero and track SDR usage
This commit is contained in:
+92
-41
@@ -14,11 +14,12 @@ import time
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Generator, Optional, List, Dict
|
from typing import Generator, Optional, List, Dict
|
||||||
|
|
||||||
from flask import Blueprint, jsonify, request, Response
|
from flask import Blueprint, jsonify, request, Response
|
||||||
|
|
||||||
from utils.logging import get_logger
|
import app as app_module
|
||||||
from utils.sse import format_sse
|
from utils.logging import get_logger
|
||||||
from utils.constants import (
|
from utils.sse import format_sse
|
||||||
|
from utils.constants import (
|
||||||
SSE_QUEUE_TIMEOUT,
|
SSE_QUEUE_TIMEOUT,
|
||||||
SSE_KEEPALIVE_INTERVAL,
|
SSE_KEEPALIVE_INTERVAL,
|
||||||
PROCESS_TERMINATE_TIMEOUT,
|
PROCESS_TERMINATE_TIMEOUT,
|
||||||
@@ -42,17 +43,19 @@ audio_frequency = 0.0
|
|||||||
audio_modulation = 'fm'
|
audio_modulation = 'fm'
|
||||||
|
|
||||||
# Scanner state
|
# Scanner state
|
||||||
scanner_thread: Optional[threading.Thread] = None
|
scanner_thread: Optional[threading.Thread] = None
|
||||||
scanner_running = False
|
scanner_running = False
|
||||||
scanner_lock = threading.Lock()
|
scanner_lock = threading.Lock()
|
||||||
scanner_paused = False
|
scanner_paused = False
|
||||||
scanner_current_freq = 0.0
|
scanner_current_freq = 0.0
|
||||||
|
scanner_active_device: Optional[int] = None
|
||||||
|
listening_active_device: Optional[int] = None
|
||||||
scanner_config = {
|
scanner_config = {
|
||||||
'start_freq': 88.0,
|
'start_freq': 88.0,
|
||||||
'end_freq': 108.0,
|
'end_freq': 108.0,
|
||||||
'step': 0.1,
|
'step': 0.1,
|
||||||
'modulation': 'wfm',
|
'modulation': 'wfm',
|
||||||
'squelch': 20,
|
'squelch': 0,
|
||||||
'dwell_time': 10.0, # Seconds to stay on active frequency
|
'dwell_time': 10.0, # Seconds to stay on active frequency
|
||||||
'scan_delay': 0.1, # Seconds between frequency hops (keep low for fast scanning)
|
'scan_delay': 0.1, # Seconds between frequency hops (keep low for fast scanning)
|
||||||
'device': 0,
|
'device': 0,
|
||||||
@@ -60,6 +63,7 @@ scanner_config = {
|
|||||||
'bias_t': False, # Bias-T power for external LNA
|
'bias_t': False, # Bias-T power for external LNA
|
||||||
'sdr_type': 'rtlsdr', # SDR type: rtlsdr, hackrf, airspy, limesdr, sdrplay
|
'sdr_type': 'rtlsdr', # SDR type: rtlsdr, hackrf, airspy, limesdr, sdrplay
|
||||||
'scan_method': 'power', # power (rtl_power) or classic (rtl_fm hop)
|
'scan_method': 'power', # power (rtl_power) or classic (rtl_fm hop)
|
||||||
|
'snr_threshold': 12,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Activity log
|
# Activity log
|
||||||
@@ -775,7 +779,7 @@ def check_tools() -> Response:
|
|||||||
@listening_post_bp.route('/scanner/start', methods=['POST'])
|
@listening_post_bp.route('/scanner/start', methods=['POST'])
|
||||||
def start_scanner() -> Response:
|
def start_scanner() -> Response:
|
||||||
"""Start the frequency scanner."""
|
"""Start the frequency scanner."""
|
||||||
global scanner_thread, scanner_running, scanner_config
|
global scanner_thread, scanner_running, scanner_config, scanner_active_device, listening_active_device
|
||||||
|
|
||||||
with scanner_lock:
|
with scanner_lock:
|
||||||
if scanner_running:
|
if scanner_running:
|
||||||
@@ -792,7 +796,7 @@ def start_scanner() -> Response:
|
|||||||
scanner_config['end_freq'] = float(data.get('end_freq', 108.0))
|
scanner_config['end_freq'] = float(data.get('end_freq', 108.0))
|
||||||
scanner_config['step'] = float(data.get('step', 0.1))
|
scanner_config['step'] = float(data.get('step', 0.1))
|
||||||
scanner_config['modulation'] = str(data.get('modulation', 'wfm')).lower()
|
scanner_config['modulation'] = str(data.get('modulation', 'wfm')).lower()
|
||||||
scanner_config['squelch'] = int(data.get('squelch', 20))
|
scanner_config['squelch'] = int(data.get('squelch', 0))
|
||||||
scanner_config['dwell_time'] = float(data.get('dwell_time', 3.0))
|
scanner_config['dwell_time'] = float(data.get('dwell_time', 3.0))
|
||||||
scanner_config['scan_delay'] = float(data.get('scan_delay', 0.5))
|
scanner_config['scan_delay'] = float(data.get('scan_delay', 0.5))
|
||||||
scanner_config['device'] = int(data.get('device', 0))
|
scanner_config['device'] = int(data.get('device', 0))
|
||||||
@@ -833,6 +837,19 @@ def start_scanner() -> Response:
|
|||||||
'status': 'error',
|
'status': 'error',
|
||||||
'message': 'rtl_power not found. Install rtl-sdr tools.'
|
'message': 'rtl_power not found. Install rtl-sdr tools.'
|
||||||
}), 503
|
}), 503
|
||||||
|
# Release listening device if active
|
||||||
|
if listening_active_device is not None:
|
||||||
|
app_module.release_sdr_device(listening_active_device)
|
||||||
|
listening_active_device = None
|
||||||
|
# Claim device for scanner
|
||||||
|
error = app_module.claim_sdr_device(scanner_config['device'], 'scanner')
|
||||||
|
if error:
|
||||||
|
return jsonify({
|
||||||
|
'status': 'error',
|
||||||
|
'error_type': 'DEVICE_BUSY',
|
||||||
|
'message': error
|
||||||
|
}), 409
|
||||||
|
scanner_active_device = scanner_config['device']
|
||||||
scanner_running = True
|
scanner_running = True
|
||||||
scanner_thread = threading.Thread(target=scanner_loop_power, daemon=True)
|
scanner_thread = threading.Thread(target=scanner_loop_power, daemon=True)
|
||||||
scanner_thread.start()
|
scanner_thread.start()
|
||||||
@@ -849,6 +866,17 @@ def start_scanner() -> Response:
|
|||||||
'status': 'error',
|
'status': 'error',
|
||||||
'message': f'rx_fm not found. Install SoapySDR utilities for {sdr_type}.'
|
'message': f'rx_fm not found. Install SoapySDR utilities for {sdr_type}.'
|
||||||
}), 503
|
}), 503
|
||||||
|
if listening_active_device is not None:
|
||||||
|
app_module.release_sdr_device(listening_active_device)
|
||||||
|
listening_active_device = None
|
||||||
|
error = app_module.claim_sdr_device(scanner_config['device'], 'scanner')
|
||||||
|
if error:
|
||||||
|
return jsonify({
|
||||||
|
'status': 'error',
|
||||||
|
'error_type': 'DEVICE_BUSY',
|
||||||
|
'message': error
|
||||||
|
}), 409
|
||||||
|
scanner_active_device = scanner_config['device']
|
||||||
|
|
||||||
scanner_running = True
|
scanner_running = True
|
||||||
scanner_thread = threading.Thread(target=scanner_loop, daemon=True)
|
scanner_thread = threading.Thread(target=scanner_loop, daemon=True)
|
||||||
@@ -861,14 +889,17 @@ def start_scanner() -> Response:
|
|||||||
|
|
||||||
|
|
||||||
@listening_post_bp.route('/scanner/stop', methods=['POST'])
|
@listening_post_bp.route('/scanner/stop', methods=['POST'])
|
||||||
def stop_scanner() -> Response:
|
def stop_scanner() -> Response:
|
||||||
"""Stop the frequency scanner."""
|
"""Stop the frequency scanner."""
|
||||||
global scanner_running
|
global scanner_running, scanner_active_device
|
||||||
|
|
||||||
scanner_running = False
|
scanner_running = False
|
||||||
_stop_audio_stream()
|
_stop_audio_stream()
|
||||||
|
if scanner_active_device is not None:
|
||||||
return jsonify({'status': 'stopped'})
|
app_module.release_sdr_device(scanner_active_device)
|
||||||
|
scanner_active_device = None
|
||||||
|
|
||||||
|
return jsonify({'status': 'stopped'})
|
||||||
|
|
||||||
|
|
||||||
@listening_post_bp.route('/scanner/pause', methods=['POST'])
|
@listening_post_bp.route('/scanner/pause', methods=['POST'])
|
||||||
@@ -1025,14 +1056,17 @@ def get_presets() -> Response:
|
|||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
@listening_post_bp.route('/audio/start', methods=['POST'])
|
@listening_post_bp.route('/audio/start', methods=['POST'])
|
||||||
def start_audio() -> Response:
|
def start_audio() -> Response:
|
||||||
"""Start audio at specific frequency (manual mode)."""
|
"""Start audio at specific frequency (manual mode)."""
|
||||||
global scanner_running
|
global scanner_running, scanner_active_device, listening_active_device
|
||||||
|
|
||||||
# Stop scanner if running
|
# Stop scanner if running
|
||||||
if scanner_running:
|
if scanner_running:
|
||||||
scanner_running = False
|
scanner_running = False
|
||||||
time.sleep(0.5)
|
if scanner_active_device is not None:
|
||||||
|
app_module.release_sdr_device(scanner_active_device)
|
||||||
|
scanner_active_device = None
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
data = request.json or {}
|
data = request.json or {}
|
||||||
|
|
||||||
@@ -1069,11 +1103,24 @@ def start_audio() -> Response:
|
|||||||
'message': f'Invalid sdr_type. Use: {", ".join(valid_sdr_types)}'
|
'message': f'Invalid sdr_type. Use: {", ".join(valid_sdr_types)}'
|
||||||
}), 400
|
}), 400
|
||||||
|
|
||||||
# Update config for audio
|
# Update config for audio
|
||||||
scanner_config['squelch'] = squelch
|
scanner_config['squelch'] = squelch
|
||||||
scanner_config['gain'] = gain
|
scanner_config['gain'] = gain
|
||||||
scanner_config['device'] = device
|
scanner_config['device'] = device
|
||||||
scanner_config['sdr_type'] = sdr_type
|
scanner_config['sdr_type'] = sdr_type
|
||||||
|
|
||||||
|
# Claim device for listening audio
|
||||||
|
if listening_active_device is None or listening_active_device != device:
|
||||||
|
if listening_active_device is not None:
|
||||||
|
app_module.release_sdr_device(listening_active_device)
|
||||||
|
error = app_module.claim_sdr_device(device, 'listening')
|
||||||
|
if error:
|
||||||
|
return jsonify({
|
||||||
|
'status': 'error',
|
||||||
|
'error_type': 'DEVICE_BUSY',
|
||||||
|
'message': error
|
||||||
|
}), 409
|
||||||
|
listening_active_device = device
|
||||||
|
|
||||||
_start_audio_stream(frequency, modulation)
|
_start_audio_stream(frequency, modulation)
|
||||||
|
|
||||||
@@ -1091,10 +1138,14 @@ def start_audio() -> Response:
|
|||||||
|
|
||||||
|
|
||||||
@listening_post_bp.route('/audio/stop', methods=['POST'])
|
@listening_post_bp.route('/audio/stop', methods=['POST'])
|
||||||
def stop_audio() -> Response:
|
def stop_audio() -> Response:
|
||||||
"""Stop audio."""
|
"""Stop audio."""
|
||||||
_stop_audio_stream()
|
global listening_active_device
|
||||||
return jsonify({'status': 'stopped'})
|
_stop_audio_stream()
|
||||||
|
if listening_active_device is not None:
|
||||||
|
app_module.release_sdr_device(listening_active_device)
|
||||||
|
listening_active_device = None
|
||||||
|
return jsonify({'status': 'stopped'})
|
||||||
|
|
||||||
|
|
||||||
@listening_post_bp.route('/audio/status')
|
@listening_post_bp.route('/audio/status')
|
||||||
|
|||||||
@@ -1172,10 +1172,10 @@
|
|||||||
<!-- SQL, Gain, Vol Knobs -->
|
<!-- SQL, Gain, Vol Knobs -->
|
||||||
<div style="display: flex; gap: 15px;">
|
<div style="display: flex; gap: 15px;">
|
||||||
<div class="knob-container">
|
<div class="knob-container">
|
||||||
<div class="radio-knob" id="radioSquelchKnob" data-value="30" data-min="0"
|
<div class="radio-knob" id="radioSquelchKnob" data-value="0" data-min="0"
|
||||||
data-max="100" data-step="1"></div>
|
data-max="100" data-step="1"></div>
|
||||||
<div class="knob-label">SQL</div>
|
<div class="knob-label">SQL</div>
|
||||||
<div class="knob-value" id="radioSquelchValue">30</div>
|
<div class="knob-value" id="radioSquelchValue">0</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="knob-container">
|
<div class="knob-container">
|
||||||
<div class="radio-knob" id="radioGainKnob" data-value="40" data-min="0"
|
<div class="radio-knob" id="radioGainKnob" data-value="40" data-min="0"
|
||||||
|
|||||||
Reference in New Issue
Block a user