Skip to content

Commit 9d9df3a

Browse files
committed
Clean up and better document ZDO exceptions
1 parent adc2b54 commit 9d9df3a

File tree

2 files changed

+37
-52
lines changed

2 files changed

+37
-52
lines changed

zigpy_znp/zigbee/application.py

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,48 +1233,48 @@ async def _send_request_raw(
12331233
Data=data,
12341234
)
12351235

1236-
# XXX: Joins *must* be sent via a ZDO command. Otherwise, Z-Stack will not
1237-
# actually permit the coordinator to send the network key.
1238-
if dst_ep == ZDO_ENDPOINT and cluster == zdo_t.ZDOCmd.Mgmt_Permit_Joining_req:
1239-
await self._znp.request_callback_rsp(
1240-
request=c.ZDO.MgmtPermitJoinReq.Req(
1241-
AddrMode=dst_addr.mode,
1242-
Dst=dst_addr.address,
1243-
Duration=data[1],
1244-
TCSignificance=data[2],
1245-
),
1246-
RspStatus=t.Status.SUCCESS,
1247-
callback=c.ZDO.MgmtPermitJoinRsp.Callback(Src=0x0000, partial=True),
1248-
)
1249-
# Internally forward ZDO requests destined for the coordinator back to zigpy so
1250-
# we can send Z-Stack internal requests when necessary
1251-
elif dst_ep == ZDO_ENDPOINT and (
1252-
# Broadcast that will reach the device
1253-
(
1236+
# Z-Stack requires special treatment when sending ZDO requests
1237+
if dst_ep == ZDO_ENDPOINT:
1238+
# XXX: Joins *must* be sent via a ZDO command, even if they are directly
1239+
# addressing another device. The router will receive the ZDO request and a
1240+
# device will try to join, but Z-Stack will never send the network key.
1241+
if cluster == zdo_t.ZDOCmd.Mgmt_Permit_Joining_req:
1242+
await self._znp.request_callback_rsp(
1243+
request=c.ZDO.MgmtPermitJoinReq.Req(
1244+
AddrMode=dst_addr.mode,
1245+
Dst=dst_addr.address,
1246+
Duration=data[1],
1247+
TCSignificance=data[2],
1248+
),
1249+
RspStatus=t.Status.SUCCESS,
1250+
callback=c.ZDO.MgmtPermitJoinRsp.Callback(Src=0x0000, partial=True),
1251+
)
1252+
# Internally forward ZDO requests destined for the coordinator back to zigpy
1253+
# so we can send internal Z-Stack requests when necessary
1254+
elif (
1255+
# Broadcast that will reach the device
12541256
dst_addr.mode == t.AddrMode.Broadcast
12551257
and dst_addr.address
12561258
in (
12571259
zigpy.types.BroadcastAddress.ALL_DEVICES,
12581260
zigpy.types.BroadcastAddress.RX_ON_WHEN_IDLE,
12591261
zigpy.types.BroadcastAddress.ALL_ROUTERS_AND_COORDINATOR,
12601262
)
1261-
)
1262-
# Or a direct unicast request
1263-
or (
1263+
) or (
1264+
# Or a direct unicast request
12641265
dst_addr.mode == t.AddrMode.NWK
12651266
and dst_addr.address == self.zigpy_device.nwk
1266-
)
1267-
):
1268-
self.handle_message(
1269-
sender=self.zigpy_device,
1270-
profile=ZDO_PROFILE,
1271-
cluster=cluster,
1272-
src_ep=ZDO_ENDPOINT,
1273-
dst_ep=ZDO_ENDPOINT,
1274-
message=data,
1275-
)
1267+
):
1268+
self.handle_message(
1269+
sender=self.zigpy_device,
1270+
profile=profile,
1271+
cluster=cluster,
1272+
src_ep=src_ep,
1273+
dst_ep=dst_ep,
1274+
message=data,
1275+
)
12761276

1277-
if dst_addr.mode == t.AddrMode.Broadcast or dst_ep == ZDO_ENDPOINT:
1277+
if dst_ep == ZDO_ENDPOINT or dst_addr.mode == t.AddrMode.Broadcast:
12781278
# Broadcasts and ZDO requests will not receive a confirmation
12791279
response = await self._znp.request(
12801280
request=request, RspStatus=t.Status.SUCCESS

zigpy_znp/zigbee/device.py

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
LOGGER = logging.getLogger(__name__)
1212

13+
NWK_UPDATE_LOOP_DELAY = 1
14+
1315

1416
class ZNPCoordinator(zigpy.device.Device):
1517
"""
@@ -44,24 +46,6 @@ class ZNPZDOEndpoint(zigpy.zdo.ZDO):
4446
def app(self):
4547
return self.device.application
4648

47-
def handle_mgmt_permit_joining_req(
48-
self,
49-
hdr: zdo_t.ZDOHeader,
50-
PermitDuration: t.uint8_t,
51-
TC_Significant: t.Bool,
52-
*,
53-
dst_addressing,
54-
):
55-
"""
56-
Handles ZDO `Mgmt_Permit_Joining_req` sent to the coordinator.
57-
"""
58-
59-
self.create_catching_task(
60-
self.async_handle_mgmt_permit_joining_req(
61-
hdr, PermitDuration, TC_Significant, dst_addressing=dst_addressing
62-
)
63-
)
64-
6549
async def async_handle_mgmt_permit_joining_req(
6650
self,
6751
hdr: zdo_t.ZDOHeader,
@@ -112,7 +96,7 @@ async def async_handle_mgmt_nwk_update_req(
11296
t.Channels.from_channel_list([old_network_info.channel])
11397
== NwkUpdate.ScanChannels
11498
):
115-
LOGGER.info("NWK update request is ignored when channel does not change")
99+
LOGGER.warning("NWK update request is ignored when channel does not change")
116100
return
117101

118102
await self.app._znp.request(
@@ -121,6 +105,7 @@ async def async_handle_mgmt_nwk_update_req(
121105
DstAddrMode=t.AddrMode.NWK,
122106
Channels=NwkUpdate.ScanChannels,
123107
ScanDuration=NwkUpdate.ScanDuration,
108+
# Missing fields in the request cannot be `None` in the Z-Stack command
124109
ScanCount=NwkUpdate.ScanCount or 0,
125110
NwkManagerAddr=NwkUpdate.nwkManagerAddr or 0x0000,
126111
),
@@ -133,7 +118,7 @@ async def async_handle_mgmt_nwk_update_req(
133118
== old_network_info.nwk_update_id
134119
):
135120
await self.app.load_network_info(load_devices=False)
136-
await asyncio.sleep(1)
121+
await asyncio.sleep(NWK_UPDATE_LOOP_DELAY)
137122

138123
# Z-Stack automatically increments the NWK update ID instead of setting it
139124
# TODO: Directly set it once radio settings API is finalized.

0 commit comments

Comments
 (0)