GATT(三)

四、GATT FEATURE REQUIREMENTS

4.1 GATT Profile一共定义了11种功能

(1)Server Configuration

(2)Primary Service Discovery

(3)Relationship Discovery

(4)Characteristic Discovery

(5)Characteristic Descriptor Discovery

(6)Reading a Characteristic Value

(7)Writing a Characteristic Value

(8)Notification of a Characteristic Value

(9)Indication of a Characteristic Value

(10)Reading a Characteristic Descriptor

(11)Writing a Characteristic Descriptor

4.2 client和server对各种功能的支持情况,其各种功能用到的程序如下图所示:

4.3 SERVER CONFIGURATION

这个功能是client用来设置ATT的,只有一个设置MTU size的程序:Exchange MTU

当client的ATT_MTU大于default ATT_MTU时,client就会调用Exchange MTU程序配置ATT_MTU,这个程序只有在连接过程中执行一次(连接中其实也可以用,Android原生的CTS测试中就有连接中更改ATT_MTU的操作)。在BR/EDR physical link不执行Exchange MTU,MTU的交互是L2CAP做的

过程:

(1)client发送ATT的Exchange MTU Request给server,参数Client Rx MTU设置为自己可以接收的最大MTU size

(2)Server有两种可能的回复,一种是Exchange MTU Response和Error Response,正常情况下回复Exchange MTU Response,参数Server Rx MTU为server端可以接收的最大MTU size,然后client和server都会取Client Rx MTU和Server Rx MTU中最小的值作为ATT_MTU。异常时回复Error Response,error code会设置失败的原因,如果Error Code为Request Not Supported,则client和server都会使用default MTU

如下图所示:

Client发送Exchange MTU Request,设置Client Rx MTU=0x0200,Server回复Exchange MTU Response,设置Server Rx MTU=0x0032,server和client都会设置ATT_MTU=0x0032

4.4 PRIMARY SERVICE DISCOVERY

Client使用这个功能搜索server上的primary services

这个功能分为两个子程序:

Discover All Primary Services和Discover Primary Services by Service UUID

4.4.1 Discover All Primary Services

Client使用这个程序搜索server上所有的primary services。

步骤:

(1)Client使用ATT的Read By Group Type Request,设置Attribute Type为«Primary Service»,Starting Handle=0x0001,Ending Handle=0xFFFF;

       (2)server有两种可能的回复:Read By Group Type Response和Error Response,如果是Error Response代表有错误发生,停止搜索,Error Code表示错误原因,如果Error Code为«Attribute Not Found»,则表示搜索完成,如果是Read By Group Type Response,则其中会包含一个链表,每个链表元素都包含Attribute Handle、End Group Handle和Attribute Value,其中Attribute Value就是要搜索的services的UUID,Attribute Handle就是service declaration的handle,End Group Handle就是service definition的最后一个attribute。如果链表中最后一个元素的End Group Handle=0xFFFF也表示搜索完成。

       (3)如果第(2)步,收到的不是Error Response或者没有搜索完成,则继续client继续发送Read By Group Type Request,设置Attribute Type为«Primary Service»,Starting Handle=(1 + Read By Group Type Response中最后一个End Group Handle),Ending Handle=0xFFFF;

       (4)重复第(2)(3)步,直到client收到Error Response或者Read by Type Group Response中最后一个End Group Handle=0xFFFF为止

注意:

(1)如果搜索到想要的primary service,程序是可以提前结束的。

举例:

(1)Client使用ATT的Read By Group Type Request,设置Attribute Type为«Primary Service»,Starting Handle=0x0001,Ending Handle=0xFFFF;

       (2)server回复Read By Group Type Response,Length=0x06,Attribute Data List为0x0001,0x000F,«UUID1»,0x0010,0x0017,«UUID2»,0x0100,0x01FF,«UUID3»;其中0x06表示链表中每个元素占6个字节,第一个元素是0x0001,0x000F,«UUID1»,第二个元素是0x0010,0x0017,«UUID2»,第三个元素是0x0100,0x01FF,«UUID3»,最后一个元素的Group End Handle=0x01FF,不是0xFFFF所以没有结束。

       (3)client继续ATT的Read By Group Type Request,设置Attribute Type为«Primary Service»,Starting Handle=1 + 0x01FF=0x0200,Ending Handle=0xFFFF;

       (4)server回复Read By Group Type Response,Length=0x06,Attribute Data List为0x0200,0x02FF,«UUID4»,0x0300,0x03FF,«UUID5»,0x0400,0x04FF,«UUID6»;最后一个元素的Group End Handle=0x04FF,不是0xFFFF所以没有结束

       (5)client继续ATT的Read By Group Type Request,设置Attribute Type为«Primary Service»,Starting Handle=1 + 0x04FF=0x0500,Ending Handle=0xFFFF;

(6)server回复Error Response,Error Code为«Attribute Not Found»,搜索结束

举例:

Client使用ATT的Read By Group Type Request,设置Attribute Type为«Primary Service»=0x2800,Starting Handle=0x0001,Ending Handle=0xFFFF;

 

