ESP-IDF BluFi API 完全指南:基于 BLE 的 Wi-Fi 配网协议与安全框架
ESP-IDF BluFi API 完全指南基于 BLE 的 Wi-Fi 配网协议与安全框架【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idfBluFi 是乐鑫 ESP-IDF 提供的一种基于 BLEGATT Profile的 Wi-Fi 配网协议它允许手机 App 通过蓝牙通道安全地将 Wi-Fi 凭据SSID/密码等下发给 ESP32 系列芯片从而让设备自动连接 AP 或建立 SoftAP。本文以 ESP-IDF 仓库中的 BluFi API 参考文档 为主线结合 BluFi 用户指南 与 源码实现系统讲解 BluFi 的事件模型、安全回调框架、核心 API 用法与底层帧格式帮助读者快速掌握这套成熟的 BLE 配网方案。BluFi 概述与核心设计思想根据 API 参考文档 的 Overview 说明BluFi 是一个基于 GATT Profile 的配网协议用于配置 ESP32 的 Wi-Fi 连接/断开 AP、建立 SoftAP 等操作。使用 BluFi 时开发者需要重点关注两件事事件驱动Profile 层会源源不断地向上抛出事件esp_blufi_cb_event_t应用层需要根据事件指示执行对应动作例如收到 STA SSID 后保存、收到连接请求后调用esp_wifi_connect()。安全参考BluFi 允许开发者自行实现安全函数包括对称加密/解密、校验和函数甚至可以自定义密钥交换/协商流程。协议层只规定数据如何封装、分片与校验具体加密算法完全开放。从 BluFi 用户指南 可以看到BluFi 的核心能力包括分片Fragmenting、数据加密与校验和验证三层机制。示例工程默认使用 DH 算法进行密钥协商、128-AES 算法进行数据加密、CRC16 算法进行校验和验证——但这些都只是默认示例开发者完全可以替换为自己的安全方案。注意官方明确指出BluFi 目前处于维护模式maintenance mode不再规划新功能。对于新项目或需要新增 Wi-Fi 配网能力的场景官方推荐使用network_provisioning组件modern、secure、actively maintained 的配网方案。应用示例仓库提供了可直接运行的 BluFi 示例工程 examples/bluetooth/blufi它演示了如何在目标芯片上通过蓝牙通道配置 Wi-Fi 连接 AP或把设备本身配置为 SoftAP示例主逻辑examples/bluetooth/blufi/main/blufi_example_main.c —— 包含事件回调、Wi-Fi 连接/重连、Wi-Fi 列表上报等完整流程安全实现examples/bluetooth/blufi/main/blufi_security.c —— 提供示例用的 DH 密钥协商与 AES 加解密、CRC16 校验实现初始化代码examples/bluetooth/blufi/main/blufi_init.c —— 完成 BLE 协议栈与 BluFi Profile 的初始化。示例依赖手机端配套 AppEspBlufiAndroid/iOS 均有对应开源版本App 通过蓝牙连接设备后即可进行配网操作。在 api-guides 用户指南 的 Getting Started 章节中详细描述了使用 EspBlufi App 将设备配置为 Station 模式或 SoftAP 模式的分步操作含截图与串口日志对照此处不再赘述 App 操作细节重点转向协议与 API 层面。设备上电完成初始化后串口会输出类似如下日志当手机 App 通过 BLE 连接成功后串口会输出如下日志BluFi 事件模型esp_blufi_cb_event_tBluFi 采用注册回调 事件分发的编程模型。应用层通过回调函数接收所有 Profile 事件事件类型定义在 esp_blufi_api.h事件触发时机ESP_BLUFI_EVENT_INIT_FINISHBluFi 初始化完成ESP_BLUFI_EVENT_DEINIT_FINISHBluFi 反初始化完成ESP_BLUFI_EVENT_SET_WIFI_OPMODE手机设置 ESP32 Wi-Fi 工作模式AP/STA/AP_STAESP_BLUFI_EVENT_BLE_CONNECT手机通过 BLE 连接上 ESP32ESP_BLUFI_EVENT_BLE_DISCONNECT手机与 ESP32 断开 BLE 连接ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP手机请求 ESP32 的 STA 连接 APESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP手机请求 ESP32 的 STA 断开 APESP_BLUFI_EVENT_GET_WIFI_STATUS手机获取 ESP32 Wi-Fi 状态ESP_BLUFI_EVENT_DEAUTHENTICATE_STA手机要求将某个 STA 从 SoftAP 踢下线ESP_BLUFI_EVENT_RECV_STA_BSSID收到手机发送的 STA BSSID用于隐藏 SSID 场景ESP_BLUFI_EVENT_RECV_STA_SSID收到手机发送的 STA SSIDESP_BLUFI_EVENT_RECV_STA_PASSWD收到手机发送的 STA 密码ESP_BLUFI_EVENT_RECV_SOFTAP_SSID收到手机发送的 SoftAP SSIDESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD收到手机发送的 SoftAP 密码ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM收到 SoftAP 最大连接数ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE收到 SoftAP 认证模式ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL收到 SoftAP 信道ESP_BLUFI_EVENT_RECV_USERNAME收到用户名企业级加密场景ESP_BLUFI_EVENT_RECV_CA_CERT收到 CA 证书ESP_BLUFI_EVENT_RECV_CLIENT_CERT收到客户端证书ESP_BLUFI_EVENT_RECV_SERVER_CERT收到服务端证书ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY收到客户端私钥ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY收到服务端私钥ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE收到手机发送的断开 BLE 指令ESP_BLUFI_EVENT_GET_WIFI_LIST手机请求获取 Wi-Fi 列表触发扫描ESP_BLUFI_EVENT_REPORT_ERRORBluFi 上报错误ESP_BLUFI_EVENT_RECV_CUSTOM_DATA收到手机发送的自定义数据事件回调函数的签名定义如下typedef void (* esp_blufi_event_cb_t)(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);回调参数param是一个联合体esp_blufi_cb_param_t根据event的不同其有效成员也不同。例如ESP_BLUFI_EVENT_BLE_CONNECT携带connect结构包含远端蓝牙地址remote_bda、服务端接口server_if、连接 IDconn_idESP_BLUFI_EVENT_RECV_STA_SSID携带sta_ssid结构包含 SSID 指针与长度。示例代码中通过switch (event)分发处理可参考 blufi_example_main.c。状态与错误枚举Wi-Fi 连接状态STAesp_blufi_sta_conn_state_t用于esp_blufi_send_wifi_conn_report()上报 STA 连接状态取值含义ESP_BLUFI_STA_CONN_SUCCESS (0x00)STA 连接成功ESP_BLUFI_STA_CONN_FAIL (0x01)STA 连接失败ESP_BLUFI_STA_CONNECTING (0x02)STA 正在连接ESP_BLUFI_STA_NO_IP (0x03)STA 已连接但未获取到 IP初始化/反初始化状态esp_blufi_init_state_t与esp_blufi_deinit_state_t分别用于INIT_FINISH与DEINIT_FINISH事件ESP_BLUFI_INIT_OK/ESP_BLUFI_DEINIT_OK表示成功_FAILED表示失败。错误状态esp_blufi_error_state_t用于ESP_BLUFI_EVENT_REPORT_ERROR事件及esp_blufi_send_error_info()覆盖协议运行中的各类异常取值含义ESP_BLUFI_SEQUENCE_ERROR序列号错误ESP_BLUFI_CHECKSUM_ERROR校验和错误ESP_BLUFI_DECRYPT_ERROR解密错误ESP_BLUFI_ENCRYPT_ERROR加密错误ESP_BLUFI_INIT_SECURITY_ERROR安全初始化错误ESP_BLUFI_DH_MALLOC_ERRORDH 内存分配错误ESP_BLUFI_DH_PARAM_ERRORDH 参数错误ESP_BLUFI_READ_PARAM_ERROR读取参数错误ESP_BLUFI_MAKE_PUBLIC_ERROR生成公钥错误ESP_BLUFI_DATA_FORMAT_ERROR数据格式错误ESP_BLUFI_CALC_MD5_ERRORMD5 计算错误为向后兼容保留ESP_BLUFI_WIFI_SCAN_FAILWi-Fi 扫描失败ESP_BLUFI_MSG_STATE_ERROR消息状态错误ESP_BLUFI_CALC_SHA_256_ERRORSHA-256 计算错误安全回调框架可完全自定义的加解密体系BluFi 是安全协议 开放安全接口的设计。协议层负责帧封装、分片重组与序列号防重放而密钥协商、加解密与校验全部通过回调交给应用层。四个安全回调类型定义在 esp_blufi_api.h1. 密钥协商处理器esp_blufi_negotiate_data_handler_ttypedef void (*esp_blufi_negotiate_data_handler_t)( uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);设备收到手机发来的协商数据后回调此函数。处理完成后输出数据通过output_data/output_len返回给 BluFi 协议层协议层会自动将其发送回手机。由于输出数据长度未知函数内需要自行malloc或指向全局变量并通过need_free告知协议层该内存是否需要在发送后释放。2. 加密函数esp_blufi_encrypt_func_ttypedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);加密明文数据必须支持原地in-place加密即输入输出可共用同一缓冲区加密前后数据长度必须保持一致。iv8是 8 位的帧序列值可将其作为 IV初始化向量的低 8 位使用。3. 解密函数esp_blufi_decrypt_func_ttypedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);与加密函数对称原地解密、长度不变、iv8同上。返回非负数为解密后长度出错返回负数。4. 校验和函数esp_blufi_checksum_func_ttypedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len);计算校验和并返回 16 位结果BluFi 协议层将用该返回值与帧内 CheckSum 字段比对实现完整性验证。回调注册结构esp_blufi_callbacks_t以上四个函数与事件回调共同组成一个注册结构typedef struct { esp_blufi_event_cb_t event_cb; esp_blufi_negotiate_data_handler_t negotiate_data_handler; esp_blufi_encrypt_func_t encrypt_func; esp_blufi_decrypt_func_t decrypt_func; esp_blufi_checksum_func_t checksum_func; } esp_blufi_callbacks_t;通过esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);一次性注册。默认安全方案与加固建议示例工程blufi_security.c默认采用DH 算法协商共享密钥 → 128-AES 加密数据 → CRC16 校验。但官方特别提醒示例中的默认加解密逻辑仅用于演示若应用需要更强安全性建议自定义安全回调实现自己的加密、解密、认证与校验算法并通过esp_blufi_register_callbacks注入或直接改用network_provisioning组件获得更健壮、面向生产的配网方案。从安全实现角度BluFi 协议本身已内置四层防护思路详见 BluFi 用户指南 的 Security 章节数据机密性Wi-Fi SSID/密码等敏感数据用对称加密AES/DES 等保护对称密钥先通过非对称算法DH/RSA/ECC 等协商数据完整性通过校验和算法SHA1/MD5/CRC 等保证数据未被篡改身份认证可使用 RSA 等签名算法若用 DH 则需配合其他签名算法防重放攻击帧内 Sequence Number 字段在每次发送时自动递增并在校验和计算中参与重连后序列清零。核心 API 函数详解BluFi 的应用层 API 全部声明在 esp_blufi_api.h底层 Profile 接口在 esp_blufi.h。按功能分为四组1. 生命周期管理esp_err_t esp_blufi_profile_init(void); // 初始化 BluFi Profile esp_err_t esp_blufi_profile_deinit(void); // 反初始化 BluFi Profile对应示例中的esp_blufi_profile_init()调用完成后会触发ESP_BLUFI_EVENT_INIT_FINISH事件携带init_finish.state。2. 数据上报设备 → 手机// 上报 Wi-Fi 连接报告opmode、STA 连接状态、SoftAP 已连接设备数、附加信息 esp_err_t esp_blufi_send_wifi_conn_report( wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info); // 上报扫描到的 Wi-Fi 列表 esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list); // 上报错误信息 esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state); // 发送自定义数据支持分片 esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len);其中esp_blufi_extra_info_t是附加信息结构可携带 STA 的 BSSID/SSID/密码、SoftAP 的 SSID/密码/认证模式/最大连接数/信道、STA 最大重连次数、连接结束原因、连接 RSSI 等字段。示例代码在 blufi_example_main.c 中通过example_record_wifi_conn_info()填充该结构并上报。esp_blufi_ap_record_t用于描述单个 APtypedef struct { uint8_t ssid[33]; // AP 的 SSID int8_t rssi; // AP 信号强度 } esp_blufi_ap_record_t;3. 版本查询uint16_t esp_blufi_get_version(void);返回 16 位版本号高 8 位为主版本低 8 位为子版本。4. Profile 底层控制接口esp_blufi.huint8_t esp_blufi_init(void); // 初始化 BluFi Profile旧接口 void esp_blufi_deinit(void); // 反初始化 void esp_blufi_adv_start(void); // 开始广播 void esp_blufi_adv_stop(void); // 停止广播 void esp_blufi_adv_start_with_name(const char *name); // 以指定名称开始广播 void esp_blufi_disconnect(void); // 断开当前连接 esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda); // 发起 SMP 安全请求其中esp_blufi_start_security_request()用于在 BLE 连接建立后触发 Security Manager ProtocolSMP流程与对端建立加密连接若 BluFi 的 BLE SMP 未启用则返回ESP_ERR_INVALID_STATE。此外esp_blufi.h中还定义了两个关键常量#define BLUFI_APP_UUID 0xFFFF // BluFi Service UUID16 bit #define BLUFI_DEVICE_NAME BLUFI_DEVICEGATT 服务与特征值BluFi 基于 GATT Server 实现其 UUID 布局如下见 BluFi 用户指南 的 GATT Related Instructions 章节角色UUID属性BluFi Service0xFFFF16 bit—手机 → ESP32 数据通道0xFF01可写writableESP32 → 手机数据通道0xFF02可读、可通知readable callable在 NimBLE 协议栈实现nimble_host/esp_blufi.c中GATT 服务器最多注册 3 个值SERVER_MAX_VALUES 3单值最大 512 字节MAX_VAL_SIZE 512并通过esp_blufi_gatt_svr_register_cb注册服务。BluFi 的实际数据交互通过 BLE 通知notification机制完成esp_blufi_send_notify()。协议帧格式深入协议层手机 App 与设备之间通过蓝牙通道交换的是结构化的协议帧。BluFi 使用 Type1 字节、Frame Control1 字节、Sequence Number1 字节、Data Length1 字节、DataN 字节、CheckSum2 字节组成帧。当 Frame Control 中分片位0x10置位时Data 字段前 2 字节为 Total Content Length指示剩余内容总长最大支持 64K 内容供接收方分配内存。Type 字段Type 占用 1 字节低 2 位表示帧类型b00控制帧、b01数据帧高 6 位为子类型。控制帧当前不加密但可带校验数据帧支持加密与校验。控制帧子类型手机 → 设备子类型含义说明0x0ACK数据字段携带被确认帧的序列号0x1设置安全模式data[0] 高 4 位控制控制帧安全模式、低 4 位控制数据帧安全模式b0000无校验无加密、b0001有校验无加密、b0010无校验有加密、b0011有校验有加密可多次设置默认无校验无加密0x2设置 Wi-Fi 工作模式data[0]0x00 NULL、0x01 STA、0x02 SoftAP、0x03 SoftAPSTA0x3连接 AP通知设备必要信息已发送完毕允许连接 AP0x4断开 AP无数据字段0x5获取 Wi-Fi 状态设备回发 Wi-Fi 连接状态报告帧0x6踢掉 SoftAP 下 STAdata[0~5] 为 STA MAC 地址多设备依次排列0x7获取版本信息—0x8断开 BLE GATT 链路设备收到后断开 BLE 连接0x9获取 Wi-Fi 列表设备扫描后回发 Wi-Fi 列表报告数据帧子类型双向子类型含义说明0x0协商数据交给应用层negotiate_data_handler处理0x1STA BSSID隐藏 SSID 场景下指定目标 AP0x2STA SSID待连接 AP 的 SSID0x3STA 密码待连接 AP 的密码0x4SoftAP SSID—0x5SoftAP 密码—0x6SoftAP 最大连接数data[0] 取值范围 1~40x7SoftAP 认证模式data[0]0x00 OPEN、0x01 WEP、0x02 WPA_PSK、0x03 WPA2_PSK、0x04 WPA_WPA2_PSK0x8SoftAP 信道data[0] 取值范围 1~140x9用户名企业级加密场景0xaCA 证书企业级加密支持分片0xb客户端证书企业级加密支持分片0xc服务端证书企业级加密支持分片0xd客户端私钥企业级加密支持分片0xe服务端私钥企业级加密支持分片0xfWi-Fi 连接状态报告data[0] opmodedata[1] STA 状态0x0 已连接有 IP、0x1 断开、0x2 连接中、0x3 已连接无 IPdata[2] SoftAP 连接数后续为 SSID/BSSID 信息连接中携带最大重连次数断开时携带结束原因与 RSSI0x10版本data[0] 主版本、data[1] 子版本0x11Wi-Fi 列表格式为 长度RSSISSID过长可分片0x12报告错误错误码与esp_blufi_error_state_t对应0x13自定义数据双向过长可分片0x14最大重连次数data[0]0x15连接结束原因类型同wifi_err_reason_t0x16连接结束 RSSIdata[0]无意义时填 -128Frame Control 字段Frame Control 占 1 字节按位定义Bit含义0x01是否加密1 加密 / 0 不加密加密范围为 DATA 字段之前的完整明文不含校验和0x02帧尾是否含校验和SHA1/MD5/CRC 等控制帧与数据帧均可选0x04数据方向0 手机→设备1 设备→手机0x08是否需要对方回复 ACK1 需要0x10是否有后续分片1 表示存在后续分片此时 Data 前 2 字节为总内容长度0x10~0x80保留Sequence Number 与 CheckSumSequence Number为序列控制字段每发送一帧自动加 1与帧类型无关用于防止重放攻击每次重连后清零。Data Length表示 Data 字段长度不含 CheckSum。CheckSum占 2 字节校验对象为 sequence data length 明文数据。典型配网流程综合 BluFi 用户指南 的流程描述与源码实现一次完整的 Station 配网流程如下设备上电进入 GATT Server 模式并广播特定 advertising data广播内容可由开发者自定义不属于 BluFi Profile 范畴手机 App 扫描到广播并作为 GATT Client 发起连接连接建立后手机发送密钥协商数据帧设备回调negotiate_data_handler完成 DH/RSA/ECC 等协商协商完成后手机发送控制帧设置安全模式0x1此后数据帧按约定的加解密/校验策略传输手机依次发送 STA 的 BSSID/SSID/密码等数据帧对应ESP_BLUFI_EVENT_RECV_STA_BSSID/SSID/PASSWD事件手机发送控制帧请求连接 AP0x3对应ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP事件设备调用esp_wifi_connect()设备连接成功后通过esp_blufi_send_wifi_conn_report()回发连接状态报告帧0xf配网流程完成。示例工程完整实现了上述流程包括 Wi-Fi 事件组等待、断线重连example_wifi_reconnect()按CONFIG_EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY重试、BSSID/SSID 记录与状态上报等可作为自定义配网应用的参考模板。注意示例编译前提是目标 SoC 支持 BluFi代码中有#ifndef CONFIG_SOC_BLUFI_SUPPORTED的编译期检查。总结BluFi 是 ESP-IDF 中一套成熟、开放、可深度定制的 BLE 配网协议它通过 GATT Profile 承载配网数据以事件回调驱动应用逻辑并将密钥协商、加解密、校验等安全环节全部抽象为可替换的回调函数配合完善的帧格式分片、序列号防重放、校验和保证传输的可靠与安全。虽然官方已将其置于维护模式并推荐新项目改用network_provisioning但 BluFi 的协议设计与实现思路事件模型、安全回调框架、帧结构对于理解 BLE 配网和自研配网协议仍有很高的参考价值。相关资源速览API 头文件esp_blufi_api.hProfile 头文件esp_blufi.h协议实现blufi_protocol.c、blufi_prf.c示例工程examples/bluetooth/blufi配套用户指南docs/en/api-guides/ble/blufi.rst【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →