Skip to content

Commit a81bbd4

Browse files
authored
Fix XNCP parsing for hacked LIDL gateway (#657)
1 parent 5dd3447 commit a81bbd4

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

bellows/ezsp/xncp.py

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ def from_payload(cls, payload: XncpCommandPayload) -> XncpCommand:
6767
def from_bytes(cls, data: bytes) -> XncpCommand:
6868
command_id, data = XncpCommandId.deserialize(data)
6969
status, data = EmberStatus.deserialize(data)
70+
71+
if command_id not in COMMANDS:
72+
raise ValueError(
73+
f"Unknown XNCP command ID: 0x{command_id:04X} (payload {data!r})"
74+
)
75+
7076
payload, rest = COMMANDS[command_id].deserialize(data)
7177

7278
if rest:

tests/test_xncp.py

+14
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ async def test_xncp_failure_multiprotocol(ezsp_f: EZSP) -> None:
4848
]
4949

5050

51+
async def test_xncp_failure_lidl(ezsp_f: EZSP) -> None:
52+
"""Test XNCP failure with hacked LIDL gateway."""
53+
ezsp_f._mock_commands["customFrame"] = customFrame = AsyncMock(
54+
return_value=[t.EmberStatus.SUCCESS, b"\x00\x01\x03"]
55+
)
56+
57+
with pytest.raises(InvalidCommandError):
58+
await ezsp_f.xncp_get_supported_firmware_features()
59+
60+
assert customFrame.mock_calls == [
61+
call(xncp.XncpCommand.from_payload(xncp.GetSupportedFeaturesReq()).serialize())
62+
]
63+
64+
5165
async def test_xncp_failure_unknown(ezsp_f: EZSP) -> None:
5266
"""Test XNCP failure, unknown command."""
5367
ezsp_f._mock_commands["customFrame"] = customFrame = AsyncMock(

0 commit comments

Comments
 (0)