diff --git a/doc/releases/migration-guide-3.7.rst b/doc/releases/migration-guide-3.7.rst index 8db43668e638669..c9ab644dc9c5a32 100644 --- a/doc/releases/migration-guide-3.7.rst +++ b/doc/releases/migration-guide-3.7.rst @@ -458,6 +458,15 @@ Bluetooth Audio :c:func:`bt_audio_codec_cfg_meta_set_lang` :c:func:`bt_audio_codec_cfg_meta_get_lang` +* Changed ``lang`` from ``uint32_t`` to ``uint8_t [3]``. This modifies the following functions + - :c:func:`bt_audio_codec_cap_meta_set_lang` + - :c:func:`bt_audio_codec_cap_meta_get_lang` + - :c:func:`bt_audio_codec_cfg_meta_set_lang` + - :c:func:`bt_audio_codec_cfg_meta_get_lang` + + The result of this is that string values such as ``"eng"`` and ``"deu"`` can now be used to set + new values, and to prevent unnecessary copies of data when getting the values. + * All occurrences of ``set_sirk`` have been changed to just ``sirk`` as the ``s`` in ``sirk`` stands for set. (:github:`73413`) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 1a93f4bc505004f..b4808463171f166 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -41,6 +41,9 @@ extern "C" { #define BT_AUDIO_BROADCAST_CODE_SIZE 16 +/** Size of the stream language value, e.g. "eng" */ +#define BT_AUDIO_LANG_SIZE 3 + /** * @brief Codec capability types * @@ -376,6 +379,7 @@ enum bt_audio_metadata_type { /** @brief Language * * 3 octet lower case language code defined by ISO 639-3 + * Possible values can be found at https://iso639-3.sil.org/code_tables/639/data */ BT_AUDIO_METADATA_TYPE_LANG = 0x04, @@ -1247,14 +1251,16 @@ int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cf * * See @ref BT_AUDIO_METADATA_TYPE_LANG for more information about this value. * - * @param codec_cfg The codec data to search in. + * @param[in] codec_cfg The codec data to search in. + * @param[out] lang Pointer to the language bytes (of length BT_AUDIO_LANG_SIZE) * * @retval The language if positive or 0 * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg *codec_cfg); +int bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **lang); /** * @brief Set the language of a codec configuration metadata. @@ -1266,7 +1272,8 @@ int bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg *codec_cfg) * @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_lang(struct bt_audio_codec_cfg *codec_cfg, uint32_t lang); +int bt_audio_codec_cfg_meta_set_lang(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t lang[BT_AUDIO_LANG_SIZE]); /** @brief Extract CCID list * @@ -1769,14 +1776,16 @@ int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_ca * * See @ref BT_AUDIO_METADATA_TYPE_LANG for more information about this value. * - * @param codec_cap The codec data to search in. + * @param[in] codec_cap The codec data to search in. + * @param[out] lang Pointer to the language bytes (of length BT_AUDIO_LANG_SIZE) * - * @retval The language if positive or 0 + * @retval 0 On success * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size */ -int bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap *codec_cap); +int bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **lang); /** * @brief Set the language of a codec capability metadata. @@ -1788,7 +1797,8 @@ int bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap *codec_cap) * @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_lang(struct bt_audio_codec_cap *codec_cap, uint32_t lang); +int bt_audio_codec_cap_meta_set_lang(struct bt_audio_codec_cap *codec_cap, + const uint8_t lang[BT_AUDIO_LANG_SIZE]); /** @brief Extract CCID list * diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index cba547ed7d27fd2..fb13ba2ea9d3e92 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -2098,7 +2098,7 @@ static bool ascs_parse_metadata(struct bt_data *data, void *user_data) break; } case BT_AUDIO_METADATA_TYPE_LANG: - if (data_len != 3) { + if (data_len != BT_AUDIO_LANG_SIZE) { *result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID, data_type); result->err = -EBADMSG; diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index d20b9b5a6a3b6cb..355d56597e4e863 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -796,7 +796,7 @@ static int codec_meta_set_program_info(uint8_t meta[], size_t meta_len, size_t m program_info, program_info_len); } -static int codec_meta_get_lang(const uint8_t meta[], size_t meta_len) +static int codec_meta_get_lang(const uint8_t meta[], size_t meta_len, const uint8_t **lang) { const uint8_t *data; int ret; @@ -806,36 +806,40 @@ static int codec_meta_get_lang(const uint8_t meta[], size_t meta_len) return -EINVAL; } + CHECKIF(lang == NULL) { + LOG_DBG("lang is NULL"); + return -EINVAL; + } + ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_LANG, &data); if (data == NULL) { return -ENODATA; } - if (ret != 3) { /* Language is 3 octets */ + if (ret != BT_AUDIO_LANG_SIZE) { return -EBADMSG; } - return sys_get_le24(data); + *lang = data; + + return 0; } -static int codec_meta_set_lang(uint8_t meta[], size_t meta_len, size_t meta_size, uint32_t lang) +static int codec_meta_set_lang(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t lang[BT_AUDIO_LANG_SIZE]) { - uint8_t lang_le[3]; - CHECKIF(meta == NULL) { LOG_DBG("meta is NULL"); return -EINVAL; } - if ((lang & 0xFFFFFFU) != lang) { - LOG_DBG("Invalid lang value: %d", lang); + CHECKIF(lang == NULL) { + LOG_DBG("lang is NULL"); return -EINVAL; } - sys_put_le24(lang, lang_le); - - return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_LANG, lang_le, - sizeof(lang_le)); + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_LANG, lang, + BT_AUDIO_LANG_SIZE); } static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, @@ -1247,17 +1251,19 @@ int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cf return ret; } -int bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg *codec_cfg) +int bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg *codec_cfg, + const uint8_t **lang) { CHECKIF(codec_cfg == NULL) { LOG_DBG("codec_cfg is NULL"); return -EINVAL; } - return codec_meta_get_lang(codec_cfg->meta, codec_cfg->meta_len); + return codec_meta_get_lang(codec_cfg->meta, codec_cfg->meta_len, lang); } -int bt_audio_codec_cfg_meta_set_lang(struct bt_audio_codec_cfg *codec_cfg, uint32_t lang) +int bt_audio_codec_cfg_meta_set_lang(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t lang[BT_AUDIO_LANG_SIZE]) { int ret; @@ -1573,17 +1579,19 @@ int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_ca return ret; } -int bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap *codec_cap) +int bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap *codec_cap, + const uint8_t **lang) { CHECKIF(codec_cap == NULL) { LOG_DBG("codec_cap is NULL"); return -EINVAL; } - return codec_meta_get_lang(codec_cap->meta, codec_cap->meta_len); + return codec_meta_get_lang(codec_cap->meta, codec_cap->meta_len, lang); } -int bt_audio_codec_cap_meta_set_lang(struct bt_audio_codec_cap *codec_cap, uint32_t lang) +int bt_audio_codec_cap_meta_set_lang(struct bt_audio_codec_cap *codec_cap, + const uint8_t lang[BT_AUDIO_LANG_SIZE]) { int ret; diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index cae5b03ccead9d6..e826b4747e12fe9 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -361,14 +361,11 @@ static inline void print_codec_meta_program_info(const struct shell *sh, size_t shell_fprintf(sh, SHELL_NORMAL, "\n"); } -static inline void print_codec_meta_language(const struct shell *sh, size_t indent, uint32_t lang) +static inline void print_codec_meta_language(const struct shell *sh, size_t indent, + const uint8_t lang[BT_AUDIO_LANG_SIZE]) { - uint8_t lang_array[3]; - - sys_put_be24(lang, lang_array); - - shell_print(sh, "%*sLanguage: %c%c%c", indent, "", (char)lang_array[0], (char)lang_array[1], - (char)lang_array[2]); + shell_print(sh, "%*sLanguage: %c%c%c", indent, "", (char)lang[0], (char)lang[1], + (char)lang[2]); } static inline void print_codec_meta_ccid_list(const struct shell *sh, size_t indent, @@ -720,9 +717,9 @@ static inline void print_codec_cap(const struct shell *sh, size_t indent, print_codec_meta_program_info(sh, indent, data, (uint8_t)ret); } - ret = bt_audio_codec_cap_meta_get_lang(codec_cap); + ret = bt_audio_codec_cap_meta_get_lang(codec_cap, &data); if (ret >= 0) { - print_codec_meta_language(sh, indent, (uint32_t)ret); + print_codec_meta_language(sh, indent, data); } ret = bt_audio_codec_cap_meta_get_ccid_list(codec_cap, &data); @@ -956,9 +953,9 @@ static inline void print_codec_cfg(const struct shell *sh, size_t indent, print_codec_meta_program_info(sh, indent, data, (uint8_t)ret); } - ret = bt_audio_codec_cfg_meta_get_lang(codec_cfg); + ret = bt_audio_codec_cfg_meta_get_lang(codec_cfg, &data); if (ret >= 0) { - print_codec_meta_language(sh, indent, (uint32_t)ret); + print_codec_meta_language(sh, indent, data); } ret = bt_audio_codec_cfg_meta_get_ccid_list(codec_cfg, &data); diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index a3a06bd610c1905..1b32c38b8894bf1 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -1966,17 +1966,15 @@ static ssize_t parse_config_meta_args(const struct shell *sh, size_t argn, size_ arg = argv[argn]; - if (strlen(arg) != 3) { + if (strlen(arg) != BT_AUDIO_LANG_SIZE) { shell_error(sh, "Failed to parse lang from %s", arg); return -1; } - val = sys_get_le24(arg); - - err = bt_audio_codec_cfg_meta_set_lang(codec_cfg, (uint32_t)val); + err = bt_audio_codec_cfg_meta_set_lang(codec_cfg, arg); if (err < 0) { - shell_error(sh, "Failed to set lang with value %lu: %d", val, err); + shell_error(sh, "Failed to set lang with value %s: %d", arg, err); return -1; } diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 968855ab641c8e7..a0963749024f1b0 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -517,34 +517,38 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_program_info) ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_lang) { - const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); 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_LANG, 'e', 'n', 'g')}); + char expected_data[] = "eng"; + const uint8_t *lang; int ret; - ret = bt_audio_codec_cfg_meta_get_lang(&codec_cfg); - zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + ret = bt_audio_codec_cfg_meta_get_lang(&codec_cfg, &lang); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, lang, BT_AUDIO_LANG_SIZE); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_lang) { - const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); - const uint32_t new_expected_data = sys_get_le24((uint8_t[]){'d', 'e', 'u'}); 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_LANG, 'e', 'n', 'g')}); - const uint32_t new_lang = sys_le32_to_cpu(new_expected_data); + char new_expected_data[] = "deu"; + char expected_data[] = "eng"; + const uint8_t *lang; int ret; - ret = bt_audio_codec_cfg_meta_get_lang(&codec_cfg); - zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + ret = bt_audio_codec_cfg_meta_get_lang(&codec_cfg, &lang); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, lang, BT_AUDIO_LANG_SIZE); - ret = bt_audio_codec_cfg_meta_set_lang(&codec_cfg, new_lang); + ret = bt_audio_codec_cfg_meta_set_lang(&codec_cfg, new_expected_data); zassert_true(ret > 0, "Unexpected return value %d", ret); - ret = bt_audio_codec_cfg_meta_get_lang(&codec_cfg); - zassert_equal(ret, new_expected_data, "Unexpected return value %d", ret); + ret = bt_audio_codec_cfg_meta_get_lang(&codec_cfg, &lang); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, lang, BT_AUDIO_LANG_SIZE); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_ccid_list) @@ -1410,34 +1414,38 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_program_info) ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_lang) { - const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); 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_LANG, 'e', 'n', 'g')}); + char expected_data[] = "eng"; + const uint8_t *lang; int ret; - ret = bt_audio_codec_cap_meta_get_lang(&codec_cap); - zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + ret = bt_audio_codec_cap_meta_get_lang(&codec_cap, &lang); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, lang, BT_AUDIO_LANG_SIZE); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_lang) { - const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); - const uint32_t new_expected_data = sys_get_le24((uint8_t[]){'d', 'e', 'u'}); 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_LANG, 'e', 'n', 'g')}); - const uint32_t new_lang = sys_le32_to_cpu(new_expected_data); + char new_expected_data[] = "deu"; + char expected_data[] = "eng"; + const uint8_t *lang; int ret; - ret = bt_audio_codec_cap_meta_get_lang(&codec_cap); - zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + ret = bt_audio_codec_cap_meta_get_lang(&codec_cap, &lang); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, lang, BT_AUDIO_LANG_SIZE); - ret = bt_audio_codec_cap_meta_set_lang(&codec_cap, new_lang); + ret = bt_audio_codec_cap_meta_set_lang(&codec_cap, new_expected_data); zassert_true(ret > 0, "Unexpected return value %d", ret); - ret = bt_audio_codec_cap_meta_get_lang(&codec_cap); - zassert_equal(ret, new_expected_data, "Unexpected return value %d", ret); + ret = bt_audio_codec_cap_meta_get_lang(&codec_cap, &lang); + zassert_equal(ret, 0, "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, lang, BT_AUDIO_LANG_SIZE); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_ccid_list) diff --git a/tests/bsim/bluetooth/audio/src/bap_common.h b/tests/bsim/bluetooth/audio/src/bap_common.h index 7508113dd690c4b..231f0eb569658e3 100644 --- a/tests/bsim/bluetooth/audio/src/bap_common.h +++ b/tests/bsim/bluetooth/audio/src/bap_common.h @@ -63,7 +63,7 @@ static inline bool valid_metadata_type(uint8_t type, uint8_t len) return true; case BT_AUDIO_METADATA_TYPE_LANG: - if (len != 3) { + if (len != BT_AUDIO_LANG_SIZE) { return false; }