From f0d7da514139313ca0e1af742aeaaee209e2f763 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Tue, 28 Apr 2026 00:59:05 -0400 Subject: [PATCH] bluez: fix a2dp (cherry-pick patch) --- modules/desktop-common.nix | 21 +++++++++++- .../0001-a2dp-connect-source-after-sink.patch | 32 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 patches/bluez/0001-a2dp-connect-source-after-sink.patch diff --git a/modules/desktop-common.nix b/modules/desktop-common.nix index 1012012..d11a8a3 100644 --- a/modules/desktop-common.nix +++ b/modules/desktop-common.nix @@ -66,7 +66,26 @@ }; # cachyos kernel overlay - nixpkgs.overlays = [ inputs.nix-cachyos-kernel.overlays.default ]; + nixpkgs.overlays = [ + inputs.nix-cachyos-kernel.overlays.default + # bluez 5.86 reversed the profile-connect order (regression of cdcd845f87ee). + # Dual-role devices that advertise both AudioSource (UUID 0x110a) and + # AudioSink (UUID 0x110b) -- e.g. any A2DP headphone with an HFP mic, like + # the Bose QC 45 -- now negotiate audio-gateway first and never expose + # a2dp-sink, with bluetoothd reporting: + # src/service.c:btd_service_connect() a2dp-sink profile connect failed + # for : Device or resource busy + # Cherry-picks bluez/bluez@066a164 "a2dp: connect source profile after + # sink" (slated for 5.87). FIX: drop overlay when nixpkgs ships >= 5.87. + # see https://github.com/bluez/bluez/issues/1922 + (_final: prev: { + bluez = prev.bluez.overrideAttrs (old: { + patches = (old.patches or [ ]) ++ [ + ../patches/bluez/0001-a2dp-connect-source-after-sink.patch + ]; + }); + }) + ]; # kernel options boot = { diff --git a/patches/bluez/0001-a2dp-connect-source-after-sink.patch b/patches/bluez/0001-a2dp-connect-source-after-sink.patch new file mode 100644 index 0000000..5a8704e --- /dev/null +++ b/patches/bluez/0001-a2dp-connect-source-after-sink.patch @@ -0,0 +1,32 @@ +From 066a164a524e4983b850f5659b921cb42f84a0e0 Mon Sep 17 00:00:00 2001 +From: Pauli Virtanen +Date: Mon, 16 Feb 2026 18:17:08 +0200 +Subject: [PATCH] a2dp: connect source profile after sink + +Since cdcd845f87ee the order in which profiles with the same priority +are connected is the same order as btd_profile_register() is called, +instead of being the opposite order. When initiating connections, we +want to prefer a2dp-sink profile over a2dp-source, as connecting both at +the same time does not work currently. + +Add .after_services to specify the order. + +Fixes: https://github.com/bluez/bluez/issues/1898 +--- + profiles/audio/a2dp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c +index 7a37003a2b..c7e0fc75c0 100644 +--- a/profiles/audio/a2dp.c ++++ b/profiles/audio/a2dp.c +@@ -3769,6 +3769,9 @@ static struct btd_profile a2dp_source_profile = { + + .adapter_probe = a2dp_sink_server_probe, + .adapter_remove = a2dp_sink_server_remove, ++ ++ /* Connect source after sink, to prefer sink when conflicting */ ++ .after_services = BTD_PROFILE_UUID_CB(NULL, A2DP_SINK_UUID), + }; + + static struct btd_profile a2dp_sink_profile = {