def parse(cursor): version, type_id = unpack_from("u3u3", packet, cursor) cursor += 6 if type_id == 4: literal = 0 for num in count(0): fivvle = unpack_from("u5", packet, cursor)[0] cursor += 5 literal <<= 4 literal += fivvle & 0b1111 if not ((fivvle & 16) >> 4): return cursor, version, literal else: length_type_id = unpack_from("u1", packet, cursor)[0] cursor += 1 if length_type_id: subpacket_count = unpack_from("u11", packet, cursor)[0] cursor += 11 subpackets = [] for _ in range(subpacket_count): cursor, subversion, literal = parse(cursor) version += subversion subpackets.append(literal) else: subpacket_bits = unpack_from("u15", packet, cursor)[0] cursor += 15 subpackets = [] until = cursor + subpacket_bits while cursor < until: cursor, subversion, literal = parse(cursor) version += subversion subpackets.append(literal) if type_id == 0: return cursor, version, sum(subpackets) elif type_id == 1: return cursor, version, prod(subpackets) elif type_id == 2: return cursor, version, min(subpackets) elif type_id == 3: return cursor, version, max(subpackets) elif type_id == 5: return cursor, version, int(subpackets[0] > subpackets[1]) elif type_id == 6: return cursor, version, int(subpackets[0] < subpackets[1]) elif type_id == 7: return cursor, version, int(subpackets[0] == subpackets[1]) else: raise ValueError(version)
def print_cmd_message(self): """ Prints the contents of the command message buffer """ for index in range(0, self.tx_index, 4): offset = index * 8 word = bitstruct.unpack_from('u32', self.tx_data, offset) print('Index: %2d Content: 0x%08x' % (index, word[0]))
def print_cmd_message(self): """ Prints the contents of the command message buffer """ for index in range(0, self.tx_index, 4): offset = index * 8 word = bitstruct.unpack_from('u32', self.tx_data, offset) print('Index: %2d Content: 0x%08x' %(index, word[0]))
def parse_operator(data, offset): length_type = bitstruct.unpack_from(">u1>", data, offset)[0] offset += 1 subpackets = [] if length_type == 0: length = bitstruct.unpack_from(">u15>", data, offset)[0] offset += 15 end_offset = offset + length while offset < end_offset: offset, packet = parse_packet(data, offset) subpackets.append(packet) elif length_type == 1: length = bitstruct.unpack_from(">u11>", data, offset)[0] offset += 11 for _ in range(length): offset, packet = parse_packet(data, offset) subpackets.append(packet) return offset, subpackets
def print_response(self, msg, verbose=False): """ Parses and prints the contents of the response message """ unpacked = bitstruct.unpack_from_dict(self.cmd_word_fmt, self.cmd_keys, msg) msg_id = unpacked['msg_id'] rsp = unpacked['cmd_rsp'] if msg_id == 0 and rsp == 0: print('RSP <<< NULL.') else: print('RSP <<< %s.' % self.cmd_rsp[rsp]) if verbose == True: count = bitstruct.unpack_from('u32', msg, 4 * 8)[0] count &= 0x1ff for index in range(0, 8 + (count * 4), 4): offset = index * 8 word = bitstruct.unpack_from('u32', msg, offset) print('Index: %2d Content: 0x%08x' % (index, word[0]))
def print_response(self, msg, verbose = False): """ Parses and prints the contents of the response message """ unpacked = bitstruct.unpack_from_dict(self.cmd_word_fmt, self.cmd_keys, msg) msg_id = unpacked['msg_id'] rsp = unpacked['cmd_rsp'] if msg_id == 0 and rsp == 0: print('RSP <<< NULL.') else: print('RSP <<< %s.' % self.cmd_rsp[rsp]) if verbose == True: count = bitstruct.unpack_from('u32', msg, 4 * 8)[0] count &= 0x1ff for index in range(0, 8 + (count * 4), 4): offset = index * 8 word = bitstruct.unpack_from('u32', msg, offset) print('Index: %2d Content: 0x%08x' %(index, word[0]))
def get_buffer_unsigned_integer_8bit_ended_by_length(data, position, length): assert length.bits == 0 return Field( bitstruct.unpack_from("u8" * length.bytes, data, position.get_bits()), position, length)
def get_unsigned_integer_8bit(data, position): return Field( bitstruct.unpack_from("u8", data, position.get_bits())[0], position, BytesAndBits(1, 0))
def get_unsigned_integer_64bit_big_endian(data, offset): return (bitstruct.unpack_from("u64", data, offset.get_bits())[0], BytesAndBits(8, 0))
def get_unsigned_integer_32bit_big_endian(data, offset): return Field( bitstruct.unpack_from("u32", data, offset.get_bits())[0], offset, BytesAndBits(4, 0))
def get_unsigned_integer_16bit_big_endian(data, position): return Field( bitstruct.unpack_from("u16", data, position.get_bits())[0], position, BytesAndBits(2, 0))
def get_string_utf16_big_endian(data, position, length): assert length.bits == 0 return Field( bitstruct.unpack_from(f"r{length.get_bits()}", data, position.get_bits())[0].decode("utf_16_be"), position, length)
def get_string_ascii_ended_by_length(data, position, length): assert length.bits == 0 return Field( bitstruct.unpack_from(f"r{length.get_bits()}", data, position.get_bits())[0].decode("ascii"), position, length)
def get_bool_8bit(data, position): return Field( bitstruct.unpack_from("u8", data, position.get_bits())[0] == 0x01, position, BytesAndBits(1, 0))
def test_bitstruct(): word = [0xde, 0xad, 0xbe, 0xef] assert bitstruct.unpack_from('u4', word, offset=28)[0] == 0xf assert bitstruct.unpack('p28u4', word)[0] == 0xf assert bitstruct.unpack('p0u4', word)[0] == 0xd