藍牙協議分析(7)_BLE連接有關的技術分析


1. 前言

了解藍牙的人都知道,在經典藍牙中,保持連接(Connection)是一個相當消耗資源(power和帶寬)的過程。特別是當沒有數據傳輸的時候,所消耗的資源完全被浪費了。因而,對很多藍牙設備來說(特別是功耗敏感的設備),希望在無數可傳的時候,能夠斷開連接。但是,由於跳頻(hopping)以及物理通道(Physical Channel)划分的緣故,經典藍牙連接建立的速度實在難以忍受(要好幾秒)。對那些突發的數據傳輸來說,幾秒鍾的連接延遲,簡直是災難。

因此,藍牙SIG制訂BLE規范的時候,充分考慮了這方面的需求,極大的簡化了連接的建立過程,使連接速度可以達到毫秒級(最快3.75ms就可以搞定)。與此同時,為了節省功耗,也調整了跳頻的策略。至此,相比廣播通信而言,BLE面向連接的通信,幾乎沒有額外的代價。

在“藍牙協議分析(5)_BLE廣播通信相關的技術分析”中,我們對BLE的廣播通信有了比較全面的了解,本文將接着分析和面向連接的通信有關的技術,包括連接的建立和斷開、BLE跳頻(Hopping)技術、Link Layer的應答、重傳、流控、等等。

2. 怎樣才算是建立了連接?

開始之前,我們先回答一個問題,對通信的雙方而言,怎樣才算建立了連接呢?

從字面上理解,建立了連接,就是指:

二者之間,建立了一條專用的通道,它們可以隨時隨地的通信。

當然,在藍牙這種資源有限的通信系統中,通道無法獨占,退而求其次,分時也Okay。因此,在BLE中建立了連接,是這樣定義的:

在約定的時間段內,雙方都到一個指定的物理Channel上通信。

其中,“約定好的時間段”,是時分的概念。而“到指定的物理Channel上”,是跳頻的概念。后面的分析,將會圍繞這兩個概念進行。

另外,和“藍牙協議分析(5)_BLE廣播通信相關的技術分析”類似,我們也將從Link Layer、HCI、GAP三個層次,分別介紹。

3. Link Layer

3.1 角色的定義

和經典藍牙一樣,協議為處於連接狀態的BLE設備,定義了兩種Link Layer角色:Master和Slave。Master是連接的發起方(Initiator),可以決定和連接有關的參數(很重要,后面會詳細介紹)。Slave是連接的接受方(Advertiser),可以請求(或建議)連接參數,但無法決定。

注1:兩個BLE設備之間,只能建立一條連接。

3.2 PDU的定義

和廣播通信不同,面向連接的通信使用特定的PDU,稱作Data Channel PDU,格式如下(LSB---->MSB):

 

Header(16 bits) Payload(Variable size) MIC(32 bits)

 

16bits的Header的格式如下:

LLID(2 bits) NESN (1bit) SN(1 bit) MD(1 bit) RFU(3 bits) Length(8 bits) 

Data Channel傳輸的PDU有兩類,一類是數據,稱作LL Data PDU,另一類中控制信息,稱作LL Control PDU。LLID用於區分PDU的類型,具體可參考后面3.2.1和3.2.2的描述。

NESN(Next Expected Sequence Number)和SN(Sequence Number),用於數據傳輸過程中的應答(Acknowledgement)和流控(Flow Control),具體可參考后面3.7的介紹。

MD(More Data),用於連接的關閉(或者說保持),具體可參考后面3.5的介紹。

RFU(Reserved for Future Use)。

Length,有效數據的長度(Payload+MIC),只有8-bits,因此Link Layer所能傳輸的最大數據是255 bytes(有MIC的話是251bytes),如果L2CAP需要傳輸更多的數據,需要分包之后傳輸(這也是L2CAP的主要功能之一,具體可參考“藍牙協議分析(3)_藍牙低功耗(BLE)協議棧介紹”)。

 

Payload是有效數據(SDU,L2CAP的PDU),長度由Header中的Length字段覺得,有效范圍是0~255。

3.2.1 LL Data PDU

LL Data PDU有兩種:

Header中的LLID=01b時,Continuation fragment of an L2CAP message, or an Empty PDU。這種類型的PDU,要么是一個未傳輸完成L2CAP message(長度超過255,被拆包,此時不是第一個),要么是一個空包(Header中的Length為0)。

