蓝牙协议栈之L2CAP使用


前言

    本文记录对蓝牙协议栈逻辑链路及自适应协议层的学习还有后面如何在TI的蓝牙芯片上去实现L2CAP CoC的数据透传,为什么用L2CAP CoC进行数据透传呢?因为它每次透传的数据量远远能比GATT大,如果堆够用的话可以传输64KB,而GATT数据透传限于ATT-MTU,最多每次能传输的也就247个字节。

一、逻辑链路层及自适应协议层(L2CAP)

    该层属于主机的内容,位于HCI层的上一层,我们可以看下下面这个结构图1-1加强一下印象:
在这里插入图片描述

图1-1 BLE协议栈框架

    它的作用是为主机的GAP, GATT, SM, Application和链路层之间搭建起通信的桥梁,因此它有不可或缺的协议复用能力。同时,在主机和协议栈数据交换中它还有数据分段和重组的能力。所有从主机或者APP发出的数据都在这一层被封装成L2CAP packet。L2CAP允许更高层的协议(比如GATT、SM)和APP去发送和接收上层data packets(L2CAP服务数据单元,SDU),最多能传输64KB。L2CAP也允许每个通道的流控制和重发机制。

二、常用的L2CAP术语

L2CAP Channel: L2CAP通道,对端设备两节点之间的逻辑连接,用它们的信道标识符(CIDs)做通道的区分。
SDU: 服务数据单元,L2CAP与上层交换的数据包,它不包含L2CAP的帧头。
PDU: 协议数据单元,包括了L2CAP协议信息域、控制信息、上层信息数据,这个数据包就包含了L2CAP的帧头。一个SDU可能被分割成多个PDU进行传输。
MTU: 最大数据传输单元,上层应用可以接收的payload最大字节数,注意这个跟ATT的MTU是不一样的。
MPS: L2CAP可以接收的payload最大字节数。
Credit: 本蓝牙设备可以接收的LE帧数量。Credits取值范围是1~65535,在两个设备之间使用流控制。
L2CAP Basic Header: 为每个PDU预先准备的L2CAP协议信息。它包括了CID和长度。
PSM: 协议服务复用器,占用两个字节,用于定义L2CAP信道数据的解析。有动态的PSM和固定的PSMs。固定的PSMs是由SIG定义的,而动态的PSMs可以由GATT发现。
Fragmentation/Reconbination: 分包重组,分包(分段)是将单个L2CAP PDU分解成更小的数据段以供发送器发送的过程。重组是控制器将片段重新组装成完整的L2CAP PDU的过程。分包重组是由控制器实现的,并且基于LE数据长度扩展特征(可以看下Local supported feature)。
Segmentation/Reassembly: 分段是将单个L2CAP SDU分解成多个成为SDU段的L2CAP数据包的过程。在接收侧按照与此操作相反的方式进行重新组装。每个段都封装在一个适当的L2CAP报头中。分段和重组都是由L2CAP处理,并且对上下层都是透明的。
:SDU的最大字节数等于协议栈里边定义的L2CAP_SDU_SIZE。
代码如下(示例):

三、L2CAP的工作模式

    蓝牙5协议栈L2CAP支持两种不同的工作模式:Basic L2CAP Mode和LE Credit Based Flow Control Mode。

四、L2CAP通道

    L2CAP由3种通道类型:Connection-Oriented、Connectionless data、L2CAP signaling。L2CAP的每个端点由信道标识符CID引用。Connectionless data channels不适用于蓝牙5协议栈。另外,通道可以划分为固定通道动态通道
    固定通道执行特殊的L2CAP功能,使用的CIDs范围在0x0001和0x003F之间。每个固定通道的特征(比如MTU)都是独立的。
    下面罗列了协议栈和应用程序可以使用的CIDs

