From 50a88abf2f2467b6f1ebc423892177d59384da21 Mon Sep 17 00:00:00 2001 From: Martin Teichmann <martin.teichmann@xfel.eu> Date: Thu, 18 Feb 2021 15:21:31 +0000 Subject: [PATCH] support serial connections --- ebpfcat/ebpfcat.py | 1 + ebpfcat/serial.py | 82 ++++++++++++++++++++++++++++++++++++++++++++ ebpfcat/terminals.py | 20 +++++++++++ 3 files changed, 103 insertions(+) create mode 100644 ebpfcat/serial.py diff --git a/ebpfcat/ebpfcat.py b/ebpfcat/ebpfcat.py index 648243e..f39a805 100644 --- a/ebpfcat/ebpfcat.py +++ b/ebpfcat/ebpfcat.py @@ -321,6 +321,7 @@ class SyncGroup(SyncGroupBase): self.current_data = bytearray(data) for dev in self.devices: dev.update() + await sleep(0) def start(self): self.allocate() diff --git a/ebpfcat/serial.py b/ebpfcat/serial.py new file mode 100644 index 0000000..98b9ef5 --- /dev/null +++ b/ebpfcat/serial.py @@ -0,0 +1,82 @@ +from asyncio import ensure_future, Event, Queue, StreamReader, gather +from .ebpfcat import Device, TerminalVar + + +class Serial(Device): + channel = TerminalVar() + + def __init__(self, channel): + self.buffer = Queue() + self.channel = channel + self.data_arrived = Event() + + def write(self, data): + self.buffer.put_nowait(data) + + def connect(self): + self.task = ensure_future(self.run()) + self.reader = StreamReader() + return self.reader, self + + async def run(self): + while not self.channel.init_accept: + self.channel.init_request = True + await self.data_arrived.wait() + self.channel.init_request = False + while self.channel.init_accept: + await self.data_arrived.wait() + + await gather(self.receive(), self.transmit()) + + async def receive(self): + ra = self.channel.receive_accept + while True: + rr = self.channel.receive_request + while rr == self.channel.receive_request: + self.channel.receive_accept = ra + await self.data_arrived.wait() + self.reader.feed_data(self.channel.in_string) + ra = not ra + + async def transmit(self): + remainder = b"" + + async def inner(): + nonlocal remainder + s = remainder + size = len(remainder) + while not self.buffer.empty() or size == 0: + if size + len(s) > 22: + remainder = s[22-size:] + yield s[:22-size] + return + else: + yield s + size += len(s) + s = await self.buffer.get() + + while True: + ta = self.channel.transmit_accept + tr = self.channel.transmit_request + chunk = b"".join([s async for s in inner()]) + while ta == self.channel.transmit_accept: + self.channel.out_string = chunk + self.channel.transmit_request = not tr + await self.data_arrived.wait() + + def update(self): + self.data_arrived.set() + self.data_arrived.clear() + + def get_chunk(self): + def inner(): + size = 0 + while size < 22 and len(self.buffer): + s = self.buffer.popleft() + if size + len(s) > 22: + self.buffer.appendleft(s[22-size:]) + yield s[:22-size] + else: + yield + l += len(s) + return b"".join(inner()) diff --git a/ebpfcat/terminals.py b/ebpfcat/terminals.py index 620a434..060f734 100644 --- a/ebpfcat/terminals.py +++ b/ebpfcat/terminals.py @@ -32,3 +32,23 @@ class EK1814(EBPFTerminal): ch6 = PacketDesc((1, 0), 1) ch7 = PacketDesc((1, 0), 2) ch8 = PacketDesc((1, 0), 3) + + +class EL6022(EBPFTerminal): + class Channel(Struct): + transmit_accept = PacketDesc((0, 0), 0) + receive_request = PacketDesc((0, 0), 1) + init_accept = PacketDesc((0, 0), 2) + status = PacketDesc((0, 0), "H") + in_string = PacketDesc((0, 1), "23p") + wkc1 = PacketDesc((0, 24), "H") + + transmit_request = PacketDesc((1, 0), 0) + receive_accept = PacketDesc((1, 0), 1) + init_request = PacketDesc((1, 0), 2) + control = PacketDesc((1, 0), "H") + out_string = PacketDesc((1, 1), "23p") + wkc2 = PacketDesc((0, 24), "H") + + channel1 = Channel(0, 0) + channel2 = Channel(24, 24) -- GitLab