BLE之GATT原文

蓝牙核心规范 5.0 | 第 3 卷,G 部分

通用属性配置文件(GATT)

译自:BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G
Generic Attribute Profile (GATT)
日期:2016 年 12 月 6 日
版权所有 © 蓝牙技术联盟(Bluetooth SIG)


目录

  1. 简介
  2. 配置文件概述
  3. 服务互操作性要求
  4. GATT 功能需求
  5. L2CAP 互操作性要求
  6. GAP 互操作性要求
  7. GATT 服务定义
  8. 安全考虑
  9. SDP 互操作性要求
  10. 参考文献

1 简介

1.1 范围

本文档定义了通用属性配置文件(Generic Attribute Profile,GATT),该配置文件使用属性协议(Attribute Protocol,ATT)描述了一个服务框架,通过该框架可发现服务及服务相关特征(Characteristic)的配置和使用方式。

本文档适用于实现了属性协议的设备。

1.2 依赖

本文档依赖于以下蓝牙规范:

  • ATT(属性协议):Vol 3,E 部分
  • SDP(服务发现协议):Vol 3,B 部分
  • L2CAP(逻辑链路控制和自适应协议):Vol 3,A 部分
  • GAP(通用访问配置文件):Vol 3,C 部分

1.3 一致性

如果一个实现声明符合本文档,则该实现必须(shall)满足本文档中所有标注为强制性(Mandatory)的需求,并且应当(should)满足所有标注为推荐性(Recommended)的需求。

1.4 兼容性

本文档第 4 版(Version 4.0)中定义的特性与本文档完全兼容。

1.5 约定

本文档使用以下约定:

  • 强制性(M):在所有实现中必须支持该特性或过程。
  • 可选(O):该特性或过程的支持是可选的。
  • 条件(C):该特性或过程的支持取决于是否支持某其他特性或过程。
  • 排除(X):在该配置中该特性或过程不得被支持。
  • 推荐(R):建议支持该特性或过程,但并非强制性要求。
  • 禁止(P):该特性或过程不得被使用。

协议中用到的关键字含义如下:

  • shall(应当/必须):绝对要求
  • shall not(不得):绝对禁止
  • should(应该):建议,但有理由时可以不遵守
  • may(可以):可选行为
  • can(能够):关于可能性和能力的陈述

2 配置文件概述

2.1 协议栈

通用属性配置文件(GATT)位于属性协议(ATT)之上。GATT 定义了一个框架,用于通过 ATT 发现、读写属性,如图 2.1 所示。

+---------------------------+
|        应用程序            |
+---------------------------+
|  GATT(通用属性配置文件)   |
+---------------------------+
|  ATT(属性协议)           |
+---------------------------+
|  L2CAP(逻辑链路控制)      |
+---------------------------+
|  ACL(异步无连接链路)      |
+---------------------------+

图 2.1:GATT 协议栈

2.2 GATT 角色

GATT 定义了两种角色:

角色 描述
服务器(Server) 接收来自客户端的请求,接受、执行并响应任何 ATT 命令和请求。服务器包含用于存储数据的属性(Attribute)
客户端(Client) 向服务器发起命令和请求,并从服务器接收响应、通知和指示

注:GATT 角色独立于 BR/EDR 中的主/从角色,也独立于 LE 中的主/从角色。

2.3 用户需求

GATT 旨在满足以下用户需求场景:

  1. 体温计:测量并报告体温
  2. 血压计:测量并报告血压
  3. 运动/健康传感器:测量步速、步距、步数等
  4. 时间客户端/服务器:读取/写入当前时间
  5. 家庭自动化:控制家用电器
  6. 医疗设备:与医疗设备交互
  7. 电话:与手机交互
  8. 便携式媒体播放器:控制媒体播放

2.4 基础概念

2.4.1 属性(Attribute)

属性是可寻址的数据块,包含以下字段:

字段 长度 描述
属性句柄(Attribute Handle) 2 字节 在服务器中唯一标识该属性
属性类型(Attribute Type) 2 或 16 字节 使用 UUID 标识属性类型
属性值(Attribute Value) 可变长度 属性的实际数据内容
属性权限(Attribute Permissions) 由实现定义 控制属性的读/写访问权限及安全需求

2.4.2 属性句柄(Attribute Handle)

属性句柄是一个 16 位的非零值,范围为 0x0001 至 0xFFFF,用于在服务器中唯一标识一个属性。

  • 句柄 0x0000 保留不用
  • 句柄按升序分配
  • 服务器上的属性句柄不得在连接断开后重新分配

2.4.3 属性类型(Attribute Type)

