前言:
此刻我们对“数据封装过程中至顶向下的pdu名字”可能比较注意,咱们都想要知道一些“数据封装过程中至顶向下的pdu名字”的相关内容。那么小编同时在网上网罗了一些关于“数据封装过程中至顶向下的pdu名字””的相关内容,希望小伙伴们能喜欢,咱们快快来了解一下吧!一、ble协议栈整体框架:
二、 LL链路层
LL层可以发出:广播包、数据包。Access Address等于0x8e89bed6时,是广播包;否则是数据包。
LL链路格式:1. preamble(前导帧):
为1个字节,根据Access Address第一个Bit,有两种取值情况:0x55或者0xAA(纯PHY层行为);
2. Access Address:
用来标示接收者ID或者空中包身份, 根据Access Address的不同,又区分两种Packet类型:广播包和数据包:
---广播包:广播包Access Address 固定为0x8E89BED6,广播包只能在广播信道(channel)上传输,即只能在37/38/39信道上传输(注:从蓝牙5.0开始广播包可以在其它信道上传输)。广播包发送给附近所有的observer(扫描者)。
---数据包:数据包Access Address为一个32bit的随机值,由Initiator生成。数据包,其实是数据信道上的空中包的简称,数据包只在数据信道上传输,即除37/38/39之外的其余37信道(BLE总共占用40个信道)。每建立一次连接,重新生成一次Access address。数据包是给连接通信使用的,即用于master和slave之间通信的。
3. PDU:
协议数据单元,前两个字节固定为LL header(1个字节长)和payload length(1个字节长,又称data length),即上面的Packet可以展开为:
4. CRC:
24bit的校验值,主要针对PDU数据部分内容;
三、HCI格式:1.HCI作用:
蓝牙Host(蓝牙协议栈)跟蓝牙Controller(蓝牙芯片)之间交互的数据格式,蓝牙的SIG规定了四种与硬件连接的物理总线方式:USB、SDIO、UART和PC卡。
2. 数据格式以下几种类型:
--- HCI command: 由蓝牙协议栈给蓝牙芯片发送命令,来控制芯片行为,由OGF(Groups)和OCF两部分组成;
---HCI event:由蓝牙芯片上报事件给蓝牙协议栈的事件;
---HCI ACL数据:蓝牙协议栈跟蓝牙芯片双向交互的L2CAP以及上层数据;
---HCI SCO数据: 蓝牙协议栈跟蓝牙芯片交互的SCO音频实时数据;(BR/EDR支持)
---HCI ISO:蓝牙协议栈跟蓝牙芯片交互的BLE audio的数据(Core 5.2才增加,(BR/EDR支持))
2.HCI层跟LL层的关系:
a. 有些HCI command只是用来设置本地Controller,不导致无线传输
b. 有些HCI command会导致LL层发出各类广播包:比如在主动扫描时会导致LL层发出SCAN_REQ广播包;还有比如会导致LL层发出连接的CONNECT_REQ广播包;
c. 有些HCI command会导致LL层发出数据包,其中的LLID=11b,表示是“LL Control PDU”:比如从LL层发送数据给对端设备以读取对端设备的信道图的命令。
d. ACL Data是必定导致LL层发数据给对端设备的,这时的LL层数据,有可能是起始包,LLID=10b;也可能是延续包,也可能是空包;
3. HCI硬件接口:
1) HCI有多种接口,有USB口、3线串口(TxD/RxD/Gnd)、5线串口(TxD/RxD/Gnd/CTS/RTS),如下图:
2) 硬件线路上区分数据格式的方法(Command/Event/ACL/SCO)
---对于UART接口的Controller,会在数据前面加上1字节的头部用来分辨是哪一类数据;
---对于USB接中里的Controller,每类数据对应一个Endpoint,数据会直接发给Endpoint;
四、广播包格式:
广播包被封装在LL层packet中的PDU中,由Header和Payload两部分组成,是GAP协议管理的内容;
1.Header部分(16bits);
1) PDU Type:
PDU Type为4bit,具体定义如下。可以看出扫描PDU和发起连接PDU都属于广播包。
实际工作中用的较多的是ADV_IND、ADV_DIRECT_IND、SCAN_REQ、SCAN_RSP、CONNECT_REQ。
---ADV_IND 普通广播包:
由6字节的地址和0-31字节的数据组成。特别注意,AdvData不能超过31个字节,否则开启广播会有问题。净荷格式如图下所示:
---ADV_DIRECT_IND: 直连广播包
ADV_DIRECT_IND包由6字节的广播设备地址和6字节的目标设备地址组成。净荷格式如图下所示:
---SCAN_REQ:扫描请求。
SCAN_REQ包由6字节的扫描设备地址和6字节的广播设备地址组成。净荷格式如图下所示:
---SCAN_RSP: 扫描响应。
SCAN_RSP包由6字节的广播设备地址和0-31字节的扫描响应数据组成。SCAN_RSP包中的ScanRspData与ADV_IND包中的AdvData格式一样。当广播设备接收到其它设备发来的SCAN_REQ包后,一般会回复SCAN_RSP包。净荷格式如图下所示:
2) RFU: 保留
3) ChSel: 字段为0--表示不支持通道选择;1---支持通道选择;
4) TxAdd: 代表的蓝牙MAC地址类型。字段为1--表示广播设备的地址是随机的;0--表示广播设备的地址是公共的;
5) RxAdd: 代表的蓝牙MAC地址类型。字段为1--表示目标设备地址是随机的;0--表示目标设备地址是公共的;
6) Length: 表示广播数据包净荷的长度;BLE4.0-BLE4.2支持的最大广播payload包长是31字节;BLE5.0增加了扩展模式,以数据通道发送额外的数据,使得广播支持的最大payload包长是254字节。
2.Payload部分 ;
1) Advertising Data帧格式
a. 广播包中的数据域使用LTV的格式进行定义,即 length + type + value
length表示(type + value)的总长度;
b. 每个包都是 31 字节,数据包中分为有效数据(significant)和无效数据(non-significant)两部分;
c. 有效数据部分: 包含若干个广播数据单元,称为 AD Structure 。
d. 如图所示,AD Structure 的组成是:
---长度 Len ,表示这个 AD Structure 的长度(除去 len本身 1)
---类型 AD Type: 标记这段广播数据代表什么, 比如设备名, uuid 等。
---数据 AD data
---无效数据部分
广播包的长度必须是 31 个 byte,如果有效数据部分不到 31 自己,剩下的就用 0 补全。这部分的数据是无效的。 结构如下:
2)广播数据的具体字段有:
部分常见类型说明和定义如下:
---Flags: 当有一个可连接的广播包时,该位有效,Flags包括(ble中常用类型1):
---Service UUID: 包含一系列蓝牙服务UUID
---Local Name: 设备名称
---Manufacturer Specific Data: 产商的唯一标识符
---TX Power Level: 发送功率
---Slave Connection Interval Range: 可通过广播数据包请求更改对方的默认连接间隔范围
---Service Solicitation: 请求与一个或多个指定服务的广播设备连接
---Service Data: 包含服务的UUID和该服务所对应的数据
---Appearance: 根据standard Appearance assigned numbers定义的广播设备的类型
---Public Target Address: 当使用公共地址绑定一个或多个设备时,定义广播的一个或多个接收者的地址。
---Random Target Address: 当使用随机地址绑定一个或多个设备时,定义广播的一个或多个接收者的地址。
---Advertising Interval: 广播间隔
---Uniform Resource Identifier: 用于广播一个URL
---LE Supported Features: 用于定义设备的低功耗特性
3.具体实例:
1) 完整数据包格式
AAD6BE898E600E3B75AB2A02E10201010A095065646F6D657465728EC7B2
--AA: 前导帧(preamble)
--D6BE898E: 32bits,广播固定地址(access address);
--60:LL帧头字段(LL header),0110--广播类型为ADV_SCAN_IND;
--0E:有效数据包长度(payload length)
--3B75AB2A02E1:48bits, 广播者设备地址(advertiser address)
--0201010A095065646F6D65746572 广播数据
--8EC7B2: CRC24值。
2) 广播数据分析:
0201010A095065646F6D65746572
五、数据包格式:
主要包括L2CAP协议部分和链路控制协议两部分。
1.Data Header:
即上面提到的LL层头,在数据包中定义格式如下:
对于连接后的通讯包,PDU的最前面两个字节为header,header的最前两个bit为LLID,蓝牙BLE就是通过LLID来区分LL层数据和L2CAP层数据的;
1) LLID:2bits。 link layer ID,对LL PDU进行分类:LL data PDU(数据包)和LL control PDU(控制包)。要注意分清data channel packet(数据信道空中包)和LL data packet(LL数据包)的区别,
---以下为LL数据包类型:
这些数据是会经过L2CAP层,再上报到GATT和ATT应用层;
---以下为LL控制包类型:
LL Control PDU是在Link layer层直接进行交互的,这些数据不会经过后面的L2CAP层,Link layer支持如下control PDU:
2) NESN/SN:
---NESN和SN各占1bit;BLE没有专门的ACK包,它是通过NESN/SN来实现ACK和重传双重功能的;
---SN全称为sequence number,表示当前发送的packet编号,Link layer使用SN来告知对方这个packet是新数据包还是重传包;
---NESN:next expected sequence number,用来告知对方下一个期待的packet的编号;用NESN来告诉对方之前发送的包已经收到了(相当于ACK的作用),现在期待下一个新的数据包;
3) MD:
---1bit。more data,用来指示对方还有数据包要传,请继续打开射频窗口准备接收;
---比如BLE模组的一个connection interval可以发多个包(即一个connection event包含多个数据包交互),用的就是MD来实现的;
---以notify命令为例,设备(Server)notify第一个数据包并将MD置1,Client(比如手机)收到这个notify命令后,就知道Server还有数据包要传,此时手机可以继续发一个空包给设备,以让设备把第二个notify命令发过来,详情如下所示。注:Master为手机(Client),Slave为设备(Server)。
2.数据分类:
由LLID定义,payload又可分为:
1) 数据报文:
---当LLID为01或10时,为L2CAP层数据包:
---当LLID为01,且长度字段设置为0时,为空PDU;
---当LLID为01,且长度字段不为0时,该数据包为L2CAP层数据包的延续包,延续包后续没有L2CAP层的长度和L2CAP层的channel ID,但这种情况只有当MTU的值大于data length时才会出现这样的包;
---当LLID为10时,该数据包为L2CAP层数据包的起始包,起始包后续会有L2CAP层的长度和L2CAP层的channel ID;
2)控制报文:当LLID为11时;控制报文用来控制连接链路的,数据格式如下:
---控制报文中的 CtrData 字段由操作码字段指定。 对于给定的操作码,CtrData 字段的长度是固定的。
---具体操作码类型OpCode共有14种,定义如下图:
(1) LL_CONNECTION_UPDATE_REQ (OPCODE=0x00):
连接参数更新请求,这个请求包的格式如下:
---WinSize: 传输窗口大小;
---WinOffset: 传输窗口偏移时间;
---Interval: 链接时间间隔;
---Latency: 从机潜伏次数;
---Timeout: 监管超时时间
---Instant: 更新参数的生效时间(以连接事件的次数为单位)。
在连接更新参数时,并不是请求发过去参数就立刻使用,而是等一定的周期后才会有效,当连接事件的次数等于Instant时新的连接参数才会开始使用。
(2) LL_CHANNEL_MAP_REQ:当前信道图状态查询
(3) LL_TERMINATE_IND:终止连接
(4) LL_ENC_REQ:加密请求
(5) LL_ENC_RSP:加密应答
(6) 其它
共14个opcode类型,每种不同类型对应的ctrlData;
3.数据包实例:
AAAB5D65501E08040004001B130053D550F6
---AA:前导帧(preamble)
---0x50655DAB:访问地址(access address),随机分配;
---1E:LL帧头字段(LL header)
---08:有效数据包长度(payload length)
---04000400: ATT数据长度,以及L2CAP通道编号
---1B:notify command
---0x0013:应用数据handle
---0x53:真正要发送的应用数据
---0xF650D5: CRC24值
六、L2CAP、GATT、ATT、GAP、SMP格式
HCI、L2CAP和ATT协议框架如下:
1.L2CAP:
组成:
1)Data Header: LL链路层数据包头定义。具体见上面的LLID定义;
2)Playload Length:
---BT4.0/4.1定义如上所示,使用5 bits表示长度,即蓝牙4.0/4.1一个包只能传20个字节的根源;
---BT4.2之后,Payload length 使用8 bits表示长度,因此payload size最大可达251字节(255 – MIC size);
---BLE连接建立之后,可以动态更改data length长度(默认为27字节),这个特性叫做Data Length Extension(DLE),DLE是通过Link layer命令:LL_LENGTH_REQ和LL_LENGTH_RSP来实现的,因为Data length直接跟蓝牙芯片的射频能力相关,无法修改;
3)L2CAP Length: Information payload的字节长度,占两个字节;
BLE最大传输单元(MTU:Maximum transmission unit)为23Bytes,超过23Bytes的部分在LL层MD标志中会更新,Information payload信息存放在L2CAP上层ATT数据中。
4)L2CAP CID: 通道ID(channel ID),占两个字节;该字段用于解决上层协议复用同一个链路的问题。通过CID作为标识位来区分payload部分内容类型,方便设备进行处理;
a. L2CAP层的数据,根据channel ID不同,又分为多种不同的L2CAP指令,CID长16bit,每一个CID和对应的Payload类型如下:
---0x0000:保留;
--- 0x0004:对应ATT层数据的类型;简称为B帧;
---0x0005:对应L2CAP层的信令数据;L2CAP协议使用信令来控制两个设备之间L2CAP层的连接建立,配置更新等功能,以及拒绝错误操作码等操作;简称为C帧;
---0x0006:对应SMP层类型的数据;主要用于配置过程中的安全管理;
---0x0020-0x003E:对于LE,该部分为SIG预留,用户不可使用;
---0x0040-0x007F:动态分配通道ID;当两端协商好配置信息之后,会动态分配0x0040之后的信道, 用于上层的数据传输;
b. 在BLE中L2CAP有3条固定的道路---信道。
---控制器传上来的数据中都会有一个信道标识符,L2CAP根据这个信道标识符决定将传上来的数据分配到哪个上层应用来进行数据处理。
---上层的数据向下传输时也要告诉L2CAP数据包是属性协议还是低功耗信令信道还是安全管理协议,L2CAP加上信道标识符之后向下传输,控制层收到数据之后,会根据信道标识符来对不同的数据进行解析。
5)Information payload:信息载荷
a. 当CID为0x0004时,信息放的就是L2CAP上层ATT的数据包; (下面详解)
b. 当CID为0x0005,为信令指令;主要用于更新连接间隔的指令,和拒绝错误操作码码;
支持的PDU命令只有三个:
---0x01: Command reject: 回复未知命令时使用;
---0x12:Connection parameter update request,更新连接参数,比如最小连接间隔,最大连接间隔,slave latency等;
---0x13:Connection parameter update response,接受或者拒绝上面的请求;
c. 当CID为0x0006时,为SMP指令;SMP其作用主要是用来配对和Key的分发,然后用Key对链路或数据进行加密 (下面详解)
所以,L2CAP主要功能:
1)协议信道复用;
2)分段与重组;
3)每个信道流控;
4)差错控制;
2.ATT:
属性协议(Attribute Protocol)简称ATT。是应用层使用的一种数据交互协议, 它是GATT和GAP的基础。 具体分以下几个部分:
1) Opcode:
(1) Opcode PDU: 代替某种命令,不同的命令对应的Attribute Parameters格式内容不同,bit 0-5位表示;
(2) Command: 表示PDU Type 是否是命令(Command ),bit 6表示;
(3) Authentication Signature: 认证标识位.bit 7表示;
0:Information Payload不含有Authentication Signature内容;
1:Information Payload含有Authentication Signature内容;
2) Attribute Parameters:
(1) Attribute handle:
Attribute句柄,16-bit长度。Client要访问Server的Attribute,都是通过这个 句柄来访问,也就是说ATT PUD一般都包含handle的值。属性句柄值的范围:0x0001~0xFFFF, 在应用层添加service和characteristic时系统会自动按照顺序的 为相关attribute生成句柄;
(2) Attribute Type:
a. 作用:
2字节或者16字节长。作用是用以区分当前属性是服务项或是特征值等,它用UUID来表示。
b. UUID定义:
在BLE中我们使用UUID来定义数据的类型,UUID是128bit的。其中有一个UUID非常特殊,他被蓝牙联盟官方使用,这个UUID如下所示:
由于这个UUID众所周知, 所以可以将自己定义的attribute或者数据只用16bit UUID来表示,比如0x1234 (16bit数据), 完整表示为:
所以此字段会有两种长度,2字节或16字节;
C. 取值范围:
0x1800 – 0x26FF :服务项类型
0x2700 – 0x27FF :单位
0x2800 – 0x28FF :属性类型
0x2900 – 0x29FF :描述符类型
0x2A00 – 0x7FFF :特征值类型
假如UUID=0x1800,就表示它是一个主服务项(primary service)。
(3) Attribute Value: 就是数据真实的值,0到512字节长;
(4) Attribute Permissions:Attribute的权限属性,权限属性不会 直接 在 空口包中体现,在隐含 在ATT命令的操作结果中。目前主要有如下几种权限属性:
---访问权限(Access Permission):只读、只写、读写
---禁止访问权限( No Access ):禁止读或者写
---加密权限(Encryption Permission):加密、不加密
---认证权限(Authentication Permission):需要认证、无需认证
---授权权限(Authorization Permission): 需要授权、无需授权
---签名权限(Signed Permission):签名后才能读或者写,这个用得比较少
---访问(Access):如果是只读权限,就不能对其写数据,其他类似;
---加密(Encryption):就是对数据进行加密。
---认证(Authentication):指相互确认对方身份。完成认证流程的两个设备,双方建立信任关系,二者之间的通信通道即可以认为是安全的。BLE中,“认证”过程就是配对。
---授权(Authorization):是指对授信设备开放权利。
3) Authentication Signature: 身份验证签名 0B/12B, 由Opcode中的签名标志位来决定是否有;
4) 以下为一些常用的数据通信交互方式(在opcode中指定):
包括6大类: 命令、请求、响应、确认、通知(notify)和 指示(indicate)
---命令,客户端发送给服务端,不要求服务端回复
---请求,客户端发送给服务端,要求服务端回复
---响应,客户端发送了一个请求,服务端用此响应
---通知,服务端发给客户端的数据,不要求客户端回复
---指示,服务端发给客户端的数据,要求客户端回复
---确认,服务端发给客户端的数据,客户端用此进行回复
5) 数据包实例:
AAAB5D65501E08040004001B130053D550F6
---AA:前导帧(preamble)
---0x50655DAB:访问地址(access address),随机分配;
---1E:LL帧头字段(LL header)
---08:有效数据包长度(payload length)
---04000400: ATT数据长度,以及L2CAP通道编号
---1B:notify command
---0x0013:应用数据handle
---0x53:真正要发送的应用数据
---0xF650D5: CRC24值
3.GATT协议格式:
GATT 是在ATT基础上的封装的最上层的Profile, 主要定义了一些与具体服务和应用相关的数据结构;主要分为4个层次:
---根节点为Profile(配置)
---Profile有不同的Services(服务)
---不同的服务Services有不同的Characteristics(特征)
---不同的特征通过一个具体的Value(值)或者Descriptor(描述符)来定义
(1) Services:
---类型:
服务有两种类型,primary service 和secondary service:
primary service可以被其他service 所包含,可以通过discover 流程发现;
secondary service只能被primary service 或者其他secondary service 所包含,不能独立存在。一个服务的类型,会在申明中注明。
---构成:
服务申明:每个定义的service第一条就是服务申明, 因此以服务申明可以分隔开所有不同的服务。
服务声明的数据结构: ATT类型(仅有两种)+ ATT value(服务的具体类型,比如电量服务,GAP服务等等)
服务声明为read only,不可以被修改,有server 端在自定义数据表格的时候确定。 格式如下:
(2) Include:
include 是解释服务之间的关系,secondary service只能被primary service 或者其他secondary service 所包含,不能独立存在。
include 是service 中可选择的部分,不强制要求必须有这一部分。与服务一个样,include 也是从declaration 开始。格式如下:
(3) Characteristics
特征必须要有申明和值申明,可能含有特征描述申明。
同服务一样,相邻的所有特征都是通过申明ATT 间隔开的。一个特征的结束handle 一 定是下一个特征的申明handle
特征属性详解:
---broadcast: 如果被设置,允许特征值被广播,config descriptor 一定存在;
---read: 如果被设置,可以通过Read ATT相关操作访问特征值;
---write with respondse:如果被设置,可以通过 Write Request 更改特征值;
---Notify:如果被设置,特征值可以通过notify 方式通过server 发送到client,config descriptor 一定存在,控制notify发送开关;
---Indicate:如果被设置,特征值可以通过indicate,从server 发送到client,config descriptor 一定存在,控制indicate 状态开关;
---Authenticated Singend write:如果被设置,仅能通过signed write的方式去更改特征值;
---extended propertyies:如果被设置,表明改特征值必然存在一个extended properities descriptor,属性值配置过长,有一些补充的属性配置在descriptor中;
(4) Descriptor
特征描述是特征的可选项,SIG定义了一些跟特征相关的可用描述,描述有对应的uuid,所有的特征描述紧紧跟着特征值申明之后的ATT handle。
(5) Value
主要包含两个信息:characteristic type(uuid) 和value,此处的uuid 与特征申明中,uuid 一样,都是指特征值的uuid,任何特征都必须包含这一项,这一项可以通过属性定义的方法,被访问或操作。
(6)GATT所有属性类型定义:
总结:
---ATT协议负责管理设备之间的数据存储。它为服务端提供了一种客户端可以进行读写的Attribute数据结构,并为客户端提供了访问、写入和读取数据的机制(访问方法和权限)。
---GATT层定义了一个层次化的数据结构,它有助于理解存储在服务端中数据(GATT Profile)之间的关系。
4.GAP:
GAP负责处理设备的接入方式和过程,包括设备发现,链路建立,链路终止以及实现绑定,以及对安全特性的初始化;
1)对上层提供应用程序接口;对下层的linklayer层(standby state、 advertising state、scanning state、initiating state、connection state)的状态进行了抽象,转化成上层的概念;
2) GAP 协议中定义的四种角色:
---Broadcaster : 在linklayer层可以处于空闲和广播状态,不支持扫描,不支持连接;
---Observer : 在linklayer层可以处于空闲和扫描状态,具备被动扫描能力(主动扫描能力是可选的),被动扫描指的是接收广播不发送scan_req,主动扫描指的是接收广播并发送scan_req,不支持连接,不支持广播;
---Central: 在linklayer层可以处于空闲和扫描和初始化状态,支持扫描,支持连接,连接后在linklayer处于master角色;
---Peripheral: 在linklayer层可以处于空闲和广播状态,不支持扫描,支持连接,连接后在linklayer处于slave角色;
3)Broadcaster 和 Observer 属于广播阶段的概念,即在建立连接之前设备角色。
master 和slave属于建立连接之后的概念,一旦建立连接,Observer 角色变为master,Broadcaster 变为slave;
4)GAP管理的几种数据包格式(具体见上面广播数据格式部分):
---广播包:
广播使用的基本广播包ADV_IND PDU结构包含:
--AdvA:广播地址,即MAC地址
--AdvData:广播数据,0-31长度,格式有相关要求。
---扫描请求包:
基本的扫描请求包SCAN_REQ包含:
--ScanA:扫描设备的MAC地址
--AdvA:广播设备的MAC地址
---扫描响应包:
基本的扫描响应包SCAN_RSP包含:
--AdvA:广播设备的MAC地址;
--ScanRspData:扫描响应数据,0-31字节。格式要求和广播数据意义。
---连接请求包:
1) 连接请求包包含以下内容:
--InitA:主机MAC地址
--AdvA:从机MAC地址
2)LLData:连接建立参数,如下图所示:
其中LLData中的参数包含:
--AA:链路层的访问地址Access Address。即把LL包的AA又复制了一遍过来;
--CRCInit:CRC校验的初始值;
--WinSize:发送窗口的大小;
--WinOffset:发送窗口的偏移;
--Interval:连接间隔;
--Latency:可以跳过的连接事件;
--Timeout:连接超时时间;
--ChM:可用连接数据信道图;
--Hop:跳频算法;
--SCA:休眠时钟精度
---连接参数更新请求包:
5.SMP协议:
1) SMP 概述:
---蓝牙通信过程中,数据加密是非常重要的,ble配对这一步是核心步骤,所以SMP涉及到蓝牙通信的安全;
---SMP数据在固定信道0x0006中传输数据,
---整个-SMP通信过程根据如下6种情况协商确定一种实现流程:
a. 是否支持ble security connection
b. 是否具有设备IO capabilities
c. 是否支持OOB(out of band);
2) SMP命令格式:
如果支持LE security connect , L2CAP MTU = 65; 否则 L2CAP MTU = 23
SMP 交互的命令内容如下:
关于SMP中涉及到的配对流程,比较复杂,仍在学习理解中,后续补充......
标签: #数据封装过程中至顶向下的pdu名字