summaryrefslogtreecommitdiff
path: root/profiles
diff options
context:
space:
mode:
authorFrédéric Danis <frederic.danis@collabora.com>2022-08-24 17:05:19 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-08-29 12:44:47 -0700
commit34e8c20d488f8f596857813b615f81355ab70c47 (patch)
tree9ae3117e96400181e4e77d53d9c32acb7e941185 /profiles
parent9e298f8402d9e7aabce491ad9700f9ca267335fb (diff)
downloadbluez-34e8c20d488f8f596857813b615f81355ab70c47.tar.gz
profiles: Allow linked transport to release the fd
Multiple transports can be linked when using LE Audio BAP. In this case only one transport is used to Acquire the file descriptor which will be shared by all linked transports. In the same way, any transport can Release the file descriptor.
Diffstat (limited to 'profiles')
-rw-r--r--profiles/audio/transport.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 47db2a802..f36e609cb 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -281,9 +281,26 @@ static void media_owner_free(struct media_owner *owner)
g_free(owner);
}
+static void linked_transport_remove_owner(void *data, void *user_data)
+{
+ struct bt_bap_stream *stream = data;
+ struct media_owner *owner = user_data;
+ struct media_transport *transport;
+
+ transport = find_transport_by_bap_stream(stream);
+ if (!transport) {
+ error("Unable to find transport");
+ return;
+ }
+
+ DBG("Transport %s Owner %s", transport->path, owner->name);
+ transport->owner = NULL;
+}
+
static void media_transport_remove_owner(struct media_transport *transport)
{
struct media_owner *owner = transport->owner;
+ struct bap_transport *bap = transport->data;
if (!transport->owner)
return;
@@ -295,6 +312,9 @@ static void media_transport_remove_owner(struct media_transport *transport)
media_request_reply(owner->pending, EIO);
transport->owner = NULL;
+ if (bap->linked)
+ queue_foreach(bt_bap_stream_io_get_links(bap->stream),
+ linked_transport_remove_owner, owner);
if (owner->watch)
g_dbus_remove_watch(btd_get_dbus_connection(), owner->watch);
@@ -452,11 +472,34 @@ static void media_owner_exit(DBusConnection *connection, void *user_data)
media_transport_remove_owner(owner->transport);
}
+static void linked_transport_set_owner(void *data, void *user_data)
+{
+ struct bt_bap_stream *stream = data;
+ struct media_owner *owner = user_data;
+ struct media_transport *transport;
+
+ transport = find_transport_by_bap_stream(stream);
+ if (!transport) {
+ error("Unable to find transport");
+ return;
+ }
+
+ DBG("Transport %s Owner %s", transport->path, owner->name);
+ transport->owner = owner;
+}
+
static void media_transport_set_owner(struct media_transport *transport,
struct media_owner *owner)
{
+ struct bap_transport *bap = transport->data;
+
DBG("Transport %s Owner %s", transport->path, owner->name);
transport->owner = owner;
+
+ if (bap->linked)
+ queue_foreach(bt_bap_stream_io_get_links(bap->stream),
+ linked_transport_set_owner, owner);
+
owner->transport = transport;
owner->watch = g_dbus_add_disconnect_watch(btd_get_dbus_connection(),
owner->name,