一、简介
ESP32 的 BluFi 是通过蓝牙通道的 Wi-Fi 网络配置功能。它提供了一个安全协议来将 Wi-Fi 配置和凭据传递给 ESP32。使用这些信息,ESP32 可以连接到一个 AP 或建立一个 SoftAP。
BluFi 层中的分片、数据加密、校验和验证是此过程的关键要素。
您可以自定义对称加密、非对称加密和校验和支持自定义。这里我们使用DH算法进行密钥协商,128-AES算法进行数据加密,CRC16算法进行校验和验证。
二、BluFi流程

将 ESP32 设置为 GATT Server 模式,然后它将发送带有特定广告数据的广播。您可以根据需要自定义此广播,这不是 BluFi 配置文件的一部分。
使用安装在手机上的应用程序搜索此特定广播。确认广播后,手机将作为 GATT Client 连接到 ESP32。这部分使用的应用程序由您决定。
GATT连接建立成功后,手机会向ESP32发送密钥协商的数据帧(详见BluFi中定义的帧格式部分)。
ESP32 收到密钥协商的数据帧后,会根据用户自定义的协商方式解析内容。
手机配合ESP32使用DH、RSA或ECC等加密算法进行密钥协商。
协商完成后,手机会向ESP32发送安全模式设置的控制帧。
ESP32 收到此控制帧后,将能够使用共享密钥和安全配置对通信数据进行加密和解密。
手机将BluFi中定义的帧格式部分定义的数据帧连同Wi-Fi配置信息发送到ESP32,包括SSID、密码等。
手机向ESP32发送Wi-Fi连接请求的控制帧。ESP32 收到此控制帧后,会认为基本信息的通信已完成,并准备连接到 Wi-Fi。
连接到 Wi-Fi 后,ESP32 会向手机发送 Wi-Fi 连接状态报告控制帧,以报告连接状态。至此,组网过程完成。
注意:
ESP32 收到安全模式配置的控制帧后,会按照定义的安全模式执行操作。
对称加密/解密前后的数据长度必须保持不变。它还支持就地加密和解密。
三、API说明
以下 BluFi 接口位于 bt/common/api/include/api/esp_blufi_api.h
3.1 esp_blufi_register_callbacks

3.2 esp_blufi_profile_init

3.3 esp_blufi_send_wifi_conn_report

3.4 esp_blufi_send_wifi_list

3.5 esp_blufi_send_error_info

3.6 esp_blufi_send_custom_data

