From 1d5d12788188ea2cd6561acac90689e735ead3a9 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Fri, 26 Jun 2026 09:08:14 +0800 Subject: [PATCH 1/6] feat(ble/bluedroid): add DBAF host support (Core 6.0) (cherry picked from commit e20d3f01977d7bff2692d6af1930fc630faaa402) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/Kconfig.in | 9 +- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 67 ++++++++++ .../api/include/api/esp_gap_ble_api.h | 93 ++++++++++++- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 23 ++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 52 ++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 + .../bluedroid/bta/dm/include/bta_dm_int.h | 40 ++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 21 +++ .../btc/profile/std/gap/btc_gap_ble.c | 126 ++++++++++++++++++ .../btc/profile/std/include/btc_gap_ble.h | 18 +++ .../include/common/bluedroid_user_config.h | 11 ++ .../common/include/common/bt_target.h | 11 ++ .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 50 +++++++ .../bluedroid/stack/btm/include/btm_int.h | 1 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 4 + .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 73 ++++++++++ .../stack/include/stack/btm_ble_api.h | 23 +++- .../bluedroid/stack/include/stack/hcidefs.h | 14 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 21 +++ 19 files changed, 657 insertions(+), 4 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 957abd0aefc..36c7e2d499c 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1517,7 +1517,6 @@ config BT_BLE_FEAT_CHANNEL_SOUNDING default n help Enable BLE channel sounding - config BT_BLE_FEAT_ADV_MONITOR bool "Enable BLE Advertising Monitor (LE Monitor Advertisement)" depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_ADV_MONITOR_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR @@ -1527,6 +1526,14 @@ config BT_BLE_FEAT_ADV_MONITOR Allows the host to add devices to a monitor list and receive reports when the controller detects advertising from those devices (e.g. RSSI threshold). +config BT_BLE_FEAT_DBAF + bool "Enable BLE Decision-Based Advertising Filtering (DBAF)" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_DBAF_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable Decision-Based Advertising Filtering (Bluetooth Core 6.0). + Supports LE Set Decision Data and LE Set Decision Instructions HCI commands. + menuconfig BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 9ac5a99b3bc..c818357b1ff 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1957,6 +1957,72 @@ esp_err_t esp_ble_gap_enable_monitor_adv(bool enable) } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +esp_err_t esp_ble_gap_set_decision_data(const esp_ble_gap_set_decision_data_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (params->data_len > ESP_BLE_GAP_DECISION_DATA_MAX_LEN) { + return ESP_ERR_INVALID_ARG; + } + if (params->data_len > 0 && params->data == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_DECISION_DATA; + arg.set_decision_data.adv_handle = params->adv_handle; + arg.set_decision_data.decision_type_flags = params->decision_type_flags; + arg.set_decision_data.data_len = params->data_len; + arg.set_decision_data.data = (uint8_t *)params->data; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), + btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_decision_instructions(const esp_ble_gap_set_decision_instructions_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (params->num_tests == 0 || params->num_tests > ESP_BLE_GAP_DECISION_MAX_TESTS) { + return ESP_ERR_INVALID_ARG; + } + if (params->test_flags == NULL || params->test_fields == NULL || params->test_params == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_DECISION_INSTRUCTIONS; + arg.set_decision_instructions.num_tests = params->num_tests; + arg.set_decision_instructions.test_flags = (uint8_t *)params->test_flags; + arg.set_decision_instructions.test_fields = (uint8_t *)params->test_fields; + arg.set_decision_instructions.test_params = (uint8_t *)params->test_params; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), + btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) @@ -2608,6 +2674,7 @@ esp_err_t esp_ble_cs_security_enable(uint16_t conn_handle) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + esp_err_t esp_ble_cs_set_default_settings(esp_ble_cs_set_default_settings_params *default_setting_params) { btc_msg_t msg = {0}; diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 3b4e10f9847..2ffa4ad4341 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -273,6 +273,8 @@ typedef enum { ESP_GAP_BLE_CLEAR_MONITOR_ADV_COMPLETE_EVT, /*!< When clear monitor advertiser list complete, the event comes */ ESP_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT, /*!< When read monitor advertiser list size complete, the event comes */ ESP_GAP_BLE_ENABLE_MONITOR_ADV_COMPLETE_EVT, /*!< When enable/disable monitor advertising complete, the event comes */ + ESP_GAP_BLE_SET_DECISION_DATA_COMPLETE_EVT, /*!< When set decision data complete, the event comes */ + ESP_GAP_BLE_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT, /*!< When set decision instructions complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -296,6 +298,7 @@ typedef uint8_t esp_gap_ble_channels[ESP_GAP_BLE_CHANNELS_LEN]; * * - Advertising interval: unit is 0.625ms (range: 20ms to 10240ms) * - Connection interval: unit is 1.25ms (range: 7.5ms to 4000ms) + * - Connection rate interval (Core 6.2 SCI): unit is 125us (range: 375us), see ESP_BLE_GAP_CONN_RATE_* * - Scan interval/window: unit is 0.625ms * - Periodic advertising interval: unit is 1.25ms * - Supervision timeout: unit is 10ms (range: 100ms to 32000ms) @@ -1254,6 +1257,42 @@ typedef struct { } esp_ble_gap_remove_monitor_adv_params_t; #endif // (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +#define ESP_BLE_GAP_DECISION_DATA_MAX_LEN 248 +#define ESP_BLE_GAP_DECISION_MAX_TESTS 8 +#define ESP_BLE_GAP_DECISION_TEST_PARAM_LEN 16 +#define ESP_BLE_GAP_DECISION_TEST_PARAMS_MAX_LEN (ESP_BLE_GAP_DECISION_MAX_TESTS * ESP_BLE_GAP_DECISION_TEST_PARAM_LEN) +#define ESP_BLE_GAP_DECISION_TYPE_FLAG_RESOLVABLE_TAG (1 << 0) + +#define ESP_BLE_GAP_DECISION_SCAN_FILTER_NO_DECISIONS 0x00 +#define ESP_BLE_GAP_DECISION_SCAN_FILTER_ALL_PDUS 0x04 +#define ESP_BLE_GAP_DECISION_SCAN_FILTER_DECISIONS_ONLY 0x0C + +/** + * @brief Parameters for setting decision data for an advertising set (DBAF) + */ +typedef struct { + uint8_t adv_handle; /*!< Advertising set handle */ + uint8_t decision_type_flags; /*!< Decision type flags (e.g. ESP_BLE_GAP_DECISION_TYPE_FLAG_RESOLVABLE_TAG) */ + uint8_t data_len; /*!< Length of decision data, max: ESP_BLE_GAP_DECISION_DATA_MAX_LEN */ + const uint8_t *data; /*!< Pointer to decision data */ +} esp_ble_gap_set_decision_data_params_t; + +/** + * @brief Parameters for setting decision instructions for decision-based advertising filtering (DBAF) + */ +typedef struct { + uint8_t num_tests; /*!< Number of decision tests, max: ESP_BLE_GAP_DECISION_MAX_TESTS */ + const uint8_t *test_flags; /*!< Pointer to test flags array (num_tests octets) */ + const uint8_t *test_fields; /*!< Pointer to test fields array (num_tests octets) */ + const uint8_t *test_params; /*!< Pointer to test parameters (num_tests * ESP_BLE_GAP_DECISION_TEST_PARAM_LEN octets) */ +} esp_ble_gap_set_decision_instructions_params_t; +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + typedef enum { ESP_BLE_NETWORK_PRIVACY_MODE = 0X00, /*!< Network Privacy Mode for peer device (default) */ ESP_BLE_DEVICE_PRIVACY_MODE = 0X01, /*!< Device Privacy Mode for peer device */ @@ -1551,6 +1590,7 @@ typedef enum { /** Reflector role is enabled */ #define ESP_BLE_CS_REFLECTOR_ROLE_ENABLED (1 << 1) + /** * @brief CS set default settings parameters */ @@ -2207,6 +2247,20 @@ typedef union { esp_bt_status_t status; /*!< Indicate enable/disable monitor advertising operation success status */ } enable_monitor_adv; /*!< Event parameter of ESP_GAP_BLE_ENABLE_MONITOR_ADV_COMPLETE_EVT */ #endif +#if (BLE_FEAT_DBAF == TRUE) + /** + * @brief ESP_GAP_BLE_SET_DECISION_DATA_COMPLETE_EVT + */ + struct ble_set_decision_data_cmpl_param { + esp_bt_status_t status; /*!< Indicate set decision data operation success status */ + } set_decision_data; /*!< Event parameter of ESP_GAP_BLE_SET_DECISION_DATA_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT + */ + struct ble_set_decision_instructions_cmpl_param { + esp_bt_status_t status; /*!< Indicate set decision instructions operation success status */ + } set_decision_instructions; /*!< Event parameter of ESP_GAP_BLE_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT */ +#endif // #if (BLE_FEAT_DBAF == TRUE) /** * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ @@ -4068,6 +4122,34 @@ esp_err_t esp_ble_gap_read_monitor_adv_list_size(void); */ esp_err_t esp_ble_gap_enable_monitor_adv(bool enable); #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + +#if (BLE_FEAT_DBAF == TRUE) +/** +* @brief Set decision data for an advertising set (DBAF). +* +* @param[in] params : Pointer to decision data parameters. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_decision_data(const esp_ble_gap_set_decision_data_params_t *params); + +/** +* @brief Set decision instructions for decision-based advertising filtering (DBAF). +* +* @param[in] params : Pointer to decision instructions parameters. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_decision_instructions(const esp_ble_gap_set_decision_instructions_params_t *params); +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) @@ -4425,11 +4507,17 @@ esp_err_t esp_ble_gap_set_default_subrate(esp_ble_default_subrate_param_t *defau */ esp_err_t esp_ble_gap_subrate_request(esp_ble_subrate_req_param_t *subrate_req_params); +/** Host Feature Set bit position: Channel Sounding Host Support (Bluetooth Core, bit 47) */ +#define ESP_BLE_HOST_FEATURE_CS_HOST_SUPPORT 47 + /** * @brief This function is called to set host feature. * - * @param[in] bit_num: the bit position in the FeatureSet. - * @param[in] bit_val: the feature is enabled or disabled + * @param[in] bit_num: the bit position in the FeatureSet (e.g. ESP_BLE_HOST_FEATURE_CS_HOST_SUPPORT). + * @param[in] bit_val: 0x00 to disable, 0x01 to enable Host support for the feature + * + * @note Channel Sounding Host APIs require CS Host Support enabled first: + * esp_ble_gap_set_host_feature(ESP_BLE_HOST_FEATURE_CS_HOST_SUPPORT, 1). * * @return * - ESP_OK : success @@ -4533,6 +4621,7 @@ esp_err_t esp_ble_cs_write_cached_remote_supported_capabilities(esp_ble_cs_write */ esp_err_t esp_ble_cs_security_enable(uint16_t conn_handle); + /** * @brief This function is used to set default CS settings in the local Controller * 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 3f3308c1757..78f7ad41f42 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5984,6 +5984,28 @@ void bta_dm_ble_gap_enable_monitor_adv(tBTA_DM_MSG *p_data) } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +void bta_dm_ble_gap_set_decision_data(tBTA_DM_MSG *p_data) +{ + BTM_BleSetDecisionData(p_data->ble_set_decision_data.adv_handle, + p_data->ble_set_decision_data.decision_type_flags, + p_data->ble_set_decision_data.data_len, + p_data->ble_set_decision_data.data); +} + +void bta_dm_ble_gap_set_decision_instructions(tBTA_DM_MSG *p_data) +{ + BTM_BleSetDecisionInstructions(p_data->ble_set_decision_instructions.num_tests, + p_data->ble_set_decision_instructions.test_flags, + p_data->ble_set_decision_instructions.test_fields, + p_data->ble_set_decision_instructions.test_params); +} +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) void bta_dm_ble_big_create(tBTA_DM_MSG *p_data) @@ -6316,6 +6338,7 @@ void bta_dm_api_cs_procedure_enable(tBTA_DM_MSG *p_data) } #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000 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 d9eba75854f..171a5db2b0a 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2647,6 +2647,7 @@ void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t e #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /******************************************************************************* ** ** Function BTA_VendorInit @@ -3258,6 +3259,57 @@ void BTA_DmBleGapEnableMonitorAdv(UINT8 enable) } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +void BTA_DmBleGapSetDecisionData(UINT8 adv_handle, UINT8 decision_type_flags, + UINT8 data_len, const UINT8 *p_data) +{ + tBTA_DM_API_SET_DECISION_DATA *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_SET_DECISION_DATA *) osi_malloc(sizeof(tBTA_DM_API_SET_DECISION_DATA))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_SET_DECISION_DATA)); + p_msg->hdr.event = BTA_DM_API_SET_DECISION_DATA_EVT; + p_msg->adv_handle = adv_handle; + p_msg->decision_type_flags = decision_type_flags; + p_msg->data_len = data_len; + if (data_len > 0 && p_data != NULL) { + memcpy(p_msg->data, p_data, data_len); + } + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_flags, + const UINT8 *test_fields, const UINT8 *test_params) +{ + tBTA_DM_API_SET_DECISION_INSTRUCTIONS *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_SET_DECISION_INSTRUCTIONS *) osi_malloc(sizeof(tBTA_DM_API_SET_DECISION_INSTRUCTIONS))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_SET_DECISION_INSTRUCTIONS)); + p_msg->hdr.event = BTA_DM_API_SET_DECISION_INSTRUCTIONS_EVT; + p_msg->num_tests = num_tests; + if (num_tests > 0 && test_flags != NULL) { + memcpy(p_msg->test_flags, test_flags, num_tests); + } + if (num_tests > 0 && test_fields != NULL) { + memcpy(p_msg->test_fields, test_fields, num_tests); + } + if (num_tests > 0 && test_params != NULL) { + memcpy(p_msg->test_params, test_params, num_tests * BLE_DECISION_TEST_PARAM_LEN); + } + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) void BTA_DmBleGapIsoBigCreate(tBTA_DM_BLE_BIG_CREATE_PARAMS *p_big_creat_param) 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 5b7461120df..d78523e76de 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -328,6 +328,10 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_api_cs_set_procedure_params, /* BTA_DM_API_CS_SET_PROCEDURE_PARAMS */ bta_dm_api_cs_procedure_enable, /* BTA_DM_API_CS_PROCEDURE_ENABLE */ #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + bta_dm_ble_gap_set_decision_data, /* BTA_DM_API_SET_DECISION_DATA_EVT */ + bta_dm_ble_gap_set_decision_instructions, /* BTA_DM_API_SET_DECISION_INSTRUCTIONS_EVT */ +#endif // #if (BLE_FEAT_DBAF == 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 5a759a7417a..cc77f834a84 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 @@ -322,6 +322,10 @@ enum { BTA_DM_API_CS_SET_PROCEDURE_PARAMS, BTA_DM_API_CS_PROCEDURE_ENABLE, #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + BTA_DM_API_SET_DECISION_DATA_EVT, + BTA_DM_API_SET_DECISION_INSTRUCTIONS_EVT, +#endif // #if (BLE_FEAT_DBAF == TRUE) BTA_DM_MAX_EVT }; @@ -1204,6 +1208,7 @@ typedef struct { UINT8 config_id; UINT8 enable; } tBTA_DM_API_CS_PROC_ENABLE_PARAMS; + #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #endif /* BLE_INCLUDED */ @@ -1377,6 +1382,28 @@ typedef struct { } tBTA_DM_API_ENABLE_MONITOR_ADV; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +typedef struct { + BT_HDR hdr; + UINT8 adv_handle; + UINT8 decision_type_flags; + UINT8 data_len; + UINT8 data[BLE_DECISION_DATA_MAX_LEN]; +} tBTA_DM_API_SET_DECISION_DATA; + +typedef struct { + BT_HDR hdr; + UINT8 num_tests; + UINT8 test_flags[BLE_DECISION_MAX_TESTS]; + UINT8 test_fields[BLE_DECISION_MAX_TESTS]; + UINT8 test_params[BLE_DECISION_TEST_PARAMS_MAX_LEN]; +} tBTA_DM_API_SET_DECISION_INSTRUCTIONS; +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + typedef struct { BT_HDR hdr; tBTA_DM_BLE_EXT_SCAN_PARAMS params; @@ -1813,6 +1840,10 @@ typedef union { tBTA_DM_API_READ_MONITOR_ADV_LIST_SIZE ble_read_monitor_adv_list_size; tBTA_DM_API_ENABLE_MONITOR_ADV ble_enable_monitor_adv; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + tBTA_DM_API_SET_DECISION_DATA ble_set_decision_data; + tBTA_DM_API_SET_DECISION_INSTRUCTIONS ble_set_decision_instructions; +#endif // #if (BLE_FEAT_DBAF == TRUE) #if (BLE_42_DTM_TEST_EN == TRUE) tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; @@ -2492,6 +2523,15 @@ extern void bta_dm_ble_gap_read_monitor_adv_list_size(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_enable_monitor_adv(tBTA_DM_MSG *p_data); #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +extern void bta_dm_ble_gap_set_decision_data(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_set_decision_instructions(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) extern void bta_dm_ble_big_create(tBTA_DM_MSG *p_data); 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 370ccb79a4a..fa19e68c505 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1605,6 +1605,15 @@ typedef struct { #define BTA_DM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT BTM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +#define BTA_DM_BLE_5_GAP_SET_DECISION_DATA_COMPLETE_EVT BTM_BLE_5_GAP_SET_DECISION_DATA_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT BTM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + #if (BT_BLE_FEAT_PAWR_EN == TRUE) #define BTA_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT BTM_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT #define BTA_BLE_GAP_SET_PERIODIC_ADV_RESPONSE_DATA_EVT BTM_BLE_GAP_SET_PERIODIC_ADV_RESPONSE_DATA_EVT @@ -3059,6 +3068,18 @@ extern void BTA_DmBleGapReadMonitorAdvListSize(void); extern void BTA_DmBleGapEnableMonitorAdv(UINT8 enable); #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +extern void BTA_DmBleGapSetDecisionData(UINT8 adv_handle, UINT8 decision_type_flags, + UINT8 data_len, const UINT8 *p_data); +extern void BTA_DmBleGapSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_flags, + const UINT8 *test_fields, UINT8 test_params_len, + const UINT8 *test_params); +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) extern void BTA_DmBleGapIsoBigCreate(tBTA_DM_BLE_BIG_CREATE_PARAMS *p_big_creat_param); diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 568818c3942..9e7a1f2cdbb 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1283,6 +1283,18 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, break; } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + case BTA_DM_BLE_5_GAP_SET_DECISION_DATA_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_SET_DECISION_DATA_COMPLETE_EVT; + param.set_decision_data.status = btc_btm_status_to_esp_status(params->status); + break; + } + case BTA_DM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT; + param.set_decision_instructions.status = btc_btm_status_to_esp_status(params->status); + break; + } +#endif // #if (BLE_FEAT_DBAF == TRUE) #if (BLE_50_EXTEND_ADV_EN == TRUE) case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT: { param.adv_terminate.status = params->adv_term.status; @@ -2477,6 +2489,84 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) break; } #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + case BTC_GAP_BLE_SET_DECISION_DATA: { + btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; + btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + + dst->set_decision_data.data = NULL; + if (src->set_decision_data.data_len > 0 && src->set_decision_data.data) { + dst->set_decision_data.data = osi_malloc(src->set_decision_data.data_len); + if (dst->set_decision_data.data) { + memcpy(dst->set_decision_data.data, src->set_decision_data.data, + src->set_decision_data.data_len); + } else { + BTC_TRACE_WARNING("%s no mem, decision data drop %u", __func__, src->set_decision_data.data_len); + dst->set_decision_data.data_len = 0; + } + } + break; + } + case BTC_GAP_BLE_SET_DECISION_INSTRUCTIONS: { + btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; + btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + bool oom = false; + + dst->set_decision_instructions.test_flags = NULL; + dst->set_decision_instructions.test_fields = NULL; + dst->set_decision_instructions.test_params = NULL; + if (src->set_decision_instructions.num_tests > ESP_BLE_GAP_DECISION_MAX_TESTS) { + BTC_TRACE_WARNING("%s invalid num_tests %u", __func__, + src->set_decision_instructions.num_tests); + oom = true; + } + if (!oom && src->set_decision_instructions.num_tests > 0) { + if (src->set_decision_instructions.test_flags) { + dst->set_decision_instructions.test_flags = osi_malloc(src->set_decision_instructions.num_tests); + if (dst->set_decision_instructions.test_flags) { + memcpy(dst->set_decision_instructions.test_flags, src->set_decision_instructions.test_flags, + src->set_decision_instructions.num_tests); + } else { + oom = true; + } + } + if (!oom && src->set_decision_instructions.test_fields) { + dst->set_decision_instructions.test_fields = osi_malloc(src->set_decision_instructions.num_tests); + if (dst->set_decision_instructions.test_fields) { + memcpy(dst->set_decision_instructions.test_fields, src->set_decision_instructions.test_fields, + src->set_decision_instructions.num_tests); + } else { + oom = true; + } + } + } + if (!oom && src->set_decision_instructions.num_tests > 0 && + src->set_decision_instructions.test_params) { + size_t test_params_len = (size_t)src->set_decision_instructions.num_tests * + ESP_BLE_GAP_DECISION_TEST_PARAM_LEN; + dst->set_decision_instructions.test_params = osi_malloc(test_params_len); + if (dst->set_decision_instructions.test_params) { + memcpy(dst->set_decision_instructions.test_params, src->set_decision_instructions.test_params, + test_params_len); + } else { + oom = true; + } + } + if (oom) { + BTC_TRACE_WARNING("%s no mem, decision instructions drop", __func__); + if (dst->set_decision_instructions.test_flags) { + osi_free(dst->set_decision_instructions.test_flags); + dst->set_decision_instructions.test_flags = NULL; + } + if (dst->set_decision_instructions.test_fields) { + osi_free(dst->set_decision_instructions.test_fields); + dst->set_decision_instructions.test_fields = NULL; + } + dst->set_decision_instructions.num_tests = 0; + } + break; + } +#endif // #if (BLE_FEAT_DBAF == TRUE) default: BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act); break; @@ -2759,6 +2849,28 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg) break; } #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + case BTC_GAP_BLE_SET_DECISION_DATA: { + uint8_t *data = ((btc_ble_5_gap_args_t *)msg->arg)->set_decision_data.data; + if (data) { + osi_free(data); + } + break; + } + case BTC_GAP_BLE_SET_DECISION_INSTRUCTIONS: { + btc_ble_5_gap_args_t *args = (btc_ble_5_gap_args_t *)msg->arg; + if (args->set_decision_instructions.test_flags) { + osi_free(args->set_decision_instructions.test_flags); + } + if (args->set_decision_instructions.test_fields) { + osi_free(args->set_decision_instructions.test_fields); + } + if (args->set_decision_instructions.test_params) { + osi_free(args->set_decision_instructions.test_params); + } + break; + } +#endif // #if (BLE_FEAT_DBAF == TRUE) default: BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act); break; @@ -3419,6 +3531,20 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapEnableMonitorAdv(arg_5->enable_monitor_adv.enable); break; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + case BTC_GAP_BLE_SET_DECISION_DATA: + BTA_DmBleGapSetDecisionData(arg_5->set_decision_data.adv_handle, + arg_5->set_decision_data.decision_type_flags, + arg_5->set_decision_data.data_len, + arg_5->set_decision_data.data); + break; + case BTC_GAP_BLE_SET_DECISION_INSTRUCTIONS: + BTA_DmBleGapSetDecisionInstructions(arg_5->set_decision_instructions.num_tests, + arg_5->set_decision_instructions.test_flags, + arg_5->set_decision_instructions.test_fields, + arg_5->set_decision_instructions.test_params); + break; +#endif // #if (BLE_FEAT_DBAF == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: BTA_DmBleGapSetPASubevtData(arg_5->per_adv_subevent_data_params.adv_handle, arg_5->per_adv_subevent_data_params.num_subevents_with_data, (uint8_t *)(arg_5->per_adv_subevent_data_params.subevent_params)); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 306adb09a14..99e41df2d67 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -147,6 +147,10 @@ typedef enum { BTC_GAP_BLE_READ_MONITOR_ADV_LIST_SIZE, BTC_GAP_BLE_ENABLE_MONITOR_ADV, #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + BTC_GAP_BLE_SET_DECISION_DATA, + BTC_GAP_BLE_SET_DECISION_INSTRUCTIONS, +#endif // #if (BLE_FEAT_DBAF == TRUE) BTC_GAP_BLE_READ_CHANNEL_MAP, #if (BT_BLE_FEAT_PAWR_EN == TRUE) BTC_GAP_BLE_SET_PA_SUBEVT_DATA, @@ -588,6 +592,20 @@ typedef union { uint8_t enable; } enable_monitor_adv; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) + struct set_decision_data_args { + uint8_t adv_handle; + uint8_t decision_type_flags; + uint8_t data_len; + uint8_t *data; + } set_decision_data; + struct set_decision_instructions_args { + uint8_t num_tests; + uint8_t *test_flags; + uint8_t *test_fields; + uint8_t *test_params; + } set_decision_instructions; +#endif // #if (BLE_FEAT_DBAF == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) // BTC_GAP_BLE_SET_PA_SUBEVT_DATA struct per_adv_subevent_data_params_args { 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 c2aefabbe48..6c9dd987a47 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 @@ -343,12 +343,23 @@ #define UC_BT_BLE_FEAT_CHANNEL_SOUNDING FALSE #endif + #ifdef CONFIG_BT_BLE_FEAT_ADV_MONITOR #define UC_BT_BLE_FEAT_ADV_MONITOR CONFIG_BT_BLE_FEAT_ADV_MONITOR #else #define UC_BT_BLE_FEAT_ADV_MONITOR FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_DBAF +#define UC_BT_BLE_FEAT_DBAF CONFIG_BT_BLE_FEAT_DBAF +#else +#define UC_BT_BLE_FEAT_DBAF FALSE +#endif + + + + + #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN #define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN #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 def71e9c753..7e015e8a2f5 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -405,6 +405,7 @@ #define BT_BLE_FEAT_CHANNEL_SOUNDING FALSE #endif + /* LE Monitor Advertisement (Bluetooth Core 6.0) */ #if (BLE_50_FEATURE_SUPPORT == TRUE) && (defined UC_BT_BLE_FEAT_ADV_MONITOR) && (UC_BT_BLE_FEAT_ADV_MONITOR == TRUE) #define BLE_FEAT_ADV_MONITOR TRUE @@ -412,6 +413,16 @@ #define BLE_FEAT_ADV_MONITOR FALSE #endif +#if (BLE_50_FEATURE_SUPPORT == TRUE) && (UC_BT_BLE_FEAT_DBAF == TRUE) +#define BLE_FEAT_DBAF TRUE +#else +#define BLE_FEAT_DBAF FALSE +#endif + + + + + #if (UC_BT_BLE_VENDOR_HCI_EN == TRUE) #define BLE_VENDOR_HCI_EN TRUE #else diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 8be15ba602d..6d36774ae33 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -17,6 +17,15 @@ tBTM_BLE_EXTENDED_CB extend_adv_cb; tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +static UINT8 btm_ble_local_supp_le_features[BLE_LL_EXT_FEAT_DATA_LEN]; +static UINT8 btm_ble_remote_supp_le_features[BLE_LL_EXT_FEAT_DATA_LEN]; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) + +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +static tBTM_BLE_MIN_CONN_INTERVAL_GROUP btm_ble_min_conn_interval_groups[BTM_BLE_MAX_CONN_INTERVAL_GROUPS]; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + #define INVALID_VALUE_8BIT 0XFF #define INVALID_VALUE_16BIT 0XFFFF #define INVALID_VALUE_32BIT 0XFFFFFFFF @@ -1411,6 +1420,47 @@ tBTM_STATUS BTM_BleEnableMonitorAdv(UINT8 enable) } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +tBTM_STATUS BTM_BleSetDecisionData(UINT8 adv_handle, UINT8 decision_type_flags, + UINT8 data_len, const UINT8 *p_data) +{ + tHCI_STATUS err; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_decision_data(adv_handle, decision_type_flags, data_len, p_data)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE SetDecisionData: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_DECISION_DATA_COMPLETE_EVT, &cb_params); + return status; +} + +tBTM_STATUS BTM_BleSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_flags, + const UINT8 *test_fields, const UINT8 *test_params) +{ + tHCI_STATUS err; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_decision_instructions(num_tests, test_flags, test_fields, + test_params)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE SetDecisionInstructions: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT, &cb_params); + return status; +} +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + #if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params) { diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index f0a275f23b6..a6939e41fe2 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1201,6 +1201,7 @@ void btm_read_remote_trans_pwr_level_cmpl(UINT8 status); void btm_subrate_req_cmd_status(UINT8 status); #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) void btm_ble_cs_read_local_supp_caps_cmpl_evt(UINT8 *p); void btm_ble_cs_read_remote_supp_caps_cmd_status(UINT8 status); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index d9e34dcd10d..5a16e31adbf 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -2660,6 +2660,8 @@ static void btu_ble_monitor_adv_report_evt(UINT8 *p) } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + + #if (BLE_50_EXTEND_SYNC_EN == TRUE) static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt) { @@ -3334,6 +3336,8 @@ static void btu_ble_subrate_change_evt(UINT8 *p) } #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + + #if (BT_BLE_FEAT_PAWR_EN == TRUE) static void btu_ble_pa_subevt_data_request_evt(UINT8 *p) { diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 8c5494b7f04..629ea14042e 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3054,6 +3054,79 @@ UINT8 btsnd_hcic_ble_enable_monitor_adv(UINT8 enable) } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +UINT8 btsnd_hcic_ble_set_decision_data(UINT8 adv_handle, UINT8 decision_type_flags, + UINT8 data_len, const UINT8 *p_data) +{ + BT_HDR *p; + UINT8 *pp; + UINT8 param_len; + + if (data_len > BLE_DECISION_DATA_MAX_LEN) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + if (data_len > 0 && p_data == NULL) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + param_len = HCIC_PARAM_SIZE_SET_DECISION_DATA_HDR + data_len; + if (param_len > HCIC_PARAM_SIZE_SET_DECISION_DATA_MAX) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + HCIC_BLE_CMD_CREATED_U8(p, pp, param_len); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_DECISION_DATA); + UINT8_TO_STREAM(pp, param_len); + UINT8_TO_STREAM(pp, adv_handle); + UINT8_TO_STREAM(pp, decision_type_flags); + UINT8_TO_STREAM(pp, data_len); + if (data_len > 0) { + ARRAY_TO_STREAM(pp, p_data, data_len); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_decision_instructions(UINT8 num_tests, const UINT8 *test_flags, + const UINT8 *test_fields, const UINT8 *test_params) +{ + BT_HDR *p; + UINT8 *pp; + UINT8 param_len; + + if (num_tests == 0 || num_tests > BLE_DECISION_MAX_TESTS) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + if (test_flags == NULL || test_fields == NULL || test_params == NULL) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + param_len = HCIC_PARAM_SIZE_SET_DECISION_INSTRUCTIONS(num_tests); + if (param_len > HCIC_PARAM_SIZE_SET_DECISION_INSTRUCTIONS_MAX) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + HCIC_BLE_CMD_CREATED_U8(p, pp, param_len); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_DECISION_INSTRUCTIONS); + UINT8_TO_STREAM(pp, param_len); + UINT8_TO_STREAM(pp, num_tests); + for (UINT8 i = 0; i < num_tests; i++) { + UINT8_TO_STREAM(pp, test_flags[i]); + UINT8_TO_STREAM(pp, test_fields[i]); + ARRAY_TO_STREAM(pp, test_params + i * BLE_DECISION_TEST_PARAM_LEN, + BLE_DECISION_TEST_PARAM_LEN); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + #if (BT_BLE_FEAT_PAWR_EN == TRUE) UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_subevents_with_data, ble_subevent_params *subevent_params) { 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 6e153c66a3c..e0ffbe8890f 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 @@ -990,7 +990,11 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT 74 #define BTM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT 75 #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) -#define BTM_BLE_5_GAP_UNKNOWN_EVT 76 +#if (BLE_FEAT_DBAF == TRUE) +#define BTM_BLE_5_GAP_SET_DECISION_DATA_COMPLETE_EVT 79 +#define BTM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT 80 +#endif // #if (BLE_FEAT_DBAF == TRUE) +#define BTM_BLE_5_GAP_UNKNOWN_EVT 91 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #if (BLE_FEAT_ISO_EN == TRUE) @@ -1240,6 +1244,10 @@ typedef struct { } tBTM_BLE_MONITOR_ADV_LIST_SIZE; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + + + + typedef struct { UINT16 sync_handle; UINT8 tx_power; @@ -1463,6 +1471,7 @@ typedef struct { UINT16 conn_handle; } tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT; + typedef struct { UINT8 status; UINT16 conn_handle; @@ -3109,6 +3118,18 @@ tBTM_STATUS BTM_BleClearMonitorAdvList(void); tBTM_STATUS BTM_BleReadMonitorAdvListSize(void); tBTM_STATUS BTM_BleEnableMonitorAdv(UINT8 enable); #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + +#if (BLE_FEAT_DBAF == TRUE) +tBTM_STATUS BTM_BleSetDecisionData(UINT8 adv_handle, UINT8 decision_type_flags, + UINT8 data_len, const UINT8 *p_data); +tBTM_STATUS BTM_BleSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_flags, + const UINT8 *test_fields, UINT8 test_params_len, + const UINT8 *test_params); +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_50_DTM_TEST_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 43eb352bb11..ff39bb22ae4 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -439,6 +439,7 @@ #define HCI_BLE_ENABLE_MONITOR_ADV (0x009C | HCI_GRP_BLE_CMDS) #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) #define HCI_BLE_ENH_READ_TRANS_POWER_LEVEL (0x0076 | HCI_GRP_BLE_CMDS) #define HCI_BLE_READ_REMOTE_TRANS_POWER_LEVEL (0x0077 | HCI_GRP_BLE_CMDS) @@ -464,6 +465,12 @@ #define HCI_BLE_SET_PERIOD_ADV_PARAMS_V2 (0x0086 | HCI_GRP_BLE_CMDS) #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + +#if (BLE_FEAT_DBAF == TRUE) +#define HCI_BLE_SET_DECISION_DATA (0x0080 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_DECISION_INSTRUCTIONS (0x0081 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_DBAF == TRUE) + #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #define HCI_BLE_CS_READ_LOCAL_SUPP_CAPS (0x0089 | HCI_GRP_BLE_CMDS) #define HCI_BLE_CS_READ_REMOTE_SUPP_CAPS (0x008A | HCI_GRP_BLE_CMDS) @@ -479,6 +486,9 @@ #define HCI_BLE_CS_SET_PROCEDURE_ENABLE (0x0094 | HCI_GRP_BLE_CMDS) #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + + + // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -970,10 +980,14 @@ #define HCI_BLE_PA_RESPONSE_REPORT_EVT 0x28 #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + #if (BLE_FEAT_ADV_MONITOR == TRUE) #define HCI_BLE_MONITOR_ADV_REPORT_EVT 0x34 #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) + + + #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #define HCI_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT 0x2C #define HCI_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT 0x2D diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 897d0f636e7..3dfc7bc9a1d 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -825,6 +825,26 @@ BOOLEAN btsnd_hcic_ble_read_monitor_adv_list_size(void); UINT8 btsnd_hcic_ble_enable_monitor_adv(UINT8 enable); #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_DBAF == TRUE) +#define HCIC_PARAM_SIZE_SET_DECISION_DATA_HDR 3 +#define HCIC_PARAM_SIZE_SET_DECISION_DATA_MAX 251 +#define HCIC_PARAM_SIZE_SET_DECISION_INSTRUCTIONS_HDR 1 +#define HCIC_PARAM_SIZE_SET_DECISION_INSTRUCTIONS_MAX 251 +#define BLE_DECISION_DATA_MAX_LEN 248 +#define BLE_DECISION_MAX_TESTS 8 +#define BLE_DECISION_TEST_PARAMS_MAX_LEN 229 + +UINT8 btsnd_hcic_ble_set_decision_data(UINT8 adv_handle, UINT8 decision_type_flags, + UINT8 data_len, const UINT8 *p_data); +UINT8 btsnd_hcic_ble_set_decision_instructions(UINT8 num_tests, const UINT8 *test_flags, + const UINT8 *test_fields, UINT8 test_params_len, + const UINT8 *test_params); +#endif // #if (BLE_FEAT_DBAF == TRUE) + + + + + /* ULP HCI command */ BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask); @@ -1355,4 +1375,5 @@ UINT8 btsnd_hcic_ble_cs_set_procedure_params(UINT16 conn_handle, UINT8 config_id UINT8 btsnd_hcic_ble_cs_procedure_enable(UINT16 conn_handle, UINT8 config_id, UINT8 enable); #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #endif From 03f7c044060b1231eaa6fcdf9382bcff1a4020b1 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Fri, 26 Jun 2026 09:08:15 +0800 Subject: [PATCH 2/6] feat(ble/bluedroid): add Frame Space Update host support (Core 6.0) Co-authored-by: Cursor (cherry picked from commit 5372ce03a3ce958554ab501e5fef4bbd68e7b9ce) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/Kconfig.in | 7 ++ .../bt/host/bluedroid/api/esp_gap_ble_api.c | 37 +++++++ .../api/include/api/esp_gap_ble_api.h | 61 ++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 10 ++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 20 ++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 + .../bluedroid/bta/dm/include/bta_dm_int.h | 19 ++++ .../host/bluedroid/bta/include/bta/bta_api.h | 10 +- .../btc/profile/std/gap/btc_gap_ble.c | 21 ++++ .../btc/profile/std/include/btc_gap_ble.h | 12 +++ .../include/common/bluedroid_user_config.h | 7 ++ .../common/include/common/bt_target.h | 5 + .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 49 ++++++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 3 + .../bluedroid/stack/btm/include/btm_int.h | 3 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 98 +++++++++++++++++++ .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 21 ++++ .../stack/include/stack/btm_ble_api.h | 23 ++++- .../bluedroid/stack/include/stack/hcidefs.h | 6 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 13 ++- 20 files changed, 421 insertions(+), 7 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 36c7e2d499c..7bd489c6ff0 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1534,6 +1534,13 @@ config BT_BLE_FEAT_DBAF Enable Decision-Based Advertising Filtering (Bluetooth Core 6.0). Supports LE Set Decision Data and LE Set Decision Instructions HCI commands. +config BT_BLE_FEAT_FRAME_SPACE_UPDATE + bool "Enable BLE Frame Space Update" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_FRAME_SPACE_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable Frame Space Update feature (Bluetooth Core 6.0). + menuconfig BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index c818357b1ff..2f45ac285df 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2019,6 +2019,43 @@ esp_err_t esp_ble_gap_set_decision_instructions(const esp_ble_gap_set_decision_i } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +esp_err_t esp_ble_gap_frame_space_update(const esp_ble_gap_frame_space_update_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (params->frame_space_min > ESP_BLE_GAP_FRAME_SPACE_MAX_US || + params->frame_space_max > ESP_BLE_GAP_FRAME_SPACE_MAX_US || + params->frame_space_min > params->frame_space_max) { + return ESP_ERR_INVALID_ARG; + } + if ((params->phys & ~ESP_BLE_GAP_FRAME_SPACE_PHY_MASK) != 0 || params->phys == 0) { + return ESP_ERR_INVALID_ARG; + } + if ((params->spacing_types & ~ESP_BLE_GAP_FRAME_SPACE_SPACING_MASK) != 0 || + params->spacing_types == 0) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_FRAME_SPACE_UPDATE; + arg.frame_space_update.conn_handle = params->conn_handle; + arg.frame_space_update.frame_space_min = params->frame_space_min; + arg.frame_space_update.frame_space_max = params->frame_space_max; + arg.frame_space_update.phys = params->phys; + arg.frame_space_update.spacing_types = params->spacing_types; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 2ffa4ad4341..1ac0c703b9c 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -275,6 +275,7 @@ typedef enum { ESP_GAP_BLE_ENABLE_MONITOR_ADV_COMPLETE_EVT, /*!< When enable/disable monitor advertising complete, the event comes */ ESP_GAP_BLE_SET_DECISION_DATA_COMPLETE_EVT, /*!< When set decision data complete, the event comes */ ESP_GAP_BLE_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT, /*!< When set decision instructions complete, the event comes */ + ESP_GAP_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT, /*!< When frame space update complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1289,6 +1290,41 @@ typedef struct { } esp_ble_gap_set_decision_instructions_params_t; #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#define ESP_BLE_GAP_FRAME_SPACE_MAX_US 10000 +#define ESP_BLE_GAP_FRAME_SPACE_PHY_1M_MASK (1 << 0) +#define ESP_BLE_GAP_FRAME_SPACE_PHY_2M_MASK (1 << 1) +#define ESP_BLE_GAP_FRAME_SPACE_PHY_CODED_MASK (1 << 2) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_ACL_CP_MASK (1 << 0) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_ACL_PC_MASK (1 << 1) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_MCES_MASK (1 << 2) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_CIS_MASK (1 << 3) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_MSS_CIS_MASK (1 << 4) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_ACL_IFS_MASK \ + (ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_ACL_CP_MASK | ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_ACL_PC_MASK) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_ACL_MASK \ + (ESP_BLE_GAP_FRAME_SPACE_SPACING_ACL_IFS_MASK | ESP_BLE_GAP_FRAME_SPACE_SPACING_MCES_MASK) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_CIS_MASK \ + (ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_CIS_MASK | ESP_BLE_GAP_FRAME_SPACE_SPACING_MSS_CIS_MASK) +#define ESP_BLE_GAP_FRAME_SPACE_PHY_MASK \ + (ESP_BLE_GAP_FRAME_SPACE_PHY_1M_MASK | ESP_BLE_GAP_FRAME_SPACE_PHY_2M_MASK | \ + ESP_BLE_GAP_FRAME_SPACE_PHY_CODED_MASK) +#define ESP_BLE_GAP_FRAME_SPACE_SPACING_MASK \ + (ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_ACL_CP_MASK | ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_ACL_PC_MASK | \ + ESP_BLE_GAP_FRAME_SPACE_SPACING_MCES_MASK | ESP_BLE_GAP_FRAME_SPACE_SPACING_IFS_CIS_MASK | \ + ESP_BLE_GAP_FRAME_SPACE_SPACING_MSS_CIS_MASK) + +/** + * @brief Parameters for requesting a Frame Space Update on a connection + */ +typedef struct { + uint16_t conn_handle; /*!< Connection handle */ + uint16_t frame_space_min; /*!< Minimum frame space in microseconds, max: ESP_BLE_GAP_FRAME_SPACE_MAX_US */ + uint16_t frame_space_max; /*!< Maximum frame space in microseconds, max: ESP_BLE_GAP_FRAME_SPACE_MAX_US */ + uint8_t phys; /*!< PHY mask (ESP_BLE_GAP_FRAME_SPACE_PHY_*_MASK) */ + uint16_t spacing_types; /*!< Spacing types mask (ESP_BLE_GAP_FRAME_SPACE_SPACING_*_MASK) */ +} esp_ble_gap_frame_space_update_params_t; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) @@ -2261,6 +2297,19 @@ typedef union { esp_bt_status_t status; /*!< Indicate set decision instructions operation success status */ } set_decision_instructions; /*!< Event parameter of ESP_GAP_BLE_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT */ #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + /** + * @brief ESP_GAP_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT + */ + struct ble_frame_space_update_cmpl_param { + esp_bt_status_t status; /*!< Indicate frame space update operation success status */ + uint16_t conn_handle; /*!< Connection handle */ + uint8_t initiator; /*!< 0x00: Local Host initiated, 0x01: Local Controller initiated, 0x02: Peer initiated */ + uint16_t frame_space; /*!< Updated frame space in microseconds */ + uint8_t phys; /*!< PHY mask updated */ + uint16_t spacing_types; /*!< Spacing types mask updated */ + } frame_space_update; /*!< Event parameter of ESP_GAP_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT */ +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) /** * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ @@ -4147,6 +4196,18 @@ esp_err_t esp_ble_gap_set_decision_data(const esp_ble_gap_set_decision_data_para esp_err_t esp_ble_gap_set_decision_instructions(const esp_ble_gap_set_decision_instructions_params_t *params); #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +/** +* @brief Request a Frame Space Update on a connection. +* +* @param[in] params : Pointer to frame space update parameters. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_frame_space_update(const esp_ble_gap_frame_space_update_params_t *params); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) 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 78f7ad41f42..1c6492de1ab 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6002,6 +6002,16 @@ void bta_dm_ble_gap_set_decision_instructions(tBTA_DM_MSG *p_data) } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +void bta_dm_ble_gap_frame_space_update(tBTA_DM_MSG *p_data) +{ + BTM_BleFrameSpaceUpdate(p_data->ble_frame_space_update.conn_handle, + p_data->ble_frame_space_update.frame_space_min, + p_data->ble_frame_space_update.frame_space_max, + p_data->ble_frame_space_update.phys, + p_data->ble_frame_space_update.spacing_types); +} +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == 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 171a5db2b0a..c7d234688cc 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3305,6 +3305,26 @@ void BTA_DmBleGapSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_flag } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +void BTA_DmBleGapFrameSpaceUpdate(UINT16 conn_handle, UINT16 frame_space_min, + UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types) +{ + tBTA_DM_API_FRAME_SPACE_UPDATE *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_FRAME_SPACE_UPDATE *) osi_malloc(sizeof(tBTA_DM_API_FRAME_SPACE_UPDATE))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_FRAME_SPACE_UPDATE)); + p_msg->hdr.event = BTA_DM_API_FRAME_SPACE_UPDATE_EVT; + p_msg->conn_handle = conn_handle; + p_msg->frame_space_min = frame_space_min; + p_msg->frame_space_max = frame_space_max; + p_msg->phys = phys; + p_msg->spacing_types = spacing_types; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) 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 d78523e76de..627dfda344e 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -332,6 +332,9 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_set_decision_data, /* BTA_DM_API_SET_DECISION_DATA_EVT */ bta_dm_ble_gap_set_decision_instructions, /* BTA_DM_API_SET_DECISION_INSTRUCTIONS_EVT */ #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + bta_dm_ble_gap_frame_space_update, /* BTA_DM_API_FRAME_SPACE_UPDATE_EVT */ +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == 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 cc77f834a84..5d87002563e 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 @@ -326,6 +326,9 @@ enum { BTA_DM_API_SET_DECISION_DATA_EVT, BTA_DM_API_SET_DECISION_INSTRUCTIONS_EVT, #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + BTA_DM_API_FRAME_SPACE_UPDATE_EVT, +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) BTA_DM_MAX_EVT }; @@ -1400,6 +1403,16 @@ typedef struct { } tBTA_DM_API_SET_DECISION_INSTRUCTIONS; #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT16 frame_space_min; + UINT16 frame_space_max; + UINT8 phys; + UINT16 spacing_types; +} tBTA_DM_API_FRAME_SPACE_UPDATE; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) @@ -1844,6 +1857,9 @@ typedef union { tBTA_DM_API_SET_DECISION_DATA ble_set_decision_data; tBTA_DM_API_SET_DECISION_INSTRUCTIONS ble_set_decision_instructions; #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + tBTA_DM_API_FRAME_SPACE_UPDATE ble_frame_space_update; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BLE_42_DTM_TEST_EN == TRUE) tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; @@ -2528,6 +2544,9 @@ extern void bta_dm_ble_gap_set_decision_data(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_decision_instructions(tBTA_DM_MSG *p_data); #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +extern void bta_dm_ble_gap_frame_space_update(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) 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 fa19e68c505..b1903c7d45c 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1610,6 +1610,9 @@ typedef struct { #define BTA_DM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT BTM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#define BTA_DM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT BTM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) @@ -3072,10 +3075,13 @@ extern void BTA_DmBleGapEnableMonitorAdv(UINT8 enable); extern void BTA_DmBleGapSetDecisionData(UINT8 adv_handle, UINT8 decision_type_flags, UINT8 data_len, const UINT8 *p_data); extern void BTA_DmBleGapSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_flags, - const UINT8 *test_fields, UINT8 test_params_len, - const UINT8 *test_params); + const UINT8 *test_fields, const UINT8 *test_params); #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +extern void BTA_DmBleGapFrameSpaceUpdate(UINT16 conn_handle, UINT16 frame_space_min, + UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 9e7a1f2cdbb..b4e2a342540 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1295,6 +1295,18 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, break; } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + case BTA_DM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT; + param.frame_space_update.status = btc_btm_status_to_esp_status(params->frame_space_update.status); + param.frame_space_update.conn_handle = params->frame_space_update.conn_handle; + param.frame_space_update.initiator = params->frame_space_update.initiator; + param.frame_space_update.frame_space = params->frame_space_update.frame_space; + param.frame_space_update.phys = params->frame_space_update.phys; + param.frame_space_update.spacing_types = params->frame_space_update.spacing_types; + break; + } +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BLE_50_EXTEND_ADV_EN == TRUE) case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT: { param.adv_terminate.status = params->adv_term.status; @@ -3545,6 +3557,15 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) arg_5->set_decision_instructions.test_params); break; #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + case BTC_GAP_BLE_FRAME_SPACE_UPDATE: + BTA_DmBleGapFrameSpaceUpdate(arg_5->frame_space_update.conn_handle, + arg_5->frame_space_update.frame_space_min, + arg_5->frame_space_update.frame_space_max, + arg_5->frame_space_update.phys, + arg_5->frame_space_update.spacing_types); + break; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: BTA_DmBleGapSetPASubevtData(arg_5->per_adv_subevent_data_params.adv_handle, arg_5->per_adv_subevent_data_params.num_subevents_with_data, (uint8_t *)(arg_5->per_adv_subevent_data_params.subevent_params)); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 99e41df2d67..0ecb1834e75 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -151,6 +151,9 @@ typedef enum { BTC_GAP_BLE_SET_DECISION_DATA, BTC_GAP_BLE_SET_DECISION_INSTRUCTIONS, #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + BTC_GAP_BLE_FRAME_SPACE_UPDATE, +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) BTC_GAP_BLE_READ_CHANNEL_MAP, #if (BT_BLE_FEAT_PAWR_EN == TRUE) BTC_GAP_BLE_SET_PA_SUBEVT_DATA, @@ -606,6 +609,15 @@ typedef union { uint8_t *test_params; } set_decision_instructions; #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + struct frame_space_update_args { + uint16_t conn_handle; + uint16_t frame_space_min; + uint16_t frame_space_max; + uint8_t phys; + uint16_t spacing_types; + } frame_space_update; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) // BTC_GAP_BLE_SET_PA_SUBEVT_DATA struct per_adv_subevent_data_params_args { 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 6c9dd987a47..c669d1339d7 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 @@ -350,6 +350,13 @@ #define UC_BT_BLE_FEAT_ADV_MONITOR FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE +#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE +#else +#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE FALSE +#endif + + #ifdef CONFIG_BT_BLE_FEAT_DBAF #define UC_BT_BLE_FEAT_DBAF CONFIG_BT_BLE_FEAT_DBAF #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 7e015e8a2f5..01315494dc6 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -419,6 +419,11 @@ #define BLE_FEAT_DBAF FALSE #endif +#if (BLE_50_FEATURE_SUPPORT == TRUE) && (UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#define BLE_FEAT_FRAME_SPACE_UPDATE TRUE +#else +#define BLE_FEAT_FRAME_SPACE_UPDATE FALSE +#endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 6d36774ae33..16487f71f48 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1457,6 +1457,55 @@ tBTM_STATUS BTM_BleSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_fl } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +tBTM_STATUS BTM_BleFrameSpaceUpdate(UINT16 conn_handle, UINT16 frame_space_min, + UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types) +{ + tHCI_STATUS err; + + err = btsnd_hcic_ble_frame_space_update(conn_handle, frame_space_min, frame_space_max, + phys, spacing_types); + if (err != HCI_SUCCESS) { + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + cb_params.frame_space_update.status = BTM_HCI_ERROR | err; + cb_params.frame_space_update.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT, &cb_params); + return BTM_NO_RESOURCES; + } + return BTM_CMD_STARTED; +} + +void btm_frame_space_update_cmd_status(UINT8 status, UINT16 conn_handle) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (status == HCI_SUCCESS) { + return; + } + + cb_params.frame_space_update.status = status | BTM_HCI_ERROR; + cb_params.frame_space_update.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT, &cb_params); +} + +void btm_ble_frame_space_update_complete_evt(UINT8 *p) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(cb_params.frame_space_update.status, p); + STREAM_TO_UINT16(cb_params.frame_space_update.conn_handle, p); + STREAM_TO_UINT8(cb_params.frame_space_update.initiator, p); + STREAM_TO_UINT16(cb_params.frame_space_update.frame_space, p); + STREAM_TO_UINT8(cb_params.frame_space_update.phys, p); + STREAM_TO_UINT16(cb_params.frame_space_update.spacing_types, p); + + if (cb_params.frame_space_update.status != HCI_SUCCESS) { + cb_params.frame_space_update.status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == 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 bc4a33db287..9959e025b9f 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 @@ -599,6 +599,9 @@ void btm_ble_transmit_power_report_evt(tBTM_BLE_TRANS_POWER_REPORT_EVT *params); #if (BLE_FEAT_CONN_SUBRATING == TRUE) void btm_ble_subrate_change_evt(tBTM_BLE_SUBRATE_CHANGE_EVT *params); #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +void btm_ble_frame_space_update_complete_evt(UINT8 *p); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) void btm_ble_pa_subevt_data_req_evt(tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT *params); void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index a6939e41fe2..4600b262622 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1201,6 +1201,9 @@ void btm_read_remote_trans_pwr_level_cmpl(UINT8 status); void btm_subrate_req_cmd_status(UINT8 status); #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +void btm_frame_space_update_cmd_status(UINT8 status, UINT16 conn_handle); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) void btm_ble_cs_read_local_supp_caps_cmpl_evt(UINT8 *p); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 5a16e31adbf..d3119d62364 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -174,6 +174,18 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len); #if (BLE_FEAT_ADV_MONITOR == TRUE) static void btu_ble_monitor_adv_report_evt(UINT8 *p); #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +static void btu_ble_read_all_remote_feat_complete_evt(UINT8 *p); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +static void btu_ble_frame_space_update_complete_evt(UINT8 *p); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +static void btu_ble_utp_receive_evt(UINT8 *p, UINT16 evt_len); +#endif // #if (BLE_FEAT_LE_UTP == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +static void btu_ble_conn_rate_change_evt(UINT8 *p); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_50_EXTEND_SYNC_EN == TRUE) static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt); static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len, bool v2_evt); @@ -560,6 +572,16 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_ble_monitor_adv_report_evt(p); break; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + case HCI_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT: + btu_ble_read_all_remote_feat_complete_evt(p); + break; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + case HCI_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT: + btu_ble_frame_space_update_complete_evt(p); + break; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) case HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT: btu_ble_periodic_adv_sync_trans_recv(p); @@ -629,6 +651,16 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_ble_subrate_change_evt(p); break; #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + case HCI_BLE_UTP_RECEIVE_EVT: + btu_ble_utp_receive_evt(p, hci_evt_len); + break; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + case HCI_BLE_CONN_RATE_CHANGE_EVT: + btu_ble_conn_rate_change_evt(p); + break; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case HCI_BLE_PA_SUBEVT_DATA_REQUEST_EVT: btu_ble_pa_subevt_data_request_evt(p); @@ -1483,6 +1515,16 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_read_monitor_adv_list_size_complete(p); break; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + case HCI_BLE_READ_ALL_LOCAL_SUPP_FEATURES: + btm_ble_read_all_local_supp_features_complete(p); + break; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + case HCI_BLE_READ_MIN_SUPP_CONN_INTERVAL: + btm_ble_read_min_supp_conn_interval_complete(p); + break; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #endif /* (BLE_INCLUDED == TRUE) */ default: { @@ -1652,6 +1694,18 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c btm_subrate_req_cmd_status(status); break; #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + case HCI_BLE_FRAME_SPACE_UPDATE: + { + UINT16 conn_handle = HCI_INVALID_HANDLE; + if (p_cmd != NULL) { + p_cmd++; /* skip param length */ + STREAM_TO_UINT16(conn_handle, p_cmd); + } + btm_frame_space_update_cmd_status(status, conn_handle); + break; + } +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) case HCI_BLE_CS_READ_REMOTE_SUPP_CAPS: btm_ble_cs_read_remote_supp_caps_cmd_status(status); @@ -2660,7 +2714,19 @@ static void btu_ble_monitor_adv_report_evt(UINT8 *p) } #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +static void btu_ble_read_all_remote_feat_complete_evt(UINT8 *p) +{ + btm_ble_read_all_remote_features_complete_evt(p); +} +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +static void btu_ble_frame_space_update_complete_evt(UINT8 *p) +{ + btm_ble_frame_space_update_complete_evt(p); +} +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BLE_50_EXTEND_SYNC_EN == TRUE) static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt) @@ -3336,7 +3402,39 @@ static void btu_ble_subrate_change_evt(UINT8 *p) } #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +static void btu_ble_conn_rate_change_evt(UINT8 *p) +{ + tBTM_BLE_CONN_RATE_CHANGE conn_rate_change = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(conn_rate_change.status, p); + STREAM_TO_UINT16(conn_rate_change.conn_handle, p); + STREAM_TO_UINT16(conn_rate_change.conn_interval, p); + STREAM_TO_UINT16(conn_rate_change.subrate_factor, p); + STREAM_TO_UINT16(conn_rate_change.peripheral_latency, p); + STREAM_TO_UINT16(conn_rate_change.continuation_number, p); + STREAM_TO_UINT16(conn_rate_change.supervision_timeout, p); + + btm_ble_conn_rate_change_evt(&conn_rate_change); +} +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + +#if (BLE_FEAT_LE_UTP == TRUE) +static void btu_ble_utp_receive_evt(UINT8 *p, UINT16 evt_len) +{ + if (!p || evt_len < 1) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + btm_ble_utp_receive_evt(p, evt_len); +} +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) static void btu_ble_pa_subevt_data_request_evt(UINT8 *p) diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 629ea14042e..43ee2d87ce9 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3123,6 +3123,27 @@ UINT8 btsnd_hcic_ble_set_decision_instructions(UINT8 num_tests, const UINT8 *tes } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +UINT8 btsnd_hcic_ble_frame_space_update(UINT16 conn_handle, UINT16 frame_space_min, + UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types) +{ + BT_HDR *p; + UINT8 *pp; + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_FRAME_SPACE_UPDATE); + + UINT16_TO_STREAM(pp, HCI_BLE_FRAME_SPACE_UPDATE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_FRAME_SPACE_UPDATE); + UINT16_TO_STREAM(pp, conn_handle); + UINT16_TO_STREAM(pp, frame_space_min); + UINT16_TO_STREAM(pp, frame_space_max); + UINT8_TO_STREAM(pp, phys); + UINT16_TO_STREAM(pp, spacing_types); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return HCI_SUCCESS; +} +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == 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 e0ffbe8890f..239784f77e7 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 @@ -990,6 +990,9 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT 74 #define BTM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT 75 #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#define BTM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT 78 +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BLE_FEAT_DBAF == TRUE) #define BTM_BLE_5_GAP_SET_DECISION_DATA_COMPLETE_EVT 79 #define BTM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT 80 @@ -1245,6 +1248,16 @@ typedef struct { #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +typedef struct { + tBTM_STATUS status; + UINT16 conn_handle; + UINT8 initiator; + UINT16 frame_space; + UINT8 phys; + UINT16 spacing_types; +} tBTM_BLE_FRAME_SPACE_UPDATE; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) @@ -1958,6 +1971,9 @@ typedef union { tBTM_BLE_MONITOR_ADV_REPORT monitor_adv_report; tBTM_BLE_MONITOR_ADV_LIST_SIZE monitor_adv_list_size; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) + tBTM_BLE_FRAME_SPACE_UPDATE frame_space_update; +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -3123,10 +3139,13 @@ tBTM_STATUS BTM_BleEnableMonitorAdv(UINT8 enable); tBTM_STATUS BTM_BleSetDecisionData(UINT8 adv_handle, UINT8 decision_type_flags, UINT8 data_len, const UINT8 *p_data); tBTM_STATUS BTM_BleSetDecisionInstructions(UINT8 num_tests, const UINT8 *test_flags, - const UINT8 *test_fields, UINT8 test_params_len, - const UINT8 *test_params); + const UINT8 *test_fields, const UINT8 *test_params); #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +tBTM_STATUS BTM_BleFrameSpaceUpdate(UINT16 conn_handle, UINT16 frame_space_min, + UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index ff39bb22ae4..3fd8ab97353 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -439,6 +439,9 @@ #define HCI_BLE_ENABLE_MONITOR_ADV (0x009C | HCI_GRP_BLE_CMDS) #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#define HCI_BLE_FRAME_SPACE_UPDATE (0x009D | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) #define HCI_BLE_ENH_READ_TRANS_POWER_LEVEL (0x0076 | HCI_GRP_BLE_CMDS) @@ -985,6 +988,9 @@ #define HCI_BLE_MONITOR_ADV_REPORT_EVT 0x34 #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#define HCI_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT 0x35 +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 3dfc7bc9a1d..36b86a33579 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -832,15 +832,22 @@ UINT8 btsnd_hcic_ble_enable_monitor_adv(UINT8 enable); #define HCIC_PARAM_SIZE_SET_DECISION_INSTRUCTIONS_MAX 251 #define BLE_DECISION_DATA_MAX_LEN 248 #define BLE_DECISION_MAX_TESTS 8 -#define BLE_DECISION_TEST_PARAMS_MAX_LEN 229 +#define BLE_DECISION_TEST_PARAM_LEN 16 +#define BLE_DECISION_TEST_PARAMS_MAX_LEN (BLE_DECISION_MAX_TESTS * BLE_DECISION_TEST_PARAM_LEN) +#define HCIC_PARAM_SIZE_SET_DECISION_INSTRUCTIONS(n) (HCIC_PARAM_SIZE_SET_DECISION_INSTRUCTIONS_HDR + (n) * 18) UINT8 btsnd_hcic_ble_set_decision_data(UINT8 adv_handle, UINT8 decision_type_flags, UINT8 data_len, const UINT8 *p_data); UINT8 btsnd_hcic_ble_set_decision_instructions(UINT8 num_tests, const UINT8 *test_flags, - const UINT8 *test_fields, UINT8 test_params_len, - const UINT8 *test_params); + const UINT8 *test_fields, const UINT8 *test_params); #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#define HCIC_PARAM_SIZE_FRAME_SPACE_UPDATE 9 + +UINT8 btsnd_hcic_ble_frame_space_update(UINT16 conn_handle, UINT16 frame_space_min, + UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types); +#endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) From 22840d0259ee12a9dbc4b1f6c3cea3bef9016b40 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Fri, 26 Jun 2026 09:08:15 +0800 Subject: [PATCH 3/6] feat(ble/bluedroid): add LL Extended Feature Set host support (Core 6.0) (cherry picked from commit d568f2f1519d672e505a34781a414ee29b9ceff3) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/Kconfig.in | 8 ++ .../bt/host/bluedroid/api/esp_gap_ble_api.c | 39 ++++++++++ .../api/include/api/esp_gap_ble_api.h | 56 ++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 13 ++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 29 ++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 + .../bluedroid/bta/dm/include/bta_dm_int.h | 23 ++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 8 ++ .../btc/profile/std/gap/btc_gap_ble.c | 37 ++++++++++ .../btc/profile/std/include/btc_gap_ble.h | 10 +++ .../include/common/bluedroid_user_config.h | 5 ++ .../common/include/common/bt_target.h | 5 ++ .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 73 +++++++++++++++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 4 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 5 -- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 40 ++++++++++ .../stack/include/stack/btm_ble_api.h | 31 ++++++++ .../bluedroid/stack/include/stack/hcidefs.h | 7 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 8 ++ 19 files changed, 400 insertions(+), 5 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 7bd489c6ff0..7e7b4ea477b 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1541,6 +1541,14 @@ config BT_BLE_FEAT_FRAME_SPACE_UPDATE help Enable Frame Space Update feature (Bluetooth Core 6.0). +config BT_BLE_FEAT_LL_EXT_FEAT + bool "Enable BLE LL Extended Feature Set" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_LL_EXT_FEAT_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable LL Extended Feature Set (Bluetooth Core 6.0). + Supports LE Read All Local/Remote Supported Features HCI commands. + menuconfig BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 2f45ac285df..5d6ddd4ad93 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2057,6 +2057,45 @@ esp_err_t esp_ble_gap_frame_space_update(const esp_ble_gap_frame_space_update_pa } #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +esp_err_t esp_ble_gap_read_all_local_supp_features(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_read_all_remote_features(const esp_ble_gap_read_all_remote_feat_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (params->page_requested > ESP_BLE_GAP_LL_EXT_FEAT_MAX_PAGE) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_READ_ALL_REMOTE_FEAT; + arg.read_all_remote_feat.conn_handle = params->conn_handle; + arg.read_all_remote_feat.page_requested = params->page_requested; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 1ac0c703b9c..5d10394515c 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -276,6 +276,8 @@ typedef enum { ESP_GAP_BLE_SET_DECISION_DATA_COMPLETE_EVT, /*!< When set decision data complete, the event comes */ ESP_GAP_BLE_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT, /*!< When set decision instructions complete, the event comes */ ESP_GAP_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT, /*!< When frame space update complete, the event comes */ + ESP_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT, /*!< When read all local supported LE features complete, the event comes */ + ESP_GAP_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT, /*!< When read all remote LE features complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1326,6 +1328,19 @@ typedef struct { } esp_ble_gap_frame_space_update_params_t; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#define ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN 248 +#define ESP_BLE_GAP_LL_EXT_FEAT_MAX_PAGE 10 + +/** + * @brief Parameters for reading all remote LE features for a connection + */ +typedef struct { + uint16_t conn_handle; /*!< Connection handle */ + uint8_t page_requested; /*!< The number of the highest-numbered page of features that the Host requires and the Controller shall obtain, + range: 0 to ESP_BLE_GAP_LL_EXT_FEAT_MAX_PAGE */ +} esp_ble_gap_read_all_remote_feat_params_t; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) @@ -2310,6 +2325,26 @@ typedef union { uint16_t spacing_types; /*!< Spacing types mask updated */ } frame_space_update; /*!< Event parameter of ESP_GAP_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT */ #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + /** + * @brief ESP_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT + */ + struct ble_read_all_local_supp_feat_cmpl_param { + esp_bt_status_t status; /*!< Indicate read all local supported LE features operation success status */ + uint8_t max_page; /*!< Maximum supported features page number */ + uint8_t le_features[ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN]; /*!< LE features data */ + } read_all_local_supp_feat; /*!< Event parameter of ESP_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT + */ + struct ble_read_all_remote_feat_cmpl_param { + esp_bt_status_t status; /*!< Indicate read all remote LE features operation success status */ + uint16_t conn_handle; /*!< Connection handle */ + uint8_t max_remote_page; /*!< Maximum remote features page number supported by peer */ + uint8_t max_valid_page; /*!< Maximum valid features page number in le_features */ + uint8_t le_features[ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN]; /*!< Remote LE features data */ + } read_all_remote_feat; /*!< Event parameter of ESP_GAP_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT */ +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) /** * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ @@ -4209,6 +4244,27 @@ esp_err_t esp_ble_gap_set_decision_instructions(const esp_ble_gap_set_decision_i esp_err_t esp_ble_gap_frame_space_update(const esp_ble_gap_frame_space_update_params_t *params); #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +/** +* @brief Read all local supported LE features (LL Extended Feature Set). +* +* @return - ESP_OK : success (command sent) +* - other : failed +* +*/ +esp_err_t esp_ble_gap_read_all_local_supp_features(void); + +/** +* @brief Read all remote LE features for a connection (LL Extended Feature Set). +* +* @param[in] params : Pointer to read remote features parameters. +* +* @return - ESP_OK : success (command sent) +* - other : failed +* +*/ +esp_err_t esp_ble_gap_read_all_remote_features(const esp_ble_gap_read_all_remote_feat_params_t *params); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) 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 1c6492de1ab..f47f333ac39 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6013,6 +6013,19 @@ void bta_dm_ble_gap_frame_space_update(tBTA_DM_MSG *p_data) } #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +void bta_dm_ble_gap_read_all_local_supp_features(tBTA_DM_MSG *p_data) +{ + (void)p_data; + BTM_BleReadAllLocalSuppFeatures(); +} + +void bta_dm_ble_gap_read_all_remote_features(tBTA_DM_MSG *p_data) +{ + BTM_BleReadAllRemoteFeatures(p_data->ble_read_all_remote_feat.conn_handle, + p_data->ble_read_all_remote_feat.page_requested); +} +#endif // #if (BLE_FEAT_LL_EXT_FEAT == 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 c7d234688cc..270d552935e 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3326,6 +3326,35 @@ void BTA_DmBleGapFrameSpaceUpdate(UINT16 conn_handle, UINT16 frame_space_min, } #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +void BTA_DmBleGapReadAllLocalSuppFeatures(void) +{ + tBTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT *) osi_malloc(sizeof(tBTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT)); + p_msg->hdr.event = BTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT_EVT; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapReadAllRemoteFeatures(UINT16 conn_handle, UINT8 page_requested) +{ + tBTA_DM_API_READ_ALL_REMOTE_FEAT *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_READ_ALL_REMOTE_FEAT *) osi_malloc(sizeof(tBTA_DM_API_READ_ALL_REMOTE_FEAT))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_READ_ALL_REMOTE_FEAT)); + p_msg->hdr.event = BTA_DM_API_READ_ALL_REMOTE_FEAT_EVT; + p_msg->conn_handle = conn_handle; + p_msg->page_requested = page_requested; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) 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 627dfda344e..9c26391d0f7 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -335,6 +335,10 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) bta_dm_ble_gap_frame_space_update, /* BTA_DM_API_FRAME_SPACE_UPDATE_EVT */ #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + bta_dm_ble_gap_read_all_local_supp_features, /* BTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT_EVT */ + bta_dm_ble_gap_read_all_remote_features, /* BTA_DM_API_READ_ALL_REMOTE_FEAT_EVT */ +#endif // #if (BLE_FEAT_LL_EXT_FEAT == 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 5d87002563e..f8fa339c166 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 @@ -329,6 +329,10 @@ enum { #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) BTA_DM_API_FRAME_SPACE_UPDATE_EVT, #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + BTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT_EVT, + BTA_DM_API_READ_ALL_REMOTE_FEAT_EVT, +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) BTA_DM_MAX_EVT }; @@ -1414,6 +1418,17 @@ typedef struct { } tBTA_DM_API_FRAME_SPACE_UPDATE; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +typedef struct { + BT_HDR hdr; +} tBTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 page_requested; +} tBTA_DM_API_READ_ALL_REMOTE_FEAT; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) @@ -1860,6 +1875,10 @@ typedef union { #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) tBTA_DM_API_FRAME_SPACE_UPDATE ble_frame_space_update; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + tBTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT ble_read_all_local_supp_feat; + tBTA_DM_API_READ_ALL_REMOTE_FEAT ble_read_all_remote_feat; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BLE_42_DTM_TEST_EN == TRUE) tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; @@ -2548,6 +2567,10 @@ extern void bta_dm_ble_gap_set_decision_instructions(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_frame_space_update(tBTA_DM_MSG *p_data); #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +extern void bta_dm_ble_gap_read_all_local_supp_features(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_read_all_remote_features(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) 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 b1903c7d45c..745ec2514b6 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1614,6 +1614,10 @@ typedef struct { #define BTA_DM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT BTM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#define BTA_DM_BLE_5_GAP_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT BTM_BLE_5_GAP_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT BTM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) @@ -3083,6 +3087,10 @@ extern void BTA_DmBleGapFrameSpaceUpdate(UINT16 conn_handle, UINT16 frame_space_ UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types); #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +extern void BTA_DmBleGapReadAllLocalSuppFeatures(void); +extern void BTA_DmBleGapReadAllRemoteFeatures(UINT16 conn_handle, UINT8 page_requested); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index b4e2a342540..d93fffa9138 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1307,6 +1307,34 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, break; } #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + case BTA_DM_BLE_5_GAP_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT; + param.read_all_local_supp_feat.status = btc_btm_status_to_esp_status(params->read_all_local_supp_feat.status); + param.read_all_local_supp_feat.max_page = params->read_all_local_supp_feat.max_page; + if (params->read_all_local_supp_feat.le_features != NULL) { + memcpy(param.read_all_local_supp_feat.le_features, params->read_all_local_supp_feat.le_features, + ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN); + } else { + memset(param.read_all_local_supp_feat.le_features, 0, ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN); + } + break; + } + case BTA_DM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT; + param.read_all_remote_feat.status = btc_btm_status_to_esp_status(params->read_all_remote_feat.status); + param.read_all_remote_feat.conn_handle = params->read_all_remote_feat.conn_handle; + param.read_all_remote_feat.max_remote_page = params->read_all_remote_feat.max_remote_page; + param.read_all_remote_feat.max_valid_page = params->read_all_remote_feat.max_valid_page; + if (params->read_all_remote_feat.le_features != NULL) { + memcpy(param.read_all_remote_feat.le_features, params->read_all_remote_feat.le_features, + ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN); + } else { + memset(param.read_all_remote_feat.le_features, 0, ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN); + } + break; + } +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BLE_50_EXTEND_ADV_EN == TRUE) case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT: { param.adv_terminate.status = params->adv_term.status; @@ -3566,6 +3594,15 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) arg_5->frame_space_update.spacing_types); break; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + case BTC_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT: + BTA_DmBleGapReadAllLocalSuppFeatures(); + break; + case BTC_GAP_BLE_READ_ALL_REMOTE_FEAT: + BTA_DmBleGapReadAllRemoteFeatures(arg_5->read_all_remote_feat.conn_handle, + arg_5->read_all_remote_feat.page_requested); + break; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: BTA_DmBleGapSetPASubevtData(arg_5->per_adv_subevent_data_params.adv_handle, arg_5->per_adv_subevent_data_params.num_subevents_with_data, (uint8_t *)(arg_5->per_adv_subevent_data_params.subevent_params)); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 0ecb1834e75..5c71e6fc9ec 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -154,6 +154,10 @@ typedef enum { #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) BTC_GAP_BLE_FRAME_SPACE_UPDATE, #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + BTC_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT, + BTC_GAP_BLE_READ_ALL_REMOTE_FEAT, +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) BTC_GAP_BLE_READ_CHANNEL_MAP, #if (BT_BLE_FEAT_PAWR_EN == TRUE) BTC_GAP_BLE_SET_PA_SUBEVT_DATA, @@ -618,6 +622,12 @@ typedef union { uint16_t spacing_types; } frame_space_update; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + struct read_all_remote_feat_args { + uint16_t conn_handle; + uint8_t page_requested; + } read_all_remote_feat; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) // BTC_GAP_BLE_SET_PA_SUBEVT_DATA struct per_adv_subevent_data_params_args { 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 c669d1339d7..7d632153708 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 @@ -364,6 +364,11 @@ #endif +#ifdef CONFIG_BT_BLE_FEAT_LL_EXT_FEAT +#define UC_BT_BLE_FEAT_LL_EXT_FEAT CONFIG_BT_BLE_FEAT_LL_EXT_FEAT +#else +#define UC_BT_BLE_FEAT_LL_EXT_FEAT FALSE +#endif 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 01315494dc6..621a805f1db 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -425,6 +425,11 @@ #define BLE_FEAT_FRAME_SPACE_UPDATE FALSE #endif +#if (BLE_50_FEATURE_SUPPORT == TRUE) && (UC_BT_BLE_FEAT_LL_EXT_FEAT == TRUE) +#define BLE_FEAT_LL_EXT_FEAT TRUE +#else +#define BLE_FEAT_LL_EXT_FEAT FALSE +#endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 16487f71f48..1294c5a5bde 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1507,6 +1507,79 @@ void btm_ble_frame_space_update_complete_evt(UINT8 *p) } #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +tBTM_STATUS BTM_BleReadAllLocalSuppFeatures(void) +{ + if (!btsnd_hcic_ble_read_all_local_supp_features()) { + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + cb_params.read_all_local_supp_feat.status = BTM_HCI_ERROR | HCI_ERR_MEMORY_FULL; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT, &cb_params); + return BTM_NO_RESOURCES; + } + return BTM_CMD_STARTED; +} + +void btm_ble_read_all_local_supp_features_complete(UINT8 *p) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(cb_params.read_all_local_supp_feat.status, p); + if (cb_params.read_all_local_supp_feat.status == HCI_SUCCESS) { + STREAM_TO_UINT8(cb_params.read_all_local_supp_feat.max_page, p); + cb_params.read_all_local_supp_feat.le_features = btm_ble_local_supp_le_features; + STREAM_TO_ARRAY(btm_ble_local_supp_le_features, p, BLE_LL_EXT_FEAT_DATA_LEN); + } else { + cb_params.read_all_local_supp_feat.status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT, &cb_params); +} + +tBTM_STATUS BTM_BleReadAllRemoteFeatures(UINT16 conn_handle, UINT8 page_requested) +{ + tHCI_STATUS err; + + err = btsnd_hcic_ble_read_all_remote_features(conn_handle, page_requested); + if (err != HCI_SUCCESS) { + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + cb_params.read_all_remote_feat.status = BTM_HCI_ERROR | err; + cb_params.read_all_remote_feat.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT, &cb_params); + return BTM_NO_RESOURCES; + } + return BTM_CMD_STARTED; +} + +void btm_read_all_remote_feat_cmd_status(UINT8 status) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (status == HCI_SUCCESS) { + return; + } + + cb_params.read_all_remote_feat.status = status | BTM_HCI_ERROR; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT, &cb_params); +} + +void btm_ble_read_all_remote_features_complete_evt(UINT8 *p) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(cb_params.read_all_remote_feat.status, p); + STREAM_TO_UINT16(cb_params.read_all_remote_feat.conn_handle, p); + if (cb_params.read_all_remote_feat.status == HCI_SUCCESS) { + STREAM_TO_UINT8(cb_params.read_all_remote_feat.max_remote_page, p); + STREAM_TO_UINT8(cb_params.read_all_remote_feat.max_valid_page, p); + cb_params.read_all_remote_feat.le_features = btm_ble_remote_supp_le_features; + STREAM_TO_ARRAY(btm_ble_remote_supp_le_features, p, BLE_LL_EXT_FEAT_DATA_LEN); + } else { + cb_params.read_all_remote_feat.status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_LL_EXT_FEAT == 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 9959e025b9f..82ef4967f6c 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 @@ -602,6 +602,10 @@ void btm_ble_subrate_change_evt(tBTM_BLE_SUBRATE_CHANGE_EVT *params); #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) void btm_ble_frame_space_update_complete_evt(UINT8 *p); #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +void btm_ble_read_all_local_supp_features_complete(UINT8 *p); +void btm_ble_read_all_remote_features_complete_evt(UINT8 *p); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) void btm_ble_pa_subevt_data_req_evt(tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT *params); void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index d3119d62364..fc600fbf50e 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1520,11 +1520,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_read_all_local_supp_features_complete(p); break; #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) -#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) - case HCI_BLE_READ_MIN_SUPP_CONN_INTERVAL: - btm_ble_read_min_supp_conn_interval_complete(p); - break; -#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #endif /* (BLE_INCLUDED == TRUE) */ default: { diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 43ee2d87ce9..0741159f259 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3145,6 +3145,46 @@ UINT8 btsnd_hcic_ble_frame_space_update(UINT16 conn_handle, UINT16 frame_space_m } #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +BOOLEAN btsnd_hcic_ble_read_all_local_supp_features(void) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF(0)) == NULL) { + return FALSE; + } + pp = (UINT8 *)(p + 1); + p->len = HCIC_PREAMBLE_SIZE; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_READ_ALL_LOCAL_SUPP_FEATURES); + UINT8_TO_STREAM(pp, 0); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +UINT8 btsnd_hcic_ble_read_all_remote_features(UINT16 conn_handle, UINT8 page_requested) +{ + BT_HDR *p; + UINT8 *pp; + + if (page_requested > BLE_LL_EXT_FEAT_MAX_PAGE) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_READ_ALL_REMOTE_FEATURES); + + UINT16_TO_STREAM(pp, HCI_BLE_READ_ALL_REMOTE_FEATURES); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_ALL_REMOTE_FEATURES); + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, page_requested); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return HCI_SUCCESS; +} +#endif // #if (BLE_FEAT_LL_EXT_FEAT == 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 239784f77e7..1b4ad689170 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 @@ -990,6 +990,10 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_READ_MONITOR_ADV_LIST_SIZE_COMPLETE_EVT 74 #define BTM_BLE_5_GAP_ENABLE_MONITOR_ADV_COMPLETE_EVT 75 #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#define BTM_BLE_5_GAP_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT 76 +#define BTM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT 77 +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) #define BTM_BLE_5_GAP_FRAME_SPACE_UPDATE_COMPLETE_EVT 78 #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) @@ -1247,6 +1251,25 @@ typedef struct { } tBTM_BLE_MONITOR_ADV_LIST_SIZE; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#ifndef BLE_LL_EXT_FEAT_DATA_LEN +#define BLE_LL_EXT_FEAT_DATA_LEN 248 +#endif + +typedef struct { + tBTM_STATUS status; + UINT8 max_page; + UINT8 *le_features; +} tBTM_BLE_READ_ALL_LOCAL_SUPP_FEAT; + +typedef struct { + tBTM_STATUS status; + UINT16 conn_handle; + UINT8 max_remote_page; + UINT8 max_valid_page; + UINT8 *le_features; +} tBTM_BLE_READ_ALL_REMOTE_FEAT; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) typedef struct { @@ -1971,6 +1994,10 @@ typedef union { tBTM_BLE_MONITOR_ADV_REPORT monitor_adv_report; tBTM_BLE_MONITOR_ADV_LIST_SIZE monitor_adv_list_size; #endif // #if (BLE_FEAT_ADV_MONITOR == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + tBTM_BLE_READ_ALL_LOCAL_SUPP_FEAT read_all_local_supp_feat; + tBTM_BLE_READ_ALL_REMOTE_FEAT read_all_remote_feat; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) tBTM_BLE_FRAME_SPACE_UPDATE frame_space_update; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) @@ -3147,6 +3174,10 @@ tBTM_STATUS BTM_BleFrameSpaceUpdate(UINT16 conn_handle, UINT16 frame_space_min, UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types); #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +tBTM_STATUS BTM_BleReadAllLocalSuppFeatures(void); +tBTM_STATUS BTM_BleReadAllRemoteFeatures(UINT16 conn_handle, UINT8 page_requested); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 3fd8ab97353..8aa44bda5f9 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -468,6 +468,10 @@ #define HCI_BLE_SET_PERIOD_ADV_PARAMS_V2 (0x0086 | HCI_GRP_BLE_CMDS) #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#define HCI_BLE_READ_ALL_LOCAL_SUPP_FEATURES (0x0087 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_READ_ALL_REMOTE_FEATURES (0x0088 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BLE_FEAT_DBAF == TRUE) #define HCI_BLE_SET_DECISION_DATA (0x0080 | HCI_GRP_BLE_CMDS) @@ -983,6 +987,9 @@ #define HCI_BLE_PA_RESPONSE_REPORT_EVT 0x28 #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#define HCI_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT 0x2B +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) #if (BLE_FEAT_ADV_MONITOR == TRUE) #define HCI_BLE_MONITOR_ADV_REPORT_EVT 0x34 diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 36b86a33579..cdc98c943cc 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -849,6 +849,14 @@ UINT8 btsnd_hcic_ble_frame_space_update(UINT16 conn_handle, UINT16 frame_space_m UINT16 frame_space_max, UINT8 phys, UINT16 spacing_types); #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#define HCIC_PARAM_SIZE_READ_ALL_REMOTE_FEATURES 3 +#define BLE_LL_EXT_FEAT_DATA_LEN 248 +#define BLE_LL_EXT_FEAT_MAX_PAGE 10 + +BOOLEAN btsnd_hcic_ble_read_all_local_supp_features(void); +UINT8 btsnd_hcic_ble_read_all_remote_features(UINT16 conn_handle, UINT8 page_requested); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) From 90dbfc2777ee75a21d92c509536326a775394361 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Fri, 26 Jun 2026 09:08:16 +0800 Subject: [PATCH 4/6] feat(ble/bluedroid): add Shorter Connection Intervals host support (Core 6.2) Co-authored-by: Cursor (cherry picked from commit 2a8a96d6506f29471319e04f7aea391fe9abbca1) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/Kconfig.in | 13 ++ .../bt/host/bluedroid/api/esp_gap_ble_api.c | 151 ++++++++++++++++ .../api/include/api/esp_gap_ble_api.h | 162 ++++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 34 ++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 70 ++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 5 + .../bluedroid/bta/dm/include/bta_dm_int.h | 47 +++++ .../host/bluedroid/bta/include/bta/bta_api.h | 19 ++ .../btc/profile/std/gap/btc_gap_ble.c | 75 ++++++++ .../btc/profile/std/include/btc_gap_ble.h | 30 ++++ .../include/common/bluedroid_user_config.h | 5 + .../common/include/common/bt_target.h | 5 + .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 131 ++++++++++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 4 + .../bluedroid/stack/btm/include/btm_int.h | 9 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 25 +++ .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 80 +++++++++ .../stack/include/stack/btm_ble_api.h | 54 ++++++ .../bluedroid/stack/include/stack/hcidefs.h | 8 + .../bluedroid/stack/include/stack/hcimsgs.h | 16 ++ 20 files changed, 943 insertions(+) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 7e7b4ea477b..a5304797378 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1549,6 +1549,19 @@ config BT_BLE_FEAT_LL_EXT_FEAT Enable LL Extended Feature Set (Bluetooth Core 6.0). Supports LE Read All Local/Remote Supported Features HCI commands. +config BT_BLE_FEAT_SHORTER_CONN_INTERVALS + bool "Enable BLE Shorter Connection Intervals (Core 6.2)" + depends on BT_BLE_FEAT_CONN_SUBRATING && (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_SHORTER_CONN_INTERVALS_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable Shorter Connection Intervals feature (Bluetooth Core 6.2). + Requires Connection Subrating (Core 5.3) per [Vol 6] Part B, Section 4.6.50. + Supports LE Connection Rate Request, LE Set Default Rate Parameters, + LE Read Minimum Supported Connection Interval commands and LE Connection Rate Change event. + Connection intervals use 125 us units (minimum 375 us). Use esp_ble_gap_connection_rate_request(), + esp_ble_gap_set_default_rate_parameters(), esp_ble_gap_read_min_supported_connection_interval() + and ESP_BLE_GAP_CONN_RATE_* conversion macros in esp_gap_ble_api.h. + menuconfig BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 5d6ddd4ad93..132aa31e773 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2097,6 +2097,157 @@ esp_err_t esp_ble_gap_read_all_remote_features(const esp_ble_gap_read_all_remote } #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +static bool esp_ble_gap_conn_rate_common_params_valid(uint16_t conn_interval_min, + uint16_t conn_interval_max, + uint16_t subrate_min, + uint16_t subrate_max, + uint16_t max_latency, + uint16_t continuation_number, + uint16_t supervision_timeout, + uint16_t min_ce_len, + uint16_t max_ce_len) +{ + if (conn_interval_min < ESP_BLE_GAP_CONN_RATE_INTERVAL_MIN || + conn_interval_max < ESP_BLE_GAP_CONN_RATE_INTERVAL_MIN || + conn_interval_min > conn_interval_max || + conn_interval_max > ESP_BLE_GAP_CONN_RATE_INTERVAL_MAX) { + return false; + } + if (subrate_min < ESP_BLE_GAP_CONN_RATE_SUBRATE_MIN || + subrate_max < ESP_BLE_GAP_CONN_RATE_SUBRATE_MIN || + subrate_min > subrate_max || + subrate_max > ESP_BLE_GAP_CONN_RATE_SUBRATE_MAX) { + return false; + } + if (continuation_number >= subrate_max || + continuation_number > ESP_BLE_GAP_CONN_RATE_CONTINUATION_NUMBER_MAX) { + return false; + } + if (max_latency > ESP_BLE_GAP_CONN_RATE_MAX_LATENCY_MAX) { + return false; + } + if ((uint32_t)subrate_max * (uint32_t)(max_latency + 1U) > + ESP_BLE_GAP_CONN_RATE_SUBRATE_LATENCY_PRODUCT_MAX) { + return false; + } + if (supervision_timeout < ESP_BLE_GAP_CONN_RATE_SUPERVISION_TIMEOUT_MIN || + supervision_timeout > ESP_BLE_GAP_CONN_RATE_SUPERVISION_TIMEOUT_MAX) { + return false; + } + if ((uint32_t)conn_interval_max * (uint32_t)subrate_max * (uint32_t)(max_latency + 1U) >= + (uint32_t)supervision_timeout * ESP_BLE_GAP_CONN_RATE_SUPERVISION_TIMEOUT_FACTOR) { + return false; + } + if (min_ce_len > max_ce_len) { + return false; + } + return true; +} + +static bool esp_ble_gap_connection_rate_params_valid(const esp_ble_gap_connection_rate_request_params_t *params) +{ + return esp_ble_gap_conn_rate_common_params_valid(params->conn_interval_min, + params->conn_interval_max, + params->subrate_min, + params->subrate_max, + params->max_latency, + params->continuation_number, + params->supervision_timeout, + params->min_ce_len, + params->max_ce_len); +} + +static bool esp_ble_gap_default_rate_params_valid(const esp_ble_gap_default_rate_param_t *params) +{ + return esp_ble_gap_conn_rate_common_params_valid(params->conn_interval_min, + params->conn_interval_max, + params->subrate_min, + params->subrate_max, + params->max_latency, + params->continuation_number, + params->supervision_timeout, + params->min_ce_len, + params->max_ce_len); +} + +esp_err_t esp_ble_gap_connection_rate_request(const esp_ble_gap_connection_rate_request_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (!esp_ble_gap_connection_rate_params_valid(params)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CONNECTION_RATE_REQUEST; + arg.connection_rate_request.conn_handle = params->conn_handle; + arg.connection_rate_request.conn_interval_min = params->conn_interval_min; + arg.connection_rate_request.conn_interval_max = params->conn_interval_max; + arg.connection_rate_request.subrate_min = params->subrate_min; + arg.connection_rate_request.subrate_max = params->subrate_max; + arg.connection_rate_request.max_latency = params->max_latency; + arg.connection_rate_request.continuation_number = params->continuation_number; + arg.connection_rate_request.supervision_timeout = params->supervision_timeout; + arg.connection_rate_request.min_ce_len = params->min_ce_len; + arg.connection_rate_request.max_ce_len = params->max_ce_len; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_default_rate_parameters(const esp_ble_gap_default_rate_param_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (!esp_ble_gap_default_rate_params_valid(params)) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS; + arg.set_default_rate_parameters.conn_interval_min = params->conn_interval_min; + arg.set_default_rate_parameters.conn_interval_max = params->conn_interval_max; + arg.set_default_rate_parameters.subrate_min = params->subrate_min; + arg.set_default_rate_parameters.subrate_max = params->subrate_max; + arg.set_default_rate_parameters.max_latency = params->max_latency; + arg.set_default_rate_parameters.continuation_number = params->continuation_number; + arg.set_default_rate_parameters.supervision_timeout = params->supervision_timeout; + arg.set_default_rate_parameters.min_ce_len = params->min_ce_len; + arg.set_default_rate_parameters.max_ce_len = params->max_ce_len; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_read_min_supported_connection_interval(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 5d10394515c..257e081c929 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -278,6 +278,10 @@ typedef enum { ESP_GAP_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT, /*!< When frame space update complete, the event comes */ ESP_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT_COMPLETE_EVT, /*!< When read all local supported LE features complete, the event comes */ ESP_GAP_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT, /*!< When read all remote LE features complete, the event comes */ + ESP_GAP_BLE_CONNECTION_RATE_REQUEST_COMPLETE_EVT, /*!< When connection rate request command complete, the event comes */ + ESP_GAP_BLE_CONN_RATE_CHANGE_EVT, /*!< When connection rate change event is received, the event comes */ + ESP_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT, /*!< When set default rate parameters complete, the event comes */ + ESP_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT, /*!< When read minimum supported connection interval complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1342,6 +1346,70 @@ typedef struct { } esp_ble_gap_read_all_remote_feat_params_t; #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#define ESP_BLE_GAP_CONN_RATE_INTERVAL_UNIT_US 125 +#define ESP_BLE_GAP_CONN_RATE_INTERVAL_MIN 3 +#define ESP_BLE_GAP_CONN_RATE_INTERVAL_MAX 0x7D00 +#define ESP_BLE_GAP_CONN_RATE_SUBRATE_MIN 0x0001 +#define ESP_BLE_GAP_CONN_RATE_SUBRATE_MAX 0x01F4 +#define ESP_BLE_GAP_CONN_RATE_MAX_LATENCY_MAX 0x01F3 +#define ESP_BLE_GAP_CONN_RATE_SUBRATE_LATENCY_PRODUCT_MAX 500 +#define ESP_BLE_GAP_CONN_RATE_CONTINUATION_NUMBER_MAX 0x01F3 +#define ESP_BLE_GAP_CONN_RATE_SUPERVISION_TIMEOUT_MIN 0x000A +#define ESP_BLE_GAP_CONN_RATE_SUPERVISION_TIMEOUT_MAX 0x0C80 +#define ESP_BLE_GAP_CONN_RATE_SUPERVISION_TIMEOUT_FACTOR 40 + +#define ESP_BLE_GAP_CONN_RATE_INTERVAL_US(units) \ + ((uint32_t)(units) * ESP_BLE_GAP_CONN_RATE_INTERVAL_UNIT_US) +#define ESP_BLE_GAP_CONN_RATE_INTERVAL_FROM_US(us) \ + ((uint16_t)(((us) + (ESP_BLE_GAP_CONN_RATE_INTERVAL_UNIT_US - 1U)) / ESP_BLE_GAP_CONN_RATE_INTERVAL_UNIT_US)) +#define ESP_BLE_GAP_CONN_RATE_INTERVAL_FROM_MS(ms) \ + ESP_BLE_GAP_CONN_RATE_INTERVAL_FROM_US((uint32_t)(ms) * 1000U) +#define ESP_BLE_GAP_CONN_RATE_EFF_INTERVAL_US(interval, subrate) \ + (ESP_BLE_GAP_CONN_RATE_INTERVAL_US(interval) * (uint32_t)(subrate)) + +/** + * @brief Parameters for requesting a connection rate update (Shorter Connection Intervals) + */ +typedef struct { + uint16_t conn_handle; /*!< Connection handle */ + uint16_t conn_interval_min; /*!< Minimum connection interval in 125 us units. Range: 0x0003 to 0x7D00 */ + uint16_t conn_interval_max; /*!< Maximum connection interval in 125 us units. Range: 0x0003 to 0x7D00 */ + uint16_t subrate_min; /*!< Minimum subrate factor. Range: 0x0001 to 0x01F4 */ + uint16_t subrate_max; /*!< Maximum subrate factor. Range: 0x0001 to 0x01F4 */ + uint16_t max_latency; /*!< Maximum Peripheral latency in subrated connection intervals. Range: 0x0000 to 0x01F3 */ + uint16_t continuation_number; /*!< Continuation number. Range: 0x0000 to 0x01F3 */ + uint16_t supervision_timeout; /*!< Supervision timeout in 10 ms units. Range: 0x000A to 0x0C80 */ + uint16_t min_ce_len; /*!< Minimum connection event length in 125 us units */ + uint16_t max_ce_len; /*!< Maximum connection event length in 125 us units */ +} esp_ble_gap_connection_rate_request_params_t; + +/** + * @brief Default connection rate parameters for future Central connections + */ +typedef struct { + uint16_t conn_interval_min; /*!< Minimum connection interval in 125 us units. Range: 0x0003 to 0x7D00 */ + uint16_t conn_interval_max; /*!< Maximum connection interval in 125 us units. Range: 0x0003 to 0x7D00 */ + uint16_t subrate_min; /*!< Minimum subrate factor. Range: 0x0001 to 0x01F4 */ + uint16_t subrate_max; /*!< Maximum subrate factor. Range: 0x0001 to 0x01F4 */ + uint16_t max_latency; /*!< Maximum Peripheral latency in subrated connection intervals. Range: 0x0000 to 0x01F3 */ + uint16_t continuation_number; /*!< Continuation number. Range: 0x0000 to 0x01F3 */ + uint16_t supervision_timeout; /*!< Supervision timeout in 10 ms units. Range: 0x000A to 0x0C80 */ + uint16_t min_ce_len; /*!< Minimum connection event length in 125 us units */ + uint16_t max_ce_len; /*!< Maximum connection event length in 125 us units */ +} esp_ble_gap_default_rate_param_t; + +#define ESP_BLE_GAP_CONN_RATE_MAX_INTERVAL_GROUPS 41 + +/** + * @brief Supported connection interval group returned by read minimum supported connection interval + */ +typedef struct { + uint16_t min_125us; /*!< Lower bound of supported interval group in 125 us units */ + uint16_t max_125us; /*!< Upper bound of supported interval group in 125 us units */ + uint16_t stride_125us; /*!< Stride between supported intervals in 125 us units */ +} esp_ble_gap_min_conn_interval_group_t; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) typedef enum { @@ -2345,6 +2413,45 @@ typedef union { uint8_t le_features[ESP_BLE_GAP_LL_EXT_FEAT_DATA_LEN]; /*!< Remote LE features data */ } read_all_remote_feat; /*!< Event parameter of ESP_GAP_BLE_READ_ALL_REMOTE_FEAT_COMPLETE_EVT */ #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + /** + * @brief ESP_GAP_BLE_CONNECTION_RATE_REQUEST_COMPLETE_EVT + * + * Reported when the HCI Connection Rate Request command is accepted or rejected by the controller, + * or when the host fails to send the command locally. + */ + struct ble_connection_rate_request_cmpl_param { + esp_bt_status_t status; /*!< Command success status, or host/controller error code */ + uint16_t conn_handle; /*!< Connection handle */ + } connection_rate_req_cmpl; /*!< Event parameter of ESP_GAP_BLE_CONNECTION_RATE_REQUEST_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_CONN_RATE_CHANGE_EVT + */ + struct ble_conn_rate_change_evt { + esp_bt_status_t status; /*!< Indicate connection rate change status */ + uint16_t conn_handle; /*!< Connection handle */ + uint16_t conn_interval; /*!< Underlying connection interval in 125 us units */ + uint16_t subrate_factor; /*!< Subrate factor applied to the connection interval */ + uint16_t peripheral_latency; /*!< Peripheral latency in subrated connection intervals */ + uint16_t continuation_number; /*!< Continuation number */ + uint16_t supervision_timeout; /*!< Supervision timeout in 10 ms units */ + } conn_rate_change_evt; /*!< Event parameter of ESP_GAP_BLE_CONN_RATE_CHANGE_EVT. Effective interval (us) = ESP_BLE_GAP_CONN_RATE_EFF_INTERVAL_US(conn_interval, subrate_factor) */ + /** + * @brief ESP_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT + */ + struct ble_set_default_rate_parameters_cmpl_param { + esp_bt_status_t status; /*!< Indicate set default rate parameters operation success status */ + } set_default_rate_parameters_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT + */ + struct ble_read_min_supp_conn_interval_cmpl_param { + esp_bt_status_t status; /*!< Indicate read minimum supported connection interval operation success status */ + uint8_t min_supported_conn_interval; /*!< Minimum supported connection interval in 125 us units */ + uint8_t num_groups; /*!< Number of supported interval groups; 0 if only RCV is supported */ + esp_ble_gap_min_conn_interval_group_t groups[ESP_BLE_GAP_CONN_RATE_MAX_INTERVAL_GROUPS]; + } read_min_supp_conn_interval; /*!< Event parameter of ESP_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT */ +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) /** * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ @@ -4266,6 +4373,61 @@ esp_err_t esp_ble_gap_read_all_local_supp_features(void); esp_err_t esp_ble_gap_read_all_remote_features(const esp_ble_gap_read_all_remote_feat_params_t *params); #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +/** +* @brief Request a connection rate update (Shorter Connection Intervals, Core 6.2). +* +* This API may be used by a Central or a Peripheral to request a change to the +* connection interval, subrate factor, and/or other connection parameters. +* `conn_interval_min/max` use 125 us units (minimum 375 us = 3). +* Use ESP_BLE_GAP_CONN_RATE_INTERVAL_FROM_MS() or ESP_BLE_GAP_CONN_RATE_INTERVAL_FROM_US() +* to convert from common time units. +* +* When the controller accepts or rejects the HCI command, `ESP_GAP_BLE_CONNECTION_RATE_REQUEST_COMPLETE_EVT` +* is reported with `status` and `conn_handle`. On command acceptance, `ESP_GAP_BLE_CONN_RATE_CHANGE_EVT` +* subsequently reports the applied parameters. The effective connection interval in microseconds is: +* ESP_BLE_GAP_CONN_RATE_EFF_INTERVAL_US(conn_interval, subrate_factor). +* +* @param[in] params : Pointer to connection rate request parameters. +* +* @return - ESP_OK : success (command sent) +* - ESP_ERR_INVALID_ARG : invalid parameters +* - ESP_ERR_INVALID_STATE : Bluedroid is not enabled +* - ESP_FAIL : other failures +* +*/ +esp_err_t esp_ble_gap_connection_rate_request(const esp_ble_gap_connection_rate_request_params_t *params); + +/** +* @brief Set default connection rate parameters for future Central connections (Core 6.2). +* +* Preconfigures the default connection rate parameters that may be requested by a +* Peripheral on new ACL connections where the local device is Central. +* +* @param[in] params : Pointer to default rate parameters. +* +* @return - ESP_OK : success +* - ESP_ERR_INVALID_ARG : invalid parameters +* - ESP_ERR_INVALID_STATE : Bluedroid is not enabled +* - ESP_FAIL : other failures +* +*/ +esp_err_t esp_ble_gap_set_default_rate_parameters(const esp_ble_gap_default_rate_param_t *params); + +/** +* @brief Read the Controller minimum supported connection interval and interval groups. +* +* On success, `ESP_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT` returns the +* minimum supported interval and optional interval groups. If `num_groups` is 0, +* the Controller only supports Rounded Connection Interval Values (RCV). +* +* @return - ESP_OK : success (command sent) +* - ESP_ERR_INVALID_STATE : Bluedroid is not enabled +* - ESP_FAIL : other failures +* +*/ +esp_err_t esp_ble_gap_read_min_supported_connection_interval(void); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) 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 f47f333ac39..615ba3e56de 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6027,6 +6027,40 @@ void bta_dm_ble_gap_read_all_remote_features(tBTA_DM_MSG *p_data) } #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +void bta_dm_ble_gap_connection_rate_request(tBTA_DM_MSG *p_data) +{ + BTM_BleConnectionRateRequest(p_data->ble_connection_rate_request.conn_handle, + p_data->ble_connection_rate_request.conn_interval_min, + p_data->ble_connection_rate_request.conn_interval_max, + p_data->ble_connection_rate_request.subrate_min, + p_data->ble_connection_rate_request.subrate_max, + p_data->ble_connection_rate_request.max_latency, + p_data->ble_connection_rate_request.continuation_number, + p_data->ble_connection_rate_request.supervision_timeout, + p_data->ble_connection_rate_request.min_ce_len, + p_data->ble_connection_rate_request.max_ce_len); +} + +void bta_dm_ble_gap_set_default_rate_parameters(tBTA_DM_MSG *p_data) +{ + BTM_BleSetDefaultRateParameters(p_data->ble_set_default_rate_parameters.conn_interval_min, + p_data->ble_set_default_rate_parameters.conn_interval_max, + p_data->ble_set_default_rate_parameters.subrate_min, + p_data->ble_set_default_rate_parameters.subrate_max, + p_data->ble_set_default_rate_parameters.max_latency, + p_data->ble_set_default_rate_parameters.continuation_number, + p_data->ble_set_default_rate_parameters.supervision_timeout, + p_data->ble_set_default_rate_parameters.min_ce_len, + p_data->ble_set_default_rate_parameters.max_ce_len); +} + +void bta_dm_ble_gap_read_min_supp_conn_interval(tBTA_DM_MSG *p_data) +{ + (void)p_data; + BTM_BleReadMinSuppConnInterval(); +} +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_FEAT_ISO_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 270d552935e..5e1c7211075 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3356,7 +3356,77 @@ void BTA_DmBleGapReadAllRemoteFeatures(UINT16 conn_handle, UINT8 page_requested) } #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +void BTA_DmBleGapConnectionRateRequest(UINT16 conn_handle, UINT16 conn_interval_min, + UINT16 conn_interval_max, UINT16 subrate_min, + UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len) +{ + tBTA_DM_API_BLE_CONNECTION_RATE_REQUEST *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_BLE_CONNECTION_RATE_REQUEST *) + osi_malloc(sizeof(tBTA_DM_API_BLE_CONNECTION_RATE_REQUEST))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_CONNECTION_RATE_REQUEST)); + p_msg->hdr.event = BTA_DM_API_CONNECTION_RATE_REQUEST_EVT; + p_msg->conn_handle = conn_handle; + p_msg->conn_interval_min = conn_interval_min; + p_msg->conn_interval_max = conn_interval_max; + p_msg->subrate_min = subrate_min; + p_msg->subrate_max = subrate_max; + p_msg->max_latency = max_latency; + p_msg->continuation_number = continuation_number; + p_msg->supervision_timeout = supervision_timeout; + p_msg->min_ce_len = min_ce_len; + p_msg->max_ce_len = max_ce_len; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +void BTA_DmBleGapSetDefaultRateParameters(UINT16 conn_interval_min, UINT16 conn_interval_max, + UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len) +{ + tBTA_DM_API_BLE_SET_DEFAULT_RATE_PARAMETERS *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_BLE_SET_DEFAULT_RATE_PARAMETERS *) + osi_malloc(sizeof(tBTA_DM_API_BLE_SET_DEFAULT_RATE_PARAMETERS))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_SET_DEFAULT_RATE_PARAMETERS)); + p_msg->hdr.event = BTA_DM_API_SET_DEFAULT_RATE_PARAMETERS_EVT; + p_msg->conn_interval_min = conn_interval_min; + p_msg->conn_interval_max = conn_interval_max; + p_msg->subrate_min = subrate_min; + p_msg->subrate_max = subrate_max; + p_msg->max_latency = max_latency; + p_msg->continuation_number = continuation_number; + p_msg->supervision_timeout = supervision_timeout; + p_msg->min_ce_len = min_ce_len; + p_msg->max_ce_len = max_ce_len; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapReadMinSuppConnInterval(void) +{ + tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL *) + osi_malloc(sizeof(tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL)); + p_msg->hdr.event = BTA_DM_API_READ_MIN_SUPP_CONN_INTERVAL_EVT; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) 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 9c26391d0f7..96697706b4e 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -339,6 +339,11 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_read_all_local_supp_features, /* BTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT_EVT */ bta_dm_ble_gap_read_all_remote_features, /* BTA_DM_API_READ_ALL_REMOTE_FEAT_EVT */ #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + bta_dm_ble_gap_connection_rate_request, /* BTA_DM_API_CONNECTION_RATE_REQUEST_EVT */ + bta_dm_ble_gap_set_default_rate_parameters, /* BTA_DM_API_SET_DEFAULT_RATE_PARAMETERS_EVT */ + bta_dm_ble_gap_read_min_supp_conn_interval, /* BTA_DM_API_READ_MIN_SUPP_CONN_INTERVAL_EVT */ +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == 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 f8fa339c166..396abcd3946 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 @@ -333,6 +333,11 @@ enum { BTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT_EVT, BTA_DM_API_READ_ALL_REMOTE_FEAT_EVT, #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + BTA_DM_API_CONNECTION_RATE_REQUEST_EVT, + BTA_DM_API_SET_DEFAULT_RATE_PARAMETERS_EVT, + BTA_DM_API_READ_MIN_SUPP_CONN_INTERVAL_EVT, +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) BTA_DM_MAX_EVT }; @@ -1430,6 +1435,38 @@ typedef struct { } tBTA_DM_API_READ_ALL_REMOTE_FEAT; #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT16 conn_interval_min; + UINT16 conn_interval_max; + UINT16 subrate_min; + UINT16 subrate_max; + UINT16 max_latency; + UINT16 continuation_number; + UINT16 supervision_timeout; + UINT16 min_ce_len; + UINT16 max_ce_len; +} tBTA_DM_API_BLE_CONNECTION_RATE_REQUEST; + +typedef struct { + BT_HDR hdr; + UINT16 conn_interval_min; + UINT16 conn_interval_max; + UINT16 subrate_min; + UINT16 subrate_max; + UINT16 max_latency; + UINT16 continuation_number; + UINT16 supervision_timeout; + UINT16 min_ce_len; + UINT16 max_ce_len; +} tBTA_DM_API_BLE_SET_DEFAULT_RATE_PARAMETERS; + +typedef struct { + BT_HDR hdr; +} tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) typedef struct { @@ -1879,6 +1916,11 @@ typedef union { tBTA_DM_API_READ_ALL_LOCAL_SUPP_FEAT ble_read_all_local_supp_feat; tBTA_DM_API_READ_ALL_REMOTE_FEAT ble_read_all_remote_feat; #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + tBTA_DM_API_BLE_CONNECTION_RATE_REQUEST ble_connection_rate_request; + tBTA_DM_API_BLE_SET_DEFAULT_RATE_PARAMETERS ble_set_default_rate_parameters; + tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL ble_read_min_supp_conn_interval; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_42_DTM_TEST_EN == TRUE) tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; @@ -2572,6 +2614,11 @@ extern void bta_dm_ble_gap_read_all_local_supp_features(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_read_all_remote_features(tBTA_DM_MSG *p_data); #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +extern void bta_dm_ble_gap_connection_rate_request(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_set_default_rate_parameters(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_read_min_supp_conn_interval(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) 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 745ec2514b6..27b1cde936b 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1619,6 +1619,12 @@ typedef struct { #define BTA_DM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT BTM_BLE_5_GAP_READ_ALL_REMOTE_FEAT_COMPLETE_EVT #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#define BTA_DM_BLE_5_GAP_CONNECTION_RATE_REQUEST_COMPLETE_EVT BTM_BLE_5_GAP_CONNECTION_RATE_REQUEST_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_CONN_RATE_CHANGE_EVT BTM_BLE_5_GAP_CONN_RATE_CHANGE_EVT +#define BTA_DM_BLE_5_GAP_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT BTM_BLE_5_GAP_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT BTM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) @@ -3092,6 +3098,19 @@ extern void BTA_DmBleGapReadAllLocalSuppFeatures(void); extern void BTA_DmBleGapReadAllRemoteFeatures(UINT16 conn_handle, UINT8 page_requested); #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +extern void BTA_DmBleGapConnectionRateRequest(UINT16 conn_handle, UINT16 conn_interval_min, + UINT16 conn_interval_max, UINT16 subrate_min, + UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len); +extern void BTA_DmBleGapSetDefaultRateParameters(UINT16 conn_interval_min, UINT16 conn_interval_max, + UINT16 subrate_min, UINT16 subrate_max, + UINT16 max_latency, UINT16 continuation_number, + UINT16 supervision_timeout, UINT16 min_ce_len, + UINT16 max_ce_len); +extern void BTA_DmBleGapReadMinSuppConnInterval(void); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index d93fffa9138..9b304a559c4 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1335,6 +1335,53 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, break; } #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + case BTA_DM_BLE_5_GAP_CONNECTION_RATE_REQUEST_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_CONNECTION_RATE_REQUEST_COMPLETE_EVT; + param.connection_rate_req_cmpl.status = btc_btm_status_to_esp_status(params->conn_rate_request.status); + param.connection_rate_req_cmpl.conn_handle = params->conn_rate_request.conn_handle; + break; + } + case BTA_DM_BLE_5_GAP_CONN_RATE_CHANGE_EVT: { + msg.act = ESP_GAP_BLE_CONN_RATE_CHANGE_EVT; + param.conn_rate_change_evt.status = btc_btm_status_to_esp_status(params->conn_rate_change.status); + param.conn_rate_change_evt.conn_handle = params->conn_rate_change.conn_handle; + param.conn_rate_change_evt.conn_interval = params->conn_rate_change.conn_interval; + param.conn_rate_change_evt.subrate_factor = params->conn_rate_change.subrate_factor; + param.conn_rate_change_evt.peripheral_latency = params->conn_rate_change.peripheral_latency; + param.conn_rate_change_evt.continuation_number = params->conn_rate_change.continuation_number; + param.conn_rate_change_evt.supervision_timeout = params->conn_rate_change.supervision_timeout; + break; + } + case BTA_DM_BLE_5_GAP_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT; + param.set_default_rate_parameters_cmpl.status = btc_btm_status_to_esp_status(params->status); + break; + } + case BTA_DM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT; + param.read_min_supp_conn_interval.status = + btc_btm_status_to_esp_status(params->read_min_supp_conn_interval.status); + param.read_min_supp_conn_interval.min_supported_conn_interval = + params->read_min_supp_conn_interval.min_supported_conn_interval; + param.read_min_supp_conn_interval.num_groups = + params->read_min_supp_conn_interval.num_groups; + if (params->read_min_supp_conn_interval.groups != NULL) { + for (uint8_t i = 0; i < params->read_min_supp_conn_interval.num_groups; i++) { + param.read_min_supp_conn_interval.groups[i].min_125us = + params->read_min_supp_conn_interval.groups[i].min_125us; + param.read_min_supp_conn_interval.groups[i].max_125us = + params->read_min_supp_conn_interval.groups[i].max_125us; + param.read_min_supp_conn_interval.groups[i].stride_125us = + params->read_min_supp_conn_interval.groups[i].stride_125us; + } + } else { + memset(param.read_min_supp_conn_interval.groups, 0, + sizeof(param.read_min_supp_conn_interval.groups)); + } + break; + } +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_50_EXTEND_ADV_EN == TRUE) case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT: { param.adv_terminate.status = params->adv_term.status; @@ -3603,6 +3650,34 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) arg_5->read_all_remote_feat.page_requested); break; #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + case BTC_GAP_BLE_CONNECTION_RATE_REQUEST: + BTA_DmBleGapConnectionRateRequest(arg_5->connection_rate_request.conn_handle, + arg_5->connection_rate_request.conn_interval_min, + arg_5->connection_rate_request.conn_interval_max, + arg_5->connection_rate_request.subrate_min, + arg_5->connection_rate_request.subrate_max, + arg_5->connection_rate_request.max_latency, + arg_5->connection_rate_request.continuation_number, + arg_5->connection_rate_request.supervision_timeout, + arg_5->connection_rate_request.min_ce_len, + arg_5->connection_rate_request.max_ce_len); + break; + case BTC_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS: + BTA_DmBleGapSetDefaultRateParameters(arg_5->set_default_rate_parameters.conn_interval_min, + arg_5->set_default_rate_parameters.conn_interval_max, + arg_5->set_default_rate_parameters.subrate_min, + arg_5->set_default_rate_parameters.subrate_max, + arg_5->set_default_rate_parameters.max_latency, + arg_5->set_default_rate_parameters.continuation_number, + arg_5->set_default_rate_parameters.supervision_timeout, + arg_5->set_default_rate_parameters.min_ce_len, + arg_5->set_default_rate_parameters.max_ce_len); + break; + case BTC_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL: + BTA_DmBleGapReadMinSuppConnInterval(); + break; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: BTA_DmBleGapSetPASubevtData(arg_5->per_adv_subevent_data_params.adv_handle, arg_5->per_adv_subevent_data_params.num_subevents_with_data, (uint8_t *)(arg_5->per_adv_subevent_data_params.subevent_params)); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 5c71e6fc9ec..b66538f76a7 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -158,6 +158,11 @@ typedef enum { BTC_GAP_BLE_READ_ALL_LOCAL_SUPP_FEAT, BTC_GAP_BLE_READ_ALL_REMOTE_FEAT, #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + BTC_GAP_BLE_CONNECTION_RATE_REQUEST, + BTC_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS, + BTC_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL, +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) BTC_GAP_BLE_READ_CHANNEL_MAP, #if (BT_BLE_FEAT_PAWR_EN == TRUE) BTC_GAP_BLE_SET_PA_SUBEVT_DATA, @@ -628,6 +633,31 @@ typedef union { uint8_t page_requested; } read_all_remote_feat; #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + struct connection_rate_request_args { + uint16_t conn_handle; + uint16_t conn_interval_min; + uint16_t conn_interval_max; + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t continuation_number; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; + } connection_rate_request; + struct set_default_rate_parameters_args { + uint16_t conn_interval_min; + uint16_t conn_interval_max; + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t continuation_number; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; + } set_default_rate_parameters; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) // BTC_GAP_BLE_SET_PA_SUBEVT_DATA struct per_adv_subevent_data_params_args { 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 7d632153708..1d36d769c7c 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 @@ -370,6 +370,11 @@ #define UC_BT_BLE_FEAT_LL_EXT_FEAT FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_SHORTER_CONN_INTERVALS +#define UC_BT_BLE_FEAT_SHORTER_CONN_INTERVALS CONFIG_BT_BLE_FEAT_SHORTER_CONN_INTERVALS +#else +#define UC_BT_BLE_FEAT_SHORTER_CONN_INTERVALS FALSE +#endif #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN 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 621a805f1db..66266553401 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -431,6 +431,11 @@ #define BLE_FEAT_LL_EXT_FEAT FALSE #endif +#if (BLE_50_FEATURE_SUPPORT == TRUE) && (UC_BT_BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#define BLE_FEAT_SHORTER_CONN_INTERVALS TRUE +#else +#define BLE_FEAT_SHORTER_CONN_INTERVALS FALSE +#endif #if (UC_BT_BLE_VENDOR_HCI_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 1294c5a5bde..e70f3aae9af 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1581,6 +1581,137 @@ void btm_ble_read_all_remote_features_complete_evt(UINT8 *p) } #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +tBTM_STATUS BTM_BleConnectionRateRequest(UINT16 conn_handle, UINT16 conn_interval_min, + UINT16 conn_interval_max, UINT16 subrate_min, + UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len) +{ + tHCI_STATUS err; + + err = btsnd_hcic_ble_connection_rate_request(conn_handle, conn_interval_min, conn_interval_max, + subrate_min, subrate_max, max_latency, + continuation_number, supervision_timeout, + min_ce_len, max_ce_len); + if (err != HCI_SUCCESS) { + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + cb_params.conn_rate_request.status = BTM_HCI_ERROR | err; + cb_params.conn_rate_request.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_CONNECTION_RATE_REQUEST_COMPLETE_EVT, &cb_params); + return BTM_NO_RESOURCES; + } + return BTM_CMD_STARTED; +} + +void btm_conn_rate_req_cmd_status(UINT8 status, UINT16 conn_handle) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (status != HCI_SUCCESS) { + status = (status | BTM_HCI_ERROR); + } + cb_params.conn_rate_request.status = status; + cb_params.conn_rate_request.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_CONNECTION_RATE_REQUEST_COMPLETE_EVT, &cb_params); +} + +void btm_ble_conn_rate_change_evt(tBTM_BLE_CONN_RATE_CHANGE *params) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (!params) { + return; + } + + /* Like btm_ble_subrate_change_evt(), notify the application only. + * Do not fold interval*subrate into L2CAP current_used_conn_interval: + * that field is UINT16 in 1.25 ms units and cannot represent SCI + * effective intervals; apps use ESP_GAP_BLE_CONN_RATE_CHANGE_EVT and + * ESP_BLE_GAP_CONN_RATE_EFF_INTERVAL_US() instead. */ + cb_params.conn_rate_change = *params; + if (cb_params.conn_rate_change.status != HCI_SUCCESS) { + cb_params.conn_rate_change.status |= BTM_HCI_ERROR; + } + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_CONN_RATE_CHANGE_EVT, &cb_params); +} + +void BTM_BleSetDefaultRateParameters(UINT16 conn_interval_min, UINT16 conn_interval_max, + UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_default_rate_parameters(conn_interval_min, conn_interval_max, + subrate_min, subrate_max, max_latency, + continuation_number, supervision_timeout, + min_ce_len, max_ce_len)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT, &cb_params); +} + +tBTM_STATUS BTM_BleReadMinSuppConnInterval(void) +{ + if (!btsnd_hcic_ble_read_min_supp_conn_interval()) { + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + cb_params.read_min_supp_conn_interval.status = BTM_HCI_ERROR | HCI_ERR_MEMORY_FULL; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT, &cb_params); + return BTM_NO_RESOURCES; + } + return BTM_CMD_STARTED; +} + +void btm_ble_read_min_supp_conn_interval_cmd_status(UINT8 status) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (status == HCI_SUCCESS) { + return; + } + + cb_params.read_min_supp_conn_interval.status = status | BTM_HCI_ERROR; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT, &cb_params); +} + +void btm_ble_read_min_supp_conn_interval_complete(UINT8 *p) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + UINT8 num_groups; + + if (!p) { + return; + } + + STREAM_TO_UINT8(cb_params.read_min_supp_conn_interval.status, p); + if (cb_params.read_min_supp_conn_interval.status == HCI_SUCCESS) { + STREAM_TO_UINT8(cb_params.read_min_supp_conn_interval.min_supported_conn_interval, p); + STREAM_TO_UINT8(num_groups, p); + if (num_groups > BTM_BLE_MAX_CONN_INTERVAL_GROUPS) { + BTM_TRACE_WARNING("%s num_groups %u exceeds max %u", __func__, num_groups, + BTM_BLE_MAX_CONN_INTERVAL_GROUPS); + num_groups = BTM_BLE_MAX_CONN_INTERVAL_GROUPS; + } + cb_params.read_min_supp_conn_interval.num_groups = num_groups; + cb_params.read_min_supp_conn_interval.groups = btm_ble_min_conn_interval_groups; + for (UINT8 i = 0; i < num_groups; i++) { + STREAM_TO_UINT16(btm_ble_min_conn_interval_groups[i].min_125us, p); + STREAM_TO_UINT16(btm_ble_min_conn_interval_groups[i].max_125us, p); + STREAM_TO_UINT16(btm_ble_min_conn_interval_groups[i].stride_125us, p); + } + } else { + cb_params.read_min_supp_conn_interval.status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BLE_50_EXTEND_ADV_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 82ef4967f6c..3ca39f4bec7 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 @@ -606,6 +606,10 @@ void btm_ble_frame_space_update_complete_evt(UINT8 *p); void btm_ble_read_all_local_supp_features_complete(UINT8 *p); void btm_ble_read_all_remote_features_complete_evt(UINT8 *p); #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +void btm_ble_conn_rate_change_evt(tBTM_BLE_CONN_RATE_CHANGE *params); +void btm_ble_read_min_supp_conn_interval_complete(UINT8 *p); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) void btm_ble_pa_subevt_data_req_evt(tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT *params); void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 4600b262622..0d0120051e3 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1205,6 +1205,15 @@ void btm_subrate_req_cmd_status(UINT8 status); void btm_frame_space_update_cmd_status(UINT8 status, UINT16 conn_handle); #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) +void btm_read_all_remote_feat_cmd_status(UINT8 status); +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) + +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +void btm_conn_rate_req_cmd_status(UINT8 status, UINT16 conn_handle); +void btm_ble_read_min_supp_conn_interval_cmd_status(UINT8 status); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) void btm_ble_cs_read_local_supp_caps_cmpl_evt(UINT8 *p); void btm_ble_cs_read_remote_supp_caps_cmd_status(UINT8 status); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index fc600fbf50e..f973f66adfa 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1520,6 +1520,11 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_read_all_local_supp_features_complete(p); break; #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + case HCI_BLE_READ_MIN_SUPP_CONN_INTERVAL: + btm_ble_read_min_supp_conn_interval_complete(p); + break; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #endif /* (BLE_INCLUDED == TRUE) */ default: { @@ -1701,6 +1706,26 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c break; } #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LL_EXT_FEAT == TRUE) + case HCI_BLE_READ_ALL_REMOTE_FEATURES: + btm_read_all_remote_feat_cmd_status(status); + break; +#endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + case HCI_BLE_CONNECTION_RATE_REQUEST: + { + UINT16 conn_handle = HCI_INVALID_HANDLE; + if (p_cmd != NULL) { + p_cmd++; /* skip param length */ + STREAM_TO_UINT16(conn_handle, p_cmd); + } + btm_conn_rate_req_cmd_status(status, conn_handle); + break; + } + case HCI_BLE_READ_MIN_SUPP_CONN_INTERVAL: + btm_ble_read_min_supp_conn_interval_cmd_status(status); + break; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) case HCI_BLE_CS_READ_REMOTE_SUPP_CAPS: btm_ble_cs_read_remote_supp_caps_cmd_status(status); diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 0741159f259..d9782abfd7f 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3187,6 +3187,86 @@ UINT8 btsnd_hcic_ble_read_all_remote_features(UINT16 conn_handle, UINT8 page_req #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +UINT8 btsnd_hcic_ble_connection_rate_request(UINT16 conn_handle, UINT16 conn_interval_min, + UINT16 conn_interval_max, UINT16 subrate_min, + UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci conn rate req, handle %u int [%u, %u] subrate [%u, %u] latency %u cont %u timeout %u ce [%u, %u]", + conn_handle, conn_interval_min, conn_interval_max, subrate_min, subrate_max, + max_latency, continuation_number, supervision_timeout, min_ce_len, max_ce_len); + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_CONNECTION_RATE_REQUEST); + UINT16_TO_STREAM(pp, HCI_BLE_CONNECTION_RATE_REQUEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CONNECTION_RATE_REQUEST); + UINT16_TO_STREAM(pp, conn_handle); + UINT16_TO_STREAM(pp, conn_interval_min); + UINT16_TO_STREAM(pp, conn_interval_max); + UINT16_TO_STREAM(pp, subrate_min); + UINT16_TO_STREAM(pp, subrate_max); + UINT16_TO_STREAM(pp, max_latency); + UINT16_TO_STREAM(pp, continuation_number); + UINT16_TO_STREAM(pp, supervision_timeout); + UINT16_TO_STREAM(pp, min_ce_len); + UINT16_TO_STREAM(pp, max_ce_len); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return HCI_SUCCESS; +} + +UINT8 btsnd_hcic_ble_set_default_rate_parameters(UINT16 conn_interval_min, UINT16 conn_interval_max, + UINT16 subrate_min, UINT16 subrate_max, + UINT16 max_latency, UINT16 continuation_number, + UINT16 supervision_timeout, UINT16 min_ce_len, + UINT16 max_ce_len) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set default rate, int [%u, %u] subrate [%u, %u] latency %u cont %u timeout %u ce [%u, %u]", + conn_interval_min, conn_interval_max, subrate_min, subrate_max, + max_latency, continuation_number, supervision_timeout, min_ce_len, max_ce_len); + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_SET_DEFAULT_RATE_PARAMETERS); + UINT16_TO_STREAM(pp, HCI_BLE_SET_DEFAULT_RATE_PARAMETERS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_DEFAULT_RATE_PARAMETERS); + UINT16_TO_STREAM(pp, conn_interval_min); + UINT16_TO_STREAM(pp, conn_interval_max); + UINT16_TO_STREAM(pp, subrate_min); + UINT16_TO_STREAM(pp, subrate_max); + UINT16_TO_STREAM(pp, max_latency); + UINT16_TO_STREAM(pp, continuation_number); + UINT16_TO_STREAM(pp, supervision_timeout); + UINT16_TO_STREAM(pp, min_ce_len); + UINT16_TO_STREAM(pp, max_ce_len); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +BOOLEAN btsnd_hcic_ble_read_min_supp_conn_interval(void) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF(0)) == NULL) { + return FALSE; + } + pp = (UINT8 *)(p + 1); + p->len = HCIC_PREAMBLE_SIZE; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_READ_MIN_SUPP_CONN_INTERVAL); + UINT8_TO_STREAM(pp, 0); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_subevents_with_data, ble_subevent_params *subevent_params) 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 1b4ad689170..eb2428c1764 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 @@ -1001,6 +1001,12 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_SET_DECISION_DATA_COMPLETE_EVT 79 #define BTM_BLE_5_GAP_SET_DECISION_INSTRUCTIONS_COMPLETE_EVT 80 #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#define BTM_BLE_5_GAP_CONNECTION_RATE_REQUEST_COMPLETE_EVT 81 +#define BTM_BLE_5_GAP_CONN_RATE_CHANGE_EVT 82 +#define BTM_BLE_5_GAP_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT 86 +#define BTM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT 87 +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #define BTM_BLE_5_GAP_UNKNOWN_EVT 91 typedef UINT8 tBTM_BLE_5_GAP_EVENT; @@ -1282,6 +1288,37 @@ typedef struct { } tBTM_BLE_FRAME_SPACE_UPDATE; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +typedef struct { + tBTM_STATUS status; + UINT16 conn_handle; +} tBTM_BLE_CONNECTION_RATE_REQUEST_CMPL; + +typedef struct { + tBTM_STATUS status; + UINT16 conn_handle; + UINT16 conn_interval; + UINT16 subrate_factor; + UINT16 peripheral_latency; + UINT16 continuation_number; + UINT16 supervision_timeout; +} tBTM_BLE_CONN_RATE_CHANGE; + +#define BTM_BLE_MAX_CONN_INTERVAL_GROUPS 41 + +typedef struct { + UINT16 min_125us; + UINT16 max_125us; + UINT16 stride_125us; +} tBTM_BLE_MIN_CONN_INTERVAL_GROUP; + +typedef struct { + tBTM_STATUS status; + UINT8 min_supported_conn_interval; + UINT8 num_groups; + tBTM_BLE_MIN_CONN_INTERVAL_GROUP *groups; +} tBTM_BLE_READ_MIN_SUPP_CONN_INTERVAL; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) typedef struct { @@ -2001,6 +2038,11 @@ typedef union { #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) tBTM_BLE_FRAME_SPACE_UPDATE frame_space_update; #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) + tBTM_BLE_CONNECTION_RATE_REQUEST_CMPL conn_rate_request; + tBTM_BLE_CONN_RATE_CHANGE conn_rate_change; + tBTM_BLE_READ_MIN_SUPP_CONN_INTERVAL read_min_supp_conn_interval; +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -3179,6 +3221,18 @@ tBTM_STATUS BTM_BleReadAllLocalSuppFeatures(void); tBTM_STATUS BTM_BleReadAllRemoteFeatures(UINT16 conn_handle, UINT8 page_requested); #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +tBTM_STATUS BTM_BleConnectionRateRequest(UINT16 conn_handle, UINT16 conn_interval_min, + UINT16 conn_interval_max, UINT16 subrate_min, + UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len); +void BTM_BleSetDefaultRateParameters(UINT16 conn_interval_min, UINT16 conn_interval_max, + UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len); +tBTM_STATUS BTM_BleReadMinSuppConnInterval(void); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 8aa44bda5f9..c96524d626d 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -495,6 +495,11 @@ +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#define HCI_BLE_CONNECTION_RATE_REQUEST (0x00A1 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_DEFAULT_RATE_PARAMETERS (0x00A2 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_READ_MIN_SUPP_CONN_INTERVAL (0x00A3 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -1000,6 +1005,9 @@ #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#define HCI_BLE_CONN_RATE_CHANGE_EVT 0x37 +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #define HCI_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT 0x2C diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index cdc98c943cc..75c4f7ed95e 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -859,6 +859,22 @@ UINT8 btsnd_hcic_ble_read_all_remote_features(UINT16 conn_handle, UINT8 page_req #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#define HCIC_PARAM_SIZE_CONNECTION_RATE_REQUEST 20 +#define HCIC_PARAM_SIZE_SET_DEFAULT_RATE_PARAMETERS 18 + +UINT8 btsnd_hcic_ble_connection_rate_request(UINT16 conn_handle, UINT16 conn_interval_min, + UINT16 conn_interval_max, UINT16 subrate_min, + UINT16 subrate_max, UINT16 max_latency, + UINT16 continuation_number, UINT16 supervision_timeout, + UINT16 min_ce_len, UINT16 max_ce_len); +UINT8 btsnd_hcic_ble_set_default_rate_parameters(UINT16 conn_interval_min, UINT16 conn_interval_max, + UINT16 subrate_min, UINT16 subrate_max, + UINT16 max_latency, UINT16 continuation_number, + UINT16 supervision_timeout, UINT16 min_ce_len, + UINT16 max_ce_len); +BOOLEAN btsnd_hcic_ble_read_min_supp_conn_interval(void); +#endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) /* ULP HCI command */ BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask); From ea68f1efd1ad093d993d0aa1095f49a232bf48e0 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Fri, 26 Jun 2026 09:08:16 +0800 Subject: [PATCH 5/6] feat(ble/bluedroid): add LE UTP host support (Core 6.2) (cherry picked from commit 3844e242076dac335f6f9a15247348b0417c020b) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/Kconfig.in | 8 +++ .../bt/host/bluedroid/api/esp_gap_ble_api.c | 44 ++++++++++++ .../api/include/api/esp_gap_ble_api.h | 67 ++++++++++++++++++- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 11 +++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 35 ++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 ++ .../bluedroid/bta/dm/include/bta_dm_int.h | 27 ++++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 9 +++ .../btc/profile/std/gap/btc_gap_ble.c | 58 ++++++++++++++++ .../btc/profile/std/include/btc_gap_ble.h | 13 ++++ .../include/common/bluedroid_user_config.h | 19 ++++-- .../common/include/common/bt_target.h | 5 ++ .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 52 ++++++++++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 3 + .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 42 ++++++++++++ .../stack/include/stack/btm_ble_api.h | 18 +++++ .../bluedroid/stack/include/stack/hcidefs.h | 7 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 9 +++ 18 files changed, 423 insertions(+), 8 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index a5304797378..10584dbff98 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1562,6 +1562,14 @@ config BT_BLE_FEAT_SHORTER_CONN_INTERVALS esp_ble_gap_set_default_rate_parameters(), esp_ble_gap_read_min_supported_connection_interval() and ESP_BLE_GAP_CONN_RATE_* conversion macros in esp_gap_ble_api.h. +config BT_BLE_FEAT_LE_UTP + bool "Enable BLE Unified Test Protocol (UTP)" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_LE_UTP_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable LE Unified Test Protocol (Bluetooth Core 6.2). + Supports LE Enable UTP OTA Mode, LE UTP Send commands and LE UTP Receive event. + menuconfig BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 132aa31e773..718faa8bf3a 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2249,6 +2249,50 @@ esp_err_t esp_ble_gap_read_min_supported_connection_interval(void) } #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +esp_err_t esp_ble_gap_enable_utp_ota_mode(const esp_ble_gap_enable_utp_ota_mode_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL || params->enable > 1) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ENABLE_UTP_OTA_MODE; + arg.enable_utp_ota_mode.enable = params->enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_utp_send(const esp_ble_gap_utp_send_params_t *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (params == NULL || params->data == NULL || + params->data_len == 0 || params->data_len > ESP_BLE_GAP_UTP_DATA_MAX_LEN) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_UTP_SEND; + arg.utp_send.data_len = params->data_len; + arg.utp_send.data = (uint8_t *)params->data; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), + btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 257e081c929..5571130b3be 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -282,6 +282,9 @@ typedef enum { ESP_GAP_BLE_CONN_RATE_CHANGE_EVT, /*!< When connection rate change event is received, the event comes */ ESP_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT, /*!< When set default rate parameters complete, the event comes */ ESP_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT, /*!< When read minimum supported connection interval complete, the event comes */ + ESP_GAP_BLE_ENABLE_UTP_OTA_MODE_COMPLETE_EVT, /*!< When enable UTP OTA mode complete, the event comes */ + ESP_GAP_BLE_UTP_SEND_COMPLETE_EVT, /*!< When UTP send complete, the event comes */ + ESP_GAP_BLE_UTP_RECEIVE_EVT, /*!< When UTP data is received, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1411,6 +1414,24 @@ typedef struct { } esp_ble_gap_min_conn_interval_group_t; #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +#define ESP_BLE_GAP_UTP_DATA_MAX_LEN 254 + +/** + * @brief Parameters for enabling or disabling LE Unified Test Protocol (UTP) OTA mode + */ +typedef struct { + uint8_t enable; /*!< 0x00: Disable UTP OTA mode, 0x01: Enable UTP OTA mode */ +} esp_ble_gap_enable_utp_ota_mode_params_t; + +/** + * @brief Parameters for sending LE Unified Test Protocol (UTP) data + */ +typedef struct { + uint8_t data_len; /*!< UTP data length, range: 0x01 to 0xFE */ + const uint8_t *data; /*!< Pointer to UTP data */ +} esp_ble_gap_utp_send_params_t; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) typedef enum { ESP_BLE_NETWORK_PRIVACY_MODE = 0X00, /*!< Network Privacy Mode for peer device (default) */ @@ -2449,9 +2470,30 @@ typedef union { esp_bt_status_t status; /*!< Indicate read minimum supported connection interval operation success status */ uint8_t min_supported_conn_interval; /*!< Minimum supported connection interval in 125 us units */ uint8_t num_groups; /*!< Number of supported interval groups; 0 if only RCV is supported */ - esp_ble_gap_min_conn_interval_group_t groups[ESP_BLE_GAP_CONN_RATE_MAX_INTERVAL_GROUPS]; + esp_ble_gap_min_conn_interval_group_t groups[ESP_BLE_GAP_CONN_RATE_MAX_INTERVAL_GROUPS]; /*!< Supported interval groups; valid when num_groups > 0 */ } read_min_supp_conn_interval; /*!< Event parameter of ESP_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT */ #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + /** + * @brief ESP_GAP_BLE_ENABLE_UTP_OTA_MODE_COMPLETE_EVT + */ + struct ble_enable_utp_ota_mode_cmpl_param { + esp_bt_status_t status; /*!< Indicate enable UTP OTA mode operation success status */ + } enable_utp_ota_mode_cmpl; /*!< Event parameter of ESP_GAP_BLE_ENABLE_UTP_OTA_MODE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_UTP_SEND_COMPLETE_EVT + */ + struct ble_utp_send_cmpl_param { + esp_bt_status_t status; /*!< Indicate UTP send operation success status */ + } utp_send_cmpl; /*!< Event parameter of ESP_GAP_BLE_UTP_SEND_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_UTP_RECEIVE_EVT + */ + struct ble_utp_receive_evt { + uint8_t len; /*!< UTP data length */ + uint8_t data[ESP_BLE_GAP_UTP_DATA_MAX_LEN]; /*!< UTP data */ + } utp_receive; /*!< Event parameter of ESP_GAP_BLE_UTP_RECEIVE_EVT */ +#endif // #if (BLE_FEAT_LE_UTP == TRUE) /** * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ @@ -4429,6 +4471,29 @@ esp_err_t esp_ble_gap_set_default_rate_parameters(const esp_ble_gap_default_rate esp_err_t esp_ble_gap_read_min_supported_connection_interval(void); #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +/** +* @brief Enable or disable LE Unified Test Protocol (UTP) OTA mode. +* +* @param[in] params : Pointer to enable UTP OTA mode parameters. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_enable_utp_ota_mode(const esp_ble_gap_enable_utp_ota_mode_params_t *params); + +/** +* @brief Send LE UTP data. +* +* @param[in] params : Pointer to UTP send parameters. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_utp_send(const esp_ble_gap_utp_send_params_t *params); +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) 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 615ba3e56de..b00f23c8b00 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6062,6 +6062,17 @@ void bta_dm_ble_gap_read_min_supp_conn_interval(tBTA_DM_MSG *p_data) } #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +void bta_dm_ble_gap_enable_utp_ota_mode(tBTA_DM_MSG *p_data) +{ + BTM_BleEnableUtpOtaMode(p_data->ble_enable_utp_ota_mode.enable); +} + +void bta_dm_ble_gap_utp_send(tBTA_DM_MSG *p_data) +{ + BTM_BleUtpSend(p_data->ble_utp_send.data_len, p_data->ble_utp_send.data); +} +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_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 5e1c7211075..6ccc7e9d1ea 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3428,6 +3428,41 @@ void BTA_DmBleGapReadMinSuppConnInterval(void) } #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +void BTA_DmBleGapEnableUtpOtaMode(UINT8 enable) +{ + tBTA_DM_API_BLE_ENABLE_UTP_OTA_MODE *p_msg; + APPL_TRACE_API("%s", __func__); + if ((p_msg = (tBTA_DM_API_BLE_ENABLE_UTP_OTA_MODE *) + osi_malloc(sizeof(tBTA_DM_API_BLE_ENABLE_UTP_OTA_MODE))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_ENABLE_UTP_OTA_MODE)); + p_msg->hdr.event = BTA_DM_API_ENABLE_UTP_OTA_MODE_EVT; + p_msg->enable = enable; + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapUtpSend(UINT8 data_len, const UINT8 *p_data) +{ + tBTA_DM_API_BLE_UTP_SEND *p_msg; + APPL_TRACE_API("%s", __func__); + if (data_len == 0 || data_len > BLE_UTP_DATA_MAX_LEN || p_data == NULL) { + APPL_TRACE_ERROR("%s invalid params", __func__); + return; + } + if ((p_msg = (tBTA_DM_API_BLE_UTP_SEND *) osi_malloc(sizeof(tBTA_DM_API_BLE_UTP_SEND))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_UTP_SEND)); + p_msg->hdr.event = BTA_DM_API_UTP_SEND_EVT; + p_msg->data_len = data_len; + memcpy(p_msg->data, p_data, data_len); + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) 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 96697706b4e..b85c91663b9 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -344,6 +344,10 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_set_default_rate_parameters, /* BTA_DM_API_SET_DEFAULT_RATE_PARAMETERS_EVT */ bta_dm_ble_gap_read_min_supp_conn_interval, /* BTA_DM_API_READ_MIN_SUPP_CONN_INTERVAL_EVT */ #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + bta_dm_ble_gap_enable_utp_ota_mode, /* BTA_DM_API_ENABLE_UTP_OTA_MODE_EVT */ + bta_dm_ble_gap_utp_send, /* BTA_DM_API_UTP_SEND_EVT */ +#endif // #if (BLE_FEAT_LE_UTP == 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 396abcd3946..eed23f69050 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 @@ -25,6 +25,9 @@ #define BTA_DM_INT_H #include "common/bt_target.h" +#if (BLE_FEAT_DBAF == TRUE) || (BLE_FEAT_LL_EXT_FEAT == TRUE) || (BLE_FEAT_LE_UTP == TRUE) +#include "stack/hcimsgs.h" +#endif #include "freertos/semphr.h" #include "bta/bta_sys.h" #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) @@ -338,6 +341,10 @@ enum { BTA_DM_API_SET_DEFAULT_RATE_PARAMETERS_EVT, BTA_DM_API_READ_MIN_SUPP_CONN_INTERVAL_EVT, #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + BTA_DM_API_ENABLE_UTP_OTA_MODE_EVT, + BTA_DM_API_UTP_SEND_EVT, +#endif // #if (BLE_FEAT_LE_UTP == TRUE) BTA_DM_MAX_EVT }; @@ -1468,6 +1475,18 @@ typedef struct { } tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL; #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +typedef struct { + BT_HDR hdr; + UINT8 enable; +} tBTA_DM_API_BLE_ENABLE_UTP_OTA_MODE; + +typedef struct { + BT_HDR hdr; + UINT8 data_len; + UINT8 data[BLE_UTP_DATA_MAX_LEN]; +} tBTA_DM_API_BLE_UTP_SEND; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) typedef struct { BT_HDR hdr; @@ -1921,6 +1940,10 @@ typedef union { tBTA_DM_API_BLE_SET_DEFAULT_RATE_PARAMETERS ble_set_default_rate_parameters; tBTA_DM_API_BLE_READ_MIN_SUPP_CONN_INTERVAL ble_read_min_supp_conn_interval; #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + tBTA_DM_API_BLE_ENABLE_UTP_OTA_MODE ble_enable_utp_ota_mode; + tBTA_DM_API_BLE_UTP_SEND ble_utp_send; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_42_DTM_TEST_EN == TRUE) tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; @@ -2620,6 +2643,10 @@ extern void bta_dm_ble_gap_set_default_rate_parameters(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_read_min_supp_conn_interval(tBTA_DM_MSG *p_data); #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +extern void bta_dm_ble_gap_enable_utp_ota_mode(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_utp_send(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) 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 27b1cde936b..5295770db22 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1626,6 +1626,11 @@ typedef struct { #define BTA_DM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT BTM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +#define BTA_DM_BLE_5_GAP_ENABLE_UTP_OTA_MODE_COMPLETE_EVT BTM_BLE_5_GAP_ENABLE_UTP_OTA_MODE_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_UTP_SEND_COMPLETE_EVT BTM_BLE_5_GAP_UTP_SEND_COMPLETE_EVT +#define BTA_DM_BLE_5_GAP_UTP_RECEIVE_EVT BTM_BLE_5_GAP_UTP_RECEIVE_EVT +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) #define BTA_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT BTM_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT @@ -3112,6 +3117,10 @@ extern void BTA_DmBleGapSetDefaultRateParameters(UINT16 conn_interval_min, UINT1 extern void BTA_DmBleGapReadMinSuppConnInterval(void); #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +extern void BTA_DmBleGapEnableUtpOtaMode(UINT8 enable); +extern void BTA_DmBleGapUtpSend(UINT8 data_len, const UINT8 *p_data); +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 9b304a559c4..0d8e2ca07c9 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1382,6 +1382,29 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, break; } #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + case BTA_DM_BLE_5_GAP_ENABLE_UTP_OTA_MODE_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_ENABLE_UTP_OTA_MODE_COMPLETE_EVT; + param.enable_utp_ota_mode_cmpl.status = btc_btm_status_to_esp_status(params->status); + break; + } + case BTA_DM_BLE_5_GAP_UTP_SEND_COMPLETE_EVT: { + msg.act = ESP_GAP_BLE_UTP_SEND_COMPLETE_EVT; + param.utp_send_cmpl.status = btc_btm_status_to_esp_status(params->status); + break; + } + case BTA_DM_BLE_5_GAP_UTP_RECEIVE_EVT: { + msg.act = ESP_GAP_BLE_UTP_RECEIVE_EVT; + param.utp_receive.len = params->utp_receive.len; + if (params->utp_receive.data && params->utp_receive.len > 0) { + if (params->utp_receive.len > ESP_BLE_GAP_UTP_DATA_MAX_LEN) { + param.utp_receive.len = ESP_BLE_GAP_UTP_DATA_MAX_LEN; + } + memcpy(param.utp_receive.data, params->utp_receive.data, param.utp_receive.len); + } + break; + } +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_50_EXTEND_ADV_EN == TRUE) case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT: { param.adv_terminate.status = params->adv_term.status; @@ -2654,6 +2677,24 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) break; } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + case BTC_GAP_BLE_UTP_SEND: { + btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; + btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + + dst->utp_send.data = NULL; + if (src->utp_send.data_len > 0 && src->utp_send.data) { + dst->utp_send.data = osi_malloc(src->utp_send.data_len); + if (dst->utp_send.data) { + memcpy(dst->utp_send.data, src->utp_send.data, src->utp_send.data_len); + } else { + BTC_TRACE_WARNING("%s no mem, utp data drop %u", __func__, src->utp_send.data_len); + dst->utp_send.data_len = 0; + } + } + break; + } +#endif // #if (BLE_FEAT_LE_UTP == TRUE) default: BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act); break; @@ -2958,6 +2999,15 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg) break; } #endif // #if (BLE_FEAT_DBAF == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + case BTC_GAP_BLE_UTP_SEND: { + uint8_t *data = ((btc_ble_5_gap_args_t *)msg->arg)->utp_send.data; + if (data) { + osi_free(data); + } + break; + } +#endif // #if (BLE_FEAT_LE_UTP == TRUE) default: BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act); break; @@ -3678,6 +3728,14 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapReadMinSuppConnInterval(); break; #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + case BTC_GAP_BLE_ENABLE_UTP_OTA_MODE: + BTA_DmBleGapEnableUtpOtaMode(arg_5->enable_utp_ota_mode.enable); + break; + case BTC_GAP_BLE_UTP_SEND: + BTA_DmBleGapUtpSend(arg_5->utp_send.data_len, arg_5->utp_send.data); + break; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: BTA_DmBleGapSetPASubevtData(arg_5->per_adv_subevent_data_params.adv_handle, arg_5->per_adv_subevent_data_params.num_subevents_with_data, (uint8_t *)(arg_5->per_adv_subevent_data_params.subevent_params)); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index b66538f76a7..7f4d6e590f8 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -163,6 +163,10 @@ typedef enum { BTC_GAP_BLE_SET_DEFAULT_RATE_PARAMETERS, BTC_GAP_BLE_READ_MIN_SUPP_CONN_INTERVAL, #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + BTC_GAP_BLE_ENABLE_UTP_OTA_MODE, + BTC_GAP_BLE_UTP_SEND, +#endif // #if (BLE_FEAT_LE_UTP == TRUE) BTC_GAP_BLE_READ_CHANNEL_MAP, #if (BT_BLE_FEAT_PAWR_EN == TRUE) BTC_GAP_BLE_SET_PA_SUBEVT_DATA, @@ -658,6 +662,15 @@ typedef union { uint16_t max_ce_len; } set_default_rate_parameters; #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + struct enable_utp_ota_mode_args { + uint8_t enable; + } enable_utp_ota_mode; + struct utp_send_args { + uint8_t data_len; + uint8_t *data; + } utp_send; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) // BTC_GAP_BLE_SET_PA_SUBEVT_DATA struct per_adv_subevent_data_params_args { 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 1d36d769c7c..66575a782fd 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 @@ -350,13 +350,6 @@ #define UC_BT_BLE_FEAT_ADV_MONITOR FALSE #endif -#ifdef CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE -#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE -#else -#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE FALSE -#endif - - #ifdef CONFIG_BT_BLE_FEAT_DBAF #define UC_BT_BLE_FEAT_DBAF CONFIG_BT_BLE_FEAT_DBAF #else @@ -376,6 +369,18 @@ #define UC_BT_BLE_FEAT_SHORTER_CONN_INTERVALS FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_LE_UTP +#define UC_BT_BLE_FEAT_LE_UTP CONFIG_BT_BLE_FEAT_LE_UTP +#else +#define UC_BT_BLE_FEAT_LE_UTP FALSE +#endif + +#ifdef CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE +#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE +#else +#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE FALSE +#endif + #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN #define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN 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 66266553401..14a68cacd7a 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -437,6 +437,11 @@ #define BLE_FEAT_SHORTER_CONN_INTERVALS FALSE #endif +#if (BLE_50_FEATURE_SUPPORT == TRUE) && (UC_BT_BLE_FEAT_LE_UTP == TRUE) +#define BLE_FEAT_LE_UTP TRUE +#else +#define BLE_FEAT_LE_UTP FALSE +#endif #if (UC_BT_BLE_VENDOR_HCI_EN == TRUE) #define BLE_VENDOR_HCI_EN TRUE diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index e70f3aae9af..4ccdec8174e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1713,6 +1713,58 @@ void btm_ble_read_min_supp_conn_interval_complete(UINT8 *p) } #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +tBTM_STATUS BTM_BleEnableUtpOtaMode(UINT8 enable) +{ + tHCI_STATUS err; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_enable_utp_ota_mode(enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE EnableUtpOtaMode: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_ENABLE_UTP_OTA_MODE_COMPLETE_EVT, &cb_params); + return status; +} + +tBTM_STATUS BTM_BleUtpSend(UINT8 data_len, const UINT8 *p_data) +{ + tHCI_STATUS err; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_utp_send(data_len, p_data)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE UtpSend: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_UTP_SEND_COMPLETE_EVT, &cb_params); + return status; +} + +void btm_ble_utp_receive_evt(UINT8 *p, UINT16 len) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + UINT8 data_len; + + if (!p || len < 1) { + return; + } + + STREAM_TO_UINT8(data_len, p); + if (data_len == 0 || len < (UINT16)(1 + data_len)) { + return; + } + + cb_params.utp_receive.len = data_len; + cb_params.utp_receive.data = p; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_UTP_RECEIVE_EVT, &cb_params); +} +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_50_EXTEND_ADV_EN == TRUE) void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params) 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 3ca39f4bec7..398c2fec990 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 @@ -610,6 +610,9 @@ void btm_ble_read_all_remote_features_complete_evt(UINT8 *p); void btm_ble_conn_rate_change_evt(tBTM_BLE_CONN_RATE_CHANGE *params); void btm_ble_read_min_supp_conn_interval_complete(UINT8 *p); #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +void btm_ble_utp_receive_evt(UINT8 *p, UINT16 len); +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BT_BLE_FEAT_PAWR_EN == TRUE) void btm_ble_pa_subevt_data_req_evt(tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT *params); void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params); diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index d9782abfd7f..cb725a94ba2 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3186,6 +3186,48 @@ UINT8 btsnd_hcic_ble_read_all_remote_features(UINT16 conn_handle, UINT8 page_req } #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +UINT8 btsnd_hcic_ble_enable_utp_ota_mode(UINT8 enable) +{ + BT_HDR *p; + UINT8 *pp; + + if (enable > 1) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_ENABLE_UTP_OTA_MODE); + UINT16_TO_STREAM(pp, HCI_BLE_ENABLE_UTP_OTA_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ENABLE_UTP_OTA_MODE); + UINT8_TO_STREAM(pp, enable); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_utp_send(UINT8 data_len, const UINT8 *p_data) +{ + BT_HDR *p; + UINT8 *pp; + UINT16 param_len; + + if (data_len == 0 || data_len > BLE_UTP_DATA_MAX_LEN || p_data == NULL) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + param_len = HCIC_PARAM_SIZE_UTP_SEND_HDR + data_len; + if (param_len > HCIC_PARAM_SIZE_UTP_SEND_MAX) { + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + + HCIC_BLE_CMD_CREATED_U8(p, pp, param_len); + UINT16_TO_STREAM(pp, HCI_BLE_UTP_SEND); + UINT8_TO_STREAM(pp, param_len); + UINT8_TO_STREAM(pp, data_len); + ARRAY_TO_STREAM(pp, p_data, data_len); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) UINT8 btsnd_hcic_ble_connection_rate_request(UINT16 conn_handle, UINT16 conn_interval_min, 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 eb2428c1764..cdc884c627d 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 @@ -1007,6 +1007,11 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_SET_DEFAULT_RATE_PARAMETERS_COMPLETE_EVT 86 #define BTM_BLE_5_GAP_READ_MIN_SUPP_CONN_INTERVAL_COMPLETE_EVT 87 #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +#define BTM_BLE_5_GAP_ENABLE_UTP_OTA_MODE_COMPLETE_EVT 83 +#define BTM_BLE_5_GAP_UTP_SEND_COMPLETE_EVT 84 +#define BTM_BLE_5_GAP_UTP_RECEIVE_EVT 85 +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #define BTM_BLE_5_GAP_UNKNOWN_EVT 91 typedef UINT8 tBTM_BLE_5_GAP_EVENT; @@ -1320,6 +1325,12 @@ typedef struct { } tBTM_BLE_READ_MIN_SUPP_CONN_INTERVAL; #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +typedef struct { + UINT8 len; + UINT8 *data; +} tBTM_BLE_UTP_RECEIVE; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) typedef struct { UINT16 sync_handle; @@ -2043,6 +2054,9 @@ typedef union { tBTM_BLE_CONN_RATE_CHANGE conn_rate_change; tBTM_BLE_READ_MIN_SUPP_CONN_INTERVAL read_min_supp_conn_interval; #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) + tBTM_BLE_UTP_RECEIVE utp_receive; +#endif // #if (BLE_FEAT_LE_UTP == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -3234,6 +3248,10 @@ void BTM_BleSetDefaultRateParameters(UINT16 conn_interval_min, UINT16 conn_inter tBTM_STATUS BTM_BleReadMinSuppConnInterval(void); #endif // #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +tBTM_STATUS BTM_BleEnableUtpOtaMode(UINT8 enable); +tBTM_STATUS BTM_BleUtpSend(UINT8 data_len, const UINT8 *p_data); +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_50_DTM_TEST_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index c96524d626d..14259213170 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -494,6 +494,10 @@ #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +#define HCI_BLE_ENABLE_UTP_OTA_MODE (0x009F | HCI_GRP_BLE_CMDS) +#define HCI_BLE_UTP_SEND (0x00A0 | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #define HCI_BLE_CONNECTION_RATE_REQUEST (0x00A1 | HCI_GRP_BLE_CMDS) @@ -1004,6 +1008,9 @@ #define HCI_BLE_FRAME_SPACE_UPDATE_COMPLETE_EVT 0x35 #endif // #if (BLE_FEAT_FRAME_SPACE_UPDATE == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +#define HCI_BLE_UTP_RECEIVE_EVT 0x36 +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #define HCI_BLE_CONN_RATE_CHANGE_EVT 0x37 diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 75c4f7ed95e..f9e6c91c20d 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -858,6 +858,15 @@ BOOLEAN btsnd_hcic_ble_read_all_local_supp_features(void); UINT8 btsnd_hcic_ble_read_all_remote_features(UINT16 conn_handle, UINT8 page_requested); #endif // #if (BLE_FEAT_LL_EXT_FEAT == TRUE) +#if (BLE_FEAT_LE_UTP == TRUE) +#define HCIC_PARAM_SIZE_ENABLE_UTP_OTA_MODE 1 +#define HCIC_PARAM_SIZE_UTP_SEND_HDR 1 +#define HCIC_PARAM_SIZE_UTP_SEND_MAX 255 +#define BLE_UTP_DATA_MAX_LEN 254 + +UINT8 btsnd_hcic_ble_enable_utp_ota_mode(UINT8 enable); +UINT8 btsnd_hcic_ble_utp_send(UINT8 data_len, const UINT8 *p_data); +#endif // #if (BLE_FEAT_LE_UTP == TRUE) #if (BLE_FEAT_SHORTER_CONN_INTERVALS == TRUE) #define HCIC_PARAM_SIZE_CONNECTION_RATE_REQUEST 20 From a842d54f4deece9c9693e951052bfdbaf60d0188 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Fri, 26 Jun 2026 09:08:17 +0800 Subject: [PATCH 6/6] feat(ble/bluedroid): add CS Security Requirements host support (Core 6.3) (cherry picked from commit 919622c01ce8f05de41ad2c033fdfa947d84c44c) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/Kconfig.in | 16 +++- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 52 +++++++++++ .../api/include/api/esp_gap_ble_api.h | 89 +++++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 12 +++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 27 ++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 + .../bluedroid/bta/dm/include/bta_dm_int.h | 24 +++++ .../host/bluedroid/bta/include/bta/bta_api.h | 8 ++ .../btc/profile/std/gap/btc_gap_ble.c | 20 +++++ .../btc/profile/std/include/btc_gap_ble.h | 14 +++ .../include/common/bluedroid_user_config.h | 17 ++-- .../common/include/common/bt_target.h | 5 ++ .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 36 ++++++++ .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 39 ++++++++ .../stack/include/stack/btm_ble_api.h | 24 ++++- .../bluedroid/stack/include/stack/hcidefs.h | 4 + .../bluedroid/stack/include/stack/hcimsgs.h | 7 ++ 17 files changed, 389 insertions(+), 9 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 10584dbff98..8b2006baba8 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1516,7 +1516,21 @@ config BT_BLE_FEAT_CHANNEL_SOUNDING depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_CHANNEL_SOUNDING_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR default n help - Enable BLE channel sounding + Enable BLE channel sounding. + CS Security Requirements (Core 6.3) is configured separately via + BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS. + +config BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS + bool "Enable BLE CS Security Requirements (Core 6.3)" + depends on BT_BLE_FEAT_CHANNEL_SOUNDING && ((BT_CONTROLLER_ENABLED && SOC_BLE_CS_SECURITY_REQUIREMENTS_SUPPORTED) || BT_CONTROLLER_DISABLED) # NOERROR + default n + help + Enable Channel Sounding security requirements HCI commands (Bluetooth Core 6.3). + Supports LE CS Set Security Requirements (0x00A7) and + LE CS Set Default Security Requirements (0x00A8). + Use esp_ble_cs_set_security_requirements() and + esp_ble_cs_set_default_security_requirements(). + config BT_BLE_FEAT_ADV_MONITOR bool "Enable BLE Advertising Monitor (LE Monitor Advertisement)" depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_ADV_MONITOR_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 718faa8bf3a..eca58b2515e 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2945,6 +2945,58 @@ esp_err_t esp_ble_cs_security_enable(uint16_t conn_handle) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +/* Host does not validate conn_handle range or CS_Security_Requirements reserved bits; Controller checks. */ +esp_err_t esp_ble_cs_set_security_requirements(esp_ble_cs_set_security_requirements_params *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!params) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS; + + arg.cs_set_security_requirements_params.conn_handle = params->conn_handle; + arg.cs_set_security_requirements_params.cs_security_requirements = params->cs_security_requirements; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +/* Host does not validate CS_Security_Requirements reserved bits; Controller checks. */ +esp_err_t esp_ble_cs_set_default_security_requirements(esp_ble_cs_set_default_security_requirements_params *params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + memset(&arg, 0, sizeof(arg)); + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!params) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS; + + arg.cs_set_default_security_requirements_params.cs_security_requirements = params->cs_security_requirements; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) esp_err_t esp_ble_cs_set_default_settings(esp_ble_cs_set_default_settings_params *default_setting_params) { diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 5571130b3be..b76289d8bf8 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -285,6 +285,8 @@ typedef enum { ESP_GAP_BLE_ENABLE_UTP_OTA_MODE_COMPLETE_EVT, /*!< When enable UTP OTA mode complete, the event comes */ ESP_GAP_BLE_UTP_SEND_COMPLETE_EVT, /*!< When UTP send complete, the event comes */ ESP_GAP_BLE_UTP_RECEIVE_EVT, /*!< When UTP data is received, the event comes */ + ESP_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT, /*!< When CS set security requirements complete, the event comes */ + ESP_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT, /*!< When CS set default security requirements complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1730,6 +1732,33 @@ typedef enum { /** Reflector role is enabled */ #define ESP_BLE_CS_REFLECTOR_ROLE_ENABLED (1 << 1) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +/** CS tone security requirement (bit 0 of CS_Security_Requirements) */ +#define ESP_BLE_CS_SECURITY_REQUIREMENT_CS_TONE (1ULL << 0) +/** 150 ns RTT accuracy security requirement (bit 1) */ +#define ESP_BLE_CS_SECURITY_REQUIREMENT_RTT_150NS_ACCURACY (1ULL << 1) +/** 10 ns RTT accuracy security requirement (bit 2) */ +#define ESP_BLE_CS_SECURITY_REQUIREMENT_RTT_10NS_ACCURACY (1ULL << 2) +/** RTT sounding sequence or random sequence security requirement (bit 3) */ +#define ESP_BLE_CS_SECURITY_REQUIREMENT_RTT_SOUNDING_OR_RANDOM (1ULL << 3) +/** Normalized Attack Detector Metric security requirement (bit 4) */ +#define ESP_BLE_CS_SECURITY_REQUIREMENT_NADM (1ULL << 4) + +/** +* @brief CS set security requirements parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle. Host does not validate the handle range; the Controller checks it (0x0000 to 0x0EFF). */ + uint64_t cs_security_requirements; /*!< 8-octet CS security requirements bitmask (bits 0-4). Host does not validate reserved bits 5-63; the Controller checks they are zero. */ +} esp_ble_cs_set_security_requirements_params; + +/** +* @brief CS set default security requirements parameters +*/ +typedef struct { + uint64_t cs_security_requirements; /*!< 8-octet CS security requirements bitmask for future connections (bits 0-4). Host does not validate reserved bits 5-63; the Controller checks they are zero. */ +} esp_ble_cs_set_default_security_requirements_params; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) /** * @brief CS set default settings parameters @@ -2494,6 +2523,23 @@ typedef union { uint8_t data[ESP_BLE_GAP_UTP_DATA_MAX_LEN]; /*!< UTP data */ } utp_receive; /*!< Event parameter of ESP_GAP_BLE_UTP_RECEIVE_EVT */ #endif // #if (BLE_FEAT_LE_UTP == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + /** + * @brief ESP_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT + */ + struct ble_cs_set_security_requirements { + esp_bt_status_t status; /*!< 0x00: CS set security requirements command succeeded + other: CS set security requirements command failed */ + uint16_t conn_handle; /*!< Connection Handle */ + } cs_set_security_requirements; /*!< Event parameter of ESP_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT + */ + struct ble_cs_set_default_security_requirements { + esp_bt_status_t status; /*!< 0x00: CS set default security requirements command succeeded + other: CS set default security requirements command failed */ + } cs_set_default_security_requirements; /*!< Event parameter of ESP_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT */ +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) /** * @brief ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT */ @@ -4965,6 +5011,49 @@ esp_err_t esp_ble_cs_write_cached_remote_supported_capabilities(esp_ble_cs_write */ esp_err_t esp_ble_cs_security_enable(uint16_t conn_handle); +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +/** + * @brief Set Channel Sounding security requirements for a connection (Core 6.3). + * + * Requires CONFIG_BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS and CS Host Support enabled + * via esp_ble_gap_set_host_feature(ESP_BLE_HOST_FEATURE_CS_HOST_SUPPORT, 1). + * Must be issued before CS procedures are enabled on the connection. + * + * The Host does not validate Connection_Handle range or CS_Security_Requirements + * reserved bits (5-63); the Controller performs these checks and reports errors + * via ESP_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT. + * + * @param[in] params: CS set security requirements parameters + * + * @return + * - ESP_OK : success (command queued) + * - ESP_ERR_INVALID_ARG : params is NULL + * - ESP_ERR_INVALID_STATE : Bluedroid is not enabled + * - ESP_FAIL : other failures + */ +esp_err_t esp_ble_cs_set_security_requirements(esp_ble_cs_set_security_requirements_params *params); + +/** + * @brief Set initial Channel Sounding security requirements for future connections (Core 6.3). + * + * Requires CONFIG_BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS and CS Host Support enabled + * via esp_ble_gap_set_host_feature(ESP_BLE_HOST_FEATURE_CS_HOST_SUPPORT, 1). + * Does not affect existing connections. + * + * The Host does not validate CS_Security_Requirements reserved bits (5-63); + * the Controller performs this check and reports errors via + * ESP_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT. + * + * @param[in] params: CS set default security requirements parameters + * + * @return + * - ESP_OK : success (command queued) + * - ESP_ERR_INVALID_ARG : params is NULL + * - ESP_ERR_INVALID_STATE : Bluedroid is not enabled + * - ESP_FAIL : other failures + */ +esp_err_t esp_ble_cs_set_default_security_requirements(esp_ble_cs_set_default_security_requirements_params *params); +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) /** * @brief This function is used to set default CS settings in the local Controller 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 b00f23c8b00..0130e7db02d 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6406,6 +6406,18 @@ void bta_dm_api_cs_procedure_enable(tBTA_DM_MSG *p_data) } #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +void bta_dm_api_cs_set_security_requirements(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsSetSecurityRequirements(p_data->set_security_requirements_params.conn_handle, + p_data->set_security_requirements_params.cs_security_requirements); +} + +void bta_dm_api_cs_set_default_security_requirements(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsSetDefaultSecurityRequirements(p_data->set_default_security_requirements_params.cs_security_requirements); +} +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT 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 6ccc7e9d1ea..57f816f913f 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2647,6 +2647,33 @@ void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t e #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +void BTA_DmBleGapCsSetSecurityRequirements(uint16_t conn_handle, uint64_t cs_security_requirements) +{ + tBTA_DM_API_CS_SET_SECURITY_REQUIREMENTS_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_SET_SECURITY_REQUIREMENTS_PARAMS *) + osi_malloc(sizeof(tBTA_DM_API_CS_SET_SECURITY_REQUIREMENTS_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_SET_SECURITY_REQUIREMENTS; + p_msg->conn_handle = conn_handle; + p_msg->cs_security_requirements = cs_security_requirements; + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsSetDefaultSecurityRequirements(uint64_t cs_security_requirements) +{ + tBTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_PARAMS *) + osi_malloc(sizeof(tBTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS; + p_msg->cs_security_requirements = cs_security_requirements; + bta_sys_sendmsg(p_msg); + } +} + +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) /******************************************************************************* ** 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 b85c91663b9..2ee25451264 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -328,6 +328,10 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_api_cs_set_procedure_params, /* BTA_DM_API_CS_SET_PROCEDURE_PARAMS */ bta_dm_api_cs_procedure_enable, /* BTA_DM_API_CS_PROCEDURE_ENABLE */ #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + bta_dm_api_cs_set_security_requirements, /* BTA_DM_API_CS_SET_SECURITY_REQUIREMENTS */ + bta_dm_api_cs_set_default_security_requirements, /* BTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS */ +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #if (BLE_FEAT_DBAF == TRUE) bta_dm_ble_gap_set_decision_data, /* BTA_DM_API_SET_DECISION_DATA_EVT */ bta_dm_ble_gap_set_decision_instructions, /* BTA_DM_API_SET_DECISION_INSTRUCTIONS_EVT */ 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 eed23f69050..e2e61e0f1af 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 @@ -325,6 +325,10 @@ enum { BTA_DM_API_CS_SET_PROCEDURE_PARAMS, BTA_DM_API_CS_PROCEDURE_ENABLE, #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + BTA_DM_API_CS_SET_SECURITY_REQUIREMENTS, + BTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS, +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #if (BLE_FEAT_DBAF == TRUE) BTA_DM_API_SET_DECISION_DATA_EVT, BTA_DM_API_SET_DECISION_INSTRUCTIONS_EVT, @@ -1228,6 +1232,18 @@ typedef struct { UINT8 enable; } tBTA_DM_API_CS_PROC_ENABLE_PARAMS; +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT64 cs_security_requirements; +} tBTA_DM_API_CS_SET_SECURITY_REQUIREMENTS_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT64 cs_security_requirements; +} tBTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_PARAMS; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #endif /* BLE_INCLUDED */ @@ -2030,6 +2046,10 @@ typedef union { tBTA_DM_API_CS_SET_PROC_PARAMS set_proc_params; tBTA_DM_API_CS_PROC_ENABLE_PARAMS proc_enable_params; #endif +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + tBTA_DM_API_CS_SET_SECURITY_REQUIREMENTS_PARAMS set_security_requirements_params; + tBTA_DM_API_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_PARAMS set_default_security_requirements_params; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) } tBTA_DM_MSG; @@ -2727,4 +2747,8 @@ void bta_dm_api_cs_set_channel_classification(tBTA_DM_MSG *p_data); void bta_dm_api_cs_set_procedure_params(tBTA_DM_MSG *p_data); void bta_dm_api_cs_procedure_enable(tBTA_DM_MSG *p_data); #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +void bta_dm_api_cs_set_security_requirements(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_set_default_security_requirements(tBTA_DM_MSG *p_data); +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == 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 5295770db22..92c8af0fd61 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1655,6 +1655,10 @@ typedef struct { #define BTA_BLE_GAP_CS_SUBEVENT_RESULT_EVT BTM_BLE_GAP_CS_SUBEVENT_RESULT_EVT #define BTA_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT BTM_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +#define BTA_BLE_GAP_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT BTM_BLE_GAP_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT +#define BTA_BLE_GAP_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT BTM_BLE_GAP_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT typedef tBTM_BLE_5_GAP_EVENT tBTA_DM_BLE_5_GAP_EVENT; @@ -2985,6 +2989,10 @@ void BTA_DmBleGapCsSetChannelClass(uint8_t *channel_class, uint8_t channl_len); void BTA_DmBleGapCsSetProcPatams(tBTA_DM_CS_SET_PROC_PARAMS *set_proc_params); void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t enable); #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +void BTA_DmBleGapCsSetSecurityRequirements(uint16_t conn_handle, uint64_t cs_security_requirements); +void BTA_DmBleGapCsSetDefaultSecurityRequirements(uint64_t cs_security_requirements); +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 0d8e2ca07c9..7e4a11e3898 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1711,6 +1711,17 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, param.cs_security_enable.status = btc_btm_status_to_esp_status(params->cs_security_enable.status); param.cs_security_enable.conn_handle = params->cs_security_enable.conn_handle; break; +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + case BTA_BLE_GAP_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT; + param.cs_set_security_requirements.status = btc_btm_status_to_esp_status(params->cs_set_security_requirements.status); + param.cs_set_security_requirements.conn_handle = params->cs_set_security_requirements.conn_handle; + break; + case BTA_BLE_GAP_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT; + param.cs_set_default_security_requirements.status = btc_btm_status_to_esp_status(params->cs_set_default_security_requirements.status); + break; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) case BTA_BLE_GAP_CS_CONFIG_CMPL_EVT: msg.act = ESP_GAP_BLE_CS_CONFIG_CMPL_EVT; param.cs_config_update.status = btc_btm_status_to_esp_status(params->cs_config_update.status); @@ -3787,6 +3798,15 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapCsProcEnable(arg_5->cs_procedure_enable_params.conn_handle, arg_5->cs_procedure_enable_params.config_id, arg_5->cs_procedure_enable_params.enable); break; #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + case BTC_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS: + BTA_DmBleGapCsSetSecurityRequirements(arg_5->cs_set_security_requirements_params.conn_handle, + arg_5->cs_set_security_requirements_params.cs_security_requirements); + break; + case BTC_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS: + BTA_DmBleGapCsSetDefaultSecurityRequirements(arg_5->cs_set_default_security_requirements_params.cs_security_requirements); + break; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) case BTC_GAP_BLE_ACT_SET_KEY_MATERIAL: BTA_DmBleSetKeyMaterial(arg->set_key_material.session_key, arg->set_key_material.iv); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 7f4d6e590f8..41fc24c7a74 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -187,6 +187,10 @@ typedef enum { BTC_GAP_BLE_CS_SET_PROCEDURE_PARAMS, BTC_GAP_BLE_CS_PROCEDURE_ENABLE, #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + BTC_GAP_BLE_CS_SET_SECURITY_REQUIREMENTS, + BTC_GAP_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS, +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) BTC_GAP_BLE_ACT_SET_KEY_MATERIAL, #endif @@ -798,6 +802,16 @@ typedef union { uint8_t enable; } cs_procedure_enable_params; #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + struct cs_set_security_requirements_params_args { + uint16_t conn_handle; + uint64_t cs_security_requirements; + } cs_set_security_requirements_params; + + struct cs_set_default_security_requirements_params_args { + uint64_t cs_security_requirements; + } cs_set_default_security_requirements_params; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) } btc_ble_5_gap_args_t; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) 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 66575a782fd..a6887c2ec18 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 @@ -343,6 +343,11 @@ #define UC_BT_BLE_FEAT_CHANNEL_SOUNDING FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS +#define UC_BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS CONFIG_BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS +#else +#define UC_BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS FALSE +#endif #ifdef CONFIG_BT_BLE_FEAT_ADV_MONITOR #define UC_BT_BLE_FEAT_ADV_MONITOR CONFIG_BT_BLE_FEAT_ADV_MONITOR @@ -356,6 +361,11 @@ #define UC_BT_BLE_FEAT_DBAF FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE +#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE +#else +#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE FALSE +#endif #ifdef CONFIG_BT_BLE_FEAT_LL_EXT_FEAT #define UC_BT_BLE_FEAT_LL_EXT_FEAT CONFIG_BT_BLE_FEAT_LL_EXT_FEAT @@ -375,13 +385,6 @@ #define UC_BT_BLE_FEAT_LE_UTP FALSE #endif -#ifdef CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE -#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE CONFIG_BT_BLE_FEAT_FRAME_SPACE_UPDATE -#else -#define UC_BT_BLE_FEAT_FRAME_SPACE_UPDATE FALSE -#endif - - #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN #define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN #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 14a68cacd7a..3c9151b7cc4 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -405,6 +405,11 @@ #define BT_BLE_FEAT_CHANNEL_SOUNDING FALSE #endif +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) && (UC_BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +#define BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS TRUE +#else +#define BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS FALSE +#endif /* LE Monitor Advertisement (Bluetooth Core 6.0) */ #if (BLE_50_FEATURE_SUPPORT == TRUE) && (defined UC_BT_BLE_FEAT_ADV_MONITOR) && (UC_BT_BLE_FEAT_ADV_MONITOR == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 4ccdec8174e..bcf2cc0ea45 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -2602,3 +2602,39 @@ void btm_ble_cs_subevt_continue_result_evt(tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EV } #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +/* Host does not validate conn_handle range or CS_Security_Requirements reserved bits; Controller checks. */ +void BTM_BleGapCsSetSecurityRequirements(UINT16 conn_handle, UINT64 cs_security_requirements) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_cs_set_security_requirements(conn_handle, cs_security_requirements)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cs set security requirements, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cs_set_security_requirements.status = status; + cb_params.cs_set_security_requirements.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT, &cb_params); +} + +/* Host does not validate CS_Security_Requirements reserved bits; Controller checks. */ +void BTM_BleGapCsSetDefaultSecurityRequirements(UINT64 cs_security_requirements) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_cs_set_default_security_requirements(cs_security_requirements)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cs set default security requirements, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cs_set_default_security_requirements.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT, &cb_params); +} + +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index cb725a94ba2..1dbe71b2886 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3770,3 +3770,42 @@ UINT8 btsnd_hcic_ble_cs_procedure_enable(UINT16 conn_handle, UINT8 config_id, UI return TRUE; } #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +UINT8 btsnd_hcic_ble_cs_set_security_requirements(UINT16 conn_handle, UINT64 cs_security_requirements) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs set security requirements conn_handle %d", conn_handle); + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_CS_SET_SECURITY_REQUIREMENTS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_SET_SECURITY_REQUIREMENTS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CS_SET_SECURITY_REQUIREMENTS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + ARRAY_TO_STREAM(pp, (UINT8 *)&cs_security_requirements, 8); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_cs_set_default_security_requirements(UINT64 cs_security_requirements) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs set default security requirements"); + + HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_LEN); + ARRAY_TO_STREAM(pp, (UINT8 *)&cs_security_requirements, 8); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == 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 cdc884c627d..eae0a71b2ee 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 @@ -1012,7 +1012,11 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_UTP_SEND_COMPLETE_EVT 84 #define BTM_BLE_5_GAP_UTP_RECEIVE_EVT 85 #endif // #if (BLE_FEAT_LE_UTP == TRUE) -#define BTM_BLE_5_GAP_UNKNOWN_EVT 91 +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +#define BTM_BLE_GAP_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT 88 +#define BTM_BLE_GAP_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT 89 +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +#define BTM_BLE_5_GAP_UNKNOWN_EVT 90 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #if (BLE_FEAT_ISO_EN == TRUE) @@ -1555,6 +1559,16 @@ typedef struct { UINT16 conn_handle; } tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT; +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +typedef struct { + UINT8 status; + UINT16 conn_handle; +} tBTM_BLE_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT; + +typedef struct { + UINT8 status; +} tBTM_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) typedef struct { UINT8 status; @@ -2057,6 +2071,10 @@ typedef union { #if (BLE_FEAT_LE_UTP == TRUE) tBTM_BLE_UTP_RECEIVE utp_receive; #endif // #if (BLE_FEAT_LE_UTP == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) + tBTM_BLE_CS_SET_SECURITY_REQUIREMENTS_CMPL_EVT cs_set_security_requirements; + tBTM_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_CMPL_EVT cs_set_default_security_requirements; +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -3397,5 +3415,9 @@ void BTM_BleGapCsSetProcPatams(UINT16 conn_handle, UINT8 config_id, UINT16 max_p UINT8 SNR_control_initiator, UINT8 SNR_control_reflector); void BTM_BleGapCsProcEnable(UINT16 conn_handle, UINT8 config_id, UINT8 enable); #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +void BTM_BleGapCsSetSecurityRequirements(UINT16 conn_handle, UINT64 cs_security_requirements); +void BTM_BleGapCsSetDefaultSecurityRequirements(UINT64 cs_security_requirements); +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == 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 14259213170..6622e6bd434 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -493,6 +493,10 @@ #define HCI_BLE_CS_SET_PROCEDURE_ENABLE (0x0094 | HCI_GRP_BLE_CMDS) #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +#define HCI_BLE_CS_SET_SECURITY_REQUIREMENTS (0x00A7 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS (0x00A8 | HCI_GRP_BLE_CMDS) +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #if (BLE_FEAT_LE_UTP == TRUE) #define HCI_BLE_ENABLE_UTP_OTA_MODE (0x009F | HCI_GRP_BLE_CMDS) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index f9e6c91c20d..30b2f5794e8 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1415,5 +1415,12 @@ UINT8 btsnd_hcic_ble_cs_set_procedure_params(UINT16 conn_handle, UINT8 config_id UINT8 btsnd_hcic_ble_cs_procedure_enable(UINT16 conn_handle, UINT8 config_id, UINT8 enable); #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) +#define HCIC_PARAM_SIZE_CS_SET_SECURITY_REQUIREMENTS_LEN 10 +#define HCIC_PARAM_SIZE_CS_SET_DEFAULT_SECURITY_REQUIREMENTS_LEN 8 + +UINT8 btsnd_hcic_ble_cs_set_security_requirements(UINT16 conn_handle, UINT64 cs_security_requirements); +UINT8 btsnd_hcic_ble_cs_set_default_security_requirements(UINT64 cs_security_requirements); +#endif // (BT_BLE_FEAT_CS_SECURITY_REQUIREMENTS == TRUE) #endif