===== 介紹 =====
Function
L2CAP 允許較高層級的協定以及應用程式傳送和接收L2CAP資料封包,最大可到64Kㄛ
僅支援非同步連結
AUX1 packet是被禁止的,因為不支援資料一致性(no CRC).
L2CAP 的 packet 有兩種格式,一種是 single-slot, 一種是 multi-slot,主要差別是
packet 欄位的長度. 欄位內容及說明可參考 page 250
必須要可以
1.協定多路傳輸,因為 Baseband Protocol(以下簡稱BP) 不支援任何可被辨識型態的欄位,這樣在之上的協定才能多路傳輸.
需要上層的協定像SDP,RFCOMM,TC可以辨識.
2.可被切割和重組
3.服務的品質(QoS)
4.群組
assumption 設想
這個協定建立在三個設想上
1.兩個單位之間的非同步連結預設適用 Link Manager 協定(page185)
baseband 順序提供封包傳送,即使可能有壞的封包或重複的
設備之間只有一個非同步連結
2.baseband提供全雙工的通訊頻道
但這不意味所有的L2CAP通訊都具備雙向的特性
廣播或者不具方向性的交通(如video)就不需要雙工的頻道
3.在baseband之上提供一個可靠的頻道
當要求或重送資料時,baseband會提供資料一致性的檢查直到成功或者逾時為止
因為回音有可能遺失,逾時就可能發生
baseband使用一個 1-bit 的循序號碼來移除重複的情形
baseband broadcast packet是被禁止的,會影響可靠度
Scope
說明一些主要的限制與範圍
===== 一般性運作 =====
建立在channel之上,每個頻道都有一個 頻道識別 來參考
2.1 Channel identifiers (CIDS) 頻道識別
0x0001~0x003F是被保留給特定的L2CAP功能的
0x0000則是被定義為一個不正常的識別
然後可以參考page 253的表格
主要就是說明識別對每個設備而言只能唯一,不會重複
比如 A 連到 B 也連到 C
A 給 B 的號碼是 0x0070
給 C 的號碼是 0x0071
而 B 連到 C 也連到 A
B 給 C 的號碼也是 0x0070
B 給 A 的號碼也是 0x0071
這樣子其實是沒有重複的
2.2 設備間的運作
page 254 的圖說明了如何運作
另外也有一張表提供CID的一些預設值
2.3 Layer間的運作
2.4 分割與組合
分割與重新組合主要是用來增進傳輸的效率
所有的L2CAP packet 可以被分割來在baseband packets之上傳輸
並不執行任何分割和重組的動作,但是packet的格式支援適應去變為更小的實體框架.
一個L2CAP的實作揭露了外出的MTU和分割為較高層次的packets到較大的單位,以便可以經由HCI被傳遞到 link manager
在接受端,L2CAP的實作從HCI接收較大的片,並使用HCI和packet表頭的資訊重組這些較大的片成為L2CAP packets
可以參考page 255的圖,會比較容易瞭解
baseband packet的表頭,前兩個bit,如果是’10’,表示是在L2CAP packet裡的第一個分割.
’01’則是一個順序的分割.(參考page 256的圖)
2.4.1
L2CAP MTU會使用一個特定服務介面的實作來把他批露出來
這是較高層級協定的任務,要限制送給L2CAP層級packet的大小要小於MTU的限制.
如果要送到baseband,就需要轉為 baseband packet
所有與L2CAP packet相關的L2CAP 分割必須在任何其他L2CAP packet到達相同單位之前被送到baseband
2.4.2
baseband協定順序傳送acl packet並且用 16bit的 CRC來保護資料的一致性
同時也使用一個自動重複要求的機械動作來支援可被信賴的連結.
如同baseband控制器接收acl packets, 他同時也在每個baseband packet到達的同時,通知L2CAP 層級.
或者在(buffer滿or逾時發生)的時候累積一定數量的packet
L2CAP時坐必須使用L2CAP packet的”長度”欄位. (refer to page 272)
不符合長度的packet會被靜靜的放棄掉.
為了可被信賴的channels, L2CAP 實作必須告訴上層, channel已經被成不可被信賴的.
藉著擁有一個無限flush的實限數值,我們可以定義可被信賴的channels.(refer to page 290)
page 257有一張解說的蠻詳盡的圖表
3.狀態機器??
定義狀態, 狀態轉移所發生的事件, 和事件回應時被執行的動作.
page 258的圖可以幫助你了解整件事情的始末,下面的文字則是對圖的描述
page 259則是更明確指出上一張圖裡面所謂回應與確認(L2CA_Request, L2CA_Confirm, L2CA_Response, L2CA_Indication)的動作,
並且加上了時序的觀念
當L2CA_Request進來,被接受後,變成L2CA_Indication
於是回應(L2CA_Response),出去成為一個確認(L2CA_Confirm)
3.1 事件
簡單的來說事件區分為: 1.從底層來的Indication 和 Confirms, 2.從高層來的 Request 和 Responses, 3.從同層來的資料, 4.同層來的要求與回應, 5.逾時所觸發的事件
3.1.1 由底層到L2CAP的事件
Lp_ConnectCfm 確認建立lower layer連結的要求.如果認證被需要用來建立實體連結的話,就包括傳遞認證挑戰的工作.
LP_ConnectCfmNeg 建立lower layer連結失敗的時候,可以用來確認失敗的事件,包括裝置沒接觸到,拒絕要求,或者是認證失敗
LP_ConnectInd 指出已經跟lower protocol建立連結了.在baseband的狀況下,這將會是一個ACL Link.一個L2CAP實體會用來追蹤實體連接是否存在
LP_DisconnectInd 指出 lower protocol 已經被 LMP commands 或者是逾時事件所關閉
LP_QoSCfmNeg 因為QoS所造成的要求失敗.
LP_QoSViolationInd 指出 lower protocol 已經偵測到違反QoS規定. 跟上面那個有關喔
3.1.2 L2CAP to L2CAP 警示事件
每個L2CAP實體跟L2CAP警示 PDUs交換時所發生的事件.可參考Section 5
經由lower protocol從lower layer收到事件.此部份也可以參考page 258 的圖
L2CAP_ConnectReq 一個連結要求packet被收到
L2CAP_ConnectRsp 當一個明確指出連結已建立的連結回應packet已經收到
L2CAP_ConnectRspPnd 一個連結回應packet被收到, 並指出遠端端點已經收到 request 並正在執行.
L2CAP_ConnectRspNeg 一個連結回應packet已經被收到,指出連結未被建立.
L2CAP_ConfigReq 一個配置回應packet已經收到並指出遠端端點同意所有洽談過的參數
L2CAP_ConfigRspNeg 類似上一個,不過這個是不同意
L2CAP_DisconnectReq 收到這個, channel必須初始化disconnection的process: L2CAP實體應該傳回對應的CID
L2CAP_DisconnectRsp 一個中斷連結的回應封包被收到. 然後會把相符的CID資料釋放,丟回pool裡面去. 中斷的要求一定會成功.
3.1.3 L2CAP 對 L2CAP 資料事件
L2CAP_Data 一個資料封包已經被收到
3.1.4 上層對L2CAP的 事件
L2CA_ConnectReq 上層來的要求說要對遠端設備Channel的建立
L2CA_ConnectRsp 從上層來的回應說從遠端設備的連接要求表示(可以參考 3.2.4 L2CA_Connectind )
L2CA_ConnectRspNeg 從上層來的回應說連接被遠端設備拒絕的時候(可以參考 3.2.4 )
L2CA_ConfigReq 從上層來的要求說要重新設置channel
L2CA_ConfigRsp 從上層來的回硬說重新設置要求的indication (突然發現indication很難翻)
L2CA_ConfigRspNeg 重新設置要求的indication,從上層來的失敗回應
L2CA_DisconnectReq 為了channel立即中斷連接而從上層來的要求.
L2CA_DisconnectRsp 從上層給中斷連接要求的indication來的回應.中斷指示必須總是被接受!
L2CAP_DataRead 為了從L2CAP實體到上層的接收資料的傳輸而從上層來的回應.
L2CAP_DataWrite 為了從上層到L2CAP實體的資料傳輸而從上層來的要求.
11/20~11/25
3.1.5 Timer events
當一個信號用的要求被送出去的時候,這個timer就開始了.一直到遠端有了回應之後,這個timer才結束.
如果這個timer超過了一定的時間,一個副本的要求訊息會被送出或者CID在這個要求就會被結束掉.
當一個副本訊息被送出,RTX 的timeout數值必須重新設置一個新的數值,至少要是原來數值的兩倍.
實作時必須要去決定在中斷channel之前重新傳播要求的次數.
3.2 Actions
被分成五個主要的部分:向高層級確認與通知, 向低層級要取與回應,同層級間的要取與回應,同層級間的資料傳輸,設定timer.
3.2.1 L2CAP對低層的的動作
LP_ConnectReq L2CAP 要求低層的協定去建立連結,如果與遠端裝置的實體連結不存在,這個訊息必定會被送往低層協定已完成實體連接.
在兩個設備之間,不會超過一個ACL連結, 在兩設備之間的額外L2CAP channels必須與其他相同baseband的acl link共享
遵循這個要求的執行,低層必須回傳一個 LP_ConnectCfm 或者一個 LP_ConnectCfmNeg 去指示目前這個要求是否令人滿意.
LP_QosReq L2CAP要求低層協定去容納一個獨有的Qos參數集.遵循這要求的執行,低層回傳一個LP_QosCfm 或者LP_QosCfmNeg去只是這個要求是否令人滿意.
LP_ConnectRsp 一個確定的回應接受之前連結指示的要求.(可參考 Section 3.1.1 的LP_ConnectInd)
LP_ConnectRspNeg 這個就跟上面相反,是拒絕
3.2.2 L2CAP對L2CAP警示的動作
這一節包含了和Section 3.1.2 相同的名稱識別,除了動作參考了傳輸,而不是接受.
3.2.3 L2CAP對L2CAP資料動作
這一節與Section 3.1.3極為相似,資料傳輸是主要的動作.
3.2.4 L2CAP對上層的動作
L2CA_ConnectInd 指示一個連接要求已經從遠端設備被接受.(參考 Section 3.1.4 的 L2CA_ConnectReq)
L2CA_ConnectCfm 確認連接要求已經被接受(參考 Section 3.1.4 的L2CAP_ConnectReq),
L2CA_ConnectCfmNeg 連結要求的否定確認(參考Section 3.1.4 的L2CA_ConnectReq). 或者是RTX timer逾時發生(參考Section 3.1.5 與L2CA_TimeOutInd的下面)
L2CA_ConnectedPnd 確認連結回應已經被遠端的設備接收.
L2CA_ConfigCfm 指示遵循從遠端裝置的回應安裝要求已經被接受
L2CA_ConfigInd 指示一個裝置要求已經從遠端裝置被接收.
L2CA_ConfigCfmNeg 裝置要求的相反確認. 或者是 RTX timer 逾時發生
L2CA_DisconnectInd 從遠端裝置來的指示中斷連接要求已經被接收.或者遠端裝置已經中斷連接,因為他已經無法回應一個警示要求.
L2CA_DisconnectCfm 確認一個遵循自遠端裝置收到的中斷連接回應的中斷連接要求已經被遠端裝置執行.
L2CA_TimeOutInd 指示RTX或ERTX timer已經逾時. 這個指示將會在L2CAP快放棄時或在送出L2CA_DisconnectInd而發生.
L2CA_QoSViolationInd 指示服務同意品質已經污損.
3.3 Channel Operational States
.Closed 在此狀況下,沒有任何頻道會與CID關聯.這是唯一一個 link level 連結baseband不會存在的狀況. 連接中斷連結強迫所有其他狀態到Closed的狀態
.W4_L2CAP_Connect_rsp 在此狀態,CID呈現一個區域終端和一個已經被送達的L2CAP_ConnectReq訊息
891204~891209
.W4_L2CA_CONNECT_RSP
在這個狀態下,遠端終端點存在,而且一個L2CAP_ConnectReq已經被本地的L2CAP實體所接收.
一個L2CA_ConnectInd已經被送到上層而且一部份正在處理已經收到的L2CAP_ConnectReq的本地L2CAP實體等待一致的回應
回應有可能需要一個安全的防護被執行
.CONFIG
在這個狀態,連接已經被建立,但是兩邊仍然在協商channel參數.
當channel參數被重新談判的時候,配置狀態可能也被進入.
進入配置狀態之前,所有出去的資料傳遞應該被暫停,直到資料傳遞的傳遞參數被重新談判.
直到遠端channel端點已經進入配置狀態之前,進來的資料傳遞都必須被接受.
在配置狀態,兩邊必須發布L2CAP_ConfigReq訊息,如果預設已經被使用,一個null的訊息必須被送出,可以參考Page 280的Section 5.4.
如果大量的參數需要被重新談判,多重訊息可以被送出,以避免任何MTU限制以及多餘的談判,可參考Page289的Section6.
從配置狀態移到開啟狀態,需要兩邊都ok才行.當L2CAP實體收到一個確定的回應發出最後的要求而且也正確的回應遠端裝置最後的要求時,一個L2CAP實體才ready.
.OPEN
在此狀態下,連接已經被建立並被配置,而且資料流可能已處理.
.W4_L2CAP_DISCONNECT_RSP
在此狀態,連接正在關閉,而且L2CAP_DisconnectReq訊息已經送出.此狀態正在等待一致的回應.
.W4_L2CA_DISCONNECT_RSP
在此狀態,在遠端端點的連接正在關閉而且一個L2CAP_DisconnectReq訊息已經被接收.
一個L2CA_DisconnectInd已經送出到上層去通知正在被關閉中的CID的擁有者.
此狀態正在等待從在回應遠端端點之前的上層而來的一致回應.
3.4 對應
這邊則是一份超清楚的對應圖
什麼樣的事情會發生什麼樣的事件
什麼樣的事件跟其他事件又有什麼關係
什麼時候該發生
超清楚
page 266~271
891211~891215
4 資料封包格式
L2CAP以packet為基底,但是遵循以channel為基底的通訊模式.
一個channel呈現一個在遠端L2CAP實體設備間的資料流.
Channels可以是”連接導向傳輸”或者是”無連接傳輸模式”.
所有packet欄位使用小印地安位元排序.
4.1 連接導向傳輸
圖4.1描述包含了連接導向channel的L2CAP packet格式(也參考了 L2CAP PDU)
長度欄位共有2 octets (16 bits)
排除掉L2CAP表頭的長度,其他就是可搭載的資料量.
可搭載的資料量可以到65535 bytes.
傳輸結束時,長度欄位為要重組的L2CAP packet提供了一個簡單的一致性檢查.
Channel ID: 2 octets
Channel ID 識別出packet的目的channel端點.channel ID 的範圍與packet要被送到的設備有關.
Information: 0 到 65535 octets
這包含了從上層協定收到的packet(outgoing packet),或者是傳送到上層協定的packet(incoming packet).
連接導向型(MTUcno)的最小被支援的MTU是在channel配置中被協商出來的.(可看Page 289的Section 6.1)
信號型的(MTUsig)的最小被支援的MTU有48 bytes.(可看Page275 的 section 5 ).
4.2 無連接傳輸模式
附加於連接導向傳輸的channel,L2CAP也提供群組導向channel的概念.
再最好的狀況下,資料被送到 ‘group’ channel 然後會被轉送到所有在此 group 中的成員.
群組(group)沒有任何與它們相關的服務品質.
群組channels是不可被信賴的; L2CAP不提供任何資料會成功送到群組成員的保證.
如果相關的群組轉移是必須的,他必須在更高的層面去實作.
傳播到一個群組必須不可以獨占的送到該群組的所有成員.
本地端設備不能是一個群組中的成員,而且高層協定正預料著回傳任何傳送到本地端設備的資料.
不可以獨占意味著無群組的成員可能收到群組的傳訊而且高層(或連結層)的加密可以被使用來支援私密的通訊.
欄位有:
Length: 2 octets
長度指示資料量的大小,包含PSM欄位的大小,但不包含L2CAP表頭的長度.
Channel ID: 2 octets
Channel ID (0x0002)保留用來作無連接傳輸模式的傳遞.
Protocol/Service Multiplexer(PSM): 2 octets (最小)
PSM 欄位以ISO 3309為主的一個位址欄.
PSM欄位的內容起源於PSM的值,必須是奇數, 最小的指示octet必須是’1′
看 page 278 的 section 5.2,有比較詳細的定義.
資料: 0 到 65533 octets
資料量要被散佈到群組中的每個成員.
實作必須支援最小無連接傳輸MTU 670 octets, 在某些特例下可以小於這個數值.
L2CAP群組服務介面提供基本群組的管理途徑, 包括建立一個群組,為群組增加成員,從群組中移除成員.
沒有任何預先定義的群組.