第12節-BLE協議HCI層的數據格式


學習資料:

1. 藍牙協議core_v5.0.pdf 《Vol 2: Core System Package [BR/EDR Controller volume]》的“Part E: Host Controller Interface Functional Specification”

2. BTStack源碼

對於被動掃描,周邊的外設會給controller發送各種廣播包,解析廣播包,從而得到設備的信息。

對於主動掃描,除了被動的獲得廣播包外,controller還可以給某個設備發出掃描請求,設備就會返回一個掃描回應,將更多的信息給controller。

兩個藍牙設備互相通信,涉及兩個Controller。Controller是具備一定智能的,它可以自行決定做什么事情:不需要Host決定它的每一個細節。比如說:要想讓Controller發出掃描請求(SCAN REQ),Host只需要向Controller發出一個“scan enable”的命令即可,Controller就會根據預設的參數自動發出掃描請求(SCAN REQ)廣播包。

Controller就是一個芯片,它封裝了LL層、PHY層那些復雜的操作;Host不需要理解芯片內部復雜的操作,只需要遵守Controller的規范,向它提供command,從它獲得event,與它交互acl data。

HCI層跟LL層的關系:

a. 有些HCI command只是用來設置本地Controller,不導致無線傳輸

b. 有些HCI command會導致LL層發出各類廣播包,

   比如“LE Set Scan Enable Command”在主動掃描時會導致LL層發出SCAN_REQ廣播包,

   比如“LE Create Connection Command”會導致LL層發出CONNECT_REQ廣播包

c. 有些HCI command會導致LL層發出數據包,其中的LLID=11b,表示是“LL Control PDU”

   比如“LE Read Channel Map Command”就會導致LL層發數據給對端設備,以便讀取對端設備的信道圖。

d. ACL Data是必定導致LL層發數據給對端設備的

這時的LL層數據,有可能是起始包,LLID=10b;

也可能是延續包,LLID=01b;

也可能是空包,LLID=01b

在上一篇博客里,在傳遞Command/Event/ACL Data這3類數據時:

1. 對於UART接口的Controller,會在數據前面加上1字節的頭部用來分辨是哪一類數據

2. 對於USB接中里的Controller,每類數據對應一個Endpoint,數據會直接發給Endpoint

 

下面,介紹Command/Event/ACL Data這3類數據的格式。

一、Command格式:

 

Command前有2字節的頭部OpCode,用來表示是哪一個Command。

OGF表示“OpCode Group Field”,即“哪一組命令”,它占據高6位。

OCF表示“OpCode Command Field”,即“這組里的哪一個命令”,它占據低10位。

 

在藍牙協議里,每一個OGF用一節來描述,在這節里會描述該組(OGF)的所有命令(OCF),位置如下圖:

 

BTStack示例:

btstack-master\src\hci_cmd.c

 12211分別表示1個字節用來表示掃描類型、2個字節用來表示掃描間隔、2個字節用來表示scan_window、1個字節用來表示own_address_type、1個字節用來表示scanning_filter_policy。

以后發送命令的時候,就需要根據12211這個格式來組裝這些參數。在代碼中搜索hci_le_set_scan_parameters.

hci_send_cmd(&hci_le_set_scan_parameters, 1, 0x1e0, 0x30, hci_stack->le_own_addr_type, 0);

 

代碼中和文檔中OCF的值剛好對應,正好是B。

 再來看一個例子:

 

 它帶有兩個參數,每個參數占一個字節,即hci_stack->le_scanning_enabled占一個自己;0占一個字節

 其他的命令也是類似的,具體需要查看藍牙文檔core_5.0

二、Event格式:

在官方協議中對於Event並沒有明確的分類,按我的理解可以分為以下3類

Event分類

說明

Command Status Event

命令狀態事件,

表示控制器已經接收到命令並正在處理

Command Complete Event

命令完成事件,

表示命令已經處理完畢並返回結果

