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,类似“文件地址”

0x00100x0011

类型

16/128bit

属性的 UUID,类似“文件扩展名”

0x2803(特征声明)

不定长

实际数据

心率值 72bpm、开关状态

权限

本地存储

是否可读、可写、需要加密/认证

读需加密、写无需认证

关键理解:

  • 句柄是访问属性的钥匙,客户端必须知道句柄才能读写。
  • 类型(UUID)决定了属性的含义,比如告诉客户端“这个属性是电池电量”。

4. ATT PDU:客户端与服务器的对话

ATT 协议通过一系列固定格式的 协议数据单元 交换数据。主要分为 6 大类:

方向

操作类型

常见 PDU 举例

作用

客户端 →

请求

Read Request

Write Request

要求服务器回应

服务器 →

响应

Read Response

Write Response

回应请求

客户端 →

命令

Write Command

不需要回应,速度快

服务器 →

通知

Handle Value Notification

客户端不需确认

服务器 →

指示

Handle Value Indication

客户端必须确认(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 属性,连续分配句柄。
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