BLE service, characteristic以及CCCD概念 9

来自:https://www.cnblogs.com/iini/p/9095622.html

客户端(client):手机使用设备提供服务,因此手机就是client

服务端(server):以数据为载体,提供各种有价值的数据,比如蓝牙体温计

BLE service, characteristic以及CCCD概念 9_第1张图片

上图的Request和Reponse其实就是我们经常说的ATT命令(ATT PDU),

Client和Server之间就是通过ATT PDU进行交互的,例如一个数据“37”,可以说是体温37,也可以说是心率37

因此Server需要将数据进行包装和分类,在BLE中,数据是通过characterristic进行包装的,

个服务有多个characteristic组成的,service是一个独立的服务单元,也可以称作为profile,比如:心率/HID/体温/

都是标准蓝牙服务。

 

BLE 协议栈构架:

BLE service, characteristic以及CCCD概念 9_第2张图片

      对应开发应用程序或者service的时候,调用的都是GATT API, 而GATT又调用了ATT API,

BLE数据最终都是通过ATT PDU来传输的,

    Server是通过characteristic来表示数据的,虽然一条数据最有价值的部分是它的值(value),但是仅有

value是不够的,比如,27 表示27温度还是27%湿度,同时每个value还应该有读写属性及权限属性,

    一个characteristic包含三种条目:characteristic 声明,characteristic的值,以及characteristic的描述符(可以多个描述符)

BLE service, characteristic以及CCCD概念 9_第3张图片

    一个service可以保护多个characteristic ,characteristic declaration就是每个characteristic的分界符,

解析时一旦遇到characteristic declaration,就可以认为接下来又是一个新的characteristics了,同时characteristic declaration还将包含value的读写属性,

    Characteristic value 就是数据值了

    Characteristic descriptor就是数据的额外信息,比如温度的单位是什么;CCCD是一种特殊characterristic descriptor,

一般而言,都是cilent来访问server的characteristic,我们把这种操作称作为读或写,另外,server可以直接把自己的charactertis的值告诉client,我们称作为notify或者indicate,跟read操作相比,只有需要传输数据的时候或者说数据有效时,server才开始notify或者indicate数据到client,因此这种操作方式可以大大节省server的功耗,有时候client不想监听characteristic notify或者indicate过来的数据,那么就可以使用CCCD来关闭characteristic 的notify或者indicate功能,如果client又需要监听characteristic 的notify或者indicate,俺么它可以重新使能CCCD来打开相关操作,总结一下,当characteristic 具有notify或者indicate操作功能时,那么必须添加CCCD,以方便cilent来使能或者禁止notify功能

    不管是characteristic declaration,characteristic value 还是characteristic descriptor来实现的时候,我们都是用attribute来表达

BLE service, characteristic以及CCCD概念 9_第4张图片

         Attribute handle,Attribute句柄,16-bit长度,Client 访问Server的Attribute,都是通过这个句柄来访问的,也就是说ATT PDU一般都包含handle的值,用户在软件代码添加characteristic 的时候,系统自动按顺序为相关attribute生成句柄

      Attribute tye,Attribute类型,2字节或者16字节,在BLE中我们使用UUID来定义数据类型,UUID是128bit,所以我们有足够的UUID来表达万事万物,

BLE service, characteristic以及CCCD概念 9_第5张图片

       ATT层定义了一个通信的基本框架,数据结构,以及通信的指令,而GATT层就是前文描述的service和characteristic,GATT层用来赋予每个数据一个具体内涵,让数据变得有结构和意义,换句话说,没有GATT层,低功耗蓝牙可以通信起来,但会产生兼容性问题及通信的低效率,

   Attribute value 就是数据真正的值,0到512字节长

  Attribute permission,Attribute的权限属性,权限属性不会直接在空中包体现,而是隐含在ATT命令操作结果中,假设一个attribute read 属性设为open(读操作不需要任何权限),那么cilent去读这个attribute时server将直接返回attribute的值,如果这个attribure read 属性设置为authentication (即需要配对才能访问,),如果client没有与server配对而言直接访问这个attribute,那么server会返回一个错误码,告诉client你的权限不够,此时client会对server发起配对请求,以满足这个attribute的属性要求,目前有如下四种权限属性:

      Open :直接可以读或者写

     No Access :禁止读或者写

     Autherntication :需要配对才能读或者写,由于配置有多种类型,因此authentication又衍生多种类型,比如带不带MIM,有没有LESC

     Authorization:跟Open一样,不过server返回attribute的值之前需要应用先授权,也就是说应用可以调回函数里面去修改读或者写的原始值,

  Signed 签名后才能读或者写,这个用的比较少,

BLE service, characteristic以及CCCD概念 9_第6张图片

      NUS 包含2 个characteristic :RX和TX,每一个条目都是一个attribute,NUS服务本身就是一个attribute,而Rx charactertic本身又包含2条attribute:一条是delclaration attribute ,一条是value 本身attribute.由于TX支持notify,所以它包含3条attribute,另外一条attribute是CCCD,每个attribute都有一个handle和UUID,handle用来访问该attribute,UUID用来指明该attribute的类型,可以说,server提供数据,而数据是由attribute来表达,所有attribute组成一个attribute table,支持该服务不同,attribute talbe就不同,

当你在nodic已有的基础上添加新的服务或者删除已有的服务,记得一定要去修改ATTR_TAB_SIZE那个宏,否则协议栈初始会有问题。

         Client和Server之间是通过ATT PDU来通信的,ATT PDU主要包括4类:读,写,notify和indicate。如果一个命令需要response,那么会在相应命令后面加上request;如果一个命令只需要ACK而不需要response,那么它的后面就不会带request。这里要特别强调一点,BLE所有命令都是“必达”的,也就是说每个命令发出去之后,会立马等ACK信息,如果收到了ACK包,发起方认为命令完成;否则发起方会一直重传该命令直到超时导致BLE连接断开

        其实大家经常碰到的“丢包”,不是空中把包丢了或者包在空中被干扰了,而是大家发送的代码写得有问题,导致你要发送的包没有被安全送达到协议栈射频FIFO中,所以以后大家碰到丢包情况,请先检查你的代码,保证你的数据包正确完整安全地送达到协议栈射频FIFO中,只要数据包放到了协议栈射频FIFO中,蓝牙协议栈就能保证该数据包“必达”对方。

    既然每个ATT命令都必达对方,那么还需要request做什么?如果一个命令带request后缀,那么发起方就可以收到命令的response包,这个response包在应用层是由回调事件的,而前述ACK包在应用层是没有回到事件的,所以采用request/response方式,应用层可以按照顺序发送一些数据包,这个在很多应用场合是非常有用的,相反,如果对你应用层数据包顺序没有要求,俺么就可以不使用request/response.

  另外request/resonse 有一个副作用:大大降低通信的吞吐率,因为request/resonse必须在不同链接间隔中出现,也就是说,你在间隔1中发送了一个request命令,那么resonse包必须在间隔2或者稍后间隔中回复,而不能再间隔1中回复,这就导致两个连接间隔最多只能发一个数据包,而不带request后缀的ATT命令就没有这个问题,在同一个连接间隔,你可以同时发送多个数据包,这样将大大提高数据吞吐率,

 

 

 

 

 

你可能感兴趣的:(蓝牙51822)