Bluetooth GATT Profile Spec 解读

时间:2022-07-02 03:27:54

    ATT(Attribute) protocol为所有基于LE link的应用提供了一个底层的框架。它定义了server与client,定义了属性以及client如何获取server端的一系列属性。Generic Attribute Profile作为一个通用的基于ATT的profile,为上层应用提供了一个基本的服务框架(service framework),使得所有基于LE的应用都可以将自身的功能映射到这个框架中来。

    相比ATT protocol,GATT Profile定义了以下更为具体的概念:

  • 一组通用的Attribute Type,如Primary Service、Characteristic;
  • 以上通用Attribute Type的Attribute Value的格式,不是所有的Attribute Value都只有一个UUID;
  • 如何使用ATT PDU对这组通用的Attribute进行读写、查询、配置;
  • 上层应用要如何基于GATT定义自己的Service

Attribute Type

    GATT定义了以下通用的Attribute Type:

Attribute Type UUID Description
《Primary Service》 0x2800

基础服务,通常包含《Include》以及《Characteristic》

来描述它的具体特性

《Secondary Service》 0x2801 二级服务
《Include》 0x2802

通常被包含在另一个Primary Service中,表示当前Service

用到了这个《Include》service。它的Attribute Value包含了

《Include》service的Attribute Handle、End Group Handle。

如果这个《Include》Service的UUID是BT SIG定义的

16bit UUID,则还包含这个UUID值

《Characteristic》 0x2803

服务的特性,包含Property和Value,以及零或多个Descriptor

(下面都是Descriptor)。所有的Descriptor都是用来

描述《Characteristic》的。

《Characteristic Extended Properties》 0x2900

扩展属性Descriptor,《Characteristic》本身只有一个字节

来描述它的property,更多属性将在这个Descriptor中说明

《Characteristic User Descriptor》 0x2901 对某个《Characteristic》的描述,是一个UTF-8格式的字符串
《Client Characteristic Configuration》 0x2902

GATT的client可以通过配置这个Descriptor,来使能

对应《Characteristic》的notification或Indication。

不同的GATT client有各自独立的

《Client Characteristic Configuration》

《Server Characteristic Configuration》 0x2903

也是一个GATT client可以配置的Descriptor,可以使能

Server的“Broadcast”特性,即将该Descriptor所属的

《Characteristic》的value放在LE广播包中进行传输。

和《Client Characteristic Configuration》不同的是,

所有GATT client共享一个

《Server Characteristic Configuration》

《Characteristic Format》 0x2904

描述了Characteristic Value的格式,比如一个温度计的

度数所呈现的格式

《Characteristic Aggregate Format》 0x2905

一组《Characteristic Format》Descriptors的handle的集合,

每个handle指向一个《Characteristic Format》

    以上,《Primary Service》、《Secondary Service》和《Characteristic》属于ATT protocol中定义的“group of attributes”。Service由其声明(declaration)、《Include》和《Characteristic》组成一个group。《Characteristic》则由其声明、Value以及隶属于它的Descriptors组成。《Primary Service》、《Secondary Service》都可以通过“Read By Group Type Request”来查询它们的起止handle,而《Characteristic》则需要多个procedure的组合来查询它的所有信息。

    有了以上的几个“group of attributes”的概念,一个完整的GATT Profile的层级视图就可以用下面的图大致勾画出来了:

        Bluetooth GATT Profile Spec 解读

    注意到在上面的图中,《Include》、Descriptors都是用虚线框表示的。因此,一个最简单的GATT层级图,将只有一个Service的描述、一个Characteristic的描述以及Characteristic的Value组成。此外,上图并没有单独列出Service的声明,而实际上它就是Service这个group的第一个Attribute。

Primary Service

    关于Service的格式,Spec定义如下图:

        Bluetooth GATT Profile Spec 解读

    首先,它的Attribute Type就是前面说的一个GATT定义的通用的Attribute Type。其次,Attribut Value字段就是UUID,一般是上层应用的Service UUID。BT SIG已经定义了一些,比如HID Service为0x1812,这些UUID都可以直接用16bit来表示;如果需要自己定义一个Service,就需要使用一个128-bit的UUID了。最后,Attribute Permission描述了Service的权限为可读。这也就是ATT protocol规定的由上层(这里就是GATT Profile)来定义的permission。

