class BTLE(Packet): name = "BT4LE" fields_desc = [ XLEIntField("access_addr", 0x8E89BED6), LEX3BytesField("crc", None) ] @staticmethod def compute_crc(pdu, init=0x555555): def swapbits(a): v = 0 if a & 0x80 != 0: v |= 0x01 if a & 0x40 != 0: v |= 0x02 if a & 0x20 != 0: v |= 0x04 if a & 0x10 != 0: v |= 0x08 if a & 0x08 != 0: v |= 0x10 if a & 0x04 != 0: v |= 0x20 if a & 0x02 != 0: v |= 0x40 if a & 0x01 != 0: v |= 0x80 return v state = swapbits(init & 0xff) + (swapbits((init >> 8) & 0xff) << 8) + ( swapbits((init >> 16) & 0xff) << 16) # noqa: E501 lfsr_mask = 0x5a6000 for i in (orb(x) for x in pdu): for j in range(8): next_bit = (state ^ i) & 1 i >>= 1 state >>= 1 if next_bit: state |= 1 << 23 state ^= lfsr_mask return struct.pack("<L", state)[:-1] def post_build(self, p, pay): # Switch payload and CRC crc = p[-3:] p = p[:-3] + pay p += crc if self.crc is not None else self.compute_crc(p[4:]) return p def post_dissect(self, s): self.raw_packet_cache = None # Reset packet to allow post_build return s def pre_dissect(self, s): # move crc return s[:4] + s[-3:] + s[4:-3] def hashret(self): return struct.pack("!L", self.access_addr)
class Join_Accept(Packet): name = "Join_Accept" dcflist = False fields_desc = [LEX3BytesField("JoinAppNonce", 0), LEX3BytesField("NetID", 0), XLEIntField("DevAddr", 0), DLsettings, XByteField("RxDelay", 0), ConditionalField(StrFixedLenField("CFList", b"\x00" * 16, 16), # noqa: E501 lambda pkt:(Join_Accept.dcflist is True))] # pylint: disable=R0201 def extract_padding(self, p): return "", p def __init__(self, packet=""): # CFList calculated with rest of packet len if len(packet) > 18: Join_Accept.dcflist = True super(Join_Accept, self).__init__(packet)
class BTLE_CONNECT_REQ(Packet): name = "BTLE connect request" fields_desc = [ BDAddrField("InitA", None), BDAddrField("AdvA", None), # LLDATA XLEIntField("AA", 0x00), LEX3BytesField("crc_init", 0x0), XByteField("win_size", 0x0), XLEShortField("win_offset", 0x0), XLEShortField("interval", 0x0), XLEShortField("latency", 0x0), XLEShortField("timeout", 0x0), BTLEChanMapField("chM", 0), BitField("SCA", 0, 3), BitField("hop", 0, 5), ]
class PCOMBinaryResponse(PCOMBinary): name = "PCOM/Binary Response" fields_desc = [ StrFixedLenField("stx", "/_OPLC", 6), XByteField("reserved1", 0xfe), XByteField("id", 0x0), XByteField("reserved2", 0x1), LEX3BytesField("reserved3", 0x0), PCOMBinaryCommandField("command", None), XByteField("reserved4", 0x0), StrFixedLenField("commandSpecific", '', 6), LEFieldLenField("len", 0, length_of="data"), XLEShortField("headerChksum", None), StrLenField("data", '', length_from=lambda pkt: pkt.len), XLEShortField("footerChksum", None), XByteField("etx", 0x5c) ]
class DevAddrElem(Packet): name = "DevAddrElem" fields_desc = [ XByteField("NwkID", 0x0), LEX3BytesField("NwkAddr", b"\x00" * 3) ]