btstack/tool/create_packet_log.py
2024-08-23 09:31:17 +02:00

165 lines
4.0 KiB
Python
Executable File

#!/usr/bin/env python3
# BlueKitchen GmbH (c) 2014
# convert log output to PacketLogger format
# can be viewed with Wireshark
# APPLE PacketLogger
# typedef struct {
# uint32_t len;
# uint32_t ts_sec;
# uint32_t ts_usec;
# uint8_t type; // 0xfc for note
# }
import re
import sys
import time
import os
default_date="2001-01-01"
default_hours = 12
packet_counter = 0
last_time = default_date + " " + str(default_hours) + ":00:00.000"
def chop(line, prefix):
if line.startswith(prefix):
return line[len(prefix):]
return None
def str2hex(value):
if value:
return int(value, 16)
return None
def arrayForNet32(value):
return bytearray([value >> 24, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff])
def generateTimestamp(t):
global last_time
global packet_counter
# use last_time if time missing for this entry
if not t:
t = last_time
if t:
last_time = t
# check for date
parts = t.split(' ')
have_date = True
if len(parts) == 1:
# only time, prepend fixed date
have_date = False
t = "2000-01-01 " + t;
# handle ms
try:
(t1, t2) = t.split('.')
if t1 and t2:
t_obj = time.strptime(t1, "%Y-%m-%d %H:%M:%S")
tv_sec = int(time.mktime(t_obj))
if not have_date:
# start at 12:00
tv_sec += 12*60*60
tv_usec = int(t2) * 1000
return (tv_sec, tv_usec)
except ValueError:
# print 'Cannot parse time', t
pass
packet_counter += 1
return (packet_counter, 0)
def dumpPacket(fout, timestamp, type, data):
length = 9 + len(data)
(tv_sec, tv_usec) = generateTimestamp(timestamp)
fout.write(arrayForNet32(length))
fout.write(arrayForNet32(tv_sec))
fout.write(arrayForNet32(tv_usec))
fout.write(bytearray([type]))
fout.write(data)
def handleHexPacket(fout, timestamp, type, text):
try:
data = bytearray(list(map(str2hex, text.strip().split())))
dumpPacket(fout, timestamp, type, data)
except TypeError:
print('Cannot parse hexdump', text.strip())
if len(sys.argv) == 1:
print('BTstack Console to PacketLogger converter')
print('Copyright 2014, BlueKitchen GmbH')
print('')
print('Usage: ', sys.argv[0], 'ascii-log-file.txt [hci_dump.pklg]')
print('Converted hci_dump.pklg can be viewed with Wireshark and OS X PacketLogger')
exit(0)
infile = sys.argv[1]
outfile = os.path.splitext(infile)[0] + ".pklg"
if len(sys.argv) > 2:
outfile = sys.argv[2]
# with open(outfile, 'w') as fout:
with open (outfile, 'wb') as fout:
with open (infile, 'rt') as fin:
packet_counter = 0
line_conter = 0
for line in fin:
try:
# try to deal with windows 16-bit unicode by dropping \0 characters
line = ''.join([c for c in line if c != '\0'])
# drop Segger RTT console prefix
if line.startswith('00> '):
line = line[4:]
line_conter += 1
timestamp = None
# strip newlines
line = line.strip("\n\r")
# skip empty lines
if len(line) == 0:
continue
parts = re.match('\[(.*)\] (.*)', line)
if parts and len(parts.groups()) == 2:
(timestamp, line) = parts.groups()
rest = chop(line,'CMD => ')
if rest:
handleHexPacket(fout, timestamp, 0, rest)
continue
rest = chop(line,'EVT <= ')
if rest:
handleHexPacket(fout, timestamp, 1, rest)
continue
rest = chop(line,'ACL => ')
if rest:
handleHexPacket(fout, timestamp, 2, rest)
continue
rest = chop(line,'ACL <= ')
if rest:
handleHexPacket(fout, timestamp, 3, rest)
continue
rest = chop(line,'SCO => ')
if rest:
handleHexPacket(fout, timestamp, 8, rest)
continue
rest = chop(line,'SCO <= ')
if rest:
handleHexPacket(fout, timestamp, 9, rest)
continue
rest = chop(line,'ISO => ')
if rest:
handleHexPacket(fout, timestamp, 0x0c, rest)
continue
rest = chop(line,'ISO <= ')
if rest:
handleHexPacket(fout, timestamp, 0x0d, rest)
continue
rest = chop(line,'LOG -- ')
if rest:
line = rest
dumpPacket(fout, timestamp, 0xfc, line.encode('ascii'))
except:
print("Error in line %u: '%s'" % (line_conter, line))
print("\nPacket Log: %s" % outfile)