协议栈解析编程
蓝牙的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