Characteristic

    一个Service的主要特性由它的Characteristic来说明。它可以是《Device Information Service》中用于描述厂商信息的《PnP_ID》,只能用于client读取;也可以是《HID Service》中的《HID Report》,用于将HOGP device(GATT Server)的按键消息传送给HOGP Host(GATT Client)。一个Characteristic由声明、Value以及零或多个Descriptors组成。声明的格式如下:

    Bluetooth GATT Profile Spec 解读

    在这里,Characteristic Declaration这个Attribute的Value由properties、value attribute handle和UUID三个部分组成。除了Characteristic,其他也有很多的通用Attribute Type的Value是由多个字段组成的。

    Characteristic Properties是一个单字节的bit mask,格式如下:

        Bluetooth GATT Profile Spec 解读

    不同于ATT protocol定义的Attribute Permission,它涉及的主要是如何使用Characteristic,而不是access的权限。部分bit,如Notify和Indicate,一旦置位为1,就意味着这个Characteristic将包含一个《Client Characteristic Configuration》Descriptor。GATT client可以通过这个Descriptor来配置使能/禁能Characteristic的notification或indication。此外,Extended Properties和前面提到的《Characteristic Extended Properties》相关,由这个Descriptor来说明扩展的properties。

    Characteristic Value Attribute Handle是保存Characteristic本身的value的handle值。Characteristic UUID由上层定义,比如《HID Service》中的《Report Map》的UUID为0x2A4B。

    Characteristic Value的Attribute格式如下:

        Bluetooth GATT Profile Spec 解读

    注意到,这里的Attribute Type是上层定义的。这也是GATT Profile当中唯一一个Type由上层定义的Attribute。其实它就是前面Characteristic声明中Attribute Value的Characteristic UUID字段。本身就是上层定义的,因此它的Attribute Permissions也是上层来决定的。每个基于GATT的profile都需要定义自己的Characteristic及其permissions。


GATT Feature Requirements

    其实在我看来,介绍完通用的Attribute Type及其存储格式之后,GATT Profile的工作就完成了。在Spec中,Feature这一章介绍的是如何使用ATT的protocol PDUs来获取那些通用Attribute Type的信息。比ATT更为具体的是,GATT Profile定义了不同Attribute Type具有不同的Attribute Value格式。对一个Characteristic Value handle进行read,返回的结构肯定与读取一个Characteristic  Declaration返回的不同。因此,可以将这章介绍到的procedure,当做ATT protocol PDUs那节的具体的例子来看。


GATT Service

    这里的GATT Service是GATT Profile为自己定义的一个Service,它的UUID为0x1801。它存在的意义在于,它包含了一个Service Changed Characteristic。一旦server端的GATT属性分布有变(增加了或者移除了一些信息),server就可以通过这个Characteristic的indication来通知client(前提是,client配置过server的《Client Characteristic Configuration》,允许server进行indicate)。Service Changed Characteristic的格式如下:

        Bluetooth GATT Profile Spec 解读

    Service Changed Characteristic具有固定的properties——0x20,这意味着它只能通过indication来告知自身的变化。它的Value Handle包含了发生变化的Attribute的起止handle,client可以对这个范围内的所有Attribute重新进行查询。

        Bluetooth GATT Profile Spec 解读

其他

    ATT protocol提到了“ATT Bearer”的概念,GATT对其进行了具体的解释。并不是只有LE link才能承载ATT,经典的BR\EDR link也可以传输ATT数据。不同的是,对于LE link而言,ATT使用fixed L2CAP channel(channel ID为0x0004),PDU不可被flush,断开ATT Bearer就意味着断开LE link。而在BR\EDR传输ATT时,使用PSM(0x001F)来动态分配L2CAP channel ID,MTU size也由L2CAP signal channel进行配置。基于LE link的GATT,加密是可选项目;而在BR\EDR link上使用GATT就必须先加密。最后,列出GATT的SDP record:

        Bluetooth GATT Profile Spec 解读