Bluetooth
Bluetooth is a standard for the short-range wireless interconnection of cellular phones, computers, and other electronic devices. In Linux, the canonical implementation of the Bluetooth protocol stack is BlueZ.
Pairing
phone:~# service bluetooth start
phone:~# bluetoothctl
Agent registered
[CHG] Controller XX:XX:XX:XX:XX:XX Pairable: yes
[bluetooth]# scan on
[NEW] 00:11:22:33:44:55
[bluetooth]# pair 00:11:22:33:44:55
To use bluetooth headphones with pulseaudio, the package pulseaudio-bluezPMOS is required.
Supported Bluetooth Profiles
Audio/Video Remote Control Profile (AVRCP)
To use media keys with Bluetooth, the mpris-proxy
command should be run. It needs access to Dbus.
mpris-proxy
is started at boot to enable AVRCP 1.5 support. PulseAudio and BlueZ must be installed for this which pulls in mpris-proxy
automatically.
MR at pmaports: pmaports!1804
Advanced Audio Distribution Profile (A2DP)
PulseAudio and BlueZ handle together Bluetooth A2DP 1.3 support. This is supported out-of-the-box.
PhoneBook Access Profile (PBAP)
BlueZ got PBAP 1.1 support recently in 5.63 with GNOME Evolution as backend. Currently, a MR is pending at Alpine to enable this feature: https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/29955
Object Push Profile (OPP)
OBEXd was enabled at boot to enable OPP 1.2 support for transfering and receiving files over Bluetooth. MR at pmaports: pmaports!2245
Human Interface Device Profile (HID)
BlueZ provides the HID 1.0 profile to support mice and keyboards over Bluetooth. It is enabled by default.
Unsupported Bluetooth Profiles
Message Access Profile (MAP)
BlueZ has support for MAP 1.0 but does not have a backend which is compatible with any UI stack. The supported backends are from the old Nokia Maemo days.
Personal Area Network (PAN)
BlueZ supports PAN 1.0. You should be able to use PAN network using NetworkManager. Make sure you have the networkmanager-bluetooth package, which is not there by default at the time of writing this sentence.
To connect to a shared connection using Bluetooth, desktop environments like Plasma should let you create a network manager connection automatically, but you can also do it manually: create a /etc/NetworkManager/system-connections/MyConnectionName.nmconnection with a content that looks like this:
[connection] id=MyConnectionName uuid=UUID type=bluetooth autoconnect=false metered=1 [bluetooth] bdaddr=BDADDR type=panu [ipv4} method=auto [ipv6] addr-gen-mode=default method=auto [proxy]
Where UUID is a uuid you can generate using uuidgen, and BDADDR is the Bluetooth address of your access point.
You can also try something like this:
nmcli connection add type bluetooth con-name "Bluetooth Hotspot" autoconnect no ifname btnap0 bluetooth.type nap ipv4.method shared ipv6.method disabled
For now, only IPv4 is marked as shared. IPv6 should work but was not tested. This works if BlueZ was built with BNEP support and a valid Bluetooth MAC address is available. Without a valid MAC address, the BlueZ BNEP network bridges cannot be added to the kernel.
Source: https://networkmanager.dev/docs/api/latest/nmcli-examples.html
Hands-Free Profile (HFP)
BlueZ and PulseAudio partly support HFP 1.6. Only the audio part is supported. Reporting battery levels from the AG to HF is unsupported and all cellular operations and status reporting is not supported (yet). A first step in fully supporting Bluetooth HFP 1.6 is taken here: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/631
postmarketOS edge has the necessary patches applied to PulseAudio for supporting Bluetooth HFP AT commands (battery level reporting, cellular status, accept/reject calls, etc.), audio routing not yet. Feedback is welcome in https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/693
HFP AT command support for controlling calls is merged in PipeWire and will be available officially when postmarketOS switches to PipeWire in the near future.
Other profiles
Bluetooth supports many other profiles, see https://www.bluetooth.com/specifications/ It is currently unknown if they are supported or not.
Bluetooth profiles supported by other mobile OSes
- Supported Bluetooth profiles by Apple: https://support.apple.com/en-us/HT204387
- Supported Bluetooth profile by Android: https://source.android.com/devices/bluetooth/services
Troubleshooting
No default controller available
# modprobe -r btqcomsmd
# modprobe btqcomsmd
Failed set serial line discipline: Invalid argument
in btattach or Can't set line discipline: Invalid argument
in hciattach:
Enable CONFIG_BT_HCIUART
(and possibly CONFIG_BT_HCIUART_BCM
) in kernel config.
btattach -P bcm
doesn't set desired baud rate after uploading firmware:
Use hciattach instead (https://github.com/Arkq/bluez-alsa/issues/205) and verify results with stty -F /dev/tty
.
Failed to start discovery: org.bluez.Error.NotReady
or Failed to connect: org.bluez.Error.NotReady br-connection-adapter-not-powered
[bluetooth]# power on
Changing power on succeeded
[CHG] Controller XX:XX:XX:XX:XX:XX Powered: yes
When connecting to a headset.
# apk add bluez-alsa
# service bluealsa start
# bluetoothctl
[bluetooth]# connect 00:11:22:33:44:55
Attempting to connect 00:11:22:33:44:55
Connection successful
[CHG] Device 00:11:22:33:44:55 ServicesResolved: yes
Bluetooth keyboards, mice and other HID devices
With UHID
First, install hidapi
:
# apk add hidapi
Make sure CONFIG_UHID
is enabled in your kernel. If it's enabled as a module, run:
# modprobe uhid
# service bluetooth restart
Getting the device to work might require a few tries; in general, what often works is first pairing the device, then turning off Bluetooth, turning it on again and letting the device connect again (many mice/keyboards will try to reconnect when you press any key/move the mouse).
Without UHID
Open /etc/bluetooth/input.conf
, and configure it:
[General]
# Enable HID protocol handling in userspace input profile
# Defaults to true (Use UHID instead of kernel HIDP)
UserspaceHID=false
Note that the default value was false
until 5.73[1].
Restart service bluetooth
.
# service bluetooth restart
DUALSHOCK 4 / DualSense
Disconnection of PlayStation controllers has been addressed in bluez#614. The fix[2] to the issue has been released in 5.71+.