feat(ble/bluedroid): add Shorter Connection Intervals host support (Core 6.2)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zhiweijian
2026-06-24 17:54:53 +08:00
co-authored by Cursor
parent d568f2f151
commit 2a8a96d650
20 changed files with 943 additions and 0 deletions
@@ -1502,6 +1502,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)
@@ -599,6 +599,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);
@@ -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);
@@ -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);
@@ -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)
@@ -989,6 +989,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;
@@ -1270,6 +1276,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 {
@@ -1989,6 +2026,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 {
@@ -3153,6 +3195,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)
@@ -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
@@ -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);