精华内容
下载资源
问答
  • 蓝牙协议规范--L2CAP
    2021-06-09 14:04:10

    L2CAP 分析

    记住一点,软件和硬件分开理解,数据经由物理通道交互,上层通道由各层协议打通。

    L2CAP 全称为逻辑链路控制与适配协议(Logical Link Control and Adaptation Protocol),位于基带层之上,将基带层的数据分组交换为便于高层应用的数据分组格式,并提供协议复用和服务质量交换等功能。

    L2CAP 是基于下列假设为依据而设计的:

    ● 使用链路管理器协议在两单元间建立 ACL 链路。基带提供数据分组的有序传输, 但也可能有个别分组损坏或重复。任两台设备之间只会有一条 ACL 链路。

    信道建立在链路的基础上,信道可以有多个,链路只有一条。

    ● 基带通常提供全双工信道。但这并不是说所有 L2CAP 通信都是双向的。多点传送和单向通信(例如,视频)并不要求双工信道。

    ● 通过使用基带层提供的机制,L2CAP 提供了一条可靠的信道。当收到请求和重发数据时,基带通常要执行数据完整性校验,直到数据成功确认或发生超时。由于可能会丢失确认报文,所以甚至在数据成功发送后也会发生超时。基带协议使用长度为 1 位的序列号,该序列号用于删除重复发送的分组。由于所有广播的 L2CAP 数据分组的首段都以同一序列位为起始位, 如果需要提供可靠传输,就应禁止使用基带广播分组。

    L2CAP 主要对数据进行封装,支持协议复用,统一高层协议数据格式。

    L2CAP 特点

    ● 协议复用:能够区分高层协议,在信道建立时,协议复用功能用来发送请求来连接正确的上层协议;在数据传输时,逻辑信道复用必须能够把用同一个协议的不用几个高层实体的区分出来(一对多情况)。

    ● 分段与重组:高层协议需传输的数据长度不定,L2CAP 层控制了 PDU 的长度,不仅易于管理而且通过对数据标记分组,允许数据单元的交错,可以满足延时要求,发生错误时的重传也可以更加方便准确。

    ● 差错控制和重传:

    L2CAP 以信道概念为基础,每个信道的端点有信道标识符(channel identifier, CID)来表示。从 0x0001 到 0x003F 的标识符保留用于特定的 L2CAP 功能。空标识符(0x0000)则定义为一个非法标识符, 并且不得用于目标端。可以根据实际应用目的和情况, 以合适方式自由管理其余的 CID。但在本地设备与多个远端设备存在多个并发 L2CAP 信道的情况下,同一 CID 不得重新用作本地 L2CAP 信道端。 下表对 CID 命名空间的定义和划分进行的总结。

    CID说明
    0x0000无效标识
    0x0001正在发信号的信道
    0x0002无连接的接受信道
    0x0003-0x003f保留(特定功能)
    0x0040-0xffff动态分配

    L2CAP 信道有三种类型:面向连接(Connection-Oriented,CO)信道,用于两个连接设备之间的双方通信;无连接(Connection-Less,CL)信道,用来向一组设备进行广播式的数据传输,为单项信道;信令(Signaling)信道,用于创建CO 信道,并可以通过协商过程改变 CO 信道的特性.

    BT/BLE 在 L2CAP 层的区别?? Note

    下图说明了 CID 在 L2CAP 实体间通信的使用方式,以及 L2CAP 信道的三种类型工作方式。信令信道是一个保留信道的实例,该信道用于创建和建立面向连接的数据信道,并可对这些信道的特性变化进行协商。

    CID

    L2CAP 操作模式

    根据每个 L2CAP 信道的上层协议,L2CAP 有三种不同的操作模式

    (1)基本 L2CAP 模式(这点和版本 1.1 的蓝牙协议里是一样的)

    (2)流控制模式

    (3)重传模式

    在流控制模式和重传模式中,双方传输的数据分组都是被编了号的。数据分组中的序列号码是用来控制缓冲, TxWindow 大小是用来限制需要的缓冲区空间和/或提供一种流控制的方法。另外对于窗口大小(window size)来说,流控制规范的 Token Bucket size 参数可以用来描述缓冲区的大小; 一些特殊的信道不使用流量和差错控制。

    在流控制模式下,丢失的数据分组可以被检测出来,并能通知对方丢失,但不进行重传。

    在重传模式下,使用一个定时器,把需要重新传输的数据分组传送,来确保所有的数据分组都传输给对方。

    数据分组格式

    1、面向连接信道

    connect
    各字段描述如下:

    长度: 2个字节,主要指基本 L2CAP 报文头除长度以外的信息净荷的大小,即图中空白部分,其长度可达65535字节。

    净荷信息: 静荷信息包含来自上层协议(发出的分组)的净荷或者发送到上层协议(接收的分组)的净荷。 MTU 的值在信道配置时确定。所支持的用于信令分组的 MTU 的最小值为 48 字节。

    信道ID: 2个字节,用于标识分组的目标信道终端。

    2、无连接数据信道

    disconnect
    各字段描述如下:

    长度: 2个字节,是信息净荷/有效载荷与 PSM 字段长度的和。

    净荷信息/有效载荷: 静荷信息包含来自上层协议(发出的分组)的净荷或者发送到上层协议(接收的分组)的净荷。 MTU 的值在信道配置时确定。所支持的用于信令分组的 MTU 的最小值为 48 字节。

    信道ID: 2个字节,CL 信道 ID 固定为0x0002

    协议/服务复用(PSM): 一般为 SDP、RFCOMM、TCS 等中介协议复用。小
    于 0x1000 的值,0x0001 对应 SDP,0x0003 对应 RFCOMM、0x0005 对应 TCS。主要用于标识何种上层协议。

    3、信令信道

    在这里插入图片描述
    上图所示为信令信道的分组格式,其一般用在连接、断开、请求、拒绝等命令,所有信令通道 CID 均为 0x0001。

    信令指令分组长度: 2个字节,除L2CAP分组头部分之外的数据长度,即各指令长度之和 (note:各指令长度不定,具体使用,具体分析)

    信令指令格式长度: 2个字节,为数据长度(大小不定,最大为65535字节)

    标识符: 1个字节,用于请求与应答间的匹配。

    信令命令代码: 如下图所示为各代码代表含义

    在这里插入图片描述
    举例说明: 下面是一个 L2CAP 包

    Role:Master
    Address:11
    PDULength: 6 //指令的长度,值为 06 00
    ChannelID: 0x0001 (Signaling)//L2CAP 的信令通道,值为 01 00
    Code:Information request//信息请求,值为 0a
    Identifier:1//标识符,值为 01
    CommandLength: 2//命令长度,值为 02 00
    InfoType:Extended features supported//02 00 (实际传送数据)
    

    这条指令完整的为:06 00 01 00 0a 01 02 00 02 00

    注: 蓝牙分组编码为小端模式。

    L2CAP 层接收到数据后的处理流程:

    在这里插入图片描述
    具体分析需要结合源码一起。

    详细见蓝牙核心技术概述.pdf 第42页 以及 蓝牙协议及其源码分析 第274页

    更多相关内容
  • L2CAP连接流程(以主动连接RFCOMM为例) 整个过程连接流程如下: 其中红色就是SIGNALING command,也就是C-frame,绿框是SDU(解释见截图),也就是B-frame 整理流程如下: 步骤整理如下: 步骤1)我们发送L2CAP ...

    一. 声明

    本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:

    第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

    第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

    第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

    第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

    第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

    第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

    第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

    第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

    另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

    ------------------------------------------------------------------------------------------------------------------------------------------

    CSDN学院链接(进入选择你想要学习的课程):https://edu.csdn.net/lecturer/5352?spm=1002.2001.3001.4144

    蓝牙交流扣扣群:970324688

    Github代码:https://github.com/sj15712795029/bluetooth_stack

    入手开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.18.5aeb41f973iStr&id=622836061708

    蓝牙学习目录https://blog.csdn.net/XiaoXiaoPengBo/article/details/107727900

    ------------------------------------------------------------------------------------------------------------------------------------------

    二. L2CAP的连接流程(以主动连接RFCOMM为例)

    整个过程连接流程如下:

    其中红色就是SIGNALING command,也就是C-frame,绿框是SDU(解释见截图),也就是B-frame

    整理流程如下:

    步骤整理如下:

    步骤1)我们发送L2CAP Connection Request with RFCOMM PSM,对方回复L2CAP Connection Response

    步骤2)我们发送L2CAP Configure Request配置请求 with MTU,对方回复L2CAP Configure Response

    步骤3)当MTU不符合要求的时候,对方发送L2CAP Configure Request配置请求with MTU,我们会送L2CAP Configure Response

    步骤4)后续的SDU的交互。

    我们就结合前面的知识来分析下raw data,加深我们上面的理解:

    步骤1)我们发送L2CAP Connection Request with RFCOMM PSM,对方回复L2CAP Connection Response

    ① 我们L2CAP Connection Request with RFCOMM PSM

    在这里我们还是重复下C-frame的封包格式,上面已经介绍,下面用到C-frame的时候格式我们就不再介绍。

    其中Information Payload格式为

    那么本步骤connection request以及connection response用到的information payload如下:

    Raw data分析

    08 00 01 00 02 04 04 00 03 00 41 00(hex data)

    08 00 -> payload len,也就02 01 04 00 01 00 40 00

    01 00->Signaling channel

     

    02 -> Code,L2CAP_CONNECTION_REQ (CODE 0x02)

    04->Identifier

    04 00 -> data的长度,也就是01 00 40 00

    03 00->PSM,0x0003就是RFCOMM

    40 00->0x0040,Source cid

    ② 对方回复L2CAP Connection Response

    L2CAP raw data为:0C 00 01 00 03 04 08 00 42 00 41 00 00 00 00 00

    0c 00 -> 整个L2CAP payload长度,也就是 03 04 08 00 42 00 41 00 00 00 00 00

    01 00-> Signaling channel

    03 -> L2CAP_CONNECTION_RSP (CODE 0x03)

    04 ->Identifier,可以看到跟connect req是一样的

    08 00->data长度,也就是42 00 41 00 00 00 00 00长度

    42 00 -> Destination CID

    41 00->Source CID

    00 00->Result connection successful

    00 00->Status

    步骤2)我们发送L2CAP Configure Request配置请求 with MTU,对方回复L2CAP Configure Response

    用到的C-frame information payload格式如下:

    ①我们发送L2CAP Configure Request配置请求 with MTU‘

    L2CAP raw data为0C 00 01 00 04 05 08 00 42 00 00 00 01 02 8E 04

    0c 00 -> 后续payload长度,也就是04 05 08 00 42 00 00 00 01 02 8E 04的长度

    01 00-> Signaling channel

    04 ->L2CAP_CONFIGURATION_REQ (CODE 0x04)

    05 ->Identifier

    08 00-> 后续的data长度

    42 00 -> Destination CID,在connection response的回复的

    00 00->Flags (2 octets),no continye

    01 02 8e 04是config opt,整个配置选项格式如下:

    那MTU的格式如下:

    01 -> MTU的type

    02 -> length

    8e 04 -> 0x48e = 1166byte

    ②对方回复L2CAP Configure Response

    0A 00 01 00 05 05 06 00 41 00 00 00 00 00

    0A 00-> 后续payload长度,也就是 05 05 06 00 41 00 00 00 00 00长度

    01 00-> Signaling channel

    05 ->L2CAP_CONFIGURATION_RSP (CODE 0x05)

    05 -> Identifier

    06 00 -> 后续的data长度

    41 00-> Source CID

    00 00->flag no continue

    00 00->Result

    步骤3)当MTU不符合要求的时候,对方发送L2CAP Configure Request配置请求with MTU,我们会送L2CAP Configure Response

    这个交互跟2)基本一样,所以不再重复说明

    步骤4)后续的SDU的交互

    SDU的我们走的basic mode,格式如下:

    Raw data为:04 00 42 00 03 3F 01 1C

    04 00 -> payload length是4

    42 00 -> CID

    03 3F 01 1C -> 数据,也就是rfcomm数据

     

    OK,本章结束

    展开全文
  • L2cap层是连接hci和上层profile的中转站,我们之前分析包格式的时候就说过,payload header中的llid如果标示是acl-u的话,说明就是个l2cap包。 上层profile在连接的时候,都需要先建立l2cap逻辑链路,每个逻辑链路...

    L2cap层是连接hci和上层profile的中转站,我们之前分析包格式的时候就说过,payload header中的llid如果标示是acl-u的话,说明就是个l2cap包。

    上层profile在连接的时候,都需要先建立l2cap逻辑链路,每个逻辑链路分配cid(channel id),这也是l2cap最重要的功能:协议/信道多路复用 
    然后比较重要的是,l2cap提供分包和重组功能,比如说上层的包比较大,controller支持的包比较小,就有可能需要分包了,我们前文说过,payload header中的llid含有start和continue信息,这个信息哪来的呢,看一下hci acl data的格式

    在handle中有两位pb flag就是用来标志这个事情的。

    我们看一下btstack中的代码对于pb flag的处理:

    在static void acl_handler(uint8_t *packet, int size)函数中

    case 0x02: { // first fragment
    
               
    
                // sanity check
    
                if (conn->acl_recombination_pos) {
    
                    log_error( "ACL First Fragment but data in buffer for handle 0x%02x, dropping stale fragments", con_handle);
    
                    conn->acl_recombination_pos = 0;
    
                }
    
    
    
                // peek into L2CAP packet!
    
                uint16_t l2cap_length = READ_L2CAP_LENGTH( packet );
    
    
    
                // log_info( "ACL First Fragment: acl_len %u, l2cap_len %u", acl_length, l2cap_length);
    
    
    
                // compare fragment size to L2CAP packet size
    
                if (acl_length >= (l2cap_length + 4)){
    
                    // forward fragment as L2CAP packet
    
                    hci_emit_acl_packet(packet, acl_length + 4);
    
                } else {
    
    
    
                    if (acl_length > HCI_ACL_BUFFER_SIZE){
    
                        log_error( "ACL First Fragment to large: fragment %u > buffer size %u for handle 0x%02x",
    
                            4 + acl_length, 4 + HCI_ACL_BUFFER_SIZE, con_handle);
    
                        return;
    
                    }
    
    
    
                    // store first fragment and tweak acl length for complete package
    
                    (void)memcpy(&conn->acl_recombination_buffer[HCI_INCOMING_PRE_BUFFER_SIZE],
    
                                 packet, acl_length + 4);
    
                    conn->acl_recombination_pos    = acl_length + 4;
    
                    conn->acl_recombination_length = l2cap_length;
    
                    little_endian_store_16(conn->acl_recombination_buffer, HCI_INCOMING_PRE_BUFFER_SIZE + 2, l2cap_length +4);
    
                }
    
                break;
    
               
    
            }

    如果是第一个分包,则红色字体将数据暂存到acl_recombination_buffer中去,然后、  

    case 0x01: // continuation fragment
    
               
    
                // sanity checks
    
                if (conn->acl_recombination_pos == 0) {
    
                    log_error( "ACL Cont Fragment but no first fragment for handle 0x%02x", con_handle);
    
                    return;
    
                }
    
                if ((conn->acl_recombination_pos + acl_length) > (4 + HCI_ACL_BUFFER_SIZE)){
    
                    log_error( "ACL Cont Fragment to large: combined packet %u > buffer size %u for handle 0x%02x",
    
                        conn->acl_recombination_pos + acl_length, 4 + HCI_ACL_BUFFER_SIZE, con_handle);
    
                    conn->acl_recombination_pos = 0;
    
                    return;
    
                }
    
    
    
                // append fragment payload (header already stored)
    
                (void)memcpy(&conn->acl_recombination_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + conn->acl_recombination_pos],
    
                             &packet[4], acl_length);
    
                conn->acl_recombination_pos += acl_length;
    
               
    
                // log_error( "ACL Cont Fragment: acl_len %u, combined_len %u, l2cap_len %u", acl_length,
    
                //        conn->acl_recombination_pos, conn->acl_recombination_length); 
    
               
    
                // forward complete L2CAP packet if complete.
    
                if (conn->acl_recombination_pos >= (conn->acl_recombination_length + 4 + 4)){ // pos already incl. ACL header
    
                    hci_emit_acl_packet(&conn->acl_recombination_buffer[HCI_INCOMING_PRE_BUFFER_SIZE], conn->acl_recombination_pos);
    
                    // reset recombination buffer
    
                    conn->acl_recombination_length = 0;
    
                    conn->acl_recombination_pos = 0;
    
                }
    
                break;

    如果收到continue fragment,则要比对一下数据总长度对不对,如果不对是要丢弃的,如果对的话,则和第一个包合并起来,并hci_emit_acl_packet提交给上层。

    总的来说,l2cap的分包并不复杂,不像tcp协议有可能有好多个包需要合并,而且顺序打乱,l2cap的分包就是连续的两包,如果出问题则直接丢弃的。

    L2cap还有一些其他功能,比如上文提到过的流控、重传,不过基本不用,还有QOS管理等等。

    但是最重要的两个功能,就是协议复用和分包重组这两项。

    下面我们看一下l2cap的逻辑信道是怎么连接的。

    要讲连接,首先讲一下l2capcid

    上图可以看出,如果是有连接的方式,上层l2cap实体间进行数据交互,也就是profile的数据交互需要建立l2cap连接后,互相绑定对方的cid

    如果是无连接的方式,则是向fixed channel——2channel发送数据,无连接广播包是一类不需要建立l2cap连接的方式,类似于LEadv包。

    笔者曾经实现了无连接的音乐播放,这里面挑战还是蛮大的,因为不像a2dp这种有连接的方式,传输是不可靠的,这里面涉及到底层链路设计,host层丢包处理等等,有机会可以讲一下,不过现在涉及到公司机密不太好公开的。

    所谓fixed channel,是指不同于上层profile的动态分配的cid,蓝牙core spec规定了以下fixed channel

    其实重要的也就是signal channel

    因为所有的连接都是始于signal channel的交互。

    怎么理解?

    看看我们的抓包好了:

    我们试图建立avdtpl2cap连接,首先我们发送l2cap connect req,这个req就是cid 01上发的,也就是signal id。在这条指令中,我们用psm表示了目前要建立的连接是avdtp,用source cid告诉对方我们这一端的cid0x40,注意这个cid是动态分配的。

    然后对方成功建立l2cap连接的回复,对方告诉我们,destination cid0x4d,也就是对方给到我们的cid0x4d

    然后需要进行一个配置的工作,l2cap可以配置的选项有:

    这里面最重要的是MTU,最大的包长。一般也就配置这一项就可以了。

    比如我们这次就告诉对方我们能支持的最大包长是672字节。

    这里面进行了几次的交互,直到双方协商一致为止。

    看一下btstack的代码,l2cap_signaling_handle_configure_request函数中有这么一段:

    if ((option_type == L2CAP_CONFIG_OPTION_TYPE_MAX_TRANSMISSION_UNIT) && (length == 2)){
    
                channel->remote_mtu = little_endian_read_16(command, pos);
    
                log_info("Remote MTU %u", channel->remote_mtu);
    
                if (channel->remote_mtu > l2cap_max_mtu()){
    
                    log_info("Remote MTU %u larger than outgoing buffer, only using MTU = %u", channel->remote_mtu, l2cap_max_mtu());
    
                    channel->remote_mtu = l2cap_max_mtu();
    
                }
    
                channelStateVarSetFlag(channel, L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP_MTU);
    
            }

    最终会在remote mtu和本地的mtu中找到一个最小值作为最终的mtu的。

    配置过程完成后,就可以正式在双方的绑定的cid上通信了。

    也就是————更上层的profile开始工作了。

    展开全文
  • 文章目录前言L2CAP 特性前提术语...L2CAP 为具有协议复用能力和分段和重组操作的上层协议提供面向连接和无连接的数据服务。 L2CAP 允许更高级别的协议和应用程序传输和接收长达 64 KB 的上层数据包(L2CAP 服务数据


    蓝牙逻辑链路控制和适配协议 (L2CAP) 支持更高级别的协议复用、数据包分段和重组以及服务质量信息的传送。

    规范的本部分描述了协议状态机、数据包格式和组成 。

    前言

    蓝牙规范的这一部分定义了逻辑链路控制和适配层协议,简称 L2CAP。

    • L2CAP 为具有协议复用能力和分段和重组操作的上层协议提供面向连接和无连接的数据服务。

    • L2CAP 允许更高级别的协议和应用程序传输和接收长达 64 KB 的上层数据包(L2CAP 服务数据单元,SDU)。L2CAP 还允许每个通道的流量控制和重传。

    • L2CAP 层提供逻辑信道,称为 L2CAP 信道,它们在一个或多个逻辑链路上复用。


    L2CAP 特性

    L2CAP 的功能要求包括协议/通道复用、分段和重组 (SAR)、通道流量控制和错误控制。L2CAP 位于下面的较低层级之上:

    1. BR/EDR Controller and zero or more AMP Controllers or
    2. BR/EDR/LE Controller (supporting BR/EDR and LE) and zero or more AMP Controllers, or
    3. LE Controller (supporting LE only)

    图 1.1 将 L2CAP 分解为其架构组件。
    在这里插入图片描述

    通道管理器The Channel Manager 提供the control plane functionality并负责所有内部信令internal signaling、L2CAP 对等信令L2CAP peer-to-peer signaling以及高层和底层信令signaling with higher and lower layers

    它执行第 6 节中描述的状态机功能,并使用第 4 节和第 5 节中描述的消息格式。重传和流量控制块使用数据包重传提供通道流量控制和错误恢复。

    Resource Manager 负责为Channel Manager、重传和流控块以及那些不需要重传和流控服务的应用数据流提供帧中继服务。它负责协调与多个 L2CAP 通道相关的数据包在低层接口提供的设施上的传输和接收。

    • Protocol/channel multiplexing :协议/通道复用

    L2CAP 支持在单个控制器和多个控制器上进行多路复用。**L2CAP channel一次应在一个controller上运行。**在通道建立期间,协议复用能力用于将路由连接到正确的上层协议。

    对于数据传输,需要逻辑信道复用来区分多个上层实体。使用相同协议的上层实体可能不止一个。

    • Segmentation and reassembly :分段和重组

    通过资源管理器提供的帧中继服务,传输帧的长度由运行在 L2CAP 上的各个应用程序控制。如果 L2CAP 能够控制 PDU 长度,则可以更好地服务于许多多路复用应用程序。

    这提供了以下好处:

    1. 分段将允许应用程序数据单元的交织以满足延迟要求。
    2. 当 L2CAP 控制数据包大小时,内存和缓冲区管理更容易。
    3. 可以更有效地通过重传进行纠错。
    4. 当 L2CAP PDU 损坏或丢失时被破坏的数据量可以小于应用程序的数据单元。
    5. 应用程序与将应用程序数据包映射到低层数据包所需的分段分离
    • Flow control per L2CAP channel:每个 L2CAP 通道的流量控制

    控制器为通过空中传输的数据提供错误和流量控制,而对于通过 HCI 传输的数据存在 HCI 流量控制。当多个数据流使用单独的 L2CAP 通道在同一个控制器上运行时,每个通道都需要单独的流量控制。L2Cap提供了一种基于窗口的流量控制方案。

    • Error control and retransmissions:错误控制和重传

    当 L2CAP 通道从一个控制器移动到另一个控制器时,数据可能会丢失。此外,某些应用程序需要的残余错误率远小于某些控制器所能提供的。L2CAP 提供 L2CAP PDU 的错误检查和重传。L2CAP 中的错误检查可防止由于控制器错误地接受包含错误但通过基于控制器的完整性检查的数据包而导致的错误。

    L2CAP 错误检查和重传还可以防止由于控制器刷新导致的数据包丢失。在流控制机制将节流重传以及首次传输的意义上,错误控制与流控制一起工作。

    • Support for Streaming:支持流媒体

    流媒体应用程序(例如音频)以商定的数据速率设置 L2CAP 通道,并且不希望流控制机制(包括控制器中的流控制机制)改变数据流。刷新超时用于保持数据在传输端流动。流模式用于阻止 HCI 和基于控制器的流量控制应用于接收端。

    • Fragmentation and Recombination:分片和重组

    一些控制器的传输能力可能有限,并且可能需要与 L2CAP 分段创建的不同的片段大小。因此,L2CAP 之下的层可能会进一步对 L2CAP PDU 进行分段和重组,以创建适合每一层能力的分段。在传输 L2CAP PDU 期间,两个对等设备中可能会发生许多不同级别的分段和重组。

    HCI 驱动程序或控制器可以对 L2CAP PDU 进行分段,以遵守主机控制器接口传输方案的数据包大小限制。这导致 HCI 数据包有效载荷携带 L2CAP PDU 的开始和继续片段。类似地,控制器可以将 L2CAP PDU 分段以将它们映射到控制器数据包中。这可能导致控制器数据包负载携带 L2CAP PDU 的开始和继续片段。

    协议栈的每一层可能会传递不同大小的L2CAP PDU分片,并且每一层创建的分片大小在每个对等设备中可能不同。然而,PDU 在堆栈内被分段,接收 L2CAP 实体仍然重新组合这些分段以获得原始 L2CAP PDU。

    • Quality of Service

    L2CAP 连接建立过程允许交换有关两个蓝牙设备之间预期的服务质量 (QoS) 的信息。每个 L2CAP 实现都会监控协议使用的资源并确保遵守 QoS 合同。

    对于 BR/EDR 或 BR/EDR/LE 控制器,L2CAP 可以通过设置将数据包标记为自动刷新或非自动刷新来支持同步(保证)和异步(尽力而为)数据流在同一 ACL 逻辑链路上HCI ACL 数据包中 Packet_Boundary_Flag 的适当值(参见 [Vol 4] Part E, Section 5.4.2)。

    可自动刷新的 L2CAP 数据包根据为 L2CAP 通道映射到的 ACL 逻辑链路设置的自动刷新超时进行刷新(参见 [Vol 4] E 部分,第 6.19 节)。

    Nonautomatically-flushable L2CAP 数据包不受自动刷新超时的影响,不会被刷新。可以使用 HCI_Flush 命令刷新所有 L2CAP 数据包(请参阅 [Vol 4] Part E, Section 7.3.4)。

    对于 AMP 控制器,L2CAP 将所有异步数据流通过单个逻辑链路(聚合)发送到同一远程设备。L2CAP 将每个同步数据流放置在其自己的逻辑链路上。

    前提

    该协议的设计基于以下假设:

    1. 控制器提供数据包的有序传递,尽管可能存在个别数据包损坏和重复。

      对于带有 BR/EDR 或 BR/EDR/LE 控制器的设备,任意两台设备之间只存在一条 ACL-U 逻辑链路。

      对于具有给定 AMP 控制器的设备,任意两个设备之间可能存在多个 AMP-U 逻辑链路。

      对于带有 BR/EDR/LE 或 LE 控制器的设备,任何两个设备之间不存在超过一个 LE-U 逻辑链路。

    2. 控制器总是给人以全双工通信信道的印象。

      这并不意味着所有 L2CAP 通信都是双向的。单向流量不需要双工信道。

    3. L2CAP 层基于控制器中可用的机制提供具有一定程度可靠性的信道,并且可以在增强的 L2CAP 层中启用额外的数据包分段、错误检测和重传。

      一些控制器执行数据完整性检查并重新发送数据,直到成功确认或发生超时。其他控制器将重新发送数据达到一定次数,然后刷新数据。因为确认可能会丢失,所以即使在成功发送数据之后也可能发生超时。

      注意:在 BR/EDR 或 BR/EDR/LE 控制器中使用基带广播数据包是不可靠的,所有广播都以相同的序列位开始 L2CAP 数据包的第一段。

    4. 控制器为通过空中传输的数据提供错误和流量控制,而对于通过 HCI 传输的数据存在 HCI 流量控制,但某些应用程序需要比某些控制器提供的更好的错误控制。

      此外,在控制器之间移动通道需要 L2CAP 流和错误控制。Flow and Error Control 模块提供四种模式。

      1. 增强重传模式和重传模式提供分段、流量控制
      2. L2CAP PDU 重传
      3. 流控模式只提供分段和流控功能
      4. 流模式提供分段和接收端数据包刷新

    以下功能不在 L2CAP 的职责范围内:

    • L2CAP 不传输为 SCO 或 eSCO 逻辑传输指定的同步数据。
    • L2CAP 不支持可靠的广播信道。参考 《BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part A Section 3.2》

    术语

    • SDU, or L2CAP SDU:服务数据单元Service Data Unit,L2CAP 与上层交换并使用此处指定的程序通过 L2CAP 通道透明传输的数据包。

    • Segment, or SDU segment:SDU 的一部分,由分割过程产生。 一个 SDU 可以分成一个或多个段。

    • PDU, or L2CAP PDU:Protocol Data Unit协议数据单元,包含 L2CAP 协议信息字段、控制信息 和/或 上层信息数据的数据包。

      PDU 总是由基本 L2CAP 报头开始。PDU 的类型有:B-frames、I-frames、S-frames、C-frames、G-frames 和 LE Frames。

    • Fragment:PDU 的一部分,由分片操作产生。Fragment/片段仅用于向和从较低层传送数据。它们不用于点对点传输。片段可以是关于 L2CAP PDU 的开始或继续片段。

      一个片段不包含超出 PDU 的任何协议信息; 开始和继续片段的区别由较低层协议规定传输。

      注意:起始片段总是以 PDU 的基本 L2CAP 标头的第一个八位字节开始,或者它们的长度为零(参见 [Vol 2] Part B,第 6.6.2 节)。

    • Recombination:对应于分片的反向过程,导致从分片重新建立 L2CAP PDU。在接收路径中,Controller 和/或 Host可能发生全部或部分重组操作,重组的位置不一定对应发送端发生分片的位置

    • Maximum Transmission Unit (MTU):上层实体能够接受的有效载荷数据的最大大小,以八位字节为单位,即MTU 对应于最大 SDU 大小。

    • MaxTransmit:在增强重传模式和重传模式下,MaxTransmit 控制在假设 PDU(和链路)会丢失之前允许 L2CAP 尝试的 PDU 传输次数。最小值为 1(仅允许 1 次传输),在增强重传模式中,值 0 表示无限传输。

    注意:将 MaxTransmit 设置为 1 将禁止 PDU 重传。单个 PDU 的故障将导致链路掉线。相比之下,在流量控制模式下,单个 PDU 的故障不一定会导致链路掉线。

    常规操作

    L2CAP 基于“通道”的概念。 L2CAP 通道的每个端点都由通道标识符 (CID) 引用。

    通道标识符

    通道标识符 (CID) 是表示设备上逻辑通道端点的本地名称。CID 的范围与逻辑链路有关,如图 2.1 所示。空标识符 (0x0000) 绝不能用作目标端点。

    从 0x0001 到 0x003F 的标识符是为特定的 L2CAP 功能保留的。这些通道称为固定通道。至少应支持 L2CAP 信令信道(固定信道 0x0001)或 L2CAP LE 信令信道(固定信道 0x0005)。

    如果支持固定通道 0x0005,则应支持固定通道 0x0004 和 0x0006(见表 2.2)。可以支持其他固定信道。

    L2CAP_INFORMATION_REQ / L2CAP_INFORMATION_RSP 机制(在第 4.10 节和第 4.11 节中描述)应用于确定远程设备通过 ACL-U 逻辑链路支持哪些固定信道。每个固定通道的特性是在每个通道的基础上定义的。

    固定信道特性包括配置参数(例如,可靠性、MTU 大小、QoS)、安全性以及使用 L2CAP 配置机制更改参数的能力。

    表 2.1 列出了定义的固定信道,提供了定义相关信道特性的参考,并指定了信道可以运行的逻辑链路。一旦建立了 ACL-U 或 LE-U 逻辑链路,就可以使用固定通道。当建立 ACL-U 或 LEU 逻辑链路时,应为每个支持的固定信道执行通常在创建信道时执行的所有初始化。

    固定信道只能在 ACL-U、ASB-U 或 LE-U 逻辑链路上运行,不得移动。

    实现可以以最适合该特定实现的方式自由管理剩余的 CID,前提是两个同时活动的 L2CAP 通道不应共享相同的 CID。

    每个 ACL-U、ASB-U 和 LE-U 逻辑链路都存在不同的 CID 名称空间。AMP-U 逻辑链路与其关联的 ACL-U 逻辑链路共享 CID 名称空间。
    在这里插入图片描述
    动态分配的 CID 的分配与特定的逻辑链路有关,设备可以独立于其他设备分配 CID。

    因此,即使连接到单个本地设备的多个远程设备已将相同的 CID 值分配给(远程)通道端点,本地设备仍然可以唯一地将每个远程 CID 与不同的设备相关联。

    此外,即使相同的 CID 值已由相同的远程设备分配给(远程)通道端点,也可以区分这些端点,因为它们将绑定到不同的逻辑链路。

    操作模式

    L2CAP 通道可以按为每个 L2CAP 通道选择的几种不同模式之一运行:

    • Basic L2CAP Mode
    • Flow Control Mode
    • Retransmission Mode
    • Enhanced Retransmission Mode
    • Streaming Mode
    • LE Credit Based Flow Control Mode
    • Enhanced Credit Based Flow Control Mode

    使用第 7.1 节中描述的配置过程启用这些模式。

    • 基本 L2CAP 模式应为默认模式,在没有约定其他模式时使用。
    • 增强型重传模式应用于在 AMP-U 逻辑链路上创建的所有可靠信道和 ACL-U 逻辑链路,其操作如第 7.10 节所述。
    • 对于通过 ACL-U 逻辑链路创建的可靠信道,应启用增强型重传模式,而不是按照第 7.10 节所述进行操作。
    • 流模式应用于在 AMP-U 逻辑链路和 ACL-U 逻辑链路上创建的流应用,其操作如第 7.10 节所述。
    • 应为通过 ACL-U 逻辑链路创建的流应用程序启用流模式,该应用程序的操作不如第 7.10 节所述。
    • 当两个 L2CAP 实体都支持时,应启用增强重传模式、基于增强信用的流控制模式或流模式。
    • 仅当与不支持增强重传模式、基于增强信用的流控制模式或流模式的 L2CAP 实体通信时,才应启用流控制模式和重传模式。

    数据包格式

    L2CAP 是基于数据包 packet-based 的, 但遵循基于通道channels的通信模型*。通道表示远程设备中 L2CAP 实体之间的数据流。通道可以是面向连接的或无连接的。

    除了 L2CAP 无连接通道(CID 0x0002)和两个 L2CAP 信令通道(CID 0x0001 和 0x0005)之外的固定通道被认为是面向连接的。具有动态分配的 CID 的所有通道都是面向连接的。
    在这里插入图片描述
    在这里插入图片描述

    除信息有效载荷字段外,所有 L2CAP 层数据包字段都应使用小端字节序。封装在 L2CAP 信息负载中的高层协议的字节序是特定于协议的。 参考<BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part A>

    • Basic information frame (B-frame) :B 帧是在基本 L2CAP 模式中用于 L2CAP 数据包的 PDU。它包含一个完整的 SDU 作为其有效载荷,由基本 L2CAP 标头封装。
    • Information frame (I-frame) :I 帧是在增强型重传模式、流模式、重传模式和流控制模式中使用的 PDU。它包含一个 SDU 段和附加协议信息,由基本 L2CAP 头封装。
    • Supervisory frame (S-frame) :S帧是增强型重传模式、重传模式和流量控制模式中使用的PDU。它仅包含协议信息,由基本 L2CAP 头封装,不包含 SDU 数据。
    • Control frame (C-frame) :C 帧是包含在对等 L2CAP 实体之间交换的 L2CAP 信令消息的 PDU。C 帧专门用于 L2CAP 信令信道。
    • Group frame(G-frame):G 帧是专用于无连接 L2CAP 通道的 PDU。它由基本 L2CAP 报头封装,包含 PSM,后跟完整的 SDU。G 帧可用于通过 Active Broadcast 向活动从设备广播数据或将单播数据发送到单个远程设备。
    • Credit-based frame (K-frame) :K 帧是在基于 LE Credit 的流量控制模式中使用的 PDU。它包含一个 SDU 段和附加协议信息,由基本 L2CAP 报头封装。

    CONNECTION-ORIENTED CHANNELS IN BASIC L2CAP MODE

    图 3.1 说明了在面向连接的信道上使用的 L2CAP PDU 的格式。在 Basic L2CAP 模式下,面向连接通道上的 L2CAP PDU 也称为"B-frame"。
    在这里插入图片描述
    Information payload: 0 到 65535 个八位字节

    这包含从上层协议接收到的有效载荷(传出数据包),或传递给上层协议(传入数据包)的有效载荷。 具有动态分配的 CID 的通道的 MTU 是在通道配置期间确定的(参见第 5.1 节)。 信令 PDU 支持的最小 MTU 值如表 4.1 所示。

    CONNECTIONLESS DATA CHANNEL IN BASIC L2CAP MODE

    图 3.2 说明了无连接数据通道中的 L2CAP PDU 格式。 这里,L2CAP PDU也被称为“G-frame”。

    在这里插入图片描述
    Information payload: 0 到 65535 个八位字节

    此参数包含要分发给 微微网(piconet ) 中所有slave设备以用于广播无连接流量的有效载荷信息,或用于通过 L2CAP 无连接通道发送数据的特定远程设备。

    CONNECTION-ORIENTED CHANNEL IN RETRANSMISSION/FLOW CONTROL/STREAMING MODES

    为了支持流控制、重传和流传输,除了基本 L2CAP 报头之外,还定义了具有协议元素的 L2CAP PDU 类型。

    The information frames (I-frames)用于 L2CAP 实体之间的信息传输。The supervisory frames (S-frames)用于acknowledge I-frames (确认帧)和 request retransmission of I-frames(请求重传帧)。图 3.3 说明了这些框架。

    在这里插入图片描述

    CONNECTION-ORIENTED CHANNELS IN LE CREDIT BASED FLOW CONTROL MODE AND ENHANCED CREDIT BASED FLOW CONTROL MODE

    为了支持基于 LE 信用的流量控制模式和基于增强信用的流量控制模式,除了基本 L2CAP 标头之外,还定义了具有协议元素的 L2CAP PDU 类型。

    在LE Credit Based Flow Control Mode和Enhanced Credit Based Flow Control Mode中,面向连接信道上的L2CAP PDU是一个基于Credit的帧(K-frame),如图3.12所示。
    在这里插入图片描述

    SIGNALING PACKET FORMATS

    本节介绍在对等设备上的两个 L2CAP 实体之间传递的信令命令。所有信令command都通过信令信道发送。

    管理 ACL-U 逻辑链路信道的信令信道应使用 CID 0x0001,管理 LE-U 逻辑链路信道的信令信道应使用CID 0x0005。一旦设置了低层逻辑传输并启用了 L2CAP 流量,信令信道就可用。

    图 4.1 说明了包含信令命令(C 帧)的 L2CAP PDU 的一般格式。多个命令可以在单个 C 帧中通过固定信道 CID 0x0001 发送,而每个 C 帧只能通过固定信道 CID 0x0005 发送一个命令。

    Commands 采用请求、响应和指示的形式。所有 L2CAP 实现都应支持有效载荷长度不超过信令 MTU 的 C 帧的接收。表 4.1 中定义了 C 帧(MTUsig)支持的最小有效载荷长度。
    在这里插入图片描述

    L2CAP 实现不应使用超过对等设备的 M T U s i g MTU_{sig} MTUsig 的 Cframe。如果设备接收到超过其 MTU sig 的 Cframe,则它应发送包含支持的 M T U s i g MTU_{sig} MTUsigL2CAP_COMMAND_REJECT_RSP。实现应能够处理通过固定信道 CID 0x0001 发送的 L2CAP 数据包中的多个命令的接收。

    注意:信令包的名称有一个表示其类型的后缀:_REQ 表示请求,_RSP 表示响应,_IND 表示指示。

    其中Length跟CID不需要额外说明,在signaling command的information payload的格式为:
    在这里插入图片描述

    • Identifier (1 octet):用于标示command的发送序列,response必须跟request相同。
    • Length (2 octets):用于标示后续的data长度。
    • Data (0 or more octets):针对不同的signaling command,后续的data是不同的,具体command具体分析。

    在这里插入图片描述
    在这里插入图片描述

    channel ID

    通道标识符 (CID) 是表示设备上逻辑通道端点的本地名称。CID 的范围与逻辑链路有关,如图 2.1 所示。
    在这里插入图片描述
    空标识符(0x0000)决不能用作目的地端点。从 0x0001 到 0x003F 的标识符是为特定的 L2CAP 功能保留的。这些频道称为固定频道。

    至少应支持 L2CAP Signaling 通道(固定通道 0x0001)或 L2CAP LE Signaling通道(固定通道 0x0005)。

    • 如果支持固定通道 0x0005,则应支持固定通道 0x0004 和 0x0006(见表 2.2)。
      在这里插入图片描述

    L2CAP_INFORMATION_REQ / L2CAP_INFORMATION_RSP 机制(在第 4.10 节和第 4.11 节中描述)应用于确定远程设备在 ACL-U 逻辑链路上支持哪些固定通道。每个固定通道的特性是在每个通道的基础上定义的。固定信道特性包括配置参数(例如,可靠性、MTU 大小、QoS)、安全性以及使用 L2CAP 配置机制更改参数的能力。

    表 2.1 列出了定义的固定信道,提供了对相关信道特性定义位置的参考,并指定了信道可以在其上运行的逻辑链路。一旦建立 ACL-U 或 LE-U 逻辑链路,固定信道就可用。
    在这里插入图片描述
    在这里插入图片描述

    固定信道只能在 ACL-U、ASB-U 或 LE-U 逻辑链路上运行,不得移动。

    实现可以自由地以最适合该特定实现的方式管理剩余的 CID,前提是两个同时活动的 L2CAP 通道不应共享相同的 CID。

    • 每个 ACL-U、ASB-U 和 LE-U 逻辑链路都存在不同的 CID 名称空间。
    • AMP-U 逻辑链路与其关联的 ACL-U 逻辑链路共享 CID 名称空间。
    • 动态分配的 CID 的分配与特定的逻辑链路相关,并且设备可以独立于其他设备分配 CID。

    因此,即使连接到单个本地设备的多个远程设备已将相同的 CID 值分配给(远程)通道端点,本地设备仍然可以唯一地将每个远程 CID 与不同的设备相关联。

    此外,即使同一远程设备已将相同的 CID 值分配给(远程)通道端点,也可以区分它们,因为它们将绑定到不同的逻辑链路。

    展开全文
  • 蓝牙核心-L2CAP

    2017-10-11 15:50:04
    概要: 逻辑链路控制和适配协议(L2CAP),支持高层协议多路...L2CAP层次结构(L2CAP architectural blocks): 基带规范定义了两种链路类型:同步面向连接链路(SCO)和异步无连接链路(ACL)。SCO 链路采用保留
  • 蓝牙篇之蓝牙核心规范(V5.2)深入详解汇总 本小结主要阐述主机的A部分,...每个L2CAP面向连接的通道都有一个活动的状态机。将为接收到的每个新L2CAP_ConnectReq创建一个状态机。状态机始终在关闭状态下启动。 ...
  • 前面文件描述蓝牙设备在物理通道上建立了链接,但上层应用若需要在设备之间通信,那么还需要在L2CAP层次建立连接L2CAP 的CID(通道ID)好比是计算机的端口号,在访问网络时每个应用程序会对应不同的端口号。在L2CAP...
  • L2CAP层提供逻辑通道,即L2CAP通道,这些通道在一条或多条逻辑链路上复用。在经典蓝牙无线电中,L2CAP层提供的功能比这更多,也更为复杂。 通道管理器(Channel Manager)提供一个功能控制的控制面板,并负责所有内部...
  • Android 蓝牙L2cap协议初始化、连接流程图(协议栈),非常详细的从btif-bta-btm-hci 数据流程走向,以及从controller收到数据到btm层,将Android 源码使用流程图的形式画了出来,使Android 蓝牙开发者更清楚数据...
  • 传统蓝牙L2CAP概念介绍

    千次阅读 2020-08-11 08:18:00
    那看完了L2CAP在整个协议栈中的位置,我们就来看下L2CAP内部的架构,如图: L2CAP图示一共有几个特性:Resource Manager有分包/组包,重传/流控,封装/调度,Channel Manager有连接/断开/交互频道参数等。...
  • L2CAP信令封包(SIGNALING PACKET)格式

    千次阅读 2020-08-13 07:57:04
    3 .L2CAP_CONNECTION_RSP (CODE 0x03) 该命令是响应发起连接请求,格式如下: 我们只说Destination CID,Source CID,Result,Status Destination CID:可以认为是发送response的本地CID Source CID:发送L2CAP_...
  • 一、L2CAP概述

    2021-06-17 08:06:48
    1、L2CAP:即Logical Link Control and Adaptation Layer Protocol,是介于上层和底层(例如HCI)之间的一种数据交互的媒介
  • 1、L2CAP概述L2CAP-全称是逻辑链路控制与适配层,为两个通信的蓝牙设备提供一个端到端的通道。L2CAP主要功能:1.协议信道复用(protocol/channel multiplexing)2.分段与重组(segmentation and reassembly SAR)3.每个...
  • Bluetooth L2CAP介绍

    2019-05-09 09:54:35
    Bluetooth L2CAP介绍 阅读目录 1. 介绍 2. 实现 3. 通用操作 4. 数据包格式 5. 信号包格式 6. 参数配置选项 7. 状态机 回到顶部 1. 介绍 L2CAP,Logical Link Control and Adaptation Protocol,即逻辑...
  • 面向连接的基本模式数据格式(CONNECTION-ORIENTEDCHANNELS IN BASIC L2CAP MODE) 格式如下,面向连接的基本模式称为B-frame 参数: Length:Information payload的长度 Channel ID:The channel ID (CID) identifies...
  • BLE主机之L2CAP

    2020-12-24 01:09:38
    本文介绍L2CAP 部分L2CAP 的全称是 逻辑链路控制和适配协议, L2CAP 是低功耗蓝牙的复用层,该层定义两个基本概念L2CAP 信道和L2CAP 信令,L2CAP 信道是一个双向数据通道,通向对端设备上的某一特定的协议或规范,...
  • 蓝牙L2CAP剖析(二)

    千次阅读 2016-05-10 17:42:15
    关键字:bluetooth 蓝牙协议 HCI剖析 HCI概述 HCI笔记 LMP L2CAP SDP RFCOMM  作者:zhongjun 本着互相学习的目的,来分享此一系列的文章,欢迎转载,请注明作者,尊重版权,谢谢 文章有不当处请指正,共同...
  • BlueDroid代码分析之L2CAP

    千次阅读 2015-01-13 18:55:01
    ACL 链路在 Bluetooth 中非常重要,一些重要的应用如 A2DP, 基于 RFCOMM 的应用,BNEP等都要建立 ...ACL包发送下面的图(点击大图)是各种应用层使用 L2CAP 的 API:L2CA_DataWrite 发送数据流的过
  • Bluedroid L2CAP 链路限制总结

    千次阅读 2016-10-20 10:38:02
    Android源生l2cap link设置
  • 作者:Sam (甄峰)(L2CAP协议简介,L2CAP在BlueZ中的实现以及L2CAP编程接口)一:L2CAP协议简介:Logical Link Control and Adaptation Protocol(L2CAP)逻辑连接控制和适配协议(L2CAP)为上层协议提供面向连接和无连接...
  • 蓝牙协议系列之(四) L2CAP

    万次阅读 多人点赞 2018-06-15 14:12:16
    4 L2CAP Protocol4.1 功能介绍经过Link Layer的抽象之后,两个BLE设备之间可存在两条逻辑上的数据通道:一条是无连接的广播通道,海阔凭鱼跃嘛;另一条是基于连接的数据通道,是一个点对点(Master对Slave)的逻辑...
  • 12-BLE协议L2CAP

    2020-10-28 16:54:24
    学习资料:官方手册 Vol 3: Core System Package [Host volume] Part A: Logical Link Control and Adaptation Protocol Specification 建议先复习《BLE协议各层的形象化理解》,下面是...L2CAP是“收发室”,它熟知
  • 本小结主要阐述主机的A部分,逻辑链路控制和适配协议规范(L2CAP)。支持更高级别的协议多路复用、分组分割和重组,以及服务质量信息的传输。协议状态机描述了本规范的包格式和组成。 1.L2CAP作用 为上层协议...
  • BLE协议栈 – L2CAP

    2019-08-12 10:10:49
    L2CAP(Logical Link Control and Adaptation Protocol)中文名为逻辑链路控制和适配协议,它位于BLE协议的主机(Host)部分,承担着协议复用(Protocol Multiplex)的任务。蓝牙协议官方手册的章节首页提到L2CAP还...
  • 第13节-BLE协议L2CAP

    2020-12-24 01:09:36
    request (src\ble\gatt_client.c) l2cap_send_prepared_connectionless (src\l2cap.c) hci_send_acl_packet_buffer (src\hci.c) hci_send_acl_packet_fragments (src\hci.c) 三、L2CAP层数据接收过程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,382
精华内容 2,152
关键字:

l2cap连接