
前言
寄一份文件时,我们负责写清内容,快递负责收件、分拣和运输。对方拿到包裹后,还要拆开文件,才能知道我们写了什么。包裹送到和内容读懂,是不同的事。
手机通过蓝牙读取温度,也有类似的分工。应用想知道"现在多少度",但它不会自己安排天线什么时候发信号、什么时候等回复。这些工作由设备里的不同部分配合完成。另一台设备收到信号后,也要逐步处理,才能知道对方是在读取温度。
为什么要分这么多部分?因为"要什么数据""按什么格式交换""怎样通过无线电送过去",各自要解决的问题并不相同。认识蓝牙的通信架构,就是看清这些工作由谁负责,以及它们怎样接在一起。
一、应用、主机和控制器分别是什么
通信架构描述的是:一个通信系统由哪些部分组成,各部分负责什么,以及它们如何协作。 蓝牙设备中的工作,可以先从应用、主机和控制器这三部分理解。
通信双方要对消息格式、含义和交互方式有共同约定,这样的约定叫作协议。把相关协议按职责组织起来、共同完成通信的一套实现,就是协议栈。
| 部分 | 主要职责 | 以读取温度为例 |
|---|---|---|
| 应用(Application) | 决定产品要做什么,使用或提供业务数据 | 手机显示温度;温度计采集并提供读数 |
| 主机(Host) | 实现较上层的蓝牙协议和通用规则,组织、处理数据交换 | 把"读取这个值"组织成相应的协议消息,处理对端回复 |
| 控制器(Controller) | 实现较底层的链路控制和无线电收发 | 按通信时序在相应信道上发包、收包 |
这里的"主机"不是特指手机,"控制器"也不是指手机连接的那台外设。 手机内部有自己的主机和控制器,温度计内部同样有对应的功能。它们是同一台设备内部的分工,不是两台设备的名称。
应用决定"想读哪个温度值",主机把这个要求交给相应协议处理,控制器执行底层传输。收到回复时,数据再沿相反方向交回应用。应用不必每读一次温度,就重新实现一遍无线电通信。
这些分工是逻辑上的,并不要求产品里必须有三颗芯片。手机常见的做法是由操作系统承担主机功能,由蓝牙芯片承担控制器功能;小型传感器也可以把应用、主机和控制器集成在一颗芯片中。
集成在一起,表示它们共用某些硬件资源,不表示这些职责变成了同一件事。Bluetooth LE 协议栈
二、控制器怎样把数据送到无线链路上
控制器不是只把数字交给天线。它还需要按蓝牙规则安排收发,才能让两端在合适的时间、使用合适的通信方式配合。
2.1 PHY 负责无线信号怎样表达数据
物理层,简称 PHY,规定与无线电收发相关的规则,例如使用的频率、调制方式以及发射和接收要求。
发送时,数据要转换成无线信号的变化;接收时,再从这些变化中恢复数据。这一层处理的是信号与比特之间的转换,不会自行判断收到的数字代表温度、电量还是声音。
因此,PHY 能成功恢复出一段数据,只说明无线电接收完成了相应工作,还没有说明应用已经理解数据。
2.2 LE 链路层负责按规则收发
链路层,简称 LL,是 Bluetooth LE 控制器中负责链路操作的部分。它规定空中数据包的格式,执行广播、扫描、建立和维持连接等底层过程,也负责相应的差错检查和链路控制。
在普通 LE 连接中,双方要知道何时收发、在哪个信道交换数据,并按规则处理确认和重传。这些操作有严格时序,不能靠手机应用临时决定"现在发一个比特、等一会儿再收下一个"。
可以把应用的要求理解为"我要读取温度",把控制器的工作理解为"按约定把承载这个要求的数据包发出去,并接收对方的包"。控制器负责底层通信,不负责替应用解释业务数据。
经典蓝牙也有控制器,但其内部使用无线电、基带、链路管理等组成部分,不能把 LE 的 LL 原样当成经典蓝牙的全部实现。
三、主机与控制器通过 HCI 怎样交接
HCI 是主机控制器接口,规定同一台设备内,主机和控制器之间怎样交换命令、事件和数据。
如果主机和控制器由不同厂商提供,双方仍需要一种共同的接口,才能知道"开始扫描"该怎样表达、扫描结果又该怎样交回来。HCI 就定义了这样的交接规则。
| 交接内容 | 常见方向 | 作用举例 |
|---|---|---|
| 命令(Command) | 主机 → 控制器 | 设置扫描参数、启用扫描 |
| 事件(Event) | 控制器 → 主机 | 报告命令执行情况、发现设备或连接状态变化 |
| 数据(Data) | 两个方向 | 传递由上层协议组织的待发送数据,或交回收到的数据 |
假设应用开始搜索附近的 LE 设备。主机可以通过 HCI 配置并启动扫描,控制器接收周围的广播,再通过相应事件把结果交给主机,最后由平台通知应用。
这里有一个容易混淆的地方:启动扫描的命令被成功执行,不代表已经发现了某台设备。"开始做一件事"与"这件事得到了目标结果",要分别判断。 连接也一样,不能只看本机是否接受了连接请求,就认定远端已经连接成功。
HCI 是逻辑接口,不是某一根固定的线。主机和控制器分开实现时,可以通过 UART、USB 等承载 HCI 通信;集成实现也不要求在芯片外接出一条 HCI 线。
更要分清:HCI 连接的是本机的主机与控制器,不是手机与远端温度计。 两台设备之间走的是蓝牙无线链路。也不是每个应用 API 调用都与一条 HCI 命令一一对应,平台可能需要组合多个操作。主机控制器接口
四、主机中的协议怎样配合
寄件时,分拣人员要能读懂地址,收件人要能读懂文件。它们使用的规则并不相同。蓝牙也不会让每一个部分都处理同样的内容:有的规则负责接入,有的负责数据组织,有的负责安全。
4.1 GAP 管接入,SMP 参与安全过程
GAP 是通用访问配置文件,规定设备发现、建立连接、角色和相关安全要求等通用规则。设备怎样进入可被发现或可连接的状态,就与 GAP 有关。
这里的"配置文件"来自英文 Profile,指一套共同遵守的使用规则,不是存放在磁盘上的某个文件。
GAP 定义规则,并不表示所有动作都由主机独自执行。例如,主机按 GAP 的要求配置扫描,实际在无线电上收发广播包的工作仍由控制器中的链路层执行。规定"应该怎样做",与执行底层收发,是两个层面的职责。
SMP 是安全管理协议,参与 LE 的配对、密钥分发等安全过程。需要保护数据时,两端要按安全规则建立相应的密钥关系,控制器再按要求执行链路加密等操作。
所以,"已经连接"与"可以读取受保护的数据"不是同一个结论。有的读取操作会因安全条件不足而被拒绝;也有公开数据不要求先配对。不能把配对机械地插进每一次读取之前。
4.2 GATT 组织数据,ATT 规定怎样操作它
GATT 是通用属性配置文件,定义服务、特征值、描述符等数据组织方式,以及发现、读取、写入这些数据的过程。
例如,一台传感器可能同时提供测量值和电池信息。GATT 用"服务"把相关功能归在一起,用"特征"描述具体的数据项。特征中包含实际的值,也包含是否支持读取、写入等信息;"描述符"则补充某些特征的说明或配置。日常所说的"读取特征值",就是读取其中实际保存的数据。
这使应用能够先找到需要的功能,再找到其中具体的数据项,而不是面对一段完全没有组织的字节。但"这个数据项允许读取",仍不等于应用已经知道它的单位和数值格式。
ATT 是属性协议。它把数据表示为可被寻址的属性,并规定读取请求、读取响应、写入、通知等消息怎样交换。属性可以先理解为:有编号和类型、能够按规则访问的数据项。用于定位某个属性的编号称为句柄(Handle),读取请求通过句柄指明要读取哪一项;UUID 则用来说明这项数据属于什么类型。句柄回答"是哪一项",UUID 帮助回答"它是什么",GATT 的服务和特征等结构建立在这些属性之上。
GATT 描述数据如何组织、怎样使用,ATT 提供操作这些属性的协议消息。 例如,应用读取某个特征值,主机按 GATT 过程找到相应属性,再使用 ATT 的读取消息与对端交互。两者有关联,却不是两个互相替代的名字。
在一次常见的读取中,发起读取的一方叫 GATT 客户端,提供数据的一方叫 GATT 服务器。这是访问数据时的角色,不是"主机、控制器"的另一种叫法。两端无论承担哪种角色,内部都有各自的主机和控制器。
4.3 L2CAP 把不同协议的数据交给正确的处理者
L2CAP 是逻辑链路控制与适配协议。它在主机中提供逻辑信道,让 ATT、SMP 等不同协议能够共用底层链路,并把收到的数据交给相应协议处理。
这类似快递分拣:同一辆车可以运送不同收件人的包裹,到了目的地还要按地址分开。L2CAP 的逻辑信道帮助区分数据应该交给谁,不必为每一种上层协议单独建立一套无线电收发设备。
当上下层能够处理的数据大小不一致时,L2CAP 还承担相应的数据适配工作;不同模式下的具体能力有所不同。发送端可能需要把较大的上层数据分段,接收端再重组;如果发送得太快,接收方来不及处理,流控还会限制发送节奏,避免缓存被塞满。不能把"底层分成几个包"直接当成"应用就会收到几次完整业务消息"。
这里的逻辑信道不是无线电信道。无线电信道涉及在哪个频率位置收发;L2CAP 信道涉及同一条通信链路上的数据交给哪个上层处理者。两个概念都叫"信道",解决的问题不同。L2CAP
五、一次温度读取怎样经过两端设备
假设手机与温度计已经建立 LE 连接,应用也已找到允许读取的温度特征值。手机作为 GATT 客户端,温度计作为 GATT 服务器。

图中省略了发现服务、安全协商和部分内部细节,只表示这次读取的主要传递关系:
- 手机应用发起读取,指定要访问的数据项。
- 手机主机按 GATT 过程处理,组织 ATT 读取请求,由 L2CAP 承载,再通过本机 HCI 交给控制器。在采用 HCI 的实现中,相关协议数据通过 HCI 数据包交接。
- 手机控制器按链路规则发送;温度计控制器从无线信号中恢复数据,再把它交给温度计主机。
- 温度计主机把请求交给相应协议,检查目标属性是否存在、是否允许当前访问,并按实现取得其值。值可以已经保存在设备中,也可以由应用逻辑提供。
- 成功时,温度计主机组织读取响应,经 L2CAP、HCI 和本机控制器发回。找不到属性或权限不满足时,也可能返回错误,不能把所有回复都当成温度。
- 手机控制器接收,主机逐步处理响应,再由平台 API 把结果交给手机应用。
- 应用按双方约定解析数值、单位,最终显示温度。
假设某个自定义温度特征约定:"用两个字节保存有符号整数,低位字节在前,数值单位为 0.1℃。"收到字节 EB 00,按这个约定还原为十进制 235,显示结果就是 23.5℃。
如果应用错当成 1℃ 一个单位,就会显示 235℃;如果对字节顺序理解错了,得到的数字也会不同。无线链路可能完全正常,错误发生在数据解释上。这个格式是教学示例,不是所有蓝牙温度数据的统一格式。
这个过程还有两层"送到"需要区别:链路层确认收到数据包,不等于 ATT 读取一定成功;读取响应成功,也不等于界面已经正确显示。底层传输成功、协议操作成功、业务结果正确,需要分别确认。
协议消息向下交接时,各层会加入或使用本层需要的控制信息;接收端再逐层处理。这个过程通常称为封装和解封装,但实际还会有分段等处理,并不是"一次读取固定对应一个空中数据包"。
也不是所有 LE 数据都走这条路。应用可以把数据放进广播,接收方扫描后解析,这条路径不要求经过 GATT、ATT 或 L2CAP;LE 音频还有等时数据通路。图里画的是通过连接完成的一次 GATT 读取,不能拿它概括全部蓝牙通信。
六、为什么还需要 Profile 和 Service 规范
架构和协议解决了数据怎样交换,但产品之间还需要约定:提供什么功能、有哪些角色、使用哪些数据,以及遇到某种情况时怎样响应。
Profile,通常译为"配置文件",是一套针对某类功能的共同使用规则,不是产品目录里的配置文件。 它规定相关设备承担的角色,以及应如何组合使用蓝牙的协议和过程。
例如,找钥匙的设备可以使用 Find Me Profile。手机或手表充当寻找者,钥匙扣充当被寻找的一方;寻找者按规则操作钥匙扣提供的 Immediate Alert Service,让它发出提醒。
其中,Service 规范关注某一项服务里有哪些数据、这些数据如何表示,以及服务端应怎样响应;Profile 规范则把相关角色和使用行为联系起来。知道某个值能写入,还要知道"写什么值、代表什么动作",双方才能配合完成寻找钥匙的功能。
GAP、GATT 的名字里也有 Profile,它们属于核心规范中的通用规则;找钥匙、心率等具体功能则有各自的规范。不能把所有 Profile 都理解成图中最上方一个独立的软件层。Profile 与 Service 规范
产品也可以定义自己的 GATT 服务和数据格式,但这时双方应用必须另行约定数据项的标识、含义、编码方式和交互行为。自定义并不表示没有规则,而是这些规则需要由产品设计者提供。
因此,一台手机"支持 GATT",不代表它已经理解任何厂商的自定义设备。它可能能发现服务、读取字节,但仍需要相应应用,才能把这些字节变成正确的功能。
七、经典蓝牙与 LE 共用思路,协议通路并不完全相同
应用、主机、控制器的分工,以及 HCI 这样的内部交接方式,也适用于理解经典蓝牙。但具体功能使用哪些协议,要看双方采用的技术和 Profile。
| 对比位置 | 经典蓝牙 BR/EDR | Bluetooth LE |
|---|---|---|
| 控制器 | 无线电、基带、链路管理等 | PHY、链路层等 |
| 常见功能发现 | 通过 SDP 查询对端提供的服务 | GATT 应用通过 GATT 过程发现服务 |
| 常见上层用途 | A2DP 音频、RFCOMM 串口式数据通道等 | GATT 数据访问、广播、LE Audio 等 |
SDP 是服务发现协议,它帮助查询对端支持什么服务,并不负责把该服务的业务数据全部传过来。发现了音频服务,后续播放音乐仍要使用相应的音频协议和规则。
A2DP 是高级音频分发配置文件,常用于经典蓝牙音乐播放。RFCOMM 提供串口式的数据通道,但它不表示所有蓝牙功能都像串口一样读写。
这些是常见通路,不是互斥的能力清单。GATT 也可以运行在 BR/EDR 上;LE 音频也不等于不断用 GATT 读取声音。双模设备可以同时具备经典蓝牙和 LE 的能力,但不会因此自动支持所有上层功能。
判断两台设备能否配合,应确认共同的技术、协议和功能规则,而不只看是否都有蓝牙图标。蓝牙核心架构
八、用架构判断问题停在哪一步
架构的用处不只是认全缩写,还能把"蓝牙不工作"拆成具体的问题。
- 应用根本没有收到扫描结果:先检查扫描是否真正启动、设备是否在发送相应广播,以及平台权限、过滤条件等。此时还不能直接归因于 GATT。
- 已经连接,读取却被拒绝:检查目标数据项、读权限和安全条件,而不是反复增加发射功率。
- 已读到字节,数值却不对:核对数据项是否选对,以及编码、字节顺序、单位和缩放关系。数据送到,不代表解释正确。
- 本机日志显示 HCI 命令执行成功:继续确认后续事件或协议结果,不能把它当成整个业务操作成功的证明。
这些判断给出的是排查方向,不是只凭一条现象就断定某层损坏。先保留成功和失败的具体证据,再沿着调用与数据传递关系缩小范围,才容易找到真正原因。
九、总结
蓝牙通信由多个部分共同完成:应用决定业务目标,主机处理较上层的协议和通用规则,控制器执行底层链路操作与无线电收发。HCI 定义本机主机与控制器之间的交接,不能与两台设备之间的无线链路混淆。
在常见 LE 数据访问中,GAP 规定接入等通用规则,GATT 组织数据和访问过程,ATT 交换属性操作消息,L2CAP 让不同协议共用底层链路,SMP 参与安全过程。它们各有职责,不是每份数据都要依次经过所有协议。
把数据传过去,还需要双方使用相同的功能与数据规则,应用才能真正用起来。 Profile、Service 规范和产品自定义约定,共同补齐了从"收到字节"到"完成具体功能"的关系。排查问题时,也要分清底层传输、协议操作和业务解释分别是否成功。
十、测试题
- 手机连接一台温度计,能否把手机直接称为 Host、温度计直接称为 Controller?请说明这两个词实际描述什么。
- 一个传感器只有一颗芯片,是否意味着它没有主机和控制器的分工?HCI 是否一定是一根接到芯片外的线?
- 主机收到"启动扫描命令成功"的反馈,能否认定已经找到了目标设备?还要观察什么?
- GATT 和 ATT 分别负责什么?手机成功读取了一个特征值,为什么仍可能显示错误的温度?
- L2CAP 的逻辑信道与无线电信道有什么区别?多个上层协议为什么能共用一条底层链路?
- 设备把温度放在公开广播中,手机只扫描并解析广播。它是否必须先建立连接,再使用 GATT 读取?为什么?
- 手机和钥匙扣都支持 LE,手机也有 GATT 能力,为什么仍不能只凭这些条件认定手机一定能让钥匙扣响铃?
- 已经连接,但读取受保护的数据时被拒绝。你会优先核对什么?为什么"底层能通信"还不够?