
Ble Packet
工具:WireShark、PacketLogger、Ellisys
設備: Apple Watch 、 OPPLE Enco Free2、 vivo WATCH2、HUAWEI-Watch2、vivo TWS 2e等
在數(shù)據(jù)通過BLE傳輸時,數(shù)據(jù)是以包(packet)的方式收發(fā)的,多個包可以在一個連接間隔內(nèi)發(fā)送出去,每個包大小并不一定一樣,但包有最大限制,因此又需要引入一個PDU(protocoldata unit)的概念。
最大PDU表示在一個連接間隔中能發(fā)送的最大數(shù)據(jù)能力。不同BLE協(xié)議棧中或者不同的芯片支持的值是不同的,例如下圖芯片 的是BES2500YP俯視圖。https://bbs.16rd.com/thread-579490-1-1.html
[圖片上傳失敗...(image-cd9cf7-1657542297519)]
而BES恒玄型號BES2500BP,在小米watch Color2、華為Watch GT3/Runner、vivo WATCH2 上已使用,集顯示、存儲、音頻、連接為一體;支持BT5.2雙模藍牙,可支持BLE數(shù)據(jù)傳輸、藍牙通話和音樂播放功能;
BLE 包結構如下:
| Preamble | Access Address | PDU | CRC |
|---|---|---|---|
| (1 Byte) | (4 Bytes) | x | (3 Bytes) |
preamble(前導幀)為1個字節(jié),根據(jù)Access Address第一個Bit,有兩種取值情況:0x55或者0xAA(純PHY層行為),如下所示:
Access Address用來標示接收者ID或者空中包身份,如前所示,BLE只有一種packet格式,根據(jù)Access Address的不同,又區(qū)分兩種Packet類型:廣播包和數(shù)據(jù)包:
廣播包Access Address 固定為0x8E89BED6,廣播包只能在廣播信道(channel)上傳輸,即只能在37/38/39信道上傳輸(注:從藍牙5.0開始廣播包可以在其它信道上傳輸)。廣播包發(fā)送給附近所有的observer(掃描者),屬于一對多關系。
數(shù)據(jù)包Access Address 為一個32bit的隨機值,由Initiator生成。數(shù)據(jù)包,其實是數(shù)據(jù)信道上的空中包的簡稱,數(shù)據(jù)包只在數(shù)據(jù)信道上傳輸,即除37/38/39之外的其余37信道(BLE總共占用40個信道)。每建立一次連接,重新生成一次Access address。數(shù)據(jù)包是給連接通信使用的,即用于master和slave之間通信。
CRC為24bit. 顧名思義,這里是數(shù)據(jù)完整性校驗。
藍牙協(xié)議棧


手機發(fā)送一段write without repsonse的packet數(shù)據(jù)流向:
ATT(HOST) -> L2CAP -> HCI(ACL/Conmand/Event/SCO) -> LL-> PHY
HCI(HOST CONTROLLER INTERFACE):主機控制器接口層
LL(link layer):BLE的鏈路層
PHY:BLE的物理層

L2CAP
邏輯鏈路控制與適配協(xié)議通常簡稱為L2CAP(Logical Link Control and Adaptation Protocol),它向上連接應用層,向下連接控制器層,發(fā)揮主機與控制器之間的適配器的作用,使上層應用操作無需關心控制器的數(shù)據(jù)處理細節(jié)。
經(jīng)典藍牙的L2CAP層比較復雜,它實現(xiàn)了如下多個功能操作,使得主機能夠支持LE和BR/EDR不同的控制器,實現(xiàn)音頻數(shù)據(jù)流傳輸?shù)雀呒壒δ堋?/p>
- 協(xié)議/信道多路復用
- 片段和重組(Segmentation and reassembly)
- 分段和重組 (Fragmentation and Recombination)
- 每個 L2CAP 通道的流量控制(Flow control per L2CAP channel)
- 錯誤控制和重傳(Error control and retransmissions)
- 支持流媒體(Support for Streaming)
- 服務質(zhì)量
BLE的L2CAP層是經(jīng)典藍牙L2CAP層的簡化版本,它在基礎模式下,不執(zhí)行分段和重組,不涉及流程控制和重傳機制,僅使用固定信道進行通信,在LE令牌流程控制模式下,實現(xiàn)了流程控制,執(zhí)行數(shù)據(jù)分段和重組,使用動態(tài)信道進行通信。

