Extract reusable device protocols, ports and logic analyzers from SETGUI
This commit is contained in:
71
python/set_devices/protocol_router.py
Normal file
71
python/set_devices/protocol_router.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""Выбор wire-протокола для одного последовательного канала SETGUI.
|
||||
|
||||
Во время подключения оба потоковых parser-а получают одинаковые байты. Первый
|
||||
полностью проверенный кадр фиксирует режим канала до следующего ``reset``.
|
||||
Версия находится сразу после общего SOF A5 5A, поэтому протоколы не могут
|
||||
ошибочно принять кадр друг друга.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from set_devices import protocol as gui_v1
|
||||
from setprotocol import core as setp_v2
|
||||
|
||||
|
||||
class ProtocolMode(Enum):
|
||||
"""Wire-протокол, выбранный для текущего физического соединения."""
|
||||
|
||||
AUTO = "auto"
|
||||
SETPROTOCOL_V2 = "setprotocol_v2"
|
||||
GUI_V1 = "gui_v1"
|
||||
|
||||
@property
|
||||
def display_name(self) -> str:
|
||||
return {
|
||||
ProtocolMode.AUTO: "Определение протокола…",
|
||||
ProtocolMode.SETPROTOCOL_V2: "SETProtocol v2",
|
||||
ProtocolMode.GUI_V1: "GUI protocol v1 (совместимость)",
|
||||
}[self]
|
||||
|
||||
|
||||
class ProtocolRouter:
|
||||
"""Потоковый маршрутизатор SETProtocol v2 и устаревшего GUI v1."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._v2 = setp_v2.FrameParser()
|
||||
self._v1 = gui_v1.FrameParser()
|
||||
self.mode = ProtocolMode.AUTO
|
||||
|
||||
def reset(self, mode: ProtocolMode = ProtocolMode.AUTO) -> None:
|
||||
self._v2.reset()
|
||||
self._v1.reset()
|
||||
self.mode = mode
|
||||
|
||||
def select(self, mode: ProtocolMode) -> None:
|
||||
"""Фиксирует режим и отбрасывает остатки предыдущего разбора."""
|
||||
if mode is ProtocolMode.AUTO:
|
||||
self.reset()
|
||||
return
|
||||
self.reset(mode)
|
||||
|
||||
def feed(self, data: bytes) -> list[gui_v1.Frame | setp_v2.Frame]:
|
||||
if self.mode is ProtocolMode.SETPROTOCOL_V2:
|
||||
return list(self._v2.feed(data))
|
||||
if self.mode is ProtocolMode.GUI_V1:
|
||||
return list(self._v1.feed(data))
|
||||
|
||||
# В AUTO parser-ы независимы. Неверная версия учитывается только их
|
||||
# внутренней диагностикой и не влияет на второй parser.
|
||||
v2_frames = self._v2.feed(data)
|
||||
v1_frames = self._v1.feed(data)
|
||||
if v2_frames:
|
||||
self.mode = ProtocolMode.SETPROTOCOL_V2
|
||||
self._v1.reset()
|
||||
return list(v2_frames)
|
||||
if v1_frames:
|
||||
self.mode = ProtocolMode.GUI_V1
|
||||
self._v2.reset()
|
||||
return list(v1_frames)
|
||||
return []
|
||||
Reference in New Issue
Block a user