zoukankan      html  css  js  c++  java
  • IC卡复位应答ATR解析

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

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

      1 #include <stdio.h>
      2 
      3 #define TA_BIT          (1<<4)  /**< TAx presence bit (bit 4, 0x10) */
      4 #define TB_BIT          (1<<5)  /**< TBx presence bit (bit 5, 0x20) */
      5 #define TC_BIT          (1<<6)  /**< TCx presence bit (bit 6, 0x40) */
      6 #define TD_BIT          (1<<7)  /**< TDx presence bit (bit 7, 0x80) */
      7 
      8 void atr_TS(unsigned char ch)
      9 {
     10     printf("TS: %02X
    ", ch);
     11     if(ch == 0x3B)
     12     {
     13         printf("	正向约定
    ");
     14     }
     15     else if(ch == 0x3F)
     16     {
     17         printf("	反向约定
    ");
     18     }
     19     else
     20     {
     21         printf("	ATR 错误
    ");
     22     }
     23 }
     24 void atr_T0(unsigned char ch)
     25 {
     26     printf("T0: %02X
    ", ch);
     27     
     28     if ((ch & TA_BIT) == TA_BIT)
     29     {
     30         printf("	TA1 存在
    ");
     31     }
     32     if ((ch & TB_BIT) == TB_BIT)
     33     {
     34         printf("	TB1 存在
    ");
     35     }
     36     if ((ch & TC_BIT) == TC_BIT)
     37     {
     38         printf("	TC1 存在
    ");
     39     }
     40     if ((ch & TD_BIT) == TD_BIT)
     41     {
     42         printf("	TD1 存在
    ");
     43     }
     44     printf("	历史字符数: %d
    ", ch & 0x0f);    
     45 }
     46 void atr_TA1(unsigned char ch)
     47 {
     48     int Di[16] = { 0, 1, 2, 4, 8, 16, 32, 64, 
     49         12, 20, 0, 0, 0, 0, 0, 0 };
     50     int Fi[16] = { 372, 372, 558, 744, 1116, 1488, 1860, 0, 
     51         0, 512, 768, 1024, 1536, 2048, 0, 0 };
     52     
     53     printf("TA1: %02X
    ", ch);
     54     printf("	时钟速率转换因子Fi: %d
    ", (ch >> 4) & 0x0f);
     55     printf("	位速率调节因子Di: %d
    ", (ch & 0x0f));
     56     printf("	Fi/Di: %f
    ", 
     57         (Fi[(ch>>4)&0x0f]!=0 && Di[ch&0x0f]!=0) ? (float)Fi[(ch>>4)&0x0f]/(float)Di[ch&0x0f] : 0);
     58 }
     59 void atr_TB1(unsigned char ch)
     60 {
     61     printf("TB1: %02X
    ", ch);
     62     printf("	编程电压 P 值: %d
    ", ch & 0x1f);
     63     printf("	最大编程电流 I 值: %d
    ", (ch >> 5) & 0x03);
     64 }
     65 void atr_TC1(unsigned char ch)
     66 {
     67     printf("TC1: %02X
    ", ch);
     68     printf("	额外保护时间: %d
    ", ch);
     69 }
     70 void atr_TD1(unsigned char ch)
     71 {
     72     printf("TD1: %02X
    ", ch);
     73     
     74     if ((ch & TA_BIT) == TA_BIT)
     75     {
     76         printf("	TA2 存在
    ");
     77     }
     78     if ((ch & TB_BIT) == TB_BIT)
     79     {
     80         printf("	TB2 存在
    ");
     81     }
     82     if ((ch & TC_BIT) == TC_BIT)
     83     {
     84         printf("	TC2 存在
    ");
     85     }
     86     if ((ch & TD_BIT) == TD_BIT)
     87     {
     88         printf("	TD2 存在
    ");
     89     }
     90     printf("	后续信息交换所使用的协议类型: %d
    ", ch & 0x0f);    
     91 }
     92 void atr_TA2(unsigned char ch)
     93 {
     94     printf("TA2: %02X
    ", ch);
     95     printf("	是否有能力改变它的操作模式: %s
    ", 
     96         !!!(ch & 0x80) ? "是(0)" : "否(1)");
     97     printf("	协商模式 or 特定模式: %s
    ", 
     98         !!!(ch & 0x80) ? "特定模式(0)" : "协商模式(1)");
     99     printf("	后续信息交换所使用的协议类型: %d
    ", ch & 0x0f);    
    100 }
    101 void atr_TB2(unsigned char ch)
    102 {
    103     printf("TB2: %02X
    ", ch);
    104     printf("	IC卡所需的编程电压P的值PI2: %d
    ", ch);
    105 }
    106 void atr_TC2(unsigned char ch)
    107 {
    108     printf("TC2: %02X
    ", ch);
    109     printf("	T=0, 传输工作等待时间整数WI: %d
    ", ch);
    110 }
    111 void atr_TD2(unsigned char ch)
    112 {
    113     printf("TD2: %02X
    ", ch);
    114     
    115     if ((ch & TA_BIT) == TA_BIT)
    116     {
    117         printf("	TA3 存在
    ");
    118     }
    119     if ((ch & TB_BIT) == TB_BIT)
    120     {
    121         printf("	TB3 存在
    ");
    122     }
    123     if ((ch & TC_BIT) == TC_BIT)
    124     {
    125         printf("	TC3 存在
    ");
    126     }
    127     if ((ch & TD_BIT) == TD_BIT)
    128     {
    129         printf("	TD3 存在
    ");
    130     }
    131     printf("	后续信息交换所使用的协议类型: %d
    ", ch & 0x0f);    
    132 }
    133 void atr_TA3(unsigned char ch)
    134 {
    135     printf("TA3: %02X
    ", ch);
    136     printf("	T=1, IC卡的信息域大小整数IFSI: %d
    ", ch);
    137 }
    138 void atr_TB3(unsigned char ch)
    139 {
    140     printf("TB3: %02X
    ", ch);
    141     printf("	T=1, CWI: %d
    ", ch & 0x0f);
    142     printf("	T=1, BWI: %d
    ", (ch >> 4) & 0x0f);
    143 }
    144 void atr_TC3(unsigned char ch)
    145 {
    146     printf("TC3: %02X
    ", ch);
    147     printf("	T=1, 块错误校验码的类型: %d
    ", ch & 0x01);
    148 }
    149 void atr_history(unsigned char *ch, int len)
    150 {
    151     int i;
    152     printf("TKi:");
    153     for(i = 0; i < len; i++)
    154         printf(" %02X", ch[i]);
    155     printf("
    ");
    156 }
    157 void atr_TCK(unsigned char ch)
    158 {
    159     printf("TCK: %02X
    ", ch);
    160 }
    161 
    162 #define STATE_PARSE_TS                            1
    163 #define STATE_PARSE_T0                            2
    164 #define STATE_PARSE_TA                            3
    165 #define STATE_PARSE_TB                            4
    166 #define STATE_PARSE_TC                            5
    167 #define STATE_PARSE_TD                            6
    168 #define STATE_PARSE_HIST_BYTES                    7
    169 #define STATE_PARSE_TCK                            8
    170 #define STATE_PARSE_END                            255
    171 
    172 int atr_parse(unsigned char *atr, int len)
    173 {
    174     unsigned char data;
    175     unsigned char TCK = 0;
    176     unsigned char K = 0;
    177     unsigned char Yi = 0;
    178     int k, state, index, length, protocol;    
    179     unsigned char *ptr;
    180     unsigned char hist_bytes[16];
    181     
    182 
    183     length = len;
    184     ptr = atr;
    185     state = STATE_PARSE_TS;
    186     index = 0;
    187     k = 0;
    188     protocol = 0;
    189     
    190     while( ptr < (atr + length) )
    191     {
    192         data = *ptr++;
    193         if ( state != STATE_PARSE_TS )
    194         {
    195             TCK ^= data ;
    196         }
    197         
    198         switch( state )
    199         {
    200             case STATE_PARSE_TS:
    201                 atr_TS(data);
    202                 state = STATE_PARSE_T0;
    203                 break;
    204             case STATE_PARSE_T0:
    205                 atr_T0(data);
    206                 K = data & 0x0F;
    207                 Yi = data;
    208                 if ( data & 0x10 )
    209                 {
    210                     state = STATE_PARSE_TA;
    211                 }
    212                 else if ( data & 0x20 )
    213                 {
    214                     state = STATE_PARSE_TB;
    215                 }
    216                 else
    217                 {
    218                     if ( data & 0x40 )
    219                     {
    220                         state = STATE_PARSE_TC;
    221                     }
    222                     else if ( data & 0x80 )
    223                     {
    224                         state = STATE_PARSE_TD;
    225                     }
    226                     else
    227                     {
    228                         state = STATE_PARSE_HIST_BYTES;
    229                     }
    230                 }
    231                 break;
    232             case STATE_PARSE_TA :
    233                 switch( index )
    234                 {
    235                     case 0:            /* TA1 */            
    236                         atr_TA1(data);
    237                         break;
    238                     case 1:                    
    239                         atr_TA2(data);
    240                         break;
    241                     case 2:                    
    242                         atr_TA3(data);
    243                         break;
    244                 }
    245                 if ( Yi & 0x20 )
    246                 {
    247                     state = STATE_PARSE_TB;
    248                 }
    249                 else if ( Yi & 0x40 )
    250                 {
    251                     state = STATE_PARSE_TC;
    252                 }
    253                 else if ( Yi & 0x80 )
    254                 {
    255                     state = STATE_PARSE_TD;
    256                 }
    257                 else
    258                 {
    259                     state = STATE_PARSE_HIST_BYTES;
    260                 }
    261                 break;
    262             case STATE_PARSE_TB :
    263                 switch( index )
    264                 {
    265                     case 0:            /* TB1 */
    266                         atr_TB1(data);
    267                         break ;
    268                     case 1:            /* TB2 */
    269                         atr_TB2(data);
    270                         break ;
    271                     case 2:            /* TB3 */
    272                         atr_TB3(data);
    273                         break;
    274                 }
    275                  if ( Yi & 0x40 )
    276                  {
    277                     state = STATE_PARSE_TC;
    278                  }
    279                 else if ( Yi & 0x80 )
    280                 {
    281                     state = STATE_PARSE_TD;
    282                 }
    283                 else
    284                 {
    285                     state = STATE_PARSE_HIST_BYTES;
    286                 }
    287                 break;
    288             case STATE_PARSE_TC :
    289                 switch( index )
    290                 {
    291                     case 0:            /* TC1 */
    292                         atr_TC1(data);
    293                         break;
    294                     case 1:            /* TC2 */
    295                         atr_TC2(data);
    296                         break ;
    297                     case 2:            /* TC3 */
    298                         atr_TC3(data);
    299                         break ;
    300                 }
    301                  if ( Yi & 0x80 )
    302                  {
    303                     state = STATE_PARSE_TD;
    304                  }
    305                 else
    306                 {
    307                     state = STATE_PARSE_HIST_BYTES;
    308                 }
    309                 break ;
    310             case STATE_PARSE_TD :
    311                 Yi = data ;
    312                 switch( index++ )
    313                 {
    314                     case 0:
    315                         protocol = Yi & 0x0F;        
    316                         atr_TD1(data);
    317                         break;
    318                     case 1:
    319                         atr_TD2(data);
    320                         break;
    321                 }
    322     
    323                 if ( Yi & 0xF0 )
    324                 {
    325                     if ( Yi & 0x10 )
    326                     {
    327                         /* TAx character present */
    328                         state = STATE_PARSE_TA;
    329                     }
    330                     else if ( Yi & 0x20 )
    331                     {
    332                         /* TBx character present */
    333                         state = STATE_PARSE_TB;
    334                     }
    335                     else if ( Yi & 0x40 )
    336                     {
    337                         /* TCx character present */
    338                         state = STATE_PARSE_TC;
    339                     }
    340                     else if ( Yi & 0x80 )
    341                     {
    342                         /* TDx character present */
    343                         state = STATE_PARSE_TD;
    344                     }
    345                     else
    346                     {
    347                         state = STATE_PARSE_HIST_BYTES;
    348                     }
    349                 }
    350                 else
    351                 {
    352                     state = STATE_PARSE_HIST_BYTES;
    353                 }
    354                 break ;
    355             case STATE_PARSE_HIST_BYTES:
    356                 if( K )
    357                 {
    358                     if( k < K )
    359                     {
    360                         hist_bytes[k++] = data;
    361                         if(k == K)
    362                         {
    363                             if(protocol > 0)
    364                                 state = STATE_PARSE_TCK;
    365                             else
    366                                 ptr = atr + length;
    367                             
    368                             atr_history(hist_bytes, k);
    369                         }    
    370                     }
    371                     break;    
    372                 }
    373             case STATE_PARSE_TCK:
    374                 atr_TCK(data);
    375                 if ( !TCK )
    376                 {
    377                 }
    378                 atr_TCK(TCK);
    379                 ptr = atr + length;
    380                 break ;
    381         }
    382         if( state == STATE_PARSE_HIST_BYTES && K == 0 && protocol == 0)
    383             break;
    384     }
    385     
    386     return 0;
    387 }
    388 
    389 int main(void)
    390 {
    391     //atr_TA2((0 << 7) | (0 << 4) | 0x01);
    392     //atr_TA2((0 << 7) | (1 << 4) | 0x01);
    393     //atr_TA2((1 << 7) | (0 << 4) | 0x01);
    394     //atr_TA2((1 << 7) | (1 << 4) | 0x01);
    395     //atr_TA1(0x11);    
    396     
    397     //unsigned char atr1[] = {0x3B, 0xB5, 0x11, 0x00, 0x81, 0x31, 0x46, 0x15, 0x56, 0x20, 0x31, 0x2E, 0x50, 0x1E};
    398     //unsigned char atr2[] = {0x3B, 0x9C, 0x11, 0x81, 0x21, 0x34, 0x53, 0x43, 0x20, 0x53, 0x56, 0x20, 0x31, 0x2E, 0x31, 0x20, 0x4E, 0x43, 0x0F};
    399     //unsigned char atr3[] = {0x3B, 0x89, 0x40, 0x14, 0x47, 0x47, 0x32, 0x34, 0x4d, 0x35, 0x32, 0x38, 0x30};
    400     unsigned char atr[]  = {0x3f, 0x23, 0x00, 0x80, 0x69, 0xae};
    401     
    402     atr_parse(atr, sizeof(atr)/sizeof(atr[0]));
    403     
    404     return 0;
    405 }
  • 相关阅读:
    Python基本语法_输入/输出语句详解
    集成骨骼动画Spine的几点经验
    标量 ,数组,hash 引用
    阿里RDS中插入emoji 表情插入失败的解决方案
    Target runtime Apache Tomcat v7.0 is not defined.
    销售行业ERP数据统计分析都有哪些维度?
    mysql 基于时间点恢复
    perl 闭包
    房地产企业营销分析系统建设中的关键性指标是什么?
    Python基本语法_运算符详解
  • 原文地址:https://www.cnblogs.com/utank/p/5545750.html
Copyright © 2011-2022 走看看