L2CAP層包括兩個功能模塊:資源管理器和信道管理器。
L2CAP層向下連接控制器的HCI接口,向上對應用層暴露數(shù)據(jù)收發(fā)接口。
應用層發(fā)送給L2CAP層的數(shù)據(jù)稱為SDU(Service Data Unit),SDU可能是屬性協(xié)議層的讀寫數(shù)據(jù),也可能是鏈接配置命令,也可能是配對綁定數(shù)據(jù)。
SDU在資源管理器中添加L2CAP協(xié)議頭信息,封裝成L2CAP數(shù)據(jù)包,簡稱PDU(Protocol Data Unit)。PDU的Payload字段就包含了SDU或SDU的一部分。
通常HCI接口無法發(fā)送較長數(shù)據(jù)包,需要對PDU進行分解(Fragmentation),變成數(shù)據(jù)碎片(Fragment)再依次發(fā)送到控制器。PDU總是包含完整的L2CAP協(xié)議頭,而數(shù)據(jù)碎片則不是完整的L2CAP數(shù)據(jù)包。
PDU(protocol data unit,協(xié)議數(shù)據(jù)單元)結構如下:
| LL Header | Payload(MTU) | MIC |
|---|---|---|
| (2 Bytes) | (7+x) | (4 Bytes) |
對于profile層的characteristic,其最大的長度是x字節(jié)。為什么是x呢? 看下面
Payload:BLE底層的協(xié)議包格式,一般我們認為這里的Payload屬于有效的數(shù)據(jù),其類似PDU,也有自己的協(xié)議包格式。如下:
藍牙協(xié)議層的MTU = L2CAP(4個Bytes)+ATT頭(3個Bytes)+ ATT Data(業(yè)務數(shù)據(jù)), ATT_MTU = ATT頭+ATT Data, 這里和硬件側的溝通需要注意的點, 硬件開發(fā)同事說的MUT 往往是藍牙協(xié)議層的, 而我們業(yè)務開發(fā),通過API獲取到的MTU值,是僅ATT Data,所以溝通上要特別留意。
所以一個包,在業(yè)務側實際可被使用的最大MTU是要減去協(xié)議開銷-7個byte。
L2CAP(Logical Link Control and Adaptation Protocol,即邏輯鏈路控制和適配協(xié)議),在BLE中 GAP,GATT,SMP 都使用L2CAP 通道將命令及數(shù)據(jù)打包送到鏈路層(Link Layer)。
L2CAP層有多種工作模式:
| 工作模式 | 適用范圍 |
|---|---|
| 基礎L2CAP模式 | Classic, LE |
| 流程控制模式 | Classic |
| 重傳模式 | Classic |
| 增強型重傳模式 | Classic |
| 數(shù)據(jù)流模式 | Classic |
| LE令牌流程控制模式 | LE |
基礎模式為默認工作模式,L2CAP層不執(zhí)行流程控制,對數(shù)據(jù)不執(zhí)行分段和重組操作,其他五種模式均使用了流程控制或重傳機制,需要執(zhí)行分段和重組操作。
在L2CAP層配置階段,會設置參數(shù)是否使用流程控制和重傳機制,如果不使用則使用基礎模式,否則按參數(shù)配置情況使用其他模式。
B-Frame:B幀(Basic information frame)是用于 L2CAP 數(shù)據(jù)包的基本 L2CAP 模式中的 PDU。 它包含一個完整的 SDU 作為其有效載荷,由基本 L2CAP 標頭封裝。格式如下:

