mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 22:57:47 +00:00
[otci] fix read error after close (#7331)
This commit fixes OTCI that CLI connection via serial may fail when closing.
This commit is contained in:
@@ -107,6 +107,7 @@ class OtCliCommandRunner(OTCommandHandler):
|
||||
return repr(self.__otcli)
|
||||
|
||||
def execute_command(self, cmd, timeout=10) -> List[str]:
|
||||
assert not self.__should_close.is_set(), "OT CLI is already closed."
|
||||
self.__otcli.writeline(cmd)
|
||||
|
||||
if cmd in ('reset', 'factoryreset'):
|
||||
@@ -140,6 +141,7 @@ class OtCliCommandRunner(OTCommandHandler):
|
||||
def close(self):
|
||||
self.__should_close.set()
|
||||
self.__otcli.close()
|
||||
self.__otcli_reader.join()
|
||||
|
||||
def set_line_read_callback(self, callback: Optional[Callable[[str], Any]]):
|
||||
self.__line_read_callback = callback
|
||||
@@ -181,10 +183,20 @@ class OtCliCommandRunner(OTCommandHandler):
|
||||
return output
|
||||
|
||||
def __otcli_read_routine(self):
|
||||
while not self.__should_close.isSet():
|
||||
line = self.__otcli.readline()
|
||||
while not self.__should_close.is_set():
|
||||
try:
|
||||
line = self.__otcli.readline()
|
||||
except Exception:
|
||||
if self.__should_close.is_set():
|
||||
break
|
||||
else:
|
||||
raise
|
||||
|
||||
logging.debug('%s: %r', self.__otcli, line)
|
||||
|
||||
if line is None:
|
||||
break
|
||||
|
||||
if line.startswith('> '):
|
||||
line = line[2:]
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import logging
|
||||
import subprocess
|
||||
import time
|
||||
from abc import abstractmethod
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class OtCliHandler:
|
||||
@@ -142,14 +143,25 @@ class OtCliSerial(OtCliHandler):
|
||||
self.__baudrate = baudrate
|
||||
|
||||
import serial
|
||||
self.__serial = serial.Serial(self.__dev, self.__baudrate, timeout=None, exclusive=True)
|
||||
self.__serial = serial.Serial(self.__dev, self.__baudrate, timeout=0.1, exclusive=True)
|
||||
self.__linebuffer = b''
|
||||
|
||||
def __repr__(self):
|
||||
return self.__dev
|
||||
|
||||
def readline(self) -> str:
|
||||
line = self.__serial.readline().decode('utf-8').rstrip('\r\n')
|
||||
return line
|
||||
def readline(self) -> Optional[str]:
|
||||
while self.__serial.is_open:
|
||||
line = self.__serial.readline()
|
||||
|
||||
if not line.endswith(b'\n'):
|
||||
self.__linebuffer += line
|
||||
else:
|
||||
line = self.__linebuffer + line
|
||||
self.__linebuffer = b''
|
||||
|
||||
return line.decode('utf-8').rstrip('\r\n')
|
||||
|
||||
return None
|
||||
|
||||
def writeline(self, s: str):
|
||||
self.__serial.write((s + '\n').encode('utf-8'))
|
||||
|
||||
Reference in New Issue
Block a user