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

相關文章
相關標籤/搜索