def tx(self, dst, payload, frame_type=ZigbeeNetwork.FRAME_TYPE_DATA, security=True): self.dev.tx( dst, ZigbeeNetwork.ZigbeeNetwork( aes=self.aes, frame_type=frame_type, version=2, radius=1, seq=self.seq, dst=dst, # 0xfffd for broadcast, src=self.radio.address(), ext_src=self.radio.mac(), discover_route=0, security=security, sec_key=1, sec_key_seq=0, sec_seq=pack("<I", self.sec_seq), payload=payload, ).serialize()) self.seq = (self.seq + 1) & 0x3F if enc: self.sec_seq += 1
def rx(self, data): try: nwk = ZigbeeNetwork.ZigbeeNetwork(data=data, aes=self.aes) # filter any dupes from this source if nwk.src in self.seqs \ and self.seqs[nwk.src] == nwk.seq: return self.seqs[nwk.src] = nwk.seq # don't print broadcast messages if self.verbose \ and nwk.dst & 0xFFF0 != 0xFFF0: print(nwk) except: print("NWK error: " + hexlify(data)) raise return if nwk.frame_type == ZigbeeNetwork.FRAME_TYPE_CMD: # what to do with these? # route record, etc self.handle_command(nwk) elif nwk.frame_type == ZigbeeNetwork.FRAME_TYPE_DATA: # pass it up the stack print(nwk) return self.handler(self, nwk) else: print("NWK type %02x?" % (nwk.frame_type))
def leave(): global seq tx( IEEE802154.IEEE802154( frame_type=IEEE802154.FRAME_TYPE_DATA, seq=seq, dst=0x0000, dst_pan=pan, src=nwk_addr, payload=ZigbeeNetwork.ZigbeeNetwork( aes=Parser.aes, frame_type=ZigbeeNetwork.FRAME_TYPE_CMD, version=2, radius=1, seq=12, dst=0xfffd, src=nwk_addr, ext_src=mac_addr, discover_route=0, security=1, sec_seq=bytearray(b'\x00\x00\x00\x00'), sec_key=1, sec_key_seq=0, payload=bytearray(b'\x04\x00')), )) seq += 1
def rx(self, data): try: nwk = ZigbeeNetwork.ZigbeeNetwork(data=data, aes=self.aes) # filter any dupes from this source if nwk.src in self.seqs and self.seqs[nwk.src] == nwk.seq: return self.seqs[nwk.src] = nwk.seq print(nwk) except: print("NWK error: " + hexlify(data)) raise return if nwk.frame_type == ZigbeeNetwork.FRAME_TYPE_CMD: # what to do with these? # route record, etc self.handle_command(nwk) elif nwk.frame_type == ZigbeeNetwork.FRAME_TYPE_DATA: # pass it up the stack return self.handler(nwk.payload) else: print("NWK type %02x?" % (nwk.frame_type))
from ZbPy import ZigbeeCluster from ZbPy import ZCL import gc gc.collect() # This is the "well known" zigbee2mqtt key. # The Ikea gateway uses a different key that has to be learned # by joining the network (not yet implemented) nwk_key = unhexlify(b"01030507090b0d0f00020406080a0c0d") aes = AES.AES(nwk_key) # Pre-allocate message types for the parser # Only one message can be parsed at a time ieee = IEEE802154.IEEE802154() nwk = ZigbeeNetwork.ZigbeeNetwork(aes=aes) aps = ZigbeeApplication.ZigbeeApplication() zcl = ZigbeeCluster.ZigbeeCluster() cmd = ZCL.ZCL() # For filtering dupes seqs = {} def parse(data, verbose=False, filter_dupes=False): global seqs #print("------") #print(data) ieee.deserialize(data)