2011年7月18日

【转】蓝牙协议中HCI层的研究与开发

蓝牙协议中HCI层的研究与开发


刘向阳,沈连丰

(东南大学移动通信国家重点实验室, 南京 210096)

一、HCI在蓝牙软件协议模型位置的分析

蓝牙系统的协议模型如图1所示。从图中可以看出,HCI是位于蓝牙系统的L2CAP(逻辑链路控制与适配协议)层和LMP(链路管理协议)层之间的一层协议。HCI为上层协议提供了进入LM的统一接口和进入基带的统一方式。在HCI的主机(Host)和HCI主机控制器(Host Controller)之间会存在若干传输层,这些传输层是透明的,只需完成传输数据的任务,不必清楚数据的具体格式。目前,蓝牙的SIG规定了四种与硬件连接的物理总线方式:USB、RS232、UART和PC卡。其中通过RS232串口线方式进行连接具有差错校验。

 

HCI层的底层层协议如图2所示。由图可看出,HCI层屏蔽了基带,为协议层的上层提供了进入基带的统一方式。

二、HCI与基带通信方式的研究与分析

蓝牙系统的底层协议通信如图3所示。下面结合图3对蓝牙系统中HCI层与基带间的通信作一些分析研究。

1.通信方式的分析

HCI是通过包的方式来传送数据、命令和事件的,所有在主机和主机控制器之间的通信都以包的形式进行。包括每个命令的返回参数都通过特定的事件包来传输。HCI有数据、命令和事件三种包,其中数据包是双向的,命令包只能从主机发往主机控制器,而事件包始终是主机控制器发向主机的。主机发出的大多数命令包都会触发主机控制器产生相应的事件包作为响应。
命令包分为六种类型:


* 链路控制命令;
* 链路政策和模式命令;
* 主机控制和基带命令;
* 信息命令;
* 状态命令;
* 测试命令。

事件包也可分为三种类型:
* 通用事件,包括命令完成包(Command Complete)和命令状态包(Command Status);
* 测试事件;
* 出错时发生的事件,如产生丢失(Flush Occured)和数据缓冲区溢出(Data Buffer Overflow)。
数据包则可分为ACL和SCO的数据包。包的格式如图4所示。

2.包的参数分析研究
命令包:命令包中的OCF(Opcode Command Field)和OGF(Opcode Group Field)是用于区分命令种的。Parameter Length表示所带参数的长度,以字节数为单位,随后就是所带的参数列表。下面以Inquiry命令为例对HCI的命令包做具体说明。

在Inquiry命令中,OGF=0x01表示此命令属于链路控制命令,同时OCF=0x0001则表示此命令为链路控制命令中的Inquiry命令。OCF与OGF共占2字节,又由于底位字节在前,则它们在命令包为0x0104。在Inquiry 命令中,参数Parameter Length为5。Inquiry命令带3个参数,第一个参数为LAP(low address part), 它将用来产生Baseband中查询命令包的包头中的Access Code。第二个参数为Inquiry_Length,它时表示在Inquiry命令停止前所定义的最大时间,超过此时间,Inquiry命令将终止。第三个参数为NUM_Response,它的值为0X00表示设备响应数不受限制,只为0x00-0xff则表示在Inquiry命令终止前最大的设备响应数。因此,若LAP=0x9e8b00,Inquiry_Length=0x05,NUM_Response=0x05,则协议上层调用Inquiry命令是HCI向基带发的明令包将为:0x01 04 05 00 8b 9e 05 05。

事件包:事件包的Event Code用来区分不同的事件包,Parameter Length表示所带参数的长度,以字节数为单位,随后就是所带的参数列表。以Command Status Event事件包为例对HCI的事件包进行具体说明。

当主机控制器收到主机发来的如上面所提到的Inquiry命令包并开始处理时,它就会向主机发送Command Status Event事件包,此事件包为:0x0f 04 00 0a 01 04。0xOf表示此事件包为Command Status Event事件包,0x04表示此事件包带4字节长度的参数,0x00为此事件包的第一个参数即Status,表示命令包正在处理。0x0a为事件包的第二个参数NUM_HCI_Command_Packets,表示主机最多可在向主机控制器发10个命令包。0x01 04 为第三个参数Command_Opcode, 表示此事件包是对Inquiry命令包的响应。

数据包:ACL和SCO数据包中的Connection Handle即连接句柄是一个12比特的标志符,用于唯一确认两台蓝牙设备间的数据或语音连接,可以看作是两台蓝牙设备间唯一的数据通道的标识。两台设备间只能有一条ACL连接,也就是只有一个ACL的连接句柄,相应L2CAP的信道都是建立在这个连接句柄表示的数据通道上;两台设备间可以有多个SCO的连接,则一对设备间会有多个SCO的连接句柄。连接句柄在两设备连接期间一直存在,不管设备处于什么状态。在ACL数据包中,Flags分为PB Flag和BC Flag,PB Flag为包的界限标志,PB Flag=0x00表示此数据包为上层协议包(如L2CAP包)的起始部分;PB Flag=0x01表示此数据包为上层协议包(如L2CAP包)的后续部分。BC Flag为广播发送的标志,BC Flag=0x00表示无广播发送,只是点对点的发送;BC Flag=0x01表示对所有处于激活状态的从设备进行广播发送,BC Flag=0x02表示对所有的从设备包括处于休眠状态的从设备进行广播发送。ACL和SCO数据包中的Data Total Length 都表示所载荷的数据的长度,以字节位单位。

3.通信过程的研究与分析

当主机与基带之间用命令的方式进行通信时,主机向主机控制器发送命令包。主机控制器完成一个命令,大多数情况下,它会向主机发出一个命令完成事件包(Command Complete Packet),包中携带命令完成的信息。有些命令不会收到命令完成事件,而会收到命令状态事件包(Command Status Packet),当收到该事件则表示主机发出的命令已经被主机控制器接收并开始处理,过一段时间该命令被执行完毕时,主机控制器会向主机发出相应的事件包来通知主机。如果命令参数有误,则会在命令状态事件中给出相应错误码。假如错误出现在一个返回Command Complete事件包的命令中,则此Command Complete事件包不一定含有此命令所定义的所有参数。状态参数作为解释错误原因同时也是第一个返回的参数,总是要返回的。假如紧随状态参数之后是连接句柄或蓝牙的设备地址,则此参数也总是要返回,这样可判别出此Command Complete事件包属于那个实例的一个命令。在这种情况下,事件包中连接句柄或蓝牙的设备地址应与命令包种的相应参数一致。假如错误出现在一个不返回Command Complete事件包的命令中,则事件包包含的所有参数都不一定是有效的。主机必须根据于此命令相联系的事件包中的状态参数来决定它们的有效性。

4.HCI流量控制(Flow Control)的分析研究

HCI的流量控制是为了管理主机和主机控制器中有限的资源并控制数据流量而设计的,由主机管理主机控制器的数据缓存区,主机可动态地调整每个连接句柄的流量。
对于命令包的流量控制,主机在每发一个命令之前都要确定当前能发命令包的数目,当然,在开机和重启动时发命令包可以不用考虑接收情况,直到收到命令完成事件包或命令状态事件包为止。因为在每个命令完成事件包和命令状态事件包中都有Num_HCI_Command_ Packets选项表明当时主机能向主机控制器发送的命令包的数目,而对于每个命令必然会有相应的命令完成事件包和命令状态事件包,主机就能控制命令包不会溢出。

对于数据包的流量控制,一开始,主机调用Read_Buffer_Size命令,该命令返回的两个参数决定了主机能发往主机控制器的ACL和SCO两种数据包的大小的最大值,同时两个附加参数则说明了主机控制器能接收的ACL和SCO数据包总的数目。而每隔一段时间,主机控制器会向主机发Number_Of_Complete_Packets事件,该事件的参数值表明了对每个连接句柄已经处理的数据包的数目(包括正确传输和被丢弃的)。主机根据一开始就知道的总数,减去已经处理的包的数目,则可计算出还能发多少数据包,从而控制数据包的流量。

如有必要,HCI的流量控制也可由主机控制器来实现对主机的控制,可以通过Set_Host_ Controller_To_Host_Flow_Control命令来设置,其控制过程基本与主机控制过程类似,只是命令稍有不同。当主机收到断链确认的事件后,就认为所有传往主机控制器的数据包已经全部被丢弃了,同时主机控制器中的数据缓冲区也被释放了。

三、HCI协议层软件开发

我们在对HCI层进行全面的分析研究之后,提出了HCI协议层软件开发的方案,定出了HCI层提供给协议上层的接口。这些接口给蓝牙协议栈的上层提供了进入BaseBand的统一入口。整个接口按协议站的要求分为八大部分。下面介绍每部分的接口。整个软件层采用传递消息加函数调用相结合的机制来实现,即上层对HCI层接口的调用采用函数调用的机制,HCI对上层的通信采用传递消息的方式。

1.接口分类及举例说明

(1)开始命令

此命令接口是主机向HCI注册及并启动HCI。
如启动HCI的函数接口为HCI_ReqStart(),HCI在启动后发向上层的消息接口为HCI_START_CNF()。命令执行过程如图5所示。

(2)链路控制命令

链路控制命令是允许主机控制器控制与其他蓝牙设备的连接。在链路控制命令运行时, LM 控制蓝牙微微网与分布网的建立与维持。这些命令指示LM创建及修改与远端蓝牙设备的连接链路,查询范围内的其他蓝牙设备,及其他链路管理协议命令。

以查找并发现周围设备为例,HCI层为上层提供了函数接口HCI_ReqInquiry,消息接口为HCI_INQUIRY_RESULT_EVT和HCI_INQUIRY_CNF。命令执行过程如图6所示。

主机首先调用HCI的HCI_ReqInquiry函数开始查询过程,在此过程中,如有蓝牙响应此查询,则会产生一HCI_INQUIRY_RESULT_EVT事件通知主机。在此次查询过程结束时,会产生HCI_INQUIRY_CNF这条消息通知主机,参数NrofResponse表示在此次查询过程所响应的蓝牙设备数。 

(3)链路政策命令

链路政策命令提供了一种影响LM怎样管理微微网的方法。当链路政策命令运行时,LM仍然以可调整的参数控制微微网及分布网的建立和维持。这些链路政策命令调整LM的行为,从尔导致与远端蓝牙设备的链路层连接的改变。

已建立服务质量为例,HCI层为上层提供了函数接口HCI_ReqQoSSetup,消息接口为HCI_QOS_SETUP_EVT和HCI_QOS_SETUP_CNF,HCI_QOS_SETUP_CNF_NEG。命令执行过程如图7所示。

主机首先调用HCI_ReqQosSetup请求建立Qos。当Qos建立成HCI_QOS_SETUP_CNF 消息被送往发起端,同时一个事件消息送往远端设备。当Qos建立失败时,HCI_QOS_SETUP_CNF_NEG被送往发起端。

(4)主机控制器及基带命令

主机控制器及基带命令被用来改变与建立诸如声音设置,认证模式,加密模式的连接相联系的LM的操作方式。

已读取主机控制器所存储的Link Key为例,HCI层为上层提供了函数接口HCI_ReqReadLinkKey,消息接口为HCI_READ_LINK_KEY_RRESULT_EVT和HCI_READ_LINK_KEY_ CNF。命令执行过程如图8所示。

(5)信息命令

这些信息命令的参数是由蓝牙硬件制造商确定的。它们提供了关于蓝牙设备及设备的主机控制器,链路管理器及基带的信息。主机设备不能更改这些参数。

HCI层为上层提供了函数接口为:
HCI_ReqCountryCode HCI_ReqLocalAddress
HCI_ReqReadLocalFeatures HCI_ReqReadLocalVersion
HCI_ReqReadBD_ADDR
HCI层提供的消息接口为: 
HCI_COUNTRY_CODE_CNF HCI_COUNTRY_CODE_CNF_NEG
HCI_LOCAL_ADDRESS_CNF HCI_LOCAL_ADDRESS_CNF_NEG
HCI_READ_LOCAL_FEATURES_CNF HCI_READ_LOCAL_FEATURES_CNF_NEG
HCI_READ_LOCAL_VERSION_CNF HCI_READ_LOCAL_VERSION_CNF_NEG
HCI_READ_BD_ADDR_CNF HCI_READ_BD_ADDR_CNF_NEG

(6)状态命令

