Jérôme Belleman
Home  •  Tools  •  Posts  •  Talks  •  Travels  •  Graphics  •  About Me

Bluetooth and Linux

17 Aug 2018

Behind this mundane title, some notes as I was finding my bearings attempting to use Bluetooth devices when not using a conventional desktop environment.

People who use Gnome or KDE probably have an applet running that gets it all working nicely. But preferring to use Notion instead, I felt a bit lost as to how to set up Bluetooth devices, especially because there seems to be a thousand ways to achieve this, with about 990 of them not working when there's rain. So I've got a Bluetooth mouse which sometimes pairs, sometimes doesn't. I don't really know why. I wanted to understand.

1 Concepts Behind Connecting a Bluetooth Device

That really isn't rocket science, it's not. But if you don't know what connecting a Bluetooth device entails it's easy to get lost:

2 Pairing Graphically

Here's a review of the various ways I tried to use a Bluetooth device graphically and how they didn't suit me as a user who won't use more common desktop environments:

In short, GNOME Bluetooth doesn't work inside some uncommon window managers, BlueDevil is too hungry and Blueman will only really work if you know what you're doing. And if you know what you're doing, why then not just use bluetoothctl?

3 Pairing from a Shell

In Ubuntu, apt-get install bluez will be all you'll ever need. It provides bluetoothctl and bluetoothd. And for that reason, it's likely to have already been installed because bluetoothd is crucial to so many other applications it's hard to imagine it's not here by default. There's other BlueZ-related packages but you won't need them.

The main way to pair a device from a shell is by using bluetoothctl. However, there's a catch. It's not that bluetoothctl is a command-line tool which lets you manage your devices from any shell you like. No, bluetoothctl is the shell. And nothing but a shell. Incomprehensibly, there's no easy way to achieve from its command-line options – which are very few – what you can do from its shell. As a result, there's no way to automate away.

Nevertheless, bluetoothctl is simple and pleasantly predictable. Here's a session depicting the scanning, pairing, connecting and trusting steps:

[bluetooth]# scan on
Discovery started
[NEW] Device 12:FF:4F:61:98:EC Bluetooth Mouse
[bluetooth]# pair 12:FF:4F:61:98:EC 
Attempting to pair with 12:FF:4F:61:98:EC
Pairing successful
[bluetooth]# connect 12:FF:4F:61:98:EC 
Attempting to connect to 12:FF:4F:61:98:EC
Connection successful
[bluetooth]# trust 12:FF:4F:61:98:EC 
Changing 12:FF:4F:61:98:EC trust succeeded

The bluetoothctl shell supports completion, and that's very welcome as you can see that arguments referring to devices have to be MAC addresses.

For the record, should you have lost connection with the device, there is no need to exit bluetoothctl, let alone systemctl restart bluetooth, never mind restart the whole computer. Everything can be achieved inside this shell. It's also informative, as it will log on-screen events even if you manage devices from another tool. It's only fair to say that bluetoothctl is a very nice and effective way to work with Bluetooth devices. If only it could be used programmatically for ensuring that Bluetooth devices remain connected.

4 Connecting Programmatically?

I briefly schemed through Python modules for working with Bluetooth. PyBluez isn't no longer under active development. Nor is LightBlue. Other packages I saw seemed unrelated to what I needed to achieve. Gutted, I resorted to using Pexpect:

import pexpect

child = pexpect.spawn('bluetoothctl')
child.expect('[bluetooth]#')
child.sendline('pair 12:FF:4F:61:98:EC')
child.interact()

As I was writing those lines which didn't work – bluetoothctl is a little too sophisticated what with the printouts and prompts being asynchronous and all that, or maybe it's just the colours which never match [bluetoothctl]# – it occurred to me that there might have been a simpler explanation to me losing the connections.

5 Shake and Connect

It turns out my trusted mouse – trusted in the Bluetooth sense – sort of turned itself off, perhaps after having been disconnected, perhaps even after being left idle for too long. But all it took to wake it up and reconnect was to shake it and click about a bit. And now it reliability does my biddings. All that faffing about I went through just for that. Oh, well. I learned plenty in the process.

6 References