Length: 2個字節(jié) ,Information payload的長度
Channel ID( CID): 2字節(jié)長度,對端的目的信道,BLE使用固定的通道編號,可見右表:
Information payload: 有效的數(shù)據(jù),小端序,范圍(0-65535 字節(jié)),但實際上受限于ATT_MTU, 如藍牙協(xié)議5.0中備注了,ATT_MTU最大為255個字節(jié)。
| 信道標識符 | 描述 | 是否支持BLE |
|---|---|---|
| 0x0000 | Null identityer(保留:不能使用) | |
| 0x0001 | L2CAP Signaling Channel(經(jīng)典藍牙信令信道) | |
| 0x0002 | Connectionless Channel(無連接信道) | |
| 0x0003 | AMP Manager Protocol(AMP管理協(xié)議) | |
| 0x0004 | Attitude Protocol(ATT協(xié)議) | BLE,固定信道 |
| 0x0005 | LE L2CAP Signaling Channel (BLE信令信道) | BLE,固定信道 |
| 0x0006 | Security Manager Protocol (安全管理協(xié)議) | BLE,固定信道 |
| 0x0007 ~ 0x001F | reserve (保留) | |
| 0x0020 ~ 0x003E | reserve (保留) | BLE,固定信道 |
| 0x003F | AMP Manager Test Protocol (AMP測試協(xié)議) | |
| 0x0040 ~ 0x007F | Connection-oriented Channel (面向連接信道) | BLE,動態(tài)信道 |
| 0x007F ~ 0xFFFF | Connection-oriented Channel (面向連接信道) |
常規(guī)信道中,低功耗藍牙一共使用了三條信道,0x0004、0x0005、0x0006。
分段與重組
PDU 的 分段與重組
分段是將 PDU 拆成更小的部分,以便從 L2CAP 傳遞到較低層。重組是從較低層傳遞的片段重新組裝 PDU 的過程。分段和重組可以應用于任何 L2CAP PDU。
分段
L2CAP實現(xiàn)可以對任何L2CAP PDU進行分片,以便將其發(fā)送到較低層。如果L2CAP在沒有HCI的情況下直接在Controller上運行,那么一個執(zhí)行方發(fā)是將PDU分割成多個Controller數(shù)據(jù)包,以便通過空氣進行傳輸。如果L2CAP運行在HCI之上,那么一個執(zhí)行方法會向控制器發(fā)送HCI傳輸大小的片段。與一個L2CAP PDU相關聯(lián)的所有L2CAP分片,在處理任何其他進行相同邏輯傳輸?shù)腖2CAP PDU之前,都應由控制器處理以進行傳輸。
BR/EDR鏈路控制器能夠通過使用“開始”和“延續(xù)”指示在片段被轉換成基帶數(shù)據(jù)包時對PDU施加不同的片段。因此,L2CAP和BR/EDR Link Controller都使用相同的機制來控制分片的大小。


重組
控制器將嘗試按順序傳遞數(shù)據(jù)包,并且不會出錯。片段的重組可能發(fā)生在控制器中,但最終由 L2CAP 負責重組 PDU 和 SDU 并檢查 SDU 的長度字段。當控制器接收到數(shù)據(jù)包片段時,它會在每個片段到達時向 L2CAP 層發(fā)送信號,或者在將數(shù)據(jù)包傳遞到 L2CAP 層之前累積多個片段(在接收緩沖區(qū)填滿或計時器到期之前)。 L2CAP 應使用 L2CAP PDU 報頭中的長度字段,作為一致性檢查,并應丟棄任何未能匹配長度字段的 L2CAP PDU。

例子
下面看來之網(wǎng)上的兩個例子。
- 如果BLE4.0,ATT_MTU最后client和server協(xié)商出來結果是23,那么發(fā)送20字節(jié)(ATT_payload)不需要拆包:
1字節(jié)前導碼 + 4字節(jié)訪問地址 + 2字節(jié)鏈路幀頭(其中LLID = 10b,表示一個沒有fragmentation的完整包) + 4字節(jié)L2CAP幀頭 + 3字節(jié)ATT幀頭 + 20字節(jié)的ATT_payload + 3字節(jié)CRC
- 如果BLE4.0,ATT_MTU最后client和server協(xié)商出來假設是63,那么你發(fā)送60字節(jié)數(shù)據(jù)(ATT_payload),L2CAP會將它拆成3包(拆包的原因是因為BLE4.0鏈路層PDU的限制),最終從空中發(fā)出去的包長這樣:
1)1字節(jié)前導碼 + 4字節(jié)訪問地址 + 2字節(jié)鏈路幀頭(其中LLID = 10b,表示這是第一個連續(xù)包) + 4字節(jié)L2CAP幀頭 + 3字節(jié)ATT幀頭 + 20字節(jié)的ATT_payload + 3字節(jié)CRC
2)1字節(jié)前導碼 + 4字節(jié)訪問地址 + 2字節(jié)鏈路幀頭(其中LLID = 01b,表示這是下一包連續(xù)包) + 27字節(jié)的ATT_payload + 3字節(jié)CRC
3)1字節(jié)前導碼 + 4字節(jié)訪問地址 + 2字節(jié)鏈路幀頭(其中LLID = 01b,表示這是最后一個連續(xù)包) + 13字節(jié)的ATT_payload + 3字節(jié)CRC
上面10b、01b中的“b”表示二進制格式,中間的包和最后的包的LLID都是01b,對方怎么知道什么時候收完包呢?靠的是第一包的4字節(jié)L2CAP幀頭,這里面會說明后面一共有多少數(shù)據(jù)待接收。
ATT
ATT 協(xié)議就在PDU的 Information payload里.
| OptionCode | Handle | ATT Data |
|---|---|---|
| (1 Byte) | (2 Bytes) |
ATT Commond格式如下:
| 屬性 | Size (octets) | 描述 |
|---|---|---|
| Attribute Opcode | 1 | 0x52 = ATT_WRITE_CMD PDU |
| Attribute Handle | 2 | The handle of the attribute to be set |
| Attribute Value | 0 to (ATT_MTU-3) | The value of be written to the attri- bute |
Attribute handle,Attribute句柄,16-bit長度。Client要訪問Server的Attribute,都是通過這個句柄來訪問的,也就是說ATT PDU一般都包含handle的值。用戶在軟件代碼添加characteristic的時候,系統(tǒng)會自動按順序地為相關attribute生成句柄。

在ATT中,比較重要的一個環(huán)節(jié) MTU Exchange。
MTU 交換 是為了在主從雙方設置一個PDU中最大能夠交換的數(shù)據(jù)量, 通過MTU的交換和雙方確認(注意這個MTU是不可以協(xié)商的,只是通知對方,雙方在知道對方的極限后會選擇一個較小的值作為以后的MTU,比如說,主設備發(fā)出一個150個字節(jié)的MTU請求,但是從設備回應MTU是23字節(jié),那么今后雙方要以較小的值23字節(jié)作為以后的MTU),主從雙方約定每次在做數(shù)據(jù)傳輸時不超過這個最大數(shù)據(jù)單元。 如下圖的交換:

下面看一段vivo TWS 2e 耳機在連接過程中 MTU交換過程:


