From bc400f224beb5105d1fb4d7e2b75585ef84f7bc9 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Thu, 9 Jul 2026 18:04:09 +0800 Subject: [PATCH] feat(ble/bluedroid): Support PAWR connection event --- .../bluedroid/api/include/api/esp_gatt_defs.h | 7 ++ .../bluedroid/api/include/api/esp_gattc_api.h | 4 + .../bluedroid/api/include/api/esp_gatts_api.h | 4 + .../host/bluedroid/bta/gatt/bta_gattc_act.c | 7 +- .../host/bluedroid/bta/gatt/bta_gattc_utils.c | 5 +- .../host/bluedroid/bta/gatt/bta_gatts_act.c | 4 + .../bta/gatt/include/bta_gattc_int.h | 5 +- .../bluedroid/bta/include/bta/bta_gatt_api.h | 4 + .../btc/profile/std/gatt/btc_gattc.c | 4 + .../btc/profile/std/gatt/btc_gatts.c | 4 + .../bt/host/bluedroid/device/controller.c | 2 +- .../bt/host/bluedroid/stack/btm/btm_ble.c | 116 ++++++++++++++---- .../bluedroid/stack/btm/include/btm_ble_int.h | 2 +- .../bt/host/bluedroid/stack/btu/btu_hcif.c | 19 ++- .../bluedroid/stack/include/stack/hcidefs.h | 1 + .../bluedroid/stack/l2cap/include/l2c_int.h | 7 +- .../bt/host/bluedroid/stack/l2cap/l2c_ble.c | 49 +++++++- .../bt/host/bluedroid/stack/l2cap/l2c_utils.c | 6 + 18 files changed, 216 insertions(+), 34 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h b/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h index 435ab210f94..4b34bda61f3 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h @@ -719,6 +719,13 @@ typedef struct { PHY when the long-range capability is really required. */ } esp_ble_gatt_creat_conn_params_t; +#if (CONFIG_BT_BLE_FEAT_PAWR_EN) +/** @brief Invalid Advertising_Handle in PAwR connection complete events. */ +#define ESP_BLE_PAWR_ADV_HANDLE_NONE 0xFF +/** @brief Invalid Sync_Handle in PAwR connection complete events. */ +#define ESP_BLE_PAWR_SYNC_HANDLE_NONE 0xFFFF +#endif // (CONFIG_BT_BLE_FEAT_PAWR_EN) + /** @brief Represents a creat connection element. */ typedef struct { esp_bd_addr_t remote_bda; /*!< The Bluetooth address of the remote device */ diff --git a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h index d73d6e29922..03d575f5fbf 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h @@ -212,6 +212,10 @@ typedef union { esp_gatt_conn_params_t conn_params; /*!< Current connection parameters */ esp_ble_addr_type_t ble_addr_type; /*!< Remote device address type */ uint16_t conn_handle; /*!< HCI connection handle */ +#if (CONFIG_BT_BLE_FEAT_PAWR_EN) + uint8_t adv_handle; /*!< PAwR Advertising_Handle from connection complete; ESP_BLE_PAWR_ADV_HANDLE_NONE if N/A */ + uint16_t sync_handle; /*!< PAwR Sync_Handle from connection complete; ESP_BLE_PAWR_SYNC_HANDLE_NONE if N/A */ +#endif // (CONFIG_BT_BLE_FEAT_PAWR_EN) } connect; /*!< Callback parameter for the event `ESP_GATTC_CONNECT_EVT` */ /** diff --git a/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h b/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h index 09e49b8733e..0372d32bbe0 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h @@ -189,6 +189,10 @@ typedef union { esp_gatt_conn_params_t conn_params; /*!< Current connection parameters */ esp_ble_addr_type_t ble_addr_type; /*!< Remote device address type */ uint16_t conn_handle; /*!< HCI connection handle */ +#if (CONFIG_BT_BLE_FEAT_PAWR_EN) + uint8_t adv_handle; /*!< PAwR Advertising_Handle from connection complete; ESP_BLE_PAWR_ADV_HANDLE_NONE if N/A */ + uint16_t sync_handle; /*!< PAwR Sync_Handle from connection complete; ESP_BLE_PAWR_SYNC_HANDLE_NONE if N/A */ +#endif // (CONFIG_BT_BLE_FEAT_PAWR_EN) } connect; /*!< Callback parameter for the event `ESP_GATTS_CONNECT_EVT` */ /** diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index c1350d043bc..fb5fe51cc28 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -825,7 +825,8 @@ void bta_gattc_conncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data) bta_gattc_send_connect_cback(p_rcb, p_data->int_conn.remote_bda, p_data->int_conn.hdr.layer_specific, p_data->int_conn.conn_params, p_data->int_conn.role, - p_data->int_conn.ble_addr_type, p_data->int_conn.conn_handle); + p_data->int_conn.ble_addr_type, p_data->int_conn.conn_handle, + p_data->int_conn.adv_handle, p_data->int_conn.sync_handle); } } @@ -1885,9 +1886,13 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id, p_buf->int_conn.ble_addr_type = p_lcb->ble_addr_type; #endif p_buf->int_conn.conn_handle = p_lcb->handle; + l2cu_read_pawr_conn_handles(p_lcb, &p_buf->int_conn.adv_handle, + &p_buf->int_conn.sync_handle); } else { APPL_TRACE_WARNING("gattc_conn_cb: conn params not found"); + l2cu_read_pawr_conn_handles(NULL, &p_buf->int_conn.adv_handle, + &p_buf->int_conn.sync_handle); } } p_buf->int_conn.hdr.layer_specific = conn_id; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index 332bf33e6da..a44f9bd264f 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -902,7 +902,8 @@ void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status ** *******************************************************************************/ void bta_gattc_send_connect_cback( tBTA_GATTC_RCB *p_clreg, BD_ADDR remote_bda, UINT16 conn_id, - tBTA_GATT_CONN_PARAMS conn_params, UINT8 link_role, UINT8 ble_addr_type, UINT16 conn_handle) + tBTA_GATT_CONN_PARAMS conn_params, UINT8 link_role, UINT8 ble_addr_type, + UINT16 conn_handle, UINT8 adv_handle, UINT16 sync_handle) { tBTA_GATTC cb_data; @@ -918,6 +919,8 @@ void bta_gattc_send_connect_cback( tBTA_GATTC_RCB *p_clreg, BD_ADDR remote_bda, bdcpy(cb_data.connect.remote_bda, remote_bda); cb_data.connect.ble_addr_type = ble_addr_type; cb_data.connect.conn_handle = conn_handle; + cb_data.connect.adv_handle = adv_handle; + cb_data.connect.sync_handle = sync_handle; (*p_clreg->p_cback)(BTA_GATTC_CONNECT_EVT, &cb_data); } diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c index a5221ec9043..05a71b0f644 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c @@ -1136,8 +1136,12 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, cb_data.conn.ble_addr_type = p_lcb->ble_addr_type; #endif cb_data.conn.conn_handle = p_lcb->handle; + l2cu_read_pawr_conn_handles(p_lcb, &cb_data.conn.adv_handle, + &cb_data.conn.sync_handle); }else { APPL_TRACE_WARNING("%s not found connection parameters of the device ", __func__); + l2cu_read_pawr_conn_handles(NULL, &cb_data.conn.adv_handle, + &cb_data.conn.sync_handle); } } cb_data.conn.conn_id = conn_id; diff --git a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h index 770d38456fa..57d54035d79 100644 --- a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h +++ b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h @@ -243,6 +243,8 @@ typedef struct { tBTA_GATT_CONN_PARAMS conn_params; UINT8 ble_addr_type; UINT16 conn_handle; + UINT8 adv_handle; + UINT16 sync_handle; } tBTA_GATTC_INT_CONN; typedef struct { @@ -498,7 +500,8 @@ extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data); extern void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status, BD_ADDR remote_bda, UINT16 conn_id, tBTA_TRANSPORT transport, UINT16 mtu); extern void bta_gattc_send_connect_cback( tBTA_GATTC_RCB *p_clreg, BD_ADDR remote_bda, UINT16 conn_id, - tBTA_GATT_CONN_PARAMS conn_params, UINT8 link_role, UINT8 ble_addr_type, UINT16 conn_handle); + tBTA_GATT_CONN_PARAMS conn_params, UINT8 link_role, UINT8 ble_addr_type, + UINT16 conn_handle, UINT8 adv_handle, UINT16 sync_handle); extern void bta_gattc_send_disconnect_cback( tBTA_GATTC_RCB *p_clreg, tGATT_DISCONN_REASON reason, BD_ADDR remote_bda, UINT16 conn_id); extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h index 6aa59059f68..a89b7bccdd3 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h @@ -415,6 +415,8 @@ typedef struct { tBTA_GATT_CONN_PARAMS conn_params; UINT8 ble_addr_type; UINT16 conn_handle; + UINT8 adv_handle; + UINT16 sync_handle; } tBTA_GATTC_CONNECT; typedef struct { @@ -635,6 +637,8 @@ typedef struct { tBTA_GATT_CONN_PARAMS conn_params; UINT8 ble_addr_type; UINT16 conn_handle; + UINT8 adv_handle; + UINT16 sync_handle; } tBTA_GATTS_CONN; typedef struct { diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c index 21f1c8cbf52..8b97d28825f 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -985,6 +985,10 @@ void btc_gattc_cb_handler(btc_msg_t *msg) param.connect.conn_params.timeout = connect->conn_params.timeout; param.connect.ble_addr_type = connect->ble_addr_type; param.connect.conn_handle = connect->conn_handle; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + param.connect.adv_handle = connect->adv_handle; + param.connect.sync_handle = connect->sync_handle; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) btc_gattc_cb_to_app(ESP_GATTC_CONNECT_EVT, gattc_if, ¶m); break; } diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c index b816eb3d6d2..65a01fd0ba9 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c @@ -1134,6 +1134,10 @@ void btc_gatts_cb_handler(btc_msg_t *msg) param.connect.conn_params.timeout = p_data->conn.conn_params.timeout; param.connect.ble_addr_type = p_data->conn.ble_addr_type; param.connect.conn_handle = p_data->conn.conn_handle; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + param.connect.adv_handle = p_data->conn.adv_handle; + param.connect.sync_handle = p_data->conn.sync_handle; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) btc_gatts_cb_to_app(ESP_GATTS_CONNECT_EVT, gatts_if, ¶m); break; } diff --git a/components/bt/host/bluedroid/device/controller.c b/components/bt/host/bluedroid/device/controller.c index dc3bce3bf9c..04206829597 100644 --- a/components/bt/host/bluedroid/device/controller.c +++ b/components/bt/host/bluedroid/device/controller.c @@ -31,7 +31,7 @@ #include "osi/future.h" #include "config/stack_config.h" #if (BLE_50_FEATURE_SUPPORT == TRUE) -const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\xff\xff\xff\xff\xff" }; +const bt_event_mask_t BLE_EVENT_MASK = { "\xff\xff\xff\xff\xff\xff\xff\xff" }; #else const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" }; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 3efa2a25ff8..d73eb9f9bbc 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -45,10 +45,59 @@ //#include "osi/include/log.h" #if BLE_INCLUDED == TRUE extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda); + +#define BTM_BLE_CONN_COMP_EVT_LEN_LEGACY 18 +#define BTM_BLE_CONN_COMP_EVT_LEN_ENHANCED 30 +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +#define BTM_BLE_CONN_COMP_EVT_LEN_ENH_V2 33 +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + +static void btm_ble_parse_pawr_conn_handles(UINT8 **pp, BOOLEAN enhanced, BOOLEAN enhanced_v2, + UINT8 *adv_handle, UINT16 *sync_handle) +{ + *adv_handle = L2C_BLE_PAWR_ADV_HANDLE_NONE; + *sync_handle = L2C_BLE_PAWR_SYNC_HANDLE_NONE; + /* Legacy and enhanced connection complete events both include CCA. */ + (*pp)++; /* Central_Clock_Accuracy */ +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + if (enhanced && enhanced_v2) { + STREAM_TO_UINT8(*adv_handle, *pp); + STREAM_TO_UINT16(*sync_handle, *pp); + } +#else + UNUSED(enhanced); + UNUSED(enhanced_v2); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +} + +static BOOLEAN btm_ble_conn_comp_evt_len_valid(UINT16 evt_len, BOOLEAN enhanced, BOOLEAN enhanced_v2) +{ + UINT16 min_len = BTM_BLE_CONN_COMP_EVT_LEN_LEGACY; + + if (enhanced) { + min_len = BTM_BLE_CONN_COMP_EVT_LEN_ENHANCED; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + if (enhanced_v2) { + min_len = BTM_BLE_CONN_COMP_EVT_LEN_ENH_V2; + } +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + } + + if (evt_len < min_len) { + BTM_TRACE_ERROR("%s: invalid evt_len %u (need >= %u), enhanced=%d enhanced_v2=%d", + __func__, evt_len, min_len, enhanced, enhanced_v2); + return FALSE; + } + return TRUE; +} + #if SMP_INCLUDED == TRUE #include "smp_int.h" -// The temp variable to pass parameter between functions when in the connected event callback. -static BOOLEAN temp_enhanced = FALSE; +/* Parsed before async RPA resolve; used by btm_ble_resolve_random_addr_on_conn_cmpl(). */ +static BOOLEAN s_conn_enhanced = FALSE; +static UINT8 s_conn_pawr_adv_handle = L2C_BLE_PAWR_ADV_HANDLE_NONE; +static UINT16 s_conn_pawr_sync_handle = L2C_BLE_PAWR_SYNC_HANDLE_NONE; + extern BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length, UINT16 tlen, UINT8 *p_signature); extern void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable); @@ -64,6 +113,7 @@ static void btm_ble_pseudo_bringup_conn(UINT16 handle, UINT8 role, UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout, BOOLEAN match, const UINT8 *air_peer, UINT8 air_peer_type, + UINT8 pawr_adv_handle, UINT16 pawr_sync_handle, const char *tag, BD_ADDR conn_index_bda_out); static void btm_ble_pseudo_pick_peer_identity(tBTM_SEC_DEV_REC *p_rec, const BD_ADDR on_air, UINT8 on_air_type, @@ -2100,6 +2150,7 @@ static void btm_ble_pseudo_bringup_conn(UINT16 handle, UINT8 role, UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout, BOOLEAN match, const UINT8 *air_peer, UINT8 air_peer_type, + UINT8 pawr_adv_handle, UINT16 pawr_sync_handle, const char *tag, BD_ADDR conn_index_bda_out) { BD_ADDR pseudo; @@ -2120,7 +2171,7 @@ static void btm_ble_pseudo_bringup_conn(UINT16 handle, UINT8 role, btm_ble_connected(conn_index_bda_out, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match); l2cble_conn_comp(handle, role, conn_index_bda_out, bda_type, conn_interval, - conn_latency, conn_timeout); + conn_latency, conn_timeout, pawr_adv_handle, pawr_sync_handle); /* Host RPA resolution replaced the on-air RPA with a stored pseudo on the * ACL. Restore the real on-air peer address so SC pairing f5/f6 uses what @@ -2156,6 +2207,8 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data) UINT16 handle; BD_ADDR bda, local_rpa, peer_rpa; UINT16 conn_interval, conn_latency, conn_timeout; + UINT8 pawr_adv_handle; + UINT16 pawr_sync_handle; BOOLEAN match = FALSE; #if (BLE_PERIPH_PSEUDO_ADDR_BOND == TRUE) BD_ADDR air_peer; /* on-air peer address (RPA) before resolution rewrite */ @@ -2169,13 +2222,15 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data) STREAM_TO_BDADDR (bda, p); // if the enhanced is true, means the connection is enhanced connect, // so the packet should include the local Resolvable Private Address and Peer Resolvable Private Address - if(temp_enhanced) { + if (s_conn_enhanced) { STREAM_TO_BDADDR(local_rpa, p); STREAM_TO_BDADDR(peer_rpa, p); } STREAM_TO_UINT16 (conn_interval, p); STREAM_TO_UINT16 (conn_latency, p); STREAM_TO_UINT16 (conn_timeout, p); + pawr_adv_handle = s_conn_pawr_adv_handle; + pawr_sync_handle = s_conn_pawr_sync_handle; handle = HCID_GET_HANDLE (handle); BTM_TRACE_EVENT ("%s\n", __func__); @@ -2227,13 +2282,15 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data) btm_ble_pseudo_bringup_conn(handle, role, hash_peer, hash_peer_type, air_peer, air_peer_type, conn_interval, conn_latency, conn_timeout, match, air_peer, air_peer_type, + pawr_adv_handle, pawr_sync_handle, "rpa", conn_bda); } #else btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match); - l2cble_conn_comp (handle, role, bda, bda_type, conn_interval, - conn_latency, conn_timeout); + l2cble_conn_comp(handle, role, bda, bda_type, conn_interval, + conn_latency, conn_timeout, + pawr_adv_handle, pawr_sync_handle); #endif #if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE) @@ -2241,6 +2298,9 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data) btm_ble_adjust_conn_addr_for_ext_adv(handle); #endif /* (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE) */ + s_conn_enhanced = FALSE; + s_conn_pawr_adv_handle = L2C_BLE_PAWR_ADV_HANDLE_NONE; + s_conn_pawr_sync_handle = L2C_BLE_PAWR_SYNC_HANDLE_NONE; return; } #endif @@ -2706,7 +2766,7 @@ BOOLEAN btm_ble_pseudo_apply_identity(UINT16 handle, const BD_ADDR identity, ** Description LE connection complete. ** ******************************************************************************/ -void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) +void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced, BOOLEAN enhanced_v2) { #if (BLE_PRIVACY_SPT == TRUE ) UINT8 *p_data = p, peer_addr_type; @@ -2723,7 +2783,15 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) BOOLEAN pseudo_peer_valid = FALSE; BD_ADDR conn_index_bda; /* address actually used to index ACL/dev_rec (pseudo or real) */ #endif - UNUSED(evt_len); + UINT8 pawr_adv_handle = L2C_BLE_PAWR_ADV_HANDLE_NONE; + UINT16 pawr_sync_handle = L2C_BLE_PAWR_SYNC_HANDLE_NONE; + + if (evt_len < 11) { + BTM_TRACE_ERROR("%s: invalid evt_len %u (need >= 11)", __func__, evt_len); + btm_ble_set_conn_st(BLE_CONN_IDLE); + return; + } + STREAM_TO_UINT8 (status, p); STREAM_TO_UINT16 (handle, p); STREAM_TO_UINT8 (role, p); @@ -2732,6 +2800,10 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) BTM_TRACE_DEBUG("status=%d handle=%d role=%d bda_type=%d bda="MACSTR"", status, handle, role, bda_type, MAC2STR(bda)); if (status == 0) { + if (!btm_ble_conn_comp_evt_len_valid(evt_len, enhanced, enhanced_v2)) { + btm_ble_set_conn_st(BLE_CONN_IDLE); + return; + } if (enhanced) { STREAM_TO_BDADDR (local_rpa, p); STREAM_TO_BDADDR (peer_rpa, p); @@ -2782,16 +2854,21 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) if (!match && bda_type != BLE_ADDR_PUBLIC && BTM_BLE_IS_RESOLVE_BDA(bda)) { #endif // save the enhanced value to used in btm_ble_resolve_random_addr_on_conn_cmpl func. - temp_enhanced = enhanced; + STREAM_TO_UINT16 (conn_interval, p); + STREAM_TO_UINT16 (conn_latency, p); + STREAM_TO_UINT16 (conn_timeout, p); + btm_ble_parse_pawr_conn_handles(&p, enhanced, enhanced_v2, + &s_conn_pawr_adv_handle, &s_conn_pawr_sync_handle); + s_conn_enhanced = enhanced; btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_conn_cmpl, p_data); - // set back the temp enhanced to default after used. - temp_enhanced = FALSE; } else #endif { STREAM_TO_UINT16 (conn_interval, p); STREAM_TO_UINT16 (conn_latency, p); STREAM_TO_UINT16 (conn_timeout, p); + btm_ble_parse_pawr_conn_handles(&p, enhanced, enhanced_v2, + &pawr_adv_handle, &pawr_sync_handle); handle = HCID_GET_HANDLE (handle); #if (BLE_PERIPH_PSEUDO_ADDR_BOND == TRUE) @@ -2825,12 +2902,14 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) pseudo_peer_valid ? pseudo_peer_type : bda_type, conn_interval, conn_latency, conn_timeout, match, NULL, 0, + pawr_adv_handle, pawr_sync_handle, "sync", conn_index_bda); } #else btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match); - l2cble_conn_comp (handle, role, bda, bda_type, conn_interval, - conn_latency, conn_timeout); + l2cble_conn_comp(handle, role, bda, bda_type, conn_interval, + conn_latency, conn_timeout, + pawr_adv_handle, pawr_sync_handle); #endif #if (BLE_PRIVACY_SPT == TRUE) @@ -2925,15 +3004,10 @@ void btm_ble_create_conn_cancel_complete (UINT8 *p) STREAM_TO_UINT8 (status, p); - switch (status) { - case HCI_SUCCESS: - if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) { - btm_ble_set_conn_st (BLE_CONN_IDLE); - } - break; - default: - break; + if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) { + btm_ble_set_conn_st (BLE_CONN_IDLE); } + UNUSED(status); } /***************************************************************************** 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 56ae57a4460..1f4abda6a93 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 @@ -413,7 +413,7 @@ void btm_ble_read_remote_features_complete(UINT8 *p); void btm_ble_write_adv_enable_complete(UINT8 *p); #endif // #if (BLE_42_ADV_EN == TRUE) -void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced); +void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced, BOOLEAN enhanced_v2); void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len); tBTM_BLE_CONN_ST btm_ble_get_conn_st(void); void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 6634e24d684..47ffe3f6892 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -165,6 +165,9 @@ static void btu_ble_rc_param_req_evt(UINT8 *p); #endif //#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) static void btu_ble_proc_enhanced_conn_cmpl (UINT8 *p, UINT16 evt_len); +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +static void btu_ble_proc_enhanced_conn_cmpl_v2 (UINT8 *p, UINT16 evt_len); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) //#endif #if (BLE_50_FEATURE_SUPPORT == TRUE) static void btu_ble_phy_update_complete_evt(UINT8 *p); @@ -668,6 +671,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) case HCI_BLE_PA_RESPONSE_REPORT_EVT: btu_ble_pa_response_report_evt(p, hci_evt_len); break; + case HCI_BLE_ENHANCED_CONN_COMPLETE_EVT_V2: + btu_ble_proc_enhanced_conn_cmpl_v2(p, hci_evt_len); + break; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) case HCI_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT: @@ -1892,6 +1898,9 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c #if (BLE_50_FEATURE_SUPPORT == TRUE) case HCI_BLE_EXT_CREATE_CONN: #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case HCI_BLE_EXT_CREATE_CONN_V2: +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) case HCI_BLE_CREATE_LL_CONN: btm_ble_create_ll_conn_complete(status); break; @@ -2566,13 +2575,19 @@ static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p) static void btu_ble_ll_conn_complete_evt ( UINT8 *p, UINT16 evt_len) { - btm_ble_conn_complete(p, evt_len, FALSE); + btm_ble_conn_complete(p, evt_len, FALSE, FALSE); } //#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) static void btu_ble_proc_enhanced_conn_cmpl( UINT8 *p, UINT16 evt_len) { - btm_ble_conn_complete(p, evt_len, TRUE); + btm_ble_conn_complete(p, evt_len, TRUE, FALSE); } +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +static void btu_ble_proc_enhanced_conn_cmpl_v2( UINT8 *p, UINT16 evt_len) +{ + btm_ble_conn_complete(p, evt_len, TRUE, TRUE); +} +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) //#endif static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len) { diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index a52740054b3..abbbaf2df7e 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -998,6 +998,7 @@ #if (BT_BLE_FEAT_PAWR_EN == TRUE) #define HCI_BLE_PA_SUBEVT_DATA_REQUEST_EVT 0x27 #define HCI_BLE_PA_RESPONSE_REPORT_EVT 0x28 +#define HCI_BLE_ENHANCED_CONN_COMPLETE_EVT_V2 0x29 #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) #if (BLE_FEAT_LL_EXT_FEAT == TRUE) diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index 2df7e4b3013..452aa23b263 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -415,6 +415,7 @@ typedef struct t_l2c_linkcb { BOOLEAN is_pawr_synced; UINT8 adv_handle; UINT8 subevent; + UINT16 sync_handle; #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) TIMER_LIST_ENT timer_entry; /* Timer list entry for timeout evt */ UINT16 handle; /* The handle used with LM */ @@ -841,12 +842,16 @@ extern void l2c_fcr_free_timer (tL2C_CCB *p_ccb); ************************************ */ #if (BLE_INCLUDED == TRUE) +#define L2C_BLE_PAWR_ADV_HANDLE_NONE 0xFF +#define L2C_BLE_PAWR_SYNC_HANDLE_NONE 0xFFFF extern BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb); extern void l2cble_remove_pending_direct_conn (tL2C_LCB *p_lcb); extern void l2cble_cleanup_alloc_ccb_failed_conn (tL2C_LCB *p_lcb); extern void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len); extern void l2cble_conn_comp (UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, - UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout); + UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout, + UINT8 adv_handle, UINT16 sync_handle); +extern void l2cu_read_pawr_conn_handles(const tL2C_LCB *p_lcb, UINT8 *adv_handle, UINT16 *sync_handle); extern BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb); extern void l2cble_notify_le_connection (BD_ADDR bda); extern void l2c_ble_link_adjust_allocation (void); diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 2cb1ac8928f..b10422a325c 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -328,8 +328,39 @@ void l2cble_notify_le_connection (BD_ADDR bda) ** Returns void ** *******************************************************************************/ +static void l2cble_store_pawr_conn_handles(tL2C_LCB *p_lcb, UINT8 adv_handle, UINT16 sync_handle) +{ +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + /* Keep the outgoing adv_handle if the controller reports NONE (non-PAwR central). */ + if (adv_handle != L2C_BLE_PAWR_ADV_HANDLE_NONE) { + p_lcb->adv_handle = adv_handle; + } + p_lcb->sync_handle = sync_handle; +#else + UNUSED(p_lcb); + UNUSED(adv_handle); + UNUSED(sync_handle); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +} + +void l2cu_read_pawr_conn_handles(const tL2C_LCB *p_lcb, UINT8 *adv_handle, UINT16 *sync_handle) +{ +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + if (p_lcb != NULL) { + *adv_handle = p_lcb->adv_handle; + *sync_handle = p_lcb->sync_handle; + return; + } +#else + UNUSED(p_lcb); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + *adv_handle = L2C_BLE_PAWR_ADV_HANDLE_NONE; + *sync_handle = L2C_BLE_PAWR_SYNC_HANDLE_NONE; +} + void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, - UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) + UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout, + UINT8 adv_handle, UINT16 sync_handle) { tL2C_LCB *p_lcb; tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda); @@ -381,6 +412,8 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, p_lcb->updating_param_flag = false; p_lcb->ble_addr_type = type; + l2cble_store_pawr_conn_handles(p_lcb, adv_handle, sync_handle); + /* If there are any preferred connection parameters, set them now */ if ( (p_dev_rec->conn_params.min_conn_int >= BLE_CONN_INT_MIN_HOST_CHECK ) && (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) && @@ -435,7 +468,8 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, ** *******************************************************************************/ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, - UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) + UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout, + UINT8 adv_handle, UINT16 sync_handle) { tL2C_LCB *p_lcb; tBTM_SEC_DEV_REC *p_dev_rec; @@ -482,6 +516,8 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ p_lcb->updating_param_flag = false; p_lcb->ble_addr_type = type; + l2cble_store_pawr_conn_handles(p_lcb, adv_handle, sync_handle); + /* Tell BTM Acl management about the link */ p_dev_rec = btm_find_or_alloc_dev (bda); @@ -518,7 +554,8 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ ** *******************************************************************************/ void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, - UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) + UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout, + UINT8 adv_handle, UINT16 sync_handle) { #if (BLE_TOPOLOGY_CHECK == TRUE) btm_ble_update_link_topology_mask(role, TRUE); @@ -528,9 +565,11 @@ void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE typ btm_cb.ble_ctr_cb.inq_var.directed_conn = BTM_BLE_CONNECT_EVT; #endif // (BLE_TOPOLOGY_CHECK == TRUE) if (role == HCI_ROLE_MASTER) { - l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout); + l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout, + adv_handle, sync_handle); } else { - l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout); + l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout, + adv_handle, sync_handle); } } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 66a7aef1a8a..124e036441d 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -119,6 +119,10 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR if (transport == BT_TRANSPORT_LE) { l2cb.num_ble_links_active++; l2c_ble_link_adjust_allocation(); +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + p_lcb->adv_handle = L2C_BLE_PAWR_ADV_HANDLE_NONE; + p_lcb->sync_handle = L2C_BLE_PAWR_SYNC_HANDLE_NONE; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) } else #endif { @@ -192,6 +196,8 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) #if (BT_BLE_FEAT_PAWR_EN == TRUE) p_lcb->is_pawr_synced = FALSE; + p_lcb->adv_handle = L2C_BLE_PAWR_ADV_HANDLE_NONE; + p_lcb->sync_handle = L2C_BLE_PAWR_SYNC_HANDLE_NONE; #endif /* Stop and release timers */