From 9b415a7d1fbddfe544cfeffeb702ab240252d649 Mon Sep 17 00:00:00 2001 From: Liu Linyan Date: Wed, 17 Jun 2026 21:12:32 +0800 Subject: [PATCH] feat(ble_audio): Support Zephyr LE Audio v4.4.1 --- .../bt/esp_ble_audio/Kconfig/Kconfig.bap.in | 2 +- .../bt/esp_ble_audio/Kconfig/Kconfig.tbs.in | 7 + .../esp_ble_audio/api/esp_ble_audio_ccp_api.c | 28 +- .../esp_ble_audio/api/esp_ble_audio_tbs_api.c | 28 +- .../api/include/esp_ble_audio_ccp_api.h | 18 +- .../api/include/esp_ble_audio_tbs_api.h | 19 +- .../host/adapter/nimble/profiles/csis.c | 128 +++++-- .../bt/esp_ble_audio/host/common/init.c | 22 +- .../include/zephyr/bluetooth/audio/aics.h | 5 +- .../include/zephyr/bluetooth/audio/bap.h | 83 ++++- .../include/zephyr/bluetooth/audio/cap.h | 38 +- .../include/zephyr/bluetooth/audio/ccp.h | 62 +++- .../include/zephyr/bluetooth/audio/csip.h | 9 +- .../include/zephyr/bluetooth/audio/has.h | 27 +- .../include/zephyr/bluetooth/audio/micp.h | 5 +- .../include/zephyr/bluetooth/audio/tbs.h | 31 +- .../include/zephyr/bluetooth/audio/vcp.h | 5 +- .../include/zephyr/bluetooth/audio/vocs.h | 5 +- .../include/zephyr/bluetooth/services/ots.h | 5 +- .../bt/esp_ble_audio/lib/include/audio.h | 14 +- components/bt/esp_ble_audio/lib/lib | 2 +- .../host/adapter/bluedroid/gatt/gatt.c | 4 +- components/bt/esp_ble_iso/host/common/conn.c | 11 +- components/bt/esp_ble_iso/host/iso/iso.c | 331 +++++------------- .../subsys/bluetooth/host/conn_internal.h | 4 +- .../include/zephyr/bluetooth/conn.h | 2 +- .../include/zephyr/bluetooth/iso.h | 20 -- .../esp_ble_iso/cis_central/main/main.c | 5 +- .../esp_ble_iso/cis_peripheral/main/main.c | 3 - 29 files changed, 525 insertions(+), 398 deletions(-) diff --git a/components/bt/esp_ble_audio/Kconfig/Kconfig.bap.in b/components/bt/esp_ble_audio/Kconfig/Kconfig.bap.in index 36d060e8bc5..df2abc19ac5 100644 --- a/components/bt/esp_ble_audio/Kconfig/Kconfig.bap.in +++ b/components/bt/esp_ble_audio/Kconfig/Kconfig.bap.in @@ -175,7 +175,7 @@ if BT_BAP_BROADCAST_SINK config BT_BAP_BROADCAST_SNK_COUNT int "Basic Audio Broadcaster Sink count" default 1 - range 0 BT_ISO_MAX_BIG + range 1 BT_ISO_MAX_BIG help This option sets the number of broadcast sinks to support. One broadcast sink can receive multiple streams diff --git a/components/bt/esp_ble_audio/Kconfig/Kconfig.tbs.in b/components/bt/esp_ble_audio/Kconfig/Kconfig.tbs.in index c9ad16b89d2..312f7460f2c 100644 --- a/components/bt/esp_ble_audio/Kconfig/Kconfig.tbs.in +++ b/components/bt/esp_ble_audio/Kconfig/Kconfig.tbs.in @@ -249,4 +249,11 @@ if BT_TBS || BT_TBS_CLIENT help Sets the maximum length of the bearer provider name. + config BT_TBS_MAX_FRIENDLY_NAME_LENGTH + int "The maximum length of the friendly name supported" + default 30 + range 1 512 + help + Sets the maximum length of the friendly name in octets (without NULL terminator). + endif # BT_TBS || BT_TBS_CLIENT diff --git a/components/bt/esp_ble_audio/api/esp_ble_audio_ccp_api.c b/components/bt/esp_ble_audio/api/esp_ble_audio_ccp_api.c index 222d91b529e..e527c273283 100644 --- a/components/bt/esp_ble_audio/api/esp_ble_audio_ccp_api.c +++ b/components/bt/esp_ble_audio/api/esp_ble_audio_ccp_api.c @@ -73,7 +73,7 @@ esp_err_t esp_ble_audio_ccp_call_control_server_set_bearer_provider_name( } esp_err_t esp_ble_audio_ccp_call_control_server_get_bearer_provider_name( - esp_ble_audio_ccp_call_control_server_bearer_t *bearer, const char **name) + esp_ble_audio_ccp_call_control_server_bearer_t *bearer, char *name, size_t name_size) { esp_err_t err; @@ -81,7 +81,31 @@ esp_err_t esp_ble_audio_ccp_call_control_server_get_bearer_provider_name( return ESP_ERR_INVALID_ARG; } - err = bt_ccp_call_control_server_get_bearer_provider_name_safe(bearer, name); + err = bt_ccp_call_control_server_get_bearer_provider_name_safe(bearer, name, name_size); + if (err) { + switch (err) { + case -EFAULT: + return ESP_ERR_INVALID_STATE; + case -ENOMEM: + return ESP_ERR_NO_MEM; + default: + return ESP_FAIL; + } + } + + return ESP_OK; +} + +esp_err_t esp_ble_audio_ccp_call_control_server_get_bearer_uci( + esp_ble_audio_ccp_call_control_server_bearer_t *bearer, char *uci) +{ + esp_err_t err; + + if (bearer == NULL || uci == NULL) { + return ESP_ERR_INVALID_ARG; + } + + err = bt_ccp_call_control_server_get_bearer_uci_safe(bearer, uci); if (err) { return ESP_FAIL; } diff --git a/components/bt/esp_ble_audio/api/esp_ble_audio_tbs_api.c b/components/bt/esp_ble_audio/api/esp_ble_audio_tbs_api.c index 5d6b7f2d269..d9dddbfa06c 100644 --- a/components/bt/esp_ble_audio/api/esp_ble_audio_tbs_api.c +++ b/components/bt/esp_ble_audio/api/esp_ble_audio_tbs_api.c @@ -231,19 +231,16 @@ esp_err_t esp_ble_audio_tbs_set_status_flags(uint8_t bearer_index, uint16_t stat return ESP_OK; } -esp_err_t esp_ble_audio_tbs_set_uri_scheme_list(uint8_t bearer_index, - const char **uri_list, - uint8_t uri_count) +esp_err_t esp_ble_audio_tbs_set_uri_scheme_list(uint8_t bearer_index, const char *uri_scheme_list) { uint8_t count = CONFIG_BT_TBS_BEARER_COUNT; int err; - if (count == 0 || bearer_index >= count || - (uri_count && uri_list == NULL)) { + if (count == 0 || bearer_index >= count || uri_scheme_list == NULL) { return ESP_ERR_INVALID_ARG; } - err = bt_tbs_set_uri_scheme_list_safe(bearer_index, uri_list, uri_count); + err = bt_tbs_set_uri_scheme_list_safe(bearer_index, uri_scheme_list); if (err) { return ESP_FAIL; } @@ -994,4 +991,23 @@ unlock: return ret; } #endif /* CONFIG_BT_TBS_CLIENT_CCID */ + +esp_ble_audio_tbs_instance_t *esp_ble_audio_tbs_client_get_by_index(uint16_t conn_handle, uint8_t index) +{ + esp_ble_audio_tbs_instance_t *ret = NULL; + void *conn; + + bt_le_host_lock(); + + conn = bt_le_acl_conn_find(conn_handle); + if (conn == NULL) { + goto unlock; + } + + ret = lib_tbs_client_get_by_index(conn, index); + +unlock: + bt_le_host_unlock(); + return ret; +} #endif /* CONFIG_BT_TBS_CLIENT */ diff --git a/components/bt/esp_ble_audio/api/include/esp_ble_audio_ccp_api.h b/components/bt/esp_ble_audio/api/include/esp_ble_audio_ccp_api.h index 346850c8699..cfa9e2ee41f 100644 --- a/components/bt/esp_ble_audio/api/include/esp_ble_audio_ccp_api.h +++ b/components/bt/esp_ble_audio/api/include/esp_ble_audio_ccp_api.h @@ -99,13 +99,25 @@ esp_err_t esp_ble_audio_ccp_call_control_server_set_bearer_provider_name( /** * @brief Get the bearer provider name. * - * @param bearer The bearer to get the name for. - * @param name Pointer that will be updated to be the bearer provider name. + * @param bearer The bearer to get the name for. + * @param name Buffer that will be populated with the bearer provider name. + * @param name_size The size of the @p name buffer. * * @return ESP_OK on success, or an error code on failure. */ esp_err_t esp_ble_audio_ccp_call_control_server_get_bearer_provider_name( - esp_ble_audio_ccp_call_control_server_bearer_t *bearer, const char **name); + esp_ble_audio_ccp_call_control_server_bearer_t *bearer, char *name, size_t name_size); + +/** + * @brief Get the bearer UCI. + * + * @param bearer The bearer to get the UCI for. + * @param uci Buffer of size BT_TBS_MAX_UCI_SIZE that the bearer UCI will be written to. + * + * @return ESP_OK on success, or an error code on failure. + */ +esp_err_t esp_ble_audio_ccp_call_control_server_get_bearer_uci( + esp_ble_audio_ccp_call_control_server_bearer_t *bearer, char *uci); /** * @brief Discovers the Telephone Bearer Service (TBS) support on a remote device. diff --git a/components/bt/esp_ble_audio/api/include/esp_ble_audio_tbs_api.h b/components/bt/esp_ble_audio/api/include/esp_ble_audio_tbs_api.h index 0248eb4cf29..97afcea3c2a 100644 --- a/components/bt/esp_ble_audio/api/include/esp_ble_audio_tbs_api.h +++ b/components/bt/esp_ble_audio/api/include/esp_ble_audio_tbs_api.h @@ -318,15 +318,12 @@ esp_err_t esp_ble_audio_tbs_set_status_flags(uint8_t bearer_index, uint16_t stat /** * @brief Sets the URI scheme list of a bearer. * - * @param bearer_index The index of the Telephone Bearer. - * @param uri_list List of URI prefixes (e.g. {"skype", "tel"}). - * @param uri_count Number of URI prefixes in @p uri_list. + * @param bearer_index The index of the Telephone Bearer. + * @param uri_scheme_list Comma-separated list of URI prefixes (e.g. "skype,tel"). * * @return ESP_OK on success, or an error code on failure. */ -esp_err_t esp_ble_audio_tbs_set_uri_scheme_list(uint8_t bearer_index, - const char **uri_list, - uint8_t uri_count); +esp_err_t esp_ble_audio_tbs_set_uri_scheme_list(uint8_t bearer_index, const char *uri_scheme_list); /** * @brief Register the callbacks for TBS. @@ -628,6 +625,16 @@ esp_err_t esp_ble_audio_tbs_client_register_cb(esp_ble_audio_tbs_client_cb_t *cb */ esp_ble_audio_tbs_instance_t *esp_ble_audio_tbs_client_get_by_ccid(uint16_t conn_handle, uint8_t ccid); +/** + * @brief Look up Telephone Bearer Service instance by index. + * + * @param conn_handle Connection handle. + * @param index The index to lookup a service instance for. + * + * @return Pointer to TBS instance if found, NULL otherwise. + */ +esp_ble_audio_tbs_instance_t *esp_ble_audio_tbs_client_get_by_index(uint16_t conn_handle, uint8_t index); + #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_audio/host/adapter/nimble/profiles/csis.c b/components/bt/esp_ble_audio/host/adapter/nimble/profiles/csis.c index 238c1296b47..d2f0879436c 100644 --- a/components/bt/esp_ble_audio/host/adapter/nimble/profiles/csis.c +++ b/components/bt/esp_ble_audio/host/adapter/nimble/profiles/csis.c @@ -45,8 +45,13 @@ LOG_MODULE_REGISTER(LEA_CSIS, CONFIG_BT_ISO_LOG_LEVEL); (BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC) #endif /* CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE */ +#if CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE #define CSIS_CHR_FLAGS_SET_SIZE \ (BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_READ_ENC) +#else /* CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE */ +#define CSIS_CHR_FLAGS_SET_SIZE \ + (BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC) +#endif /* CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE */ #define CSIS_CHR_FLAGS_SET_LOCK \ (BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_WRITE | \ @@ -138,34 +143,60 @@ static int csis_svc_check(void) int bt_le_nimble_csis_attr_handle_set(void) { - struct bt_gatt_attr *attr; uint16_t start_handle = 0; - uint16_t end_handle = 0; LOG_DBG("[N]CsisAttrHdlSet[%u]", csis_svc_count); for (size_t i = 0; i < csis_svc_count; i++) { - assert(csis_insts[i].svc_p); + struct bt_gatt_service *zsvc = csis_insts[i].svc_p; + assert(zsvc); assert(csis_insts[i].sirk_handle >= 2); + + /* SIRK is always the first characteristic, so its value handle anchors the range. */ start_handle = csis_insts[i].sirk_handle - 2; /* server attr handle & char def handle */ - end_handle = csis_insts[i].rank_handle; /* no cccd for chr Set Member Rank */ - LOG_DBG("[N]CsisInst[%u][%u][%u][%u]", - i, start_handle, end_handle, csis_insts[i].svc_p->attr_count); + LOG_DBG("[N]CsisInst[%u][%u][%u]", i, start_handle, zsvc->attr_count); - for (size_t j = 0; j < csis_insts[i].svc_p->attr_count; j++) { - (csis_insts[i].svc_p->attrs + j)->handle = start_handle + j; + for (size_t j = 0; j < zsvc->attr_count; j++) { + (zsvc->attrs + j)->handle = start_handle + j; } - /* Last attribute in CSIS */ - attr = csis_insts[i].svc_p->attrs + csis_insts[i].svc_p->attr_count - 1; + /* Cross-check the last characteristic value against the handle NimBLE assigned, to + * catch divergence between the lib's attribute layout and NimBLE's registration. The + * last characteristic is no longer necessarily Rank, as optional ones may be absent. + */ + for (size_t j = zsvc->attr_count; j-- > 0;) { + const struct bt_uuid_16 *uuid = (const struct bt_uuid_16 *)(zsvc->attrs + j)->uuid; + uint16_t chr_handle = 0; - if (attr->handle != end_handle) { - LOG_ERR("[N]CsisMismatchAttrHdl[%u][%u][%u][%u][%u]", - i, start_handle, end_handle, attr->handle, - csis_insts[i].svc_p->attr_count); - return -1; + if (uuid->uuid.type != BT_UUID_TYPE_16) { + continue; + } + + switch (uuid->val) { + case BT_UUID_CSIS_SIRK_VAL: + chr_handle = csis_insts[i].sirk_handle; + break; + case BT_UUID_CSIS_SET_SIZE_VAL: + chr_handle = csis_insts[i].set_size_handle; + break; + case BT_UUID_CSIS_SET_LOCK_VAL: + chr_handle = csis_insts[i].set_lock_handle; + break; + case BT_UUID_CSIS_RANK_VAL: + chr_handle = csis_insts[i].rank_handle; + break; + default: + continue; + } + + if ((zsvc->attrs + j)->handle != chr_handle) { + LOG_ERR("[N]CsisMismatchAttrHdl[%u][%u][%u]", + i, (zsvc->attrs + j)->handle, chr_handle); + return -1; + } + break; } } @@ -189,8 +220,11 @@ static inline void csis_chr_init(struct ble_gatt_chr_def *chr, } static void csis_svc_init(struct csis_inst *inst, - struct ble_gatt_svc_def *svc) + struct ble_gatt_svc_def *svc, + const struct bt_gatt_service *zsvc) { + size_t chr_cnt = 0U; + LOG_DBG("[N]CsisSvcInit"); svc->type = BLE_GATT_SVC_TYPE_PRIMARY; @@ -200,29 +234,47 @@ static void csis_svc_init(struct csis_inst *inst, svc->characteristics = calloc(CSIS_CHR_COUNT, sizeof(struct ble_gatt_chr_def)); assert(svc->characteristics); - /* Characteristic - Set Identity Resolving Key */ - csis_chr_init((void *)&svc->characteristics[0], - &csis_uuid_sirk, - &inst->sirk_handle, - CSIS_CHR_FLAGS_SIRK); + /* Build the NimBLE characteristics from the ones actually present in the Zephyr + * service. Optional characteristics (set size, lock, rank) may be absent depending + * on the registration parameters, so the layout is data-driven rather than fixed. + */ + for (size_t i = 0; i < zsvc->attr_count; i++) { + const struct bt_uuid_16 *uuid = (const struct bt_uuid_16 *)zsvc->attrs[i].uuid; - /* Characteristic - Coordinated Set Size */ - csis_chr_init((void *)&svc->characteristics[1], - &csis_uuid_set_size, - &inst->set_size_handle, - CSIS_CHR_FLAGS_SET_SIZE); + if (uuid->uuid.type != BT_UUID_TYPE_16) { + continue; + } - /* Characteristic - Set Member Lock */ - csis_chr_init((void *)&svc->characteristics[2], - &csis_uuid_set_lock, - &inst->set_lock_handle, - CSIS_CHR_FLAGS_SET_LOCK); + switch (uuid->val) { + case BT_UUID_CSIS_SIRK_VAL: + csis_chr_init((void *)&svc->characteristics[chr_cnt++], &csis_uuid_sirk, + &inst->sirk_handle, CSIS_CHR_FLAGS_SIRK); + break; + case BT_UUID_CSIS_SET_SIZE_VAL: + csis_chr_init((void *)&svc->characteristics[chr_cnt++], &csis_uuid_set_size, + &inst->set_size_handle, CSIS_CHR_FLAGS_SET_SIZE); + break; + case BT_UUID_CSIS_SET_LOCK_VAL: + csis_chr_init((void *)&svc->characteristics[chr_cnt++], &csis_uuid_set_lock, + &inst->set_lock_handle, CSIS_CHR_FLAGS_SET_LOCK); + break; + case BT_UUID_CSIS_RANK_VAL: + csis_chr_init((void *)&svc->characteristics[chr_cnt++], &csis_uuid_rank, + &inst->rank_handle, CSIS_CHR_FLAGS_RANK); + break; + default: + break; + } + } - /* Characteristic - Set Member Rank */ - csis_chr_init((void *)&svc->characteristics[3], - &csis_uuid_rank, - &inst->rank_handle, - CSIS_CHR_FLAGS_RANK); + /* svc->characteristics has CSIS_CHR_COUNT (= 4 + 1) slots: up to 4 real chars plus + * a trailing zeroed slot that NimBLE requires as the NULL-uuid array terminator. + * chr_cnt is the real-char count written via [chr_cnt++], so it must stay strictly + * below CSIS_CHR_COUNT — chr_cnt == CSIS_CHR_COUNT means a write already clobbered + * the terminator slot. Trips if the switch matches a 5th char: a new CSIS case added + * without bumping the (4 + 1), or a duplicate UUID in the Zephyr service table. + */ + assert(chr_cnt < CSIS_CHR_COUNT); } int bt_le_nimble_csis_init(void *svc, uint8_t count) @@ -239,9 +291,9 @@ int bt_le_nimble_csis_init(void *svc, uint8_t count) csis_svc_count = count; for (size_t i = 0; i < csis_svc_count; i++) { - csis_svc_init(&csis_insts[i], &gatt_svc_csis[i]); - csis_insts[i].svc_p = ((struct bt_gatt_service **)svc)[i]; + + csis_svc_init(&csis_insts[i], &gatt_svc_csis[i], csis_insts[i].svc_p); } rc = ble_gatts_count_cfg(gatt_svc_csis); diff --git a/components/bt/esp_ble_audio/host/common/init.c b/components/bt/esp_ble_audio/host/common/init.c index ed38ffd8bd7..b699adcaaa4 100644 --- a/components/bt/esp_ble_audio/host/common/init.c +++ b/components/bt/esp_ble_audio/host/common/init.c @@ -182,7 +182,7 @@ static const uint16_t ext_structs[] = { sizeof(struct bt_bond_info), }; -#define LEA_VERSION (0x20260616) +#define LEA_VERSION (0x20260624) struct lib_ext_cfgs { /* BLE */ @@ -401,6 +401,7 @@ struct lib_ext_cfgs { bool config_tbs_client_call_friendly_name; uint8_t config_tbs_max_uri_length; uint16_t config_tbs_max_provider_name_length; + uint16_t config_tbs_max_friendly_name_length; /* TMAP (Telephony and Media Audio Profile) */ bool config_tmap_cg_supported; @@ -893,6 +894,7 @@ static const struct lib_ext_cfgs ext_cfgs = { #if CONFIG_BT_TBS || CONFIG_BT_TBS_CLIENT .config_tbs_max_uri_length = CONFIG_BT_TBS_MAX_URI_LENGTH, .config_tbs_max_provider_name_length = CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH, + .config_tbs_max_friendly_name_length = CONFIG_BT_TBS_MAX_FRIENDLY_NAME_LENGTH, #endif /* CONFIG_BT_TBS || CONFIG_BT_TBS_CLIENT */ /* TMAP (Telephony and Media Audio Profile) */ @@ -1083,6 +1085,7 @@ struct lib_ext_funcs { void *data); int (*_conn_get_info)(const struct bt_conn *conn, struct bt_conn_info *info); uint8_t (*_conn_index)(const struct bt_conn *conn); + struct bt_conn *(*_conn_lookup_index)(uint8_t index); const bt_addr_le_t *(*_conn_get_dst)(const struct bt_conn *conn); struct bt_conn *(*_conn_ref)(struct bt_conn *conn); void (*_conn_unref)(struct bt_conn *conn); @@ -1299,6 +1302,7 @@ static const struct lib_ext_funcs ext_funcs = { ._conn_foreach = (void *)bt_conn_foreach, ._conn_get_info = (void *)bt_conn_get_info, ._conn_index = (void *)bt_conn_index, + ._conn_lookup_index = (void *)bt_conn_lookup_index, ._conn_get_dst = (void *)bt_conn_get_dst, ._conn_ref = (void *)bt_conn_ref, ._conn_unref = (void *)bt_conn_unref, @@ -1363,6 +1367,7 @@ struct lib_funcs { /* BAP Unicast Client */ bool (*_bap_unicast_client_has_ep)(const struct bt_bap_ep *ep); + struct bt_conn *(*_bap_unicast_client_ep_get_conn)(const struct bt_bap_ep *ep); int (*_bap_unicast_client_register_cb)(struct bt_bap_unicast_client_cb *cb); int (*_bap_unicast_client_config)(struct bt_bap_stream *stream, const struct bt_audio_codec_cfg *codec_cfg); @@ -1375,6 +1380,7 @@ struct lib_funcs { /* BAP Unicast Server */ bool (*_bap_unicast_server_has_ep)(const struct bt_bap_ep *ep); + struct bt_conn *(*_bap_unicast_server_ep_get_conn)(const struct bt_bap_ep *ep); int (*_bap_unicast_server_reconfig)(struct bt_bap_stream *stream, const struct bt_audio_codec_cfg *codec_cfg); int (*_bap_unicast_server_start)(struct bt_bap_stream *stream); @@ -1407,11 +1413,11 @@ struct lib_funcs { /* CAP Handover */ bool (*_cap_common_handover_is_active)(void); bool (*_cap_handover_is_handover_broadcast_source)(const struct bt_cap_broadcast_source *cap_broadcast_source); - void (*_cap_handover_complete)(void); - void (*_cap_handover_unicast_proc_complete)(void); + void (*_cap_handover_complete)(struct bt_cap_common_proc *active_proc); + void (*_cap_handover_unicast_proc_complete)(struct bt_cap_common_proc *active_proc); void (*_cap_handover_broadcast_source_stopped)(uint8_t reason); void (*_cap_handover_unicast_to_broadcast_reception_start)(void); - int (*_cap_handover_broadcast_reception_stopped)(void); + int (*_cap_handover_broadcast_reception_stopped)(struct bt_cap_common_proc *active_proc); void (*_cap_handover_receive_state_updated)(const struct bt_conn *conn, const struct bt_bap_scan_delegator_recv_state *state); @@ -1503,6 +1509,8 @@ struct lib_funcs { int (*_tbs_client_primary_discover_gtbs)(struct bt_conn *conn); struct bt_tbs_instance *(*_tbs_client_get_by_ccid)(const struct bt_conn *conn, uint8_t ccid); + struct bt_tbs_instance *(*_tbs_client_get_by_index)(const struct bt_conn *conn, + uint8_t index); /* VCP Volume Controller */ void (*_vcp_vol_ctlr_aics_init)(void); @@ -1551,6 +1559,7 @@ static const struct lib_funcs lib_funcs = { #if CONFIG_BT_BAP_UNICAST_CLIENT ._bap_unicast_client_has_ep = lib_bap_unicast_client_has_ep, + ._bap_unicast_client_ep_get_conn = lib_bap_unicast_client_ep_get_conn, ._bap_unicast_client_register_cb = lib_bap_unicast_client_register_cb, ._bap_unicast_client_config = lib_bap_unicast_client_config, ._bap_unicast_client_metadata = lib_bap_unicast_client_metadata, @@ -1562,6 +1571,7 @@ static const struct lib_funcs lib_funcs = { #if CONFIG_BT_BAP_UNICAST_SERVER ._bap_unicast_server_has_ep = lib_bap_unicast_server_has_ep, + ._bap_unicast_server_ep_get_conn = lib_bap_unicast_server_ep_get_conn, ._bap_unicast_server_reconfig = lib_bap_unicast_server_reconfig, ._bap_unicast_server_start = lib_bap_unicast_server_start, ._bap_unicast_server_metadata = lib_bap_unicast_server_metadata, @@ -1697,6 +1707,10 @@ static const struct lib_funcs lib_funcs = { ._tbs_client_get_by_ccid = lib_tbs_client_get_by_ccid, #endif /* CONFIG_BT_TBS_CLIENT_CCID */ +#if CONFIG_BT_TBS_CLIENT + ._tbs_client_get_by_index = lib_tbs_client_get_by_index, +#endif /* CONFIG_BT_TBS_CLIENT */ + #if CONFIG_BT_VCP_VOL_CTLR_AICS ._vcp_vol_ctlr_aics_init = lib_vcp_vol_ctlr_aics_init, #endif /* CONFIG_BT_VCP_VOL_CTLR_AICS */ diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/aics.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/aics.h index bb3390534bd..fcf72f244a3 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/aics.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/aics.h @@ -125,7 +125,10 @@ extern "C" { #define BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED 0x84 /** @} */ -/** @brief Opaque Audio Input Control Service instance. */ +/** + * @struct bt_aics + * @brief Opaque Audio Input Control Service instance. + */ struct bt_aics; /** @brief Structure for initializing a Audio Input Control Service instance. */ diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/bap.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/bap.h index 56a0f9790e1..f05f4f47bd9 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/bap.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/bap.h @@ -619,16 +619,28 @@ struct bt_bap_ascs_rsp { */ #define BT_BAP_ASCS_RSP(c, r) (struct bt_bap_ascs_rsp) { .code = c, .reason = r } -/** @brief Abstract Audio Broadcast Source structure. */ +/** + * @struct bt_bap_broadcast_source + * @brief Abstract Audio Broadcast Source structure. + */ struct bt_bap_broadcast_source; -/** @brief Abstract Audio Broadcast Sink structure. */ +/** + * @struct bt_bap_broadcast_sink + * @brief Abstract Audio Broadcast Sink structure. + */ struct bt_bap_broadcast_sink; -/** @brief Abstract Audio Unicast Group structure. */ +/** + * @struct bt_bap_unicast_group + * @brief Abstract Audio Unicast Group structure. + */ struct bt_bap_unicast_group; -/** @brief Abstract Audio Endpoint structure. */ +/** + * @struct bt_bap_ep + * @brief Abstract Audio Endpoint structure. + */ struct bt_bap_ep; /** Struct to hold subgroup specific information for the receive state */ @@ -871,6 +883,22 @@ struct bt_bap_ep_info { */ int bt_bap_ep_get_info_safe(const struct bt_bap_ep *ep, struct bt_bap_ep_info *info); +/** + * @brief Get the pointer to the ACL connection of an endpoint + * + * The caller gets a new reference to the connection object, if not NULL, which must be + * released with bt_conn_unref() once done using the object. + * + * @param ep The endpoint to get the ACL connection of + * + * @return The ACL connection pointer, or NULL if: + * - @p ep is NULL + * - @p ep is a broadcast endpoint + * - @p ep is a Unicast Server endpoint not yet configured by a remote client + * - @p ep is a Unicast Client endpoint not yet discovered on a remote server + */ +struct bt_conn *bt_bap_ep_get_conn(const struct bt_bap_ep *ep); + /** * @brief Basic Audio Profile stream structure. * @@ -1189,7 +1217,7 @@ int bt_bap_stream_disable_safe(struct bt_bap_stream *stream); * @retval 0 in case of success * @retval -EINVAL if the stream, endpoint, ISO channel or connection is NULL * @retval -EBADMSG if the stream or ISO channel is in an invalid state for connection - * @retval -EOPNOTSUPP if the role of the stream is not @ref BT_HCI_ROLE_CENTRAL + * @retval -EOPNOTSUPP if the role of the stream is not @ref BT_CONN_ROLE_CENTRAL * @retval -EALREADY if the ISO channel is already connecting or connected * @retval -EBUSY if another ISO channel is connecting * @retval -ENOEXEC if otherwise rejected by the ISO layer @@ -1233,7 +1261,7 @@ int bt_bap_stream_start_safe(struct bt_bap_stream *stream); * * @retval 0 Success * @retval -EINVAL The @p stream does not have an endpoint or a connection, of the stream's - * connection's role is not @p BT_HCI_ROLE_CENTRAL + * connection's role is not @p BT_CONN_ROLE_CENTRAL * @retval -EBADMSG The state of the @p stream endpoint is not @ref BT_BAP_EP_STATE_DISABLING * @retval -EALREADY The CIS state of the @p is not in a connected state, and thus is already * stopping @@ -1530,8 +1558,11 @@ int bt_bap_unicast_server_unregister_cb_safe(const struct bt_bap_unicast_server_ * * @param ep The structure object with endpoint info. * @param user_data Data to pass to the function. + * + * @retval true Continue iterating. + * @retval false Stop iterating. */ -typedef void (*bt_bap_ep_func_t)(struct bt_bap_ep *ep, void *user_data); +typedef bool (*bt_bap_ep_func_t)(struct bt_bap_ep *ep, void *user_data); /** * @brief Iterate through all endpoints of the given connection. @@ -1539,8 +1570,12 @@ typedef void (*bt_bap_ep_func_t)(struct bt_bap_ep *ep, void *user_data); * @param conn Connection object * @param func Function to call for each endpoint. * @param user_data Data to pass to the callback function. + * + * @retval 0 Success + * @retval -ECANCELED Iteration was stopped by the callback function before complete. + * @retval -EINVAL @p conn or @p func were NULL. */ -void bt_bap_unicast_server_foreach_ep(struct bt_conn *conn, bt_bap_ep_func_t func, void *user_data); +int bt_bap_unicast_server_foreach_ep(struct bt_conn *conn, bt_bap_ep_func_t func, void *user_data); /** * @brief Initialize and configure a new ASE. @@ -1711,8 +1746,8 @@ int bt_bap_unicast_group_delete_safe(struct bt_bap_unicast_group *unicast_group) * @param stream The audio stream * @param user_data User data * - * @retval true Stop iterating. - * @retval false Continue iterating. + * @retval true Continue iterating. + * @retval false Stop iterating. */ typedef bool (*bt_bap_unicast_group_foreach_stream_func_t)(struct bt_bap_stream *stream, void *user_data); @@ -1770,11 +1805,22 @@ struct bt_bap_unicast_client_cb { * @param conn Connection to the remote unicast server. * @param dir Direction of the location. * @param loc The location bitfield value. - * - * @return 0 in case of success or negative value in case of error. */ void (*location)(struct bt_conn *conn, enum bt_audio_dir dir, enum bt_audio_location loc); + /** + * @brief Remote Unicast Server Supported Contexts + * + * This callback is called whenever the supported contexts are read + * from the server or otherwise notified to the client. + * + * @param conn Connection to the remote unicast server. + * @param snk_ctx The sink context bitfield value. + * @param src_ctx The source context bitfield value. + */ + void (*supported_contexts)(struct bt_conn *conn, enum bt_audio_context snk_ctx, + enum bt_audio_context src_ctx); + /** * @brief Remote Unicast Server Available Contexts * @@ -1784,8 +1830,6 @@ struct bt_bap_unicast_client_cb { * @param conn Connection to the remote unicast server. * @param snk_ctx The sink context bitfield value. * @param src_ctx The source context bitfield value. - * - * @return 0 in case of success or negative value in case of error. */ void (*available_contexts)(struct bt_conn *conn, enum bt_audio_context snk_ctx, enum bt_audio_context src_ctx); @@ -2453,8 +2497,8 @@ int bt_bap_broadcast_source_get_base_safe(struct bt_bap_broadcast_source *source * @param stream The audio stream * @param user_data User data * - * @retval true Stop iterating. - * @retval false Continue iterating. + * @retval true Continue iterating. + * @retval false Stop iterating. */ typedef bool (*bt_bap_broadcast_source_foreach_stream_func_t)(struct bt_bap_stream *stream, void *user_data); @@ -2467,7 +2511,7 @@ typedef bool (*bt_bap_broadcast_source_foreach_stream_func_t)(struct bt_bap_stre * @param user_data User specified data that is sent to the callback function * * @retval 0 Success (even if no streams exists in the broadcast source). - * @retval -ECANCELED The @p func returned true. + * @retval -ECANCELED The @p func returned false and stopped the iteration. * @retval -EINVAL @p source or @p func were NULL. */ int bt_bap_broadcast_source_foreach_stream_safe(struct bt_bap_broadcast_source *source, @@ -2539,7 +2583,7 @@ struct bt_bap_broadcast_sink_cb { * It is possible to register multiple struct of callbacks, but a single struct can only be * registered once. * Registering the same callback multiple times is undefined behavior and may break the stack. - * + * @param cb Broadcast sink callback structure. * * @retval 0 on success @@ -2956,7 +3000,8 @@ int bt_bap_broadcast_assistant_discover_safe(struct bt_conn *conn); * @retval -ENOMEM Could not allocated memory for the request * @retval -ENOEXEC Unexpected scan or GATT error */ -int bt_bap_broadcast_assistant_scan_start(struct bt_conn *conn, bool start_scan); +int bt_bap_broadcast_assistant_scan_start(struct bt_conn *conn, + bool start_scan); int bt_bap_broadcast_assistant_scan_start_safe(struct bt_conn *conn, bool start_scan); diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/cap.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/cap.h index 2786d172fe3..107780714ed 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/cap.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/cap.h @@ -47,10 +47,16 @@ extern "C" { #endif -/** @brief Abstract Audio Broadcast Source structure. */ +/** + * @struct bt_cap_broadcast_source + * @brief Abstract Audio Broadcast Source structure. + */ struct bt_cap_broadcast_source; -/** @brief Abstract CAP Unicast Group structure. */ +/** + * @struct bt_cap_unicast_group + * @brief Abstract CAP Unicast Group structure. + */ struct bt_cap_unicast_group; /** @@ -394,13 +400,13 @@ int bt_cap_unicast_group_add_streams_safe(struct bt_cap_unicast_group *unicast_g */ int bt_cap_unicast_group_delete_safe(struct bt_cap_unicast_group *unicast_group); -/** Callback function for bt_bap_unicast_group_foreach_stream() +/** Callback function for bt_cap_unicast_group_foreach_stream() * * @param stream The audio stream * @param user_data User data * - * @retval true Stop iterating. - * @retval false Continue iterating. + * @retval true Continue iterating. + * @retval false Stop iterating. */ typedef bool (*bt_cap_unicast_group_foreach_stream_func_t)(struct bt_cap_stream *stream, void *user_data); @@ -413,7 +419,7 @@ typedef bool (*bt_cap_unicast_group_foreach_stream_func_t)(struct bt_cap_stream * @param user_data User specified data that is sent to the callback function * * @retval 0 Success (even if no streams exists in the group). - * @retval -ECANCELED The @p func returned true. + * @retval -ECANCELED The @p func returned false and stopped the iteration. * @retval -EINVAL @p unicast_group or @p func were NULL. */ int bt_cap_unicast_group_foreach_stream_safe(struct bt_cap_unicast_group *unicast_group, @@ -832,8 +838,8 @@ int bt_cap_initiator_broadcast_get_base_safe(struct bt_cap_broadcast_source *bro * @param stream The audio stream * @param user_data User data * - * @retval true Stop iterating. - * @retval false Continue iterating. + * @retval true Continue iterating. + * @retval false Stop iterating. */ typedef bool (*bt_cap_initiator_broadcast_foreach_stream_func_t)(struct bt_cap_stream *stream, void *user_data); @@ -846,7 +852,7 @@ typedef bool (*bt_cap_initiator_broadcast_foreach_stream_func_t)(struct bt_cap_s * @param user_data User specified data that is sent to the callback function. * * @retval 0 Success (even if no streams exists in the group). - * @retval -ECANCELED The @p func returned true. + * @retval -ECANCELED The @p func returned false and stopped the iteration. * @retval -EINVAL @p broadcast_source or @p func were NULL. */ int bt_cap_initiator_broadcast_foreach_stream_safe(struct bt_cap_broadcast_source *broadcast_source, @@ -887,6 +893,20 @@ struct bt_cap_handover_unicast_to_broadcast_param { /** Callback structure for CAP procedures */ struct bt_cap_handover_cb { + /** + * @brief The broadcast source has been created for handover + * + * When this is called, the broadcast source has been created and the BASE can be + * generated by bt_cap_initiator_broadcast_get_base(). To continue with the broadcast + * reception part of the procedure, the application shall enable extended and periodic + * advertising and set the BASE in the periodic advertising data with + * bt_le_per_adv_set_data(). The procedure will finish once the CAP acceptors have synced + * to the newly created broadcast source. + * + * @param broadcast_source Pointer to newly created broadcast source. + */ + void (*unicast_to_broadcast_created)(struct bt_cap_broadcast_source *broadcast_source); + /** * @brief The unicast to broadcast handover procedure has finished * diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/ccp.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/ccp.h index ccd6db4be04..e92c312498a 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/ccp.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/ccp.h @@ -47,7 +47,10 @@ extern "C" { * @ingroup bt_ccp * @{ */ -/** @brief Abstract Call Control Server Telephone Bearer structure. */ +/** + * @struct bt_ccp_call_control_server_bearer + * @brief Abstract Call Control Server Telephone Bearer structure. + */ struct bt_ccp_call_control_server_bearer; /** @@ -101,8 +104,10 @@ int bt_ccp_call_control_server_unregister_bearer_safe(struct bt_ccp_call_control * * @retval 0 Success * @retval -EINVAL @p bearer or @p name is NULL, or @p name is the empty string or @p name is larger - * than @kconfig{CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH} + * than @kconfig{CONFIG_BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LEN} * @retval -EFAULT @p bearer is not registered + * @retval -EBUSY The TBS instance of @p bearer is busy + * @retval -ENOEXEC The TBS instance of @p bearer returned unexpected error */ int bt_ccp_call_control_server_set_bearer_provider_name_safe( struct bt_ccp_call_control_server_bearer *bearer, const char *name); @@ -111,14 +116,32 @@ int bt_ccp_call_control_server_set_bearer_provider_name_safe( * @brief Get the bearer provider name. * * @param[in] bearer The bearer to get the name for. - * @param[out] name Pointer that will be updated to be the bearer provider name. + * @param[out] name Pointer a buffer that will be populated with the bearer provider name. + * @param name_size The size of the @p name buffer. The suggested size is + * @kconfig{CONFIG_BT_CCP_CALL_CONTROL_SERVER_PROVIDER_NAME_MAX_LEN} + 1 to + * ensure that the name always fits. * * @retval 0 Success * @retval -EINVAL @p bearer or @p name is NULL * @retval -EFAULT @p bearer is not registered + * @retval -ENOMEM @p name_size is insufficient to hold the bearer name (including null terminator) */ int bt_ccp_call_control_server_get_bearer_provider_name_safe( - struct bt_ccp_call_control_server_bearer *bearer, const char **name); + struct bt_ccp_call_control_server_bearer *bearer, char *name, size_t name_size); + +/** + * @brief Get the bearer UCI. + * + * @param[in] bearer The bearer to get the UCI for. + * @param[out] uci Pointer to a buffer of size @ref BT_TBS_MAX_UCI_SIZE that the bearer UCI will be + * written to. + * + * @retval 0 Success + * @retval -EINVAL @p bearer or @p uci is NULL + * @retval -EFAULT @p bearer is not registered + */ +int bt_ccp_call_control_server_get_bearer_uci_safe(struct bt_ccp_call_control_server_bearer *bearer, + char uci[BT_TBS_MAX_UCI_SIZE]); /** @} */ /* End of group bt_ccp_call_control_server */ @@ -127,10 +150,17 @@ int bt_ccp_call_control_server_get_bearer_provider_name_safe( * @ingroup bt_ccp * @{ */ -/** Abstract Call Control Client structure. */ + +/** + * @struct bt_ccp_call_control_client + * @brief Abstract Call Control Client structure. + */ struct bt_ccp_call_control_client; -/** Abstract Call Control Client bearer structure. */ +/** + * @struct bt_ccp_call_control_client_bearer + * @brief Abstract Call Control Client bearer structure. + */ struct bt_ccp_call_control_client_bearer; /** Struct with information about bearers of a client */ @@ -159,23 +189,29 @@ struct bt_ccp_call_control_client_cb { * @param client Call Control Client pointer. * @param err Error value. 0 on success, GATT error on positive * value or errno on negative value. - * @param bearers The bearers found. + * @param bearers The bearers found. Value must be copied if used after return. + * @param user_data User data stored in the callback struct. */ void (*discover)(struct bt_ccp_call_control_client *client, int err, - struct bt_ccp_call_control_client_bearers *bearers); + struct bt_ccp_call_control_client_bearers *bearers, void *user_data); /** * @brief Callback function for bt_ccp_call_control_client_read_bearer_provider_name(). * * This callback is called once the read bearer provider name procedure is completed. * - * @param client Call Control Client instance pointer. - * @param err Error value. 0 on success, GATT error on positive - * value or errno on negative value. - * @param name The bearer provider name. NULL if @p err is not 0. + * @param bearer Call Control Client bearer instance pointer. + * @param err Error value. 0 on success, GATT error on positive + * value or errno on negative value. + * @param name The bearer provider name. NULL if @p err is not 0. + * Value must be copied if used after return. + * @param user_data User data stored in the callback struct. */ void (*bearer_provider_name)(struct bt_ccp_call_control_client_bearer *bearer, int err, - const char *name); + const char *name, void *user_data); + + /** User data that will be supplied to all callbacks */ + void *user_data; /** @cond INTERNAL_HIDDEN */ /** Internally used field for list handling */ diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/csip.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/csip.h index 166f5ad84e7..9acc6428527 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/csip.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/csip.h @@ -83,7 +83,10 @@ extern "C" { */ #define BT_CSIP_DATA_RSI(_rsi) BT_DATA(BT_DATA_CSIS_RSI, _rsi, BT_CSIP_RSI_SIZE) -/** @brief Opaque Coordinated Set Identification Service instance. */ +/** + * @struct bt_csip_set_member_svc_inst + * @brief Opaque Coordinated Set Identification Service instance. + */ struct bt_csip_set_member_svc_inst; /** Callback structure for the Coordinated Set Identification Service */ @@ -224,6 +227,8 @@ int bt_csip_set_member_sirk_safe(struct bt_csip_set_member_svc_inst *svc_inst, * It is important to note that a set cannot have multiple devices with the same rank in a set, * and it is up to the caller of this function to ensure that. * Similarly, it is important that the size is updated on all devices in the set at the same time. + * The rank of a device cannot be modified on its own, and a new rank can only be set if the @p size + * is different from the current set size. * * If @kconfig{CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE} is enabled, this will also send a * notification to all connected or bonded clients. @@ -234,7 +239,7 @@ int bt_csip_set_member_sirk_safe(struct bt_csip_set_member_svc_inst *svc_inst, * * @retval -EINVAL @p svc_inst is NULL, @p size is less than 1, @p rank is less than 1 or higher * than @p size for a lockable @p svc_inst. - * @retval -EALREADY @p size and @p rank are already the provided values. + * @retval -EALREADY @p size is already set. * @retval 0 Success. */ int bt_csip_set_member_set_size_and_rank_safe(struct bt_csip_set_member_svc_inst *svc_inst, uint8_t size, diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/has.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/has.h index 70efc5c574d..75212a28d7b 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/has.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/has.h @@ -56,7 +56,10 @@ extern "C" { /** Preset name maximum length */ #define BT_HAS_PRESET_NAME_MAX 40 -/** @brief Opaque Hearing Access Service object. */ +/** + * @struct bt_has + * @brief Opaque Hearing Access Service object. + */ struct bt_has; /** Hearing Aid device type */ @@ -424,14 +427,6 @@ int bt_has_preset_available_safe(uint8_t index); */ int bt_has_preset_unavailable_safe(uint8_t index); -/** Enum for return values for @ref bt_has_preset_func_t functions */ -enum { - /** Stop iterating */ - BT_HAS_PRESET_ITER_STOP = 0, - /** Continue iterating */ - BT_HAS_PRESET_ITER_CONTINUE, -}; - /** * @typedef bt_has_preset_func_t * @brief Preset iterator callback. @@ -441,11 +436,11 @@ enum { * @param name Preset name. * @param user_data Data given. * - * @return BT_HAS_PRESET_ITER_CONTINUE if should continue to the next preset. - * @return BT_HAS_PRESET_ITER_STOP to stop. + * @retval true Continue iterating. + * @retval false Stop iterating. */ -typedef uint8_t (*bt_has_preset_func_t)(uint8_t index, enum bt_has_properties properties, - const char *name, void *user_data); +typedef bool (*bt_has_preset_func_t)(uint8_t index, enum bt_has_properties properties, + const char *name, void *user_data); /** * @brief Preset iterator. @@ -455,8 +450,12 @@ typedef uint8_t (*bt_has_preset_func_t)(uint8_t index, enum bt_has_properties pr * @param index Preset index, passing @ref BT_HAS_PRESET_INDEX_NONE skips index matching. * @param func Callback function. * @param user_data Data to pass to the callback. + * + * @retval 0 Success + * @retval -ECANCELED Iteration was stopped by the callback function before complete. + * @retval -EINVAL @p func was NULL. */ -void bt_has_preset_foreach_safe(uint8_t index, bt_has_preset_func_t func, void *user_data); +int bt_has_preset_foreach_safe(uint8_t index, bt_has_preset_func_t func, void *user_data); /** * @brief Set active preset. diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/micp.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/micp.h index f2edec701a9..353eaccda78 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/micp.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/micp.h @@ -54,7 +54,10 @@ extern "C" { #define BT_MICP_MUTE_DISABLED 0x02 /** @} */ -/** @brief Opaque Microphone Controller instance. */ +/** + * @struct bt_micp_mic_ctlr + * @brief Opaque Microphone Controller instance. + */ struct bt_micp_mic_ctlr; /** @brief Register parameters structure for Microphone Control Service */ diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/tbs.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/tbs.h index 6609dbc5190..f17e65b5de3 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/tbs.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/tbs.h @@ -201,7 +201,17 @@ extern "C" { */ #define BT_TBS_GTBS_INDEX 0xFF -/** @brief Opaque Telephone Bearer Service instance. */ +/** Maximum size of bearer uniform caller identifier (UCI) + * + * Includes the NULL terminator. + * Allowed values are defined by Bluetooth Assigned Numbers. + */ +#define BT_TBS_MAX_UCI_SIZE 6 + +/** + * @struct bt_tbs_instance + * @brief Opaque Telephone Bearer Service instance. + */ struct bt_tbs_instance; /** @@ -453,13 +463,11 @@ int bt_tbs_set_status_flags_safe(uint8_t bearer_index, uint16_t status_flags); * @brief Sets the URI scheme list of a bearer. * * @param bearer_index The index of the Telephone Bearer. - * @param uri_list List of URI prefixes (e.g. {"skype", "tel"}). - * @param uri_count Number of URI prefixes in @p uri_list. + * @param uri_scheme_list Comma-separated list of URI prefixes (e.g. "skype,tel"). * * @return BT_TBS_RESULT_CODE_* if positive or 0, errno value if negative. */ -int bt_tbs_set_uri_scheme_list_safe(uint8_t bearer_index, const char **uri_list, - uint8_t uri_count); +int bt_tbs_set_uri_scheme_list_safe(uint8_t bearer_index, const char *uri_scheme_list); /** * @brief Register the callbacks for TBS. * @@ -1086,7 +1094,8 @@ int bt_tbs_client_read_friendly_name_safe(struct bt_conn *conn, uint8_t inst_ind * @note @kconfig{CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES} must be set * for this function to be effective. */ -int bt_tbs_client_read_optional_opcodes(struct bt_conn *conn, uint8_t inst_index); +int bt_tbs_client_read_optional_opcodes(struct bt_conn *conn, + uint8_t inst_index); int bt_tbs_client_read_optional_opcodes_safe(struct bt_conn *conn, uint8_t inst_index); @@ -1115,6 +1124,16 @@ int bt_tbs_client_register_cb_safe(struct bt_tbs_client_cb *cbs); struct bt_tbs_instance *bt_tbs_client_get_by_ccid_safe(const struct bt_conn *conn, uint8_t ccid); +/** + * @brief Look up Telephone Bearer Service instance by index + * + * @param conn The connection to the TBS server. + * @param index The index to lookup a service instance for. + * + * @return Pointer to a Telephone Bearer Service instance if found else NULL. + */ +struct bt_tbs_instance *bt_tbs_client_get_by_index_safe(const struct bt_conn *conn, uint8_t index); + #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vcp.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vcp.h index 9b12c761b52..d92b978cc78 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vcp.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vcp.h @@ -61,7 +61,10 @@ extern "C" { #define BT_VCP_STATE_MUTED 0x01 /** @} */ -/** @brief Opaque Volume Control Service instance. */ +/** + * @struct bt_vcp_vol_ctlr + * @brief Opaque Volume Control Service instance. + */ struct bt_vcp_vol_ctlr; /** Register structure for Volume Control Service */ diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vocs.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vocs.h index ff9afcb2902..b037f821f71 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vocs.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/audio/vocs.h @@ -66,7 +66,10 @@ extern "C" { #define BT_VOCS_MAX_OFFSET 255 /** @} */ -/** @brief Opaque Volume Offset Control Service instance. */ +/** + * @struct bt_vocs + * @brief Opaque Volume Offset Control Service instance. + */ struct bt_vocs; /** @brief Structure for registering a Volume Offset Control Service instance. */ diff --git a/components/bt/esp_ble_audio/include/zephyr/bluetooth/services/ots.h b/components/bt/esp_ble_audio/include/zephyr/bluetooth/services/ots.h index ef887f26193..94bd75ec3e9 100644 --- a/components/bt/esp_ble_audio/include/zephyr/bluetooth/services/ots.h +++ b/components/bt/esp_ble_audio/include/zephyr/bluetooth/services/ots.h @@ -551,7 +551,10 @@ struct bt_ots_obj_metadata { uint32_t props; }; -/** @brief Opaque OTS instance. */ +/** + * @struct bt_ots + * @brief Opaque OTS instance. + */ struct bt_ots; /** @brief Descriptor for OTS object addition */ diff --git a/components/bt/esp_ble_audio/lib/include/audio.h b/components/bt/esp_ble_audio/lib/include/audio.h index 091a7ad75fe..7f55c9443a0 100644 --- a/components/bt/esp_ble_audio/lib/include/audio.h +++ b/components/bt/esp_ble_audio/lib/include/audio.h @@ -134,6 +134,7 @@ enum bt_cap_common_subproc_type; enum bt_cap_common_proc_type; struct bt_cap_stream; struct bt_cap_broadcast_source; +struct bt_cap_common_proc; struct bt_ots; struct bt_ots_client; @@ -174,6 +175,7 @@ extern bool lib_bap_broadcast_source_has_ep(const struct bt_bap_ep *ep); #if CONFIG_BT_BAP_UNICAST_CLIENT extern bool lib_bap_unicast_client_has_ep(const struct bt_bap_ep *ep); +extern struct bt_conn *lib_bap_unicast_client_ep_get_conn(const struct bt_bap_ep *ep); extern int lib_bap_unicast_client_register_cb(struct bt_bap_unicast_client_cb *cb); extern int lib_bap_unicast_client_config(struct bt_bap_stream *stream, const struct bt_audio_codec_cfg *codec_cfg); @@ -187,6 +189,7 @@ extern int lib_bap_unicast_client_release(struct bt_bap_stream *stream); #if CONFIG_BT_BAP_UNICAST_SERVER extern bool lib_bap_unicast_server_has_ep(const struct bt_bap_ep *ep); +extern struct bt_conn *lib_bap_unicast_server_ep_get_conn(const struct bt_bap_ep *ep); extern int lib_bap_unicast_server_reconfig(struct bt_bap_stream *stream, const struct bt_audio_codec_cfg *codec_cfg); extern int lib_bap_unicast_server_start(struct bt_bap_stream *stream); @@ -222,11 +225,11 @@ extern void lib_cap_initiator_released(struct bt_cap_stream *cap_stream); #if CONFIG_BT_CAP_HANDOVER extern bool lib_cap_common_handover_is_active(void); extern bool lib_cap_handover_is_handover_broadcast_source(const struct bt_cap_broadcast_source *cap_broadcast_source); -extern void lib_cap_handover_complete(void); -extern void lib_cap_handover_unicast_proc_complete(void); +extern void lib_cap_handover_complete(struct bt_cap_common_proc *active_proc); +extern void lib_cap_handover_unicast_proc_complete(struct bt_cap_common_proc *active_proc); extern void lib_cap_handover_broadcast_source_stopped(uint8_t reason); extern void lib_cap_handover_unicast_to_broadcast_reception_start(void); -extern int lib_cap_handover_broadcast_reception_stopped(void); +extern int lib_cap_handover_broadcast_reception_stopped(struct bt_cap_common_proc *active_proc); extern void lib_cap_handover_receive_state_updated(const struct bt_conn *conn, const struct bt_bap_scan_delegator_recv_state *state); #endif /* CONFIG_BT_CAP_HANDOVER */ @@ -340,6 +343,11 @@ extern struct bt_tbs_instance *lib_tbs_client_get_by_ccid(const struct bt_conn * uint8_t ccid); #endif /* CONFIG_BT_TBS_CLIENT_CCID */ +#if CONFIG_BT_TBS_CLIENT +extern struct bt_tbs_instance *lib_tbs_client_get_by_index(const struct bt_conn *conn, + uint8_t index); +#endif /* CONFIG_BT_TBS_CLIENT */ + #if CONFIG_BT_VCP_VOL_CTLR_AICS extern void lib_vcp_vol_ctlr_aics_init(void); #endif /* CONFIG_BT_VCP_VOL_CTLR_AICS */ diff --git a/components/bt/esp_ble_audio/lib/lib b/components/bt/esp_ble_audio/lib/lib index 77cf36bd773..8af29109827 160000 --- a/components/bt/esp_ble_audio/lib/lib +++ b/components/bt/esp_ble_audio/lib/lib @@ -1 +1 @@ -Subproject commit 77cf36bd77300ab1c18e543dfedf359e876c3d56 +Subproject commit 8af29109827eb9e3bc636b2a1ae6596fdfacaf4a diff --git a/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c b/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c index d06f785d947..730c06f68fd 100644 --- a/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c +++ b/components/bt/esp_ble_iso/host/adapter/bluedroid/gatt/gatt.c @@ -1851,7 +1851,7 @@ static void handle_gatts_read_event(struct bt_le_gatts_read_event *event) } else { ret = attr->read(conn, attr, (void *)rsp, GATT_MAX_ATTR_LEN, 0); if (ret < 0) { - LOG_ERR("[B]GattsRdEvtFail[%u][%d]", event->attr_handle, ret); + LOG_DBG("[B]GattsRdEvtErr[%u][%d]", event->attr_handle, ret); status = BT_GATT_ERR(ret); } @@ -1942,7 +1942,7 @@ static void handle_gatts_write_event(struct bt_le_gatts_write_event *event) } else { ret = attr->write(conn, attr, event->value, event->len, 0, 0); if (ret < 0) { - LOG_ERR("[B]GattsWrEvtFail[%u][%d]", event->attr_handle, ret); + LOG_DBG("[B]GattsWrEvtErr[%u][%d]", event->attr_handle, ret); status = BT_GATT_ERR(ret); } diff --git a/components/bt/esp_ble_iso/host/common/conn.c b/components/bt/esp_ble_iso/host/common/conn.c index 4a8b940fa37..cb0158b0c3e 100644 --- a/components/bt/esp_ble_iso/host/common/conn.c +++ b/components/bt/esp_ble_iso/host/common/conn.c @@ -162,7 +162,7 @@ int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info) info->id = conn->id; info->state = conn_internal_to_public_state(conn->state); info->le.dst = &conn->le.dst; - info->le.interval = conn->le.interval; + info->le.interval_us = conn->le.interval_us; if (conn->encrypt) { /* Currently the flags is updated for lib usage. @@ -330,6 +330,15 @@ struct bt_conn *bt_conn_lookup_handle(uint16_t handle, enum bt_conn_type type) return conn; } +struct bt_conn *bt_conn_lookup_index(uint8_t index) +{ + if (index >= ARRAY_SIZE(acl_conns)) { + return NULL; + } + + return bt_conn_ref(&acl_conns[index]); +} + _IDF_ONLY struct bt_conn *bt_le_acl_conn_find(uint16_t conn_handle) { diff --git a/components/bt/esp_ble_iso/host/iso/iso.c b/components/bt/esp_ble_iso/host/iso/iso.c index 8ecfb5b9ec5..d63e846376e 100644 --- a/components/bt/esp_ble_iso/host/iso/iso.c +++ b/components/bt/esp_ble_iso/host/iso/iso.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2020 Intel Corporation - * SPDX-FileCopyrightText: 2021-2025 Nordic Semiconductor ASA + * SPDX-FileCopyrightText: 2021-2026 Nordic Semiconductor ASA * SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,8 @@ struct bt_conn iso_conns[CONFIG_BT_ISO_MAX_CHAN]; struct bt_iso_cig cigs[CONFIG_BT_ISO_MAX_CIG]; static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan); +static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t count); + #endif /* CONFIG_BT_ISO_CENTRAL */ #if defined(CONFIG_BT_ISO_PERIPHERAL) @@ -220,65 +223,65 @@ static int validate_iso_setup_data_path_parms(const struct bt_iso_chan *chan, ui struct bt_conn *iso; CHECKIF(chan == NULL) { - LOG_DBG("ChanNull"); + LOG_ERR("ChanNull"); return -EINVAL; } CHECKIF(path == NULL) { - LOG_DBG("PathNull"); + LOG_ERR("PathNull"); return -EINVAL; } CHECKIF(dir != BT_HCI_DATAPATH_DIR_HOST_TO_CTLR && dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) { - LOG_DBG("InvDir[%u]", dir); + LOG_ERR("InvDir[%u]", dir); return -EINVAL; } iso = chan->iso; if (iso == NULL) { - LOG_DBG("ChanNotAssociated[%p]", chan); + LOG_ERR("ChanNotAssociated[%p]", chan); return -ENODEV; } if (!iso->iso.info.can_recv && dir == BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) { - LOG_DBG("InvDirForChanCannotRecv[%u][%p]", dir, chan); + LOG_ERR("InvDirForChanCannotRecv[%u][%p]", dir, chan); return -EINVAL; } if (!iso->iso.info.can_send && dir == BT_HCI_DATAPATH_DIR_HOST_TO_CTLR) { - LOG_DBG("InvDirForChanCannotSend[%u][%p]", dir, chan); + LOG_ERR("InvDirForChanCannotSend[%u][%p]", dir, chan); return -EINVAL; } CHECKIF(path->pid != BT_ISO_DATA_PATH_HCI && !IN_RANGE(path->pid, BT_ISO_DATA_PATH_VS_ID_MIN, BT_ISO_DATA_PATH_VS_ID_MAX)) { - LOG_DBG("InvPid[%u]", path->pid); + LOG_ERR("InvPid[%u]", path->pid); return -EINVAL; } CHECKIF(path->format > BT_HCI_CODING_FORMAT_G729A && path->format != BT_HCI_CODING_FORMAT_VS) { - LOG_DBG("InvFormat[%u]", path->format); + LOG_ERR("InvFormat[%u]", path->format); return -EINVAL; } CHECKIF(path->delay > BT_ISO_CONTROLLER_DELAY_MAX) { - LOG_DBG("InvDelay[%u]", path->delay); + LOG_ERR("InvDelay[%u]", path->delay); return -EINVAL; } CHECKIF(path->cc_len > 0U && path->cc == NULL) { - LOG_DBG("NoCcProvidedForCcLen[%u]", path->cc_len); + LOG_ERR("NoCcProvidedForCcLen[%u]", path->cc_len); return -EINVAL; } @@ -300,14 +303,14 @@ int bt_iso_setup_data_path(const struct bt_iso_chan *chan, uint8_t dir, err = hci_le_setup_iso_data_path(chan->iso, dir, path); if (err != 0) { - LOG_DBG("SetDataPathFail[%d]", err); + LOG_ERR("SetDataPathFail[%d]", err); /* Return known possible errors */ if (err == -ENOBUFS || err == -EIO || err == -EACCES) { return err; } - LOG_DBG("UnkErrFromSetupIsoDataPath[%d]", err); + LOG_ERR("UnkErrFromSetupIsoDataPath[%d]", err); return -ENOEXEC; } @@ -360,21 +363,21 @@ static int validate_iso_remove_data_path(const struct bt_iso_chan *chan, uint8_t struct bt_conn *iso; CHECKIF(chan == NULL) { - LOG_DBG("ChanNull"); + LOG_ERR("ChanNull"); return -EINVAL; } CHECKIF(dir != BT_HCI_DATAPATH_DIR_HOST_TO_CTLR && dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) { - LOG_DBG("InvDir[%u]", dir); + LOG_ERR("InvDir[%u]", dir); return -EINVAL; } iso = chan->iso; if (iso == NULL) { - LOG_DBG("ChanNotAssociated[%p]", chan); + LOG_ERR("ChanNotAssociated[%p]", chan); return -ENODEV; } @@ -393,14 +396,14 @@ int bt_iso_remove_data_path(const struct bt_iso_chan *chan, uint8_t dir) err = hci_le_remove_iso_data_path(chan->iso, dir); if (err != 0) { - LOG_DBG("RemoveDataPathFail[%d]", err); + LOG_ERR("RemoveDataPathFail[%d]", err); /* Return known possible errors */ if (err == -ENOBUFS || err == -EIO || err == -EACCES) { return err; } - LOG_DBG("UnkErrFromRemoveIsoDataPath[%d]", err); + LOG_ERR("UnkErrFromRemoveIsoDataPath[%d]", err); return -ENOEXEC; } @@ -438,7 +441,7 @@ static void bt_iso_chan_disconnected(struct bt_iso_chan *chan, uint8_t reason) const uint8_t conn_type = chan->iso->iso.info.type; - LOG_DBG("IsoChanDisconnected[%02x]", reason); + LOG_INF("IsoChanDisconnected[%02x]", reason); bt_iso_chan_set_state(chan, BT_ISO_STATE_DISCONNECTED); bt_conn_set_state(chan->iso, BT_CONN_DISCONNECT_COMPLETE); @@ -492,6 +495,7 @@ static void bt_iso_chan_disconnected(struct bt_iso_chan *chan, uint8_t reason) * complete in the same way as ACL and CIS do. Call bt_conn_tx_notify directly here * to flush the chan->iso->tx_complete for each disconnected BIS */ + /* TBD: do we need to clean the BIS tx list here? */ } else { /* No special handling for BT_ISO_CHAN_TYPE_SYNC_RECEIVER */ } @@ -525,8 +529,6 @@ const char *bt_iso_chan_state_str(uint8_t state) return "disconnected"; case BT_ISO_STATE_CONNECTING: return "connecting"; - case BT_ISO_STATE_ENCRYPT_PENDING: - return "encryption pending"; case BT_ISO_STATE_CONNECTED: return "connected"; case BT_ISO_STATE_DISCONNECTING: @@ -547,8 +549,6 @@ void bt_iso_chan_set_state_debug(struct bt_iso_chan *chan, enum bt_iso_state sta case BT_ISO_STATE_DISCONNECTED: /* regardless of old state always allows this states */ break; - case BT_ISO_STATE_ENCRYPT_PENDING: - __fallthrough; case BT_ISO_STATE_CONNECTING: if (chan->state != BT_ISO_STATE_DISCONNECTED) { LOG_WRN("InvTransition[%s][%d]", func, line); @@ -691,8 +691,8 @@ static bool valid_chan_io_qos(const struct bt_iso_chan_io_qos *io_qos, bool is_t LOG_DBG("ValidChanIoQos[%u][%u][%u]", is_tx, is_broadcast, advanced); if (io_qos->phy != BT_GAP_LE_PHY_1M && - io_qos->phy != BT_GAP_LE_PHY_2M && - io_qos->phy != BT_GAP_LE_PHY_CODED) { + io_qos->phy != BT_GAP_LE_PHY_2M && + io_qos->phy != BT_GAP_LE_PHY_CODED) { LOG_ERR("InvPhy[%u]", io_qos->phy); return false; @@ -816,17 +816,6 @@ int bt_iso_chan_disconnect(struct bt_iso_chan *chan) return -ENOTCONN; } - if (chan->state == BT_ISO_STATE_ENCRYPT_PENDING) { - LOG_WRN("ChanAlreadyDisconnected"); - bt_iso_chan_set_state(chan, BT_ISO_STATE_DISCONNECTED); - - if (chan->ops->disconnected) { - chan->ops->disconnected(chan, BT_HCI_ERR_LOCALHOST_TERM_CONN); - } - - return 0; - } - if (chan->state == BT_ISO_STATE_DISCONNECTING) { LOG_WRN("AlreadyDisconnecting"); @@ -950,14 +939,14 @@ static void store_cis_info(const struct bt_hci_evt_le_cis_established *evt, stru central->bn = evt->c_bn; central->phy = bt_get_phy(evt->c_phy); - central->latency = sys_get_le16(evt->c_latency); + central->latency = sys_get_le24(evt->c_latency); central->max_pdu = sys_le16_to_cpu(evt->c_max_pdu); /* Transform to n * 1.25ms */ central->flush_timeout = info->iso_interval * evt->c_ft; peripheral->bn = evt->p_bn; peripheral->phy = bt_get_phy(evt->p_phy); - peripheral->latency = sys_get_le16(evt->p_latency); + peripheral->latency = sys_get_le24(evt->p_latency); peripheral->max_pdu = sys_le16_to_cpu(evt->p_max_pdu); /* Transform to n * 1.25ms */ peripheral->flush_timeout = info->iso_interval * evt->p_ft; @@ -1155,17 +1144,6 @@ int bt_iso_server_register(struct bt_iso_server *server) return -EINVAL; } -#if defined(CONFIG_BT_SMP) - if (server->sec_level > BT_SECURITY_L3) { - LOG_ERR("InvSrvSecLevel[%u]", server->sec_level); - return -EINVAL; - } else if (server->sec_level < BT_SECURITY_L1) { - LOG_DBG("SrvSecLevelUpdatedToL1"); - /* Level 0 is only applicable for BR/EDR */ - server->sec_level = BT_SECURITY_L1; - } -#endif /* CONFIG_BT_SMP */ - iso_server = server; return 0; @@ -1218,10 +1196,6 @@ static int iso_accept(struct bt_conn *acl, struct bt_conn *iso) return -ENOMEM; } -#if defined(CONFIG_BT_SMP) - chan->required_sec_level = iso_server->sec_level; -#endif /* CONFIG_BT_SMP */ - bt_iso_chan_add(iso, chan); bt_iso_chan_set_state(chan, BT_ISO_STATE_CONNECTING); @@ -1277,32 +1251,12 @@ static int hci_le_accept_cis(uint16_t handle) return 0; } -static uint8_t iso_server_check_security(struct bt_conn *conn) -{ - LOG_DBG("IsoSrvCheckSec[%u][%u]", conn->sec_level, iso_server->sec_level); - - if (IS_ENABLED(CONFIG_BT_CONN_DISABLE_SECURITY)) { - return BT_HCI_ERR_SUCCESS; - } - -#if defined(CONFIG_BT_SMP) - if (conn->sec_level >= iso_server->sec_level) { - return BT_HCI_ERR_SUCCESS; - } - - return BT_HCI_ERR_INSUFFICIENT_SECURITY; -#else - return BT_HCI_ERR_SUCCESS; -#endif /* CONFIG_BT_SMP */ -} - void hci_le_cis_req(struct net_buf *buf) { struct bt_hci_evt_le_cis_req *evt = (void *)buf->data; uint16_t acl_handle = sys_le16_to_cpu(evt->acl_handle); uint16_t cis_handle = sys_le16_to_cpu(evt->cis_handle); struct bt_conn *acl, *iso; - uint8_t sec_err; int err; LOG_DBG("CisReqEvt[%u][%u][%u][%u]", @@ -1331,18 +1285,6 @@ void hci_le_cis_req(struct net_buf *buf) return; } - sec_err = iso_server_check_security(acl); - if (sec_err != BT_HCI_ERR_SUCCESS) { - LOG_DBG("InsuffSec[%u]", sec_err); - err = hci_le_reject_cis(cis_handle, sec_err); - if (err != 0) { - LOG_ERR("RejectCisFail[%d]", err); - } - - bt_conn_unref(acl); - return; - } - /* Add ISO connection */ iso = bt_conn_add_iso(acl); @@ -1361,7 +1303,7 @@ void hci_le_cis_req(struct net_buf *buf) /* Request application to accept */ err = iso_accept(acl, iso); if (err) { - LOG_DBG("AppRejectedCis[%d]", err); + LOG_INF("AppRejectedCis[%d]", err); bt_iso_cleanup_acl(iso); bt_conn_unref(iso); hci_le_reject_cis(cis_handle, BT_HCI_ERR_INSUFFICIENT_RESOURCES); @@ -1412,17 +1354,17 @@ static bool valid_chan_qos(const struct bt_iso_chan_qos *qos, bool advanced) #endif /* CONFIG_BT_ISO_TEST_PARAMS */ if (qos->rx == NULL && qos->tx == NULL) { - LOG_DBG("BothRxAndTxQosNull"); + LOG_ERR("BothRxAndTxQosNull"); return false; } if (qos->rx != NULL && !valid_chan_io_qos(qos->rx, false, false, advanced)) { - LOG_DBG("InvRxQos"); + LOG_ERR("InvRxQos"); return false; } if (qos->tx != NULL && !valid_chan_io_qos(qos->tx, true, false, advanced)) { - LOG_DBG("InvTxQos"); + LOG_ERR("InvTxQos"); return false; } @@ -1459,7 +1401,7 @@ static struct net_buf *hci_le_set_cig_params(const struct bt_iso_cig *cig, struct net_buf *rsp; int i, err; - LOG_DBG("SetCigParams[%u]", cig->id); + LOG_INF("SetCigParams[%u]", cig->id); buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CIG_PARAMS, sizeof(*req) + sizeof(*cis_param) * param->num_cis); @@ -1482,7 +1424,7 @@ static struct net_buf *hci_le_set_cig_params(const struct bt_iso_cig *cig, req->framing = param->framing; req->num_cis = param->num_cis; - LOG_DBG("[%u][%u][%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("[%u][%u][%u][%u][%u][%u][%u][%u][%u]", cig->id, param->c_to_p_latency, param->p_to_c_latency, param->c_to_p_interval, param->p_to_c_interval, param->sca, param->packing, param->framing, param->num_cis); @@ -1526,7 +1468,7 @@ static struct net_buf *hci_le_set_cig_params(const struct bt_iso_cig *cig, cis_param->p_rtn = qos->rx->rtn; } - LOG_DBG("[%d]:[%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("[%d]:[%u][%u][%u][%u][%u][%u][%u]", i, cis_param->cis_id, cis_param->c_phy, cis_param->c_sdu, cis_param->c_rtn, cis_param->p_phy, cis_param->p_sdu, cis_param->p_rtn); @@ -1550,7 +1492,7 @@ static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, struct net_buf *rsp; int err; - LOG_DBG("SetCigTestParams"); + LOG_INF("SetCigTestParams"); buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CIG_PARAMS_TEST, sizeof(*req) + sizeof(*cis_param) * param->num_cis); @@ -1574,7 +1516,7 @@ static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, req->framing = param->framing; req->num_cis = param->num_cis; - LOG_DBG("[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", cig->id, param->c_to_p_interval, param->p_to_c_interval, param->c_to_p_ft, param->p_to_c_ft, param->iso_interval, param->sca, param->packing, param->framing, param->num_cis); @@ -1621,7 +1563,7 @@ static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, cis_param->p_bn = qos->rx->burst_number; } - LOG_DBG("[%d]:[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("[%d]:[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", i, cis_param->cis_id, cis_param->nse, cis_param->c_sdu, cis_param->p_sdu, cis_param->c_pdu, cis_param->p_pdu, cis_param->c_phy, cis_param->p_phy, cis_param->c_bn, @@ -1638,7 +1580,7 @@ static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig, static bool is_advanced_cig_param(const struct bt_iso_cig_param *param) { - LOG_DBG("IsAdvancedCigParam[%u][%u][%u]", + LOG_INF("IsAdvancedCigParam[%u][%u][%u]", param->c_to_p_ft, param->p_to_c_ft, param->iso_interval); if (param->c_to_p_ft != 0U || param->p_to_c_ft != 0U || param->iso_interval != 0U) { @@ -1673,7 +1615,7 @@ static bool is_advanced_cig_param(const struct bt_iso_cig_param *param) static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan) { - LOG_DBG("GetCig[%p]", iso_chan); + LOG_INF("GetCig[%p]", iso_chan); if (iso_chan == NULL || iso_chan->iso == NULL) { return NULL; @@ -1688,19 +1630,19 @@ static struct bt_iso_cig *get_free_cig(void) { /* We can use the index in the `cigs` array as CIG ID */ - LOG_DBG("GetFreeCig"); + LOG_INF("GetFreeCig"); for (size_t i = 0; i < ARRAY_SIZE(cigs); i++) { if (cigs[i].state == BT_ISO_CIG_STATE_IDLE) { cigs[i].state = BT_ISO_CIG_STATE_CONFIGURED; cigs[i].id = i; sys_slist_init(&cigs[i].cis_channels); - LOG_DBG("CigNew[%zu]", i); + LOG_INF("CigNew[%zu]", i); return &cigs[i]; } } - LOG_ERR("NoFreeCig"); + LOG_WRN("NoFreeCig"); return NULL; } @@ -1716,7 +1658,7 @@ static bool cis_is_in_cig(const struct bt_iso_cig *cig, const struct bt_iso_chan static int cig_init_cis(struct bt_iso_cig *cig, const struct bt_iso_cig_param *param) { - LOG_DBG("CigInitCis[%u]", cig->id); + LOG_INF("CigInitCis[%u]", cig->id); for (uint8_t i = 0; i < param->num_cis; i++) { struct bt_iso_chan *cis = param->cis_channels[i]; @@ -1726,7 +1668,7 @@ static int cig_init_cis(struct bt_iso_cig *cig, const struct bt_iso_cig_param *p cis->iso = iso_new(); if (cis->iso == NULL) { - LOG_ERR("NoFreeCis"); + LOG_WRN("NoFreeCis"); return -ENOMEM; } iso_conn = &cis->iso->iso; @@ -1748,7 +1690,7 @@ static void cleanup_cig(struct bt_iso_cig *cig) { struct bt_iso_chan *cis, *tmp; - LOG_DBG("CleanupCig"); + LOG_INF("CleanupCig"); SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&cig->cis_channels, cis, tmp, node) { if (cis->iso != NULL) { @@ -1818,6 +1760,15 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced, if (cis->qos->tx != NULL && cis->qos->tx->sdu != 0U) { is_c_to_p = true; } + + /* Validate the current CIS, not the cumulative is_*_to_* flags: once an + * earlier CIS sets a direction the flags would mask a later CIS that has none. + */ + if ((cis->qos->rx == NULL || cis->qos->rx->sdu == 0U) && + (cis->qos->tx == NULL || cis->qos->tx->sdu == 0U)) { + LOG_ERR("InvNoSduDir[%u]", i); + return false; + } } if (param->framing != BT_ISO_FRAMING_UNFRAMED && param->framing != BT_ISO_FRAMING_FRAMED) { @@ -1941,7 +1892,7 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, struct bt_iso_cig ** err = cig_init_cis(cig, param); if (err) { - LOG_DBG("InitCisFail[%d]", err); + LOG_WRN("InitCisFail[%d]", err); cleanup_cig(cig); return err; } @@ -1984,7 +1935,7 @@ int bt_iso_cig_create(const struct bt_iso_cig_param *param, struct bt_iso_cig ** *out_cig = cig; - LOG_DBG("OutCig[%u]", cig->id); + LOG_INF("OutCig[%u]", cig->id); return err; } @@ -1994,7 +1945,7 @@ static void restore_cig(struct bt_iso_cig *cig, uint8_t existing_num_cis) struct bt_iso_chan *cis, *tmp; sys_snode_t *prev = NULL; - LOG_DBG("RestoreCig[%u][%u]", cig->id, existing_num_cis); + LOG_INF("RestoreCig[%u][%u]", cig->id, existing_num_cis); SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&cig->cis_channels, cis, tmp, node) { /* Remove all newly added by comparing the cis_id to the number @@ -2045,7 +1996,7 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, const struct bt_iso_cig_param #endif /* CONFIG_BT_ISO_TEST_PARAMS */ CHECKIF(!valid_cig_param(param, advanced, cig)) { - LOG_DBG("InvCigParams"); + LOG_ERR("InvCigParams"); return -EINVAL; } @@ -2054,7 +2005,7 @@ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, const struct bt_iso_cig_param err = cig_init_cis(cig, param); if (err != 0) { - LOG_DBG("InitCisFail[%d]", err); + LOG_ERR("InitCisFail[%d]", err); restore_cig(cig, existing_num_cis); return err; } @@ -2111,7 +2062,7 @@ int bt_iso_cig_terminate(struct bt_iso_cig *cig) { int err; - LOG_DBG("IsoCigTerminate"); + LOG_INF("IsoCigTerminate"); CHECKIF(cig == NULL) { LOG_ERR("CigNull"); @@ -2140,7 +2091,7 @@ static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t co struct bt_hci_cp_le_create_cis *req; struct net_buf *buf; - LOG_DBG("CreateCis[%u]", count); + LOG_INF("CreateCis[%u]", count); buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_CIS, sizeof(*req) + sizeof(*cis) * count); if (!buf) { @@ -2153,12 +2104,6 @@ static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t co /* Program the cis parameters */ for (size_t i = 0; i < count; i++) { - struct bt_iso_chan *iso_chan = param[i].iso_chan; - - if (iso_chan->state == BT_ISO_STATE_ENCRYPT_PENDING) { - continue; - } - cis = net_buf_add(buf, sizeof(*cis)); memset(cis, 0, sizeof(*cis)); @@ -2168,90 +2113,25 @@ static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t co req->num_cis++; } - /* If all CIS are pending for security, do nothing, - * but return a recognizable return value - */ - if (req->num_cis == 0) { - net_buf_unref(buf); - - return -ECANCELED; - } - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CIS, buf, NULL); } -#if defined(CONFIG_BT_SMP) -static int iso_chan_connect_security(const struct bt_iso_connect_param *param, size_t count) -{ - /* conn_idx_handled is an array of booleans for which conn indexes - * already have been used to call bt_conn_set_security. - * Using indexes avoids looping the array when checking if it has been - * handled. - */ - bool conn_idx_handled[CONFIG_BT_MAX_CONN]; - - LOG_DBG("IsoChanConnectSec[%u]", count); - - memset(conn_idx_handled, false, sizeof(conn_idx_handled)); - for (size_t i = 0; i < count; i++) { - struct bt_iso_chan *iso_chan = param[i].iso_chan; - struct bt_conn *acl = param[i].acl; - uint8_t conn_idx = bt_conn_index(acl); - - LOG_DBG("SecLevel[%zu][%u][%u]", - i, acl->sec_level, iso_chan->required_sec_level); - - if (acl->sec_level < iso_chan->required_sec_level) { - if (!conn_idx_handled[conn_idx]) { - int err; - - err = bt_conn_set_security(acl, iso_chan->required_sec_level); - if (err != 0) { - LOG_ERR("SetSecFail[%zu][%d]", i, err); - - /* Restore states */ - for (size_t j = 0; j < i; j++) { - iso_chan = param[j].iso_chan; - - if (iso_chan->state == BT_ISO_STATE_ENCRYPT_PENDING) { - bt_iso_cleanup_acl(iso_chan->iso); - bt_iso_chan_set_state(iso_chan, - BT_ISO_STATE_DISCONNECTED); - } - } - - return err; - } - - conn_idx_handled[conn_idx] = true; - } - - iso_chan->iso->iso.acl = bt_conn_ref(acl); - bt_iso_chan_set_state(iso_chan, BT_ISO_STATE_ENCRYPT_PENDING); - } - } - - return 0; -} -#endif /* CONFIG_BT_SMP */ - static bool iso_chans_connecting(void) { - LOG_DBG("IsoChansConnecting"); + LOG_INF("IsoChansConnecting"); for (size_t i = 0U; i < ARRAY_SIZE(iso_conns); i++) { const struct bt_conn *iso = &iso_conns[i]; const struct bt_iso_chan *iso_chan; if (!(iso->iso.info.type == BT_ISO_CHAN_TYPE_CENTRAL || - iso->iso.info.type == BT_ISO_CHAN_TYPE_PERIPHERAL)) { + iso->iso.info.type == BT_ISO_CHAN_TYPE_PERIPHERAL)) { continue; } iso_chan = iso_chan(iso); if (iso_chan != NULL && - (iso_chan->state == BT_ISO_STATE_CONNECTING || - iso_chan->state == BT_ISO_STATE_ENCRYPT_PENDING)) { + iso_chan->state == BT_ISO_STATE_CONNECTING) { return true; } } @@ -2263,7 +2143,7 @@ int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count) { int err; - LOG_DBG("IsoChanConnect[%u]", count); + LOG_INF("IsoChanConnect[%u]", count); CHECKIF(param == NULL) { LOG_ERR("ParamNull"); @@ -2313,23 +2193,8 @@ int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count) return -EBUSY; } -#if defined(CONFIG_BT_SMP) - /* Check for and initiate security for all channels that have - * requested encryption if the ACL link is not already secured - */ - err = iso_chan_connect_security(param, count); - if (err != 0) { - LOG_ERR("InitSecForCisFail[%d]", err); - return err; - } -#endif /* CONFIG_BT_SMP */ - err = hci_le_create_cis(param, count); - if (err == -ECANCELED) { - LOG_DBG("CisPendingOnSec"); - - return 0; - } else if (err != 0) { + if (err != 0) { LOG_ERR("ConnectCisFail[%d]", err); return err; @@ -2340,10 +2205,6 @@ int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count) struct bt_iso_chan *iso_chan = param[i].iso_chan; struct bt_iso_cig *cig; - if (iso_chan->state == BT_ISO_STATE_ENCRYPT_PENDING) { - continue; - } - iso_chan->iso->iso.acl = bt_conn_ref(param[i].acl); bt_conn_set_state(iso_chan->iso, BT_CONN_INITIATING); bt_iso_chan_set_state(iso_chan, BT_ISO_STATE_CONNECTING); @@ -2379,12 +2240,12 @@ static struct bt_iso_big *get_free_big(void) if (!atomic_test_and_set_bit(bigs[i].flags, BT_BIG_INITIALIZED)) { bigs[i].handle = i; sys_slist_init(&bigs[i].bis_channels); - LOG_DBG("BigNew[%u]", i); + LOG_INF("BigNew[%u]", i); return &bigs[i]; } } - LOG_ERR("NoFreeBig"); + LOG_WRN("NoFreeBig"); return NULL; } @@ -2428,7 +2289,7 @@ static void big_disconnect(struct bt_iso_big *big, uint8_t reason) { struct bt_iso_chan *bis; - LOG_DBG("BigDisconnect[%02x]", reason); + LOG_INF("BigDisconnect[%02x]", reason); atomic_set_bit(big->flags, BT_BIG_BUSY); @@ -2457,13 +2318,13 @@ static void big_disconnect(struct bt_iso_big *big, uint8_t reason) static int big_init_bis(struct bt_iso_big *big, struct bt_iso_chan *bis, uint8_t bis_number, bool broadcaster) { - LOG_DBG("BigInitBis[%u][%u][%u]", big->handle, bis_number, broadcaster); + LOG_INF("BigInitBis[%u][%u][%u]", big->handle, bis_number, broadcaster); struct bt_conn_iso *iso_conn; bis->iso = iso_new(); if (bis->iso == NULL) { - LOG_ERR("NoFreeBis"); + LOG_WRN("NoFreeBis"); return -ENOMEM; } @@ -2494,13 +2355,13 @@ static int big_init_bis(struct bt_iso_big *big, struct bt_iso_chan *bis, uint8_t int bt_iso_big_register_cb(struct bt_iso_big_cb *cb) { CHECKIF(cb == NULL) { - LOG_DBG("BigCbNull"); + LOG_ERR("BigCbNull"); return -EINVAL; } if (sys_slist_find(&iso_big_cbs, &cb->_node, NULL)) { - LOG_DBG("BigCbAlreadyReg[%p]", cb); + LOG_WRN("BigCbAlreadyReg[%p]", cb); return -EEXIST; } @@ -2520,7 +2381,7 @@ static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big, int err; struct bt_iso_chan *bis; - LOG_DBG("CreateBig"); + LOG_INF("CreateBig"); buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_BIG, sizeof(*req)); @@ -2552,12 +2413,12 @@ static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big, memset(req->bcode, 0, sizeof(req->bcode)); } - LOG_DBG("[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", req->big_handle, req->adv_handle, req->num_bis, param->interval, req->max_sdu, req->max_latency, req->rtn, req->phy, req->packing, req->framing, req->encryption); if (req->encryption) { - LOG_DBG("[%s]", bt_hex(req->bcode, sizeof(req->bcode))); + LOG_INF("[%s]", bt_hex(req->bcode, sizeof(req->bcode))); } err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_BIG, buf, NULL); @@ -2583,7 +2444,7 @@ static int hci_le_create_big_test(const struct bt_le_ext_adv *padv, struct bt_is struct net_buf *buf; int err; - LOG_DBG("CreateBigTest"); + LOG_INF("CreateBigTest"); buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_BIG_TEST, sizeof(*req)); @@ -2619,13 +2480,13 @@ static int hci_le_create_big_test(const struct bt_le_ext_adv *padv, struct bt_is memset(req->bcode, 0, sizeof(req->bcode)); } - LOG_DBG("[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("[%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", req->big_handle, req->adv_handle, req->num_bis, param->interval, param->iso_interval, req->nse, req->max_sdu, req->max_pdu, req->phy, req->packing, req->framing, req->bn, req->irc, req->pto, req->encryption); if (req->encryption) { - LOG_DBG("[%s]", bt_hex(req->bcode, sizeof(req->bcode))); + LOG_INF("[%s]", bt_hex(req->bcode, sizeof(req->bcode))); } err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_BIG_TEST, buf, NULL); @@ -2642,7 +2503,7 @@ static int hci_le_create_big_test(const struct bt_le_ext_adv *padv, struct bt_is static bool is_advanced_big_param(const struct bt_iso_big_create_param *param) { - LOG_DBG("IsAdvancedBigParam[%u][%u]", param->irc, param->iso_interval); + LOG_INF("IsAdvancedBigParam[%u][%u]", param->irc, param->iso_interval); if (param->irc != 0U || param->iso_interval != 0U) { return true; @@ -2823,7 +2684,7 @@ int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param err = big_init_bis(big, bis_channels[i], bis_number, true); if (err != 0) { - LOG_DBG("InitBisFail[%u][%d]", i, err); + LOG_ERR("InitBisFail[%u][%d]", i, err); cleanup_big(big); return err; @@ -2848,7 +2709,7 @@ int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *out_big = big; - LOG_DBG("OutBig[%u]", big->handle); + LOG_INF("OutBig[%u]", big->handle); return err; } @@ -2877,7 +2738,7 @@ static void store_bis_broadcaster_info(const struct bt_hci_evt_le_big_complete * info->can_send = true; info->can_recv = false; - LOG_DBG("StoreBisInfo[%u]", broadcaster_info->pto); + LOG_INF("StoreBisInfo[%u]", broadcaster_info->pto); } void hci_le_big_complete(struct net_buf *buf) @@ -2887,8 +2748,8 @@ void hci_le_big_complete(struct net_buf *buf) struct bt_iso_big *big; int i; - LOG_DBG("BigComp"); - LOG_DBG("Evt[%02x][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("BigComp"); + LOG_INF("Evt[%02x][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u][%u]", evt->status, evt->big_handle, sys_get_le24(evt->sync_delay), sys_get_le24(evt->latency), evt->phy, evt->nse, evt->bn, evt->pto, evt->irc, evt->max_pdu, evt->iso_interval, @@ -2925,7 +2786,7 @@ void hci_le_big_complete(struct net_buf *buf) const uint16_t handle = evt->handle[i++]; struct bt_conn *iso_conn = bis->iso; - LOG_DBG("BisHdl[%04x]", handle); + LOG_INF("BisHdl[%04x]", handle); iso_conn->handle = sys_le16_to_cpu(handle); store_bis_broadcaster_info(evt, iso_conn); @@ -2950,7 +2811,7 @@ void hci_le_big_terminate(struct net_buf *buf) struct bt_hci_evt_le_big_terminate *evt = (void *)buf->data; struct bt_iso_big *big; - LOG_DBG("BigTerminateEvt[%u][%02x]", evt->big_handle, evt->reason); + LOG_INF("BigTerminateEvt[%u][%02x]", evt->big_handle, evt->reason); if (evt->big_handle >= ARRAY_SIZE(bigs)) { LOG_ERR("InvBigHdl[%u][%u]", evt->big_handle, ARRAY_SIZE(bigs)); @@ -3041,7 +2902,7 @@ int bt_iso_big_terminate(struct bt_iso_big *big) } if (atomic_test_bit(big->flags, BT_BIG_BUSY)) { - LOG_DBG("BigBusy[%u]", big->handle); + LOG_WRN("BigBusy[%u]", big->handle); return -EBUSY; } @@ -3111,8 +2972,8 @@ void hci_le_big_sync_established(struct net_buf *buf) struct bt_iso_big *big; int i; - LOG_DBG("BigSyncEstab"); - LOG_DBG("Evt[%02x][%u][%u][%u][%u][%u][%u][%u][%u][%u]", + LOG_INF("BigSyncEstab"); + LOG_INF("Evt[%02x][%u][%u][%u][%u][%u][%u][%u][%u][%u]", evt->status, evt->big_handle, sys_get_le24(evt->latency), evt->nse, evt->bn, evt->pto, evt->irc, evt->max_pdu, evt->iso_interval, evt->num_bis); @@ -3148,7 +3009,7 @@ void hci_le_big_sync_established(struct net_buf *buf) const uint16_t handle = evt->handle[i++]; struct bt_conn *iso_conn = bis->iso; - LOG_DBG("BisHdl[%04x]", handle); + LOG_INF("BisHdl[%04x]", handle); iso_conn->handle = sys_le16_to_cpu(handle); store_bis_sync_receiver_info(evt, iso_conn); @@ -3173,7 +3034,7 @@ void hci_le_big_sync_lost(struct net_buf *buf) struct bt_hci_evt_le_big_sync_lost *evt = (void *)buf->data; struct bt_iso_big *big; - LOG_DBG("BigSyncLostEvt[%u][%02x]", evt->big_handle, evt->reason); + LOG_INF("BigSyncLostEvt[%u][%02x]", evt->big_handle, evt->reason); if (evt->big_handle >= ARRAY_SIZE(bigs)) { LOG_ERR("InvBigHdl[%u][%u]", evt->big_handle, ARRAY_SIZE(bigs)); @@ -3195,7 +3056,7 @@ static int hci_le_big_create_sync(const struct bt_le_per_adv_sync *sync, struct int err; uint8_t bit_idx = 0; - LOG_DBG("BigCreateSync[%u][%u]", big->handle, big->num_bis); + LOG_INF("BigCreateSync[%u][%u]", big->handle, big->num_bis); buf = bt_hci_cmd_create(BT_HCI_OP_LE_BIG_CREATE_SYNC, sizeof(*req) + big->num_bis); if (!buf) { @@ -3346,7 +3207,7 @@ int bt_iso_big_sync(struct bt_le_per_adv_sync *sync, struct bt_iso_big_sync_para */ err = big_init_bis(big, bis_channels[i], bis_number, false); if (err != 0) { - LOG_DBG("InitBisFail[%u]: %d", i, err); + LOG_ERR("InitBisFail[%u]: %d", i, err); cleanup_big(big); return err; @@ -3357,7 +3218,7 @@ int bt_iso_big_sync(struct bt_le_per_adv_sync *sync, struct bt_iso_big_sync_para err = hci_le_big_create_sync(sync, big, param); if (err) { - LOG_DBG("CreateBigSyncFail[%d]", err); + LOG_ERR("CreateBigSyncFail[%d]", err); cleanup_big(big); return err; } @@ -3368,7 +3229,7 @@ int bt_iso_big_sync(struct bt_le_per_adv_sync *sync, struct bt_iso_big_sync_para *out_big = big; - LOG_DBG("OutBig[%u]", big->handle); + LOG_INF("OutBig[%u]", big->handle); return 0; } diff --git a/components/bt/esp_ble_iso/include/subsys/bluetooth/host/conn_internal.h b/components/bt/esp_ble_iso/include/subsys/bluetooth/host/conn_internal.h index b9d8c125185..c65f5413241 100644 --- a/components/bt/esp_ble_iso/include/subsys/bluetooth/host/conn_internal.h +++ b/components/bt/esp_ble_iso/include/subsys/bluetooth/host/conn_internal.h @@ -29,7 +29,7 @@ typedef enum __packed { struct bt_conn_le { bt_addr_le_t dst; - uint16_t interval; + uint32_t interval_us; /** @brief Remote LE features * @@ -114,5 +114,7 @@ bool bt_conn_is_peer_addr_le(const struct bt_conn *conn, uint8_t id, */ #define BT_CONN_INDEX_INVALID 0xff +struct bt_conn *bt_conn_lookup_index(uint8_t index); + /* Set connection object in certain state and perform action related to state */ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state); diff --git a/components/bt/esp_ble_iso/include/zephyr/bluetooth/conn.h b/components/bt/esp_ble_iso/include/zephyr/bluetooth/conn.h index 594b25509a7..e9fcbb6ab6a 100644 --- a/components/bt/esp_ble_iso/include/zephyr/bluetooth/conn.h +++ b/components/bt/esp_ble_iso/include/zephyr/bluetooth/conn.h @@ -112,7 +112,7 @@ struct bt_conn_le_info { * Address (RPA) before identity has been resolved. */ const bt_addr_le_t *dst; - uint16_t interval; /**< Connection interval */ + uint32_t interval_us; /**< Connection interval in microseconds */ }; /** @brief Convert connection interval to milliseconds diff --git a/components/bt/esp_ble_iso/include/zephyr/bluetooth/iso.h b/components/bt/esp_ble_iso/include/zephyr/bluetooth/iso.h index 08500234ecd..a555865eb22 100644 --- a/components/bt/esp_ble_iso/include/zephyr/bluetooth/iso.h +++ b/components/bt/esp_ble_iso/include/zephyr/bluetooth/iso.h @@ -182,8 +182,6 @@ extern "C" { enum bt_iso_state { /** Channel disconnected */ BT_ISO_STATE_DISCONNECTED, - /** Channel is pending ACL encryption before connecting */ - BT_ISO_STATE_ENCRYPT_PENDING, /** Channel in connecting state */ BT_ISO_STATE_CONNECTING, /** Channel ready for upper layer traffic on it */ @@ -213,17 +211,6 @@ struct bt_iso_chan { struct bt_iso_chan_qos *qos; /** Channel state */ enum bt_iso_state state; - /** - * @brief The required security level of the channel - * - * This value can be set as the central before connecting a CIS - * with bt_iso_chan_connect(). - * The value is overwritten to @ref bt_iso_server::sec_level for the - * peripheral once a channel has been accepted. - * - * Only available when @kconfig{CONFIG_BT_SMP} is enabled. - */ - bt_security_t required_sec_level; /** @internal Node used internally by the stack */ sys_snode_t node; }; @@ -783,13 +770,6 @@ struct bt_iso_accept_info { /** @brief ISO Server structure. */ struct bt_iso_server { - /** - * @brief Required minimum security level. - * - * Only available when @kconfig{CONFIG_BT_SMP} is enabled. - */ - bt_security_t sec_level; - /** * @brief Server accept callback * diff --git a/examples/bluetooth/esp_ble_iso/cis_central/main/main.c b/examples/bluetooth/esp_ble_iso/cis_central/main/main.c index 423faf1eca6..76ced1a872c 100644 --- a/examples/bluetooth/esp_ble_iso/cis_central/main/main.c +++ b/examples/bluetooth/esp_ble_iso/cis_central/main/main.c @@ -120,7 +120,6 @@ static esp_ble_iso_chan_qos_t iso_qos = { static esp_ble_iso_chan_t iso_chan = { .ops = &iso_ops, .qos = &iso_qos, - .required_sec_level = SECURITY_LEVEL, }; static void create_cig_and_cis(uint16_t acl_handle) @@ -253,8 +252,8 @@ static void acl_connect(esp_ble_iso_gap_app_event_t *event) event->acl_connect.conn_handle, event->acl_connect.role, EXAMPLE_BT_ADDR_PRINT_ARGS(event->acl_connect.dst.val)); - if (iso_chan.required_sec_level == ESP_BLE_ISO_SECURITY_NO_MITM || - iso_chan.required_sec_level == ESP_BLE_ISO_SECURITY_MITM) { + if (SECURITY_LEVEL == ESP_BLE_ISO_SECURITY_NO_MITM || + SECURITY_LEVEL == ESP_BLE_ISO_SECURITY_MITM) { err = pairing_start(event->acl_connect.conn_handle); if (err) { ESP_LOGE(TAG, "Failed to initiate security, err %d", err); diff --git a/examples/bluetooth/esp_ble_iso/cis_peripheral/main/main.c b/examples/bluetooth/esp_ble_iso/cis_peripheral/main/main.c index eeb0f80b95c..d4e6dd0286f 100644 --- a/examples/bluetooth/esp_ble_iso/cis_peripheral/main/main.c +++ b/examples/bluetooth/esp_ble_iso/cis_peripheral/main/main.c @@ -19,8 +19,6 @@ #include "peripheral.h" -#define SECURITY_LEVEL ESP_BLE_ISO_SECURITY_NO_MITM - #define CIS_SDU_SIZE 120 static uint8_t ext_adv_data[3 + 2 + LOCAL_DEVICE_NAME_LEN]; @@ -95,7 +93,6 @@ static int iso_accept(const esp_ble_iso_accept_info_t *info, } static esp_ble_iso_server_t iso_server = { - .sec_level = SECURITY_LEVEL, .accept = iso_accept, };