diff --git a/bellows/ezsp/__init__.py b/bellows/ezsp/__init__.py index 32761829..9c9e8064 100644 --- a/bellows/ezsp/__init__.py +++ b/bellows/ezsp/__init__.py @@ -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) @@ -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: @@ -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 diff --git a/tests/test_ezsp.py b/tests/test_ezsp.py index c2a59388..d9238ccb 100644 --- a/tests/test_ezsp.py +++ b/tests/test_ezsp.py @@ -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))