蓝牙低功耗profile:ATT和GATT(转载)

原文:https://epx.com.br/artigos/bluetooth_gatt.php

蓝牙4.0版本推出了低功耗规范,引入了两个核心协议:ATT(Attribute Protocol)和GATT(Generic Attribute Protocol).这两个协议主要目标是BLE,但是也可以运行在传统蓝牙上(BR/EDR).

Overview

ATT是wire applicationprotocol(怎么翻译?连接协议?),GATT基于ATT协议。所有的BLE profile一定基于GATT。也就是所有的BLE服务都使用ATT作为应用协议。

锁定BLE使用这两个协议的好处是:

1, 开发和实现新的BLEprofile更加容易,因为不需要从头实现wire protocol。

2, ATT针对BLE 设备进行了特别的优化:使用尽可能少的字节,因此可能在存储中使用定长结构来生成PDU。

3, ATT/GATT的简单意味着固件可能提供某种程度的协议支持,省去了微处理器软件的麻烦。

4, 对于软件实现的协议栈来说,ATT/GATT在协议栈里实现,省去了应用的麻烦。

5, 即使有的场景下,ATT/GATT不够理想。也可以在L2CAP连接上实现平行于ATTchannel的协议。

ATT: Attribute Protocol

ATT协议的唯一基础是属性。每个属性由三个元素构成:

1,一个16bit handle;

2,一个UUID来定义属性的类型;

3,确定长度的属性值

在ATT中,属性值可以是任意长度的byte数组。属性值的实际意义依赖于UUID,而且ATT并不会检查属性值长度是否与给定的UUID定义一致。

Handle是用来唯一识别属性的数字,因为在一个BLE 设备中可能存在多个属性具有相同的UUID。

ATT协议本身没有定义任何UUID。这部分工作留给了GATT和上层协议。

ATT server存储属性。ATT client什么也不存储,它使用ATT协议来读写server端的属性。

和属性相关的还有读写权限。读写权限存在属性值里,由高层协议确定。ATT本身不会关心,也不会试图解释属性值来确定权限。这部分工作也留给了GATT和上层协议。

ATT有一些良好的特征,比如通过UUID来搜索属性,通过handle区间范围来获取所有区间内的属性,因此client不需要提前获得handle的值,也不需要高层协议硬编码这些值。

但是在特定的设备上handle的取值最好保持不变,这样的话client能够缓冲信息。在第一个discovery以后,client能够使用缓冲信息,这样能够减少传输的包数量,也能够节约能量。如果服务端的属性布局已经发生了变换,高层协议应该能够”暗示”client,比如固件升级。

大多数情况下ATT协议都是纯C/S架构,client发起请求,server响应。但是服务端也有通知的能力,在服务端属性发生变化时,server能够通知client,这样避免了client不停的poll。

ATT协议不会显式发送属性值的长度,只能从PDU长度里面获得。因此client最好能够知道某种UUID类型所代表的属性的精确结构。

不发送属性值长度,是为了减少发送的字节,因为LE的MTU只有23bytes。

23bytes的MTU对于较长的属性值来说是个麻烦。因此不得采用“read long”,”write long“这样的操作。

ATT是如此通用,意味着高层协议有太多工作要做。过度的自由也会带来问题,比如:如果一个设备提供多个服务怎么办?对每一个设备只有一个ATT handle空间,多个服务不得不共享同一份空间。

幸运地是,我们还有GATT,它为我们提供了属性用法,并解除了这些限制。

GATT:Generic Attribute Profile

GATT是所有LE顶层协议的基础。它定义了怎么把一堆ATT属性分组成为有意义的服务。

GATT services

GATT service的基础是UUID值为0x2800的属性。所有跟在这个属性后面的属性都属于这个属性定义的服务,直到另一个0x2800属性出现。

比如说,一个设备里面的三个属性布局如下:

每一个属性不知道它自己属于哪个服务,GATT需要根据0x2800属性作为标记来识别出哪个属性属于哪个服务。

按照这个定义,handle值就有意义了。在上面的例子中,属于service B的属性handle必须位于0x0151和0x02ff之间。

UUID 0x2800定义了primary
服务,也可以使用0x2801来定义secondary
服务。Secondary
服务表示包含于primary
服务。

然后我们怎么能知道一个服务是温度计,智能钥匙或者GPS?答案是通过读取属性值。服务属值包含了一个UUID,通过这个UUID区分服务。

因此,每个属性定义事实上包含了两个UUID,0x2800或者0x2801作为属性UUID,另外一个属性值里面存储的UUID。后面这个UUID是服务ID。

举个栗子:

在图中, thermometer service的UUID是0x1816。

是不是有点晕啊?两个UUID定义一个服务?这是GATT/ATT分层方式导致的后果。UUID
0x2800被GATT用来寻找服务定义边界。一旦找到了边界,属性值,也就是第二个UUID用来指定服务。这样client能够找到所有的服务而不需要知道服务的具体定义。

GATT service characteristics

每一个服务有几个特征。特征存储了有用的值以及权限。

比如,一个温度计可能有只读的温度特征,也可能有可读写的时间戳。

每一个服务可能有几个特征,这些特征也是通过路碑属性来发现的。

主特征的UUID是0x2803,然后主特征的属性值用来定义特征。比如图中 0x2803用来找到特征,0x2A2B用来找到特征包含的信息。

每一个特征至少包含两个属性,主属性0x2803和真正的值属性。主属性知道属性值的handle和UUID。这能够进行一定程度的交叉检测。

特征值的真正格式是由UUID决定的。因此,如果客户端知道如何解释UUID为 0x2A08的特征值,就能够从包含这个特征任何服务里面读取日期和时间。当然如果客户端不知道如何解释这个UUID的话,也可以选择忽略。

Characteristic descriptors

除了特征值,我们也可以为每个特征增加更多的属性。在GATT语法里,这个额外的属性成为描述符。

举个栗子,我们也许需要指定温度的计量单位。

GATT知道handle 0x0104是特征0x0101的描述符,因为:

1, 他不是特征的值,因为特征值的handle应该是0x0102

2, 他的handle落在了0x0103-0x010f之间,因此也不属于下一个特征。

描述符值的意义依赖于属性UUID。例子中,描述符的UUID是0x2A1F,客户端如果不能识别这个UUId,他可以选择忽略。这样可以实现向下兼容。

每个服务可能定义自己的描述符,但是GATT已经定义了能够覆盖大多数情况的标准描述符,比如:

数值格式和表示;

人类可读的描述;

合理范围扩展属性等等。其中特别重要的描述符是client characteristic configuration。

Client Characteristic Configurationdescriptor

Client Characteristic Configurationdescriptor的UUID是0x2902,具有一个16bit的可读写值,作为一个bitmap来使用。

这个属性被server用来存储和代表每个已经绑定的client的独立实例,每个client只能看到它自己的拷贝。

前两个bit被GATT用来定义通知和暗示。其他bit暂时未使用。

通过设置CCC,client能够让server在特征发生改变时得到通知。比如包含了CCC的属性布局如下:

Servicediscovery in Low Energy

因为GATT中所有的服务细节通过ATT来描述,所以不需要像BR/EDR那样设置专门的服务发现协议。ATT负责一切:发现服务,查找特征,读写值等等。

GATT andvanilla Bluetooth

GATT也可以工作在传统蓝牙上面,但是规范规定传统蓝牙仍然使用SDP发送服务,即使通过GATT来进行实际数据交换。

这样的好处是在双模设备上不用设置标识来识别LE-only服务。如果一个服务只能通过GATT发现,就是LE-only。如果能够通过GATT和SDP发现,就是双模。

如果一个profile通过GATT来进行数据交换,并且是双模的,它必须首先发布SDP record。然后这个服务通过SDP来发现,然后通过GATT来查找特征。

当然,现在没有双模的profile。以前的profile是BR/EDR only,并且没有适配到GATT;LE-only只有LE。

如果想要测试GATT而没有LE硬件,可以修改蓝牙协议栈来使BR/EDR可以进行GATT discovery。这是规范不运行的,但是开发者可以。

Notificationsversus connections

通知和暗示使得server可以发送消息给client。这样客户端不需要pollserver来获取新的数据。

另外,典型的GATT server是“小的“外设,像非常需要节能的传感器之类。因此,外设的LE 设备不能发起连接。那么通知怎么发送呢?

在BLE协议栈,如果server有数据发送,它就进入广播模式,并且发送一些信号。每个profile定义了广播时长和频率。时长和频率应该根据使用场景进行了节能和及时性的权衡。

处于中心模式的设备随时处于监听模式。当它监听到广播后,如果发现广播设备是认识的(配对过或者白名单中的),就会向外设发起连接。

连接建立以后,GATT通信能够进行,通知得以发送。所以典型的序列是:1,server发送广播 2,client连接 3server通知

如果没有更多的数据发送,server和client就会超时断开。最佳超时时间依赖于用例;如果服务不会频繁发送通知并且没有实时性要求的话,可以立马断开。因为BLE重连是非常快的。

典型的GATT server是外设设备,但是不是必须的。也可以外设做client,center做server。在这种场景下,client想要读写数据的时候,需要先进入广播模式。

蓝牙低功耗profile:ATT和GATT

蓝牙4.0版本推出了低功耗规范,引入了两个核心协议:ATT(Attribute Protocol)和GATT(Generic Attribute Protocol).这两个协议主要目标是BLE,但是也可以运行在传统蓝牙上(BR/EDR).

Overview

ATT是wire applicationprotocol(怎么翻译?连接协议?),GATT基于ATT协议。所有的BLE profile一定基于GATT。也就是所有的BLE服务都使用ATT作为应用协议。

锁定BLE使用这两个协议的好处是:

1, 开发和实现新的BLEprofile更加容易,因为不需要从头实现wire protocol。

2, ATT针对BLE 设备进行了特别的优化:使用尽可能少的字节,因此可能在存储中使用定长结构来生成PDU。

3, ATT/GATT的简单意味着固件可能提供某种程度的协议支持,省去了微处理器软件的麻烦。

4, 对于软件实现的协议栈来说,ATT/GATT在协议栈里实现,省去了应用的麻烦。

5, 即使有的场景下,ATT/GATT不够理想。也可以在L2CAP连接上实现平行于ATTchannel的协议。

ATT: Attribute Protocol

ATT协议的唯一基础是属性。每个属性由三个元素构成:

1,一个16bit handle;

2,一个UUID来定义属性的类型;

3,确定长度的属性值

在ATT中,属性值可以是任意长度的byte数组。属性值的实际意义依赖于UUID,而且ATT并不会检查属性值长度是否与给定的UUID定义一致。

Handle是用来唯一识别属性的数字,因为在一个BLE 设备中可能存在多个属性具有相同的UUID。

ATT协议本身没有定义任何UUID。这部分工作留给了GATT和上层协议。

ATT server存储属性。ATT client什么也不存储,它使用ATT协议来读写server端的属性。

和属性相关的还有读写权限。读写权限存在属性值里,由高层协议确定。ATT本身不会关心,也不会试图解释属性值来确定权限。这部分工作也留给了GATT和上层协议。

ATT有一些良好的特征,比如通过UUID来搜索属性,通过handle区间范围来获取所有区间内的属性,因此client不需要提前获得handle的值,也不需要高层协议硬编码这些值。

但是在特定的设备上handle的取值最好保持不变,这样的话client能够缓冲信息。在第一个discovery以后,client能够使用缓冲信息,这样能够减少传输的包数量,也能够节约能量。如果服务端的属性布局已经发生了变换,高层协议应该能够”暗示”client,比如固件升级。

大多数情况下ATT协议都是纯C/S架构,client发起请求,server响应。但是服务端也有通知的能力,在服务端属性发生变化时,server能够通知client,这样避免了client不停的poll。

ATT协议不会显式发送属性值的长度,只能从PDU长度里面获得。因此client最好能够知道某种UUID类型所代表的属性的精确结构。