server回复Read By Group Type Response,attribute value为:0x06,0x0001,0x0205,0x1800,0x1001,0x1001,0x1801,0x2001,0xFFFF,0xFF00;其中0x06表示链表中每个元素占6个字节,第一个元素是0x0001,0x0205,0x1800,第二个元素是0x1001,0x1001,0x1801,第三个元素是0x2001,0xFFFF, 0xFF00,最后一个元素的Group End Handle=0xFFFF,表示搜索结束。 

 

4.4.2 Discover Primary Service by Service UUID

当知道Service UUID的情况下,Client使用这个程序搜索指定的primary service,这个指定的primary service在server端可能存在多个。

步骤:

(1)client使用ATT的Find By Type Value Request,设置Attribute Type参数为«Primary Service»,Attribute Value设置为指定primary service的16-bit Bluetooth UUID或者128-bit UUID,Starting Handle=0x0001,Ending Handle=0xFFFF;

(2)server有两种可能的回复:Find By Type Value Response和Error Response,如果是Error Response代表有错误发生,停止搜索,Error Code表示错误原因,如果Error Code为«Attribute Not Found»,则表示搜索完成,如果是Find By Type Value Response,则其中会包含一个链表,每个链表元素都包含Found Attribute Handle和Group End Handle,其中Found Attribute Handle就是service declaration的handle,End Group Handle就是service definition的最后一个attribute。如果链表中最后一个元素的End Group Handle=0xFFFF也表示搜索完成。

(3)如果第(2)步,收到的不是Error Response或者没有搜索完成,则继续client继续发送Find By Type Value Response,设置Attribute Type为«Primary Service»,Attribute Value设置为指定primary service的16-bit Bluetooth UUID或者128-bit UUID,Starting Handle=(1 + Find By Type Value Response中最后一个End Group Handle),Ending Handle=0xFFFF;

       (4)重复第(2)(3)步,直到client收到Error Response或者Find By Type Value Response中最后一个End Group Handle=0xFFFF为止

注意:

(1)如果搜索到想要的primary service,程序是可以提前结束的。

举例:

(1)Client使用ATT的Find By Type Value Request,设置Attribute Type为«Primary Service»,Starting Handle=0x0001,Ending Handle=0xFFFF,Attribute Value设置为UUID1;

       (2)server回复Find By Type Value Response,Handles Information List为:0x0200,0x0214;最后一个元素的Group End Handle=0x0214,不是0xFFFF所以没有结束。

       (3)client继续ATT的Find By Type Value Request,设置Attribute Type为«Primary Service»,Starting Handle=1 + 0x0214=0x0215,Ending Handle=0xFFFF,Attribute Value设置为UUID1;

       (4)server回复Error Response,Error Code为«Attribute Not Found»,搜索结束

 

4.5 RELATIONSHIP DISCOVERY

Client使用这个功能搜索一个service和其他services的关系。只有一个程序:Find Included Services

4.5.1 Find Included Services这个程序是client用来搜索Server上某个service definition内的

include service declarations使用的

步骤:

(1)client发送ATT的Read By Type Request,设置Attribute Type为«Include»,Starting Handle为包含这个«Include»的Service的starting handle,Ending Handle为包含这个«Include»的Service的ending handle

(2)server有两种可能的回复:Read By Type Response和Error Response,如果是Error Response代表有错误发生,停止搜索,Error Code表示错误原因,如果Error Code为«Attribute Not Found»,则表示搜索完成,如果是Read By Type Response,则其中包含一个Attribute Handle和Attribute Value对的集合,Attribute Handle即include declaration的handle,每个Attribute Value由include service declaration的Attribute Handle和End Group Handle组成,如果include service的service UUID是16-bit Bluetooth UUID也会包含在response中,如果Read By Type Response的最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Read By Type Request的Ending Handle参数,也表示搜索完成

注意:如果被包含的那个service的service UUID是128-bit UUID,则下一步client需要使用Read Request去获取,Read Request的参数Attribute Handle应该是Attribute Handle和Attribute Value对的Attribute Handle

(3)如果第(2)步,收到的不是Error Response或者没有搜索完成,则client继续发送Read By Type Request,设置Attribute Type为«Include»,Starting Handle =(1 + Read By Type Response中最后一个Attribute Handle和Attribute Value对的Attribute Handle),Ending Handle为包含这个«Include»的Service的ending handle

       (4)重复第(2)(3)步,直到client收到Error Response或者Read By Type Response中最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Read By Type Request的Ending Handle参数

注意:

(1)如果搜索到想要的primary service,discovering all the primary services是可以提前结束的。

举例:

(1)Client使用Read By Type Request,Attribute Type为«Include»,Starting Handle为包含这个«Include»的Service的starting handle即0x0200,Ending Handle为包含这个«Include»的Service的最后一个handle即0x0214

       (2)server回复Read By Type Response,Length=0x08,Attribute Data List为:0x0201,0x0500,0x518,«UUID1»;其中0x08表示Attribute Data List中每个元素的长度,0x0201表示include declaration的handle,0x0500,0x518分别表示被包含的那个service的service declaration、End Group Handle,«UUID1»即被包含的service的16bit的UUID。

0x0201!=0x0214,所以没有结束。

       (3)client继续发送ATT的Read By Type Request,设置Attribute Type为«Include»,Starting Handle=1 + 0x0201=0x0202,Ending Handle=0x0214

       (4)server回复Read By Type Response,Length=0x06,Attribute Data List为:0x0202,0x0550,0x568;其中0x06表示Attribute Data List中每个元素的长度,0x0202表示include declaration的handle,0x0550,0x558分别表示被包含的那个service的service declaration、End Group Handle,没有被包含的那个service的UUID,所以被包含的那个service的UUID应该是128bit的,需要使用Read Request去获取

(5)Client使用Read Request,Attribute Handle参数设置为0x550

(6)Server回复Read Response,参数Attribute Value就是被包含的那个service的128bit的UUID

(7)client继续发送ATT的Read By Type Request,设置Attribute Type为«Include»,Starting Handle=1 + 0x0202=0x0203,Ending Handle=0x0214

(8)server回复Error Response,Error Code为«Attribute Not Found»,搜索结束

 

4.6 CHARACTERISTIC DISCOVERY

Client使用这个功能搜索service characteristics。主要分为两个子程序:Discover All Characteristics of a Service和Discover Characteristics by UUID

4.6.1 Discover All Characteristics of a Service

当知道一个service的handle范围时,Client可以使用这个程序搜索一个service definition内所有的characteristic declarations

步骤:

(1)client发送ATT的Read By Type Request,设置Attribute Type为«Characteristic»,Starting Handle为包含这个«Characteristic»的Service的starting handle,Ending Handle为包含这个«Characteristic»的Service的ending handle

(2)server有两种可能的回复:Read By Type Response和Error Response,如果是Error Response代表有错误发生,停止搜索,Error Code表示错误原因,如果Error Code为«Attribute Not Found»,则表示搜索完成,如果是Read By Type Response,则其中包含一个Attribute Handle和Attribute Value对的集合,Attribute Handle即characteristic declaration的handle,Attribute Value包含Characteristic Properties、Characteristic Value Handle和Characteristic UUID,如果Read By Type Response的最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Read By Type Request的Ending Handle参数,也表示搜索完成

(3)如果第(2)步,收到的不是Error Response或者没有搜索完成,则client继续发送Read By Type Request,设置Attribute Type为«Characteristic»,Starting Handle =(1 + Read By Type Response中最后一个Attribute Handle和Attribute Value对的Attribute Handle),Ending Handle为包含这个«Characteristic»的Service的ending handle

(4)重复第(2)(3)步,直到client收到Error Response或者Read By Type Response中最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Read By Type Request的Ending Handle参数

注意:

(1)如果搜索到想要的Characteristic,程序是可以提前结束的。

举例:

(1)Client使用Read By Type Request,Attribute Type为«Characteristic»,Starting Handle为包含这个«Characteristic»的Service的starting handle即0x0200,Ending Handle为包含这个«Characteristic»的Service的最后一个handle即0x0214

       (2)server回复Read By Type Response,Length=0x07,Attribute Data List为:0x0203,0x02,0x0204, «UUID1»,0x0210,0x02,0x212,«UUID2»;其中0x07表示Attribute Data List中每个元素的长度,0x0203,0x02,0x204, «UUID1»是第一个Attribute Handle和Attribute Value对(Attribute Handle=0x0203,Characteristic Properties=0x02,Characteristic Value Handle=0x0204,Characteristic UUID= «UUID1»),0x0210,0x02,0x212,«UUID2»是第二个Attribute Handle和Attribute Value对;0x0210!=0x0214,所以没有结束。

       (3)client继续发送ATT的Read By Type Request,设置Attribute Type为«Characteristic»,Starting Handle=1 + 0x0210=0x0211,Ending Handle=0x0214

       (4)server回复Error Response,Error Code为«Attribute Not Found»,搜索结束

 

4.6.2 Discover Characteristics by UUID(这个有问题)

当知道service的handle范围和characteristic的UUID时,client可以使用这个程序搜索service characteristics

步骤:

(1)client发送ATT的Read By Type Request,设置Attribute Type为«Characteristic»,Starting Handle为包含这个«Characteristic»的Service的starting handle,Ending Handle为包含这个«Characteristic»的Service的最后一个ending handle

(2)server有两种可能的回复:Read By Type Response和Error Response,如果是Error Response代表有错误发生,停止搜索,Error Code表示错误原因,如果Error Code为«Attribute Not Found»,则表示搜索完成,如果是Read By Type Response,则其中包含一个Attribute Handle和Attribute Value对的集合,Attribute Handle即characteristic declaration的handle,Attribute Value包含Characteristic Properties、Characteristic Value Handle和Characteristic UUID,然后检测每个Attribute Value的Characteristic UUID,看是否能找到与要搜索的Characteristics UUID相同的,如果Read By Type Response的最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Read By Type Request的Ending Handle参数,也表示搜索完成

