From 3a951d6524ed2a3b0535c0e3c40b4687ef7b624c Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Tue, 27 Dec 2022 01:35:38 +0100 Subject: [PATCH 1/3] Add rfc2217 support --- serial_asyncio/__init__.py | 85 +++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 46 deletions(-) diff --git a/serial_asyncio/__init__.py b/serial_asyncio/__init__.py index e173b56..83feef9 100644 --- a/serial_asyncio/__init__.py +++ b/serial_asyncio/__init__.py @@ -65,7 +65,8 @@ def __init__(self, loop, protocol, serial_instance): # Asynchronous I/O requires non-blocking devices self._serial.timeout = 0 - self._serial.write_timeout = 0 + if not self.serial.port.startswith("rfc2217"): + self._serial.write_timeout = 0 # These two callbacks will be enqueued in a FIFO queue by asyncio loop.call_soon(protocol.connection_made, self) @@ -284,60 +285,52 @@ def _write_ready(self): self._maybe_resume_protocol() assert self._has_writer - if os.name == "nt": - def _poll_read(self): - if self._has_reader and not self._closing: - try: - self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read) - if self.serial.in_waiting: - self._read_ready() - except serial.SerialException as exc: - self._fatal_error(exc, 'Fatal write error on serial transport') - - def _ensure_reader(self): - if not self._has_reader and not self._closing: + def _poll_read(self): + if self._has_reader and not self._closing: + try: self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read) - - def _remove_reader(self): - if self._has_reader: - self._has_reader.cancel() - self._has_reader = False - - def _poll_write(self): - if self._has_writer and not self._closing: - self._has_writer = self._loop.call_later(self._poll_wait_time, self._poll_write) - if self.serial.out_waiting < self._max_out_waiting: - self._write_ready() - - def _ensure_writer(self): - if not self._has_writer and not self._closing: - self._has_writer = self._loop.call_soon(self._poll_write) - - def _remove_writer(self): - if self._has_writer: - self._has_writer.cancel() - self._has_writer = False - - else: - def _ensure_reader(self): - if (not self._has_reader) and (not self._closing): + if self.serial.in_waiting: + self._read_ready() + except serial.SerialException as exc: + self._fatal_error(exc, 'Fatal write error on serial transport') + + def _ensure_reader(self): + if not self._has_reader and not self._closing: + if os.name == "nt" or self._serial.port.startswith("rfc2217"): + self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read) + else: self._loop.add_reader(self._serial.fileno(), self._read_ready) self._has_reader = True - def _remove_reader(self): - if self._has_reader: + def _remove_reader(self): + if self._has_reader: + if os.name == "nt" or self._serial.port.startswith("rfc2217"): + self._has_reader.cancel() + else: self._loop.remove_reader(self._serial.fileno()) - self._has_reader = False + self._has_reader = False - def _ensure_writer(self): - if (not self._has_writer) and (not self._closing): - self._loop.add_writer(self._serial.fileno(), self._write_ready) + def _poll_write(self): + if self._has_writer and not self._closing: + self._has_writer = self._loop.call_later(self._poll_wait_time, self._poll_write) + if not self._serial.port.startswith("rfc2217") and self.serial.out_waiting < self._max_out_waiting: + self._write_ready() + + def _ensure_writer(self): + if not self._has_writer and not self._closing: + if os.name == "nt" or self._serial.port.startswith("rfc2217"): + self._has_writer = self._loop.call_soon(self._poll_write) + else: + self._loop.add_writer(self.serial.fileno(), self._write_ready) self._has_writer = True - def _remove_writer(self): - if self._has_writer: + def _remove_writer(self): + if self._has_writer: + if os.name == "nt" or self._serial.port.startswith("rfc2217"): + self._has_writer.cancel() + else: self._loop.remove_writer(self._serial.fileno()) - self._has_writer = False + self._has_writer = False def _set_write_buffer_limits(self, high=None, low=None): """Ensure consistent write-buffer limits.""" From 7ff85e56e024c6da4d4a5781f94fa1092481bb70 Mon Sep 17 00:00:00 2001 From: Jon Caruana Date: Thu, 29 Dec 2022 17:36:45 +0000 Subject: [PATCH 2/3] Use the polling method for any Serial implementation that doesn't support fileno. --- serial_asyncio/__init__.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/serial_asyncio/__init__.py b/serial_asyncio/__init__.py index 83feef9..e7dd79c 100644 --- a/serial_asyncio/__init__.py +++ b/serial_asyncio/__init__.py @@ -61,12 +61,18 @@ def __init__(self, loop, protocol, serial_instance): self._poll_wait_time = 0.0005 self._max_out_waiting = 1024 - # XXX how to support url handlers too + try: + self._serial.fileno() + self._has_fileno = True + except: + self._has_fileno = False # Asynchronous I/O requires non-blocking devices self._serial.timeout = 0 - if not self.serial.port.startswith("rfc2217"): + try: self._serial.write_timeout = 0 + except: + pass # best effort, not supported by all Serial implementations # These two callbacks will be enqueued in a FIFO queue by asyncio loop.call_soon(protocol.connection_made, self) @@ -296,7 +302,7 @@ def _poll_read(self): def _ensure_reader(self): if not self._has_reader and not self._closing: - if os.name == "nt" or self._serial.port.startswith("rfc2217"): + if not self._has_fileno: self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read) else: self._loop.add_reader(self._serial.fileno(), self._read_ready) @@ -304,7 +310,7 @@ def _ensure_reader(self): def _remove_reader(self): if self._has_reader: - if os.name == "nt" or self._serial.port.startswith("rfc2217"): + if not self._has_fileno: self._has_reader.cancel() else: self._loop.remove_reader(self._serial.fileno()) @@ -318,7 +324,7 @@ def _poll_write(self): def _ensure_writer(self): if not self._has_writer and not self._closing: - if os.name == "nt" or self._serial.port.startswith("rfc2217"): + if not self._has_fileno: self._has_writer = self._loop.call_soon(self._poll_write) else: self._loop.add_writer(self.serial.fileno(), self._write_ready) @@ -326,7 +332,7 @@ def _ensure_writer(self): def _remove_writer(self): if self._has_writer: - if os.name == "nt" or self._serial.port.startswith("rfc2217"): + if not self._has_fileno: self._has_writer.cancel() else: self._loop.remove_writer(self._serial.fileno()) From 3bdbbbc76a1bd1cdb4da62034060c38568ddf382 Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Sun, 26 Nov 2023 01:42:45 +0100 Subject: [PATCH 3/3] Fix writing issue for rfc2217 --- serial_asyncio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serial_asyncio/__init__.py b/serial_asyncio/__init__.py index e7dd79c..aeb10e0 100644 --- a/serial_asyncio/__init__.py +++ b/serial_asyncio/__init__.py @@ -319,7 +319,7 @@ def _remove_reader(self): def _poll_write(self): if self._has_writer and not self._closing: self._has_writer = self._loop.call_later(self._poll_wait_time, self._poll_write) - if not self._serial.port.startswith("rfc2217") and self.serial.out_waiting < self._max_out_waiting: + if not hasattr(self.serial, "out_waiting") or self.serial.out_waiting < self._max_out_waiting: self._write_ready() def _ensure_writer(self):