藍牙LMP概述

LMP 全稱是Link Manager Protocol,咱們仍是要一張圖,說明LMP 在哪裏?網絡

他是在HCI 如下,baseband 以上,實如今藍牙控制器中。架構

 按照協議規範,咱們分幾個部分來分別介紹LMP加密

  1. introduction
  2. general rules
  3. device features
  4. procedure rules

下面咱們先來看看 總體的介紹部分:spa

Introduction

LMP是用來控制和協商兩個設備鏈接行爲的協議,涉及的方面包括邏輯傳輸鏈接的創建和控制,以及對於物理鏈路的控制等等,它是兩個設備的LMP模塊以前的交流,其消息是傳輸在ACL-C 的邏輯鏈路上,對於這一點,咱們在baseband的概述中已經提過:debug

這裏須要注意的一點是,LMP 是實如今控制器裏面,其消息並不會通過HCI 接口傳輸到HOST 端,其架構以下圖:3d

咱們能夠看到其是 兩個設備的LMP 模塊以前的通訊。code

General rules

 2.1 Message Transport

 這裏描述的就是三個點:orm

  1. LMP的消息的交互是傳輸在ACL-C 邏輯鏈路上的,他和ACL-U的區別是經過LLID 來區分的。
  2. ACL-C有更高的優先級,通常控制信號都會有較高的優先級
  3. LMP消息自己沒有攜帶額外的數據錯誤檢測的信息

2.2 Synchronization

   LMP 傳輸在ACL-C的邏輯鏈路上面,但這並不能保證傳輸的時間的以及對方ack的及時性。blog

 

 2.3Packet Format

 LMP 的數據包的格式有兩種,一種是7bit的opcode,另一種是15bit的opcode接口

咱們發現除了opcode,在最低位還有一個TID,他是transtransaction ID,當它是0 的時候,說明這個LMP message是 master 發起的,當它是1的是時候說明是slave 發起的。

上圖中是 header的最低位是0,表明是Transaction ID Initiated by master。

 

2.4Transactions

 transaction 就是一次完整的打成某種目的的傳輸。全部屬於同一個transaction 的單次傳輸的transaction ID 都是想同的。

好比下面:

LMP version exchange 的Transaction ID 都是 Initiated by slave

另外LMP_setup_complete 是一個 獨立PDU,它本身造成一個transaction,

 

 

上面兩個OpCode LMP_setup_complete 的transaction ID 是不一樣的,他們是獨立的PDU

LMP response的timeout 時間是30s

 2.5ERROR HANDLING

關於出錯處理,每個錯誤都分配了一個錯誤碼,常見的錯誤以下:

  1. Unknown opcode(0x19)
  2. Invalid parameters(0x1E)
  3. PDU is not allowed(0x24)
  4. PDU not supported(0x1A)
  5. Transaction Collision / LL Procedure Collision(0x23)
  6. Different Transaction Collision(0x2A)

2.6GENERAL RESPONSE MESSAGES

 general response  在不少的procedure中,被用來對於各類流程的應答消息,若是opcode是7bit,那麼應該使用前兩種 PDU,若是opcode 是15bit,那麼應答的PDU 應該使用後兩種。

 

DEVICE FEATURES

device feature,顧名思義,這裏面定義了不少的設備的特性,而且這些特定是能夠用特定的LMP message 來獲取的。那麼這些feature 是如何傳輸的呢?其實就是定義了一些bit 位來表明相應的feature,當這些位被設置爲1的時候,就說明支持該feature,這個咱們在程序代碼實現中常常見到這樣的技巧。

 這些feature 定義在兩個page 上面,page1 裏面使用8個字節,64bit 定義了64個feature,page2用2個字節定義了12個feature,其中包括2個reserved 位。

這裏簡單列舉幾個feature:

 

 PROCEDURE RULES

 這裏包含了不少的基本流程,主要有以下的項目:

  1. Connection control

  2. Information Requests
  3. Role Switch
  4. Modes of Operation
  5. Logical Transports

 咱們下面分別看看這幾個流程:

4.1Connection control 

