Skip to content

Commit 7408276

Browse files
committed
avoid _unknown_addr_discovery rewrite
1 parent 8e0d338 commit 7408276

File tree

1 file changed

+70
-20
lines changed

1 file changed

+70
-20
lines changed

zigpy_zboss/zigbee/application.py

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -504,26 +504,6 @@ def add_device(self, ieee: t.EUI64, nwk: t.NWK):
504504
self.devices[ieee] = dev
505505
return dev
506506

507-
async def _discover_unknown_device(self, nwk: t.NWK) -> None:
508-
"""Discover the IEEE address of a device with an unknown NWK."""
509-
res = await self._api.request(
510-
c.ZDO.IeeeAddrReq.Req(
511-
TSN=self.get_sequence(),
512-
DstNWK=t.BroadcastAddress.RX_ON_WHEN_IDLE,
513-
NWKtoMatch=nwk,
514-
RequestType=zdo_t.AddrRequestType.Single,
515-
StartIndex=0,
516-
)
517-
)
518-
519-
nwk = res.RemoteDevNWK
520-
ieee = res.RemoteDevIEEE
521-
522-
LOGGER.debug("Discovered IEEE address for NWK=%s: %s", nwk, ieee)
523-
self.handle_join(
524-
nwk=nwk, ieee=ieee, parent_nwk=None, handle_rejoin=False
525-
)
526-
527507
#####################################################
528508
# Callbacks attached during startup #
529509
#####################################################
@@ -645,6 +625,10 @@ async def send_packet(self, packet: t.ZigbeePacket) -> None:
645625
raise DeliveryError(
646626
"Coordinator is disconnected, cannot send request")
647627

628+
if zigpy.zdo.ZDO_ENDPOINT in (packet.src_ep, packet.dst_ep):
629+
await self._handle_zdo_packet(packet)
630+
return
631+
648632
LOGGER.debug("Sending packet %r", packet)
649633

650634
options = c.aps.TransmitOptions.NONE
@@ -697,3 +681,69 @@ async def send_packet(self, packet: t.ZigbeePacket) -> None:
697681
Payload=t_zboss.Payload(packet.data.serialize()),
698682
)
699683
)
684+
685+
async def _handle_zdo_packet(self, packet: t.ZigbeePacket) -> None:
686+
"""ZDO packets that can't be send using the ZBOSS APSDE request."""
687+
# The current zigpy device may not exist if we receive a packet early
688+
try:
689+
zdo = self._device.zdo
690+
except KeyError:
691+
zdo = zigpy.zdo.ZDO(None)
692+
693+
try:
694+
zdo_hdr, zdo_args = zdo.deserialize(
695+
cluster_id=packet.cluster_id, data=packet.data.serialize()
696+
)
697+
except ValueError:
698+
LOGGER.debug("Could not parse ZDO message from packet")
699+
return
700+
701+
if zdo_hdr.command_id == zdo_t.ZDOCmd.IEEE_addr_req:
702+
await self._ieee_addr_req(packet, zdo_hdr, zdo_args)
703+
704+
async def _ieee_addr_req(
705+
self,
706+
packet: t.ZigbeePacket,
707+
zdo_hdr: zdo_t.ZDOHeader,
708+
zdo_args: tuple[Any]) -> None:
709+
"""Send ZDO IEEE addr request and handle the response."""
710+
tsn = zdo_hdr.tsn
711+
nwki, req_type, index = zdo_args
712+
res = await self._api.request(
713+
c.ZDO.IeeeAddrReq.Req(
714+
TSN=tsn,
715+
DstNWK=packet.dst.address,
716+
NWKtoMatch=nwki,
717+
RequestType=req_type,
718+
StartIndex=index,
719+
)
720+
)
721+
722+
status = zdo_t.Status(res.StatusCode)
723+
ieee = res.RemoteDevIEEE
724+
nwki = res.RemoteDevNWK
725+
data = tsn.serialize() \
726+
+ status.serialize() \
727+
+ ieee.serialize() \
728+
+ nwki.serialize()
729+
730+
packet = t.ZigbeePacket(
731+
src=t.AddrModeAddress(
732+
addr_mode=t.AddrMode.NWK,
733+
address=res.RemoteDevNWK,
734+
),
735+
src_ep=0,
736+
dst=t.AddrModeAddress(
737+
addr_mode=t.AddrMode.NWK,
738+
address=self.state.node_info.nwk,
739+
),
740+
dst_ep=0,
741+
tsn=tsn,
742+
profile_id=0,
743+
cluster_id=zdo_t.ZDOCmd.IEEE_addr_rsp,
744+
data=t.SerializableBytes(data),
745+
tx_options=t.TransmitOptions.NONE,
746+
lqi=None,
747+
rssi=None
748+
)
749+
self.packet_received(packet)

0 commit comments

Comments
 (0)