不发送属性值长度,是为了减少发送的字节,因为LE的MTU只有23bytes。

23bytes的MTU对于较长的属性值来说是个麻烦。因此不得采用“read long”,”write long“这样的操作。

ATT是如此通用,意味着高层协议有太多工作要做。过度的自由也会带来问题,比如:如果一个设备提供多个服务怎么办?对每一个设备只有一个ATT handle空间,多个服务不得不共享同一份空间。

幸运地是,我们还有GATT,它为我们提供了属性用法,并解除了这些限制。

GATT:Generic Attribute Profile

GATT是所有LE顶层协议的基础。它定义了怎么把一堆ATT属性分组成为有意义的服务。

GATT services

GATT service的基础是UUID值为0x2800的属性。所有跟在这个属性后面的属性都属于这个属性定义的服务,直到另一个0x2800属性出现。

比如说,一个设备里面的三个属性布局如下:

每一个属性不知道它自己属于哪个服务,GATT需要根据0x2800属性作为标记来识别出哪个属性属于哪个服务。

按照这个定义,handle值就有意义了。在上面的例子中,属于service B的属性handle必须位于0x0151和0x02ff之间。

UUID 0x2800定义了primary
服务,也可以使用0x2801来定义secondary
服务。Secondary
服务表示包含于primary
服务。

然后我们怎么能知道一个服务是温度计,智能钥匙或者GPS?答案是通过读取属性值。服务属值包含了一个UUID,通过这个UUID区分服务。

因此,每个属性定义事实上包含了两个UUID,0x2800或者0x2801作为属性UUID,另外一个属性值里面存储的UUID。后面这个UUID是服务ID。

举个栗子:

在图中, thermometer service的UUID是0x1816。

是不是有点晕啊?两个UUID定义一个服务?这是GATT/ATT分层方式导致的后果。UUID
0x2800被GATT用来寻找服务定义边界。一旦找到了边界,属性值,也就是第二个UUID用来指定服务。这样client能够找到所有的服务而不需要知道服务的具体定义。

GATT service characteristics

每一个服务有几个特征。特征存储了有用的值以及权限。

比如,一个温度计可能有只读的温度特征,也可能有可读写的时间戳。

每一个服务可能有几个特征,这些特征也是通过路碑属性来发现的。

主特征的UUID是0x2803,然后主特征的属性值用来定义特征。比如图中 0x2803用来找到特征,0x2A2B用来找到特征包含的信息。

每一个特征至少包含两个属性,主属性0x2803和真正的值属性。主属性知道属性值的handle和UUID。这能够进行一定程度的交叉检测。

特征值的真正格式是由UUID决定的。因此,如果客户端知道如何解释UUID为 0x2A08的特征值,就能够从包含这个特征任何服务里面读取日期和时间。当然如果客户端不知道如何解释这个UUID的话,也可以选择忽略。

Characteristic descriptors

除了特征值,我们也可以为每个特征增加更多的属性。在GATT语法里,这个额外的属性成为描述符。

举个栗子,我们也许需要指定温度的计量单位。

GATT知道handle 0x0104是特征0x0101的描述符,因为:

1, 他不是特征的值,因为特征值的handle应该是0x0102

2, 他的handle落在了0x0103-0x010f之间,因此也不属于下一个特征。

描述符值的意义依赖于属性UUID。例子中,描述符的UUID是0x2A1F,客户端如果不能识别这个UUId,他可以选择忽略。这样可以实现向下兼容。

每个服务可能定义自己的描述符,但是GATT已经定义了能够覆盖大多数情况的标准描述符,比如:

数值格式和表示;

人类可读的描述;

合理范围扩展属性等等。其中特别重要的描述符是client characteristic configuration。

Client Characteristic Configurationdescriptor

Client Characteristic Configurationdescriptor的UUID是0x2902,具有一个16bit的可读写值,作为一个bitmap来使用。

这个属性被server用来存储和代表每个已经绑定的client的独立实例,每个client只能看到它自己的拷贝。

前两个bit被GATT用来定义通知和暗示。其他bit暂时未使用。

通过设置CCC,client能够让server在特征发生改变时得到通知。比如包含了CCC的属性布局如下:

Servicediscovery in Low Energy

因为GATT中所有的服务细节通过ATT来描述,所以不需要像BR/EDR那样设置专门的服务发现协议。ATT负责一切:发现服务,查找特征,读写值等等。

GATT andvanilla Bluetooth

GATT也可以工作在传统蓝牙上面,但是规范规定传统蓝牙仍然使用SDP发送服务,即使通过GATT来进行实际数据交换。

这样的好处是在双模设备上不用设置标识来识别LE-only服务。如果一个服务只能通过GATT发现,就是LE-only。如果能够通过GATT和SDP发现,就是双模。

如果一个profile通过GATT来进行数据交换,并且是双模的,它必须首先发布SDP record。然后这个服务通过SDP来发现,然后通过GATT来查找特征。

当然,现在没有双模的profile。以前的profile是BR/EDR only,并且没有适配到GATT;LE-only只有LE。

如果想要测试GATT而没有LE硬件,可以修改蓝牙协议栈来使BR/EDR可以进行GATT discovery。这是规范不运行的,但是开发者可以。

Notificationsversus connections

通知和暗示使得server可以发送消息给client。这样客户端不需要pollserver来获取新的数据。

另外,典型的GATT server是“小的“外设,像非常需要节能的传感器之类。因此,外设的LE 设备不能发起连接。那么通知怎么发送呢?

在BLE协议栈,如果server有数据发送,它就进入广播模式,并且发送一些信号。每个profile定义了广播时长和频率。时长和频率应该根据使用场景进行了节能和及时性的权衡。

处于中心模式的设备随时处于监听模式。当它监听到广播后,如果发现广播设备是认识的(配对过或者白名单中的),就会向外设发起连接。

连接建立以后,GATT通信能够进行,通知得以发送。所以典型的序列是:1,server发送广播 2,client连接 3server通知

如果没有更多的数据发送,server和client就会超时断开。最佳超时时间依赖于用例;如果服务不会频繁发送通知并且没有实时性要求的话,可以立马断开。因为BLE重连是非常快的。

典型的GATT server是外设设备,但是不是必须的。也可以外设做client,center做server。在这种场景下,client想要读写数据的时候,需要先进入广播模式。

时间: 2024-10-10 23:20:22

蓝牙低功耗profile:ATT和GATT(转载)的相关文章

浅谈蓝牙低功耗(BLE)的几种常见的应用场景及架构(转载)

转载来至beautifulzzzz,网址http://www.cnblogs.com/zjutlitao/,推荐学习 蓝牙在短距离无线通信领域占据举足轻重的地位—— 从手机.平板.PC到车载设备, 到耳机.游戏手柄.音响.电视, 再到手环.电子秤.智能医疗器械(血糖仪.数字血压计.血气计.数字脉搏/心率监视器.数字体温计.耳温枪.皮肤水分计等), 再到智能家居等领域均占有一席之地. 而蓝牙低功耗(BLE)是在蓝牙4.0协议上修改以适用低功耗应用场景的一种蓝牙协议. 随着上一股智能消费类电子大潮的

【Android应用开发】Android 蓝牙低功耗 (BLE) ( 第一篇 . 概述 . 蓝牙低功耗文档 翻译)

转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50515359 参考 :  -- 官方文档 : https://developer.android.com/guide/topics/connectivity/bluetooth-le.html; 1. 概述 BLE 概述 : -- 版本支持 : Android 4.3 (API Level 18) 内置框架引入了 蓝牙低功耗方案 (Bluetooth Low Energy,

Bluetooth Low Energy——蓝牙低功耗

Android4.3(API级别18)引入内置平台支持BLE的central角色,同时提供API和app应用程序用来发现设备,查询服务,和读/写characteristics.与传统蓝牙(ClassicBluetooth)不同,蓝牙低功耗(BLE)的目的是提供更显著的低功耗.这使得Android应用程序可以和具有低功耗的要求BLE设备,如接近传感器,心脏速率监视器,健身设备等进行通信. 关键术语和概念 下面是关键BLE术语和概念的总结: 通用属性规范(GATT)—GATTprofile是一个通用