Header中的LLID=10b時,Start of an L2CAP message or a complete L2CAP message with no fragmentation。這種類型的PDU,要么是L2CAP message的第一個包,要么是不需要拆包的完整的L2CAP message,無論哪種情況,Header中的Length均不能為0。

3.2.2 LL Control PDU

Header中的LLID=11b時,表示這個數據包是用於控制、管理LL連接的LL control PDU。LL control PDU的payload的格式如下:

Opcode(1 octet) CtrlData(0 ~ 26 octets)

其中Opcode指示控制&管理packet的類型,包括:

LL_CONNECTION_UPDATE_REQ,連接參數的更新; 
LL_CHANNEL_MAP_REQ,Channel map的更新; 
LL_TERMINATE_IND,連接即將被關閉的通知(可以通知被關閉的原因); 
LL_ENC_REQ、LL_ENC_RSP、LL_START_ENC_REQ、LL_START_ENC_RSP,加密有關的請求;等等,具體可參考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”。

3.3 連接的建立

對BLE來說,連接建立的過程很簡單,包括:

1)處於connectable狀態設備(Advertiser),按照一定的周期廣播ADV_IND或者ADV_DIRECT_IND包(可參考“藍牙協議分析(5)_BLE廣播通信相關的技術分析”)。

2)主動連接的設備(Initiator),在收到廣播包之后,會回應一個CONNECT_REQ請求,該請求攜帶了可決定后續“通信時序”的參數,例如雙方在哪一個時間點、哪一個Physical Channel收發數據,等等,后面會詳細描述。

3)Initiator在發出CONNECT_REQ數據包之后,自動轉變為Connection狀態,成為Master角色(注意:這是“自動”的,不需要等待另一方的回應)。同樣,Advertiser在收到CONNECT_REQ請求之后,也自動轉變為Connection狀態,成為Slave角色。

4)此后,雙方按照CONNECT_REQ參數所給出的約定,定時到切換到某一個Physical Channel上,按照Master->Slave然后Slave->Master的順序,收發數據,直至連接斷開。

master在發出連接請求的時候,需要在CONNECT_REQ PDU的payload中,定義和連接有關的參數。payload的格式如下:

InitA (6 octets) AdvA (6 octets) LL Data (22 octets)

 其中InitA和AdvA分別是Master和Slave的藍牙地址,LL data則包含了所有的連接參數,包括:

AA 
(4 octets)
CRCInit 
(3 octets)
WinSize 
(1 octet)
WinOffset 
(2 octets)
Interval 
(2 octets)
Latency 
(2 octets)
Timeout 
(2 octets)
ChM 
(5 octets)
Hop 
(5 bits)
SCA 
(3 bits)

AA==LL Connection的Access Address,在不同設備組合之間,需要唯一,並遵守一些原則,具體可參考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”。

CRCInit==用於CRC計算的一個初始值,由Link Layer隨機生成。

WinSize和WinOffset==全稱是transmitWindowSize和transmitWindowOffset,用於決定連接雙方收發數據的時間窗口(第2章提到的時分的概念)。下面3.4小節會詳細介紹。

Interval==全稱是connInterval,連接雙方收發數據的周期。由於一個Master可能會和多個Slave建立連接,因此藍牙的信道資源不能被某一個LL Connection所獨占,所以一個收發周期中,可能有多個連接進行收發數據(具體的時間窗口,由transmitWindowOffset決定)。下面3.4小節會詳細介紹。

Latency和Timeout==全稱是connSlaveLatency和connSupervisionTimeout,和連接超時、自動斷開有關,具體可參考3.4小節的描述。

ChM==全稱是Channel map,用於標識當前使用和未使用的Physical Channel。

Hop==全稱是hopIncrement,它和ChM一起決定了數據傳輸過程中的跳頻算法,具體可參考3.6小節的描述。

SCA==(sleep clock accuracy),用於定義最差的Master睡眠時鍾精度,具體可參考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”,本文不再詳細介紹。

 

3.4 連接建立后的通信過程

3.3小節提到,當Master發出/Slave收到CONNECT_REQ后,就自動進入連接狀態,那雙方在收發數據的時間窗口怎么確定呢?可參考下面圖片1和圖片2:

BLE連接時序---Master視角

圖片1 BLE連接時序---Master視角

BLE連接時序---Slave視角

圖片2 BLE連接時序---Slave視角

1)從Master的視角看,當它發出CONNECT_REQ后,會在1.25 ms + transmitWindowOffset到1.25ms + transmitWindowOffset + transmitWindowSize之間,發送第一個packet(M->S)。同理,Slave在收到CONNECT_REQ之后,也會在相應的時間區間去接收packet(M->S)。

a)transmitWindowOffset可以控制這個LL Connection使用哪一段時間進行通信,從而保證了同一個Master和多個Slave之間的多個連接,可以互不影響的通信(時分)。transmitWindowOffset的取值范圍是:0 ms到connInterval(后面會介紹connInterval)。

b)從Master發出CONNECT_REQ,到Slave接收到CONNECT_REQ,是有一定的時間延遲的,因此需要一定的時間窗口(transmitWindowSize),才能保證第一個packet能否正確的發送並被接收。transmitWindowSize必須是1.25ms的倍數,最小值是1.25 ms,最大值是(connInterval - 1.25 ms),但不能超過10ms。

c)正常情況下,所有“M->S”數據包的發送,不能超過transmitWindowSize,以便留出S->M的時間。但第一個packet例外(參考上面圖片1)。

2)Master發出第一個packet之后,將以此為起始點(稱作anchor point),以connInterval為周期,接着發送后續的packet(M->S),以及接收Slave的packet(S->M),具體可參考上面圖片1。

a)這樣以connInterval為周期的發送(M->S)、接收(S->M)組合(可能有多個),稱作Connection Event。因此BLE面向連接的通信的基礎,就是Connection Event。

b)connInterval的大小,決定了數據傳輸的周期。對一個連接來說,每個周期只能有一次的收發,因此connInterval的選擇,直接決定了數據傳輸的速度。BLE協議規定,connInterval必須是1.25ms的倍數,范圍是7.5ms~4s。

3)Slave如果沒有收到第一個packet(M->S),則會以1.25 ms + transmitWindowOffset為起點,等待connInterval之后,再次嘗試接收,直到接收到為止。Slave接收到packet之后,則以收到該packet的時間點為起始點(anchor point),以connInterval為周期,接着接收后續的packet(M->S),以及發送packet給Master(S->M),具體可參考上面圖片2。

注2,關於數據傳輸的速率: 
由上面的通信過程可知,BLE面向連接的通信速率,是由connInterval以及每個Connection Event中所傳輸的數據量決定的。 
由上面3.2的描述可知,LL Data PDU的有效負荷不能超過255(251)bytes,不過考慮到一次傳輸的效率、錯誤處理等因素,具體的Link Layer不會使用這么大的packet。相應地,為了提高傳輸速度,一般會在一個Connection Event中,傳輸多個packet。以iOS為例,它可能會在一個Connection Event中,傳輸6個packets,每個packet的長度是20bytes。 
另外,很多平台為了保證自身作為Master的性能,會限制connInterval的最小值,以iOS為例,最小值是30ms。因此,可估算得到相應的傳輸速率為20B * 6 / 30ms = 32kbps,是相當緩慢的。

注3:BLE的面向連接通信是使用跳頻技術的,即每次Connection Event,都會使用不同Physical Channel收發數據,具體的跳頻機制,可參考3.6小節的介紹。

3.5 連接的控制與管理

連接建立之后,Master或者Slave可以借助Link Layer Control Protocol (LLCP),通過LL Control PDU,對連接進行管理控制,包括:

Connection Update Procedure,連接參數(包括connInterval,connSlaveLatency,connSupervisionTimeout)更新的通知。只能由Master發起。

Channel Map Update Procedure,更新Channel map。只能由Master發起。

Encryption Procedure,對連接進行加密,可由master或者slave發起。

Termination Procedure,斷開連接。

Connection Parameters Request Procedure,請求更新連接參數(connInterval,connSlaveLatency,connSupervisionTimeout),Slave或者Master都可以發起,和Connection Update Procedure不同是,這是一個協商的過程,不是一定能夠成功。

LE Ping Procedure,類似於網絡協議中ping操作。

等等。不再詳細介紹,具體可參考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”。

3.6 連接超時及斷開

