BLE 协议栈:HCI ACL 数据详解
- 前言
- 一、定义
-
- [1、HCI ACL 数据包(ACL Data Packet)](#1、HCI ACL 数据包(ACL Data Packet))
- [二、ACL 数据包结构](#二、ACL 数据包结构)
- [三、Handle and Flags 格式](#三、Handle and Flags 格式)
- [四、Packet Boundary Flag(PBF,包边界标志)](#四、Packet Boundary Flag(PBF,包边界标志))
-
- 1、包边界标志定义
- [2、PBF 状态机](#2、PBF 状态机)
- [3、PBF 使用规则](#3、PBF 使用规则)
- [五、Broadcast Flag(BC,广播标志)](#五、Broadcast Flag(BC,广播标志))
- 六、数据分片
- [七、ACL 数据包传输](#七、ACL 数据包传输)
- 八、主机到控制器流控
- 九、缓冲区管理
- [十、L2CAP 的关系](#十、L2CAP 的关系)
-
- [1、L2CAP PDU 分片示例](#1、L2CAP PDU 分片示例)
- 2、重组过程
前言
在蓝牙技术中,ACL(Asynchronous Connection-Less,异步无连接)数据包则是 HCI 层传输数据的核心载体,承担着 L2CAP 协议数据转发、多模式传输等关键职责。
一、定义
1、HCI ACL 数据包(ACL Data Packet)
核心职责:
-
在 ACL 连接上实现数据的双向传输,是蓝牙非实时数据(如文件传输、消息推送)的主要传输载体;
-
作为 L2CAP(逻辑链路控制和适配协议)与链路层(LL)之间的桥梁,转发 L2CAP 协议数据单元(PDU);
-
支持两种传输模式:可靠传输(基于 ARQ 确认机制)和不可靠传输(无需确认,适用于对实时性要求高、可容忍少量丢包的场景);
-
自动实现大数据包的分片与重组,解决链路层 MTU(最大传输单元)限制问题,保障数据完整性。
二、ACL 数据包结构
HCI ACL 数据包采用固定的三段式结构:句柄和标志(Handle and Flags)、数据总长度(Data Total Length)、数据负载(Data),整体结构清晰,便于主机与控制器快速解析和处理。
plain
┌─────────────────────────────────────────────────────────────┐
│ HCI ACL Data Packet(HCI ACL 数据包) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Handle and Flags(句柄和标志) - 2字节 │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Connection Handle(连接句柄) - 12 位 │ │ │
│ │ │ Packet Boundary Flag(包边界标志) - 2 位 │ │ │
│ │ │ Broadcast Flag(广播标志) - 2 位 │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Data Total Length(数据总长度) - 2字节 │ │
│ │ - 长度: 2 字节(16位) │ │
│ │ - 范围: 0x0000 - 0xFFFF(对应0~65535字节) │ │
│ │ - 作用: 标识后续 Data 字段的实际长度,便于解析 │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Data(数据负载) - N字节 │ │
│ │ - 长度: 0~65535 字节(N = Data Total Length值) │ │
│ │ - 内容: 主要为 L2CAP PDU,也可包含其他上层协议数据 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
三、Handle and Flags 格式
Handle and Flags 是 ACL 数据包的"身份标识+控制信号",共 2 字节(16 位),分为 3 个部分:12 位连接句柄、2 位包边界标志、2 位广播标志,各字段紧密配合,保障数据传输的准确性和有序性。
1、Handle and Flags 结构
plain
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ Connection Handle (12 bits) │ PB │ BC │
└───────────────────────────────────────────────────────────────────────────────┘
说明:高位(15~4位)为连接句柄,中位(3~2位)为PB(包边界标志),低位(1~0位)为BC(广播标志)
2、字段定义
| 位字段 | 长度 | 名称 | 范围 | 说明 |
|---|---|---|---|---|
| Connection Handle | 12 位 | 连接句柄 | 0x000 - 0xFFF | 唯一标识一个 ACL 连接,由控制器分配,主机通过该句柄区分不同的 ACL 连接,实现多连接并发传输 |
| PB (Packet Boundary) | 2 位 | 包边界标志 | 0x0 - 0x3 | 标识当前 ACL 数据包在 L2CAP PDU 分片中的位置,用于分片重组,是保障数据有序性的关键 |
| BC (Broadcast) | 2 位 | 广播标志 | 0x0 - 0x3 | 标识数据包的广播类型,主要用于 BR/EDR 蓝牙的多从设备广播场景,LE 蓝牙中多使用点对点模式 |
3、连接句柄
| 句柄范围 | 说明 | 实操注意 |
|---|---|---|
| 0x000 - 0x0EFF | 有效的 ACL 连接句柄 | 主机可通过该范围的句柄发起 ACL 数据传输,超过该范围的句柄会被控制器判定为无效 |
| 0x0F00 - 0x0FFF | 保留 | 该范围句柄为蓝牙规范预留,不可用于实际 ACL 连接,否则会导致数据传输失败 |
四、Packet Boundary Flag(PBF,包边界标志)
PBF 是分片重组的核心控制标志,用于告知控制器当前数据包在 L2CAP PDU 分片中的角色(开始、继续、完整),确保多个分片能够正确重组为完整的 L2CAP PDU,避免数据错乱。
1、包边界标志定义
| 二进制值 | 十六进制值 | 名称 | 说明 |
|---|---|---|---|
| 00 | 0x0 | First Non Flushable | L2CAP 分段的开始(非可刷新),后续分片不可被控制器丢弃,适用于对数据完整性要求高的场景 |
| 01 | 0x1 | Continuing | 继续分段,可作为中间分片或最后一个分片(可刷新),适用于实时性要求高、可容忍少量丢包的场景 |
| 10 | 0x2 | First Flushable | L2CAP 分段的开始(可刷新),后续分片可被控制器根据资源情况丢弃,优先保障实时性 |
| 11 | 0x3 | Complete L2CAP PDU | 完整的 L2CAP PDU,无需分片,单个 ACL 数据包即可承载整个 L2CAP 协议数据单元 |
2、PBF 状态机
完整 L2CAP PDU (PB=11)
接收完成
L2CAP 分段开始 (PB=00)
继续分段 (PB=01)
继续分段 (PB=01)
最后分段 (PB=11)
重组完成
L2CAP 分段开始 (PB=10)
继续分段 (PB=01)
Complete_PDU
First_NonFlushable
Continuing
First_Flushable
3、PBF 使用规则
| 应用场景 | PB 值(二进制) | 说明 | 适用场景 |
|---|---|---|---|
| 完整 L2CAP PDU | 11 | 单个 HCI 包包含完整 PDU,无需分片和重组,传输效率最高 | L2CAP PDU 长度 ≤ 链路层 MTU(如 LE 蓝牙默认27字节) |
| L2CAP 段开始(非刷新) | 00 | 分段开始,后续包不可刷新(不可丢弃),确保所有分片都能被重组 | 文件传输、数据同步等对完整性要求高的场景 |
| 继续分段 | 01 | 中间或最后段,可刷新(可丢弃),优先保障实时性 | 语音辅助数据、实时状态推送等对实时性要求高的场景 |
| L2CAP 段开始(可刷新) | 10 | 分段开始,后续包可刷新,平衡实时性和完整性 | 视频流、实时监控等需要兼顾实时性和数据量的场景 |
五、Broadcast Flag(BC,广播标志)
BC 标志用于标识 ACL 数据包的广播类型,主要应用于 BR/EDR(经典蓝牙)的多从设备连接场景,LE(低功耗蓝牙)中多采用点对点模式,广播功能多由 ADV(广播包)实现。
1、广播标志定义
| 二进制值 | 十六进制值 | 名称 | 说明 |
|---|---|---|---|
| 00 | 0x0 | Point-to-Point | 点对点传输,最常用模式,数据仅在单个主机与单个从机之间传输 |
| 01 | 0x1 | Active Slave Broadcast | 活跃从广播(BR/EDR 专属),主机向所有处于活跃状态的从机广播数据 |
| 10 | 0x2 | Parked Slave Broadcast | 休眠从广播(BR/EDR 专属),主机向所有处于休眠状态的从机广播数据,唤醒休眠设备 |
| 11 | 0x3 | Reserved | 保留,蓝牙规范未定义其用途,不可使用,否则会导致数据传输异常 |
2、广播类型说明
| 类型 | 说明 | 应用场景 | 蓝牙类型适配 |
|---|---|---|---|
| Point-to-Point (00) | 点对点传输,一对一通信,数据私密性高,传输效率稳定 | 手机与蓝牙耳机、智能手表与手机、蓝牙打印机与电脑等常规一对一连接 | LE 蓝牙、BR/EDR 蓝牙均支持,是最常用模式 |
| Active Slave Broadcast (01) | 活跃从广播,一对多通信,仅向活跃状态的从机发送数据 | BR/EDR 蓝牙的多设备组网,如蓝牙音响阵列、多从机数据同步 | 仅支持 BR/EDR 蓝牙,LE 蓝牙不支持 |
| Parked Slave Broadcast (10) | 休眠从广播,一对多通信,唤醒休眠从机并发送数据,功耗较低 | BR/EDR 蓝牙的低功耗多设备场景,如物联网设备休眠唤醒、多传感器数据采集 | 仅支持 BR/EDR 蓝牙,LE 蓝牙通过广告包实现类似功能 |
六、数据分片
由于链路层存在 MTU 限制(如 LE 蓝牙默认 MTU 为27字节,BR/EDR 蓝牙 ACL 最大 MTU 为1024字节),当 L2CAP PDU 长度超过链路层 MTU 时,HCI 主机会自动将其拆分为多个 ACL 数据包(分片),传输至控制器后,由链路层重组为完整的 L2CAP PDU,保障大数据量传输的完整性。
1、分片机制
Link_Layer HCI_Controller HCI_Host L2CAP Link_Layer HCI_Controller HCI_Host L2CAP 重组 L2CAP PDU (Large) Fragmentation HCI ACL (PB=00, Segment 1) HCI ACL (PB=01, Segment 2) HCI ACL (PB=01, Segment N) Packets L2CAP PDU
2、分片大小限制
| 传输层类型 | MTU 限制(字节) | 单分片最大数据长度(字节) | 补充说明 |
|---|---|---|---|
| BR/EDR ACL | 1024 | 1024 | 经典蓝牙 ACL 传输的默认 MTU,可通过协议配置调整 |
| LE ACL | 27(默认) | 23 | LE 蓝牙默认 MTU 为27字节,扣除 4 字节 ACL 头部(Handle+Length),实际数据负载最大23字节 |
| LE ACL(扩展) | 251(2M PHY) | 247 | LE 蓝牙使用 2M PHY 时,可扩展 MTU 至251字节,数据负载最大247字节,传输效率提升明显 |
3、分片参数
| 参数名称 | 说明 | 默认值 | 配置方式 |
|---|---|---|---|
| HCI_ACL_Data_Packet_Length | HCI ACL 数据包最大长度,决定单分片的最大数据负载 | 1024 字节 | 通过 HCI_Host_Buffer_Size 命令配置 |
| HCI_Total_Num_ACL_Data_Packets | 控制器可缓存的 ACL 数据包数量,影响分片传输的并发能力 | 取决于控制器硬件(通常为8~32个) | 通过 Read_Num_ACL_Data_Packets 命令读取,部分控制器支持配置 |
七、ACL 数据包传输
ACL 数据包的传输流程涉及主机、控制器、链路层三个核心组件,从数据发送、验证、转发到确认,形成完整的闭环,确保数据传输的可靠性和有序性,同时支持无效数据包的快速处理。
1、传输流程
LL Controller Host LL Controller Host 检查连接句柄 alt [有效数据包] [无效数据包] HCI ACL Data Packet 验证 PB 标志 传递给链路层 数据排队 发送完成 Number of Completed Packets Event Disconnection Complete Event
八、主机到控制器流控
1、流控机制
| 机制 | 说明 |
|---|---|
| Num_HCI_Command_Packets | 控制器允许的命令包数量 |
| HCI_Num_Completed_Packets | 已完成的 ACL 数据包数量 |
| Host Buffer Config | 主机缓冲区配置 |
2、流控命令
| 命令 | 说明 |
|---|---|
| HCI_Host_Buffer_Size | 设置主机缓冲区大小 |
| HCI_Host_Number_Of_Completed_Packets | 通知控制器处理完成的包 |
3、流控状态机
初始化
发送 ACL 数据
检查缓冲区
缓冲区可用
缓冲区满
发送完成
收到 Num_Completed_Packets
收到 Num_Completed_Packets
Ready
Sending
Checking
Transmitting
Waiting
Complete
九、缓冲区管理
1、缓冲区参数
| 参数 | 主机 | 控制器 |
|---|---|---|
| ACL 数据包长度 | 1024 字节 | 1024 字节 |
| 数据包数量 | 可配置 | 可配置 |
| 总缓冲区大小 | 可配置 | 可配置 |
2、缓冲区读取命令
| 命令 | OGF:OCF | 说明 |
|---|---|---|
| Read_Buffer_Size | 0x04:0x0005 | 读取 ACL 和 SCO 缓冲区大小 |
| Read_Num_ACL_Data_Packets | 0x04:0x0006 | 读取 ACL 数据包数量 |
3、Read_Buffer_Size 响应
| 偏移 | 长度 | 参数 | 说明 |
|---|---|---|---|
| 0 | 2 | HCI_ACL_Data_Packet_Length | ACL 数据包最大长度 |
| 2 | 1 | HCI_SCO_Data_Packet_Length | SCO 数据包最大长度 |
| 3 | 2 | HCI_Total_Num_ACL_Data_Packets | ACL 数据包总数 |
| 5 | 2 | HCI_Total_Num_SCO_Data_Packets | SCO 数据包总数 |
十、L2CAP 的关系
1、L2CAP PDU 分片示例
L2CAP PDU (300 字节)
│
├─ HCI ACL 1: PB=00, Data (27 bytes) - 段开始
├─ HCI ACL 2: PB=01, Data (27 bytes) - 继续
├─ HCI ACL 3: PB=01, Data (27 bytes) - 继续
├─ ...
└─ HCI ACL N: PB=01, Data (19 bytes) - 最后段
2、重组过程
L2CAP PDU 300B
Fragment 1: 27B
Fragment 2: 27B
Fragment 3: 27B
Fragment N: 19B
HCI Host
L2CAP PDU Reassembled