From 8487639a87eabec68444c1b53195d98f310f7703 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 21 Oct 2025 17:53:20 +0800 Subject: [PATCH] feat(ble/bluedroid): add API to get local BLE IRK (cherry picked from commit 3c68650d7e0853ad8880db1608c35007c8edf1af) Co-authored-by: zhanghaipeng --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 22 ++++++++++++++++++ .../api/include/api/esp_gap_ble_api.h | 23 +++++++++++++++++++ .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 12 ++++++++++ .../stack/include/stack/btm_ble_api.h | 14 +++++++++++ 4 files changed, 71 insertions(+) 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 1da02cf877..3c3a48e5b9 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -805,6 +805,28 @@ esp_err_t esp_ble_create_sc_oob_data(void) return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + +esp_err_t esp_ble_gap_get_local_irk(uint8_t local_irk[16]) +{ + if (local_irk == NULL) { + ESP_LOGE(__func__, "local_irk is NULL"); + return ESP_ERR_INVALID_ARG; + } + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + ESP_LOGE(__func__, "Bluedroid is not enabled"); + return ESP_ERR_INVALID_STATE; + } + + /* Use BTM API to safely retrieve local IRK */ + if (BTM_GetLocalIRK(local_irk)) { + ESP_LOGD(__func__, "Local IRK retrieved successfully"); + return ESP_OK; + } else { + ESP_LOGW(__func__, "Local IRK not available"); + return ESP_ERR_INVALID_STATE; + } +} #endif /* #if (SMP_INCLUDED == TRUE) */ esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device) 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 dafa370cb7..89b14f7b75 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 @@ -2088,6 +2088,7 @@ esp_err_t esp_ble_gap_set_resolvable_private_address_timeout(uint16_t rpa_timeou * */ esp_err_t esp_ble_gap_add_device_to_resolving_list(esp_bd_addr_t peer_addr, uint8_t addr_type, uint8_t *peer_irk); + /** * @brief This function clears the random address for the application * @@ -2493,6 +2494,28 @@ esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8 * */ esp_err_t esp_ble_create_sc_oob_data(void); + +/** + * @brief Get the local Identity Resolving Key (IRK). + * + * @note This API retrieves the local IRK stored in the device's security database. + * The IRK is used by the controller to generate and resolve Resolvable Private Addresses (RPA). + * The IRK length is always 16 bytes (ESP_BT_OCTET16_LEN). + * + * @note Usage Restrictions: Do NOT call this API during a disconnection event or while + * a BLE disconnection is in progress. Calling this API during disconnection may lead + * to undefined behavior or accessing invalid information. + * + * @param[out] local_irk: Buffer to hold the 16-byte IRK. The array notation [16] explicitly + * indicates the required buffer size (ESP_BT_OCTET16_LEN). + * + * @return + * - ESP_OK : success + * - ESP_ERR_INVALID_ARG : local_irk is NULL + * - ESP_ERR_INVALID_STATE : BLE stack not initialized or IRK not available + */ +esp_err_t esp_ble_gap_get_local_irk(uint8_t local_irk[16]); + #endif /* #if (SMP_INCLUDED == TRUE) */ /** diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index b8d050a427..faf2e1848f 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -4869,4 +4869,16 @@ bool btm_ble_adv_pkt_post(pkt_linked_item_t *pkt) } #endif // #if (BLE_42_SCAN_EN == TRUE) +#if (SMP_INCLUDED == TRUE) +/* Retrieve local IRK safely */ +bool BTM_GetLocalIRK(uint8_t *irk) +{ + if (!irk) { + return false; + } + + memcpy(irk, btm_cb.devcb.id_keys.irk, sizeof(btm_cb.devcb.id_keys.irk)); + return true; +} +#endif // (SMP_INCLUDED == TRUE) #endif /* BLE_INCLUDED */ 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 7ec384ef1b..e696fe65cf 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 @@ -2561,6 +2561,20 @@ void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback); //extern UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT16 adv_data_len, UINT8 type, UINT8 *p_length); +/****************************************************************************** +** +** Function BTM_GetLocalIRK +** +** Description Get the local Identity Resolving Key (IRK) from the device control block. +** +** Parameters irk : output buffer (16 bytes) to copy IRK into +** +** Returns true if IRK is available, false otherwise +** +******************************************************************************/ +bool BTM_GetLocalIRK(uint8_t *irk); + + /******************************************************************************* ** ** Function BTM_BleGetCurrentAddress