xref: /btstack/tool/dump_h4.py (revision 293fae36ed66799edbed8fe84ba7103961874078)
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