BlueZ 5.39 BLE setup on the Raspberry Pi

One of the things that I have done to really accelerate development of Mr. Gibbs is to do much of my work on an old laptop running ubuntu linux. Since ubuntu and raspbian are both debian based, most things work exactly the same. Of course most is not all as I found out the hard way when moving the code to the Pi Zero.

My Ubuntu machine ran BlueZ 5.35 and Mr. Gibbs works find there. Meanwhile, Raspbian Jessie runs a much older 5.23. The biggest issue I found with 5.23 is that the d-bus interfaces for BLE don't seem to exist. This poses a problem for me since I need BLE for my wind vane.

My first attempt at a solution was to follow this answer and install BlueZ 5.36 on raspbian using apt. Sure enough, once 5.36 was installed the BLE devices began to work, BUT my Pebbles would no longer pair with the Pi. checking dmesg, I found the error message Bluetooth: SMP security requested but not available. At first I thought this was a kernel bug after reading a few forum posts, but it turned out that updating to BlueZ 5.39 I could resolve both my BLE issues and my pairing issue.

I try to maintain the readme for the project as much as I can, so if something there conflicts with my blog, go by that. Compiling bluez is somewhat straightforward.


sudo apt-get update
sudo apt-get install git build-essential autoconf cmake libtool libglib2.0 libdbus-1-dev libudev-dev libical-dev libreadline-dev
wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.39.tar.xz
tar xvf bluez-5.39.tar.xz 
cd bluez-5.39/
./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --enable-experimental --with-systemdsystemunitdir=/lib/systemd/system --with-systemduserunitdir=/usr/lib/systemd
make
sudo make install

Note that if you already installed bluetooth on raspbian you will end up with 2 copies of bluetoothd, one in /usr/sbin, and one in /usr/libexec/bluetooth. The latter is the one you want running. To ensure this, as well as to enable experimental mode you will need to update systemd in /etc/systemd/system/bluetooth.target.wants/bluetooth.service

Change

ExecStart=/usr/libexec/bluetooth/bluetoothd

or

ExecStart=/usr/sbin/bluetoothd

to

ExecStart=/usr/libexec/bluetooth/bluetoothd --experimental

The experimental flag is mandatory for bluez to expose BLE via dbus.

You will also need to either run as root, or add the pi user to the dbus security for bluetooth in /etc/dbus-1/system.d/bluetooth.conf by duplicating the root section and changing the user to pi.

Once this is done, it is best to simply reboot. I experimented for a while with starting/stopping services, sudo systemctl daemon-reload, taking the interfaces down/up, but really just save some time and reboot.

The easiest way to tell if BLE is functioning is to use run bluetoothctl. Once running, start a scan using scan on, then connect to a device using connect XX:XX:XX:XX:XX:XX substituting in your devices address. If BLE is functioning you should see it find and list all BLE services and characteristics of your BLE device, as well as the dbus path to each interface. If you're using Mono.BlueZ, the blend micro bootstrap class can show you how to connect to your device programmatically. If you're working in another language the examples included with BlueZ are probably best for you.