From 99d9f6b50afa65b442120169ddf1ef71b5f521fe Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Sun, 3 May 2026 23:50:54 -0400 Subject: [PATCH 1/2] RFC2217 flush --- serialx/platforms/serial_rfc2217/__init__.py | 16 ++++++++++++++-- tests/test_sync_transports.py | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/serialx/platforms/serial_rfc2217/__init__.py b/serialx/platforms/serial_rfc2217/__init__.py index ea07e16..ffe08a3 100644 --- a/serialx/platforms/serial_rfc2217/__init__.py +++ b/serialx/platforms/serial_rfc2217/__init__.py @@ -52,6 +52,7 @@ SetModemstateMaskCmd, SetParityCmd, SetStopsizeCmd, + SignatureCmd, TelnetCmdId, TelnetCommand, TelnetOption, @@ -665,7 +666,12 @@ def _get_modem_pins(self) -> ModemPins: return self._engine.get_modem_pins() def _flush(self) -> None: - """Flush write buffers (no-op, TCP handles buffering).""" + """Wait for the server to acknowledge all preceding writes.""" + if not self._engine.negotiated: + return + + # RFC2217 has no flush. Instead, we "flush" the pipe with a req/rsp sequence. + self._send_and_wait(SignatureCmd()) class _RFC2217ProxyProtocol(asyncio.Protocol): @@ -1007,7 +1013,13 @@ def abort(self) -> None: self._tcp_connection_lost(None) async def flush(self) -> None: - """Flush write buffers (no-op, TCP transport handles buffering).""" + """Wait for the server to acknowledge all preceding writes.""" + assert self._serial is not None + if not self._serial._engine.negotiated: + return + + # RFC2217 has no flush. Instead, we "flush" the pipe with a req/rsp sequence. + await self._send_and_wait(SignatureCmd()) def get_write_buffer_size(self) -> int: """Get the number of bytes currently in the write buffer.""" diff --git a/tests/test_sync_transports.py b/tests/test_sync_transports.py index 641c7c8..27e04ad 100644 --- a/tests/test_sync_transports.py +++ b/tests/test_sync_transports.py @@ -869,6 +869,11 @@ def test_fast_open_close(serial_pair: SerialPair) -> None: with Serial.from_url(serial_pair.left, baudrate=115200) as left: with Serial.from_url(serial_pair.right, baudrate=115200) as right: right.write(message) + right.flush() + + # Some backends (notably complex chained RFC2217) lose data on close, making + # this test flaky without a tiny delay + time.sleep(0.01) assert left.readexactly(len(message)) == message From ee9ef582c1de71904df301f49dce32805e5ce57e Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 4 May 2026 01:08:37 -0400 Subject: [PATCH 2/2] Try a different command --- serialx/platforms/serial_rfc2217/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/serialx/platforms/serial_rfc2217/__init__.py b/serialx/platforms/serial_rfc2217/__init__.py index ffe08a3..d9f7eb9 100644 --- a/serialx/platforms/serial_rfc2217/__init__.py +++ b/serialx/platforms/serial_rfc2217/__init__.py @@ -52,7 +52,6 @@ SetModemstateMaskCmd, SetParityCmd, SetStopsizeCmd, - SignatureCmd, TelnetCmdId, TelnetCommand, TelnetOption, @@ -671,7 +670,7 @@ def _flush(self) -> None: return # RFC2217 has no flush. Instead, we "flush" the pipe with a req/rsp sequence. - self._send_and_wait(SignatureCmd()) + self._send_and_wait(SetBaudrateCmd(baudrate=self._baudrate)) class _RFC2217ProxyProtocol(asyncio.Protocol): @@ -1019,7 +1018,7 @@ async def flush(self) -> None: return # RFC2217 has no flush. Instead, we "flush" the pipe with a req/rsp sequence. - await self._send_and_wait(SignatureCmd()) + await self._send_and_wait(SetBaudrateCmd(baudrate=self._serial._baudrate)) def get_write_buffer_size(self) -> int: """Get the number of bytes currently in the write buffer."""