From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> bt_bap_stream_metadata maybe used before enabling state in which case it will be store in the stream->meta so when processing bt_bap_stream_enable if there is no metadata set use the existing one set in stream->meta. --- src/shared/bap.c | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/shared/bap.c b/src/shared/bap.c index 3fae72d9d8a2..2cc970c0ef91 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -2276,6 +2276,17 @@ static unsigned int bap_ucast_qos(struct bt_bap_stream *stream, return req->id; } +static void bap_stream_get_context(size_t i, uint8_t l, uint8_t t, uint8_t *v, + void *user_data) +{ + bool *found = user_data; + + if (!v) + return; + + *found = true; +} + static unsigned int bap_stream_metadata(struct bt_bap_stream *stream, uint8_t op, struct iovec *data, bt_bap_stream_func_t func, @@ -2284,11 +2295,7 @@ static unsigned int bap_stream_metadata(struct bt_bap_stream *stream, struct iovec iov[2]; struct bt_ascs_metadata meta; struct bt_bap_req *req; - struct metadata { - uint8_t len; - uint8_t type; - uint8_t data[2]; - } ctx = LTV(0x02, 0x01, 0x00); /* Context = Unspecified */ + uint16_t value = cpu_to_le16(0x0001); /* Context = Unspecified */ memset(&meta, 0, sizeof(meta)); @@ -2297,13 +2304,33 @@ static unsigned int bap_stream_metadata(struct bt_bap_stream *stream, iov[0].iov_base = &meta; iov[0].iov_len = sizeof(meta); - if (data) - iov[1] = *data; - else { - iov[1].iov_base = &ctx; - iov[1].iov_len = sizeof(ctx); + if (data) { + util_iov_free(stream->meta, 1); + stream->meta = util_iov_dup(data, 1); } + /* Check if metadata contains an Audio Context */ + if (stream->meta) { + uint8_t type = 0x02; + bool found = false; + + util_ltv_foreach(stream->meta->iov_base, + stream->meta->iov_len, &type, + bap_stream_get_context, &found); + if (!found) + util_ltv_push(stream->meta, sizeof(value), type, + &value); + } + + /* If metadata doesn't contain an Audio Context, add one */ + if (!stream->meta) { + stream->meta = new0(struct iovec, 1); + util_ltv_push(stream->meta, sizeof(value), 0x02, &value); + } + + iov[1].iov_base = stream->meta->iov_base; + iov[1].iov_len = stream->meta->iov_len; + meta.len = iov[1].iov_len; req = bap_req_new(stream, op, iov, 2, func, user_data); -- 2.49.0