ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ESP-IDF BluFi 配网协议全解析:基于蓝牙通道的 Wi-Fi 配置实战指南

ESP-IDF BluFi 配网协议全解析:基于蓝牙通道的 Wi-Fi 配置实战指南 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、密码等配置信息经由蓝牙传输到设备端设备收到这些信息后即可连接指定的 APStation 模式或建立 SoftAP 热点。BluFi 流程的关键部分包括数据分片Fragmentation长数据如证书、认证信息可分片传输数据加密Encryption保护 SSID/密码等敏感信息在空中的传输安全校验和验证Checksum保证数据的完整性。用户可按需自定义对称加密、非对称加密以及校验算法。协议默认方案为DHDiffie-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.pngI (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.pngI (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/0x3SSID/密码与控制帧 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.pngI (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.cbtc_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 b01还是控制帧二进制0x0 b00子类型占高 6 位表示该帧的具体含义。规则控制帧暂不加密、可校验数据帧可加密、可校验。1.1 控制帧二进制0x0 b00控制帧含义解释备注0x0 (b000000)ACKACK 帧的数据字段使用回复对象帧的序列值数据字段占用 1 字节其序列值与回复对象帧的序列值相同0x1 (b000001)将 ESP 设备设置为安全模式通知设备发送数据时使用的安全模式发送过程中可多次重置设置后影响后续使用的安全模式。若不设置设备默认发送不带校验和加密的控制帧和数据帧数据字段占 1 字节高 4 位用于控制帧的安全模式低 4 位用于数据帧的安全模式。取值b0000无校验、无加密b0001有校验、无加密b0010无校验、有加密b0011有校验、有加密0x2 (b000010)设置 Wi-Fi 的 opmode包含设置设备 Wi-Fi 模式opmode的信息data[0]0x00NULL、0x01STA、0x02SoftAP、0x03SoftAP STA。若设置中包含 AP请尽量优先设置 AP 模式的 SSID/密码/最大连接数等0x3 (b000011)将 ESP 设备连接至 AP通知设备必要信息已发送完毕可以连接 AP不包含数据字段0x4 (b000100)断开 ESP 设备与 AP 的连接—不包含数据字段0x5 (b000101)获取 ESP 设备的 Wi-Fi 模式和状态等信息—不包含数据字段。设备收到后回发一个报告 Wi-Fi 连接状态的帧告知 opmode、连接状态、SSID 等提供给手机端的信息类型由手机应用决定0x6 (b000110)断开 STA 设备与 SoftAP 的连接SoftAP 模式—data[0~5]为 STA 设备 MAC 地址如有多个 STA 设备第二个使用data[6-11]依次类推0x7 (b000111)获取版本信息——0x8 (b001000)断开低功耗蓝牙 GATT 连接—设备收到后主动断开 GATT 连接0x9 (b001001)获取 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 b01数据帧含义解释备注0x0 (b000000)发送协商数据协商数据发送到应用层注册的回调函数中数据长度取决于数据长度字段0x1 (b000001)发送 STA 模式的 BSSIDSSID 隐藏时发送 STA 要连接的 AP 的 BSSID参见备注 10x2 (b000010)发送 STA 模式的 SSID发送 STA 要连接的 AP 的 SSID参见备注 10x3 (b000011)发送 STA 模式的密码发送 STA 要连接的 AP 的密码参见备注 10x4 (b000100)发送 SoftAP 模式的 SSID—参见备注 10x5 (b000101)发送 SoftAP 模式的密码—参见备注 10x6 (b000110)设置 SoftAP 模式的最大连接数—data[0]为连接数范围 1 到 4。若传输方向是设备到手机表示向手机端提供所需信息0x7 (b000111)设置 SoftAP 的认证模式—data[0]0x00OPEN、0x01WEP、0x02WPA_PSK、0x03WPA2_PSK、0x04WPA_WPA2_PSK。若传输方向是设备到手机表示向手机端提供所需信息0x8 (b001000)设置 SoftAP 模式的通道数量—data[0]代表支持的通道数量范围 1 到 14。若传输方向是设备到手机表示向手机端提供所需信息0x9 (b001001)用户名企业级加密时提供 GATT 客户端用户名数据长度取决于数据长度字段0xa (b001010)CA 认证企业级加密时提供 CA 认证参见备注 20xb (b001011)客户端认证企业级加密时提供客户端认证是否包含私钥取决于认证内容参见备注 20xc (b001100)服务端认证企业级加密时提供服务端认证是否包含私钥取决于认证内容参见备注 20xd (b001101)客户端私钥企业级加密时提供客户端私钥参见备注 20xe (b001110)服务端私钥企业级加密时提供服务端私钥参见备注 20xf (b001111)Wi-Fi 连接状态报告通知手机设备的 Wi-Fi 状态包括 STA 状态和 SoftAP 状态手机收到后除本帧外还可以回复其他帧data[0]表示 opmode0x00NULL、0x01STA、0x02SoftAP、0x03SoftAP STA。data[1]STA 连接状态0x0已连接且获得 IP、0x1未连接、0x2正在连接、0x3已连接但未获得 IP。data[2]SoftAP 连接状态即已连接的 STA 数量。data[3]及之后按 SSID/BSSID 格式提供信息正在连接时包含最大重连次数未连接时包含断开原因和 RSSI 信息0x10 (b010000)版本—data[0] 主版本data[1] 子版本0x11 (b010001)Wi-Fi 热点列表将 Wi-Fi 热点列表发送给设备数据帧格式为 Length RSSI SSID数据较长时可分片发送0x12 (b010010)报告异常通知手机 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 error0x13 (b010011)自定义数据用户发送或接收自定义数据数据较长时可分片发送0x14 (b010100)设置最大 Wi-Fi 重连次数—data[0]表示最大重连次数0x15 (b010101)设置 Wi-Fi 连接失败原因—data[0]表示失败原因类型与wifi_err_reason_t一致0x16 (b010110)设置 Wi-Fi 连接失败的 RSSI—data[0]表示连接失败时的 RSSI若结束时没有有意义的 RSSI应设为无意义值-128备注 1数据的长度取决于数据长度字段若传输方向是从设备到手机则表示向手机端提供所需信息。备注 2数据的长度取决于数据长度字段如果数据长度不够该帧可用分片。对照示例代码数据帧 0x1/0x2/0x3BSSID/SSID/密码与 0x4~0x8SoftAP 参数在 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未加密。加密部分包括数据字段加密之前的完整明文数据不包括校验部分。控制帧暂不加密故控制帧此位为 00x02帧尾是否包含校验位如 SHA1、MD5、CRC 等。该校验覆盖序列、数据长度以及明文。控制帧和数据帧都可选择包含或不包含校验位0x04数据方向0为手机到设备1为设备到手机0x08是否要求对方回复 ACK0不要求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.htypedef 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 UUID0xFFFF16 bitBluFi手机 → 设备特性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),仅供参考
返回列表