Skip to content

Commit

Permalink
Bluetooth: Audio: Add bt_audio_codec unset functions
Browse files Browse the repository at this point in the history
Add functions to unset, or remove, specific codec
LTV structure from codec_cfgs or codec_caps.

Signed-off-by: Emil Gydesen <[email protected]>
  • Loading branch information
Thalley committed Nov 21, 2023
1 parent 9c90ed6 commit 61a67a1
Show file tree
Hide file tree
Showing 3 changed files with 522 additions and 0 deletions.
55 changes: 55 additions & 0 deletions include/zephyr/bluetooth/audio/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,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 or 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 @@ -837,6 +851,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 or 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 @@ -1172,6 +1199,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 or 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 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 @@ -1330,6 +1371,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 or 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
127 changes: 127 additions & 0 deletions subsys/bluetooth/audio/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,38 @@ 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;) {
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 + 1;
data_len_to_move = buf->len - (next_data_start - buf->data);
memmove(value, 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 @@ -307,6 +339,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 @@ -592,6 +645,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 @@ -1080,6 +1148,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 @@ -1388,6 +1475,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 @@ -1747,6 +1853,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

0 comments on commit 61a67a1

Please sign in to comment.