Diff between 8054693b0c5b6b201a262b4db7ddd0a4cb239a5c and 66a83fde5c4932d57e0eb084d35ad1374d331e17

Changed Files

File Additions Deletions Status
profiles/audio/bap.c +39 -168 modified
profiles/audio/bass.c +21 -9 modified
profiles/audio/bass.h +1 -1 modified

Full Patch

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 6acb089..2a194d7 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -1034,13 +1034,6 @@ static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
 	}
 }
 
-static void print_ltv(size_t i, uint8_t l, uint8_t t, uint8_t *v,
-		void *user_data)
-{
-	util_debug(user_data, NULL, "CC #%zu: l:%u t:%u", i, l, t);
-	util_hexdump(' ', v, l, user_data, NULL);
-}
-
 void bap_qos_to_iso_qos(struct bt_bap_qos *bap_qos,
 				struct bt_iso_qos *iso_qos)
 {
@@ -1093,15 +1086,16 @@ void bap_iso_qos_to_bap_qos(struct bt_iso_qos *iso_qos,
 }
 
 static void create_stream_for_bis(struct bap_data *bap_data,
-		struct bt_bap_pac *lpac, struct bt_iso_qos *qos,
+		struct bt_bap_pac *lpac, struct bt_bap_qos *qos,
 		struct iovec *caps, struct iovec *meta, char *path)
 {
 	struct bap_setup *setup;
 
 	setup = setup_new(NULL);
+	setup->qos = *qos;
 
-	/* Create BAP QoS structure */
-	bap_iso_qos_to_bap_qos(qos, &setup->qos);
+	/* Create an internal copy for bcode */
+	setup->qos.bcast.bcode = util_iov_dup(qos->bcast.bcode, 1);
 
 	queue_push_tail(bap_data->bcast_snks, setup);
 
@@ -1116,170 +1110,37 @@ static void create_stream_for_bis(struct bap_data *bap_data,
 			NULL, NULL);
 }
 
-static bool parse_base(struct bap_data *bap_data, struct bt_iso_base *base,
-		struct bt_iso_qos *qos, util_debug_func_t func)
+static void bis_handler(uint8_t bis, uint8_t sgrp, struct iovec *caps,
+	struct iovec *meta, struct bt_bap_qos *qos, void *user_data)
 {
-	struct iovec iov = {
-		.iov_base = base->base,
-		.iov_len = base->base_len,
-	};
-	uint32_t pres_delay;
-	uint8_t num_subgroups;
-	bool ret = true;
-
-	util_debug(func, NULL, "BASE len: %ld", iov.iov_len);
-
-	if (!util_iov_pull_le24(&iov, &pres_delay))
-		return false;
-	util_debug(func, NULL, "PresentationDelay: %d", pres_delay);
-
-	if (!util_iov_pull_u8(&iov, &num_subgroups))
-		return false;
-	util_debug(func, NULL, "Number of Subgroups: %d", num_subgroups);
-
-	/* Loop subgroups */
-	for (int idx = 0; idx < num_subgroups; idx++) {
-		uint8_t num_bis;
-		struct bt_bap_codec codec;
-		struct iovec *l2_caps = NULL;
-		struct iovec *meta = NULL;
-
-		util_debug(func, NULL, "Subgroup #%d", idx);
-
-		if (!util_iov_pull_u8(&iov, &num_bis)) {
-			ret = false;
-			goto fail;
-		}
-		util_debug(func, NULL, "Number of BISes: %d", num_bis);
-
-		memcpy(&codec,
-				util_iov_pull_mem(&iov,
-						sizeof(struct bt_bap_codec)),
-				sizeof(struct bt_bap_codec));
-		util_debug(func, NULL, "Codec: ID %d CID 0x%2.2x VID 0x%2.2x",
-				codec.id, codec.cid, codec.vid);
-
-		/* Level 2 */
-		/* Read Codec Specific Configuration */
-		l2_caps = new0(struct iovec, 1);
-		if (!util_iov_pull_u8(&iov, (void *)&l2_caps->iov_len)) {
-			ret = false;
-			goto group_fail;
-		}
-
-		util_iov_memcpy(l2_caps, util_iov_pull_mem(&iov,
-				l2_caps->iov_len),
-				l2_caps->iov_len);
-
-		/* Print Codec Specific Configuration */
-		util_debug(func, NULL, "CC len: %ld", l2_caps->iov_len);
-		util_ltv_foreach(l2_caps->iov_base, l2_caps->iov_len, NULL,
-				print_ltv, func);
-
-		/* Read Metadata */
-		meta = new0(struct iovec, 1);
-		if (!util_iov_pull_u8(&iov, (void *)&meta->iov_len)) {
-			ret = false;
-			goto group_fail;
-		}
-
-		util_iov_memcpy(meta,
-				util_iov_pull_mem(&iov, meta->iov_len),
-				meta->iov_len);
-
-		/* Print Metadata */
-		util_debug(func, NULL, "Metadata len: %i",
-				(uint8_t)meta->iov_len);
-		util_hexdump(' ', meta->iov_base, meta->iov_len, func, NULL);
-
-		/* Level 3 */
-		for (; num_bis; num_bis--) {
-			uint8_t bis_index;
-			struct iovec *l3_caps;
-			struct iovec *merged_caps;
-			struct bt_bap_pac *matched_lpac;
-			char *path;
-			int err;
-
-			if (!util_iov_pull_u8(&iov, &bis_index)) {
-				ret = false;
-				goto group_fail;
-			}
-
-			util_debug(func, NULL, "BIS #%d", bis_index);
-			err = asprintf(&path, "%s/bis%d",
-					device_get_path(bap_data->device),
-					bis_index);
-			if (err < 0)
-				continue;
-
-			/* Read Codec Specific Configuration */
-			l3_caps = new0(struct iovec, 1);
-			if (!util_iov_pull_u8(&iov,
-						(void *)&l3_caps->iov_len)) {
-				free(l3_caps);
-				free(path);
-				ret = false;
-				goto group_fail;
-			}
-
-			util_iov_memcpy(l3_caps,
-					util_iov_pull_mem(&iov,
-							l3_caps->iov_len),
-					l3_caps->iov_len);
-
-			/* Print Codec Specific Configuration */
-			util_debug(func, NULL, "CC Len: %d",
-					(uint8_t)l3_caps->iov_len);
-			util_ltv_foreach(l3_caps->iov_base,
-					l3_caps->iov_len, NULL, print_ltv,
-					func);
-
-			merged_caps = bt_bap_merge_caps(l2_caps, l3_caps);
-			if (!merged_caps) {
-				free(path);
-				continue;
-			}
-
-			bass_add_stream(bap_data->device, meta, merged_caps,
-						qos, idx, bis_index);
-
-			if (!bass_check_bis(bap_data->device, bis_index)) {
-				/* If this Broadcast Sink is acting as a Scan
-				 * Delegator, only attempt to create streams
-				 * for the BISes required by the peer Broadcast
-				 * Assistant.
-				 */
-				continue;
-			}
+	struct bap_data *data = user_data;
+	struct bt_bap_pac *lpac;
+	char *path;
 
-			/* Check if this BIS matches any local PAC */
-			bt_bap_verify_bis(bap_data->bap, bis_index,
-					merged_caps, &matched_lpac);
+	bass_add_stream(data->device, meta, caps, qos, sgrp, bis);
 
-			if (matched_lpac == NULL) {
-				free(path);
-				continue;
-			}
+	if (!bass_check_bis(data->device, bis))
+		/* If this Broadcast Sink is acting as a Scan
+		 * Delegator, only attempt to create streams
+		 * for the BISes required by the peer Broadcast
+		 * Assistant.
+		 */
+		return;
 
-			create_stream_for_bis(bap_data, matched_lpac, qos,
-					merged_caps, meta, path);
-		}
+	/* Check if this BIS matches any local PAC */
+	bt_bap_verify_bis(data->bap, bis,
+			caps, &lpac);
 
-group_fail:
-		if (l2_caps != NULL)
-			free(l2_caps);
-		if (meta != NULL)
-			free(meta);
-		if (!ret)
-			break;
-	}
+	if (!lpac)
+		return;
 
-fail:
-	if (!ret)
-		util_debug(func, NULL, "Unable to parse Base");
+	if (asprintf(&path, "%s/bis%d",
+			device_get_path(data->device),
+			bis) < 0)
+		return;
 
-	return ret;
+	create_stream_for_bis(data, lpac, qos,
+			caps, meta, path);
 }
 
 static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
@@ -1290,6 +1151,8 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
 	struct bap_data *data = btd_service_get_user_data(req->data.service);
 	struct bt_iso_base base;
 	struct bt_iso_qos qos;
+	struct iovec iov;
+	struct bt_bap_qos bap_qos = {0};
 
 	DBG("BIG Info received");
 
@@ -1329,7 +1192,15 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
 	/* Analyze received BASE data and create remote media endpoints for each
 	 * BIS matching our capabilities
 	 */
-	parse_base(data, &base, &qos, bap_debug);
+	iov.iov_base = base.base;
+	iov.iov_len = base.base_len;
+
+	/* Create BAP QoS structure */
+	bap_iso_qos_to_bap_qos(&qos, &bap_qos);
+
+	bt_bap_parse_base(&iov, &bap_qos, bap_debug, bis_handler, data);
+
+	util_iov_free(bap_qos.bcast.bcode, 1);
 
 	service_set_connecting(req->data.service);
 
diff --git a/profiles/audio/bass.c b/profiles/audio/bass.c
index 6237f5a..d3b35f6 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
@@ -92,7 +92,7 @@ struct bass_assistant {
 	uint8_t sgrp;
 	uint8_t bis;
 	uint32_t bid;
-	struct bt_iso_qos qos;
+	struct bt_bap_qos qos;
 	struct iovec *meta;
 	struct iovec *caps;
 	enum assistant_state state;
@@ -399,8 +399,8 @@ static int assistant_parse_qos(struct bass_assistant *assistant,
 				return -EINVAL;
 			}
 
-			memcpy(assistant->qos.bcast.bcode, iov.iov_base,
-								iov.iov_len);
+			util_iov_free(assistant->qos.bcast.bcode, 1);
+			assistant->qos.bcast.bcode = util_iov_dup(&iov, 1);
 
 			return 0;
 		}
@@ -592,7 +592,12 @@ static gboolean get_qos(const GDBusPropertyTable *property,
 {
 	struct bass_assistant *assistant = data;
 	DBusMessageIter dict;
-	uint8_t *bcode = assistant->qos.bcast.bcode;
+	uint8_t arr[BT_BASS_BCAST_CODE_SIZE] = {0};
+	uint8_t *bcode = arr;
+
+	if (assistant->qos.bcast.bcode)
+		memcpy(arr, assistant->qos.bcast.bcode->iov_base,
+						BT_BASS_BCAST_CODE_SIZE);
 
 	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
 					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -648,7 +653,7 @@ static void src_ad_search_bid(void *data, void *user_data)
 
 static struct bass_assistant *assistant_new(struct btd_adapter *adapter,
 		struct btd_device *device, struct bass_data *data,
-		uint8_t sgrp, uint8_t bis, struct bt_iso_qos *qos,
+		uint8_t sgrp, uint8_t bis, struct bt_bap_qos *qos,
 		struct iovec *meta, struct iovec *caps)
 {
 	struct bass_assistant *assistant;
@@ -666,6 +671,10 @@ static struct bass_assistant *assistant_new(struct btd_adapter *adapter,
 	assistant->sgrp = sgrp;
 	assistant->bis = bis;
 	assistant->qos = *qos;
+
+	/* Create an internal copy for bcode */
+	assistant->qos.bcast.bcode = util_iov_dup(qos->bcast.bcode, 1);
+
 	assistant->meta = util_iov_dup(meta, 1);
 	assistant->caps = util_iov_dup(caps, 1);
 
@@ -689,7 +698,7 @@ static struct bass_assistant *assistant_new(struct btd_adapter *adapter,
 }
 
 void bass_add_stream(struct btd_device *device, struct iovec *meta,
-			struct iovec *caps, struct bt_iso_qos *qos,
+			struct iovec *caps, struct bt_bap_qos *qos,
 			uint8_t sgrp, uint8_t bis)
 {
 	const struct queue_entry *entry;
@@ -998,7 +1007,7 @@ static void bass_attached(struct bt_bass *bass, void *user_data)
 static void bass_handle_bcode_req(struct bass_assistant *assistant, int id)
 {
 	struct bt_bass_bcast_audio_scan_cp_hdr hdr;
-	struct bt_bass_set_bcast_code_params params;
+	struct bt_bass_set_bcast_code_params params = {0};
 	struct iovec iov = {0};
 	int err;
 
@@ -1007,8 +1016,11 @@ static void bass_handle_bcode_req(struct bass_assistant *assistant, int id)
 	hdr.op = BT_BASS_SET_BCAST_CODE;
 
 	params.id = id;
-	memcpy(params.bcast_code, assistant->qos.bcast.bcode,
-					BT_BASS_BCAST_CODE_SIZE);
+
+	if (assistant->qos.bcast.bcode)
+		memcpy(params.bcast_code,
+			assistant->qos.bcast.bcode->iov_base,
+			BT_BASS_BCAST_CODE_SIZE);
 
 	iov.iov_base = malloc0(sizeof(params));
 	if (!iov.iov_base)
diff --git a/profiles/audio/bass.h b/profiles/audio/bass.h
index 2573463..8459491 100644
--- a/profiles/audio/bass.h
+++ b/profiles/audio/bass.h
@@ -8,7 +8,7 @@
  */
 
 void bass_add_stream(struct btd_device *device, struct iovec *meta,
-			struct iovec *caps, struct bt_iso_qos *qos,
+			struct iovec *caps, struct bt_bap_qos *qos,
 			uint8_t sgrp, uint8_t bis);
 void bass_remove_stream(struct btd_device *device);