本文主要是介绍蓝牙核心规范中HCI层的研究与开发分析□ 张 熠 姜玉泉 《电脑知识与技术》 2007年第09期,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
摘要:通过对蓝牙核心规范1.2的主机控制接口的研究,分析蓝牙基带层和主机侧的通讯机制以及通讯方法。并举例说明了一些蓝牙基本命令和事件,解释了相关接口,在此基础上能够方便的进行蓝牙HCI层的开发。
关键词:蓝牙;HCI;基带;流量控制
中图分类号:TP399 文献标识码:A文章编号:1009-3044(2007)06-11671-04
1 引言
蓝牙是无线数据和语音传输的开放式标准。蓝牙采用跳频技术,工作在2.4GHz的ISM频段,在采用不对称的信道时单向最高传输速率可达 723.2kb/s,可以同时支持数据与语音通讯。蓝牙支持点到点和点到多点的连接,可采用无线方式将若干蓝牙设备连成一个微微网(Piconet),多 个微微网又可互连成分散网(Scatternet),形成灵活的多重微微网的拓扑结构,从而实现各类设备之间的快速通讯。
2 HCI在蓝牙软件协议模型位置的分析
蓝牙系统的协议模型如图1所示。从图中可以看出,HCI是位于蓝牙系统的L2CAP(逻辑链路控制与适配协议)层和LMP(链路管理协议)层 之间的一层协议。HCI为上层协议提供了进入LM的统一接口和进入基带的统一方式。在HCI的主机(Host)和HCI主机控制器(Host Controller)之间会存在若干传输层,这些传输层是透明的,只需完成传输数据的任务,不必清楚数据的具体格式。目前,蓝牙的SIG规定了四种与硬 件连接的物理总线方式:USB、RS232、UART和PC卡。其中通过RS232串口线方式进行连接具有差错校验。
图1 蓝牙系统的协议模型
HCI层的底层协议如图2所示。由图可看出,HCI层屏蔽了基带,为协议层的上层提供了进入基带的统一方式。 图2提供了较低的软件层的概观。HCI 固件为蓝牙硬件访问执行基带命令,链路管理器指令,硬件状态记录器,控制记录器和事件记录器而实现HCI 指令。
3 HCI与基带通信方式的研究与分析
图2 HCI层的底层协议
蓝牙系统的底层协议通信如图3所示。下面结合图3对蓝牙系统中HCI层与基带间的通信作一些分析研究。
图3 蓝牙系统的底层协议通信
图3指出了一个数据从一个设备到发送到另外的设备所经过的路径。在主机上的HCI驱动器通过 Bluetooth 硬件上的HCI 固件交换数据和命令。主机控制传输层(也就是物理总线)驱动器提供能力给两者的HCI层彼此交换信息。主机接受HCI事件的异步通讯,HCI事件是独立于 物理总线的。
3.1 通信方式的分析
HCI是通过包的方式来传送数据、命令和事件的,所有在主机和主机控制器之间的通信都以包的形式进行。包括每个命令的返回参数都通过特定的事 件包来传输。HCI有数据、命令和事件三种包,其中数据包是双向的,命令包只能从主机发往主机控制器,而事件包始终是主机控制器发向主机的。主机发出的大 多数命令包都会触发主机控制器产生相应的事件包作为响应。
命令包分为六种类型:
链路控制命令;
链路政策和模式命令;
主机控制和基带命令;
信息命令;
状态命令;
测试命令。
事件包也可分为三种类型:
通用事件,包括命令完成包(Command Complete)和命令状态包(Command Status);
测试事件;
出错时发生的事件,如产生丢失(Flush Occured)和数据缓冲区溢出(Data Buffer Overflow)。
数据包则可分为ACL和SCO的数据包。包的格式如图4所示。
图4 包的格式
3.2 包的参数分析研究
命令包:命令包中的OCF(Opcode Command Field)和OGF(Opcode Group Field)是用于区分命令种的。Parameter Length表示所带参数的长度,以字节数为单位,随后就是所带的参数列表。下面以Inquiry命令为例对HCI的命令包做具体说明。(注:OGF范围 是 0x00~0x3F,其中0x3E保留作为蓝牙logo测试用,0x3F保留作为厂家制定调试命令)
在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 都表示所载荷的数据的长度,以字节位单位。(注:只有在ACL链路起来后,才能建立SCO链路)
本文原文
3.3 通信过程的研究与分析
当主机与基带之间用命令的方式进行通信时,主机向主机控制器发送命令包。主机控制器完成一个命令,大多数情况下,它会向主机发出一个命令完成 事件包(Command Complete Packet),包中携带命令完成的信息。有些命令不会收到命令完成事件,而会收到命令状态事件包(Command Status Packet),当收到该事件则表示主机发出的命令已经被主机控制器接收并开始处理,过一段时间该命令被执行完毕时,主机控制器会向主机发出相应的事件包 来通知主机。如果命令参数有误,则会在命令状态事件中给出相应错误码。假如错误出现在一个返回Command Complete事件包的命令中,则此Command Complete事件包不一定含有此命令所定义的所有参数。状态参数作为解释错误原因同时也是第一个返回的参数,总是要返回的。假如紧随状态参数之后是连 接句柄或蓝牙的设备地址,则此参数也总是要返回,这样可判别出此Command Complete事件包属于那个实例的一个命令。在这种情况下,事件包中连接句柄或蓝牙的设备地址应与命令包种的相应参数一致。假如错误出现在一个不返回 Command Complete事件包的命令中,则事件包包含的所有参数都不一定是有效的。主机必须根据于此命令相联系的事件包中的状态参数来决定它们的有效性。
3.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命令来设置,其控制过程基本与主机控制过程类似,只是命令稍有不同。当主机收到断链确认 的事件后,就认为所有传往主机控制器的数据包已经全部被丢弃了,同时主机控制器中的数据缓冲区也被释放了。
4 HCI协议层软件开发
在对HCI层进行全面的分析研究之后,可以提出HCI协议层软件开发方案,定出HCI层提供给协议上层的接口。这些接口给蓝牙协议栈的上层提 供了进入BaseBand的统一入口。整个接口按协议栈的要求分为八大部分。下面分析每个部分的接口。整个软件层采用传递消息加函数调用相结合的机制来实 现,即上层对HCI层接口的调用采用函数调用的机制,HCI对上层的通信采用传递消息的方式。还是以例子的形式来说明这八部分的接口
4.1 开始命令
此命令接口是主机向HCI注册及并启动HCI。
如启动HCI的函数接口为HCI_ReqStart(),HCI在启动后发向上层的消息接口为HCI_START_CNF()。命令执行过程如图5所示。
图5 HCI启动及注册过程
4.2 链路控制命令
链路控制命令是允许主机控制器控制与其他蓝牙设备的连接。在链路控制命令运行时, LM 控制蓝牙微微网与分布网的建立与维持。这些命令指示LM创建及修改与远端蓝牙设备的连接链路,查询范围内的其他蓝牙设备,及其他链路管理协议命令。
以查找并发现周围设备为例,HCI层为上层提供了函数接口HCI_Inquiry,消息接口为HCI_INQUIRY_RESULT_EVT和HCI_INQUIRY_CNF。命令执行过程如图6所示。
图6 HCI查询过程
主机首先调用HCI的HCI_Inquiry函数开始查询过程,在此过程中,如有蓝牙响应此查询,则会产生一 HCI_INQUIRY_RESULT_EVT事件通知主机。在此次查询过程结束时,会产生HCI_INQUIRY_CNF这条消息通知主机,参数 NrofResponse表示在此次查询过程所响应的蓝牙设备数。
4.3 链路策略命令
链路政策命令提供了一种影响LM怎样管理微微网的方法。当链路政策命令运行时,LM仍然以可调整的参数控制微微网及分布网的建立和维持。这些链路政策命令调整LM的行为,从而导致与远端蓝牙设备的链路层连接的改变。
已建立服务质量为例,HCI层为上层提供了函数接口HCI_QoSSetup,消息接口为HCI_QOS_SETUP_EVT和HCI_QOS_SETUP_CNF,HCI_QOS_SETUP_CNF_NEG。命令执行过程如图7所示。
图7 HCI服务质量建立过程
主机首先调用HCI_QosSetup请求建立Qos。当Qos建立成HCI_QOS_SETUP_CNF 消息被送往发起端,同时一个事件消息送往远端设备。当Qos建立失败时,HCI_QOS_SETUP_CNF_NEG被送往发起端。
4.4 主机控制器及基带命令
主机控制器及基带命令被用来改变与建立诸如声音设置,认证模式,加密模式的连接相联系的LM的操作方式。
已读取主机控制器所存储的Link Key为例,HCI层为上层提供了函数接口HCI_ReadLinkKey,消息接口为HCI_READ_LINK_KEY_RRESULT_EVT和HCI_READ_LINK_KE
Y_ CNF。命令执行过程如图8所示。
图8 HCI读取Link Key
4.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
4.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
4.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
4.8 数据传输命令
这些命令为蓝牙设备之间传输数据提供了所需要的接口。如分配所需内存的接口HCI_DataAlloc,传输数据的接口HCI_DataSend,提取数据的接口HCI_DataExtract。图9说明了在蓝牙系统中传输数据时对这些接口的使用。
图9 HCI数据传输过程
由于HCI为蓝牙协议层的上层提供了进入基带的统一接口,可以开发上述的接口使上层的数据流匹配到基带,使基带能够对之进行处理,并产生相应的事件。
5 结束语
蓝牙产品的开发重在有特色的应用, 将蓝牙技术与现实生活中的各种终端产品相结合, 如条码扫描器、耳机、电话等, 从而使人们摆脱各种线缆的束缚。目前蓝牙的开发, 特别是与终端产品相结合的嵌入式开发, 正在短距离无线通信中显示出一股强劲的势头, 蓝牙技术的大发展期必将很快地到来。
参考文献:
[1]张禄林.蓝牙协议及其实现[M].北京:人民邮电出版社,2001.
[2]金纯.蓝牙技术[M].北京:电子工业出版社,2001.
[3]Ericssion,Nokia,IBM.Specification of the Bluetooth system Version1.0B[S],1999.
[4]Core,version 1.2B,Bluetooth SIG.Specification of the Bluetooth system[S],2003.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
这篇关于蓝牙核心规范中HCI层的研究与开发分析□ 张 熠 姜玉泉 《电脑知识与技术》 2007年第09期的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!