From 7daadbcd90f92d7dca0924e6e04b7bec23551d6a Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Tue, 1 Apr 2025 11:03:37 +0800 Subject: [PATCH] feat(bt/bluedroid): Support BLE CTE in bluedroid host (cherry picked from commit fcad8b7ebdb7250daef00244fa59e5e9424e1689) Co-authored-by: zhiweijian --- components/bt/CMakeLists.txt | 6 + components/bt/common/btc/core/btc_task.c | 7 + .../bt/common/btc/include/btc/btc_task.h | 3 + components/bt/host/bluedroid/Kconfig.in | 21 + .../bt/host/bluedroid/api/esp_ble_cte_api.c | 224 ++++++++++ .../api/include/api/esp_ble_cte_api.h | 379 +++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 51 +++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 180 ++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 14 + .../bluedroid/bta/dm/include/bta_dm_int.h | 116 +++++ .../host/bluedroid/bta/include/bta/bta_api.h | 43 ++ .../btc/profile/std/cte/btc_ble_cte.c | 395 ++++++++++++++++++ .../btc/profile/std/include/btc_ble_cte.h | 98 +++++ .../include/common/bluedroid_user_config.h | 18 + .../common/include/common/bt_target.h | 18 + .../bt/host/bluedroid/stack/btm/btm_ble_cte.c | 237 +++++++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 7 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 113 +++++ .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 194 +++++++++ .../stack/include/stack/btm_ble_api.h | 142 +++++++ .../bluedroid/stack/include/stack/hcidefs.h | 20 + .../bluedroid/stack/include/stack/hcimsgs.h | 30 ++ 22 files changed, 2316 insertions(+) create mode 100644 components/bt/host/bluedroid/api/esp_ble_cte_api.c create mode 100644 components/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h create mode 100644 components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c create mode 100644 components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h create mode 100644 components/bt/host/bluedroid/stack/btm/btm_ble_cte.c diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index ac562e81ae..b28b1a6049 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -475,6 +475,12 @@ if(CONFIG_BT_ENABLED) "host/bluedroid/hci/ble_hci_iso.c") endif() + if(CONFIG_BT_BLE_FEAT_CTE_EN) + list(APPEND srcs "host/bluedroid/stack/btm/btm_ble_cte.c" + "host/bluedroid/btc/profile/std/cte/btc_ble_cte.c" + "host/bluedroid/api/esp_ble_cte_api.c") + endif() + endif() if(CONFIG_BLE_MESH) diff --git a/components/bt/common/btc/core/btc_task.c b/components/bt/common/btc/core/btc_task.c index 81a98792d9..c2a44eebfc 100644 --- a/components/bt/common/btc/core/btc_task.c +++ b/components/bt/common/btc/core/btc_task.c @@ -25,6 +25,7 @@ #include "btc_gatt_common.h" #include "btc_gap_ble.h" #include "btc_iso_ble.h" +#include "btc_ble_cte.h" #include "btc/btc_dm.h" #include "bta/bta_gatt_api.h" #if CLASSIC_BT_INCLUDED @@ -262,6 +263,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = { #if (BLE_FEAT_ISO_EN == TRUE) [BTC_PID_ISO_BLE] = {btc_iso_ble_call_handler, btc_iso_ble_cb_handler }, #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) + [BTC_PID_BLE_CTE] = {btc_ble_cte_call_handler, btc_ble_cte_cb_handler }, +#endif // #if (BLE_FEAT_CTE_EN == TRUE) }; /***************************************************************************** @@ -532,6 +536,9 @@ bt_status_t btc_init(void) #if (BLE_FEAT_ISO_EN == TRUE) btc_iso_callback_init(); #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) + btc_cte_callback_init(); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) btc_gap_ble_init(); #endif ///BLE_INCLUDED == TRUE diff --git a/components/bt/common/btc/include/btc/btc_task.h b/components/bt/common/btc/include/btc/btc_task.h index 6e19a87cc0..b1fbf3edf3 100644 --- a/components/bt/common/btc/include/btc/btc_task.h +++ b/components/bt/common/btc/include/btc/btc_task.h @@ -108,6 +108,9 @@ typedef enum { #if (BLE_FEAT_ISO_EN == TRUE) BTC_PID_ISO_BLE, #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) + BTC_PID_BLE_CTE, +#endif // #if (BLE_FEAT_CTE_EN == TRUE) BTC_PID_NUM, } btc_pid_t; //btc profile id diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index e965f78e84..1a6d20a062 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1382,6 +1382,27 @@ choice BT_BLE_ISO_FLOW_CONTROL endchoice +menuconfig BT_BLE_FEAT_CTE_EN + bool "Enable BLE CTE feature" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_CTE_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable BLE 5.1 CTE + +config BT_BLE_FEAT_CTE_CONNECTIONLESS_EN + bool "Enable BLE CTE connectionless feature" + depends on BT_BLE_FEAT_CTE_EN + default y + help + Transmission of CTE in periodic advertising + +config BT_BLE_FEAT_CTE_CONNECTION_EN + bool "Enable BLE CTE connection feature" + depends on BT_BLE_FEAT_CTE_EN + default y + help + Transmission of CTE by ACL connection + config BT_BLE_HIGH_DUTY_ADV_INTERVAL bool "Enable BLE high duty advertising interval feature" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_ble_cte_api.c b/components/bt/host/bluedroid/api/esp_ble_cte_api.c new file mode 100644 index 0000000000..37503c4746 --- /dev/null +++ b/components/bt/host/bluedroid/api/esp_ble_cte_api.c @@ -0,0 +1,224 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_bt_device.h" +#include "esp_bt_main.h" +#if (BLE_FEAT_CTE_EN == TRUE) +#include "esp_ble_cte_api.h" +#include "btc_ble_cte.h" +#include "btc/btc_manage.h" + + +esp_err_t esp_ble_cte_register_callback(esp_ble_cte_cb_t callback) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + return (btc_profile_cb_set(BTC_PID_BLE_CTE, callback) == 0 ? ESP_OK : ESP_FAIL); +} + +esp_ble_cte_cb_t esp_ble_cte_get_callback(void) +{ + return (esp_ble_cte_cb_t) btc_profile_cb_get(BTC_PID_BLE_CTE); +} + +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +esp_err_t esp_ble_cte_set_connectionless_trans_params(esp_ble_cte_connless_trans_params_t *cte_trans_params) +{ + btc_msg_t msg; + btc_ble_cte_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if ((cte_trans_params == NULL) || (cte_trans_params->antenna_ids == NULL)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_SET_TRANS_PARAMS; + + arg.cte_trans_params.adv_handle = cte_trans_params->adv_handle; + arg.cte_trans_params.cte_len = cte_trans_params->cte_len; + arg.cte_trans_params.cte_type = cte_trans_params->cte_type; + arg.cte_trans_params.cte_count = cte_trans_params->cte_count; + arg.cte_trans_params.switching_pattern_len = cte_trans_params->switching_pattern_len; + arg.cte_trans_params.antenna_ids = cte_trans_params->antenna_ids; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cte_set_connectionless_trans_enable(esp_ble_cte_trans_enable_params_t *cte_trans_enable) +{ + btc_msg_t msg; + btc_ble_cte_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (cte_trans_enable == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_SET_TRANS_ENABLE; + + arg.cte_trans_enable.adv_handle = cte_trans_enable->adv_handle; + arg.cte_trans_enable.cte_enable = cte_trans_enable->cte_enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), NULL , NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cte_set_connectionless_iq_sampling_enable(esp_ble_cte_iq_sampling_params_t *iq_sampling_en) +{ + btc_msg_t msg; + btc_ble_cte_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if ((iq_sampling_en == NULL) || (iq_sampling_en->antenna_ids == NULL)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_SET_IQ_SAMPLING_EN; + + arg.cte_iq_sampling_en.sync_handle = iq_sampling_en->sync_handle; + arg.cte_iq_sampling_en.sampling_en = iq_sampling_en->sampling_en; + arg.cte_iq_sampling_en.slot_dur = iq_sampling_en->slot_dur; + arg.cte_iq_sampling_en.max_sampled_ctes = iq_sampling_en->max_sampled_ctes; + arg.cte_iq_sampling_en.switching_pattern_len = iq_sampling_en->switching_pattern_len; + arg.cte_iq_sampling_en.antenna_ids = iq_sampling_en->antenna_ids; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +esp_err_t esp_ble_cte_set_connection_receive_params(esp_ble_cte_recv_params_params_t *cte_recv_params) +{ + btc_msg_t msg; + btc_ble_cte_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if ((cte_recv_params == NULL) || (cte_recv_params->antenna_ids == NULL)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS; + + arg.cte_recv_params.conn_handle = cte_recv_params->conn_handle; + arg.cte_recv_params.sampling_en = cte_recv_params->sampling_en; + arg.cte_recv_params.slot_dur = cte_recv_params->slot_dur; + arg.cte_recv_params.switching_pattern_len = cte_recv_params->switching_pattern_len; + arg.cte_recv_params.antenna_ids = cte_recv_params->antenna_ids; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cte_set_connection_transmit_params(esp_ble_cte_conn_trans_params_t *cte_conn_trans_params) +{ + btc_msg_t msg; + btc_ble_cte_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if ((cte_conn_trans_params == NULL) || (cte_conn_trans_params->antenna_ids == NULL)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS; + + arg.cte_conn_trans_params.conn_handle = cte_conn_trans_params->conn_handle; + arg.cte_conn_trans_params.cte_types = cte_conn_trans_params->cte_types; + arg.cte_conn_trans_params.switching_pattern_len = cte_conn_trans_params->switching_pattern_len; + arg.cte_conn_trans_params.antenna_ids = cte_conn_trans_params->antenna_ids; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), btc_ble_cte_arg_deep_copy, btc_ble_cte_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cte_connection_cte_request_enable(esp_ble_cte_req_en_params_t *cte_conn_req_en) +{ + btc_msg_t msg; + btc_ble_cte_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (cte_conn_req_en == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_SET_CONN_CTE_REQUEST_EN; + + arg.cte_req_en.conn_handle = cte_conn_req_en->conn_handle; + arg.cte_req_en.enable = cte_conn_req_en->enable; + arg.cte_req_en.cte_req_interval = cte_conn_req_en->cte_req_interval; + arg.cte_req_en.req_cte_len = cte_conn_req_en->req_cte_len; + arg.cte_req_en.req_cte_Type = cte_conn_req_en->req_cte_Type; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cte_connection_cte_response_enable(esp_ble_cte_rsp_en_params_t *cte_conn_rsp_en) +{ + btc_msg_t msg; + btc_ble_cte_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (cte_conn_rsp_en == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_SET_CONN_CTE_RESPONSE_EN; + + arg.cte_rsp_en.conn_handle = cte_conn_rsp_en->conn_handle; + arg.cte_rsp_en.enable = cte_conn_rsp_en->enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_cte_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +esp_err_t esp_ble_cte_read_antenna_information(void) +{ + btc_msg_t msg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_BLE_CTE; + msg.act = BTC_CTE_ACT_READ_ANTENNA_INFOR; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h b/components/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h new file mode 100644 index 0000000000..80dc5b15d2 --- /dev/null +++ b/components/bt/host/bluedroid/api/include/api/esp_ble_cte_api.h @@ -0,0 +1,379 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BLE_CTE_API_H__ +#define __ESP_BLE_CTE_API_H__ + +#include +#include + +#include "esp_err.h" +#include "esp_bt_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// BLE CTE callback event type +typedef enum { + ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT = 0, /*!< When CTE set connectionless transmit parameters complete, the event comes */ + ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT, /*!< When CTE set connectionless transmit enable complete, the event comes */ + ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT, /*!< When CTE set connectionless IQ sampling enable complete, the event comes */ + ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT, /*!< When CTE set connection receive parameters complete, the event comes */ + ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT, /*!< When CTE set connection transmit parameters complete, the event comes */ + ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT, /*!< When CTE set connection CTE request enable complete, the event comes */ + ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT, /*!< When CTE set connection CTE response enable complete, the event comes */ + ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT, /*!< When CTE read antenna information complete, the event comes */ + ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT, /*!< When the device receives CTE connectionless IQ information, the event comes */ + ESP_BLE_CTE_CONN_IQ_REPORT_EVT, /*!< When the device receives CTE connection IQ information , the event comes */ + ESP_BLE_CTE_REQUEST_FAILED_EVT, /*!< When CTE request progress failed , the event comes */ + ESP_BLE_CTE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ +} esp_ble_cte_cb_event_t; + +#define ESP_BLE_CTE_SAMPLING_DISABLE (0x00) +#define ESP_BLE_CTE_SAMPLING_ENABLE (0x01) + +#define ESP_BLE_CTE_ADV_WITH_CTE_DISABLE (0x00) +#define ESP_BLE_CTE_ADV_WITH_CTE_ENABLE (0x01) + +// Constant Tone Extension length in 8 µs units +#define ESP_BLE_CTE_MIN_CTE_LENGTH (0x02) +#define ESP_BLE_CTE_MAX_CTE_LENGTH (0x14) + +#define ESP_BLE_CTE_TYPE_AOA (0x00) /*!< AoA Constant Tone Extension */ +#define ESP_BLE_CTE_TYPE_AOD_WITH_1US (0x01) /*!< AoD Constant Tone Extension with 1 µs slots */ +#define ESP_BLE_CTE_TYPE_AOD_WITH_2US (0x02) /*!< AoD Constant Tone Extension with 2 µs slots */ +typedef uint8_t esp_ble_cte_type_t; + +#define ESP_BLE_CTE_MIN_CTE_COUNT (0x01) +#define ESP_BLE_CTE_MAX_CTE_COUNT (0x10) + +#define ESP_BLE_CTE_MIN_SWITCHING_PATTERN_LENGTH (0x02) +#define ESP_BLE_CTE_MAX_SWITCHING_PATTERN_LENGTH (0x4B) + +#define ESP_BLE_CTE_SLOT_DURATION_1US (0x01) +#define ESP_BLE_CTE_SLOT_DURATION_2US (0x02) +typedef uint8_t esp_ble_cte_slot_dur_type_t; + +#define ESP_BLE_CTE_MIN_SAMPLED_CTES (0x00) +#define ESP_BLE_CTE_MAX_SAMPLED_CTES (0x10) + +#define ESP_BLE_CTE_TYPES_AOA_RESPONSE (0x01) +#define ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_1US (0x02) +#define ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_2US (0x04) +#define ESP_BLE_CTE_TYPES_ALL (ESP_BLE_CTE_TYPES_AOA_RESPONSE | ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_1US | ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_2US) +typedef uint8_t esp_ble_cte_conn_cte_types_t; + +#define ESP_BLE_CTE_REQUEST_FOR_CONNECTION_DISABLE (0x00) +#define ESP_BLE_CTE_REQUEST_FOR_CONNECTION_ENABLE (0x01) + +#define ESP_BLE_CTE_MIN_REQUESTED_CTE_LENGTH (0x02) +#define ESP_BLE_CTE_MAX_REQUESTED_CTE_LENGTH (0x14) + +#define ESP_BLE_CTE_RESPONSE_FOR_CONNECTION_DISABLE (0x00) +#define ESP_BLE_CTE_RESPONSE_FOR_CONNECTION_ENABLE (0x01) + +typedef struct { + uint8_t adv_handle; /*!< Used to identify an advertising set */ + uint8_t cte_len; /*!< Constant Tone Extension length in 8 µs units, range: 0x02 to 0x14 */ + esp_ble_cte_type_t cte_type; /*!< AoA or AoD Constant Tone Extension */ + uint8_t cte_count; /*!< The number of Constant Tone Extensions to transmit in each periodic advertising interval, range: 0x01 to 0x10 */ + uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */ + uint8_t *antenna_ids; /*!< Antenna ID in the pattern */ +} __attribute__((packed)) esp_ble_cte_connless_trans_params_t; + +typedef struct { + uint8_t adv_handle; /*!< Identifier for the advertising set in which Constant Tone Extension is being enabled or disabled */ + uint8_t cte_enable; /*!< Advertising with Constant Tone Extension is enabled or disabled */ +} __attribute__((packed)) esp_ble_cte_trans_enable_params_t; + +typedef struct { + uint16_t sync_handle; /*!< Identifier for the periodic advertising train */ + uint8_t sampling_en; /*!< Enable or disable connectionless IQ sampling */ + esp_ble_cte_slot_dur_type_t slot_dur; /*!< Switching and sampling slots, 1 us or 2 us */ + uint8_t max_sampled_ctes; /*!< The maximum number of CTE to sample and report in each periodic advertising interval, range: 0x00 - 0x10 */ + uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */ + uint8_t *antenna_ids; /*!< Antenna ID in the pattern */ +} __attribute__((packed)) esp_ble_cte_iq_sampling_params_t; + +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t sampling_en; /*!< Enable or disable connection IQ sampling */ + esp_ble_cte_slot_dur_type_t slot_dur; /*!< Switching and sampling slots, 1 us or 2 us */ + uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */ + uint8_t *antenna_ids; /*!< Antenna ID in the pattern */ +} __attribute__((packed)) esp_ble_cte_recv_params_params_t; + +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + esp_ble_cte_conn_cte_types_t cte_types; /*!< Allow AoA or AoD Constant Tone Extension Response */ + uint8_t switching_pattern_len; /*!< The number of Antenna IDs in the pattern, range: 0x02 to 0x4B */ + uint8_t *antenna_ids; /*!< Antenna ID in the pattern */ +} __attribute__((packed)) esp_ble_cte_conn_trans_params_t; + +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t enable; /*!< Enable or disable Constant Tone Extension Request for the connection */ + uint16_t cte_req_interval; /*!< Requested interval for initiating the CTE Request procedure in number of underlying connection events, range: 0x0000 - 0xFFFF */ + uint8_t req_cte_len; /*!< Minimum length of the Constant Tone Extension being requested in 8 µs units, range: 0x02 - 0x14 */ + esp_ble_cte_type_t req_cte_Type; /*!< AoA or AoD Constant Tone Extension, range: 0x00 - 0x02 */ +} __attribute__((packed)) esp_ble_cte_req_en_params_t; + +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t enable; /*!< Enable or disable Constant Tone Extension Response for the connection */ +} __attribute__((packed)) esp_ble_cte_rsp_en_params_t; + +/** + * @brief CTE callback parameters union + */ +typedef union { + /** + * @brief ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT + */ + struct ble_set_trans_params_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate setting transmit parameters status, status = (controller error code | 0x100) if status is not equal to 0 */ + } set_trans_params_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT + */ + struct ble_set_trans_enable_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate setting transmit enable status, status = (controller error code | 0x100) if status is not equal to 0 */ + } set_trans_enable_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT + */ + struct ble_set_iq_sampling_en_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate setting IQ sampling enable status, status = (controller error code | 0x100) if status is not equal to 0 */ + uint16_t sync_handle; /*!< Sync_Handle identifying the periodic advertising */ + } iq_sampling_enable_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT + */ + struct ble_set_conn_recv_params_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate setting received parameters status, status = (controller error code | 0x100) if status is not equal to 0 */ + uint16_t conn_handle; /*!< The connection identifier */ + } conn_recv_params_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT + */ + struct ble_set_conn_trans_params_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate setting connection transmit parameters status, status = (controller error code | 0x100) if status is not equal to 0 */ + uint16_t conn_handle; /*!< The connection identifier */ + } conn_trans_params_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT + */ + struct ble_set_conn_req_en_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate setting connection request enable status, status = (controller error code | 0x100) if status is not equal to 0 */ + uint16_t conn_handle; /*!< The connection identifier */ + } conn_req_en_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT + */ + struct ble_set_conn_rsp_en_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate setting connection response enable status, status = (controller error code | 0x100) if status is not equal to 0 */ + uint16_t conn_handle; /*!< The connection identifier */ + } conn_rsp_en_cmpl; /*!< Event parameter of ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT + */ + struct ble_read_ant_infor_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate reading antenna information status, status = (controller error code | 0x100) if status is not equal to 0 */ + uint8_t supported_switching_sampling_rates; /*!< bit 0: 1 µs switching supported for AoD transmission + bit 1: 1 µs sampling supported for AoD reception + bit 2: 1 µs switching and sampling supported for AoA reception */ + uint8_t num_antennae; /*!< The number of antennae supported by the Controller */ + uint8_t max_switching_pattern_len; /*!< Maximum length of antenna switching pattern supported by the Controller */ + uint8_t max_cte_len; /*!< Maximum length of a transmitted Constant Tone Extension supported in 8 µs units */ + } read_ant_infor_cmpl; /*!< Event parameter of ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT */ + + /** + * @brief ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT + */ + struct ble_cte_connless_iq_rpt_evt_param { + uint16_t sync_handle; /*!< Sync_Handle identifying the periodic advertising train */ + uint8_t channel_idx; /*!< The index of the channel on which the packet was received */ + int16_t rssi; /*!< RSSI of the packet, Range: -1270 to +200, Units: 0.1 dBm */ + uint8_t rssi_ant_id; /*!< Antenna ID */ + uint8_t cte_type; /*!< The type of Constant Tone Extension, range: 0x00 - 0x02 */ + uint8_t slot_dur; /*!< Switching and sampling slots, 1 us or 2us, range: 0x01 - 0x02 */ + uint8_t pkt_status; /*!< indicates whether the received packet had a valid CRC, range: 0x00 - 0x02 and 0xFF */ + uint16_t periodic_evt_counter; /*!< The value of paEventCounter for the reported AUX_SYNC_IND PDU */ + uint8_t sample_count; /*!< Total number of sample pairs, range: 0x00 and 0x09 - 0x52*/ + uint8_t *i_sample; /*!< I sample for the reported packet. No valid sample available if value is 0x80 */ + uint8_t *q_sample; /*!< Q sample for the reported packet. No valid sample available if value is 0x80 */ + } connless_iq_rpt; /*!< Event parameter of ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT */ + + /** + * @brief ESP_BLE_CTE_CONN_IQ_REPORT_EVT + */ + struct ble_cte_conn_iq_rpt_evt_param { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t rx_phy; /*!< The receiver PHY for the connection, range: 0x01 - 0x02 */ + uint8_t data_channel_idx; /*!< The index of the data channel on which the Data Physical Channel PDU was received, range: 0x00 - 0x24 */ + int16_t rssi; /*!< RSSI of the packet, range: -1270 - +200, units: 0.1 dBm */ + uint8_t rssi_ant_id; /*!< ID of the antenna on which the RSSI is measured */ + uint8_t cte_type; /*!< AoA or AoD Constant Tone Extension, range: 0x00 - 0x02 */ + uint8_t slot_dur; /*!< Switching and sampling slots, range: 0x01 - 0x02 */ + uint8_t pkt_status; /*!< indicates whether the received packet had a valid CRC, range: 0x00 - 0x02 and 0xFF */ + uint16_t conn_evt_counter; /*!< The value of connEventCounter for the reported PDU */ + uint8_t sample_count; /*!< Total number of sample pairs, range: 0x00 and 0x09 - 0x52 */ + uint8_t *i_sample; /*!< I sample for the reported PDU. No valid sample available if value is 0x80 */ + uint8_t *q_sample; /*!< Q sample for the reported PDU,. No valid sample available if value is 0x80 */ + } conn_iq_rpt; /*!< Event parameter of ESP_BLE_CTE_CONN_IQ_REPORT_EVT */ + + /** + * @brief ESP_BLE_CTE_REQUEST_FAILED_EVT + */ + struct ble_cte_req_failed_evt_param{ + uint8_t reason; /*!< value: 0x00, LL_CTE_RSP PDU received successfully but without a Constant Tone Extension field; + value: 0x01 to 0xFF, Peer rejected the request, see [Vol 1] Part F controller error codes and descriptions */ + uint16_t conn_handle; /*!< Connection_Handle */ + } req_failed_evt; /*!< Event parameter of ESP_BLE_CTE_REQUEST_FAILED_EVT */ + +} esp_ble_cte_cb_param_t; + +/** + * @brief CTE callback function type + * @param event : Event type + * @param param : Point to callback parameter, currently is union type + */ +typedef void (* esp_ble_cte_cb_t)(esp_ble_cte_cb_event_t event, esp_ble_cte_cb_param_t *param); + +/** + * @brief This function is called to occur cte event + * + * @param[in] callback: callback function + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_register_callback(esp_ble_cte_cb_t callback); + +/** + * @brief This function is called to get the current cte callback + * + * @return + * - esp_ble_cte_cb_t : callback function + * + */ +esp_ble_cte_cb_t esp_ble_cte_get_callback(void); + +/** + * @brief This function is called to set parameters for the transmission of CTE in the periodic advertising. + * + * @param[in] cte_trans_params: pointer to User defined cte_trans_params data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_set_connectionless_trans_params(esp_ble_cte_connless_trans_params_t *cte_trans_params); + +/** + * @brief This function is called to request that the Controller enables or disables the use of CTE in the periodic advertising. + * + * @param[in] cte_trans_enable: pointer to User defined cte_trans_enable data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_set_connectionless_trans_enable(esp_ble_cte_trans_enable_params_t *cte_trans_enable); + +/** + * @brief This function is called to request that the Controller enables or disables capturing IQ samples from the CTE +* of periodic advertising packets. + * + * @param[in] iq_sampling_en: pointer to User defined iq_sampling_en data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_set_connectionless_iq_sampling_enable(esp_ble_cte_iq_sampling_params_t *iq_sampling_en); + +/** + * @brief This function is called to enable or disable sampling received CTE fields on the connection. + * + * @param[in] cte_recv_params: pointer to User defined cte_recv_params data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_set_connection_receive_params(esp_ble_cte_recv_params_params_t *cte_recv_params); + +/** + * @brief This function is called to set the parameters used for transmitting CTE requested by the peer + * device on the connection. + * + * @param[in] cte_conn_trans_params: pointer to User defined cte_conn_trans_params data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_set_connection_transmit_params(esp_ble_cte_conn_trans_params_t *cte_conn_trans_params); + +/** + * @brief This function is called to request the Controller to start or stop initiating the CTE Request + * procedure on a connection. + * + * @param[in] cte_conn_req_en: pointer to User defined cte_conn_req_en data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_connection_cte_request_enable(esp_ble_cte_req_en_params_t *cte_conn_req_en); + +/** + * @brief This function is called to request the Controller to respond to LL_CTE_REQ PDUs with + * LL_CTE_RSP PDUs on the specified connection. + * + * @param[in] cte_conn_rsp_en: pointer to User defined cte_conn_rsp_en data structure. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_connection_cte_response_enable(esp_ble_cte_rsp_en_params_t *cte_conn_rsp_en); + +/** + * @brief This function is called to read the parameters of a transmitted CTE supported by the Controller. + * + * @param[in] none. + + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_cte_read_antenna_information(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_BLE_CTE_API_H__ */ diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 2af8bf187c..6d0a2187fc 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6225,6 +6225,57 @@ void bta_dm_ble_discon_cis(tBTA_DM_MSG *p_data) #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +void bta_dm_ble_set_cte_trans_params(tBTA_DM_MSG *p_data) +{ + BTM_BleSetCteTransParams(p_data->set_cte_trans_params.adv_handle, p_data->set_cte_trans_params.cte_len, p_data->set_cte_trans_params.cte_type, + p_data->set_cte_trans_params.cte_count, p_data->set_cte_trans_params.switching_pattern_len, p_data->set_cte_trans_params.antenna_ids); +} + +void bta_dm_ble_set_cte_trans_enable(tBTA_DM_MSG *p_data) +{ + BTM_BleCteSetConnectionlessTransEnable(p_data->set_trans_en.adv_handle, p_data->set_trans_en.cte_enable); +} + +void bta_dm_ble_set_iq_sampling_en(tBTA_DM_MSG *p_data) +{ + BTM_BleCteSetConnectionlessIqSamplingEnable(p_data->iq_samp_en.sync_handle, p_data->iq_samp_en.sampling_en, p_data->iq_samp_en.slot_dur, + p_data->iq_samp_en.max_sampled_ctes, p_data->iq_samp_en.switching_pattern_len, p_data->iq_samp_en.antenna_ids); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void bta_dm_ble_set_conn_cte_recv_params(tBTA_DM_MSG *p_data) +{ + BTM_BleCteSetConnectionReceiveParams(p_data->recv_params.conn_handle, p_data->recv_params.sampling_en, p_data->recv_params.slot_dur, + p_data->recv_params.switching_pattern_len, p_data->recv_params.antenna_ids); +} + +void bta_dm_ble_set_conn_trans_params(tBTA_DM_MSG *p_data) +{ + BTM_BleCteSetConnectionTransParams(p_data->conn_trans_params.conn_handle, p_data->conn_trans_params.cte_types, + p_data->conn_trans_params.switching_pattern_len, p_data->conn_trans_params.antenna_ids); +} + +void bta_dm_ble_set_conn_cte_req_en(tBTA_DM_MSG *p_data) +{ + BTM_BleCteSetConnectionRequestEnable(p_data->conn_req_en.conn_handle, p_data->conn_req_en.enable, p_data->conn_req_en.cte_req_interval, + p_data->conn_req_en.req_cte_len, p_data->conn_req_en.req_cte_Type); +} + +void bta_dm_ble_set_conn_cte_rsp_en(tBTA_DM_MSG *p_data) +{ + BTM_BleCteSetConnectionRspEnable(p_data->conn_rsp_en.conn_handle, p_data->conn_rsp_en.enable); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +void bta_dm_ble_read_cte_ant_infor(tBTA_DM_MSG *p_data) +{ + BTM_BleCteReadAntInfor(); +} +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index a55ec9ea4a..f3c0b6361b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3926,4 +3926,184 @@ void BTA_DmBleIsoDisconCis(uint16_t cis_handle, uint8_t reason) #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +void BTA_DmBleCteSetConnectionlessTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, + uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_CTE_SET_TRANS_PARAMS *p_buf; + if ((p_buf = (tBTA_DM_BLE_CTE_SET_TRANS_PARAMS *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_SET_TRANS_PARAMS) + switching_pattern_len)) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_SET_TRANS_PARAMS) + switching_pattern_len); + p_buf->hdr.event = BTA_DM_API_CTE_SET_TRANS_PARAMS; + + p_buf->adv_handle = adv_handle; + p_buf->cte_len = cte_len; + p_buf->cte_type = cte_type; + p_buf->cte_count = cte_count; + p_buf->switching_pattern_len = switching_pattern_len; + p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL; + if (switching_pattern_len) { + memcpy(p_buf->antenna_ids, antenna_ids, switching_pattern_len); + } + //start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_CTE_SET_TRANS_ENABLE *p_buf; + if ((p_buf = (tBTA_DM_BLE_CTE_SET_TRANS_ENABLE *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_SET_TRANS_ENABLE))) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_SET_TRANS_ENABLE)); + p_buf->hdr.event = BTA_DM_API_CTE_SET_TRANS_ENABLE; + + p_buf->adv_handle = adv_handle; + p_buf->cte_enable = cte_en; + // start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_CTE_IQ_SAMP_EN *p_buf; + if ((p_buf = (tBTA_DM_BLE_CTE_IQ_SAMP_EN *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_IQ_SAMP_EN) + switching_pattern_len)) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_IQ_SAMP_EN) + switching_pattern_len); + p_buf->hdr.event = BTA_DM_API_CTE_SET_IQ_SAMPLING_EN; + + p_buf->sync_handle = sync_handle; + p_buf->sampling_en = sampling_en; + p_buf->slot_dur = slot_dur; + p_buf->max_sampled_ctes = max_sampled_ctes; + p_buf->switching_pattern_len = switching_pattern_len; + p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL; + if (switching_pattern_len) { + memcpy(p_buf->antenna_ids, ant_ids, switching_pattern_len); + } + // start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void BTA_DmBleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_CTE_RECV_PARAMS *p_buf; + if ((p_buf = (tBTA_DM_BLE_CTE_RECV_PARAMS *) osi_malloc(sizeof(tBTA_DM_BLE_CTE_RECV_PARAMS) + switching_pattern_len)) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_CTE_RECV_PARAMS) + switching_pattern_len); + p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_RECV_PARAMS; + + p_buf->conn_handle = conn_handle; + p_buf->sampling_en = sampling_en; + p_buf->slot_dur = slot_dur; + p_buf->switching_pattern_len = switching_pattern_len; + p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL; + if (switching_pattern_len) { + memcpy(p_buf->antenna_ids, ant_ids, switching_pattern_len); + } + // start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS *p_buf; + if ((p_buf = (tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS *) osi_malloc(sizeof(tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS) + switching_pattern_len)) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS) + switching_pattern_len); + p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_TRANS_PARAMS; + + p_buf->conn_handle = conn_handle; + p_buf->cte_types = cte_types; + p_buf->switching_pattern_len = switching_pattern_len; + p_buf->antenna_ids = (switching_pattern_len != 0) ? (UINT8 *)(p_buf + 1) : NULL; + if (switching_pattern_len) { + memcpy(p_buf->antenna_ids, ant_ids, switching_pattern_len); + } + // start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_interval, + uint8_t req_cte_len, uint8_t req_cte_Type) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_CONN_CTE_REQ_EN *p_buf; + if ((p_buf = (tBTA_DM_BLE_CONN_CTE_REQ_EN *) osi_malloc(sizeof(tBTA_DM_BLE_CONN_CTE_REQ_EN))) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_CONN_CTE_REQ_EN)); + p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_REQUEST_EN; + + p_buf->conn_handle = conn_handle; + p_buf->enable = enable; + p_buf->cte_req_interval = cte_req_interval; + p_buf->req_cte_len = req_cte_len; + p_buf->req_cte_Type = req_cte_Type; + // start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_CONN_CTE_RSP_EN *p_buf; + if ((p_buf = (tBTA_DM_BLE_CONN_CTE_RSP_EN *) osi_malloc(sizeof(tBTA_DM_BLE_CONN_CTE_RSP_EN))) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_CONN_CTE_RSP_EN)); + p_buf->hdr.event = BTA_DM_API_CTE_SET_CONN_CTE_RESPONSE_EN; + + p_buf->conn_handle = conn_handle; + p_buf->enable = enable; + // start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void BTA_DmBleCteReadAntInfor(void) +{ + APPL_TRACE_API("%s", __func__); + + tBTA_DM_BLE_READ_ANT_INFOR *p_buf; + if ((p_buf = (tBTA_DM_BLE_READ_ANT_INFOR *) osi_malloc(sizeof(tBTA_DM_BLE_READ_ANT_INFOR))) != NULL) { + memset(p_buf, 0, sizeof(tBTA_DM_BLE_READ_ANT_INFOR)); + p_buf->hdr.event = BTA_DM_API_CTE_READ_ANTENNA_INFOR; + // start sent the msg to the bta system control module + bta_sys_sendmsg(p_buf); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 809005ca6a..db573d7b3a 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -316,6 +316,20 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_discon_cis, /* BTA_DM_API_DISCON_CIS_EVT */ #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + bta_dm_ble_set_cte_trans_params, /* BTA_DM_API_CTE_SET_TRANS_PARAMS */ + bta_dm_ble_set_cte_trans_enable, /* BTA_DM_API_CTE_SET_TRANS_ENABLE */ + bta_dm_ble_set_iq_sampling_en, /* BTA_DM_API_CTE_SET_IQ_SAMPLING_EN */ +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + bta_dm_ble_set_conn_cte_recv_params, /* BTA_DM_API_CTE_SET_CONN_CTE_RECV_PARAMS */ + bta_dm_ble_set_conn_trans_params, /* BTA_DM_API_CTE_SET_CONN_CTE_TRANS_PARAMS */ + bta_dm_ble_set_conn_cte_req_en, /* BTA_DM_API_CTE_SET_CONN_CTE_REQUEST_EN */ + bta_dm_ble_set_conn_cte_rsp_en, /* BTA_DM_API_CTE_SET_CONN_CTE_RESPONSE_EN */ +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + bta_dm_ble_read_cte_ant_infor, /* BTA_DM_API_CTE_READ_ANTENNA_INFOR */ +#endif // #if (BLE_FEAT_CTE_EN == TRUE) }; diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 540f5fb42a..6fde7526de 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -307,6 +307,20 @@ enum { BTA_DM_API_DISCON_CIS_EVT, #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + BTA_DM_API_CTE_SET_TRANS_PARAMS, + BTA_DM_API_CTE_SET_TRANS_ENABLE, + BTA_DM_API_CTE_SET_IQ_SAMPLING_EN, +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + BTA_DM_API_CTE_SET_CONN_CTE_RECV_PARAMS, + BTA_DM_API_CTE_SET_CONN_CTE_TRANS_PARAMS, + BTA_DM_API_CTE_SET_CONN_CTE_REQUEST_EN, + BTA_DM_API_CTE_SET_CONN_CTE_RESPONSE_EN, +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + BTA_DM_API_CTE_READ_ANTENNA_INFOR, +#endif // #if (BLE_FEAT_CTE_EN == TRUE) BTA_DM_MAX_EVT }; @@ -1449,6 +1463,75 @@ typedef struct { #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +typedef struct { + BT_HDR hdr; + UINT8 adv_handle; + UINT8 cte_len; + UINT8 cte_type; + UINT8 cte_count; + UINT8 switching_pattern_len; + UINT8 *antenna_ids; +} tBTA_DM_BLE_CTE_SET_TRANS_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT8 adv_handle; + UINT8 cte_enable; +} tBTA_DM_BLE_CTE_SET_TRANS_ENABLE; + +typedef struct { + BT_HDR hdr; + UINT16 sync_handle; + UINT8 sampling_en; + UINT8 slot_dur; + UINT8 max_sampled_ctes; + UINT8 switching_pattern_len; + UINT8 *antenna_ids; +} tBTA_DM_BLE_CTE_IQ_SAMP_EN; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 sampling_en; + UINT8 slot_dur; + UINT8 switching_pattern_len; + UINT8 *antenna_ids; +} tBTA_DM_BLE_CTE_RECV_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 cte_types; + UINT8 switching_pattern_len; + UINT8 *antenna_ids; +} tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 enable; + UINT16 cte_req_interval; + UINT8 req_cte_len; + UINT8 req_cte_Type; +} tBTA_DM_BLE_CONN_CTE_REQ_EN; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 enable; +} tBTA_DM_BLE_CONN_CTE_RSP_EN; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +typedef struct { + BT_HDR hdr; +} tBTA_DM_BLE_READ_ANT_INFOR; +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + /* union of all data types */ typedef union { /* event buffer header */ @@ -1683,6 +1766,21 @@ typedef union { tBTA_DM_API_DISCON_CIS_PARAM discon_cis; #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + tBTA_DM_BLE_CTE_SET_TRANS_PARAMS set_cte_trans_params; + tBTA_DM_BLE_CTE_SET_TRANS_ENABLE set_trans_en; + tBTA_DM_BLE_CTE_IQ_SAMP_EN iq_samp_en; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTA_DM_BLE_CTE_RECV_PARAMS recv_params; + tBTA_DM_BLE_CONN_CTE_TRANS_PARAMS conn_trans_params; + tBTA_DM_BLE_CONN_CTE_REQ_EN conn_req_en; + tBTA_DM_BLE_CONN_CTE_RSP_EN conn_rsp_en; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTA_DM_BLE_READ_ANT_INFOR read_ant_infor; +#endif // #if (BLE_FEAT_CTE_EN == TRUE) } tBTA_DM_MSG; @@ -2318,4 +2416,22 @@ void bta_dm_ble_reject_cis_req(tBTA_DM_MSG *p_data); void bta_dm_ble_discon_cis(tBTA_DM_MSG *p_data); #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +void bta_dm_ble_set_cte_trans_params(tBTA_DM_MSG *p_data); +void bta_dm_ble_set_cte_trans_enable(tBTA_DM_MSG *p_data); +void bta_dm_ble_set_iq_sampling_en(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void bta_dm_ble_set_conn_cte_recv_params(tBTA_DM_MSG *p_data); +void bta_dm_ble_set_conn_trans_params(tBTA_DM_MSG *p_data); +void bta_dm_ble_set_conn_cte_req_en(tBTA_DM_MSG *p_data); +void bta_dm_ble_set_conn_cte_rsp_en(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +void bta_dm_ble_read_cte_ant_infor(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + #endif /* BTA_DM_INT_H */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 416e430f13..d71a016db5 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1724,6 +1724,27 @@ extern tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; #define BTA_DM_BLE_ISO_UNKNOWN_EVT BTM_BLE_ISO_UNKNOWN_EVT #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define BTA_BLE_CTE_SET_TRANS_PARAMS_EVT BTM_BLE_CTE_SET_TRANS_PARAMS_EVT +#define BTA_BLE_CTE_SET_TRANS_ENABLE_EVT BTM_BLE_CTE_SET_TRANS_ENABLE_EVT +#define BTA_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BTA_BLE_CTE_SET_CONN_RECV_PARAMS_EVT BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT +#define BTA_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT +#define BTA_BLE_CTE_SET_CONN_REQ_ENABLE_EVT BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT +#define BTA_BLE_CTE_SET_CONN_RSP_ENABLE_EVT BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BTA_BLE_CTE_READ_ANT_INFOR_EVT BTM_BLE_CTE_READ_ANT_INFOR_EVT +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define BTA_BLE_CTE_CONNLESS_IQ_REPORT_EVT BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BTA_BLE_CTE_CONN_IQ_REPORT_EVT BTM_BLE_CTE_CONN_IQ_REPORT_EVT +#define BTA_BLE_CTE_REQUEST_FAILED_EVT BTM_BLE_CTE_REQUEST_FAILED_EVT +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) typedef struct { @@ -3337,6 +3358,28 @@ extern void BTA_DmBleIsoRejectCisReq(uint16_t cis_handle, uint8_t reason); extern void BTA_DmBleIsoDisconCis(uint16_t cis_handle, uint8_t reason); #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #endif // if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +void BTA_DmBleCteSetConnectionlessTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, + uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids); +void BTA_DmBleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en); +void BTA_DmBleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void BTA_DmBleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *ant_ids); + +void BTA_DmBleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids); +void BTA_DmBleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_interval, + uint8_t req_cte_len, uint8_t req_cte_Type); +void BTA_DmBleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void BTA_DmBleCteReadAntInfor(void); +#endif // if (BLE_FEAT_CTE_EN == TRUE) + #endif enum { diff --git a/components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c b/components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c new file mode 100644 index 0000000000..a4f4377cb6 --- /dev/null +++ b/components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c @@ -0,0 +1,395 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "osi/allocator.h" + +#include "bta/bta_api.h" +#include "bta/bta_dm_co.h" +#include "btc/btc_task.h" +#include "btc/btc_util.h" +#if (BLE_FEAT_CTE_EN == TRUE) +#include "btc_ble_cte.h" + +static inline void btc_cte_ble_cb_to_app(esp_ble_cte_cb_event_t event, esp_ble_cte_cb_param_t *param) +{ + esp_ble_cte_cb_t btc_cte_ble_cb = (esp_ble_cte_cb_t)btc_profile_cb_get(BTC_PID_BLE_CTE); + if (btc_cte_ble_cb) { + btc_cte_ble_cb(event, param); + } +} + +static void btc_ble_cte_callback(tBTM_BLE_CTE_EVENT event, + tBTM_BLE_CTE_CB_PARAMS *params) +{ + esp_ble_cte_cb_param_t param; + bt_status_t ret; + btc_msg_t msg; + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_BLE_CTE; + + BTC_TRACE_DEBUG("%s event %d\n", __func__, event); + + switch(event) { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case BTA_BLE_CTE_SET_TRANS_PARAMS_EVT: + msg.act = ESP_BLE_CTE_SET_CONNLESS_TRANS_PARAMS_CMPL_EVT; + param.set_trans_params_cmpl.status = btc_btm_status_to_esp_status(params->cte_trans_params_cmpl.status); + break; + case BTA_BLE_CTE_SET_TRANS_ENABLE_EVT: + msg.act = ESP_BLE_CTE_SET_CONNLESS_TRANS_ENABLE_CMPL_EVT; + param.set_trans_enable_cmpl.status = btc_btm_status_to_esp_status(params->cte_trans_params_cmpl.status); + break; + case BTA_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT: + msg.act = ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT; + param.iq_sampling_enable_cmpl.status = btc_btm_status_to_esp_status(params->cte_iq_samp_en_cmpl.status); + param.iq_sampling_enable_cmpl.sync_handle = params->cte_iq_samp_en_cmpl.sync_handle; + break; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case BTA_BLE_CTE_SET_CONN_RECV_PARAMS_EVT: + msg.act = ESP_BLE_CTE_SET_CONN_RECV_PARAMS_CMPL_EVT; + param.conn_recv_params_cmpl.status = btc_btm_status_to_esp_status(params->cte_recv_params_cmpl.status); + param.conn_recv_params_cmpl.conn_handle = params->cte_recv_params_cmpl.conn_handle; + break; + case BTA_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT: + msg.act = ESP_BLE_CTE_SET_CONN_TRANS_PARAMS_CMPL_EVT; + param.conn_trans_params_cmpl.status = btc_btm_status_to_esp_status(params->cte_conn_trans_params_cmpl.status); + param.conn_trans_params_cmpl.conn_handle = params->cte_conn_trans_params_cmpl.conn_handle; + break; + case BTA_BLE_CTE_SET_CONN_REQ_ENABLE_EVT: + msg.act = ESP_BLE_CTE_SET_CONN_REQ_ENABLE_CMPL_EVT; + param.conn_req_en_cmpl.status = btc_btm_status_to_esp_status(params->cte_conn_req_en_cmpl.status); + param.conn_req_en_cmpl.conn_handle = params->cte_conn_req_en_cmpl.conn_handle; + break; + case BTA_BLE_CTE_SET_CONN_RSP_ENABLE_EVT: + msg.act = ESP_BLE_CTE_SET_CONN_RSP_ENABLE_CMPL_EVT; + param.conn_rsp_en_cmpl.status = btc_btm_status_to_esp_status(params->cte_conn_rsp_en_cmpl.status); + param.conn_rsp_en_cmpl.conn_handle = params->cte_conn_rsp_en_cmpl.conn_handle; + break; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case BTA_BLE_CTE_READ_ANT_INFOR_EVT: + msg.act = ESP_BLE_CTE_READ_ANT_INFOR_CMPL_EVT; + param.read_ant_infor_cmpl.status = btc_btm_status_to_esp_status(params->cte_read_ant_infor_cmpl.status); + param.read_ant_infor_cmpl.supported_switching_sampling_rates = params->cte_read_ant_infor_cmpl.supported_switching_sampling_rates; + param.read_ant_infor_cmpl.num_antennae = params->cte_read_ant_infor_cmpl.num_ant; + param.read_ant_infor_cmpl.max_switching_pattern_len = params->cte_read_ant_infor_cmpl.max_switching_pattern_len; + param.read_ant_infor_cmpl.max_cte_len = params->cte_read_ant_infor_cmpl.max_cte_len; + break; +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case BTA_BLE_CTE_CONNLESS_IQ_REPORT_EVT: + msg.act = ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT; + param.connless_iq_rpt.sync_handle = params->cte_connless_iq_rpt.sync_handle; + param.connless_iq_rpt.channel_idx = params->cte_connless_iq_rpt.channel_idx; + param.connless_iq_rpt.rssi = params->cte_connless_iq_rpt.rssi; + param.connless_iq_rpt.rssi_ant_id = params->cte_connless_iq_rpt.rssi_ant_id; + param.connless_iq_rpt.cte_type = params->cte_connless_iq_rpt.cte_type; + param.connless_iq_rpt.slot_dur = params->cte_connless_iq_rpt.slot_dur; + param.connless_iq_rpt.pkt_status = params->cte_connless_iq_rpt.pkt_status; + param.connless_iq_rpt.periodic_evt_counter = params->cte_connless_iq_rpt.periodic_evt_counter; + param.connless_iq_rpt.sample_count = params->cte_connless_iq_rpt.sample_count; + param.connless_iq_rpt.i_sample = &(params->cte_connless_iq_rpt.i_sample[0]); + param.connless_iq_rpt.q_sample = &(params->cte_connless_iq_rpt.q_sample[0]); + break; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case BTA_BLE_CTE_CONN_IQ_REPORT_EVT: + msg.act = ESP_BLE_CTE_CONN_IQ_REPORT_EVT; + param.conn_iq_rpt.conn_handle = params->cte_conn_iq_rpt.conn_handle; + param.conn_iq_rpt.data_channel_idx = params->cte_conn_iq_rpt.data_channel_idx; + param.conn_iq_rpt.rssi = params->cte_conn_iq_rpt.rssi; + param.conn_iq_rpt.rssi_ant_id = params->cte_conn_iq_rpt.rssi_ant_id; + param.conn_iq_rpt.cte_type = params->cte_conn_iq_rpt.cte_type; + param.conn_iq_rpt.slot_dur = params->cte_conn_iq_rpt.slot_dur; + param.conn_iq_rpt.pkt_status = params->cte_conn_iq_rpt.pkt_status; + param.conn_iq_rpt.conn_evt_counter = params->cte_conn_iq_rpt.conn_evt_counter; + param.conn_iq_rpt.sample_count = params->cte_conn_iq_rpt.sample_count; + param.conn_iq_rpt.i_sample = ¶ms->cte_conn_iq_rpt.i_sample[0]; + param.conn_iq_rpt.q_sample = ¶ms->cte_conn_iq_rpt.q_sample[0]; + break; + case BTA_BLE_CTE_REQUEST_FAILED_EVT: + msg.act = ESP_BLE_CTE_REQUEST_FAILED_EVT; + param.req_failed_evt.reason = btc_btm_status_to_esp_status(params->cte_req_failed.status); + param.req_failed_evt.conn_handle = params->cte_req_failed.conn_handle; + break; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + default: + break; + } + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_cte_cb_param_t), btc_ble_cte_cb_deep_copy, btc_ble_cte_cb_deep_free); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + +void btc_ble_cte_cb_handler(btc_msg_t *msg) +{ + BTC_TRACE_DEBUG("%s act %d \n", __func__, msg->act); + esp_ble_cte_cb_param_t *param = (esp_ble_cte_cb_param_t *)msg->arg; + + if (msg->act < ESP_BLE_CTE_EVT_MAX) { + btc_cte_ble_cb_to_app(msg->act, param); + } else { + BTC_TRACE_ERROR("%s, unknown msg->act = %d", __func__, msg->act); + } + + btc_ble_cte_cb_deep_free(msg); + +} + +void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) +{ +#if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE)) + btc_ble_cte_args_t *src = (btc_ble_cte_args_t *)p_src; + btc_ble_cte_args_t *dst = (btc_ble_cte_args_t *)p_dest; +#endif // #if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE)) + switch (msg->act) { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case BTC_CTE_ACT_SET_TRANS_PARAMS: + if (src->cte_trans_params.switching_pattern_len && src->cte_trans_params.antenna_ids) { + dst->cte_trans_params.antenna_ids = osi_malloc(src->cte_trans_params.switching_pattern_len); + if (dst->cte_trans_params.antenna_ids) { + memcpy(dst->cte_trans_params.antenna_ids, src->cte_trans_params.antenna_ids, src->cte_trans_params.switching_pattern_len); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; + case BTC_CTE_ACT_SET_IQ_SAMPLING_EN: + if (src->cte_iq_sampling_en.switching_pattern_len && src->cte_iq_sampling_en.antenna_ids) { + dst->cte_iq_sampling_en.antenna_ids = osi_malloc(src->cte_iq_sampling_en.switching_pattern_len); + if (dst->cte_iq_sampling_en.antenna_ids) { + memcpy(dst->cte_iq_sampling_en.antenna_ids, src->cte_iq_sampling_en.antenna_ids, src->cte_iq_sampling_en.switching_pattern_len); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS: + if (src->cte_recv_params.switching_pattern_len && src->cte_recv_params.antenna_ids) { + dst->cte_recv_params.antenna_ids = osi_malloc(src->cte_recv_params.switching_pattern_len); + if (dst->cte_recv_params.antenna_ids) { + memcpy(dst->cte_recv_params.antenna_ids, src->cte_recv_params.antenna_ids, src->cte_recv_params.switching_pattern_len); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; + case BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS: + if (src->cte_conn_trans_params.switching_pattern_len && src->cte_conn_trans_params.antenna_ids) { + dst->cte_conn_trans_params.antenna_ids = osi_malloc(src->cte_conn_trans_params.switching_pattern_len); + if (dst->cte_conn_trans_params.antenna_ids) { + memcpy(dst->cte_conn_trans_params.antenna_ids, src->cte_conn_trans_params.antenna_ids, src->cte_conn_trans_params.switching_pattern_len); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + default: + BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act); + break; + } +} + +void btc_ble_cte_arg_deep_free(btc_msg_t *msg) +{ + BTC_TRACE_DEBUG("%s \n", __func__); + switch (msg->act) { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case BTC_CTE_ACT_SET_TRANS_PARAMS: { + uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_trans_params.antenna_ids; + if (antenna_ids) { + osi_free(antenna_ids); + } + break; + } + case BTC_CTE_ACT_SET_IQ_SAMPLING_EN: { + uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_iq_sampling_en.antenna_ids; + if (antenna_ids) { + osi_free(antenna_ids); + } + break; + } +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS: { + uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_recv_params.antenna_ids; + if (antenna_ids) { + osi_free(antenna_ids); + } + break; + } + case BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS: { + uint8_t *antenna_ids = ((btc_ble_cte_args_t *)msg->arg)->cte_conn_trans_params.antenna_ids; + if (antenna_ids) { + osi_free(antenna_ids); + } + break; + } +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + default: + BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act); + break; + } +} + +void btc_ble_cte_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) +{ + esp_ble_cte_cb_param_t *src = (esp_ble_cte_cb_param_t *)p_src; + esp_ble_cte_cb_param_t *dst = (esp_ble_cte_cb_param_t *) p_dest; + + switch (msg->act) { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT: + if (src->connless_iq_rpt.sample_count) { + dst->connless_iq_rpt.i_sample = osi_malloc(src->connless_iq_rpt.sample_count); + if (dst->connless_iq_rpt.i_sample) { + memcpy(dst->connless_iq_rpt.i_sample, &(src->connless_iq_rpt.i_sample[0]), + src->connless_iq_rpt.sample_count); + } else { + BTC_TRACE_ERROR("%s, i_sample malloc failed\n", __func__); + } + dst->connless_iq_rpt.q_sample = osi_malloc(src->connless_iq_rpt.sample_count); + if (dst->connless_iq_rpt.q_sample) { + memcpy(dst->connless_iq_rpt.q_sample, &(src->connless_iq_rpt.q_sample[0]), + src->connless_iq_rpt.sample_count); + } else { + BTC_TRACE_ERROR("%s, q_sample malloc failed\n", __func__); + } + } + break; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case ESP_BLE_CTE_CONN_IQ_REPORT_EVT: + if (src->conn_iq_rpt.sample_count) { + dst->conn_iq_rpt.i_sample = osi_malloc(src->conn_iq_rpt.sample_count); + if (dst->conn_iq_rpt.i_sample) { + memcpy(dst->conn_iq_rpt.i_sample, src->conn_iq_rpt.i_sample, + src->conn_iq_rpt.sample_count); + } else { + BTC_TRACE_ERROR("%s, i_sample malloc failed\n", __func__); + } + dst->conn_iq_rpt.q_sample = osi_malloc(src->conn_iq_rpt.sample_count); + if (dst->conn_iq_rpt.q_sample) { + memcpy(dst->conn_iq_rpt.q_sample, src->conn_iq_rpt.q_sample, + src->conn_iq_rpt.sample_count); + } else { + BTC_TRACE_ERROR("%s, q_sample malloc failed\n", __func__); + } + } + break; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + default: + BTC_TRACE_DEBUG("%s, Unhandled deep copy %d\n", __func__, msg->act); + break; + } +} + +void btc_ble_cte_cb_deep_free(btc_msg_t *msg) +{ + BTC_TRACE_DEBUG("%s", __func__); + switch (msg->act) { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT: { + esp_ble_cte_cb_param_t *params = (esp_ble_cte_cb_param_t *)msg->arg; + uint8_t *i_sample = &(params->connless_iq_rpt.i_sample[0]); + uint8_t *q_sample = &(params->connless_iq_rpt.q_sample[0]); + if (i_sample) { + osi_free(i_sample); + } + if (q_sample) { + osi_free(q_sample); + } + break; + } +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case ESP_BLE_CTE_CONN_IQ_REPORT_EVT: { + esp_ble_cte_cb_param_t *params = (esp_ble_cte_cb_param_t *)msg->arg; + uint8_t *i_sample = params->conn_iq_rpt.i_sample; + uint8_t *q_sample = params->conn_iq_rpt.q_sample; + if (i_sample) { + osi_free(i_sample); + } + if (q_sample) { + osi_free(q_sample); + } + break; + } +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + default: + BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act); + break; + } +} + +void btc_ble_cte_call_handler(btc_msg_t *msg) +{ +#if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE)) + btc_ble_cte_args_t *arg = (btc_ble_cte_args_t *)msg->arg; +#endif // #if ((BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) || (BLE_FEAT_CTE_CONNECTION_EN == TRUE)) + BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act); + + switch (msg->act) { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case BTC_CTE_ACT_SET_TRANS_PARAMS: + struct cte_set_trans_params_arg *cte_trans_params = &arg->cte_trans_params; + BTA_DmBleCteSetConnectionlessTransParams(cte_trans_params->adv_handle, cte_trans_params->cte_len, cte_trans_params->cte_type, + cte_trans_params->cte_count, cte_trans_params->switching_pattern_len, cte_trans_params->antenna_ids); + break; + case BTC_CTE_ACT_SET_TRANS_ENABLE: + BTA_DmBleCteSetConnectionlessTransEnable(arg->cte_trans_enable.adv_handle, arg->cte_trans_enable.cte_enable); + break; + case BTC_CTE_ACT_SET_IQ_SAMPLING_EN: + struct cte_iq_sampling_en_arg *iq_sampling_en = &arg->cte_iq_sampling_en; + BTA_DmBleCteSetConnectionlessIqSamplingEnable(iq_sampling_en->sync_handle, iq_sampling_en->sampling_en, iq_sampling_en->slot_dur, + iq_sampling_en->max_sampled_ctes, iq_sampling_en->switching_pattern_len, iq_sampling_en->antenna_ids); + break; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS: + struct cte_recv_params_arg *recv_params = &arg->cte_recv_params; + BTA_DmBleCteSetConnectionReceiveParams(recv_params->conn_handle, recv_params->sampling_en, recv_params->slot_dur, + recv_params->switching_pattern_len, recv_params->antenna_ids); + break; + case BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS: + struct cte_set_conn_trans_params_arg *trans_params = &arg->cte_conn_trans_params; + BTA_DmBleCteSetConnectionTransParams(trans_params->conn_handle, trans_params->cte_types, trans_params->switching_pattern_len, trans_params->antenna_ids); + break; + case BTC_CTE_ACT_SET_CONN_CTE_REQUEST_EN: + struct cte_req_en_arg *cte_req_en = &arg->cte_req_en; + BTA_DmBleCteSetConnectionRequestEnable(cte_req_en->conn_handle, cte_req_en->enable, cte_req_en->cte_req_interval, + cte_req_en->req_cte_len, cte_req_en->req_cte_Type); + break; + case BTC_CTE_ACT_SET_CONN_CTE_RESPONSE_EN: + BTA_DmBleCteSetConnectionRspEnable(arg->cte_rsp_en.conn_handle, arg->cte_rsp_en.enable); + break; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case BTC_CTE_ACT_READ_ANTENNA_INFOR: + BTA_DmBleCteReadAntInfor(); + break; + default: + break; + } + + btc_ble_cte_arg_deep_free(msg); +} + +//register connection parameter update callback +void btc_cte_callback_init(void) +{ + BTM_BleCteRegisterCallback(btc_ble_cte_callback); +} + +#endif ///BLE_FEAT_CTE_EN == TRUE diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h new file mode 100644 index 0000000000..659bfb3199 --- /dev/null +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __BTC_CTE_BLE_H__ +#define __BTC_CTE_BLE_H__ + +#if (BLE_FEAT_CTE_EN == TRUE) +#include "esp_bt_defs.h" +#include "esp_ble_cte_api.h" +#include "btc/btc_manage.h" + +typedef enum { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + BTC_CTE_ACT_SET_TRANS_PARAMS, + BTC_CTE_ACT_SET_TRANS_ENABLE, + BTC_CTE_ACT_SET_IQ_SAMPLING_EN, +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + BTC_CTE_ACT_SET_CONN_CTE_RECV_PARAMS, + BTC_CTE_ACT_SET_CONN_CTE_TRANS_PARAMS, + BTC_CTE_ACT_SET_CONN_CTE_REQUEST_EN, + BTC_CTE_ACT_SET_CONN_CTE_RESPONSE_EN, +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + BTC_CTE_ACT_READ_ANTENNA_INFOR, +} btc_cte_ble_act_t; + +/* btc_ble_cte_args_t */ +typedef union { +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + struct cte_set_trans_params_arg { + uint8_t adv_handle; + uint8_t cte_len; + uint8_t cte_type; + uint8_t cte_count; + uint8_t switching_pattern_len; + uint8_t *antenna_ids; + } cte_trans_params; + + struct cte_set_trans_enable_arg { + uint8_t adv_handle; + uint8_t cte_enable; + } cte_trans_enable; + + struct cte_iq_sampling_en_arg { + uint16_t sync_handle; + uint8_t sampling_en; + uint8_t slot_dur; + uint8_t max_sampled_ctes; + uint8_t switching_pattern_len; + uint8_t *antenna_ids; + } cte_iq_sampling_en; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + struct cte_recv_params_arg { + uint16_t conn_handle; + uint8_t sampling_en; + uint8_t slot_dur; + uint8_t switching_pattern_len; + uint8_t *antenna_ids; + } cte_recv_params; + + struct cte_set_conn_trans_params_arg { + uint16_t conn_handle; + uint8_t cte_types; + uint8_t switching_pattern_len; + uint8_t *antenna_ids; + } cte_conn_trans_params; + + struct cte_req_en_arg { + uint16_t conn_handle; + uint8_t enable; + uint16_t cte_req_interval; + uint8_t req_cte_len; + uint8_t req_cte_Type; + } cte_req_en; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + + struct cte_rsp_en_arg { + uint16_t conn_handle; + uint8_t enable; + } cte_rsp_en; + +} btc_ble_cte_args_t; + +void btc_ble_cte_call_handler(btc_msg_t *msg); +void btc_ble_cte_cb_handler(btc_msg_t *msg); +void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); +void btc_ble_cte_arg_deep_free(btc_msg_t *msg); +void btc_ble_cte_cb_deep_free(btc_msg_t *msg); +void btc_ble_cte_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); +void btc_cte_callback_init(void); + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + +#endif /* __BTC_CTE_BLE_H__ */ diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 95368f0b3c..280bbb52da 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -276,6 +276,24 @@ #define UC_BT_BLE_ISO_NON_STD_FLOW_CTRL CONFIG_BT_BLE_ISO_NON_STD_FLOW_CTRL #endif +#ifdef CONFIG_BT_BLE_FEAT_CTE_EN +#define UC_BT_BLE_FEAT_CTE_EN CONFIG_BT_BLE_FEAT_CTE_EN +#else +#define UC_BT_BLE_FEAT_CTE_EN FALSE +#endif + +#ifdef CONFIG_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN +#define UC_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN CONFIG_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN +#else +#define UC_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN FALSE +#endif + +#ifdef CONFIG_BT_BLE_FEAT_CTE_CONNECTION_EN +#define UC_BT_BLE_FEAT_CTE_CONNECTION_EN CONFIG_BT_BLE_FEAT_CTE_CONNECTION_EN +#else +#define UC_BT_BLE_FEAT_CTE_CONNECTION_EN FALSE +#endif + #ifdef CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL #define UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL #else diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index ecba3cedc3..5449a32e6d 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -347,6 +347,24 @@ #error "Only one of standard or non-standard can be enabled" #endif +#if (UC_BT_BLE_FEAT_CTE_EN == TRUE) +#define BLE_FEAT_CTE_EN TRUE +#else +#define BLE_FEAT_CTE_EN FALSE +#endif + +#if (UC_BT_BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define BLE_FEAT_CTE_CONNECTIONLESS_EN TRUE +#else +#define BLE_FEAT_CTE_CONNECTIONLESS_EN FALSE +#endif + +#if (UC_BT_BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BLE_FEAT_CTE_CONNECTION_EN TRUE +#else +#define BLE_FEAT_CTE_CONNECTION_EN FALSE +#endif + #if (UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL == TRUE) #define BLE_HIGH_DUTY_ADV_INTERVAL TRUE #else diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c b/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c new file mode 100644 index 0000000000..a79932de2f --- /dev/null +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c @@ -0,0 +1,237 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "btm_int.h" +#include "stack/hcimsgs.h" +#include "osi/allocator.h" +#include "device/controller.h" +#include +#include "l2c_int.h" + +tBTM_BLE_CTE_CBACK ble_cte_cb; + +extern void btm_ble_inter_set(bool extble_inter); + +void BTM_BleCteRegisterCallback(tBTM_BLE_CTE_CBACK cb) +{ + if (cb) { + ble_cte_cb = cb; + } else { + BTM_TRACE_ERROR("%s, register fail, the cb function is NULL.", __func__); + } +} + +void BTM_CteBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_CTE_CB_PARAMS *params) +{ + BTM_TRACE_DEBUG("%s event %x", __func__, event); + + if(params && params->status == BTM_SUCCESS) { + btm_ble_inter_set(true); + } + if (ble_cte_cb) { + ble_cte_cb(event, params); + } +} +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + + + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_connless_cte_trans_params(adv_handle, cte_len, cte_type, cte_count, switching_pattern_len, antenna_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set trans params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_trans_params_cmpl.status = status; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_TRANS_PARAMS_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_connless_cte_enable(adv_handle, cte_en)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set trans enable, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_trans_en_cmpl.status = status; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_TRANS_ENABLE_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_connless_iq_sampling_enable(sync_handle, sampling_en, slot_dur, max_sampled_ctes, switching_pattern_len, ant_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set trans enable, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_iq_samp_en_cmpl.status = status; + cb_params.cte_iq_samp_en_cmpl.sync_handle = sync_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT, &cb_params); + + return status; +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +tBTM_STATUS BTM_BleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_conn_cte_receive_params(conn_handle, sampling_en, slot_dur, switching_pattern_len, ant_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn recv params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_recv_params_cmpl.status = status; + cb_params.cte_recv_params_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_conn_cte_trans_params(conn_handle, cte_types, switching_pattern_len, ant_ids)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn trans params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_conn_trans_params_cmpl.status = status; + cb_params.cte_conn_trans_params_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_int, + uint8_t req_cte_len, uint8_t req_cte_type) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_conn_cte_req_enable(conn_handle, enable, cte_req_int, req_cte_len, req_cte_type)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn req en, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_conn_req_en_cmpl.status = status; + cb_params.cte_conn_req_en_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT, &cb_params); + + return status; +} + +tBTM_STATUS BTM_BleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_conn_cte_rsp_enable(conn_handle, enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte set conn rsp en, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cte_conn_rsp_en_cmpl.status = status; + cb_params.cte_conn_rsp_en_cmpl.conn_handle = conn_handle; + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT, &cb_params); + + return status; +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +tBTM_STATUS BTM_BleCteReadAntInfor(void) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + + if ((err = btsnd_hcic_ble_read_antenna_info()) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cte read ant information, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + return status; +} + +void btm_ble_cte_read_ant_infor_complete(UINT8 *p) +{ + tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.status, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.supported_switching_sampling_rates, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.num_ant, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.max_switching_pattern_len, p); + STREAM_TO_UINT8(cb_params.cte_read_ant_infor_cmpl.max_cte_len, p); + + if (cb_params.cte_read_ant_infor_cmpl.status != HCI_SUCCESS) { + cb_params.cte_read_ant_infor_cmpl.status = (BTM_HCI_ERROR | cb_params.cte_read_ant_infor_cmpl.status); + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_READ_ANT_INFOR_EVT, &cb_params); +} + +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +void btm_ble_connless_iq_report_evt(tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +void btm_ble_conn_iq_report_evt(tBTM_BLE_CTE_CONN_IQ_REPORT_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_CONN_IQ_REPORT_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params); +} + +void btm_ble_cte_req_failed_evt(tBTM_BLE_CTE_REQ_FAILED_EVT *params) +{ + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + if (params->status != HCI_SUCCESS) { + params->status = (params->status | BTM_HCI_ERROR); + } + + BTM_CteBleCallbackTrigger(BTM_BLE_CTE_REQUEST_FAILED_EVT, (tBTM_BLE_CTE_CB_PARAMS *)params); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 6e00feeefa..cd1bc8aabe 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -584,6 +584,13 @@ void btm_ble_biginfo_adv_report_evt(tBTM_BLE_BIGINFO_ADV_REPORT_EVT *params); #endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) void btm_ble_iso_data_path_update_complete(UINT16 opcode, UINT8 hci_status, UINT16 conn_handle); #endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +void btm_ble_cte_read_ant_infor_complete(UINT8 *p); +void btm_ble_connless_iq_report_evt(tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT *params); +void btm_ble_conn_iq_report_evt(tBTM_BLE_CTE_CONN_IQ_REPORT_EVT *params); +void btm_ble_cte_req_failed_evt(tBTM_BLE_CTE_REQ_FAILED_EVT *params); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) /* #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 08b2eb7883..3ba49e4e25 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -208,6 +208,17 @@ static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason); #endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +static void btu_ble_cte_connless_iq_report_evt(UINT8 *p); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +static void btu_ble_cte_conn_iq_report_evt(UINT8 *p); +static void btu_ble_cte_req_failed_evt(UINT8 *p); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + #if (BLE_42_ADV_EN == TRUE) extern osi_sem_t adv_enable_sem; extern osi_sem_t adv_data_sem; @@ -536,6 +547,23 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) break; #endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + case HCI_BLE_CONNLESS_IQ_REPORT_EVT: + btu_ble_cte_connless_iq_report_evt(p); + break; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + case HCI_BLE_CONN_IQ_REPORT_EVT: + btu_ble_cte_conn_iq_report_evt(p); + break; + case HCI_BLE_CTE_REQUEST_FAILED_EVT: + btu_ble_cte_req_failed_evt(p); + break; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) } break; #endif /* BLE_INCLUDED */ @@ -1325,6 +1353,11 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l #endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) + case HCI_BLE_READ_ANT_INFOR: + btm_ble_cte_read_ant_infor_complete(p); + break; +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #endif /* (BLE_INCLUDED == TRUE) */ default: { @@ -2872,6 +2905,86 @@ static void btu_ble_biginfo_adv_report_evt(UINT8 *p) } #endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) +{ + tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT connless_iq_rpt = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(connless_iq_rpt.sync_handle, p); + STREAM_TO_UINT8(connless_iq_rpt.channel_idx, p); + STREAM_TO_UINT16(connless_iq_rpt.rssi, p); + STREAM_TO_UINT8(connless_iq_rpt.rssi_ant_id, p); + STREAM_TO_UINT8(connless_iq_rpt.cte_type, p); + STREAM_TO_UINT8(connless_iq_rpt.slot_dur, p); + STREAM_TO_UINT8(connless_iq_rpt.pkt_status, p); + STREAM_TO_UINT16(connless_iq_rpt.periodic_evt_counter, p); + STREAM_TO_UINT8(connless_iq_rpt.sample_count, p); + + for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) + { + STREAM_TO_UINT8(connless_iq_rpt.i_sample[i], p); + STREAM_TO_UINT8(connless_iq_rpt.q_sample[i], p); + } + + btm_ble_connless_iq_report_evt(&connless_iq_rpt); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +static void btu_ble_cte_conn_iq_report_evt(UINT8 *p) +{ + tBTM_BLE_CTE_CONN_IQ_REPORT_EVT conn_iq_rpt = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(conn_iq_rpt.conn_handle, p); + STREAM_TO_UINT8(conn_iq_rpt.rx_phy, p); + STREAM_TO_UINT8(conn_iq_rpt.data_channel_idx, p); + STREAM_TO_UINT16(conn_iq_rpt.rssi, p); + STREAM_TO_UINT8(conn_iq_rpt.rssi_ant_id, p); + STREAM_TO_UINT8(conn_iq_rpt.cte_type, p); + STREAM_TO_UINT8(conn_iq_rpt.slot_dur, p); + STREAM_TO_UINT8(conn_iq_rpt.pkt_status, p); + STREAM_TO_UINT16(conn_iq_rpt.conn_evt_counter, p); + STREAM_TO_UINT8(conn_iq_rpt.sample_count, p); + + for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) + { + STREAM_TO_UINT8(conn_iq_rpt.i_sample[i], p); + STREAM_TO_UINT8(conn_iq_rpt.q_sample[i], p); + } + + btm_ble_conn_iq_report_evt(&conn_iq_rpt); +} + +static void btu_ble_cte_req_failed_evt(UINT8 *p) +{ + tBTM_BLE_CTE_REQ_FAILED_EVT cte_req_failed = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(cte_req_failed.status, p); + STREAM_TO_UINT16(cte_req_failed.conn_handle, p); + + btm_ble_cte_req_failed_evt(&cte_req_failed); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + /********************************************** ** End of BLE Events Handler ***********************************************/ diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 8cb61d78ba..bc01cd6553 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -2447,3 +2447,197 @@ UINT8 btsnd_hcic_ble_iso_read_iso_link_quality(uint16_t iso_handle) } #endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +UINT8 btsnd_hcic_ble_set_connless_cte_trans_params(uint8_t adv_hdl, uint8_t cte_len, uint8_t cte_type, + uint8_t cte_cnt, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connless cte trans: adv_hdl %d cte_len %d cte_type %d cte_cnt %d", adv_hdl, cte_len, cte_type, cte_cnt); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_CTE_TRANS_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS + switching_pattern_len); + + UINT8_TO_STREAM(pp, adv_hdl); + UINT8_TO_STREAM(pp, cte_len); + UINT8_TO_STREAM(pp, cte_type); + UINT8_TO_STREAM(pp, cte_cnt); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_connless_cte_enable(uint8_t adv_hdl, uint8_t cte_en) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connect cte enable: adv_hdl %d cte_en %d", adv_hdl, cte_en); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_CTE_TRANS_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE); + + UINT8_TO_STREAM(pp, adv_hdl); + UINT8_TO_STREAM(pp, cte_en); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_connless_iq_sampling_enable(uint16_t sync_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci enable IQ sampling: sync_hdl %d sampling_en %d slot_dur %d", sync_hdl, sampling_en, slot_dur); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONNLESS_IQ_SAMPLING_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE + switching_pattern_len); + + UINT16_TO_STREAM(pp, sync_hdl); + UINT8_TO_STREAM(pp, sampling_en); + UINT8_TO_STREAM(pp, slot_dur); + UINT8_TO_STREAM(pp, max_sampled_ctes); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +UINT8 btsnd_hcic_ble_set_conn_cte_receive_params(uint16_t conn_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connection cte receive params: conn_hdl %d sampling_en %d slot_dur %d", conn_hdl, sampling_en, slot_dur); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_RECEIVE_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS + switching_pattern_len); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, sampling_en); + UINT8_TO_STREAM(pp, slot_dur); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_conn_cte_trans_params(uint16_t conn_hdl, uint8_t cte_type, uint8_t switching_pattern_len, uint8_t *antenna_ids) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connection cte trans params: conn_hdl %d cte_type %d len %d", conn_hdl, cte_type, switching_pattern_len); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS + switching_pattern_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_TRANS_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS + switching_pattern_len); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, cte_type); + UINT8_TO_STREAM(pp, switching_pattern_len); + for (uint8_t i = 0; i < switching_pattern_len; i++) + { + UINT8_TO_STREAM(pp, antenna_ids[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_conn_cte_req_enable(uint16_t conn_hdl, uint8_t enable, uint16_t cte_req_int, uint8_t req_cte_len, uint8_t req_cte_type) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connect cte request enable: conn_hdl %d enable %d cte_req_int %d req_cte_len %d req_cte_type %d", conn_hdl, enable, cte_req_int, req_cte_len, req_cte_type); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_REQ_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, enable); + UINT16_TO_STREAM(pp, cte_req_int); + UINT8_TO_STREAM(pp, req_cte_len); + UINT8_TO_STREAM(pp, req_cte_type); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_conn_cte_rsp_enable(uint16_t conn_hdl, uint8_t enable) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set connect cte response enable: conn_hdl %d enable %d", conn_hdl, enable); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_CONN_CTE_RSP_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE); + + UINT16_TO_STREAM(pp, conn_hdl); + UINT8_TO_STREAM(pp, enable); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +UINT8 btsnd_hcic_ble_read_antenna_info(void) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci read antenna information"); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_ANT_INFO); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_READ_ANT_INFOR); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_ANT_INFO); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_CTE_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index 5b24eb1983..6e1fee4b59 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -1106,6 +1106,25 @@ typedef UINT8 tBTM_BLE_5_GAP_EVENT; typedef UINT8 tBTM_BLE_ISO_EVENT; #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define BTM_BLE_CTE_SET_TRANS_PARAMS_EVT 1 +#define BTM_BLE_CTE_SET_TRANS_ENABLE_EVT 2 +#define BTM_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT 3 +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BTM_BLE_CTE_SET_CONN_RECV_PARAMS_EVT 4 +#define BTM_BLE_CTE_SET_CONN_TRANS_PARAMS_EVT 5 +#define BTM_BLE_CTE_SET_CONN_REQ_ENABLE_EVT 6 +#define BTM_BLE_CTE_SET_CONN_RSP_ENABLE_EVT 7 +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define BTM_BLE_CTE_READ_ANT_INFOR_EVT 8 +#define BTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT 9 +#define BTM_BLE_CTE_CONN_IQ_REPORT_EVT 10 +#define BTM_BLE_CTE_REQUEST_FAILED_EVT 11 +typedef UINT8 tBTM_BLE_CTE_EVENT; +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #define BTM_BLE_EXT_ADV_DATA_COMPLETE 0x00 #define BTM_BLE_EXT_ADV_DATA_INCOMPLETE 0x01 @@ -1558,6 +1577,108 @@ typedef union { typedef void (*tBTM_BLE_ISO_CBACK)(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *params); #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +typedef struct { + UINT8 status; +} __attribute__((packed)) tBTM_BLE_CTE_SET_TRANS_PARAMS_CMPL; + +typedef struct { + UINT8 status; +} __attribute__((packed)) tBTM_BLE_CTE_SET_TRANS_EN_CMPL; + +typedef struct { + UINT8 status; + UINT16 sync_handle; +} __attribute__((packed)) tBTM_BLE_CTE_IQ_SAMP_EN_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_RECV_PARAMS_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_TRANS_PARAMS_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_REQ_ENABLE_CMPL; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_RSP_ENABLE_CMPL; + +typedef struct { + UINT8 status; + UINT8 supported_switching_sampling_rates; + UINT8 num_ant; + UINT8 max_switching_pattern_len; + UINT8 max_cte_len; +} __attribute__((packed)) tBTM_BLE_CTE_READ_ANT_INFOR_CMPL; + +typedef struct { + UINT16 sync_handle; + UINT8 channel_idx; + INT16 rssi; + UINT8 rssi_ant_id; + UINT8 cte_type; + UINT8 slot_dur; + UINT8 pkt_status; + UINT16 periodic_evt_counter; + UINT8 sample_count; + UINT8 i_sample[0x52]; + UINT8 q_sample[0x52]; +} __attribute__((packed)) tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT; + +typedef struct { + UINT16 conn_handle; + UINT8 rx_phy; + UINT8 data_channel_idx; + INT16 rssi; + UINT8 rssi_ant_id; + UINT8 cte_type; + UINT8 slot_dur; + UINT8 pkt_status; + UINT16 conn_evt_counter; + UINT8 sample_count; + UINT8 i_sample[0x52]; + UINT8 q_sample[0x52]; +} __attribute__((packed)) tBTM_BLE_CTE_CONN_IQ_REPORT_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CTE_REQ_FAILED_EVT; + +typedef union { + UINT8 status; +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + tBTM_BLE_CTE_SET_TRANS_PARAMS_CMPL cte_trans_params_cmpl; + tBTM_BLE_CTE_SET_TRANS_EN_CMPL cte_trans_en_cmpl; + tBTM_BLE_CTE_IQ_SAMP_EN_CMPL cte_iq_samp_en_cmpl; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTM_BLE_CTE_CONN_RECV_PARAMS_CMPL cte_recv_params_cmpl; + tBTM_BLE_CTE_CONN_TRANS_PARAMS_CMPL cte_conn_trans_params_cmpl; + tBTM_BLE_CTE_CONN_REQ_ENABLE_CMPL cte_conn_req_en_cmpl; + tBTM_BLE_CTE_CONN_RSP_ENABLE_CMPL cte_conn_rsp_en_cmpl; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTM_BLE_CTE_READ_ANT_INFOR_CMPL cte_read_ant_infor_cmpl; +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT cte_connless_iq_rpt; +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + tBTM_BLE_CTE_CONN_IQ_REPORT_EVT cte_conn_iq_rpt; + tBTM_BLE_CTE_REQ_FAILED_EVT cte_req_failed; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +} tBTM_BLE_CTE_CB_PARAMS; + +typedef void (*tBTM_BLE_CTE_CBACK)(tBTM_BLE_CTE_EVENT event, tBTM_BLE_CTE_CB_PARAMS *params); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + typedef union { UINT8 status; tBTM_BLE_READ_PHY_CMPL read_phy; @@ -3114,4 +3235,25 @@ tBTM_STATUS BTM_BleRejectCisReq(uint16_t cis_handle, uint8_t reason); tBTM_STATUS BTM_BleDisconCis(uint16_t cis_handle, uint8_t reason); #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #endif // #if (BLE_FEAT_ISO_EN == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +void BTM_BleCteRegisterCallback(tBTM_BLE_CTE_CBACK cb); +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids); +tBTM_STATUS BTM_BleCteSetConnectionlessTransEnable(uint8_t adv_handle, uint8_t cte_en); +tBTM_STATUS BTM_BleCteSetConnectionlessIqSamplingEnable(uint16_t sync_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *ant_ids); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) + +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +tBTM_STATUS BTM_BleCteSetConnectionReceiveParams(uint16_t conn_handle, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *ant_ids); +tBTM_STATUS BTM_BleCteSetConnectionTransParams(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, uint8_t *ant_ids); +tBTM_STATUS BTM_BleCteSetConnectionRequestEnable(uint16_t conn_handle, uint8_t enable, uint16_t cte_req_int, + uint8_t req_cte_len, uint8_t req_cte_type); +tBTM_STATUS BTM_BleCteSetConnectionRspEnable(uint16_t conn_handle, uint8_t enable); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) + +tBTM_STATUS BTM_BleCteReadAntInfor(void); + +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index b90b36cb9a..a45b7d2160 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -390,6 +390,20 @@ #define HCI_BLE_WR_RF_PATH_COMPENSATION (0x004D | HCI_GRP_BLE_CMDS) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define HCI_BLE_SET_CONNLESS_CTE_TRANS_PARAMS (0x0051 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONNLESS_CTE_TRANS_ENABLE (0x0052 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONNLESS_IQ_SAMPLING_ENABLE (0x0053 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCI_BLE_SET_CONN_CTE_RECEIVE_PARAMS (0x0054 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONN_CTE_TRANS_PARAMS (0x0055 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONN_CTE_REQ_ENABLE (0x0056 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_CONN_CTE_RSP_ENABLE (0x0057 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCI_BLE_READ_ANT_INFOR (0x0058 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS) @@ -860,6 +874,12 @@ #define HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT 0x18 #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_FEAT_CTE_EN == TRUE) +#define HCI_BLE_CONNLESS_IQ_REPORT_EVT 0x15 +#define HCI_BLE_CONN_IQ_REPORT_EVT 0x16 +#define HCI_BLE_CTE_REQUEST_FAILED_EVT 0x17 +#endif // #if (BLE_FEAT_CTE_EN == TRUE) + #if (BLE_FEAT_ISO_EN == TRUE) #define HCI_BLE_CIS_ESTABLISHED_V1_EVT 0x19 #define HCI_BLE_CIS_REQUEST_EVT 0x1A diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index ce9c5f2e7c..cf355b5faa 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1185,4 +1185,34 @@ UINT8 btsnd_hcic_ble_iso_read_tx_sync(uint16_t iso_hdl); UINT8 btsnd_hcic_ble_iso_read_iso_link_quality(uint16_t iso_hdl); #endif // #if (BLE_FEAT_ISO_EN == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#define HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_PARAMS 5 +#define HCIC_PARAM_SIZE_SET_CONNLESS_CTE_TRANS_ENABLE 2 +#define HCIC_PARAM_SIZE_SET_CONNLESS_IQ_SAMPLING_ENABLE 6 +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCIC_PARAM_SIZE_SET_CONN_CTE_RECEIVE_PARAMS 5 +#define HCIC_PARAM_SIZE_SET_CONN_CTE_TRANS_PARAMS 4 +#define HCIC_PARAM_SIZE_CONN_CTE_REQ_ENABLE 7 +#define HCIC_PARAM_SIZE_CONN_CTE_RSP_ENABLE 3 +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +#define HCIC_PARAM_SIZE_READ_ANT_INFO 0 +#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +UINT8 btsnd_hcic_ble_set_connless_cte_trans_params(uint8_t adv_hdl, uint8_t cte_len, uint8_t cte_type, + uint8_t cte_cnt, uint8_t switching_pattern_len, uint8_t *antenna_ids); +UINT8 btsnd_hcic_ble_set_connless_cte_enable(uint8_t adv_hdl, uint8_t cte_en); +UINT8 btsnd_hcic_ble_set_connless_iq_sampling_enable(uint16_t sync_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t max_sampled_ctes, uint8_t switching_pattern_len, uint8_t *antenna_ids); +#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) +#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +UINT8 btsnd_hcic_ble_set_conn_cte_receive_params(uint16_t conn_hdl, uint8_t sampling_en, uint8_t slot_dur, + uint8_t switching_pattern_len, uint8_t *antenna_ids); +UINT8 btsnd_hcic_ble_set_conn_cte_trans_params(uint16_t conn_hdl, uint8_t cte_type, uint8_t switching_pattern_len, uint8_t *antenna_ids); +UINT8 btsnd_hcic_ble_conn_cte_req_enable(uint16_t conn_hdl, uint8_t enable, uint16_t cte_req_int, uint8_t req_cte_len, uint8_t req_cte_type); +UINT8 btsnd_hcic_ble_conn_cte_rsp_enable(uint16_t conn_hdl, uint8_t enable); +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) +UINT8 btsnd_hcic_ble_read_antenna_info(void); +#endif // #if (BLE_FEAT_CTE_EN == TRUE) #endif