Browse Source

Bluetooth: Audio: Add helpers for broadcast name

Added helper functions to set and get broadcast name
for codec capabilities and codec configs.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
pull/80299/head
Emil Gydesen 11 months ago committed by Carles Cufí
parent
commit
fb6c4427b8
  1. 8
      doc/releases/release-notes-4.0.rst
  2. 66
      include/zephyr/bluetooth/audio/audio.h
  3. 97
      subsys/bluetooth/audio/codec.c
  4. 78
      tests/bluetooth/audio/codec/src/main.c

8
doc/releases/release-notes-4.0.rst

@ -113,6 +113,14 @@ Bluetooth @@ -113,6 +113,14 @@ Bluetooth
* :c:func:`bt_audio_codec_cap_meta_get_assisted_listening_stream`
* :c:func:`bt_audio_codec_cap_meta_set_assisted_listening_stream`
* Added APIs for getting and setting the broadcast name in codec capabilities
and codec configuration:
* :c:func:`bt_audio_codec_cfg_meta_get_broadcast_name`
* :c:func:`bt_audio_codec_cfg_meta_set_broadcast_name`
* :c:func:`bt_audio_codec_cap_meta_get_broadcast_name`
* :c:func:`bt_audio_codec_cap_meta_set_broadcast_name`
* Host
* Added API :c:func:`bt_gatt_get_uatt_mtu` to get current Unenhanced ATT MTU of a given

66
include/zephyr/bluetooth/audio/audio.h

