Merge pull request #113 from maxburto/fix/get-msg-channel-data

Wait for CHANNEL_DATA_RECV in get_msg()
This commit is contained in:
fdlamotte
2026-10-03 15:11:31 -04:00
committed by GitHub
2 changed files with 46 additions and 0 deletions
+1
View File
@@ -19,6 +19,7 @@ class MessagingCommands(CommandHandlerBase):
[ [
EventType.CONTACT_MSG_RECV, EventType.CONTACT_MSG_RECV,
EventType.CHANNEL_MSG_RECV, EventType.CHANNEL_MSG_RECV,
EventType.CHANNEL_DATA_RECV,
EventType.ERROR, EventType.ERROR,
EventType.NO_MORE_MSGS, EventType.NO_MORE_MSGS,
], ],
+45
View File
@@ -12,6 +12,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
from meshcore.events import Event, EventType, EventDispatcher from meshcore.events import Event, EventType, EventDispatcher
from meshcore.reader import MessageReader from meshcore.reader import MessageReader
from meshcore.packets import PacketType, CommandType from meshcore.packets import PacketType, CommandType
from meshcore.commands.messaging import MessagingCommands
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -489,6 +490,50 @@ async def test_channel_data_recv_widened_data_type():
assert evt.payload["payload"] == "" assert evt.payload["payload"] == ""
@pytest.mark.asyncio
async def test_get_msg_returns_channel_data_recv():
"""get_msg() resolves on CHANNEL_DATA_RECV instead of timing out.
The companion protocol lists PACKET_CHANNEL_DATA_RECV (0x1B) as an answer
to GET_MESSAGE (0x0A). When the next queued message is a channel datagram
the device answers with that frame, and get_msg() must return it rather
than an ERROR event with reason "timeout".
"""
dispatcher = EventDispatcher()
await dispatcher.start()
reader = MessageReader(dispatcher)
commands = MessagingCommands()
commands.dispatcher = dispatcher
frame = bytes([
PacketType.CHANNEL_DATA_RECV.value,
0x10, # SNR
0x00, 0x00, # reserved
0x01, # channel_idx
0xFF, # path_len direct
0x23, 0x01, # data_type = 0x0123 (little-endian)
0x04, # data_len
0xDE, 0xAD, 0xBE, 0xEF, # payload
])
async def device(data):
# The device answers GET_MESSAGE with the queued channel datagram.
assert data == b"\x0a"
await reader.handle_rx(bytearray(frame))
commands._sender_func = device
try:
result = await commands.get_msg(timeout=2.0)
finally:
await dispatcher.stop()
assert result.type == EventType.CHANNEL_DATA_RECV
assert result.payload["channel_idx"] == 1
assert result.payload["data_type"] == 0x0123
assert result.payload["payload"] == "deadbeef"
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Command wrapper: send_channel_data (CMD_SEND_CHANNEL_DATA, 0x3E) # Command wrapper: send_channel_data (CMD_SEND_CHANNEL_DATA, 0x3E)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------