BLE連接斷開的原因有兩種:一種是預期內的、主動斷開,此時會走3.4小節提到的Termination Procedure過程;第二種是一些非預期的原因導致的超時斷開,如距離超出、遭受嚴重的干擾、突然斷電等。

對於第一種,是協議內的正常流程,沒有什么好說的。而對於第二種,則需要一些timeout機制,檢測這寫異常情況,具體如下。

1)Master和Slave的Link Layer,都會啟動一個名稱為TLLconnSupervision的timer,每接收到一個有效的數據包時,該timer都會重置。

2)連接建立的過程中,如果TLLconnSupervision超過6 * connInterval(沒有接收到第一個數據包),則認為連接建立失敗。

3)在連接成功之后,如果TLLconnSupervision超過connSupervisionTimeout,則說明link loss,則執行超時斷開。connSupervisionTimeout是一個可配置的參數,范圍是100ms~32s,並且不能大於(1 + connSlaveLatency) * connInterval * 2。

4)BLE協議允許slave忽略掉“connSlaveLatency”個Connection Event,在被忽略的這段時間內,Slave不需要收發數據包,也不會增加TLLconnSupervision,從而引發超時斷開。connSlaveLatency是一個整數,有效范圍應該在0到((connSupervisionTimeout / (connInterval*2)) - 1)之間,並且不能大於500。

注4:connSlaveLatency是一個非常有用的參數,它允許Slave在數據通信不頻繁的時候,忽略掉一些Connection Event,進而可以睡得更久,更加省電。

3.7 跳頻(Hopping)策略

BLE的跳頻策略是非常簡單的,即:每一個Connection Event,更換一次Physical Channel,當然,master和slave需要按照相同的約定更換,不然就無法通信。這個約定如下:

BLE跳頻策略

圖片3 BLE跳頻策略

1)首先,使用一個Basic的算法,利用lastUnmappedChannel和hopIncrement,計算出unmappedChannel。

a)lastUnmappedChannel在連接建立之初的值是0,每一次Connection Event計算出新的unmappedChannel之后,會更新lastUnmappedChannel。

b)hopIncrement是由Master在連接建立時隨機指定的,范圍是5到16(可參考3.3中的Hop)。

c)確定unmappedChannel的算法為:unmappedChannel = (lastUnmappedChannel + hopIncrement) mod 37,本質上就是每隔“hopIncrement”個Channel取一次,相當直白和簡單。

2)計算出unmappedChannel之后,查找當前的Channel map,檢查unmappedChannel所代表的Channel是否為used channel。如果是,恭喜,找到了。

Channel map也是由master,在連接建立時,或者后來的Channel map update的時候指定的。

3)如果不是,將所有的used Channel以升序的方式見一個表,表的長度是numUsedChannels,用unmappedChannel和numUsedChannels做模運算,得到一個index,從按照該index,從表中取出對應的channel即可。

3.8 應答(Acknowledgement)和流控(Flow Control)

由3.2小節的描述可知,LL Data PDU的Header中,有NESN(Next Expected Sequence Number)和SN(Sequence Number)兩個標記,利用它們,可以很輕松的在Link Layer實現應答、重傳、流控等機制。

為了實現這些功能,Link Layer會為每個連接創建兩個變量,transmitSeqNum和nextExpectedSeqNum(為了和packet的SN/NESN bit區分,我們將它們簡稱為sn和nesn),並在連接建立的時候,它們都被初始化為0。

sn用於標識本地設備(Link Layer)發送出去的packets。

nesn是對端設備(Link Layer)用來應答本地設備發送的packet,或者請求本地設備重發packet。

Link Layer在收發packet時,會遵循如下的原則(可結合下面圖片4理解):

注5:下面圖片4是從“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”中截的一張圖,不過spec中畫的有問題,我用紅色字體改正了。另外,這個圖片非常有歧義、難以理解,我會在下面解釋。

1)無論是Master還是Slave,發送packet的時候,都會將當前的sn和nesn copy到packet的SN和NESN bit中。

2)無論是Master還是Slave,當接收到一個packet的時候,會將該packet的NESN bit和本地的sn比較:如果相同,說明該packet是對端設備發來的NAK packet(請求重發),則需要將舊的packet重新發送出去;如果不同,說明是對端設備發來的ACK packet(數據被正確接收),則需要將本地的sn加1,接着發送新的packet。

a)以上過程可參考下面圖片4中的左邊部分。

