diff mbox series

[RFC,BlueZ,8/9] bap: do not try QoS before links are updated & io created

Message ID 643267ffb9f4c4b2b7b5e36b551f890f3e9e81c4.1740844617.git.pav@iki.fi (mailing list archive)
State New
Headers show
Series BAP stream reconfiguration | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success

Commit Message

Pauli Virtanen March 1, 2025, 3:57 p.m. UTC
It's not possible to QoS in config_cb, even if stream is in Config
state, because stream->io may not exist and stream links are not yet
updated. The stream links are updated only before bap_state(), so the
completion of config has to be handled only there.

Wait for both events to complete before proceeding to QoS.
---
 profiles/audio/bap.c | 80 +++++++++++++++++++++++---------------------
 1 file changed, 42 insertions(+), 38 deletions(-)
diff mbox series

Patch

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 46512a7f3..da1f9feb1 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -83,6 +83,7 @@  struct bap_setup {
 	struct iovec *base;
 	struct future *qos_done;
 	struct future *close_done;
+	bool config_done;
 	void (*destroy)(struct bap_setup *setup);
 };
 
@@ -851,32 +852,49 @@  static void qos_cb(struct bt_bap_stream *stream, uint8_t code, uint8_t reason,
 	future_clear(&setup->qos_done, code ? EIO : 0, "Unable to configure");
 }
 
+static void setup_create_io(struct bap_data *data, struct bap_setup *setup,
+				struct bt_bap_stream *stream, int defer);
+
+static void setup_qos(struct bap_setup *setup)
+{
+	struct bap_data *data = setup->ep->data;
+	struct bt_bap_stream *stream = setup->stream;
+
+	if (setup->id || !stream)
+		return;
+
+	setup_create_io(data, setup, stream, true);
+	if (!setup->io) {
+		error("Unable to create io");
+		if (bt_bap_stream_get_state(stream) !=
+						BT_BAP_STREAM_STATE_RELEASING)
+			bt_bap_stream_release(stream, NULL, NULL);
+		return;
+	}
+
+	/* Wait QoS response to respond */
+	setup->id = bt_bap_stream_qos(stream, &setup->qos, qos_cb, setup);
+	if (!setup->id) {
+		error("Failed to Configure QoS");
+		bt_bap_stream_release(stream, NULL, NULL);
+	}
+}
+
 static void config_cb(struct bt_bap_stream *stream,
 					uint8_t code, uint8_t reason,
 					void *user_data)
 {
 	struct bap_setup *setup = user_data;
+	const char *err_msg = "Unable to configure";
 
 	DBG("stream %p code 0x%02x reason 0x%02x", stream, code, reason);
 
 	setup->id = 0;
 
-	if (!code) {
-		/* Check state is already set to config then proceed to qos */
-		if (bt_bap_stream_get_state(stream) ==
-					BT_BAP_STREAM_STATE_CONFIG) {
-			setup->id = bt_bap_stream_qos(stream, &setup->qos,
-							qos_cb, setup);
-			if (!setup->id) {
-				error("Failed to Configure QoS");
-				bt_bap_stream_release(stream, NULL, NULL);
-			}
-		}
-
-		return;
-	}
-
-	future_clear(&setup->qos_done, EIO, "Unable to configure");
+	if (code)
+		future_clear(&setup->qos_done, EIO, err_msg);
+	else if (setup->config_done)
+		setup_qos(setup);
 }
 
 static void setup_io_close(void *data, void *user_data)
@@ -1128,6 +1146,8 @@  static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
 		return btd_error_invalid_args(msg);
 	}
 
+	setup->config_done = false;
+
 	if (setup->metadata && setup->metadata->iov_len)
 		bt_bap_stream_metadata(setup->stream, setup->metadata, NULL,
 								NULL);
@@ -1655,6 +1675,8 @@  static void setup_config(void *data, void *user_data)
 		return;
 	}
 
+	setup->config_done = false;
+
 	if (setup->metadata && setup->metadata->iov_len)
 		bt_bap_stream_metadata(setup->stream, setup->metadata, NULL,
 								NULL);
@@ -2086,9 +2108,6 @@  static bool is_cig_busy(struct bap_data *data, uint8_t cig)
 	return queue_find(sessions, cig_busy_session, &info);
 }
 
-static void setup_create_io(struct bap_data *data, struct bap_setup *setup,
-				struct bt_bap_stream *stream, int defer);
-
 static gboolean setup_io_recreate(void *user_data)
 {
 	struct bap_setup *setup = user_data;
@@ -2473,25 +2492,10 @@  static void bap_state(struct bt_bap_stream *stream, uint8_t old_state,
 			queue_remove(data->streams, stream);
 		break;
 	case BT_BAP_STREAM_STATE_CONFIG:
-		if (setup && !setup->id) {
-			setup_create_io(data, setup, stream, true);
-			if (!setup->io) {
-				error("Unable to create io");
-				if (old_state != BT_BAP_STREAM_STATE_RELEASING)
-					bt_bap_stream_release(stream, NULL,
-								NULL);
-				return;
-			}
-
-			/* Wait QoS response to respond */
-			setup->id = bt_bap_stream_qos(stream,
-							&setup->qos,
-							qos_cb,	setup);
-			if (!setup->id) {
-				error("Failed to Configure QoS");
-				bt_bap_stream_release(stream,
-							NULL, NULL);
-			}
+		if (setup) {
+			setup->config_done = true;
+			if (!setup->id)
+				setup_qos(setup);
 		}
 		break;
 	case BT_BAP_STREAM_STATE_QOS: