BLE GATT / ATT 抓包实战
BLE GATT / ATT 基础BLE GATT / ATT 抓包实战——服务发现全流程与心率数据流一、服务发现全流程1.1 BLE 协议栈的经典封装1.2 实例Read By Type查 Appearance 0x2a011.3 服务发现Read By Group Type0x10 / 0x111.3.1 第一次服务发现1.3.2 第二批服务1.3.3 服务发现结束1.4 特征发现Read By TypeUUID 0x28031.4.1 请求帧1.4.2 响应帧1.4.3 Database Hash0x2b2a1.4.4 特征发现结束1.5 Find Information0x04 / 0x05查描述符1.6 Include Declaration 查询0x28021.7 ★ GATT 发现模式总结二、peripheral_hr 的完整属性表2.1 GAP Service0x18002.2 Battery Service0x180F2.3 Device Information Service0x180A2.4 ★ Heart Rate Service0x180D2.5 订阅与数据上报2.6 完整属性表总览一、服务发现全流程1.1 BLE 协议栈的经典封装链路层BLE LL ├── Header └── L2CAP ├── CID: 0x0004 Attribute Protocol (ATT) └── ATT PDU ├── Opcode: Read By Type Request / Response └── Payload链路层头部字段字段值含义LLID0x2Start of an L2CAP message这是一个新的 L2CAP 消息的开始NESN1 / 0确认号Next Expected Sequence NumberSN0 / 1序列号Sequence NumberMDFalse / True第一个包 MDFalse第二个 MDTrueLength11 / 10链路层 payload 长度L2CAP 层字段值含义Length7 / 6L2CAP payload 长度CID0x0004Attribute Protocol说明上面是 ATT 层1.2 实例Read By Type查 Appearance 0x2a01第 1 个包Read By Type Request0x08—— 手机 → 板子Opcode: 0x08 Starting Handle: 0x0001 Ending Handle: 0xffff UUID: Appearance (0x2a01)手机在问什么“从 handle0x0001到0xffff范围内找到所有类型为 Appearance0x2a01的属性把值发给我。”第 2 个包Read By Type Response0x09—— 板子 → 手机Opcode: 0x09 Length: 4 Attribute Data: Handle: 0x000d Value: 0x0341板子回应“handle0x000d这个属性是 Appearance它的值是0x0341。”0x0341 Heart Rate Belt心率带1.3 服务发现Read By Group Type0x10 / 0x11这组包是服务发现的核心手机用 Read By Group Type 查板子有哪些 Primary Service。1.3.1 第一次服务发现第一次回应里列了 3 个服务ServiceHandle 范围UUIDGATT0x0001 ~ 0x00080x1801GAP0x0009 ~ 0x000f0x1800Battery0x0010 ~ 0x00140x180fRead By Type 和 Read By Group Type 的区别Read By Type0x08/0x09Read By Group Type0x10/0x11查什么按 UUID 读取单个属性值按 UUID 读取一组属性返回handle value这个组的范围start ~ end handle典型用途读特征声明或特征值服务发现为什么是 0x0001 ~ 0xffff这是第一次做服务发现时的标准做法从第一个可能存在的 handle0x0001到最后一个0xffff全扫一遍。但因为ATT_MTU 限制一次可能装不下所有服务。板子会尽可能返回如果还有未返回的服务手机会继续发下一次请求用上一次返回的最后一个 End Group Handle 1作为新的 Starting Handle。• 第一次请求 Start 0x0001, End 0xffff, UUID 0x2800• 板子返回 3 个服务最后一个 End Group Handle 0x0014• 第二次请求 Start 0x0015, End 0xffff, UUID 0x2800← 从0x0015继续扫• 直到返回空或 Error ResponseAttribute Not Found0x0A说明查完了1.3.2 第二批服务ServiceHandle 范围UUIDDevice Information0x0015 ~ 0x00190x180aHeart Rate0x001a ~ 0x00210x180d1.3.3 服务发现结束0x0022上什么都没有服务发现到此结束。这个0x0A错误不是真的 “错误”而是协议规定的结束标志。1.4 特征发现Read By TypeUUID 0x28031.4.1 请求帧手机在问板子从 handle0x0001到0x0008之间所有 UUID 为0x2803的「Characteristic Declaration特征声明」有哪些。在 GATT 里每个特征都由Declaration声明和一个Value值组成。 Declaration 的 UUID固定为 0x2803Value 的 UUID 才是具体特征 UUID如0x2a05Service Changed。1.4.2 响应帧Read By Type Response 的 Length 7Characteristic 长度 2 (Handle) 1 (Properties) 2 (Value Handle) 2 (UUID) 7 字节特征 1Service Changed0x2a05字段值含义Declaration Handle0x0002这是特征声明本身的位置Characteristic Value Handle0x0003真正的特征值在 handle 0x0003Characteristic UUID0x2a05Service ChangedProperties0x20Indicate只支持 Indication不支持 Read/Write/NotifyService Changed 是干什么用的当服务端板子的属性表服务/特征发生变化时会通过这个特征发 Indication 告诉客户端手机。客户端收到后要回 Handle Value Confirmation0x1E。为什么 Declaration Handle 是0x0002和0x0005中间跳过了0x00040x0004没有出现在这次响应里因为它不是 0x2803 类型的特征声明。合理推断它是Service Changed 的 CCCD0x2902用来让客户端开启/关闭 Indication。后面 1.5 节的 Find Information 会证实这一点板子回复0x0004就是0x2902。特征 2Client Supported Features0x2b29字段值含义Declaration Handle0x0005特征声明位置Characteristic Value Handle0x0006特征值在 handle 0x0006Characteristic UUID0x2b29Client Supported FeaturesProperties0x0aRead WriteClient Supported Features 是干什么用的手机端写入自己支持的 GATT 高级特性标志位比如 Enhanced ATT bearer 支持等。这是BLE 5.1引入的 GATT 特性协商机制。1.4.3 Database Hash0x2b2a手机从0x0006开始继续查 Characteristic Declaration。0x2b2a是Database Hash也是BLE 5.1引入的 GATT 特性用于让客户端缓存服务端属性表哈希避免重复做完整服务发现。 这是个很实用的优化手机第二次连同一个设备时如果 Database Hash 没变就可以直接用缓存的 GATT 表跳过整个发现流程 ——连接速度会快很多。1.4.4 特征发现结束收到0x0A→ GATT Service 里的 Characteristic Declaration 已经查完了。1.5 Find Information0x04 / 0x05查描述符Find Information 的作用是查询指定 handle 范围内每个属性的 UUID。它不回 value只回 “handle UUID”。板子回复0x0004是 Client Characteristic Configuration0x2902—— 证实了 1.4.2 节的推断。为什么手机要专门查这个 CCCD因为 Service Changed 的 Properties 是0x20 Indicate。要接收 Indication客户端必须找到这个特征对应的 CCCDUUID0x2902向 CCCD 写入0x0002bit1 Indication 使能Find Information 和 Read By Type 的区别Find Information0x04/0x05Read By Type0x08/0x09查什么handle 对应的 UUID指定 UUID 类型的属性值返回内容handle UUIDhandle value典型用途发现描述符如 CCCD读特征声明或特征值是否带 UUID 过滤不带带可以这样记Read By Type 是 “按类型找值”Find Information 是 “按 handle 找类型”1.6 Include Declaration 查询0x2802Include Declaration 用于一个服务 “引用” 另一个服务。比如某个自定义服务可能 Include 一个 Battery Service这样客户端发现主服务时就能知道里面还嵌套了另一个服务但 GAP Service0x1800是标准服务通常自己独立存在不会 Include 别的服务。所以这里返回0x0A是预期行为。1.7 ★ GATT 发现模式总结对每个 Primary Service客户端按这个固定套路走for 每个 Primary Service: 1. Read By Type Req (UUID0x2802) → 查 Include 2. Read By Type Req (UUID0x2803) → 查 Characteristic 3. 如果特征支持 Notify/Indicate: Find Information Req → 查该特征附近的 Descriptors主要是 CCCD把整个流程串起来① Read By Group Type Req (0x2800) → 发现所有主服务可能分多批0x0A 结束 │ ├─ 对每个服务 │ ② Read By Type Req (0x2802) → 查 Include通常 0x0A │ ③ Read By Type Req (0x2803) → 发现特征声明拿到 Properties Value Handle │ ④ Find Information Req (0x04) → 发现描述符找 CCCD │ ⑤ 对需要订阅的特征Write Req (0x12) 写 CCCD 0x0001 / 0x0002 │ ⑥ 之后 Server 就开始发 Notification (0x1B) / Indication (0x1D)GATT 服务0x1801完整属性表Handle内容属性类型值 / Properties0x0001GATT 服务声明0x2800值 0x1801GATT 服务 UUID0x0002Service Changed 声明0x2803Properties 0x20 (Indicate)Value Handle 0x00030x0003Service Changed 值0x2a05—0x0004Service Changed CCCD0x2902—0x0005Client Supported Features 声明0x2803Properties 0x0a (Read Write)Value Handle 0x00060x0006Client Supported Features 值0x2b29—0x0007Database Hash 声明0x2803Properties 0x02 (Read)Value Handle 0x00080x0008Database Hash 值0x2b2a—二、peripheral_hr 的完整属性表2.1 GAP Service0x1800Handle内容属性类型值0x0009GAP 服务声明0x28000x1800GAP 服务 UUID0x000aDevice Name 声明0x2803Properties 0x02Value Handle 0x000b0x000bDevice Name 值0x2a00设备名0x000cAppearance 声明0x2803Properties 0x02Value Handle 0x000d0x000dAppearance 值0x2a010x0341心率带0x000ePPCP 声明0x2803Properties 0x02Value Handle 0x000f0x000fPPCP 值0x2a048 字节连接参数偏好1. Device Name0x2a00设备名称比如 “Zephyr” 或 “Zephyr Heartrate Sensor”只读Properties 0x022. Appearance0x2a01设备外观图标分类板子返回0x0341 Heart Rate Belt心率带只读3. Peripheral Preferred Connection Parameters0x2a04PPCP外围设备偏好的连接参数Value 是 8 字节字段长度Minimum Connection Interval2 bytesMaximum Connection Interval2 bytesSlave Latency2 bytesConnection Supervision Timeout2 bytes只读供中央设备手机参考2.2 Battery Service0x180FHandle内容属性类型值0x0010Battery 服务声明0x28000x180FBattery 服务 UUID0x0011Battery Level 声明0x2803Properties 0x12Value Handle 0x00120x0012Battery Level 值0x2a19电量百分比0x0013CCCD0x2902通知开关0x0014Characteristic Presentation Format0x2904百分比格式0x2904Characteristic Presentation Format是 “特征展示格式”用来描述 Battery Level 的数据格式比如百分比、单位、指数等。2.3 Device Information Service0x180AHandle内容属性类型值0x0015DIS 服务声明0x28000x180ADevice Information 服务 UUID0x0016Model Number 声明0x2803Properties 0x02Value Handle 0x00170x0017Model Number 值0x2a24型号字符串0x0018Manufacturer Name 声明0x2803Properties 0x02Value Handle 0x00190x0019Manufacturer Name 值0x2a29厂商字符串两个特征都是 Read only0x02用来读设备型号和厂商名称。2.4 ★ Heart Rate Service0x180DHandle内容属性类型值0x001aHRS 服务声明0x2800值 0x180DHeart Rate 服务 UUID0x001bHR Measurement 声明0x2803Properties Notify (0x10)Value Handle 0x001c0x001cHR Measurement 值0x2a37—0x001dCCCD0x2902—0x001eBody Sensor Location 声明0x2803Properties Read (0x02)Value Handle 0x001f0x001fBody Sensor Location 值0x2a38—0x0020HR Control Point 声明0x2803Properties Write (0x08)Value Handle 0x00210x0021HR Control Point 值0x2a39—1. Heart Rate Measurement0x2a37只支持 Notify真正的心率数据从这里上报要接收数据手机需要写 CCCD0x001d为0x00012. Body Sensor Location0x2a38只读描述传感器位置比如胸口、手腕、手指等值是一个枚举0x00 Other,0x01 Chest,0x02 Wrist …3. Heart Rate Control Point0x2a39只写用于控制心率计比如重置能量消耗累计值2.5 订阅与数据上报第 1 步手机写 CCCDWrite Request 0x12字段值含义Opcode0x12Write RequestHandle0x001dHeart Rate Measurement 的 CCCDValue0x0001Notification 使能手机在告诉板子请开启 Heart Rate Measurement 的 Notification一有数据就发给我。第 2 步板子回应Write Response 0x13字段值含义Opcode0x13Write ResponseHandle0x001d对应刚才的 CCCD板子回给手机的确认已收到CCCD 写入成功Notification 已使能。第 3 步板子发通知Handle Value Notification 0x1B字段值含义Opcode0x1BHandle Value Notification服务器主动上报无需确认Handle0x001cHeart Rate Measurement 的特征值 handleFlags0x06数据格式标志位Value156心率值 156 bpm2.6 完整属性表总览Handle 范围服务关键内容0x0001 ~ 0x0008Generic Attribute (0x1801)Service Changed (0x2a05)、Client Supported Features (0x2b29)、Database Hash (0x2b2a)0x0009 ~ 0x000fGeneric Access (0x1800)Device Name (0x2a00)、Appearance (0x2a01 0x0341)、PPCP (0x2a04)0x0010 ~ 0x0014Battery (0x180F)Battery Level (0x2a19, ReadNotify)、CCCD、CPF (0x2904)0x0015 ~ 0x0019Device Information (0x180A)Model Number (0x2a24)、Manufacturer Name (0x2a29)0x001a ~ 0x0021Heart Rate (0x180D)HR Measurement (0x2a37, Notify) CCCD、Body Sensor Location (0x2a38)、HR Control Point (0x2a39)0x0022—空服务发现结束0x0A
上一篇/下一篇内容由系统自动关联
返回资讯列表 →