Skip to content

Commit

Permalink
Fix joining error with firmware versions >= 20210708
Browse files Browse the repository at this point in the history
  • Loading branch information
puddly committed Aug 2, 2021
1 parent c9cb576 commit ddf79f6
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 38 deletions.
49 changes: 22 additions & 27 deletions tests/application/test_joining.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,25 @@
import zigpy_znp.types as t
import zigpy_znp.commands as c

from ..conftest import FORMED_DEVICES, FORMED_ZSTACK3_DEVICES, CoroutineMock
from ..conftest import (
FORMED_DEVICES,
FORMED_ZSTACK3_DEVICES,
CoroutineMock,
FormedLaunchpadCC26X2R1,
)

pytestmark = [pytest.mark.asyncio]


@pytest.mark.parametrize("device", FORMED_DEVICES)
async def test_permit_join(device, make_application):
app, znp_server = make_application(server_cls=device)

# Handle the startup permit join clear
znp_server.reply_once_to(
request=c.ZDO.MgmtPermitJoinReq.Req(
AddrMode=t.AddrMode.NWK, Dst=0x0000, Duration=0, partial=True
),
responses=[
c.ZDO.MgmtPermitJoinReq.Rsp(Status=t.Status.SUCCESS),
c.ZDO.MgmtPermitJoinRsp.Callback(Src=0x0000, Status=t.ZDOStatus.SUCCESS),
],
override=True,
)
@pytest.mark.parametrize(
"device,fixed_joining_bug",
[(d, False) for d in FORMED_DEVICES] + [(FormedLaunchpadCC26X2R1, True)],
)
async def test_permit_join(device, fixed_joining_bug, mocker, make_application):
if fixed_joining_bug:
mocker.patch.object(device, "code_revision", 20210708)

znp_server.reply_once_to(
request=c.ZDO.MgmtPermitJoinReq.Req(
AddrMode=t.AddrMode.Broadcast, Dst=0xFFFC, Duration=0, partial=True
),
responses=[
c.ZDO.MgmtPermitJoinReq.Rsp(Status=t.Status.SUCCESS),
c.ZDO.MgmtPermitJoinRsp.Callback(Src=0x0000, Status=t.ZDOStatus.SUCCESS),
],
)
app, znp_server = make_application(server_cls=device)

# Handle us opening joins on the coordinator
permit_join_coordinator = znp_server.reply_once_to(
Expand All @@ -65,8 +54,14 @@ async def test_permit_join(device, make_application):
await app.startup(auto_form=False)
await app.permit(time_s=10)

await permit_join_coordinator
await permit_join_broadcast
if fixed_joining_bug:
await permit_join_broadcast

# Joins should not have been opened on the coordinator
assert not permit_join_coordinator.done()
else:
await permit_join_coordinator
await permit_join_broadcast

await app.shutdown()

Expand Down
9 changes: 6 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ def zdo_route_check(self, request):
class BaseZStack1CC2531(BaseZStackDevice):
align_structs = False
version = 1.2
code_revision = 20190608

@reply_to(c.SYS.OSALNVRead.Req(partial=True))
@reply_to(c.SYS.OSALNVReadExt.Req(partial=True))
Expand Down Expand Up @@ -766,7 +767,7 @@ def version_replier(self, request):
MajorRel=2,
MinorRel=6,
MaintRel=3,
CodeRevision=20190608,
CodeRevision=self.code_revision,
BootloaderBuildType=c.sys.BootloaderBuildType.BUILT_AS_BIN,
BootloaderRevision=0,
)
Expand Down Expand Up @@ -963,6 +964,7 @@ def connection_made(self):
class BaseLaunchpadCC26X2R1(BaseZStack3Device):
version = 3.30
align_structs = True
code_revision = 20200805

def create_nib(self, _=None):
super().create_nib()
Expand Down Expand Up @@ -1034,7 +1036,7 @@ def version_replier(self, request):
MajorRel=2,
MinorRel=7,
MaintRel=1,
CodeRevision=20200805,
CodeRevision=self.code_revision,
BootloaderBuildType=c.sys.BootloaderBuildType.NON_BOOTLOADER_BUILD,
BootloaderRevision=0xFFFFFFFF,
)
Expand Down Expand Up @@ -1070,6 +1072,7 @@ def led_responder(self, req):
class BaseZStack3CC2531(BaseZStack3Device):
version = 3.0
align_structs = False
code_revision = 20190425

def create_nib(self, _=None):
super().create_nib()
Expand Down Expand Up @@ -1100,7 +1103,7 @@ def version_replier(self, request):
MajorRel=2,
MinorRel=7,
MaintRel=2,
CodeRevision=20190425,
CodeRevision=self.code_revision,
BootloaderBuildType=c.sys.BootloaderBuildType.BUILT_AS_BIN,
BootloaderRevision=0,
)
Expand Down
16 changes: 8 additions & 8 deletions zigpy_znp/zigbee/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,12 +699,12 @@ async def permit(self, time_s=60, node=None):

LOGGER.info("Permitting joins for %d seconds", time_s)

# If joins were permitted through a specific router, older Z-Stack builds
# did not allow the key to be distributed unless the coordinator itself was
# also permitting joins.
#
# Fixed in https://github.com/Koenkk/Z-Stack-firmware/commit/efac5ee46b9b437
if time_s == 0 or self._version_rsp.CodeRevision < 20210708:
# If joins were permitted through a specific router, older Z-Stack builds
# did not allow the key to be distributed unless the coordinator itself was
# also permitting joins.
#
# Fixed in https://github.com/Koenkk/Z-Stack-firmware/commit/efac5ee46b9b437
response = await self._znp.request_callback_rsp(
request=c.ZDO.MgmtPermitJoinReq.Req(
AddrMode=t.AddrMode.NWK,
Expand All @@ -716,10 +716,10 @@ async def permit(self, time_s=60, node=None):
callback=c.ZDO.MgmtPermitJoinRsp.Callback(Src=0x0000, partial=True),
)

if response.Status != t.Status.SUCCESS:
raise RuntimeError(f"Failed to permit joins on the coordinator: {response}")
if response.Status != t.Status.SUCCESS:
raise RuntimeError(f"Failed to permit joins on coordinator: {response}")

return await super().permit(time_s=time_s, node=node)
await super().permit(time_s=time_s, node=node)

async def permit_ncp(self, time_s: int) -> None:
"""
Expand Down

0 comments on commit ddf79f6

Please sign in to comment.