-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhopping_pattern_demo
executable file
·125 lines (109 loc) · 3.56 KB
/
hopping_pattern_demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env python
# Copyright 2016 Dominic Spill
try:
import seaborn as sns
sns.set_style("dark")
except:
pass
from BT_hopping_pattern import BR_EDR, LE
import matplotlib
#matplotlib.use('qt5agg')
import matplotlib.pyplot as plt
import matplotlib.animation as animation
HOP_HISTORY = 50
channels = []
colours = [
'#0000cc',
#'#ff3300',
'#0000ff',
'#0066ff',
'#3399ff',
'#66ccff'
]
def animated_barplot(count, fig, pattern, bars, waterfall):
if len(channels) == HOP_HISTORY:
previous_channel = channels.pop()
waterfall[previous_channel[0]].set_color('white')
waterfall[previous_channel[0]].set_height(0)
freq, direction = pattern.next()
channels.insert(0, (freq-2400, direction))
# Clear previous set
for bar in bars:
bar.set_color('white')
bar.set_height(0)
for idx, timeslot in enumerate(channels):
channel, direction = timeslot
if idx < len(colours):
bars[channel].set_color(colours[idx])
bars[channel].set_height(1)
waterfall[channel].set_height(-0.1)
waterfall[channel].set_y(-0.1 * idx)
# Blue for master to slave
# Red for slave to master
if direction:
waterfall[channel].set_color('blue')
else:
waterfall[channel].set_color('red')
fig.canvas.draw()
def draw_pattern(title, pattern):
fig = plt.figure()
fig.canvas.set_window_title(title)
bars = plt.bar(range(2000, 2083), [0]*83, width=1)
waterfall = plt.bar(range(2000, 2083), [0]*83, width=1)
plt.title(title)
plt.xticks([2000, 2040, 2083], ('2400', '2440', '2483'))
plt.xlabel('Frequency (MHz)')
plt.yticks([-5,0,1], ('', '', ''))
ani = animation.FuncAnimation(fig, animated_barplot, fargs=(fig, pattern, bars, waterfall))
plt.show()
def addr_to_mac(address):
return "%02X:%02X:%02X:%02X:%02X:%02X" % \
((address >> 40) & 0xFF,
(address >> 32) & 0xFF,
(address >> 24) & 0xFF,
(address >> 16) & 0xFF,
(address >> 8) & 0xFF,
address & 0xFF)
def bluetooth_classic_pattern(address):
print "Performing hopping pattern pre-calculations"
pn = BR_EDR.Piconet(address)
print "Pre-calculations complete"
pattern = pn.gen_hops()
title = 'Bluetooth Hopping Pattern for ' + addr_to_mac(address)
draw_pattern(title, pattern)
def bluetooth_le_pattern(hop_increment, channel_map):
conn = LE.Connection(hop_increment, channel_map)
pattern = conn.gen_hops()
draw_pattern("Bluetooth LE Hopping Pattern", pattern)
def hex_int(x):
return int(x, 16)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Animate Bluetooth hopping patterns.')
parser.add_argument('-b', '--bredr', action='store_true', help="BR/EDR")
parser.add_argument('-a', '--address', nargs=1, help="BD address for BR/EDR")
parser.add_argument('-l', '--le', action='store_true', help="LE")
parser.add_argument('-i', '--hop-increment', nargs=1, type=int, help="Hop increment for LE")
parser.add_argument('-c', '--channel-map', nargs=1, type=hex_int, help="Channel map for LE")
args = parser.parse_args()
if args.bredr:
if args.address is None or len(args.address) == 0:
address = 0x6587cba9
print "Using default address of " + addr_to_mac(address)
else:
address = int(args.address[0].replace(':',''), 16)
bluetooth_classic_pattern(address)
elif args.le:
hop_increment = args.hop_increment
if hop_increment is None:
print "Using default hop increment of 7"
hop_increment = 7
print args.channel_map
if args.channel_map is None:
print "Using default channel map of 0x1fffffffff"
channel_map = 0x1fffffffff
else:
channel_map = args.channel_map[0]
bluetooth_le_pattern(hop_increment, channel_map)
else:
print "Specify either --bredr or --le"