From e15e50c5ee9c0653c9976cc3c141fba41887e50c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Danis?= Date: Tue, 16 Dec 2025 13:29:18 +0100 Subject: [PATCH] spa: bluez: backend-native: Prevent HSP/HFP connection in both directions The HSP and HFP profiles expect that a device function only as an audio gateway or as an headset, which is the normal behavior for a headset, a hands-free car unit or a phone. In case of a desktop, it can perform both functionalities, but there's no interest to get them at the same time as the bidirectional audio is already supported. --- spa/plugins/bluez5/backend-native.c | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spa/plugins/bluez5/backend-native.c b/spa/plugins/bluez5/backend-native.c index b7661fd5b..5c4a2b785 100644 --- a/spa/plugins/bluez5/backend-native.c +++ b/spa/plugins/bluez5/backend-native.c @@ -3401,6 +3401,43 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag } spa_bt_device_add_profile(d, profile); + /* Prevent to connect HSP/HFP in both directions, i.e. HS->AG and AG->HS. + * This may only occur when connecting to a device which provides both + * HS and AG which should not be the case with headsets and phones. */ + spa_list_for_each(rfcomm, &backend->rfcomm_list, link) { + if (spa_streq(rfcomm->device->address, d->address) && + spa_streq(rfcomm->device->adapter->address, d->adapter->address)) { + bool connected = false; + + switch (profile) { + case SPA_BT_PROFILE_HFP_HF: + if (rfcomm->profile == SPA_BT_PROFILE_HFP_AG) + connected = true; + break; + case SPA_BT_PROFILE_HFP_AG: + if (rfcomm->profile == SPA_BT_PROFILE_HFP_HF) + connected = true; + break; + case SPA_BT_PROFILE_HSP_HS: + if (rfcomm->profile == SPA_BT_PROFILE_HSP_AG) + connected = true; + break; + case SPA_BT_PROFILE_HSP_AG: + if (rfcomm->profile == SPA_BT_PROFILE_HSP_HS) + connected = true; + break; + default: + spa_log_warn(backend->log, "Unsupported profile: %s", handler); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (connected) { + spa_log_debug(backend->log, "Already connected in the opposite direction"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + } + } + dbus_message_iter_next(&it); dbus_message_iter_get_basic(&it, &fd);