蓝牙协议学习整理(三)蓝牙协议规范(HCI、L2CAP、SDP、RFOCMM)

第三章 蓝牙协议规范(HCI、L2CAP、SDP、RFOCMM)

一、主机控制接口协议 HCI

蓝牙主机-主机控模型
这里写图片描述

蓝牙软件协议栈堆的数据传输过程:
这里写图片描述

1、蓝牙控制器接口数据分组:

指令分组、事件分组、数据分组

(1)、指令分组
这里写图片描述

这里写图片描述

如:Accpet Connection Request

  • Opcode为: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 Flag

SCO 数据分组

数据…………
连接句柄(12bit)PB(2bit)BC(2bit)数据长度(16bit)

(4)、RS232分组指示器:

HCI分组类型RS232分组指示器
HCI指令分组0x01
HCIACL数据分组0x02
HCISCO数据分组0x03
HCI事件分组0x04
HCI错误消息分组0x05
HCI协商分组0x06

#### 2、HCI控制命令

(1)、链路控制指令

命令OCF概述
Inquiry0x0001蓝牙设备进入查询模式,搜索临近设备
InquiryCancel0x0002退出查询模式
PeriodicInquiryMode0x0003蓝牙设备在指定周期内自动查询
ExitPeriodicInquiryMode0x0004退出自动查询模式
CreateConnection0x0005按指定蓝牙设备的BD_ADDR创建ACL链路
Disconnect0x0006终止现有连接
AddSCOConnection0x0007利用连接句柄参数指定的ACL连接创建SCO
CancelCreateConnection0x0008
AcceptConnectionRequest0x0009接收新的呼入连接请求
RejectConnectionRequest0x000A拒绝新的呼入连接请求
LinkKeyRequestReply0x000B应答从主机控制器发出的链路密钥请求事件,并指定存储在主机上的链路密钥做为与BD_ADDR指定的蓝牙设备进行连接使用的链路密钥请求事件
LinkKeyRequestNegativeReply0x000C如果主机上没有存储链路密钥,作为与BD_ADDR指定的蓝牙设备进行连接使用的链路密钥,就应答从主机控制器发出的链路密钥请求事件
PINCodeRequestReply0x000D应答从主机控制器发出的PIN请求事件,并指定用于连接的PIN
PINCodeRequestNegativeReply0x000E当主机不能指定连接的PIN时,应回答从机控制器发出的PIN请求事件
ChangeConnectionPacketType0x000F改变正在建立连接的分组类型
AuthenticationRequest0x0011指定连接句柄关联的两个蓝牙设备之间建立身份鉴权
SetConnectionEncryption0x0013建立取消连接加密
ChangeConnectionLinkKey0x0015强制关联了连接句柄的两个设备建立连接,并生成一个新的链路密钥
MasterLinkKey0x0017强制关联了连接句柄的两个设备利用主设备时链路密钥或常规密钥
RemoteNameRequest0x0019获取远端设备的名称
CancelRemoteNameRequest
ReadRemoteSupportedFeatures0x001B请求远端设备所支持的特性列表
ReadRemoteExtendedFeatures
ReadRemoteVersionInformation0x001D从远端设备读取版本信息
ReadClockOffset0x001F读取远端的时钟信息

(2)、链路策略指令

命令OCF简介
HoldMode0x0001改变LM状态和本地及远程设备为主模式的LM位置
SniffMode0x0003改变LM状态和本地及远程设备为呼吸模式的LM位置
ExitSniffMode0x0004结束连接句柄在当前呼吸模式里的呼吸模式
ParkState0x0005改变LM状态和本地及远程设备为休眠模式的LM位置
ExitParkState0x0006切换从休眠模式返回到激活模式的蓝牙设备
QoSSetup0x0007指出连接句柄的服务质量参数
RoleDiscovery0x0009蓝牙设备连接后确定自己的主从角色
SwitchRole0x000B角色互换
ReadLinkPolicySettings0x000C为指定连接句柄读链路策略设置。链路策略设置允许主机控制器指定用于连接句柄的LM连接模式
WriteLinkPolicySettings0x000D为指定连接句柄写链路策略设置。链路策略设置允许主机控制器指定用于连接句柄的LM连接模式
ReadDefaultLinkPolicySettings0x000E
WriteDefaultLinkPolicySettings0x000F
FlowSpecification0X0010

(3)、主机控制器与基带指令

SetEventMark0x0001使能主机过滤HCI产生的事件
Reset0x0003复位蓝牙控制器、链路管理器、基带链路管理器
SetEventFilter0x0005使能主机指定不同事件过滤
Flush0x0008针对指定的蓝牙句柄,放弃所有作为当前待传输数据,甚至当前是属于多个在主机控制器里的L2CAP指令的数据块
ReadPINType0x0009主机读取指定主机的PIN类型是可变的还是固定的
WritePINType0x000A主机写入指定主机的PIN类型是可变的还是固定的
CreateNewUnitKey0x000B创建新的单一密钥
ReadStoredLinkKey0x000D读取存放在蓝牙控制器中的单个或者多个密钥
WriteStoredLinkKey0x0011写入存放在蓝牙控制器中的单个或者多个密钥
DeleteStoredLinkKey0x0012删除存放在蓝牙控制器中的单个或者多个密钥
WriteLocalName0x0013修改蓝牙设备名称
ReadLocalName0x0014读取蓝牙设备名称
ReadConnectionAcceptTimeout0x0015读连接识别超时参数值,定时器终止后蓝牙硬件自动拒绝连接
WriteConnectionAcceptTimeout0x0016写连接识别超时参数值,定时器终止后蓝牙硬件自动拒绝连接
ReadPageTimeout0x0017读寻呼超时参数值,本地设备返回连接失败前,该值是允许蓝牙硬件定义等待远程设备连接申请时间
WritePageTimeout0x0018写寻呼超时参数值,本地设备返回连接失败前,该值是允许蓝牙硬件定义等待远程设备连接申请时间
ReadScanEnable0x0019写出扫描允许参数值—用来控制蓝牙设备周期性查询
WriteScanEnable0x001A读出扫描允许参数值—用来控制蓝牙设备周期性查询
ReadPageScanActivity0x001B读寻呼扫描间隔、寻呼扫描区间参数
WritePageScanActivity0x001C写寻呼扫描间隔、寻呼扫描区间参数
ReadInquiryScanActivity0x001D读查询扫描间隔、查询扫描区间参数
WriteInquiryScanActivity0x001E写查询扫描间隔、查询扫描区间参数
ReadAuthenticationEnable0x001F读取鉴权允许参数—控制蓝牙设备是否对每个连接进行鉴权
WriteAuthenticationEnable0x0020写取鉴权允许参数—控制蓝牙设备是否对每个连接进行鉴权
ReadEncryptionMode0x0021读加密模式数值—控制蓝牙设备是否对每个连接进行加密
WriteEncryptionMode0x0022写加密模式数值—控制蓝牙设备是否对每个连接进行加密
ReadClassOfDevice0x0023读取设备类型参数值,用于区别设备能力
WriteClassOfDevice0x0024写设备类型参数值,用于区别设备能力
ReadVoiceSetting0x0025读取语音设置参数值,控制语音连接的各种设置
WriteVoiceSetting0x0026写语音设置参数值,控制语音连接的各种设置
ReadAutomaticFlushTimeout0x0027对指定句柄,读取刷新超时值
WriteAutomaticFlushTimeout0x0028对指定句柄,写入刷新超时值
ReadNumBroadcastRetransmissions0x0029读取设备的广播重复发送次数,重复发送提高广播消息的可靠性
WriteNumBroadcastRetransmissions0x002A写入设备的广播重复发送次数,重复发送提高广播消息的可靠性
ReadHoldModeActivity0x002B读取HoldModeActivity的参数值,用来确定Hold挂起的时间
WriteHoldModeActivity0x002C写入HoldModeActivity的参数值,用来确定Hold挂起的时间
ReadTransmitPowerLevel0x002D对指定句柄,读取传输功率的参数值
ReadSynchronousFlowControlEnable0x002E读取SCO流量控制设置。通过使用该设置,主机控制器决定是否主机控制器发送与SCO连接句柄相关的完成分组事件的数量
WriteSynchronousFlowControlEnable0x002F读写入SCO流量控制设置。通过使用该设置,主机控制器决定是否主机控制器发送与SCO连接句柄相关的完成分组事件的数量
SetHostControllerToHostFlowControl0x0031主机控制器的打开、关闭,主机控制器到主机的流量控制
HostBufferSize0x0033主机通知主机控制器自己的ACL、SCO数据缓冲区大小。主机控制器分段传输数据,而数据不会超出这个范围
HostNumberOfCompletedPackets0x0035当主机对于任何连接的句柄准备接受较多的HCI指令时,该指令用于通过主机指出主机控制器
ReadLinkSupervisionTimeout0x0036读取连接管理超时参数。主从蓝牙设备用该参数监视链路丢失情况
WriteLinkSupervisionTimeout0x0037写入连接管理超时参数。主从蓝牙设备用该参数监视链路丢失情况
ReadNumberofSupportedIAC0x0038读取查询扫描期间本地蓝牙扫描的查询识别码(ICA)的数值
ReadCurrentIACLAP0x0039读取创建在查询扫描期间本地蓝牙设备正同时扫描的蓝牙识别码的LAP
WriteCurrentIACLAP0x003A写入创建在查询扫描期间本地蓝牙设备正同时扫描的蓝牙识别码的LAP
ReadPageScanPeriodMode0x003B读取本地蓝牙设备的强制寻呼扫描区间模式
WritePageScanPeriodMode0x003C写入本地蓝牙设备的强制寻呼扫描区间模式
ReadPageScanMode0x003D读取本地蓝牙设备的默认寻呼扫描区间模式
WritePageScanMode0x003E写入本地蓝牙设备的默认寻呼扫描区间模式

(4)、信息指令参数

ReadLocalVersionInformation0x0001读取本地蓝牙版本信息
ReadLocalSupportedFeatures0x0003读取本地蓝牙设备特征表
ReadLocalExtendedFeatures0x0004
ReadBufferSize0x0005返回HCI缓冲容量。缓冲容量用于传输缓冲数据
ReadCountryCode[Deprecated]0x0007读取国家代码状态参数值
ReadBDADDR0x0009读取BD_ADDR的参数值

(5)、状态指令参数
ReadFailedContactCount0x0001读取对于其他设备特殊连接的FailedContactCount参数值。FailedContactCount记录在刷新时终止及当前正在传输的L2CAP数据指令被自动刷新后,主单元或从单元不能连续响应事件次数
ResetFailedContactCount0x0002复位时对于其他设备的连接的FailedContactCount的参数值。FailedContactCount记录在刷新时终止及当前正在传输的L2CAP数据指令被自动刷新后,主单元或从单元不能连续响应事件次数
GetLinkQuality0x0003读取指定连接句柄的LinkQuality的值
ReadRSSI0x0005读取对于其他蓝牙设备连接句柄的接收信号强度指示
ReadAFHChannelMap0x0007
ReadBDClock0x0009

(6)、测试指令
ReadLoopbackMode0x0001读取主机端控制器会送模式的设置值。回送模式设置可以确定信息发送路径
WriteLoopbackMode0x0002写入主机控制器会送模式的设置值。回送模式设置可以确定信息发送路径
EnableDeviceUnderTestMode0x0003允许本地蓝牙设备模块通过LMP测试指令接入测试模式。当主机要求本地设备作为待测试设备,实现蓝牙测试模式文件中规定测试场景,则发送该指令

(7)、错误代码

错误代码错误含义错误代码错误含义
0x01位置HCI指令0x14由于另一端引起连接中断:资源限制
0x02不能连接0x15由于另一端引起连接中断:关机
0x03硬件故障0x16本机中断连接
0x04寻呼超时0x17重复尝试
0x05身份验证失败0x18不允许匹配
0x06键丢失0x19未知LMPPDU
0x07存储器已满0x1A不支持远端特性
0x08连接超时0x1B拒绝SCO补偿
0x09最大连接数0x1C拒绝SCO间歇模式
0x0A连接到设备A的最大SCO连接数0x1D拒绝SCO无线模式
0x0BACL连接已存在0x1E非法链路管理参数
0x0C指令非法0x1F未特别指明错误
0x0D由于资源有限,主机被拒绝0x20不支持链路管理器协议参数
0x0E由于安全原因,主机被拒绝0x21不允许角色改变
0x0F由于远端设备单连接设备,主机拒绝0x22链路管理响应超时
0x10主机超时0x23链路管理错误处理事务冲突
0x11不支持特性或参数值0x24不允许LMPPDU
0x12非法主机控制接口指令0x25~0xFF保留
0x13由于另一端引起连接中断:用户中断连接