状态命令提供了目前HCI,LM,及BB的状态消息。这些状态参数不能被主机改变,除了一些参数可以被重置。

HCI层为上层提供了函数接口为:
HCI_ReqGetLinkQuality HCI_ReqReadFailedCounter
HCI_ReqResetFailedCounter HCI_ReqRssi
HCI层提供的消息接口为:
HCI_GET_LINK_QUALITY_CNF HCI_GET_LINK_QUALITY_CNF_NEG HCI_READ_FAILED_COUNTER_CNF HCI_READ_FAILED_COUNTER_CNF_NEG
HCI_RESET_FAILED_COUNTER_CNF HCI_RESET_FAILED_COUNTER_CNF_NEG
HCI_RSSI_CNF HCI_RSSI_CNF_NEG

(7)测试命令

测试命令能够测试蓝牙硬件各种功能,并蔚蓝牙设备的测试提供不同的测试条件。

HCI层为上层提供了函数接口为:
HCI_ReqEnableDutMode HCI_ReqReadLoopbackMode
HCI_ReqWriteLoopbackMode
HCI层提供的消息接口为:
HCI_ENABLE_DUT_MODE_CNF HCI_ENABLE_DUT_MODE_CNF_NEG
HCI_READ_LOOPBACK_MODE_CNF HCI_READ_LOOPBACK_MODE_CNF_NEG
HCI_WRITE_LOOPBACK_MODE_CNF HCI_WRITE_LOOPBACK_MODE_CNF_NEG

(8)数据传输命令:

这些命令为蓝牙设备之间传输数据提供了所需要的接口。如分配所需内存的接口HCI_DataAlloc,传输数据的接口HCI_DataSend,提取数据的接口HCI_DataExtract。图9说明了在蓝牙系统中传输数据时对这些接口的使用。

四、结论

HCI为为蓝牙协议层的上层提供了进入基带的统一接口。经过测试,所开发的接口能将上层的数据流匹配到基带,使基带能对之进行处理,并产生相应的事件。

posted @ 2011-07-18 17:16 SeanLin 阅读(328) 评论(0) 编辑

【转】蓝牙协议的命令和事件

蓝牙协议的命令和事件
(廖铮 2001年06月18日 16:21)

命令

下表列出蓝牙协议中从L2CAP到物理层的命令和事件映射。希望这个列表可以帮助你分析蓝牙协议中从协议高层发给较低层次的控制命令和消息命令。我们还会通过讲解一个示例来具体地说明协议高层收到连接请求时的情况。

L2CAP

HCI

LMP/BASEBAND

连接和不连接

L2CAP_ConnectReq
L2CAP_ConnectRsp
L2CAP_ConnectRspPnd
L2CAP_ConnectRspNeg
LP_ConnectReq
LP_ConnectRsp
LP_ConnectRspNeg
LP_ConnectCfm
LP_ConnectCfmNeg
LP_ConnectInd
L2CA_ConnectInd
L2CA_ConnectCfm
L2CA_ConnectCfmNeg
L2CA_ConnectPnd
L2CA_ConnectReq
L2CA_ConnectRsp
L2CA_ConnectRspNeg

HCI_Create_Connection
HCI_Accept_Connection_Request
HCI_Reject_Connection_Request
HCI_Add_SCO_Connection
HCI_Read_Connection_Accept_Timeout
HCI_Write_Connection_Accept_Timeout

LMP_host_connection_req
LMP_setup_complete
LMP_SCO_link_req

L2CAP_DisconnectReq
L2CAP_DisconnectRsp
LP_DisconnectInd
L2CA_DisconnectReq
L2CA_DisconnectRsp
L2CA_DisconnectInd
L2CA_DisconnectCfm

HCI_Disconnect

LMP_detach
LMP_remove_SCO_link_req

安全

L2CAP层不安全

HCI_Authentication_Requested
HCI_Set_Connection_Encryption
HCI_Change_Connection_Link_Key
HCI_Master_Link_Key
HCI_PIN_Code_Request_Reply
HCI_PIN_Code_Request_Negative_Reply
HCI_Link_Key_Request_Reply
HCI_Link_Key_Request_Negative_Reply
HCI_Read_Pin_Type
HCI_Write_Pin_Type
HCI_Create_New_Unit_Key
HCI_Read_Stored_Link_Key
HCI_Write_Stored_Link_Key
HCI_Delete_Stored_Link_Key
HCI_Read_Authentication_Enable
HCI_Write_Authentication_Enable
HCI_Read_Encryption_Mode
HCI_Write_Encryption_Mode

LMP_au_rand
LMP_in_rand
LMP_temp_rand
LMP_temp_key
LMP_comb_key
LMP_unit_key
LMP_sres
LMP_start_encryption_req
LMP_stop_encryption_req
LMP_encryption_mode_req
LMP_encryption_key_size_req
LMP_use_semi_permanent_key

模式处理

L2CAP层不进行模式处理

HCI_Hold_Mode
HCI_Sniff_Mode
HCI_Exit_Sniff_Mode
HCI_Park_Mode
HCI_Exit_Park_Mode
HCI_Read_Hold_Mode_Activity
HCI_Write_Hold_Mode_Activity

LMP_hold
LMP_hold_req
LMP_sniff
LMP_sniff_req
LMP_unsniff_req
LMP_park_req
LMP_park
LMP_set_broadcast_scan_window
LMP_modify_beacon
LMP_unpark_PM_ADDR_req
LMP_unpark_BD_ADDR_req

连接子状态

L2CAP不进行连接子状态处理

HCI_Inquiry
HCI_Inquiry_Cancel
HCI_Periodic_Inquiry_Mode
HCI_Exit_Periodic_Inquiry_Mode
HCI_Read_Page_Timeout
HCI_Write_Page_Timeout
HCI_Read_Scan_Enable
HCI_Write_Scan_Enable
HCI_Read_Page_Scan_Activity
HCI_Write_Page_Scan_Activity
HCI_Read_Inquiry_Scan_Activity
HCI_Write_Inquiry_Scan_Activity
HCI_Read_Page_Scan_Mode
HCI_Write_Page_Scan_Mode
HCI_Read_Page_Scan_Period_Mode
HCI_Write_Page_Scan_Period_Mode
HCI_Read_Num_Broadcast_Retransmissions
HCI_Write_Num_Broadcast_Retransmissions

LMP_page_mode_req
LMP_page_scan_mode_req

QoS和流控

LP_QoSReq
LP_QoSCfm
LP_QoSCfmNeg
LP_QoSViolationInd
L2CA_QoSViolationInd

HCI_QoS_Setup
HCI_Read_SCO_Flow_Control_Enable
HCI_Write_SCO_Flow_Control_Enable
HCI_Set_Host_Controller_To_Host_Flow_Control
HCI_Get_Link_Quality

LMP_quality_of_service
LMP_quality_of_service_req
LMP_auto_rate
LMP_preferred_rate

其他

L2CAP_Data
L2CAP_ConfigReq
L2CAP_ConfigRsp
L2CAP_ConfigRspNeg
L2CA_ConfigReq
L2CA_ConfigRsp
L2CA_ConfigRspNeg
L2CA_ConfigInd
L2CA_ConfigCfm
L2CA_ConfigCfmNeg
L2CA_TimeOutInd
L2CA_DataRead
L2CA_DataWrite

HCI_Change_Connection_Packet_Type
HCI_Remote_Name_Requested
HCI_Read_Remote_Supported_Features
HCI_Read_Remote_Version_Information
HCI_Read_Local_Version_Information
HCI_Local_Supported_Features
HCI_Read_Clock_Offset
HCI_Role_Discovery
HCI_Switch_Role
HCI_Read_Link_Policy_Settings
HCI_Write_Link_Policy_Settings
HCI_Read_Buffer_Size
HCI_Host_Buffer_Size
HCI_Read_Country_Code
HCI_BD_ADDR
HCI_Read_Current_IAC_LAP
HCI_Write_Current_IAC_LAP
HCI_Read_Number_Of_Supported_IAC
HCI_Read_Class_Of_Device
HCI_Write_Class_Of_Device
HCI_Read_Voice_Setting
HCI_Write_Voice_Setting
HCI_Read_Automatic_Flush_Timeout
HCI_Write_Automatic_Flush_Timeout
HCI_Read_Supervision_Timeout
HCI_Read_Link_Supervision_Timeout
HCI_Write_Link_Supervision_Timeout
HCI_Read_Transmit_Power_Level
HCI_Change_Local_Name
HCI_Read_Local_Name
HCI_Set_Event_Mask
HCI_Set_Event_Filter
HCI_Flush
HCI_Reset
HCI_Host_Number_Of_Completed_Packets