属性类型使用 UUID(通用唯一标识符)来标识,UUID 可以是:

  • 16 位蓝牙 UUID:蓝牙技术联盟(Bluetooth SIG)分配的标准 UUID
  • 128 位供应商自定义 UUID:供应商或应用开发者自定义的 UUID

标准蓝牙 UUID 的完整 128 位格式为:

xxxxxxxx-0000-1000-8000-00805F9B34FB

其中 xxxxxxxx 为 16 位或 32 位的蓝牙 UUID 值。

2.4.4 属性值(Attribute Value)

属性值是一个可变长度的字节序列,其含义由属性类型(UUID)决定,长度为 0 至 512 字节。

2.4.5 属性权限(Attribute Permissions)

属性权限不通过 ATT 协议直接暴露,但控制以下访问方式:

  • 可读(Readable):允许读取属性值
  • 可写(Writeable):允许写入属性值
  • 读需要认证(Read Requires Authentication)
  • 读需要授权(Read Requires Authorization)
  • 读需要加密(Read Requires Encryption)
  • 写需要认证(Write Requires Authentication)
  • 写需要授权(Write Requires Authorization)
  • 写需要加密(Write Requires Encryption)

2.5 属性协议(ATT)

GATT 使用 ATT 协议传输服务相关数据。ATT 定义了客户端和服务器之间的通信规则:

通信类型 描述
命令(Command) 客户端发送给服务器,服务器不响应
请求(Request) 客户端发送给服务器,服务器必须响应
响应(Response) 服务器对请求的回复
通知(Notification) 服务器主动发送给客户端,无需确认
指示(Indication) 服务器主动发送给客户端,需要客户端确认
确认(Confirmation) 客户端对指示的确认回复

2.6 GATT 层次结构

GATT 使用以下数据层次结构组织数据:

配置文件(Profile)
└── 服务(Service)
    ├── 包含的服务(Included Service)
    └── 特征(Characteristic)
        ├── 特征值(Characteristic Value)
        └── 特征描述符(Characteristic Descriptor)

2.6.1 配置文件(Profile)

配置文件定义了特定用途场景下一个或多个服务的使用方法,配置文件本身不存储在服务器上。

2.6.2 服务(Service)

服务是相关行为的集合,由特征(Characteristic)和关系(包含其他服务)组成。服务有两类:

  • 主服务(Primary Service):提供主要功能,可被其他服务或客户端发现
  • 次要服务(Secondary Service):被其他服务引用,一般不直接使用

2.6.3 包含的服务(Included Service)

包含关系允许一个服务引用另一个服务,实现服务的复用。

2.6.4 特征(Characteristic)

特征包含:

  • 特征声明(Characteristic Declaration):定义特征的属性(Properties)、句柄和 UUID
  • 特征值(Characteristic Value):实际的数据内容
  • 特征描述符(Characteristic Descriptor)(可选):提供特征值的附加信息

2.6.5 特征属性(Characteristic Properties)

特征属性是一个位字段,定义了如何使用特征值及特征描述符:

属性名称 描述
0 广播(Broadcast) 可将特征值通过服务器特征配置描述符广播
1 读(Read) 可用 ATT 读操作读取特征值
2 无响应写入(Write Without Response) 可用 ATT 写命令写入特征值
3 写(Write) 可用 ATT 写请求写入特征值
4 通知(Notify) 服务器可主动发送通知
5 指示(Indicate) 服务器可主动发送需确认的指示
6 认证签名写入(Authenticated Signed Writes) 可用 ATT 签名写命令写入特征值
7 扩展属性(Extended Properties) 存在额外属性定义,详见特征扩展属性描述符

3 服务互操作性要求

本章描述服务和特征在服务器中的存储方式,以及如何被客户端读取和使用。

3.1 服务定义

服务定义包含一个服务声明(Service Declaration),以及零个或多个包含声明(Include Declaration)、特征定义(Characteristic Definition)。

服务声明属性(Service Declaration Attribute)

字段 要求 格式 描述
属性句柄 强制(M) 0x0001 ~ 0xFFFF 该服务声明的唯一句柄
属性类型 强制(M) 0x2800(主服务)或 0x2801(次要服务) 标识服务声明类型
属性值 强制(M) UUID 服务的 UUID(16 位或 128 位)
属性权限 强制(M) 可读,无需认证 可被任意客户端读取

主服务(Primary Service)使用 UUID 0x2800次要服务(Secondary Service)使用 UUID 0x2801

3.2 包含定义

包含定义允许一个服务内嵌引用另一个服务。

包含声明属性(Include Declaration Attribute)

字段 要求 格式 描述
属性句柄 强制(M) 0x0001 ~ 0xFFFF 该包含声明的句柄
属性类型 强制(M) 0x2802 标识包含声明
属性值 强制(M) 起始句柄、结束句柄(可选 UUID) 被包含服务的句柄范围,若为 16 位 UUID 服务则附带 UUID
属性权限 强制(M) 可读,无需认证 可被任意客户端读取

