4. BLE连接建立:连接参数、连接请求过程、白名单与过滤策略
好,咱们接着聊。上一章我们把广播和扫描讲透了,现在设备已经互相发现了,接下来就是「牵手」的过程——建立连接。
连接建立,说白了就是两个设备商量好「咱们以后怎么通信」。这个商量过程,涉及三个核心要素:连接参数、连接请求流程、以及白名单过滤。我当年刚接触BLE时,觉得连接就是发个请求、回个应答,简单得很。结果在实际项目中,连接参数没配好,设备要么功耗爆炸,要么频繁断连,搞得我焦头烂额。嗯,今天咱们就把这些坑一个个填上。
核心观点:连接建立不是一次性的握手,而是一个参数协商的过程。主设备说了算,但从设备可以提要求。
4.1 连接参数详解
连接参数有三个关键指标:连接间隔、从设备延迟、监督超时。这三个参数共同决定了连接的功耗、实时性和稳定性。
4.1.1 连接间隔(Connection Interval)
连接间隔,就是主设备和从设备之间两次通信的时间间隔。单位是1.25ms,取值范围从6(7.5ms)到3200(4.0s)。
你想想看,间隔越短,数据传得越频繁,实时性越好,但功耗也越高。反之,间隔越长,省电,但数据延迟大。
我个人习惯,对于需要实时响应的应用(比如鼠标、键盘),连接间隔设在7.5ms到20ms之间。对于传感器数据采集(比如温度计、心率带),30ms到100ms比较合适。如果是那种一天传一次数据的设备,间隔拉到1秒以上也没问题。
| 应用场景 | 推荐连接间隔 | 说明 |
|---|---|---|
| 鼠标/键盘 | 7.5ms - 15ms | 低延迟,高功耗 |
| 运动手环 | 30ms - 50ms | 平衡功耗与实时性 |
| 温度传感器 | 100ms - 1s | 低功耗为主 |
| ibeacon信标 | 1s - 4s | 极低功耗,不频繁通信 |
注意:连接间隔不是越小越好。我在一个项目中把连接间隔设成了7.5ms,结果手机端蓝牙芯片发热严重,电池半天就耗光了。后来改到30ms,问题解决。一定要根据实际硬件能力来选。
4.1.2 从设备延迟(Slave Latency)
这个参数很有意思。它允许从设备在连接事件中「偷懒」——跳过一些连接事件,继续睡觉。
举个例子:连接间隔是50ms,从设备延迟设为9。那么从设备最多可以连续跳过9个连接事件,也就是450ms才响应一次。这期间主设备还是会按时发数据包,但从设备可以不回。
为什么要这样?说白了就是为了省电。从设备大部分时间都在睡觉,只在需要时才醒来。但要注意,延迟值不能太大,否则主设备会以为从设备掉线了。
我曾经在一个穿戴设备项目中,把从设备延迟设成了499(最大值),结果设备经常被主设备踢出连接。后来查规范才发现,延迟值受监督超时限制,不能乱设。
4.1.3 监督超时(Supervision Timeout)
监督超时是连接的安全网。如果主设备在超时时间内没有收到从设备的任何数据包,就会认为连接已断开,主动终止连接。
单位是10ms,范围从10(100ms)到3200(32s)。
这里有个关键公式:有效连接间隔 × (从设备延迟 + 1) < 监督超时。如果不满足这个条件,连接可能不稳定。
经验之谈:监督超时一般设为连接间隔的10倍以上。比如连接间隔30ms,监督超时至少设300ms。太短容易误断,太长则断连后反应迟钝。
4.2 连接请求过程
连接建立的过程,其实就是一个连接请求(CONNECT_REQ)数据包的发送与接收。这个包由主设备(发起者)发出,从设备(广播者)接收并解析。
整个流程分三步:
- 扫描阶段:主设备扫描到从设备的广播包
- 连接请求:主设备发送CONNECT_REQ,包含所有连接参数
- 连接确认:从设备收到后,在第一个连接事件中回复数据包,连接建立
CONNECT_REQ数据包的结构,我给大家拆解一下:
CONNECT_REQ PDU格式:
- InitA: 发起者地址(6字节)
- AdvA: 广播者地址(6字节)
- LLData: 连接参数(22字节)
- Access Address: 访问地址(4字节)
- CRC Init: CRC初始值(3字节)
- WinSize: 传输窗口大小(1字节)
- WinOffset: 传输窗口偏移(2字节)
- Interval: 连接间隔(2字节)
- Latency: 从设备延迟(2字节)
- Timeout: 监督超时(2字节)
- ChM: 信道映射(5字节)
- Hop: 跳频增量(5位)
- SCA: 睡眠时钟精度(3位)
你可能会问:「为什么要有传输窗口?」嗯,这是因为两个设备的时钟不同步,需要一个窗口来对齐。窗口大小和偏移由主设备计算,从设备照着来就行。
小技巧:在实际调试中,如果连接总是失败,可以抓空中的CONNECT_REQ包看看。我遇到过好几次,都是因为从设备地址填错了,导致连接请求被忽略。
4.3 白名单与过滤策略
白名单,说白了就是一个「允许列表」。只有列表中的设备才能连接或扫描到。这在安全性和功耗优化上非常有用。
4.3.1 白名单的作用
白名单可以用于两个场景:
- 扫描白名单:只接收白名单中设备的广播包
- 连接白名单:只允许白名单中的设备发起连接
我做过一个智能门锁项目,门锁作为从设备,只允许主人的手机连接。我们把主人的手机MAC地址加入白名单,其他设备扫描到门锁也连不上。这样既省电又安全。
4.3.2 白名单的实现方式
白名单基于设备地址进行过滤。BLE支持两种地址类型:
- 公共地址(Public Address):固定不变,由IEEE分配
- 随机地址(Random Address):可动态生成,又分静态随机和私有随机
在实际产品中,我建议使用可解析私有地址(Resolvable Private Address)。这种地址会定期变化,但可以通过IRK(身份解析密钥)来解析。既保护了隐私,又能实现白名单功能。
4.3.3 过滤策略的配置
在蓝牙协议栈中,过滤策略通过过滤策略(Filter Policy)字段来配置。这个字段存在于扫描参数和连接参数中。
| 过滤策略值 | 含义 | 适用场景 |
|---|---|---|
| 0x00 | 不启用白名单,接受所有设备 | 开发调试阶段 |
| 0x01 | 只接受白名单中的设备 | 产品化部署 |
| 0x02 | 不接受白名单,但接受特定设备 | 特殊场景 |
| 0x03 | 白名单+特定设备组合 | 复杂场景 |
避坑指南:我曾经在一个项目中,把过滤策略设成了0x01,但忘记把设备地址加入白名单。结果设备死活连不上,排查了整整一天。后来发现是白名单没配置。记住:启用白名单前,一定要先添加设备。
4.4 知识体系总览
为了让大家更直观地理解本章内容,我画了一张流程图,展示连接建立的完整逻辑:
4.5 实战建议
最后,我给大家几个实战中的建议:
- 参数调试:先用默认参数(连接间隔50ms,延迟0,超时4s)跑通连接,再根据功耗需求逐步调整
- 白名单测试:开发阶段关掉白名单,产品阶段再启用。否则调试时自己都连不上
- 抓包工具:强烈建议用BLE抓包工具(如Ellisys、nRF Sniffer)查看CONNECT_REQ包内容,参数一目了然
- 兼容性:不同手机厂商对连接参数的支持不同。我遇到过某品牌手机对7.5ms连接间隔支持不好,换成10ms就正常了
最后说一句:连接建立是BLE通信的基石。参数配好了,后面的数据传输就顺风顺水。配不好,后面全是坑。多花点时间在这上面,绝对值得。
公众号:蓝海资料掘金营,微信deep3321