1. 角色
除了GAP定义了角色之外,BLE还定义了另外2种角色:GATT服务器和GATT客户端,它们完全独立于GAP的角色。提供数据的设备称为GATT服务器,访问GATT服务器而获得数据的设备称为GATT客户端。
以LED Button应用为例,外围设备(带有LED和按键)作为服务器,集中器作为客户端。
注意:一个设备可以同时作为服务器和客户端。
2. GATT层
GATT层是传输真正数据所在的层。
一个GATT服务器通过一个称为属性表的表格组织数据,这些数据就是用于真正发送的数据。
2.1 属性
一个属性包含句柄、UUID(类型)、值,句柄是属性在GATT表中的索引,在一个设备中每一个属性的句柄都是唯一的。UUID是包含属性表中数据类型的信息,它是理解属性表中的值的每一个字节的意义的关键信息。在一个GATT表中可能有许多属性,这些属性能可能有相同的UUID。
2.2 特性
一个特性至少包含2个属性:一个属性用于声明,一个属性用于存放特性的值。
所有通过GATT服务传输的数据必须映射成一系列的特性,可以把特性中的这些数据看成是一个个捆绑起来的数据,每个特性就是一个自我包容而独立的数据点。 例如,如果几块数据总是一起变化,那么我们可以把它们集中在一个特性里。
以LED Button应用为例,外围设备(带有LED和按键)作为服务器,集中器作为客户端。在LED Button服务中,LED和按键之间没有任何联系,而且它们可以各自独立地改变, 因此,可以让它们成为独立的特性,所以我们用一个特性表示当前按键的状态,用另一个特性用来表示当前LED的状态。
2.3描述符
任何在特性中的属性,不是定义为属性值,就是为描述符。描述符是一个额外的属性,以提供更多特性的信息,它提供一个人类可识别的特性描述的实例。
然而,有一个特别的描述符值得特别地提起:客户端特性配置描述符(Client Characteristic Configuration Descriptor,CCCD),这个描述符是给任何支持通知或指示功能的特性额外增加的。
在CCCD中写入“1”使能通知功能,写入“2”使能指示功能,写入“0”同时禁止通知和指示功能。
2.4服务
一个服务包含一个或多个特性,这些特性是逻辑上相关的集合体。
GATT服务一般包含几块具有相关的功能,比如特定传感器的读取和设置,人机接口的输入输出。组织具有相关的特性到服务中既实用又有效,因为它使得逻辑上和用户数据上的边界变得更加清晰,同时它也有助于不同应用程序间代码的重用。GATT基于蓝牙技术联盟(SIG)官方而设计,SIG建议根据它们的规范设计自己的profile。
对于LED Button应用例程,因为不关心它们的重用,所以把LED特性和按键特性放到了一个服务中。
2.5 profile(数据配置文件)
一个profile文件可以包含一个或者多个服务,一个profile文件包含需要的服务的信息,或为对等设备如何交互的配置文件的选项信息。设备的GAP和GATT的角色都可能在数据的交换过程中改变,因此,这个文件应该包含广播的种类、所使用的连接间隔、所需的安全等级等信息。
需要注意的是: 一个profile中的属性表不能包含另一个属性表。
2.6 标准的定制服务和特性
蓝牙技术联盟(SIG)已经定义一些profile、服务、特性和根据协议栈的GATT层定义的属性。但是,协议栈中只实现了一部分应用的BLE服务,那就意味着,只要协议栈支持GATT,就可能为一个应用建立一个它需要的profile和服务。
既然在一个应用中可以支持profile和服务,那么就可以在这个应用中建立一个定制的服务。
2.7 UUID
“GATT层”中定义的所有属性都有一个UUID值,UUID是全球唯一的128位的号码,它用来识别不同的特性。
2.7.1 蓝牙技术联盟 UUID
蓝牙核心规范制定了两种不同的UUID,一种是基本的UUID,一种是代替基本UUID的16位UUID。
蓝牙技术联盟定义所有的UUID共用了一个基本的UUID:0x0000xxxx-0000-1000-8000-00805F9B34FB
为了进一步简化基本UUID,蓝牙技术联盟定义的每一个属性有一个唯一的16位UUID,以代替上面的基本UUID的‘x’部分。例如,心率测量特性使用0X2A37作为它的16位UUID,因此它完整的128位UUID为:
0x00002A37-0000-1000-8000-00805F9B34FB
虽然蓝牙技术联盟使用相同的基本UUID,但是16位的UUID足够唯一地识别蓝牙技术联盟所定义的各种属性。蓝牙技术联盟所用的基本UUID不能用于任何定制的属性、服务和特性。对于定制的属性,必须使用另外完整的128位UUID。
2.7.2 供应商特定的UUID
SoftDevice 根据蓝牙技术联盟定义UUID类似的方式定义UUID:先增加一个特定的基本UUID,再定义一个16位的UUID(类似于一个别名),然后加载在基本UUID之上。这种采用为所有的定制属性定义一个共用的基本UUID的方式使得应用变为更加简单,至少在同一服务中更是如此。
使用软件nRFgo Studio非常容易产生一个新的基本UUID: 例如,在LED BUTTON示例中,采用0x0000xxxx-1212-EFDE-1523-785FEABCD123作为基本UUID。
蓝牙核心规范没有任何规则或是建议如何对加入基本UUID的16位UUID进行分配,因此你可以按照你的意图来任意分配。例如,在LED BUTTON示例中,0x1523作为服务的UUID,0x1524作为LED特性的UUID,0x1525作为按键状态特性的UUID。
2.8 空中操作和性质
大部分的空中操作事件都是采用句柄来进行的,因为句柄能够唯一识别各个属性。如何使用特性依据它的性质,特性的性质包括:
1)写
2)没有回应的写
3)读
4)通知
5)指示
2.8.1 写和没有回应的写
写和没有回应的写,允许GATT客户端写入一个值到GATT服务器的一个特性中。它们之间不同的地方在于:没有回应的写事件,没有任何应用层上的确认或回应。
2.8.2 读
读性质表明一个GATT客户端可以读取在GATT服务器中特性的值。
2.8.3 通知和指示
通知和指示性质允许GATT服务器在其某个特性改变的时候对GATT客户端进行提醒,通知和指示之间不同之处在于指示有应用层上的确认,而通知没有。