Debug Bluetooth on Linux


Recently, I installed Debian minimal on my old laptop. The earlier plan was to use this as a server, but I changed my mind and settled on using it as a development server, to avoid storing personal code on my work laptop. The intention was to use it as a headless machine and keep it connected to a monitor and keyboard-mouse pair to interact with it. I was able to connect my monitor to this laptop (after setting up xrandr) but the bluetooth on the machine failed to turn on. This post details various steps I took to root cause and fix the issue.

Install the basic packages

To make bluetooth work on Debian/Ubuntu systems, following packages should be installed -

sudo apt install bluetooth pulseaudio-module-bluetooth blueman bluez-firmware bluez-tools

Now enable the bluetooth service -

sudo systemctl enable bluetooth.service
sudo systemctl start bluetooth.service

You can also enable the kernel bluetooth module using this command -

modprobe btusb

Now, restart the system (it is optional, but recommended).

Reset bluetooth adapter

Use following command to reset bluetooth adapter -

sudo hciconfig hci0 reset

Scan for bluetooth devices using following command to test the fix -

bt-adapter -d

Check your Wireless Card

After following the previous steps, the bluetooth should be working. If it doesn’t, the next step is to find any issues with your wireless module. In my case, my laptop has RTL8723BE which in the past has troubled me with many connectivity issues. Recent Linux Kernels are supposed to have a driver for this particular card.

This card supports two antennas but many manufacturers only put one antenna to save costs. When Linux tries to use both the antennas the failure occurs. The fix is to tell Linux to only use one of the antennas. To do this, run the following commands -

# Tell kernel to use antenna 1
echo "options rtl8723be ant_sel=1" >> /etc/modprobe.d/rtl8723be.conf

# remove the existing driver
sudo modprobe -r rtl8723be

# mount the driver again
sudo modprobe rtl8723be

If this doesn’t improve the wifi signal, try changing ant_sel to 2 and try again.

Another thing that can be done is to disable power management features of this card. This will help if you face frequent disconnections. To disable power management on this card, this StackOverflow post can be followed.

This should increase the bluetooth and wifi range of your card which may help in better connections. If the bluetooth still doesn’t work, continue reading.

Bluetooth driver failures

Another thing to observe is the dmesg output for any bluetooth related errors. In my case, I saw following errors -

sudo dmesg -w | grep -i blue

[    8.415745] Bluetooth: hci0: rtl: examining hci_ver=06 hci_rev=000b lmp_ver=06 lmp_subver=8723
[    8.415750] Bluetooth: hci0: rtl: loading rtl_bt/rtl8723b_config.bin
[    8.422228] bluetooth hci0: Direct firmware load for rtl_bt/rtl8723b_config.bin failed with error -2
[    8.422238] Bluetooth: hci0: Failed to load rtl_bt/rtl8723b_config.bin
[    8.422319] Bluetooth: hci0: rtl: loading rtl_bt/rtl8723b_fw.bin
[    8.461783] Bluetooth: hci0: rom_version status=0 version=1

Searching of this error on the web led me to one Arch Linux forum post which suggested to manually download the config binary file and put it in the right place. I have used artefacts from the lwfinger before, so I decided to trust this. But it is not usually recommended to download random files from the Internet and execute them. After downloading the file, I executed following command -

sudo cp rtl8723b_config /usr/lib/firmware/rtl_bt/rtl8723b_config.bin

Reboot the system afterwards.

Rfkill

However, this also didn’t work. Rfkill is a Linux utility used to manage wireless devices. Sometimes, a bluetooth device can be soft-blocked by rfkill. In that case, you will have to enable it before the bluetooth can be used.

yash@homelab ~> rfkill list
0: phy0: Wireless LAN
	Soft blocked: no
	Hard blocked: no
1: hci0: Bluetooth
	Soft blocked: yes
	Hard blocked: no

If any of your devices are soft-blocked, run the following command to unblock it -

rfkill unblock bluetooth

After this step, again check if the bluetooth can be enabled. In my case, even after this step, the bluetooth didn’t work, so I debugged further.

Udev

After a long debugging session, I discovered the following udev rule in /etc/udev/rules.d/ -

## DISABLE BLUETOOTH
SUBSYSTEM=="rfkill", ATTR{type}=="bluetooth", ATTR{state}="0"

I may have added this rule when I was trying to configure my system as a headless home server. Having this rule on a fresh system is highly unlikely, so you may not have to worry about this.

I removed this rule and rebooted the system.

Conclusion

Finally, after almost two hours of debugging, the bluetooth on my laptop was finally working. It is a story for another day that I didn’t use the bluetooth for even for 10 minutes after this.

Do leave a comment if you find this post helpful.