Rework radar system
This commit is contained in:
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user