Compare commits
1 Commits
new-ios
...
blacklisting2
| Author | SHA1 | Date | |
|---|---|---|---|
| 295043bed9 |
+14
-2
@@ -1,10 +1,22 @@
|
||||
InternalBlue PoCs and Examples
|
||||
==============================
|
||||
|
||||
All examples were tested on a *Nexus 5* (*BCM4339* chip with firmware *BCM4335C0*) on *Android* and *LineageOS*.
|
||||
The following examples were tested on a *Nexus 5* (*BCM4339* chip with firmware *BCM4335C0*) on *Android* and *LineageOS*.
|
||||
|
||||
* [CVE_2018_5383_Invalid_Curve_Attack_PoC](CVE_2018_5383_Invalid_Curve_Attack_PoC.py)
|
||||
provides tries to set the y-coordinate during ECDH key exchange to zero. If the device under test accepts the pairing (50% probability), it is vulnerable.
|
||||
* [LMP_MAC_Address_Filter](LMP_MAC_Address_Filter.py)
|
||||
replies to all LMP packets with `LMP_not_accepted` if their source is not from a MAC address in the whitelist.
|
||||
* [NiNo_PoC](NiNo_PoC.py) sets the IO capabilities of the *Nexus 5* to no input, no output.
|
||||
* [NiNo_PoC](NiNo_PoC.py) sets the IO capabilities of the *Nexus 5* to no input, no output.
|
||||
|
||||
Examples for the Raspberry Pi 3:
|
||||
|
||||
* [raspi3_rxdn](raspi3_rxdn.py) prints the first bytes of the LE connection struct within the `_connTaskRxDone` callback.
|
||||
For debugging purposes, warnings are shown for packet failures. The full logging can be enabled via `log_level debug` on the
|
||||
*InternalBlue* command line. It contains the current channel, RSSI, and event number for each packet. To blacklist channels
|
||||
from hopping, use `sendhcicmd 0x2014 ff00000000` or similar. Use `wireshark` or `btmon`
|
||||
to see the channel blacklisting live within the connection struct.
|
||||
|
||||
|
||||
Examples for the Samsung Galaxy S8:
|
||||
* [s8_rxdn](s8_rxdn.py) same as for Raspberry Pi 3. Call *InternalBlue* with `internalblue -s` for serial setup.
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python2
|
||||
|
||||
from pwn import *
|
||||
from internalblue.adbcore import ADBCore
|
||||
from internalblue.bluezcore import BluezCore
|
||||
|
||||
"""
|
||||
Script that shows receive statistics from LE connections over HCI on the CYW20735B1 evaluation board.
|
||||
Generated with Nexmon.
|
||||
"""
|
||||
|
||||
internalblue = ADBCore()
|
||||
try:
|
||||
internalblue.interface = internalblue.device_list()[0][1] # just use the first Android device
|
||||
except IndexError:
|
||||
internalblue = BluezCore()
|
||||
try:
|
||||
internalblue.interface = internalblue.device_list()[0][1] # ...or the first local HCI interface
|
||||
except IndexError:
|
||||
log.critical("Adapt the Python script to use an available Broadcom Bluetooth interface.")
|
||||
exit(-1)
|
||||
|
||||
# setup sockets
|
||||
if not internalblue.connect():
|
||||
log.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
progress_log = log.info("Connected to first target, installing patches...")
|
||||
|
||||
# GENERATED PATCHES
|
||||
internalblue.patchRom(0x0008ea46, '\x89\xf1\x5b\xbc')
|
||||
internalblue.patchRom(0x0008edc2, '\x89\xf1\x1d\xbc')
|
||||
internalblue.patchRom(0x0008eec0, '\x89\xf1\x1e\xbb')
|
||||
internalblue.writeMem(0x00218200, '\x10\xb5\xcc\x22\xff\x21\xce\x20\x0c\xf6\x43\xfe\x04\x46\x04\x22\x07\x49\x0a\x30\x50\xf6\x53\xfb\x06\x4b\x04\xf1\x0e\x00\x19\x68\xc8\x22\x50\xf6\x4c\xfb\x20\x46\xbd\xe8\x10\x40\x0c\xf6\x03\xbd\x18\x80\x21\x00\x80\x28\x28\x00')
|
||||
internalblue.writeMem(0x00218300, '\x95\xf6\x70\xfc\xff\xf7\x7c\xff\x76\xf6\x9f\xbb\x00\xbf\x00\xbf')
|
||||
internalblue.writeMem(0x00218500, '\x2d\xe9\xf0\x5f\xfe\xb5\x07\x46\xf3\x22\xff\x21\xf5\x20\x0c\xf6\xc0\xfc\x04\x46\x04\xf1\x0a\x03\x04\x22\x0f\x49\x18\x46\x50\xf6\xce\xf9\x04\xf1\x0e\x03\x4f\xf0\xef\x02\x39\x46\x18\x46\x50\xf6\xc6\xf9\x04\xf1\x0e\x03\x4f\xf0\x01\x02\x07\xf5\xe9\x71\x18\x46\x50\xf6\xbd\xf9\x20\x46\x0c\xf6\x76\xfb\x38\x46\xbd\xe8\xfe\x40\x76\xf6\xb8\xbc\x00\xbf\x00\xbf\x00\x80\x21\x00')
|
||||
internalblue.writeMem(0x00218600, '\x70\xb5\x05\x46\xfe\xb5\x05\x46\xf4\x22\xff\x21\xf6\x20\x0c\xf6\x40\xfc\x04\x46\x04\xf1\x0a\x03\x04\x22\x0b\x49\x18\x46\x50\xf6\x4e\xf9\x04\xf1\x0e\x03\x4f\xf0\xf0\x02\x29\x46\x18\x46\x50\xf6\x46\xf9\x20\x46\x0c\xf6\xff\xfa\x00\xf0\xe2\xf8\xbd\xe8\xfe\x40\x76\xf6\xc1\xbb\x00\xbf\x00\xbf\x08\x80\x21\x00')
|
||||
internalblue.writeMem(0x00218800, '\x10\xb5\x08\x22\x82\xb0\xff\x21\x0a\x20\x0c\xf6\x42\xfb\x04\x22\x04\x46\x0b\x49\x0a\x30\x50\xf6\x52\xf8\x00\x20\x9f\xf6\xec\xff\x95\xf6\x3f\xff\x02\xa9\x41\xf8\x04\x0d\x04\x22\x04\xf1\x0e\x00\x50\xf6\x45\xf8\x20\x46\x0c\xf6\xfe\xf9\x02\xb0\x10\xbd\x00\xbf\x10\x80\x21\x00')
|
||||
internalblue.writeMem(0x00218000, '\x52\x58\x44\x4e\x00\x00\x00\x00\x4c\x45\x50\x52\x00\x00\x00\x00\x52\x53\x53\x49\x00\x00\x00\x00\x52\x42\x55\x46\x00')
|
||||
|
||||
|
||||
# shutdown connection
|
||||
internalblue.shutdown()
|
||||
|
||||
|
||||
log.info("--------------------")
|
||||
log.info("To see statistics, execute 'internalblue' and run 'log_level debug'.")
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# Jiska Classen
|
||||
|
||||
# Get receive statistics on a Raspberry Pi 3 for BLE connection events
|
||||
|
||||
from pwn import *
|
||||
from internalblue.hcicore import HCICore
|
||||
|
||||
|
||||
internalblue = HCICore()
|
||||
device_list = internalblue.device_list()
|
||||
if len(device_list) == 0:
|
||||
log.warn("No HCI devices connected!")
|
||||
exit(-1)
|
||||
internalblue.interface = device_list[0][1] # just use the first device
|
||||
|
||||
|
||||
RX_DONE_HOOK_ADDRESS = 0x35fbc # _connTaskRxDone
|
||||
HOOKS_LOCATION = 0x210500
|
||||
ASM_HOOKS = """
|
||||
|
||||
// restore first 4 bytes of _connTaskRxDone
|
||||
push {r4-r6,lr}
|
||||
mov r4, r0
|
||||
|
||||
// fix registers for our own routine
|
||||
push {r1-r7, lr}
|
||||
mov r7, r0
|
||||
|
||||
// allocate vendor specific hci event
|
||||
mov r2, 243
|
||||
mov r1, 0xff
|
||||
mov r0, 245
|
||||
bl 0x3670 // bthci_event_AllocateEventAndFillHeader(4+239+2, 0xff, 4+239);
|
||||
mov r4, r0 // save pointer to the buffer in r4
|
||||
|
||||
// append buffer with "RXDN"
|
||||
add r0, 10 // buffer starts at 10 with data
|
||||
ldr r1, =0x4e445852 // RXDN
|
||||
str r1, [r0]
|
||||
add r0, 4 // advance buffer by 4
|
||||
|
||||
// copy 239 bytes of le_conn to buffer
|
||||
mov r2, #238
|
||||
mov r1, r7 // le_conn[0]
|
||||
bl 0x45824 // __rt_memcpy
|
||||
|
||||
// for debugging purposes, we overwrite the first byte
|
||||
// (which is the connTaskCallback anyway) with RSSI info
|
||||
mov r2, #1 // 1 rssi byte
|
||||
add.w r1, r7, #0x10a // le_conn[0x10a] is position of rssi
|
||||
mov r0, r4
|
||||
add r0, 14
|
||||
bl 0x45824 // __rt_memcpy
|
||||
|
||||
// send hci event
|
||||
mov r0, r4 // back to buffer at offset 0
|
||||
bl 0x358e // send_hci_event
|
||||
|
||||
// undo registers for our own routine
|
||||
mov r0, r7
|
||||
pop {r1-r7, lr}
|
||||
|
||||
// branch back to _connTaskRxDone + 4
|
||||
b 0x35fc0
|
||||
|
||||
"""
|
||||
|
||||
# setup sockets
|
||||
if not internalblue.connect():
|
||||
log.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
# Install hooks
|
||||
code = asm(ASM_HOOKS, vma=HOOKS_LOCATION)
|
||||
log.info("Writing hooks to 0x%x..." % HOOKS_LOCATION)
|
||||
if not internalblue.writeMem(HOOKS_LOCATION, code):
|
||||
log.critical("Cannot write hooks at 0x%x" % HOOKS_LOCATION)
|
||||
exit(-1)
|
||||
|
||||
log.info("Installing hook patch...")
|
||||
patch = asm("b 0x%x" % HOOKS_LOCATION, vma=RX_DONE_HOOK_ADDRESS)
|
||||
if not internalblue.patchRom(RX_DONE_HOOK_ADDRESS, patch):
|
||||
log.critical("Installing patch for _connTaskRxDone failed!")
|
||||
exit(-1)
|
||||
|
||||
|
||||
log.info("--------------------")
|
||||
log.info("To see statistics, execute 'internalblue' and run 'log_level debug'.")
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# Jiska Classen
|
||||
|
||||
# Get receive statistics on a Raspberry Pi 3 for BLE connection events
|
||||
|
||||
from pwn import *
|
||||
from internalblue.hcicore import HCICore
|
||||
|
||||
|
||||
internalblue = HCICore()
|
||||
device_list = internalblue.device_list()
|
||||
if len(device_list) == 0:
|
||||
log.warn("No HCI devices connected!")
|
||||
exit(-1)
|
||||
internalblue.interface = device_list[0][1] # just use the first device
|
||||
|
||||
|
||||
RX_DONE_HOOK_ADDRESS = 0x56622 # _connTaskRxDone
|
||||
HOOKS_LOCATION = 0x210500
|
||||
ASM_HOOKS = """
|
||||
|
||||
// restore first 4 bytes of _connTaskRxDone
|
||||
push {r4-r6,lr}
|
||||
mov r4, r0
|
||||
|
||||
// fix registers for our own routine
|
||||
push {r1-r7, lr}
|
||||
mov r7, r0
|
||||
|
||||
// allocate vendor specific hci event
|
||||
mov r2, 243
|
||||
mov r1, 0xff
|
||||
mov r0, 245
|
||||
bl 0x2770 // bthci_event_AllocateEventAndFillHeader(4+239+2, 0xff, 4+239);
|
||||
mov r4, r0 // save pointer to the buffer in r4
|
||||
|
||||
// append buffer with "RXDN"
|
||||
add r0, 10 // buffer starts at 10 with data
|
||||
ldr r1, =0x4e445852 // RXDN
|
||||
str r1, [r0]
|
||||
add r0, 4 // advance buffer by 4
|
||||
|
||||
// copy 239 bytes of le_conn to buffer
|
||||
mov r2, #238
|
||||
mov r1, r7 // le_conn[0]
|
||||
bl 0x775C8 // __rt_memcpy
|
||||
|
||||
// for debugging purposes, we overwrite the first byte
|
||||
// (which is the connTaskCallback anyway) with RSSI info
|
||||
mov r2, #1 // 1 rssi byte
|
||||
add.w r1, r7, #0x10a // le_conn[0x10a] is position of rssi
|
||||
mov r0, r4
|
||||
add r0, 14
|
||||
bl 0x775C8 // __rt_memcpy
|
||||
|
||||
// send hci event
|
||||
mov r0, r4 // back to buffer at offset 0
|
||||
bl 0x268E // send_hci_event
|
||||
|
||||
// undo registers for our own routine
|
||||
mov r0, r7
|
||||
pop {r1-r7, lr}
|
||||
|
||||
// branch back to _connTaskRxDone + 4
|
||||
b 0x56626
|
||||
|
||||
"""
|
||||
|
||||
# setup sockets
|
||||
if not internalblue.connect():
|
||||
log.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
# Install hooks
|
||||
code = asm(ASM_HOOKS, vma=HOOKS_LOCATION)
|
||||
log.info("Writing hooks to 0x%x..." % HOOKS_LOCATION)
|
||||
if not internalblue.writeMem(HOOKS_LOCATION, code):
|
||||
log.critical("Cannot write hooks at 0x%x" % HOOKS_LOCATION)
|
||||
exit(-1)
|
||||
|
||||
log.info("Installing hook patch...")
|
||||
patch = asm("b 0x%x" % HOOKS_LOCATION, vma=RX_DONE_HOOK_ADDRESS)
|
||||
if not internalblue.patchRom(RX_DONE_HOOK_ADDRESS, patch):
|
||||
log.critical("Installing patch for _connTaskRxDone failed!")
|
||||
exit(-1)
|
||||
|
||||
|
||||
log.info("--------------------")
|
||||
log.info("To see statistics, execute 'internalblue' and run 'log_level debug'.")
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# Jiska Classen
|
||||
|
||||
# Get receive statistics on a Raspberry Pi 3 for BLE connection events
|
||||
|
||||
from pwn import *
|
||||
from internalblue.adbcore import ADBCore
|
||||
|
||||
|
||||
internalblue = ADBCore(serial=True)
|
||||
device_list = internalblue.device_list()
|
||||
if len(device_list) == 0:
|
||||
log.warn("No HCI devices connected!")
|
||||
exit(-1)
|
||||
internalblue.interface = device_list[0][1] # just use the first device
|
||||
|
||||
|
||||
RX_DONE_HOOK_ADDRESS = 0x1344D0 # _connTaskRxDone !!! has a Patchram position
|
||||
HOOKS_LOCATION = 0x210500
|
||||
ASM_HOOKS = """
|
||||
|
||||
// restore first 4 bytes of _connTaskRxDone
|
||||
push {r4-r12,lr}
|
||||
mov r4, r0
|
||||
|
||||
// fix registers for our own routine
|
||||
push {r1-r7, lr}
|
||||
mov r7, r0
|
||||
|
||||
// allocate vendor specific hci event
|
||||
mov r2, 243
|
||||
mov r1, 0xff
|
||||
mov r0, 245
|
||||
bl 0xE628 // bthci_event_AllocateEventAndFillHeader(4+239+2, 0xff, 4+239);
|
||||
mov r4, r0 // save pointer to the buffer in r4
|
||||
|
||||
// append buffer with "RXDN"
|
||||
add r0, 10 // buffer starts at 10 with data
|
||||
ldr r1, =0x4e445852 // RXDN
|
||||
str r1, [r0]
|
||||
add r0, 4 // advance buffer by 4
|
||||
|
||||
// copy 239 bytes of le_conn to buffer
|
||||
mov r2, #238
|
||||
mov r1, r7 // le_conn[0]
|
||||
bl 0x857B4 // __rt_memcpy
|
||||
|
||||
// for debugging purposes, we overwrite the first byte
|
||||
// (which is the connTaskCallback anyway) with RSSI info
|
||||
mov r2, #1 // 1 rssi byte
|
||||
add.w r1, r7, #0x1ca // le_conn[0x1ca] is position of rssi
|
||||
mov r0, r4
|
||||
add r0, 14
|
||||
bl 0x857B4 // __rt_memcpy
|
||||
|
||||
// send hci event
|
||||
mov r0, r4 // back to buffer at offset 0
|
||||
bl 0xE418 // bthci_event_AttemptToEnqueueEventToTransport
|
||||
|
||||
// undo registers for our own routine
|
||||
mov r0, r7
|
||||
pop {r1-r7, lr}
|
||||
|
||||
// branch back to _connTaskRxDone + 4
|
||||
b 0x1344D4
|
||||
|
||||
"""
|
||||
|
||||
# setup sockets
|
||||
if not internalblue.connect():
|
||||
log.critical("No connection to target device.")
|
||||
exit(-1)
|
||||
|
||||
# Install hooks
|
||||
code = asm(ASM_HOOKS, vma=HOOKS_LOCATION)
|
||||
log.info("Writing hooks to 0x%x..." % HOOKS_LOCATION)
|
||||
if not internalblue.writeMem(HOOKS_LOCATION, code):
|
||||
log.critical("Cannot write hooks at 0x%x" % HOOKS_LOCATION)
|
||||
exit(-1)
|
||||
|
||||
log.info("Installing hook patch...")
|
||||
patch = asm("b 0x%x" % HOOKS_LOCATION, vma=RX_DONE_HOOK_ADDRESS)
|
||||
if not internalblue.writeMem(RX_DONE_HOOK_ADDRESS, patch):
|
||||
log.critical("Installing patch for _connTaskRxDone failed!")
|
||||
exit(-1)
|
||||
|
||||
|
||||
log.info("--------------------")
|
||||
log.info("To see statistics, execute 'internalblue' and run 'log_level debug'.")
|
||||
@@ -46,6 +46,23 @@ class InternalBlue:
|
||||
self.interface = None # holds the context.device / hci interaface which is used to connect, is set in cli
|
||||
self.fw = None # holds the firmware file
|
||||
|
||||
# RXDN statistics callback variables
|
||||
self.last_nesn_sn = None
|
||||
self.last_success_event = None
|
||||
self.last_event_ctr = 0
|
||||
self.last_channel = 0
|
||||
self.last_channel_map = 0
|
||||
self.last_event_timestamp = 0
|
||||
|
||||
# variables for measuring PDR
|
||||
self.pdr_values = {}
|
||||
for i in range(0, 37):
|
||||
self.pdr_values[i] = collections.deque([1, 1, 1, 1, 1, 1, 1, 1, 1], maxlen=10)
|
||||
|
||||
self.PDR_THRESHOLD = 0.9
|
||||
self.CHAN_COUNT_THRESHOLD = 10
|
||||
|
||||
self.pdr_logfile = open("/tmp/pdr.log", "w")
|
||||
|
||||
self.data_directory = data_directory
|
||||
self.s_inject = None # This is the TCP socket to the HCI inject port
|
||||
@@ -119,6 +136,7 @@ class InternalBlue:
|
||||
# Register callbacks which handle specific HCI Events:
|
||||
self.registerHciCallback(self.connectionStatusCallback)
|
||||
self.registerHciCallback(self.coexStatusCallback)
|
||||
self.registerHciCallback(self.lereceiveStatusCallback)
|
||||
|
||||
def check_binutils(self, fix=True):
|
||||
"""
|
||||
@@ -1495,6 +1513,132 @@ class InternalBlue:
|
||||
log.info("[Coexistence Statistics: Grant=%d Reject=%d -> Reject Ratio %.4f]" % (coex_grant, coex_reject, ratio))
|
||||
return
|
||||
|
||||
def lereceiveStatusCallback(self, record):
|
||||
"""
|
||||
RXDN Callback Function
|
||||
|
||||
Depends on the raspi3_rxdn.py or eval_rxdn.py script,
|
||||
which patches the _connTaskRxDone() function and copies
|
||||
info from the LE connection struct to HCI.
|
||||
"""
|
||||
|
||||
hcipkt = record[0] # get HCI Event packet
|
||||
|
||||
if not issubclass(hcipkt.__class__, hci.HCI_Event):
|
||||
return
|
||||
|
||||
# Only do something when we have the correct firmware
|
||||
if not self.fw:
|
||||
return
|
||||
|
||||
raspi = False
|
||||
eval = False
|
||||
s8 = False
|
||||
if self.fw.FW_NAME == "BCM43430A1":
|
||||
raspi = True
|
||||
elif self.fw.FW_NAME == "CYW27035B1":
|
||||
eval = True
|
||||
elif self.fw.FW_NAME == "BCM4347B0":
|
||||
s8 = True
|
||||
else:
|
||||
return
|
||||
|
||||
if self.fw and hcipkt.data[0:4] == "RXDN":
|
||||
data = hcipkt.data[4:]
|
||||
# log.info("data: " + data.encode('hex'))
|
||||
|
||||
# Raspi 3 gets errors
|
||||
if len(data) < 239:
|
||||
return
|
||||
|
||||
if raspi or s8:
|
||||
packet_curr_nesn_sn = u8(data[0xa0])
|
||||
|
||||
elif eval:
|
||||
packet_curr_nesn_sn = u8(data[0xa4])
|
||||
|
||||
packet_channel_map = data[0x54:0x7b]
|
||||
packet_channel = u8(data[0x83])
|
||||
packet_event_ctr = u16(data[0x8e:0x90])
|
||||
packet_rssi = u8(data[0]) # currently not supported by s8!
|
||||
|
||||
# When looking at the NESN and the SN bit, we check for TX and RX errors
|
||||
# if self.last_nesn_sn and ((self.last_nesn_sn ^ packet_curr_nesn_sn) & 0b1100) !=0b1100:
|
||||
# log.info(" ^----------------------------- ERROR --------------------------------")
|
||||
|
||||
# When looking only at the NESN bit, we check for TX errors -> this is the thing we want in our EWSN paper
|
||||
if self.last_nesn_sn and ((self.last_nesn_sn ^ packet_curr_nesn_sn) & 0b0100) != 0b0100:
|
||||
pdr_current = 0
|
||||
else:
|
||||
pdr_current = 1
|
||||
|
||||
self.pdr_values[packet_channel].appendleft(pdr_current)
|
||||
pdr_avg = sum(self.pdr_values[packet_channel]) / float(len(self.pdr_values[packet_channel]))
|
||||
|
||||
# log.info("%s event: %5d, channel: %2d, channel_map: 0x%010x, PDR: %d, PDR_avg: %f" % (self.last_event_timestamp, self.last_event_ctr, self.last_channel, self.last_channel_map, pdr_current, pdr_avg))
|
||||
self.pdr_logfile.write("%s event: %5d, channel: %2d, channel_map: 0x%010x, PDR: 1\r\n" % (
|
||||
self.last_event_timestamp, self.last_event_ctr, self.last_channel, self.last_channel_map))
|
||||
self.pdr_logfile.flush()
|
||||
|
||||
if pdr_avg < self.PDR_THRESHOLD:
|
||||
active_channels = bin(self.last_channel_map).count('1')
|
||||
if active_channels <= self.CHAN_COUNT_THRESHOLD:
|
||||
# log.info('to few channels active -> whiteliste all')
|
||||
self.pdr_logfile.write('to few channels active -> whiteliste all')
|
||||
self.pdr_logfile.flush()
|
||||
self.sendHciCommand(0x2014, '\xff\xff\xff\xff\xf1', timeout=0)
|
||||
else:
|
||||
self.pdr_logfile.write(
|
||||
"going to BLACKLIST channel %2d, %2d channels active" % (self.last_channel, active_channels))
|
||||
new_channel_map = self.last_channel_map & (0x1fffffffff ^ (0b1 << self.last_channel))
|
||||
self.pdr_logfile.write(
|
||||
"current_channel_map: 0x%010x, new map: 0x%010x" % (self.last_channel_map, new_channel_map))
|
||||
self.pdr_logfile.flush()
|
||||
|
||||
new_channel_map_bytes = []
|
||||
for i in range(0, 5):
|
||||
new_channel_map_bytes.append(chr(new_channel_map >> (i * 8) & 0xff))
|
||||
|
||||
self.sendHciCommand(0x2014, ''.join(new_channel_map_bytes), timeout=0)
|
||||
|
||||
# currently only supported by eval board: check if we also went into the process payload routine,
|
||||
# which probably corresponds to a correct CRC
|
||||
# if self.last_success_event and (self.last_success_event + 1) != packet_event_ctr:
|
||||
# log.info(" ^----------------------------- MISSED -------------------------------")
|
||||
|
||||
# TODO example for setting the channel map
|
||||
# timeout needs to be zero, because we are already in an event reception routine!
|
||||
# self.sendHciCommand(0x2014, '\x00\x00\xff\x00\x00', timeout=0)
|
||||
|
||||
self.last_nesn_sn = packet_curr_nesn_sn
|
||||
|
||||
# draw channel with rssi color
|
||||
color = '\033[92m' # green
|
||||
if 0xc8 > packet_rssi >= 0xc0:
|
||||
color = '\033[93m' # yellow
|
||||
elif packet_rssi < 0xc0:
|
||||
color = '\033[91m' # red
|
||||
|
||||
channels_total = u8(packet_channel_map[37])
|
||||
channel_map = 0x0000000000
|
||||
if channels_total <= 37: # raspi 3 messes up with this during blacklisting
|
||||
for channel in range(0, channels_total):
|
||||
# channel_map |= (0b1 << 39) >> u8(packet_channel_map[channel]) # Use the flipped representation of the channel map to be consistent in my code
|
||||
channel_map |= (0b1 << u8(packet_channel_map[channel]))
|
||||
|
||||
# log.debug("LE event %5d, map %10x, RSSI %d: %s%s*\033[0m " % (packet_event_ctr, channel_map,
|
||||
# (packet_rssi & 0x7f) - (128*(packet_rssi >>7)), color, ' '*packet_channel))
|
||||
|
||||
# Store the following information for the next connection event, because we will know only by then, if the event was successful
|
||||
self.last_event_ctr = packet_event_ctr
|
||||
self.last_channel = packet_channel
|
||||
self.last_channel_map = channel_map
|
||||
self.last_event_timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||
|
||||
if self.fw and hcipkt.data[0:4] == "LEPR":
|
||||
data = hcipkt.data[4:]
|
||||
self.last_success_event = u16(data[0x8e:0x90])
|
||||
|
||||
def readHeapInformation(self):
|
||||
"""
|
||||
Traverses the double-linked list of BLOC structs and returns them as a
|
||||
|
||||
Reference in New Issue
Block a user