BLE学习

协议栈解析编程

  • 对开发者来讲,很简单,他只须要调用send(0x53)
  • GATT层定义数据的类型和分组,方便起见,咱们用0x0013表示电量这种数据类型,这样GATT层把数据打包成130053(小端模式!)
  • ATT层用来选择具体的通讯命令,好比读/写/notify/indicate等,这里选择notify命令0x1B,这样数据包变成了:1B130053
  • L2CAP用来指定connection interval(链接间隔),好比每10ms同步一次(CI不体如今数据包中),同时指定逻辑通道编号0004(表示ATT命令),最后把ATT数据长度0x0004加在包头,这样数据就变为:040004001B130053
  • LL层要作的工做不少,首先LL层须要指定用哪一个物理信道进行传输(物理信道不体如今数据包中),而后再给此链接分配一个Access address(0x50655DAB)以标识此链接只为设备A和设备B直连服务,而后加上LL header和payload length字段,LL header标识此packet为数据packet,而不是control packet等,payload length为整个L2CAP字段的长度,最后加上CRC24字段,以保证整个packet的数据完整性,因此数据包最后变成:
    • AAAB5D65501E08040004001B130053D550F6
      • AA – 前导帧(preamble)
      • 0x50655DAB – 访问地址(access address)
      • 1E – LL帧头字段(LL header)
      • 08 – 有效数据包长度(payload length)
      • 04000400 – ATT数据长度,以及L2CAP通道编号
      • 1B – notify command
      • 0x0013 – 电量数据handle
      • 0x53 – 真正要发送的电量数据
      • 0xF650D5 – CRC24值
      • 虽然开发者只调用了 send(0x53),但因为低功耗蓝牙协议栈层层打包,最后空中实际传输的数据将变成下图所示的模样,这就既知足了低功耗蓝牙通讯的需求,又让用户API变得简单,可谓一举两得!

 

经常使用ATT命令

        蓝牙的request/response安全

        Client和Server之间是经过ATT PDU来通讯的,ATT PDU主要包括4类:读,写,notify和indicate。若是一个命令须要response,那么会在相应命令后面加上request;若是一个命令只须要ACK而不须要response,那么它的后面就不会带request。这里要特别强调一点,BLE全部命令都是“必达”的,也就是说每一个命令发出去以后,会立马等ACK信息,若是收到了ACK包,发起方认为命令完成;不然发起方会一直重传该命令直到超时致使BLE链接断开。换句话说,只要你的BLE没有断开,那么你以前发送的数据包,无论它是用什么ATT PDU来发送的,它确定被对方收到了。我估计不少人对此会产生疑问,由于他们常常碰到丢包的状况,其实你们常常碰到的“丢包”,不是空中把包丢了或者包在空中被干扰了,而是你们发送的代码写得有问题,致使你要发送的包没有被安全送达到协议栈射频FIFO中,因此之后你们碰到丢包状况,请先检查你的代码,保证你的数据包正确完整安全地送达到协议栈射频FIFO中,只要数据包放到了协议栈射频FIFO中,蓝牙协议栈就能保证该数据包“必达”对方。既然每一个ATT命令都必达对方,那么还须要request作什么?若是一个命令带有request后缀,那么发起方就能够收到命令的response包,这个response包在应用层是有回调事件的,而前述的ACK包在应用层是没有回调事件的。因此采用request/response方式,应用层能够按顺序地发送一些数据包,这个在不少应用场合是很是有用的。相反,若是你对应用层数据包的顺序没有要求,那么就能够不使用request/response形式。另外Request/response有一个反作用:大大下降通讯的吞吐率,由于request/response必须在不一样的链接间隔中出现,也就是说,你在间隔1中发送了一个request命令,那么response包必须在间隔2或者稍后间隔中回复,而不能在间隔1中回复,这就致使两个链接间隔最多只能发一个数据包,而不带request后缀的ATT命令就没有这个问题,在同一个链接间隔中,你能够同时发多个数据包,这样将大大提升数据的吞吐率。你们能够参考下图来理解request和非request命令的区别:模块化

 

经常使用的带request的命令:全部read命令,write request,indication等,而经常使用的不带request的命令有write command,notification等,完整的ATT命令列表以下所示:函数

 

NRF_SDH_BLE_OBSERVER用来为本地文件(此处为main.c)注册一个BLE回调函数(此处为ble_evt_handler),NRF_SDH_BLE_OBSERVER这个宏执行成功后,全部的BLE事件都会被ble_evt_handler捕获。进入ble_evt_handler,你会发现BLE有上百个回调事件,你不须要每一个都处理,你只须要处理你关心的事件便可,好比链接成功事件BLE_GAP_EVT_CONNECTED或者链接断开事件BLE_GAP_EVT_DISCONNECTEDspa

NRF_SDH_BLE_OBSERVER有一个很大的好处:某个模块若是须要捕获BLE事件,那么它本身调用NRF_SDH_BLE_OBSERVER这个宏注册相应回调函数便可,而再也不须要在其它文件中去注册这个回调函数,将模块的耦合性降到最低,符合模块化编程思想。(即response包在应用层的回调函数)blog

相关文章
相关标签/搜索