【Bluetooth-SIG】【CoreV6.2】【Vol3 Part F】【Attribute Protocol(ATT)逐行学习计划与博客目录索引】
Core_v6.2 Vol 3 Part F:Attribute Protocol(ATT)逐行学习计划与博客目录索引
0. 前言
我接下来准备系统学习 Bluetooth Core Specification v6.2 中的:
Vol 3, Part F:Attribute Protocol,简称 ATT
这部分是 BLE/GATT 协议栈里非常核心的一层。很多人一开始学 BLE,会直接冲到 GATT Service、Characteristic、Notification、CCCD,结果一抓包看到 ATT_READ_BY_TYPE_REQ、ATT_HANDLE_VALUE_NTF、ATT_ERROR_RSP,瞬间变成“蓝牙考古现场”。
其实 GATT 不是空中楼阁,它下面靠 ATT 托着。
ATT 就像 GATT 世界里的“快递协议”:
GATT 说“我要读这个特征值”,ATT 就负责把“读哪个 handle、怎么读、怎么回、错了报什么错”这件事讲清楚。
所以这一轮学习,我不打算泛泛而谈,而是准备按 逐行翻译 + 逐段讲解 + 表格整理 + 流程图 + 抓包对应 + 工程实现思考 的方式,完整学习 Vol 3 Part F。
本文作为整个 ATT 学习系列的目录索引,后续每篇文章都会挂在这个目录下。
1. ATT 在蓝牙协议栈中的位置
先看 ATT 在协议栈里的位置:
一句话理解:
GATT 负责定义“数据模型和业务操作”,ATT 负责定义“这些操作在协议层怎么传”。
例如:
| GATT 层看到的动作 | ATT 层实际使用的 PDU |
|---|---|
| Exchange MTU | ATT_EXCHANGE_MTU_REQ / RSP |
| Discover Services | ATT_READ_BY_GROUP_TYPE_REQ / RSP |
| Discover Characteristics | ATT_READ_BY_TYPE_REQ / RSP |
| Read Characteristic | ATT_READ_REQ / RSP |
| Read Long Characteristic | ATT_READ_BLOB_REQ / RSP |
| Write Characteristic | ATT_WRITE_REQ / RSP |
| Write Without Response | ATT_WRITE_CMD |
| Long Write / Reliable Write | ATT_PREPARE_WRITE_REQ / RSP + ATT_EXECUTE_WRITE_REQ / RSP |
| Notification | ATT_HANDLE_VALUE_NTF |
| Indication | ATT_HANDLE_VALUE_IND / CFM |
所以学 ATT,不能只背 opcode。
要把它和 GATT Procedure、L2CAP、MTU、安全权限、抓包、代码实现一起串起来。
2. 本系列学习目标
本系列目标不是“看过一遍文档”,而是达到下面这些能力:
| 能力 | 目标 |
|---|---|
| 读懂规范原文 | 能逐行解释 ATT 章节里的 shall、may、shall not |
| 看懂 ATT 抓包 | 能从 Wireshark / btmon / HCI snoop 里识别每个 ATT PDU |
| 理解 ATT 数据模型 | 明白 Attribute Type、Handle、Value、Permission 的关系 |
| 理解 ATT bearer | 明白 ATT 如何跑在 L2CAP 上,固定信道和动态信道有何区别 |
| 理解 MTU | 明白 ATT_MTU 如何影响读写、长属性和吞吐 |
| 理解读写流程 | 能解释 Read、Read Blob、Read Multiple、Write、Prepare Write、Execute Write |
| 理解 Server initiated | 能解释 Notification、Indication、Confirmation |
| 理解错误码 | 能根据 ATT_ERROR_RSP 判断问题原因 |
| 理解安全检查 | 能分析 Authentication、Authorization、Encryption、Key Size |
| 能指导实现 | 能写出 ATT Server / Client 的基本处理逻辑 |
3. 学习方法
每篇文章固定采用下面的结构。
1. 本节原文范围
2. 逐行翻译
3. 逐段解释
4. 关键术语表
5. PDU / 表格转换为 Markdown
6. Mermaid 流程图
7. 抓包对应
8. 工程实现注意点
9. 常见坑
10. 本篇小结
学习 ATT 不能只“读”,还要“拆包”。
因为 ATT 很像蓝牙世界里的快递单:
-
Opcode 是快递类型;
-
Handle 是收件地址;
-
Value 是包裹内容;
-
Error Code 是快递异常;
-
MTU 是快递箱最大尺寸;
-
Permission 是门禁;
-
Encryption 是保安;
-
Authorization 是物业批准;
-
Indication 是“必须签收”的快递;
-
Notification 是“放门口不签收”的快递。
4. 系列文章总规划
整个 Vol 3 Part F 计划拆成 24 篇学习文档。
为什么是 24 篇?
因为 ATT 章节虽然不算 Core 里最长的部分,但它每个 PDU 都非常关键。如果一篇塞太多,就会变成“协议八宝粥”,看着热闹,消化困难。
第一部分:ATT 总览与基础概念
第 1 篇:Vol 3 Part F 总览:ATT 到底解决什么问题?
对应章节
-
Part F 标题页
-
Contents
-
1 Introduction
-
1.1 Scope
-
1.3 Conventions
文章目标
搞清楚 ATT 的定位:
-
ATT 是什么;
-
ATT 和 GATT 的关系;
-
ATT 和 L2CAP 的关系;
-
ATT Client / Server 是什么;
-
为什么 ATT 是 GATT 的底层基础。
核心问题
| 问题 | 目标 |
|---|---|
| ATT 解决什么问题? | 发现、读取、写入、通知、指示 Attribute |
| ATT 是应用层吗? | 不是,它是 Host 层协议 |
| ATT 和 GATT 谁在上面? | GATT 在 ATT 上面 |
| ATT 能不能跑在 BR/EDR? | 可以,ATT/GATT 不是 LE 专属 |
| BLE 为什么强依赖 ATT/GATT? | BLE 使用 GATT 进行服务发现和数据交互 |
输出物
第 2 篇:Protocol Overview:ATT 协议模型
对应章节
- 2 Protocol overview
文章目标
从整体上理解 ATT 的通信模型。
核心问题
| 问题 | 说明 |
|---|---|
| 谁是 Client? | 发起 Request / Command 的一方 |
| 谁是 Server? | 保存 Attribute 并响应访问的一方 |
| Client 和 Server 是否固定? | 不固定,一个设备可以同时是 Client 和 Server |
| ATT 是点对点还是广播? | ATT 是基于 bearer 的点对点交互 |
| ATT 和 Attribute Database 是什么关系? | Server 维护 Attribute Database,Client 访问它 |
计划图
第 3 篇:Protocol Requirements 总览:ATT 规范里的强制要求
对应章节
-
3 Protocol requirements
-
3.1 Introduction
文章目标
掌握 ATT 的基本规则,尤其是规范里的 shall、may、shall not。
核心问题
| 问题 | 说明 |
|---|---|
| Attribute 如何被访问? | 通过 Attribute Handle |
| Attribute 如何被识别? | 通过 Attribute Type,即 UUID |
| Attribute 是否可以重复? | 同一种 Attribute Type 可以出现多次 |
| 权限在哪里生效? | Attribute Permissions |
| 安全要求在哪里体现? | Authentication、Authorization、Encryption、Key Size |
第 4 篇:Attribute Type:UUID 是 Attribute 的身份证
对应章节
- 3.2.1 Attribute type
文章目标
理解 Attribute Type 和 UUID 的关系。
核心内容
| 概念 | 说明 |
|---|---|
| Attribute Type | 属性类型 |
| UUID | 通用唯一标识 |
| 16-bit UUID | Bluetooth SIG 分配的短 UUID |
| 32-bit UUID | 需要转换为 128-bit |
| 128-bit UUID | Vendor Specific UUID |
| Assigned Numbers | 官方编号表 |
工程思考
在代码里,Attribute Type 往往会设计成:
typedef struct {
uint8_t type; // 16-bit or 128-bit
uint8_t uuid[16];
} att_uuid_t;
常见坑
-
不要把 Handle 当 UUID;
-
不要把 Characteristic UUID 和 Declaration UUID 混在一起;
-
Vendor UUID 字节序很容易看花眼,蓝牙小端序能让新手怀疑人生。
第 5 篇:Attribute Handle:ATT 世界里的门牌号
对应章节
- 3.2.2 Attribute handle
文章目标
理解 Handle 的作用、范围、唯一性和生命周期。
核心内容
| 项 | 说明 |
|---|---|
| Handle 长度 | 16 bit |
| 有效范围 | 0x0001 到 0xFFFF |
0x0000 |
保留 |
| 唯一性 | 同一个 Server 上 handle 唯一 |
| 排序规则 | Attribute 按 handle 递增排列 |
| 访问方式 | Client 通过 handle 访问 Attribute |
示例
Handle 0x0001: Primary Service Declaration
Handle 0x0002: Characteristic Declaration
Handle 0x0003: Characteristic Value
Handle 0x0004: CCCD
工程思考
GATT DB 中最核心的字段就是 handle。
typedef struct {
uint16_t handle;
att_uuid_t type;
uint8_t *value;
uint16_t value_len;
uint16_t permissions;
} att_attr_t;
第 6 篇:Attribute Grouping、Value、Permissions
对应章节
-
3.2.3 Attribute handle grouping
-
3.2.4 Attribute value
-
3.2.5 Attribute permissions
文章目标
理解 Attribute 的完整结构。
Attribute 逻辑结构
核心问题
| 问题 | 说明 |
|---|---|
| Grouping 是什么? | 用一个起始 Attribute 表示一组 Attribute |
| Value 是什么? | 字节数组,对 ATT 来说是 opaque data |
| Permission 控制什么? | 读、写、加密、认证、授权等 |
| Permission 是 ATT PDU 字段吗? | 不是,通常是 Server 本地数据库属性 |
常见坑
ATT 只负责搬运 value,不理解 value 的业务含义。
就像快递员不关心你箱子里是键盘还是榴莲,他只负责送到。
第 7 篇:Control-point Attributes 与 Protocol Methods
对应章节
-
3.2.6 Control-point attributes
-
3.2.7 Protocol methods
文章目标
理解控制点属性和 ATT 方法分类。
核心内容
| 类型 | 说明 |
|---|---|
| Control-point Attribute | 不能读,只能写、通知或指示的控制属性 |
| Command | 不需要响应 |
| Request | 需要响应 |
| Response | 对 Request 的响应 |
| Notification | Server 主动发,不需要确认 |
| Indication | Server 主动发,需要确认 |
| Confirmation | Client 对 Indication 的确认 |
示例
写入某个控制点 Characteristic:
Client -> Server: ATT_WRITE_REQ / ATT_WRITE_CMD
Server 执行动作
Server -> Client: ATT_HANDLE_VALUE_IND / NTF 表示完成或状态变化
第 8 篇:ATT_MTU:协议包裹箱到底有多大?
对应章节
-
3.2.8 Exchanging MTU size
-
3.4.2 MTU exchange
-
3.4.2.1 ATT_EXCHANGE_MTU_REQ
-
3.4.2.2 ATT_EXCHANGE_MTU_RSP
文章目标
理解 ATT_MTU 的意义、交换流程和工程影响。
核心问题
| 问题 | 说明 |
|---|---|
| ATT_MTU 是什么? | ATT PDU 的最大长度 |
| 默认 MTU 是多少? | 通常默认值由上层定义,BLE 常见默认 23 |
| 实际使用 MTU 怎么确定? | 双方 Rx MTU 取最小值 |
| MTU 对吞吐有什么影响? | 影响单个 ATT PDU 可承载的 value 长度 |
| MTU 是否等于 L2CAP MTU? | 固定信道和动态信道情况下处理不同 |
MTU 流程
工程公式
Read Response 最大 Value 长度 = ATT_MTU - 1
Write Request 最大 Value 长度 = ATT_MTU - 3
Notification 最大 Value 长度 = ATT_MTU - 3
Indication 最大 Value 长度 = ATT_MTU - 3
Signed Write Command 最大 Value 长度 = ATT_MTU - 15
第 9 篇:Long Attribute Values 与 Atomic Operations
对应章节
-
3.2.9 Long attribute values
-
3.2.10 Atomic operations
文章目标
理解长属性读写和原子操作。
核心内容
| 概念 | 说明 |
|---|---|
| Long Attribute | 一个 PDU 装不下的 Attribute Value |
| Read Blob | 分段读取长属性 |
| Prepare Write | 分段准备写入 |
| Execute Write | 执行或取消队列写入 |
| Atomic Operation | 单个 Request/Command 不应被其他 bearer 干扰 |
| 最大 Attribute Value 长度 | 512 octets |
常见坑
-
ATT_READ_REQ只能读开头部分; -
ATT_READ_BLOB_REQ需要 offset; -
长写不是一个包搞定;
-
多 bearer 并发时,要注意属性访问的原子性;
-
长属性读写时,上层要处理 value 变化的一致性。
第 10 篇:ATT Bearer:ATT 怎么跑在 L2CAP 上?
对应章节
- 3.2.11 ATT bearers
文章目标
理解 ATT bearer、L2CAP fixed channel、dynamic channel、Enhanced ATT bearer。
核心内容
| 概念 | 说明 |
|---|---|
| ATT bearer | 用于发送 ATT PDU 的 L2CAP channel |
| LE fixed channel | LE Attribute Protocol fixed channel |
| Dynamic channel | 动态分配的 L2CAP channel |
| Unenhanced ATT bearer | 普通 ATT bearer |
| Enhanced ATT bearer | 基于增强 L2CAP 模式的 ATT bearer |
| EATT | Enhanced ATT,多 bearer 并发能力基础 |
图示
第二部分:ATT PDU 与事务模型
第 11 篇:Attribute PDU 总览:六大类型
对应章节
- 3.3 Attribute PDU
文章目标
理解 ATT PDU 的六种类型。
六大类型
| 类型 | 后缀 | 是否需要响应/确认 | 方向 |
|---|---|---|---|
| Command | CMD | 不需要 Response | Client → Server |
| Request | REQ | 需要 Response | Client → Server |
| Response | RSP | 对 Request 的响应 | Server → Client |
| Notification | NTF | 不需要 Confirmation | Server → Client |
| Indication | IND | 需要 Confirmation | Server → Client |
| Confirmation | CFM | 对 Indication 的确认 | Client → Server |
图示
第 12 篇:Attribute PDU Format、Sequential Protocol、Transaction
对应章节
-
3.3.1 Attribute PDU format
-
3.3.2 Sequential protocol
-
3.3.3 Transaction
文章目标
理解 ATT PDU 格式和事务模型。
ATT PDU 基本结构
+--------+----------------------+--------------------------+
| Opcode | Attribute Parameters | Authentication Signature |
+--------+----------------------+--------------------------+
核心问题
| 问题 | 说明 |
|---|---|
| Opcode 多大? | 1 octet |
| Parameters 是否固定? | 根据 PDU 类型变化 |
| Signature 什么时候存在? | Signed Write Command 等场景 |
| Sequential Protocol 是什么? | 一个 bearer 上的事务需要按顺序处理 |
| Transaction 是什么? | Request 与 Response 构成一次事务 |
工程坑
一个 ATT bearer 上不能无限并发 Request。
想并发?上 EATT,多开 bearer。
不然就像一个窗口排队办业务,后面的人再急,也得等前面那个大爷办完。
第三部分:ATT Protocol PDUs 逐个学习
第 13 篇:Error Handling:ATT_ERROR_RSP
对应章节
-
3.4.1 Error handling
-
3.4.1.1 ATT_ERROR_RSP
文章目标
掌握 ATT 错误响应格式和错误码定位方法。
ATT_ERROR_RSP 典型字段
| 字段 | 说明 |
|---|---|
| Attribute Opcode | 0x01 |
| Request Opcode In Error | 出错的请求 opcode |
| Attribute Handle In Error | 出错 handle |
| Error Code | 错误码 |
常见错误码
| 错误码 | 含义 |
|---|---|
0x01 |
Invalid Handle |
0x02 |
Read Not Permitted |
0x03 |
Write Not Permitted |
0x04 |
Invalid PDU |
0x05 |
Insufficient Authentication |
0x06 |
Request Not Supported |
0x07 |
Invalid Offset |
0x08 |
Insufficient Authorization |
0x09 |
Prepare Queue Full |
0x0A |
Attribute Not Found |
0x0B |
Attribute Not Long |
0x0C |
Encryption Key Size Too Short |
0x0D |
Invalid Attribute Value Length |
0x0E |
Unlikely Error |
0x0F |
Insufficient Encryption |
0x10 |
Unsupported Group Type |
0x11 |
Insufficient Resources |
0x12 |
Database Out Of Sync |
工程思考
看到 ATT_ERROR_RSP 不要慌。
它不是协议崩了,而是 Server 在跟你说:
“哥们,你这个请求我处理不了,原因写在 Error Code 里了。”
第 14 篇:Find Information:发现 Attribute Handle 与 Type
对应章节
-
3.4.3 Find information
-
3.4.3.1 ATT_FIND_INFORMATION_REQ
-
3.4.3.2 ATT_FIND_INFORMATION_RSP
文章目标
理解如何发现 Attribute Handle 与 Attribute Type 的映射。
典型用途
GATT 中 Discover All Characteristic Descriptors 常用它。
流程
工程重点
| 字段 | 说明 |
|---|---|
| Starting Handle | 起始 handle |
| Ending Handle | 结束 handle |
| Format | 返回 UUID 是 16-bit 还是 128-bit |
| Information Data | Handle + UUID 列表 |
第 15 篇:Find By Type Value:按类型和值查找 Attribute
对应章节
-
3.4.3.3 ATT_FIND_BY_TYPE_VALUE_REQ
-
3.4.3.4 ATT_FIND_BY_TYPE_VALUE_RSP
文章目标
理解按 Attribute Type 和 Attribute Value 查找 handle range。
典型用途
GATT 中 Discover Primary Service by Service UUID。
流程
工程重点
这个 PDU 有点像数据库查询:
SELECT handle_range
FROM attribute_db
WHERE type = xxx AND value = yyy;
第 16 篇:Read By Type:按 UUID 读取 Attribute
对应章节
-
3.4.4.1 ATT_READ_BY_TYPE_REQ
-
3.4.4.2 ATT_READ_BY_TYPE_RSP
文章目标
理解按 Attribute Type 读取 attribute value 的机制。
典型用途
| GATT Procedure | ATT PDU |
|---|---|
| Discover Characteristics | ATT_READ_BY_TYPE_REQ / RSP |
| Read Using Characteristic UUID | ATT_READ_BY_TYPE_REQ / RSP |
| Find Included Services | ATT_READ_BY_TYPE_REQ / RSP |
流程
常见坑
返回列表中的每个 Attribute Data 长度必须一致。
如果不同长度的 value 混在一起,Server 需要按规范处理,不能随便塞一锅乱炖。
第 17 篇:Read Request 与 Read Blob:普通读与长读
对应章节
-
3.4.4.3 ATT_READ_REQ
-
3.4.4.4 ATT_READ_RSP
-
3.4.4.5 ATT_READ_BLOB_REQ
-
3.4.4.6 ATT_READ_BLOB_RSP
文章目标
理解普通读取和分段读取长属性。
普通读
长读
工程重点
| 场景 | 使用 PDU |
|---|---|
| Value 较短 | ATT_READ_REQ |
| Value 超过单个 PDU | ATT_READ_BLOB_REQ |
| offset 非法 | Invalid Offset |
| Attribute 不支持长读 | Attribute Not Long |
第 18 篇:Read Multiple 与 Read By Group Type
对应章节
-
3.4.4.7 ATT_READ_MULTIPLE_REQ
-
3.4.4.8 ATT_READ_MULTIPLE_RSP
-
3.4.4.9 ATT_READ_BY_GROUP_TYPE_REQ
-
3.4.4.10 ATT_READ_BY_GROUP_TYPE_RSP
文章目标
理解多 handle 读取和分组读取。
Read Multiple
用于一次读取多个 attribute value。
Read By Group Type
GATT 中 Discover All Primary Services 的核心 PDU。
工程重点
| PDU | 常见用途 |
|---|---|
ATT_READ_MULTIPLE_REQ |
批量读多个固定长度 value |
ATT_READ_BY_GROUP_TYPE_REQ |
服务发现 |
ATT_READ_BY_GROUP_TYPE_RSP |
返回 group start/end handle 和 value |
第 19 篇:Read Multiple Variable:变长多属性读取
对应章节
-
3.4.4.11 ATT_READ_MULTIPLE_VARIABLE_REQ
-
3.4.4.12 ATT_READ_MULTIPLE_VARIABLE_RSP
文章目标
理解变长 attribute 的多值读取。
核心问题
| 问题 | 说明 |
|---|---|
| 为什么需要 Variable 版本? | 普通 Read Multiple 不适合变长 value |
| 返回格式是什么? | Length + Value tuple list |
| handle 顺序是否要求递增? | 返回顺序按请求顺序 |
| 是否可能超出 ATT_MTU? | 需要按 MTU 限制处理 |
第 20 篇:Writing Attributes:Write Request、Write Command、Signed Write
对应章节
-
3.4.5 Writing attributes
-
3.4.5.1 ATT_WRITE_REQ
-
3.4.5.2 ATT_WRITE_RSP
-
3.4.5.3 ATT_WRITE_CMD
-
3.4.5.4 ATT_SIGNED_WRITE_CMD
文章目标
理解三种写操作。
对比表
| PDU | 是否需要响应 | 是否有签名 | 典型用途 |
|---|---|---|---|
ATT_WRITE_REQ |
是 | 否 | 可靠写入,需要知道结果 |
ATT_WRITE_CMD |
否 | 否 | 高速写入,不关心响应 |
ATT_SIGNED_WRITE_CMD |
否 | 是 | 未加密 bearer 上的认证写 |
流程
工程重点
-
Write Request有错误响应; -
Write Command没有错误响应; -
Signed Write Command需要安全上下文; -
ATT_MTU - 3影响普通写 payload; -
ATT_MTU - 15影响 signed write payload。
第 21 篇:Queued Writes:Prepare Write 与 Execute Write
对应章节
-
3.4.6 Queued writes
-
3.4.6.1 ATT_PREPARE_WRITE_REQ
-
3.4.6.2 ATT_PREPARE_WRITE_RSP
-
3.4.6.3 ATT_EXECUTE_WRITE_REQ
-
3.4.6.4 ATT_EXECUTE_WRITE_RSP
文章目标
理解长写和可靠写。
流程
工程重点
| 点 | 说明 |
|---|---|
| Prepare Queue | Server 需要缓存写入片段 |
| Offset | 决定写入位置 |
| Echo 校验 | Response 需要回显部分字段 |
| Execute | 决定执行或取消 |
| Queue Full | 队列满时返回错误 |
| Reliable Write | Client 可校验 Server 回显内容 |
常见坑
Prepare Write 是“先放购物车”,Execute Write 才是“提交订单”。
只 Prepare 不 Execute,就像加了一购物车东西但没付款,老板不会发货。
第 22 篇:Server Initiated:Notification、Indication、Confirmation
对应章节
-
3.4.7 Server initiated
-
3.4.7.1 ATT_HANDLE_VALUE_NTF
-
3.4.7.2 ATT_HANDLE_VALUE_IND
-
3.4.7.3 ATT_HANDLE_VALUE_CFM
-
3.4.7.4 ATT_MULTIPLE_HANDLE_VALUE_NTF
文章目标
理解 Server 主动发送数据的机制。
对比表
| 类型 | PDU | 是否需要确认 | 常见用途 |
|---|---|---|---|
| Notification | ATT_HANDLE_VALUE_NTF |
否 | 传感器连续上报 |
| Indication | ATT_HANDLE_VALUE_IND |
是 | 关键状态变化 |
| Confirmation | ATT_HANDLE_VALUE_CFM |
是,Client 回 Server | Indication 确认 |
| Multiple Notification | ATT_MULTIPLE_HANDLE_VALUE_NTF |
否 | 多 handle 合并通知 |
流程
工程重点
-
Notification 不保证应用层确认;
-
Indication 一次只能等待一个确认;
-
CCCD 属于 GATT 层,但会影响 ATT Notification/Indication 是否发送;
-
多 handle notification 有利于减少包开销。
第四部分:总结表、安全与实现
第 23 篇:Opcode Summary 与 Response Summary
对应章节
-
3.4.8 Attribute Opcode summary
-
3.4.9 Attribute PDU response summary
文章目标
把所有 ATT PDU 做成速查表。
计划输出表
| PDU | Opcode | 类型 | 参数 | 成功响应 | 是否可能 Error |
|---|---|---|---|---|---|
ATT_ERROR_RSP |
0x01 |
Response | Error fields | 无 | 否 |
ATT_EXCHANGE_MTU_REQ |
0x02 |
Request | Client Rx MTU | ATT_EXCHANGE_MTU_RSP |
是 |
ATT_EXCHANGE_MTU_RSP |
0x03 |
Response | Server Rx MTU | 无 | 否 |
ATT_FIND_INFORMATION_REQ |
0x04 |
Request | Start/End Handle | ATT_FIND_INFORMATION_RSP |
是 |
ATT_FIND_INFORMATION_RSP |
0x05 |
Response | Format + Info | 无 | 否 |
ATT_FIND_BY_TYPE_VALUE_REQ |
0x06 |
Request | Start/End/Type/Value | ATT_FIND_BY_TYPE_VALUE_RSP |
是 |
ATT_FIND_BY_TYPE_VALUE_RSP |
0x07 |
Response | Handle Info List | 无 | 否 |
ATT_READ_BY_TYPE_REQ |
0x08 |
Request | Start/End/UUID | ATT_READ_BY_TYPE_RSP |
是 |
ATT_READ_BY_TYPE_RSP |
0x09 |
Response | Attribute Data List | 无 | 否 |
ATT_READ_REQ |
0x0A |
Request | Handle | ATT_READ_RSP |
是 |
ATT_READ_RSP |
0x0B |
Response | Value | 无 | 否 |
ATT_READ_BLOB_REQ |
0x0C |
Request | Handle/Offset | ATT_READ_BLOB_RSP |
是 |
ATT_READ_BLOB_RSP |
0x0D |
Response | Part Value | 无 | 否 |
ATT_READ_MULTIPLE_REQ |
0x0E |
Request | Handle Set | ATT_READ_MULTIPLE_RSP |
是 |
ATT_READ_MULTIPLE_RSP |
0x0F |
Response | Value Set | 无 | 否 |
ATT_READ_BY_GROUP_TYPE_REQ |
0x10 |
Request | Start/End/UUID | ATT_READ_BY_GROUP_TYPE_RSP |
是 |
ATT_READ_BY_GROUP_TYPE_RSP |
0x11 |
Response | Attribute Data List | 无 | 否 |
ATT_WRITE_REQ |
0x12 |
Request | Handle/Value | ATT_WRITE_RSP |
是 |
ATT_WRITE_RSP |
0x13 |
Response | 无 | 无 | 否 |
ATT_PREPARE_WRITE_REQ |
0x16 |
Request | Handle/Offset/Part Value | ATT_PREPARE_WRITE_RSP |
是 |
ATT_PREPARE_WRITE_RSP |
0x17 |
Response | Handle/Offset/Part Value | 无 | 否 |
ATT_EXECUTE_WRITE_REQ |
0x18 |
Request | Flags | ATT_EXECUTE_WRITE_RSP |
是 |
ATT_EXECUTE_WRITE_RSP |
0x19 |
Response | 无 | 无 | 否 |
ATT_HANDLE_VALUE_NTF |
0x1B |
Notification | Handle/Value | 无 | 否 |
ATT_HANDLE_VALUE_IND |
0x1D |
Indication | Handle/Value | ATT_HANDLE_VALUE_CFM |
否 |
ATT_HANDLE_VALUE_CFM |
0x1E |
Confirmation | 无 | 无 | 否 |
ATT_READ_MULTIPLE_VARIABLE_REQ |
0x20 |
Request | Set Of Handles | ATT_READ_MULTIPLE_VARIABLE_RSP |
是 |
ATT_READ_MULTIPLE_VARIABLE_RSP |
0x21 |
Response | Length Value Tuple List | 无 | 否 |
ATT_MULTIPLE_HANDLE_VALUE_NTF |
0x23 |
Notification | Tuple List | 无 | 否 |
ATT_WRITE_CMD |
0x52 |
Command | Handle/Value | 无 | 否 |
ATT_SIGNED_WRITE_CMD |
0xD2 |
Command | Handle/Value/Signature | 无 | 否 |
第 24 篇:Security Considerations、References、Appendix 与系列总结
对应章节
-
4 Security considerations
-
5 References
-
Appendix A Changes to PDU names
文章目标
总结 ATT 的安全检查和版本兼容注意事项。
安全检查重点
| 安全项 | 说明 |
|---|---|
| Authentication | 是否完成认证 |
| Authorization | 是否被授权 |
| Encryption | 是否加密 |
| Encryption Key Size | 密钥长度是否足够 |
| Permission | Attribute 本地权限 |
| Error Code | 安全失败时返回的错误码 |
安全检查顺序
Server 应该优先检查安全条件。
否则可能出现信息泄露,比如攻击者通过不同错误码推测 attribute 长度或存在性。
Appendix 重点
旧版 PDU 名称与新版 PDU 名称对照。
这对读老代码、老协议栈、旧抓包工具特别有用。
5. 系列文章目录索引
下面是最终目录索引,后续每写完一篇,就在这里补链接。
| 编号 | 文章标题 | 对应章节 | 状态 |
|---|---|---|---|
| 01 | Vol 3 Part F 总览:ATT 到底解决什么问题? | Part F 标题、1 Introduction | 待写 |
| 02 | Protocol Overview:ATT 协议模型 | 2 Protocol overview | 待写 |
| 03 | Protocol Requirements 总览:ATT 规范里的强制要求 | 3、3.1 | 待写 |
| 04 | Attribute Type:UUID 是 Attribute 的身份证 | 3.2.1 | 待写 |
| 05 | Attribute Handle:ATT 世界里的门牌号 | 3.2.2 | 待写 |
| 06 | Attribute Grouping、Value、Permissions | 3.2.3–3.2.5 | 待写 |
| 07 | Control-point Attributes 与 Protocol Methods | 3.2.6–3.2.7 | 待写 |
| 08 | ATT_MTU:协议包裹箱到底有多大? | 3.2.8、3.4.2 | 待写 |
| 09 | Long Attribute Values 与 Atomic Operations | 3.2.9–3.2.10 | 待写 |
| 10 | ATT Bearer:ATT 怎么跑在 L2CAP 上? | 3.2.11 | 待写 |
| 11 | Attribute PDU 总览:六大类型 | 3.3 | 待写 |
| 12 | Attribute PDU Format、Sequential Protocol、Transaction | 3.3.1–3.3.3 | 待写 |
| 13 | Error Handling:ATT_ERROR_RSP | 3.4.1 | 待写 |
| 14 | Find Information:发现 Attribute Handle 与 Type | 3.4.3.1–3.4.3.2 | 待写 |
| 15 | Find By Type Value:按类型和值查找 Attribute | 3.4.3.3–3.4.3.4 | 待写 |
| 16 | Read By Type:按 UUID 读取 Attribute | 3.4.4.1–3.4.4.2 | 待写 |
| 17 | Read Request 与 Read Blob:普通读与长读 | 3.4.4.3–3.4.4.6 | 待写 |
| 18 | Read Multiple 与 Read By Group Type | 3.4.4.7–3.4.4.10 | 待写 |
| 19 | Read Multiple Variable:变长多属性读取 | 3.4.4.11–3.4.4.12 | 待写 |
| 20 | Writing Attributes:Write Request、Write Command、Signed Write | 3.4.5 | 待写 |
| 21 | Queued Writes:Prepare Write 与 Execute Write | 3.4.6 | 待写 |
| 22 | Server Initiated:Notification、Indication、Confirmation | 3.4.7 | 待写 |
| 23 | Opcode Summary 与 Response Summary | 3.4.8–3.4.9 | 待写 |
| 24 | Security Considerations、References、Appendix 与系列总结 | 4、5、Appendix A | 待写 |
6. 推荐文件归档方式
为了后续持续维护,建议目录这样组织:
bluetooth-core-v6.2-study/
└── vol3-partf-att/
├── 00-index.md
├── 01-att-overview.md
├── 02-protocol-overview.md
├── 03-protocol-requirements.md
├── 04-attribute-type.md
├── 05-attribute-handle.md
├── 06-attribute-grouping-value-permissions.md
├── 07-control-point-protocol-methods.md
├── 08-att-mtu.md
├── 09-long-attribute-atomic.md
├── 10-att-bearer.md
├── 11-att-pdu-types.md
├── 12-pdu-format-sequential-transaction.md
├── 13-error-response.md
├── 14-find-information.md
├── 15-find-by-type-value.md
├── 16-read-by-type.md
├── 17-read-and-read-blob.md
├── 18-read-multiple-read-by-group-type.md
├── 19-read-multiple-variable.md
├── 20-writing-attributes.md
├── 21-queued-writes.md
├── 22-server-initiated.md
├── 23-opcode-response-summary.md
├── 24-security-appendix-summary.md
├── images/
├── captures/
└── notes/
7. 每篇文章建议产出内容
每篇文章至少包含以下内容:
| 模块 | 说明 |
|---|---|
| 原文范围 | 标明学习的是哪一小节 |
| 逐行翻译 | 每句规范原文对应中文解释 |
| 段落讲解 | 用工程语言解释它到底想表达什么 |
| 术语表 | 本文涉及的关键术语 |
| 表格转换 | 原文表格整理为 Markdown |
| 流程图 | 使用 Mermaid 表示交互过程 |
| 抓包对应 | 给出 Wireshark / HCI log 中的对应字段 |
| 代码思考 | ATT Client / Server 如何实现 |
| 常见坑 | 工程实现和调试中容易踩的坑 |
| 小结 | 本篇核心观点 |
8. ATT 学习中的重点难点排序
P0:必须完全掌握
| 内容 | 原因 |
|---|---|
| Attribute Type / Handle / Value / Permission | ATT 数据模型基础 |
| ATT Bearer | 关系到 L2CAP、EATT、BR/EDR/LE 承载 |
| ATT_MTU | 关系到吞吐、分片、长读写 |
| Request / Response 模型 | 所有同步操作基础 |
| Error Response | 调试必看 |
| Read / Write | GATT 操作基本盘 |
| Notification / Indication | BLE 数据上报核心 |
| Security Considerations | 权限、安全、隐私相关 |
P1:需要深入理解
| 内容 | 原因 |
|---|---|
| Read By Type | GATT 发现特征值常用 |
| Read By Group Type | GATT 服务发现核心 |
| Prepare Write / Execute Write | OTA、长写、可靠写场景 |
| Signed Write | 安全相关,虽然不一定常用 |
| Multiple Handle Value Notification | 新特性和性能优化相关 |
| Enhanced ATT Bearer | EATT 并发基础 |
P2:可后续结合 GATT 再强化
| 内容 | 原因 |
|---|---|
| Find By Type Value | GATT Primary Service by UUID 使用 |
| Read Multiple Variable | 特定场景使用 |
| Appendix PDU name changes | 读旧资料、旧代码时有用 |
9. 抓包学习建议
后续每篇文章都尽量找对应抓包。
推荐抓包来源
| 工具 | 用途 |
|---|---|
| Wireshark | 分析 btsnoop / pcap |
| Android HCI snoop log | 手机 BLE 抓包 |
| Linux btmon | BlueZ 协议栈调试 |
| nRF Connect | 触发 GATT 操作 |
| Ellisys / Frontline | 专业空口分析 |
| 自研日志 | 协议栈内部状态机分析 |
抓包观察路径
HCI ACL Data
└── L2CAP
└── ATT
├── Opcode
├── Handle
├── Value
└── Error Code
建议抓的典型流程
| 流程 | 观察的 ATT PDU |
|---|---|
| 连接后交换 MTU | ATT_EXCHANGE_MTU_REQ / RSP |
| 发现服务 | ATT_READ_BY_GROUP_TYPE_REQ / RSP |
| 发现特征值 | ATT_READ_BY_TYPE_REQ / RSP |
| 发现描述符 | ATT_FIND_INFORMATION_REQ / RSP |
| 读特征值 | ATT_READ_REQ / RSP |
| 写 CCCD | ATT_WRITE_REQ / RSP |
| Notification | ATT_HANDLE_VALUE_NTF |
| Indication | ATT_HANDLE_VALUE_IND / CFM |
| 长读 | ATT_READ_BLOB_REQ / RSP |
| 长写 | ATT_PREPARE_WRITE_REQ / RSP + ATT_EXECUTE_WRITE_REQ / RSP |
| 权限错误 | ATT_ERROR_RSP |
10. ATT 与 GATT 的配套学习关系
学习 ATT 时,要始终和 GATT 对照。
对照表
| GATT 概念 | ATT 对应 |
|---|---|
| Service | 一组 Attribute |
| Characteristic Declaration | Attribute |
| Characteristic Value | Attribute |
| Descriptor | Attribute |
| UUID | Attribute Type |
| Handle | Attribute Handle |
| Read Characteristic | ATT_READ_REQ / RSP |
| Write Characteristic | ATT_WRITE_REQ / RSP |
| Notify | ATT_HANDLE_VALUE_NTF |
| Indicate | ATT_HANDLE_VALUE_IND / CFM |
11. ATT Server 实现思路
学习完 ATT 后,应该能设计一个最小 ATT Server。
ATT Server 核心模块
伪代码
void att_handle_pdu(att_bearer_t *bearer, uint8_t *pdu, uint16_t len)
{
uint8_t opcode = pdu[0];
switch (opcode) {
case ATT_EXCHANGE_MTU_REQ:
att_handle_exchange_mtu_req(bearer, pdu, len);
break;
case ATT_FIND_INFORMATION_REQ:
att_handle_find_information_req(bearer, pdu, len);
break;
case ATT_READ_REQ:
att_handle_read_req(bearer, pdu, len);
break;
case ATT_WRITE_REQ:
att_handle_write_req(bearer, pdu, len);
break;
case ATT_WRITE_CMD:
att_handle_write_cmd(bearer, pdu, len);
break;
case ATT_PREPARE_WRITE_REQ:
att_handle_prepare_write_req(bearer, pdu, len);
break;
case ATT_EXECUTE_WRITE_REQ:
att_handle_execute_write_req(bearer, pdu, len);
break;
default:
if (is_request(opcode)) {
att_send_error_rsp(bearer, opcode, 0x0000, ATT_ERR_REQUEST_NOT_SUPPORTED);
}
break;
}
}
12. ATT Client 实现思路
ATT Client 重点是事务管理。
Client 需要维护
| 状态 | 说明 |
|---|---|
| bearer MTU | 当前 ATT_MTU |
| pending request | 当前等待响应的 request |
| timeout timer | 响应超时计时 |
| callback | 上层 GATT procedure 回调 |
| transaction queue | 请求队列 |
| indication state | 是否需要发送 confirmation |
Client 状态机
13. 本系列最终验收标准
学完 24 篇后,应该能完成下面这些任务。
| 任务 | 验收标准 |
|---|---|
| 拆解任意 ATT PDU | 能指出 opcode、参数、方向、响应关系 |
| 分析 GATT 发现服务流程 | 能对应到 ATT_READ_BY_GROUP_TYPE |
| 分析 GATT 发现特征值流程 | 能对应到 ATT_READ_BY_TYPE |
| 分析 CCCD 写入 | 能对应到 ATT_WRITE_REQ |
| 分析 Notification | 能对应到 ATT_HANDLE_VALUE_NTF |
| 分析 Indication | 能对应到 ATT_HANDLE_VALUE_IND / CFM |
| 分析长读 | 能解释 offset 和 Read Blob |
| 分析长写 | 能解释 Prepare Queue 和 Execute |
| 分析错误码 | 能根据 ATT_ERROR_RSP 定位权限、安全、handle、offset 问题 |
| 设计最小 ATT Server | 能完成基础 request/response 处理 |
| 设计最小 ATT Client | 能完成事务管理和超时处理 |
| 对接 GATT | 能说明 GATT Procedure 和 ATT PDU 映射关系 |
14. 总结
Vol 3 Part F:Attribute Protocol 是 BLE/GATT 学习中的核心章节。
如果把 GATT 比作“超市货架”,那么:
-
Attribute 是货架上的商品;
-
Handle 是商品编号;
-
UUID 是商品类别;
-
Value 是商品内容;
-
Permission 是购买权限;
-
ATT Request 是顾客提需求;
-
ATT Response 是店员回答;
-
Notification 是店员主动喊“新货到了”;
-
Indication 是店员喊完还要你点头确认;
-
ATT_MTU 是购物袋大小;
-
Error Response 是店员告诉你“这东西不能买”。
这个系列计划拆成 24 篇文章,按照规范目录逐行学习,从基础概念到每一个 PDU,再到安全、抓包和工程实现。后续学习就按照这个索引逐篇推进。
更多推荐



所有评论(0)