January 26, 2019
This is a short note reporting some changes encountered with the newest
version of BlueAlsa when used with BlueZ version 5.43 with the latest version of Raspbian Stretch. In essence, I will take up the subject
matter covered in Baby
Bluetooth Steps on Raspberry Pi 3 - Raspbian (Stretch) which was
my first incursion into this complicated subject. There will also be an incursion
into the possibility of playing an audio stream from a Bluetooth device on
the Raspberry Pi as discussed in Bluetooth Audio with Rasbian
Stretch on the Raspberry Pi 3).
I hope to look at versions 5.49 and 5.50 of BlueZ in a further note to come. Versions 5.49 and 5.50 of
BlueZ are examined in A Note on BlueAlsa 0.9 with BlueZ 5.49 and 5.50 on Rasbian Stretch.
Table of Contents
- BlueZ 5.43 on Raspbian Stretch
- Installing BlueAlsa 0.9
As a first step after starting with an updated and upgraded image
of the operating system, let's look at what was installed and what is
available.
pi@tarte:~ $ apt-cache policy bluez*
bluez:
Installed: 5.43-2+rpt2+deb9u2
Candidate: 5.43-2+rpt2+deb9u2
Version table:
*** 5.43-2+rpt2+deb9u2 500
500 http://archive.raspberrypi.org/debian stretch/main armhf Packages
100 /var/lib/dpkg/status
5.43-2+deb9u1+b4 500
500 http://raspbian.raspberrypi.org/raspbian stretch/main armhf Packages
bluez-firmware:
Installed: 1.2-3+rpt6
Candidate: 1.2-3+rpt6
Version table:
*** 1.2-3+rpt6 500
500 http://archive.raspberrypi.org/debian stretch/main armhf Packages
100 /var/lib/dpkg/status
1.2-3 500
500 http://raspbian.raspberrypi.org/raspbian stretch/non-free armhf Packages
pi@raspberrypi:~ $ apt-cache policy bluealsa
bluealsa:
Installed: (none)
Candidate: 0.9
Version table:
0.9 500
500 http://archive.raspberrypi.org/debian stretch/main armhf Packages
As before, version 5.43 of BlueZ is included,
but how well is it integrated in the newest version of Stretch?
pi@tarte:~ $ dmesg | grep -i blue
[ 10.638731] Bluetooth: Core ver 2.22
[ 10.638784] Bluetooth: HCI device and connection manager initialized
[ 10.638797] Bluetooth: HCI socket layer initialized
[ 10.638805] Bluetooth: L2CAP socket layer initialized
[ 10.638823] Bluetooth: SCO socket layer initialized
[ 10.649042] Bluetooth: HCI UART driver ver 2.3
[ 10.649052] Bluetooth: HCI UART protocol H4 registered
[ 10.649055] Bluetooth: HCI UART protocol Three-wire (H5) registered
[ 10.649175] Bluetooth: HCI UART protocol Broadcom registered
[ 10.840891] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 10.840899] Bluetooth: BNEP filters: protocol multicast
[ 10.840914] Bluetooth: BNEP socket layer initialized
No change from before. But looking at the status of the Bluetooth service
there is now a fourth error message that was not present back in December of
2017 with the same version of BlueZ on Jessie.
pi@tarte:~ $ sudo systemctl status bluetoo*
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset
Active: active (running) since Sat 2019-01-26 13:37:58 AST; 2min 33s ago
Docs: man:bluetoothd(8)
Main PID: 420 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─420 /usr/lib/bluetooth/bluetoothd
Jan 26 13:37:58 tarte systemd[1]: Starting Bluetooth service...
Jan 26 13:37:58 tarte bluetoothd[420]: Bluetooth daemon 5.43
Jan 26 13:37:58 tarte systemd[1]: Started Bluetooth service.
Jan 26 13:37:58 tarte bluetoothd[420]: Starting SDP server
Jan 26 13:37:58 tarte bluetoothd[420]: Bluetooth management interface 1.14 initialized
Jan 26 13:37:58 tarte bluetoothd[420]: Failed to obtain handles for "Service Changed" characteristic
Jan 26 13:37:58 tarte bluetoothd[420]: Sap driver initialization failed.
Jan 26 13:37:58 tarte bluetoothd[420]: sap-server: Operation not permitted (1)
Jan 26 13:37:58 tarte bluetoothd[420]: Failed to set privacy: Rejected (0x0b)
● bluetooth.target - Bluetooth
Loaded: loaded (/lib/systemd/system/bluetooth.target; static; vendor preset: enabled)
Loaded: loaded (/lib/systemd/system/bluetooth.target; static; vendor preset:
Active: active since Sat 2019-01-26 13:37:58 AST; 2min 33s ago
Docs: man:systemd.special(7)
Jan 26 13:37:58 tarte systemd[1]: Reached target Bluetooth.
Well that is not encouraging, but restarting the service does make the last
reported failure go away.
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 Sat 2019-01-26 13:43:22 AST; 15s ago
Docs: man:bluetoothd(8)
Main PID: 653 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─653 /usr/lib/bluetooth/bluetoothd
Jan 26 13:43:22 tarte systemd[1]: Stopped Bluetooth service.
Jan 26 13:43:22 tarte systemd[1]: Starting Bluetooth service...
Jan 26 13:43:22 tarte bluetoothd[653]: Bluetooth daemon 5.43
Jan 26 13:43:22 tarte systemd[1]: Started Bluetooth service.
Jan 26 13:43:22 tarte bluetoothd[653]: Starting SDP server
Jan 26 13:43:22 tarte bluetoothd[653]: Bluetooth management interface 1.14 initialized
Jan 26 13:43:22 tarte bluetoothd[653]: Failed to obtain handles for "Service Changed" characteristic
Jan 26 13:43:22 tarte bluetoothd[653]: Sap driver initialization failed.
Jan 26 13:43:22 tarte bluetoothd[653]: sap-server: Operation not permitted (1)
This type of behaviour is an indication that there is a problem with the
order in which modules are loaded when the system is rebooted. There is a
lengthy discussion by John H. Rucker on the topic Bluetooth LE peripheral can not resolve a bound device's
random address after reboot in the Raspberry Raspbian Forum. Even if the
topic was rather obscure for me, the information it contains is informative.
I also recommend his message Help troubleshooting a random Bluez 5.50 Failed to set
privacy: Rejected (0x0b) error during IPL in the Linux Bluetooht Wireless
archive. As of January 25, it seems no one could offer help and my blind
attempts at changing the order in which services are loaded by playing with
systemd unit files came to nought. So I opted for a crude, but
hopefully temporary solution. I added a task to be performed by the
cron scheduler five seconds after each boot.
pi@tarte:~ $ crontab -e
...
#For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
@reboot sleep 5 && sudo systemctl restart bluetooth.service
To get rid of the SIM access profile (sap) related
errors, the Bluetooth
configuration file needs to be modified to stop loading that (non-existant)
driver.
pi@tarte:~ $ sudo nano /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/lib/bluetooth/bluetoothd --compat --noplugin=sap -E
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
Finally, the default user still needs to be added to the
bluetooth group, otherwise it will be impossible to use
bluetoothctl.
pi@tarte:~ $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi
pi@tarte:~ $ sudo adduser pi bluetooth
Adding user `pi' to group `bluetooth' ...
Adding user pi to group bluetooth
Done.
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 Sat 2019-01-26 16:34:27 AST; 41s ago
Docs: man:bluetoothd(8)
Main PID: 548 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─548 /usr/lib/bluetooth/bluetoothd --compat --noplugin=sap -E
Jan 26 16:34:27 tarte systemd[1]: Starting Bluetooth service...
Jan 26 16:34:27 tarte bluetoothd[548]: Bluetooth daemon 5.43
Jan 26 16:34:27 tarte bluetoothd[548]: Starting SDP server
Jan 26 16:34:27 tarte bluetoothd[548]: Excluding (cli) sap
Jan 26 16:34:27 tarte systemd[1]: Started Bluetooth service.
Jan 26 16:34:27 tarte bluetoothd[548]: Bluetooth management interface 1.14 initialized
Jan 26 16:34:27 tarte bluetoothd[548]: Failed to obtain handles for "Service Changed" characteristic
So the added --compat and -E options did not
manage to get rid of the handles problem. Still, three out of four is not a
bad average right? I will now take BlueZ out for a spin,
making sure that a Bluetooth speaker is on.
pi@tarte:~ $ bluetoothctl
[NEW] Controller B8:27:EB:55:FC:57 tarte [default]
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:55:FC:57 Discovering: yes
[NEW] Device 30:21:3E:31:C6:2B AUDIOPOD2
[bluetooth]# pair 30:21:3E:31:C6:2B
Attempting to pair with 30:21:3E:31:C6:2B
[CHG] Device 30:21:3E:31:C6:2B Connected: yes
[CHG] Device 30:21:3E:31:C6:2B UUIDs: 00001108-0000-1000-8000-00805f9b34fb
[CHG] Device 30:21:3E:31:C6:2B UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device 30:21:3E:31:C6:2B UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 30:21:3E:31:C6:2B UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device 30:21:3E:31:C6:2B UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device 30:21:3E:31:C6:2B ServicesResolved: yes
[CHG] Device 30:21:3E:31:C6:2B Paired: yes
Pairing successful
[CHG] Device 30:21:3E:31:C6:2B ServicesResolved: no
[CHG] Device 30:21:3E:31:C6:2B Connected: no
[CHG] Device 30:21:3E:31:C6:2B RSSI: -64
[bluetooth]# connect 30:21:3E:31:C6:2B
Attempting to connect to 30:21:3E:31:C6:2B
Failed to connect: org.bluez.Error.Failed
[bluetooth]# quit
The inability to connect to the speaker is not unexpected since "...
Bluez >= 5, the build-in integration has been removed in favor of 3rd party
audio applications. From now on, Bluez acts as a middleware between an audio
application, which implements Bluetooth audio profile, and a Bluetooth audio
device" (source). The next step is to install Bluetooth Audio ALSA Backend a.k.a. BlueALSA which acts as a proxy between Bluez and ALSA
alleviating the need to install PulseAudio no longer
included by default with Stretch.
Luckily the Bluetooth audio ALSA backend is easily added.
pi@tarte:~ $ sudo apt install bluealsa -y
Reading package lists... Done
...
Setting up bluealsa (0.9) ...
bluealsa.service is a disabled or a static unit, not starting it.
That list line is new and does indicate a problem.
pi@tarte:~ $ sudo systemctl status bluealsa
● bluealsa.service - BluezALSA proxy
Loaded: loaded (/lib/systemd/system/bluealsa.service; static; vendor preset:
Active: inactive (dead)
So unlike before, the service has to be started explicitly, or the
system has to be rebooted to start the service. The former is faster.
pi@tarte:~ $ sudo systemctl start bluealsa
pi@tarte:~ $ sudo systemctl status bluealsa
● bluealsa.service - BluezALSA proxy
Loaded: loaded (/lib/systemd/system/bluealsa.service; static; vendor preset:
Active: active (running) since Sun 2019-01-27 11:49:36 AST; 2s ago
Main PID: 901 (bluealsa)
CGroup: /system.slice/bluealsa.service
└─901 /usr/bin/bluealsa
Now it was possible to connect to the Bluetooth speaker.
[bluetooth]# connect 30:21:3E:31:C6:2B
Attempting to connect to 30:21:3E:31:C6:2B
[CHG] Device 30:21:3E:31:C6:2B Connected: yes
Connection successful
[CHG] Device 30:21:3E:31:C6:2B ServicesResolved: yes
[AUDIOPOD2]# info 30:21:3E:31:C6:2B
Device 30:21:3E:31:C6:2B
Name: AUDIOPOD2
Alias: AUDIOPOD2
Class: 0x240408
Icon: audio-card
Paired: yes
Trusted: no
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Headset (00001108-0000-1000-8000-00805f9b34fb)
UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb)
UUID: Handsfree (0000111e-0000-1000-8000-00805f9b34fb)
[AUDIOPOD2]# quit
[DEL] Controller B8:27:EB:55:FC:57 tarte [default]
Failed to unregister advertisement method
That was a new error message, nevertheless it was possible to play
an audio stream through the Bluetooth speaker.
pi@tarte~ $ aplay -D bluealsa:HCI=hci0,DEV=30:21:3E:31:C6:2B,PROFILE=a2dp sound/test.wav
or the simpler
pi@tarte~ $ aplay -D bluealsa:DEV=30:21:3E:31:C6:2B sound/test.wav
Playing WAVE 'sound/test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
As before the bluealsa device can be made the default
player.
pi@tarte:~ $ nano .asoundrc
Add the following content in what should be an empty file.
pcm.!default {
type plug
slave.pcm {
type bluealsa
device "30:21:3E:31:C6:2B"
profile "a2dp"
}
}
The aplay command can be invoked with just the file name, and
as long as the Bluetooth speaker is still connected, the output will
be heard through it.
pi@tarte~ $ aplay sound/test.wav
Playing WAVE 'sound/test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
If using the .asoundrc configuration suggested by Arkadiusz Bokowy
then the command to play the sound file would be slightly different.
pi@tarte~ $ aplay -D sound/test.wav
Playing WAVE 'sound/test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
While all this looks to be the same, I did find a change from before when
running the audio playback and capture volume
controller, AlsaMixer. Only the
AUDIOPOD -A2DP profile was shown. The SCO and
Battery profiles were gone .
It is also possible (to some extent) to use the Raspberry Pi as an "audio
sink," in other words, to use it to play sound from a Bluetooth source such
as a tablet through a connected speaker as explained in Receiving Sound from
Bluetooth Audio Devices in my post note on the subject. However, to do
this, it was necessary to change the bluealsa.service
beforehand.
pi@tarte:~ $ sudo nano /lib/systemd/system/bluealsa.service
As per the answer by Arkadiusz Bokowy it is now necessary to
add the Bluetooth sink profile.
[Unit]
Description=BluezALSA proxy
Requires=bluetooth.service
After=bluetooth.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/bluealsa -p a2dp-source -p a2dp-sink
For the changes to take place, reload the daemons (services) and restart
bluealsa.
pi@tarte:~ $ sudo systemctl daemon-reload
pi@tarte:~ $ sudo systemctl restart bluealsa
After that, I followed my own instructions to successfully stream the
audio from a YouTube video playing on my tablet to the Raspberry Pi. There
is no miracle, sound output is still choppy unless Wi-Fi is disabled and the
synchronization of sound and image is awful.
I used a different tablet from the previous example, with a different
version of Android, so the steps to connect the
Raspberry Pi bluetooth were slightly different from what I wrote... as one
would expect. I will not be updating the post, I don't even have a device
that can be updated to a recent version of Android.
What changes when moving to newer versions of Bluez will be examined in another note in the following note