四、程序结构
使用 esp-idfexamplesbluetoothbluedroidbleblufi 中的例程
4.1 四个事件处理
4.1.1 WIFI部分事件处理
主要负责WIFI的连接、断开重连、扫描
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data){
wifi_event_sta_connected_t *event;
wifi_mode_t mode;
switch (event_id) {
case WIFI_EVENT_STA_START:
esp_wifi_connect();
break;
case WIFI_EVENT_STA_CONNECTED:
gl_sta_connected = true;
event = (wifi_event_sta_connected_t*) event_data;
memcpy(gl_sta_bssid, event->bssid, 6);
memcpy(gl_sta_ssid, event->ssid, event->ssid_len);
gl_sta_ssid_len = event->ssid_len;
break;
case WIFI_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
gl_sta_connected = false;
memset(gl_sta_ssid, 0, 32);
memset(gl_sta_bssid, 0, 6);
gl_sta_ssid_len = 0;
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
case WIFI_EVENT_AP_START:
esp_wifi_get_mode(&mode);
/* TODO: get config or information of softap, then set to report extra_info */
if (ble_is_connected == true) {
if (gl_sta_connected) {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, 0, NULL);
} else {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, 0, NULL);
}
} else {
BLUFI_INFO('BLUFI BLE is not connected yetn');
}
break;
case WIFI_EVENT_SCAN_DONE: {
uint16_t apCount = 0;
esp_wifi_scan_get_ap_num(&apCount);
if (apCount == 0) {
BLUFI_INFO('Nothing AP found');
break;
}
wifi_ap_record_t *ap_list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);
if (!ap_list) {
BLUFI_ERROR('malloc error, ap_list is NULL');
break;
}
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, ap_list));
esp_blufi_ap_record_t * blufi_ap_list = (esp_blufi_ap_record_t *)malloc(apCount * sizeof(esp_blufi_ap_record_t));
if (!blufi_ap_list) {
if (ap_list) {
free(ap_list);
}
BLUFI_ERROR('malloc error, blufi_ap_list is NULL');
break;
}
for (int i = 0; i < apCount; ++i)
{
blufi_ap_list[i].rssi = ap_list[i].rssi;
memcpy(blufi_ap_list[i].ssid, ap_list[i].ssid, sizeof(ap_list[i].ssid));
}
if (ble_is_connected == true) {
esp_blufi_send_wifi_list(apCount, blufi_ap_list);
} else {
BLUFI_INFO('BLUFI BLE is not connected yetn');
}
esp_wifi_scan_stop();
free(ap_list);
free(blufi_ap_list);
break;
}
default:
break;
}
return;}
4.1.2 NETIF部分事件处理
获取网络IP地址,完成IP接口搭建(默认IO口);
更多netif功能介绍与使用参考链接:ESP-NETIF
static void ip_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data){
wifi_mode_t mode;
switch (event_id) {
case IP_EVENT_STA_GOT_IP: {
esp_blufi_extra_info_t info;
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
esp_wifi_get_mode(&mode);
memset(&info, 0, sizeof(esp_blufi_extra_info_t));
memcpy(info.sta_bssid, gl_sta_bssid, 6);
info.sta_bssid_set = true;
info.sta_ssid = gl_sta_ssid;
info.sta_ssid_len = gl_sta_ssid_len;
if (ble_is_connected == true) {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, 0, &info);
} else {
BLUFI_INFO('BLUFI BLE is not connected yetn');
}
break;
}
default:
break;
}
return;}
4.1.3 BLUFI配网部分事件处理
此过程事件的处理均按照收到的请求作相应的功能处理,可按照个人需求进行修改
ESP_BLUFI_EVENT_INIT_FINISH:完成blufi功能初始化,设置设备名称(Device Name) 并发送特定的 adv data 广播;
ESP_BLUFI_EVENT_DEINIT_FINISH:处理deinit配置事件;
ESP_BLUFI_EVENT_BLE_CONNECT:连接Blufi Ble,并设备进入安全模式;
ESP_BLUFI_EVENT_BLE_DISCONNECT:设置ble断开重连;
ESP_BLUFI_EVENT_SET_WIFI_OPMODE:设置WiFi进入运行模式——op_mode;
ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP:设置断开原有的WiFi连接,并连接指定WiFi;
ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:断开当前WiIFi连接到的AP;
ESP_BLUFI_EVENT_REPORT_ERROR:上报错误信息;
ESP_BLUFI_EVENT_GET_WIFI_STATUS:获取WiFi状态信息,包括:WiFi当前模式、以及是否连接成功;
ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:关闭blufi的gatt服务连接;
ESP_BLUFI_EVENT_RECV_STA_BSSID:设置进入STA模式,获取目标AP的bssid;
ESP_BLUFI_EVENT_RECV_STA_SSID:设置进入STA模式,获取目标AP的WiFi账号;
ESP_BLUFI_EVENT_RECV_STA_PASSWD:设置进入STA模式,获取目标AP的WiFi密码;
ESP_BLUFI_EVENT_RECV_SOFTAP_SSID:设置进入Soft AP模式,获取AP自定义账号;
ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD:设置进入Soft AP模式,获取AP自定义密码;
ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM:设置Soft AP模式下最大可连接设备数量;
ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE:设置Soft AP模式下进入认证模式;
ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL:设置Soft AP模式下的通讯通道;
ESP_BLUFI_EVENT_GET_WIFI_LIST:获取扫描到的空中WiFi账号、通信通道以及站点MAC地址;
ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:将接收到的数据打印出来;
static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param){
/* actually, should post to blufi_task handle the procedure,
* now, as a example, we do it more simply */
switch (event) {
case ESP_BLUFI_EVENT_INIT_FINISH:
BLUFI_INFO('BLUFI init finishn');
esp_ble_gap_set_device_name(BLUFI_DEVICE_NAME);
esp_ble_gap_config_adv_data(&example_adv_data);
break;
case ESP_BLUFI_EVENT_DEINIT_FINISH:
BLUFI_INFO('BLUFI deinit finishn');
break;
case ESP_BLUFI_EVENT_BLE_CONNECT:
BLUFI_INFO('BLUFI ble connectn');
ble_is_connected = true;
server_if = param->connect.server_if;
conn_id = param->connect.conn_id;
esp_ble_gap_stop_advertising();
blufi_security_init();
break;
case ESP_BLUFI_EVENT_BLE_DISCONNECT:
BLUFI_INFO('BLUFI ble disconnectn');
ble_is_connected = false;
blufi_security_deinit();
esp_ble_gap_start_advertising(&example_adv_params);
break;
case ESP_BLUFI_EVENT_SET_WIFI_OPMODE:
BLUFI_INFO('BLUFI Set WIFI opmode %dn', param->wifi_mode.op_mode);
ESP_ERROR_CHECK( esp_wifi_set_mode(param->wifi_mode.op_mode) );
break;
上一篇:ESP32学习笔记(37)——搭建ESP-ADF(乐鑫音频开发框架)
下一篇:ESP32学习笔记(35)——蓝牙MAC地址
推荐阅读最新更新时间:2026-02-26 16:26
- DI-88 - PoE检测和分类(0-3类)接口电路
- LTC2207-14 和 LTC6401-14 的组合演示板 (14dB)
- DER-979 - 使用 InnoSwitch4-CZ PowiGaN 和 ClampZero 的 100 W 入墙式 USB 插座,具有可选输出电压
- LT1317CMS8 数码相机电源典型应用电路
- LT1171HVIQ、5V/2.5A 正电流升压降压转换器的典型应用
- LTC3633AEUFD-2 1.8V/2.5V 4MHz 降压稳压器典型应用电路
- AD8532ARZ-REEL7 高输出电流基准/稳压器的典型应用
- 154W、12V、16V、20V、125V交流转直流多路输出高清电视电源
- AD8601ARTZ-REEL 低侧运算放大器电流监视器的典型应用
- RDR-734 - 适用于使用 LinkSwitch-3 的设备的 8.4 W 开放式电源



【Follow me第三季第3期】代码
【Follow me第三季第3期】XIAO ESP32S3任务代码提交
Follow me第三季第3期源代码
现代雷达系统的信号设计
LM219H
BFR340T






京公网安备 11010802033920号