xref: /btstack/tool/sm_random_check.py (revision 565fe80db1335fc811f93c03161901a9c5490478)
1#!/usr/bin/env python3
2# BlueKitchen GmbH (c) 2014
3
4# Report SM Pairing Random packets with value zero
5
6
7import re
8import sys
9import time
10import datetime
11
12packet_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <="]
13
14def read_net_32(f):
15    a = f.read(1)
16    if a == '':
17    	return -1
18    b = f.read(1)
19    if b == '':
20    	return -1
21    c = f.read(1)
22    if c == '':
23    	return -1
24    d = f.read(1)
25    if d == '':
26    	return -1
27    return ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d)
28
29def as_hex(data):
30	str_list = []
31	for byte in data:
32	    str_list.append("{0:02x} ".format(ord(byte)))
33	return ''.join(str_list)
34
35def check_file(infile):
36	with open (infile, 'rb') as fin:
37		pos = 0
38		warning = True
39		try:
40			while True:
41				len     = read_net_32(fin)
42				if len < 0:
43					break
44				ts_sec  = read_net_32(fin)
45				ts_usec = read_net_32(fin)
46				type    = ord(fin.read(1))
47				packet_len = len - 9;
48				if (packet_len > 66000):
49					print ("Error parsing pklg at offset %u (%x)." % (pos, pos))
50					break
51				packet  = fin.read(packet_len)
52				pos     = pos + 4 + len
53				time    = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000)
54				if type not in [0x02, 0x03]:
55					continue
56				packet_boundary_flags = (ord(packet[1]) >> 4) & 3
57				if packet_boundary_flags not in [0x00, 0x02]:
58					continue
59				channel = ord(packet[6]) | (ord(packet[7]) << 8)
60				if channel != 0x06:
61					continue
62				smp_command = ord(packet[8])
63				if smp_command != 4:
64					continue
65				random = [ ord(i) for i in packet[9:25] ]
66				num_zeros = random.count(0)
67				if num_zeros != 16:
68					continue
69				if warning:
70					print("%s contains SM Pairing Random command with Zeroes:" % infile)
71					warning = False
72				print (time, packet_types[type], as_hex(packet))
73
74			if not warning:
75				print("")
76
77		except TypeError:
78			print ("Error parsing pklg at offset %u (%x)." % (pos, pos))
79
80if len(sys.argv) == 1:
81	print ('Usage: ' + sys.argv[0] + ' hci_dump.pklg')
82	exit(0)
83
84for infile in sys.argv[2:]:
85	check_file(infile)
86
87infile = sys.argv[1]
88
89