LMP_name_req
LMP_name_res
LMP_accpted
LMP_not_accepted
LMP_switch_req
LMP_version_req
LMP_version_res
LMP_clkoffset_req
LMP_clkoffset_res
LMP_timing_accuracy_req
LMP_timing_accuracy_res
LMP_max_power
LMP_min_power
LMP_incr_power_req
LMP_decr_power_req
LMP_slot_offset
LMP_max_slot
LMP_max_slot_req
LMP_features_req
LMP_features_res

 事件

HCI事件

说明

Inquiry Complete Event

表示查询已经完成。

Inquiry Result Event

表示某台蓝牙设备或者多台蓝牙设备在当前查询过程中已经做出响应。

Connection Complete Event

向形成连接的主机双方指示新连接已经建立。

Connection Request Event

表示新入站连接正在建立过程中。

Disconnection Complete Event

在连接被终止后触发。

Authentication Complete Event

当指定连接的认证过程完成后触发。

Remote Name Request Complete Event

表示远端名称请求已经完成。

Encryption Change Event

表示连接句柄(Connection_Handle)的加密变更已经完成。

Change Connection Link Key Complete Event

表示连接句柄的链路密钥(Link Key)变更已经完成。

Master Link Key Complete Event

表示蓝牙主机方的临时或者半永久链路密钥的变更已经完成。

Read Remote Supported Features Complete Event

表示获得远端蓝牙设备所支持特性的链路管理器(Link Manager)过程已经完成。

Read Remote Version Information Complete Event

表示获得远端蓝牙设备版本信息的链路管理器(Link Manager)过程已经完成。

QoS Setup Complete Event

表示设置远端蓝牙设备QoS的链路管理器过程已经完成。

Command Complete Event

主机控制器(Host Controller)使用该事件传递命令的返回状态。

Command Status Event

表示命令已经收到,主机控制器目前正在执行该命令下达的任务。

Hardware Error Event

表示蓝牙设备的某种类型硬件出现故障。

Flush Occurred Event

表示对指定的连接句柄当前被传输的用户数据已经取消。

Role Change Event

表示和特定连接相关联的当前蓝牙设备的角色已经改变。

Number Of Completed Packets Event

主机控制器使用该事件向主机表示在前一个Number Of Completed Packets 之后到目前每个Connection Handle 所完成的HCI 数据分组数量。

Mode Change Event

表示关联连接句柄的设备在Active、Hold、Sniff和Park模式之间发生了变更。

Return Link Keys Event

用于返回存储的链路秘钥。

PIN Code Request Event

表示需要PIN码来为某个连接创建新链路秘钥。

Link Key Request Event

表示以和BD_ADDR指定的设备连接需要一个链路密钥。

Link Key Notification Event

向主机表示和BD_ADDR指定的设备连接所需要的新链路密钥已经创建。

Loopback Command Event

回送主机发送给主机控制器的大多数命令。

Data Buffer Overflow Event

表示主机控制器的数据缓冲已经溢出。

Max Slots Change Event

在LMP_Max_Slots参数改变的时候通知主机。

Read Clock Offset Complete Event

表示获得Clock Offset 信息的LM过程已经完成。

Connection Packet Type Changed Event

表示改变指定连接句柄数据包类型的LM过程已经完成。

QoS Violation Event

表示LM不能为当前的连接句柄提供所需的QoS。

Page Scan Mode Change Event

表示已经连接的、具有指定连接句柄的远端蓝牙设备已经成功改变其寻呼扫描模式(Page_Scan_Mode)。

Page Scan Repetition Mode Change Event

表示已经连接的、具有指定连接句柄的远端蓝牙设备已经成功地改变Page_Scan_Repetition_Mode(SR)。

posted @ 2011-07-18 17:04 SeanLin 阅读(359) 评论(0) 编辑