Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Direct Control of HCI Device (Bypass Bluetooth Drivers) on Linux

I need to control an HCI device directly without the Linux drivers/kernel interfering. For example, when creating an LE connection to a peripheral, the driver is independently sending an "LE Connection Update" command which I would like to avoid.

I though of two approaches to resolve this:

  1. Configure the bluetooth drivers to somehow disable interference with the HCI device (similar to the -r flag on hciattach), then control the HCI device using a regular AF_BLUEOOTH socket.
  2. Disable this particular HCI device, but keep the parent char device and connect to it directly.

So far I did not succeed in finding a way of how to implement any of these approaches.

I should also mention that I still need a different HCI device to be "normally" used by the system so disabling the bluetooth drivers completely is not an option.

like image 320
Dan Shemesh Avatar asked Apr 30 '17 06:04

Dan Shemesh


1 Answers

I was able to achieve option #1.

Digging in the Linux kernel code for bluetooth drivers, I found an option for binding an HCI socket with hci_channel=1. 1 is the enum for HCI_USER_CHANNEL which causes the driver not to add its own commands to the HCI device.

To achieve this in C:

struct sockaddr_hci {
    sa_family_t     hci_family;
    unsigned short  hci_dev;
    unsigned short  hci_channel;
};

struct sockaddr_hci a;

memset(&a, 0, sizeof(a));
a.hci_family = AF_BLUETOOTH;
a.hci_dev = 0; //0 for hci0
a.hci_channel = 1; //1 for HCI_CHANNEL_USER

bind(sock, (struct sockaddr *) &a, sizeof(a));

To achieve this in Python:

Python's socket module does not support this option. A workaround for the missing support in Python was implemented in Scapy: https://github.com/secdev/scapy/blob/d2f2b0c7b46b607fcdf79860f8f866446bb625fb/scapy/layers/bluetooth.py#L808

Example for C++: https://github.com/sandeepmistry/node-bluetooth-hci-socket/blob/560a956c3e1421e31366115444ca9027d45b0e71/src/BluetoothHciSocket.cpp#L184

If you are interested in the relevant part of the Linux kernel: https://github.com/torvalds/linux/blob/86292b33d4b79ee03e2f43ea0381ef85f077c760/net/bluetooth/hci_sock.c#L1693

like image 65
Dan Shemesh Avatar answered Sep 28 '22 03:09

Dan Shemesh