From 511bafb4361ee6225b69e59823e982140d595f63 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Mon, 8 Mar 2021 23:39:01 +0200 Subject: [PATCH] bluez5: release transports on profile change SCO transports have timer-delayed release, but they need to be released immediately when changing profiles to close connections before switching to A2DP. --- spa/plugins/bluez5/bluez5-dbus.c | 22 ++++++++++++++++++++++ spa/plugins/bluez5/bluez5-device.c | 2 ++ spa/plugins/bluez5/defs.h | 1 + 3 files changed, 25 insertions(+) diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 60604f1da..b7af690b2 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -1184,6 +1184,28 @@ int spa_bt_transport_release(struct spa_bt_transport *transport) return res; } +static int spa_bt_transport_release_now(struct spa_bt_transport *transport) +{ + int res; + + if (transport->acquire_refcount == 0) + return 0; + + spa_bt_transport_stop_release_timer(transport); + res = spa_bt_transport_impl(transport, release, 0); + if (res >= 0) + transport->acquire_refcount = 0; + + return res; +} + +int spa_bt_device_release_transports(struct spa_bt_device *device) +{ + struct spa_bt_transport *t; + spa_list_for_each(t, &device->transport_list, device_link) + spa_bt_transport_release_now(t); +} + static void spa_bt_transport_release_timer_event(struct spa_source *source) { struct spa_bt_transport *transport = source->data; diff --git a/spa/plugins/bluez5/bluez5-device.c b/spa/plugins/bluez5/bluez5-device.c index 99c910d66..b6ac9286e 100644 --- a/spa/plugins/bluez5/bluez5-device.c +++ b/spa/plugins/bluez5/bluez5-device.c @@ -270,6 +270,8 @@ static int set_profile(struct impl *this, uint32_t profile, const struct a2dp_co emit_remove_nodes(this); + spa_bt_device_release_transports(this->bt_dev); + this->profile = profile; this->selected_a2dp_codec = a2dp_codec; diff --git a/spa/plugins/bluez5/defs.h b/spa/plugins/bluez5/defs.h index e5b9cad1f..ce471a22b 100644 --- a/spa/plugins/bluez5/defs.h +++ b/spa/plugins/bluez5/defs.h @@ -404,6 +404,7 @@ int spa_bt_device_check_profiles(struct spa_bt_device *device, bool force); int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec **codecs); bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec); const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count); +int spa_bt_device_release_transports(struct spa_bt_device *device); #define spa_bt_device_emit(d,m,v,...) spa_hook_list_call(&(d)->listener_list, \ struct spa_bt_device_events, \