廣播通道空中包
在學習BLE的過程中,對於廣播通道的空中包有許多混淆的地方,包括各個空中包的用途,幀格式等。現在想把他們做一個總結和歸納。
BLE廣播通道中的空中包分為有以下幾種:
- 可連線非定向廣播 (ADV_IND)
- 可連線定向廣播 (ADV_DIRECT_IND)
- 不可連線廣播 (ADV_NONCONN_IND)
- 掃描請求 (SCAN_REQ)
- 掃描響應 (SCAN_RSP)
- 連線請求 (CONNECT_REQ)
- 可掃描指示 (ADV_SCAN_IND)
下面將分別詳細介紹下這幾種空中包。
空中包幀格式
之前的博文中有介紹BLE協議空中包的格式,所有空中包格式如下圖所示:
廣播通道空中包的PDU部分如下圖所示:
Header部分如下圖所示:
接下來將結合6中廣播通道的空中包來解釋幀格式中各個欄位的意義
可連線非定向廣播 (ADV_IND)
可連線非定向廣播,是使用最為頻繁的廣播包,幾乎所有提供了連線功能的BLE裝置都使用這種空中包。
可連線的意思是,該裝置提供了能與之建立鏈路層連線的功能;非定向的意思是,並非只有某個特定的裝置才能與之建立連線。可連線非定向合起來的意思是,所有收到該廣播的裝置,都可與之建立鏈路層連線
接下來看一下這種廣播包幀格式中的payload部分,如下圖所示:
由上圖可知,payload部分包含2個欄位:AdvA和AdvData
- AdvA: Adv Address,它表示廣播者的裝置地址
- AdvData:廣播資料,包括service data,service uuid以及manufacture data等等。
那麼AdvA中的裝置地址到底是公共裝置地址還是私有裝置地址呢?我們知道Header部分有一個欄位TxAdd,佔位1個bite。如果該位元為0,則表示AdvA是公共裝置地址;如果該位元為1,則表示AdvA是私有裝置地址
可連線定向廣播 (ADV_DIRECT_IND)
可連線定向廣播,是指明瞭對方裝置地址的,為之提供了連線功能的廣播包。簡而言之就是,只有廣播包中指定的那個裝置才能與之建立鏈路層連線,其餘裝置的連線請求均被忽略。
幀格式中的payload部分,如下圖所示:
由上圖可知,payload部分包含2個欄位:AdvA和InitA:
- AdvA:Adv Address,它表示廣播者的裝置地址
- InitA:表示接收者的裝置地址,它指明瞭該廣播包的接收者地址,也表示後續也只有該裝置才能與之建立鏈路層連線
Header中的TxAdd欄位表示AdvA地址是公共地址還是私有地址;RxAdd欄位表示InitA地址是公共地址還是私有地址。相應的,如果為0表示公共地址;如果是1,則表示私有地址
不可連線廣播 (ADV_NONCONN_IND)
不可連線廣播,通常用於向周圍的裝置週期性的廣播一些特定的資訊,附近的任何裝置都可以接收這種廣播包,但不可與之建立連線。
例如,這種廣播包可用於防丟器的應用場景,在一些容易丟棄的物件上內建BLE晶片,並週期性的廣播不可連線廣播包,手機掃描這種廣播包,同時也會獲得這種廣播包的接收訊號強度(RSSI),接收訊號強度是與距離相關的,手機離裝置遠的時候,它的強度就弱,弱到一定程度手機就會發出報警聲,表示物件已經離開手機很遠了。
幀格式中的payload部分,如下圖所示:
它的payload部分和可連線非定向廣播包一模一樣,只不過它是不可連線的。
掃描請求 (SCAN_REQ)
上面說到的那些廣播包都是廣播者發出的空中包,掃描請求是掃描者向指定的廣播者發出的空中包,廣播者收到掃描請求後,要立即回覆掃描響應
掃描請求的payload部分如下圖所示:
由上圖可知,它包含2個欄位:ScanA和AdvA:
- ScanA:Scanner Address, 表示掃描者的裝置地址
- AdvA:廣播者的裝置地址
我們知道對於掃描請求來說,掃描者是傳送方,廣播者是接收方。所以Header中的TxAdd表示掃描者的裝置地址型別,RxAdd表示廣播者的裝置地址型別,相應的,為0表示公共裝置地址,為1表示私有裝置地址
掃描響應 (SCAN_RSP)
掃描響應是廣播者發出的空中包,它是作為對掃描請求的響應,其中會攜帶一些與廣播者相關的資料,並返回給掃描者。
掃描響應的payload部分如下圖所示:
由上圖可知,它包含2個欄位:AdvA和ScanRspData:
- AdvA:廣播者的裝置地址
- ScanRspData:Scanner Response Data,表示返回給掃描者的響應資料
對於掃描響應來說,廣播者是傳送方,掃描者是接收方。因而Header中的TxAdd表示AdvA的裝置地址型別,0是公共地址,1是私有地址
值得注意的是,雖然掃描響應中並沒有指定掃描者的裝置地址,但也只有發出對應掃描請求的裝置才能接收該掃描請求,其他裝置會將其忽略。
連線請求 (CONNECT_REQ)
連線請求,既不是廣播者發出的,也不是掃描者發出的。它是由發起者發出,並由廣播者來接收,簡而言之就是發起者向指定的廣播者發起的一個連線請求。
發起者在發起連線請求之前,它必須先知道廣播者的裝置地址,那麼它是如何知道對方地址的呢?一種方式就是通過掃描。我們知道廣播者有2種可連線的廣播包,分別是可連線非定向廣播包和可連線定向廣播包。那麼當掃描者接收到其中一種可連線廣播包的時候,它就知道對方的裝置地址了,因而可以發起連線請求。如果是可連線定向廣播包,前提是定向的是掃描者自己,那麼才能發起連線請求。
連線請求的payload部分如下圖所示:
由上圖可知,payload部分包含3個欄位:
- InitA: Initiator Address,發起者裝置地址
- AdvA:廣播者裝置地址
- LLData:Link Layer Data,表示與鏈路層連線相關的連線引數
LLData的結構如下圖所示:
LLData的內容比較複雜,下面簡單介紹一下:
- AA:Access Address,訪問地址
- CRCInit:用於CRC計算的一個初始值
- WinSize:transmitWindowSize,傳輸視窗的大小
- WinOffset:transmitWindowOffset,傳輸視窗的偏移量
- Interval:connInterval,簡單理解就是一個睡眠喚醒週期的時間
- Latency:connSlaveLatency,表示Slave可以連續多長時間不用監聽通道
- Timeout:connSuppervisionTimeout,裝置雙方約定這麼長時間之後沒有相互收到對方的包了,那麼彼此可以認為連線已經丟失了,比如裝置超出距離的情形
- Chm:Channel Map,後續連線中使用到和未使用到的資料通道
- Hop:跳頻的跳數
- SCA:它和Master的睡眠時鐘精度有關