输入的是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. Java期末设计(十三周)

    一.项目完成计划     十三周和十四周完成用户交互界面的设计(1.登陆界面2.订票以及查询界面3.用户管理界面4.退票界面):     十三周完成登陆界面,十四周完成订票以及查询界面,用户管理界面和 ...

  2. codeforces problem 140E New Year Garland

    排列组合题 题意 用m种颜色的彩球装点n层的圣诞树.圣诞树的第i层恰由l[i]个彩球串成一行,且同一层内的相邻彩球颜色不同,同时相邻两层所使用彩球的颜色集合不同.求有多少种装点方案,答案对p取模. 只 ...

  3. web学习之开发环境的搭建

    开发工具 myeclipse2014: tomcat7.0 jdk7.0 1:新建一个web projcat 2:找到web root目录下的index.jsp 这是项目首页 3:访问web项目 ht ...

  4. POJ 1061

    题意: 两只青蛙在同一条纬度上,它们各自朝西跳,问它们要跳多少步才能碰面(必须同时到达同一点). 分析: 假设它们跳了t步才相遇,青蛙a初始坐标为x,青蛙b初始坐标为y,则跳了t步相遇后a的坐标为 x ...

  5. Ubuntu Install Java

    http://linuxpilot.com/ubuntu-java class HelloWorld{public static void main(String[]arg){System.out.p ...

  6. Titanium studio安装

    在Win7 Titanium Studio的安装过程. 1.准备工作 Titanium存储空间的要求,Titanium Studio 需要1 GB.Android SDK需要1.5 GB.Blackb ...

  7. c语言操作一维数组-3

    C语言选择题#includemain(){double a[15],k;k=fun(a);} 则以下选项中错误的fun函数首部是 ( D)A.double fun(double a[15]) B.do ...

  8. local认证

    文件路径 用途 示例 备注 #gedit /usr/local/etc/raddb/sites-available/default #gedit /usr/local/etc/raddb/sites- ...

  9. The property on could not be set to a 'Int16' value.You must set this property to a non-null value of type ‘Int32’.”

    在vs2010 EF4中查询数据总是报错: The property  on “XX” could not be set to a 'Int16' value. You must set this p ...

  10. 可滑动的ExpandableListView

    可以向左滑动的扩展列表 向左滑动源码是参照GitHub上的里的 ListView的思路写出来的,按照他的思路,由于本人水平有限,只写了关键代码,能够完美运行,adapter改变之后能自动收回. 滑出状 ...