@@ -504,26 +504,6 @@ def add_device(self, ieee: t.EUI64, nwk: t.NWK):
504
504
self .devices [ieee ] = dev
505
505
return dev
506
506
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
-
527
507
#####################################################
528
508
# Callbacks attached during startup #
529
509
#####################################################
@@ -645,6 +625,10 @@ async def send_packet(self, packet: t.ZigbeePacket) -> None:
645
625
raise DeliveryError (
646
626
"Coordinator is disconnected, cannot send request" )
647
627
628
+ if zigpy .zdo .ZDO_ENDPOINT in (packet .src_ep , packet .dst_ep ):
629
+ await self ._handle_zdo_packet (packet )
630
+ return
631
+
648
632
LOGGER .debug ("Sending packet %r" , packet )
649
633
650
634
options = c .aps .TransmitOptions .NONE
@@ -697,3 +681,69 @@ async def send_packet(self, packet: t.ZigbeePacket) -> None:
697
681
Payload = t_zboss .Payload (packet .data .serialize ()),
698
682
)
699
683
)
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