Advertising Report Event

廣播上報事件,本Event是Controller主動上報的

而上述2個Event都是由command導致的

示例:

有些命令需要一定時間才能執行完,比如LE Create Connection命令。控制器接收到該命令后會首先返回一個“命令狀態事件”,隨后等待連接建議完成或者失敗,再返回“命令完成事件”。

Event的格式:

三、ACL Data格式:

ACL Data是傳遞給對端設備的數據,在建立連接之后才可以傳輸ACL Data,格式如下:

 

Handle表示對端設備:主設備的Controller要與對端設備連接時,會生成一個32位的隨機數,它被稱為Access Address。在LL層的數據包中,Access Address被用來表示對端設備。但是Host程序並不想使用這個32位的數據,於是Controller又分配一個12位的Handle來表示這個Access Address、表示對端的設備。

Packet_Boundary_Flag:

PB Flag

描述

Host to Controller

Controller to Host

00b

L2CAP PDU起始包

P

 

01b

L2CAP PDU延續包

P

P

10b

L2CAP PDU起始包

 

P

 

Controller在傳輸ACL Data時,每次傳輸的字節數是有限制的,這可以通過“Read Buffer Size”命令讀到這個值。

當要傳輸非常大的ACL Data時,需要把數據拆分來傳輸,這就要用到上面表格中的“PB Flag”來分辨起始包、延續包。

這些起始包、延續包由Host送到Controller后,會馬上通過LL層重新編碼、發給PHY層發給對端設備,對端設備的L2CAP層再把這些起始包、延續包組裝起來。

注意,在LL層的數據包里有LLID域,10b表示起始包、01b表示延續包。

Broadcast_Flag在BLE協議中都是00b,表示“Point-to-point”。

四、示例:

Broadcast_Flag在BLE協議中都是00b,表示“Point-to-point”。

1. 掃描設備

a. Host向Controller發出“LE Set Scan Parameters Command”

b. Controller向Host發送“Command Complete Event”

c. Host向Controller發出“LE Set Scan Enable Command”

d. Controller向Host發送“Command Complete Event”

e. 如果掃描參數為“主動掃描”,對於新發現的設備會,LL層發出“SCAN REQ”廣播包

f. Controller接收到各類廣播包,比如ADV_IND、SCAN_RSP

   LL層解析后,會通過HCI上報EVENT

2. 連接設備

a. Host向Controller發出“LE Create Connection Command”

b. 不需要對端設備回應數據,發起方就認為連接已經建立

c. Controller向Host發送“Command Status Event”

d. Controller向Host發送“Command Complete Event”

3. 寫數據

a. Host向Controller發出ACL數據:Write Command, Handle….

b. Controller的LL層構造數據包(LLID=10b),通過PHY發出無線信號

c. Controller向Host發送“Number of Completed Packets”事件

4. 讀數據

a. Host向Controller發出ACL數據:Read Request, Handle….

b. Controller的LL層構造數據包(LLID=10b),通過PHY發出無線信號

c. Controller向Host發送“Number of Completed Packets”事件

d. 對端設備的LL層通過PHY返回數據(LLID=10b)

e. Controller向Host發送ACL數據:Read Response

 問題:右邊抓取的空中數據包,在對端設備接收到讀請求后,過了一會才回復一個無線信號給本地設備,中間有很多空包,這些空包是誰發起的呢?

是由master發給slave的,

這些空包起什么作用呢?

兩個設備建立連接之后,本地設備要知道對端設備什么時候要斷開,它是怎么判斷對端設備有沒有斷開呢?

不斷的發送空包給對端設備,對端設備收到空包后,要回復一個空包,這樣本地設備才知道對端設備還沒有斷開。當然為了省電,對端設備沒有必要每次收到空包都要回復,可以在收到幾個空包后回復,但是一定要有回復。這些空包是是由controller自主發起的,與host層沒有什么關系。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM