<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>BLE on Hacper&#39;s Blog</title>
    <link>https://hacperme.com/tags/ble/</link>
    <description>Recent content in BLE on Hacper&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh</language>
    <lastBuildDate>Wed, 25 Oct 2023 23:02:30 +0800</lastBuildDate>
    <atom:link href="https://hacperme.com/tags/ble/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ESP32 BLUFI 协议和代码实现梳理</title>
      <link>https://hacperme.com/posts/notes/20231025_esp32_blufi/</link>
      <pubDate>Wed, 25 Oct 2023 23:02:30 +0800</pubDate>
      <guid>https://hacperme.com/posts/notes/20231025_esp32_blufi/</guid>
      <description>Blufi 是乐鑫设计的一个用在 ESP32 上的蓝牙配网协议，网上开源 Blufi 协议细节和实现代码。最近一个项目需要用到 Blufi，将其移植到了 bk 的 bk7231n mcu WiFi 上。 下面是 esp-idf 上</description>
      <content:encoded><![CDATA[<p>Blufi 是乐鑫设计的一个用在 ESP32 上的蓝牙配网协议，网上开源 Blufi 协议细节和实现代码。最近一个项目需要用到 Blufi，将其移植到了 bk 的 bk7231n mcu WiFi 上。</p>
<p>下面是 esp-idf 上 Blufi 实现的代码整理。</p>
<p><img loading="lazy" src="https://github.com/hacperme/picx_hosting/raw/master/20210507/ESP_BLUFI-%e4%bb%a3%e7%a0%81%e6%a2%b3%e7%90%86.27k4yfeh2kro.webp" alt=""  />
</p>
<p>移植过程主要需要关注 ble 驱动和应用 api 两部分，应用接口相关代码对平台没有太多依赖，主要解决从 esp-idf 迁移到新平台上的编译问题；ble 驱动层相关的代码则需要替换为新平台的实现，这里改动较为费劲。</p>
<p>Blufi 的代码流程可以看 esp-idf 代码中 blufi_profile_cb、esp_blufi_gap_event_handler、btc_blufi_cb_handler、btc_blufi_call_handler 这几个回调函数中各个事件的处理过程。驱动层主要关注的事情：</p>
<ol>
<li>ble GATT UUID 配置</li>
<li>ble 广播开启和关闭</li>
<li>ble 连接断开，数据读写的事件的处理</li>
<li>wifi sta softap 的配置，状态获取，连接断开事件处理</li>
</ol>
<h2 id="blufi-协议设计的一些考量">Blufi 协议设计的一些考量</h2>
<p>Blufi 协议帧格式如下。</p>
<p>帧不分片格式：</p>
<table>
<thead>
<tr>
<th>字段</th>
<th>值（字节）</th>
</tr>
</thead>
<tbody>
<tr>
<td>类型（最低有效位）</td>
<td>1</td>
</tr>
<tr>
<td>帧控制</td>
<td>1</td>
</tr>
<tr>
<td>序列号</td>
<td>1</td>
</tr>
<tr>
<td>数据长度</td>
<td>1</td>
</tr>
<tr>
<td>数据</td>
<td>${Data Length}</td>
</tr>
<tr>
<td>校验（最高有效位）</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>帧分片格式：</p>
<table>
<thead>
<tr>
<th>字段</th>
<th>值（字节）</th>
</tr>
</thead>
<tbody>
<tr>
<td>类型（最低有效位）</td>
<td>1</td>
</tr>
<tr>
<td>帧控制（分片）</td>
<td>1</td>
</tr>
<tr>
<td>序列号</td>
<td>1</td>
</tr>
<tr>
<td>数据长度</td>
<td>1</td>
</tr>
<tr>
<td>数据</td>
<td>内容总长度：2数据内容长度：${Data Length} - 2</td>
</tr>
<tr>
<td>校验（最高有效位）</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>Blufi 协议设计的一些考虑：</p>
<ul>
<li>
<p>数据帧的功能区分：通过帧类型区分，分为数据帧和控制帧，以及子类型下的具体功能。</p>
</li>
<li>
<p>帧控制的作用：是否加密、校验、分片，是否需要ACK以及表明传输方向，提高灵活性。</p>
</li>
<li>
<p>保障数据安全：采用 DH 算法进行密钥协商, 128-AES 算法用于数据加密。</p>
</li>
<li>
<p>保障数据完整性：CRC16 算法用于校验和验证。</p>
</li>
<li>
<p>防止重放攻击：通过校验帧序列号来保障</p>
</li>
<li>
<p>传输长数据：数据长度1字节，一帧数据长度有限，长数据可帧分片传输，代码中根据mtu大小设置数据分片大小。</p>
</li>
</ul>
<p>相比于其他常见的通信协议，Blufi 中没有用于帧同步的帧头帧尾，在 ble 传输中可能不用考虑，但在其他通信场景需要考虑帧同步的情况。</p>
<h2 id="资料">资料</h2>
<ul>
<li><a href="https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/blufi">Blufi source code</a></li>
<li><a href="https://github.com/EspressifApp/EspBlufiForAndroid">EspBlufiForAndroid</a></li>
<li><a href="https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/blufi.html">BluFi protocol</a></li>
</ul>
]]></content:encoded>
    </item>
  </channel>
</rss>