(3)client继续发送Read By Type Request,设置Attribute Type为«Characteristic»,Starting Handle =(1 + Read By Type Response中最后一个Attribute Handle和Attribute Value对的Attribute Handle),Ending Handle为包含这个«Characteristic»的Service的ending handle

(4)重复第(2)(3)步,直到client收到Error Response或者Read By Type Response中最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Read By Type Request的Ending Handle参数

注意:

(1)如果搜索到想要的Characteristics,程序是可以提前结束的。

根据文档的描述:
The Read By Type Request is called again with the Starting Handle set to one greater than the last Attribute Handle in the Read By Type Response.
下面图中第二次发送Read By Type Request的参数Starting Handle应该等于0x0211,其实我感觉0x0211和0x0213其实效果是一样的

 

举例:

(1)Client使用Read By Type Request,Attribute Type为«Characteristic»即0x2803,Starting Handle为包含这个«Characteristic»的Service的starting handle即0x0001,Ending Handle为包含这个«Characteristic»的Service的最后一个handle即0x0205

 

(2)server回复Read By Type Response,Length=0x07,Attribute Data List为:0x0011,0x02,0x0012,0x2A00,0x0204,0x02,0x050A,0x2A01; Attribute Data List的第一组元素是0x0011,0x02,0x0012,0x2A00(Attribute Handle=0x0011,Attribute Value包含的Characteristic Properties=0x02、Characteristic Value Handle=0x0012,Characteristic UUID=0x2A00),第二组元素是0x0204,0x0A,0x0205,0x2A01(Attribute Handle=0x0204,Attribute Value包含的Characteristic Properties=0x0A、Characteristic Value Handle=0x0205,Characteristic UUID=0x2A01),没有结束 

(3)client继续发送ATT的Read By Type Request,设置Attribute Type为«Characteristic»即0x2803,Starting Handle=1 + 0x0204=0x0205,Ending Handle=0x0205

(4)server回复Error Response,Error Code为«Attribute Not Found»,搜索结束 

4.7 CHARACTERISTIC DESCRIPTOR DISCOVERY

Client使用这个方法搜索一个characteristic的characteristic descriptors。这里只有一个程序:Discover All Characteristic Descriptors

4.7.1 Discover All Characteristic Descriptors

Client使用这个程序搜索一个characteristic definition内的所有的characteristic descriptor。

步骤:

       (1)client发送ATT的Find Information Request,设置Starting Handle为要搜索的characteristic definition内的characteristic value的handle加1,Ending Handle为这个characteristic definition的最后一个handle

(2)server有两种可能的回复:Find Information Response和Error Response,如果是Error Response代表有错误发生,停止搜索,Error Code表示错误原因,如果Error Code为«Attribute Not Found»,则表示搜索完成,如果是Find Information Response,则其中包含一个Attribute Handle和Attribute Value对的链表,Attribute Handle即characteristic descriptor的handle,Attribute Value即Characteristic descriptor的UUID,如果Find Information Response的最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Find Information Request的Ending Handle参数,也表示搜索完成

(3)client继续发送Find Information Request,设置Starting Handle =(1 + Find Information中最后一个Attribute Handle和Attribute Value对的Attribute Handle),Ending Handle为这个characteristic definition的最后一个handle

(4)重复第(2)(3)步,直到client收到Error Response或者Find Information Response中最后一个Attribute Handle和Attribute Value对的Attribute Handle等于Find Information Request的Ending Handle参数

注意:

(1)如果搜索到想要的Characteristic Descriptors,程序是可以提前结束的。

举例:

(1)Client使用Find Information Request,Starting Handle为要搜索的characteristic definition内的characteristic value的handle加1即0205,Ending Handle为这个characteristic definition的最后一个handle即0x020F(注意:Discover All Characteristics of a Service的图中,搜索到2个characteristic,一个从handle=0x0203开始即characteristic declaration handle=0x0203,而characteristic value handle=0x0204,另一个从handle=0x0210开始即characteristic declaration handle=0x0210,所以要搜索第一个characteristic内部的characteristic descriptors的范围就在0x0205-0x020F)

       (2)server回复Find Information Response,format=0x01,即16bit UUID,Information Data为:0x0205, «UUID1»,0x0206, «UUID2»;0x0205, «UUID1»是第一个characteristic descriptor, 0x0206, «UUID2»是第二个characteristic descriptor;0x0206!=0x020F,所以没有结束。

       (3)client继续发送ATT的Find Information Request,设置Starting Handle=1 + 0x0206=0x0207,Ending Handle=0x020F

       (4)server回复Error Response,Error Code为«Attribute Not Found»,搜索结束

举例:

(1)Client使用Find Information Request,Starting Handle=0x0013,Ending Handle=0x0203(注意:Discover All Characteristics of a Service的实例图中,搜索到2个characteristic,一个从handle=0x00011开始即characteristic declaration handle=0x0011,而characteristic value handle=0x0012,另一个从handle=0x0402开始即characteristic declaration handle=0x0204,所以要搜索第一个characteristic内部的characteristic descriptors的范围就在0x0013-0x0203)

