The BAP Unicast Client stream configuration flow has two steps, Config Codec and Config QoS. Previously both the ASE Codec & QoS configuration was obtained from the local PAC via bt_bap_pac_ops.select, but the information what the BAP Server supports becomes available only after Config Codec completes successfully. So the single-step configuration doesn't work out correctly in the API. Split out the QoS configuration to a separate PAC operation. Rename "select" to "select_codec", and add select_qos and bt_bap_stream_select_qos for the QoS configuration step. Also add bt_bap_stream_get_lpac/rpac, which will be needed in the QoS configuration callback. --- src/shared/bap.c | 37 ++++++++++++++++++++++++++++++++----- src/shared/bap.h | 23 +++++++++++++++++------ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/shared/bap.c b/src/shared/bap.c index 13bbcf793..6155b8640 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -4617,17 +4617,34 @@ static bool match_pac(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, return false; } -int bt_bap_select(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, - bt_bap_pac_select_t func, void *user_data) +int bt_bap_select_codec(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, + bt_bap_pac_select_codec_t func, void *user_data) { if (!lpac || !rpac || !func) return -EINVAL; - if (!lpac->ops || !lpac->ops->select) + if (!lpac->ops || !lpac->ops->select_codec) return -EOPNOTSUPP; - lpac->ops->select(lpac, rpac, &rpac->qos, - func, user_data, lpac->user_data); + lpac->ops->select_codec(lpac, rpac, func, user_data, lpac->user_data); + + return 0; +} + +int bt_bap_stream_select_qos(struct bt_bap_stream *stream, + bt_bap_pac_select_qos_t func, void *user_data) +{ + struct bt_bap_pac *lpac = stream->lpac; + struct bt_bap_pac *rpac = stream->rpac; + + if (!lpac || !rpac || !func) + return -EINVAL; + + if (!lpac->ops || !lpac->ops->select_qos) + return -EOPNOTSUPP; + + lpac->ops->select_qos(stream, &rpac->qos, func, user_data, + lpac->user_data); return 0; } @@ -5124,6 +5141,16 @@ uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream) return stream->bap->ldb->pacs->source_loc_value; } +struct bt_bap_pac *bt_bap_stream_get_lpac(struct bt_bap_stream *stream) +{ + return stream->lpac; +} + +struct bt_bap_pac *bt_bap_stream_get_rpac(struct bt_bap_stream *stream) +{ + return stream->rpac; +} + struct iovec *bt_bap_stream_get_config(struct bt_bap_stream *stream) { if (!stream) diff --git a/src/shared/bap.h b/src/shared/bap.h index 23edbf4c6..d8fae0ef8 100644 --- a/src/shared/bap.h +++ b/src/shared/bap.h @@ -104,12 +104,15 @@ typedef void (*bt_bap_pac_func_t)(struct bt_bap_pac *pac, void *user_data); typedef bool (*bt_bap_pac_foreach_t)(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, void *user_data); -typedef void (*bt_bap_pac_select_t)(struct bt_bap_pac *pac, int err, +typedef void (*bt_bap_pac_select_codec_t)(struct bt_bap_pac *pac, int err, struct iovec *caps, struct iovec *metadata, struct bt_bap_qos *qos, void *user_data); typedef void (*bt_bap_pac_config_t)(struct bt_bap_stream *stream, int err); +typedef void (*bt_bap_pac_select_qos_t)(struct bt_bap_stream *stream, + int err, struct bt_bap_qos *qos, + void *user_data); typedef void (*bt_bap_state_func_t)(struct bt_bap_stream *stream, uint8_t old_state, uint8_t new_state, void *user_data); @@ -150,9 +153,12 @@ struct bt_bap_pac *bt_bap_add_pac(struct gatt_db *db, const char *name, struct iovec *metadata); struct bt_bap_pac_ops { - int (*select)(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, - struct bt_bap_pac_qos *qos, - bt_bap_pac_select_t cb, void *cb_data, void *user_data); + int (*select_codec)(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, + bt_bap_pac_select_codec_t cb, void *cb_data, + void *user_data); + int (*select_qos)(struct bt_bap_stream *stream, + struct bt_bap_pac_qos *qos, bt_bap_pac_select_qos_t cb, + void *cb_data, void *user_data); int (*config)(struct bt_bap_stream *stream, struct iovec *cfg, struct bt_bap_qos *qos, bt_bap_pac_config_t cb, void *user_data); @@ -233,8 +239,8 @@ void bt_bap_pac_set_user_data(struct bt_bap_pac *pac, void *user_data); void *bt_bap_pac_get_user_data(struct bt_bap_pac *pac); /* Stream related functions */ -int bt_bap_select(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, - bt_bap_pac_select_t func, void *user_data); +int bt_bap_select_codec(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, + bt_bap_pac_select_codec_t func, void *user_data); struct bt_bap_stream *bt_bap_stream_new(struct bt_bap *bap, struct bt_bap_pac *lpac, @@ -249,6 +255,9 @@ bool bt_bap_stream_set_user_data(struct bt_bap_stream *stream, void *user_data); void *bt_bap_stream_get_user_data(struct bt_bap_stream *stream); +int bt_bap_stream_select_qos(struct bt_bap_stream *stream, + bt_bap_pac_select_qos_t func, void *user_data); + unsigned int bt_bap_stream_config(struct bt_bap_stream *stream, struct bt_bap_qos *pqos, struct iovec *data, @@ -293,6 +302,8 @@ uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream); struct iovec *bt_bap_stream_get_config(struct bt_bap_stream *stream); struct bt_bap_qos *bt_bap_stream_get_qos(struct bt_bap_stream *stream); struct iovec *bt_bap_stream_get_metadata(struct bt_bap_stream *stream); +struct bt_bap_pac *bt_bap_stream_get_lpac(struct bt_bap_stream *stream); +struct bt_bap_pac *bt_bap_stream_get_rpac(struct bt_bap_stream *stream); struct io *bt_bap_stream_get_io(struct bt_bap_stream *stream); bool bt_bap_match_bcast_sink_stream(const void *data, const void *user_data); -- 2.41.0