mirror of
https://github.com/espressif/openthread.git
synced 2026-10-01 13:27:42 +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)
|
return repr(self.__otcli)
|
||||||
|
|
||||||
def execute_command(self, cmd, timeout=10) -> List[str]:
|
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)
|
self.__otcli.writeline(cmd)
|
||||||
|
|
||||||
if cmd in ('reset', 'factoryreset'):
|
if cmd in ('reset', 'factoryreset'):
|
||||||
@@ -140,6 +141,7 @@ class OtCliCommandRunner(OTCommandHandler):
|
|||||||
def close(self):
|
def close(self):
|
||||||
self.__should_close.set()
|
self.__should_close.set()
|
||||||
self.__otcli.close()
|
self.__otcli.close()
|
||||||
|
self.__otcli_reader.join()
|
||||||
|
|
||||||
def set_line_read_callback(self, callback: Optional[Callable[[str], Any]]):
|
def set_line_read_callback(self, callback: Optional[Callable[[str], Any]]):
|
||||||
self.__line_read_callback = callback
|
self.__line_read_callback = callback
|
||||||
@@ -181,10 +183,20 @@ class OtCliCommandRunner(OTCommandHandler):
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
def __otcli_read_routine(self):
|
def __otcli_read_routine(self):
|
||||||
while not self.__should_close.isSet():
|
while not self.__should_close.is_set():
|
||||||
line = self.__otcli.readline()
|
try:
|
||||||
|
line = self.__otcli.readline()
|
||||||
|
except Exception:
|
||||||
|
if self.__should_close.is_set():
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
logging.debug('%s: %r', self.__otcli, line)
|
logging.debug('%s: %r', self.__otcli, line)
|
||||||
|
|
||||||
|
if line is None:
|
||||||
|
break
|
||||||
|
|
||||||
if line.startswith('> '):
|
if line.startswith('> '):
|
||||||
line = line[2:]
|
line = line[2:]
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import logging
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
class OtCliHandler:
|
class OtCliHandler:
|
||||||
@@ -142,14 +143,25 @@ class OtCliSerial(OtCliHandler):
|
|||||||
self.__baudrate = baudrate
|
self.__baudrate = baudrate
|
||||||
|
|
||||||
import serial
|
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):
|
def __repr__(self):
|
||||||
return self.__dev
|
return self.__dev
|
||||||
|
|
||||||
def readline(self) -> str:
|
def readline(self) -> Optional[str]:
|
||||||
line = self.__serial.readline().decode('utf-8').rstrip('\r\n')
|
while self.__serial.is_open:
|
||||||
return line
|
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):
|
def writeline(self, s: str):
|
||||||
self.__serial.write((s + '\n').encode('utf-8'))
|
self.__serial.write((s + '\n').encode('utf-8'))
|
||||||
|
|||||||
Reference in New Issue
Block a user