二、逻辑链路控制与适配协议 L2CAP

L2CAP位于基带之上,将基带的数据分组转换为便于高层应用的数据分组格式,并提供协议复用和服务质量交换等功能。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
信令指令分组:

L2CAP分组头部分
长度(2byte)CID(0x0001)指令1指令2……………指令n

信令指令格式:

信令指令头
代码(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信令指令码:

CodeDescription
0x00RESERVED保留
0x01Commandreject拒绝命令
0x02Connectionrequest连接请求
0x03Connectionresponse连接响应
0x04Configurerequest配置请求
0x05Configureresponse配置响应
0x06Disconnectionrequest断开请求
0x07Disconnectionresponse断开响应
0x08Echorequest
0x09Echoresponse
0x0AInformationrequest信息请求
0x0BInformationresponse信息响应

1)、连接请求Connection_Request Code=0x02

代码(0x02)标识符(1字节)长度(2字节)PSM(2字节)源CID(2字节)

例如:SDP 连接请求

这里写图片描述

如上红框所示:
代码(0x02)标识符(1字节)长度(2字节)PSM(2字节)源CID(2字节)
0x0234SDP0x0040
2)、连接相应Connection_ResponseCode=0x03
代码(0x03)标识符长度目标CID源CID结果状态

例如:SDP请求响应
这里写图片描述
如上面红框所示:
代码(0x03)标识符长度目标CID源CID结果状态
0x03380x00400x00400x0000

(2)、MTU MAXIMUMTRANSMISSION UNIT最大传输单元

MTU最大传输单元,L2CAP应用必须支持最小为48字节的MTU,默认值为672
(3)、QoS 服务质量

三、服务发现协议SDP

SDP两种服务发现模式:
1)、服务搜索:查询具有特定服务属性的服务;
2)、服务浏览:简单的浏览全部可用服务。

1 、PDU 格式:(协议数据单元)

Header
PDUID(1byte)TransactionID(2byte)参数长度(2byte)参数1……参数N

不同PDU ID实现SDP的不同功能,概述如下表格:

ValueParameterDescirption
0x00Reserved保留
0x01SDP_ErrorResponse错误响应
0x02SDP_ServiceSearchRequest服务搜索请求
0x03SDP_ServiceSearchResponse服务搜索响应
0x04SDP_ServiceAttributeRequest服务属性请求
0x05SDP_ServiceAttributeResponse服务属性响应
0x06SDP_ServiceSearchAttributeRequest服务搜索属性请求
0x07SDP_ServiceSearchAttributeResponse服务搜索属性响应
0x08-0xffReserved保留

2、服务记录表

SDP的服务记录表对每一个服务进行描述,每条记录包含服务句柄、一组服务属性:
这里写图片描述

  • Service Record Attributes:服务记录;
  • Service Record Handle 服务句柄;

这里写图片描述

四、串口仿真协议 RFCOMM

为建立在串口之上的传统应用提供环境接口,使他们可以做比较少协议改动就可以在蓝牙无线通信无线链路上工作。多路串口仿真是RFCOMM的重要功能,通过多路复用器(multiplexer),一条L2CAP链路可以同时 多个串行应用。
两台设备间的串口仿真:
这里写图片描述

RFCOMM 两个蓝牙设备之间可以支持多达60多路仿真串口。

RFCOMM帧类型如下:

SABM异步平衡模式设置指令
UA未加编号的确认响应
DM断开连接模式响应
DISC断开连接指令
UIH带头校验的未编号信息命令和响应

这里写图片描述
传送门:
(一)蓝牙的概述
(二)蓝牙协议规范(射频、基带链路控制、链路管理)
(三)蓝牙协议规范(HCI、L2CAP、SDP、RFOCMM)
(四)蓝牙协议规范(irOBEX、BNEP、AVDTP、AVCTP)

引用自xubin的博客

By Xiaolong,每一天都值得被认真对待!