IC卡复位应答ATR解析
2016-06-05 11:09
357 查看
输入的是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[16] = { 0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0 }; int Fi[16] = { 372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0 }; printf("TA1: %02X\r\n", ch); printf("\t时钟速率转换因子Fi: %d\r\n", (ch >> 4) & 0x0f); printf("\t位速率调节因子Di: %d\r\n", (ch & 0x0f)); printf("\tFi/Di: %f\r\n", (Fi[(ch>>4)&0x0f]!=0 && Di[ch&0x0f]!=0) ? (float)Fi[(ch>>4)&0x0f]/(float)Di[ch&0x0f] : 0); } 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 >> 5) & 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 >> 4) & 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 = 0; 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 = 0; unsigned char K = 0; unsigned char Yi = 0; int k, state, index, length, protocol; unsigned char *ptr; unsigned char hist_bytes[16]; length = len; ptr = atr; state = STATE_PARSE_TS; index = 0; k = 0; protocol = 0; 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 0: /* TA1 */ atr_TA1(data); break; case 1: atr_TA2(data); break; case 2: 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 0: /* TB1 */ atr_TB1(data); break ; case 1: /* TB2 */ atr_TB2(data); break ; case 2: /* 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 0: /* TC1 */ atr_TC1(data); break; case 1: /* TC2 */ atr_TC2(data); break ; case 2: /* 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 0: protocol = Yi & 0x0F; atr_TD1(data); break; case 1: 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 > 0) 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 == 0 && protocol == 0) break; } return 0; } 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[0])); return 0; }
相关文章推荐
- python2.7 倒计时
- 对字节读写操作示例,来自微软
- linux shell 重定向
- 排序算法(5)-希尔排序
- jQuery创建节点和插入节
- Twitter API 申请key
- 学习进度条14
- leetcode 105 Constract Binary Tree from Preorder and Inorder Traversal
- JAVA反射机制
- ccleaner的专业版和商业版的注册码
- 作业 1
- 机器视觉开源代码集合-2
- 第十周、十一周项目
- 第十五周项目-阅读程序-4
- 非3D Touch的设备上模拟Peek Preview效果
- stm32中GPIO端口的输出配置例子
- 网站扫描与用户信息绑定方案
- 第十五周项目一 阅读下面程序,解释运行结果(5)
- 网吧装修记录
- Codeforces Beta Round #3