输入的是ATR,通过解析输出TA、TB、TC、TD的信息。

似乎没有容错处理,~~~~(>_<)~~~~

 #include <stdio.h>

 #define TA_BIT          (1<<4)  /**< TAx presence bit (bit 4, 0x10) */
#define TB_BIT (1<<5) /**< TBx presence bit (bit 5, 0x20) */
#define TC_BIT (1<<6) /**< TCx presence bit (bit 6, 0x40) */
#define TD_BIT (1<<7) /**< TDx presence bit (bit 7, 0x80) */ void atr_TS(unsigned char ch)
{
printf("TS: %02X\r\n", ch);
if(ch == 0x3B)
{
printf("\t正向约定\r\n");
}
else if(ch == 0x3F)
{
printf("\t反向约定\r\n");
}
else
{
printf("\tATR 错误\r\n");
}
}
void atr_T0(unsigned char ch)
{
printf("T0: %02X\r\n", ch); if ((ch & TA_BIT) == TA_BIT)
{
printf("\tTA1 存在\r\n");
}
if ((ch & TB_BIT) == TB_BIT)
{
printf("\tTB1 存在\r\n");
}
if ((ch & TC_BIT) == TC_BIT)
{
printf("\tTC1 存在\r\n");
}
if ((ch & TD_BIT) == TD_BIT)
{
printf("\tTD1 存在\r\n");
}
printf("\t历史字符数: %d\r\n", ch & 0x0f);
}
void atr_TA1(unsigned char ch)
{
int Di[] = { , , , , , , , ,
, , , , , , , };
int Fi[] = { , , , , , , , ,
, , , , , , , }; printf("TA1: %02X\r\n", ch);
printf("\t时钟速率转换因子Fi: %d\r\n", (ch >> ) & 0x0f);
printf("\t位速率调节因子Di: %d\r\n", (ch & 0x0f));
printf("\tFi/Di: %f\r\n",
(Fi[(ch>>)&0x0f]!= && Di[ch&0x0f]!=) ? (float)Fi[(ch>>)&0x0f]/(float)Di[ch&0x0f] : );
}
void atr_TB1(unsigned char ch)
{
printf("TB1: %02X\r\n", ch);
printf("\t编程电压 P 值: %d\r\n", ch & 0x1f);
printf("\t最大编程电流 I 值: %d\r\n", (ch >> ) & 0x03);
}
void atr_TC1(unsigned char ch)
{
printf("TC1: %02X\r\n", ch);
printf("\t额外保护时间: %d\r\n", ch);
}
void atr_TD1(unsigned char ch)
{
printf("TD1: %02X\r\n", ch); if ((ch & TA_BIT) == TA_BIT)
{
printf("\tTA2 存在\r\n");
}
if ((ch & TB_BIT) == TB_BIT)
{
printf("\tTB2 存在\r\n");
}
if ((ch & TC_BIT) == TC_BIT)
{
printf("\tTC2 存在\r\n");
}
if ((ch & TD_BIT) == TD_BIT)
{
printf("\tTD2 存在\r\n");
}
printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
}
void atr_TA2(unsigned char ch)
{
printf("TA2: %02X\r\n", ch);
printf("\t是否有能力改变它的操作模式: %s\r\n",
!!!(ch & 0x80) ? "是(0)" : "否(1)");
printf("\t协商模式 or 特定模式: %s\r\n",
!!!(ch & 0x80) ? "特定模式(0)" : "协商模式(1)");
printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
}
void atr_TB2(unsigned char ch)
{
printf("TB2: %02X\r\n", ch);
printf("\tIC卡所需的编程电压P的值PI2: %d\r\n", ch);
}
void atr_TC2(unsigned char ch)
{
printf("TC2: %02X\r\n", ch);
printf("\tT=0, 传输工作等待时间整数WI: %d\r\n", ch);
}
void atr_TD2(unsigned char ch)
{
printf("TD2: %02X\r\n", ch); if ((ch & TA_BIT) == TA_BIT)
{
printf("\tTA3 存在\r\n");
}
if ((ch & TB_BIT) == TB_BIT)
{
printf("\tTB3 存在\r\n");
}
if ((ch & TC_BIT) == TC_BIT)
{
printf("\tTC3 存在\r\n");
}
if ((ch & TD_BIT) == TD_BIT)
{
printf("\tTD3 存在\r\n");
}
printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
}
void atr_TA3(unsigned char ch)
{
printf("TA3: %02X\r\n", ch);
printf("\tT=1, IC卡的信息域大小整数IFSI: %d\r\n", ch);
}
void atr_TB3(unsigned char ch)
{
printf("TB3: %02X\r\n", ch);
printf("\tT=1, CWI: %d\r\n", ch & 0x0f);
printf("\tT=1, BWI: %d\r\n", (ch >> ) & 0x0f);
}
void atr_TC3(unsigned char ch)
{
printf("TC3: %02X\r\n", ch);
printf("\tT=1, 块错误校验码的类型: %d\r\n", ch & 0x01);
}
void atr_history(unsigned char *ch, int len)
{
int i;
printf("TKi:");
for(i = ; i < len; i++)
printf(" %02X", ch[i]);
printf("\r\n");
}
void atr_TCK(unsigned char ch)
{
printf("TCK: %02X\r\n", ch);
} #define STATE_PARSE_TS 1
#define STATE_PARSE_T0 2
#define STATE_PARSE_TA 3
#define STATE_PARSE_TB 4
#define STATE_PARSE_TC 5
#define STATE_PARSE_TD 6
#define STATE_PARSE_HIST_BYTES 7
#define STATE_PARSE_TCK 8
#define STATE_PARSE_END 255 int atr_parse(unsigned char *atr, int len)
{
unsigned char data;
unsigned char TCK = ;
unsigned char K = ;
unsigned char Yi = ;
int k, state, index, length, protocol;
unsigned char *ptr;
unsigned char hist_bytes[]; length = len;
ptr = atr;
state = STATE_PARSE_TS;
index = ;
k = ;
protocol = ; while( ptr < (atr + length) )
{
data = *ptr++;
if ( state != STATE_PARSE_TS )
{
TCK ^= data ;
} switch( state )
{
case STATE_PARSE_TS:
atr_TS(data);
state = STATE_PARSE_T0;
break;
case STATE_PARSE_T0:
atr_T0(data);
K = data & 0x0F;
Yi = data;
if ( data & 0x10 )
{
state = STATE_PARSE_TA;
}
else if ( data & 0x20 )
{
state = STATE_PARSE_TB;
}
else
{
if ( data & 0x40 )
{
state = STATE_PARSE_TC;
}
else if ( data & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
}
break;
case STATE_PARSE_TA :
switch( index )
{
case : /* TA1 */
atr_TA1(data);
break;
case :
atr_TA2(data);
break;
case :
atr_TA3(data);
break;
}
if ( Yi & 0x20 )
{
state = STATE_PARSE_TB;
}
else if ( Yi & 0x40 )
{
state = STATE_PARSE_TC;
}
else if ( Yi & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break;
case STATE_PARSE_TB :
switch( index )
{
case : /* TB1 */
atr_TB1(data);
break ;
case : /* TB2 */
atr_TB2(data);
break ;
case : /* TB3 */
atr_TB3(data);
break;
}
if ( Yi & 0x40 )
{
state = STATE_PARSE_TC;
}
else if ( Yi & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break;
case STATE_PARSE_TC :
switch( index )
{
case : /* TC1 */
atr_TC1(data);
break;
case : /* TC2 */
atr_TC2(data);
break ;
case : /* TC3 */
atr_TC3(data);
break ;
}
if ( Yi & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break ;
case STATE_PARSE_TD :
Yi = data ;
switch( index++ )
{
case :
protocol = Yi & 0x0F;
atr_TD1(data);
break;
case :
atr_TD2(data);
break;
} if ( Yi & 0xF0 )
{
if ( Yi & 0x10 )
{
/* TAx character present */
state = STATE_PARSE_TA;
}
else if ( Yi & 0x20 )
{
/* TBx character present */
state = STATE_PARSE_TB;
}
else if ( Yi & 0x40 )
{
/* TCx character present */
state = STATE_PARSE_TC;
}
else if ( Yi & 0x80 )
{
/* TDx character present */
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break ;
case STATE_PARSE_HIST_BYTES:
if( K )
{
if( k < K )
{
hist_bytes[k++] = data;
if(k == K)
{
if(protocol > )
state = STATE_PARSE_TCK;
else
ptr = atr + length; atr_history(hist_bytes, k);
}
}
break;
}
case STATE_PARSE_TCK:
atr_TCK(data);
if ( !TCK )
{
}
atr_TCK(TCK);
ptr = atr + length;
break ;
}
if( state == STATE_PARSE_HIST_BYTES && K == && protocol == )
break;
} return ;
} int main(void)
{
//atr_TA2((0 << 7) | (0 << 4) | 0x01);
//atr_TA2((0 << 7) | (1 << 4) | 0x01);
//atr_TA2((1 << 7) | (0 << 4) | 0x01);
//atr_TA2((1 << 7) | (1 << 4) | 0x01);
//atr_TA1(0x11); //unsigned char atr1[] = {0x3B, 0xB5, 0x11, 0x00, 0x81, 0x31, 0x46, 0x15, 0x56, 0x20, 0x31, 0x2E, 0x50, 0x1E};
//unsigned char atr2[] = {0x3B, 0x9C, 0x11, 0x81, 0x21, 0x34, 0x53, 0x43, 0x20, 0x53, 0x56, 0x20, 0x31, 0x2E, 0x31, 0x20, 0x4E, 0x43, 0x0F};
//unsigned char atr3[] = {0x3B, 0x89, 0x40, 0x14, 0x47, 0x47, 0x32, 0x34, 0x4d, 0x35, 0x32, 0x38, 0x30};
unsigned char atr[] = {0x3f, 0x23, 0x00, 0x80, 0x69, 0xae}; atr_parse(atr, sizeof(atr)/sizeof(atr[])); return ;
}

IC卡复位应答ATR解析的更多相关文章

  1. IC卡复位应答ATR的数据元和它们的意义

    ISO/IEC 7816-3标准中对ATR的数据串和数据元做了规定和描述.ATR的数据元和它们的意义: 数据元 说明 TS 起始字符 T0 格式字符 TA1,TB1,TC1,TD1,... 接口字符 ...

  2. 复位应答ATR的基本结构和数据元

    根据定义,复位应答是一系列字节的值,这些字节是由卡作为对复位命令的响应发送给接口设备的 ,在I/O电路上,每个字节在一个异步字符中传输.每个成功的复位操作,都会导致I/O上的一个初始字符TS,TS后面 ...

  3. EMV卡复位应答的时间特性 ---ISO7816协议

    1.冷复位的时间特性 图1 如图1所示: T0为200clk 从T0结束到RST变为高电平为40000-45000个clock 从RST变为高电平后,卡片必须在400-40000个clock之间应答, ...

  4. IC卡热复位时序

    热复位(warm reset):在时钟CLK和电源电压VCC处于激活状态的前提下,IC卡收到复位信号时产生的复位. 冷复位过程之后,如果收到的复位应答信号不满足规定,终端将启动热复位并从IC卡获得复位 ...

  5. IC卡冷复位时序

    冷复位(cold reset):当提供给IC卡的电源电压和其他信号从静止状态中复苏且收到复位信号后,IC卡产生的复位. 在触点激活后,终端将发出一个冷复位信号,并从IC卡获得一个复位应答信号,过程如下 ...

  6. IC卡接口芯片TDA8007的读写器设计

    摘要:阐述T=0传输协议,给出IC卡读写器中使用的IC卡APDU指令流程和原理框图:重点介绍其中的IC卡接口芯片Philips的TDA8007,给出通过TDA8007对CPU IC卡上下电过程.具体程 ...

  7. 智能卡 ATR解析

    如果终端不支持IC卡支持的其它传输协议以及传输参数值,IC卡应该有能力用基本ATR定义的模式和终端进行交互. 终端如果无法满足IC卡回送ATR中定义的传输模式,将发送一个热复位信号,或将IC卡置为静止 ...

  8. IC卡

    本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . IC卡 (Integrated Circuit Card,集成电路卡),也称智能卡(Smart card).智慧卡(Intelligent ...

  9. 智能IC卡与终端(读卡器)之间的传输协议

    1.有两种协议 T=0,异步半双工字符传输协议 T=1,异步半双工块传输协议 终端一般都支持这两种协议,IC卡可以选择支持其中的一种.(因为终端可能需要面对各种类型的卡片,所以必须两种协议都支持,而卡 ...

随机推荐

  1. telnet 使用

    Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成远程主机工作的能力.在终端使用者的电脑上使用telnet程序,用它连接 ...

  2. js关闭子窗口,刷新父窗口

    父页面js:function btnAdd_onclick() {window.open("xxx.jsp", "","height=600, wid ...

  3. 通过GET方法返回定义的任意对象

    package util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputSt ...

  4. win8.1安装Matlab7.0的兼容问题

     Matlab7.0安装完成后打开就立即关闭,此时右键点击MATLAB7.0快捷方式-"用图形处理器运行"-"更改默认图形处理器",将"集成图形&qu ...

  5. 计算机网络(8)-----TCP报文段的首部格式

    TCP报文段的首部格式 概述 TCP报文段首部的前20个字节是固定的,因此TCP首部的最小长度是20字节. 源端口和目标端口 各占2个字节,分别写入源端口号和目的端口号. 序列号 占4个字节,表示本报 ...

  6. php发送邮件

    <?php header("content-Type: text/html; charset=utf-8"); require("class.phpmailer.p ...

  7. IOS 学习 开发 自定义 UINavigationController 导航

    文件目录如下:基本导航顺序: root -> First -> Second -> Third.其中,FirstViewController作为 navigation堆栈的rootv ...

  8. 查询数据库表大小sql

    SELECT a.name, b.rowsFROM sysobjects AS a INNER JOIN sysindexes AS b ON a.id = b.idWHERE (a.type = ' ...

  9. 两台装有Ubuntu系统的服务器搭建VPN(一台为本地服务器,另一台为云服务器)

    我们搭建VPN采用的是openvpn,搭建过程总体需要经过三大步骤:   1.openvpn的安装与配置    2.端口转发    3.系统重启iptables规则自动生效  注意:以下所有名令在ro ...

  10. angularjs ng-click

    在angularjs的controller中一段代码,展示如下: var sortList = new SortList(); sortList.setSorts([$scope.year_inves ...