(2)server回复Error Response,Error Code为«Attribute Not Found»,搜索结束

4.8 CHARACTERISTIC VALUE READ

Client使用这个功能从server读取一个Characteristic Value,有4种方法:Read Characteristic Value、Read Using Characteristic UUID、Read Long Characteristic Values和Read Multiple Characteristic Values

4.8.1 Read Characteristic Value

当client知道Characteristic Value Handle时,可以使用这个方法从server端读取Characteristic Value

步骤:

       (1)client使用ATT的Read Request,设置Attribute Handle为想要读取的Characteristic的Characteristic Value Handle

(2)server可能会回复Read Response,这里面只包含一个长度小于等于(ATT_MTU – 1)个字节的Characteristic Value,如果Characteristic Value的长度大于(ATT_MTU – 1)个字节且需要剩余数据的话,可以使用程序Read Long Characteristic Value;server也可能回复Error Response(error code例如:insufficient authentication、insufficient authorization、insufficient encryption key size或者没有read权限),具体参考error code的说明

举例:

       (1)client使用ATT的Read Request,设置Attribute Handle=0x0002请求读取对应的Characteristic Value

       (2)server回复Read Response,Characteristic Value为“Example Device”

 

4.8.2 Read Using Characteristic UUID

当client知道characteristic UUID而不知道characteristic handle时,Client使用这个程序从server读取Characteristic Value

步骤:

       (1)client发送ATT的Read By Type Request,设置Attribute Type为已知的characteristic UUID,Starting Handle和Ending Handle表示要搜索的handle范围的最小值和最大值。通常是characteristic所在的service的范围。

       (2)client可能回复Read By Type Response或者Error Response,当发送错误时会回复Error Response,如果Error code为Attribute Not Found,则表示在Starting Handle到Ending Handle的范围内没有characteristic存在;如果回复Read By Type Response,会包含一个Attribute Handle和Attribute Value对的链表

举例:

       (1)client发送ATT的Read By Type Request,设置Attribute Type为«UUID12»,Starting Handle=0x0001,Ending Handle=0xFFFF

       (2)server回复Read By Type Response,length=0x04,表示链表中每个元素长度是4,Attribute Handle和Attribute Value对是0x0380,0x08EC,其中Attribute Handle=0x0380,Attribute Value=0x08EC

4.8.3 Read Long Characteristic Values

当client知道Characteristic Value Handle且Characteristic Value的长度一个Read Response放不了的情况下,client会使用这个程序来获取Characteristic Value

步骤:

       (1)client发送ATT的Read Blob Request,设置Attribute Handle为Characteristic Value Handle,Value Offset=0x00;

       (2)如果server回复Error Response,Error code为Attribute Not Long,则表示Characteristic Value的长度小于等于(ATT_MTU – 1),如果回复Read Blob Response,继续执行第(3)步

       (3)client发送Attribute Protocol Read Blob Request,设置Attribute Handle为Characteristic Value Handle,假如之前所获取的所有Characteristic Value的总长度是A,则Value Offset=A;

       (4)service回复回复Read Blob Response,如果Part Attribute Value的长度小于(ATT_MTU – 1)个字节,则表示读取结束了,如果Part Attribute Value的长度等于(ATT_MTU – 1)个字节,则重复步骤(3)

注意:步骤(1)也可以不使用Attribute Protocol Read Blob Request,而使用Read Request

举例:

       (1)client发送Read Request,设置Attribute Handle为0x0003

       (2)server回复Read Response,Characteristic Value的长度是0x0016,一般ATT_MTU是0x0017,0x0016=ATT_MTU-1,所以说明可能字节没有read完

       (3)client发送Read Blob Request,设置Attribute Handle为0x0003,offset=0x0016,表示从Characteristic Value的下标为0x0016的位置开始读。

       (4)server回复Read Response,Characteristic Value的长度还是0x0016,所以说明可能字节没有read完

       (5)client发送Read Blob Request,设置Attribute Handle为0x0003,offset=0x002C,继续读取

       (6)server回复Read Response,Characteristic Value的长度是0x0002,0x0002<0x0016,所以表示read完成。

 

4.8.4 Read Multiple Characteristic Values

       Client如果要读取多个Characteristic Values,可以使用这个程序,前提是client知道这些Characteristic Value对应的handle。

步骤:

       (1)client发送ATT的Read Multiple Requests,设置参数Set Of Handles为要读取的所有Characteristic Value对应的handle

       (2)server可能回复Error Response,失败原因参数Error code,也可能回复Read Multiple Response,其中参数Set Of Values包含的就是与Read Multiple Requests中Set Of Handles里面的handle相对应的Characteristic Values,但是参数Set Of Values的长度必须要小于等于(ATT_MTU – 1)个字节,如果所有的Characteristic Values的总长度大于(ATT_MTU – 1)个字节,也只有前面的(ATT_MTU – 1)个字节会包含在Read Multiple Response中

       注意:假如client收到的Set Of Values的长度等于(ATT_MTU – 1)个字节,那么说明client不能使用Read Multiple Requests,因为不能确定Set Of Values中最后一个Characteristic Value是否被截断。

