Rework radar system

This commit is contained in:
Ayzen
2026-10-06 12:32:26 +03:00
parent 552cdc688a
commit 5bb86b7165
299 changed files with 13537 additions and 27763 deletions
@@ -6,7 +6,7 @@ from contextlib import suppress
import logging
import threading
import time
from typing import Callable
from typing import Callable, cast
from ..exceptions import DeviceDisconnectedError, TimeoutError
from ..models import USBDeviceDescriptor
@@ -40,8 +40,9 @@ class USBTransport:
self._on_disconnect = on_disconnect
self._read_chunk_size = read_chunk_size
self._ctx: usb1.USBContext | None = None # type: ignore[valid-type]
self._handle: usb1.USBDeviceHandle | None = None # type: ignore[valid-type]
self._ctx: usb1.USBContext | None = None
# libusb1 binds close() to a zero-argument finalizer on each handle.
self._handle: usb1.USBDeviceHandle | None = None
self._rx_thread: threading.Thread | None = None
self._stop_event = threading.Event()
self._tx_lock = threading.Lock()
@@ -78,7 +79,7 @@ class USBTransport:
finally:
if handle is not None:
with suppress(usb1.USBError):
handle.close()
cast(Callable[[], None], handle.close)()
devices.append(USBDeviceDescriptor(serial=serial, vendor_id=vid, product_id=pid))
@@ -114,7 +115,7 @@ class USBTransport:
finally:
if handle is not None and handle is not selected_handle:
with suppress(usb1.USBError):
handle.close()
cast(Callable[[], None], handle.close)()
if selected_handle is None:
serial_msg = f" with serial '{serial}'" if serial else ""
@@ -149,7 +150,7 @@ class USBTransport:
self.disconnect()
raise
def _claim_interface_with_busy_recovery(self, handle: "usb1.USBDeviceHandle") -> None: # type: ignore[name-defined]
def _claim_interface_with_busy_recovery(self, handle: "usb1.USBDeviceHandle") -> None:
"""Claim the data interface, clearing a stale BUSY claim once if needed.
When a previous session's RX thread wedged inside libusb, ``disconnect()``
@@ -163,7 +164,9 @@ class USBTransport:
try:
handle.claimInterface(self.INTERFACE)
return
except usb1.USBErrorBusy as exc:
except usb1.USBError as exc:
if exc.value != -6: # LIBUSB_ERROR_BUSY
raise
logger.warning(
"USB interface %d busy on claim; resetting device to clear a stale claim: %s",
self.INTERFACE,
@@ -202,7 +205,7 @@ class USBTransport:
with suppress(usb1.USBError):
self._handle.releaseInterface(self.INTERFACE)
with suppress(usb1.USBError):
self._handle.close()
cast(Callable[[], None], self._handle.close)()
self._handle = None
if self._ctx is not None:
@@ -223,11 +226,9 @@ class USBTransport:
with self._tx_lock:
try:
written = handle.bulkWrite(self.DATA_EP_OUT, data, timeout=timeout_ms)
except usb1.USBErrorTimeout as exc:
raise TimeoutError("Timed out writing USB bulk packet") from exc
except usb1.USBErrorNoDevice as exc:
raise DeviceDisconnectedError("USB device disconnected during write") from exc
except usb1.USBError as exc:
if exc.value == -7: # LIBUSB_ERROR_TIMEOUT
raise TimeoutError("Timed out writing USB bulk packet") from exc
raise DeviceDisconnectedError(f"USB write failed: {exc}") from exc
if written != len(data):
@@ -248,16 +249,9 @@ class USBTransport:
while not self._stop_event.is_set():
try:
data = handle.bulkRead(self.DATA_EP_IN, self._read_chunk_size, timeout=timeout_ms)
except usb1.USBErrorTimeout:
continue
except usb1.USBErrorInterrupted:
continue
except usb1.USBErrorNoDevice as exc:
if self._on_disconnect is not None:
self._on_disconnect(DeviceDisconnectedError(f"USB device disconnected: {exc}"))
logger.warning("USB RX stopped: device disconnected: %s", exc)
return
except usb1.USBError as exc:
if exc.value in (-7, -10): # LIBUSB_ERROR_TIMEOUT / INTERRUPTED
continue
if self._stop_event.is_set():
return
if self._on_disconnect is not None:
@@ -294,7 +288,7 @@ class USBTransport:
@classmethod
def _iter_matching_devices(
cls,
ctx: "usb1.USBContext", # type: ignore[name-defined]
ctx: "usb1.USBContext",
):
"""Yield USB devices matching supported LibreVNA VID/PID pairs."""
for device in ctx.getDeviceList(skip_on_error=True):