Blufi 是乐鑫设计的一个用在 ESP32 上的蓝牙配网协议,网上开源 Blufi 协议细节和实现代码。最近一个项目需要用到 Blufi,将其移植到了 bk 的 bk7231n mcu WiFi 上。
下面是 esp-idf 上 Blufi 实现的代码整理。
移植过程主要需要关注 ble 驱动和应用 api 两部分,应用接口相关代码对平台没有太多依赖,主要解决从 esp-idf 迁移到新平台上的编译问题;ble 驱动层相关的代码则需要替换为新平台的实现,这里改动较为费劲。
Blufi 的代码流程可以看 esp-idf 代码中 blufi_profile_cb、esp_blufi_gap_event_handler、btc_blufi_cb_handler、btc_blufi_call_handler 这几个回调函数中各个事件的处理过程。驱动层主要关注的事情:
- ble GATT UUID 配置
- ble 广播开启和关闭
- ble 连接断开,数据读写的事件的处理
- wifi sta softap 的配置,状态获取,连接断开事件处理
Blufi 协议设计的一些考量
Blufi 协议帧格式如下。
帧不分片格式:
字段 | 值(字节) |
---|---|
类型(最低有效位) | 1 |
帧控制 | 1 |
序列号 | 1 |
数据长度 | 1 |
数据 | ${Data Length} |
校验(最高有效位) | 2 |
帧分片格式:
字段 | 值(字节) |
---|---|
类型(最低有效位) | 1 |
帧控制(分片) | 1 |
序列号 | 1 |
数据长度 | 1 |
数据 | 内容总长度:2数据内容长度:${Data Length} - 2 |
校验(最高有效位) | 2 |
Blufi 协议设计的一些考虑:
数据帧的功能区分:通过帧类型区分,分为数据帧和控制帧,以及子类型下的具体功能。
帧控制的作用:是否加密、校验、分片,是否需要ACK以及表明传输方向,提高灵活性。
保障数据安全:采用 DH 算法进行密钥协商, 128-AES 算法用于数据加密。
保障数据完整性:CRC16 算法用于校验和验证。
防止重放攻击:通过校验帧序列号来保障
传输长数据:数据长度1字节,一帧数据长度有限,长数据可帧分片传输,代码中根据mtu大小设置数据分片大小。
相比于其他常见的通信协议,Blufi 中没有用于帧同步的帧头帧尾,在 ble 传输中可能不用考虑,但在其他通信场景需要考虑帧同步的情况。