Merge branch 'feat/show_how_to_use_smp_in_blufi_example' into 'master'

feat(ble/blufi): Support setting BLE encryption for blufi

Closes BLERP-2232 and DOC-13032

See merge request espressif/esp-idf!41779
This commit is contained in:
Island
2025-11-24 10:31:03 +08:00
10 changed files with 322 additions and 44 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,6 +32,7 @@
#include "esp_bt_device.h"
#include "esp_err.h"
#include "esp_blufi.h"
#include <esp_gap_ble_api.h>
#if (BLUFI_INCLUDED == TRUE)
@@ -70,12 +71,155 @@ static esp_ble_adv_params_t blufi_adv_params = {
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
static char *esp_auth_req_to_str(esp_ble_auth_req_t auth_req)
{
char *auth_str = NULL;
switch(auth_req) {
case ESP_LE_AUTH_NO_BOND:
auth_str = "ESP_LE_AUTH_NO_BOND";
break;
case ESP_LE_AUTH_BOND:
auth_str = "ESP_LE_AUTH_BOND";
break;
case ESP_LE_AUTH_REQ_MITM:
auth_str = "ESP_LE_AUTH_REQ_MITM";
break;
case ESP_LE_AUTH_REQ_BOND_MITM:
auth_str = "ESP_LE_AUTH_REQ_BOND_MITM";
break;
case ESP_LE_AUTH_REQ_SC_ONLY:
auth_str = "ESP_LE_AUTH_REQ_SC_ONLY";
break;
case ESP_LE_AUTH_REQ_SC_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_BOND";
break;
case ESP_LE_AUTH_REQ_SC_MITM:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM";
break;
case ESP_LE_AUTH_REQ_SC_MITM_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM_BOND";
break;
default:
auth_str = "INVALID BLE AUTH REQ";
break;
}
return auth_str;
}
static char *esp_key_type_to_str(esp_ble_key_type_t key_type)
{
char *key_str = NULL;
switch(key_type) {
case ESP_LE_KEY_NONE:
key_str = "ESP_LE_KEY_NONE";
break;
case ESP_LE_KEY_PENC:
key_str = "ESP_LE_KEY_PENC";
break;
case ESP_LE_KEY_PID:
key_str = "ESP_LE_KEY_PID";
break;
case ESP_LE_KEY_PCSRK:
key_str = "ESP_LE_KEY_PCSRK";
break;
case ESP_LE_KEY_PLK:
key_str = "ESP_LE_KEY_PLK";
break;
case ESP_LE_KEY_LLK:
key_str = "ESP_LE_KEY_LLK";
break;
case ESP_LE_KEY_LENC:
key_str = "ESP_LE_KEY_LENC";
break;
case ESP_LE_KEY_LID:
key_str = "ESP_LE_KEY_LID";
break;
case ESP_LE_KEY_LCSRK:
key_str = "ESP_LE_KEY_LCSRK";
break;
default:
key_str = "INVALID BLE KEY TYPE";
break;
}
return key_str;
}
#endif
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
BLUFI_TRACE_DEBUG("GAP_EVT, event %d", event);
switch (event) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&blufi_adv_params);
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//advertising start complete event to indicate advertising start successfully or failed
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("Advertising start failed, status %x", param->adv_start_cmpl.status);
break;
}
BLUFI_TRACE_API("Advertising start successfully");
break;
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
case ESP_GAP_BLE_PASSKEY_REQ_EVT: /* passkey request event */
BLUFI_TRACE_API("Passkey request");
break;
case ESP_GAP_BLE_OOB_REQ_EVT: {
BLUFI_TRACE_API("OOB request");
uint8_t tk[16] = {1}; //If you paired with OOB, both devices need to use the same tk
esp_ble_oob_req_reply(param->ble_security.ble_req.bd_addr, tk, sizeof(tk));
break;
}
case ESP_GAP_BLE_LOCAL_IR_EVT: /* BLE local IR event */
BLUFI_TRACE_API("Local identity root");
break;
case ESP_GAP_BLE_LOCAL_ER_EVT: /* BLE local ER event */
BLUFI_TRACE_API("Local encryption root");
break;
case ESP_GAP_BLE_NC_REQ_EVT:
/* The app will receive this evt when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability.
show the passkey number to the user to confirm it with the number displayed by peer device. */
esp_ble_confirm_reply(param->ble_security.ble_req.bd_addr, true);
BLUFI_TRACE_WARNING("Numeric Comparison request, passkey %" PRIu32, param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_SEC_REQ_EVT:
/* send the positive(true) security response to the peer device to accept the security request.
If not accept the security request, should send the security response with negative(false) accept value*/
esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
///show the passkey number to the user to input it in the peer device.
BLUFI_TRACE_WARNING("Passkey notify, passkey %06" PRIu32, param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key info share with peer device to the user.
BLUFI_TRACE_API("Key exchanged, key_type %s", esp_key_type_to_str(param->ble_security.ble_key.key_type));
break;
case ESP_GAP_BLE_AUTH_CMPL_EVT: {
esp_bd_addr_t bd_addr;
memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t));
BLUFI_TRACE_API("Authentication complete, addr_type %u, addr "ESP_BD_ADDR_STR"",
param->ble_security.auth_cmpl.addr_type, ESP_BD_ADDR_HEX(bd_addr));
if(!param->ble_security.auth_cmpl.success) {
BLUFI_TRACE_WARNING("Pairing failed, reason 0x%x",param->ble_security.auth_cmpl.fail_reason);
} else {
BLUFI_TRACE_WARNING("Pairing successfully, auth_mode %s",esp_auth_req_to_str(param->ble_security.auth_cmpl.auth_mode));
}
break;
}
case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
BLUFI_TRACE_DEBUG("Bond device remove, status %d, device "ESP_BD_ADDR_STR"",
param->remove_bond_dev_cmpl.status, ESP_BD_ADDR_HEX(param->remove_bond_dev_cmpl.bd_addr));
break;
}
case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){
BLUFI_TRACE_WARNING("Local privacy config failed, status %x", param->local_privacy_cmpl.status);
}
break;
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
default:
break;
}
@@ -251,10 +395,16 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
break;
case BTA_GATTS_CREATE_EVT:
blufi_env.handle_srvc = p_data->create.service_id;
#if CONFIG_BT_BLUFI_BLE_SMP_ENABLE
BLUFI_TRACE_WARNING("BLE SMP support in BLUFI is ENABLED!");
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
//add the first blufi characteristic --> write characteristic
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
(GATT_PERM_WRITE),
#if CONFIG_BT_BLUFI_BLE_SMP_ENABLE
GATT_PERM_WRITE_ENC_MITM,
#else
GATT_PERM_WRITE,
#endif
(GATT_CHAR_PROP_BIT_WRITE),
NULL, NULL);
break;
@@ -398,6 +548,16 @@ void esp_blufi_adv_stop(void)
esp_ble_gap_stop_advertising();
}
esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda)
{
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
return esp_ble_set_encryption(remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
#else
return ESP_ERR_INVALID_STATE;
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
}
void esp_blufi_send_encap(void *arg)
{
struct blufi_hdr *hdr = (struct blufi_hdr *)arg;

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -90,6 +90,22 @@ void esp_blufi_adv_start_with_name(const char *name);
void esp_blufi_send_encap(void *arg);
/*
* @brief Initiate BLE security request with the connected peer device.
*
* This function triggers the BLE Security Manager Protocol (SMP) procedure
* to establish a secure, encrypted connection with the specified remote device.
* It should be called after a BLE connection is established.
*
* @param[in] remote_bda Bluetooth device address of the connected peer.
*
* @return
* - ESP_OK: Security request initiated successfully
* - ESP_FAIL: Security request failed
* - ESP_ERR_INVALID_STATE: BluFi BLE SMP is not enabled
*/
esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda);
#ifdef CONFIG_BT_NIMBLE_ENABLED
/**
* @brief Handle gap event for BluFi.

View File

@@ -291,6 +291,16 @@ config BT_BLE_BLUFI_ENABLE
help
This option can be close when the app does not require blufi function.
config BT_BLUFI_BLE_SMP_ENABLE
bool "Enable BLE SMP support for BluFi"
depends on BT_BLE_BLUFI_ENABLE && BT_BLE_SMP_ENABLE
default n
help
Enable BLE Security Manager Protocol (SMP) for BluFi.
When enabled, BluFi will support BLE pairing and encryption
before Wi-Fi provisioning, providing a more secure provisioning process.
This feature is only supported with the Bluedroid host.
config BT_GATT_MAX_SR_PROFILES
int "Max GATT Server Profiles"
depends on BT_GATTS_ENABLE && BT_BLUEDROID_ENABLED

View File

@@ -12,6 +12,12 @@ Fragmenting, data encryption, and checksum verification in the BluFi layer are t
You can customize symmetric encryption, asymmetric encryption, and checksum support customization. Here we use the DH algorithm for key negotiation, 128-AES algorithm for data encryption, and CRC16 algorithm for checksum verification.
.. note::
**BluFi is currently in maintenance mode, and no new features are planned.**
For new projects or when adding Wi-Fi provisioning, we recommend using the `network_provisioning`_ component, which offers a modern, secure, and actively maintained solution.
Getting Started
---------------
@@ -665,43 +671,46 @@ The Security Implementation of {IDF_TARGET_NAME}
The application layer needs to register several security-related functions to BluFi:
.. code-block:: c
.. code-block:: c
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
This function is for {IDF_TARGET_NAME} to receive normal data during negotiation. After processing is completed, the data will be transmitted using Output_data and Output_len.
This function is for {IDF_TARGET_NAME} to receive normal data during negotiation. After processing is completed, the data will be transmitted using Output_data and Output_len.
BluFi will send output_data from Negotiate_data_handler after Negotiate_data_handler is called.
BluFi will send output_data from Negotiate_data_handler after Negotiate_data_handler is called.
Here are two "*", which means the length of the data to be emitted is unknown. Therefore, it requires the function to allocate itself (malloc) or point to the global variable to inform whether the memory needs to be freed by NEED_FREE.
Here are two ``*``, which means the length of the data to be emitted is unknown. Therefore, it requires the function to allocate itself (malloc) or point to the global variable to inform whether the memory needs to be freed by NEED_FREE.
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as a 8-bit of IV.
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as a 8-bit of IV.
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as an 8-bit of IV.
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as an 8-bit of IV.
.. code-block:: c
.. code-block:: c
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
This function is used to compute CheckSum and return a value of CheckSum. BluFi uses the returned value to compare the CheckSum of the frame.
This function is used to compute CheckSum and return a value of CheckSum. BluFi uses the returned value to compare the CheckSum of the frame.
5. Implementing Stronger Security
The default encryption/decryption logic in this example is intended for demonstration purposes only.
The default encryption and decryption logic in this example is intended for demonstration purposes only. If your application requires stronger security guarantees, consider one of the following approaches:
If you require a higher level of security, it is recommended to implement your own encryption, decryption, authentication, and checksum algorithms by customizing the security callbacks in the BluFi framework.
- **Custom Security Callbacks**: Implement your own encryption, decryption, authentication, and checksum algorithms by defining custom security callbacks in the Blufi framework:
.. code-block:: c
.. code-block:: c
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);
- **Network Provisioning Component (recommended)**: For a more robust, secure, and production-ready provisioning solution, consider using the `network_provisioning`_ component.
GATT Related Instructions
@@ -715,3 +724,6 @@ BluFi Service UUID: 0xFFFF, 16 bit
BluFi (the mobile > {IDF_TARGET_NAME}): 0xFF01, writable
Blufi ({IDF_TARGET_NAME} > the mobile phone): 0xFF02, readable and callable
.. _network_provisioning: https://github.com/espressif/idf-extra-components/tree/master/network_provisioning

View File

@@ -12,6 +12,12 @@ BluFi 流程的关键部分包括数据的分片、加密以及校验和验证
用户可按需自定义用于对称加密、非对称加密以及校验的算法。此处,我们采用 DH 算法进行密钥协商128-AES 算法用于数据加密CRC16 算法用于校验和验证。
.. note::
**BluFi 目前处于维护模式,暂不计划增加新功能。**
对于新项目或需要添加 Wi-Fi 配网功能的场景,建议使用 `network_provisioning`_ 组件。该组件更加现代、安全,并且仍在积极维护中。
快速入门
--------
@@ -665,43 +671,46 @@ ACK 帧格式 (8 bit)
应用层需向 BluFi 注册以下几个与安全相关的函数:
.. code-block:: c
.. code-block:: c
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
该函数用来接收协商期间的正常数据 (normal data)。数据处理完成后,需要将待发送的数据使用 output_data 和 output_len 传出。
该函数用来接收协商期间的正常数据 (normal data)。数据处理完成后,需要将待发送的数据使用 output_data 和 output_len 传出。
BluFi 会在调用完 Negotiate_data_handler 后,发送 Negotiate_data_handler 传出的 output_data。
BluFi 会在调用完 Negotiate_data_handler 后,发送 Negotiate_data_handler 传出的 output_data。
这里的两个 “*” 是因为需要发出去的数据长度未知,所以需要函数自行分配 (malloc) 或者指向全局变量,并告知是否需要通过 NEED_FREE 释放内存。
这里的两个 ``*`` 是因为需要发出去的数据长度未知,所以需要函数自行分配 (malloc) 或者指向全局变量,并告知是否需要通过 NEED_FREE 释放内存。
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
.. code-block:: c
.. code-block:: c
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
该函数用来进行校验返回值为校验的值。BluFi 会使用该函数返回值与帧的校验值进行比较。
该函数用来进行校验返回值为校验的值。BluFi 会使用该函数返回值与帧的校验值进行比较。
5. 实现更强的安全性
示例中默认加密/解密逻辑仅用于演示目的。
示例中默认加密解密逻辑仅用于演示目的。如果你的应用需要更高的安全保障,可选择以下任一方法:
如果需要更高等级的安全性,建议通过自定义 BluFi 框架中的安全回调函数,实现您自己的加密、解密、认证以及校验算法
- **自定义安全回调**:通过改写 BluFi 框架中的安全回调函数,自定义加密、解密、认证以及校验算法
.. code-block:: c
.. code-block:: c
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);
- **网络配网组件(推荐使用)**:使用 ESP-IDF 提供的 `network_provisioning`_ 组件,实现安全、可直接使用的配网解决方案。
GATT 相关说明
@@ -715,3 +724,6 @@ BluFi Service UUID 0xFFFF16 bit
BluFi手机 > {IDF_TARGET_NAME}特性0xFF01主要权限可写
BluFi{IDF_TARGET_NAME} > 手机特性0xFF02主要权限可读可通知
.. _network_provisioning: https://github.com/espressif/idf-extra-components/tree/master/network_provisioning

View File

@@ -696,7 +696,7 @@ void app_main(void)
/* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; //bonding with peer device after authentication
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT; //set the IO capability to No output No input
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT; //set the IO capability to DisplayOnly
uint8_t key_size = 16; //the key size should be 7~16 bytes
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;

View File

@@ -82,3 +82,9 @@ I (1198) BLUFI_EXAMPLE: BLUFI init finish
## Troubleshooting
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
## Note
BluFi is currently in maintenance mode, and no new features are planned.
For new projects or when adding network_provisioning, we recommend using the [network_provisioning](https://github.com/espressif/idf-extra-components/tree/master/network_provisioning).

View File

@@ -33,4 +33,23 @@ menu "Example Configuration"
bool "WAPI PSK"
endchoice
config EXAMPLE_BLUFI_BLE_SMP_ENABLE
bool "Enable BLE SMP support in BLUFI"
depends on BT_BLUEDROID_ENABLED
select BT_BLUFI_BLE_SMP_ENABLE
select BT_BLE_SMP_ENABLE
default n
help
Enable BLE Security Manager Protocol (SMP) for BLUFI.
Currently, this feature is only supported with the Bluedroid host.
If enabled:
- BLUFI will configure SMP security parameters such as
IO capabilities, authentication mode, and key size.
- After a BLE connection is established, BLUFI will
proactively initiate a security request.
- Only after the BLE pairing is successfully completed,
BLUFI can proceed with Wi-Fi provisioning.
- If the user rejects pairing or inputs an incorrect passkey,
BLUFI will not start Wi-Fi provisioning.
endmenu

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -319,6 +319,14 @@ static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_para
ble_is_connected = true;
esp_blufi_adv_stop();
blufi_security_init();
#ifdef CONFIG_EXAMPLE_BLUFI_BLE_SMP_ENABLE
// Try to initiate BLE security request after connection established.
BLUFI_INFO("Try to initiate BLE security request\n");
esp_err_t ret = esp_blufi_start_security_request(param->connect.remote_bda);
if (ret != ESP_OK) {
BLUFI_ERROR("Failed to start security request: %s\n", esp_err_to_name(ret));
}
#endif // CONFIG_EXAMPLE_BLUFI_BLE_SMP_ENABLE
break;
case ESP_BLUFI_EVENT_BLE_DISCONNECT:
BLUFI_INFO("BLUFI ble disconnect\n");

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -16,6 +16,7 @@
#ifdef CONFIG_BT_BLUEDROID_ENABLED
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_ble_api.h"
#endif
#ifdef CONFIG_BT_NIMBLE_ENABLED
@@ -57,6 +58,37 @@ esp_err_t esp_blufi_host_init(void)
}
#ifdef CONFIG_EXAMPLE_BLUFI_BLE_SMP_ENABLE
void esp_blufi_set_ble_security_params(void)
{
/* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM; // Secure Connections with MITM protection (no bonding)
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT; // IO capability: DisplayOnly
uint8_t key_size = 16; //the key size should be 7~16 bytes
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
//set static passkey
uint32_t passkey = 123456;
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE;
uint8_t oob_support = ESP_BLE_OOB_DISABLE;
BLUFI_INFO("BLE SMP passkey: %06" PRIu32 " (WARNING: Change this default value for production or don't use static passkey!)\n", passkey);
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_OOB_SUPPORT, &oob_support, sizeof(uint8_t));
/* If your BLE device acts as a Slave, the init_key means you hope which types of key of the master should distribute to you,
and the response key means which key you can distribute to the master;
If your BLE device acts as a master, the response key means you hope which types of key of the slave should distribute to you,
and the init key means which key you can distribute to the slave. */
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
}
#endif // #if CONFIG_EXAMPLE_BLUFI_BLE_SMP_ENABLE
esp_err_t esp_blufi_host_deinit(void)
{
int ret;
@@ -113,8 +145,11 @@ esp_err_t esp_blufi_host_and_cb_init(esp_blufi_callbacks_t *example_callbacks)
return ret;
}
return ESP_OK;
#ifdef CONFIG_EXAMPLE_BLUFI_BLE_SMP_ENABLE
esp_blufi_set_ble_security_params();
#endif // CONFIG_EXAMPLE_BLUFI_BLE_SMP_ENABLE
return ESP_OK;
}
#endif /* CONFIG_BT_BLUEDROID_ENABLED */