From be594ffd5725c9fc64dc50d0a30fc8632951a4dd Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 10 Jun 2026 19:54:06 +0800 Subject: [PATCH] fix(ble/bluedroid): fix CTE and ISO API validation (cherry picked from commit 0c3c894b7de9740f324ae8043e7abdd932216b51) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/api/esp_ble_cte_api.c | 65 +++++++++++++++---- .../bt/host/bluedroid/api/esp_ble_iso_api.c | 9 ++- .../api/include/api/esp_ble_iso_api.h | 2 +- .../btc/profile/std/cte/btc_ble_cte.c | 9 ++- .../btc/profile/std/iso/btc_iso_ble.c | 13 +++- .../bt/host/bluedroid/hci/ble_hci_iso.c | 16 +++++ 6 files changed, 91 insertions(+), 23 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_ble_cte_api.c b/components/bt/host/bluedroid/api/esp_ble_cte_api.c index faeb58e8705..27f489d19e2 100644 --- a/components/bt/host/bluedroid/api/esp_ble_cte_api.c +++ b/components/bt/host/bluedroid/api/esp_ble_cte_api.c @@ -34,7 +34,7 @@ esp_ble_cte_cb_t esp_ble_cte_get_callback(void) #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_msg_t msg = {0}; btc_ble_cte_args_t arg; memset(&arg, 0, sizeof(arg)); @@ -42,7 +42,15 @@ esp_err_t esp_ble_cte_set_connectionless_trans_params(esp_ble_cte_connless_trans return ESP_ERR_INVALID_STATE; } - if ((cte_trans_params == NULL) || (cte_trans_params->antenna_ids == NULL)) { + if (cte_trans_params == NULL) { + return ESP_ERR_INVALID_ARG; + } + /* + * Per Core Spec, switching_pattern_len and Antenna_IDs is ignored when no switching pattern is used + * For AoA CTE type, the transmitter does not + * switch antenna, so Antenna_IDs may be omitted as well. + */ + if ((cte_trans_params->cte_type != ESP_BLE_CTE_TYPE_AOA) && (cte_trans_params->antenna_ids == NULL)) { return ESP_ERR_INVALID_ARG; } // The controller has performed parameter checking, and the host will no longer verify the validity of these parameters repeatedly. @@ -72,15 +80,24 @@ esp_err_t esp_ble_cte_set_connectionless_trans_params(esp_ble_cte_connless_trans 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; + /* For AoA CTE type, the transmitter does not switch antenna; normalize + * switching_pattern_len and antenna_ids so the BTC layer does not perform + * an unnecessary deep copy of data that the controller will ignore. + */ + if (cte_trans_params->cte_type != ESP_BLE_CTE_TYPE_AOA) { + arg.cte_trans_params.switching_pattern_len = cte_trans_params->switching_pattern_len; + arg.cte_trans_params.antenna_ids = cte_trans_params->antenna_ids; + } else { + arg.cte_trans_params.switching_pattern_len = 0; + arg.cte_trans_params.antenna_ids = NULL; + } 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_msg_t msg = {0}; btc_ble_cte_args_t arg; memset(&arg, 0, sizeof(arg)); @@ -108,7 +125,7 @@ esp_err_t esp_ble_cte_set_connectionless_trans_enable(esp_ble_cte_trans_enable_p 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_msg_t msg = {0}; btc_ble_cte_args_t arg; memset(&arg, 0, sizeof(arg)); @@ -169,7 +186,7 @@ esp_err_t esp_ble_cte_set_connectionless_iq_sampling_enable(esp_ble_cte_iq_sampl #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_msg_t msg = {0}; btc_ble_cte_args_t arg; memset(&arg, 0, sizeof(arg)); @@ -221,7 +238,7 @@ esp_err_t esp_ble_cte_set_connection_receive_params(esp_ble_cte_recv_params_para 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_msg_t msg = {0}; btc_ble_cte_args_t arg; memset(&arg, 0, sizeof(arg)); @@ -229,9 +246,19 @@ esp_err_t esp_ble_cte_set_connection_transmit_params(esp_ble_cte_conn_trans_para return ESP_ERR_INVALID_STATE; } - if ((cte_conn_trans_params == NULL) || (cte_conn_trans_params->antenna_ids == NULL)) { + if (cte_conn_trans_params == NULL) { return ESP_ERR_INVALID_ARG; } + /* + * Per Core Spec, switching_pattern_len and Antenna_IDs is ignored when no switching pattern is used + * For AoA CTE type, the transmitter does not + * switch antenna, so Antenna_IDs may be omitted as well. + */ + if ((cte_conn_trans_params->cte_types & (ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_1US | ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_2US)) && + (cte_conn_trans_params->antenna_ids == NULL)) { + return ESP_ERR_INVALID_ARG; + } + // The controller has performed parameter checking, and the host will no longer verify the validity of these parameters repeatedly. #if (0) if ((cte_conn_trans_params->switching_pattern_len < ESP_BLE_CTE_MIN_SWITCHING_PATTERN_LENGTH) || @@ -251,15 +278,25 @@ esp_err_t esp_ble_cte_set_connection_transmit_params(esp_ble_cte_conn_trans_para 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; + /* Antenna switching is only required for AoD CTE responses; when only AoA + * is enabled, normalize switching_pattern_len and antenna_ids so the BTC + * layer does not perform an unnecessary deep copy of data that the + * controller will ignore. + */ + if (cte_conn_trans_params->cte_types & (ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_1US | ESP_BLE_CTE_TYPES_AOD_RESPONSE_WITH_2US)) { + 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; + } else { + arg.cte_conn_trans_params.switching_pattern_len = 0; + arg.cte_conn_trans_params.antenna_ids = NULL; + } 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_msg_t msg = {0}; btc_ble_cte_args_t arg; memset(&arg, 0, sizeof(arg)); @@ -302,7 +339,7 @@ esp_err_t esp_ble_cte_connection_cte_request_enable(esp_ble_cte_req_en_params_t 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_msg_t msg = {0}; btc_ble_cte_args_t arg; memset(&arg, 0, sizeof(arg)); @@ -334,7 +371,7 @@ esp_err_t esp_ble_cte_connection_cte_response_enable(esp_ble_cte_rsp_en_params_t esp_err_t esp_ble_cte_read_antenna_information(void) { - btc_msg_t msg; + btc_msg_t msg = {0}; if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { return ESP_ERR_INVALID_STATE; diff --git a/components/bt/host/bluedroid/api/esp_ble_iso_api.c b/components/bt/host/bluedroid/api/esp_ble_iso_api.c index 132b8880add..486c8676535 100644 --- a/components/bt/host/bluedroid/api/esp_ble_iso_api.c +++ b/components/bt/host/bluedroid/api/esp_ble_iso_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,7 +63,8 @@ esp_err_t esp_ble_iso_create_big(esp_ble_iso_big_creat_params_t *big_creat_param if (big_creat_param->rtn > 0x1E) { return ESP_ERR_INVALID_ARG; } - if ((big_creat_param->phy != 0x01) && (big_creat_param->phy != 0x02) && (big_creat_param->phy != 0x04)) { + /* phy is a bit field: bit0=1M, bit1=2M, bit2=Coded (HCI_LE_Create_BIG, Core Spec): at least one bit. */ + if ((big_creat_param->phy == 0) || (big_creat_param->phy & ~0x07)) { return ESP_ERR_INVALID_ARG; } if (big_creat_param->packing > 0x01) { @@ -118,7 +119,9 @@ esp_err_t esp_ble_iso_create_big_test(esp_ble_iso_big_creat_test_params_t *big_c if (big_creat_test_param->max_pdu < 0x0001 || big_creat_test_param->max_pdu > 0x00FB) { return ESP_ERR_INVALID_ARG; } - if ((big_creat_test_param->phy != 0x01) && (big_creat_test_param->phy != 0x02) && (big_creat_test_param->phy != 0x04)) { + /* HCI_LE_Create_BIG_Test (Core Spec): host shall set exactly one of 1M / 2M / Coded PHY. */ + if ((big_creat_test_param->phy != 0x01) && (big_creat_test_param->phy != 0x02) && + (big_creat_test_param->phy != 0x04)) { return ESP_ERR_INVALID_ARG; } if (big_creat_test_param->framing > BLE_ISO_FRAMING_FRAMED_PDU_UNSEGMENTABLE_MODE) { diff --git a/components/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h b/components/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h index c2afa745c75..d8eeb5b82d6 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_ble_iso_api.h @@ -69,7 +69,7 @@ typedef enum { #define BLE_ISO_WORST_CASE_SCA_LEVEL_20_PPM (0x07) #define BLE_ISO_PACKING_SEQUENTIAL (0x00) -#define BLE_ISO_PACKING_INTERLEAVED (0x00) +#define BLE_ISO_PACKING_INTERLEAVED (0x01) #define BLE_ISO_FRAMING_UNFRAMED_PDU (0x00) #define BLE_ISO_FRAMING_FRAMED_PDU_SEGMENTABLE_MODE (0x01) 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 index 6bdfc1b9dca..ab38419dfaa 100644 --- 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 @@ -28,7 +28,7 @@ static void btc_ble_cte_callback(tBTM_BLE_CTE_EVENT event, { esp_ble_cte_cb_param_t param = {0}; bt_status_t ret; - btc_msg_t msg; + btc_msg_t msg = {0}; msg.sig = BTC_SIG_API_CB; msg.pid = BTC_PID_BLE_CTE; @@ -42,7 +42,7 @@ static void btc_ble_cte_callback(tBTM_BLE_CTE_EVENT event, 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); + param.set_trans_enable_cmpl.status = btc_btm_status_to_esp_status(params->cte_trans_en_cmpl.status); break; case BTA_BLE_CTE_SET_IQ_SAMP_ENABLE_EVT: msg.act = ESP_BLE_CTE_SET_CONNLESS_IQ_SAMPLING_ENABLE_CMPL_EVT; @@ -100,6 +100,7 @@ static void btc_ble_cte_callback(tBTM_BLE_CTE_EVENT event, 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.rx_phy = params->cte_conn_iq_rpt.rx_phy; 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; @@ -163,6 +164,7 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) dst->cte_trans_params.antenna_ids = NULL; } } else { + dst->cte_trans_params.switching_pattern_len = 0; dst->cte_trans_params.antenna_ids = NULL; } break; @@ -177,6 +179,7 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); } } else { + dst->cte_iq_sampling_en.switching_pattern_len = 0; dst->cte_iq_sampling_en.antenna_ids = NULL; } break; @@ -194,6 +197,7 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); } } else { + dst->cte_recv_params.switching_pattern_len = 0; dst->cte_recv_params.antenna_ids = NULL; } break; @@ -208,6 +212,7 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); } } else { + dst->cte_conn_trans_params.switching_pattern_len = 0; dst->cte_conn_trans_params.antenna_ids = NULL; } break; diff --git a/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c b/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c index 6376a3ac1fb..60384a56860 100644 --- a/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,9 +29,10 @@ static void btc_ble_iso_callback(tBTM_BLE_ISO_EVENT event, { esp_ble_iso_cb_param_t param = {0}; bt_status_t ret; - btc_msg_t msg; + btc_msg_t msg = {0}; msg.sig = BTC_SIG_API_CB; msg.pid = BTC_PID_ISO_BLE; + msg.act = ESP_BLE_ISO_EVT_MAX; switch(event) { #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) @@ -208,6 +209,11 @@ static void btc_ble_iso_callback(tBTM_BLE_ISO_EVENT event, break; } + if (msg.act == ESP_BLE_ISO_EVT_MAX) { + BTC_TRACE_ERROR("%s unk ISO evt %d", __func__, event); + return; + } + ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_iso_cb_param_t), NULL, NULL); @@ -341,13 +347,14 @@ void btc_iso_ble_call_handler(btc_msg_t *msg) (uint8_t *)&set_cig_params->cis_params[0]); break; } - case BTC_ISO_ACT_SET_CIG_PARAMS_TEST: + case BTC_ISO_ACT_SET_CIG_PARAMS_TEST: { struct set_cig_params_test_arg *set_cig_params_test = (struct set_cig_params_test_arg *)arg; BTA_DmBleIsoSetCigParamsTest(set_cig_params_test->cig_id, set_cig_params_test->sdu_int_c_to_p, set_cig_params_test->sdu_int_p_to_c, set_cig_params_test->ft_c_to_p, set_cig_params_test->ft_p_to_c, set_cig_params_test->iso_interval, set_cig_params_test->worse_case_SCA, set_cig_params_test->packing, set_cig_params_test->framing, set_cig_params_test->cis_cnt, (uint8_t *)&set_cig_params_test->cis_params_test[0]); break; + } case BTC_ISO_ACT_CREATE_CIS: { struct creat_cis_arg * create_cis = (struct creat_cis_arg *)arg; BTA_DmBleIsoCreateCis(create_cis->cis_count, (uint8_t *)&create_cis->cis_hdls[0]); diff --git a/components/bt/host/bluedroid/hci/ble_hci_iso.c b/components/bt/host/bluedroid/hci/ble_hci_iso.c index 49632b67d3c..af72e52f8cc 100644 --- a/components/bt/host/bluedroid/hci/ble_hci_iso.c +++ b/components/bt/host/bluedroid/hci/ble_hci_iso.c @@ -17,6 +17,22 @@ * under the License. */ +/* + * ============================================================================ + * WARNING + * ============================================================================ + * NOTE: The code in this file is for INTERNAL TEMPORARY TESTING ONLY. + * + * - DO NOT use it in any product code or user application. + * - It is not part of the public/stable API and provides NO compatibility + * guarantees of any kind (behavior, ABI, function signatures, side effects). + * - It may be changed, refactored, or REMOVED at any time without notice. + * + * This file will be deleted in a future release. Any external dependency on + * the symbols defined here is unsupported and will break. + * ============================================================================ + */ + #include #include #include "hci/ble_hci_iso.h"