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