feat(ble/bluedroid): Support multi-connection optimization vendor hci command

(cherry picked from commit f0cfb6e33c)

Co-authored-by: chenjianhua <chenjianhua@espressif.com>
This commit is contained in:
Chen Jian Hua
2025-08-12 21:34:10 +08:00
parent df8533a46e
commit 15b0ff3c2b
3 changed files with 111 additions and 4 deletions

View File

@@ -1759,6 +1759,42 @@ esp_err_t esp_ble_gap_set_csa_support(uint8_t csa_select)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
} }
#if CONFIG_SOC_BLE_MULTI_CONN_OPTIMIZATION
esp_err_t esp_ble_gap_set_common_factor(uint32_t common_factor)
{
esp_ble_vendor_cmd_params_t vs_cmd;
uint8_t cmd_param[5];
cmd_param[0] = common_factor & 0xFF;
cmd_param[1] = (common_factor >> 8) & 0xFF;
cmd_param[2] = (common_factor >> 16) & 0xFF;
cmd_param[3] = (common_factor >> 24) & 0xFF;
cmd_param[4] = 0x01;
vs_cmd.opcode = 0xFD0F;
vs_cmd.param_len = 5;
vs_cmd.p_param_buf = cmd_param;
return esp_ble_gap_vendor_command_send(&vs_cmd);
}
esp_err_t esp_ble_gap_set_sch_len(uint8_t role, uint32_t len)
{
esp_ble_vendor_cmd_params_t vs_cmd;
uint8_t cmd_param[5];
cmd_param[0] = role;
cmd_param[1] = len & 0xFF;
cmd_param[2] = (len >> 8) & 0xFF;
cmd_param[3] = (len >> 16) & 0xFF;
cmd_param[4] = (len >> 24) & 0xFF;
vs_cmd.opcode = 0xFD10;
vs_cmd.param_len = 5;
vs_cmd.p_param_buf = cmd_param;
return esp_ble_gap_vendor_command_send(&vs_cmd);
}
#endif // CONFIG_SOC_BLE_MULTI_CONN_OPTIMIZATION
#endif // (BLE_VENDOR_HCI_EN == TRUE) #endif // (BLE_VENDOR_HCI_EN == TRUE)
#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)

View File

