news 2026/10/1 10:27:57

BLE GATT / ATT 基础

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BLE GATT / ATT 基础

BLE GATT / ATT 抓包实战

BLE GATT / ATT 基础 —— 属性、Handle、Characteristic 与 ATT 协议

  • 一、GATT 是什么
    • 1.1 GATT 站在哪一层
    • 1.2 GATT 和 ATT 的关系
    • 1.3 属性(Attribute)—— GATT 的最小单位
    • 1.4 Handle(句柄)—— GATT 的"地址"
    • 1.5 UUID —— 属性的"类型标识"
    • 1.6 常见标准 UUID 速查
    • 1.7 GATT 层级结构
  • 二、Characteristic 的完整解剖
    • 2.1 一个 Characteristic 至少占 2 个属性
    • 2.2 Properties 位域
    • 2.3 Notification vs Indication
    • 2.4 CCCD(0x2902)—— 通知开关
  • 三、ATT 协议
    • 3.1 ATT 在协议栈的位置
    • 3.2 ATT 的 6 种 PDU 类型
    • 3.3 ATT PDU 的通用格式
    • 3.4 PDU 详细 opcode 速查
      • 3.4.1 Requests(需要 Response)
      • 3.4.2 Responses
      • 3.4.3 Commands(不需要 Response)
      • 3.4.4 Notifications
      • 3.4.5 Indications
      • 3.4.6 Confirmations
    • 3.5 ATT_MTU
    • 3.6 ATT 错误处理:Error Response(0x01)

一、GATT 是什么

1.1 GATT 站在哪一层

应用层(心率应用) ↑ ( GATT Generic Attribute Profile ) ← 数据组织规范 ↑ 基于 ( ATT Attribute Protocol ) ← 传输协议,本文重点 ↑ 基于 L2CAP(逻辑链路控制与适配协议,CID = 0x0004) ↑ 基于 Link Layer(链路层) ↑ 基于 Physical Layer(1M / 2M / Coded PHY)

记住这条链:GATT 基于 ATT,ATT 跑在 L2CAP CID 0x0004 上,L2CAP 跑在链路层上。 抓包时从上往下解,每一层都有自己的头部。

1.2 GATT 和 ATT 的关系

协议角色类比
ATT传输协议:定义"怎么读写数据"像 SQL 语言(SELECT/UPDATE)
GATT框架/规范:定义"数据怎么组织"像数据库表结构规范(有哪些表、字段)

1.3 属性(Attribute)—— GATT 的最小单位

一个属性包含4 个部分:

组成部分说明例子
Attribute Handle属性的 “门牌号”(16-bit)0x000d
Attribute Type属性的类型(用 UUID 表示)0x2a01(Appearance)
Attribute Value属性的实际值0x0341(心率带)
Attribute Permissions读/写权限Read Only / Read+Write

⚠️ 注意:Permissions 不出现在空口上,它是服务端内部的安全策略。空口上客户端只能看到 Properties(见第 2.2 节)。

1.4 Handle(句柄)—— GATT 的"地址"

为什么需要 Handle?为什么不直接用 UUID 来读写数据?
因为:同一个 UUID 可能出现多次,但 Handle 是全局唯一的。

比如一个设备可能有 3 个温度传感器特征,UUID 都是0x2A6E,但 handle 分别是0x0012、0x0018、0x0024。

Handle 的特点:

特点说明
16-bit范围0x0001~0xFFFF
服务器分配GATT Server(板子)在建库时分配
单调递增通常按声明顺序递增
客户端靠它操作所有 ATT 请求都填 handle
UUID 靠它发现客户端先通过发现流程知道"handle X 是 UUID Y"

核心结论:所有 ATT 操作(读/写/通知)都是针对 handle 的,不是针对 UUID。

1.5 UUID —— 属性的"类型标识"

两种长度:

类型长度格式用途
16-bit UUID2 字节0x180D蓝牙 SIG 定义的标准类型
128-bit UUID16 字节0000180D-0000-1000-8000-00805F9B34FB厂商自定义

转换规则:蓝牙 SIG 定义了一个基础 UUID(Base UUID)

00000000-0000-1000-8000-00805F9B34FB ↑ 这 16 位用 16-bit UUID 替换

所以:

0x180D → 0000180D-0000-1000-8000-00805F9B34FB 0x2A37 → 00002A37-0000-1000-8000-00805F9B34FB

💡 因为 16-bit UUID 都能无损展开成 128-bit,所以协议里传输 16-bit UUID 只是省带宽,两者语义完全等价。

1.6 常见标准 UUID 速查

服务(Service)

UUID名称
0x1800Generic Access(GAP)
0x1801Generic Attribute(GATT)
0x180ADevice Information
0x180DHeart Rate⭐
0x180FBattery⭐
0x1812Human Interface Device(HID)
0x110AAudio Source