注:若被包含的服务使用 128 位 UUID,则包含声明的属性值中不包含 UUID,需通过被包含服务的服务声明属性读取 UUID。

3.3 特征定义

特征定义由以下部分组成:

  1. 特征声明(Characteristic Declaration)
  2. 特征值声明(Characteristic Value Declaration)
  3. 特征描述符声明(Characteristic Descriptor Declarations)(可选)

3.3.1 特征声明属性(Characteristic Declaration Attribute)

字段 要求 格式 描述
属性句柄 强制(M) 0x0001 ~ 0xFFFF 该特征声明的句柄
属性类型 强制(M) 0x2803 标识特征声明
属性值 强制(M) 特征属性(1字节)+ 特征值句柄(2字节)+ 特征 UUID 特征的属性、值句柄和类型
属性权限 强制(M) 可读,无需认证 可被任意客户端读取

3.3.2 特征值声明(Characteristic Value Declaration)

特征值声明包含特征的实际数据,其属性类型 UUID 与特征声明中的 UUID 相同。

字段 要求 格式 描述
属性句柄 强制(M) 特征声明属性值中的值句柄 特征值的句柄
属性类型 强制(M) 特征 UUID 与特征声明中的 UUID 相同
属性值 强制(M) 特征值 实际数据内容
属性权限 由特征属性决定 可读/可写等 由具体实现定义

3.3.3 特征描述符

特征描述符(Characteristic Descriptor)提供特征的附加元数据。以下是标准定义的描述符:


3.3.3.1 特征扩展属性描述符(Characteristic Extended Properties Descriptor)
  • UUID:0x2900
  • 属性权限:可读,无需认证
  • 属性值:2 字节位字段
属性名称 描述
0 可靠写入(Reliable Write) 可以使用 ATT 可靠写入过程(Reliable Write Procedure)写入特征值
1 可写辅助信息(Writable Auxiliaries) 特征用户描述符(Characteristic User Description Descriptor)可写
2~15 保留 保留供未来使用

3.3.3.2 特征用户描述符(Characteristic User Description Descriptor)
  • UUID:0x2901
  • 属性权限:可读(无需认证);若"可写辅助信息"位已设置则可写
  • 属性值:UTF-8 编码字符串,对特征的用户可读描述

3.3.3.3 客户端特征配置描述符(Client Characteristic Configuration Descriptor,CCCD)
  • UUID:0x2902
  • 属性权限:可读(无需认证);可写(每个客户端独立)
  • 属性值:2 字节位字段
名称 描述
0 通知(Notification) 0 = 禁用通知;1 = 启用通知
1 指示(Indication) 0 = 禁用指示;1 = 启用指示
2~15 保留 保留,应设为 0

重要:

  • 一个特征只能有一个 CCCD
  • 每个连接的客户端(通过地址区分)拥有独立的 CCCD 值
  • 断开连接后,非绑定(Non-bonded)设备的 CCCD 值将恢复为默认值(0x0000);绑定设备的 CCCD 值将被保留

3.3.3.4 服务器特征配置描述符(Server Characteristic Configuration Descriptor,SCCD)
  • UUID:0x2903
  • 属性权限:可读(无需认证);可写(全局性,不区分客户端)
  • 属性值:2 字节位字段
名称 描述
0 广播(Broadcast) 0 = 不通过广播发送;1 = 在广播的服务器特征配置中发送
1~15 保留 保留,应设为 0

注:一个特征只能有一个 SCCD,且仅当特征属性中"广播"位被设置时才能使用。


3.3.3.5 特征展示格式描述符(Characteristic Presentation Format Descriptor)
  • UUID:0x2904
  • 属性权限:可读,无需认证
  • 属性值:7 字节
字段 长度(字节) 描述
格式(Format) 1 特征值的数据格式(参见蓝牙分配号码)
指数(Exponent) 1 用于计算实际值:Actual Value = Characteristic Value × 10^Exponent(有符号整数)
单位(Unit) 2 值的单位,使用蓝牙 UUID(参见蓝牙分配号码)
命名空间(Namespace) 1 描述符命名空间(0x01 = 蓝牙技术联盟)
描述(Description) 2 在指定命名空间内的描述(0x0000 = 无描述)

常见的格式值(Format)示例:

格式值 格式名称 描述
0x01 boolean 1 位布尔值
0x04 uint8 8 位无符号整数
0x06 uint16 16 位无符号整数
0x08 uint32 32 位无符号整数
0x0C sint8 8 位有符号整数
0x0E sint16 16 位有符号整数
0x10 sint32 32 位有符号整数
0x14 float32 32 位 IEEE 754 浮点数
0x19 utf8s UTF-8 编码字符串
0x1B struct 不透明数据结构

