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