举例:

(1)client发送Read Multiple Requests,设置参数Set Of Handles为0x0380,0x0009,说明client要读取Characteristic Value handle为0x0380和0x0009对应的value

(2)server回复Read Multiple Response,Set Of Values为0x08EC,0x0A,说明Characteristic Value handle=0x0380对应的Characteristic value是0x08EC;Characteristic Value handle=0x0009对应的Characteristic value是0x0A

 

4.9 CHARACTERISTIC VALUE WRITE

Client使用这个功能向server写入Characteristic Value,一共有5种方法:Write Without Response、Signed Write Without Response、Write Characteristic Value、Write Long Characteristic Values和Reliable Writes

4.9.1 Write Without Response

当client知道Characteristic Value Handle并且不在乎是否写入成功的时候,可以使用这个程序

       注意:这个程序只能写入Characteristic Value的前(ATT_MTU – 3)个字节,不能写入long characteristic,如果要写入long characteristic,需要使用程序Write Long Characteristic Values

       步骤:

       (1)client发送ATT的Write Command,参数Attribute Handle设置为想要写入的Characteristic Value Handle,Attribute Value设置为想要写入的新的Characteristic Value

4.9.2 Signed Write Without Response

       当client知道Characteristic Value Handle且ATT Bearer未加密的情况下,可以使用这个程序,只有当Characteristic Properties中的authenticated bit设置为enable且client和server 按照Generic Access Profile中规定的方式绑定时这个方法才能使用。

这个程序只能写入Attribute Value的前 (ATT_MTU – 15) 个字节,不能写入long Attribute value

Client发送ATT的Signed Write Command,设置Attribute Handle为Characteristic Value Handle,Attribute Value为已认证的新的Characteristic Value

       注意:

(1)无论写入成功还是失败,client都不知道

(2)如果ATT Bearer已经使用LE security mode 1,level 2或者level 3加密,则应该使用程序Write Without Response代替Signed Write Without Response.

注意:BR/EDR上,ATT Bearer已经被加密,使用的是Security Mode 4,所以不能使用这个程序 

 

4.9.3 Write Characteristic Value

当client知道Characteristic Value Handle时可以使用这个程序,这个程序可以知道写入是否成功。这个程序只能写入Attribute Value的前 (ATT_MTU – 3) 个字节,不能写入long Attribute value

步骤:

       (1)client发送ATT的Write Request,参数Attribute Handle设置为想要写入的Characteristic Value Handle,Attribute Value设置为想要写入的新的Characteristic Value

       (2)server可能回复Error Response或者Write Response,如果回复Error Response说明写入失败,失败原因参考Error Code,如果回复Write Response说明写入成功

 

4.9.4 Write Long Characteristic Values

       当client知道Characteristic Value Handle,但是要写入的Characteristic Value太长使用一个Write Request无法发送,此时可以用使用这个方法

步骤:

       (1)client发送ATT的Prepare Write Request,参数Attribute Handle设置为想要写入的Characteristic Value Handle,Part Attribute Value设置为要写入的新的Attribute Value的一部分,Value Offset设置为Part Attribute Value在新的Attribute Value中的偏移 ,第一次Prepare Write Request的Value Offset应该是0x0000

       (2)server可能回复Error Response或者Prepare Write Response,如果是Error Response表示写入失败,停止写入,如果是Prepare Write Response则继续执行

       (3)如果还有数据没有写完,则重复(1)(2)步

       (4)所有的数据都写完了,则client发送Executive Write Request,设置参数Flag=0x01(立即将之前Prepare Write Request的所有数据写入对应的Characteristic value)

(5)server回复Executive Write Response,表示写入完成。

举例:

       (1)client发送ATT的Prepare Write Request,Attribute Handle=0x0003,第一次写入所以Value Offset=0x0000,Part Attribute Value=“My Special Device ”,这次一共是0x0012个字节

       (2)server回复Prepare Write Response

       (3)还未写完,client发送ATT的Prepare Write Request,Attribute Handle=0x0003, Value Offset=0x0000 + 0x0012=0x0012,Part Attribute Value=“Next To The Kitche”,这次也是0x0012个字节

       (4)server回复Prepare Write Response

       (5)还未写完,client发送ATT的Prepare Write Request,Attribute Handle=0x0003, Value Offset=0x0000 + 0x0012 + 0x0012=0x0024,Part Attribute Value=“n Door”,这次是0x0006个字节

       (6)server回复Prepare Write Response

       (7)写完了,client发送Executive Write Request,设置Flag=0x01

       (8)server回复Executive Write Response,写入完成。

注意:client不需要验证Prepare Write Response返回的Part Attribute Value是否和Prepare Write Request中的一样

 

4.9.5 Reliable Writes

       当client知道Characteristic Value Handle且在执行write前要确定向server写入的数据是正确的时,可以使用这个程序,当需要按照顺序写入多个Characteristic Value时也可以使用这个程序。

步骤:

(1)client发送ATT的Prepare Write Request,参数Attribute Handle设置为想要写入的Characteristic Value Handle,Part Attribute Value设置为要写入的新的Attribute Value的一部分,Value Offset设置为Part Attribute Value在新的Attribute Value中的偏移 

       (2)server可能回复Error Response或者Prepare Write Response,如果是Error Response表示写入失败,停止写入,如果是Prepare Write Response则client会检测其中的Value Offset和Part Attribute Value是否正确,如果错误,则终止传输,client发送Execute

Write Request设置参数Flags=0x00,取消之前所有的prepared write,此时可能会重新开始这个程序;如果检测是正确的则继续执行

       (3)如果还有Attribute Value未写完,则重复(1)(2)步

       (4)Attribute Value写完后,client发送Execute Write Request,设置Flag=0x01

       (5)server回复Executive Write Response,写入完成。

注意:   

(1)如果prepared write requests的数量超过支持的最大数量,server会回复Error Response,设置Error Code为Prepare Queue Full

举例:

       (1)client发送ATT的Prepare Write Request,Attribute Handle=0x0323,Value Offset=0x0000,Part Attribute Value=0x00,放入Prepare队列

       (2)server回复Prepare Write Response,Attribute Handle=0x0323,Value Offset=0x0000,Part Attribute Value=0x00,验证与client发送的数据一样

       (3)client发送ATT的Prepare Write Request,Attribute Handle=0x0324,Value Offset=0x0000,Part Attribute Value=0x0103,放入Prepare队列

       (4)server回复Prepare Write Response,Attribute Handle=0x0324,Value Offset=0x0000,Part Attribute Value=0x0103,验证与client发送的数据一样

       (5)client发送ATT的Prepare Write Request,Attribute Handle=0x0325,Value Offset=0x0000,Part Attribute Value=0xC0,放入Prepare队列

       (6)server回复Prepare Write Response,Attribute Handle=0x0325,Value Offset=0x0000,Part Attribute Value=0xC0,验证与client端数据一样

(7)client发送ATT的Prepare Write Request,Attribute Handle=0x0327,Value Offset=0x0000,Part Attribute Value=0xFF,放入Prepare队列

       (8)server回复Prepare Write Response,Attribute Handle=0x0327,Value Offset=0x0000,Part Attribute Value=0xFF,验证与client发送的数据一样

(9)client发送ATT的Prepare Write Request,Attribute Handle=0x0326,Value Offset=0x0000,Part Attribute Value=0x07,放入Prepare队列

       (10)server回复Prepare Write Response,Attribute Handle=0x0326,Value Offset=0x0000,Part Attribute Value=0x07,验证与client发送的数据一样

(11)client发送ATT的Prepare Write Request,Attribute Handle=0x0323,Value Offset=0x0000,Part Attribute Value=0x01,放入Prepare队列

       (12)server回复Prepare Write Response,Attribute Handle=0x0323,Value Offset=0x0000,Part Attribute Value=0x01,验证与client发送的数据一样,此时Prepare队列里面的数据就是:

       Attribute Handle=0x0323,Value Offset=0x0000,Part Attribute Value=0x00

       Attribute Handle=0x0324,Value Offset=0x0000,Part Attribute Value=0x0103

       Attribute Handle=0x0325,Value Offset=0x0000,Part Attribute Value=0xC0

       Attribute Handle=0x0327,Value Offset=0x0000,Part Attribute Value=0xFF

       Attribute Handle=0x0326,Value Offset=0x0000,Part Attribute Value=0x07

       Attribute Handle=0x0323,Value Offset=0x0000,Part Attribute Value=0x01

       (13)client发送Executive Write Request,设置Flag=0x01

       (14)server按照Prepare队列中数据的顺序依次写入(先入先出),然后回复Executive Write Response,写入完成。

 

4.10 CHARACTERISTIC VALUE NOTIFICATION

Server使用这个程序发送Characteristic Value给client,是否发送Notifications可以使用Client Characteristic Configuration descriptor进行配置,server发送Notifications后,client不会有任何回复

4.10.1 Notifications

       当server配置为可以使用Notifications给client发送Attribute Value,server会发送ATT的Handle Value Notification,设置Attribute Handle为想要通知的Characteristic Value的Handle,Attribute Value设置为想要通知的Characteristic Value.

       注意:client不会有任何回复

 

4.11 CHARACTERISTIC VALUE INDICATIONS

Server使用这个程序发送Characteristic Value给client,是否发送Indications可以使用Client Characteristic Configuration descriptor进行配置,server发送Indications后,client会回复Confirmation

4.11.1 Indications

       当server配置为可以使用Indications给client发送Attribute Value时,server会发送ATT的Handle Value Indication,设置Attribute Handle为想要指示的Characteristic Value的Handle,Attribute Value设置为想要指示的Characteristic Value.

       Client收到Indications后,应该回复Handle Value Confirmation

 

