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 16import struct 17 18packet_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <="] 19 20def read_header(f): 21 bytes_read = f.read(13) 22 if bytes_read: 23 return struct.unpack(">IIIB", bytes_read) 24 else: 25 return (-1, 0, 0, 0) 26 27def as_hex(data): 28 str_list = [] 29 for byte in data: 30 str_list.append("{0:02x} ".format(byte)) 31 return ''.join(str_list) 32 33if len(sys.argv) == 1: 34 print ('Dump PacketLogger file') 35 print ('Copyright 2014, BlueKitchen GmbH') 36 print ('') 37 print ('Usage: ', sys.argv[0], 'hci_dump.pklg') 38 exit(0) 39 40infile = sys.argv[1] 41 42with open (infile, 'rb') as fin: 43 pos = 0 44 try: 45 while True: 46 (len, ts_sec, ts_usec, type) = read_header(fin) 47 if len < 0: 48 break 49 packet_len = len - 9; 50 if (packet_len > 66000): 51 print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 52 break 53 packet = fin.read(packet_len) 54 pos = pos + 4 + len 55 time = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000) 56 if type == 0xfc: 57 print (time, "LOG", packet.decode('ascii')) 58 continue 59 if type <= 0x03: 60 print (time, packet_types[type], as_hex(packet)) 61 except TypeError: 62 print ("Error parsing pklg at offset %u (%x)." % (pos, pos)) 63