Skip to content

Instantly share code, notes, and snippets.

@WayneKeenan
Last active March 28, 2020 00:14
Show Gist options
  • Save WayneKeenan/3ff68e7e72df18bdaeb82a91d2c68d67 to your computer and use it in GitHub Desktop.
Save WayneKeenan/3ff68e7e72df18bdaeb82a91d2c68d67 to your computer and use it in GitHub Desktop.
Experimenting with Bluetooth LE HCI commands in Python
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