Bluetooth configuration (with alpine linux)

Hi everyone,

I try to configure Bluetooth connection with my smartphone to a container.
I take a look around the forum but can’t find an idea (I don’t know the Bluetooth protocol very well).

From my understanding : bluetoothd communicate with the Bluetooth device and run on the BalenaOS host and them the container communicate with the daemon through dbus with an agent (bluetoothctl for example).

I can pair my device but can’t connect it. I try to adapt what was done in the Bluetooth BalenaSound container but got an error :

bash-5.0# /usr/bin/bluealsa -i hci0 -p a2dp-sink
/usr/bin/bluealsa: E: Couldn't acquire D-Bus name: org.bluealsa

info : Raspberry Pi 3 A+ , Alpine Linux 3.11

package installed :

apk add --no-cache bluez bluez-deprecated alsa-utils alsa-utils-doc alsa-lib alsaconf
apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing bluez-alsa

bluetoothctl seems good :

bash-5.0# bluetoothctl 
Agent registered
[bluetooth]# show
Controller B8:27:EB:14:A6:97 (public)
        Name: 5fc958d
        Alias: chambre
        Class: 0x00000000
        Powered: yes
        Discoverable: yes
        DiscoverableTimeout: 0x00000000
        Pairable: yes
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v1D6Bp0246d0532
        Discovering: no
Advertising Features:
        ActiveInstances: 0x00
        SupportedInstances: 0x05
        SupportedIncludes: tx-power
        SupportedIncludes: appearance
        SupportedIncludes: local-name

and I paired my device :

[NEW] Device 58:CB:52:16:4B:35 Thibault
[CHG] Device 58:CB:52:16:4B:35 Modalias: bluetooth:v00E0p1200d1436
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001112-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001115-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001116-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 0000112d-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 0000112f-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001132-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device 58:CB:52:16:4B:35 UUIDs: b3b7e28e-a000-3e17-bd86-6e97b9e28c11
[CHG] Device 58:CB:52:16:4B:35 ServicesResolved: yes
[CHG] Device 58:CB:52:16:4B:35 Paired: yes
[CHG] Device 58:CB:52:16:4B:35 ServicesResolved: no
[CHG] Device 58:CB:52:16:4B:35 Connected: no
[bluetooth]# paired-devices 
Device 58:CB:52:16:4B:35 Thibault

One thing I don’t uderstand is why the device disconnect after the pairing phase :

[CHG] Device 58:CB:52:16:4B:35 ServicesResolved: no
[CHG] Device 58:CB:52:16:4B:35 Connected: no

And I can’t connect after that :

[bluetooth]# connect 58:CB:52:16:4B:35                   
Attempting to connect to 58:CB:52:16:4B:35
Failed to connect: org.bluez.Error.Failed

I also try to trust the device then connect from the shell or from the phone can’t make it work :

[bluetooth]# trust 58:CB:52:16:4B:35 
[CHG] Device 58:CB:52:16:4B:35 Trusted: yes
Changing 58:CB:52:16:4B:35 trust succeeded
[bluetooth]# connect 58:CB:52:16:4B:35
Attempting to connect to 58:CB:52:16:4B:35
Failed to connect: org.bluez.Error.Failed

there is some info from the device :

[bluetooth]# info 58:CB:52:16:4B:35 
Device 58:CB:52:16:4B:35 (public)
        Name: Thibault
        Alias: Thibault
        Class: 0x005a020c
        Icon: phone
        Paired: yes
        Trusted: yes
        Blocked: no
        Connected: no
        LegacyPairing: no
        UUID: OBEX Object Push          (00001105-0000-1000-8000-00805f9b34fb)
        UUID: Audio Source              (0000110a-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: Headset AG                (00001112-0000-1000-8000-00805f9b34fb)
        UUID: PANU                      (00001115-0000-1000-8000-00805f9b34fb)
        UUID: NAP                       (00001116-0000-1000-8000-00805f9b34fb)
        UUID: Handsfree Audio Gateway   (0000111f-0000-1000-8000-00805f9b34fb)
        UUID: SIM Access                (0000112d-0000-1000-8000-00805f9b34fb)
        UUID: Phonebook Access Server   (0000112f-0000-1000-8000-00805f9b34fb)
        UUID: Message Access Server     (00001132-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: Vendor specific           (b3b7e28e-a000-3e17-bd86-6e97b9e28c11)
        Modalias: bluetooth:v00E0p1200d1436

Hi

  • Can you share your dockerfile? We’d like to take a closer look at it
  • Also, looking at the logs, this could be a one-off issue with a particular device. Can you also try another phone/device and share the output for that if it’s different?

Hi,

I try from my phone and chromebook.

The strange part : It is working with the same phone if I use bluetooth container from BalenaSound with the same phone :confused:

docker-compose :

bluetooth:
    build: ./bluetooth
    restart: unless-stopped
    network_mode: host
    privileged: true
    labels:
      io.balena.features.dbus: 1
      io.balena.features.supervisor-api: '1'
      io.balena.features.balena-api: '1'

Dockerfile :

FROM balenalib/%%BALENA_MACHINE_NAME%%-alpine:3.11

# set dbus address
ENV DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
ENV UDEV=1

# create folder to store install scripts
RUN mkdir /root/install

# copy script to the created folder
COPY install-base.sh /root/install/install-base.sh
COPY install-bluetooth.sh /root/install/install-bluetooth.sh
COPY start.sh /root/install/start.sh
#COPY bluetooth-agent /usr/bin/bluetooth-agent
#RUN chmod +x /usr/bin/bluetooth-agent

# run script to prepare env
RUN /bin/ash /root/install/install-base.sh
RUN /bin/ash /root/install/install-bluetooth.sh

CMD [ "/bin/ash", "/root/install/start.sh" ]

start.sh :

#!/bin/ash

# if tag to be stop then exit it
if [ "$IS_STARTED" != "true" ] ; then
    curl --header "Content-Type:application/json" "$BALENA_SUPERVISOR_ADDRESS/v2/applications/$BALENA_APP_ID/stop-service?apikey=$BALENA_SUPERVISOR_API_KEY" -d '{"serviceName": "'$BALENA_SERVICE_NAME'"}'
fi

# if spotify device name not defined in balena service var use host name
if [ "$BLUETOOTH_DEVICE_NAME" == "none" ] ; then
    BLUETOOTH_DEVICE_NAME=$BALENA_DEVICE_NAME_AT_INIT
fi

# set dbus address
export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

# configure bluetooth
bluetoothctl power off
bluetoothctl system-alias $BLUETOOTH_DEVICE_NAME
bluetoothctl set-alias $BLUETOOTH_DEVICE_NAME
bluetoothctl pairable on
bluetoothctl discoverable on
bluetoothctl discoverable-timeout 0
bluetoothctl power on
#hciconfig hci0 class 0x200428
#hciconfig hci0 sspmode 1

/usr/bin/bluealsa -i hci0 -p a2dp-sink &

# start
sleep infinity

Hi,

Good to hear that balenaSound works for you with that phone - that shows that the balena platform and your phone are working OK. There’s nothing wrong with your dockerfile, so I think it’s down to your particular shell scripts in your app. Luckily you can compare your app with the code in balenaSound and work out where the difference(s) is.

Good luck.
Phil

Hi,

Well after some search I think bluetooth is working fine.

From the BalenaSound Bluetooth debian container I’m able to reproduce it.
The bluetooth python agent need to be launch with bluealsa.
I don’t uderstand the process (mean how bluez and bluetooth work) but the disconnection I get is “normal” cause no agent (the python script) is authorizing the service (bluealsa is not runing).

I think my issue come from the dbus with bluealsa. I open a case (https://github.com/Arkq/bluez-alsa/issues/335) just to clarify.

On the debian container we are using an old bluealsa version :

alpine linux :

bash-5.0# bluealsa --version
2.1.0

debian :

root@5fc958d:/# bluealsa --version
1.3.0

I suppose bluealsa 2.1.0 try to use a bus named org.bluealsa :

bash-5.0# bluealsa
bluealsa: E: Couldn't acquire D-Bus name: org.bluealsa

that is not authorize on BalenaOS :

root@5fc958d:~# dbus-monitor --system | grep org.bluealsa
   string "org.bluealsa"
   string "Connection ":1.343" is not allowed to own the service "org.bluealsa" due to security policies in the configuration file"

I suppose the debian bluealsa version use another bus address but I can’t find the good one (dbus logs is a pain).

Is there a way to add some conf file to /etc/dbus-1/system.d/bluealsa.conf ?
I can’t write file to it… read only

Hey @tdesaules thats great to hear and looks like we are getting somewhere. To test setting some config changes in /etc/dbus-1/system.d/bluealsa.conf you can temporarily mount the rootFS as read-write using mount -o remount, rw / then you should be able to make changes. However, please note that this is not recommended for production use as will be wiped out with OS updates. So once you have done the testing and worked out what needs to be added where, we can work with the OS team to add those configs officially. My one worry is that since we don’t have bluealsa on the OS this might not apply, but perhaps just having the config there will be enough, interested to see your results.

Well I just try it and this is working, bluealsa from the alpine container can access dbus service org.bluealsa :slight_smile:

I’m not sure thats a good idea to allow globaly the org.bluealsa dbus service. It is strange just for one use case…

Is there a way to do it using balena-cli (like the inject for the config.json) ? After that it should be a part of my CD pipeline.
I also rebuild the balena img but it will be a pain :confused:

Thats great that it works. Unfortunately there isn’t a way to do it with the CLI and it wouldn’t solve the issue because that setting would be wiped out when an OS update is performed and we want people to get very comfortable with OS updates as having people stick to old version massively slows down our ability to improve the platform. Why do you think having it default in the OS would be a bad idea? Can you post the config you added to bluealsa.conf here and I can run it by the linux/os gurus and we can try work out a product based solution to enable this for you and others that need this in the future.

I just find this a litle oversized just for my use case

But you are right, for the update there is no workaround (or you have to transform the upgrade process ^^)

I also see on the BalenaSound git (somewhere) that they are stuck with the debian 10 upgrade on the bluetooth-audio container (maybe related)

well I just add this file :

/etc/dbus-1/system.d/bluealsa.conf

Content from : https://github.com/Arkq/bluez-alsa/blob/master/src/bluealsa.conf (if you prefere the source) :

<!-- This configuration file specifies the required security policies
     for BlueALSA core daemon to work. -->

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>

  <!-- ../system.conf have denied everything, so we just punch some holes -->

  <policy user="root">
    <allow own_prefix="org.bluealsa"/>
    <allow send_destination="org.bluealsa"/>
  </policy>

  <policy group="audio">
    <allow send_destination="org.bluealsa"/>
  </policy>

</busconfig>

I don’t try yet the bluealsa-aplay part so I’m not sure all the stack is working (but dbus is able to communicate)

While it might seem overkill for just your usecase, it might help 100s of other people in the future, we might also be able to come up with a less “all or nothing” method after some brainstorming. I think as long as it doesn’t interfere with other users using bluetooth (which looks like it shouldn’t) I don’t see why we can’t include it in the OS by default, but I will let the OS guys have the final say.

1 Like

Let us know how you get along with this change, I have tagged this for some internal discussion with the team and if we come up with a good idea we will come back to update you.

of course !

thank you

Hi there,

I just finish some testing and I confirm adding the bluealsa.conf file solved my problem.
Still need to find a reliable way to do it.

Thank you

Thank you for the information you have given us and I am happy to hear that adding the file will solve the problem.
We have started to discuss internally how to improve this process but we still need to do some more investigation.
We will keep you updated as soon as we have some news.

1 Like

Hi there,

Just to know is there any update on this ?

Thank you

Hi there, we are still looking into it, we’ll get back to you as soon as we have an update. Thanks!