連接之后,host可以向controller發(fā)起mtu exchange procedure,即host告訴controller自己的最大接收能力ATT_MTU(client’s local att protocol channel MTU),controller也會告訴client自己的最大接收能力ATT_MTU(server’s local att protocol channel MTU),最后取兩者的最小值為這條通道的ATT_MTU(actual att protocol channel MTU)。
PHY LAYER
作為軟件開發(fā)者,對這物理層,基本都不會關心,或者說也不用太小,只需了解理論知識。
藍牙工作頻道:免許可的2.4GHz
范圍: 2400MHz - 2483.5MHz,頻段寬度為83.5MHz, BLE將這83.5MHz的寬度分成了0到39共40個通道,每一個通道寬度為2MHz。f=2402+k*2 MHz, k=0, … ,39
調(diào)制方式:BLE規(guī)范目前定義了兩種調(diào)制速率1Mbit/s和2Mbps,BLE 5.0理論上最高可以支持到2Mbps
[圖片上傳失敗...(image-2c9ced-1657542297519)]
上圖為1M PHY和2M PHY在2404頻點發(fā)送數(shù)據(jù)0b1010的對比圖。
BLE的調(diào)制方式為GFSK,BLE定義在信道中傳輸?shù)氖嵌M制符號(波形),即1個符號(波形)表示1個比特,其中相對頻點正偏代表數(shù)字基帶信號1,相對頻點負偏的代表數(shù)字基帶信號0。
之所以速率提高了,本質(zhì)應該是2M PHY的碼長變小了,即發(fā)送一個符號(波形)所需的時間變小了。
可以看出:2M PHY的比特率是1M PHY的兩倍,即2M PHY傳輸完0b1010的時間是1M PHY的一半
其中廣播通道為37/38/39,對應的中心頻率分別為2402MHz、2426MHz、2480MHz。BLE在廣播的時候會輪流使用這3個通道進行廣播。
藍牙協(xié)議層,影響ble速度的相關點,上面都有涉及到了。
BLE 傳輸原理

從上圖看出BLE鏈路層傳輸速率的快慢主要由以下因素決定:
- Connection Interval 的大小;
- 每個 Connection Event 可以發(fā)送多少個 Link Layer Packet;
- 每個 Link Layer Packet 可以負載多少用戶數(shù)據(jù);
- 相鄰 Link Layer Packet之間的時間間隔T_IFS(幀間空間 150μs)。
一旦BLE設備建立連接后,兩個設備會以相等的時間間隔交換數(shù)據(jù),這個間隔成為連接間隔(Connection Interval),間隔范圍是7.5ms-4s。
其中iPhone最小間隔是11.25ms(帶HID),Android最小間隔是7.5ms,Android一個間隔最多傳6包,iOS最多傳4包,這個就是我們再空中抓包時看到的現(xiàn)象。
下圖是iPhone手機上,不同應用上,Ellisys抓的兩端空中包數(shù)據(jù)截圖:


很明顯,第二段的數(shù)據(jù)包非常漂亮。
總結:
不考慮以下的一些客觀因素:
- 射頻環(huán)境, 如果主從設備之間的環(huán)境不好,藍牙交互肯定會受影響,比如丟包了,Link layer層會嘗試丟包重發(fā),這樣就會出現(xiàn)一個LL Packet發(fā)送多遍。
- CPU任務時的響應速度。
- 多鏈路復用場景,多個鏈路分時復用radio,吞吐量會被降低,治理只考慮單鏈路情況。
看下圖:

- 用write without response而不要用write characteristic value
- ATT_MTU盡可能大(這樣可以減少L2CAP的幀頭數(shù)量,通過Fragmentation來盡可能占據(jù)帶寬,提高吞吐量)
- 減少連接間隔(connection interval),增大連接事件(connection event)
- 啟用數(shù)據(jù)包擴展特性(link layer packet)
- 啟用2M PHY特性(BLE5.0可選特性)
附錄:
| 名詞 | 描述 |
|---|---|
| Basic L2CAP header | Minimum L2CAP protocol information that is present in the beginning of each PDU: a length field and a field containing the Channel Identi- fier (CID). |
| CID | Channel Identifiers, L2CAP通道ID |
| SDU | 來自上層的數(shù)據(jù),不包含任何L2CAP層協(xié)議字段 |
| Segment or SDU segment | SDU 的一部分,由分割過程產(chǎn)生。 一個 SDU 可以分成一個或多個段 |
| PDU or L2CAP PDU | (協(xié)議數(shù)據(jù)單元)Protocol Data Unit,協(xié)議數(shù)據(jù)單元:包含 L2CAP 協(xié)議信息字段、控制信息和/或上層信息數(shù)據(jù)的數(shù)據(jù)包。PDU 總是由基本 L2CAP 報頭開始。 PDU 的類型有:B 幀、I 幀、S 幀、C 幀、G 幀和 LE 幀。 |
| B-frame | B幀(Basic information frame)是用于 L2CAP 數(shù)據(jù)包的基本 L2CAP 模式中的 PDU。 它包含一個完整的 SDU 作為其有效載荷,由基本 L2CAP 標頭封裝。 |
| I-frame | I幀(Information frame),I 幀是在增強重傳模式、流模式、重傳模式和流控制模式中使用的 PDU。 它包含一個 SDU 段和附加協(xié)議信息,由基本 L2CAP 頭封裝 |
| S-frame | S幀(Supervisory frame), S 幀是在增強重傳模式、重傳模式和流控制模式中使用的 PDU。 它僅包含協(xié)議信息,由基本 L2CAP 頭封裝,不包含 SDU 數(shù)據(jù)。 |
| C-frame | C幀(Control frame), C 幀是包含在兩端 L2CAP 實體之間交換L2CAP 信令消息的 PDU。 C 幀專門用于 L2CAP 信令信道。 |
| G-frame | G幀(Group frame), G 幀是專用于無連接 L2CAP 通道的 PDU。 它由基本 L2CAP 報頭封裝,包含 PSM,后跟完整的 SDU。 G 幀可用于通過 Active Broadcast 向活動從設備廣播數(shù)據(jù)或將單播數(shù)據(jù)發(fā)送到單個遠程設備 |
| K-frame | K 幀是在基于 LE 的流量控制模式中使用的 PDU。 它包含一個 SDU 段和附加協(xié)議信息,由基本 L2CAP 報頭封裝。 |
| Fragment | 片段是PDU 的一部分,由分片操作產(chǎn)生。 片段僅用于與底層之間的數(shù)據(jù)傳遞。 它們不用于點對點傳輸。 片段可以是關于 L2CAP PDU 的開始或繼續(xù)片段。 一個片段不包含PDU以外的任何協(xié)議信息; 起始片段和延續(xù)片段的區(qū)別是由底層協(xié)議規(guī)定來傳輸?shù)摹?/td> |
| Fragmentation | 將L2CAP pdu拆分成更小的部分的過程,稱為fragments,適合于傳送到較低的傳輸層。盡管在L2CAP層中進行了描述,但碎片實際上可能發(fā)生在HCI主機驅動程序中,和/或控制器中,以適應L2CAP PDU傳輸?shù)紿CI數(shù)據(jù)包或控制器數(shù)據(jù)包的大小。pdu分片可以應用于所有L2CAP模式。 |
| Recombination | 與fragmentation相對應的反向過程,從碎片中重新建立一個L2CAP PDU。在接收路徑中,全部或部分重組操作可能發(fā)生在控制器和/或主機上,重組的位置不一定對應于發(fā)送端發(fā)生分片的位置。 |
| MTU | 最大傳輸單元(Maximum Transmission Unit), 上層能夠接受的有效載荷數(shù)據(jù)的最大大?。ㄒ宰止?jié)單位),即 MTU 對應于最大 SDU 大小。 |
| MPS | L2CAP可接受最大的payload大小(Maximum PDU payload Size),對應于MTU,在沒有分段的情況下,或在基本 L2CAP 模式下,最大傳輸單元與最大 PDU 有效載荷大小相同,兩個配置參數(shù)應設置為相同的值。 |
| MTU(sig) | L2CAP信令MTU大小 |
參考: