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