3、链路层基础:状态机、角色定义(Master/Slave)、连接建立流程
好,咱们进入第三讲。这一章是BLE协议栈里最核心的底层逻辑——链路层。说白了,它就是蓝牙芯片里那个负责“收发数据、管理连接”的硬件状态机。你上层应用写得再花哨,底层链路层要是没搞对,连接就是连不上。
我个人习惯,讲链路层之前,先让大家把脑子里那些“主从”、“连接”的模糊概念清空。咱们从最原始的状态开始聊。
3.1 链路层的五种状态
BLE链路层定义了五种基本状态。一个蓝牙芯片,在任何时刻,都只能处于其中一种状态。嗯,这里要注意,这五种状态不是软件模拟的,是硬件状态机直接实现的。
| 状态 | 英文 | 说明 |
|---|---|---|
| 待机 | Standby | 初始状态,不发射也不接收 |
| 广播 | Advertising | 向外发送广播包,可以被扫描或连接 |
| 扫描 | Scanning | 监听广播包,获取周围设备信息 |
| 发起连接 | Initiating | 主动向指定广播者发送连接请求 |
| 已连接 | Connected | 建立连接后,双方按固定间隔收发数据 |
你想想看,这五种状态其实就覆盖了蓝牙设备从“出生”到“建立连接”的全过程。我在项目中遇到过不少新手,上来就调连接参数,结果发现设备根本进不了连接态——一查,广播状态就没配对。
核心要点:链路层状态机是严格的状态转换模型。你不能从“广播”直接跳到“扫描”,必须经过“待机”状态。这是硬件规定的,不是软件能绕过去的。
3.2 角色定义:Master 与 Slave
连接建立之后,角色就定下来了。发起连接的那一方叫 Master(主设备),接受连接的那一方叫 Slave(从设备)。
这里有个容易混淆的点:广播者不一定是 Slave,扫描者也不一定是 Master。只有在“发起连接”这个动作发生之后,角色才被锁定。
举个例子:
- 手机在扫描,手环在广播。手机发起连接 → 手机是 Master,手环是 Slave。
- 反过来,如果手环发起连接(虽然很少见),那手环就是 Master。
我曾经在一个项目中,把两个设备都配成了“只能做 Slave”的模式。结果两边都在等对方来连,谁也连不上谁。嗯,这种低级错误,犯过一次就记住了。
我的建议:在设计多连接系统时,提前规划好哪个设备是 Master,哪个是 Slave。Master 负责调度时序,Slave 负责响应。Master 的功耗通常比 Slave 高,因为要管理连接间隔和重传。
3.3 连接建立流程
好,咱们一步步拆解连接建立的过程。这步搞懂了,后面调连接参数、处理断连,你心里就有底了。
3.3.1 第一步:广播者发送广播包
广播者(将来可能是 Slave)在三个广播信道上(37、38、39)轮流发送广播包。广播包里包含设备地址、设备名称、以及一些厂商自定义数据。
3.3.2 第二步:发起者发送连接请求
发起者(将来是 Master)在扫描到广播包后,如果满足连接条件,就在同一个广播信道上发送 CONNECT_IND 包。这个包里包含了关键的连接参数:
- 连接间隔(Connection Interval)
- 从设备延迟(Slave Latency)
- 监督超时(Supervision Timeout)
- 跳频算法参数(Channel Map)
3.3.3 第三步:连接建立,进入连接态
广播者收到 CONNECT_IND 后,解析参数,双方同时切换到连接态。从这一刻起,双方不再在广播信道上通信,而是按照约定的连接间隔,在数据信道上跳频通信。
注意:连接建立后,广播者就不再是“广播者”了,它变成了 Slave。发起者变成了 Master。这个角色转换是硬件自动完成的,但软件层需要做好状态管理。
3.4 连接参数详解
连接参数是链路层最关键的配置项。我建议你把它背下来,或者至少知道每个参数的含义。
| 参数 | 范围 | 说明 |
|---|---|---|
| 连接间隔 | 7.5ms ~ 4s | 两个连接事件之间的时间间隔。越小延迟越低,但功耗越高。 |
| 从设备延迟 | 0 ~ 499 | Slave 可以跳过多少个连接事件不响应。用于省电。 |
| 监督超时 | 100ms ~ 32s | 如果超过这个时间没收到任何包,就认为连接丢失。 |
我在项目中遇到过一个问题:连接间隔设得太小(比如 7.5ms),结果两个设备距离稍远一点,就开始频繁丢包重传。后来我把间隔调到 30ms,配合适当的从设备延迟,连接稳定多了。
避坑指南:我曾经把监督超时设得太大(32秒),结果设备断连后,上层应用过了半分钟才知道。用户体验极差。建议根据应用场景,把监督超时控制在 2~6 秒之间。
3.5 链路层数据流
连接建立后,数据是怎么流动的?
- Master 在每个连接事件开始时,先发送一个数据包。
- Slave 收到后,在同一个连接事件内回复一个数据包。
- 如果 Master 没收到回复,会在下一个连接事件重传。
- 如果连续多次重传失败,链路层会触发监督超时,断开连接。
说白了,这就是一个“你问我答”的机制。Master 永远是主动方,Slave 只能被动响应。这种设计简化了链路层的调度,但也意味着 Slave 不能主动发数据——除非 Master 先给它一个机会。
嗯,这里要注意,BLE 5.0 引入了“数据长度扩展”(LE Data Length Extension),允许单次传输更多数据。但底层的主从通信模型没有变。
3.6 小结
这一章我们讲了链路层的状态机、主从角色定义、以及连接建立的完整流程。你记住几个关键点:
- 五种状态,严格转换,不能跳转。
- 角色在连接建立时确定,Master 主动,Slave 被动。
- 连接参数直接影响功耗和稳定性,需要根据场景调优。
下一章,我们会深入广播通道和数据通道的细节,包括跳频算法和空中包格式。到时候你会看到,链路层其实比你想的要聪明得多。