15c544019SMatthias Ringwald#!/usr/bin/env python3 21ca3442bSMatthias Ringwald# BlueKitchen GmbH (c) 2014 31ca3442bSMatthias Ringwald 41ca3442bSMatthias Ringwald# primitive dump for PacketLogger format 51ca3442bSMatthias Ringwald 61ca3442bSMatthias Ringwald# APPLE PacketLogger 71ca3442bSMatthias Ringwald# typedef struct { 81ca3442bSMatthias Ringwald# uint32_t len; 91ca3442bSMatthias Ringwald# uint32_t ts_sec; 101ca3442bSMatthias Ringwald# uint32_t ts_usec; 111ca3442bSMatthias Ringwald# uint8_t type; // 0xfc for note 121ca3442bSMatthias Ringwald# } 131ca3442bSMatthias Ringwald 141ca3442bSMatthias Ringwaldimport sys 151ca3442bSMatthias Ringwaldimport datetime 16cac83658SMatthias Ringwaldimport struct 171ca3442bSMatthias Ringwald 18*a63b240eSMilanka Ringwaldpacket_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <=", "0x04", "0x05", "0x06", "0x07", "SCO =>", "SCO <=", "0x0A", "0x0B", "ISO =>", "ISO <="] 191ca3442bSMatthias Ringwald 20cac83658SMatthias Ringwalddef read_header(f): 21cac83658SMatthias Ringwald bytes_read = f.read(13) 22cac83658SMatthias Ringwald if bytes_read: 23cac83658SMatthias Ringwald return struct.unpack(">IIIB", bytes_read) 24cac83658SMatthias Ringwald else: 25cac83658SMatthias Ringwald return (-1, 0, 0, 0) 261ca3442bSMatthias Ringwald 271ca3442bSMatthias Ringwalddef as_hex(data): 281ca3442bSMatthias Ringwald str_list = [] 291ca3442bSMatthias Ringwald for byte in data: 305c544019SMatthias Ringwald str_list.append("{0:02x} ".format(byte)) 311ca3442bSMatthias Ringwald return ''.join(str_list) 321ca3442bSMatthias Ringwald 331ca3442bSMatthias Ringwaldif len(sys.argv) == 1: 345c544019SMatthias Ringwald print ('Dump PacketLogger file') 355c544019SMatthias Ringwald print ('Copyright 2014, BlueKitchen GmbH') 365c544019SMatthias Ringwald print ('') 375c544019SMatthias Ringwald print ('Usage: ', sys.argv[0], 'hci_dump.pklg') 381ca3442bSMatthias Ringwald exit(0) 391ca3442bSMatthias Ringwald 401ca3442bSMatthias Ringwaldinfile = sys.argv[1] 411ca3442bSMatthias Ringwald 421ca3442bSMatthias Ringwaldwith open (infile, 'rb') as fin: 4346b37c0bSMatthias Ringwald pos = 0 441ca3442bSMatthias Ringwald try: 451ca3442bSMatthias Ringwald while True: 46cac83658SMatthias Ringwald (len, ts_sec, ts_usec, type) = read_header(fin) 47a0ecb5f3SMatthias Ringwald if len < 0: 48a0ecb5f3SMatthias Ringwald break 491ca3442bSMatthias Ringwald packet_len = len - 9; 5046b37c0bSMatthias Ringwald if (packet_len > 66000): 5146b37c0bSMatthias Ringwald print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 5246b37c0bSMatthias Ringwald break 531ca3442bSMatthias Ringwald packet = fin.read(packet_len) 5446b37c0bSMatthias Ringwald pos = pos + 4 + len 551ca3442bSMatthias Ringwald time = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000) 561ca3442bSMatthias Ringwald if type == 0xfc: 575c544019SMatthias Ringwald print (time, "LOG", packet.decode('ascii')) 581ca3442bSMatthias Ringwald continue 59*a63b240eSMilanka Ringwald if type <= 0x0D: 605c544019SMatthias Ringwald print (time, packet_types[type], as_hex(packet)) 611ca3442bSMatthias Ringwald except TypeError: 6246b37c0bSMatthias Ringwald print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 63