diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 9e8317be0a6add0..858c6b057a79228 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -1019,6 +1019,35 @@ struct bt_bap_unicast_server_cb { int (*release)(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp); }; + +struct bt_bap_unicast_server_register_param { + /* Sink Count to register */ + uint8_t snk_cnt; + /* Source Count to register */ + uint8_t src_cnt; +}; + +/** + * @brief Register ASCS in gatt DB. + * + * Register ASCS in gatt DB. This allows the user to set the number + * ASEs to be used, between 0 and BT_ASCS_MAX_ASE_SNK_COUNT / + * BT_ASCS_MAX_ASE_SRC_COUNT. + * + * @param param Registration parameters for ascs. + * + * @return 0 in case of success. + */ +int bt_bap_unicast_server_register(const struct bt_bap_unicast_server_register_param *param); + +/** + * @brief Unregister ASCS in gatt DB. + * + * Register ASCS in gatt DB. This will also clear out any callbacks + * registered by bt_bap_unicast_server_register_cb(). + */ +void bt_bap_unicast_server_unregister(void); + /** * @brief Register unicast server callbacks. * diff --git a/include/zephyr/bluetooth/audio/gmap.h b/include/zephyr/bluetooth/audio/gmap.h index 0fb5c3b064e2dbc..edb38d042dad6c1 100644 --- a/include/zephyr/bluetooth/audio/gmap.h +++ b/include/zephyr/bluetooth/audio/gmap.h @@ -89,7 +89,7 @@ enum bt_gmap_ugt_feat { /** * @brief Source support * - * Requires @kconfig{CONFIG_BT_ASCS_ASE_SRC_COUNT} > 0 + * Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 0 */ BT_GMAP_UGT_FEAT_SOURCE = BIT(0), /** @@ -101,7 +101,7 @@ enum bt_gmap_ugt_feat { /** * @brief Sink support * - * Requires @kconfig{CONFIG_BT_ASCS_ASE_SNK_COUNT} > 0 + * Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 0 */ BT_GMAP_UGT_FEAT_SINK = BIT(2), /** @@ -119,14 +119,14 @@ enum bt_gmap_ugt_feat { /** * @brief Support for receiving at least two audio channels, each in a separate CIS * - * Requires @kconfig{CONFIG_BT_ASCS_ASE_SNK_COUNT} > 1 and + * Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 1 and * @kconfig{CONFIG_BT_ASCS_MAX_ACTIVE_ASES} > 1, and BT_GMAP_UGT_FEAT_SINK to be set as well */ BT_GMAP_UGT_FEAT_MULTISINK = BIT(5), /** * @brief Support for sending at least two audio channels, each in a separate CIS * - * Requires @kconfig{CONFIG_BT_ASCS_ASE_SRC_COUNT} > 1 and + * Requires @kconfig{CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT} > 1 and * @kconfig{CONFIG_BT_ASCS_MAX_ACTIVE_ASES} > 1, and BT_GMAP_UGT_FEAT_SOURCE to be set * as well */ diff --git a/samples/bluetooth/bap_unicast_server/prj.conf b/samples/bluetooth/bap_unicast_server/prj.conf index 2705d0c1895642c..a80b779e5730663 100644 --- a/samples/bluetooth/bap_unicast_server/prj.conf +++ b/samples/bluetooth/bap_unicast_server/prj.conf @@ -5,8 +5,8 @@ CONFIG_BT_ISO_PERIPHERAL=y CONFIG_BT_AUDIO=y CONFIG_BT_BAP_UNICAST_SERVER=y CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=2 -CONFIG_BT_ASCS_ASE_SRC_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1 CONFIG_BT_ISO_TX_BUF_COUNT=2 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=4 @@ -16,3 +16,7 @@ CONFIG_BT_ATT_PREPARE_COUNT=1 CONFIG_BT_EXT_ADV=y CONFIG_BT_DEVICE_NAME="Unicast Audio Server" + +CONFIG_BT_ASCS_LOG_LEVEL_DBG=y +#CONFIG_BT_GATT_LOG_LEVEL_DBG=y +CONFIG_LOG_BUFFER_SIZE=2048 \ No newline at end of file diff --git a/samples/bluetooth/bap_unicast_server/src/main.c b/samples/bluetooth/bap_unicast_server/src/main.c index 90bff48719f67f4..bd61142e5fed9b6 100644 --- a/samples/bluetooth/bap_unicast_server/src/main.c +++ b/samples/bluetooth/bap_unicast_server/src/main.c @@ -29,7 +29,7 @@ BT_AUDIO_CONTEXT_TYPE_MEDIA | \ BT_AUDIO_CONTEXT_TYPE_GAME) -NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_ASE_SRC_COUNT, +NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); @@ -40,13 +40,13 @@ static const struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3( static struct bt_conn *default_conn; static struct k_work_delayable audio_send_work; -static struct bt_bap_stream sink_streams[CONFIG_BT_ASCS_ASE_SNK_COUNT]; +static struct bt_bap_stream sink_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT]; static struct audio_source { struct bt_bap_stream stream; uint16_t seq_num; uint16_t max_sdu; size_t len_to_send; -} source_streams[CONFIG_BT_ASCS_ASE_SRC_COUNT]; +} source_streams[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; static size_t configured_source_stream_count; static const struct bt_audio_codec_qos_pref qos_pref = @@ -466,6 +466,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp return 0; } +static struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static const struct bt_bap_unicast_server_cb unicast_server_cb = { .config = lc3_config, .reconfig = lc3_reconfig, @@ -722,6 +727,7 @@ int main(void) printk("Bluetooth initialized\n"); + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&unicast_server_cb); bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap_sink); @@ -775,7 +781,7 @@ int main(void) printk("Advertising successfully started\n"); - if (CONFIG_BT_ASCS_ASE_SRC_COUNT > 0) { + if (CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0) { /* Start send timer */ k_work_init_delayable(&audio_send_work, audio_timer_timeout); } diff --git a/samples/bluetooth/cap_acceptor/prj.conf b/samples/bluetooth/cap_acceptor/prj.conf index 4a67de1e58226d6..36da8d2bb04f6dc 100644 --- a/samples/bluetooth/cap_acceptor/prj.conf +++ b/samples/bluetooth/cap_acceptor/prj.conf @@ -23,8 +23,8 @@ CONFIG_BT_ATT_PREPARE_COUNT=1 # Support an ISO channel per ASE CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=1 -CONFIG_BT_ASCS_ASE_SRC_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=2 diff --git a/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c b/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c index 9015eb409955a8d..cfc6e7f5b655f81 100644 --- a/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c +++ b/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c @@ -402,6 +402,17 @@ int init_cap_acceptor_unicast(struct peer_config *peer) if (!cbs_registered) { int err; + struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + }; + + err = bt_bap_unicast_server_register(¶m); + if (err != 0) { + LOG_ERR("Failed to register BAP unicast server: %d", err); + + return -ENOEXEC; + } err = bt_bap_unicast_server_register_cb(&unicast_server_cb); if (err != 0) { diff --git a/samples/bluetooth/hap_ha/prj.conf b/samples/bluetooth/hap_ha/prj.conf index c492cdeb1ecbcc7..938d851fbcdf819 100644 --- a/samples/bluetooth/hap_ha/prj.conf +++ b/samples/bluetooth/hap_ha/prj.conf @@ -18,8 +18,8 @@ CONFIG_BT_ATT_PREPARE_COUNT=1 CONFIG_BT_AUDIO=y CONFIG_BT_BAP_UNICAST_SERVER=y CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=1 -CONFIG_BT_ASCS_ASE_SRC_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=2 diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 6244bb76bf11019..c671ad0ccd76621 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -18,7 +18,7 @@ #include #include -NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_ASE_SRC_COUNT, +NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); @@ -29,11 +29,12 @@ static const struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3( static struct bt_conn *default_conn; static struct k_work_delayable audio_send_work; -static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; +static struct bt_bap_stream streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; static struct audio_source { struct bt_bap_stream *stream; uint16_t seq_num; -} source_streams[CONFIG_BT_ASCS_ASE_SRC_COUNT]; +} source_streams[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; static size_t configured_source_stream_count; static const struct bt_audio_codec_qos_pref qos_pref = @@ -316,6 +317,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp return 0; } +static struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static const struct bt_bap_unicast_server_cb unicast_server_cb = { .config = lc3_config, .reconfig = lc3_reconfig, @@ -394,6 +400,7 @@ static struct bt_pacs_cap cap_source = { int bap_unicast_sr_init(void) { + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&unicast_server_cb); bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap_sink); diff --git a/samples/bluetooth/tmap_peripheral/prj.conf b/samples/bluetooth/tmap_peripheral/prj.conf index 35f5d15502c2e07..69e721a3c9c77db 100644 --- a/samples/bluetooth/tmap_peripheral/prj.conf +++ b/samples/bluetooth/tmap_peripheral/prj.conf @@ -29,8 +29,8 @@ CONFIG_BT_MCC=y # Support an ISO channel per ASE CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=1 -CONFIG_BT_ASCS_ASE_SRC_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=2 diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index 8e325855e655a1d..a4e81dd0838ba32 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -30,11 +30,12 @@ static const struct bt_audio_codec_cap lc3_codec_cap = (AVAILABLE_SINK_CONTEXT | AVAILABLE_SOURCE_CONTEXT)); static struct bt_conn *default_conn; -static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; +static struct bt_bap_stream streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; static struct audio_source { struct bt_bap_stream *stream; uint16_t seq_num; -} source_streams[CONFIG_BT_ASCS_ASE_SRC_COUNT]; +} source_streams[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; static size_t configured_source_stream_count; static const struct bt_audio_codec_qos_pref qos_pref = @@ -271,6 +272,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp return 0; } +static struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static const struct bt_bap_unicast_server_cb unicast_server_cb = { .config = lc3_config, .reconfig = lc3_reconfig, @@ -351,6 +357,7 @@ static struct bt_pacs_cap cap = { int bap_unicast_sr_init(void) { + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&unicast_server_cb); if (IS_ENABLED(CONFIG_BT_PAC_SNK)) { diff --git a/subsys/bluetooth/audio/Kconfig.ascs b/subsys/bluetooth/audio/Kconfig.ascs index acf539f3ac8c6e9..61d92c2b4846ef1 100644 --- a/subsys/bluetooth/audio/Kconfig.ascs +++ b/subsys/bluetooth/audio/Kconfig.ascs @@ -12,16 +12,16 @@ config BT_ASCS This option enables support for Audio Stream Control Service. if BT_ASCS -config BT_ASCS_ASE_SNK_COUNT - int "Number of Audio Stream Endpoint Sink Characteristics" +config BT_ASCS_MAX_ASE_SNK_COUNT + int "Maximum number of Audio Stream Endpoint Sink Characteristics" default 2 range 0 $(UINT8_MAX) help An ASE Sink characteristic represents the state of an ASE, which is coupled to a single direction of a unicast Audio Stream. -config BT_ASCS_ASE_SRC_COUNT - int "Number of Audio Stream Endpoint Source Characteristics" +config BT_ASCS_MAX_ASE_SRC_COUNT + int "Maximum number of Audio Stream Endpoint Source Characteristics" default 2 range 0 $(UINT8_MAX) help @@ -29,12 +29,12 @@ config BT_ASCS_ASE_SRC_COUNT coupled to a single direction of a unicast Audio Stream. config BT_ASCS_ASE_SNK - def_bool BT_ASCS_ASE_SNK_COUNT > 0 + def_bool BT_ASCS_MAX_ASE_SNK_COUNT > 0 select BT_PAC_SNK select BT_AUDIO_RX config BT_ASCS_ASE_SRC - def_bool BT_ASCS_ASE_SRC_COUNT > 0 + def_bool BT_ASCS_MAX_ASE_SRC_COUNT > 0 select BT_PAC_SRC select BT_AUDIO_TX diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 17aeda10edb3119..d78acd7bf6912ac 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -4,6 +4,7 @@ /* * Copyright (c) 2020 Intel Corporation * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -54,8 +55,8 @@ LOG_MODULE_REGISTER(bt_ascs, CONFIG_BT_ASCS_LOG_LEVEL); #define ASE_BUF_SEM_TIMEOUT K_MSEC(CONFIG_BT_ASCS_ASE_BUF_TIMEOUT) #define MAX_ASES_SESSIONS CONFIG_BT_MAX_CONN * \ - (CONFIG_BT_ASCS_ASE_SNK_COUNT + \ - CONFIG_BT_ASCS_ASE_SRC_COUNT) + (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + \ + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT) #define NTF_HEADER_SIZE (3) /* opcode (1) + handle (2) */ @@ -67,10 +68,10 @@ BUILD_ASSERT(CONFIG_BT_ASCS_MAX_ACTIVE_ASES <= MAX(MAX_ASES_SESSIONS, #define ASE_ID(_ase) ase->ep.status.id #define ASE_DIR(_id) \ - (_id > CONFIG_BT_ASCS_ASE_SNK_COUNT ? BT_AUDIO_DIR_SOURCE : BT_AUDIO_DIR_SINK) + (_id > CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT ? BT_AUDIO_DIR_SOURCE : BT_AUDIO_DIR_SINK) #define ASE_UUID(_id) \ - (_id > CONFIG_BT_ASCS_ASE_SNK_COUNT ? BT_UUID_ASCS_ASE_SRC : BT_UUID_ASCS_ASE_SNK) -#define ASE_COUNT (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT) + (_id > CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT ? BT_UUID_ASCS_ASE_SRC : BT_UUID_ASCS_ASE_SNK) +#define ASE_COUNT (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT) #define BT_BAP_ASCS_RSP_NULL ((struct bt_bap_ascs_rsp[]) { BT_BAP_ASCS_RSP(0, 0) }) static struct bt_ascs_ase { @@ -3080,22 +3081,100 @@ static ssize_t ascs_cp_write(struct bt_conn *conn, BT_AUDIO_CCC(ascs_ase_cfg_changed) #define BT_ASCS_ASE_SNK_DEFINE(_n, ...) BT_ASCS_ASE_DEFINE(BT_UUID_ASCS_ASE_SNK, (_n) + 1) #define BT_ASCS_ASE_SRC_DEFINE(_n, ...) BT_ASCS_ASE_DEFINE(BT_UUID_ASCS_ASE_SRC, (_n) + 1 + \ - CONFIG_BT_ASCS_ASE_SNK_COUNT) - -BT_GATT_SERVICE_DEFINE(ascs_svc, - BT_GATT_PRIMARY_SERVICE(BT_UUID_ASCS), - BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_CP, - BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_WRITE_ENCRYPT | BT_GATT_PERM_PREPARE_WRITE, - NULL, ascs_cp_write, NULL), - BT_AUDIO_CCC(ascs_cp_cfg_changed), -#if CONFIG_BT_ASCS_ASE_SNK_COUNT > 0 - LISTIFY(CONFIG_BT_ASCS_ASE_SNK_COUNT, BT_ASCS_ASE_SNK_DEFINE, (,)), -#endif /* CONFIG_BT_ASCS_ASE_SNK_COUNT > 0 */ -#if CONFIG_BT_ASCS_ASE_SRC_COUNT > 0 - LISTIFY(CONFIG_BT_ASCS_ASE_SRC_COUNT, BT_ASCS_ASE_SRC_DEFINE, (,)), -#endif /* CONFIG_BT_ASCS_ASE_SRC_COUNT > 0 */ -); + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT) + +#define BT_ASCS_CHR_ASE_CONTROL_POINT \ + BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_CP, \ + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_WRITE_ENCRYPT | BT_GATT_PERM_PREPARE_WRITE, \ + NULL, ascs_cp_write, NULL), \ + BT_AUDIO_CCC(ascs_cp_cfg_changed) + +#if CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 0 +#define BT_ASCS_ASE_SINKS \ + LISTIFY(CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, BT_ASCS_ASE_SNK_DEFINE, (,)), +#else +#define BT_ASCS_ASE_SINKS +#endif /* CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 0 */ + +#if CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0 +#define BT_ASCS_ASE_SOURCES \ + LISTIFY(CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, BT_ASCS_ASE_SRC_DEFINE, (,)), +#else +#define BT_ASCS_ASE_SOURCES +#endif /* CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0 */ + +#define BT_ASCS_SERVICE_DEFINITION() { \ + BT_GATT_PRIMARY_SERVICE(BT_UUID_ASCS), \ + BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_CP, \ + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_WRITE_ENCRYPT | BT_GATT_PERM_PREPARE_WRITE, \ + NULL, ascs_cp_write, NULL), \ + BT_AUDIO_CCC(ascs_cp_cfg_changed), \ + BT_ASCS_ASE_SINKS \ + BT_ASCS_ASE_SOURCES \ + } + +#define ASCS_ASE_CHAR_ATTR_COUNT 3 /* declaration + value + cccd */ + +static struct bt_gatt_attr ascs_attrs[] = BT_ASCS_SERVICE_DEFINITION(); +static struct bt_gatt_service ascs_svc = (struct bt_gatt_service)BT_GATT_SERVICE(ascs_attrs); + +static void configure_ase_char(uint8_t snk_cnt, uint8_t src_cnt) +{ + uint8_t snk_ases_to_rem = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT - snk_cnt; + uint8_t src_ases_to_rem = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT - src_cnt; + size_t attrs_to_rem; + + /* Remove the Source ASEs. The ones to remove will always be at the very tail of the + * attributes, so we just decrease the count withe the amount of sources we want to remove. + */ + attrs_to_rem = src_ases_to_rem * ASCS_ASE_CHAR_ATTR_COUNT; + ascs_svc.attr_count -= attrs_to_rem; + + /* Remove the Sink ASEs. + */ + attrs_to_rem = snk_ases_to_rem * ASCS_ASE_CHAR_ATTR_COUNT; + if (CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT == 0 || CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + == src_ases_to_rem) { + /* If there are no Source ASEs present, then we can just decrease the + * attribute count + */ + ascs_svc.attr_count -= attrs_to_rem; + } else { + /* As Source ASEs are present, we need to iterate backwards (as this will likely be + * the shortest distance). Find the first Sink to save, and move all Sources + * backwards to it. + */ + size_t src_start_idx = ascs_svc.attr_count - (src_cnt * ASCS_ASE_CHAR_ATTR_COUNT); + size_t new_src_start_idx = src_start_idx - (snk_ases_to_rem * + ASCS_ASE_CHAR_ATTR_COUNT); + + for (size_t i = 0; i < src_cnt * ASCS_ASE_CHAR_ATTR_COUNT; i++) { + ascs_svc.attrs[new_src_start_idx + i] = ascs_svc.attrs[src_start_idx + i]; + } + + ascs_svc.attr_count -= attrs_to_rem; + } +} + +int bt_ascs_service_register(uint8_t snk_cnt, uint8_t src_cnt) +{ + int err = 0; + + if (snk_cnt < CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT || + src_cnt < CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT) { + configure_ase_char(snk_cnt, src_cnt); + } + + err = bt_gatt_service_register(&ascs_svc); + + if (err != 0) { + LOG_ERR("Failed to register ASCS in gatt DB"); + } + + return err; +} static int control_point_notify(struct bt_conn *conn, const void *data, uint16_t len) { @@ -3135,10 +3214,31 @@ void bt_ascs_cleanup(void) bt_ascs_release_ase(&ase->ep); } } - if (unicast_server_cb != NULL) { bt_iso_server_unregister(&iso_server); unicast_server_cb = NULL; } } + +int bt_ascs_service_unregister(void) +{ + int err; + + bt_ascs_cleanup(); + err = bt_gatt_service_unregister(&ascs_svc); + /* If unregistration was succesfull, make sure to reset ascs_attrs so it can be used for + * new registrations + */ + if (err != 0) { + LOG_ERR("Failed to unregister ASCS"); + } else { + struct bt_gatt_attr _ascs_attrs[] = BT_ASCS_SERVICE_DEFINITION(); + + memcpy(&ascs_attrs, &_ascs_attrs, sizeof(struct bt_gatt_attr)); + } + + LOG_DBG("Unregister ASCS returning with err=%d", err); + + return err; +} #endif /* BT_BAP_UNICAST_SERVER */ diff --git a/subsys/bluetooth/audio/ascs_internal.h b/subsys/bluetooth/audio/ascs_internal.h index f96a1905ec52525..9f4732b929ea5ea 100644 --- a/subsys/bluetooth/audio/ascs_internal.h +++ b/subsys/bluetooth/audio/ascs_internal.h @@ -3,6 +3,7 @@ * Copyright (c) 2020 Intel Corporation * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -357,4 +358,7 @@ int bt_ascs_release_ase(struct bt_bap_ep *ep); void bt_ascs_foreach_ep(struct bt_conn *conn, bt_bap_ep_func_t func, void *user_data); +int bt_ascs_service_register(uint8_t snk_cnt, uint8_t src_cnt); +int bt_ascs_service_unregister(void); + #endif /* BT_ASCS_INTERNAL_H */ diff --git a/subsys/bluetooth/audio/bap_unicast_server.c b/subsys/bluetooth/audio/bap_unicast_server.c index 0c631186c03a490..25a54ef6912aacf 100644 --- a/subsys/bluetooth/audio/bap_unicast_server.c +++ b/subsys/bluetooth/audio/bap_unicast_server.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2021-2023 Nordic Semiconductor ASA + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +29,17 @@ LOG_MODULE_REGISTER(bt_bap_unicast_server, CONFIG_BT_BAP_UNICAST_SERVER_LOG_LEVE static const struct bt_bap_unicast_server_cb *unicast_server_cb; +int bt_bap_unicast_server_register(const struct bt_bap_unicast_server_register_param *param) +{ + LOG_DBG("reg"); + return bt_ascs_service_register(param->snk_cnt, param->src_cnt); +} + +void bt_bap_unicast_server_unregister(void) +{ + bt_ascs_service_unregister(); +} + int bt_bap_unicast_server_register_cb(const struct bt_bap_unicast_server_cb *cb) { int err; diff --git a/subsys/bluetooth/audio/gmap_server.c b/subsys/bluetooth/audio/gmap_server.c index d80003bf210a79d..b5c96fe3dade852 100644 --- a/subsys/bluetooth/audio/gmap_server.c +++ b/subsys/bluetooth/audio/gmap_server.c @@ -226,26 +226,27 @@ static bool valid_gmap_features(enum bt_gmap_role role, struct bt_gmap_feat feat } if ((ugt_feat & BT_GMAP_UGT_FEAT_SOURCE) != 0 && - CONFIG_BT_ASCS_ASE_SRC_COUNT == 0) { + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT == 0) { LOG_DBG("Cannot support BT_GMAP_UGT_FEAT_SOURCE with " - "CONFIG_BT_ASCS_ASE_SRC_COUNT == 0"); + "CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT == 0"); return false; } if ((ugt_feat & BT_GMAP_UGT_FEAT_MULTISOURCE) != 0 && - (CONFIG_BT_ASCS_ASE_SRC_COUNT < 2 || CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2)) { + (CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2 || CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2)) { LOG_DBG("Cannot support BT_GMAP_UGT_FEAT_MULTISOURCE with " - "CONFIG_BT_ASCS_ASE_SRC_COUNT (%d) or " + "CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT (%d) or " "CONFIG_BT_ASCS_MAX_ACTIVE_ASES (%d) < 2", - CONFIG_BT_ASCS_ASE_SRC_COUNT, CONFIG_BT_ASCS_MAX_ACTIVE_ASES); + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, CONFIG_BT_ASCS_MAX_ACTIVE_ASES); return false; } - if ((ugt_feat & BT_GMAP_UGT_FEAT_SINK) != 0 && CONFIG_BT_ASCS_ASE_SNK_COUNT == 0) { + if ((ugt_feat & BT_GMAP_UGT_FEAT_SINK) != 0 + && CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT == 0) { LOG_DBG("Cannot support BT_GMAP_UGT_FEAT_SINK with " - "CONFIG_BT_ASCS_ASE_SNK_COUNT == 0"); + "CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT == 0"); return false; } @@ -262,11 +263,11 @@ static bool valid_gmap_features(enum bt_gmap_role role, struct bt_gmap_feat feat } if ((ugt_feat & BT_GMAP_UGT_FEAT_MULTISINK) != 0 && - (CONFIG_BT_ASCS_ASE_SNK_COUNT < 2 || CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2)) { + (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT < 2 || CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2)) { LOG_DBG("Cannot support BT_GMAP_UGT_FEAT_MULTISINK with " - "CONFIG_BT_ASCS_ASE_SNK_COUNT (%d) or " + "CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT (%d) or " "CONFIG_BT_ASCS_MAX_ACTIVE_ASES (%d) < 2", - CONFIG_BT_ASCS_ASE_SNK_COUNT, CONFIG_BT_ASCS_MAX_ACTIVE_ASES); + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, CONFIG_BT_ASCS_MAX_ACTIVE_ASES); return false; } diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index a13879c4c9f4a78..7c6bf99b93e1430 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -199,7 +199,8 @@ struct broadcast_sink { #if defined(CONFIG_BT_BAP_UNICAST) #define UNICAST_SERVER_STREAM_COUNT \ - COND_CODE_1(CONFIG_BT_ASCS, (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT), \ + COND_CODE_1(CONFIG_BT_ASCS, \ + (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT), \ (0)) #define UNICAST_CLIENT_STREAM_COUNT \ COND_CODE_1(CONFIG_BT_BAP_UNICAST_CLIENT, \ diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 9dcffab16354081..12c9bb444b46fc8 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -752,6 +752,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp return 0; } +static struct bt_bap_unicast_server_register_param unicast_server_param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static const struct bt_bap_unicast_server_cb unicast_server_cb = { .config = lc3_config, .reconfig = lc3_reconfig, @@ -3650,6 +3655,7 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[]) } #if defined(CONFIG_BT_BAP_UNICAST_SERVER) + bt_bap_unicast_server_register(&unicast_server_param); bt_bap_unicast_server_register_cb(&unicast_server_cb); #endif /* CONFIG_BT_BAP_UNICAST_SERVER */ diff --git a/subsys/bluetooth/audio/shell/gmap.c b/subsys/bluetooth/audio/shell/gmap.c index 2ec5d86e2d60ddc..964fbfbadc7a527 100644 --- a/subsys/bluetooth/audio/shell/gmap.c +++ b/subsys/bluetooth/audio/shell/gmap.c @@ -96,18 +96,18 @@ static void set_gmap_features(struct bt_gmap_feat *features) } if (IS_ENABLED(CONFIG_BT_GMAP_UGT_SUPPORTED)) { -#if CONFIG_BT_ASCS_ASE_SRC_COUNT > 0 +#if CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0 features->ugt_feat |= (BT_GMAP_UGT_FEAT_SOURCE | BT_GMAP_UGT_FEAT_80KBPS_SOURCE); -#if CONFIG_BT_ASCS_ASE_SRC_COUNT > 1 +#if CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 1 features->ugt_feat |= BT_GMAP_UGT_FEAT_MULTISOURCE; -#endif /* CONFIG_BT_ASCS_ASE_SRC_COUNT > 1 */ -#endif /* CONFIG_BT_ASCS_ASE_SRC_COUNT > 0 */ -#if CONFIG_BT_ASCS_ASE_SNK_COUNT > 0 +#endif /* CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 1 */ +#endif /* CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0 */ +#if CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 0 features->ugt_feat |= (BT_GMAP_UGT_FEAT_SINK | BT_GMAP_UGT_FEAT_64KBPS_SINK); -#if CONFIG_BT_ASCS_ASE_SNK_COUNT > 1 +#if CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 1 features->ugt_feat |= BT_GMAP_UGT_FEAT_MULTISINK; -#endif /* CONFIG_BT_ASCS_ASE_SNK_COUNT > 1 */ -#endif /* CONFIG_BT_ASCS_ASE_SNK_COUNT > 0 */ +#endif /* CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 1 */ +#endif /* CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 0 */ } if (IS_ENABLED(CONFIG_BT_GMAP_BGS_SUPPORTED)) { diff --git a/tests/bluetooth/audio/ascs/prj.conf b/tests/bluetooth/audio/ascs/prj.conf index 2ed3485e3358415..a9d4b988b08d456 100644 --- a/tests/bluetooth/audio/ascs/prj.conf +++ b/tests/bluetooth/audio/ascs/prj.conf @@ -7,8 +7,8 @@ CONFIG_BT_ISO_PERIPHERAL=y CONFIG_BT_ISO_MAX_CHAN=1 CONFIG_BT_AUDIO=y CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=1 -CONFIG_BT_ASCS_ASE_SRC_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=1 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=1 CONFIG_BT_ASCS_MAX_ACTIVE_ASES=1 CONFIG_BT_BAP_UNICAST_SERVER=y diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index 69e738dceb8251b..226d6ec7110efb5 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2023 Codecoup + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,8 +61,15 @@ struct ascs_test_suite_fixture { static void ascs_test_suite_fixture_init(struct ascs_test_suite_fixture *fixture) { + struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + }; + memset(fixture, 0, sizeof(*fixture)); + bt_bap_unicast_server_register(¶m); + fixture->ase_cp = test_ase_control_point_get(); test_conn_init(&fixture->conn); @@ -84,11 +92,15 @@ static void *ascs_test_suite_setup(void) fixture = malloc(sizeof(*fixture)); zassert_not_null(fixture); - ascs_test_suite_fixture_init(fixture); - return fixture; } +static void ascs_test_suite_before(void *f) +{ + memset(f, 0, sizeof(struct ascs_test_suite_fixture)); + ascs_test_suite_fixture_init(f); +} + static void ascs_test_suite_teardown(void *f) { free(f); @@ -96,11 +108,12 @@ static void ascs_test_suite_teardown(void *f) static void ascs_test_suite_after(void *f) { - bt_ascs_cleanup(); + bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb); + bt_bap_unicast_server_unregister(); } -ZTEST_SUITE(ascs_test_suite, NULL, ascs_test_suite_setup, NULL, ascs_test_suite_after, - ascs_test_suite_teardown); +ZTEST_SUITE(ascs_test_suite, NULL, ascs_test_suite_setup, ascs_test_suite_before, + ascs_test_suite_after, ascs_test_suite_teardown); ZTEST_F(ascs_test_suite, test_has_sink_ase_chrc) { @@ -158,7 +171,6 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_callback_unregister) bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb); - /* Set ASE to non-idle state */ test_ase_control_client_config_codec(conn, ase_id, stream); /* Reset mock, as we expect ASE notification to be sent */ @@ -179,45 +191,6 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_callback_unregister) zassert_equal(0x00, hdr->ase_state, "unexpected ASE_State 0x%02x", hdr->ase_state); } -ZTEST_F(ascs_test_suite, test_abort_client_operation_if_callback_not_registered) -{ - const struct test_ase_cp_chrc_value_param *param; - const struct test_ase_cp_chrc_value_hdr *hdr; - const struct bt_gatt_attr *ase_cp = fixture->ase_cp; - struct bt_bap_stream *stream = &fixture->stream; - struct bt_conn *conn = &fixture->conn; - struct bt_gatt_notify_params *notify_params; - uint8_t ase_id; - - if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) { - ase_id = fixture->ase_snk.id; - } else { - ase_id = fixture->ase_src.id; - } - - zexpect_not_null(ase_cp); - zexpect_true(ase_id != 0x00); - - /* Set ASE to non-idle state */ - test_ase_control_client_config_codec(conn, ase_id, stream); - - /* Expected ASE Control Point notification with Unspecified Error was sent */ - expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, - EMPTY, TEST_ASE_CP_CHRC_VALUE_SIZE(1)); - - notify_params = mock_bt_gatt_notify_cb_fake.arg1_val; - hdr = (void *)notify_params->data; - zassert_equal(0x01, hdr->opcode, "unexpected Opcode 0x%02x", hdr->opcode); - zassert_equal(0x01, hdr->number_of_ases, "unexpected Number_of_ASEs 0x%02x", - hdr->number_of_ases); - param = (void *)hdr->params; - zassert_equal(ase_id, param->ase_id, "unexpected ASE_ID 0x%02x", param->ase_id); - /* Expect Unspecified Error */ - zassert_equal(0x0E, param->response_code, "unexpected Response_Code 0x%02x", - param->response_code); - zassert_equal(0x00, param->reason, "unexpected Reason 0x%02x", param->reason); -} - ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection) { struct bt_bap_stream *stream = &fixture->stream; diff --git a/tests/bluetooth/audio/ascs/src/test_ase_control_params.c b/tests/bluetooth/audio/ascs/src/test_ase_control_params.c index a89af5bf170d97a..193582e9455a92e 100644 --- a/tests/bluetooth/audio/ascs/src/test_ase_control_params.c +++ b/tests/bluetooth/audio/ascs/src/test_ase_control_params.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2023 Codecoup + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,25 +42,32 @@ static void *test_ase_control_params_setup(void) fixture = malloc(sizeof(*fixture)); zassert_not_null(fixture); - test_conn_init(&fixture->conn); - fixture->ase_cp = test_ase_control_point_get(); - - if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) { - test_ase_snk_get(1, &fixture->ase); - } else { - test_ase_src_get(1, &fixture->ase); - } - return fixture; } static void test_ase_control_params_before(void *f) { struct test_ase_control_params_fixture *fixture = f; + struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + }; ARG_UNUSED(fixture); + bt_bap_unicast_server_register(¶m); + bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb); + + test_conn_init(&fixture->conn); + fixture->ase_cp = test_ase_control_point_get(); + + if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) { + test_ase_snk_get(1, &fixture->ase); + } else { + test_ase_src_get(1, &fixture->ase); + } + } static void test_ase_control_params_after(void *f) @@ -171,7 +179,8 @@ ZTEST_F(test_ase_control_params, test_codec_configure_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_codec_configure_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; /* Skip if number of ASEs configured is high enough to support any value in the write req */ if (ase_cnt > UINT8_MAX) { @@ -367,13 +376,13 @@ static int unicast_server_cb_config_custom_fake(struct bt_conn *conn, const stru ZTEST_F(test_ase_control_params, test_codec_configure_invalid_ase_id_unavailable) { /* Test requires support for at least 2 ASEs */ - if (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT < 2) { + if (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2) { ztest_test_skip(); } const uint8_t ase_id_valid = 0x01; - const uint8_t ase_id_invalid = CONFIG_BT_ASCS_ASE_SNK_COUNT + - CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint8_t ase_id_invalid = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; const uint8_t buf[] = { 0x01, /* Opcode = Config Codec */ 0x02, /* Number_of_ASEs */ @@ -546,7 +555,8 @@ ZTEST_F(test_ase_control_params, test_config_qos_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_config_qos_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; /* Skip if number of ASEs configured is high enough to support any value in the write req */ if (ase_cnt > UINT8_MAX) { @@ -655,7 +665,8 @@ ZTEST_F(test_ase_control_params, test_enable_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_enable_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; /* Skip if number of ASEs configured is high enough to support any value in the write req */ if (ase_cnt > UINT8_MAX) { @@ -720,13 +731,13 @@ ZTEST_F(test_ase_control_params, test_enable_metadata_too_short) ZTEST_F(test_ase_control_params, test_enable_invalid_ase_id) { /* Test requires support for at least 2 ASEs */ - if (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT < 2) { + if (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2) { ztest_test_skip(); } const uint8_t ase_id_valid = 0x01; - const uint8_t ase_id_invalid = CONFIG_BT_ASCS_ASE_SNK_COUNT + - CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint8_t ase_id_invalid = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; const uint8_t buf[] = { 0x03, /* Opcode = Enable */ 0x02, /* Number_of_ASEs */ @@ -831,7 +842,7 @@ ZTEST_F(test_ase_control_params, test_receiver_start_ready_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_receiver_start_ready_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; const struct bt_gatt_attr *ase; Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC); @@ -932,7 +943,8 @@ ZTEST_F(test_ase_control_params, test_disable_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_disable_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; /* Skip if number of ASEs configured is high enough to support any value in the write req */ if (ase_cnt > UINT8_MAX) { @@ -1021,7 +1033,7 @@ ZTEST_F(test_ase_control_params, test_receiver_stop_ready_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_receiver_stop_ready_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; const struct bt_gatt_attr *ase; Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC); @@ -1123,7 +1135,8 @@ ZTEST_F(test_ase_control_params, test_update_metadata_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_update_metadata_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; /* Skip if number of ASEs configured is high enough to support any value in the write req */ if (ase_cnt > UINT8_MAX) { @@ -1188,13 +1201,13 @@ ZTEST_F(test_ase_control_params, test_update_metadata_metadata_too_short) ZTEST_F(test_ase_control_params, test_update_metadata_invalid_ase_id) { /* Test requires support for at least 2 ASEs */ - if (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT < 2) { + if (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2) { ztest_test_skip(); } const uint8_t ase_id_valid = 0x01; - const uint8_t ase_id_invalid = CONFIG_BT_ASCS_ASE_SNK_COUNT + - CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint8_t ase_id_invalid = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; const uint8_t buf[] = { 0x07, /* Opcode = Update Metadata */ 0x02, /* Number_of_ASEs */ @@ -1260,7 +1273,8 @@ ZTEST_F(test_ase_control_params, test_release_number_of_ases_0x00) ZTEST_F(test_ase_control_params, test_release_number_of_ases_above_max) { - const uint16_t ase_cnt = CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT + 1; + const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1; /* Skip if number of ASEs configured is high enough to support any value in the write req */ if (ase_cnt > UINT8_MAX) { diff --git a/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c b/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c index 0d4e6928d5f8d26..b7cae461e9433a7 100644 --- a/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c +++ b/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2023 Codecoup + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,19 +48,52 @@ static void *test_sink_ase_state_transition_setup(void) fixture = malloc(sizeof(*fixture)); zassert_not_null(fixture); - memset(fixture, 0, sizeof(*fixture)); + return fixture; +} + +static void test_ase_snk_state_transition_before(void *f) +{ + struct test_ase_state_transition_fixture *fixture = + (struct test_ase_state_transition_fixture *) f; + struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + }; + + bt_bap_unicast_server_register(¶m); + + bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb); + + memset(fixture, 0, sizeof(struct test_ase_state_transition_fixture)); test_conn_init(&fixture->conn); test_ase_snk_get(1, &fixture->ase.attr); if (fixture->ase.attr != NULL) { fixture->ase.id = test_ase_id_get(fixture->ase.attr); } - return fixture; + bt_bap_stream_cb_register(&fixture->stream, &mock_bap_stream_ops); } -static void test_ase_state_transition_before(void *f) +static void test_ase_src_state_transition_before(void *f) { + struct test_ase_state_transition_fixture *fixture = + (struct test_ase_state_transition_fixture *) f; + struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + }; + + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb); + + memset(fixture, 0, sizeof(struct test_ase_state_transition_fixture)); + test_conn_init(&fixture->conn); + test_ase_src_get(1, &fixture->ase.attr); + if (fixture->ase.attr != NULL) { + fixture->ase.id = test_ase_id_get(fixture->ase.attr); + } + + bt_bap_stream_cb_register(&fixture->stream, &mock_bap_stream_ops); } static void test_ase_state_transition_after(void *f) @@ -73,7 +107,7 @@ static void test_ase_state_transition_teardown(void *f) } ZTEST_SUITE(test_sink_ase_state_transition, NULL, test_sink_ase_state_transition_setup, - test_ase_state_transition_before, test_ase_state_transition_after, + test_ase_snk_state_transition_before, test_ase_state_transition_after, test_ase_state_transition_teardown); ZTEST_F(test_sink_ase_state_transition, test_client_idle_to_codec_configured) @@ -90,7 +124,6 @@ ZTEST_F(test_sink_ase_state_transition, test_client_idle_to_codec_configured) expect_bt_bap_unicast_server_cb_config_called_once(conn, EMPTY, BT_AUDIO_DIR_SINK, EMPTY); expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); } - ZTEST_F(test_sink_ase_state_transition, test_client_codec_configured_to_qos_configured) { struct bt_bap_stream *stream = &fixture->stream; @@ -611,7 +644,7 @@ static void *test_source_ase_state_transition_setup(void) } ZTEST_SUITE(test_source_ase_state_transition, NULL, test_source_ase_state_transition_setup, - test_ase_state_transition_before, test_ase_state_transition_after, + test_ase_src_state_transition_before, test_ase_state_transition_after, test_ase_state_transition_teardown); ZTEST_F(test_source_ase_state_transition, test_client_idle_to_codec_configured) diff --git a/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c b/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c index c36943c0956acf4..cb8644756205016 100644 --- a/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c +++ b/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2023 Codecoup + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,18 +41,27 @@ static void *test_ase_state_transition_invalid_setup(void) fixture = malloc(sizeof(*fixture)); zassert_not_null(fixture); - memset(fixture, 0, sizeof(*fixture)); - fixture->ase_cp = test_ase_control_point_get(); - test_conn_init(&fixture->conn); - test_ase_snk_get(1, &fixture->ase_snk); - test_ase_src_get(1, &fixture->ase_src); return fixture; } static void test_ase_state_transition_invalid_before(void *f) { + struct test_ase_state_transition_invalid_fixture *fixture = + (struct test_ase_state_transition_invalid_fixture *) f; + struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + }; + + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb); + + memset(fixture, 0, sizeof(struct test_ase_state_transition_invalid_fixture)); + fixture->ase_cp = test_ase_control_point_get(); + test_conn_init(&fixture->conn); + test_ase_snk_get(1, &fixture->ase_snk); + test_ase_src_get(1, &fixture->ase_src); } static void test_ase_state_transition_invalid_after(void *f) diff --git a/tests/bluetooth/audio/ascs/testcase.yaml b/tests/bluetooth/audio/ascs/testcase.yaml index e646ea28bbf118f..ba6e549c306b70b 100644 --- a/tests/bluetooth/audio/ascs/testcase.yaml +++ b/tests/bluetooth/audio/ascs/testcase.yaml @@ -8,11 +8,11 @@ tests: bluetooth.audio.ascs.test_snk_only: type: unit extra_configs: - - CONFIG_BT_ASCS_ASE_SRC_COUNT=0 + - CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=0 bluetooth.audio.ascs.test_src_only: type: unit extra_configs: - - CONFIG_BT_ASCS_ASE_SNK_COUNT=0 + - CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=0 bluetooth.audio.ascs.test_unicast_client_enabled: type: unit extra_configs: diff --git a/tests/bluetooth/audio/mocks/CMakeLists.txt b/tests/bluetooth/audio/mocks/CMakeLists.txt index ead819b901abc0a..4f12849fc2e827f 100644 --- a/tests/bluetooth/audio/mocks/CMakeLists.txt +++ b/tests/bluetooth/audio/mocks/CMakeLists.txt @@ -1,5 +1,6 @@ # # Copyright (c) 2023 Codecoup +# Coperight (c) 2024 Demant A/S # # SPDX-License-Identifier: Apache-2.0 # @@ -24,6 +25,14 @@ target_include_directories(mocks PUBLIC ${ZEPHYR_BASE}/tests/bluetooth/audio ${ZEPHYR_BASE}/subsys/bluetooth ${ZEPHYR_BASE}/subsys/bluetooth/audio + ${ZEPHYR_BASE}/subsys/bluetooth/common + ${ZEPHYR_BASE}/include/zephyr +) + +target_sources(testbinary PRIVATE + ${ZEPHYR_BASE}/subsys/bluetooth/common/bt_str.c + ${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c + ${ZEPHYR_BASE}/include/zephyr/kernel.h ) add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/host host_mocks) diff --git a/tests/bluetooth/audio/mocks/include/gatt.h b/tests/bluetooth/audio/mocks/include/gatt.h index 43b56dac29e451a..619d35f13e9c685 100644 --- a/tests/bluetooth/audio/mocks/include/gatt.h +++ b/tests/bluetooth/audio/mocks/include/gatt.h @@ -20,5 +20,7 @@ DECLARE_FAKE_VALUE_FUNC(bool, mock_bt_gatt_is_subscribed, struct bt_conn *, void bt_gatt_notify_cb_reset(void); uint16_t bt_gatt_get_mtu(struct bt_conn *conn); +int bt_gatt_service_register(struct bt_gatt_service *svc); +int bt_gatt_service_unregister(struct bt_gatt_service *svc); #endif /* MOCKS_GATT_H_ */ diff --git a/tests/bluetooth/audio/mocks/src/gatt.c b/tests/bluetooth/audio/mocks/src/gatt.c index 3a9db441cb517c6..4b4b90a538400e7 100644 --- a/tests/bluetooth/audio/mocks/src/gatt.c +++ b/tests/bluetooth/audio/mocks/src/gatt.c @@ -1,18 +1,30 @@ /* * Copyright (c) 2023 Codecoup + * Copyright (c) 2024 Demant A/S * * SPDX-License-Identifier: Apache-2.0 */ +#include +#include #include +#include + +#include +#include +#include #include #include #include #include +#include #include +#include +#include #include "gatt.h" #include "conn.h" +#include "common/bt_str.h" #define LOG_LEVEL CONFIG_BT_GATT_LOG_LEVEL #include @@ -28,6 +40,9 @@ DEFINE_FAKE_VALUE_FUNC(int, mock_bt_gatt_notify_cb, struct bt_conn *, DEFINE_FAKE_VALUE_FUNC(bool, mock_bt_gatt_is_subscribed, struct bt_conn *, const struct bt_gatt_attr *, uint16_t); +static uint16_t last_static_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; +static sys_slist_t db; + ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { @@ -182,9 +197,6 @@ void bt_gatt_notify_cb_reset(void) RESET_FAKE(mock_bt_gatt_notify_cb); } -#define foreach_attr_type_dyndb(...) -#define last_static_handle BT_ATT_LAST_ATTRIBUTE_HANDLE - /* Exact copy of subsys/bluetooth/host/gatt.c:gatt_foreach_iter() */ static uint8_t gatt_foreach_iter(const struct bt_gatt_attr *attr, uint16_t handle, uint16_t start_handle, @@ -226,6 +238,39 @@ static uint8_t gatt_foreach_iter(const struct bt_gatt_attr *attr, return result; } +/* Exact copy of subsys/bluetooth/host/gatt.c:foreach_attr_type_dyndb() */ +static void foreach_attr_type_dyndb(uint16_t start_handle, uint16_t end_handle, + const struct bt_uuid *uuid, const void *attr_data, + uint16_t num_matches, bt_gatt_attr_func_t func, void *user_data) +{ + size_t i; + struct bt_gatt_service *svc; + + LOG_DBG("foreach_attr_type_dyndb"); + + SYS_SLIST_FOR_EACH_CONTAINER(&db, svc, node) { + struct bt_gatt_service *next; + + next = SYS_SLIST_PEEK_NEXT_CONTAINER(svc, node); + if (next) { + /* Skip ahead if start is not within service handles */ + if (next->attrs[0].handle <= start_handle) { + continue; + } + } + + for (i = 0; i < svc->attr_count; i++) { + struct bt_gatt_attr *attr = &svc->attrs[i]; + + if (gatt_foreach_iter(attr, attr->handle, start_handle, end_handle, uuid, + attr_data, &num_matches, func, + user_data) == BT_GATT_ITER_STOP) { + return; + } + } + } +} + /* Exact copy of subsys/bluetooth/host/gatt.c:bt_gatt_foreach_attr_type() */ void bt_gatt_foreach_attr_type(uint16_t start_handle, uint16_t end_handle, const struct bt_uuid *uuid, @@ -234,6 +279,8 @@ void bt_gatt_foreach_attr_type(uint16_t start_handle, uint16_t end_handle, { size_t i; + LOG_DBG("bt_gatt_foreach_attr_type"); + if (!num_matches) { num_matches = UINT16_MAX; } @@ -255,17 +302,165 @@ void bt_gatt_foreach_attr_type(uint16_t start_handle, uint16_t end_handle, attr_data, &num_matches, func, user_data) == BT_GATT_ITER_STOP) { + LOG_DBG("Returning after searching static DB"); return; } } } } + LOG_DBG("foreach_attr_type_dyndb"); /* Iterate over dynamic db */ foreach_attr_type_dyndb(start_handle, end_handle, uuid, attr_data, num_matches, func, user_data); } +static void bt_gatt_service_init(void) +{ + last_static_handle = 0U; + + STRUCT_SECTION_FOREACH(bt_gatt_service_static, svc) { + last_static_handle += svc->attr_count; + } +} + +/* Exact copy of subsys/bluetooth/host/gatt.c:found_attr() */ +static uint8_t found_attr(const struct bt_gatt_attr *attr, uint16_t handle, void *user_data) +{ + const struct bt_gatt_attr **found = user_data; + + *found = attr; + + return BT_GATT_ITER_STOP; +} + +/* Exact copy of subsys/bluetooth/host/gatt.c:find_attr() */ +static const struct bt_gatt_attr *find_attr(uint16_t handle) +{ + const struct bt_gatt_attr *attr = NULL; + + bt_gatt_foreach_attr(handle, handle, found_attr, &attr); + + return attr; +} + +/* Exact copy of subsys/bluetooth/host/gatt.c:gatt_insert() */ +static void gatt_insert(struct bt_gatt_service *svc, uint16_t last_handle) +{ + struct bt_gatt_service *tmp, *prev = NULL; + + if (last_handle == 0 || svc->attrs[0].handle > last_handle) { + sys_slist_append(&db, &svc->node); + return; + } + + /* DB shall always have its service in ascending order */ + SYS_SLIST_FOR_EACH_CONTAINER(&db, tmp, node) { + if (tmp->attrs[0].handle > svc->attrs[0].handle) { + if (prev) { + sys_slist_insert(&db, &prev->node, &svc->node); + } else { + sys_slist_prepend(&db, &svc->node); + } + return; + } + + prev = tmp; + } +} + +/* Exact copy of subsys/bluetooth/host/gatt.c:gatt_register() */ +static int gatt_register(struct bt_gatt_service *svc) +{ + struct bt_gatt_service *last; + uint16_t handle, last_handle; + struct bt_gatt_attr *attrs = svc->attrs; + uint16_t count = svc->attr_count; + + LOG_ERR("Mock: Registering 0x%04x", attrs->handle); + + if (sys_slist_is_empty(&db)) { + handle = last_static_handle; + last_handle = 0; + goto populate; + } + + last = SYS_SLIST_PEEK_TAIL_CONTAINER(&db, last, node); + handle = last->attrs[last->attr_count - 1].handle; + last_handle = handle; + +populate: + /* Populate the handles and append them to the list */ + for (; attrs && count; attrs++, count--) { + if (!attrs->handle) { + /* Allocate handle if not set already */ + attrs->handle = ++handle; + } else if (attrs->handle > handle) { + /* Use existing handle if valid */ + handle = attrs->handle; + } else if (find_attr(attrs->handle)) { + /* Service has conflicting handles */ + LOG_ERR("Mock: Unable to register handle 0x%04x", attrs->handle); + return -EINVAL; + } + + LOG_DBG("attr %p handle 0x%04x uuid %s perm 0x%02x", attrs, attrs->handle, + bt_uuid_str(attrs->uuid), attrs->perm); + } + + gatt_insert(svc, last_handle); + + return 0; +} + +static int gatt_unregister(struct bt_gatt_service *svc) +{ + if (!sys_slist_find_and_remove(&db, &svc->node)) { + return -ENOENT; + } + + return 0; +} + +int bt_gatt_service_register(struct bt_gatt_service *svc) +{ + int err; + + __ASSERT(svc, "invalid parameters\n"); + __ASSERT(svc->attrs, "invalid parameters\n"); + __ASSERT(svc->attr_count, "invalid parameters\n"); + + /* Init GATT core services */ + bt_gatt_service_init(); + + /* Do no allow to register mandatory services twice */ + if (!bt_uuid_cmp(svc->attrs[0].uuid, BT_UUID_GAP) || + !bt_uuid_cmp(svc->attrs[0].uuid, BT_UUID_GATT)) { + return -EALREADY; + } + + err = gatt_register(svc); + if (err < 0) { + return err; + } + + return 0; +} + +int bt_gatt_service_unregister(struct bt_gatt_service *svc) +{ + int err; + + __ASSERT(svc, "invalid parameters\n"); + + err = gatt_unregister(svc); + if (err) { + return err; + } + + return 0; +} + /* Exact copy of subsys/bluetooth/host/gatt.c:bt_gatt_attr_read() */ ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t buf_len, uint16_t offset, diff --git a/tests/bluetooth/shell/audio.conf b/tests/bluetooth/shell/audio.conf index e783677ad0fc50f..404a04c885279bd 100644 --- a/tests/bluetooth/shell/audio.conf +++ b/tests/bluetooth/shell/audio.conf @@ -58,8 +58,8 @@ CONFIG_BT_ISO_RX_MTU=310 CONFIG_BT_AUDIO=y CONFIG_BT_BAP_UNICAST_SERVER=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=2 -CONFIG_BT_ASCS_ASE_SRC_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=2 CONFIG_BT_BAP_UNICAST_CLIENT=y CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=4 @@ -70,8 +70,8 @@ CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE=255 CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE=255 CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=2 -CONFIG_BT_ASCS_ASE_SRC_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=2 CONFIG_BT_BAP_UNICAST_CLIENT=y CONFIG_BT_BAP_BROADCAST_SOURCE=y CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=4 diff --git a/tests/bluetooth/shell/testcase.yaml b/tests/bluetooth/shell/testcase.yaml index e122332c0b7e02f..321d205f8bd8058 100644 --- a/tests/bluetooth/shell/testcase.yaml +++ b/tests/bluetooth/shell/testcase.yaml @@ -248,12 +248,12 @@ tests: extra_args: CONF_FILE="audio.conf" build_only: true extra_configs: - - CONFIG_BT_ASCS_ASE_SNK_COUNT=0 + - CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=0 bluetooth.audio_shell.no_server_ase_src: extra_args: CONF_FILE="audio.conf" build_only: true extra_configs: - - CONFIG_BT_ASCS_ASE_SRC_COUNT=0 + - CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=0 bluetooth.audio_shell.no_client_ase_snk: extra_args: CONF_FILE="audio.conf" build_only: true @@ -280,14 +280,14 @@ tests: extra_configs: - CONFIG_BT_BAP_BROADCAST_SOURCE=n - CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=0 - - CONFIG_BT_ASCS_ASE_SRC_COUNT=0 + - CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=0 bluetooth.audio_shell.no_audio_rx: extra_args: CONF_FILE="audio.conf" build_only: true extra_configs: - CONFIG_BT_BAP_BROADCAST_SINK=n - CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=0 - - CONFIG_BT_ASCS_ASE_SNK_COUNT=0 + - CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=0 bluetooth.audio_shell.no_has: extra_args: CONF_FILE="audio.conf" build_only: true diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 6b0186e55d8595e..d0c40206f0a8c03 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -57,8 +57,8 @@ CONFIG_BT_BUF_ACL_RX_SIZE=255 # ASCS CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=2 -CONFIG_BT_ASCS_ASE_SRC_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=2 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=4 diff --git a/tests/bluetooth/tester/src/audio/btp_bap_audio_stream.c b/tests/bluetooth/tester/src/audio/btp_bap_audio_stream.c index 4cbc0883f9ea40f..15f979a3b58f72e 100644 --- a/tests/bluetooth/tester/src/audio/btp_bap_audio_stream.c +++ b/tests/bluetooth/tester/src/audio/btp_bap_audio_stream.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #include "btp/btp.h" #include "btp_bap_audio_stream.h" -NET_BUF_POOL_FIXED_DEFINE(tx_pool, MAX(CONFIG_BT_ASCS_ASE_SRC_COUNT, +NET_BUF_POOL_FIXED_DEFINE(tx_pool, MAX(CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT), BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8, NULL); diff --git a/tests/bluetooth/tester/src/audio/btp_bap_unicast.c b/tests/bluetooth/tester/src/audio/btp_bap_unicast.c index 531605689fcf9b0..f05d55ec10fcbde 100644 --- a/tests/bluetooth/tester/src/audio/btp_bap_unicast.c +++ b/tests/bluetooth/tester/src/audio/btp_bap_unicast.c @@ -897,6 +897,11 @@ static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir) btp_send_discovery_completed_ev(conn, BTP_BAP_DISCOVERY_STATUS_SUCCESS); } +static struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static struct bt_bap_unicast_client_cb unicast_client_cbs = { .location = unicast_client_location_cb, .available_contexts = available_contexts_cb, @@ -1652,6 +1657,13 @@ int btp_bap_unicast_init(void) (void)memset(connections, 0, sizeof(connections)); + err = bt_bap_unicast_server_register(¶m); + if (err != 0) { + FAIL("Failed to register unicast server (err %d)\n", err); + + return; + } + err = bt_bap_unicast_server_register_cb(&unicast_server_cb); if (err != 0) { LOG_DBG("Failed to register client callbacks: %d", err); diff --git a/tests/bluetooth/tester/src/audio/btp_bap_unicast.h b/tests/bluetooth/tester/src/audio/btp_bap_unicast.h index e4111289da8c6cd..1ac0bac1aa93538 100644 --- a/tests/bluetooth/tester/src/audio/btp_bap_unicast.h +++ b/tests/bluetooth/tester/src/audio/btp_bap_unicast.h @@ -9,9 +9,9 @@ #include #define BTP_BAP_UNICAST_MAX_SNK_STREAMS_COUNT MIN(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT, \ - CONFIG_BT_ASCS_ASE_SNK_COUNT) + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT) #define BTP_BAP_UNICAST_MAX_SRC_STREAMS_COUNT MIN(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT, \ - CONFIG_BT_ASCS_ASE_SRC_COUNT) + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT) #define BTP_BAP_UNICAST_MAX_STREAMS_COUNT BTP_BAP_UNICAST_MAX_SNK_STREAMS_COUNT + \ BTP_BAP_UNICAST_MAX_SRC_STREAMS_COUNT #define BTP_BAP_UNICAST_MAX_END_POINTS_COUNT CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT + \ diff --git a/tests/bsim/bluetooth/audio/prj.conf b/tests/bsim/bluetooth/audio/prj.conf index ac1809dbf20d552..c5e429b67e569b4 100644 --- a/tests/bsim/bluetooth/audio/prj.conf +++ b/tests/bsim/bluetooth/audio/prj.conf @@ -25,8 +25,8 @@ CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=4 CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=2 CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=2 CONFIG_BT_ASCS=y -CONFIG_BT_ASCS_ASE_SNK_COUNT=2 -CONFIG_BT_ASCS_ASE_SRC_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT=2 +CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT=2 CONFIG_BT_BAP_BROADCAST_SOURCE=y CONFIG_BT_BAP_BROADCAST_SINK=y CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE=196 diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c index c2f2fd2c3c51c74..09319fc106e46fc 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c @@ -68,7 +68,7 @@ static const struct bt_audio_codec_cap lc3_codec_cap = { }; static struct audio_test_stream - test_streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; + test_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; static const struct bt_audio_codec_qos_pref qos_pref = BT_AUDIO_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000); @@ -225,6 +225,11 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp return 0; } +static struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static const struct bt_bap_unicast_server_cb unicast_server_cb = { .config = lc3_config, .reconfig = lc3_reconfig, @@ -487,6 +492,13 @@ static void init(void) printk("Bluetooth initialized\n"); + err = bt_bap_unicast_server_register(¶m); + if (err != 0) { + FAIL("Failed to register unicast server (err %d)\n", err); + + return; + } + bt_bap_unicast_server_register_cb(&unicast_server_cb); err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap); diff --git a/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c b/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c index 4e7485b97d0da8a..6088da5b8475d5d 100644 --- a/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c @@ -88,8 +88,8 @@ static uint32_t bis_index_bitfield; #define UNICAST_CHANNEL_COUNT_1 BIT(0) -static struct bt_cap_stream unicast_streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + - CONFIG_BT_ASCS_ASE_SRC_COUNT]; +static struct bt_cap_stream unicast_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; CREATE_FLAG(flag_unicast_stream_configured); @@ -575,6 +575,11 @@ static int unicast_server_release(struct bt_bap_stream *stream, struct bt_bap_as return 0; } +static struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static struct bt_bap_unicast_server_cb unicast_server_cbs = { .config = unicast_server_config, .reconfig = unicast_server_reconfig, @@ -739,6 +744,13 @@ static void init(void) return; } + err = bt_bap_unicast_server_register(¶m); + if (err != 0) { + FAIL("Failed to register unicast server (err %d)\n", err); + + return; + } + err = bt_bap_unicast_server_register_cb(&unicast_server_cbs); if (err != 0) { FAIL("Failed to register unicast server callbacks (err %d)\n", diff --git a/tests/bsim/bluetooth/audio/src/gmap_ugt_test.c b/tests/bsim/bluetooth/audio/src/gmap_ugt_test.c index 4ac3c1cfe0e869e..09de70135fefa6b 100644 --- a/tests/bsim/bluetooth/audio/src/gmap_ugt_test.c +++ b/tests/bsim/bluetooth/audio/src/gmap_ugt_test.c @@ -48,7 +48,7 @@ static const struct bt_audio_codec_qos_pref unicast_qos_pref = #define UNICAST_CHANNEL_COUNT_1 BIT(0) static struct bt_cap_stream - unicast_streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; + unicast_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT]; CREATE_FLAG(flag_unicast_stream_started); CREATE_FLAG(flag_gmap_discovered); @@ -219,6 +219,11 @@ static int unicast_server_release(struct bt_bap_stream *stream, struct bt_bap_as return 0; } +static struct bt_bap_unicast_server_register_param param = { + CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT +}; + static struct bt_bap_unicast_server_cb unicast_server_cbs = { .config = unicast_server_config, .reconfig = unicast_server_reconfig, @@ -404,6 +409,13 @@ static void test_main(void) return; } + err = bt_bap_unicast_server_register(¶m); + if (err != 0) { + FAIL("Failed to register unicast server (err %d)\n", err); + + return; + } + err = bt_bap_unicast_server_register_cb(&unicast_server_cbs); if (err != 0) { FAIL("Failed to register unicast server callbacks (err %d)\n", err);