佳木斯市网站建设_网站建设公司_门户网站_seo优化
2026/1/20 8:46:44 网站建设 项目流程

liwen01 2026.01.01

前言

我们现在使用的蓝牙,它不是一蹴而就的,它经历了从电缆替代者(经典蓝牙)到 万物互联基石(低功耗蓝牙)的演变。

要理解 SDPGAPATTGATT 这些类似重叠的协议,需要回到蓝牙技术发展的历史背景和设计哲学。

(一)历史背景

(1)早期无线通信的春秋战国

在蓝牙标准诞生之初,不同厂家对如何发现对方如何加密如何连接有不同的理解。如果没有一个统一的框架,A 厂家的手机可能根本搜不到 B 厂家的耳机。

GAP (Generic Access Profile) 的存在是为了定义通用的行为准则,设计目的有两个:

(A)标准化流程:它规定了所有蓝牙设备必须如何打招呼(广播)、如何交换名片(发现)以及如何建立外交关系(连接)。

(B)解耦:它让上层应用不需要关心底层的物理跳频或链路层状态转换,只需知道自己是中心设备(Central)还是 外围设备(Peripheral)。

(2)解决经典蓝牙业务繁杂问题

image

经典蓝牙(BR/EDR)的设计初衷是取代各种电缆(串口线、打印线、耳机线)。

因此,它承载了非常多的特定协议(Profiles),如 HFP(通话)、A2DP(音乐)、SPP(串口)。

SDP (Service Discovery Protocol) 就是蓝牙世界里的黄页服务,设计目的也有两个:

(A)动态查询: 经典蓝牙设备通常功能复杂,当手机连接音箱时,它不知道这个音箱是否带麦克风(HFP),也不知其音质等级(A2DP)。

(B)按需建立: 通过 SDP,设备可以先查询对方支持哪些服务,获取连接这些服务所需的端口号(如 RFCOMM 通道),然后再建立真正的业务连接,节省了系统资源。

(3)解决BLE极致功耗问题

image

2010年左右,蓝牙 4.0 (BLE) 问世。此时的设计目标变了:不再是传输高带宽的音频,而是传输极小的数据(如温度、心率),且要求一颗纽扣电池能用一年。

经典蓝牙的协议栈(包括 SDP)对于这些小传感器来说太重、太费电了。

为了极致省电,蓝牙设计者提出了 ATT 和 GATT 的组合:

传感器数据通常非常简单(就是一个数值),比如温度湿度传感器。

(A)ATT (Attribute Protocol):极简的搬运工

ATT 弃了复杂的握手,将所有数据简化为属性(Attribute)。它只负责最简单的操作:读、写、通知。它像是一个高效的仓库搬运工,只认货架号(Handle),不问数据背后的逻辑。

但是ATT的属性(Attribute)太底层了,一堆 handle 很难管理,所以就有了GATT 。

(B)GATT (Generic Attribute Profile):逻辑的架构师

GATT 的目的是在 ATT 之上建立了一套层级结构(Service > Characteristic),把 ATT 相关的属性打包。

GATT 是声明式的,它不需要像 SDP 那样进行复杂的动态交互,而是通过简单的属性列表直接告诉对方:我的 0x0012 货架放的是心率数据

(二)GAP(Generic Access Profile)

image

GAP(Generic Access Profile,通用访问配置文件)是蓝牙协议栈中最基础、最重要的配置文件之一。

可以把它看做是蓝牙设备的身份证外交官。它定义了设备如何互相发现、建立连接以及确保基本的互操作性。

(1)GAP 的核心作用

为确保不同厂商的设备能够互相发现并建立连接,GAP 的核心作用有4个:

(A)模式与过程 (Modes and Procedures): 设备如何被发现(广播)以及如何发现别人(扫描)。

(B)角色 (Roles): 定义设备在蓝牙网络中的身份(如手机是 Central,手环是 Peripheral)。

(C)安全 (Security): 定义安全级别和配对模式的基础。

(D)数据格式 (Data Formats): 定义广播数据和扫描响应数据的通用格式。

(2)GAP 四大核心角色(Roles)

在连接建立之前,GAP 首先定义了设备在链路层表现出的身份。这决定了谁负责发信号,谁负责找信号。

在低功耗蓝牙 (BLE) 中,GAP 定义了四种特定的角色。这些角色决定了链路层 (Link Layer) 的状态。

(A)Broadcaster(广播者): 仅发送广播数据,不支持建立连接,比如:温度传感器、Beacon。此时链路层处于 Advertising State 状态。

(B)Observer(观察者): 仅扫描广播数据,不支持发起连接,比如:仅用于数据采集的网关,此时链路层处于 Scanning State 状态。

(C)Peripheral(外设): 发送广播,支持被连接。通常是数据提供方,通常是性能受限、对功耗敏感的设备,比如:智能手环、心率带、智能锁。

此时链路层处于Advertising / Connection (Slave) 状态

(D)Central(中心设备): 扫描广播,发起连接。通常是控制方和数据处理方,一般拥有更强处理能力和电量的设备,比如:智能手机、平板电脑。

此时链路层处于Scanning / Connection (Master) 状态

注意: 一个设备可以在不同时间切换不同角色,甚至在 V5.x 中通过多重连接拓扑同时扮演不同角色。

(3)GAP 的操作模式、过程、连接参数

(A)发现模式 (Discoverability Modes) :有三种发现模式:

不可被发现模式 (Non-Discoverable Mode): 设备不发送广播,或者发送的广播不支持被发现(仅用于维持现有连接或广播特定非发现数据)。

有限可发现模式 (Limited Discoverable Mode): 设备在短时间内(通常有超时限制)可被发现。常用于按下按钮后的配对状态。

一般可发现模式 (General Discoverable Mode): 设备在很长一段时间内都可以被发现。这是大多数消费电子产品的默认状态。

(B)连接模式 (Connectability Modes) 有三种:

不可连接 (Non-Connectable): 仅广播数据,拒绝连接请求。

定向可连接 (Directed Connectable): 仅接受来自特定(已绑定)设备的连接请求,用于快速重连。

无向可连接 (Undirected Connectable): 接受任何设备的连接请求。

(C)发现过程 (Discovery Procedures)

作为中心设备(Central)或观察者(Observer),GAP 定义了如何去发现周围设备:

有限发现过程 (Limited Discovery Procedure): 仅过滤并显示处于有限可发现模式的设备。

一般发现过程 (General Discovery Procedure): 发现所有可发现的设备。

(D)连接参数 (Connection Parameters)

在 GAP 中,定义了中心设备和外围设备建立连接时必须协商的关键参数。这些参数直接影响功耗数据吞吐量

连接间隔 (Connection Interval): 两次通信之间的时间间隔(7.5ms ~ 4.0s)。

间隔越短,速度越快但耗电;间隔越长,越省电。

外围设备延迟 (Peripheral Latency/Slave Latency): 允许外围设备在没有数据发送时跳过连接事件的次数。这对低功耗至关重要。

监督超时 (Supervision Timeout): 如果超过这个时间没有通信,连接被视为断开。

在蓝牙 5.3 引入了 Connection Subrating (连接子速率),虽然这主要是链路层的功能,

但在 GAP 层面,它允许设备在保持低占空比(省电)的同时,能够更快速地切换到高占空比(高性能)模式,而无需完全重新协商连接参数。

(4)GAP 与底层(Link Layer)的协调逻辑

image

在架构图中,GAP 位于 L2CAP 和 Link Layer (LL) 之上。它的管理指令是自上而下下达的:

GAP 发指令: 应用层告诉 GAP 我要连接那台名为 'Apple Watch' 的设备

GAP 调度: GAP 检查当前配置,并命令 Link Layer 进入 Initiating State(发起状态)

LL 执行: Link Layer 在空中监听对方的广播包,并在极短的窗口期内完成握手。

GAP 反馈: 连接成功后,GAP 会通知上层(如 GATT 或应用层):链路已建立,可以开始传输数据了

(5)为什么手环设备能省电

这里我们以蓝牙手环来举例,从手环的初始化、连接、进入静默期、调整 这个周期来看它是如何进行功耗管理的。

初始化: 手环 GAP 设置为 Peripheral,每 1 秒发一次广播。

连接: 手机 Central 发现手环,GAP 建立连接,初始连接间隔设为 30ms(为了快速同步数据)。

进入静默期: 数据同步完了,App 进入后台。此时手机 GAP 发起连接参数更新请求

调整: 连接间隔被拉长到 500ms,且设置了 Slave Latency = 10。这意味着手环即使每 500ms 该醒来一次,但如果没数据,它可以连续 10 次,也就是 5 秒钟才跟手机通信一次。

结果就是:这种由 GAP 协调的参数调整,让你的手环续航从 3 天延长到了 20 天。

(三)SDP (Service Discovery Protocol)

image

SDP (Service Discovery Protocol) 是 金典蓝牙(BR/EDR)设备的 黄页电话簿

在两个金典蓝牙设备建立连接后,必须通过 SDP 来查询对方:你到底支持哪些功能?怎么连接这些功能?

(1)SDP 的核心概念与适用范围

SDP 提供了一种机制,允许客户端应用程序发现服务器应用程序提供的服务以及这些服务的属性。

它不定义具体的服务操作(那是各个 Profile 的事),只负责发现。

重要前提: SDP 主要用于 蓝牙经典 (BR/EDR) 技术,虽然 BLE 设备主要用 GATT,但双模设备(Dual Mode,同时支持 Classic 和 BLE)依然必须实现 SDP 栈以支持经典蓝牙部分的功能。

(2)SDP 架构与角色 (Architecture & Roles)

image

SDP 采用简单的 Client-Server (客户端-服务器) 模型:

SDP Server (服务端): 通常是提供服务的设备(如蓝牙音箱),它维护一个服务记录数据库。

SDP Client (客户端): 通常是想要使用服务的设备(如手机),它向服务端发起查询。

常见的查询方式有:

服务搜索 (Service Search): 客户端问:你这里有支持 UUID 为 0x110B(音频接收)的服务吗?

属性获取 (Service Attribute): 客户端问:对于这个音频服务,你的连接通道是多少?

服务浏览 (Service Browsing): 客户端请求查看服务器上所有可公开的服务列表。

(3)SDP 的核心组件、数据模型

SDP 服务器维护的数据库由一系列 Service Records (服务记录) 组成。

(1)Service Record (服务记录)

image

Service Record Handle:  每一个服务(如免提通话串口通信)都对应一条记录,这是 SDP 服务器分配给某一个服务的索引号。

在一台设备(Server)上,每一个服务记录都有一个唯一的句柄,长度为32位,称为 Handle。

分配规则: 范围是 0x00000000 到 0xFFFFFFFF。通常 0x00000000 是保留给 SDP 服务本身的。

(2)Service Attributes (服务属性)

image

每条记录包含多个属性,描述该服务的细节。属性由 Attribute ID 和 Attribute Value 组成。

Attribute ID  (属性 ID): 定义了该属性的含义,由蓝牙 SIG 统一规定,例如:

  • 0x0001:始终代表 ServiceClassIDList(服务类别列表)。
  • 0x0100:始终代表 ServiceName(服务名称)。

客户端通过这个 ID 告诉服务器:请把这个服务的 ServiceName(0x0100) 告诉我。

Attribute Value (属性值) : 这是最具体的数据,它的格式叫 Data Element,可以是一个整数、一个字符串、一个布尔值,甚至是一个嵌套的列表。

(3)UUID (通用唯一标识符)

UUID 这是 SDP 的灵魂,它是一个全球唯一的标签,用来标识这就是 A2DP 音频这就是串口协议

关键点: UUID 通常是作为Attribute Value的一部分出现的。

比如在 ServiceClassIDList 这个属性(ID 为 0x0001)里,它的值通常就是一个 UUID(如 0x110B 代表 A2DP Audio Sink)。

一般16位 UUID(简短版)用于官方标准服务,128位 UUID(完整版)用于厂商自定义服务。

(4)Handle、Attribute ID、Value、UUID 的区别

Handle (32位)找到那个服务记录的钥匙。

Attribute ID (16位):指明你想看记录里的哪一项。

Attribute Value:那一项里存的实际数据。

UUID:存在数据里的标准身份标签

(4)SDP 协议过程 (Protocol Procedures)

SDP 定义了三种主要的 PDU (协议数据单元) 交互模式,运行在 L2CAP 协议之上(通常使用 PSM 0x0001)。

(A)Service Search Transaction (服务搜索)

image

Client 问: 你有支持 UUID 为 0x1101 (Serial Port) 的服务吗?

Server 答: 有,对应的 Service Record Handle 是 0x00010005

用途: 仅获取记录的句柄,不获取具体细节。

(B)Service Attribute Transaction (属性获取)

image

Client 问: 请给我 Handle 为 0x00010005 的所有属性(或者特定属性,如协议列表)。

Server 答: 这是属性列表:ID 0x0001 是...,ID 0x0004 是...

用途: 已知句柄,获取详细信息。

(C)Service Search Attribute Transaction (搜索并获取)

image

Client 问: 查找支持 UUID 0x1101 的服务,并直接把它们的协议列表属性发给我。

Server 答: 找到了,这是数据...

用途: 最高效的方式,一次交互完成搜索和读取,减少空中交互时间。

(四)ATT (Attribute Protocol)

image

ATT (Attribute Protocol) 是蓝牙低功耗 (BLE) 世界的 搬运工。它是 BLE 通信的最底层数据传输协议。

上层的 GATT (Generic Attribute Profile) 几乎所有的操作(读、写、通知)都是通过 ATT 协议定义的 PDU (协议数据单元) 来完成的。

(1)ATT 的核心架构与角色

ATT 定义了两个核心角色,这两个角色完全独立于 GAP 的主机/从机中心/外围角色。

服务器 (Server)::数据持有者,它存储了所有的状态、数据和配置信息(即属性)。它通常是传感器设备(如心率带、温度计)。

注意:在大多数情况下,BLE 外围设备 (Peripheral) 充当 ATT Server,但这并不是强制的。

客户端 (Client):数据请求者,它向服务器发起请求,或者接收服务器推送的数据。通常是手机、网关或平板电脑。

(2)ATT 的属性(数据单元)

ATT 层传输的最小单位就是 Attribute (属性)。服务器本质上就是一个巨大的属性列表(Attribute Table)。每一个属性都由以下四个元素组成:

Attribute Handle:handle 长度16bit,它是属性的地址或索引。客户端通过句柄来找到它要读写的数据。范围:0x0001 ~ 0xFFFF。

Attribute Type :定义这到底是什么数据。使用 UUID 标识(如 0x2800 代表服务声明,0x2A37 代表心率测量值)。

Attribute Value :实际的数据载体。长度可变(0 ~ 512 字节)。

Attribute Permissions:定义谁可以访问该属性(读/写/加密要求)。注意:权限不通过空中传输,仅存在于服务器内部逻辑中。

(3)ATT PDU 类型 (通信方式)

ATT 协议定义了 6 种基本的通信交互模式 (PDU Types)。理解这 6 种模式是理解 BLE 数据流的关键。

(A)请求 (Request) 由 Client -> Server,客户端发送请求,必须等待服务器回复响应,比如:手机读取手环电量 (Read Request)。 特点是:串行,慢,但可靠。

(B)响应(Response):由 Server -> Client,服务器对请求的回复,比如:手环回复电量值 (Read Response)。

(C)命令 (Command):由 Client -> Server 。客户端发送数据,不需要服务器回复。也叫 "Write without Response"。比如:手机快速向智能灯泡发送调色指令。

特点是:由底层链路层保证数据到达,应用层不确认,速度最快

(D)通知 (Notification): 由 Server -> Client。服务器主动推送数据,不需要客户端确认。比如:心率带每秒推送一次实时心率。特点是:最常用的数据上报方式,吞吐量高。

(E)指示 (Indication):由Server -> Client。服务器主动推送数据,必须等待客户端回复确认。在收到确认前,服务器不能发下一条。比如:血糖仪发送血糖结果(数据至关重要,必须确保对方应用层收到了)。

特点是:慢,但在应用层极其可靠

(F)确认 (Confirmation):由 Client -> Server。是客户端收到指示 (Indication) 后的回复。

(4)增强型 ATT (Enhanced ATT, EATT)

增强型 ATT (Enhanced ATT, EATT) 这是从蓝牙 5.2 引入并在 V5.3 中继续强化的重要特性。

传统 ATT (Legacy ATT): 是顺序 (Sequential)的。如果你发送了一个 Read Request,在收到 Read Response 之前,你不能发送任何其他请求。

这就像单行道,容易造成阻塞(Head-of-Line Blocking)。

增强型 ATT (EATT): 它运行在 L2CAP 的增强型基于信用的流量控制 (Enhanced Credit Based Flow Control) 模式之上。

它的特点是:

  • 支持并发 (Concurrent): 允许同时执行多个 ATT 事务。
  • 低延迟: 优先级高的命令不会被前面正在处理的大数据包阻塞。
  • MTU: EATT 的 MTU 是独立配置的,通常更灵活。

在 V5.3 设备中,如果双方都支持 EATT,设备将优先建立 EATT 信道以提升用户体验(如音频流传输时的同时控制操作)。

(5)ATT MTU (最大传输单元)

image

ATT_MTU 决定了在一个数据包中最多能传多少字节的有效载荷。默认值为 23 字节 (BLE 4.0)。

典型值: 为247 字节 (常见的 DLE 扩展后数值) 或 512 字节 (最大)。

ATT连接建立后,客户端通常会发起 Exchange MTU Request,双方协商使用两者支持的较小值。

(五)GATT (Generic Attribute Profile)

image

如果 ATT 是负责运输数据的卡车,那么 GATT (Generic Attribute Profile) 就是定义货物如何打包、存放、分类以及如何进行存取操作的仓库管理规范

(1)GATT 核心概念与角色 (Roles)

GATT 定义了两个在数据交换中完全不同的角色。请注意,这与链路层的主机 (Central/Master) 和从机 (Peripheral/Slave) 概念是独立的,尽管通常存在某种映射关系。

GATT Server (服务端): 拥有数据并接受数据访问请求的设备。它的职责是存储数据(Services 和 Characteristics),响应 Client 的读/写请求,或主动向 Client 推送数据。比如智能手环(存有心率数据)

GATT Client (客户端): 发起命令和请求,试图读取或写入数据的设备。它的职责是执行服务发现 (Service Discovery),发起读写操作,接收 Server 推送的数据。比如智能手机(想要读取手环的心率)。

(2)GATT 数据层级结构 (Hierarchy)

image

GATT 最重要的贡献是定义了严格的数据层级结构,使得不同厂商的设备可以互相理解。

(A)Profile (配置文件) Profile 实际上不是 GATT 协议本身定义的实体,而是由 Bluetooth SIG 或厂商定义的集合。一个 Profile 可能包含一个或多个 Service。

(B)Service (服务) :Service 是数据和相关行为的逻辑集合,用于实现特定的功能或特性。这里分三种服务:

Primary Service (首要服务): 暴露设备主要功能的服务。

Secondary Service (次要服务): 仅作为被引用的辅助服务(较少见)。

Include Service (引用服务): 一个服务可以引用另一个服务(类似于编程中的 #include),例如跑步服务可能引用心率服务

(C)Characteristic (特征) :Characteristic 是 GATT 中最小的逻辑数据单元,包含实际的数据值。它由三个主要部分组成:

Declaration (声明): 包含属性(读、写、通知等)、Handle(句柄)和 UUID。

Value (值): 实际的数据(例如:心率值 0x48)。

Descriptor (描述符): (可选)关于特征的额外信息。

(D)Descriptor (描述符) :对 Characteristic 的进一步描述或配置。

最著名的 Descriptor 是 CCCD (Client Characteristic Configuration Descriptor)。Client 必须写入这个描述符来开启 Server 的通知 (Notify) 或指示 (Indicate) 功能。

(3)GATT 核心操作流程 (GATT Procedures)

(A)配置与发现 (Discovery)

image

Client 连接 Server 后,通常不知道 Server 有什么功能,需要进行发现:

  • Discover Primary Services: 找出设备支持的所有主要服务。

  • Discover Characteristics: 找出某个服务下有哪些特征。

  • Discover Descriptors: 找出特征下有哪些描述符。

  • Exchange MTU: 协商最大传输单元,以决定一次能传多少字节(蓝牙 4.2/5.0+ 之后非常重要,以提高吞吐量)。

(B)数据读取 (Client -> Server)

image
  • Read Characteristic Value: 读取某个句柄的值。
  • Read Blob: 读取长数据的片段(当数据超过 MTU 时)。
  • Read Multiple: 一次性读取多个句柄的值。

(C)数据写入 (Client -> Server)

image
  • Write Request: Client 写入数据,Server 必须回复 (Ack)。可靠,但慢。
  • Write Command (Write without Response): Client 写入数据,Server 不回复。速度快,用于高吞吐量场景(如 OTA 升级)。
  • Signed Write: 带有签名的写入,用于未加密连接但需要认证的场景。

(D)服务器发起的数据推送 (Server -> Client)

image

这是 BLE 低功耗的关键,Client 不需要一直轮询 (Polling),而是订阅后等待 Server 推送。

  • Notification (通知): Server 发送数据给 Client,Client 不回复。速度快,但如果丢包不会重传。
  • Indication (指示): Server 发送数据给 Client,Client 必须回复 Confirmation。可靠,但在收到回复前 Server 不能发下一条,速度较慢。

注意: 要启用 Notification 或 Indication,Client 必须先在对应的 CCCD (描述符) 中写入特定的值。

结尾

随着低功耗蓝牙的普及,Host 层的改进越来越趋向于高效率低延迟。理解 GAP 的连接管理、ATT 的原子操作以及 GATT 的层级解构,是开发高性能蓝牙产品的基本。

希望这篇文章能有助于你更好地理解蓝牙协议栈及其工作原理。

------------------End------------------
如需获取更多内容
请关注 liwen01 公众号
 
 

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询