@@ -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: