From 9c47eb924faf272c76c36bdae47c59cd63003146 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 27 Sep 2023 11:27:01 +0200 Subject: [PATCH] Bluetooth: Audio: Refactor codec_cfg_get_frame_duration_us Refactor the codec_cfg_get_frame_duration function to return the assigned numbers value, instead of a converted value, but with support for converting the value. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 37 ++++++++++++- include/zephyr/bluetooth/audio/lc3.h | 18 ++++--- samples/bluetooth/hap_ha/src/bap_unicast_sr.c | 8 ++- .../tmap_peripheral/src/bap_unicast_sr.c | 8 ++- .../bluetooth/unicast_audio_client/src/main.c | 6 ++- .../bluetooth/unicast_audio_server/src/main.c | 18 ++++--- subsys/bluetooth/audio/codec.c | 54 ++++++++++++++++--- subsys/bluetooth/audio/shell/bap.c | 16 ++++-- tests/bluetooth/audio/codec/src/main.c | 45 ++++++++++++++-- tests/bluetooth/tester/src/btp_bap.c | 15 +++--- 10 files changed, 185 insertions(+), 40 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 3d5f28372a..403993172e 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -635,16 +635,49 @@ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg); int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_codec_config_freq freq); +/** + * @brief Convert assigned numbers frame duration to duration in microseconds. + * + * @param frame_dur The assigned numbers frame duration to convert. + * + * @retval -EINVAL if arguments are invalid. + * @retval The converted frame duration value in microseconds. + */ +int bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_config_frame_dur frame_dur); + +/** + * @brief Convert frame duration in microseconds to assigned numbers frame duration. + * + * @param frame_dur_us The frame duration in microseconds to convert. + * + * @retval -EINVAL if arguments are invalid. + * @retval The assigned numbers frame duration (@ref bt_audio_codec_config_frame_dur). + */ +int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us); + /** @brief Extract frame duration from BT codec config * * @param codec_cfg The codec configuration to extract data from. * - * @retval Frame duration in microseconds + * @retval A @ref bt_audio_codec_config_frame_dur value * @retval -EINVAL if arguments are invalid * @retval -ENODATA if not found * @retval -EBADMSG if found value has invalid size or value */ -int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg); +int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg); + +/** + * @brief Set the frame duration of a codec configuration. + * + * @param codec_cfg The codec configuration to set data for. + * @param frame_dur The assigned numbers frame duration to set. + * + * @retval 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_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_frame_dur frame_dur); /** @brief Extract channel allocation from BT codec config * diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index 28737fc367..5ca0f27684 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -243,14 +243,16 @@ enum bt_audio_codec_config_freq { BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ = 0x0d, }; -/** - * @brief LC3 7.5 msec Frame Duration configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5 0x00 -/** - * @brief LC3 10 msec Frame Duration configuration - */ -#define BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10 0x01 +enum bt_audio_codec_config_frame_dur { + /** + * @brief LC3 7.5 msec Frame Duration configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5 = 0x00, + /** + * @brief LC3 10 msec Frame Duration configuration + */ + BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10 = 0x01, +}; /** * @brief Helper to declare LC3 codec capability diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 5ed64e8620..1eca1fd25c 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -87,8 +87,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - printk(" Frame Duration: %d us\n", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + printk(" Frame Duration: %d us\n", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index ef78551efd..bb431ef478 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -76,8 +76,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - printk(" Frame Duration: %d us\n", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + printk(" Frame Duration: %d us\n", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index a3aca0424f..0e35a7d5a3 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -234,7 +234,11 @@ static int init_lc3(void) return ret; } - frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } + octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); diff --git a/samples/bluetooth/unicast_audio_server/src/main.c b/samples/bluetooth/unicast_audio_server/src/main.c index 7c20ee34df..7625bcdbf7 100644 --- a/samples/bluetooth/unicast_audio_server/src/main.c +++ b/samples/bluetooth/unicast_audio_server/src/main.c @@ -147,8 +147,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - printk(" Frame Duration: %d us\n", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + printk(" Frame Duration: %d us\n", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { printk(" Channel allocation: 0x%x\n", chan_allocation); } @@ -354,8 +358,7 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t #if defined(CONFIG_LIBLC3) { - const int frame_duration_us = - bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg); + int frame_duration_us; int freq; int ret; @@ -369,11 +372,14 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t return ret; } - if (frame_duration_us < 0) { + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } else { printk("Error: Frame duration not set, cannot start codec."); *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID, BT_BAP_ASCS_REASON_CODEC_DATA); - return -1; + return ret; } frames_per_sdu = diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 8a9826f863..5b064987a2 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -88,6 +88,30 @@ int bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz) } } +int bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_config_frame_dur frame_dur) +{ + switch (frame_dur) { + case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5: + return 7500; + case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10: + return 10000; + default: + return -EINVAL; + } +} + +int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us) +{ + switch (frame_dur_us) { + case 7500U: + return BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5; + case 10000U: + return BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10; + default: + return -EINVAL; + } +} + struct search_type_param { bool found; uint8_t type; @@ -309,8 +333,9 @@ int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg, sizeof(freq_u8)); } -int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg) +int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg) { + enum bt_audio_codec_config_frame_dur frame_dur; const uint8_t *data; uint8_t data_len; @@ -328,14 +353,29 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co return -EBADMSG; } - switch (data[0]) { - case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5: - return 7500; - case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10: - return 10000; - default: + frame_dur = data[0]; + if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) { + LOG_DBG("Invalid frame_dur value: 0x%02X", frame_dur); return -EBADMSG; } + + return frame_dur; +} + +int bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_frame_dur frame_dur) +{ + uint8_t frame_dur_u8; + + if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) { + LOG_DBG("Invalid freq value: %d", frame_dur); + return -EINVAL; + } + + frame_dur_u8 = (uint8_t)frame_dur; + + return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_DURATION, + &frame_dur_u8, sizeof(frame_dur_u8)); } int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg, diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 82ed1d3c5e..aa6561f679 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -245,7 +245,13 @@ static int init_lc3(const struct bt_bap_stream *stream) return ret; } - lc3_frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg); + ret = bt_audio_codec_cfg_get_frame_dur(stream->codec_cfg); + if (ret > 0) { + lc3_frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + } else { + return ret; + } + lc3_octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(stream->codec_cfg); lc3_frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(stream->codec_cfg, true); lc3_octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(stream->codec_cfg); @@ -2637,8 +2643,12 @@ static bool stream_start_sine_verify(const struct bt_bap_stream *bap_stream) return false; } - stream_frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(bap_stream->codec_cfg); - if (stream_frame_duration_us != lc3_frame_duration_us) { + err = bt_audio_codec_cfg_get_frame_dur(bap_stream->codec_cfg); + if (err > 0) { + if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(err) != lc3_frame_duration_us) { + return false; + } + } else { return false; } diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 28dee9bdec..edc87c5600 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -73,15 +73,54 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_freq) zassert_equal(ret, 0x06, "Unexpected return value %d", ret); } -ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_duration_us) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_frame_dur_to_frame_dur_us) +{ + const struct frame_dur_test_input { + enum bt_audio_codec_config_frame_dur frame_dur; + uint32_t frame_dur_us; + } frame_dur_test_inputs[] = { + {.frame_dur = BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5, .frame_dur_us = 7500U}, + {.frame_dur = BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10, .frame_dur_us = 10000U}, + }; + + for (size_t i = 0U; i < ARRAY_SIZE(frame_dur_test_inputs); i++) { + const struct frame_dur_test_input *fdti = &frame_dur_test_inputs[i]; + + zassert_equal(bt_audio_codec_cfg_frame_dur_to_frame_dur_us(fdti->frame_dur), + fdti->frame_dur_us, "frame_dur %d was not coverted to %u", + fdti->frame_dur, fdti->frame_dur_us); + zassert_equal(bt_audio_codec_cfg_frame_dur_us_to_frame_dur(fdti->frame_dur_us), + fdti->frame_dur, "frame_dur_us %u was not coverted to %d", + fdti->frame_dur_us, fdti->frame_dur); + } +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_dur) { const struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_48_2_2(BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); int ret; - ret = bt_audio_codec_cfg_get_frame_duration_us(&preset.codec_cfg); - zassert_equal(ret, 10000u, "unexpected return value %d", ret); + ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg); + zassert_equal(ret, 0x01, "unexpected return value %d", ret); +} + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_frame_dur) +{ + struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_16_2_1( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + int ret; + + ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_set_frame_dur(&preset.codec_cfg, + BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg); + zassert_equal(ret, 0x00, "Unexpected return value %d", ret); } ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_chan_allocation) diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index 3e171e2407..7d45781000 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -148,8 +148,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) LOG_DBG(" Frequency: %d Hz", bt_audio_codec_cfg_freq_to_freq_hz(ret)); } - LOG_DBG(" Frame Duration: %d us", - bt_audio_codec_cfg_get_frame_duration_us(codec_cfg)); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret > 0) { + LOG_DBG(" Frame Duration: %d us", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret)); + } + if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) { LOG_DBG(" Channel allocation: 0x%x", chan_allocation); } @@ -260,14 +264,12 @@ static void btp_send_ascs_ase_state_changed_ev(struct bt_conn *conn, uint8_t ase static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg) { - int frame_duration_us; int frames_per_sdu; int octets_per_frame; int chan_allocation_err; enum bt_audio_location chan_allocation; int ret; - frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg); chan_allocation_err = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation); octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); @@ -279,8 +281,9 @@ static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg) return -EINVAL; } - if (frame_duration_us < 0) { - LOG_DBG("Error: Invalid frame duration."); + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret < 0) { + LOG_DBG("Error: Invalid frame duration: %d", ret); return -EINVAL; }