4.12 CHARACTERISTIC DESCRIPTORS

这个功能用来读写server端的characteristic descriptors

4.12.1 Read Characteristic Descriptors

当client知道characteristic descriptor declaration的Attribute handle时,可以使用这个方法读取characteristic descriptor

步骤:

       (1)client发送ATT的Read Request,设置参数Attribute Handle为characteristic descriptor handle

(2)server可能回复Error Response和Read Response,如果回复Error Response说明出现问题,具体参考Error code,如果回复Read Response,则参数Attribute Value就是对应的characteristic descriptor value

 

4.12.2 Read Long Characteristic Descriptors

当client知道characteristic descriptor declaration的Attribute handle且一个Read Response放不开characteristic descriptor declaration时,可以使用这个方法读取characteristic descriptor

步骤(文档描述有问题,这里是个人理解):
    (1)client发送ATT的Read Blob Request,设置Attribute Handle为characteristic descriptor handle,Value Offset=0x00;
    (2)如果Read Blob Response’s Part Attribute Value的长度小于(ATT_MTU – 1),则表示读取结束,如果等于(ATT_MTU – 1)则继续发送Read Blob Request。如果收到的是Error Response则停止读取
(3)client继续发送Read Blob Request,设置Attribute Handle为characteristic descriptor handle,假如之前所获取的所有Characteristic Descriptor Value的总长度是A,则Value Offset=A;
    (4)service回复Read Blob Response,如果Part Attribute Value的长度是0或者长度小于(ATT_MTU – 1),则表示读取结束了,如果service回复Error Response,Error code为Invalid Offset,也表示读取完成,否则重复步骤(3)
注意:步骤(1)也可以不使用Attribute Protocol Read Blob Request,而使用Read Request
注意:
(1)下面的图中也有问题,第一次读取到的是18个字节,MTU最小也是23,则MTU-1最小也是22,那返回18个字节是不是表示已经没有数据了,如果说有数据那下一次offset是不是应该为0x12,但是图中下一次却从0x0016开始的。如果说是按照文档中的描述Read Blob Response’s Part Attribute Value为0或者Error Response且Error Code为Invalid Offset表示结束,那么第二次收到数据“umidity”就不再读取了,也不符合上面两个条件怎么就结束了。

4.12.3 Write Characteristic Descriptors

       当client知道characteristic descriptor handle时,可以使用这个程序写入characteristic descriptor value

步骤:

       (1)client发送ATT的Write Request,设置参数Attribute Handle为characteristic descriptor handle,Attribute Value设置为新的characteristic descriptor value

(2)server可能回复Error Response和Write Response,如果回复Error Response说明出现问题,具体参考Error code,如果回复Write Response,则表示写入完成

 

4.12.4 Write Long Characteristic Descriptors

当client知道characteristic descriptor handle且一个Write Request放不了新的characteristic descriptor value时,可以使用这个程序写入characteristic descriptor value

步骤:

       (1)client发送ATT的Prepare Write Request,参数Attribute Handle设置为想要写入的Characteristic Descriptor Handle,Part Attribute Value设置为要写入的新的Attribute Value的一部分,Value Offset设置为Part Attribute Value在新的Attribute Value中的偏移 ,第一次Prepare Write Request的Value Offset应该是0x0000

       (2)server可能回复Error Response或者Prepare Write Response,如果是Error Response表示写入失败,停止写入,如果是Prepare Write Response则继续执行

       (3)如果还有数据没有写完,则重复(1)(2)步

       (4)所有的数据都写完了,则client发送Executive Write Request,设置参数Flag=0x01(立即将之前Prepare Write Request的所有数据写入对应的Characteristic Descriptor value)

(5)server回复Executive Write Response,表示写入完成。

举例:

       (1)client发送ATT的Prepare Write Request,Attribute Handle=0x0214,第一次写入所以Value Offset=0x0000,Part Attribute Value=“My Special Device ”,这次一共是0x0012个字节

       (2)server回复Prepare Write Response

       (3)还未写完,client发送ATT的Prepare Write Request,Attribute Handle=0x0214, Value Offset=0x0000 + 0x0012=0x0012,Part Attribute Value=“Next To The Kitche”,这次也是0x0012个字节

       (4)server回复Prepare Write Response

       (5)还未写完,client发送ATT的Prepare Write Request,Attribute Handle=0x0214, Value Offset=0x0000 + 0x0012 + 0x0012=0x0024,Part Attribute Value=“n Door”,这次是0x0006个字节

       (6)server回复Prepare Write Response

       (7)写完了,client发送Executive Write Request,设置Flag=0x01

       (8)server回复Executive Write Response,写入完成。

注意:client不需要验证Prepare Write Response返回的Part Attribute Value是否和Prepare Write Request中的一样

 

4.13 总结

 

4.14 PROCEDURE TIMEOUTS

如果出现Attribute Protocol transaction timeout,则认为相关的GATT程序失败了,通知上层并关闭ATT Bearer,如果有新的GATT程序要执行,需要重新建立ATT Bearer

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值