BlueZ 5

Life goes on, everythng changes. With new bluez tree fakehid was completely wiped out from bluetoothd userspace. Now, thanks to David Dillow ps3bt code lives in HID kernel code since commit 5844c1cdb630b537a2ecdf74dab2985e51dc1bd9. Let see how it works...

It took longer than I expected to fight my inertia and finally move to Bluez5. First impression - it works. And it works great.

Update: <rant active="on">Well... not entirely. It worked with devices added in bluez4. Then it doesn't honour power states (ignores rfkill expecting someone to pull it off or plug in) and it cannot stand suspend/resume... In general it became dumb translation layer, encapsulating higher level protocols into BT wire code. All the management is left to bigger smarter brother. Kernel part is handling hardware, userspace (bluetoothd) is now simply dbus service implementing API calls passing them to hardware.

Now, given that there's no worthy userspace management tool... you're left on your own to script and implement whatever you need. They say API doc is updated - so feel free. Somehow I'm not a bit surprised.<rant active="off">

Nevertheless no one is going to provide you anything better and if devs decided to give up user space/interface - it's their choice. At least they provided us DBus API and simple bluetoothctl tool.

First thing first - by default bluetooth interface is powered down - so if you want to do somehting with bluez you first need to power it up. With systemd it's a matter of setting simple boot-time service:

# cat > /etc/systemd/system/hciboot@.service
Description=Bluetooth power enable
Requires=sys-subsystem-bluetooth-devices-%i.device bluetooth.service

ExecStartPre=/usr/bin/dbus-send --system --type=method_call --dest=org.bluez\
    /org/bluez/%I org.freedesktop.DBus.Properties.Set \
    string:org.bluez.Adapter1 string:Powered variant:boolean:false
ExecStart=/usr/bin/dbus-send --system --type=method_call --dest=org.bluez \
    /org/bluez/%I org.freedesktop.DBus.Properties.Set \
    string:org.bluez.Adapter1 string:Powered variant:boolean:true
ExecStop=/usr/bin/dbus-send --system --type=method_call --dest=org.bluez \
    /org/bluez/%I org.freedesktop.DBus.Properties.Set \
    string:org.bluez.Adapter1 string:Powered variant:boolean:false


Here we use DBus API to control the device. First we ensure it is really powered down. You can do it theoretically with hciconfig command but then you may be left with out-of-sync state where daemon thinks hw is down but it is up or viceversa. So just play nice and follow the rules. And to enable it simply:

# systemctl enable hciboot@hci0
# systemctl start hciboot@hci0

At this point bluez should power the hci0 interface and bring it up. Next, we want to connect some bluetooth devices. If we're on headless or at least desktop(environment)less system we can only use bluetoothctl tool. So here's example:

# bluetoothctl 
[NEW] Controller 00:10:20:30:40:50 pi [default]
[bluetooth]# agent KeyboardOnly 
Agent registered
[bluetooth]# default-agent 
Default agent request successful
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:10:20:30:40:50 Discovering: yes
[NEW] Device 00:12:34:56:78:90 myLino
[CHG] Device 00:12:34:56:78:90 LegacyPairing: yes
[bluetooth]# pair 00:12:34:56:78:90
Attempting to pair with 00:12:34:56:78:90
[CHG] Device 00:12:34:56:78:90 Connected: yes
[CHG] Device 00:12:34:56:78:90 Connected: no
[CHG] Device 00:12:34:56:78:90 Connected: yes
Request PIN code
[agent] Enter PIN code: 1234
[CHG] Device 00:12:34:56:78:90 Paired: yes
Pairing successful
[CHG] Device 00:12:34:56:78:90 Connected: no

Here we were pairing pin-able device, for pin-less devices you can simply say agent on and it will deal with default request/response negotiation.

Sat Nov 10 23:17:31 2012 Upd.: Sat Oct 5 15:16:20 2013
© ruff 2011