[systemd-devel] powering on bluetooth after suspend - required services aren't ready

Marcel Holtmann marcel at holtmann.org
Sat Sep 26 10:49:48 PDT 2015


Hi Lukas,

> When a system wakes from suspend, the Bluetooth adapter needs to be
> explicitly powered on. This can be conveniently done by a systemd
> service file, as described for example on Archlinux wiki [1] (the
> systemd service file at the bottom of the section).
> 
> The hciconfig binary used to work up to kernel 4.1.5, with 4.1.6 and up
> it stops working with Bluetooth LE (4.0) devices. The tool is
> deprecated, instead a dbus call (ie. the commented line in the systemd
> service file in [1]) or another tool, btmgmt, can be used to power on
> the Bluetooth adapter.
> 
> The problem is neither of these tools work at the time systemd invokes
> them, they require the bluetooth daemon to reinitialize itself after
> resume (at least for the dbus call it needs to listen on dbus, not sure
> about the btmgmt tool). Normally systemd handles this gracefully, but
> after resume, the required services appear ready to systemd while they
> aren't.
> 
> What is the proper solution to this problem?

anybody hacking in a tool that manually powers on the previously powered Bluetooth controller is doing something wrong. The question that should have been asked is why the controller got powered down in the first place.

An obvious issue could be that for some reason the device manufacturer decided to pull the power on the Bluetooth controller (aka USB disconnect) instead of handling proper suspend/resume. The btusb driver for example does support suspend/resume correctly, but it can not do anything about stupid devices. If they physically disappear from the bus, then they are for all intense and purposes unplugged.

Now for the lifetime of bluetoothd, it could remember the state of such a controller and restore it when it comes back. However that does not really help us sine we actually want to stop bluetoothd when no Bluetooth hardware is attached to the system. So that means that bluetoothd would have to store the value persistently over restarts. Which now is a problem since we need to account for the overall offline mode policy. That offline mode policy is not well defined (unless you run something like ConnMan) and so the only safe bet is to initialize the controller, but not power it on.

Just for reference, hciconfig has been deprecated since a long time now. It is a nice tool for quick and dirty testing, but using in production systems to power on a controller will not make your life happy. Especially if you want to use Bluetooth 4.0 Low Energy (LE) feature. The btmgmt is for developers and testers of the kernel API and is not even installed by BlueZ upstream package.

The correct way is indeed to use bluetoothctl or send a D-Bus message. Something that can be done easily by the Bluetooth UI that also provides the Bluetooth agent. The UI will most likely have a good idea about the offline policy and can nicely enforce it.

Regards

Marcel



More information about the systemd-devel mailing list