b)本地的sn,代表本地設備已經發送出去的packet,而packet中的NESN bit,代表對端設備期望本地設備發送的packet。如果二者相同,說明對方期望下次發送的packet,和我們已經發送的packet相同,因此是NAK信號,要求重發。如果二者不同,說明對方設備期望發送一個新的packet,也說明我們上次發送的packet已經成功接收,因此可以將本地的sn加1了。

3)無論是Master還是Slave,當接收到一個packet的時候,會將該packet的SN bit和本地的nesn比較:如果相同,則說明是一個新的packet,接收即可,同時將本地的nesn加1;如果不同,則說明是一個舊的packet,什么都不需要處理。

a)以上過程可參考下面圖片4中的右邊部分。

b)packet中的SN bit,代表對端設備正在發送的packet,而本地設備的nesn,代表本地設備期望對端設備發送的packet。如果二者相同,則說明是一個期望的packet(新的),就可以收下該packet,並將期望值加1(nesn加1)。如果二者不同,說明不是本地設備期望的packet,什么都不做就可以了。

4)上面2)和3)兩個步驟,是相互獨立的,因此一個NAK packet,也可能攜帶新的數據,反之亦然。

5)當一個設備無法接收新的packet的時候(例如RX buffer已滿),它可以采取不增加nesn的方式,發送NAK packet。對端設備收到該類型的packet之后,會發送舊的packet(圖片4左邊部分的“TX old data, sn”分支)。該設備收到這樣舊的packet的時候,不會做任何處理(圖片4右邊部分的“Ignore RX data”分支)。這就是Link Layer的流控機制(Flow control)

BLE應答和流控機制

圖片4 BLE應答和流控機制

4. HCI

HCI(Host Control Interface)的功能就簡單多了,就是要封裝Link Layer所提供的功能,包括兩類。

1)連接的建立、關閉、參數設置、管理等,這一類是通過HCI command/event(其格式可參考“藍牙協議分析(5)_BLE廣播通信相關的技術分析”中的介紹)完成的,包括:

LE Create Connection Command,建立連接的命令,需要提供連接有關的參數,包括connInterval(Conn_Interval_Min和Conn_Interval_Max)、connSlaveLatency(Conn_Latency)和connSupervisionTimeout(Supervision_Timeout)。

LE Create Connection Cancel Command,取消或者斷開連接。

LE Connection Update Command,更新連接參數,包括connInterval(Conn_Interval_Min和Conn_Interval_Max)、connSlaveLatency(Conn_Latency)和connSupervisionTimeout(Supervision_Timeout)。

LE Set Host Channel Classification Command,配置Channel map。

LE Read Channel Map Command,讀取Channel map。

等等。

有關這些命令的具體描述,可參考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 2, Part E] Host Controller Interface Functional Specification”。

2)對ACL data的封裝和轉發,不再詳細說明。

5. GAP

GAP(Generic Access Profile)的主要功能,是定義BLE設備所具備的能力,以實現互聯互通的功能。

對BEL基於連接的通信來說,GAP定義了4種連接有關的模式(不同的產品形態,可以選擇是否支持這些模式,具體可參考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] 9.3 CONNECTION MODES AND PROCEDURES”):

Non-connectable mode,不可被連接。

Directed connectable mode,可以被“直連”(在知道對方藍牙地址的情況下的快速連接)。

Undirected connectable mode,可以被“盲連”(不知道對方藍牙地址)。

Auto connection establishment procedure,可以被自動連接(不需要host干預)。

相應地,GAP定義了5中和這些模式有關的過程(不同的產品形態,可以選擇是否支持這些過程):

General connection establishment procedure,通用的連接建立過程,搜索、發現、連接,都需要Host參與。

Selective connection establishment procedure,有選擇的連接建立過程,Host需要告訴Controller,自己只希望於特定的設備建立連接。

Direct Connection Establishment Procedure,直接和某一個已知設備建立連接(對方也知道我們)。

Connection Parameter Update Procedure,連接參數的更新過程。

Terminate Connection Procedure,斷開連接。

這些mode和procedure的具體描述,可參考藍牙spec[1]

6. 參考文檔

[1] Core_v4.2.pdf

 

原創文章,轉發請注明出處。蝸窩科技,www.wowotech.net。

 


免責聲明!

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



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