mirror of
https://github.com/smittix/intercept.git
synced 2026-06-09 06:31:55 -07:00
Fix RF scanning and add status feedback
- Remove requirement for sdr_device to be set before RF scanning - Add RTL-SDR device detection check with rtl_test before scanning - Lower signal detection threshold from -50dBm to -70dBm - Lower noise floor threshold from 15dB to 10dB above noise - Add rf_status event for frontend feedback when RF unavailable - Show status message in RF panel explaining why scanning isn't working - Add CSS styling for status messages - Reset RF status message when sweep starts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+39
-4
@@ -1022,10 +1022,36 @@ def _scan_rf_signals(sdr_device: int | None, duration: int = 30) -> list[dict]:
|
||||
rtl_power_path = shutil.which('rtl_power')
|
||||
if not rtl_power_path:
|
||||
logger.warning("rtl_power not found in PATH, RF scanning unavailable")
|
||||
_emit_event('rf_status', {
|
||||
'status': 'error',
|
||||
'message': 'rtl_power not installed. Install rtl-sdr package for RF scanning.',
|
||||
})
|
||||
return signals
|
||||
|
||||
logger.info(f"Found rtl_power at: {rtl_power_path}")
|
||||
|
||||
# Test if RTL-SDR device is accessible
|
||||
rtl_test_path = shutil.which('rtl_test')
|
||||
if rtl_test_path:
|
||||
try:
|
||||
test_result = subprocess.run(
|
||||
[rtl_test_path, '-t'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
if 'No supported devices found' in test_result.stderr or test_result.returncode != 0:
|
||||
logger.warning("No RTL-SDR device found")
|
||||
_emit_event('rf_status', {
|
||||
'status': 'error',
|
||||
'message': 'No RTL-SDR device connected. Connect an RTL-SDR dongle for RF scanning.',
|
||||
})
|
||||
return signals
|
||||
except subprocess.TimeoutExpired:
|
||||
pass # Device might be busy, continue anyway
|
||||
except Exception as e:
|
||||
logger.debug(f"rtl_test check failed: {e}")
|
||||
|
||||
# Define frequency bands to scan (in Hz) - focus on common bug frequencies
|
||||
# Format: (start_freq, end_freq, bin_size, description)
|
||||
scan_bands = [
|
||||
@@ -1089,12 +1115,12 @@ def _scan_rf_signals(sdr_device: int | None, duration: int = 30) -> list[dict]:
|
||||
hz_step = float(parts[4])
|
||||
db_values = [float(x) for x in parts[6:] if x.strip()]
|
||||
|
||||
# Find peaks above noise floor (typically -60 dBm is strong)
|
||||
# Find peaks above noise floor
|
||||
noise_floor = sum(db_values) / len(db_values) if db_values else -100
|
||||
threshold = noise_floor + 15 # Signal must be 15dB above noise
|
||||
threshold = noise_floor + 10 # Signal must be 10dB above noise
|
||||
|
||||
for idx, db in enumerate(db_values):
|
||||
if db > threshold and db > -50: # Strong signal
|
||||
if db > threshold and db > -70: # Detect signals above -70dBm
|
||||
freq_hz = hz_low + (idx * hz_step)
|
||||
freq_mhz = freq_hz / 1000000
|
||||
|
||||
@@ -1282,7 +1308,7 @@ def _run_sweep(
|
||||
logger.error(f"Bluetooth scan error: {e}")
|
||||
|
||||
# Perform RF scan using SDR
|
||||
if rf_enabled and sdr_device is not None and (current_time - last_rf_scan) >= rf_scan_interval:
|
||||
if rf_enabled and (current_time - last_rf_scan) >= rf_scan_interval:
|
||||
try:
|
||||
_emit_event('sweep_progress', {
|
||||
'progress': min(100, int(((current_time - start_time) / duration) * 100)),
|
||||
@@ -1291,7 +1317,16 @@ def _run_sweep(
|
||||
'bt_count': len(all_bt),
|
||||
'rf_count': len(all_rf),
|
||||
})
|
||||
# Try RF scan even if sdr_device is None (will use device 0)
|
||||
rf_signals = _scan_rf_signals(sdr_device)
|
||||
|
||||
# If no signals and this is first RF scan, send info event
|
||||
if not rf_signals and last_rf_scan == 0:
|
||||
_emit_event('rf_status', {
|
||||
'status': 'no_signals',
|
||||
'message': 'RF scan completed but no signals detected. Check RTL-SDR connection.',
|
||||
})
|
||||
|
||||
for signal in rf_signals:
|
||||
freq_key = f"{signal['frequency']:.3f}"
|
||||
if freq_key not in [f"{s['frequency']:.3f}" for s in all_rf]:
|
||||
|
||||
+47
-1
@@ -2061,6 +2061,20 @@
|
||||
.classification-indicator {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.tscm-status-message {
|
||||
padding: 12px;
|
||||
background: rgba(255, 153, 51, 0.15);
|
||||
border: 1px solid rgba(255, 153, 51, 0.3);
|
||||
border-radius: 6px;
|
||||
color: var(--text-primary);
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.tscm-status-message .status-icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
.tscm-device-reasons {
|
||||
font-size: 10px;
|
||||
color: var(--text-secondary);
|
||||
@@ -10189,6 +10203,7 @@
|
||||
tscmWifiDevices = [];
|
||||
tscmBtDevices = [];
|
||||
tscmRfSignals = [];
|
||||
tscmRfStatusMessage = null;
|
||||
updateTscmDisplays();
|
||||
|
||||
// Start SSE stream
|
||||
@@ -10281,6 +10296,9 @@
|
||||
case 'rf_signal':
|
||||
addTscmRfSignal(data);
|
||||
break;
|
||||
case 'rf_status':
|
||||
handleRfStatus(data);
|
||||
break;
|
||||
case 'threat_detected':
|
||||
addTscmThreat(data);
|
||||
break;
|
||||
@@ -10331,7 +10349,11 @@
|
||||
}
|
||||
|
||||
let tscmRfSignals = [];
|
||||
let tscmRfStatusMessage = null;
|
||||
|
||||
function addTscmRfSignal(signal) {
|
||||
// Clear any error message since we're receiving signals
|
||||
tscmRfStatusMessage = null;
|
||||
// Check if already exists (within 0.1 MHz)
|
||||
const exists = tscmRfSignals.some(s => Math.abs(s.frequency - signal.frequency) < 0.1);
|
||||
if (!exists) {
|
||||
@@ -10345,6 +10367,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
function handleRfStatus(data) {
|
||||
// Store status message to display in RF panel
|
||||
tscmRfStatusMessage = data.message;
|
||||
updateRfDisplay();
|
||||
}
|
||||
|
||||
function updateRfDisplay() {
|
||||
const rfList = document.getElementById('tscmRfList');
|
||||
if (!rfList) return;
|
||||
|
||||
if (tscmRfSignals.length === 0) {
|
||||
if (tscmRfStatusMessage) {
|
||||
rfList.innerHTML = `<div class="tscm-status-message"><span class="status-icon">⚠️</span> ${escapeHtml(tscmRfStatusMessage)}</div>`;
|
||||
} else {
|
||||
rfList.innerHTML = '<div class="tscm-empty">No RF signals detected</div>';
|
||||
}
|
||||
}
|
||||
// If there are signals, updateTscmDisplays() will handle the display
|
||||
}
|
||||
|
||||
// Track high-interest devices for the threats panel
|
||||
let tscmHighInterestDevices = [];
|
||||
function addHighInterestDevice(device, protocol) {
|
||||
@@ -10780,7 +10822,11 @@
|
||||
// Update RF list
|
||||
const rfList = document.getElementById('tscmRfList');
|
||||
if (tscmRfSignals.length === 0) {
|
||||
rfList.innerHTML = '<div class="tscm-empty">No RF signals detected</div>';
|
||||
if (tscmRfStatusMessage) {
|
||||
rfList.innerHTML = `<div class="tscm-status-message"><span class="status-icon">⚠️</span> ${escapeHtml(tscmRfStatusMessage)}</div>`;
|
||||
} else {
|
||||
rfList.innerHTML = '<div class="tscm-empty">No RF signals detected</div>';
|
||||
}
|
||||
} else {
|
||||
// Sort by score (highest first)
|
||||
const sorted = [...tscmRfSignals].sort((a, b) => (b.score || 0) - (a.score || 0));
|
||||
|
||||
Reference in New Issue
Block a user