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 ConfigurationDescriptor,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客户端进行提醒,通知和指示之间不同之处在于指示有应用层上的确认,而通知没有。