[nRF51822] 14、浅谈蓝牙低功耗(BLE)的几种常见的应用场景及架构(科普类干货)

蓝牙在短距离无线通信领域占据举足轻重的地位—— 从手机.平板.PC到车载设备, 到耳机.游戏手柄.音响.电视, 再到手环.电子秤.智能医疗器械(血糖仪.数字血压计.血气计.数字脉搏/心率监视器.数字体温计.耳温枪.皮肤水分计等), 再到智能家居等领域均占有一席之地. 而蓝牙低功耗(BLE)是在蓝牙4.0协议上修改以适用低功耗应用场景的一种蓝牙协议. 随着上一股智能消费类电子大潮的到来,BLE的各种应用也像雨后春笋般在市场上铺开. 如果想 紧跟蓝牙协议的最新动态 ,可以在https://www.b

CC2540是一款高性价比,低功耗片上系统(Soc)解决方案,它适合蓝牙低功耗应用领域

CC2540是一款高性价比,低功耗片上系统(Soc)解决方案,它适合蓝牙低功耗应用领域,极少的外围元器件以及强大网络节点建立成为可能.CC2540是一款含有高速和低功耗8051内核的RF收发器.适用于低功耗系统,有超低功耗的睡眠模式以及超低功耗运行模式. 市场上流通广泛的两款 CC2540F128及CC2540F256的区别如下: CC2540F128 含有128KB 程序Flash及8KB RAM; CC2540F256 含有256KB 程序Flash及8KB RAM; CC2540是深圳市动

CC2541是功率优化的真正系统级芯片(SoC)解决方案,适用于蓝牙低功耗(BLE)和专用的2.4GHz应用

CC2541是功率优化的真正系统级芯片(SoC)解决方案,适用于蓝牙低功耗(BLE)和专用的2.4GHz应用.该SOC芯片集成性能极好RF收发器以及标准工业级增强型8051内核,支持系统编程Flash,8KRAM及强大功能支持跟外设. NRF52832是深圳市动能世纪科技有限公司(www.dnsj88.com)从原厂渠道代理经销. 深圳市动能世纪科技有限公司成立于2000年,是一家IC集成电路销售的独立分销商,一直专注于经销世界著名的电子元器件,同时为客户提供被动元器件的配套.公司拥有一支专业且

Android ble (蓝牙低功耗)使用注意事项(转)

一.如何定义ble中service uuid? 蓝牙标准规范里面定义了很多已经定义过的service uuid,如果冲突了会造成很多意外的问题. 蓝牙的service uuid的格式如下 UUID.fromString("00001234-0000-1000-8000-00805f9b34fb") 在Android可以简单的采用这个原则:1.利用这个字符串[00002903-0000-1000-8000-00805f9b34fb]用第5-8位的数字做变化,其他数字保持不变.比如 UUI

Android蓝牙A2dp profile的使用

A2dp profile是android支持的一种蓝牙情景模式,一般用于蓝牙立体声耳机,即蓝牙音频的输出 在android的app层中,A2dp的使用并不是很开放,api只提供了非常少的操作接口,连基本的连接都只能用反射来调用底层的方法.a2dp的使用是通过BluetoothA2dp这个代理类来控制A2dp服务的,这里简单举例使用的方法: private BluetoothAdapter mBluetooth = BluetoothAdapter.getDefaultAdapter(); mBl

Nordic资料:蓝牙低功耗介绍(三)

ATT:概要 1. ATT (Attribute Protocol) 在BLE中,它是强制性的,并且用于所有的数据传输 快速的,简单的,独立于连接逻辑的 2. 客户端--服务器 结构 服务器用于存储数据(比如,我们的Nordic nRF51 系列的芯片就可以用于服务器的角色) 客户端负责请求数据(比如蓝牙手机终端) 服务器负责发起通知和指示 3. 支持细粒度安全(fine-grained security) ATT 事务(Transaction) Handle--ATT表格的索引值,用于ATT的