January 28, 2019
This is a continuation of the previous note on Bluetooth on the
November 2018 version of Raspbian Stretch in which
the default version of BlueZ is replaced with
version 5.49 and later version 5.50. It will be shown that for streaming
audio, there is not much difference between these three versions of the Bluetooth
protocol stack for Linux.
Table of Contents
- Installing BlueZ 5.49 on Raspbian Stretch
- Installing BlueZ 5.50 on Raspbian Stretch
- Conclusion
In the last note, I showed how to work around three of the four
errors occurring when starting the bluetooth.service
. I undid
those changes, reverting back to the original /lib/systemd/system/bluetooth.service
and removing the cron
entry to restart the service on boots.
After a reboot, the initial service status with its multiple errors returned.
pi@tarte:~ $ sudo systemctl status bluetoo*
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-01-28 12:54:28 AST; 2min 52s ago
Docs: man:bluetoothd(8)
Main PID: 423 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─423 /usr/lib/bluetooth/bluetoothd
Jan 28 12:54:27 tarte bluetoothd[423]: Bluetooth daemon 5.43
Jan 28 12:54:28 tarte systemd[1]: Started Bluetooth service.
Jan 28 12:54:28 tarte bluetoothd[423]: Starting SDP server
Jan 28 12:54:28 tarte bluetoothd[423]: Bluetooth management interface 1.14 initialized
Jan 28 12:54:28 tarte bluetoothd[423]: Failed to obtain handles for "Service Changed" characteristic
Jan 28 12:54:28 tarte bluetoothd[423]: Sap driver initialization failed.
Jan 28 12:54:28 tarte bluetoothd[423]: sap-server: Operation not permitted (1)
Jan 28 12:54:28 tarte bluetoothd[423]: Failed to set privacy: Rejected (0x0b)
Jan 28 12:54:28 tarte bluetoothd[423]: Endpoint registered: sender=:1.6 path=/A2DP/SBC/Source/1
Jan 28 12:54:28 tarte bluetoothd[423]: Endpoint registered: sender=:1.6 path=/A2DP/SBC/Sink/1
● bluetooth.target - Bluetooth
Loaded: loaded (/lib/systemd/system/bluetooth.target; static; vendor preset: enabled)
Active: active since Mon 2019-01-28 12:54:28 AST; 2min 52s ago
Docs: man:systemd.special(7)
Jan 28 12:54:28 tarte systemd[1]: Reached target Bluetooth.
Essentially, I followed my own instructions to update to BlueZ 5.49 as found in 2. Updating
BlueZ changing a couple of minor things. For one I kept a copy of the
original configuration file /etc/dbus-1/system.d/bluetooth.conf
.
This makes for a simpler adjustment later. Secondly, I cleaned up as I went
along.
pi@tarte:~ $ sudo cp /etc/dbus-1/system.d/bluetooth.conf /etc/dbus-1/system.d/bluetooth_conf.543
pi@tarte:~ $ sudo apt install -y libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
...
pi@tarte:~ $ wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.49.tar.xz
...
pi@tarte:~ $ tar -xf bluez-5.49.tar.xz
pi@tarte:~ $ mkdir downloads
pi@tarte:~ $ mv bluez-5.49.tar.xz downloads
pi@tarte:~ $ cd bluez-5.49/
pi@tarte:~/bluez-5.49 $ ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --enable-experimental
...
pi@tarte:~/bluez-5.49 $ make -j4
...
pi@tarte:~/bluez-5.49 $ sudo make install
...
pi@tarte:~/bluez-5.49 $ cd -
/home/pi
pi@tarte:~ $ rm -r bluez-5.49/
pi@tarte:~ $ sudo adduser pi bluetooth
Strictly speaking that last line was not needed in my case because the
default user had already been added to the bluetooth
group.
But do make sure pi
(or whatever is the name of the user)
is a member of the group, otherwise nothing can be accomplished.
pi@tarte:~ $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev bluetooth gpio i2c spi
Comparing the freshly installed configuration file with the old
one, only one more "hole" was punched: LE Advertisement, whereas
the three "watchers" (Thermometer, Heart Rate and Cycling Speed)
had been disabled. I am not sure if these changes are at all
meaning full. However the missing bluetooth group policy in the
new configuration file is needed. Accordingly I edited the old configuration
file to add one line and saved it as the current configuration file.
pi@tarte:~ $ cd /etc/dbus-1/system.d
pi@tarte:/etc/dbus-1/system.d $ sudo nano bluetooth_conf.543
Add the line as shown below.
<allow send_interface="org.bluez.GattCharacteristic1"/>
<allow send_interface="org.bluez.GattDescriptor1"/>
<allow send_interface="org.bluez.LEAdvertisement1"/>
<allow send_interface="org.freedesktop.DBus.ObjectManager"/>
<allow send_interface="org.freedesktop.DBus.Properties"/>
</policy>
And save the file as bluetooth.conf
. Reboot the system
to see how things have changed.
pi@tarte:/etc/dbus-1/system.d $ sudo reboot
Connection to tarte.local closed by remote host.
Connection to tarte.local closed.
michel@hp:~$ ssh pi@tarte.local
...
pi@tarte:~ $ sudo systemctl status bluetooth.service
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-01-28 13:34:46 AST; 1min 37s ago
Docs: man:bluetoothd(8)
Main PID: 532 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─532 /usr/libexec/bluetooth/bluetoothd
Jan 28 13:34:46 tarte systemd[1]: Starting Bluetooth service...
Jan 28 13:34:46 tarte bluetoothd[532]: Bluetooth daemon 5.49
Jan 28 13:34:46 tarte systemd[1]: Started Bluetooth service.
Jan 28 13:34:46 tarte bluetoothd[532]: Starting SDP server
Jan 28 13:34:46 tarte bluetoothd[532]: Bluetooth management interface 1.14 initialized
Jan 28 13:34:46 tarte bluetoothd[532]: Failed to set privacy: Rejected (0x0b)
Jan 28 13:34:46 tarte bluetoothd[532]: Endpoint registered: sender=:1.6 path=/A2DP/SBC/Source/1
Jan 28 13:34:46 tarte bluetoothd[532]: Endpoint registered: sender=:1.6 path=/A2DP/SBC/Sink/1
There remains that pesky failure which disappears when the service
is restarted.
pi@tarte:~ $ sudo systemctl restart bluetooth.service
pi@tarte:~ $ sudo systemctl status bluetooth.service
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-01-28 13:38:33 AST; 6s ago
Docs: man:bluetoothd(8)
Main PID: 705 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─705 /usr/libexec/bluetooth/bluetoothd
Jan 28 13:38:33 tarte systemd[1]: Starting Bluetooth service...
Jan 28 13:38:33 tarte bluetoothd[705]: Bluetooth daemon 5.49
Jan 28 13:38:33 tarte systemd[1]: Started Bluetooth service.
Jan 28 13:38:33 tarte bluetoothd[705]: Starting SDP server
Jan 28 13:38:33 tarte bluetoothd[705]: Bluetooth management interface 1.14 initialized
Jan 28 13:38:33 tarte bluetoothd[705]: Endpoint registered: sender=:1.23 path=/A2DP/SBC/Source/1
Jan 28 13:38:33 tarte bluetoothd[705]: Endpoint registered: sender=:1.23 path=/A2DP/SBC/Sink/1
So back to the brute force solution, this time adding a comment to remember
why that entry is added.
pi@tarte:~ $ crontab -e
# m h dom mon dow command
# work around bluetoothd: Failed to set privacy: Rejected (0x0b)
@reboot sleep 5 && sudo systemctl restart bluetooth.service
Verification of its status after a reboot shows that the service
started, or more accurately, restarted without a problem.
pi@tarte:~ $ sudo reboot
Connection to tarte.local closed by remote host.
Connection to tarte.local closed.
michel@hp:~$ ssh pi@tarte.local
...
pi@tarte:~ $ sudo systemctl status bluetooth.service
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-01-28 14:08:37 AST; 59s ago
Docs: man:bluetoothd(8)
Main PID: 559 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─559 /usr/libexec/bluetooth/bluetoothd
Jan 28 14:08:37 tarte systemd[1]: Starting Bluetooth service...
Jan 28 14:08:37 tarte bluetoothd[559]: Bluetooth daemon 5.49
Jan 28 14:08:37 tarte systemd[1]: Started Bluetooth service.
Jan 28 14:08:37 tarte bluetoothd[559]: Starting SDP server
Jan 28 14:08:37 tarte bluetoothd[559]: Bluetooth management interface 1.14 initialized
Jan 28 14:08:38 tarte bluetoothd[559]: Endpoint registered: sender=:1.9 path=/A2DP/SBC/Source/1
Jan 28 14:08:38 tarte bluetoothd[559]: Endpoint registered: sender=:1.9 path=/A2DP/SBC/Sink/1
There was a change in the content of the service configuration file.
pi@tarte:~ $ cat /lib/systemd/system/bluetooth.service
[Unit]
Description=Bluetooth service
Documentation=man:bluetoothd(8)
ConditionPathIsDirectory=/sys/class/bluetooth
[Service]
Type=dbus
BusName=org.bluez
ExecStart=/usr/libexec/bluetooth/bluetoothd
NotifyAccess=main
#WatchdogSec=10
#Restart=on-failure
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
LimitNPROC=1
ProtectHome=true
ProtectSystem=full
[Install]
WantedBy=bluetooth.target
Alias=dbus-org.bluez.service
Verion 5.49 of the daemon is installed in /usr/libexec/bluetooth
while the old version remains in /usr/lib/bluetooth
. I removed
the old directory hoping that not having done that before did not
have an impact.
pi@tarte:~ $ sudo rm -r /usr/lib/bluetooth
Testing showed that the Raspberry Pi could both send out an audio stream
over a Bluetooth connection (i.e. source a stream) and receive an audio
stream (i.e. sink a stream). Do not forget that the BlueAlsa configuration had to be modified to allow the sinking
of Bluetooth streams, as explained in the previous notes.
To test version 5.50 of BlueZ, which is currently
the newest version, I started with a fresh install of
Rasbpian Stretch. The installation of
version 5.50 is almost exactly the same as above with version 5.49.
pi@berry:~ $ sudo rm -r /usr/lib/bluetooth
pi@berry:~ $ sudo cp /etc/dbus-1/system.d/bluetooth.conf /etc/dbus-1/system.d/bluetooth_conf.543
pi@berry:~ $ sudo apt install -y libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
...
pi@berry:~ $ wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.50.tar.xz
...
pi@berry:~ $ tar -xf bluez-5.50.tar.xz
pi@berry:~ $ mkdir downloads
pi@berry:~ $ mv bluez-5.50.tar.xz downloads
pi@berry:~ $ cd bluez-5.50/
pi@berry:~/bluez-5.50 $ ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --enable-experimental
...
pi@berry:~/bluez-5.50 $ make -j4
...
pi@berry:~/bluez-5.50 $ sudo make install
...
pi@berry:~/bluez-5.50 $ cd -
/home/pi
pi@berry:~ $ rm -r bluez-5.50/
pi@berry:~ $ sudo adduser pi bluetooth
Adding user `pi' to group `bluetooth' ...
Adding user pi to group bluetooth
Done.
pi@berry:~ $ sudo apt install bluealsa -y
...
Setting up bluealsa (0.9) ...
bluealsa.service is a disabled or a static unit, not starting it.
pi@berry:~ $ sudo systemctl start bluealsa
pi@berry:~ $ sudo reboot
Connection to berry.local closed by remote host.
Connection to berry.local closed.
michel@hp:~$ ssh pi@berry.local
...
pi@berry:~ $ sudo systemctl status bluetooth.service
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-01-28 18:29:07 AST; 1min 39s ago
...
Jan 28 18:29:07 berry bluetoothd[417]: Failed to set privacy: Rejected (0x0b)
This is exactly where we were with version 5.49. And I have no better
solution than to restart the service after each reboot to get rid of the
error message.
Interestingly, it was possible to source and sink an audio stream over a
Bluetooth connections even without rebooting the system to get rid of that
error. Do not forget that the BlueAlsa configuration had to be modified to
allow the sinking of Bluetooth streams, as explained in the previous
notes.
I only tried out the new versions of BlueZ and
BlueALSA because of a message from a reader about the
new error: Failed to set privacy: Rejected (0x0b)
. I can now
answer his question with some consequence. That failure is of no consequence
when it comes to streaming sound to a Bluetooth speaker or when using the
Raspberry Pi to read a sound stream from a Bluetooth device. Indeed as these
last two notes have shown, it is not even necessary to update BlueZ for those purposes.
To be sure, there are changes but they do not seem to be directly related
to BlueZ. I believe them related to the new version
of BlueAlsa included in the November 2018 edition of
Raspbian. Perhaps changes to one or both of two other packages,
bluez-firmware
and pi-bluetooth
, could also be
at play.
The comments quoted in the previous note with respect to BLE connections
reveal that there is a real problem, but I have not encountered it. Indeed, I
have not used Bluetooth on the Raspberry Pi since my initial tests back in
the spring of last year. Hence, I do not know if the simple brute force
restarting of the Bluetooth service on reboots is a viable solution. It is
certainly not very elegant.