Linux

Disabling the built in bluetooth and use a USB adaptor instead (on Linux)

My laptop has an Intel wireless card for wifi, and an Intel Bluetooth adaptor too. Hardware wise I suspect there is just one hardware device, and this causes problems on Linux. Although I can scan for devices and pair with some of them, connections rarely work, and my Bluetooth headset does not connect and work most of the time. Apparently this is a known problem with the Intel driver.

I suspected the issue was entirely related to this combination device, so I bought a plug-in USB Bluetooth adaptor. This is where the next problem began. Although the underlying Bluetooth stack on Linux supports multiple controllers, none of the graphical configuration tools do. GNOME’s Bluetooth support, blueman, blueberry… they all are written to only work with one controller. Whatever I did, they only saw the Intel controller.

You can select the default Bluetooth controller via the bluetoothctl command line tool, but this still doesn’t affect the graphical tools. If you disable the Intel Bluetooth controller via the same tool – or via the graphical tools – then all of them insist Bluetooth is turned off whilst gleefully ignoring the second Bluetooth controller.

You also can’t just blacklist a kernel module, such as btintel because this seemingly disables the btusb module too, and the USB adaptor doesn’t work either. Trying to use rfkill won’t likely get you anywhere either.

There is however a solution! We can use good ‘ol udev rules to remove authorisation from a particular device. First of all we need to work out how to specify what USB device we want to disable. We need to find the vendor ID and the product ID. One method for this is lsusb -v. There is a lot of output from this, but you’ll want to find the built in device (in my case, Bus 001 Device 003: ID 8087:0a2b Intel Corp.). Underneath this it will have some information:

Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          224 Wireless
  bDeviceSubClass         1 Radio Frequency
  bDeviceProtocol         1 Bluetooth
  bMaxPacketSize0        64
  idVendor           0x8087 Intel Corp.
  idProduct          0x0a2b 

The lines we’re interested in are idVendor and idProduct. In my case the values I took from this output were 8087 for the vendor (Intel) and 0a2b (the product ID). As an aside, I love how Intel’s vendor ID is a reference to the Intel 8087 co-processor! (Apparently the Intel PCI ID is 8086 too!).

Another approach to find the information is to use udevadm, like so:

udevadm info -a -p /sys/class/bluetooth/hci0

This also outputs a lot of information. You want to find lines like:

    ATTRS{idProduct}=="0a2b"
    ATTRS{idVendor}=="8087"

If there are multiple entries you want to choose the entries near the top as the udevadm command walks up the device tree showing information for all parent devices (which we don’t want).

Once you know the product ID and the vendor ID we can now create a rules file and disable the device. Create a new rules file at /etc/udev/rules.d/81-bluetooth-hci.rules and add the following:

SUBSYSTEM=="usb", ATTRS{idVendor}=="your-vendor-id-here", ATTRS{idProduct}=="your-product-id-here", ATTR{authorized}="0"

Here is mine for example:

SUBSYSTEM=="usb", ATTRS{idVendor}=="8087", ATTRS{idProduct}=="0a2b", ATTR{authorized}="0"

Now all you need to do is reboot! Once you do the built in Bluetooth controller should vanish and all of the graphical tools should work nicely with your Bluetooth USB adaptor instead. 😀

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s