這裏每個流程都有不少的子流程,這裏只簡單介紹下Connection establishment和Detach的流程:

下面先看一下Connection establishment的流程圖

在通過了page的流程以後,可能的行爲是請求時鐘的偏移量,LMP的版本,對端支持的feature請求,對端的name請求,以及可能的deteach行爲。

以後若是要創建鏈接的話,paging的設備就會發送LMP_host_connection_req,對端若是贊成創建鏈接就會回覆LMP_accepted 不然就是LMP_not_accepted

後續可能走得關於認證和加密的流程,最後是LMP_setup_complete,下面咱們來看一個例子:

 

 下面的創建鏈接的PDU:

 

 下面咱們看看detach 的流程:

咱們發現關於detach 是沒有LMP response 的消息的過來的,從實際的air log 中,也的確沒有detach response 回覆,對端設置只會簡單的ack 該 消息:

下面咱們看看 從設備的host 端 去斷開對端設備的 LMP 與HCI 的message 流向:

咱們發現是 A設備再收到了對端的ACK 以後就會向host 端上傳斷開完成事件。

關於 驗證和加密的部分,會在分析配對的文章中專門講述。

下面咱們咱們看看

4.2Information Requests

 這一類的message 交互都是 信息請求類型的,具體的有以下幾種:

  1. Timing accuracy

  2. Clock offset
  3. LMP version
  4. Supported features
  5. Name request

這幾個流程也是很是的類型,咱們也是挑選其中一個來 看一下:

咱們看看lmp version 的流程:

其交互流程很簡單,發起端發起一個LMP_version_req,對端迴應一個LMP_version_res

涉及到的PDU的包以下:

這裏咱們發現,發起這個LMP version請求的時候,還會攜帶本端的LMP version,Company ID 以及Sub Version Number,這個Sub Version Number 應該是公司內部的編號了,那這樣一來,一個request,一個response,就完成了LMP 相關版本信息的交互。咱們看看air log 關於這交互的消息:

response 以下:

 

 這裏須要提一點就是LMP 數據包的payload header 裏面也是有流控相關的,可是這個流控對於LMP 是不起做用的。其應該是主要針對ACL-U的數據。

 

這裏再簡單名字的獲取的流程,當沒有創建物理link的時候,獲取名字和已經創建了link的獲取的名字的流程有點區別。咱們先下有link的時候 流程:

 

有link的時候,很簡單,直接是在LMP 層進行LMP_name_req的交互,收到對方的應答以後,經過HCI接口上報的到host端,若是是沒有link的話,那麼是要先創建一個臨時的link,其流程見下圖:

咱們能夠看到兩個設備通過page 以後,會先進行LMP feature exchange以及extend feature exchange,而後上報到host 端,接下來才進行LMP_name_req 的交互,最後是detach 這個臨時的link,

咱們看看 air log 中實際的交互狀況:

實際狀況和上面的流程也是很是的吻合,最後會把這個 臨時創建起來的獲取名字的link斷開。

下面咱們看看role switch 相關的

4.3Role switch

 關於role switch ,由於咱們日常在debug 中會遇到,值得仔細講一下:

role switch的執行須要符合幾個條件:

  1. 設備要處於active mode
  2. 加密的流程被終止或者已經關閉
  3. 在當前的link上面,沒有sco數據在傳輸
  4. 須要停掉當前link全部的ACL-U 數據流

role switch 從字面含義上來看,很是的簡單,就是交互角色,咱們知道兩個設備鏈接以後,一開始發起配對的那個設備在創建鏈接以後就是master,這樣一種默認模式不能老是符合應用場景,因此常常在兩個設備以後須要交互角色。

role switch 是master 和slave 均可以發起的,咱們先看一下,master 發起的角色交換的流程:

LMP 層面的交互很簡單,就三個指令。下面咱們詳細講一下LMP_switch_req和LMP_slot_offset的 做用。

 

咱們看出 LMP_slot_offset 攜帶兩個關鍵的信息,一個slot offset,另一個 藍牙設備地址。這個地址是當前 slave 地址,也是role switch 以後master的地址。這個slot offset 是幹嗎的呢?

這個在specification中原話是「The slot offset shall be the time in microseconds between the start of a master transmission in the current piconet to the start of the next following master transmission in the piconet where the BD_ADDR device (normally the slave) is master at the time that the request is interpreted by the BD_ADDR device.

 其含義就是,當前網絡的master的開始傳輸的時機(時鐘上升沿)到交換後的網絡master 進行傳輸的時機(時鐘上升沿)的時間間隔,次時間是用ms 來描述的。

 

從這裏,咱們可以覺悟出,slot offset 應該都是由當前網絡的slave(role switch 以後的master) 來發送,而不論是 哪一端的設備先發起的,下面咱們看看slave 端發起的role switch的交互流程:

咱們發現,slot offset,的確是由slave端送出,以後才送出 LMP_switch_req,如今咱們看看一下LMP_switch_req這個命令:

咱們能夠設想一下,藍牙設備之間的交互是要保持時鐘同步的,不然就會「失去聯繫」,那麼咱們在進行role swtich 以後仍是要保持時鐘同步才能繼續通訊,那在什麼樣的時機進行role switch呢?

咱們先看下LMP_switch_req的參數:

 

 咱們發現其有一個參數是 switch instant ,這就是 描述 具體在哪個時間點進行TDD switch。

這個instant 應該是一個將來的時間,若是是過去的時間,那麼當接受者受到這個instant的時候,並不會接受這樣的參數,會回覆 LMP_not_accepted PDU with the error code Instant Passed (0x28)。

當role switch 完成的時候,兩個設備都要向各自的host 上報HCI_Role_Change event,以下圖:

 

 Modes of Operation

 hold mode 不多遇到,這裏主要講一下 sniff mode ,

sniff mode 就是呼吸模式,主要是爲了省電而應用的,好比一些藍牙設備,好比鍵盤鼠標,當他們在active mode的時候,每個master to slave  slot,設備都要去監聽master是否有數據發過來。而當他們不使用的時候,若是仍是一直處於active mode 的話,那麼這段時間的消耗的電量就浪費了,而進入到sniff mode 可使得設備進入了相似睡眠的狀態,只是按期去監聽master 的封包,這樣能夠節省電量。

咱們先看看 進入sniff mode  的流程圖:

咱們這裏主要着眼於LMP層面,當host端有進入sniff mode的命令下來,那麼控制器 將向對方發出LMP_sniff_req的請求,對方若是贊成,那麼回覆LMP_accepted。由於這是一個協商的過程,上圖只顯示了一次協商的過程,其實可能存在有發屢次的LMP_sniff_req的狀況。如今咱們看看 LMP_sniff_req的參數:

Dsniff = Clock_Value (bits 26-1) mod Tsniff

Tsniff  是 sniff interval,就是每次起來監聽的時間間隔

Tsniff 就是 相鄰的兩個sniff anchor point的時間間隔。

sniff attempt 是 每次起來以後 嘗試去監聽的次數,若是監聽了sniff  attempt 次數以後發現master 沒有發數據過來,那麼再次進入到睡眠的狀態。

sniff timeout 是 在slave 去監聽master 的封包的時候,若是有封包發過來,那麼就要繼續監聽額外的sniff timeout 個master to slave slot。

咱們這裏說一下Sniff 第一個錨點的計算方法:Dsniff = Clock_Value (bits 26-1) mod Tsniff 

 這裏Dsniff 和Tsniff  是參數已經給出的,那麼就是根據上面的公式去反推第一個錨點的clk的值。咱們這裏舉一個例子來講明:

其當前的clk值是Clock[27-0] 0x04301E02  這裏的Dsniff 的值是0,

bit27  = 0,咱們先看看當前的clk是0x04301E02,那麼下一個錨點必定是 大於當前值而小於(0x04301E02+800*2)

咱們先看看當前的Clock_Value (bits 26-1) mod Tsniff  = (0x04301E02>>1)mod(800) = 737

那麼下一個錨點的clk = ((800-737)+ (0x04301E02>>1))*2 = 0x4301E80  

 

 那麼關於LMP 的概述就先介紹到這裏。

相關文章
相關標籤/搜索