二、蓝牙核心协议栈:BR/EDR与BLE基础、HCI层、L2CAP层、ATT/GATT协议、配对与绑定流程
好,咱们今天聊点硬核的。蓝牙协议栈,说白了就是蓝牙设备之间沟通的「规矩」。你想想看,耳机要跟手机说话,总得有个统一的语言吧?这个语言就是协议栈。
我个人习惯把蓝牙协议栈分成两大阵营:BR/EDR(经典蓝牙)和BLE(低功耗蓝牙)。很多新手容易搞混,其实它们俩是「同门师兄弟」,但专攻方向完全不同。
2.1 BR/EDR 与 BLE:你该选谁?
BR/EDR,全称 Basic Rate / Enhanced Data Rate。说白了就是咱们以前用的传统蓝牙,比如老款蓝牙耳机、车载免提。它的特点是:速度快、延迟低、功耗高。适合传输连续音频流。
BLE,低功耗蓝牙。这玩意儿是后来为了物联网(IoT)场景设计的。它的特点是:功耗极低、连接快、数据量小。适合传传感器数据、控制指令。
我在项目中遇到过最典型的坑:有人用 BLE 传音频,结果卡成 PPT。嗯,这里要注意——BLE 不适合传实时音频流,那是 BR/EDR 的活。但 BLE 做语音助手唤醒词检测,倒是很合适。
- BR/EDR:3 个音频通道(SCO/eSCO),适合通话、音乐
- BLE:40 个信道(37 个数据 + 3 个广播),适合小数据包
- BR/EDR 配对慢(几秒),BLE 配对快(毫秒级)
2.2 HCI 层:主机与控制器的「翻译官」
HCI,Host Controller Interface。这层是干嘛的?说白了就是把蓝牙芯片(控制器)和操作系统(主机)之间的通信标准化。
你想想看,你的手机 CPU 要告诉蓝牙芯片「给我连那个耳机」,总得有个接口吧?HCI 就是干这个的。它定义了命令、事件、数据包的格式。
我曾经调试过一个 bug:耳机连上手机后,音频断断续续。查了半天,发现是 HCI 层的流控参数没配好。HCI 层有个叫 Flow Control 的机制,如果主机和控制器之间的缓冲区大小不匹配,数据就会丢包。
hcitool 或 btmon 抓 HCI 日志,是排查蓝牙连接问题的第一利器。我习惯先看 HCI_Command_Complete 事件,确认命令是否被正确执行。
2.3 L2CAP 层:数据包的「快递分拣中心」
L2CAP,Logical Link Control and Adaptation Protocol。名字挺长,功能其实很简单:把上层的数据拆成小包,或者把小包拼成大包。
为什么需要这层?因为蓝牙底层的物理传输有最大包长限制(比如 BR/EDR 是 1021 字节,BLE 是 251 字节)。你上层应用要发 10KB 的数据,L2CAP 就得帮你拆成几十个小包发出去,到了对面再拼回来。
L2CAP 还负责多路复用。什么意思?就是同一个蓝牙连接上,可以同时跑音频、传文件、发指令。L2CAP 用 Channel ID (CID) 来区分不同的数据流。
| 协议 | L2CAP 通道 | 用途 |
|---|---|---|
| SDP | CID 0x0001 | 服务发现 |
| RFCOMM | 动态分配 | 串口仿真 |
| ATT | CID 0x0004 | 属性协议(BLE) |
嗯,这里要注意:L2CAP 层有一个 MTU(最大传输单元)协商 的过程。如果两端 MTU 不一致,数据可能被截断。我建议在初始化时主动协商一个较大的 MTU(比如 512 字节),能显著提升传输效率。
2.4 ATT/GATT 协议:BLE 的灵魂
ATT,Attribute Protocol。GATT,Generic Attribute Profile。这两个东西是 BLE 的核心,也是你做语音助手集成时打交道最多的部分。
ATT 定义了「属性」这个概念。每个属性都有一个 UUID、一组权限、一段数据。比如「耳机电量」就是一个属性,UUID 是 0x2A19,数据是 0-100 的数值。
GATT 则是在 ATT 之上定义了「服务」和「特征值」的层级结构。一个服务包含多个特征值,一个特征值包含一个属性值。
举个例子:你的蓝牙耳机里有一个「电池服务」(Battery Service),它包含一个「电池电量特征值」(Battery Level Characteristic)。手机通过 GATT 协议读取这个特征值,就能知道耳机还剩多少电。
- Profile(配置文件)→ 比如 HFP、A2DP
- Service(服务)→ 比如 Battery Service
- Characteristic(特征值)→ 比如 Battery Level
- Descriptor(描述符)→ 比如 Client Characteristic Configuration
我在做语音助手集成时,最常用的 GATT 操作就是 Notify(通知)。当耳机检测到唤醒词时,通过 Notify 把事件推送给手机,比轮询高效得多。
2.5 配对与绑定流程:从陌生人到老朋友
配对(Pairing)和绑定(Bonding)是两回事。配对是临时建立加密连接,绑定是把配对信息存下来,下次自动连接。
BLE 的配对流程分三个阶段:
- 配对特征交换:双方告诉对方自己支持什么加密方式(Just Works、Passkey Entry、Numeric Comparison 等)。
- 认证:根据选定的方式验证身份。比如 Passkey Entry 需要你在手机上输入耳机上显示的 6 位数字。
- 密钥分发:交换加密密钥、身份解析密钥等。这些密钥存下来,就是绑定。
对于语音助手场景,我建议使用 Numeric Comparison 配对方式。它比 Just Works 安全,又比 Passkey Entry 方便。用户只需要确认两边显示的 6 位数字是否一致即可。
2.6 小结:协议栈的「骨架」
好了,咱们把蓝牙核心协议栈捋了一遍。从 BR/EDR 和 BLE 的选择,到 HCI 层的命令交互,再到 L2CAP 的数据分拆,最后到 ATT/GATT 的属性读写,以及配对绑定的安全流程。
说白了,这些就是蓝牙耳机的「骨架」。你理解了这些,后面做语音助手集成时,就知道数据是怎么从麦克风到手机,再从手机到扬声器的。
下一章,咱们会深入 HFP(免提协议)和 A2DP(高级音频分发协议),这两个才是音频传输的「主角」。到时候我会分享一些音频同步和延迟优化的实战经验。
公众号:蓝海资料掘金营,微信deep3321