@ -496,11 +496,14 @@ enum bt_audio_metadata_type { @@ -496,11 +496,14 @@ enum bt_audio_metadata_type {
*/
BT_AUDIO_METADATA_TYPE_ASSISTED_LISTENING_STREAM = 0x0A,
/** UTF-8 encoded Broadcast name */
BT_AUDIO_METADATA_TYPE_BROADCAST_NAME = 0x0B,
/** Extended metadata */
BT_AUDIO_METADATA_TYPE_EXTENDED = 0xFE,
BT_AUDIO_METADATA_TYPE_EXTENDED = 0xFE,
/** Vendor specific metadata */
BT_AUDIO_METADATA_TYPE_VENDOR = 0xFF,
BT_AUDIO_METADATA_TYPE_VENDOR = 0xFF,
};
/**
@ -1367,6 +1370,36 @@ int bt_audio_codec_cfg_meta_get_assisted_listening_stream( @@ -1367,6 +1370,36 @@ int bt_audio_codec_cfg_meta_get_assisted_listening_stream(
int bt_audio_codec_cfg_meta_set_assisted_listening_stream(
struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_assisted_listening_stream val);
/**
* @brief Extract broadcast name
*
* See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_NAME for more information about this value.
*
* @param[in] codec_cfg The codec data to search in.
* @param[out] broadcast_name Pointer to the UTF-8 formatted broadcast name.
*
* @retval length The length of the @p broadcast_name (may be 0)
* @retval -EINVAL if arguments are invalid
* @retval -ENODATA if not found
*/
int bt_audio_codec_cfg_meta_get_broadcast_name(const struct bt_audio_codec_cfg *codec_cfg,
const uint8_t **broadcast_name);
/**
* @brief Set the broadcast name of a codec configuration metadata.
*
* @param codec_cfg The codec configuration to set data for.
* @param broadcast_name The broadcast name to set.
* @param broadcast_name_len The length of @p broadcast_name.
*
* @retval length The data_len of @p codec_cfg on success
* @retval -EINVAL if arguments are invalid
* @retval -ENOMEM if the new value could not set or added due to memory
*/
int bt_audio_codec_cfg_meta_set_broadcast_name(struct bt_audio_codec_cfg *codec_cfg,
const uint8_t *broadcast_name,
size_t broadcast_name_len);
/**
* @brief Extract extended metadata
*
@ -1938,6 +1971,35 @@ int bt_audio_codec_cap_meta_get_assisted_listening_stream( @@ -1938,6 +1971,35 @@ int bt_audio_codec_cap_meta_get_assisted_listening_stream(
int bt_audio_codec_cap_meta_set_assisted_listening_stream(
struct bt_audio_codec_cap *codec_cap, enum bt_audio_assisted_listening_stream val);
/**
* @brief Extract broadcast name
*
* See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_NAME for more information about this value.
*
* @param[in] codec_cap The codec data to search in.
* @param[out] broadcast_name Pointer to the UTF-8 formatted broadcast name.
*
* @retval length The length of the @p broadcast_name (may be 0)
* @retval -EINVAL if arguments are invalid
* @retval -ENODATA if not found
*/
int bt_audio_codec_cap_meta_get_broadcast_name(const struct bt_audio_codec_cap *codec_cap,
const uint8_t **broadcast_name);
/**
* @brief Set the broadcast name of a codec capability metadata.
*
* @param codec_cap The codec capability to set data for.
* @param broadcast_name The broadcast name to set.
* @param broadcast_name_len The length of @p broadcast_name.
*
* @retval length The data_len of @p codec_cap on success
* @retval -EINVAL if arguments are invalid
* @retval -ENOMEM if the new value could not set or added due to memory
*/
int bt_audio_codec_cap_meta_set_broadcast_name(struct bt_audio_codec_cap *codec_cap,
const uint8_t *broadcast_name,
size_t broadcast_name_len);
/**
* @brief Extract extended metadata
*

97
subsys/bluetooth/audio/codec.c

@ -1102,6 +1102,49 @@ static int codec_meta_set_assisted_listening_stream(uint8_t meta[], size_t meta_ @@ -1102,6 +1102,49 @@ static int codec_meta_set_assisted_listening_stream(uint8_t meta[], size_t meta_
sizeof(val_u8));
}
static int codec_meta_get_broadcast_name(const uint8_t meta[], size_t meta_len,
const uint8_t **broadcast_name)
{
const uint8_t *data;
int ret;
CHECKIF(meta == NULL) {
LOG_DBG("meta is NULL");
return -EINVAL;
}
CHECKIF(broadcast_name == NULL) {
LOG_DBG("broadcast_name is NULL");
return -EINVAL;
}
ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_BROADCAST_NAME, &data);
if (data == NULL) {
return -ENODATA;
}
*broadcast_name = data;
return ret;
}
static int codec_meta_set_broadcast_name(uint8_t meta[], size_t meta_len, size_t meta_size,
const uint8_t *broadcast_name, size_t broadcast_name_len)
{
CHECKIF(meta == NULL) {
LOG_DBG("meta is NULL");
return -EINVAL;
}
CHECKIF(broadcast_name == NULL) {
LOG_DBG("broadcast_name is NULL");
return -EINVAL;
}
return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_BROADCAST_NAME,
broadcast_name, broadcast_name_len);
}
static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len,
const uint8_t **extended_meta)
{
@ -1547,6 +1590,33 @@ int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg, @@ -1547,6 +1590,33 @@ int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg,
return ret;
}
int bt_audio_codec_cfg_meta_get_broadcast_name(const struct bt_audio_codec_cfg *codec_cfg,
const uint8_t **broadcast_name)
{
CHECKIF(codec_cfg == NULL) {
LOG_DBG("codec_cfg is NULL");
return -EINVAL;
}
return codec_meta_get_broadcast_name(codec_cfg->meta, codec_cfg->meta_len, broadcast_name);
}
int bt_audio_codec_cfg_meta_set_broadcast_name(struct bt_audio_codec_cfg *codec_cfg,
const uint8_t *broadcast_name,
size_t broadcast_name_len)
{
int ret;
ret = codec_meta_set_broadcast_name(codec_cfg->meta, codec_cfg->meta_len,
ARRAY_SIZE(codec_cfg->meta), broadcast_name,
broadcast_name_len);
if (ret >= 0) {
codec_cfg->meta_len = ret;
}
return ret;
}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
@ -1900,6 +1970,33 @@ int bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap *codec_cap, @@ -1900,6 +1970,33 @@ int bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap *codec_cap,
return ret;
}
int bt_audio_codec_cap_meta_get_broadcast_name(const struct bt_audio_codec_cap *codec_cap,
const uint8_t **broadcast_name)
{
CHECKIF(codec_cap == NULL) {
LOG_DBG("codec_cap is NULL");
return -EINVAL;
}
return codec_meta_get_broadcast_name(codec_cap->meta, codec_cap->meta_len, broadcast_name);
}
int bt_audio_codec_cap_meta_set_broadcast_name(struct bt_audio_codec_cap *codec_cap,
const uint8_t *broadcast_name,
size_t broadcast_name_len)
{
int ret;
ret = codec_meta_set_broadcast_name(codec_cap->meta, codec_cap->meta_len,
ARRAY_SIZE(codec_cap->meta), broadcast_name,
broadcast_name_len);
if (ret >= 0) {
codec_cap->meta_len = ret;
}
return ret;
}
#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \
* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \

78
tests/bluetooth/audio/codec/src/main.c

@ -959,6 +959,45 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_assisted_listenin @@ -959,6 +959,45 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_assisted_listenin
zassert_equal(ret, 0x00, "Unexpected return value %d", ret);
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_broadcast_name)
{
const uint8_t expected_data[] = {'m', 'y', ' ', 'b', 'c', 'a', 's', 't'};
const struct bt_audio_codec_cfg codec_cfg =
BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {},
{BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_BROADCAST_NAME, 'm',
'y', ' ', 'b', 'c', 'a', 's', 't')});
const uint8_t *broadcast_name;
int ret;
ret = bt_audio_codec_cfg_meta_get_broadcast_name(&codec_cfg, &broadcast_name);
zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret);
zassert_mem_equal(expected_data, broadcast_name, ARRAY_SIZE(expected_data));
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_broadcast_name)
{
const uint8_t expected_data[] = {'m', 'y', ' ', 'b', 'c', 'a', 's', 't'};
const uint8_t new_expected_data[] = {'n', 'e', 'w', ' ', 'b', 'c', 'a', 's', 't'};
struct bt_audio_codec_cfg codec_cfg =
BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {},
{BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_BROADCAST_NAME, 'm',
'y', ' ', 'b', 'c', 'a', 's', 't')});
const uint8_t *broadcast_name;
int ret;
ret = bt_audio_codec_cfg_meta_get_broadcast_name(&codec_cfg, &broadcast_name);
zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret);
zassert_mem_equal(expected_data, broadcast_name, ARRAY_SIZE(expected_data));
ret = bt_audio_codec_cfg_meta_set_broadcast_name(&codec_cfg, new_expected_data,
ARRAY_SIZE(new_expected_data));
zassert_true(ret > 0, "Unexpected return value %d", ret);
ret = bt_audio_codec_cfg_meta_get_broadcast_name(&codec_cfg, &broadcast_name);
zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret);
zassert_mem_equal(new_expected_data, broadcast_name, ARRAY_SIZE(new_expected_data));
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_extended)
{
const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03};
@ -1873,6 +1912,45 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_assisted_listenin @@ -1873,6 +1912,45 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_assisted_listenin
zassert_equal(ret, 0x00, "Unexpected return value %d", ret);
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_broadcast_name)
{
const uint8_t expected_data[] = {'m', 'y', ' ', 'b', 'c', 'a', 's', 't'};
const struct bt_audio_codec_cap codec_cap =
BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {},
{BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_BROADCAST_NAME, 'm',
'y', ' ', 'b', 'c', 'a', 's', 't')});
const uint8_t *broadcast_name;
int ret;
ret = bt_audio_codec_cap_meta_get_broadcast_name(&codec_cap, &broadcast_name);
zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret);
zassert_mem_equal(expected_data, broadcast_name, ARRAY_SIZE(expected_data));
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_broadcast_name)
{
const uint8_t expected_data[] = {'m', 'y', ' ', 'b', 'c', 'a', 's', 't'};
const uint8_t new_expected_data[] = {'n', 'e', 'w', ' ', 'b', 'c', 'a', 's', 't'};
struct bt_audio_codec_cap codec_cap =
BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {},
{BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_BROADCAST_NAME, 'm',
'y', ' ', 'b', 'c', 'a', 's', 't')});
const uint8_t *broadcast_name;
int ret;
ret = bt_audio_codec_cap_meta_get_broadcast_name(&codec_cap, &broadcast_name);
zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret);
zassert_mem_equal(expected_data, broadcast_name, ARRAY_SIZE(expected_data));
ret = bt_audio_codec_cap_meta_set_broadcast_name(&codec_cap, new_expected_data,
ARRAY_SIZE(new_expected_data));
zassert_true(ret > 0, "Unexpected return value %d", ret);
ret = bt_audio_codec_cap_meta_get_broadcast_name(&codec_cap, &broadcast_name);
zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret);
zassert_mem_equal(new_expected_data, broadcast_name, ARRAY_SIZE(new_expected_data));
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_extended)
{
const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03};

Loading…
Cancel
Save