若一个特征有多个展示格式描述符,则每个描述符描述特征值中一个字段的格式,且这些字段须按照句柄升序依次对应特征值中各字段。


3.3.3.6 特征聚合格式描述符(Characteristic Aggregate Format Descriptor)
  • UUID:0x2905
  • 属性权限:可读,无需认证
  • 属性值:特征展示格式描述符句柄列表(每个句柄 2 字节),定义特征值多个字段的格式组合方式

注:只有当一个特征包含多个特征展示格式描述符时,才可使用聚合格式描述符。


4 GATT 功能需求

本章描述 GATT 服务器和客户端支持的功能及其具体过程(Procedure)。

4.1 服务器配置(Server Configuration)

4.1.1 交换 MTU 大小(Exchange MTU Size)

此过程允许客户端通知服务器其接收 ATT 协议数据单元(PDU)的最大大小(MTU)。

角色 要求
客户端 可选(O)
服务器 可选(O)

过程描述

  1. 客户端发送 ATT 交换 MTU 请求(Exchange MTU Request),携带客户端 MTU 值
  2. 服务器回复 ATT 交换 MTU 响应(Exchange MTU Response),携带服务器 MTU 值
  3. 连接使用两者中的较小值作为最终 MTU

注:此过程只能执行一次,且只有在 BR/EDR 连接上才需要执行;LE 连接中可使用 LE L2CAP 连接参数更新代替。


4.2 主服务发现(Primary Service Discovery)

4.2.1 发现所有主服务(Discover All Primary Services)

此过程用于发现服务器上所有主服务。

角色 要求
客户端 可选(O)
服务器 强制(M),若存在主服务

过程描述

  1. 客户端发送 ATT 按类型读取属性组(Read By Group Type Request),属性类型为 主服务 UUID(0x2800),句柄范围为 0x0001 ~ 0xFFFF
  2. 服务器返回所有主服务的句柄范围和服务 UUID
  3. 客户端重复发送请求(从上次结束句柄 +1 开始),直到服务器返回错误响应(错误码:属性未找到)

4.2.2 按服务 UUID 发现主服务(Discover Primary Service by Service UUID)

此过程用于发现具有特定 UUID 的主服务。

角色 要求
客户端 可选(O)
服务器 强制(M),若存在主服务

过程描述

  1. 客户端发送 ATT 按类型和值查找(Find By Type Value Request),属性类型为 0x2800,属性值为目标服务 UUID
  2. 服务器返回找到的服务句柄范围列表
  3. 客户端继续发送请求直到收到错误响应

4.3 关系发现(Relationship Discovery)

4.3.1 查找包含的服务(Find Included Services)

此过程用于发现服务中包含(Include)的其他服务。

角色 要求
客户端 可选(O)
服务器 强制(M),若存在包含声明

过程描述

  1. 客户端发送 ATT 按类型读取(Read By Type Request),属性类型为 包含 UUID(0x2802),句柄范围为目标服务的范围
  2. 服务器返回找到的包含声明
  3. 若包含声明中未包含 UUID(即被包含服务使用 128 位 UUID),客户端再发送 ATT 读取请求(Read Request) 读取服务声明属性以获取 UUID
  4. 客户端重复操作直到遍历完服务范围

4.4 特征发现(Characteristic Discovery)

4.4.1 发现服务内所有特征(Discover All Characteristics of a Service)

此过程用于发现服务内的全部特征及其特征属性。

角色 要求
客户端 可选(O)
服务器 强制(M),若存在特征

过程描述

  1. 客户端发送 ATT 按类型读取(Read By Type Request),属性类型为 特征 UUID(0x2803),句柄范围为目标服务的范围
  2. 服务器返回特征声明列表(包含特征属性、特征值句柄、特征 UUID)
  3. 客户端重复操作直到遍历完服务范围

4.4.2 按 UUID 发现特征(Discover Characteristics by UUID)

此过程用于发现具有特定 UUID 的特征。

角色 要求
客户端 可选(O)
服务器 强制(M),若存在特征

过程描述

  1. 客户端发送 ATT 按类型读取(Read By Type Request),属性类型为目标特征的 UUID,句柄范围为目标服务的范围
  2. 服务器返回匹配的特征声明
  3. 客户端重复操作直到遍历完服务范围

4.5 特征描述符发现(Characteristic Descriptor Discovery)

4.5.1 发现所有特征描述符(Discover All Characteristic Descriptors)

此过程用于发现特征的所有描述符。

角色 要求
客户端 可选(O)
服务器 强制(M),若存在描述符

过程描述

  1. 客户端使用特征声明的值句柄 + 1 至下一特征声明的句柄 - 1(或服务结束句柄)作为范围,发送 ATT 查找信息请求(Find Information Request)
  2. 服务器返回该范围内所有属性的句柄和 UUID(即特征描述符)
  3. 客户端重复操作直到遍历完描述符范围

4.6 特征值读取(Reading Characteristic Values)

4.6.1 读取特征值(Read Characteristic Value)

角色 要求
客户端 可选(O)
服务器 强制(M),若特征属性包含"读"

过程描述

  1. 客户端发送 ATT 读取请求(Read Request),携带特征值句柄
  2. 服务器返回特征值(若权限允许)

注:ATT 读取请求的响应受 MTU 限制,最多返回 MTU - 1 个字节。如需读取完整长值,使用"读取长特征值"过程。

4.6.2 使用 UUID 读取(Read Using Characteristic UUID)

角色 要求
客户端 可选(O)
服务器 强制(M),若特征属性包含"读"

过程描述

  1. 客户端发送 ATT 按类型读取(Read By Type Request),属性类型为目标特征 UUID,句柄范围为目标服务或所有句柄的范围
  2. 服务器返回匹配特征的值

4.6.3 读取长特征值(Read Long Characteristic Values)

角色 要求
客户端 可选(O)
服务器 强制(M),若特征属性包含"读"

过程描述

  1. 客户端首先发送 ATT 读取请求(Read Request) 获取起始数据
  2. 若数据不完整(响应填满了 MTU),继续发送 ATT 读取 Blob 请求(Read Blob Request),指定偏移量
  3. 重复直到获取完整数据(响应未填满 MTU,或收到错误)

4.6.4 读取多个特征值(Read Multiple Characteristic Values)

角色 要求
客户端 可选(O)
服务器 强制(M)

过程描述

  1. 客户端发送 ATT 读取多个(Read Multiple Request),携带多个特征值句柄列表
  2. 服务器将所有特征值拼接在一起返回(按句柄顺序)

注:不适用于可变长度的特征值,因为无法确定各值边界。


4.7 特征值写入(Writing Characteristic Values)

4.7.1 写入特征值(Write Characteristic Value)

角色 要求
客户端 可选(O)
服务器 强制(M),若特征属性包含"写"

过程描述

  1. 客户端发送 ATT 写入请求(Write Request),携带特征值句柄和数据
  2. 服务器写入数据后发送 ATT 写入响应(Write Response)

4.7.2 无响应写入特征值(Write Without Response)

角色 要求
客户端 可选(O)
服务器 强制(M),若特征属性包含"无响应写入"

过程描述

  1. 客户端发送 ATT 写入命令(Write Command),携带特征值句柄和数据
  2. 服务器写入数据,不发送响应

4.7.3 认证签名写入特征值(Signed Write Without Response)

角色 要求
客户端 可选(O)
服务器 强制(M),若特征属性包含"认证签名写入"

过程描述

  1. 客户端发送 ATT 签名写入命令(Signed Write Command),携带特征值句柄、数据和认证签名
  2. 服务器验证签名后写入数据,不发送响应

注:仅可用于未加密的连接;若连接已加密,应使用普通写入命令。

4.7.4 写入长特征值(Write Long Characteristic Values)

角色 要求
客户端 可选(O)
服务器 强制(M),若特征属性包含"写"

过程描述

  1. 客户端发送多个 ATT 预写请求(Prepare Write Request),每次指定句柄、偏移量和部分数据
  2. 服务器将数据缓存后回应 ATT 预写响应(Prepare Write Response)
  3. 所有数据发送完毕后,客户端发送 ATT 执行写入请求(Execute Write Request),标志为 0x01(执行)
  4. 服务器原子性地写入所有数据并回应 ATT 执行写入响应(Execute Write Response)

客户端也可发送执行写入请求(标志 0x00)取消所有预写操作。

4.7.5 可靠写入(Reliable Writes)

角色 要求
客户端 可选(O)
服务器 强制(M),若支持可靠写入

过程描述

  1. 客户端发送 ATT 预写请求(Prepare Write Request)
  2. 服务器回应 ATT 预写响应(Prepare Write Response),响应中包含与请求相同的句柄、偏移量和数据
  3. 客户端验证响应中的数据与发送的数据一致(可靠性校验)
  4. 确认无误后,客户端发送 ATT 执行写入请求(标志 0x01)提交,或(标志 0x00)取消

4.8 通知(Notifications)

4.8.1 特征值通知(Notifications of Characteristic Values)

角色 要求
客户端 强制(M),若服务器支持通知
服务器 可选(O)

过程描述

  1. 客户端订阅通知:将 CCCD(0x2902) 中的通知位设置为 1
  2. 服务器在特征值变更时发送 ATT 句柄值通知(Handle Value Notification),携带特征值句柄和新值
  3. 客户端无需响应

4.9 指示(Indications)

4.9.1 特征值指示(Indications of Characteristic Values)

角色 要求
客户端 强制(M),若服务器支持指示
服务器 可选(O)

过程描述

  1. 客户端订阅指示:将 CCCD(0x2902) 中的指示位设置为 1
  2. 服务器在特征值变更时发送 ATT 句柄值指示(Handle Value Indication),携带特征值句柄和新值
  3. 客户端发送 ATT 句柄值确认(Handle Value Confirmation) 作为响应
  4. 服务器在收到确认前不得发送新的指示

4.10 特征描述符读写(Reading and Writing Characteristic Descriptors)

4.10.1 读取特征描述符(Read Characteristic Descriptors)

角色 要求
客户端 可选(O)
服务器 强制(M)

过程描述

  1. 客户端发送 ATT 读取请求(Read Request),携带描述符句柄
  2. 服务器返回描述符值

4.10.2 读取长特征描述符(Read Long Characteristic Descriptors)

(参见 4.6.3 读取长特征值,过程相同,将特征值替换为描述符)

4.10.3 写入特征描述符(Write Characteristic Descriptors)

角色 要求
客户端 可选(O)
服务器 强制(M)

过程描述

  1. 客户端发送 ATT 写入请求(Write Request),携带描述符句柄和数据
  2. 服务器写入后发送 ATT 写入响应(Write Response)

4.10.4 写入长特征描述符(Write Long Characteristic Descriptors)

(参见 4.7.4 写入长特征值,过程相同,将特征值替换为描述符)


4.11 服务器特征配置(Server Characteristics Configuration)

此功能允许客户端通过服务器特征配置描述符(SCCD)配置服务器行为,如启用特征值广播。

角色 要求
客户端 可选(O)
服务器 可选(O)

过程:客户端读写 SCCD(UUID 0x2903),设置广播位(Bit 0)以启用/禁用广播。


5 L2CAP 互操作性要求

本章描述 GATT 对 L2CAP 层的要求。

5.1 BR/EDR 上的 ATT

在 BR/EDR(经典蓝牙)连接上,ATT 协议使用 L2CAP 通道,PSM(协议/服务复用器)值为 0x001F

  • L2CAP 通道以 面向连接模式(Connection-oriented channel) 运行
  • 默认 MTU:48 字节(BR/EDR ATT 连接的初始 MTU)
  • 实现可以通过"交换 MTU 大小"过程协商更大的 MTU

5.2 LE 上的 ATT

在 LE(低功耗蓝牙)连接上,ATT 协议使用固定的 L2CAP 通道 ID 0x0004

  • L2CAP 通道以 不可靠模式(Unacknowledged mode) 运行(使用固定通道)
  • 默认 MTU:23 字节(LE ATT 的默认 MTU)
  • 实现可以通过"交换 MTU 大小"过程协商最大 517 字节 的 MTU

6 GAP 互操作性要求

本章描述 GATT 与通用访问配置文件(GAP)的关系及互操作性要求。

6.1 连接模式和过程

GAP 角色 GATT 角色 要求
外设(Peripheral) 服务器(Server) 通常担任此角色
中央(Central) 客户端(Client) 通常担任此角色
广播者(Broadcaster) N/A 仅发送广播数据,不使用 GATT
观察者(Observer) N/A 仅接收广播数据,不使用 GATT

注:设备可以同时担任 GATT 服务器和客户端。

6.2 安全模式

GATT 操作的安全级别:

安全级别 描述
1 级,模式 1 无安全要求(无需认证或加密)
1 级,模式 2 未经认证的加密
2 级,模式 1 经认证的加密
2 级,模式 2 需要授权

7 GATT 服务定义

GATT 服务(Generic Attribute Service)本身也通过 GATT 协议暴露。

7.1 服务定义

  • 服务 UUID0x1801(Generic Attribute)
  • 服务类型:主服务(Primary Service)

7.2 服务变更特征(Service Changed Characteristic)

字段
特征 UUID 0x2A05
特征属性 指示(Indicate)
特征值 两个 16 位无符号整数:受影响属性句柄范围的起始值和结束值

描述符

描述符 UUID 要求
客户端特征配置描述符(CCCD) 0x2902 强制(M)

用途

当服务器上的服务、包含关系或特征定义发生变更时,服务器应向已订阅指示的客户端发送"服务变更"特征的指示,通知客户端重新发现受影响范围内的属性。

  • 如果客户端与服务器之间存在绑定(Bonded)关系,且在连接断开期间服务发生了变更,则服务器必须在下次连接时发送该指示
  • 若设备不支持添加或删除服务,可以不包含此特征(可选)

8 安全考虑

8.1 概述

GATT 使用 ATT 协议传输数据,ATT 的安全性依赖于底层连接的安全模式。

8.2 属性权限与安全

属性的安全性由其权限决定:

  • 服务和特征的声明属性(Service Declaration、Characteristic Declaration)可被任意客户端读取,无需认证或加密
  • 特征描述符的访问安全性由具体配置文件定义
  • 若客户端尝试访问需要更高安全级别的属性,服务器应返回相应的 ATT 错误码(如"读取不允许"、"写入不允许"、"权限不足"等)

8.3 隐私与随机地址

当设备使用可解析随机私有地址(Resolvable Private Address)时:

  • GATT 客户端应在建立连接后检查 CCCD 等配置,确认是否为之前认识的设备
  • 若是已绑定设备,应恢复之前存储的配置

8.4 服务器安全建议

  • 对敏感数据的特征值,应要求加密和/或认证
  • 对可改变设备行为的特征(如写操作),应要求认证
  • 推荐使用 LE 安全连接(LE Secure Connections)以获得更高安全级别

9 SDP 互操作性要求

本章描述 GATT 与 SDP(服务发现协议)的互操作性要求,适用于支持 BR/EDR 的设备。

9.1 服务记录

支持 BR/EDR 连接的 GATT 服务器应在 SDP 数据库中包含一条 GATT 服务的记录,以便 BR/EDR 客户端发现 GATT 服务。

SDP 属性
ServiceClassIDList 0x1801(Generic Attribute Profile)
ProtocolDescriptorList L2CAP(PSM = 0x001F)、ATT(起始句柄、结束句柄)
BrowseGroupList PublicBrowseRoot(0x1002)
ProfileDescriptorList Generic Attribute Profile(版本 0x0100)

9.2 句柄范围

SDP 记录中的 ATT 句柄范围(起始句柄和结束句柄)指定了通过 BR/EDR 连接可访问的 GATT 属性范围。


10 参考文献

  1. 蓝牙核心规范 5.0(BLUETOOTH SPECIFICATION Version 5.0)

    • Vol 3, Part E: Attribute Protocol (ATT)
    • Vol 3, Part C: Generic Access Profile (GAP)
    • Vol 3, Part A: Logical Link Control and Adaptation Protocol (L2CAP)
    • Vol 3, Part B: Service Discovery Protocol (SDP)
  2. 蓝牙分配号码(Bluetooth Assigned Numbers)

    • GATT 特征 UUID 列表
    • 展示格式(Format)值定义
    • 单位 UUID 列表
  3. IEEE 802.11:无线局域网媒体访问控制(MAC)和物理层(PHY)规范

  4. IEEE 754:IEEE 浮点运算标准


附录 A:示例属性服务器属性

本附录提供了一个示例,展示一个属性服务器可能包含的属性组织结构。

A.1 示例场景描述

本示例模拟一个环境传感设备(如户外气象站/背包传感器),该设备安装于瑞典北博滕省(Norrbottens Län)阿比斯科旅游站(Abisko Turiststation)一侧,具有以下特性:

  • 设备名称:"Example Device"(示例设备)
  • 支持全部 ATT 操作码
  • 支持最多两个预写值(Prepare Write 队列容量为 2)

A.2 服务列表与数据

该设备包含以下服务:

主服务 1:Generic Access Service(通用访问服务)

句柄 属性类型 属性值
0x0001 «Primary Service» «Generic Access»
0x0002 «Characteristic»
0x0003 «Device Name» "Example Device"
0x0004 «Characteristic»
0x0005 «Appearance» 0x0000

主服务 2:Generic Attribute Service(通用属性服务)

句柄 属性类型 属性值
0x0010 «Primary Service» «Generic Attribute»
0x0011 «Characteristic»
0x0012 «Service Changed»
0x0013 «Client Characteristic Configuration» 0x0000

主服务 3:Device Information Service(设备信息服务)

句柄 属性类型 属性值
0x0020 «Primary Service» «Device Information»
0x0021 «Characteristic»
0x0022 «System ID» 0x123456FFFE9ABCDE
0x0023 «Characteristic»
0x0024 «PnP ID»

主服务 4:Battery Service(电池服务)

句柄 属性类型 属性值
0x0030 «Primary Service» «Battery Service»
0x0031 «Characteristic»
0x0032 «Battery Level State» 0x0604(电量良好,正在放电)
0x0033 «Client Characteristic Configuration» 0x0000

