Diff between bd2f851be865e8c1718e6397f390dd000f8121fd and ead7f4028a1033d02e675e23c653f63218027349

Changed Files

File Additions Deletions Status
profiles/audio/bap.c +86 -0 modified

Full Patch

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index f382b43..77df945 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -905,6 +905,83 @@ static void setup_free(void *data)
 	free(setup);
 }
 
+static bool match_io_qos(const struct bt_bap_io_qos *io_qos,
+		const struct bt_bap_io_qos *match)
+{
+	if (io_qos->interval != match->interval)
+		return false;
+
+	if (io_qos->latency != match->latency)
+		return false;
+
+	if (io_qos->sdu != match->sdu)
+		return false;
+
+	if (io_qos->phy != match->phy)
+		return false;
+
+	if (io_qos->rtn != match->rtn)
+		return false;
+
+	return true;
+}
+
+static bool match_bcast_qos(const struct bt_bap_bcast_qos *qos,
+		const struct bt_bap_bcast_qos *match)
+{
+	if (qos->sync_factor != match->sync_factor)
+		return false;
+
+	if (qos->packing != match->packing)
+		return false;
+
+	if (qos->framing != match->framing)
+		return false;
+
+	if (qos->encryption != match->encryption)
+		return false;
+
+	if (qos->encryption && util_iov_memcmp(qos->bcode, match->bcode))
+		return false;
+
+	if (qos->options != match->options)
+		return false;
+
+	if (qos->skip != match->skip)
+		return false;
+
+	if (qos->sync_timeout != match->sync_timeout)
+		return false;
+
+	if (qos->sync_cte_type != match->sync_cte_type)
+		return false;
+
+	if (qos->mse != match->mse)
+		return false;
+
+	if (qos->timeout != match->timeout)
+		return false;
+
+	if (qos->pa_sync != match->pa_sync)
+		return false;
+
+	return match_io_qos(&qos->io_qos, &match->io_qos);
+}
+
+static bool setup_mismatch_qos(const void *data, const void *user_data)
+{
+	const struct bap_setup *setup = data;
+	const struct bap_setup *match = user_data;
+
+	/* Match setups that are part of the same BIG */
+	if (setup == match ||
+		setup->qos.bcast.big == BT_ISO_QOS_BIG_UNSET ||
+		setup->qos.bcast.big != match->qos.bcast.big)
+		return false;
+
+	return !match_bcast_qos(&setup->qos.bcast, &match->qos.bcast);
+}
+
 static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -937,6 +1014,15 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
 		return btd_error_invalid_args(msg);
 	}
 
+	if (bt_bap_pac_get_type(ep->lpac) == BT_BAP_BCAST_SOURCE)
+		/* All streams in a BIG should have the same QoS.
+		 * Check that the new configuration matches previous ones.
+		 */
+		if (queue_find(setup->ep->setups, setup_mismatch_qos, setup)) {
+			setup_free(setup);
+			return btd_error_invalid_args(msg);
+		}
+
 	setup->stream = bt_bap_stream_new(ep->data->bap, ep->lpac, ep->rpac,
 						&setup->qos, setup->caps);
 	bt_bap_stream_set_user_data(setup->stream, ep->path);