關鍵詞:藍牙核心技術協議 HCI L2CAP SDP RFCOMM
作者:xubin341719(歡迎轉載,請注明作者,請尊重版權,謝謝!)歡迎指正錯誤,共同學習、共同進步!!下載鏈接:Bluetooth PROFILE SPECIFICATIONS (基本涵蓋所有藍牙協議)、buletooth core 2.1-4.0 SPECIFICATION(三藍牙版本的核心協議v2.1/v3.0/v4.0)、藍牙核心技術與應用 馬建倉 版(藍牙協議相關初學者必讀,開發者參考)
藍牙核心技術概述(一):藍牙概述藍牙核心技術概述(二):藍牙使用場景藍牙核心技術概述(三): 藍牙協議規范(射頻、基帶鏈路控制、鏈路管理)藍牙核心技術概述(四):藍牙協議規范(HCI、L2CAP、SDP、RFOCMM)藍牙核心技術概述(五):藍牙協議規范(irOBEX、BNEP、AVDTP、AVCTP)
一、主機控制接口協議  HCI藍牙主機-主機控模型
藍牙軟件協議棧堆的數據傳輸過程:
1、藍牙控制器接口數據分組:指令分組、事件分組、數據分組(1)、指令分組

如:Accpet Connection RequestOpcode為:0x0409參數長度為: 07 參數中藍牙地址為:00:0d:fd:5f:16:9f角色為:從設備  0x01大端數據模式指令為:09 04 07 9f 16 5f fd 0d 00 01(2)、事件分組

如上圖:Opcode :0x0409狀態: 0x00總長度: 4字節命令狀態:0x0f(3)、數據分組ACL 數據分組
連接句柄(12bit)  | PB(2bit)  | BC(2bit)  | 數據長度(16bit)  | 
數據…………  | |||
注:PB Packet_Boundary BC Broadcast FlagSCO 數據分組
連接句柄(12bit)  | 保留(4bit)  | 數據長度(16bit)  | 
數據…………  | ||
(4)、RS232分組指示器:
HCI 分組類型  | RS232分組指示器  | 
HCI指令分組  | 0x01  | 
HCI ACL數據分組  | 0x02  | 
HCI SCO數據分組  | 0x03  | 
HCI事件分組  | 0x04  | 
HCI錯誤消息分組  | 0x05  | 
HCI協商分組  | 0x06  | 
2、HCI控制命令
(1)、鏈路控制指令
命令  | OCF  | 概述  | 
Inquiry  | 0x0001  | 藍牙設備進入查詢模式,搜索臨近設備  | 
Inquiry Cancel  | 0x0002  | 退出查詢模式  | 
Periodic Inquiry Mode  | 0x0003  | 藍牙設備在指定周期內自動查詢  | 
Exit Periodic Inquiry Mode  | 0x0004  | 退出自動查詢模式  | 
Create Connection  | 0x0005  | 按指定藍牙設備的BD_ADDR創建ACL鏈路  | 
Disconnect  | 0x0006  | 終止現有連接  | 
Add SCO Connection  | 0x0007  | 利用連接句柄參數指定的ACL連接創建SCO  | 
Cancel Create Connection  | 0x0008  | 
  | 
Accept Connection Request  | 0x0009  | 接收新的呼入連接請求  | 
Reject Connection Request  | 0x000A  | 拒絕新的呼入連接請求  | 
Link Key Request Reply  | 0x000B  | 應答從主機控制器發出的鏈路密鑰請求事件,并指定存儲在主機上的鏈路密鑰做為與BD_ADDR指定的藍牙設備進行連接使用的鏈路密鑰請求事件  | 
Link Key Request Negative Reply  | 0x000C  | 如果主機上沒有存儲鏈路密鑰,作為與BD_ADDR指定的藍牙設備進行連接使用的鏈路密鑰,就應答從主機控制器發出的鏈路密鑰請求事件  | 
PIN Code Request Reply  | 0x000D  | 應答從主機控制器發出的PIN請求事件,并指定用于連接的PIN  | 
PIN Code Request Negative Reply  | 0x000E  | 當主機不能指定連接的PIN時,應回答從機控制器發出的PIN請求事件  | 
Change Connection Packet Type  | 0x000F  | 改變正在建立連接的分組類型  | 
Authentication Request  | 0x0011  | 指定連接句柄關聯的兩個藍牙設備之間建立身份鑒權  | 
Set Connection Encryption  | 0x0013  | 建立取消連接加密  | 
Change Connection Link Key  | 0x0015  | 強制關聯了連接句柄的兩個設備建立連接,并生成一個新的鏈路密鑰  | 
Master Link Key  | 0x0017  | 強制關聯了連接句柄的兩個設備利用主設備時鏈路密鑰或常規密鑰  | 
Remote Name Request  | 0x0019  | 獲取遠端設備的名稱  | 
Cancel Remote Name Request  | 
  | 
  | 