电量状态值 0x04 表示电池正在放电(Discharging)。

次要服务 1:Manufacturer Service(制造商服务)—— 用于温度传感器

句柄 属性类型 属性值
0x0500 «Secondary Service» «Manufacturer Service»
0x0501 «Characteristic»
0x0502 «Manufacturer Name» "ACME Temperature Sensor"
0x0503 «Characteristic»
0x0504 «Serial Number» "237495-3282-A"

次要服务 2:Manufacturer Service(制造商服务)—— 用于称重传感器

句柄 属性类型 属性值
0x0505 «Secondary Service» «Manufacturer Service»
0x0506 «Characteristic»
0x0507 «Manufacturer Name» "ACME Weighing Scales"
0x0508 «Characteristic»
0x0509 «Serial Number» "11267-2327A00239"

次要服务 3:Vendor Specific Service(厂商自定义服务)

句柄 属性类型 属性值
0x0550 «Secondary Service» «Vendor Specific Service»
0x0560 «Characteristic»
0x0568 «Vendor Specific Type» 0x56656E646F72

主服务 5:Environment Service(环境服务)

句柄 属性类型 属性值
0x00A0 «Primary Service» «Environment Service»
0x00A1 «Included Service»
0x00A2 «Characteristic»
0x00A3 «Temperature Measurement» 0x0041(表示 6.5 °C)
0x00A4 «Client Characteristic Configuration» 0x0000
0x00A5 «Characteristic Presentation Format» {0x0E, -1, 0x272F, 0x01, 0x0000}(sint16,× 0.1,摄氏度)
0x00A6 «Characteristic User Description» "Outside Temperature"
0x00A7 «Characteristic»
0x00A8 «Humidity» 0x27(39%)
0x00A9 «Client Characteristic Configuration» 0x0000
0x00AA «Characteristic Presentation Format» {0x04, 0, 0x27AD, 0x01, 0x0000}(uint8,百分比)
0x00AB «Characteristic User Description» "Outside Relative Humidity"

主服务 6:Weight Service(称重服务)

句柄 属性类型 属性值
0x0200 «Primary Service» «Weight Service»
0x0201 «Included Service»
0x0202 «Included Service»
0x0203 «Characteristic»
0x0204 «Weight» 0x088D(2189,实际值 21.89 kg)
0x0205 «Client Characteristic Configuration» 0x0000
0x0206 «Characteristic Presentation Format» {0x06, -2, 0x27A8, 0x01, 0x0000}(uint16,× 0.01,千克)
0x0207 «Characteristic User Description» "Hanging Weight"
0x0280 «Characteristic»
0x0281 «Rucksack Weight» 0x088D(2189,实际值 21.89 kg)
0x0282 «Characteristic Presentation Format» {0x06, -2, 0x27A8, 0x01, 0x0000}(uint16,× 0.01,千克)
0x0283 «Characteristic» {0x02, 0x0284, «Rucksack Weight»}(称重传感器读数)
0x0284 «Rucksack Weight» 0x088D
0x0285 «Characteristic User Description» "Rucksack Weight"

主服务 7:Position Service(位置服务)

句柄 属性类型 属性值
0x0300 «Primary Service» «Position Service»
0x0301 «Characteristic»
0x0302 «Latitude Longitude» 0x28BEAFA40B320FCE(纬度 68.3585444°N,经度 18.7830222°E)
0x0304 «Characteristic»
0x0305 «Latitude Longitude Elevation» 0x28BEAFA40B320FCE0176(纬度、经度,海拔 374 米)

主服务 8:Alert Service(告警服务)

句柄 属性类型 属性值
0x0400 «Primary Service» «Alert Service»
0x0401 «Characteristic»
0x0402 «Alert Enumeration» 0x00(无告警)

A.3 服务器信息摘要

上述服务器包含如下信息:

  • 设备名称特征值为 "Example Device"
  • 支持全部属性操作码,且预写缓冲区支持最多 2 个条目
  • 电池状态值为 0x04,表示正在放电
  • 室外温度值为 6.5 °C
  • 室外相对湿度值为 39%
  • 挂载重量值为 21.89 kg
  • 设备位置:北纬 68.3585444°,东经 18.7830222°,海拔 374 米
  • 温度传感器制造商:ACME Temperature Sensor,序列号:237495-3282-A
  • 称重传感器制造商:ACME Weighing Scales,序列号:11267-2327A00239

该设备位于瑞典北博滕省阿比斯科旅游站侧面,电池状态良好,当天气温较高、湿度较低,背包较重。


——翻译自 BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G: Generic Attribute Profile (GATT),2016 年 12 月 6 日版本

posted @ 2026-06-10 16:05  wzm888  阅读(8)  评论(1)    收藏  举报