二、蓝牙核心协议栈: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 的机制,如果主机和控制器之间的缓冲区大小不匹配,数据就会丢包。

实战小技巧:hcitoolbtmon 抓 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 协议读取这个特征值,就能知道耳机还剩多少电。

GATT 层级结构:
  • Profile(配置文件)→ 比如 HFP、A2DP
  • Service(服务)→ 比如 Battery Service
  • Characteristic(特征值)→ 比如 Battery Level
  • Descriptor(描述符)→ 比如 Client Characteristic Configuration

我在做语音助手集成时,最常用的 GATT 操作就是 Notify(通知)。当耳机检测到唤醒词时,通过 Notify 把事件推送给手机,比轮询高效得多。

2.5 配对与绑定流程:从陌生人到老朋友

配对(Pairing)和绑定(Bonding)是两回事。配对是临时建立加密连接,绑定是把配对信息存下来,下次自动连接

BLE 的配对流程分三个阶段:

  1. 配对特征交换:双方告诉对方自己支持什么加密方式(Just Works、Passkey Entry、Numeric Comparison 等)。
  2. 认证:根据选定的方式验证身份。比如 Passkey Entry 需要你在手机上输入耳机上显示的 6 位数字。
  3. 密钥分发:交换加密密钥、身份解析密钥等。这些密钥存下来,就是绑定。
避坑指南: 我曾经遇到一个耳机,每次重连都要重新配对。查了三天,发现是绑定信息没存到非易失性存储器里。断电后密钥丢失,自然就「不认识」了。记住:绑定信息一定要持久化

对于语音助手场景,我建议使用 Numeric Comparison 配对方式。它比 Just Works 安全,又比 Passkey Entry 方便。用户只需要确认两边显示的 6 位数字是否一致即可。

2.6 小结:协议栈的「骨架」

好了,咱们把蓝牙核心协议栈捋了一遍。从 BR/EDR 和 BLE 的选择,到 HCI 层的命令交互,再到 L2CAP 的数据分拆,最后到 ATT/GATT 的属性读写,以及配对绑定的安全流程。

说白了,这些就是蓝牙耳机的「骨架」。你理解了这些,后面做语音助手集成时,就知道数据是怎么从麦克风到手机,再从手机到扬声器的。

下一章,咱们会深入 HFP(免提协议)和 A2DP(高级音频分发协议),这两个才是音频传输的「主角」。到时候我会分享一些音频同步和延迟优化的实战经验。

课后动手: 用 nRF Connect 或 LightBlue 工具,扫描你身边的 BLE 设备。看看它们的 Service UUID 和 Characteristic,试着理解 GATT 的层级结构。你会发现,所有蓝牙设备都在用同一套「语言」。

公众号:蓝海资料掘金营,微信deep3321