特征(Characteristic)

UUID名称
0x2A00Device Name
0x2A01Appearance(外观)
0x2A04Peripheral Preferred Connection Parameters(PPCP)
0x2A19Battery Level⭐
0x2A37Heart Rate Measurement⭐
0x2A38Body Sensor Location
0x2A39Heart Rate Control Point
0x2A29Manufacturer Name
0x2A24Model Number

声明/描述符(Declaration / Descriptor)

UUID名称作用
0x2800Primary Service声明"这是一个主服务"
0x2801Secondary Service声明次服务
0x2802Include引用其他服务
0x2803Characteristic声明"这是一个特征"
0x2902Client Characteristic ConfigurationCCCD,控制通知开关⭐
0x2901Characteristic User Description人类可读描述
0x2900Characteristic Extended Properties扩展属性
0x2904Characteristic Presentation Format数据格式(单位、指数等)

1.7 GATT 层级结构

Profile (规范,非协议实体) │ ├── Service 1 (服务,如心率服务 0x180D) │ │ │ ├── Characteristic 1 (特征,如心率测量 0x2A37) │ │ ├── Declaration(声明,UUID 0x2803) │ │ ├── Value(值,UUID 0x2A37) │ │ └── Descriptor(描述符,如 CCCD 0x2902) │ │ │ └── Characteristic 2 (如 Body Sensor Location 0x2A38) │ ├── Declaration(0x2803) │ └── Value(0x2A38) │ └── Service 2 (如电池服务 0x180F) │ └── Characteristic Battery Level(0x2A19) ├── Declaration(0x2803) ├── Value(0x2A19) └── CCCD(0x2902)
概念说明是否协议实体
Profile一组服务的 “规范/约定”(如 “心率 Profile” 规定了必须有 HRS + DIS)❌ 概念,不是实体
Service一组相关特征的集合✅ 实体
Characteristic数据的基本单位✅ 实体
Descriptor特征的附加元数据✅ 实体

二、Characteristic 的完整解剖

2.1 一个 Characteristic 至少占 2 个属性

一个 Characteristic 在 GATT 表里占用至少 2 个属性(Attribute):

属性 1:Characteristic Declaration(特征声明)

UUID = 0x2803,Value 包含 3 个部分:

字段长度说明
Properties1 字节读/写/通知权限(位域,见 2.3)
Value Handle2 字节特征值的 handle(指向下一个属性)
Characteristic UUID2 或 16 字节特征的 UUID

2.1.2 属性 2:Characteristic Value(特征值)

  • UUID= 特征本身的 UUID(如0x2A37)
  • Value= 实际数据

属性 3+:Descriptors(可选)

  • 如 CCCD(0x2902)。

2.2 Properties 位域

Properties 是1 字节的位域,定义在 Characteristic Declaration 里:

Bit名称含义
0Broadcast允许广播该特征值
1Read允许读
2Write Without Response允许写,不需要回应
3Write允许写,需要回应
4Notify允许通知(服务端主动发,无确认)
5Indicate允许指示(服务端主动发,需确认)
6Authenticated Signed Writes允许签名写
7Extended Properties有扩展属性

速记常数值:

Properties 值拆解含义
0x02bit1Read
0x08bit3Write
0x0Abit1 + bit3Read + Write
0x10bit4Notify
0x12bit1 + bit4Read + Notify
0x20bit5Indicate

2.3 Notification vs Indication

这是 GATT 数据上报的两种方式:

对比NotificationIndication
Opcode0x1B(Handle Value Notification)0x1D(Handle Value Indication)
方向Server → ClientServer → Client
应用层确认?❌ 不需要✅ 需要(Client 回0x1EConfirmation)
链路层 ACK✅ 有✅ 有
可靠性较低(可能丢)较高(有确认)
速率快(可连发)慢(要等确认)
触发条件写 CCCD =0x0001写 CCCD =0x0002
典型用途传感器数据(心率、温度)关键告警、状态变更

Notification 的 “不需要确认” 是指应用层不确认,但链路层仍然有 ACK 和重传机制。 所以 Notification 在链路层是可靠的,只是应用层不知道对方有没有收到。

2.4 CCCD(0x2902)—— 通知开关

CCCD =Client Characteristic Configuration Descriptor,是客户端用来控制服务端是否发通知的开关。

值含义
0x0000关闭通知和指示
0x0001使能Notification
0x0002使能Indication
0x0003同时使能(很少用)

为什么需要 CCCD?
因为服务端(板子)不知道客户端(手机)想不想收通知。所以:

  • 手机连接后,写 CCCD =0x0001告诉板子:“我要收通知”
  • 板子收到后,才在特征值变化时发 Notification
  • 如果手机不写,板子不会主动发任何通知

三、ATT 协议

3.1 ATT 在协议栈的位置

GATT(数据组织规范:Service / Characteristic / Descriptor) ↑ 基于 ATT(传输协议:Read / Write / Notify / Indicate) ← 这一层 ↑ 基于 L2CAP(CID = 0x0004,固定给 ATT 用) ↑ 基于 Link Layer

ATT 占用的 L2CAP 通道是固定的CID = 0x0004。

3.2 ATT 的 6 种 PDU 类型

类型方向需要回应?典型 opcode
RequestClient → Server✅ 必须等 Response0x08Read By Type Req
ResponseServer → Client—(本身就是回应)0x09Read By Type Rsp
CommandClient → Server❌ 不等0x52Write Command
NotificationServer → Client❌ 不确认0x1B
IndicationServer → Client✅ 需 Confirmation0x1D
ConfirmationClient → Server—(回应 Indication)0x1E

3.3 ATT PDU 的通用格式

┌──────────┬─────────────────────────┐ │ Opcode │ Parameters(参数) │ │ 1 byte │ 长度取决于 opcode │ └──────────┴─────────────────────────┘

Opcode 的位结构(严格定义)

Bit: 7 6 5 4 3 2 1 0 ┌────────┬────────┬──────────────────────────┐ │AuthSig │Command │ Method │ │ Flag │ Flag │ (6 bits) │ └────────┴────────┴──────────────────────────┘
位名称含义
Bit 7Auth Sig Flag1 = 该 PDU 带认证签名
Bit 6Command Flag1 = Command(不需回应);0 = Request(需回应)
Bit 0~5Method方法编号(0~63),决定 “做什么操作”

💡这个位结构解释了那些 “奇怪的” opcode 值:

所有 Write 操作的Method 字段都是0x12,区别只在上面两个 flag 位:

完整 Opcode二进制bit7 AuthSigbit6 CommandMethod名称
0x120001 0010000x12WriteRequest(要回应)
0x520101 0010010x12WriteCommand(不回应)
0xD21101 0010110x12SignedWrite Command(带签名)

3.4 PDU 详细 opcode 速查

3.4.1 Requests(需要 Response)

Opcode名称作用
0x02Exchange MTU Request协商 MTU
0x04Find Information Request查某 handle 的类型
0x08Read By Type Request按 UUID 查属性
0x0ARead Request按 handle 读值
0x10Read By Group Type Request按 UUID 查一组(服务发现)
0x12Write Request写值(要回应)
0x16Prepare Write Request准备写(长数据分块)
0x18Execute Write Request执行写(提交分块)

特点:Client 发完必须等 Response,期间不能发第二个 Request(串行)。

3.4.2 Responses

Opcode名称
0x01Error Response(任何请求失败都回这个)
0x03Exchange MTU Response
0x05Find Information Response
0x09Read By Type Response
0x0BRead Response
0x11Read By Group Type Response
0x13Write Response

3.4.3 Commands(不需要 Response)

Opcode名称用途
0x52Write Command快速写,不等回应(如串口透传 TX)
0xD2Signed Write Command带签名的写

特点:Client 发完就走,可以连发多个(流控靠链路层)。

3.4.4 Notifications

Opcode名称
0x1BHandle Value Notification

Server 主动发,Client 不回任何确认。

3.4.5 Indications

Opcode名称
0x1DHandle Value Indication

Server 主动发,Client 必须回 Confirmation。

3.4.6 Confirmations

Opcode名称
0x1EHandle Value Confirmation

Client 回应 Indication。

3.5 ATT_MTU

ATT_MTU = ATT 层一次能传输的最大字节数。

项值
默认 ATT_MTU23 字节
最大 ATT_MTU517 字节
协商方式Exchange MTU Request(0x02)/ Response(0x03)

为什么默认是 23?

链路层 payload 默认 27 字节 - L2CAP 头 4 字节 = 23 字节 ← ATT_MTU 默认值

这就是 ATT_MTU 和 DLE 的绑定关系:想让 ATT_MTU 变大,必须先把链路层的 DLE 协商上去。否则链路层一次只能装 27 字节,MTU 再大也没用。

MTU 协商流程

Client → Server: Exchange MTU Request (Client RX MTU = 247) Server → Client: Exchange MTU Response (Server RX MTU = 65) ──────────────────────────────────────────────────────── 最终 ATT_MTU = min(247, 65) = 65

和 DLE 一样,也是取min。

MTU 对实际数据的影响

Notification 的 PDU 格式:

[1 byte opcode][2 bytes handle][Value...]

所以实际能传的数据 = ATT_MTU - 3:

