ESP-IDF BluFi 配网协议全解析:基于蓝牙通道的 Wi-Fi 配置实战指南
【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf
本指南以 ESP-IDF 官方文档《BluFi》(docs/zh_CN/api-guides/ble/blufi.rst)为主体,结合仓库内的 BluFi 示例工程与协议栈源码,系统讲解 BluFi 的配网流程、帧格式、安全机制以及基于 EspBlufi 手机应用的完整实操步骤,帮助开发者快速掌握这一经典蓝牙配网方案的原理与用法。
概览:BluFi 是什么
BluFi 是 ESP-IDF 提供的一项基于蓝牙通道的 Wi-Fi 网络配置功能,适用于 ESP32 系列芯片。它通过一套安全协议,将 Wi-Fi 的 SSID、密码等配置信息经由蓝牙传输到设备端;设备收到这些信息后,即可连接指定的 AP(Station 模式)或建立 SoftAP 热点。
BluFi 流程的关键部分包括:
- 数据分片(Fragmentation):长数据(如证书、认证信息)可分片传输;
- 数据加密(Encryption):保护 SSID/密码等敏感信息在空中的传输安全;
- 校验和验证(Checksum):保证数据的完整性。
用户可按需自定义对称加密、非对称加密以及校验算法。协议默认方案为:
- DH(Diffie-Hellman)算法:用于密钥协商,协商出共享密钥;
- 128 位 AES 算法:用于数据加密;
- CRC16 算法:用于校验和验证。
注意:维护状态BluFi 目前处于维护模式,官方暂不计划增加新功能。对于新项目或需要添加 Wi-Fi 配网功能的场景,官方建议使用 ESP-IDF 额外组件仓库(idf-extra-components)中的
network_provisioning组件——它更加现代、安全,并且仍在积极维护中。仓库中的示例说明同样标注了这一点(见 examples/bluetooth/blufi/README.md)。
快速入门:使用 EspBlufi 应用完成配网
本节将指导读者使用 EspBlufi 手机应用在设备上配置 Wi-Fi。
硬件及软件准备
硬件:
- ESP32 系列模组/开发板一个(仓库示例支持 ESP32、ESP32-C2/C3/C5/C6/C61、ESP32-S3/S31,见 examples/bluetooth/blufi/README.md 中的 Supported Targets 表);
- 电脑一台,与模组连接,为其供电并提供串口打印;
- 运行 Android 或 iOS 的手机一台。
软件:
- BluFi 示例工程:examples/bluetooth/blufi(需编译并烧录至设备);
- 手机应用程序 EspBlufi:可从 Espressif 官方渠道获取 Android 版(EspBlufi For Android)与 iOS 版(EspBlufi For iOS)。
关于示例工程的烧录与编译,参考 ESP-IDF 的入门指南。工程使用方式很简单:先通过idf.py set-target <chip_name>设置目标芯片,再执行idf.py -p PORT flash monitor完成编译、烧录与串口监视(退出串口监视按Ctrl-])。
Station 模式配置示例
1. 给设备上电
将设备连接至电脑,通过串口工具可看到如下初始化完成的打印(对应文档插图 blufi-init-finish.png):
I (3185) BLUFI_DEMO: BD ADDR: 24:0a:c4:01:4d:be I (3185) BLUFI_DEMO: BLUFI_VERSION 0100 I (3185) BLUFI_DEMO: BLUFI init finish日志中的BLUFI_VERSION即示例通过esp_blufi_get_version()获取的 BluFi 协议版本号(见 blufi_example_main.c 末尾的BLUFI_INFO("BLUFI VERSION %04x\n", esp_blufi_get_version()))。
2. 通过 EspBlufi 建立连接
- 在手机上开启 Wi-Fi、蓝牙和位置权限;
- 打开 EspBlufi 应用程序,下拉刷新界面,扫描附近的蓝牙设备;
- 点击目标设备,选择连接建立蓝牙连接。连接成功后,界面会显示已连接状态;同时串口工具会打印类似如下的信息(见 blufi-ble-connect.png)。
若界面未显示配网按钮,或按钮无法点击,请重启设备并确认已开启蓝牙权限。
3. 配置 Wi-Fi 网络
点击配网按钮进入网络配置界面;
从下拉列表中选择设备模式。BluFi 支持以下三种模式:
- Station:连接至现有 Wi-Fi 网络;
- SoftAP:创建 Wi-Fi 热点;
- SoftAP/Station:同时启用 SoftAP 和 Station 模式。
选择Station模式,点击刷新按钮扫描附近的 Wi-Fi 热点,选择目标 Wi-Fi 名称并输入密码;
点击确定完成配置。成功连接后界面会显示当前 Wi-Fi 模式及连接信息(如 AP 的 BSSID、SSID 和连接状态)。
ESP32 系列设备仅支持 2.4 GHz Wi-Fi,请确保选择兼容的网络。
此时串口工具会打印完整的配网过程(见 station-connection-log.png):
I (121745) BLUFI_DEMO: BLUFI Set WIFI opmode 1 I (121845) BLUFI_DEMO: Recv STA SSID DVES_HOME I (121945) BLUFI_DEMO: Recv STA PASSWORD 12345678 I (122085) BLUFI_DEMO: BLUFI request wifi connect to AP I (122955) wifi: n:6 2, o:1 0, ap:255 255, sta:6 2, prof:1 I (123615) wifi: init -> auth (0) I (123625) wifi: state: auth -> assoc (0) I (123645) wifi: state: assoc -> run (10) I (123675) wifi: connected with DVES_HOME, channel 6 I (124305) event: ip: 192.168.1.105, mask: 255.255.255.0, gw: 192.168.1.1注意其中依次出现的BLUFI Set WIFI opmode 1、Recv STA SSID、Recv STA PASSWORD、BLUFI request wifi connect to AP,恰好对应下文 BluFi 协议中的控制帧 0x2(设置 opmode)、数据帧 0x2/0x3(SSID/密码)与控制帧 0x3(连接 AP)。这些日志由示例的事件回调打印,对应实现可参见 blufi_example_main.c 中的example_event_callback()。
SoftAP 模式配置示例
1. 通过 EspBlufi 建立连接
将模组上电,使用 EspBlufi 应用通过蓝牙连接设备,在配网界面选择SoftAP模式。
2. 配置 SoftAP 参数
- 选择加密方式、信道和最大连接数;
- 输入 SoftAP 的 SSID 和密码;
- 点击确定完成配置。
3. 验证 SoftAP 配置
成功配置 SoftAP 后,界面显示当前 Wi-Fi 模式和连接状态;串口工具打印如下信息(见 softap-connection-log.png):
I (141967) wifi: mode : softAP (24:0a:c4:01:4d:be) I (142067) BLUFI_DEMO: Recv SOFTAP SSID blufi_softap I (142167) BLUFI_DEMO: Recv SOFTAP PASSWORD 12345678 I (142267) BLUFI_DEMO: Recv SOFTAP CHANNEL 10 I (142357) BLUFI_DEMO: Recv SOFTAP MAX CONN NUM 2 I (143107) BLUFI_DEMO: Recv SOFTAP AUTH MODE 44. 连接 SoftAP 热点
- 打开手机 Wi-Fi,可搜索到已配置的 SoftAP 热点;
- 连接该热点,成功连接后设备即已入网。
至此,设备已通过蓝牙配网成功连接 Wi-Fi 网络。
BluFi 配网流程与协议交互
BluFi 配网流程包含配置 SoftAP 和配置 Station 两部分。下面以配置 Station 为例,说明广播、连接、服务发现、协商共享密钥、传输数据、回传连接状态等关键步骤:
- 设备开启 GATT Server 模式,发送带有特定advertising data的广播。该广播不属于 BluFi Profile,可以按需自定义;
- 手机应用搜索到该广播后,作为 GATT Client 连接设备(该步骤对具体使用哪款手机应用并无特殊要求);
- 建立 GATT 连接后,手机向设备发送数据帧进行密钥协商(帧格式见下文);
- 设备收到密钥协商数据帧后,按自定义的协商方法进行解析;
- 手机与设备进行密钥协商,协商过程可使用DH/RSA/ECC等非对称加密算法;
- 协商结束后,手机向设备发送控制帧,用于设置安全模式;
- 设备收到控制帧后,使用共享密钥及安全配置对通信数据进行加密和解密;
- 手机向设备发送数据帧,包括 SSID、密码等 Wi-Fi 配置信息;
- 手机向设备发送Wi-Fi 连接请求的控制帧。设备收到后即默认手机已完成必要信息的传输,准备连接 Wi-Fi;
- 设备连接 Wi-Fi 后,发送Wi-Fi 连接状态报告的控制帧到手机,至此配网结束。
注意:设备收到安全模式配置的控制帧后,会根据定义的安全模式进行相关操作;进行对称加密和解密时,加密和解密前后的数据长度必须一致,且支持原地加密和解密(即输入输出共用同一缓冲区,参见 API 文档中
esp_blufi_encrypt_func_t的 "autochthonous encrypt" 说明)。
BluFi 流程图
整个交互可用如下时序描述:
Phone <-- 设备 广播 Phone --> 设备 建立 GATT 链接 Phone --> 设备 协商密钥 Phone <-- 设备 协商密钥 Phone --> 设备 CTRL: 设置设备为手机安全模式 Phone --> 设备 DATA: SSID Phone --> 设备 DATA: Password Phone --> 设备 DATA: 其他信息,如 CA 认证 Phone --> 设备 CTRL: 连接到 AP Phone <-- 设备 DATA: 连接状态报告从源码角度看,这条链路在协议栈中的落点位于 blufi_protocol.c:btc_blufi_protocol_handler()根据帧类型字段(BLUFI_GET_TYPE)区分控制帧与数据帧,控制帧(如设置 opmode、连接 AP、断开 AP、获取 Wi-Fi 状态、获取版本等)通过btc_transfer_context转交上层事件回调;数据帧(如协商数据、SSID/密码)则递交给blufi_env.cbs中注册的回调函数处理。
BluFi 帧格式详解
手机应用与设备之间的 BluFi 通信帧格式定义如下。
帧不分片格式
| 字段 | 值(字节) |
|---|---|
| 类型(最低有效位) | 1 |
| 帧控制 | 1 |
| 序列号 | 1 |
| 数据长度 | 1 |
| 数据 | ${Data Length} |
| 校验(最高有效位) | 2 |
如果使能帧控制字段中的分片位,则数据字段中会出现 2 字节的内容总长度。该内容总长度表示帧的剩余部分的总长度,并用于报告终端需要分配的内存大小。
帧分片格式
| 字段 | 值(字节) |
|---|---|
| 类型(最低有效位) | 1 |
| 帧控制(分片) | 1 |
| 序列号 | 1 |
| 数据长度 | 1 |
| 数据 | 内容总长度:2;数据内容长度:${Data Length} - 2 |
| 校验(最高有效位) | 2 |
通常情况下,控制帧不包含数据位,ACK 帧类型除外。
ACK 帧格式(8 bit)
| 字段 | 值(字节) |
|---|---|
| 类型 - ACK(最低有效位) | 1 |
| 帧控制 | 1 |
| 序列号 | 1 |
| 数据长度 | 1 |
| 数据 | ACK 序列号:2 |
| 校验(最高有效位) | 2 |
类型字段
类型字段占 1 字节,分为类型与子类型两部分:
- 类型占低 2 位,表明该帧是数据帧(二进制
0x1 b'01)还是控制帧(二进制0x0 b'00); - 子类型占高 6 位,表示该帧的具体含义。
规则:控制帧暂不加密、可校验;数据帧可加密、可校验。
1.1 控制帧(二进制:0x0 b'00)
| 控制帧 | 含义 | 解释 | 备注 |
|---|---|---|---|
| 0x0 (b'000000) | ACK | ACK 帧的数据字段使用回复对象帧的序列值 | 数据字段占用 1 字节,其序列值与回复对象帧的序列值相同 |
| 0x1 (b'000001) | 将 ESP 设备设置为安全模式 | 通知设备发送数据时使用的安全模式,发送过程中可多次重置,设置后影响后续使用的安全模式。若不设置,设备默认发送不带校验和加密的控制帧和数据帧 | 数据字段占 1 字节:高 4 位用于控制帧的安全模式,低 4 位用于数据帧的安全模式。取值:b'0000无校验、无加密;b'0001有校验、无加密;b'0010无校验、有加密;b'0011有校验、有加密 |
| 0x2 (b'000010) | 设置 Wi-Fi 的 opmode | 包含设置设备 Wi-Fi 模式(opmode)的信息 | data[0]:0x00NULL、0x01STA、0x02SoftAP、0x03SoftAP & STA。若设置中包含 AP,请尽量优先设置 AP 模式的 SSID/密码/最大连接数等 |
| 0x3 (b'000011) | 将 ESP 设备连接至 AP | 通知设备必要信息已发送完毕,可以连接 AP | 不包含数据字段 |
| 0x4 (b'000100) | 断开 ESP 设备与 AP 的连接 | — | 不包含数据字段 |
| 0x5 (b'000101) | 获取 ESP 设备的 Wi-Fi 模式和状态等信息 | — | 不包含数据字段。设备收到后回发一个报告 Wi-Fi 连接状态的帧,告知 opmode、连接状态、SSID 等;提供给手机端的信息类型由手机应用决定 |
| 0x6 (b'000110) | 断开 STA 设备与 SoftAP 的连接(SoftAP 模式) | — | data[0~5]为 STA 设备 MAC 地址;如有多个 STA 设备,第二个使用data[6-11],依次类推 |
| 0x7 (b'000111) | 获取版本信息 | — | — |
| 0x8 (b'001000) | 断开低功耗蓝牙 GATT 连接 | — | 设备收到后主动断开 GATT 连接 |
| 0x9 (b'001001) | 获取 Wi-Fi 列表 | 通知设备扫描周围 Wi-Fi 热点 | 不包含数据字段。设备收到后会回发一个包含 Wi-Fi 热点报告的帧 |
对照源码:上述控制帧在 blufi_protocol.c 中分别对应BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE(写入blufi_env.sec_mode)、SET_WIFI_OPMODE、CONN_TO_AP、DISCONN_FROM_AP、GET_WIFI_STATUS、DEAUTHENTICATE_STA、GET_VERSION(回发BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION)、DISCONNECT_BLE、GET_WIFI_LIST等分支。
1.2 数据帧(二进制:0x1 b'01)
| 数据帧 | 含义 | 解释 | 备注 |
|---|---|---|---|
| 0x0 (b'000000) | 发送协商数据 | 协商数据发送到应用层注册的回调函数中 | 数据长度取决于数据长度字段 |
| 0x1 (b'000001) | 发送 STA 模式的 BSSID | SSID 隐藏时,发送 STA 要连接的 AP 的 BSSID | 参见备注 1 |
| 0x2 (b'000010) | 发送 STA 模式的 SSID | 发送 STA 要连接的 AP 的 SSID | 参见备注 1 |
| 0x3 (b'000011) | 发送 STA 模式的密码 | 发送 STA 要连接的 AP 的密码 | 参见备注 1 |
| 0x4 (b'000100) | 发送 SoftAP 模式的 SSID | — | 参见备注 1 |
| 0x5 (b'000101) | 发送 SoftAP 模式的密码 | — | 参见备注 1 |
| 0x6 (b'000110) | 设置 SoftAP 模式的最大连接数 | — | data[0]为连接数,范围 1 到 4。若传输方向是设备到手机,表示向手机端提供所需信息 |
| 0x7 (b'000111) | 设置 SoftAP 的认证模式 | — | data[0]:0x00OPEN、0x01WEP、0x02WPA_PSK、0x03WPA2_PSK、0x04WPA_WPA2_PSK。若传输方向是设备到手机,表示向手机端提供所需信息 |
| 0x8 (b'001000) | 设置 SoftAP 模式的通道数量 | — | data[0]代表支持的通道数量,范围 1 到 14。若传输方向是设备到手机,表示向手机端提供所需信息 |
| 0x9 (b'001001) | 用户名 | 企业级加密时提供 GATT 客户端用户名 | 数据长度取决于数据长度字段 |
| 0xa (b'001010) | CA 认证 | 企业级加密时提供 CA 认证 | 参见备注 2 |
| 0xb (b'001011) | 客户端认证 | 企业级加密时提供客户端认证,是否包含私钥取决于认证内容 | 参见备注 2 |
| 0xc (b'001100) | 服务端认证 | 企业级加密时提供服务端认证,是否包含私钥取决于认证内容 | 参见备注 2 |
| 0xd (b'001101) | 客户端私钥 | 企业级加密时提供客户端私钥 | 参见备注 2 |
| 0xe (b'001110) | 服务端私钥 | 企业级加密时提供服务端私钥 | 参见备注 2 |
| 0xf (b'001111) | Wi-Fi 连接状态报告 | 通知手机设备的 Wi-Fi 状态,包括 STA 状态和 SoftAP 状态;手机收到后除本帧外还可以回复其他帧 | data[0]表示 opmode:0x00NULL、0x01STA、0x02SoftAP、0x03SoftAP & STA。data[1]:STA 连接状态,0x0已连接且获得 IP、0x1未连接、0x2正在连接、0x3已连接但未获得 IP。data[2]:SoftAP 连接状态,即已连接的 STA 数量。data[3]及之后按 SSID/BSSID 格式提供信息:正在连接时包含最大重连次数;未连接时包含断开原因和 RSSI 信息 |
| 0x10 (b'010000) | 版本 | — | data[0]= 主版本,data[1]= 子版本 |
| 0x11 (b'010001) | Wi-Fi 热点列表 | 将 Wi-Fi 热点列表发送给设备 | 数据帧格式为 Length + RSSI + SSID,数据较长时可分片发送 |
| 0x12 (b'010010) | 报告异常 | 通知手机 BluFi 过程出现异常 | 错误码:0x00sequence error、0x01checksum error、0x02decrypt error、0x03encrypt error、0x04init security error、0x05dh malloc error、0x06dh param error、0x07read param error、0x08make public error、0x09data format error、0x0acalculate MD5 error、0x0bWi-Fi scan error |
| 0x13 (b'010011) | 自定义数据 | 用户发送或接收自定义数据 | 数据较长时可分片发送 |
| 0x14 (b'010100) | 设置最大 Wi-Fi 重连次数 | — | data[0]表示最大重连次数 |
| 0x15 (b'010101) | 设置 Wi-Fi 连接失败原因 | — | data[0]表示失败原因,类型与wifi_err_reason_t一致 |
| 0x16 (b'010110) | 设置 Wi-Fi 连接失败的 RSSI | — | data[0]表示连接失败时的 RSSI;若结束时没有有意义的 RSSI,应设为无意义值-128 |
备注 1:数据的长度取决于数据长度字段;若传输方向是从设备到手机,则表示向手机端提供所需信息。备注 2:数据的长度取决于数据长度字段;如果数据长度不够,该帧可用分片。
对照示例代码,数据帧 0x1/0x2/0x3(BSSID/SSID/密码)与 0x4~0x8(SoftAP 参数)在 blufi_example_main.c 中分别触发ESP_BLUFI_EVENT_RECV_STA_BSSID、RECV_STA_SSID、RECV_STA_PASSWD、RECV_SOFTAP_SSID、RECV_SOFTAP_PASSWD、RECV_SOFTAP_MAX_CONN_NUM、RECV_SOFTAP_AUTH_MODE、RECV_SOFTAP_CHANNEL等事件;注意示例对 SoftAP 最大连接数做了> 4的防御性校验,与协议规定的 1~4 范围一致;而 Wi-Fi 状态报告帧(0xf)则对应esp_blufi_send_wifi_conn_report()的调用。
帧控制字段
帧控制字段占 1 字节,每个位表示不同含义:
| 位 | 含义 |
|---|---|
| 0x01 | 帧是否加密:1加密,0未加密。加密部分包括数据字段加密之前的完整明文数据(不包括校验部分)。控制帧暂不加密,故控制帧此位为 0 |
| 0x02 | 帧尾是否包含校验位(如 SHA1、MD5、CRC 等)。该校验覆盖序列、数据长度以及明文。控制帧和数据帧都可选择包含或不包含校验位 |
| 0x04 | 数据方向:0为手机到设备,1为设备到手机 |
| 0x08 | 是否要求对方回复 ACK:0不要求,1要求 |
| 0x10 | 是否有后续数据分片:0无后续分片,1还有后续分片用于传输较长数据。对于分片帧,在数据字段前两个字节中给出当前内容部分和随后内容部分的总长度(即最大支持 64 K 的数据内容) |
| 0x10~0x80 | 保留 |
序列控制
序列控制字段在帧发送时自动加 1(无论帧类型),用于防止重放攻击(Replay Attack);每次重新连接后序列清零。API 层将帧的 8 位序列作为 IV8 传入加密/解密/校验回调,作为初始化向量的一部分参与运算(见下文安全实现)。
长度、数据与校验
- 长度:数据字段的长度,不包含校验部分;
- 数据:对于不同的类型或子类型,数据字段含义不同(参考上文表格);
- 校验:占两个字节,用来校验序列、数据长度以及明文。
ESP32 端的安全实现
为保证 Wi-Fi 配网过程的安全性,BluFi 在设备端设计了四层安全机制:
1. 数据安全
为保证 Wi-Fi SSID 和密码的传输安全,需使用对称加密算法(如 AES、DES 等)对报文加密;使用对称加密之前,需先用非对称加密算法(DH、RSA、ECC 等)协商(或生成)出一个共享密钥。仓库示例在 blufi_security.c 中实现了完整的 DH 密钥协商与 AES 加解密:协商数据包含SEC_TYPE_DH_PARAM_LEN/DATA、SEC_TYPE_DH_P、SEC_TYPE_DH_G、SEC_TYPE_DH_PUBLIC等自定义类型,AES 密钥长度为 32 字节,加解密操作对象在连接建立(ESP_BLUFI_EVENT_BLE_CONNECT)时通过blufi_security_init()初始化。
2. 保证数据完整性
为保证数据完整性,需加入校验算法,例如 SHA1、MD5、CRC 等。示例使用 CRC 校验(blufi_crc_checksum)。
3. 身份安全(签名)
某些算法如 RSA 可以保证身份安全;但 DH 这类算法本身不能保证身份安全,需要添加其他算法进行签名。
4. 防止重放攻击(Replay Attack)
在序列字段中加入序列号,并在数据校验过程中使用(校验覆盖序列字段)。
在设备端代码中,你可以决定和开发如密钥协商等安全处理的流程:手机应用向设备发送协商数据,数据会传送给应用层处理;如果应用层不处理,可使用 BluFi 提供的 DH 加密算法来协商密钥。
安全回调函数注册
应用层需向 BluFi 注册以下几个与安全相关的回调函数,其完整定义位于 esp_blufi_api.h:
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传出。BluFi 会在调用完negotiate_data_handler后,发送其传出的output_data。这里的两个*是因为需要发出去的数据长度未知,所以需要函数自行分配(malloc)或指向全局变量,并通过need_free告知是否需要释放内存。
typedef int (*esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)加密和解密的数据长度必须一致。其中iv8为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
typedef int (*esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)加密和解密的数据长度必须一致。其中iv8为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)该函数用来进行校验,返回值为校验的值。BluFi 会使用该函数返回值与帧的校验值进行比较。
上述四个回调连同事件回调一起,通过esp_blufi_callbacks_t结构体聚合:
typedef struct { esp_blufi_event_cb_t event_cb; /*!< BLUFI event callback */ esp_blufi_negotiate_data_handler_t negotiate_data_handler; /*!< negotiate share key */ esp_blufi_encrypt_func_t encrypt_func; /*!< encrypt data with share key */ esp_blufi_decrypt_func_t decrypt_func; /*!< decrypt data with share key */ esp_blufi_checksum_func_t checksum_func; /*!< check sum function (FCS) */ } esp_blufi_callbacks_t;示例工程在 blufi_example_main.c 中按此结构注册了 DH 协商、AES 加解密与 CRC 校验回调,并调用esp_blufi_host_and_cb_init(&example_callbacks)完成初始化:
static esp_blufi_callbacks_t example_callbacks = { .event_cb = example_event_callback, .negotiate_data_handler = blufi_dh_negotiate_data_handler, .encrypt_func = blufi_aes_encrypt, .decrypt_func = blufi_aes_decrypt, .checksum_func = blufi_crc_checksum, };在协议栈侧,协商数据帧会直接调用negotiate_data_handler并将产出通过封包回发手机(见 blufi_protocol.c 中BLUFI_TYPE_DATA_SUBTYPE_NEG分支),这印证了"协商数据由应用层回调处理"的设计。
实现更强的安全性
示例中的默认加密、解密逻辑仅用于演示目的。如果你的应用需要更高的安全保障,可选择以下任一方法:
- 自定义安全回调:通过改写 BluFi 框架中的安全回调函数,自定义加密、解密、认证以及校验算法:
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);- 网络配网组件(推荐):使用 ESP-IDF 额外组件仓库中的
network_provisioning组件,实现安全、可直接使用的配网解决方案。
GATT 相关说明:UUID 定义
BluFi 基于标准 BLE GATT 服务实现,使用固定 UUID(可在 esp_blufi.h 中看到BLUFI_APP_UUID 0xFFFF的定义):
- BluFi Service UUID:
0xFFFF,16 bit; - BluFi(手机 → 设备)特性:
0xFF01,主要权限:可写; - BluFi(设备 → 手机)特性:
0xFF02,主要权限:可读、可通知。
其中 0xFF01 用于手机下发配网帧,0xFF02 用于设备上报状态(如 Wi-Fi 连接状态报告、Wi-Fi 热点列表等),与上文帧格式中"数据方向"位(0x04)的语义相互印证。
小结
BluFi 为 ESP-IDF 提供了一套完整、可裁剪的蓝牙配网协议栈:从 GATT 层的 UUID 定义,到帧层的分片/加密/校验设计,再到应用层的安全回调注册,均有清晰的实现与示例支撑。本文结合 BluFi 官方文档、示例工程 与协议栈源码,完整还原了 Station/SoftAP 两种配网流程、全部帧类型定义及设备端安全机制,可作为二次开发与协议联调的直接参考。需要提醒的是,BluFi 已处于维护模式,新项目建议优先评估network_provisioning组件;若仍需使用 BluFi,请务必自行实现或加固安全回调,以保障配网凭据的传输安全。
【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考