Skip to content

Commit

Permalink
avoid _unknown_addr_discovery rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
DamKast committed Mar 13, 2024
1 parent 8e0d338 commit 7408276
Showing 1 changed file with 70 additions and 20 deletions.
90 changes: 70 additions & 20 deletions zigpy_zboss/zigbee/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,26 +504,6 @@ def add_device(self, ieee: t.EUI64, nwk: t.NWK):
self.devices[ieee] = dev
return dev

async def _discover_unknown_device(self, nwk: t.NWK) -> None:
"""Discover the IEEE address of a device with an unknown NWK."""
res = await self._api.request(
c.ZDO.IeeeAddrReq.Req(
TSN=self.get_sequence(),
DstNWK=t.BroadcastAddress.RX_ON_WHEN_IDLE,
NWKtoMatch=nwk,
RequestType=zdo_t.AddrRequestType.Single,
StartIndex=0,
)
)

nwk = res.RemoteDevNWK
ieee = res.RemoteDevIEEE

LOGGER.debug("Discovered IEEE address for NWK=%s: %s", nwk, ieee)
self.handle_join(
nwk=nwk, ieee=ieee, parent_nwk=None, handle_rejoin=False
)

#####################################################
# Callbacks attached during startup #
#####################################################
Expand Down Expand Up @@ -645,6 +625,10 @@ async def send_packet(self, packet: t.ZigbeePacket) -> None:
raise DeliveryError(
"Coordinator is disconnected, cannot send request")

if zigpy.zdo.ZDO_ENDPOINT in (packet.src_ep, packet.dst_ep):
await self._handle_zdo_packet(packet)
return

LOGGER.debug("Sending packet %r", packet)

options = c.aps.TransmitOptions.NONE
Expand Down Expand Up @@ -697,3 +681,69 @@ async def send_packet(self, packet: t.ZigbeePacket) -> None:
Payload=t_zboss.Payload(packet.data.serialize()),
)
)

async def _handle_zdo_packet(self, packet: t.ZigbeePacket) -> None:
"""ZDO packets that can't be send using the ZBOSS APSDE request."""
# The current zigpy device may not exist if we receive a packet early
try:
zdo = self._device.zdo
except KeyError:
zdo = zigpy.zdo.ZDO(None)

try:
zdo_hdr, zdo_args = zdo.deserialize(
cluster_id=packet.cluster_id, data=packet.data.serialize()
)
except ValueError:
LOGGER.debug("Could not parse ZDO message from packet")
return

if zdo_hdr.command_id == zdo_t.ZDOCmd.IEEE_addr_req:
await self._ieee_addr_req(packet, zdo_hdr, zdo_args)

async def _ieee_addr_req(
self,
packet: t.ZigbeePacket,
zdo_hdr: zdo_t.ZDOHeader,
zdo_args: tuple[Any]) -> None:
"""Send ZDO IEEE addr request and handle the response."""
tsn = zdo_hdr.tsn
nwki, req_type, index = zdo_args
res = await self._api.request(
c.ZDO.IeeeAddrReq.Req(
TSN=tsn,
DstNWK=packet.dst.address,
NWKtoMatch=nwki,
RequestType=req_type,
StartIndex=index,
)
)

status = zdo_t.Status(res.StatusCode)
ieee = res.RemoteDevIEEE
nwki = res.RemoteDevNWK
data = tsn.serialize() \
+ status.serialize() \
+ ieee.serialize() \
+ nwki.serialize()

packet = t.ZigbeePacket(
src=t.AddrModeAddress(
addr_mode=t.AddrMode.NWK,
address=res.RemoteDevNWK,
),
src_ep=0,
dst=t.AddrModeAddress(
addr_mode=t.AddrMode.NWK,
address=self.state.node_info.nwk,
),
dst_ep=0,
tsn=tsn,
profile_id=0,
cluster_id=zdo_t.ZDOCmd.IEEE_addr_rsp,
data=t.SerializableBytes(data),
tx_options=t.TransmitOptions.NONE,
lqi=None,
rssi=None
)
self.packet_received(packet)

0 comments on commit 7408276

Please sign in to comment.