1#!/usr/bin/env python3 2# BlueKitchen GmbH (c) 2014 3 4# primitive dump for PacketLogger format 5 6# APPLE PacketLogger 7# typedef struct { 8# uint32_t len; 9# uint32_t ts_sec; 10# uint32_t ts_usec; 11# uint8_t type; // 0xfc for note 12# } 13 14import sys 15import datetime 16 17packet_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <="] 18 19def read_net_32(f): 20 a = f.read(1) 21 if a == '': 22 return -1 23 b = f.read(1) 24 if b == '': 25 return -1 26 c = f.read(1) 27 if c == '': 28 return -1 29 d = f.read(1) 30 if d == '': 31 return -1 32 return ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d) 33 34def as_hex(data): 35 str_list = [] 36 for byte in data: 37 str_list.append("{0:02x} ".format(byte)) 38 return ''.join(str_list) 39 40if len(sys.argv) == 1: 41 print ('Dump PacketLogger file') 42 print ('Copyright 2014, BlueKitchen GmbH') 43 print ('') 44 print ('Usage: ', sys.argv[0], 'hci_dump.pklg') 45 exit(0) 46 47infile = sys.argv[1] 48 49with open (infile, 'rb') as fin: 50 pos = 0 51 try: 52 while True: 53 len = read_net_32(fin) 54 if len < 0: 55 break 56 ts_sec = read_net_32(fin) 57 ts_usec = read_net_32(fin) 58 type = ord(fin.read(1)) 59 packet_len = len - 9; 60 if (packet_len > 66000): 61 print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 62 break 63 packet = fin.read(packet_len) 64 pos = pos + 4 + len 65 time = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000) 66 if type == 0xfc: 67 print (time, "LOG", packet.decode('ascii')) 68 continue 69 if type <= 0x03: 70 print (time, packet_types[type], as_hex(packet)) 71 except TypeError: 72 print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 73