2.1 通用访问规范(Generic Access Profile,GAP)
GAP是应用层能够直接访问BLE协议栈的最底层,它包括管理广播和连接事件的有关参数。
注意:GAP的更多详细介绍见《Bluetooth Core Specification》(蓝牙核心规范)的第3卷C部分。
2.1.1 角色
为了创建和维持一个BLE连接,引入了“角色”这一概念。一个BLE设备不是集中器角色就是外围设备角色,这是根据是谁发起这个连接来确定的。集中器设备总是连接的发起者,而外围设备总是被连接者。集中器和外围设备的关系就像链路层中的主机和从机的概念。
在LED Button应用例程中,使用S110 SoftDevice烧录到nRF51822作为外围设备,计算机或者手机作为集中器。
除了集中器角色和外围设备角色,蓝牙核心规范还定义了观察者角色和广播者角色,观察者角色监听空中的事件,广播者角色只是广播信息而不接收信息。观察者角色和广播者角色都只广播而并不建立连接。它们在我们的这个应用中并不适用。
注意:在一个连接的另一端的设备被称为对等设备,不管它是集中器还是外围设备。
2.1.2 广播
集中器能够与外围设备建立连接,外围设备必须处于广播状态,它每经过一个时间间隔发送一次广播数据包,这个时间间隔称为广播间隔,它的范围是20ms到10.24s。广播间隔影响建立连接的时间。
集中器发送一个连接请求来发起连接之前,必须接收到一个广播数据包,外围设备发送一个广播数据包之后一小段时间内只监听连接请求。
一个广播数据包最多能携带31字节的数据,它通常包含用户可读的名字、关于设备发送数据包的有关信息、用于表示此设备是否可被发现的标志等类似的标志。
当集中器接收到广播数据包后,它可能发送请求更多数据包的请求,称为扫描回应,如果它被设置成主动扫描,外围设备将会发送一个扫描回应做为对集中器请求的回应,扫描回应最多可以携带31字节的数据。
广播,包括扫描请求和扫描回应,出现在远离WLAN使用的2.4G频段之外的3个频率上,以防止被WiFi干扰。
2.1.3 扫描
扫描是集中器监听广播数据包和发送扫描请求的过程,它有2个定时参数需要特别注意:扫描窗口和扫描间隔。
对于每一个扫描间隔,集中器扫描的时间等于一个扫描窗口,这就意味着如果扫描窗口等于扫描间隔,那么集中器将处于连续扫描之中。扫描窗口和扫描间隔之比为扫描占空比。
2.1.4 发起
如果集中器想建立一个连接,当扫描监听到广播数据包后它将采用相同的过程:当要发起连接时,集中器接收到一个广播数据包之后将会发送一个连接请求。
2.1.5 连接
集中器和外围设备第一次交换数据定义为连接状态。在一个连接状态中,集中器将会在一个特定定义的间隔从外围设备请求数据,这个间隔称为连接间隔,它由集中器决定并应用于连接,但是外围设备可以发送连接参数更新请求给集中器。根据蓝牙核心规范,连接间隔必须在7.5ms到4s之间。
如果外围设备在一个时间帧内没有回应集中器的数据包,称为连接监管超时,连接被认为丢失。
可以通过在每一个连接间隔中传输多个数据包以获得更高的数据吞吐量,每一个传输数据包最多可以携带20个字节的应用数据。但是如果电流消耗是重点,同时外围设备也没有数据要发送,它可以选择忽略一定数量的连接间隔,这个忽略连接间隔的数目称为从机延时(slave latency)。
在一个连接中,除了广播信道,设备间在频带的所有信道中进行通信。当然对于应用层,这是完全透明的。
2.2 通用属性配置文件(Generic Attribute profile,GATT)
GATT层是传输真正数据所在的层。
2.2
2.2.1角色
除了GAP定义了角色之外,BLE还定义了另外2种角色:GATT服务器和GATT客户端,它们完全独立于GAP的角色。提供数据的设备称为GATT服务器,访问GATT服务器而获得数据的设备称为GATT客户端。
以LED Button应用为例,外围设备(带有LED和按键)作为服务器,集中器作为客户端。 |
注意:一个设备可以同时作为服务器和客户端。
2.2.2 GATT层
一个GATT服务器通过一个称为属性表的表格组织数据,这些数据就是用于真正发送的数据。
2.2.2.1 属性
一个属性包含句柄、UUID、值,句柄是属性在GATT表中的索引,在一个设备中每一个属性的句柄都是唯一的。UUID包含属性表中数据类型的信息,它是理解属性表中的值的每一个字节的意义的关键信息。在一个GATT表中可能有许多属性,这些属性能可能有相同的UUID。
2.2.2.2 特性
一个特性至少包含2个属性:一个属性用于声明,一个属性用于存放特性的值。
所有通过GATT服务传输的数据必须映射成一系列的特性,可以把特性中的这些数据看成是一个个捆绑起来的数据,每个特性就是一个自我包容而独立的数据点。例如,如果几块数据总是一起变化,那么我们可以把它们集中在一个特性里。
以LED Button应用为例,外围设备(带有LED和按键)作为服务器,集中器作为客户端。
在LED Button服务中,LED和按键之间没有任何联系,而且它们可以各自独立地改变, 因此,可以让它们成为独立的特性,所以我们用一个特性表示当前按键的状态,用另一个特性用来表示当前LED的状态。 |
2.2.2.3描述符
任何在特性中的属性不是定义为属性值就是为描述符。描述符是一个额外的属性以提供更多特性的信息,它提供一个人类可识别的特性描述的实例。
然而,有一个特别的描述符值得特别地提起:客户端特性配置描述符(Client Characteristic Configuration Descriptor,CCCD),这个描述符是给任何支持通知或指示功能的特性额外增加的,参见第15页第2.2.5节“空中操作和性质”。
在CCCD中写入“1”使能通知功能,写入“2”使能指示功能,写入“0”同时禁止通知和指示功能。
在S110 SoftDevice协议栈中,对任何使能了通知功能或是指示功能的特性,协议栈将自动加入这个类型的描述符。
2.2.2.4服务
一个服务包含一个或多个特性,这些特性是逻辑上相关的集合体。
GATT服务一般包含几块具有相关的功能,比如特定传感器的读取和设置,人机接口的输入输出。组织具有相关的特性到服务中既实用又有效,因为它使得逻辑上和用户数据上的边界变得更加清晰,同时它也有助于不同应用程序间代码的重用。GATT基于蓝牙技术联盟(SIG)官方而设计,SIG建议根据它们的规范设计自己的profile。
对于LED Button应用例程,因为不关心它们的重用,所以把LED特性和按键特性放到了一个服务中。 |
2.2.2.5 profile(数据配置文件)
一个profile文件可以包含一个或者多个服务,一个profile文件包含需要的服务的信息或者为对等设备如何交互的配置文件的选项信息。设备的GAP和GATT的角色都可能在数据的交换过程中改变,因此,这个文件应该包含广播的种类、所使用的连接间隔、所需的安全等级等信息。
需要注意的是一个profile中的属性表不能包含另一个属性表。
在LED BUTTON示例中的profile不是一个标准描述的profile。 |
2.2.3 标准的定制服务和特性
蓝牙技术联盟(SIG)已经定义一些profile、服务、特性和根据协议栈的GATT层定义的属性。但是,协议栈中只实现了一部分应用的BLE服务,那就意味着,只要协议栈支持GATT,就可能为一个应用建立一个它需要的profile和服务。
既然在一个应用中可以支持profile和服务,那么就可以在这个应用中建立一个定制的服务。
对于LED BUTTON这个示例来说,蓝牙技术联盟没有包含这个应用,因此它建立了一个定制的服务,包括2个定制的特性。 |
2.2.4 UUID
在第10页2.2.2节“GATT层”中定义的所有属性都有一个UUID值,UUID是全球唯一的128位的号码,它用来识别不同的特性。
2.2.4.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.2.4.2 供应商特定的UUID
SoftDevice 根据蓝牙技术联盟定义UUID类似的方式定义UUID:先增加一个特定的基本UUID,再定义一个16位的UUID(类似于一个别名),再加载在基本UUID之上。这种采用为所有的定制属性定义一个共用的基本UUID的方式使得应用变为更加简单,至少在同一服务中更是如此。
使用软件nRFgo Studio非常容易产生一个新的基本UUID,见第29页第4.4.3节“服务初始化”。
例如,在LED BUTTON示例中,采用0x0000xxxx-1212-EFDE-1523-785FEABCD123作为基本UUID。 |
蓝牙核心规范没有任何规则或是建议如何对加入基本UUID的16位UUID进行分配,因此你可以按照你的意图来任意分配。
例如,在LED BUTTON示例中,0x1523作为服务的UUID,0x1524作为LED特性的UUID,0x1525作为按键状态特性的UUID。 |
2.2.5 空中操作和性质
大部分的空中操作事件都是采用句柄来进行的,因为句柄能够唯一识别各个属性。如何使用特性依据它的性质,特性的性质包括:
l 写
l 没有回应的写
l 读
l 通知
l 指示
更多的性质在蓝牙规范中有明确的定义,但以上性质更为常用。
2.2.5
2.2.5.1 写和没有回应的写
写和没有回应的写允许GATT客户端写入一个值到GATT服务器的一个特性中。它们之间不同的地方在于没有回应的写事件没有任何应用层上的确认或回应。
2.2.5.2 读
读性质表明一个GATT客户端可以读取在GATT服务器中特性的值。
2.2.5.3 通知和指示
通知和指示性质允许GATT服务器在其某个特性改变的时候对GATT客户端进行提醒,通知和指示之间不同之处在于指示有应用层上的确认,而通知没有。