ATT_MTUNotification 最大数据
2320 字节
6562 字节
247244 字节
517514 字节

📌 这解释了那个经典数字:BLE 4.0/4.1 时代一次通知最多只能带 20 字节有效数据(23 - 3)。

3.6 ATT 错误处理:Error Response(0x01)

当任何 Request 失败时,Server 返回 Error Response:

┌────────┬─────────────────────────┬───────────────────────────┬─────────────┐ │ Opcode │ Request Opcode In Error │ Attribute Handle In Error │ Error Code │ │ 1 byte │ 1 byte │ 2 bytes │ 1 byte │ └────────┴─────────────────────────┴───────────────────────────┴─────────────┘
字段含义
Request Opcode In Error哪个请求出错了
Attribute Handle In Error哪个 handle 出问题
Error Code错误原因

常见错误码

Code名称含义
0x01Invalid Handlehandle 不存在
0x02Read Not Permitted不允许读
0x03Write Not Permitted不允许写
0x05Insufficient Authentication需要认证(配对)
0x06Request Not Supported不支持该请求
0x07Invalid Offset偏移错误
0x08Insufficient Authorization需要授权
0x0AAttribute Not Found找不到属性
0x0CInsufficient Encryption Key Size密钥长度不够
0x0DInvalid Attribute Value Length值长度错误

★ 0x0A Attribute Not Found 的特殊用途

服务发现就是靠这个错误码 "结束"的!

Client: Read By Group Type Request (handle 0x0001~0xffff) Server: Read By Group Type Response (服务 1, 2, 3) Client: Read By Group Type Request (handle 0x0015~0xffff) ← 从下一个 handle 继续 Server: Read By Group Type Response (服务 4, 5) Client: Read By Group Type Request (handle 0x0020~0xffff) Server: Error Response (0x0A Attribute Not Found) ← 没有了!

收到0x0A,客户端就知道 “所有服务都发现完了”。

这是一个非常巧妙的设计 —— 用错误码表示 “迭代结束”。所以抓包里看到0x0A不要慌,在发现流程里它是正常的终止信号,不是故障。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 10:27:00

多Agent调度容错:节点失败后如何让工作流继续运行

先问个问题:你跑过多Agent编排吗?就是那种把大活拆成几个角色,各自调用模型、工具、API,最后拼出一个结果的工作流。如果你跑过,大概率经历过这个场面——5个Agent并行跑,其他4个都快出结果了,突…

作者头像 李华
网站建设 2026/10/1 10:26:37

WeKnora实战:多智能体检索增强引擎如何解决RAG知识库难题

最近项目组要搭一套私有知识库,我把 Dify、RAGFlow、FastGPT 基本试了个遍,结果都卡在同一个地方:文档进来之后,看似能聊,实际问答一追细节就露馅——要么答非所问,要么引用来源张冠李戴。后来看到微信团队…

作者头像 李华
网站建设 2026/10/1 10:26:28

写在前面:这套测试到底在测什么

缘起 电力监控系统里,104 规约(IEC 60870-5-104)过去是明文跑的,谁都能在链路上看,也能往里塞东西。IEC 62351-3 就是来解决这个问题的,它把 TLS 套在 TCP 之上,让 104 的报文有了加密和双向认…

作者头像 李华
网站建设 2026/10/1 10:26:04

DDoS+CC综合防护、WAF 与边缘加速怎么选?同入口与分层部署对比测评

摘要 大促当晚的告警最能暴露分层问题。某次活动中,监控大屏同时出现三种异常:入口带宽十分钟内冲到日常峰值的数倍,应用层请求量翻了几番而单个请求都很小,商品详情页响应时间从 300 毫秒涨到 2 秒。三者分别指向流量型攻击、应用…

作者头像 李华
网站建设 2026/10/1 10:24:28

自动售货机品牌怎么选?从技术路线到售后网络,六个维度拆解选购标准

自动售货机行业品牌众多,但真正具备自有工厂、自主研发能力和全国售后网络的厂家并不多。本文从技术路线、产品矩阵、后台系统、售后覆盖、费用模式、资质认证六个维度,梳理选购自动售货机时的评估标准,供采购时参考。一、技术路线&#xff1…

作者头像 李华
网站建设 2026/10/1 10:16:27

PUBG‑Ally:具备对话能力的具身游戏AI队友智能体

PUBG‑Ally:具备对话能力的具身游戏AI队友智能体 arXiv编号:arXiv:2609.29837v1 摘要 本文介绍PUBG‑Ally(简称Ally),部署在《绝地求生》中的语音交互具身智能体,它可以自主推理、执行游戏动作,作为AI队友和真人玩家并肩作战。开发该AI队友需要同时攻克两大难点:严格延…

作者头像 李华