Read Remote Supported Features  | 0x001B  | 請求遠端設備所支持的特性列表  | 
Read Remote Extended Features  | 
  | 
  | 
Read Remote Version Information  | 0x001D  | 從遠端設備讀取版本信息  | 
Read Clock Offset  | 0x001F  | 讀取遠端的時鐘信息  | 
(2)、鏈路策略指令
命令  | OCF  | 簡介  | 
Hold Mode  | 0x0001  | 改變LM狀態和本地及遠程設備為主模式的LM位置  | 
Sniff Mode  | 0x0003  | 改變LM狀態和本地及遠程設備為呼吸模式的LM位置  | 
Exit Sniff Mode  | 0x0004  | 結束連接句柄在當前呼吸模式里的呼吸模式  | 
Park State  | 0x0005  | 改變LM狀態和本地及遠程設備為休眠模式的LM位置  | 
Exit Park State  | 0x0006  | 切換從休眠模式返回到激活模式的藍牙設備  | 
QoS Setup  | 0x0007  | 指出連接句柄的服務質量參數  | 
Role Discovery  | 0x0009  | 藍牙設備連接后確定自己的主從角色  | 
Switch Role  | 0x000B  | 角色互換  | 
Read Link Policy Settings  | 0x000C  | 為指定連接句柄讀鏈路策略設置。鏈路策略設置允許主機控制器指定用于連接句柄的LM連接模式  | 
Write Link Policy Settings  | 0x000D  | 為指定連接句柄寫鏈路策略設置。鏈路策略設置允許主機控制器指定用于連接句柄的LM連接模式  | 
Read Default Link Policy Settings  | 0x000E  | 
  | 
Write Default Link Policy Settings  | 0x000F  | 
  | 
Flow Specification  | 0X0010  | 
  | 
(3)、主機控制器與基帶指令
Set Event Mark  | 0x0001  | 使能主機過濾HCI產生的事件  | 
Reset  | 0x0003  | 復位藍牙控制器、鏈路管理器、基帶鏈路管理器  | 
Set Event Filter  | 0x0005  | 使能主機指定不同事件過濾  | 
Flush  | 0x0008  | 針對指定的藍牙句柄,放棄所有作為當前待傳輸數據,甚至當前是屬于多個在主機控制器里的L2CAP指令的數據塊  | 
Read PIN Type  | 0x0009  | 主機讀取指定主機的PIN類型是可變的還是固定的  | 
Write PIN Type  | 0x000A  | 主機寫入指定主機的PIN類型是可變的還是固定的  | 
Create New Unit Key  | 0x000B  | 創建新的單一密鑰  | 
Read Stored Link Key  | 0x000D  | 讀取存放在藍牙控制器中的單個或者多個密鑰  | 
Write Stored Link Key  | 0x0011  | 寫入存放在藍牙控制器中的單個或者多個密鑰  | 
Delete Stored Link Key  | 0x0012  | 刪除存放在藍牙控制器中的單個或者多個密鑰  | 
Write Local Name  | 0x0013  | 修改藍牙設備名稱  | 
Read Local Name  | 0x0014  | 讀取藍牙設備名稱  | 
Read Connection Accept Timeout  | 0x0015  | 讀連接識別超時參數值,定時器終止后藍牙硬件自動拒絕連接  | 
Write Connection Accept Timeout  | 0x0016  | 寫連接識別超時參數值,定時器終止后藍牙硬件自動拒絕連接  | 
Read Page Timeout  | 0x0017  | 讀尋呼超時參數值,本地設備返回連接失敗前,該值是允許藍牙硬件定義等待遠程設備連接申請時間  | 
Write Page Timeout  | 0x0018  | 寫尋呼超時參數值,本地設備返回連接失敗前,該值是允許藍牙硬件定義等待遠程設備連接申請時間  | 
Read Scan Enable  | 0x0019  | 寫出掃描允許參數值---用來控制藍牙設備周期性查詢  | 
Write Scan Enable  | 0x001A  | 讀出掃描允許參數值---用來控制藍牙設備周期性查詢  | 
Read Page Scan Activity  | 0x001B  | 讀尋呼掃描間隔、尋呼掃描區間參數  | 
Write Page Scan Activity  | 0x001C  | 寫尋呼掃描間隔、尋呼掃描區間參數  | 
Read Inquiry Scan Activity  | 0x001D  | 讀查詢掃描間隔、查詢掃描區間參數  | 
Write Inquiry Scan Activity  | 0x001E  | 寫查詢掃描間隔、查詢掃描區間參數  | 
Read Authentication Enable  | 0x001F  | 讀取鑒權允許參數---控制藍牙設備是否對每個連接進行鑒權  | 
Write Authentication Enable  | 0x0020  | 寫取鑒權允許參數---控制藍牙設備是否對每個連接進行鑒權  | 
Read Encryption Mode  | 0x0021  | 讀加密模式數值---控制藍牙設備是否對每個連接進行加密  | 
Write Encryption Mode  | 0x0022  | 寫加密模式數值---控制藍牙設備是否對每個連接進行加密  | 
Read Class Of Device  | 0x0023  | 讀取設備類型參數值,用于區別設備能力  | 
Write Class Of Device  | 0x0024  | 寫設備類型參數值,用于區別設備能力  | 
Read Voice Setting  | 0x0025  | 讀取語音設置參數值,控制語音連接的各種設置  | 
Write Voice Setting  | 0x0026  | 寫語音設置參數值,控制語音連接的各種設置  | 
Read Automatic Flush Timeout  | 0x0027  | 對指定句柄,讀取刷新超時值  | 
Write Automatic Flush Timeout  | 0x0028  | 對指定句柄,寫入刷新超時值  | 
Read Num Broadcast Retransmissions  | 0x0029  | 讀取設備的廣播重復發送次數,重復發送提高廣播消息的可靠性  | 
Write Num Broadcast Retransmissions  | 0x002A  | 寫入設備的廣播重復發送次數,重復發送提高廣播消息的可靠性  | 
Read Hold Mode Activity  | 0x002B  | 讀取Hold Mode Activity的參數值,用來確定Hold掛起的時間  | 
Write Hold Mode Activity  | 0x002C  | 寫入Hold Mode Activity的參數值,用來確定Hold掛起的時間  | 
Read Transmit Power Level  | 0x002D  | 對指定句柄,讀取傳輸功率的參數值  | 
Read Synchronous Flow Control Enable  | 0x002E  | 讀取SCO流量控制設置。通過使用該設置,主機控制器決定是否主機控制器發送與SCO連接句柄相關的完成分組事件的數量  | 
Write Synchronous Flow Control Enable  | 0x002F  | 讀寫入SCO流量控制設置。通過使用該設置,主機控制器決定是否主機控制器發送與SCO連接句柄相關的完成分組事件的數量  | 
Set Host Controller To Host Flow Control  | 0x0031  | 主機控制器的打開、關閉,主機控制器到主機的流量控制  | 
Host Buffer Size  | 0x0033  | 主機通知主機控制器自己的ACL、SCO數據緩沖區大小。主機控制器分段傳輸數據,而數據不會超出這個范圍  | 
Host Number Of Completed Packets  | 0x0035  | 當主機對于任何連接的句柄準備接受較多的HCI指令時,該指令用于通過主機指出主機控制器  | 
Read Link Supervision Timeout  | 0x0036  | 讀取連接管理超時參數。主從藍牙設備用該參數監視鏈路丟失情況  | 
Write Link Supervision Timeout  | 0x0037  | 寫入連接管理超時參數。主從藍牙設備用該參數監視鏈路丟失情況  | 
Read Number of Supported IAC  | 0x0038  | 讀取查詢掃描期間本地藍牙掃描的查詢識別碼(ICA)的數值  | 
Read Current IAC LAP  | 0x0039  | 讀取創建在查詢掃描期間本地藍牙設備正同時掃描的藍牙識別碼的LAP  | 
Write Current IAC LAP  | 0x003A  | 寫入創建在查詢掃描期間本地藍牙設備正同時掃描的藍牙識別碼的LAP  | 
Read Page Scan Period Mode  | 0x003B  | 讀取本地藍牙設備的強制尋呼掃描區間模式  | 
Write Page Scan Period Mode  | 0x003C  | 寫入本地藍牙設備的強制尋呼掃描區間模式  | 
Read Page Scan Mode  | 0x003D  | 讀取本地藍牙設備的默認尋呼掃描區間模式  | 
Write Page Scan Mode  | 0x003E  | 寫入本地藍牙設備的默認尋呼掃描區間模式  | 
(4)、信息指令參數
Read Local Version Information  | 0x0001  | 讀取本地藍牙版本信息  | 
Read Local Supported Features  | 0x0003  | 讀取本地藍牙設備特征表  | 
Read Local Extended Features  | 0x0004  | 
  | 
Read Buffer Size  | 0x0005  | 返回HCI緩沖容量。緩沖容量用于傳輸緩沖數據  | 
Read Country Code [Deprecated]  | 0x0007  | 讀取國家代碼狀態參數值  | 
Read BD ADDR  | 0x0009  | 讀取BD_ADDR的參數值  | 
(5)、狀態指令參數
Read Failed Contact Count  | 0x0001  | 讀取對于其他設備特殊連接的Failed Contact Count參數值。Failed Contact Count記錄在刷新時終止及當前正在傳輸的L2CAP數據指令被自動刷新后,主單元或從單元不能連續響應事件次數  | 
Reset Failed Contact Count  | 0x0002  | 復位時對于其他設備的連接的Failed Contact Count的參數值。Failed Contact Count記錄在刷新時終止及當前正在傳輸的L2CAP數據指令被自動刷新后,主單元或從單元不能連續響應事件次數  | 
Get Link Quality  | 0x0003  | 讀取指定連接句柄的Link Quality的值  | 
Read rssI  | 0x0005  | 讀取對于其他藍牙設備連接句柄的接收信號強度指示  | 
Read AFH Channel Map  | 0x0007  | 
  | 
Read BD Clock  | 0x0009  | 
  | 
(6)、測試指令
Read Loopback Mode  | 0x0001  | 讀取主機端控制器會送模式的設置值。回送模式設置可以確定信息發送路徑  | 
Write Loopback Mode  | 0x0002  | 寫入主機控制器會送模式的設置值。回送模式設置可以確定信息發送路徑  | 
Enable Device Under Test Mode  | 0x0003  | 允許本地藍牙設備模塊通過LMP測試指令接入測試模式。當主機要求本地設備作為待測試設備,實現藍牙測試模式文件中規定測試場景,則發送該指令  | 
(7)、錯誤代碼
錯誤代碼  | 錯誤含義  | 錯誤代碼  | 錯誤含義  | 
0x01  | 位置HCI指令  | 0x14  | 由于另一端引起連接中斷:資源限制  | 
0x02  | 不能連接  | 0x15  | 由于另一端引起連接中斷:關機  | 
0x03  | 硬件故障  | 0x16  | 本機中斷連接  | 
0x04  | 尋呼超時  | 0x17  | 重復嘗試  | 
0x05  | 身份驗證失敗  | 0x18  | 不允許匹配  | 
0x06  | 鍵丟失  | 0x19  | 未知LMP PDU  | 
0x07  | 存儲器已滿  | 0x1A  | 不支持遠端特性  | 
0x08  | 連接超時  | 0x1B  | 拒絕SCO補償  | 
0x09  | 最大連接數  | 0x1C  | 拒絕SCO間歇模式  | 
0x0A  | 連接到設備A的最大SCO連接數  | 0x1D  | 拒絕SCO無線模式  | 
0x0B  | ACL連接已存在  | 0x1E  | 非法鏈路管理參數  | 
0x0C  | 指令非法  | 0x1F  | 未特別指明錯誤  | 
0x0D  | 由于資源有限,主機被拒絕  | 0x20  | 不支持鏈路管理器協議參數  | 
0x0E  | 由于安全原因,主機被拒絕  | 0x21  | 不允許角色改變  | 
0x0F  | 由于遠端設備單連接設備,主機拒絕  | 0x22  | 鏈路管理響應超時  | 
0x10  | 主機超時  | 0x23  | 鏈路管理錯誤處理事務沖突  | 
0x11  | 不支持特性或參數值  | 0x24  | 不允許LMP PDU  | 
0x12  | 非法主機控制接口指令  | 0x25~0xFF  | 保留  | 
0x13  | 由于另一端引起連接中斷:用戶中斷連接  | 
  | 
  | 
二、邏輯鏈路控制與適配協議  L2CAPL2CAP位于基帶之上,將基帶的數據分組轉換為便于高層應用的數據分組格式,并提供協議復用和服務質量交換等功能。L2CAP只支持ACL數據傳輸,不支持SCO數據。L2CAP本身不提供加強信道可靠性和保證數據完整性的機制,其信道的可靠性依靠基帶提供。
1、協議復用:底層傳輸協議沒有提供對高層協議的復用機制,因而L2CAP支持高層協議復用,L2CAP層可以區分其上的SDP、RFCOMM、TCS等。
2、分段重組:L2CAP層幫助實現基帶的短PDU和高層的長PDU相互傳輸,L2CAP本身不完成任何PDU的分段重組,具體的分段重組有低層和高層來完成。
3、服務質量 Qualityof Serivce 信息的交換:藍牙建立連接的過程中,L2CAP允許交互藍牙所期望的服務質量,建立完成后,通過監視資源的使用情況,來保證服務質量。
4、組抽象:L2CAP忽略地址組概念,他只關心數據。
L2CAP信道有三種類型:
A、面向連接信道:Connection-OrientedCO,用于兩個設備之間的數據通信。
B、無連接信道:Connection-LessCL,用來向一組設備廣播方式傳輸數據。CID為固定值:0x0002。
C、信令信道:Signaling,用于創建CO通道,可以通過協商改變CO信道的特性。
CL信道的L2CAP_PDU
長度(2bytes)  | 信道ID(0x0002)  | PSM(最小為2bytes)  | 有效載荷  | 
PSM為 協議/服務復用器Protocol/Service Multiplexer,一般為SDP、RFCOMM、TCS等中介協議復用。小于0x1000的值,0x0001對應SDP,0x0003對應RFCOMM、0x0005對應TCS。(1)、藍牙邏輯鏈路控制與適配協議信令:L2CAP的信令通道的CID為0x0001
信令指令分組:
長度(2byte)  | CID(0x0001)  | 指令1  | 指令2  | ……………  | 指令n  | 
L2CAP 分組頭部分  | 
  | ||||
信令指令格式:
代碼(1byte)  | 標識符(1byte)  | 長度(2byte)  | 數據  | 
信令指令頭  | |||

如上圖所示,一條L2CAP信令,1為L2CAP分組頭,2為信令指令頭,3為數據部分。
L2CAP:
Role:Master
Address:11
PDULength: 6 //指令的長度,值為06 00
ChannelID: 0x0001 (Signaling)//L2CAP的信令通道,值為01 00
Code:Information request//信息請求,值為0a
Identifier:1//標識符,值為01
CommandLength: 2//命令長度,值為02 00
InfoType:Extended features supported//02 00
所以這條指令完整的為:
06 00 01 00 0a 01 02 00 02 00
信令的其他操作如下:

L2CAP信令指令碼:
Code  | Description  | 
  | 
0x00  | RESERVED  | 保留  | 
0x01  | Command reject  | 拒絕命令  | 
0x02  | Connection request  | 連接請求  | 
0x03  | Connection response  | 連接響應  | 
0x04  | Configure request  | 配置請求  | 
0x05  | Configure response  | 配置響應  | 
0x06  | Disconnection request  | 斷開請求  | 
0x07  | Disconnection response  | 斷開響應  | 
0x08  | Echo request  | 
  | 
0x09  | Echo response  | 
  | 
0x0A  | Information request  | 信息請求  | 
0x0B  | Information response  | 信息響應  | 
1)、連接請求Connection_Request Code=0x02
代碼(0x02)  | 標識符(1字節)  | 長度(2字節)  | PSM(2字節)  | 源CID(2字節)  | 
例如:SDP 連接請求
如上紅框所示:
代碼(0x02)  | 標識符(1字節)  | 長度(2字節)  | PSM(2字節)  | 源CID(2字節)  | 
0x02  | 3  | 4  | SDP  | 0x0040  | 
2)、連接相應Connection_Response Code=0x03
代碼(0x03)  | 標識符  | 長度  | 目標CID  | 源CID  | 結果  | 狀態  | 
例如:SDP請求響應
如上面紅框所示:
代碼(0x03)  | 標識符  | 長度  | 目標CID  | 源CID  | 結果  | 狀態  | 
0x03  | 3  | 8  | 0x0040  | 0x0040  | 0x0000  | 
  | 
(2)、MTU MAXIMUMTRANSMISSION UNIT最大傳輸單元
MTU最大傳輸單元,L2CAP應用必須支持最小為48字節的MTU,默認值為672
(3)、QoS 服務質量
三、服務發現協議 SDP
SDP兩種服務發現模式:1)、服務搜索:查詢具有特定服務屬性的服務;2)、服務瀏覽:簡單的瀏覽全部可用服務。(1)、PDU 格式:(協議數據單元)
PDU ID(1byte)  | Transaction ID(2byte)  | 參數長度(2byte)  | 參數1  | ……  | 參數N  | 
Header  | 
  | ||||
不同PDU ID實現SDP的不同功能,概述如下表格:
Value  | Parameter Descirption  | 
  | 
0x00  | Reserved  | 保留  | 
0x01  | SDP_ErrorResponse  | 錯誤響應  | 
0x02  | SDP_ServiceSearchRequest  | 服務搜索請求  | 
0x03  | SDP_ServiceSearchResponse  | 服務搜索響應  | 
0x04  | SDP_ServiceAttributeRequest  | 服務屬性請求  | 
0x05  | SDP_ServiceAttributeResponse  | 服務屬性響應  | 
0x06  | SDP_ServiceSearchAttributeRequest  | 服務搜索屬性請求  | 
0x07  | SDP_ServiceSearchAttributeResponse  | 服務搜索屬性響應  | 
0x08-0xff  | Reserved  | 保留  | 
(2)、服務記錄表SDP的服務記錄表對每一個服務進行描述,每條記錄包含服務句柄、一組服務屬性:

Service Record Attributes:服務記錄;Service Record Handle 服務句柄;Attribute 服務屬性;

四、串口仿真協議 RFCOMM
為建立在串口之上的傳統應用提供環境接口,使他們可以做比較少協議改動就可以在藍牙無線通信無線鏈路上工作。多路串口仿真是RFCOMM的重要功能,通過多路復用器(multiplexer),一條L2CAP鏈路可以同時 多個串行應用。兩臺設備間的串口仿真:
RFCOMM 兩個藍牙設備之間可以支持多達60多路仿真串口。
RFCOMM幀類型如下:
SABM  | 異步平衡模式設置指令  | 
UA  | 未加編號的確認響應  | 
DM  | 斷開連接模式響應  | 
DISC  | 斷開連接指令  | 
UIH  | 帶頭校驗的未編號信息命令和響應  | 

新聞熱點
疑難解答