Skip to content

Commit

Permalink
Ensure custom EUI64 token can be written with RCP firmware (#583)
Browse files Browse the repository at this point in the history
  • Loading branch information
puddly committed Sep 19, 2023
1 parent b50af94 commit 1674fd6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
10 changes: 7 additions & 3 deletions bellows/ezsp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ async def _get_mfg_custom_eui_64(self) -> t.EmberEUI64 | None:

# Manufacturing tokens do not exist in RCP firmware: all reads are empty
if not data:
raise EzspError("Firmware does not support MFG_CUSTOM_EUI_64 token")
raise ValueError("Firmware does not support MFG_CUSTOM_EUI_64 token")

mfg_custom_eui64, _ = t.EmberEUI64.deserialize(data)

Expand All @@ -410,7 +410,7 @@ async def can_burn_userdata_custom_eui64(self) -> bool:
"""Checks if the device EUI64 can be burned into USERDATA."""
try:
return await self._get_mfg_custom_eui_64() is None
except EzspError:
except ValueError:
return False

async def can_rewrite_custom_eui64(self) -> bool:
Expand Down Expand Up @@ -442,7 +442,11 @@ async def write_custom_eui64(

# A custom EUI64 can be stored in NV3 storage (rewritable)
nv3_eui64_key = await self._get_nv3_restored_eui64_key()
mfg_custom_eui64 = await self._get_mfg_custom_eui_64()

try:
mfg_custom_eui64 = await self._get_mfg_custom_eui_64()
except ValueError:
mfg_custom_eui64 = None

if nv3_eui64_key is not None:
# Prefer NV3 storage over MFG_CUSTOM_EUI_64, as it can be rewritten
Expand Down
26 changes: 26 additions & 0 deletions tests/test_ezsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,32 @@ async def test_write_custom_eui64(ezsp_f):
ezsp_f.setTokenData.assert_not_called()


async def test_write_custom_eui64_rcp(ezsp_f):
"""Test writing a custom EUI64 with RPC firmware."""

old_eui64 = t.EmberEUI64.convert("AA" * 8)
new_eui64 = t.EmberEUI64.convert("BB" * 8)

ezsp_f.getEui64 = AsyncMock(return_value=[old_eui64])
ezsp_f.setMfgToken = AsyncMock(return_value=[t.EmberStatus.INVALID_CALL])
ezsp_f.setTokenData = AsyncMock(return_value=[t.EmberStatus.SUCCESS])

# RCP firmware does not support manufacturing tokens
ezsp_f.getMfgToken = AsyncMock(return_value=[b""])
ezsp_f.getTokenData = AsyncMock(return_value=[t.EmberStatus.SUCCESS, b"\xFF" * 8])

await ezsp_f.write_custom_eui64(new_eui64)

ezsp_f.setMfgToken.assert_not_called()
ezsp_f.setTokenData.mock_calls == [
call(
t.NV3KeyId.NVM3KEY_STACK_RESTORED_EUI64,
0,
new_eui64.serialize(),
)
]


@patch.object(ezsp.EZSP, "version", new_callable=AsyncMock)
@patch.object(ezsp.EZSP, "reset", new_callable=AsyncMock)
@patch("bellows.uart.connect", return_value=MagicMock(spec_set=uart.Gateway))
Expand Down

0 comments on commit 1674fd6

Please sign in to comment.