2、GAP层避坑:广播参数配置、连接间隔协商、设备发现与配对绑定
GAP 层,说白了就是 BLE 设备的“社交礼仪”。
它决定了你的设备怎么让别人发现、怎么建立连接、怎么交换密钥。很多刚入门的工程师觉得 GAP 很简单,不就是配几个参数嘛。嗯,我当年也这么想,直到产品在产线上批量出问题……
这一章,我把 GAP 层最常踩的坑,一个一个掰开讲。
2.1 广播参数配置:别让设备“隐身”或“吵死人”
广播是 BLE 设备的第一印象。配置不好,要么别人搜不到你,要么你一直在空中“大喊大叫”,把整个频段都占满了。
2.1.1 广播间隔与占空比
广播间隔(Advertising Interval)决定了设备多久发一次广播包。单位是 0.625ms,取值范围 20ms ~ 10.24s。
| 场景 | 推荐间隔 | 注意 |
|---|---|---|
| 快速发现(如配网) | 20ms ~ 100ms | 功耗高,适合短暂使用 |
| 常规广播(如信标) | 100ms ~ 1s | 平衡功耗与发现速度 |
| 低功耗后台广播 | 1s ~ 10s | 发现慢,但省电 |
2.1.2 广播类型选择
BLE 有四种广播类型,选错了直接导致连接失败。
- 可连接非定向广播(Connectable Undirected):最常用,任何扫描者都能连接。
- 可连接定向广播(Connectable Directed):只允许指定设备连接,速度快,但容易丢。
- 不可连接非定向广播(Non-connectable Undirected):只广播,不接收连接请求,适合信标。
- 可扫描非定向广播(Scannable Undirected):允许扫描者读取扫描响应数据,但不建立连接。
我习惯在配网阶段用可连接非定向广播,连接成功后立即停止广播。这样既保证发现效率,又避免不必要的功耗。
2.1.3 广播数据与扫描响应
广播包最多 31 字节,扫描响应也是 31 字节。很多人把数据全塞进广播包,结果放不下。
2.2 连接间隔协商:别让双方“吵架”
连接间隔(Connection Interval)是主从设备之间交换数据的周期。单位是 1.25ms,范围 7.5ms ~ 4s。
连接间隔的协商,其实是主设备和从设备之间的“讨价还价”。从设备可以提要求,但最终决定权在主设备手里。
2.2.1 连接参数请求流程
- 从设备发送
LL_CONNECTION_PARAM_REQ或L2CAP Connection Parameter Update Request。 - 主设备检查参数是否在可接受范围内。
- 主设备回复接受或拒绝。
为什么主设备会拒绝?因为连接间隔太短,主设备要频繁处理中断,CPU 负载会飙升。
核心原则: 从设备提的连接间隔,必须满足主设备的 latency 和 supervision timeout 约束。否则,主设备会直接忽略你的请求。
2.2.2 连接间隔与吞吐量的关系
连接间隔越短,吞吐量越高,但功耗也越大。我整理了一个经验表:
| 连接间隔 | 理论吞吐量(1M PHY) | 典型功耗(从设备) |
|---|---|---|
| 7.5ms | ~236 kbps | 高(~15mA) |
| 30ms | ~59 kbps | 中(~5mA) |
| 100ms | ~18 kbps | 低(~1mA) |
2.2.3 连接参数更新失败的处理
我遇到过最头疼的问题:从设备请求更新连接参数,主设备一直不响应。结果从设备卡在等待状态,无法进行后续操作。
解决方案:
- 设置超时机制,比如 5 秒内没收到响应,就断开重连。
- 在广播阶段就把连接参数写进广播数据,让主设备一开始就用合适的参数。
- 使用
GAP_SetParam或类似 API 提前配置好默认参数。
2.3 设备发现与扫描:别让设备“视而不见”
设备发现是 GAP 层的核心功能之一。扫描参数配置不当,会导致设备明明在广播,却怎么也搜不到。
2.3.1 扫描窗口与扫描间隔
扫描窗口(Scan Window)和扫描间隔(Scan Interval)决定了扫描器的“监听”频率。
- 扫描窗口:每次监听持续的时间。
- 扫描间隔:两次监听开始之间的时间。
如果扫描窗口等于扫描间隔,就是连续扫描,功耗高但发现快。如果扫描窗口远小于扫描间隔,就是间歇扫描,省电但可能漏包。
2.3.2 主动扫描 vs 被动扫描
| 扫描类型 | 行为 | 适用场景 |
|---|---|---|
| 被动扫描 | 只监听广播包,不发送扫描请求 | 省电,适合信标接收 |
| 主动扫描 | 监听广播包后,发送扫描请求获取扫描响应 | 需要更多设备信息时 |
主动扫描会多一次空中交互,功耗更高,但能获取到扫描响应里的额外数据。我建议在需要过滤设备时用主动扫描,否则用被动扫描就够了。
2.3.3 过滤策略
很多芯片支持白名单过滤。白名单里只有指定设备的 MAC 地址,扫描器只处理这些设备的广播包。
这样做的好处:
- 减少 CPU 中断次数。
- 降低功耗。
- 避免被无关设备干扰。
2.4 配对与绑定:别让密钥“丢了”
配对是建立安全连接的过程,绑定是存储密钥以便下次快速重连。很多人把这两个概念混为一谈,结果密钥管理一塌糊涂。
2.4.1 配对流程
BLE 配对分为三个阶段:
- 配对特征交换:双方交换 IO 能力、认证要求、密钥大小等信息。
- 短期密钥(STK)生成:根据配对方式生成临时密钥。
- 传输特定密钥:交换长期密钥(LTK)、身份解析密钥(IRK)等。
配对方式有四种:Just Works、Passkey Entry、Numeric Comparison、Out of Band。选哪种取决于你的设备有没有显示屏、键盘等 IO 能力。
| 配对方式 | IO 能力要求 | 安全性 |
|---|---|---|
| Just Works | 无 | 低(易受中间人攻击) |
| Passkey Entry | 一方有输入,一方有显示 | 中 |
| Numeric Comparison | 双方都有显示和确认 | 高 |
| Out of Band | NFC 等带外通道 | 高 |
2.4.2 绑定与密钥存储
绑定成功后,设备会存储 LTK、IRK、CSRK 等密钥。下次重连时,双方可以直接用存储的密钥加密通信,跳过配对过程。
这里有个坑:密钥存储的位置。有些芯片把密钥放在 RAM 里,掉电就丢了。有些放在 Flash 里,但擦写次数有限。
2.4.3 绑定信息丢失的处理
如果从设备绑定了主设备,但主设备换了(比如用户换了手机),从设备还拿着旧的密钥,就会导致连接失败。
解决方案:
- 在从设备上实现“清除绑定信息”的功能,比如长按按键 5 秒。
- 在配对时加入“白名单”机制,只允许已知设备连接。
- 如果连接失败,自动回退到未绑定状态,重新开始配对。
2.5 GAP 层核心流程总览
下面这张图,把 GAP 层的主要流程串起来了。从广播开始,到扫描、连接、配对、绑定,每一步都有对应的参数和注意事项。
GAP 层看似简单,但每个环节都有隐藏的坑。广播参数配不好,设备就“隐身”;连接间隔没协商好,双方就“吵架”;配对绑定没处理好,密钥就“丢了”。
我个人习惯在项目初期就把 GAP 层的参数配置写成一个配置文件,每个参数都加上注释说明为什么选这个值。这样后期调试时,一眼就能看出问题出在哪。
嗯,这一章的内容就到这里。记住,GAP 层是 BLE 设备的“脸面”,把脸面收拾好了,后面的工作才能顺利。