HCI协议栈
HCI(Host Controller Interface),主机控制器接口,定义了一套用以在CLF及SE/UICC之间通信的逻辑接口,HCI协议定义了CLF与SE/UICC通信时数据的帧结构以及交互流程,SE/UICC可以通过HCI实现非接应用功能,包括NFC论坛定义的卡模拟模式(Card Emulation Mode)或读卡器(Reader Mode)模式。
其中,
CLF: Contactless Front end,非接前端控制器,一般指终端的NFC芯片或模块;
SE: Secure Element,安全单元,一般指终端内嵌的安全芯片(embedded Secure Element, eSE);
UICC: Universal Integrated Circuit Card,通用集成电路卡,对智能终端来说,UICC一般指具备SWP功能的SIM卡。
一、HCI架构
HCI协议中定义的主机(host)以星形拓扑结构组织,即,一个或多个主机通过实际的物理链路链接到主机控制器(host controller),这里的主机可以是SE安全单元,也可以是UICC,主机控制器则对应CLF,即NFC模块。主机之间不能直接相互通信,均需通过主机控制器进行。参考OSI分层模型,可将主机与主机控制器之间的通信链路进行分层,从下至上分别为:
- 物理层(Physical Layer)
- 数据链路层(Data Link Layer)
- 传输层(Transport Layer)。
其中,物理层与数据链路层不由HCI协议详细定义,对于UICC与CLF之间的通信,其数据链路层使用SWP协议,遵循ETSI TS 102 613的定义,UICC的C6引脚将用于SWP/HCI的通信。
HCI协议对主机间的通信接口包含三个定义,分别为:
- HCP(Host Controller Protocol,主机控制器协议)路由及数据切分;
- HCP消息封装格式;
- 用以交换具体数据的关口(gate)集。
下图描述了一个拥有两个主机(分别为UICC host和Terminal Host,实际的主机网络或不止两个主机)的主机网络架构,以及其通信的示例,可以看到,两个主机之间的通信至少需由主机控制器进行路由,在具体指令的体现可见下文。
![](https://pic2.zhimg.com/80/v2-120e153ac7c0c31c370bbf0721364375_720w.webp)
二、术语及定义
1. 主机(Hosts)
主机是HCI网络中的逻辑实体,一个或多个主机与主机控制器一同构成了HCI定义的星形拓扑网络。一个主机会有一个对应的一字节ID进行标识,HID(host identifier),HID的取值如下表所示
![](https://pic3.zhimg.com/80/v2-29c1021d46016922eb5388591bc952de_720w.webp)
HID的分配有如下原则:
- 特定主机将被分配特定值的HID,如UICC;
- 当有多个UICC存在时,'02'值将会优先分配给版本12的(如有),且优先被探测到的·,其余的UICC会被动态分配HID值,取值范围见上表;
- 动态分配给一个主机的HID在不同会话间保持一致,除非其本身硬件有改动。
2. 关口(Gates)
关口为主机提供了服务的入口点(entry point),一个主机与外部的数据交换需经过关口进行,同主机一样,关口也有一字节的ID进行标识,GID,GID的取值如下表所示
![](https://pic1.zhimg.com/80/v2-bc77122808598d0ffe0b5de8742a9820_720w.webp)
关口主要分为两种类型,分别为:
- 管理关口(management gate),用以传输有关主机网络管理相关信息的关口;
- 一般关口(generic gate),与主机网络管理不相关的关口,如用以具体业务的那些关口。
对于一个主机,其应该具备
- 一个专门的管理关口(administration gate);
- 一个特性管理关口;
- 一个回环关口;
主机控制器除了以上要求外,还应具备:
- 链路管理关口(link management gate);
主机也可以拥有链路管理关口,两者都可以拥有一个或多个一般关口。
GID取值在'00' - '0F'中的,在不同主机中对应相同的关口,GID取值在'10' - 'FF' 中的,在不同主机间应保持唯一性。
3. 管道(Pipes)
管道是连接两个关口的一个逻辑通信通道,管道分为两种类型:
- 静态管道,静态管道不能被删除,也不需要显式地创建,且一直都处于可用状态,静态管道总是从一个主机连接到主机控制器上,;
- 动态管道,需显式创建或删除,动态管道连接除主机控制器外的任意两个主机上的关口。
同主机一样,管道也有ID进行标识,PID,7位长度,PID地值用于HCP数据包在不同主机之间的路由,静态管道的PID值根据管道对应的两端关口预先分配,如下表,动态管道的PID值由主机控制器进行动态·分配,且在主机网络中保持唯一性。
![](https://pic3.zhimg.com/80/v2-12f77269589177b69f48bcfd3bc77636_720w.webp)
管道有开启和关闭两种状态,动态管道创建以后,其初始状态为关闭状态,管道的状态需在主机断电再上电时,或被临时移除又没有被别的主机替代的情况下维持状态一致。
下图展示了一个拥有两个主机的主机网络是如何组织的,其中PIPEx中的x表示动态分配的PID,PIPEy、PIPEz的以此类推。
![](https://pic1.zhimg.com/80/v2-f4261e562469f419191705205fda2d98_720w.webp)
4. 注册表(Registries)
一个关口会维护一个注册表模板用以定义跟其有关的参数,每个参数会用一个一字节的,唯一的参数ID标识,取值范围在'00'-'EF'之间。
当在关口上建立一个管道时,对应地会创建一个注册表实例,其中的各参数将被赋予默认值或由管理注册表的实体,一般是关口所属的主机,去分配一个合适的值,当管道被删除时,注册表实例也相应删除。
三、帧结构及指令类型
1. 数据帧
由前述的HCI架构组成可知,在主机网络的通信中,数据至少被封装为两层,较底层的与路由相关的成为HCP包(HCP packets),在HCP包,数据又以HCP消息的格式进行封装(HCP message)。HCP包的格式如下图所示:
![](https://pic4.zhimg.com/80/v2-cf684e297a89d29eecbe6ad8356bf527_720w.webp)
其中CB(chaining bit)是多帧标识,当数据被切分成多帧发送时,该位置1;PID则标识了所使用的管道,主机控制器根据PID将信息路由至正确的关口。
HCP消息的格式如下图所示:
![](https://pic3.zhimg.com/80/v2-093fac743e2882cd67ac7015f240e5ca_720w.webp)
其中类型标识(TYPE identifier)标识了指令(INSTRUCTION)的类型,而指令字段则包含了具体的指令,后续的数据部分是可选的,根据指令字段指示的指令是否包含参数而决定。
类型标识的不同值对应不同的指令类型,共三种:
- 值为0时,表示当前的指令是一条命令(command)
- 值为1时,表示当前的指令是一个事件(event)
- 值为2时,表示当前的指令是对一条命令的响应(response)
- 类型标识为3是保留值,没有使用。
当数据量超过了底层数据链路所支持的最大长度时,数据将会按照如下规则切分成多个帧,如下图所示:
- 第一帧包含HCP消息头(即类型标识与指令头),后续的帧不包含消息头;
- 最后一帧的CB位置1,其余帧的CB位置0。
数据的切分及组装由管道两端的关口负责,若在传输过程中底层数据链路发生了重置的动作,那些接收到部分的消息将被丢弃并被请求重新发送。
2. 指令类型
这里按照类型标识进行划分。
2.1. 命令(Commands)
指令主要用于传送数据以及对主机网络进行管理,ETSI TS 102 622中定义的命令如下表所示,其中,部分命令只允许专有的管理关口下发。
![](https://pic4.zhimg.com/80/v2-17ab4837145ee19dc8ac3fe8250aa50f_720w.webp)
关于这些命令的具体参数及描述,可见ETSI TS 102 622的clause 6.1。
2.2. 响应(Responses)
当指令类型是响应时,指令码(INSTRUCTION)指的是命令的返回码,与前面发送的命令相对应,乱序的响应应不被接收。
ETSI TS 102 622中定义的响应如下表所示:
![](https://pic3.zhimg.com/80/v2-9914d67671daf85887dfd390b7d22aa2_720w.webp)
关于这些响应与指令的对应关系,可见ETSI TS 102 622的clause 6.2。
2.3. 事件(Events)
如果其他地方所定义的事件那样,事件用以通知某一事件的发生。
关于这些事件的具体参数及描述,可见ETSI TS 102 622的clause 6.3。
![](https://pic2.zhimg.com/80/v2-7ece34a0a7bdbfdd7e0851bd45618145_720w.webp)
四、交互流程
不同关口会维护不同的注册表,且不同版本定义的参数种类也不一,较新版本会新增一些参数,关于不同关口的注册表具体细节,可见ETSI TS 102 622 的 clause 7,这里仅对设及到的参数做简单介绍。
1. 管道管理
管道的管理主要涉及管道的创建与删除,这些都是通过管理关口(administration gate)进行的,且皆须经过主机控制器,主机控制器负责接收创建通道的请求,并下发或转发创建通道的请求,在两个主机之间建立或删除管道的流程大致如下,静态管道不能被删除或创建,因此这里指的都是动态管道:
1) 主机A向主机控制器发送建立/删除管道的请求,如果是创建管道,主机控制器将检查与主机B相连的管理关口中的注册表里的WHITELIST参数,若主机A不在白名单内,则向主机A返回ANY_E_PIPE_ACCESS_DENIED以拒绝请求,若在白名单内,则分配一个未使用的管道ID;
2) 主机控制器通过ADM_NOTIFY_PIPE_CREATED/ ADM_NOTIFY_PIPE_DELETED通知给主机B有主机A请求建立/删除连接;
3) 主机B返回ANY_OK或其他合适的响应码接受或拒绝该请求;
4) 主机控制器返回执行结果给主机A。
两主机创建或删除管道的时序图如下:
创建管道:
![](https://pic4.zhimg.com/80/v2-e6bf163ad5ae4e15b6bffe55760f5467_720w.webp)
删除管道:
![](https://pic2.zhimg.com/80/v2-ec9c277c1dbe6dcd58c25c863f8b893d_720w.webp)
若是主机控制器请求建立/删除管道,或是主机请求与主机控制器建立/删除管道,则上述指令流程中仅涉及单一条ADM_CREATE_PIPE/ ADM_DELETE_PIPE或ADM_NOTIFY_PIPE_CREATED/ ADM_NOTIFY_PIPE_DELETED,当中不涉及白名单的校验。
主机控制器请求与主机A建立管道的时序图如下:
![](https://pic3.zhimg.com/80/v2-65f0f968b1735ae763387d12c14ca4ea_720w.webp)
主机A请求与主机控制器建立管道的时序图如下:
![](https://pic3.zhimg.com/80/v2-b10595484ec7ffea06be82c7c69ac70a_720w.webp)
主机可以请求删除所有与之连接的动态管道以及关闭所有与之连接的动态管道,通过ADM_CLEAR_ALL_PIPE指令,届时主机控制器将通过ADM_NOTIFY_ALL_PIPE_CLEARED通知到与之有连接的所有主机,并清除掉其相连接的管道,下图演示了主机A请求清除管道时的执行过程,主机B和主机C分别与主机A有动态管道连接:
![](https://pic3.zhimg.com/80/v2-de8335b0fe33241d38183829c6bc7fc2_720w.webp)
2. 访问注册表
任意两个建立了管道的主机(包括主机控制器)可以通过ANY_GET_PARAMETER来读取目的关口的注册表参数,或通过ANY_SET_PARAMETER来设置目的关口的注册表参数,下图展示了主机A获取主机B某一关口参数及设置某一关口参数的流程:
![](https://pic2.zhimg.com/80/v2-224c37617b06e3447708f6195fe286a5_720w.webp)
3. 主机嗅探
下图展示了主机A如何感知主机网络中存在的主机以及支持的关口,并创建管道及访问注册表的过程:
![](https://pic2.zhimg.com/80/v2-ac608ee32c2f8d6bd8fb0cca34331361_720w.webp)
流程如下:
1) 主机A通过管理关口与主机控制器的管理关口建立的管道(PIPE1),向主机控制器请求当前主机网络中连接的主机列表(对应主机控制器管理关口的注册表里的HOST_LIST参数);
2) 主机控制器返回主机列表;
3) 主机A从中选择主机B,并发起建立管道的请求;
4) 主机控制器返回管道创建的响应,PIPEx被建立,这里省略了主机控制器与主机B的交互;
5) 主机A打开管道
6) 主机B返回正常响应;
7) 主机A请求主机B的关口列表(对应特性管理关口Identity Management Gate中注册表中的GATES_LIST参数);
8) 主机B返回关口列表
9) 主机A请求主机B特性管理关口的注册表中的VENDOR_NAME参数,该参数记录主机B的供应商相关的信息;
10) 主机B返回VENDOR_NAME参数。
4. 会话初始化
管道状态不会实时变化的,当主机网络发生变化时,比如UICC被装入到别的终端上,就会导致配置信息没能及时更新,会话初始化(session initialization)的过程就是用以感知主机网络的变化,避免因此导致问题,这一流程仅允许在没有非接事务进行中,且在启动时执行。下图展示了主机A感知网络状态变化,并更新相关信息以实现会话初始化的过程:
![](https://pic4.zhimg.com/80/v2-f708002611dd312fd273c2688b6bbdcb_720w.webp)
流程如下:
1) 主机A通过ANY_GET_PARAMETER读取当前主机控制器管理关口注册表里的SESSION IDENTITY参数,该参数记录一个会话ID,默认值为8字节的'FF',该参数应使用随机值;
2) 主机A对比该值与之前保存的是否一致,一致则终止该流程;
3) 主机A开始重新初始化的流程,并通过ADM_CLEAR_ALL_PIPE请求主机控制器清除所有与之连接的管道;
4) 主机控制器返回确认信息,较新版本的HCI协议还要求主机A设置主机控制器管理关口的注册表中的HOST_TYPE值为对应值,这个2字节的参数用以标识主机类型;
5) 主机A生成一个新的会话id并将其值同步给主机控制器的注册表实例;
6) 主机控制器返回确认信息。
5. 回环关口使用
回环关口用以调试管道,验证管道是否接通,当别的关口向某一主机的回环关口发送数据时,回环关口将返回相同的数据回去,源关口可以验证其返回的数据与原始数据是否一致,从而判断管道状态。
下图展示了主机A中的一个关口与主机B的回环关口建立管道并发送数据测试的过程,测试数据通过EVT_POST_DATA发送。
![](https://pic1.zhimg.com/80/v2-d58738857f8a87ec08d445e85aae52c0_720w.webp)
loopback gate test
【转】https://zhuanlan.zhihu.com/p/458999680