輸入的是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\r\n", ch); 11 if(ch == 0x3B) 12 { 13 printf("\t正向約定\r\n"); 14 } 15 else if(ch == 0x3F) 16 { 17 printf("\t反向約定\r\n"); 18 } 19 else 20 { 21 printf("\tATR 錯誤\r\n"); 22 } 23 } 24 void atr_T0(unsigned char ch) 25 { 26 printf("T0: %02X\r\n", ch); 27 28 if ((ch & TA_BIT) == TA_BIT) 29 { 30 printf("\tTA1 存在\r\n"); 31 } 32 if ((ch & TB_BIT) == TB_BIT) 33 { 34 printf("\tTB1 存在\r\n"); 35 } 36 if ((ch & TC_BIT) == TC_BIT) 37 { 38 printf("\tTC1 存在\r\n"); 39 } 40 if ((ch & TD_BIT) == TD_BIT) 41 { 42 printf("\tTD1 存在\r\n"); 43 } 44 printf("\t歷史字符數: %d\r\n", 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\r\n", ch); 54 printf("\t時鍾速率轉換因子Fi: %d\r\n", (ch >> 4) & 0x0f); 55 printf("\t位速率調節因子Di: %d\r\n", (ch & 0x0f)); 56 printf("\tFi/Di: %f\r\n", 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\r\n", ch); 62 printf("\t編程電壓 P 值: %d\r\n", ch & 0x1f); 63 printf("\t最大編程電流 I 值: %d\r\n", (ch >> 5) & 0x03); 64 } 65 void atr_TC1(unsigned char ch) 66 { 67 printf("TC1: %02X\r\n", ch); 68 printf("\t額外保護時間: %d\r\n", ch); 69 } 70 void atr_TD1(unsigned char ch) 71 { 72 printf("TD1: %02X\r\n", ch); 73 74 if ((ch & TA_BIT) == TA_BIT) 75 { 76 printf("\tTA2 存在\r\n"); 77 } 78 if ((ch & TB_BIT) == TB_BIT) 79 { 80 printf("\tTB2 存在\r\n"); 81 } 82 if ((ch & TC_BIT) == TC_BIT) 83 { 84 printf("\tTC2 存在\r\n"); 85 } 86 if ((ch & TD_BIT) == TD_BIT) 87 { 88 printf("\tTD2 存在\r\n"); 89 } 90 printf("\t后續信息交換所使用的協議類型: %d\r\n", ch & 0x0f); 91 } 92 void atr_TA2(unsigned char ch) 93 { 94 printf("TA2: %02X\r\n", ch); 95 printf("\t是否有能力改變它的操作模式: %s\r\n", 96 !!!(ch & 0x80) ? "是(0)" : "否(1)"); 97 printf("\t協商模式 or 特定模式: %s\r\n", 98 !!!(ch & 0x80) ? "特定模式(0)" : "協商模式(1)"); 99 printf("\t后續信息交換所使用的協議類型: %d\r\n", ch & 0x0f); 100 } 101 void atr_TB2(unsigned char ch) 102 { 103 printf("TB2: %02X\r\n", ch); 104 printf("\tIC卡所需的編程電壓P的值PI2: %d\r\n", ch); 105 } 106 void atr_TC2(unsigned char ch) 107 { 108 printf("TC2: %02X\r\n", ch); 109 printf("\tT=0, 傳輸工作等待時間整數WI: %d\r\n", ch); 110 } 111 void atr_TD2(unsigned char ch) 112 { 113 printf("TD2: %02X\r\n", ch); 114 115 if ((ch & TA_BIT) == TA_BIT) 116 { 117 printf("\tTA3 存在\r\n"); 118 } 119 if ((ch & TB_BIT) == TB_BIT) 120 { 121 printf("\tTB3 存在\r\n"); 122 } 123 if ((ch & TC_BIT) == TC_BIT) 124 { 125 printf("\tTC3 存在\r\n"); 126 } 127 if ((ch & TD_BIT) == TD_BIT) 128 { 129 printf("\tTD3 存在\r\n"); 130 } 131 printf("\t后續信息交換所使用的協議類型: %d\r\n", ch & 0x0f); 132 } 133 void atr_TA3(unsigned char ch) 134 { 135 printf("TA3: %02X\r\n", ch); 136 printf("\tT=1, IC卡的信息域大小整數IFSI: %d\r\n", ch); 137 } 138 void atr_TB3(unsigned char ch) 139 { 140 printf("TB3: %02X\r\n", ch); 141 printf("\tT=1, CWI: %d\r\n", ch & 0x0f); 142 printf("\tT=1, BWI: %d\r\n", (ch >> 4) & 0x0f); 143 } 144 void atr_TC3(unsigned char ch) 145 { 146 printf("TC3: %02X\r\n", ch); 147 printf("\tT=1, 塊錯誤校驗碼的類型: %d\r\n", 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("\r\n"); 156 } 157 void atr_TCK(unsigned char ch) 158 { 159 printf("TCK: %02X\r\n", 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 }