Bluetooth: Audio: Refactor bt_audio_codec_cfg to flat arrays

Refactor the bt_audio_codec_cfg to use flat arrays to store
metadata and codec specific configurations.

The purpose of this is to make it easier to copy the data
between layers, but also to support non-LTV data for non-LC3
codec configurations.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2023-05-22 15:08:57 +02:00 committed by Carles Cufí
commit 6ccd112c56
50 changed files with 1181 additions and 1824 deletions

View file

@ -307,7 +307,6 @@ static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup,
const struct bt_audio_codec_cfg *codec_cfg;
uint8_t stream_count;
uint8_t bis_index;
uint8_t *start;
uint8_t len;
stream_count = 0;
@ -322,28 +321,15 @@ static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup,
net_buf_simple_add_le16(buf, codec_cfg->cid);
net_buf_simple_add_le16(buf, codec_cfg->vid);
/* Insert codec configuration data in LTV format */
start = net_buf_simple_add(buf, sizeof(len));
net_buf_simple_add_u8(buf, codec_cfg->data_len);
#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
if ((buf->size - buf->len) < codec_cfg->data_len) {
LOG_DBG("No room for config data: %zu", codec_cfg->data_len);
for (int i = 0; i < codec_cfg->data_count; i++) {
const struct bt_data *codec_data = &codec_cfg->data[i].data;
if ((buf->size - buf->len) < (sizeof(codec_data->data_len) +
sizeof(codec_data->type) +
codec_data->data_len)) {
LOG_DBG("No room for codec[%d] with len %u", i, codec_data->data_len);
return false;
}
net_buf_simple_add_u8(buf, codec_data->data_len + sizeof(codec_data->type));
net_buf_simple_add_u8(buf, codec_data->type);
net_buf_simple_add_mem(buf, codec_data->data, codec_data->data_len);
return false;
}
/* Calculate length of codec config data */
len = net_buf_simple_tail(buf) - start - sizeof(len);
/* Update the length field */
*start = len;
net_buf_simple_add_mem(buf, codec_cfg->data, codec_cfg->data_len);
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
if ((buf->size - buf->len) < sizeof(len)) {
LOG_DBG("No room for metadata length");
@ -351,31 +337,21 @@ static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup,
return false;
}
/* Insert codec metadata in LTV format*/
start = net_buf_simple_add(buf, sizeof(len));
for (int i = 0; i < codec_cfg->meta_count; i++) {
const struct bt_data *metadata = &codec_cfg->meta[i].data;
net_buf_simple_add_u8(buf, codec_cfg->meta_len);
if ((buf->size - buf->len) < (sizeof(metadata->data_len) +
sizeof(metadata->type) +
metadata->data_len)) {
LOG_DBG("No room for metadata[%d] with len %u", i, metadata->data_len);
#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
if ((buf->size - buf->len) < codec_cfg->meta_len) {
LOG_DBG("No room for metadata data: %zu", codec_cfg->meta_len);
return false;
}
net_buf_simple_add_u8(buf, metadata->data_len + sizeof(metadata->type));
net_buf_simple_add_u8(buf, metadata->type);
net_buf_simple_add_mem(buf, metadata->data, metadata->data_len);
return false;
}
/* Calculate length of codec config data */
len = net_buf_simple_tail(buf) - start - sizeof(len);
/* Update the length field */
*start = len;
net_buf_simple_add_mem(buf, codec_cfg->meta, codec_cfg->meta_len);
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
/* Create BIS index bitfield */
bis_index = 0;
for (int i = 0; i < stream_count; i++) {
for (uint8_t i = 0U; i < stream_count; i++) {
bis_index++;
if ((buf->size - buf->len) < (sizeof(bis_index) + sizeof(uint8_t))) {
LOG_DBG("No room for BIS[%d] index", i);
@ -391,32 +367,16 @@ static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup,
return false;
}
/* Insert codec configuration data in LTV format */
start = net_buf_simple_add(buf, sizeof(len));
net_buf_simple_add_u8(buf, stream_data[i].data_len);
#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
if ((buf->size - buf->len) < stream_data[i].data_len) {
LOG_DBG("No room for BIS[%u] data: %zu", i, stream_data[i].data_len);
#if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT)
for (size_t j = 0U; j < stream_data[i].data_count; j++) {
const struct bt_data *codec_data = &stream_data[i].data[j].data;
if ((buf->size - buf->len) < (sizeof(codec_data->data_len) +
sizeof(codec_data->type) +
codec_data->data_len)) {
LOG_DBG("No room for BIS [%u] codec[%zu] with len %u", bis_index, j,
codec_data->data_len);
return false;
}
net_buf_simple_add_u8(buf, codec_data->data_len + sizeof(codec_data->type));
net_buf_simple_add_u8(buf, codec_data->type);
net_buf_simple_add_mem(buf, codec_data->data, codec_data->data_len);
return false;
}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT */
/* Calculate length of codec config data */
len = net_buf_simple_tail(buf) - start - sizeof(len);
/* Update the length field */
*start = len;
net_buf_simple_add_mem(buf, stream_data[i].data, stream_data[i].data_len);
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
streams_encoded++;
}
@ -602,34 +562,23 @@ static bool valid_create_param(const struct bt_bap_broadcast_source_create_param
return false;
}
CHECKIF(stream_param->data == NULL && stream_param->data_count != 0) {
CHECKIF(stream_param->data == NULL && stream_param->data_len != 0) {
LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data is "
"NULL with count %zu",
i, j, stream_param->data_count);
"NULL with len %zu",
i, j, stream_param->data_len);
return false;
}
#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT > 0
CHECKIF(stream_param->data_count >
CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT) {
LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data_count too "
"large: %zu/%d",
i, j, stream_param->data_count,
CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT);
#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
CHECKIF(stream_param->data_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE) {
LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data_len too "
"large: %zu > %d",
i, j, stream_param->data_len,
CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE);
return false;
}
for (size_t k = 0U; k < stream_param->data_count; k++) {
CHECKIF(!(bt_audio_valid_codec_data(&stream_param->data[k]))) {
LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data[%zu]"
" invalid",
i, j, k);
return false;
}
}
}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT > 0 */
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
}
return true;
@ -755,14 +704,9 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param *
* only relevant for the broadcast source, and not used
* for unicast or broadcast sink.
*/
(void)memcpy(source->stream_data[stream_count].data,
stream_param->data,
stream_param->data_count * sizeof(*stream_param->data));
source->stream_data[stream_count].data_count = stream_param->data_count;
for (uint8_t k = 0U; k < stream_param->data_count; k++) {
source->stream_data[stream_count].data[k].data.data =
source->stream_data[stream_count].data[k].value;
}
(void)memcpy(source->stream_data[stream_count].data, stream_param->data,
stream_param->data_len * sizeof(*stream_param->data));
source->stream_data[stream_count].data_len = stream_param->data_len;
sys_slist_append(&subgroup->streams, &stream->_node);
stream_count++;
@ -851,30 +795,8 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source,
return 0;
}
static void broadcast_source_store_metadata(struct bt_audio_codec_cfg *codec_cfg,
const struct bt_audio_codec_data meta[],
size_t meta_count)
{
size_t old_meta_count;
old_meta_count = codec_cfg->meta_count;
/* Update metadata */
codec_cfg->meta_count = meta_count;
(void)memcpy(codec_cfg->meta, meta, meta_count * sizeof(*meta));
if (old_meta_count > meta_count) {
size_t meta_count_diff = old_meta_count - meta_count;
/* If we previously had more metadata entries we reset the
* data that was not overwritten by the new metadata
*/
(void)memset(&codec_cfg->meta[meta_count], 0, meta_count_diff * sizeof(*meta));
}
}
int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *source,
const struct bt_audio_codec_data meta[],
size_t meta_count)
const uint8_t meta[], size_t meta_len)
{
struct bt_bap_broadcast_subgroup *subgroup;
enum bt_bap_ep_state broadcast_state;
@ -885,29 +807,19 @@ int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *sour
return -EINVAL;
}
CHECKIF((meta == NULL && meta_count != 0) ||
(meta != NULL && meta_count == 0)) {
LOG_DBG("Invalid metadata combination: %p %zu",
meta, meta_count);
CHECKIF((meta == NULL && meta_len != 0) || (meta != NULL && meta_len == 0)) {
LOG_DBG("Invalid metadata combination: %p %zu", meta, meta_len);
return -EINVAL;
}
CHECKIF(meta_count > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_COUNT) {
LOG_DBG("Invalid meta_count: %zu (max %d)", meta_count,
CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_COUNT);
CHECKIF(meta_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
LOG_DBG("Invalid meta_len: %zu (max %d)", meta_len,
CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
return -EINVAL;
}
for (size_t i = 0; i < meta_count; i++) {
CHECKIF(meta[i].data.data_len > sizeof(meta[i].value)) {
LOG_DBG("Invalid meta[%zu] data_len %u",
i, meta[i].data.data_len);
return -EINVAL;
}
}
broadcast_state = broadcast_source_get_state(source);
if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_STREAMING) {
LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
@ -919,7 +831,8 @@ int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *sour
* for each subgroup individually
*/
SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
broadcast_source_store_metadata(subgroup->codec_cfg, meta, meta_count);
memset(subgroup->codec_cfg->meta, 0, sizeof(subgroup->codec_cfg->meta));
memcpy(subgroup->codec_cfg->meta, meta, meta_len);
}
return 0;