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

藍牙協議分析(7)_BLE連接有關的技術分析作者:wowo 發佈於:2016-7-1 17:17
原文地址:http://www.wowotech.net/bluetooth/ble_connection.html
分類:藍牙 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小節會詳細介紹。 connInterval,全稱是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: 圖片1 BLE連接時序—Master視角 圖片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需要按照相同的約定更換,不然就無法通信。這個約定如下: 圖片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) 圖片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的封裝和轉發,不再詳細說明。 6. 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]。 7. 參考文檔 [1] Core_v4.2.pdf

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章