属性协议(Attribute Protocol)简称ATT。

ATT层定义了属性实体的概念,包括UUID、句柄和属性值等,也规定了属性的读、写、通知等操作方法和细节,这些与属性操作相关的内容称为属性协议。ATT层规定了ATT_MTU值,如果属性值很长,超过了ATT_MTU限制,将使用特殊的读写方法进行操作。

基于ATT层,可以构建出通用属性操作规范。

1. 属性

在蓝牙协议中, 属性是指一个数据实体,它包含标识符,句柄,数据内容,访问权限,安全问题等。

属性协议规定了属性的发现和读写访问的方法。

1.1 类型

属性类型由一个UUID(Universally Unique Identifier)表示。UUID是指从时间尺度和空间尺度都具有唯一性的一串128-bit的数字,该数字串在全球范围内不会重复,并且在未来也不会出现重复。

一个典型的16字节UUID格式为XXXX-XX-XX-XX-XXXXXX。

蓝牙协议设定了一个蓝牙基础UUID: 00000000 – 0000 – 1000 – 8000 – 00805F9B34FB。

利用该基础UUID,可以使用16-bit或32-bit的UUID来代替128-bit的UUID,当传递到对端设备,再还原成128-bit的UUID。

假如16-bit的UUID为YYYY,则还原后的128-bit的UUID为:0000YYYY – 0000 – 1000 – 8000 – 00805F9B34FB。

假如32-bit的UUID为YYYYYYYY,则还原后的128-bit的UUID为:YYYYYYYY – 0000 – 1000 – 8000 – 00805F9B34FB。

ATT层支持使用16-bit和128-bit两种UUID,32-bit的UUID在使用前必须转换成128-bit。

1.2 句柄

属性句柄犹如指向属性实体的指针,对端设备通过句柄来访问该属性。

属性句柄是一个2字节数,有效范围为0x0001-0xFFFF。

属性句柄为有序排列,后面的句柄值会大于前面的句柄,通常下一个属性的句柄值是上一个属性的句柄加1。

1.3 分组

多个属性可以合成一组,一组属性包含的参数为:开始句柄、结束句柄。

1.4 值

属性值可以是一个数字或一个字符串。属性值的长度信息不包含在PDU中,所以需要从PDU的长度间接推算出属性值的长度信息。

属性值通常在一个PDU中发送,如果属性值太长,也可以分成多个PDU进行发送。

1.5 权限

属性的读写权限由ATT层之上的协议层规定,有效的读写权限包括:可读、可写、读写。

在读写属性之前,客户端设备还需要具有足够的安全权限,包括:

  • 加密权限:需要加密、无需加密
  • 认证权限:需要认证、无需认证
  • 授权权限:需要授权、无需授权

如果权限不足,将触发错误处理机制。

1.6 控制点属性

控制点属性是一类特殊属性,它不可读,只能写。

1.7 协议方法

对属性的操作称为协议方法,包括:命令(Command),请求(Request),响应(Response),通知(Notification),指示(Indication)和确认(Confirmation),某些属性PDU还涉及授权签名方法。

1.8 交换MTU Size

ATT_MTU表示ATT层间传输的数据包的最大长度。两端设备可以通过Exchange MTU Request/Response进行交换MTU。

1.9 长包属性

对于读属性的数据包,最大长度为(ATT_MTU-1)个字节。其中减去的1表示1字节的操作码。

对于写属性的数据包,最大长度为(ATT_MTU-3)个字节。其中减去的3表示1字节的操作码和2字节的属性句柄。

如果数据包超过这个长度,则称为长包属性。

读长包属性,需要使用Read Blob Request,写长包属性,需要使用Prepare Write Request和Execute Write Request。

如果使用普通Read操作读长包属性,仅能读取前(ATT_MTU – 1)个字节,使用普通Write操作写长包属性,仅能写前(ATT_MTU-3)个字节。

无论普通属性还是长包属性,属性值的最大长度均为512字节。

1.10 原子操作

一个请求或一个命令,称为一个原子操作。一个原子操作结束后,才能进行新的原子操作。

读写长包属性无法在一个原子操作内完成。

2. 属性PDU

2.1 属性角色

在ATT层协议框架内,拥有一组属性的设备称为服务端(Server),读写该属性值的设备称为客户端(Client)。

2.2 分类

属性PDU有六类:

属性PDU 方向 触发响应
Command Client -> Server
Request Client -> Server Response
Response Server -> Client
Notification Server -> Client
Indication Server -> Client Confirmation
Confirmation Client -> Server

属性PDU格式如下:

字段 Opcode Parameter Authentication Signature
长度 1 octet 0 – (ATT_MTU-X) octets 0 or 12 octets

其中Opcode的第0-5位表示该属性的具体类型,第6位表示命令标志位,如果该位为1,表示该操作码对应一个命令,最后1位表示认证签名(Authentication Signature)标志位,如果该位为1,表示该PDU的最后一个字段中包含12字节的认证签名。

Parameter字段中包含了参数,其长度为0支ATT_MTU-x,如果认证签名位为1,则此处x等于13,否则等于1。

只有写命令才需要认证签名,其他命令不需要。此外,如果链路已经进行加密,则属性PDU中也无需额外添加认证签名。

2.3 操作顺序

对于Request和Indication属性,需要接收端返回响应。在发出Request和Indication后,收到响应之前,不能发出新的Request和Indication。

对于其他无需响应的属性,则可以在自由发送,但是不保证接收端一定能够收到和执行。

可以在Request和Response之间,或Indication和Confirmation之间发送其他无需响应的属性。

2.4 事务

一个Request-Response对,或Indication-Confirmation对,称为一个事务。

对于客户端设备而言,发出Request或收到Indication表示事务的开始,收到Response或返回Confirmation表示事务的结束。

对于服务端设备而言,发出Indication或收到Confirmation表示事务的开始,收到Confirmation或返回Response表示事务的结束。

3. 属性协议PDU

属性协议规定了多种Request-Response对,请求属性由客户端设备发出,响应属性由服务端设备发出。

3.1 错误处理

Opcode PDU
0x01 Error Response

如果属性PDU的操作码无效,或属性句柄无效,将返回错误响应PDU。在PDU的Parameter字段中,包含了错误编码。

3.2 交换MTU

Opcode PDU
0x02 Exchange MTU Request
0x03 Exchange MTU Response

客户端设备向服务端设备发送交换MTU请求,提供客户端设备的MTU值。服务端设备获知客户端的MTU值,并返回自己的MTU值。两端设备都将设置较小的MTU值作为新的MTU值。

如果两端设备没有交换MTU,则使用默认的MTU值(BLE下为23)处理属性事务。

3.3 查找信息

PDU Opcode
0x04 Find Information Request
0x05 Find Information Response
0x06 Find By Type Value Request
0x07 Find By Type Value Response

查找信息请求,包含两个参数:起始属性句柄和结束属性句柄,用于获取服务端设备属性句柄处于该参数区间内的属性。

查找信息响应,包含指定句柄区间内的属性UUID。如果区间内有多个属性,则返回多个响应。

按类型值查找请求,是在查找信息请求的基础上,加上了属性类型和属性值两个参数,这样能够更加精确的找到目标属性。

按类型值查找响应,包含了满足条件的属性句柄列表。

3.4 读属性

Opcode PDU
0x08 Read By Type Request
0x09 Read By Type Response
0x0A Read Request
0x0B Read Response
0x0C Read Blob Request
0x0D Read Blob Response
0x0E Read Multiple Request
0x0F Read Multiple Response
0x10 Read by Group Type Request
0x11 Read by Group Type Response

按类型读请求,包含三个参数:起始属性句柄、结束属性句柄和属性类型。

按类型读响应,包含了满足条件的属性的“句柄-值”对的列表。

读请求,包含一个参数:属性句柄。

读响应,返回满足条件的属性值。

读片段(blob)请求,用于读取一个长包属性的值,它包含两个参数:属性句柄和偏移量。以不同的偏移量作为参数,多次执行该请求可以读取长包属性的完整值。

读片段响应,包含了长包属性值的指定偏移量片段。

读多次请求,用于读取多个给定句柄的属性值,它包含一个参数:句柄列表。

读多次响应,包含了多个指定句柄的属性值。

按组类型读请求,用于读取指定组类型的属性值,组类型是由ATT层之上的协议层设定的。它包含三个参数:起始属性句柄、结束属性句柄和属性组类型。

按组类型读响应,包含了满足条件的属性值列表。

3.5 写属性

Opcode PDU
0x12 Write Request
0x13 Write Response
0x14 Write Command
0x15 Signed Write Command

写请求,将待写数值写入指定的属性值,包含两个参数:属性句柄和数值。

写响应,表示写请求执行成功,不含任何参数。

写命令,将待写数值写入指定的属性值,包含两个参数:属性句柄和数值。它不会触发一个写响应。

签名的写命令,与上面的写命令类似,指示包含了额外的参数:认证签名。典型应用是写控制点属性。

3.6 队列写属性

队列写是指利用一个先进先出的队列,缓存多个属性值的写操作,然后在一个原子操作中完成所有的值写入操作。

队列写专门用于长包属性的写操作,现将一个长数据分成多个部分并记录偏移量,然后通过队列缓存,等数据发送完毕,再按照收到的顺序,一次性将整个长数据写入属性值。

Opcode PDU
0x16 Prepare Write Request
0x17 Prepare Write Response
0x18 Execute Write Request
0x19 Execute Write Response

准备写请求,用于发送一个长数据片段,它包含三个参数:属性句柄、偏移量和待写入数据。

准备写响应,收到准备写请求以后,缓存收到的数据。

执行写请求,对前面缓存的数据执行写操作,它包含一个参数:标志位。如果标志位为1,则执行写操作,如果为0,则取消前面的缓存数据。

执行写响应,根据执行写请求的标志位,执行或取消写操作。

3.7 通知属性

Opcode PDU
0x1B Handle Value Notification
0x1D Handle Value Indication
0x1E Handle Value Confirmation

发送数值通知,它包含两个参数:属性句柄和属性值。它不需要客户端收到后返回响应。

发送数值指示,它包含两个参数:属性句柄和属性值。它需要客户端收到后返回确认。

发送数值确认,它不包含参数,客户端发出该确认消息表示收到了数值指示。

4. 权限

通知和指示与读写操作类似,也可以设置安全权限。

每个属性可以设置单独的权限。

权限不足将阻止操作,并触发错误响应。

权限问题与ATT之上的协议层有较大联系。

(完)

逻辑链路控制与适配协议通常简称为L2CAP(Logical Link Control and Adaptation Protocol),它向上连接应用层,向下连接控制器层,发挥主机与控制器之间的适配器的作用,使上层应用操作无需关心控制器的数据处理细节。

经典蓝牙的L2CAP层比较复杂,它实现了协议复用、数据分段与重组、封装调度等操作,使得主机能够支持LE和BR/EDR不同的控制器,实现音频数据流传输等高级功能。

BLE的L2CAP层是经典蓝牙L2CAP层的简化版本,它在基础模式下,不执行分段和重组,不涉及流程控制和重传机制,仅使用固定信道进行通信,在LE令牌流程控制模式下,实现了流程控制,执行数据分段和重组,使用动态信道进行通信。

1. 功能

完整的L2CAP层的功能模块分解图如下所示:

L2CAP_Feature_Block

L2CAP层包括两个功能模块:资源管理器和信道管理器。

L2CAP层向下连接控制器的HCI接口,向上对应用层暴露数据收发接口。

应用层发送给L2CAP层的数据称为SDU(Service Data Unit),SDU可能是属性协议层的读写数据,也可能是链接配置命令,也可能是配对绑定数据。

SDU在资源管理器中添加L2CAP协议头信息,封装成L2CAP数据包,简称PDU(Protocol Data Unit)。PDU的Payload字段就包含了SDU或SDU的一部分。

通常HCI接口无法发送较长数据包,需要对PDU进行分解(Fragmentation),变成数据碎片(Fragment)再依次发送到控制器。PDU总是包含完整的L2CAP协议头,而数据碎片则不是完整的L2CAP数据包。

如果资源管理器中采用了流程控制或重传机制,则可以实现传输很长的数据包,理论上长度最大可以达到65535个字节。一个很长的SDU,需要先进行分段(Segmentation),分成一个个短小的数据片段,然后再分别添加协议头封装成对应的PDU。

L2CAP协议给出两个数据包长度参数以指导分段和分解操作:MTU和MPS。

MTU(Maximum Transmission Unit)表示L2CAP层的最大可传输单元,该参数限制了应用层与L2CAP层之间传输数据的最大长度,即最大的SDU长度。经典蓝牙默认MTU值为672字节,BLE默认MTU值为23字节,意味着BLE的应用层发送给L2CAP层的数据包长度最大为23字节,超过该长度的数据包将会触发错误处理机制。

MPS(Maximum PDU payload Size)表示L2CAP层PDU的Payload最大长度,该参数限制了单个PDU的长度。分段操作时,每个段的最大长度等于MPS。

显然,L2CAP层中MPS值小于等于MTU值。两个设备建立连接时,会交换MTU和MPS信息,取最小值作为有效值进行工作。

下图为经典蓝牙的分段和分解过程示意图:

L2CAP_Segmentation_and_Fragmentation_Procedure

SDU进入L2CAP层,先进行分段操作,对各PDU再执行分解操作变成数据片段传入HCI层。注意到,分解操作实际上是在HCI层执行。

信道管理器负责将不同协议的数据分派到合适的信道中。

2. 信道ID

信道ID(Channel ID)简称CID,用一个2字节数表示L2CAP层的一个逻辑信道。

逻辑信道与真实信道不同,真实信道是指无线通信的频道,不同信道的频率不同,逻辑信道是指某个协议所占用的通道,不同协议使用不同的信道,它与射频频率无关,所以称为逻辑信道。不同的逻辑信道在控制器中可能使用相同的物理信道。

在不产生混淆的情况下,这里将L2CAP层的逻辑信道简称为信道。

L2CAP层拥有两种信道,固定信道和动态信道。两端设备一旦建立连接,固定信道即可使用而无需额外配置,建立动态信道则需要首先执行配置过程。BLE仅在收发数据时候与对端设备连接,适合使用固定信道。

0x0001-0x003F部分是固定信道,0x0040之后信道是动态信道。

BLE所使用的信道如下:

CID 描述 信道类型
0x0004 属性协议信道 固定信道
0x0005 LE信令信道 固定信道
0x0006 安全管理协议信道 固定信道
0x0020-0x003E 官方编号(Assigned Number)信道 固定信道
0x0040-0x007F 基于令牌连接机制的通信信道 动态信道

0x0004属性协议信道用于收发属性协议层的数据,也就是BLE应用层通信所传输的数据。

0x0005信令(Signaling Command)信道用于处理应用层发送的命令。

0x0006安全管理协议信道用于处理加密、配对和绑定等相关数据。

0x0020-0x003E官方编码信道没有明确指明如何使用。官方编码是指包括UUID、BD_ADDR、Comany_ID等一些列已经授权过的数字串。

0x0040-0x007F令牌连接的通信信道是动态信道,它专用于LE令牌流程控制工作模式。

注意到,广播数据不适用于任何一个L2CAP信道,事实上广播数据将从应用层直接发送到HCI接口。

3. 工作模式

L2CAP层有多种工作模式:

工作模式 适用范围
基础L2CAP模式 Classic, LE
流程控制模式 Classic
重传模式 Classic
增强型重传模式 Classic
数据流模式 Classic
LE令牌流程控制模式 LE

基础模式为默认工作模式,L2CAP层不执行流程控制,对数据不执行分段和重组操作,其他五种模式均使用了流程控制或重传机制,需要执行分段和重组操作。在L2CAP层配置阶段,会设置参数是否使用流程控制和重传机制,如果不使用则使用基础模式,否则按参数配置情况使用其他模式。

不同的工作模式,其数据帧格式略有不同。

3.1 基础模式

L2CAP层基础模式分为面向连接和面向无连接两类子模式,其中面向无连接仅应用于经典蓝牙的一对多通信场景。

面向连接的基础模式的数据帧称为B-Frame(Basic Frame),其PDU格式如下:

L2CAP_Data_Frame

其中前四个字节表示基础L2CAP协议头,后面的信息载荷包字段含应用层发送的数据。

协议头中的长度信息,表示信息载荷的有效长度,它的取值范围为0-65535字节,即信息载荷理论最大长度为65535个字节。

而实际上信息载荷的长度受限于MTU值,当MTU=23,载荷最大长度为23字节,此时PDU总长度为23 + 4 = 27字节。

L2CAP工作在基础模式时,仅使用固定信道进行通信,不对SDU进行分段和重组,应用层传输的数据长度被MTU严格限制,此时MPS等于MTU。

3.2 LE令牌流程控制模式

LE令牌流程控制模式实现了流程控制,以一个令牌参数作为流程控制依据。

LE令牌流程控制模式下的数据帧称为LE-Frame(LE Information Frame),其PDU格式如下:

L2CAP_LE_Credit_Data_Frame

相比于基础模式,该模式增加了一个2字节的L2CAP SDU Length字段。该字段记录了SDU的总长度,在分段过程中,第一个LE-Frame将包含该字段,在后续LE-Frame中不包含该字段。

LE-Frame的载荷长度不能超过MPS值,且MPS值小于等于MTU值。

L2CAP工作在LE令牌流程控制模式时,将使用动态信道,主机使用LE Credit Based Connection Request信令作为连接请求,该信令中包含了一个令牌初值,从机返回LE Credit Based Connection Response信令。

建立连接以后,两端设备每发送一个LE-Frame,令牌值都将被减1。这意味着令牌初值代表该连接能够发送的LE-Frame总数,比如令牌Credit=100,意味着两端设备最多只能发送100个数据帧,超过后将断开连接。

为了发送更多数据帧,设备需要发送LE Flow Control Credit信令以申请一个新的令牌值,新的令牌值包含在该信令参数中。

令牌值的有效范围是0-65535。

LE令牌流程控制模式下的分段与重组与上文介绍的经典蓝牙分段重组操作类似,如下图所示(参考):

L2CAP_Segmentation

建立连接时交换MTU和MPS值,获得有效值MTU=300和MPS=50,此时应用层最大数据包长度必须小于300,假如主机发送210字节数据包,将在L2CAP层被分成5个PDU,第一个PDU中包含L2CAP SDU Length,Payload长度为48,第二至第四个PDU中不包含L2CAP SDU Length,Payload长度为50,第五个PDU中不包含L2CAP SDU Length,Payload长度为12。

4. 信令

信令(Signaling Command)指L2CAP层执行的信号命令。

信令包也属于L2CAP数据包,信令内容含于数据包的信息载荷中,不同的信令将驱动L2CAP执行特定的任务。传输信令包使用信令信道,所以协议头的CID等于0x0005。

信令包的格式如下:

L2CAP_Signaling_Command_Format

编码(Code)字段用于区分不同的信令。

识别码(Identifier)字段用于两端设备收发数据时识别对应的请求与响应,一个请求对应的响应数据应该具有相同的识别啊,不同的请求对应不同的识别码。

BLE设备共支持8个信令,如下:

Code 信令 描述
0x01 Command reject 拒绝一个无效的L2CAP命令,参数中包含了拒绝的原因
0x06 Disconnection request 断开连接请求
0x07 Disconnection response 断开连接响应
0x12 Connection Parameter Update request 更新连接参数请求
0x13 Connection Parameter Update response 更新连接参数响应
0x14 LE Credit Based Connection request LE令牌连接请求,参数中包含了MTU, MPS和PSM(Protocol Service Multiplexer) 参数,其中PSM用于分配动态信道。
0x15 LE Credit Based Connection response LE令牌连接响应
0x16 LE Flow Control Credit 申请新的流程控制令牌

5. 参考

关于LE令牌流程控制模式,参考了以下文章:

http://blog.csdn.net/wendell_gong/article/details/54956499

https://community.nxp.com/thread/366041

https://devzone.nordicsemi.com/question/60552/l2cap-oriented-connection/

(完)

BLE协议栈规定物理层、链路层和DTM层属于控制器,其他协议层属于主机,主机与控制器之间的通信是通过主机控制器接口传输层完成的。

主机控制器接口常简称为HCI(Host Controller Interface)。

HCI定义了一套“命令-事件”机制,主机向控制器发送HCI命令,控制器向主机返回命令执行结果。应用层的所有操作都会转换成HCI命令传给控制器。

1. HCI通信

HCI接口物理形式可以是串口、SPI、USB和三线串口。

对于串口HCI,其通信模型如下:

HCI_UART_Interface

左侧蓝牙主机向右侧蓝牙控制器发送命令,控制器返回命令执行状态。当收到对端设备发送的消息,控制器会以事件形式发送给主机。

通过HCI的数据包括:HCI命令、HCI事件和连接数据。HCI层本身不能区分这三种类型,因此在发送HCI数据包前需要先发送该数据包的类型指示信息。串口HCI的数据包类型指示信息如下:

HCI包类型 指示信息
HCI命令 0x01
连接数据 0x02
HCI事件 0x04

指示信息中缺少0x03,该信息用于经典蓝牙概念。

包类型指示位在HCI包发送前发给给主机或控制器。

2. 连接数据

两个设备建立连接后相互收发数据,从主机将数据发送给控制器,再通过无线发送到对端设备,或控制器接收到对端设备数据后通过HCI发送给主机。连接数据的结构如下所示:

HCI_Data_Packet_Format

  • Handle:连接句柄。
  • FB Flag:数据边界标志(Packet Boundary Flag),表示当前数据包是一个完整数据包的开头片段或中间片段。
  • BC Flag:播报标志(Broadcast Flag),不用于BLE。
  • Data Total Length:数据总长度。
  • Data:有效数据。

3. HCI命令

HCI命令包包括:操作码OpCode、参数总长度和参数个数,如下所示:

HCI_Command_Packet_Format

为了避免控制器的缓冲区溢出,发送命令包时需要应用流程控制。主机向控制器发送一个命令,控制器返回命令执行状态事件,事件中包含参数Num HCI Command Packets,该参数指主机可以发送的最大命令包的数量。

控制器按接收顺序执行主机命令,但后面的命令可能提前执行完毕。

如果命令执行出错,将在控制器的状态事件中包含错误码。

HCI命令非常多,将近300个,BLE仅支持部分命令,所有BLE专属的命令OGF字段都等于0x08。

下面列出BLE支持的最基础的一部分HCI命令:

命令 描述
LE Add Device To White List Command 添加白名单
LE Clear White List Command 清空白名单
LE Read Buffer Size Command 读控制器缓存
LE Read Local Supported Features Command 读本设备支持的功能
LE Read Supported States Command 读本设备支持的状态
LE Read White List Size Command 读白名单空间
LE Remove Device From White List Command 从白名单移除设备
LE Set Event Mask Command 设置事件掩码
LE Test End Command 结束测试
Read BD_ADDR Command 读取设备地址
Reset Command 重启
LE Read Advertising Channel TX Power Command 读取广播发射功率
LE Transmitter Test Command 发送数据测试
LE Set Advertising Data Command 设置广播数据
LE Set Advertising Enable Command 开启广播
LE Set Advertising Parameters Command 设置广播参数
LE Set Random Address Command 设置随机地址
LE Receiver Test Command 接收数据测试
LE Set Scan Enable Command 开启扫描
LE Set Scan Parameters Command 设置扫描参数
Disconnect Command 断开连接

4. HCI事件

HCI事件包包括:时间代码, 参数总长度和具体参数,如下所示:

HCI_Event_Packet_Format

HCI事件包不强制要求流程控制,因为通常主机总是具有充足资源来处理控制器返回的事件。

当连接断开时,主机默认所有命令都已经执行完毕,将不再接收任何事件。

控制器收到不同的主机命令,可能返回以下类型事件:

  • 执行完毕事件
  • 状态信息事件

对于不涉及连接的命令,可以立即得到执行结果,执行完毕事件报告该命令执行成功或失败。

对于涉及连接的命令,无法立即得到执行结果,命令执行完毕后,先返回执行完毕事件,等命令最终结果产生,再返回新的执行完毕事件。比如LE Create Connection Command命令,执行命令时先返回执行完毕,表面链路层开始执行或加入执行队列,待两端设备建立连接,将返回连接完成事件。

部分读命令,比如LE Read Advertising Channel Tx Power Command,执行完毕后将读取结果存放在状态信息事件中返回。

HCI事件包括BLE专有事件和通用事件,通用事件适用于经典蓝牙和BLE。BLE专有事件称为“元事件(LE Meta Event)”,共有20个,它们的事件代码均为0x3E,事件参数的第一个字节为Subevent_code,用以区分不同的元事件。如下:

事件 Subevent_Code 描述
LE Connection Complete Event 0x01 建立连接完毕
LE Advertising Report Event 0x02 检测到广播数据或收到扫描响应数据
LE Connection Update Complete Event 0x03 连接参数更新完毕
LE Read Remote Features Complete Event 0x04 读取对端设备功能完毕
LE Long Term Key Request Event 0x05 控制器向主机发送LTK以加密链接
LE Remote Connection Parameter Request Event 0x06 对端设备发起更新连接参数请求
LE Data Length Change Event 0x07 控制器通知主机链路层数据长度发生了更新
LE Read Local P-256 Public Key Complete Event 0x08 控制器通知主机P-256密钥生成完毕
LE Generate DHKey Complete Event 0x09 控制器通知主机椭圆加密算法密钥生成完毕
LE Enhanced Connection Complete Event 0x0A 建立连接完毕(还支持扩展连接)
LE Directed Advertising Report Event 0x0B 检测到定向广播数据或扫描响应数据
LE PHY Update Complete Event 0x0C 物理层更新完毕
LE Extended Advertising Report Event 0x0D 检测到扩展广播数据或扫描响应数据
LE Periodic Advertising Sync Established Event 0x0E 建立周期广播同步完毕
LE Periodic Advertising Report Event 0x0F 检测到周期广播数据或扫描响应数据
LE Periodic Advertising Sync Lost Event 0x10 周期广播数据无法同步
LE Scan Timeout Event 0x11 扫描超时
LE Advertising Set Terminated Event 0x12 终止广播数据集事件
LE Scan Request Received Event 0x13 收到扫描请求
LE Channel Selection Algorithm Event 0x14 使用了信道选择算法

(完)