GATT 读写操作机制:读请求/响应、写请求/命令、通知与指示
GATT(Generic Attribute Profile)在 BLE 协议栈中位于 ATT(Attribute Protocol)之上,定义了客户端与服务器之间数据交互的操作原语。本章聚焦四种核心操作——读请求/响应、写请求/命令、通知与指示——从架构边界、组件职责、数据流与信任链路的角度解析其设计权衡与落地风险。
架构定位:GATT 操作是应用层与协议栈之间的“依赖注入边界”。客户端不直接感知服务器内部存储结构,而通过预定义的 Profile 和服务声明间接访问属性;服务器则通过权限检查、响应策略控制数据暴露粒度。这种边界设计决定了系统各层之间的耦合程度。
2.1 操作边界与组件职责
| 操作 | 方向 | 发起方 | 接收方 | 响应要求 | 典型场景 |
|---|---|---|---|---|---|
| 读请求 / 读响应 | 请求‑响应 | 客户端 | 服务器 | 必须响应 | 获取设备名称、电池电量 |
| 写请求 / 写响应 | 请求‑响应 | 客户端 | 服务器 | 必须响应 | 配置特征值、写入控制点 |
| 写命令(无响应) | 单向 | 客户端 | 服务器 | 无需响应 | 高频率传感器数据推送 |
| 通知(无响应) | 单向 | 服务器 | 客户端 | 无需响应 | 实时心率、温度上报 |
| 指示 / 确认 | 请求‑响应 | 服务器 | 客户端 | 必须确认 | 关键事件、需要保障送达的状态变更 |
从分层视角看,每个操作都涉及三层组件:
- 应用层:定义特征值语义和访问策略,如读取电池电量的 UUID、写命令的格式。
- GATT 层:维护服务 / 特征 / 描述符的层级结构,处理属性查找和权限校验。
- ATT 层:负责 PDU 编码 / 解码、流量控制(MTU)、安全等级映射(加密 / 认证)。
边界要点:应用层不应直接操作 ATT PDU,而应通过 GATT 抽象接口(如 gatt_read_char、gatt_write_cmd)注入数据。服务器端在 ATT 接收回调中完成权限校验后,再分发至应用层处理函数。这种分层隔离降低了协议栈升级对应用的影响。
2.2 数据流与控制流
下图为客户端读取服务器特征值时的一次完整交互流程(读请求 / 响应),以及写命令和通知的非对称路径:
2.3 信任链路与安全边界
GATT 操作的信任链路依赖于 L2CAP 层的加密状态和 ATT 层的权限校验。每次操作前 ATT 层会检查:
- 加密要求:该特征值的属性是否要求加密连接(如用于健康数据的特征);
- 授权要求:是否需要配对绑定后的认证(如用于固件升级的控制点);
- 操作许可:属性的读写权限位是否允许当前操作类型(读 / 写请求 vs 写命令)。
风险点:如果服务器在 GATT 层不区分“写请求”与“写命令”的处理路径,攻击者可以通过写命令(无响应)绕过握手确认,导致状态机不一致。典型案例如写入设备名时未做完整性校验,造成 buffer overflow。
2.4 选型权衡
| 维度 | 读请求/响应 | 写请求/响应 | 写命令 | 通知 | 指示 |
|---|---|---|---|---|---|
| 可靠性 | 高(有响应) | 高 | 低(无确认) | 低 | 高(有确认) |
| 吞吐量 | 低(往返延迟) | 低 | 高(无等待) | 高 | 低 |
| 实现复杂度 | 低 | 低 | 极低 | 低 | 中(需维护确认状态) |
| 功耗 | 中 | 中 | 低 | 低 | 中(额外确认包) |
| 典型使用 | 配置读取 | 写入关键参数 | 实时数据流 | 频繁采样上报 | 关键事件通知 |
2.5 落地步骤与验收标准
- 定义属性权限矩阵:在数据库配置中明确每种特征值的
read_permission、write_permission、notify、indicate属性,并关联安全等级(加密/认证/无)。 - 实现 ATT 分发器:在 ATT 层依据 OPcode 将 PDU 路由到对应的 GATT 操作处理器,避免应用层直接解析 ATT PDU。
- 测试覆盖:
# 验收用例(假设设备提供 Battery Level 服务) # 1. 正常读请求 → 期望收到读响应,值正确 att_tester send 0x0A 0x01 0x02 0x03 ... # Read By Type Request # 2. 写命令(无需响应)→ 不发送响应,状态变更 att_tester send 0x52 0x01 0x02 0x0A 0x0B # Write Command # 3. 通知使能后,服务器发送通知 → 客户端接收到 Handle Value Notification att_tester expect 0x1B 0x0A 0x0B ... # Handle Value Notification - 压力与边界:验证 MTU 分割后多包读写的完整性;验证写命令在连接断开后未交付的数据不残留。
验收标准:所有读请求必须在 30ms 内得到响应(BLE 4.0+ 典型间隔);写命令的丢包率应 ≤ 0.1% 且不影响 GATT 状态机;通知与指示的序列号不重复且不跳变。