Bluetooth on my Linux MacBook

We’ve been playing Elden Ring a lot lately (like roughly 12 million other people, it seems), but since it’s a controller exclusive game and I spend all day in my office, I like to play it via Steam Link in the living room, which works fine when I’m only playing with Sabriena, as we can yell at each other easily.

But when we want to play with others, I need to use Discord, which leaves me in a pickle - it doesn’t work via the Steam Link. My Windows laptop finally seems to have given up the ghost in the battery department, so I try avoid using it, and I ended up having to use my work laptop to do it, which I dislike using my work laptop for non-work things.

So today I resolved to brave the eldritch nightmare that is bluetooth audio on Linux and try get it working there, so I can use my old Macbook with Linux on it. But doing so proved every bit as fun as I expected it to be.

First step: install Bluetooth. I’m using KDE Plasma, so I did: pacman -Syu bluedevil

I then had to enable and start the bluetooth daemon:

systemctl enable bluetooth
systemctl start bluetooth

This got me a menu popping up, which is good. I click “add new device” and put my headset into pairing mode by holding the power button for 7 seconds, it pops up, I click pair and… “failed”.

But now it’s in some quantum state of being paired, but not able to connect, and I’m not able to unpair it or do anything about it. What’s going on? I decided to have a crack at using the CLI tools because maybe they’d be more helpful, so I installed bluez-utils and true to form it was actually helpful, by giving me an error message I could reasonably search the internet for: org.bluez.Error.Failed br-connection-profile-unavailable

In just another thing that seems designed to infuriate a BSD zealot, where Arch’s wiki fails, the BBS usually picks up, and I found a thread of someone with the exact same issue. After a couple of mis-steps, the folks there eventually arrived at the correct diagnosis: the connection fails because the bluetooth system doesn’t know what to do with this device, because it’s an audio device and I don’t have anything installed to handle that.

I wasn’t sure which audio system I’m using, but pacman -Q | grep audio suggested it was probably Pulse Audio, so installing pulseaudio-bluetooth finally let me connect the headphones, and it immediately picked the device up and started playing sound through it. However I couldn’t use it as a microphone, which meant more searching!

Yet another thread solved that one: pacmd list-cards shows the device in the a2dp_sink profile, when I need it in headset_head_unit to enable the microphone, but this didn’t seem to want to work (the profile is unavailable on this device). It seems that some devices don’t have this, and use handsfree_head_unit instead, but that didn’t work immediately either, however switching the profile to off and then back to handsfree_head_unit worked.

But typing pacmd set-card-profile bluez_card.00_00_00_00_00_00 handsfree_head_unit (where the string of zeroes is, goes the device ID for my headset) every time I want to connect it seems like a pain in the arse, surely there’s a better way?

Pulse Audio has a set of configuration files, and so I should be able to edit /etc/pulse/ to put this command in right? Well, I don’t want to edit default files, but I can use /etc/pulse/ instead:

$ cat /etc/pulse/ 
set-card-profile bluez_card.00_00_00_00_00_00 handsfree_head_unit

This didn’t seem to work, even when I uncommented the relevant lines from pulseaudio’s daemon config. So I guess I’m stuck keeping that command in my history, or maybe creating an alias as someone else on the forums did? It’s also worth noting that I can toggle it in the GUI settings box as well, but yeah thus far no way to make it automatically stick.

I wonder if I can do some fuckery with dev.d or systemd or something, make a unit that fires when the device is added?

Update: While talking to Avi about it, he recommended switching Pulse Audio out for Pipewire, which didn’t really help matters, but does seem to be the new hotness in Linux audio so it probably makes sense to use. However while searching for that I found a response to an issue similar to mine which did.

So basically what I did was got the PHYS address of my BT headset (which for some reason is different to the BT MAC?), and created an entry in udevd for this:

# cat > /etc/udev/rules.d/10-wi-c310.rules
ACTION=="add", SUBSYSTEM=="input", ATTRS{phys}=="XX:XX:XX:XX:XX:XX", RUN+="/usr/bin/pactl -s /run/user/1000/pulse/native set-card-profile bluez_card.YY_YY_YY_YY_YY_YY headset-head-unit"

## replacing XXXX with the physical address and YYYY with the MAC that bluez reports
## Also replace 1000 with the UID of the user who will use the machine (naturally
## multi-user setups will have a further issue to solve)

Then I can reload udev with udevadm control --reload-rules and udevadm trigger. I can then power-cycle my headset and it’s picked up as an input automatically? I think this is everything I want - I am unlikely to want to use this headset for high-def audio on this machine, so locking it to the bidirectional codec is not an issue for me at all.

Let’s see if it survives reboots I guess.

Horsham, VIC, Australia fwaggle



Filed under:


Horsham, VIC, Australia

Navigation: Older Entry Newer Entry