[PATCH BlueZ v2 7/8] bap: Fix not waiting Endpoint.SelectProperties

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

If there are multiple Endpoint.SelectProperties wait them to complete
before attempting to proceed to configure a stream otherwise streams
may not be linked properly and may end up creating multiple CIS
instead.
---
 profiles/audio/bap.c   | 58 +++++++++++++++++++++++++++++++-----------
 profiles/audio/media.c | 27 ++++++++------------
 2 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 9cee9fd030da..f28843ae6b38 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -83,6 +83,7 @@ struct bap_data {
 	struct queue *snks;
 	struct queue *streams;
 	GIOChannel *listen_io;
+	int selecting;
 };
 
 static struct queue *sessions;
@@ -503,7 +504,8 @@ static void ep_free(void *data)
 
 	bap_io_close(ep);
 
-	free(ep->caps);
+	util_iov_free(ep->caps, 1);
+	util_iov_free(ep->metadata, 1);
 	free(ep->path);
 	free(ep);
 }
@@ -566,20 +568,14 @@ static struct bap_ep *ep_register(struct btd_service *service,
 	return ep;
 }
 
-static void select_cb(struct bt_bap_pac *pac, int err, struct iovec *caps,
-				struct iovec *metadata, struct bt_bap_qos *qos,
-				void *user_data)
+static void bap_config(void *data, void *user_data)
 {
-	struct bap_ep *ep = user_data;
+	struct bap_ep *ep = data;
 
-	if (err) {
-		error("err %d", err);
+	DBG("ep %p caps %p metadata %p", ep, ep->caps, ep->metadata);
+
+	if (!ep->caps)
 		return;
-	}
-
-	ep->caps = caps;
-	ep->metadata = metadata;
-	ep->qos = *qos;
 
 	/* TODO: Check if stream capabilities match add support for Latency
 	 * and PHY.
@@ -594,13 +590,43 @@ static void select_cb(struct bt_bap_pac *pac, int err, struct iovec *caps,
 
 	if (!ep->stream) {
 		DBG("Unable to config stream");
-		free(ep->caps);
+		util_iov_free(ep->caps, 1);
 		ep->caps = NULL;
+		util_iov_free(ep->metadata, 1);
+		ep->metadata = NULL;
 	}
 
 	bt_bap_stream_set_user_data(ep->stream, ep->path);
 }
 
+static void select_cb(struct bt_bap_pac *pac, int err, struct iovec *caps,
+				struct iovec *metadata, struct bt_bap_qos *qos,
+				void *user_data)
+{
+	struct bap_ep *ep = user_data;
+
+	if (err) {
+		error("err %d", err);
+		return;
+	}
+
+	ep->caps = util_iov_dup(caps, 1);
+
+	if (metadata && metadata->iov_base && metadata->iov_len)
+		ep->metadata = util_iov_dup(metadata, 1);
+
+	ep->qos = *qos;
+
+	DBG("selecting %d", ep->data->selecting);
+	ep->data->selecting--;
+
+	if (ep->data->selecting)
+		return;
+
+	queue_foreach(ep->data->srcs, bap_config, NULL);
+	queue_foreach(ep->data->snks, bap_config, NULL);
+}
+
 static bool pac_found(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
 							void *user_data)
 {
@@ -616,8 +642,10 @@ static bool pac_found(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
 	}
 
 	/* TODO: Cache LRU? */
-	if (btd_service_is_initiator(service))
-		bt_bap_select(lpac, rpac, select_cb, ep);
+	if (btd_service_is_initiator(service)) {
+		if (!bt_bap_select(lpac, rpac, select_cb, ep))
+			ep->data->selecting++;
+	}
 
 	return true;
 }
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 6947cf96392e..fbb350889564 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -725,24 +725,21 @@ struct pac_select_data {
 	void *user_data;
 };
 
-static int parse_array(DBusMessageIter *iter, struct iovec **iov)
+static int parse_array(DBusMessageIter *iter, struct iovec *iov)
 {
 	DBusMessageIter array;
 
 	if (!iov)
 		return 0;
 
-	if (!(*iov))
-		*iov = new0(struct iovec, 1);
-
 	dbus_message_iter_recurse(iter, &array);
-	dbus_message_iter_get_fixed_array(&array, &(*iov)->iov_base,
-						(int *)&(*iov)->iov_len);
+	dbus_message_iter_get_fixed_array(&array, &iov->iov_base,
+						(int *)&iov->iov_len);
 	return 0;
 }
 
-static int parse_select_properties(DBusMessageIter *props, struct iovec **caps,
-					struct iovec **metadata,
+static int parse_select_properties(DBusMessageIter *props, struct iovec *caps,
+					struct iovec *metadata,
 					struct bt_bap_qos *qos)
 {
 	const char *key;
@@ -845,11 +842,6 @@ static int parse_select_properties(DBusMessageIter *props, struct iovec **caps,
 fail:
 	DBG("Failed parsing %s", key);
 
-	if (*caps) {
-		free(*caps);
-		*caps = NULL;
-	}
-
 	return -EINVAL;
 }
 
@@ -859,7 +851,7 @@ static void pac_select_cb(struct media_endpoint *endpoint, void *ret, int size,
 	struct pac_select_data *data = user_data;
 	DBusMessageIter *iter = ret;
 	int err;
-	struct iovec *caps = NULL, *metadata = NULL;
+	struct iovec caps, meta;
 	struct bt_bap_qos qos;
 
 	if (!ret) {
@@ -881,12 +873,15 @@ static void pac_select_cb(struct media_endpoint *endpoint, void *ret, int size,
 	qos.cig_id = BT_ISO_QOS_CIG_UNSET;
 	qos.cis_id = BT_ISO_QOS_CIS_UNSET;
 
-	err = parse_select_properties(iter, &caps, &metadata, &qos);
+	memset(&caps, 0, sizeof(caps));
+	memset(&meta, 0, sizeof(meta));
+
+	err = parse_select_properties(iter, &caps, &meta, &qos);
 	if (err < 0)
 		DBG("Unable to parse properties");
 
 done:
-	data->cb(data->pac, err, caps, metadata, &qos, data->user_data);
+	data->cb(data->pac, err, &caps, &meta, &qos, data->user_data);
 }
 
 static int pac_select(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
-- 
2.37.3




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux