http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28781109&id=4062876
如果终端不支持IC卡支持的其它传输协议以及传输参数值,IC卡应该有能力用基本ATR定义的模式和终端进行交互。
终端如果无法满足IC卡回送ATR中定义的传输模式,将发送一个热复位信号,或将IC卡置为静止状态以结束卡片操作过程。
复位应答中回送字符的最大个数(包括历史字符,但不包括TS)为32个。
1、TS--初始字符
起始字符TS具有两个功能:一是向终端提供一个便于位同步的已知位模式,二是指定解释后续字符的逻辑约定。
使用反向逻辑约定时,I/O的低电平状态等效逻辑1,并且该数据字节的最低位在起始位之后发送第一个半字节LHHL用于位同步(L表示低电平,H表示高电平)。
* (H)LHHLLLLLLH表示反向约定,值为0x3F。
* (H)LHHLHHHLLH表示正向约定,值为0x3B。
基本响应:IC卡将回送的TS为以下两个值之一。
例子:TS( The Initial character ) = 3B 表示正向约定,高电平为1,低电平为0,传输时先传输LSB,最后传输MSB
终端一般都支持正向约定和反射约定,并接收IC卡回送的0x3F和0x3B中的任何一个,对于其他值将拒绝。目前反向约定模式的卡片使用越来越少,在以后的卡片规范和应用规范版本中可能淘汰,所以在我们的设计中,建议大家使用0x3B,即正向约定。
2、T0--格式字符:
表示接口字符的个数和历史字节的数量(高4位 = f( 1 1 1 1 )表示后续字符中存在TA1 TB1 TC1 TD1)
高半字节(b5~b8)表示后续字符TA1到TD1是否存在,b5-b8位设置为逻辑“1”表示TA1到TD1存在,低半字节(b1~b4)表明可选历史字符的数目(0~15)
TA1, TB1, TC1, TA2, TB2 是全局接口字符,TC2是专用接口字符
[b] b8 b7 b6 b5 b4 b3 b2 b1 [/b] 其中X表示历史字符的数目。
T=0 0 1 1 0 x x x x 选择T=0时,IC卡应回送T0=0x6X,表示字符TB1和TC1存在
T=1 1 1 1 0 x x x x 选择T=1时,IC卡应回送T0=0xEX,表示字符TB1、TC1和TD1存在
3、TA1~TC3--接口字符
;TAi,TBi,TCi:指示协议参数。TDi:指示协议类型(T=0,1,或者其他)和是否 存在后续接口字符;
在复位应答后的终端与IC卡信息交换期间,TA1到TC3表示控制参数F、D、I、P、N、IFSC、BW1和CW1的值。这些参数都用于T=1协议,TA1到TC1和TC2传送的信息将用于后续数据交换且与所使用的协议类型无关。这些参数的具体意义在下面给出。
(1)TA1:TA1传送FI和DI的值
,其中:公式 3571200 / ( Fi / Di )其中Fi由TA1的高4位(F)查表得出,Di由TA1的低4位(D)查表得出
* FI用于确定F的值。F为时钟速率转换因子,用于修改复位应答以后终端提供的时钟频率。
* DI用于确定D的值。D为比特速率调节因子。用于调整复位应答之后所使用的位持续时间。
在复位应答期间发送ATR时所使用的默认值FI=1、DI=1,分别表示F=372、D=1。
基本响应:如果IC卡不回送TA1值,则表示IC卡使用默认参数,在整个后续信息交换过程中继续使用默认值F=372和D=1。
兼容终端接收默认的TA1值(0x11)
为提高终端与IC卡之间的数据传送速率,某些IC卡在终端支持的情况下可以选择使用其他的TA1值协商使用高速模式。
2)TB1:TB1传送PI1和II值
* PI1在b1~b5位中定义,用于确定IC卡所需的编程电压P值,PI1=0表示IC卡不需要编程电压VPP。
* II在b6~b7位定义,用于确定IC卡所需的最大编程电流I值。PI1=0时不使用这一参数。
* b8位不使用,设置位逻辑0。
基本响应:在目前使用的大多数IC卡芯片都不要编程电压的支持,所以,IC卡回送TB1=0x00,表示IC卡不使用VPP。
终端接受满足上述定义的任何TB1,如果不需要VPP的话,终端将在卡片使用过程中保持VPP为静止状态。
例子:TB1 = 00
----表示编程电流 I /电压 P,高2位表示电流I,低6位表示电压P
----高2位 = 00 ,则编程电流 I 如下
+-------+--------+--------+--------+--------+
| 高2位 | 00 | 01 | 10 | 11 |
+-------+--------+--------+--------+--------+
| 电流I | 25 | 50 | RFU | RFU |
+-------+--------+--------+--------+--------+
----低6位 = 00 ,则编程 P 电压为0
(3)TC1:TC1传送N值
N用于表示增加到最小持续时间的额外保护时间,此处的最小持续时间表示从终端发送到IC卡的、作为后续信息交换的两个连续字符的起始位上升沿之间的时间。N在TC1的b1~b8位为二进制编码,其值作为额外保护时间表示增加的etu数目,其值可在0到255之间任选。
N=255具有特殊含义,表示在使用T=0协议时,两个连续字符的起始位上升沿之间的最小延迟时间可减少到12个etu,而在使用T=1协议时可减少到11个etu。
TC1的值定义的参数只适用于终端向IC卡发送的两个连续字符之间的间隔时段,不适用于IC卡向终端发送字符的情况,也不适用于两个反方向发送字符的情况。
如果TC1值在0x00到0xFE之间,增加到字符间最少持续时间的额外保护时间为0~254个etu,对于后续传输,意味着其额外保护时间将在12~266个etu之间。
如果TC1值为0xFF,则后续传输的字符最小持续时间在使用T=0协议时为12个etu,使用T=1协议时为11个etu。
基本响应:根据芯片内I/O的处理情况,IC卡回送0x00~0xFF之间的任何值。
终端能够接收满足以上条件的任何TC1值。
在实现过程中,我们可以计算出特定芯片可接收的最小持续时间,建议TC1设置为这个最小时间,否则TC1如果过大可能造成终端与IC卡之间的通信缓慢,延长交易时间,如果TC1过小的话芯片无法及时处理I/O端口到来的数据,会造成数据丢失。
例子:TC1 = 00 额外保护时间N = 0
4)TD1:TD1表示是否还要发送更多的接口字符以及后续传输所使用的协议类型
* 高半字节用于表示字符TA2到TD2是否存在,这些位(b5~b8)设置为逻辑1状态时,分别表示TA2到TD2字符的存在。
* 低半字节用于表示后续信息交换所使用的协议类型。
基本响应:
* 当选用T=0协议时,IC卡不回送TD1,并且T=0协议作为后续传输类型的默认值。
* 当选择T=1协议时,IC卡将回送TD1=0x81,表示TD2存在,且后续传输协议类型为T=1协议。
终端接收低半字节为0或1任何值,拒绝其它情况。
例子:TD1 = 81: 通讯协议 T = 1,没有TA2,TB2,TC2
(5)TA2:TA2的存在与否表示IC卡是以特定模式还是交互模式工作
。在目前常见的应用中,通常选择的是交互模式。
基本响应:
IC卡不回送TA2,表示选择的是交互模式(默认)。
兼容终端通常还接受特定模式。
(6)TB2:TB2传送PI2
,PI2用于确定IC卡所需的编程电压P和值,当PI2出现时,它将取代TB1中回送的PI1的值。
基本响应:IC卡不回送TB2。
终端如果接受到TB2则提供相应的编程电压,否则保持VPP在IC卡使用阶段一直为静止状态。
(7)TC2:TC2专用于T=0协议
,并传送工作等待时间整数(Waiting Time Integer,简称WI)
WI用来确定IC卡发送的任意一个字符起始位上升沿与IC卡或终端发送的前一个字符起始位上升沿之间的最大时间间隔。工作等待时间为:960×D×WI。
基本响应:在通常应用中,定义的工作等待时间为1s,也就是相当于9600个etu,对应的WI为10,所以,IC卡一般不回送TC2,后续通信中使用默认值WI=10。
终端一般只不接收WI非10的情况。
(8)TD2:TD2表示是否还要发送更多的接口字节以及后续传输所使用的协议类型
* 高半字节用于表示字符TA3到TD3是否存在,这些位(b5~b8)设置为逻辑学状态时,分别表示TA3到TD3字符的存在。
* 低半字节用于表示后续信息交换所使用的协议类型,当选用T=1协议类型时,该低半字节选值为1。
基本响应:
* 选择T=0协议时,IC卡不回送TD2,且T=0协议作为后续传输类型的默认值。
* 选择T=1协议时,IC卡将回送TD2=0x31,表示TA3和TB3的存在,且后续传输协议类型为T=1。
终端可以接收满足以上定义的TD2的值。
9)TA3:TA3回送IC卡信息域大小整数IFSI
IFSI决定了IFSC(Information Field Size for the ICC),并指明了卡片接收的块信息区域(Information Field,简称INF)的最大长度。TA3以字节形式表示IFSC的长度,其取值范围从0x01到0xFF,0x00和0xFF保留。
基本响应:如果选用T=1协议,初始的IFSC在16到254Byte范围内,IC卡回送0x10到0xFE之间的任何值。
终端只接收TA3在0x10到0xFE之间的情况。
10)TB3
TB3表明了用来计算字符等待时间(Character Waiting Time,简称CWT)和块等待时间(Block Waiting Time,简称BWT)的字符等待时间整数(Character Waiting Time Integer,简称CWI)和块等待时间整数(Block Waiting Time Integer,简称BWI)值,TB3由两部分组成。低半字节(b1-b4)用于表明CWI值,而高半字节(b5-b8)用于表明BWI值。
基本响应:在选用T=1协议时,IC卡回送的TB3定义为:高半字节取值为0x00~0x05之间,低半字节取值为0x00~0x04之间。也即CWI的值在0x00~0x05之间,BWI的值在0x00~0x04之间。
11)TC3:TC3指定了所用的块错误检测代码的类型
,所用代码类型用b1位表示,b2~b8位不使用。
基本响应:IC卡不应回送那些将纵向冗余校验(LRC)作为错误代码来表明的TC3。
4、TCK--检验字符
校验字符(Check Character,简称TCK)具有一个校验复位应答期间所发送数据完整性的值。TCK的值应使从T0到包括TCK在内的所有字节进行异或运算而结果为零。
基本响应:
在使用T=0协议时,IC卡不会送TCK。
在使用T=1协议和其他协议时,IC卡回送TCK,TCK的计算方法是从T0到TCK前所有字节异或运算的结果。
终端对TCK的处理方式如下:
* 对使用T=0协议的IC卡,如果发送TCK,则终端将拒绝该卡片。
* 对使用T=1协议的IC卡,如果不发送TCK,则终端将拒绝该卡片。
* 对使用T=1协议的IC卡,终端对TCK进行检查。
TA1 = 13
--表示有增强的波特率,公式 3571200 / ( Fi / Di )
--------其中Fi由TA1的高4位(F)查表得出,Di由TA1的低4位(D)查表得出
----F = 01 ,查下表,则Fi = 372
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| F | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| Fi | 372 | 372 | 558 | 744 | 1116 | 1488 | 1860 | RFU |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| 最高时钟MHZ | 4 | 5 | 6 | 8 | 12 | 16 | 20 | -- |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| F | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| Fi | RFU | 512 | 768 | 1024 | 1536 | 2048 | RFU | RFU |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| 最高时钟MHZ | -- | 5 | 7.5 | 10 | 15 | 20 | -- | -- |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
----D = 03 ,查下表,则Di = 4
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| D | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| Di | RFU | 1 | 2 | 4 | 8 | 16 | 1860 | RFU |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| D | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
| Di | RFU | 512 | 768 | 1024 | 1536 | 2048 | RFU | RFU |
+-------------+--------+--------+--------+--------+--------+--------+--------+--------+
附录2:智能卡命令或应答
传输方向,命令或应答的详细说明
0x3b 0x6c 0x00 0x00 0x4e 0x54 0x49 0x43 0x30 0x91 0x69 0x00 0x4a 0x03 0x00 0x00
Card -> STB。YXTF的ATR。
0x00 0xa4 0x04 0x00 0x050xf9 0x5a 0x54 0x00 0x06
STB -> Card。初始命令。
0x90 0x00
Card -> STB。表示智能卡收到了正确的初始命令
0x80 0x46 0x00 0x00 0x040x01 0x00 0x00 0x04
STB -> Card。获取智能卡号码命令。
0x61 0x04
Card -> STB。告知机顶盒号码占用0x04个字节。
0x00 0xc0 0x00 0x00 0x04
STB -> Card。读取智能卡号码。
0xaa 0xbb 0xcc 0xdd0x90 0x00
Card -> STB。告知机顶盒智能卡号码,并以0x90 0x00结尾告知机顶盒获取智能卡号码的命令被完整而成功地执行。
0x80 0x46 0x00 0x00 0x040x03 0x00 0x00 0x09
STB -> Card。获取智能卡年龄等级命令。
0x61 0x09
Card -> STB。告知机顶盒年龄等级信息占用0x09个字节
0x00 0xc0 0x00 0x00 0x09
STB -> Card。读取智能卡年龄等级信息。
0x30 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x000x90 0x00
Card -> STB。告知机顶盒智能卡年龄等级信息,并以0x90 0x00结尾告知机顶盒获取智能卡年龄等级的命令被完整而成功地执行。
0x80 0x44 0x00 0x00 0x08
STB -> Card。读取智能卡运营商信息。
0x17 0x17 0x00 0x00 0x00 0x0a 0x00 0x000x90 0x00
Card -> STB。告知机顶盒运营商信息,例如0x1717十进制为5911,表示第一个运营商是电话区号为0591的第一个城市。并以0x90 0x00结尾告知机顶盒获取智能卡年龄等级的命令被完整而成功地执行。
0x80 0x4c 0x00 0x00 0x040xff 0xff 0xff 0xff
STB -> Card。检查智能卡是否需要机卡配对。
0x94 0xb2
Card -> STB。如果为0x94 0xb2,说明此卡需要机卡配对。如果为0x94 0xb1,说明此卡不需要机卡配对。
0x80 0x4c 0x00 0x00 0x040x5e 0xe4 0x82 0xf2
STB -> Card。给卡发送四个配对字节:0x5e 0xe4 0x82 0xf2,看是否能配对成功
0x90 0x00
Card -> STB。如果为0x90 0x00,说明四个配对字节与此卡配对成功。如果回复其他数据,说明配对失败。
0x80 0x46 0x17 0x17 0x040x04 0x00 0x00 0x48
STB -> Card。获取运营商一产品包列表。其中0x17 0x17是运营商一的号码。
0x61 0x48
Card -> STB。告知机顶盒运营商一产品包列表占用0x48个字节
0x00 0xc0 0x00 0x00 0x48
STB -> Card。读取运营商一产品包列表。
0x00….. 0x00(共0x48个) 0x90 0x00
Card -> STB。返回运营商一产品包列表。并以0x90 0x00结尾告知机顶盒获取运营商一产品包列表的命令被完整而成功地执行。
0x80 0x48 0x17 0x17 0x040x81 0x00 0x00 0x3e
STB -> Card。获取运营商一授权信息。其中0x17 0x17是运营商一的号码。
0x61 0x27
Card -> STB。告知机顶盒运营商一授权信息占用0x27个字节
0x00 0xc0 0x00 0x00 0x27
STB -> Card。读取运营商一授权信息。
0x00 0x00 0x09 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x01 0x00 0x00 0x01 0x00
0x00 0x00 0x80 0x00 0x00 0x01 0xff 0xfe
0x00 0x00 0x00 0x02 0x00 0x01 0x00 0x01
0x00 0x01 0x00 0x02 0x00 0x01 0x00 0x040x90 0x00
Card -> STB。返回机顶盒运营商一授权信息。其中前三个字节0x00 0x00 0x09表示授权信息共有0x09条,以后每四个字节作为一条授权信息。例如0x00 0x01 0xff 0xfe表示ID号为65534(0xff fe)的节目,第二个字节0x01表示在界面上显示此节目ID,第二个字节为0x00表示不显示。
0x80 0x46 0x00 0x0a 0x040x04 0x00 0x00 0x48
STB -> Card。获取运营商二产品包列表。其中0x00 0x0a是运营商二的号码。
0x61 0x48
Card -> STB。告知机顶盒运营商二产品包列表占用0x48个字节
0x00 0xc0 0x00 0x00 0x48
STB -> Card。读取运营商二产品包列表。
0x00….. 0x00(共0x48个) 0x90 0x00
Card -> STB。返回运营商二产品包列表。并以0x90 0x00结尾告知机顶盒获取运营商二产品包列表的命令被完整而成功地执行。
0x80 0x48 0x00 0x0a 0x040x81 0x00 0x00 0x3e
STB -> Card。获取运营商二授权信息。其中0x00 0x0a是运营商二的号码。
0x61 0x0b
Card -> STB。告知机顶盒运营商二授权信息占用0x0b个字节
0x00 0xc0 0x00 0x00 0x0b
STB -> Card。读取运营商二授权信息。
0x00 0x00 0x02 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x010x90 0x00
Card -> STB。返回机顶盒运营商一授权信息。其中前三个字节0x00 0x00 0x02表示授权信息共有0x02条。分析方法同上面运营商一授权信息的分析方法。
如果终端不支持IC卡支持的其它传输协议以及传输参数值,IC卡应该有能力用基本ATR定义的模式和终端进行交互。 终端如果无法满足IC卡回送ATR中定义的传输模式,将发送一个热复位信号,或将IC卡置为静止状态以结束卡片操作过程。 复位应答中回送字符的最大个数(包括历史字符,但不包括TS)为32个。 1、TS--初始字符 起始字符TS具有两个功能:一是向终端提供一个便于位同步
本文基于stm32l0c8t6芯片和cubemx,利用芯片USART1和USART2的smartcard功能,在不经过ST8024的情况下直接与
IC卡
和ESAM进行通讯处理。不使用ST8024的主要原因是ST8024功耗比较大,在低功耗应用场景下,性价比并不高。
IC卡
卡座与
IC卡
触点如下所示:
C1:电源
电压
(VCC)C2:复位RST;C3:时钟CLK;C4未用;C5:GND
一、
ATR
是什么
ATR
也叫复位应答,是一个字节序列,这些字节是由卡作为对复位命令的响应发送给读卡器的。在I/O电路上,每个成功的复位操作都会导致I/O上的一个由初始字符TS开始,后跟最多32个字符的复位应答。
ATR
的作用是告诉读卡器,我是一张什么样的卡片,以便读卡器知道接下来该以什么样的方式和卡片通信。
二、
ATR
的基本数据结构
三、起始字符——TS
初始字符定义了所有后继字符的解...
f8 T0 Y1 = 0xF(TA1, TB1, TC1, TD1), K = 8
13 TA1 F = 0x1(Fi = 372, Fmax = 5MHz), D = 0x3(Di = 4)
00 TB1 deprecated
00 TC1 N = 0, extra guard time integer
81 TD1 Y2 =
// Connect to the smart card
LONG rv = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext);
if (rv != SCARD_S_SUCCESS)
// Failed to establish context
// ...
rv = SCardConnect(hContext, _T("Your Card Reader"), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
if (rv != SCARD_S_SUCCESS)
// Failed to connect to the card
// ...
// Get the
ATR
rv = SCardGetAttrib(hCard, SCARD_ATTR_
ATR
_STRING, pb
Atr
, &dw
Atr
Len);
if (rv != SCARD_S_SUCCESS)
// Failed to get
ATR
// ...
// Clean up
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
SCardReleaseContext(hContext);
请替换代码中的“Your Card Reader”为您的
智能卡
读卡器名称。注意,您
需要
在代码中包含winscard.h头文件并将Winscard.lib链接到您的项目中。