harden UBX parsing/dispatch and report peer-side disconnects in GUI
A struct size-mismatch or any other parse error in a listener could propagate uncaught out of the socket-reading thread and silently kill it. Catch broadly in the event loop and per-listener in call_listener, and make the NAV-SAT/NAV-SIG/RXM-RAWX group parsers tolerate a payload length that isn't an exact multiple of the group size instead of crashing on a short struct.unpack. Also wire NetworkBackend's socket-loss detection through to ReceiverManager (via a queued signal, since the callback fires from the backend thread) so the GUI reflects a peer-initiated disconnect instead of leaving the row stuck showing "connected". Verified against a real ZED-X20P: it drops the TCP session on its own after ~20-28s regardless of traffic; the GUI now marks the receiver disconnected and frees its ID for reconnecting. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AzmCaNjDb3TAqPpTwunKTY
This commit is contained in:
+11
-1
@@ -93,12 +93,14 @@ class ReceiverManager(QObject):
|
||||
connection_changed = pyqtSignal(str, bool) # rid, connected
|
||||
receiver_added = pyqtSignal(str)
|
||||
receiver_removed = pyqtSignal(str)
|
||||
_connection_lost = pyqtSignal(str) # internal: backend thread -> GUI thread
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._states: dict = {}
|
||||
self._configs: dict = {}
|
||||
self._lru: list = self._load_lru()
|
||||
self._connection_lost.connect(self._handle_connection_lost)
|
||||
|
||||
# ── LRU ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -164,7 +166,8 @@ class ReceiverManager(QObject):
|
||||
|
||||
if config.conn_type == 'tcp':
|
||||
backend = NetworkBackend(
|
||||
[{'name': rid, 'host': config.host, 'port': config.port}]
|
||||
[{'name': rid, 'host': config.host, 'port': config.port}],
|
||||
on_disconnect=lambda name, r=rid: self._connection_lost.emit(r),
|
||||
)
|
||||
elif config.conn_type == 'serial':
|
||||
backend = SerialBackend(config.serial_port, config.baud_rate)
|
||||
@@ -211,6 +214,13 @@ class ReceiverManager(QObject):
|
||||
self._push_lru(config)
|
||||
self.connection_changed.emit(rid, True)
|
||||
|
||||
def _handle_connection_lost(self, rid: str):
|
||||
state = self._states.get(rid)
|
||||
if not state or not state.connected:
|
||||
return
|
||||
print(f"Receiver '{rid}': connection lost")
|
||||
self.remove_receiver(rid)
|
||||
|
||||
def disconnect_receiver(self, rid: str):
|
||||
state = self._states.get(rid)
|
||||
if not state or not state.connected:
|
||||
|
||||
Reference in New Issue
Block a user