Last active
March 28, 2020 00:14
-
-
Save WayneKeenan/3ff68e7e72df18bdaeb82a91d2c68d67 to your computer and use it in GitHub Desktop.
Experimenting with Bluetooth LE HCI commands in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import fcntl | |
import struct | |
import array | |
# --------------------------------------------------- | |
# HCI Constants (https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/lib/hci.h) | |
# HCI ioctl Commands: | |
HCIDEVUP = 0x400448c9 # 201 | |
HCIDEVDOWN = 0x400448ca # 202 | |
HCIGETDEVINFO = 0x7ffbb72d #_IOR(ord('H'), 211, 4) | |
HCISETSCAN = 0x400448dd #221 | |
# hex values take from: import bluetooth._bluetooth as bluez, installed by: sudo apt-get install python-bluetooth | |
# HCI Parameters | |
SCAN_DISABLED = 0x00 | |
SCAN_INQUIRY = 0x01 | |
SCAN_PAGE = 0x02 | |
# C HCI examples: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/tools/hciconfig.c | |
# Python struct data format specifiers (see: https://docs.python.org/3.0/library/struct.html) | |
# H unsigned short integer | |
# I unsigned int integer | |
# --------------------------------------------------- | |
dev_id = 0 | |
sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) | |
sock.bind((dev_id,)) | |
# Get device info | |
#zero_filled = [0 for _ in range(256)] | |
#buffer = struct.pack('I%sb' % len(zero_filled), dev_id, *zero_filled) | |
buffer = struct.pack("HbBIBBIIIHHHH10I", dev_id, *((0,) * 22)) | |
fcntl.ioctl(sock.fileno(), HCIGETDEVINFO, buffer) | |
# simple hex dump: | |
print( [hex(ord(c)) for c in buffer]) | |
# HCI Up | |
buffer = struct.pack("I", dev_id) | |
fcntl.ioctl(sock.fileno(), HCIDEVUP, buffer) | |
# Set Scan | |
buffer = struct.pack("HI", dev_id, SCAN_INQUIRY) | |
fcntl.ioctl(sock.fileno(), HCISETSCAN, buffer) | |
# HCI Down | |
buffer = struct.pack("I", dev_id) | |
fcntl.ioctl(sock.fileno(), HCIDEVDOWN, buffer) | |
sock.close() | |
# --------------------------------------------------- | |
# --------------------------------------------------- | |
# Notes: | |
# HCI Data structures for IOCTL buffers (subset, see hci.h): | |
""" | |
struct hci_dev_req { | |
uint16_t dev_id; | |
uint32_t dev_opt; | |
}; | |
struct hci_dev_list_req { | |
uint16_t dev_num; | |
struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ | |
}; | |
struct hci_dev_info { | |
uint16_t dev_id; | |
char name[8]; | |
bdaddr_t bdaddr; | |
uint32_t flags; | |
uint8_t type; | |
uint8_t features[8]; | |
uint32_t pkt_type; | |
uint32_t link_policy; | |
uint32_t link_mode; | |
uint16_t acl_mtu; | |
uint16_t acl_pkts; | |
uint16_t sco_mtu; | |
uint16_t sco_pkts; | |
struct hci_dev_stats stat; | |
}; | |
""" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment