BLE核心协议,ATT(Attribute Protocol)概念介绍
BLE ATT(Attribute Protocol) 是蓝牙低功耗协议栈的核心,负责设备间的数据存储、发现和读写。简单说,BLE 设备之所以能“读到传感器数据”或“收到开关指令”,底层都是 ATT 在起作用。
为了方便理解,我们可以把 ATT 想象成一个“带句柄的网络文件夹系统”,而 GATT 则是基于这个系统建立的“目录规范”。下面从零开始拆解。
1. ATT 在整个 BLE 协议栈中的位置

- ATT 位于 L2CAP 之上,固定使用信道 ID 0x0004。

- GATT 是 ATT 的上层封装,它定义了属性如何组成服务、特征、描述符。
绝大多数开发者接触的是 GATT,但底层实际收发是 ATT PDU。
2. 核心模型:客户端/服务器
ATT 是一个显式的客户端/服务器协议:
- ATT 服务器:持有数据的一方。通常是传感器、开关等外设。
- ATT 客户端:发起读写请求的一方。通常是手机、网关。
注意: GATT 的角色(GATT 客户端/服务器)与 ATT 完全一致,只是换了个名字。
3. 什么是“属性”(Attribute)
ATT 管理的最小单元是属性(Attribute)。一个属性是一个带标签的数据单元,包含 4 个要素:
|
Handle(属性句柄) |
Type(属性类型) |
Value(属性值) |
Permission(属性权限) |
|
字段 |
长度 |
作用 |
举例 |
|
句柄 |
16bit |
属性的唯一 ID,类似“文件地址” |
|
|
类型 |
16/128bit |
属性的 UUID,类似“文件扩展名” |
|
|
值 |
不定长 |
实际数据 |
心率值 72bpm、开关状态 |
|
权限 |
本地存储 |
是否可读、可写、需要加密/认证 |
读需加密、写无需认证 |
关键理解:
- 句柄是访问属性的钥匙,客户端必须知道句柄才能读写。
- 类型(UUID)决定了属性的含义,比如告诉客户端“这个属性是电池电量”。
4. ATT PDU:客户端与服务器的对话
ATT 协议通过一系列固定格式的 协议数据单元 交换数据。主要分为 6 大类:
|
方向 |
操作类型 |
常见 PDU 举例 |
作用 |
|
客户端 → |
请求 |
|
要求服务器回应 |
|
服务器 → |
响应 |
|
回应请求 |
|
客户端 → |
命令 |
|
不需要回应,速度快 |
|
服务器 → |
通知 |
|
客户端不需确认 |
|
服务器 → |
指示 |
|
客户端必须确认(CFM) |
|
双向 |
认证/加密 |
通过配对/绑定后链路层加密 |
权限检查在 ATT 上层完成 |
典型交互:
- 读:
Read Req(0x10) →Read Rsp(0x0B) - 写(需要确认):
Write Req(0x12) →Write Rsp(0x13) - 写(无确认):
Write Cmd(0x52) - 服务器主动推送:
Notification(0x1B) 或Indication(0x1D) →Confirmation(0x1E)
5. 属性分组与 GATT 的关系
ATT 本身不知道“服务”“特征”是什么,它只知道一个个独立的属性。
GATT 做的事情是把这些属性按照规范分组:
ATT 属性列表(按句柄连续存放):
[0x0010] UUID = 0x2800 (Primary Service) 值 = 心率服务 UUID
[0x0011] UUID = 0x2803 (Characteristic Declaration) 值 = 属性句柄、权限、特征 UUID
[0x0012] UUID = 0x2A37 (Heart Rate Measurement) 值 = 心率数据
[0x0013] UUID = 0x2902 (Client Characteristic Configuration Descriptor) 值 = 0x0001/0x0002
- GATT 发现服务 → ATT
Read By Group Type Request(0x10) 按0x2800分组读。 - GATT 发现特征 → ATT
Read By Type Request(0x08) 按0x2803读。 - GATT 读特征值 → ATT
Read Request(0x0A) 直接读0x0012句柄。
所以 GATT 是 ATT 的“使用说明书”。
6. ATT 的特性与设计意图
- 低功耗、短报文
ATT PDU 最大长度默认 23 字节(可协商 MTU 扩展)。适合小数据量传感器。 - 基于句柄的高效寻址
不像 TCP 需要长字符串标识资源,ATT 直接用 16bit 句柄,访问极快。 - 状态化缓存
蓝牙 4.2+ GATT 缓存:客户端可以记住句柄与属性映射,重连后无需重新发现。 - 原子操作支持
Prepare Write+Execute Write可实现事务性写入(所有修改同时生效)。 - 无连接广播(可选)
在连接之外,通过广播包中的 Advertising Data 也可以包含少量属性,不需要 ATT 连接即可读取。
7. 常见误区
- “GATT 和 ATT 是并列关系”
错。GATT 建立在 ATT 之上,ATT 是传输协议,GATT 是数据组织规范。 - “ATT 句柄是固定的”
不一定。每次 GATT 服务注册时由协议栈动态分配,除非开发者强制固定。 - “每个特征只有一个属性”
错。特征声明、特征值、描述符是三个独立的 ATT 属性,连续分配句柄。
更多推荐



所有评论(0)