[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:
Simon Lin
2022-01-20 08:56:47 -08:00
committed by GitHub
parent 3fdaaab07c
commit 0dccf05473
2 changed files with 30 additions and 6 deletions
+14 -2
View File
@@ -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:]
+16 -4
View File
@@ -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'))