ble之数据交换
GATT 数据特征与服务
GATT 服务是低功耗蓝牙连接中两个设备进行数据交换的基础设施,其最小数据单元是属性。在 数据表示与交换 中,我们对 ATT 层的属性以及 GATT 层的特征数据、服务与规范进行了简要介绍。下面我们对基于属性的数据结构细节进行说明。
属性
属性由以下四部分组成
|
序号 |
名称 |
说明 |
|---|---|---|
|
1 |
句柄 (Handle) |
16 位无符号整型,表示属性在 属性表中的索引 |
|
2 |
类型 (Type) |
ATT 属性使用 UUID (Universally Unique ID) 对类型进行区分 |
|
3 |
访问权限 |
是否需要加密/授权?可读或可写? |
|
4 |
值 |
实际用户数据或另一属性的元数据 |
低功耗蓝牙中存在两种类型的 UUID ,如下
-
SIG 定义的 16 位 UUID
-
厂商自定义的 128 位 UUID
在 SIG 官方提供的 Assigned Numbers 标准文件中,给出了一些常用特征数据和服务的 UUID ,例如
|
分类 |
类型名称 |
UUID |
|---|---|---|
|
服务 |
血压服务 (Blood Pressure Service) |
0x1810 |
|
服务 |
通用音频服务 (Common Audio Service) |
0x1853 |
|
特征数据 |
年龄 (Age) |
0x2A80 |
|
特征数据 |
外观 (Appearance) |
0x2A01 |
事实上,这些服务和特征数据的定义也由 SIG 一并给出。例如心率测量值 (Heart Rate Measurement) 的值中必须含有标志位、心率测量值场,可以含有能量拓展场、 RR-间隔场以及传输间隔场等。所以,使用 SIG 定义的 UUID 使得不同厂商的低功耗蓝牙设备之间可以识别对方的服务或特征数据,实现跨厂商的低功耗蓝牙设备通信。
厂商自定义的 128 位 UUID 则用于满足厂商开发私有服务或数据特征的需求,例如本例程中 LED 特征数据的 UUID 为 0x00001525-1212-EFDE-1523-785FEABCD123,是一个厂商自定义的 128 位 UUID 。
特征数据
一个特征数据常由以下几个属性组成
|
序号 |
名称 |
作用 |
备注 |
|---|---|---|---|
|
1 |
特征数据声明 (Characteristic Declaration) |
含有特征数据值的读写属性 (Properties)、句柄以及 UUID 信息 |
UUID 为 0x2803,只读属性 |
|
2 |
特征数据值 (Characteristic Value) |
实际的用户数据 |
UUID 标识特征数据的类型 |
|
3 |
特征数据描述符 (Characteristic Descriptor) |
特征数据的其他描述信息 |
可选属性 |
特征数据声明和特征数据值之间的关系
下面以心率测量值 (Heart Rate Measurement) 为例,说明特征数据声明和特征数据值之间的关系。
下表为一属性表,含心率测量值数据特征的两个属性。首先来看句柄为 0 的属性,其 UUID 为 0x2803,访问权限为只读,说明这是一个特征数据声明属性。属性值中,读写属性为只读,句柄指向 1 ,说明句柄为 1 的属性为该特征数据的值属性; UUID 为 0x2A37,说明这个特征数据类型为心率测量值。
接下来看句柄为 1 的属性,其 UUID 为 0x2A37,访问权限为只读,与特征数据声明属性的值一一对应。该属性的值由标志位和测量值两部分组成,符合 SIG 规范对心率测量值特征数据的定义。
|
Handle |
UUID |
Permissions |
Value |
Attribute Type |
|---|---|---|---|---|
|
0 |
0x2803 |
Read-only |
Properties = Read-only |
Characteristic Declaration |
|
Handle = 1 |
||||
|
UUID = 0x2A37 |
||||
|
1 |
0x2A37 |
Read-only |
Flags |
Characteristic Value |
|
Measurement value |
特征数据描述符
特征数据描述符起到对特征数据进行补充说明的作用。最常见的特征数据描述符是客户端特征数据配置描述符 (Client Characteristic Configuration Descriptor, CCCD),下由 CCCD 代指。当特征数据支持由服务器端发起的 数据操作(通知或指示)时,必须使用 CCCD 描述相关信息;这是一个可读写属性,用于 GATT 客户端告知服务器是否需要启用通知或指示,写值操作也被称为订阅 (Subscribe) 或取消订阅。
CCCD 的 UUID 是 0x2902,属性值中仅含 2 比特信息。第一个比特用于表示通知是否启用,第二个比特用于表示指示是否启用。我们将 CCCD 也添加到属性表中,并为心率测量值特征数据添加指示 (Indicate) 访问权限,就可以得到完整的心率测量值特征数据在属性表中的形态,如下
|
Handle |
UUID |
Permissions |
Value |
Attribute Type |
|---|---|---|---|---|
|
0 |
0x2803 |
Read-only |
Properties = Read/Indicate |
Characteristic Declaration |
|
Handle = 1 |
||||
|
UUID = 0x2A37 |
||||
|
1 |
0x2A37 |
Read/Indicate |
Flags |
Characteristic Value |
|
Measurement value |
||||
|
2 |
0x2902 |
Read/Write |
Notification status |
Characteristic Descriptor |
|
Indication status |
服务
服务的数据结构大致可以分为两部分
|
序号 |
名称 |
|---|---|
|
1 |
服务声明属性 (Service Declaration Attribute) |
|
2 |
特征数据定义属性 (Characteristic Definition Attributes) |
在 特征数据中提到的三种特征数据属性都属于特征数据定义属性。也就是说,服务的数据结构在本质上就是一些特征数据属性加上一个服务声明属性。
服务声明属性的 UUID 为 0x2800,访问权限为只读,值为标识服务类型的 UUID ,例如 Heart Rate Service 的 UUID 为 0x180D,那么其服务声明属性就可以表示为
|
Handle |
UUID |
Permissions |
Value |
Attribute Type |
|---|---|---|---|---|
|
0 |
0x2800 |
Read-only |
0x180D |
Service Declaration |
属性表示例
下面展示一个 GATT 服务器可能的属性表形态。例程中含有两个服务,分别是 Heart Rate Service 和 Automation IO Service ;前者含有一个 Heart Rate Measurement 特征数据,后者含有一个 LED 特征数据。整个 GATT 服务器有属性表如下
|
Handle |
UUID |
Permissions |
Value |
Attribute Type |
|---|---|---|---|---|
|
0 |
0x2800 |
Read-only |
UUID = 0x180D |
Service Declaration |
|
1 |
0x2803 |
Read-only |
Properties = Read/Indicate |
Characteristic Declaration |
|
Handle = 2 |
||||
|
UUID = 0x2A37 |
||||
|
2 |
0x2A37 |
Read/Indicate |
Flags |
Characteristic Value |
|
Measurement value |
||||
|
3 |
0x2902 |
Read/Write |
Notification status |
Characteristic Descriptor |
|
Indication status |
||||
|
4 |
0x2800 |
Read-only |
UUID = 0x1815 |
Service Declaration |
|
5 |
0x2803 |
Read-only |
Properties = Write-only |
Characteristic Declaration |
|
Handle = 6 |
||||
|
UUID = 0x00001525-1212-EFDE-1523-785FEABCD123 |
||||
|
6 |
0x00001525-1212-EFDE- 1523-785FE ABCD123 |
Write-only |
LED status |
Characteristic Value |
GATT 客户端在与 GATT 服务器初次建立通信时,会从 GATT 服务器拉取属性表中的元信息,从而获取 GATT 服务器上可用的服务以及数据特征。这一过程被称为 服务发现 (Service Discovery)。
GATT 数据操作
数据操作指的是对 GATT 服务器上的特征数据进行访问的操作,主要可以分为以下两类:
-
由客户端发起的操作
-
由服务器发起的操作
由客户端发起的操作
由客户端发起的操作有以下三种
-
读 (Read)
-
从 GATT 服务器上拉取某一特征数据的当前值。
-
-
写 (Write)
-
普通的写操作要求 GATT 服务器在收到客户端的写请求以及对应数据以后,进行确认响应。
-
-
写(无需响应) (Write without response)
-
快速写操作则不需要服务器进行确认响应。
-
由服务器发起的操作
由服务器发起的操作分两种
-
通知 (Notify)
-
通知是 GATT 服务器主动向客户端推送数据的操作,不需要客户端回复确认响应。
-
-
指示 (Indicate)
-
与通知相似,区别在于指示需要客户端回复确认,因此数据推送速度比通知慢。
-
虽然通知和指示都是由服务器发起的操作,但是服务器发起操作的前提是,客户端启用了通知或指示。所以,本质上 GATT 的数据交换过程总是以客户端请求数据开始。
更多推荐
所有评论(0)