一 介绍
L2CAP(逻辑链路控制和适配协议层)是一个复用层,可以让低功耗蓝牙复用三条不同的信道。它也支持数据的分割和重组功能,使得较大的报文可以在底层无线电中传输。在经典蓝牙无线电中,L2CAP层提供的功能比这更多,也更为复杂。
二 L2CAP的数据格式
- Length: Information payload的长度
- Channel ID(CID): 信道
- Information payload: 有效的数据
HCI层的ACL Data packet就是由L2CAP层构建的,或者说是L2CAP层的上一层委托L2CAP构建的。
2.1 CID
信道标识符 | 用法 |
---|---|
0x0000 | 保留:不能使用 |
0x0001 | 经典蓝牙信令信道 |
0x0002 | 无连接信道 |
0x0003 | AMP管理协议 |
0x0004 | ATT协议 |
0x0005 | BLE信令信道 |
0x0006 | 安全管理协议 |
0x0007 ~ 0x003E | 保留 |
0x003F | AMP测试协议 |
0x0040 ~ 0xFFFF | 面向连接信道 |
低功耗蓝牙一共使用了三条信道,0x0004、0x0005、0x0006
2.2 Information payload
L2CAP层的有效数据字段,Information payload的最大传输单元(MTU, Maximum Transmission Unit)为23个字节,这就意味着所有BLE的设备必须支持在空中传播27字节的数据包,4字节报头加上23字节的有效数据。
当CID为0x0004的时候,payload的数据内容由ATT层决定,在 ATT 一文中再做介绍。
2.3 信令信道
CID = 0x0005表示信令通道,一般传输的是控制数据,比如改变对方的连接参数等。详细信息参看 《core_v5.1》 Vol 3 -> Part A -> 4 Signaling packet formats 数据格式如下图
当CID = 0x05时,传输的数据有三种类型:
- 命令: Command
- 命令拒绝: Command Reject
- 响应:Response
code用来表示是哪一个信令。比如请求更新连接参数的code为0x12,响应更新参数请求的code为0x13,这里的id由L2CAP自己指定。
设备A给设备B发送Command,设备B可以回复Command Reject表示拒绝,或是回复Response。比如A给B发送了两个Command,Cmd1和Cmd2,Cmd1的id为123,Cmd2的id为124,B回复的Response分别为Res1(id为123)和Res2(id为124),A设备就是通过这个id来判断当前的res是和哪一条cmd对应的。
三 分包和重组
L2CAP的另外一个重要作用就是对数据包的拆分和重组,上层通过L2CAP传输数据给对方,L2CAP不应该限制其大小,但是蓝牙的Controller一般资源比较有限,太多数据传到Controller层可能它的内存就不够用了。
拆分的原理如上图所示,当数据比较短不需要分包的时候,L2CAP层的数据直接对应到HCI层的data段,LL层会根据HCI的handle来构建自己的Access Address,Access Address就代表了对端设备,LL根据HCI的PB来来设置LLID(10b 表示起始包),LL层根据HCI的length来构建header中的len,LL层将HCI的数据到封装到payload中,然后通过无线传输。
蓝色部分表示是需要拆分的后续包,后续包和第一包数据的差别在于HCI层的PB值为01b,LL层的LLID为01b,表示是后续包。
对端收到数据之后需要对数据包进行重组,L2CAP的length代表了payload、length(2个字节)和channel ID(2个字节)的总长度,第一包数据会将总长度、channel id以及部分数据传输给对端。对端收到数据之后,如果HCI中的 length等于 L2CAP 的length 值就表示已经收完了。如果HCI中的length小于 L2CAP的 length,表明还需要接收下一个延续包