mirror of
https://github.com/smittix/intercept.git
synced 2026-07-27 10:08:10 -07:00
fix: waterfall device claim fails on frequency change due to USB release lag
When restarting capture for a new frequency, the USB handle from the just-killed process may not be released by the kernel in time for the rtl_test probe inside claim_sdr_device. Add retry logic (up to 4 attempts with 0.4s backoff) matching the pattern already used by the audio start endpoint. Also clean up stale shared-monitor state in the frontend error handler so the monitor button is not left disabled when the capture restart fails.
This commit is contained in:
@@ -462,8 +462,16 @@ def init_waterfall_websocket(app: Flask):
|
|||||||
start_freq = center_freq_mhz - effective_span_mhz / 2
|
start_freq = center_freq_mhz - effective_span_mhz / 2
|
||||||
end_freq = center_freq_mhz + effective_span_mhz / 2
|
end_freq = center_freq_mhz + effective_span_mhz / 2
|
||||||
|
|
||||||
# Claim the device
|
# Claim the device (retry when restarting to allow
|
||||||
claim_err = app_module.claim_sdr_device(device_index, 'waterfall')
|
# the kernel time to release the USB handle).
|
||||||
|
max_claim_attempts = 4 if was_restarting else 1
|
||||||
|
claim_err = None
|
||||||
|
for _claim_attempt in range(max_claim_attempts):
|
||||||
|
claim_err = app_module.claim_sdr_device(device_index, 'waterfall')
|
||||||
|
if not claim_err:
|
||||||
|
break
|
||||||
|
if _claim_attempt < max_claim_attempts - 1:
|
||||||
|
time.sleep(0.4)
|
||||||
if claim_err:
|
if claim_err:
|
||||||
ws.send(json.dumps({
|
ws.send(json.dumps({
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
|
|||||||
@@ -2488,6 +2488,17 @@ const Waterfall = (function () {
|
|||||||
} else if (msg.status === 'error') {
|
} else if (msg.status === 'error') {
|
||||||
_running = false;
|
_running = false;
|
||||||
_scanStartPending = false;
|
_scanStartPending = false;
|
||||||
|
_pendingSharedMonitorRearm = false;
|
||||||
|
// If the monitor was using the shared IQ stream that
|
||||||
|
// just failed, tear down the stale monitor state so
|
||||||
|
// the button becomes clickable again after restart.
|
||||||
|
if (_monitoring && _monitorSource === 'waterfall') {
|
||||||
|
clearTimeout(_monitorRetuneTimer);
|
||||||
|
_monitoring = false;
|
||||||
|
_monitorSource = 'process';
|
||||||
|
_syncMonitorButtons();
|
||||||
|
_setMonitorState('Monitor stopped (waterfall error)');
|
||||||
|
}
|
||||||
if (_scanRunning) {
|
if (_scanRunning) {
|
||||||
_scanAwaitingCapture = true;
|
_scanAwaitingCapture = true;
|
||||||
_setScanState(msg.message || 'Waterfall retune error, retrying...', true);
|
_setScanState(msg.message || 'Waterfall retune error, retrying...', true);
|
||||||
|
|||||||
Reference in New Issue
Block a user