diff --git a/subsys/bluetooth/audio/CMakeLists.txt b/subsys/bluetooth/audio/CMakeLists.txt index 3e96eba69cf..568d68e2217 100644 --- a/subsys/bluetooth/audio/CMakeLists.txt +++ b/subsys/bluetooth/audio/CMakeLists.txt @@ -1,6 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() +zephyr_library_sources(audio.c) if (CONFIG_BT_VOCS OR CONFIG_BT_VOCS_CLIENT) zephyr_library_sources(vocs.c) diff --git a/subsys/bluetooth/audio/Kconfig.ascs b/subsys/bluetooth/audio/Kconfig.ascs index dd3db017ad5..64c5a22a792 100644 --- a/subsys/bluetooth/audio/Kconfig.ascs +++ b/subsys/bluetooth/audio/Kconfig.ascs @@ -8,7 +8,6 @@ config BT_ASCS bool "Audio Stream Control Service Support" - select BT_SMP_SC_PAIR_ONLY help This option enables support for Audio Stream Control Service. diff --git a/subsys/bluetooth/audio/Kconfig.bass b/subsys/bluetooth/audio/Kconfig.bass index c1c05c2f2ee..3356ffdc168 100644 --- a/subsys/bluetooth/audio/Kconfig.bass +++ b/subsys/bluetooth/audio/Kconfig.bass @@ -15,7 +15,6 @@ config BT_BASS select BT_OBSERVER select BT_EXT_ADV select BT_PER_ADV_SYNC - select BT_SMP_SC_PAIR_ONLY select BT_ISO_SYNC_RECEIVER help This option enables support for the Broadcast Audio Scan Service. diff --git a/subsys/bluetooth/audio/Kconfig.csis b/subsys/bluetooth/audio/Kconfig.csis index ab725ac5f7b..b845fc92761 100644 --- a/subsys/bluetooth/audio/Kconfig.csis +++ b/subsys/bluetooth/audio/Kconfig.csis @@ -31,7 +31,6 @@ config BT_CSIS_TEST_SAMPLE_DATA config BT_CSIS_ENC_SIRK_SUPPORT bool "Support for encrypted SIRK" default y - select BT_SMP_SC_PAIR_ONLY help Enables support encrypting the SIRK. @@ -92,7 +91,6 @@ config BT_CSIS_CLIENT_MAX_CSIS_INSTANCES config BT_CSIS_CLIENT_ENC_SIRK_SUPPORT bool "Support for encrypted SIRK" default y - select BT_SMP_SC_PAIR_ONLY help Enables support encrypting the SIRK. diff --git a/subsys/bluetooth/audio/Kconfig.has b/subsys/bluetooth/audio/Kconfig.has index db63cc9fe26..81ea6d1b38a 100644 --- a/subsys/bluetooth/audio/Kconfig.has +++ b/subsys/bluetooth/audio/Kconfig.has @@ -8,8 +8,6 @@ menuconfig BT_HAS bool "Hearing Access Service support [EXPERIMENTAL]" select EXPERIMENTAL select UTF8 - depends on BT_SMP_SC_PAIR_ONLY - depends on BT_SMP_MIN_ENC_KEY_SIZE = 16 depends on BT_AUDIO_UNICAST_SERVER help This option enables support for Hearing Access Service. diff --git a/subsys/bluetooth/audio/Kconfig.pacs b/subsys/bluetooth/audio/Kconfig.pacs index 58a004da6e2..db822ce9585 100644 --- a/subsys/bluetooth/audio/Kconfig.pacs +++ b/subsys/bluetooth/audio/Kconfig.pacs @@ -87,7 +87,6 @@ endif # BT_PAC_SRC config BT_PACS def_bool BT_PAC_SNK || BT_PAC_SRC - select BT_SMP_SC_PAIR_ONLY config BT_DEBUG_PACS bool "Published Audio Capabilities Service debug" diff --git a/subsys/bluetooth/audio/aics.c b/subsys/bluetooth/audio/aics.c index 5bda106ffd3..559e2a26f90 100644 --- a/subsys/bluetooth/audio/aics.c +++ b/subsys/bluetooth/audio/aics.c @@ -18,6 +18,7 @@ #include #include "aics_internal.h" +#include "audio_internal.h" #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_AICS) #define LOG_MODULE_NAME bt_aics @@ -65,36 +66,33 @@ static ssize_t read_description(struct bt_conn *conn, #define BT_AICS_SERVICE_DEFINITION(_aics) { \ BT_GATT_SECONDARY_SERVICE(BT_UUID_AICS), \ - BT_GATT_CHARACTERISTIC(BT_UUID_AICS_STATE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_LESC, \ - read_aics_state, NULL, &_aics), \ - BT_GATT_CCC(aics_state_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_LESC), \ - BT_GATT_CHARACTERISTIC(BT_UUID_AICS_GAIN_SETTINGS, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_LESC, \ - read_aics_gain_settings, NULL, &_aics), \ - BT_GATT_CHARACTERISTIC(BT_UUID_AICS_INPUT_TYPE, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_LESC, \ - read_type, NULL, &_aics), \ - BT_GATT_CHARACTERISTIC(BT_UUID_AICS_INPUT_STATUS, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_LESC, \ - read_input_status, NULL, &_aics), \ - BT_GATT_CCC(aics_input_status_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_LESC), \ - BT_GATT_CHARACTERISTIC(BT_UUID_AICS_CONTROL, \ - BT_GATT_CHRC_WRITE, \ - BT_GATT_PERM_WRITE_LESC, \ - NULL, write_aics_control, &_aics), \ - BT_GATT_CHARACTERISTIC(BT_UUID_AICS_DESCRIPTION, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_LESC, \ - read_description, NULL, &_aics), \ - BT_GATT_CCC(aics_description_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_LESC) \ + BT_AUDIO_CHRC(BT_UUID_AICS_STATE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_aics_state, NULL, &_aics), \ + BT_AUDIO_CCC(aics_state_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_AICS_GAIN_SETTINGS, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_aics_gain_settings, NULL, &_aics), \ + BT_AUDIO_CHRC(BT_UUID_AICS_INPUT_TYPE, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_type, NULL, &_aics), \ + BT_AUDIO_CHRC(BT_UUID_AICS_INPUT_STATUS, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_input_status, NULL, &_aics), \ + BT_AUDIO_CCC(aics_input_status_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_AICS_CONTROL, \ + BT_GATT_CHRC_WRITE, \ + BT_GATT_PERM_WRITE_ENCRYPT, \ + NULL, write_aics_control, &_aics), \ + BT_AUDIO_CHRC(BT_UUID_AICS_DESCRIPTION, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_description, write_description, &_aics), \ + BT_AUDIO_CCC(aics_description_cfg_changed) \ } @@ -114,7 +112,7 @@ static ssize_t read_aics_state(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_aics *inst = attr->user_data; + struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("gain %d, mute %u, gain_mode %u, counter %u", inst->srv.state.gain, inst->srv.state.mute, @@ -128,7 +126,7 @@ static ssize_t read_aics_gain_settings(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_aics *inst = attr->user_data; + struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("units %u, min %d, max %d", inst->srv.gain_settings.units, inst->srv.gain_settings.minimum, @@ -142,7 +140,7 @@ static ssize_t read_aics_gain_settings(struct bt_conn *conn, static ssize_t read_type(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_aics *inst = attr->user_data; + struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("%u", inst->srv.type); @@ -160,7 +158,7 @@ static ssize_t read_input_status(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_aics *inst = attr->user_data; + struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("%u", inst->srv.status); @@ -175,7 +173,7 @@ static ssize_t write_aics_control(struct bt_conn *conn, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { - struct bt_aics *inst = attr->user_data; + struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); const struct bt_aics_gain_control *cp = buf; bool notify = false; @@ -297,7 +295,7 @@ static ssize_t write_description(struct bt_conn *conn, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { - struct bt_aics *inst = attr->user_data; + struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); if (len >= sizeof(inst->srv.description)) { BT_DBG("Output desc was clipped from length %u to %zu", @@ -327,12 +325,35 @@ static ssize_t write_description(struct bt_conn *conn, return len; } +static int aics_write(struct bt_aics *inst, + ssize_t (*write)(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags), + const void *buf, uint16_t len) +{ + struct bt_audio_attr_user_data user_data = { + .user_data = inst, + }; + struct bt_gatt_attr attr = { + .user_data = &user_data, + }; + int err; + + err = write(NULL, &attr, buf, len, 0, 0); + if (err < 0) { + return err; + } + + return 0; +} + #if defined(CONFIG_BT_AICS) static ssize_t read_description(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_aics *inst = attr->user_data; + struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("%s", inst->srv.description); @@ -455,8 +476,7 @@ int bt_aics_register(struct bt_aics *aics, struct bt_aics_register_param *param) struct bt_gatt_chrc *chrc; chrc = aics->srv.service_p->attrs[i - 1].user_data; - attr->write = write_description; - attr->perm |= BT_GATT_PERM_WRITE_LESC; + attr->perm |= BT_GATT_PERM_WRITE_ENCRYPT; chrc->properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP; break; @@ -638,18 +658,12 @@ int bt_aics_unmute(struct bt_aics *inst) if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) { return bt_aics_client_unmute(inst); } else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) { - struct bt_gatt_attr attr; struct bt_aics_control cp; - int err; cp.opcode = BT_AICS_OPCODE_UNMUTE; cp.counter = inst->srv.state.change_counter; - attr.user_data = inst; - - err = write_aics_control(NULL, &attr, &cp, sizeof(cp), 0, 0); - - return err > 0 ? 0 : err; + return aics_write(inst, write_aics_control, &cp, sizeof(cp)); } return -ENOTSUP; @@ -665,18 +679,12 @@ int bt_aics_mute(struct bt_aics *inst) if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) { return bt_aics_client_mute(inst); } else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) { - struct bt_gatt_attr attr; struct bt_aics_control cp; - int err; cp.opcode = BT_AICS_OPCODE_MUTE; cp.counter = inst->srv.state.change_counter; - attr.user_data = inst; - - err = write_aics_control(NULL, &attr, &cp, sizeof(cp), 0, 0); - - return err > 0 ? 0 : err; + return aics_write(inst, write_aics_control, &cp, sizeof(cp)); } return -ENOTSUP; @@ -692,18 +700,12 @@ int bt_aics_manual_gain_set(struct bt_aics *inst) if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) { return bt_aics_client_manual_gain_set(inst); } else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) { - struct bt_gatt_attr attr; struct bt_aics_control cp; - int err; cp.opcode = BT_AICS_OPCODE_SET_MANUAL; cp.counter = inst->srv.state.change_counter; - attr.user_data = inst; - - err = write_aics_control(NULL, &attr, &cp, sizeof(cp), 0, 0); - - return err > 0 ? 0 : err; + return aics_write(inst, write_aics_control, &cp, sizeof(cp)); } return -ENOTSUP; @@ -719,18 +721,12 @@ int bt_aics_automatic_gain_set(struct bt_aics *inst) if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) { return bt_aics_client_automatic_gain_set(inst); } else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) { - struct bt_gatt_attr attr; struct bt_aics_control cp; - int err; cp.opcode = BT_AICS_OPCODE_SET_AUTO; cp.counter = inst->srv.state.change_counter; - attr.user_data = inst; - - err = write_aics_control(NULL, &attr, &cp, sizeof(cp), 0, 0); - - return err > 0 ? 0 : err; + return aics_write(inst, write_aics_control, &cp, sizeof(cp)); } return -ENOTSUP; @@ -746,19 +742,13 @@ int bt_aics_gain_set(struct bt_aics *inst, int8_t gain) if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) { return bt_aics_client_gain_set(inst, gain); } else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) { - struct bt_gatt_attr attr; struct bt_aics_gain_control cp; - int err; cp.cp.opcode = BT_AICS_OPCODE_SET_GAIN; cp.cp.counter = inst->srv.state.change_counter; cp.gain_setting = gain; - attr.user_data = inst; - - err = write_aics_control(NULL, &attr, &cp, sizeof(cp), 0, 0); - - return err > 0 ? 0 : err; + return aics_write(inst, write_aics_control, &cp, sizeof(cp)); } return -ENOTSUP; @@ -801,15 +791,7 @@ int bt_aics_description_set(struct bt_aics *inst, const char *description) if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) { return bt_aics_client_description_set(inst, description); } else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) { - struct bt_gatt_attr attr; - int err; - - attr.user_data = inst; - - err = write_description(NULL, &attr, description, - strlen(description), 0, 0); - - return err > 0 ? 0 : err; + return aics_write(inst, write_description, description, strlen(description)); } return -ENOTSUP; diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 0ed1a3a9b07..de351f750d2 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -27,6 +27,7 @@ #include "../host/hci_core.h" #include "../host/conn_internal.h" +#include "audio_internal.h" #include "endpoint.h" #include "unicast_server.h" #include "pacs_internal.h" @@ -932,7 +933,7 @@ static uint8_t ase_attr_cb(const struct bt_gatt_attr *attr, uint16_t handle, { struct bt_ascs_ase *ase = user_data; - if (ase->ep.status.id == POINTER_TO_UINT(attr->user_data)) { + if (ase->ep.status.id == POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr))) { ase->ep.server.attr = attr; return BT_GATT_ITER_STOP; @@ -1067,7 +1068,7 @@ static ssize_t ascs_ase_read(struct bt_conn *conn, return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); } - ase = ase_get(ascs, POINTER_TO_UINT(attr->user_data)); + ase = ase_get(ascs, POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr))); if (!ase) { BT_ERR("Unable to get ASE"); return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); @@ -2298,47 +2299,38 @@ respond: BT_GATT_SERVICE_DEFINE(ascs_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_ASCS), #if CONFIG_BT_ASCS_ASE_SNK_COUNT > 0 - BT_GATT_CHARACTERISTIC(BT_UUID_ASCS_ASE_SNK, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - ascs_ase_read, NULL, UINT_TO_POINTER(1)), - BT_GATT_CCC(ascs_ase_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_SNK, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + ascs_ase_read, NULL, UINT_TO_POINTER(1)), + BT_AUDIO_CCC(ascs_ase_cfg_changed), #endif #if CONFIG_BT_ASCS_ASE_SNK_COUNT > 1 - BT_GATT_CHARACTERISTIC(BT_UUID_ASCS_ASE_SNK, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - ascs_ase_read, NULL, UINT_TO_POINTER(2)), - BT_GATT_CCC(ascs_ase_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_SNK, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + ascs_ase_read, NULL, UINT_TO_POINTER(2)), + BT_AUDIO_CCC(ascs_ase_cfg_changed), #endif #if CONFIG_BT_ASCS_ASE_SRC_COUNT > 0 - BT_GATT_CHARACTERISTIC(BT_UUID_ASCS_ASE_SRC, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - ascs_ase_read, NULL, - UINT_TO_POINTER(CONFIG_BT_ASCS_ASE_SNK_COUNT + 1)), - BT_GATT_CCC(ascs_ase_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_SRC, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + ascs_ase_read, NULL, UINT_TO_POINTER(CONFIG_BT_ASCS_ASE_SNK_COUNT + 1)), + BT_AUDIO_CCC(ascs_ase_cfg_changed), #endif #if CONFIG_BT_ASCS_ASE_SRC_COUNT > 1 - BT_GATT_CHARACTERISTIC(BT_UUID_ASCS_ASE_SRC, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - ascs_ase_read, NULL, - UINT_TO_POINTER(CONFIG_BT_ASCS_ASE_SNK_COUNT + 2)), - BT_GATT_CCC(ascs_ase_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_SRC, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + ascs_ase_read, NULL, UINT_TO_POINTER(CONFIG_BT_ASCS_ASE_SNK_COUNT + 2)), + BT_AUDIO_CCC(ascs_ase_cfg_changed), #endif - BT_GATT_CHARACTERISTIC(BT_UUID_ASCS_ASE_CP, - BT_GATT_CHRC_WRITE | - BT_GATT_CHRC_WRITE_WITHOUT_RESP | - BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_WRITE_ENCRYPT, - NULL, ascs_cp_write, NULL), - BT_GATT_CCC(ascs_cp_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + 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, + NULL, ascs_cp_write, NULL), + BT_AUDIO_CCC(ascs_cp_cfg_changed), ); #endif /* BT_AUDIO_UNICAST_SERVER */ diff --git a/subsys/bluetooth/audio/audio.c b/subsys/bluetooth/audio/audio.c new file mode 100644 index 00000000000..18c03110f2b --- /dev/null +++ b/subsys/bluetooth/audio/audio.c @@ -0,0 +1,99 @@ +/* Common functions for LE Audio services */ + +/* + * Copyright (c) 2022 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "audio_internal.h" + +static uint8_t bt_audio_security_check(const struct bt_conn *conn) +{ + struct bt_conn_info info; + int err; + + err = bt_conn_get_info(conn, &info); + if (err < 0) { + return BT_ATT_ERR_UNLIKELY; + } + + /* Require an encryption key with at least 128 bits of entropy, derived from SC or OOB + * method. + */ + if ((info.security.flags & (BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC)) == 0) { + /* If the client has insufficient security to read/write the requested attribute + * then an ATT_ERROR_RSP PDU shall be sent with the Error Code parameter set to + * Insufficient Authentication (0x05). + */ + return BT_ATT_ERR_AUTHENTICATION; + } + + if (info.security.enc_key_size < BT_ENC_KEY_SIZE_MAX) { + return BT_ATT_ERR_ENCRYPTION_KEY_SIZE; + } + + return BT_ATT_ERR_SUCCESS; +} + +ssize_t bt_audio_read_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + const struct bt_audio_attr_user_data *user_data = attr->user_data; + + if (user_data->read == NULL) { + return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED); + } + + if (conn != NULL) { + uint8_t err; + + err = bt_audio_security_check(conn); + if (err != 0) { + return BT_GATT_ERR(err); + } + } + + return user_data->read(conn, attr, buf, len, offset); +} + +ssize_t bt_audio_write_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, uint16_t offset, uint8_t flags) +{ + const struct bt_audio_attr_user_data *user_data = attr->user_data; + + if (user_data->write == NULL) { + return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED); + } + + if (conn != NULL) { + uint8_t err; + + err = bt_audio_security_check(conn); + if (err != 0) { + return BT_GATT_ERR(err); + } + } + + return user_data->write(conn, attr, buf, len, offset, flags); +} + +ssize_t bt_audio_ccc_cfg_write(struct bt_conn *conn, const struct bt_gatt_attr *attr, + uint16_t value) +{ + if (conn != NULL) { + uint8_t err; + + err = bt_audio_security_check(conn); + if (err != 0) { + return BT_GATT_ERR(err); + } + } + + return sizeof(value); +} diff --git a/subsys/bluetooth/audio/audio_internal.h b/subsys/bluetooth/audio/audio_internal.h new file mode 100644 index 00000000000..2f440c64ace --- /dev/null +++ b/subsys/bluetooth/audio/audio_internal.h @@ -0,0 +1,60 @@ +/* @file + * @brief Internal APIs for LE Audio + * + * Copyright (c) 2022 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/** @brief LE Audio Attribute User Data. */ +struct bt_audio_attr_user_data { + /** Attribute read callback */ + ssize_t (*read)(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset); + + /** Attribute write callback */ + ssize_t (*write)(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, uint16_t offset, + uint8_t flags); + + /** Attribute user data */ + void *user_data; +}; + +/** LE Audio Read Characteristic value helper. */ +ssize_t bt_audio_read_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset); + +/** LE Audio Write Characteristic value helper. */ +ssize_t bt_audio_write_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, uint16_t offset, uint8_t flags); + +#define BT_AUDIO_ATTR_USER_DATA_INIT(_read, _write, _user_data) \ +{ \ + .read = _read, \ + .write = _write, \ + .user_data = _user_data, \ +} + +/** Helper to define LE Audio characteristic. */ +#define BT_AUDIO_CHRC(_uuid, _props, _perm, _read, _write, _user_data) \ + BT_GATT_CHARACTERISTIC(_uuid, _props, _perm, bt_audio_read_chrc, bt_audio_write_chrc, \ + ((struct bt_audio_attr_user_data[]) { \ + BT_AUDIO_ATTR_USER_DATA_INIT(_read, _write, _user_data), \ + })) + +#define BT_AUDIO_CHRC_USER_DATA(_attr) \ + (((struct bt_audio_attr_user_data *)(_attr)->user_data)->user_data) + +/** LE Audio Write CCCD value helper. */ +ssize_t bt_audio_ccc_cfg_write(struct bt_conn *conn, const struct bt_gatt_attr *attr, + uint16_t value); + +/** Helper to define LE Audio CCC descriptor. */ +#define BT_AUDIO_CCC(_changed) \ + BT_GATT_CCC_MANAGED(((struct _bt_gatt_ccc[]) \ + {BT_GATT_CCC_INITIALIZER(_changed, bt_audio_ccc_cfg_write, NULL)}), \ + (BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT)) diff --git a/subsys/bluetooth/audio/bass.c b/subsys/bluetooth/audio/bass.c index 5f8f6758bba..e01df9aed16 100644 --- a/subsys/bluetooth/audio/bass.c +++ b/subsys/bluetooth/audio/bass.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -23,6 +24,7 @@ #define LOG_MODULE_NAME bt_bass #include "common/log.h" +#include "audio_internal.h" #include "bass_internal.h" #include "../host/conn_internal.h" #include "../host/hci_core.h" @@ -1223,7 +1225,7 @@ static ssize_t read_recv_state(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - uint8_t idx = (uint8_t)(uintptr_t)attr->user_data; + uint8_t idx = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr)); struct bass_recv_state_internal *recv_state = &bass_inst.recv_states[idx]; struct bt_bass_recv_state *state = &recv_state->state; @@ -1244,19 +1246,18 @@ static ssize_t read_recv_state(struct bt_conn *conn, } #define RECEIVE_STATE_CHARACTERISTIC(idx) \ - BT_GATT_CHARACTERISTIC(BT_UUID_BASS_RECV_STATE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,\ - BT_GATT_PERM_READ_ENCRYPT, \ - read_recv_state, NULL, (void *)idx), \ - BT_GATT_CCC(recv_state_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_BASS_RECV_STATE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,\ + BT_GATT_PERM_READ_ENCRYPT, \ + read_recv_state, NULL, UINT_TO_POINTER(idx)), \ + BT_AUDIO_CCC(recv_state_cfg_changed) BT_GATT_SERVICE_DEFINE(bass_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_BASS), - BT_GATT_CHARACTERISTIC(BT_UUID_BASS_CONTROL_POINT, - BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_WRITE, - BT_GATT_PERM_WRITE_ENCRYPT, - NULL, write_control_point, NULL), + BT_AUDIO_CHRC(BT_UUID_BASS_CONTROL_POINT, + BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_WRITE, + BT_GATT_PERM_WRITE_ENCRYPT, + NULL, write_control_point, NULL), RECEIVE_STATE_CHARACTERISTIC(0), #if CONFIG_BT_BASS_RECV_STATE_COUNT > 1 RECEIVE_STATE_CHARACTERISTIC(1), diff --git a/subsys/bluetooth/audio/csis.c b/subsys/bluetooth/audio/csis.c index 2e130a81221..93455c0f2db 100644 --- a/subsys/bluetooth/audio/csis.c +++ b/subsys/bluetooth/audio/csis.c @@ -20,6 +20,8 @@ #include #include #include + +#include "audio_internal.h" #include "csis_internal.h" #include "csis_crypto.h" #include "../host/conn_internal.h" @@ -298,7 +300,7 @@ static ssize_t read_set_sirk(struct bt_conn *conn, { struct bt_csis_set_sirk enc_sirk; struct bt_csis_set_sirk *sirk; - struct bt_csis *csis = attr->user_data; + struct bt_csis *csis = BT_AUDIO_CHRC_USER_DATA(attr); if (csis->srv.cb != NULL && csis->srv.cb->sirk_read_req != NULL) { uint8_t cb_rsp; @@ -354,7 +356,7 @@ static ssize_t read_set_size(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_csis *csis = attr->user_data; + struct bt_csis *csis = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("%u", csis->srv.set_size); @@ -373,7 +375,7 @@ static ssize_t read_set_lock(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_csis *csis = attr->user_data; + struct bt_csis *csis = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("%u", csis->srv.set_lock); @@ -389,7 +391,7 @@ static ssize_t write_set_lock(struct bt_conn *conn, { uint8_t val; bool notify; - struct bt_csis *csis = attr->user_data; + struct bt_csis *csis = BT_AUDIO_CHRC_USER_DATA(attr); if (offset != 0) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); @@ -460,7 +462,7 @@ static void set_lock_cfg_changed(const struct bt_gatt_attr *attr, static ssize_t read_rank(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_csis *csis = attr->user_data; + struct bt_csis *csis = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("%u", csis->srv.rank); @@ -792,31 +794,25 @@ static void adv_connected(struct bt_le_ext_adv *adv, #define BT_CSIS_SERVICE_DEFINITION(_csis) {\ BT_GATT_PRIMARY_SERVICE(BT_UUID_CSIS), \ - BT_GATT_CHARACTERISTIC(BT_UUID_CSIS_SET_SIRK, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_set_sirk, NULL, &_csis), \ - BT_GATT_CCC(set_sirk_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_CSIS_SET_SIZE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_set_size, NULL, &_csis), \ - BT_GATT_CCC(set_size_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_CSIS_SET_LOCK, \ - BT_GATT_CHRC_READ | \ - BT_GATT_CHRC_NOTIFY | \ - BT_GATT_CHRC_WRITE, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_set_lock, write_set_lock, &_csis), \ - BT_GATT_CCC(set_lock_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_CSIS_RANK, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_rank, NULL, &_csis) \ + BT_AUDIO_CHRC(BT_UUID_CSIS_SET_SIRK, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_set_sirk, NULL, &_csis), \ + BT_AUDIO_CCC(set_sirk_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_CSIS_SET_SIZE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_set_size, NULL, &_csis), \ + BT_AUDIO_CCC(set_size_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_CSIS_SET_LOCK, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_WRITE, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_set_lock, write_set_lock, &_csis), \ + BT_AUDIO_CCC(set_lock_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_CSIS_RANK, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_rank, NULL, &_csis) \ } BT_GATT_SERVICE_INSTANCE_DEFINE(csis_service_list, csis_insts, diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index dc0ee529713..c548483582c 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -18,6 +18,7 @@ #include "../bluetooth/host/conn_internal.h" #include "../bluetooth/host/hci_core.h" +#include "audio_internal.h" #include "has_internal.h" #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HAS) @@ -71,21 +72,25 @@ static ssize_t read_features(struct bt_conn *conn, const struct bt_gatt_attr *at /* Hearing Access Service GATT Attributes */ BT_GATT_SERVICE_DEFINE(has_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_HAS), - BT_GATT_CHARACTERISTIC(BT_UUID_HAS_HEARING_AID_FEATURES, BT_GATT_CHRC_READ, - BT_GATT_PERM_READ_ENCRYPT, read_features, NULL, NULL), + BT_AUDIO_CHRC(BT_UUID_HAS_HEARING_AID_FEATURES, + BT_GATT_CHRC_READ, + BT_GATT_PERM_READ_ENCRYPT, + read_features, NULL, NULL), #if defined(CONFIG_BT_HAS_PRESET_SUPPORT) - BT_GATT_CHARACTERISTIC(BT_UUID_HAS_PRESET_CONTROL_POINT, + BT_AUDIO_CHRC(BT_UUID_HAS_PRESET_CONTROL_POINT, #if defined(CONFIG_BT_EATT) - BT_GATT_CHRC_WRITE | BT_GATT_CHRC_INDICATE | BT_GATT_CHRC_NOTIFY, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_INDICATE | BT_GATT_CHRC_NOTIFY, #else - BT_GATT_CHRC_WRITE | BT_GATT_CHRC_INDICATE, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_INDICATE, #endif /* CONFIG_BT_EATT */ - BT_GATT_PERM_WRITE_ENCRYPT, NULL, write_control_point, NULL), - BT_GATT_CCC(ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), - BT_GATT_CHARACTERISTIC(BT_UUID_HAS_ACTIVE_PRESET_INDEX, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ_ENCRYPT, - read_active_preset_index, NULL, NULL), - BT_GATT_CCC(ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_GATT_PERM_WRITE_ENCRYPT, + NULL, write_control_point, NULL), + BT_AUDIO_CCC(ccc_cfg_changed), + BT_AUDIO_CHRC(BT_UUID_HAS_ACTIVE_PRESET_INDEX, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + read_active_preset_index, NULL, NULL), + BT_AUDIO_CCC(ccc_cfg_changed), #endif /* CONFIG_BT_HAS_PRESET_SUPPORT */ ); diff --git a/subsys/bluetooth/audio/mcs.c b/subsys/bluetooth/audio/mcs.c index 551f5460d48..0638f8672ab 100644 --- a/subsys/bluetooth/audio/mcs.c +++ b/subsys/bluetooth/audio/mcs.c @@ -23,6 +23,7 @@ #include #include +#include "audio_internal.h" #include "media_proxy_internal.h" #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_MCS) @@ -620,62 +621,49 @@ static ssize_t read_content_ctrl_id(struct bt_conn *conn, /* Defines for OTS-dependent characteristics - empty if no OTS */ #ifdef CONFIG_BT_OTS #define ICON_OBJ_ID_CHARACTERISTIC_IF_OTS \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_ICON_OBJ_ID, \ - BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, \ - read_icon_id, NULL, NULL), + BT_AUDIO_CHRC(BT_UUID_MCS_ICON_OBJ_ID, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_icon_id, NULL, NULL), #define SEGMENTS_TRACK_GROUP_ID_CHARACTERISTICS_IF_OTS \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_TRACK_SEGMENTS_OBJ_ID, \ - BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, \ - read_track_segments_id, NULL, NULL), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_CURRENT_TRACK_OBJ_ID, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_current_track_id, write_current_track_id, \ - NULL), \ - BT_GATT_CCC(current_track_id_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_NEXT_TRACK_OBJ_ID, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_next_track_id, write_next_track_id, NULL), \ - BT_GATT_CCC(next_track_id_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_PARENT_GROUP_OBJ_ID, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_parent_group_id, NULL, NULL), \ - BT_GATT_CCC(parent_group_id_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_CURRENT_GROUP_OBJ_ID, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_current_group_id, write_current_group_id, NULL), \ - BT_GATT_CCC(current_group_id_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_MCS_TRACK_SEGMENTS_OBJ_ID, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_track_segments_id, NULL, NULL), \ + BT_AUDIO_CHRC(BT_UUID_MCS_CURRENT_TRACK_OBJ_ID, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ + BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_current_track_id, write_current_track_id, NULL), \ + BT_AUDIO_CCC(current_track_id_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_NEXT_TRACK_OBJ_ID, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ + BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_next_track_id, write_next_track_id, NULL), \ + BT_AUDIO_CCC(next_track_id_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_PARENT_GROUP_OBJ_ID, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_parent_group_id, NULL, NULL), \ + BT_AUDIO_CCC(parent_group_id_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_CURRENT_GROUP_OBJ_ID, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ + BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_current_group_id, write_current_group_id, NULL), \ + BT_AUDIO_CCC(current_group_id_cfg_changed), #define SEARCH_CHARACTERISTICS_IF_OTS \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_SEARCH_CONTROL_POINT, \ - BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - NULL, write_search_control_point, NULL), \ - BT_GATT_CCC(search_control_point_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_SEARCH_RESULTS_OBJ_ID, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_search_results_id, NULL, NULL), \ - BT_GATT_CCC(search_results_id_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_MCS_SEARCH_CONTROL_POINT, \ + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_WRITE_ENCRYPT, \ + NULL, write_search_control_point, NULL), \ + BT_AUDIO_CCC(search_control_point_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_SEARCH_RESULTS_OBJ_ID, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_search_results_id, NULL, NULL), \ + BT_AUDIO_CCC(search_results_id_cfg_changed), #else #define ICON_OBJ_ID_CHARACTERISTIC_IF_OTS @@ -687,97 +675,79 @@ static ssize_t read_content_ctrl_id(struct bt_conn *conn, #define BT_MCS_SERVICE_DEFINITION \ BT_GATT_PRIMARY_SERVICE(BT_UUID_GMCS), \ BT_GATT_INCLUDE_SERVICE(NULL), /* To be overwritten */ \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_PLAYER_NAME, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_player_name, NULL, NULL), \ - BT_GATT_CCC(player_name_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ + BT_AUDIO_CHRC(BT_UUID_MCS_PLAYER_NAME, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_player_name, NULL, NULL), \ + BT_AUDIO_CCC(player_name_cfg_changed), \ ICON_OBJ_ID_CHARACTERISTIC_IF_OTS \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_ICON_URL, \ - BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, \ - read_icon_url, NULL, NULL), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_TRACK_CHANGED, \ - BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_NONE, \ - NULL, NULL, NULL), \ - BT_GATT_CCC(track_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_TRACK_TITLE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_track_title, NULL, NULL), \ - BT_GATT_CCC(track_title_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_TRACK_DURATION, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_track_duration, NULL, NULL), \ - BT_GATT_CCC(track_duration_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_TRACK_POSITION, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_track_position, \ - write_track_position, NULL), \ - BT_GATT_CCC(track_position_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_PLAYBACK_SPEED, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_playback_speed, write_playback_speed, \ - NULL), \ - BT_GATT_CCC(playback_speed_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_SEEKING_SPEED, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_seeking_speed, NULL, NULL), \ - BT_GATT_CCC(seeking_speed_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ + BT_AUDIO_CHRC(BT_UUID_MCS_ICON_URL, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_icon_url, NULL, NULL), \ + BT_AUDIO_CHRC(BT_UUID_MCS_TRACK_CHANGED, \ + BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_NONE, \ + NULL, NULL, NULL), \ + BT_AUDIO_CCC(track_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_TRACK_TITLE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_track_title, NULL, NULL), \ + BT_AUDIO_CCC(track_title_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_TRACK_DURATION, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_track_duration, NULL, NULL), \ + BT_AUDIO_CCC(track_duration_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_TRACK_POSITION, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ + BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_track_position, write_track_position, NULL), \ + BT_AUDIO_CCC(track_position_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_PLAYBACK_SPEED, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ + BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_playback_speed, write_playback_speed, NULL), \ + BT_AUDIO_CCC(playback_speed_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_SEEKING_SPEED, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_seeking_speed, NULL, NULL), \ + BT_AUDIO_CCC(seeking_speed_cfg_changed), \ SEGMENTS_TRACK_GROUP_ID_CHARACTERISTICS_IF_OTS \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_PLAYING_ORDER, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_playing_order, write_playing_order, NULL), \ - BT_GATT_CCC(playing_order_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_PLAYING_ORDERS, \ - BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, \ - read_playing_orders_supported, NULL, NULL), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_MEDIA_STATE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_media_state, NULL, NULL), \ - BT_GATT_CCC(media_state_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_MEDIA_CONTROL_POINT, \ - BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP | \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - NULL, write_control_point, NULL), \ - BT_GATT_CCC(control_point_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_MCS_MEDIA_CONTROL_OPCODES, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_opcodes_supported, NULL, NULL), \ - BT_GATT_CCC(opcodes_supported_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ + BT_AUDIO_CHRC(BT_UUID_MCS_PLAYING_ORDER, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ + BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_playing_order, write_playing_order, NULL), \ + BT_AUDIO_CCC(playing_order_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_PLAYING_ORDERS, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_playing_orders_supported, NULL, NULL), \ + BT_AUDIO_CHRC(BT_UUID_MCS_MEDIA_STATE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_media_state, NULL, NULL), \ + BT_AUDIO_CCC(media_state_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_MEDIA_CONTROL_POINT, \ + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_WRITE_ENCRYPT, \ + NULL, write_control_point, NULL), \ + BT_AUDIO_CCC(control_point_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_MCS_MEDIA_CONTROL_OPCODES, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_opcodes_supported, NULL, NULL), \ + BT_AUDIO_CCC(opcodes_supported_cfg_changed), \ SEARCH_CHARACTERISTICS_IF_OTS \ - BT_GATT_CHARACTERISTIC(BT_UUID_CCID, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_content_ctrl_id, NULL, NULL) + BT_AUDIO_CHRC(BT_UUID_CCID, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_content_ctrl_id, NULL, NULL) static struct bt_gatt_attr svc_attrs[] = { BT_MCS_SERVICE_DEFINITION }; static struct bt_gatt_service mcs; diff --git a/subsys/bluetooth/audio/micp_mic_dev.c b/subsys/bluetooth/audio/micp_mic_dev.c index a132c32edc6..3b882b4d744 100644 --- a/subsys/bluetooth/audio/micp_mic_dev.c +++ b/subsys/bluetooth/audio/micp_mic_dev.c @@ -19,6 +19,8 @@ #include #include +#include "audio_internal.h" + #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_MICP_MIC_DEV) #define LOG_MODULE_NAME bt_micp #include "common/log.h" @@ -94,12 +96,11 @@ static ssize_t write_mute(struct bt_conn *conn, const struct bt_gatt_attr *attr, #define BT_MICP_SERVICE_DEFINITION \ BT_GATT_PRIMARY_SERVICE(BT_UUID_MICS), \ AICS_INCLUDES(CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT) \ - BT_GATT_CHARACTERISTIC(BT_UUID_MICS_MUTE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ - read_mute, write_mute, NULL), \ - BT_GATT_CCC(mute_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_MICS_MUTE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_mute, write_mute, NULL), \ + BT_AUDIO_CCC(mute_cfg_changed) #define MICS_ATTR_COUNT \ ARRAY_SIZE(((struct bt_gatt_attr []){ BT_MICP_SERVICE_DEFINITION })) diff --git a/subsys/bluetooth/audio/pacs.c b/subsys/bluetooth/audio/pacs.c index 05264b8daa2..aea7e3963fc 100644 --- a/subsys/bluetooth/audio/pacs.c +++ b/subsys/bluetooth/audio/pacs.c @@ -27,6 +27,7 @@ #define LOG_MODULE_NAME bt_pacs #include "common/log.h" +#include "audio_internal.h" #include "pacs_internal.h" #include "unicast_server.h" @@ -437,63 +438,53 @@ static void src_loc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) BT_GATT_SERVICE_DEFINE(pacs_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_PACS), #if defined(CONFIG_BT_PAC_SNK) - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SNK, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - snk_read, NULL, NULL), - BT_GATT_CCC(snk_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_PACS_SNK, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + snk_read, NULL, NULL), + BT_AUDIO_CCC(snk_cfg_changed), #if defined(CONFIG_BT_PAC_SNK_LOC_WRITEABLE) - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SNK_LOC, - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | - BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT | - BT_GATT_PERM_WRITE_ENCRYPT, - snk_loc_read, snk_loc_write, NULL), + BT_AUDIO_CHRC(BT_UUID_PACS_SNK_LOC, + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, + snk_loc_read, snk_loc_write, NULL), #elif defined(CONFIG_BT_PAC_SNK_LOC) - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SNK_LOC, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - snk_loc_read, NULL, NULL), + BT_AUDIO_CHRC(BT_UUID_PACS_SNK_LOC, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + snk_loc_read, NULL, NULL), #endif /* CONFIG_BT_PAC_SNK_LOC_WRITEABLE */ - BT_GATT_CCC(snk_loc_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CCC(snk_loc_cfg_changed), #endif /* CONFIG_BT_PAC_SNK */ #if defined(CONFIG_BT_PAC_SRC) - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - src_read, NULL, NULL), - BT_GATT_CCC(src_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CHRC(BT_UUID_PACS_SRC, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + src_read, NULL, NULL), + BT_AUDIO_CCC(src_cfg_changed), #if defined(CONFIG_BT_PAC_SRC_LOC_WRITEABLE) - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC_LOC, - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | - BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT | - BT_GATT_PERM_WRITE_ENCRYPT, - src_loc_read, src_loc_write, NULL), + BT_AUDIO_CHRC(BT_UUID_PACS_SRC_LOC, + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT BT_GATT_PERM_WRITE_ENCRYPT, + src_loc_read, src_loc_write, NULL), #elif defined(CONFIG_BT_PAC_SRC_LOC) - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC_LOC, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - src_loc_read, NULL, NULL), + BT_AUDIO_CHRC(BT_UUID_PACS_SRC_LOC, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + src_loc_read, NULL, NULL), #endif /* CONFIG_BT_PAC_SRC_LOC_WRITEABLE */ - BT_GATT_CCC(src_loc_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), + BT_AUDIO_CCC(src_loc_cfg_changed), #endif /* CONFIG_BT_PAC_SRC */ - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_AVAILABLE_CONTEXT, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - available_contexts_read, NULL, NULL), - BT_GATT_CCC(available_context_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), - BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SUPPORTED_CONTEXT, - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, - supported_context_read, NULL, NULL), - BT_GATT_CCC(supported_context_cfg_changed, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_PACS_AVAILABLE_CONTEXT, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + available_contexts_read, NULL, NULL), + BT_AUDIO_CCC(available_context_cfg_changed), + BT_AUDIO_CHRC(BT_UUID_PACS_SUPPORTED_CONTEXT, + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ_ENCRYPT, + supported_context_read, NULL, NULL), + BT_AUDIO_CCC(supported_context_cfg_changed) ); static struct k_work_delayable *bt_pacs_get_work(enum bt_audio_dir dir) diff --git a/subsys/bluetooth/audio/tbs.c b/subsys/bluetooth/audio/tbs.c index ce1c4bac90f..c028047e1f3 100644 --- a/subsys/bluetooth/audio/tbs.c +++ b/subsys/bluetooth/audio/tbs.c @@ -17,6 +17,7 @@ #include #include +#include "audio_internal.h" #include "tbs_internal.h" #include "ccid_internal.h" @@ -25,6 +26,8 @@ #include "common/log.h" #define BT_TBS_VALID_STATUS_FLAGS(val) ((val) <= (BIT(0) | BIT(1))) +#define IS_GTBS_CHRC(_attr) \ + IS_ENABLED(CONFIG_BT_GTBS) && BT_AUDIO_CHRC_USER_DATA(_attr) == >bs_inst /* TODO: Have tbs_service_inst include gtbs_service_inst and use CONTAINER_OF * to get a specific TBS instance from a GTBS pointer. @@ -500,11 +503,11 @@ static ssize_t read_provider_name(struct bt_conn *conn, { const char *provider_name; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { provider_name = gtbs_inst.provider_name; BT_DBG("GTBS: Provider name %s", provider_name); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); provider_name = inst->provider_name; BT_DBG("Index %u, Provider name %s", @@ -533,11 +536,11 @@ static ssize_t read_uci(struct bt_conn *conn, const struct bt_gatt_attr *attr, { const char *uci; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { uci = gtbs_inst.uci; BT_DBG("GTBS: UCI %s", uci); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); uci = inst->uci; BT_DBG("Index %u: UCI %s", inst->index, uci); @@ -553,11 +556,11 @@ static ssize_t read_technology(struct bt_conn *conn, { uint8_t technology; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { technology = gtbs_inst.technology; BT_DBG("GTBS: Technology 0x%02X", technology); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); technology = inst->technology; BT_DBG("Index %u: Technology 0x%02X", inst->index, technology); @@ -585,7 +588,7 @@ static ssize_t read_uri_scheme_list(struct bt_conn *conn, { net_buf_simple_reset(&read_buf); - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { /* TODO: Make uri schemes unique */ for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) { size_t uri_len = strlen(svc_insts[i].uri_scheme_list); @@ -604,7 +607,7 @@ static ssize_t read_uri_scheme_list(struct bt_conn *conn, read_buf.data[read_buf.len] = '\0'; BT_DBG("GTBS: URI scheme %s", read_buf.data); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); net_buf_simple_add_mem(&read_buf, inst->uri_scheme_list, strlen(inst->uri_scheme_list)); @@ -636,11 +639,11 @@ static ssize_t read_signal_strength(struct bt_conn *conn, { uint8_t signal_strength; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { signal_strength = gtbs_inst.signal_strength; BT_DBG("GTBS: Signal strength 0x%02x", signal_strength); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); signal_strength = inst->signal_strength; BT_DBG("Index %u: Signal strength 0x%02x", @@ -674,12 +677,12 @@ static ssize_t read_signal_strength_interval(struct bt_conn *conn, return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION); } - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { signal_strength_interval = gtbs_inst.signal_strength_interval; BT_DBG("GTBS: Signal strength interval 0x%02x", signal_strength_interval); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); signal_strength_interval = inst->signal_strength_interval; BT_DBG("Index %u: Signal strength interval 0x%02x", @@ -714,11 +717,11 @@ static ssize_t write_signal_strength_interval(struct bt_conn *conn, net_buf_simple_init_with_data(&net_buf, (void *)buf, len); signal_strength_interval = net_buf_simple_pull_u8(&net_buf); - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { gtbs_inst.signal_strength_interval = signal_strength_interval; BT_DBG("GTBS: 0x%02x", signal_strength_interval); } else { - struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); inst->signal_strength_interval = signal_strength_interval; BT_DBG("Index %u: 0x%02x", @@ -746,12 +749,12 @@ static ssize_t read_current_calls(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - net_buf_put_current_calls(attr->user_data); + net_buf_put_current_calls(BT_AUDIO_CHRC_USER_DATA(attr)); - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { BT_DBG("GTBS"); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("Index %u", inst->index); } @@ -770,11 +773,11 @@ static ssize_t read_ccid(struct bt_conn *conn, { uint8_t ccid; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { ccid = gtbs_inst.ccid; BT_DBG("GTBS: CCID 0x%02X", ccid); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); ccid = inst->ccid; BT_DBG("Index %u: CCID 0x%02X", inst->index, ccid); @@ -790,11 +793,11 @@ static ssize_t read_status_flags(struct bt_conn *conn, { uint16_t status_flags; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { status_flags = gtbs_inst.status_flags; BT_DBG("GTBS: status_flags 0x%04X", status_flags); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); status_flags = inst->status_flags; BT_DBG("Index %u: status_flags 0x%04X", @@ -825,13 +828,13 @@ static ssize_t read_incoming_uri(struct bt_conn *conn, const struct bt_tbs_in_uri *inc_call_target; size_t val_len; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { inc_call_target = >bs_inst.incoming_uri; BT_DBG("GTBS: call index 0x%02X, URI %s", inc_call_target->call_index, inc_call_target->uri); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); inc_call_target = &inst->incoming_uri; BT_DBG("Index %u: call index 0x%02X, URI %s", @@ -868,12 +871,12 @@ static ssize_t read_call_state(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - net_buf_put_call_state(attr->user_data); + net_buf_put_call_state(BT_AUDIO_CHRC_USER_DATA(attr)); - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { BT_DBG("GTBS"); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("Index %u", inst->index); } @@ -1278,8 +1281,7 @@ static ssize_t write_call_cp(struct bt_conn *conn, const union bt_tbs_call_cp_t *ccp = (union bt_tbs_call_cp_t *)buf; uint8_t status; uint8_t call_index = 0; - const bool is_gtbs = IS_ENABLED(CONFIG_BT_GTBS) && - attr->user_data == >bs_inst; + const bool is_gtbs = IS_GTBS_CHRC(attr); if (!is_authorized(conn)) { return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION); @@ -1297,7 +1299,8 @@ static ssize_t write_call_cp(struct bt_conn *conn, BT_DBG("GTBS: Processing the %s opcode", bt_tbs_opcode_str(ccp->opcode)); } else { - inst = (struct tbs_service_inst *)attr->user_data; + inst = BT_AUDIO_CHRC_USER_DATA(attr); + BT_DBG("Index %u: Processing the %s opcode", inst->index, bt_tbs_opcode_str(ccp->opcode)); } @@ -1485,11 +1488,11 @@ static ssize_t read_optional_opcodes(struct bt_conn *conn, { uint16_t optional_opcodes; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { optional_opcodes = gtbs_inst.optional_opcodes; BT_DBG("GTBS: Supported opcodes 0x%02x", optional_opcodes); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); optional_opcodes = inst->optional_opcodes; BT_DBG("Index %u: Supported opcodes 0x%02x", @@ -1519,13 +1522,13 @@ static ssize_t read_friendly_name(struct bt_conn *conn, const struct bt_tbs_in_uri *friendly_name; size_t val_len; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { friendly_name = >bs_inst.friendly_name; BT_DBG("GTBS: call index 0x%02X, URI %s", friendly_name->call_index, friendly_name->uri); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); friendly_name = &inst->friendly_name; BT_DBG("Index %u: call index 0x%02X, URI %s", @@ -1564,12 +1567,12 @@ static ssize_t read_incoming_call(struct bt_conn *conn, const struct bt_tbs_in_uri *remote_uri; size_t val_len; - if (IS_ENABLED(CONFIG_BT_GTBS) && attr->user_data == >bs_inst) { + if (IS_GTBS_CHRC(attr)) { remote_uri = >bs_inst.in_call; BT_DBG("GTBS: call index 0x%02X, URI %s", remote_uri->call_index, remote_uri->uri); } else { - const struct tbs_service_inst *inst = (struct tbs_service_inst *)attr->user_data; + const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr); remote_uri = &inst->in_call; BT_DBG("Index %u: call index 0x%02X, URI %s", @@ -1602,128 +1605,112 @@ static void in_call_cfg_changed(const struct bt_gatt_attr *attr, } #define BT_TBS_CHR_PROVIDER_NAME(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_PROVIDER_NAME, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_provider_name, NULL, inst), \ - BT_GATT_CCC(provider_name_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_PROVIDER_NAME, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_provider_name, NULL, inst), \ + BT_AUDIO_CCC(provider_name_cfg_changed) #define BT_TBS_CHR_UCI(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_UCI, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_uci, NULL, inst) + BT_AUDIO_CHRC(BT_UUID_TBS_UCI, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_uci, NULL, inst) #define BT_TBS_CHR_TECHNOLOGY(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_TECHNOLOGY, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_technology, NULL, inst), \ - BT_GATT_CCC(technology_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_TECHNOLOGY, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_technology, NULL, inst), \ + BT_AUDIO_CCC(technology_cfg_changed) #define BT_TBS_CHR_URI_LIST(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_URI_LIST, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_uri_scheme_list, NULL, inst), \ - BT_GATT_CCC(uri_scheme_list_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_URI_LIST, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_uri_scheme_list, NULL, inst), \ + BT_AUDIO_CCC(uri_scheme_list_cfg_changed) #define BT_TBS_CHR_SIGNAL_STRENGTH(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_SIGNAL_STRENGTH, /* Optional */ \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_signal_strength, NULL, inst), \ - BT_GATT_CCC(signal_strength_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_STRENGTH, /* Optional */ \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_signal_strength, NULL, inst), \ + BT_AUDIO_CCC(signal_strength_cfg_changed) #define BT_TBS_CHR_SIGNAL_INTERVAL(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_SIGNAL_INTERVAL, /* Conditional */ \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP, \ - BT_GATT_PERM_READ_ENCRYPT | \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - read_signal_strength_interval, \ - write_signal_strength_interval, inst) + BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_INTERVAL, /* Conditional */ \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \ + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ + read_signal_strength_interval, write_signal_strength_interval, inst) #define BT_TBS_CHR_CURRENT_CALLS(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_LIST_CURRENT_CALLS, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_current_calls, NULL, inst), \ - BT_GATT_CCC(current_calls_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_LIST_CURRENT_CALLS, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_current_calls, NULL, inst), \ + BT_AUDIO_CCC(current_calls_cfg_changed) #define BT_TBS_CHR_CCID(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_CCID, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_ccid, NULL, inst) + BT_AUDIO_CHRC(BT_UUID_CCID, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_ccid, NULL, inst) #define BT_TBS_CHR_STATUS_FLAGS(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_STATUS_FLAGS, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_status_flags, NULL, inst), \ - BT_GATT_CCC(status_flags_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_STATUS_FLAGS, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_status_flags, NULL, inst), \ + BT_AUDIO_CCC(status_flags_cfg_changed) #define BT_TBS_CHR_INCOMING_URI(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_INCOMING_URI, /* Optional */ \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_incoming_uri, NULL, inst), \ - BT_GATT_CCC(incoming_uri_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_URI, /* Optional */ \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_incoming_uri, NULL, inst), \ + BT_AUDIO_CCC(incoming_uri_cfg_changed) #define BT_TBS_CHR_CALL_STATE(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_CALL_STATE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_call_state, NULL, inst), \ - BT_GATT_CCC(call_state_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_CALL_STATE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_call_state, NULL, inst), \ + BT_AUDIO_CCC(call_state_cfg_changed) #define BT_TBS_CHR_CONTROL_POINT(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_CALL_CONTROL_POINT, \ - BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY | \ - BT_GATT_CHRC_WRITE_WITHOUT_RESP, \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - NULL, write_call_cp, inst), \ - BT_GATT_CCC(call_cp_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_CALL_CONTROL_POINT, \ + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \ + BT_GATT_PERM_WRITE_ENCRYPT, \ + NULL, write_call_cp, inst), \ + BT_AUDIO_CCC(call_cp_cfg_changed) #define BT_TBS_CHR_OPTIONAL_OPCODES(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_OPTIONAL_OPCODES, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_optional_opcodes, NULL, inst) \ + BT_AUDIO_CHRC(BT_UUID_TBS_OPTIONAL_OPCODES, \ + BT_GATT_CHRC_READ, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_optional_opcodes, NULL, inst) \ #define BT_TBS_CHR_TERMINATE_REASON(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_TERMINATE_REASON, \ - BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - NULL, NULL, inst), \ - BT_GATT_CCC(terminate_reason_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_TERMINATE_REASON, \ + BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + NULL, NULL, inst), \ + BT_AUDIO_CCC(terminate_reason_cfg_changed) #define BT_TBS_CHR_INCOMING_CALL(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_INCOMING_CALL, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_incoming_call, NULL, inst), \ - BT_GATT_CCC(in_call_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_CALL, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_incoming_call, NULL, inst), \ + BT_AUDIO_CCC(in_call_cfg_changed) #define BT_TBS_CHR_FRIENDLY_NAME(inst) \ - BT_GATT_CHARACTERISTIC(BT_UUID_TBS_FRIENDLY_NAME, /* Optional */ \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_friendly_name, NULL, inst), \ - BT_GATT_CCC(friendly_name_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_TBS_FRIENDLY_NAME, /* Optional */ \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_friendly_name, NULL, inst), \ + BT_AUDIO_CCC(friendly_name_cfg_changed) #define BT_TBS_SERVICE_DEFINITION(inst) {\ BT_GATT_PRIMARY_SERVICE(BT_UUID_TBS), \ diff --git a/subsys/bluetooth/audio/vcs.c b/subsys/bluetooth/audio/vcs.c index ce87b08f9cd..77c56d219e8 100644 --- a/subsys/bluetooth/audio/vcs.c +++ b/subsys/bluetooth/audio/vcs.c @@ -20,6 +20,7 @@ #include #include +#include "audio_internal.h" #include "vcs_internal.h" #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_VCS) @@ -249,22 +250,20 @@ static ssize_t read_flags(struct bt_conn *conn, const struct bt_gatt_attr *attr, BT_GATT_PRIMARY_SERVICE(BT_UUID_VCS), \ VOCS_INCLUDES(CONFIG_BT_VCS_VOCS_INSTANCE_COUNT) \ AICS_INCLUDES(CONFIG_BT_VCS_AICS_INSTANCE_COUNT) \ - BT_GATT_CHARACTERISTIC(BT_UUID_VCS_STATE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_vol_state, NULL, NULL), \ - BT_GATT_CCC(volume_state_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_VCS_CONTROL, \ - BT_GATT_CHRC_WRITE, \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - NULL, write_vcs_control, NULL), \ - BT_GATT_CHARACTERISTIC(BT_UUID_VCS_FLAGS, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_flags, NULL, NULL), \ - BT_GATT_CCC(flags_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) + BT_AUDIO_CHRC(BT_UUID_VCS_STATE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_vol_state, NULL, NULL), \ + BT_AUDIO_CCC(volume_state_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_VCS_CONTROL, \ + BT_GATT_CHRC_WRITE, \ + BT_GATT_PERM_WRITE_ENCRYPT, \ + NULL, write_vcs_control, NULL), \ + BT_AUDIO_CHRC(BT_UUID_VCS_FLAGS, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_flags, NULL, NULL), \ + BT_AUDIO_CCC(flags_cfg_changed) static struct bt_gatt_attr vcs_attrs[] = { BT_VCS_SERVICE_DEFINITION }; static struct bt_gatt_service vcs_svc; diff --git a/subsys/bluetooth/audio/vocs.c b/subsys/bluetooth/audio/vocs.c index e00ef88ede6..c0bd977de18 100644 --- a/subsys/bluetooth/audio/vocs.c +++ b/subsys/bluetooth/audio/vocs.c @@ -17,6 +17,7 @@ #include #include +#include "audio_internal.h" #include "vocs_internal.h" #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_VOCS) @@ -34,7 +35,7 @@ static void offset_state_cfg_changed(const struct bt_gatt_attr *attr, uint16_t v static ssize_t read_offset_state(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_vocs *inst = attr->user_data; + struct bt_vocs *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("offset %d, counter %u", inst->srv.state.offset, inst->srv.state.change_counter); return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->srv.state, @@ -51,7 +52,7 @@ static void location_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value static ssize_t write_location(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { - struct bt_vocs *inst = attr->user_data; + struct bt_vocs *inst = BT_AUDIO_CHRC_USER_DATA(attr); uint32_t old_location = inst->srv.location; if (offset) { @@ -83,7 +84,7 @@ static ssize_t write_location(struct bt_conn *conn, const struct bt_gatt_attr *a static ssize_t read_location(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_vocs *inst = attr->user_data; + struct bt_vocs *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("0x%08x", inst->srv.location); return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->srv.location, @@ -94,7 +95,7 @@ static ssize_t read_location(struct bt_conn *conn, const struct bt_gatt_attr *at static ssize_t write_vocs_control(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { - struct bt_vocs *inst = attr->user_data; + struct bt_vocs *inst = BT_AUDIO_CHRC_USER_DATA(attr); const struct bt_vocs_control *cp = buf; bool notify = false; @@ -166,7 +167,7 @@ static void output_desc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t va static ssize_t write_output_desc(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { - struct bt_vocs *inst = attr->user_data; + struct bt_vocs *inst = BT_AUDIO_CHRC_USER_DATA(attr); if (offset) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); @@ -198,11 +199,34 @@ static ssize_t write_output_desc(struct bt_conn *conn, const struct bt_gatt_attr return len; } +static int vocs_write(struct bt_vocs *inst, + ssize_t (*write)(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags), + const void *buf, uint16_t len) +{ + struct bt_audio_attr_user_data user_data = { + .user_data = inst, + }; + struct bt_gatt_attr attr = { + .user_data = &user_data, + }; + int err; + + err = write(NULL, &attr, buf, len, 0, 0); + if (err < 0) { + return err; + } + + return 0; +} + #if defined(CONFIG_BT_VOCS) static ssize_t read_output_desc(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_vocs *inst = attr->user_data; + struct bt_vocs *inst = BT_AUDIO_CHRC_USER_DATA(attr); BT_DBG("%s", inst->srv.output_desc); return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->srv.output_desc, @@ -211,28 +235,25 @@ static ssize_t read_output_desc(struct bt_conn *conn, const struct bt_gatt_attr #define BT_VOCS_SERVICE_DEFINITION(_vocs) { \ BT_GATT_SECONDARY_SERVICE(BT_UUID_VOCS), \ - BT_GATT_CHARACTERISTIC(BT_UUID_VOCS_STATE, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_offset_state, NULL, &_vocs), \ - BT_GATT_CCC(offset_state_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_VOCS_LOCATION, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_location, NULL, &_vocs), \ - BT_GATT_CCC(location_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT), \ - BT_GATT_CHARACTERISTIC(BT_UUID_VOCS_CONTROL, \ - BT_GATT_CHRC_WRITE, \ - BT_GATT_PERM_WRITE_ENCRYPT, \ - NULL, write_vocs_control, &_vocs), \ - BT_GATT_CHARACTERISTIC(BT_UUID_VOCS_DESCRIPTION, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_output_desc, NULL, &_vocs), \ - BT_GATT_CCC(output_desc_cfg_changed, \ - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT) \ + BT_AUDIO_CHRC(BT_UUID_VOCS_STATE, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_offset_state, NULL, &_vocs), \ + BT_AUDIO_CCC(offset_state_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_VOCS_LOCATION, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_location, write_location, &_vocs), \ + BT_AUDIO_CCC(location_cfg_changed), \ + BT_AUDIO_CHRC(BT_UUID_VOCS_CONTROL, \ + BT_GATT_CHRC_WRITE, \ + BT_GATT_PERM_WRITE_ENCRYPT, \ + NULL, write_vocs_control, &_vocs), \ + BT_AUDIO_CHRC(BT_UUID_VOCS_DESCRIPTION, \ + BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, \ + read_output_desc, write_output_desc, &_vocs), \ + BT_AUDIO_CCC(output_desc_cfg_changed) \ } static struct bt_vocs vocs_insts[CONFIG_BT_VOCS_MAX_INSTANCE_COUNT]; @@ -327,14 +348,12 @@ int bt_vocs_register(struct bt_vocs *vocs, if (param->location_writable && !bt_uuid_cmp(attr->uuid, BT_UUID_VOCS_LOCATION)) { /* Update attr and chrc to be writable */ chrc = vocs->srv.service_p->attrs[i - 1].user_data; - attr->write = write_location; attr->perm |= BT_GATT_PERM_WRITE_ENCRYPT; chrc->properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP; } else if (param->desc_writable && !bt_uuid_cmp(attr->uuid, BT_UUID_VOCS_DESCRIPTION)) { /* Update attr and chrc to be writable */ chrc = vocs->srv.service_p->attrs[i - 1].user_data; - attr->write = write_output_desc; attr->perm |= BT_GATT_PERM_WRITE_ENCRYPT; chrc->properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP; } @@ -399,14 +418,7 @@ int bt_vocs_location_set(struct bt_vocs *inst, uint32_t location) if (IS_ENABLED(CONFIG_BT_VOCS_CLIENT) && inst->client_instance) { return bt_vocs_client_location_set(inst, location); } else if (IS_ENABLED(CONFIG_BT_VOCS) && !inst->client_instance) { - struct bt_gatt_attr attr; - int err; - - attr.user_data = inst; - - err = write_location(NULL, &attr, &location, sizeof(location), 0, 0); - - return err > 0 ? 0 : err; + return vocs_write(inst, write_location, &location, sizeof(location)); } return -ENOTSUP; @@ -422,19 +434,13 @@ int bt_vocs_state_set(struct bt_vocs *inst, int16_t offset) if (IS_ENABLED(CONFIG_BT_VOCS_CLIENT) && inst->client_instance) { return bt_vocs_client_state_set(inst, offset); } else if (IS_ENABLED(CONFIG_BT_VOCS) && !inst->client_instance) { - struct bt_gatt_attr attr; struct bt_vocs_control cp; - int err; cp.opcode = BT_VOCS_OPCODE_SET_OFFSET; cp.counter = inst->srv.state.change_counter; cp.offset = sys_cpu_to_le16(offset); - attr.user_data = inst; - - err = write_vocs_control(NULL, &attr, &cp, sizeof(cp), 0, 0); - - return err > 0 ? 0 : err; + return vocs_write(inst, write_vocs_control, &cp, sizeof(cp)); } return -ENOTSUP; @@ -474,13 +480,7 @@ int bt_vocs_description_set(struct bt_vocs *inst, const char *description) if (IS_ENABLED(CONFIG_BT_VOCS_CLIENT) && inst->client_instance) { return bt_vocs_client_description_set(inst, description); } else if (IS_ENABLED(CONFIG_BT_VOCS) && !inst->client_instance) { - struct bt_gatt_attr attr; - int err; - - attr.user_data = inst; - - err = write_output_desc(NULL, &attr, description, strlen(description), 0, 0); - return err > 0 ? 0 : err; + return vocs_write(inst, write_output_desc, description, strlen(description)); } return -ENOTSUP; diff --git a/tests/bluetooth/bsim_bt/bsim_test_audio/prj.conf b/tests/bluetooth/bsim_bt/bsim_test_audio/prj.conf index c6f7ef4f4ca..85f2b58aff5 100644 --- a/tests/bluetooth/bsim_bt/bsim_test_audio/prj.conf +++ b/tests/bluetooth/bsim_bt/bsim_test_audio/prj.conf @@ -95,8 +95,6 @@ CONFIG_BT_BASS_CLIENT=y CONFIG_BT_HAS=y CONFIG_BT_HAS_CLIENT=y CONFIG_BT_HAS_HEARING_AID_MONAURAL=y -CONFIG_BT_SMP_SC_PAIR_ONLY=y -CONFIG_BT_SMP_MIN_ENC_KEY_SIZE=16 # Common Audio Profile CONFIG_BT_CAP_ACCEPTOR=y diff --git a/tests/bluetooth/shell/audio.conf b/tests/bluetooth/shell/audio.conf index 19865f85988..a2e9c293f7e 100644 --- a/tests/bluetooth/shell/audio.conf +++ b/tests/bluetooth/shell/audio.conf @@ -103,8 +103,6 @@ CONFIG_BT_HAS=y CONFIG_BT_HAS_HEARING_AID_MONAURAL=y CONFIG_BT_HAS_PRESET_NAME_DYNAMIC=y CONFIG_BT_HAS_PRESET_COUNT=4 -CONFIG_BT_SMP_SC_PAIR_ONLY=y -CONFIG_BT_SMP_MIN_ENC_KEY_SIZE=16 CONFIG_BT_HAS_CLIENT=y # Common Audio Profile