Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth: Audio: Add bt_audio_codec unset functions #63400

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions include/zephyr/bluetooth/audio/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,20 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_codec_config_type type, const uint8_t *data,
size_t data_len);

/**
* @brief Unset a specific codec configuration value
*
* The type and the value will be removed from the codec configuration.
*
* @param codec_cfg The codec data to set the value in.
* @param type The type id to unset.
*
* @retval The data_len of @p codec_cfg on success
* @retval -EINVAL if arguments are invalid
*/
int bt_audio_codec_cfg_unset_val(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_codec_config_type type);

/** @brief Lookup a specific metadata value based on type
*
*
Expand Down Expand Up @@ -853,6 +867,19 @@ int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_metadata_type type, const uint8_t *data,
size_t data_len);

/**
* @brief Unset a specific codec configuration metadata value
*
* The type and the value will be removed from the codec configuration metadata.
*
* @param codec_cfg The codec data to set the value in.
* @param type The type id to unset.
*
* @retval The meta_len of @p codec_cfg on success
* @retval -EINVAL if arguments are invalid
*/
int bt_audio_codec_cfg_meta_unset_val(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_metadata_type type);
/** @brief Extract preferred contexts
*
* See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value.
Expand Down Expand Up @@ -1188,6 +1215,20 @@ int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap,
enum bt_audio_codec_capability_type type, const uint8_t *data,
size_t data_len);

/**
* @brief Unset a specific codec capability value
*
* The type and the value will be removed from the codec capability.
*
* @param codec_cap The codec data to set the value in.
* @param type The type id to unset.
*
* @retval The data_len of @p codec_cap on success
* @retval -EINVAL if arguments are invalid
*/
int bt_audio_codec_cap_unset_val(struct bt_audio_codec_cap *codec_cap,
enum bt_audio_codec_capability_type type);

/**
* @brief Extract the frequency from a codec capability.
*
Expand Down Expand Up @@ -1346,6 +1387,20 @@ int bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap *codec_cap,
enum bt_audio_metadata_type type, const uint8_t *data,
size_t data_len);

/**
* @brief Unset a specific codec capability metadata value
*
* The type and the value will be removed from the codec capability metadata.
*
* @param codec_cap The codec data to set the value in.
* @param type The type id to unset.
*
* @retval The meta_len of @p codec_cap on success
* @retval -EINVAL if arguments are invalid
*/
int bt_audio_codec_cap_meta_unset_val(struct bt_audio_codec_cap *codec_cap,
enum bt_audio_metadata_type type);

/** @brief Extract preferred contexts
*
* See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value.
Expand Down
133 changes: 133 additions & 0 deletions subsys/bluetooth/audio/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,44 @@ static int ltv_set_val(struct net_buf_simple *buf, uint8_t type, const uint8_t *

return buf->len;
}

static int ltv_unset_val(struct net_buf_simple *buf, uint8_t type)
{
for (uint16_t i = 0U; i < buf->len;) {
uint8_t *ltv_start = &buf->data[i];
const uint8_t len = buf->data[i++];
const uint8_t data_type = buf->data[i++];
const uint8_t value_len = len - sizeof(data_type);

if (data_type == type) {
const uint8_t ltv_size = value_len + sizeof(data_type) + sizeof(len);
uint8_t *value = &buf->data[i];

/* Check if this is not the last value in the buffer */
if (value + value_len != buf->data + buf->len) {
uint8_t *next_data_start;
uint8_t data_len_to_move;

next_data_start = value + value_len;
data_len_to_move = buf->len - (next_data_start - buf->data);
memmove(ltv_start, next_data_start, data_len_to_move);

LOG_ERR("buf->data %p, ltv_start %p, value_len %u next_data_start "
"%p data_len_to_move %u",
buf->data, ltv_start, value_len, next_data_start,
data_len_to_move);
} /* else just reduce the length of the buffer */

buf->len -= ltv_size;

return buf->len;
}

i += value_len;
}

return buf->len;
}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 || \
* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \
* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 || \
Expand Down Expand Up @@ -310,6 +348,27 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg,
return ret;
}

int bt_audio_codec_cfg_unset_val(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_codec_config_type type)
{
struct net_buf_simple buf;
int ret;

CHECKIF(codec_cfg == NULL) {
LOG_DBG("codec_cfg is NULL");
return -EINVAL;
}

init_net_buf_simple_from_codec_cfg(&buf, codec_cfg);

ret = ltv_unset_val(&buf, type);
if (ret >= 0) {
codec_cfg->data_len = ret;
}

return ret;
}

int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg)
{
enum bt_audio_codec_config_freq freq;
Expand Down Expand Up @@ -595,6 +654,21 @@ static int codec_meta_set_val(uint8_t meta[], size_t meta_len, size_t meta_size,
return ltv_set_val(&buf, (uint8_t)type, data, data_len);
}

static int codec_meta_unset_val(uint8_t meta[], size_t meta_len, size_t meta_size,
enum bt_audio_metadata_type type)
{
struct net_buf_simple buf;

CHECKIF(meta == NULL) {
LOG_DBG("meta is NULL");
return -EINVAL;
}

init_net_buf_simple_from_meta(&buf, meta, meta_len, meta_size);

return ltv_unset_val(&buf, type);
}

static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len)
{
const uint8_t *data;
Expand Down Expand Up @@ -1083,6 +1157,25 @@ int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg,
return ret;
}

int bt_audio_codec_cfg_meta_unset_val(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_metadata_type type)
{
int ret;

CHECKIF(codec_cfg == NULL) {
LOG_DBG("codec_cfg is NULL");
return -EINVAL;
}

ret = codec_meta_unset_val(codec_cfg->meta, codec_cfg->meta_len,
ARRAY_SIZE(codec_cfg->meta), type);
if (ret >= 0) {
codec_cfg->meta_len = ret;
}

return ret;
}

int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg)
{
CHECKIF(codec_cfg == NULL) {
Expand Down Expand Up @@ -1391,6 +1484,25 @@ int bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap *codec_cap,
return ret;
}

int bt_audio_codec_cap_meta_unset_val(struct bt_audio_codec_cap *codec_cap,
enum bt_audio_metadata_type type)
{
int ret;

CHECKIF(codec_cap == NULL) {
LOG_DBG("codec_cap is NULL");
return -EINVAL;
}

ret = codec_meta_unset_val(codec_cap->meta, codec_cap->meta_len,
ARRAY_SIZE(codec_cap->meta), type);
if (ret >= 0) {
codec_cap->meta_len = ret;
}

return ret;
}

int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap)
{
CHECKIF(codec_cap == NULL) {
Expand Down Expand Up @@ -1750,6 +1862,27 @@ int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap,
return ret;
}

int bt_audio_codec_cap_unset_val(struct bt_audio_codec_cap *codec_cap,
enum bt_audio_codec_capability_type type)
{
struct net_buf_simple buf;
int ret;

CHECKIF(codec_cap == NULL) {
LOG_DBG("codec_cap is NULL");
return -EINVAL;
}

init_net_buf_simple_from_codec_cap(&buf, codec_cap);

ret = ltv_unset_val(&buf, type);
if (ret >= 0) {
codec_cap->data_len = ret;
}

return ret;
}

int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap)
{
const uint8_t *data;
Expand Down
Loading
Loading