Skip to content

Commit 92a8262

Browse files
authored
Don't try to interpret incoming data as AT command mode response. (#64)
* Update tests. * Control handling of incoming data as AT responses. Don't try to interpret incoming serial data as a AT command mode response, unless specifically entered into command mode.
1 parent 4664177 commit 92a8262

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

tests/test_uart.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ def test_close(gw):
6767

6868

6969
def test_data_received_chunk_frame(gw):
70-
data = b"~\x00\x07\x8b\x0e\xff\xfd\x00$\x02D"
70+
data = b"~\x00\r\x88\rID\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd"
7171
gw.frame_received = mock.MagicMock()
72-
gw.data_received(data[:-4])
72+
gw.data_received(data[:3])
7373
assert gw.frame_received.call_count == 0
74-
gw.data_received(data[-4:])
74+
gw.data_received(data[3:])
7575
assert gw.frame_received.call_count == 1
7676
assert gw.frame_received.call_args[0][0] == data[3:-1]
7777

7878

7979
def test_data_received_full_frame(gw):
80-
data = b"~\x00\x07\x8b\x0e\xff\xfd\x00$\x02D"
80+
data = b"~\x00\r\x88\rID\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd"
8181
gw.frame_received = mock.MagicMock()
8282
gw.data_received(data)
8383
assert gw.frame_received.call_count == 1
@@ -91,15 +91,29 @@ def test_data_received_incomplete_frame(gw):
9191
assert gw.frame_received.call_count == 0
9292

9393

94-
def test_data_received_at_response(gw):
94+
def test_data_received_at_response_non_cmd_mode(gw):
9595
data = b"OK\x0D"
9696
gw.frame_received = mock.MagicMock()
9797
gw.command_mode_rsp = mock.MagicMock()
9898

99+
gw.data_received(data)
100+
assert gw.command_mode_rsp.call_count == 0
101+
102+
103+
def test_data_received_at_response_in_cmd_mode(gw):
104+
data = b"OK\x0D"
105+
gw.frame_received = mock.MagicMock()
106+
gw.command_mode_rsp = mock.MagicMock()
107+
108+
gw.command_mode_send(b"")
99109
gw.data_received(data)
100110
assert gw.command_mode_rsp.call_count == 1
101111
assert gw.command_mode_rsp.call_args[0][0] == b"OK"
102112

113+
gw.reset_command_mode()
114+
gw.data_received(data)
115+
assert gw.command_mode_rsp.call_count == 1
116+
103117

104118
def test_extract(gw):
105119
gw._buffer = b"\x7E\x00\x02\x23\x7D\x31\xCBextra"

zigpy_xbee/api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,11 +449,11 @@ async def api_mode_at_commands(self, baudrate):
449449
cmds.insert(0, bd)
450450

451451
for cmd in cmds:
452-
if await self.command_mode_at_cmd(cmd + "\r"):
453-
LOGGER.debug("Successfuly sent %s cmd", cmd)
454-
else:
452+
if not await self.command_mode_at_cmd(cmd + "\r"):
455453
LOGGER.debug("No response to %s cmd", cmd)
456454
return None
455+
LOGGER.debug("Successfuly sent %s cmd", cmd)
456+
self._uart.reset_command_mode()
457457
return True
458458

459459
async def init_api_mode(self):

zigpy_xbee/uart.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def __init__(self, api, connected_future=None):
1919
self._buffer = b""
2020
self._connected_future = connected_future
2121
self._api = api
22+
self._in_command_mode = False
2223

2324
def send(self, data):
2425
"""Send data, taking care of escaping and framing"""
@@ -64,6 +65,7 @@ def command_mode_rsp(self, data):
6465
def command_mode_send(self, data):
6566
"""Send data in command mode."""
6667
LOGGER.debug("Command mode sending %s to uart", data)
68+
self._in_command_mode = True
6769
self._transport.write(data)
6870

6971
def data_received(self, data):
@@ -74,7 +76,7 @@ def data_received(self, data):
7476
if frame is None:
7577
break
7678
self.frame_received(frame)
77-
if self._buffer[-1:] == b"\r":
79+
if self._in_command_mode and self._buffer[-1:] == b"\r":
7880
rsp, self._buffer = (self._buffer[:-1], b"")
7981
self.command_mode_rsp(rsp)
8082

@@ -86,6 +88,10 @@ def frame_received(self, frame):
8688
def close(self):
8789
self._transport.close()
8890

91+
def reset_command_mode(self):
92+
"""Reset command mode and ignore \r character as command mode response."""
93+
self._in_command_mode = False
94+
8995
def _extract_frame(self):
9096
first_start = self._buffer.find(self.START)
9197
if first_start < 0:

0 commit comments

Comments
 (0)