ATT(Attribute Protocol)是 Bluetooth 中用于访问 attribute table 的协议:server 暴露一组 attributes,client 通过 ATT PDU 发现、读取、写入这些 attributes,server 也可以用 notification 或 indication 主动发送 attribute value。
核心问题
应用希望表达的是“读取电池电量”“写入配置值”“订阅状态变化”,但蓝牙链路上传输的是小型 PDU。ATT 解决的是低层访问模型:把所有可交互数据统一抽象成 attribute,再用 handle 定位 attribute,用 opcode 表达读写发现等动作。
GATT 在 ATT 之上定义 service、characteristic 和 descriptor;ATT 本身并不理解“电池服务”或“温度值”的业务语义。
核心对象
| 对象 | 含义 | 工程关注点 |
|---|---|---|
| ATT Client | 发起请求、命令或接收通知的一方 | discovery、read/write、缓存 handle |
| ATT Server | 持有 attribute table 的一方 | 分配 handle、检查 permissions、返回错误 |
| Attribute | 一个离散数据项 | type、handle、value、permissions |
| Attribute handle | server 内唯一索引 | 通常以 16-bit handle 引用 |
| Attribute type | attribute 的类型标识 | 使用 Bluetooth UUID |
| Attribute value | attribute 的字节数组值 | 编码由上层类型决定 |
| Attribute permissions | 访问条件 | read/write、加密、认证、授权 |
| ATT PDU | 协议数据单元 | opcode、参数、响应或错误 |
核心机制
一个 attribute 可以抽象成:
Attribute = {
handle: 0x0003,
type: 0x2A19,
value: bytes([85]),
permissions: readable + encrypted? + ...
}这里 handle 是 client 在 ATT PDU 中引用的索引;type 是这个 attribute 的语义类型;value 是实际数据;permissions 决定当前连接是否允许访问。
常见 ATT 交互形态包括:
| 形态 | 是否要求响应 | 例子 | 适用场景 |
|---|---|---|---|
| Request/Response | 要 | read request、write request | 需要知道成功或失败 |
| Command | 不要 | write command | 低延迟、不等待响应 |
| Notification | 不要应用层确认 | server 推送 value | 高频状态变化 |
| Indication | 要 confirmation | server 推送 value 并等待确认 | 需要更强确认语义 |
ATT PDU 通过 L2CAP channel 承载。ATT_MTU 表示一条 ATT PDU 的最大尺寸;如果 attribute value 比单个 PDU 可承载的数据更长,就需要 long read、prepare write / execute write 这类过程。Core 规范要求 attribute value 最大长度为 512 octets,但实际可用吞吐还受连接参数、MTU、队列和平台 API 限制。
工程用途
- 支撑 GATT service discovery、characteristic read/write、notification/indication。
- 在 BLE 配网、传感器、可穿戴设备和低功耗控制面中传输小块状态数据。
- 作为抓包和调试时的协议层:看到
ATT_READ_REQ、ATT_WRITE_REQ、ATT_HANDLE_VALUE_NTF等 PDU。
调试 ATT 时,重点看 opcode、handle、error response、ATT_MTU、是否配对/加密、是否写错 CCCD、是否把 command 当成有响应操作。
边界与常见坑
- ATT 不定义业务模型:它只知道 attribute;service/characteristic/descriptor 是 GATT 对 attribute 的解释。
- handle 是 server 局部索引:不同设备、不同固件版本甚至同一设备升级后,handle 都可能变化。
- value 是 opaque bytes:ATT 不知道这些字节是整数、字符串还是结构体,解释规则来自 attribute type 或上层 service 规范。
- write command 没有 ATT 响应:发送成功不表示 server 应用逻辑处理成功。
- notification 不保证应用消费:它比 indication 吞吐高,但没有 client confirmation。
- 安全要看 permissions 和链路状态:未加密连接读写受保护 attribute 时会失败,即使 characteristic properties 显示可读写。