@@ -246,6 +246,8 @@ typedef enum {
ESP_GAP_BLE_SUBRATE_CHANGE_EVT, /*!< when Connection Subrate Update procedure has completed and some parameters of the specified connection have changed, the event comes */ ESP_GAP_BLE_SUBRATE_CHANGE_EVT, /*!< when Connection Subrate Update procedure has completed and some parameters of the specified connection have changed, the event comes */
ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT, /*!< When host feature set complete, the event comes */ ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT, /*!< When host feature set complete, the event comes */
ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT, /*!< When BLE channel map result is received, the event comes */ ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT, /*!< When BLE channel map result is received, the event comes */
ESP_GAP_BLE_SET_COMMON_FACTOR_CMPL_EVT, /*!< When set the common factor complete, the event comes */
ESP_GAP_BLE_SET_SCH_LEN_CMPL_EVT, /*!< When set the scheduling length complete, the event comes */
ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */
} esp_gap_ble_cb_event_t; } esp_gap_ble_cb_event_t;
@@ -1748,6 +1750,18 @@ typedef union {
uint8_t param_len; /*!< The length of the event parameter buffer (for internal use only) */ uint8_t param_len; /*!< The length of the event parameter buffer (for internal use only) */
uint8_t *param_buf; /*!< The pointer of the event parameter buffer (for internal use only) */ uint8_t *param_buf; /*!< The pointer of the event parameter buffer (for internal use only) */
} vendor_hci_evt; /*!< Event parameter of ESP_GAP_BLE_VENDOR_HCI_EVT */ } vendor_hci_evt; /*!< Event parameter of ESP_GAP_BLE_VENDOR_HCI_EVT */
/**
* @brief ESP_GAP_BLE_SET_COMMON_FACTOR_CMPL_EVT
*/
struct ble_set_common_factor_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate common factor set operation success status */
} set_common_factor_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_COMMON_FACTOR_CMPL_EVT */
/**
* @brief ESP_GAP_BLE_SET_SCH_LEN_CMPL_EVT
*/
struct ble_set_sch_len_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate scheduling length set operation success status */
} set_sch_len_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_SCH_LEN_CMPL_EVT */
#endif // #if (BLE_VENDOR_HCI_EN == TRUE) #endif // #if (BLE_VENDOR_HCI_EN == TRUE)
#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) #if (BLE_FEAT_POWER_CONTROL_EN == TRUE)
/** /**
@@ -3090,6 +3104,46 @@ esp_err_t esp_ble_gap_set_csa_support(uint8_t csa_select);
*/ */
esp_err_t esp_ble_gap_set_vendor_event_mask(esp_ble_vendor_evt_mask_t event_mask); esp_err_t esp_ble_gap_set_vendor_event_mask(esp_ble_vendor_evt_mask_t event_mask);
/**
* @brief This function is used to set a common connection interval factor for multiple central-role connections.
* When multiple BLE connections in the central role exist, it is recommended that
* each connection interval be configured to either the same value or an integer
* multiple of the others. And use this function to set the common factor of all
* connection intervalsin the controller. The controller will then arrange the scheduling
* of each connection based on this factor to minimize or avoid connection conflicts.
*
* @note - This function is used in multi-connection scenarios.
* - This function takes effect only when the connection role is central.
* - This function only needs to be called once and before establishing the connection.
*
* @param[in] common_factor: The common connection interval factor (in units of 625us)
* used for scheduling across all central-role connections.
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_gap_set_common_factor(uint32_t common_factor);
/**
* @brief This function is used to Set the scheduling protection time for specific LE role.
* It can be used to configures the minimum protection time to be reserved for a
* connection's TX/RX operations, ensuring that a complete transmission and
* reception cycle is not interrupted. It helps prevent disconnect in scenarios
* with multiple connections competing for time slots.
*
* @note - This function is used in multi-connection scenarios.
* - This function must be called before establishing the connection.
*
* @param[in] role: 0: Central 1: Peripheral
* @param[in] len: The protection time length of the corresponding role (in units of us)
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_gap_set_sch_len(uint8_t role, uint32_t len);
/** /**
* @brief This function is used to read the current and maximum transmit power levels of the local Controller. * @brief This function is used to read the current and maximum transmit power levels of the local Controller.
* *

View File

@@ -1441,10 +1441,23 @@ static void btc_ble_vendor_hci_cmd_complete_callback(tBTA_VSC_CMPL *p_param)
msg.sig = BTC_SIG_API_CB; msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE; msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT; msg.act = ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT;
if (!param_invalid) { if (!param_invalid) {
param.vendor_cmd_cmpl.opcode = p_param->opcode; switch (p_param->opcode) {
param.vendor_cmd_cmpl.param_len = p_param->param_len; case 0xFD0F:
param.vendor_cmd_cmpl.p_param_buf = p_param->p_param_buf; msg.act = ESP_GAP_BLE_SET_COMMON_FACTOR_CMPL_EVT;
param.set_common_factor_cmpl.status = p_param->p_param_buf[0];
break;
case 0xFD10:
msg.act = ESP_GAP_BLE_SET_SCH_LEN_CMPL_EVT;
param.set_sch_len_cmpl.status = p_param->p_param_buf[0];
break;
default:
param.vendor_cmd_cmpl.opcode = p_param->opcode;
param.vendor_cmd_cmpl.param_len = p_param->param_len;
param.vendor_cmd_cmpl.p_param_buf = p_param->p_param_buf;
break;
}
} else { } else {
if (p_param) { if (p_param) {
param.vendor_cmd_cmpl.opcode = p_param->opcode; param.vendor_cmd_cmpl.opcode = p_param->opcode;
@@ -1455,7 +1468,11 @@ static void btc_ble_vendor_hci_cmd_complete_callback(tBTA_VSC_CMPL *p_param)
param.vendor_cmd_cmpl.p_param_buf = NULL; param.vendor_cmd_cmpl.p_param_buf = NULL;
} }
ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy, btc_gap_ble_cb_deep_free); if (msg.act == ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT) {
ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy, btc_gap_ble_cb_deep_free);
} else {
ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL, NULL);
}
if (ret != BT_STATUS_SUCCESS) { if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);