CIDDescriptionUsage
0x0004Attribute Protocol(ATT)Sending ATT information
0x0005LE Signaling ChannelSending L2CAP commands
0x0006Security Manager Protocol(SMP)Sending Pairing/Security Information
0x0040~0x007FDynamically AllocatedLE Credit Based Flow control packets

    比如,GATT层的数据交互使用的通道是0x0004,SMP(配对、安全)使用0x0006通道。应用程序不能直接访问ATT、SMP、信号通道,因为它们已经被相关的Host Layers使用了。上面提到的LE signaling channel使用在L2CAP连接参数更新流程、使用在动态通道上建立LE Credit基本连接,以及使用在交换Credits上。
    动态分配的通道ID用于识别逻辑链路和本地端点。本地端点的取值范围是0x0040到0xFFFF。这个本地端点用于面向连接的L2CAP通道(COC,全称Connection-orientated channel)。这些动态分配的通道是可以被应用程序访问和管理的,以便在L2CAP-COC上定义自己的协议。L2CAP通道是双向的,类似于套接字。动态分配一个通道,有以下3个参数:PSM、MTU、CID。前面提到,固定的PSMs是由BLE SIG定义的,它们的范围是0x00010x007F。动态的PSMs的范围是0x00800x00FF。PSMs可在GATT服务端设备上保持固定,而GATT客户端可以从GATT服务端中获取PSM。

五、L2CAP帧类型

    在蓝牙协议栈里面有两个L2CAP帧类型。
    (1)Basic Frame:基本帧,在基本模式下由固定通道使用
    (2)LE information Frame:低功耗信息帧,用于LE credit基本流控制模式下的动态通道。
:L2CAP处理来自主机或者APP的SDU数据帧。
下面是不同帧类型的帧头区别:

L2CAP Frame TypeHeader SizeHeader Contents
Basic frame4Length:2 octets CID: 2 octets
LE information frame6Length:2 octets CID: 2 octets SDU length: 2 octets

六、Fragmentation/Recombination

    从L2CAP的角度来看,所有数据包都作为完整的数据包发送到控制器和从控制器接收。这也意味着分段/重组(如果使能了LE DATA Length Extension)是由控制器执行的,并且对L2CAP不可见。当使用分段时,较大的数据包将被拆分成多个LL数据包然后在对端设备的LL层进行重组(LL层属于控制器的一部分)。

七、Segmentation/Reassembly

    当工作在基本模式下,L2CAP不执行分段或者重组。但是,动态通道工作在LE Credit基本流控模式下,是有可能发生数据包的分段和重组的。

八、L2CAP MTU

    L2CAP MTU是L2CAP层能够处理的最大数据字节大小。然而,L2CAP使用的MTU是不同的,取决于模式和通道类型。
(1)信号通道会使用L2CAP_SIG_MTU_SIZE
(2)固定通道数据包的MTU限定最大是MAX_PDU_SIZE - L2CAP_HDR_SIZE
(3)COC数据包的最大字节数取决于PSM的MTU,同时被L2CAP_SDU_SIZE限制
    当对于固定通道,MTU由更高级别的协议(如ATT)定义。在COC上,MTU受L2CAP_SDU_SIZE和对端设备支持的MTU的最小值约束。

九、Controller to Host Flow Control

    MAX_NUM_PDU定义了一次可以入列到控制器的TX数据包的最大个数。尝试发送更多数据包将导致调用的API接口返回失败,并且数据包也没有真正入列到控制器中。
    应用程序可能不清楚在给定时间内有多少个数据包在等着发送,因此我们在写代码调用API的时候最好就是检查API的返回值。还有,一般L2CAP有流控制通知功能,我们可以使用它来提高L2CAP数据通讯的效率。这里那ti的蓝牙芯片来举例,可以使用L2CAP_RegisterFlowCtrlTask()这个API使能流控,这样协议栈会有事件L2CAP_NUM_CTRL_DATA_PKT_EVT通知APP可发送的数据包数量,这个事件会在每次有新的缓冲区可用时触发。

十、总结

使用L2CAP总结如下:
    主机和从机都可以请求建立L2CAP COC通道。一旦L2CAP连接建立成功之后,协议栈会发送L2CAP_SIGNAL_EVENT到应用层,具体的事件是L2CAP_CHANNEL_ESTABLISHED_EVT,这个是双方都会触发的事件。主机和从机双方需要交换L2CAP Credits。连接建立之后,设备(双方)可以分发Credit。最后,我们就可以利用L2CAP CoC通道发送数据了,可以调用接口L2CAP_SendSDU()这个API发送数据,当成功将数据发送到空中之后,协议栈会给应用层发送L2CAP_SIGNAL_EVENT,具体事件是L2CAP_SEND_SDU_DONE_EVT。而接收数据呢?当蓝牙接收到数据之后,协议栈会给应用层发送L2CAP_DATA_EVENT事件,并携带接收到的数据。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值