diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 04f9384d64e..07ea3b561dd 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1637,6 +1637,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 c5e75b347c6..f41ae46e9d6 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 7562825b999..434b7db25ec 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6023,6 +6023,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 a51c49dc7e5..752350fd302 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) @@ -3085,6 +3089,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 9a27b3f5634..f36721e496e 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 @@ -434,6 +434,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 d8c12f16828..11f43d2c89f 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -468,6 +468,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 022ac11f1be..276e8eff4a0 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 @@ -1428,6 +1428,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 abebcea4988..65be9cf7d1c 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 @@ -595,6 +595,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 6d950f96b8f..cad56cf8365 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 2f629583223..7f70252edbf 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 @@ -978,6 +978,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) @@ -1235,6 +1239,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 { @@ -1959,6 +1982,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) @@ -3121,6 +3148,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)