xref: /btstack/tool/create_packet_log.py (revision f55dd2ad866d23393eff338b2945be48ef99e62a)
1#!/usr/bin/env python
2# BlueKitchen GmbH (c) 2014
3
4# convert log output to PacketLogger format
5# can be viewed with Wireshark
6
7# APPLE PacketLogger
8# typedef struct {
9# 	uint32_t	len;
10# 	uint32_t	ts_sec;
11# 	uint32_t	ts_usec;
12# 	uint8_t		type;   // 0xfc for note
13# }
14
15import re
16import sys
17import time
18
19packet_counter = 0
20last_time = None
21
22def chop(line, prefix):
23	if line.startswith(prefix):
24		return line[len(prefix):]
25	return None
26
27def str2hex(value):
28	if value:
29		return int(value, 16)
30	return None
31
32def arrayForNet32(value):
33	return bytearray([value >> 24, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff])
34
35def generateTimestamp(t):
36	global last_time
37	global packet_counter
38
39	# use last_time if time missing for this entry
40	if not t:
41		t = last_time
42	if t:
43		last_time = t
44		# handle ms
45		try:
46			(t1, t2) = t.split('.')
47			if t1 and t2:
48				t_obj = time.strptime(t1, "%Y-%m-%d %H:%M:%S")
49				tv_sec  = int(time.mktime(t_obj))
50				tv_usec = int(t2) * 1000
51				return (tv_sec, tv_usec)
52		except ValueError:
53			# print 'Cannot parse time', t
54			pass
55	packet_counter += 1
56	return (packet_counter, 0)
57
58def dumpPacket(fout, timestamp, type, data):
59	length = 9 + len(data)
60	(tv_sec, tv_usec) = generateTimestamp(timestamp)
61	fout.write(arrayForNet32(length))
62	fout.write(arrayForNet32(tv_sec))
63	fout.write(arrayForNet32(tv_usec))
64	fout.write(bytearray([type]))
65	fout.write(data)
66
67def handleHexPacket(fout, timestamp, type, text):
68	try:
69		data = bytearray(list(map(str2hex, text.strip().split())))
70		dumpPacket(fout, timestamp, type, data)
71	except TypeError:
72		print('Cannot parse hexdump', text.strip())
73
74if len(sys.argv) == 1:
75	print('BTstack Console to PacketLogger converter')
76	print('Copyright 2014, BlueKitchen GmbH')
77	print('')
78	print('Usage: ', sys.argv[0], 'asci-log-file.txt [hci_dump.pkgl]')
79	print('Converted hci_dump.pklg can be viewed with Wireshark and OS X PacketLogger')
80	exit(0)
81
82infile = sys.argv[1]
83outfile = 'hci_dump.pklg'
84if len(sys.argv) > 2:
85	outfile = sys.argv[2]
86
87# with open(outfile, 'w') as fout:
88with open (outfile, 'wb') as fout:
89	with open (infile, 'rt') as fin:
90		packet_counter = 0
91		for line in fin:
92			timestamp = None
93			parts = parts = re.match('\[(.*)\] (.*)', line)
94			if parts and len(parts.groups()) == 2:
95				(timestamp, line) = parts.groups()
96			rest = chop(line,'CMD => ')
97			if rest:
98				handleHexPacket(fout, timestamp, 0, rest)
99				continue
100			rest = chop(line,'EVT <= ')
101			if rest:
102				handleHexPacket(fout, timestamp, 1, rest)
103				continue
104			rest = chop(line,'ACL => ')
105			if rest:
106				handleHexPacket(fout, timestamp, 2, rest)
107				continue
108			rest = chop(line,'ACL <= ')
109			if rest:
110				handleHexPacket(fout, timestamp, 3, rest)
111				continue
112			rest = chop(line,'LOG -- ')
113			if rest:
114				line = rest
115			dumpPacket(fout, timestamp, 0xfc, line.encode('ascii'))
116