xref: /btstack/tool/create_packet_log.py (revision f55dd2ad866d23393eff338b2945be48ef99e62a)
11ca3442bSMatthias Ringwald#!/usr/bin/env python
21ca3442bSMatthias Ringwald# BlueKitchen GmbH (c) 2014
31ca3442bSMatthias Ringwald
41ca3442bSMatthias Ringwald# convert log output to PacketLogger format
51ca3442bSMatthias Ringwald# can be viewed with Wireshark
61ca3442bSMatthias Ringwald
71ca3442bSMatthias Ringwald# APPLE PacketLogger
81ca3442bSMatthias Ringwald# typedef struct {
91ca3442bSMatthias Ringwald# 	uint32_t	len;
101ca3442bSMatthias Ringwald# 	uint32_t	ts_sec;
111ca3442bSMatthias Ringwald# 	uint32_t	ts_usec;
121ca3442bSMatthias Ringwald# 	uint8_t		type;   // 0xfc for note
131ca3442bSMatthias Ringwald# }
141ca3442bSMatthias Ringwald
151ca3442bSMatthias Ringwaldimport re
161ca3442bSMatthias Ringwaldimport sys
171ca3442bSMatthias Ringwaldimport time
181ca3442bSMatthias Ringwald
191ca3442bSMatthias Ringwaldpacket_counter = 0
201ca3442bSMatthias Ringwaldlast_time = None
211ca3442bSMatthias Ringwald
221ca3442bSMatthias Ringwalddef chop(line, prefix):
231ca3442bSMatthias Ringwald	if line.startswith(prefix):
241ca3442bSMatthias Ringwald		return line[len(prefix):]
251ca3442bSMatthias Ringwald	return None
261ca3442bSMatthias Ringwald
271ca3442bSMatthias Ringwalddef str2hex(value):
281ca3442bSMatthias Ringwald	if value:
291ca3442bSMatthias Ringwald		return int(value, 16)
301ca3442bSMatthias Ringwald	return None
311ca3442bSMatthias Ringwald
321ca3442bSMatthias Ringwalddef arrayForNet32(value):
331ca3442bSMatthias Ringwald	return bytearray([value >> 24, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff])
341ca3442bSMatthias Ringwald
351ca3442bSMatthias Ringwalddef generateTimestamp(t):
361ca3442bSMatthias Ringwald	global last_time
371ca3442bSMatthias Ringwald	global packet_counter
381ca3442bSMatthias Ringwald
391ca3442bSMatthias Ringwald	# use last_time if time missing for this entry
401ca3442bSMatthias Ringwald	if not t:
411ca3442bSMatthias Ringwald		t = last_time
421ca3442bSMatthias Ringwald	if t:
431ca3442bSMatthias Ringwald		last_time = t
441ca3442bSMatthias Ringwald		# handle ms
451ca3442bSMatthias Ringwald		try:
461ca3442bSMatthias Ringwald			(t1, t2) = t.split('.')
471ca3442bSMatthias Ringwald			if t1 and t2:
481ca3442bSMatthias Ringwald				t_obj = time.strptime(t1, "%Y-%m-%d %H:%M:%S")
491ca3442bSMatthias Ringwald				tv_sec  = int(time.mktime(t_obj))
501ca3442bSMatthias Ringwald				tv_usec = int(t2) * 1000
511ca3442bSMatthias Ringwald				return (tv_sec, tv_usec)
521ca3442bSMatthias Ringwald		except ValueError:
531ca3442bSMatthias Ringwald			# print 'Cannot parse time', t
541ca3442bSMatthias Ringwald			pass
551ca3442bSMatthias Ringwald	packet_counter += 1
561ca3442bSMatthias Ringwald	return (packet_counter, 0)
571ca3442bSMatthias Ringwald
581ca3442bSMatthias Ringwalddef dumpPacket(fout, timestamp, type, data):
591ca3442bSMatthias Ringwald	length = 9 + len(data)
601ca3442bSMatthias Ringwald	(tv_sec, tv_usec) = generateTimestamp(timestamp)
611ca3442bSMatthias Ringwald	fout.write(arrayForNet32(length))
621ca3442bSMatthias Ringwald	fout.write(arrayForNet32(tv_sec))
631ca3442bSMatthias Ringwald	fout.write(arrayForNet32(tv_usec))
641ca3442bSMatthias Ringwald	fout.write(bytearray([type]))
651ca3442bSMatthias Ringwald	fout.write(data)
661ca3442bSMatthias Ringwald
671ca3442bSMatthias Ringwalddef handleHexPacket(fout, timestamp, type, text):
681ca3442bSMatthias Ringwald	try:
69*f55dd2adSMatthias Ringwald		data = bytearray(list(map(str2hex, text.strip().split())))
701ca3442bSMatthias Ringwald		dumpPacket(fout, timestamp, type, data)
711ca3442bSMatthias Ringwald	except TypeError:
72*f55dd2adSMatthias Ringwald		print('Cannot parse hexdump', text.strip())
731ca3442bSMatthias Ringwald
741ca3442bSMatthias Ringwaldif len(sys.argv) == 1:
75*f55dd2adSMatthias Ringwald	print('BTstack Console to PacketLogger converter')
76*f55dd2adSMatthias Ringwald	print('Copyright 2014, BlueKitchen GmbH')
77*f55dd2adSMatthias Ringwald	print('')
78*f55dd2adSMatthias Ringwald	print('Usage: ', sys.argv[0], 'asci-log-file.txt [hci_dump.pkgl]')
79*f55dd2adSMatthias Ringwald	print('Converted hci_dump.pklg can be viewed with Wireshark and OS X PacketLogger')
801ca3442bSMatthias Ringwald	exit(0)
811ca3442bSMatthias Ringwald
821ca3442bSMatthias Ringwaldinfile = sys.argv[1]
831ca3442bSMatthias Ringwaldoutfile = 'hci_dump.pklg'
841ca3442bSMatthias Ringwaldif len(sys.argv) > 2:
851ca3442bSMatthias Ringwald	outfile = sys.argv[2]
861ca3442bSMatthias Ringwald
871ca3442bSMatthias Ringwald# with open(outfile, 'w') as fout:
881ca3442bSMatthias Ringwaldwith open (outfile, 'wb') as fout:
89*f55dd2adSMatthias Ringwald	with open (infile, 'rt') as fin:
901ca3442bSMatthias Ringwald		packet_counter = 0
911ca3442bSMatthias Ringwald		for line in fin:
921ca3442bSMatthias Ringwald			timestamp = None
931ca3442bSMatthias Ringwald			parts = parts = re.match('\[(.*)\] (.*)', line)
941ca3442bSMatthias Ringwald			if parts and len(parts.groups()) == 2:
951ca3442bSMatthias Ringwald				(timestamp, line) = parts.groups()
961ca3442bSMatthias Ringwald			rest = chop(line,'CMD => ')
971ca3442bSMatthias Ringwald			if rest:
981ca3442bSMatthias Ringwald				handleHexPacket(fout, timestamp, 0, rest)
991ca3442bSMatthias Ringwald				continue
1001ca3442bSMatthias Ringwald			rest = chop(line,'EVT <= ')
1011ca3442bSMatthias Ringwald			if rest:
1021ca3442bSMatthias Ringwald				handleHexPacket(fout, timestamp, 1, rest)
1031ca3442bSMatthias Ringwald				continue
1041ca3442bSMatthias Ringwald			rest = chop(line,'ACL => ')
1051ca3442bSMatthias Ringwald			if rest:
1061ca3442bSMatthias Ringwald				handleHexPacket(fout, timestamp, 2, rest)
1071ca3442bSMatthias Ringwald				continue
1081ca3442bSMatthias Ringwald			rest = chop(line,'ACL <= ')
1091ca3442bSMatthias Ringwald			if rest:
1101ca3442bSMatthias Ringwald				handleHexPacket(fout, timestamp, 3, rest)
1111ca3442bSMatthias Ringwald				continue
1121ca3442bSMatthias Ringwald			rest = chop(line,'LOG -- ')
1131ca3442bSMatthias Ringwald			if rest:
1141ca3442bSMatthias Ringwald				line = rest
115*f55dd2adSMatthias Ringwald			dumpPacket(fout, timestamp, 0xfc, line.encode('ascii'))
116