00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <nfc/nfc.h>
00032 #include <err.h>
00033
00034 #include "nfc-utils.h"
00035
00036 static const byte_t OddParity[256] = {
00037 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00038 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00039 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00040 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00041 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00042 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00043 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00044 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00045 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00046 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00047 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00048 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00049 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
00050 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00051 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
00052 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
00053 };
00054
00055 byte_t
00056 oddparity (const byte_t bt)
00057 {
00058 return OddParity[bt];
00059 }
00060
00061 void
00062 oddparity_bytes_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar)
00063 {
00064 size_t szByteNr;
00065
00066 for (szByteNr = 0; szByteNr < szLen; szByteNr++) {
00067 pbtPar[szByteNr] = OddParity[pbtData[szByteNr]];
00068 }
00069 }
00070
00071 void
00072 print_hex (const byte_t * pbtData, const size_t szBytes)
00073 {
00074 size_t szPos;
00075
00076 for (szPos = 0; szPos < szBytes; szPos++) {
00077 printf ("%02x ", pbtData[szPos]);
00078 }
00079 printf ("\n");
00080 }
00081
00082 void
00083 print_hex_bits (const byte_t * pbtData, const size_t szBits)
00084 {
00085 uint8_t uRemainder;
00086 size_t szPos;
00087 size_t szBytes = szBits / 8;
00088
00089 for (szPos = 0; szPos < szBytes; szPos++) {
00090 printf ("%02x ", pbtData[szPos]);
00091 }
00092
00093 uRemainder = szBits % 8;
00094
00095 if (uRemainder != 0) {
00096 if (uRemainder < 5)
00097 printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
00098 else
00099 printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
00100 }
00101 printf ("\n");
00102 }
00103
00104 void
00105 print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar)
00106 {
00107 uint8_t uRemainder;
00108 size_t szPos;
00109 size_t szBytes = szBits / 8;
00110
00111 for (szPos = 0; szPos < szBytes; szPos++) {
00112 printf ("%02x", pbtData[szPos]);
00113 if (OddParity[pbtData[szPos]] != pbtDataPar[szPos]) {
00114 printf ("! ");
00115 } else {
00116 printf (" ");
00117 }
00118 }
00119
00120 uRemainder = szBits % 8;
00121
00122 if (uRemainder != 0) {
00123 if (uRemainder < 5)
00124 printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
00125 else
00126 printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
00127 }
00128 printf ("\n");
00129 }
00130
00131 #define SAK_UID_NOT_COMPLETE 0x04
00132 #define SAK_ISO14443_4_COMPLIANT 0x20
00133 #define SAK_ISO18092_COMPLIANT 0x40
00134
00135 void
00136 print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
00137 {
00138 printf (" ATQA (SENS_RES): ");
00139 print_hex (nai.abtAtqa, 2);
00140 if (verbose) {
00141 printf("* UID size: ");
00142 switch ((nai.abtAtqa[1] & 0xc0)>>6) {
00143 case 0:
00144 printf("single\n");
00145 break;
00146 case 1:
00147 printf("double\n");
00148 break;
00149 case 2:
00150 printf("triple\n");
00151 break;
00152 case 3:
00153 printf("RFU\n");
00154 break;
00155 }
00156 printf("* bit frame anticollision ");
00157 switch (nai.abtAtqa[1] & 0x1f) {
00158 case 0x01:
00159 case 0x02:
00160 case 0x04:
00161 case 0x08:
00162 case 0x10:
00163 printf("supported\n");
00164 break;
00165 default:
00166 printf("not supported\n");
00167 break;
00168 }
00169 }
00170 printf (" UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1'));
00171 print_hex (nai.abtUid, nai.szUidLen);
00172 if (verbose) {
00173 if (nai.abtUid[0] == 0x08) {
00174 printf ("* Random UID\n");
00175 }
00176 }
00177 printf (" SAK (SEL_RES): ");
00178 print_hex (&nai.btSak, 1);
00179 if (verbose) {
00180 if (nai.btSak & SAK_UID_NOT_COMPLETE) {
00181 printf ("* Warning! Cascade bit set: UID not complete\n");
00182 }
00183 if (nai.btSak & SAK_ISO14443_4_COMPLIANT) {
00184 printf ("* Compliant with ISO/IEC 14443-4\n");
00185 } else {
00186 printf ("* Not compliant with ISO/IEC 14443-4\n");
00187 }
00188 if (nai.btSak & SAK_ISO18092_COMPLIANT) {
00189 printf ("* Compliant with ISO/IEC 18092\n");
00190 } else {
00191 printf ("* Not compliant with ISO/IEC 18092\n");
00192 }
00193 }
00194 if (nai.szAtsLen) {
00195 printf (" ATS: ");
00196 print_hex (nai.abtAts, nai.szAtsLen);
00197 }
00198 if (nai.szAtsLen && verbose) {
00199
00200 const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
00201 printf ("* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[nai.abtAts[0] & 0x0F]);
00202
00203 size_t offset = 1;
00204 if (nai.abtAts[0] & 0x10) {
00205 byte_t TA = nai.abtAts[offset];
00206 offset++;
00207 printf ("* Bit Rate Capability:\n");
00208 if (TA == 0) {
00209 printf (" * PICC supports only 106 kbits/s in both directions\n");
00210 }
00211 if (TA & 1<<7) {
00212 printf (" * Same bitrate in both directions mandatory\n");
00213 }
00214 if (TA & 1<<4) {
00215 printf (" * PICC to PCD, DS=2, bitrate 212 kbits/s supported\n");
00216 }
00217 if (TA & 1<<5) {
00218 printf (" * PICC to PCD, DS=4, bitrate 424 kbits/s supported\n");
00219 }
00220 if (TA & 1<<6) {
00221 printf (" * PICC to PCD, DS=8, bitrate 847 kbits/s supported\n");
00222 }
00223 if (TA & 1<<0) {
00224 printf (" * PCD to PICC, DR=2, bitrate 212 kbits/s supported\n");
00225 }
00226 if (TA & 1<<1) {
00227 printf (" * PCD to PICC, DR=4, bitrate 424 kbits/s supported\n");
00228 }
00229 if (TA & 1<<2) {
00230 printf (" * PCD to PICC, DR=8, bitrate 847 kbits/s supported\n");
00231 }
00232 if (TA & 1<<3) {
00233 printf (" * ERROR unknown value\n");
00234 }
00235 }
00236 if (nai.abtAts[0] & 0x20) {
00237 byte_t TB= nai.abtAts[offset];
00238 offset++;
00239 printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((TB & 0xf0) >> 4))/13560.0);
00240 if ((TB & 0x0f) == 0) {
00241 printf ("* No Start-up Frame Guard Time required\n");
00242 } else {
00243 printf ("* Start-up Frame Guard Time: %.4g ms\n",256.0*16.0*(1<<(TB & 0x0f))/13560.0);
00244 }
00245 }
00246 if (nai.abtAts[0] & 0x40) {
00247 byte_t TC = nai.abtAts[offset];
00248 offset++;
00249 if (TC & 0x1) {
00250 printf("* Node ADdress supported\n");
00251 } else {
00252 printf("* Node ADdress not supported\n");
00253 }
00254 if (TC & 0x2) {
00255 printf("* Card IDentifier supported\n");
00256 } else {
00257 printf("* Card IDentifier not supported\n");
00258 }
00259 }
00260 if (nai.szAtsLen > offset) {
00261 printf ("* Historical bytes Tk: " );
00262 print_hex (nai.abtAts + offset, (nai.szAtsLen - offset));
00263 byte_t CIB = nai.abtAts[offset];
00264 offset++;
00265 if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
00266 printf(" * Proprietary format\n");
00267 if (CIB == 0xc1) {
00268 printf(" * Tag byte: Mifare or virtual cards of various types\n");
00269 byte_t L = nai.abtAts[offset];
00270 offset++;
00271 if (L != (nai.szAtsLen - offset)) {
00272 printf(" * Warning: Type Identification Coding length (%i)", L);
00273 printf(" not matching Tk length (%zi)\n", (nai.szAtsLen - offset));
00274 }
00275 if ((nai.szAtsLen - offset - 2) > 0) {
00276 byte_t CTC = nai.abtAts[offset];
00277 offset++;
00278 printf(" * Chip Type: ");
00279 switch (CTC & 0xf0) {
00280 case 0x00:
00281 printf("(Multiple) Virtual Cards\n");
00282 break;
00283 case 0x10:
00284 printf("Mifare DESFire\n");
00285 break;
00286 case 0x20:
00287 printf("Mifare Plus\n");
00288 break;
00289 default:
00290 printf("RFU\n");
00291 break;
00292 }
00293 printf(" * Memory size: ");
00294 switch (CTC & 0x0f) {
00295 case 0x00:
00296 printf("<1 kbyte\n");
00297 break;
00298 case 0x01:
00299 printf("1 kbyte\n");
00300 break;
00301 case 0x02:
00302 printf("2 kbyte\n");
00303 break;
00304 case 0x03:
00305 printf("4 kbyte\n");
00306 break;
00307 case 0x04:
00308 printf("8 kbyte\n");
00309 break;
00310 case 0x0f:
00311 printf("Unspecified\n");
00312 break;
00313 default:
00314 printf("RFU\n");
00315 break;
00316 }
00317 }
00318 if ((nai.szAtsLen - offset) > 0) {
00319 byte_t CVC = nai.abtAts[offset];
00320 offset++;
00321 printf(" * Chip Status: ");
00322 switch (CVC & 0xf0) {
00323 case 0x00:
00324 printf("Engineering sample\n");
00325 break;
00326 case 0x20:
00327 printf("Released\n");
00328 break;
00329 default:
00330 printf("RFU\n");
00331 break;
00332 }
00333 printf(" * Chip Generation: ");
00334 switch (CVC & 0x0f) {
00335 case 0x00:
00336 printf("Generation 1\n");
00337 break;
00338 case 0x01:
00339 printf("Generation 2\n");
00340 break;
00341 case 0x02:
00342 printf("Generation 3\n");
00343 break;
00344 case 0x0f:
00345 printf("Unspecified\n");
00346 break;
00347 default:
00348 printf("RFU\n");
00349 break;
00350 }
00351 }
00352 if ((nai.szAtsLen - offset) > 0) {
00353 byte_t VCS = nai.abtAts[offset];
00354 offset++;
00355 printf(" * Specifics (Virtual Card Selection):\n");
00356 if ((VCS & 0x09) == 0x00) {
00357 printf(" * Only VCSL supported\n");
00358 } else if ((VCS & 0x09) == 0x01) {
00359 printf(" * VCS, VCSL and SVC supported\n");
00360 }
00361 if ((VCS & 0x0e) == 0x00) {
00362 printf(" * SL1, SL2(?), SL3 supported\n");
00363 } else if ((VCS & 0x0e) == 0x02) {
00364 printf(" * SL3 only card\n");
00365 } else if ((VCS & 0x0f) == 0x0e) {
00366 printf(" * No VCS command supported\n");
00367 } else if ((VCS & 0x0f) == 0x0f) {
00368 printf(" * Unspecified\n");
00369 } else {
00370 printf(" * RFU\n");
00371 }
00372 }
00373 }
00374 } else {
00375 if (CIB == 0x00) {
00376 printf(" * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n");
00377 printf(" followed by a mandatory status indicator (the last three bytes, not in TLV)\n");
00378 printf(" See ISO/IEC 7816-4 8.1.1.3 for more info\n");
00379 }
00380 if (CIB == 0x10) {
00381 printf(" * DIR data reference: %02x\n", nai.abtAts[offset]);
00382 }
00383 if (CIB == 0x80) {
00384 if (nai.szAtsLen == offset) {
00385 printf(" * No COMPACT-TLV objects found, no status found\n");
00386 } else {
00387 printf(" * Tk after 0x80 consist of optional consecutive COMPACT-TLV data objects;\n");
00388 printf(" the last data object may carry a status indicator of one, two or three bytes.\n");
00389 printf(" See ISO/IEC 7816-4 8.1.1.3 for more info\n");
00390 }
00391 }
00392 }
00393 }
00394 }
00395 if (verbose) {
00396 printf("Fingerprinting based on ATQA & SAK values:\n");
00397 uint32_t atqasak = 0;
00398 atqasak += (((uint32_t)nai.abtAtqa[0] & 0xff)<<16);
00399 atqasak += (((uint32_t)nai.abtAtqa[1] & 0xff)<<8);
00400 atqasak += ((uint32_t)nai.btSak & 0xff);
00401 bool found_possible_match = false;
00402 switch (atqasak) {
00403 case 0x000218:
00404 printf("* Mifare Classic 4K\n");
00405 found_possible_match = true;
00406 break;
00407 case 0x000408:
00408 printf("* Mifare Classic 1K\n");
00409 printf("* Mifare Plus (4-byte UID) 2K SL1\n");
00410 found_possible_match = true;
00411 break;
00412 case 0x000409:
00413 printf("* Mifare MINI\n");
00414 found_possible_match = true;
00415 break;
00416 case 0x000410:
00417 printf("* Mifare Plus (4-byte UID) 2K SL2\n");
00418 found_possible_match = true;
00419 break;
00420 case 0x000411:
00421 printf("* Mifare Plus (4-byte UID) 4K SL2\n");
00422 found_possible_match = true;
00423 break;
00424 case 0x000418:
00425 printf("* Mifare Plus (4-byte UID) 4K SL1\n");
00426 found_possible_match = true;
00427 break;
00428 case 0x000420:
00429 printf("* Mifare Plus (4-byte UID) 2K/4K SL3\n");
00430 found_possible_match = true;
00431 break;
00432 case 0x004400:
00433 printf("* Mifare Ultralight\n");
00434 printf("* Mifare UltralightC\n");
00435 found_possible_match = true;
00436 break;
00437 case 0x004208:
00438 case 0x004408:
00439 printf("* Mifare Plus (7-byte UID) 2K SL1\n");
00440 found_possible_match = true;
00441 break;
00442 case 0x004218:
00443 case 0x004418:
00444 printf("* Mifare Plus (7-byte UID) 4K SL1\n");
00445 found_possible_match = true;
00446 break;
00447 case 0x004210:
00448 case 0x004410:
00449 printf("* Mifare Plus (7-byte UID) 2K SL2\n");
00450 found_possible_match = true;
00451 break;
00452 case 0x004211:
00453 case 0x004411:
00454 printf("* Mifare Plus (7-byte UID) 4K SL2\n");
00455 found_possible_match = true;
00456 break;
00457 case 0x004220:
00458 case 0x004420:
00459 printf("* Mifare Plus (7-byte UID) 2K/4K SL3\n");
00460 found_possible_match = true;
00461 break;
00462 case 0x034420:
00463 printf("* Mifare DESFire / Desfire EV1\n");
00464 found_possible_match = true;
00465 break;
00466 }
00467
00468
00469
00470
00471 switch (atqasak) {
00472 case 0x000488:
00473 printf("* Mifare Classic 1K Infineon\n");
00474 found_possible_match = true;
00475 break;
00476 case 0x000298:
00477 printf("* Gemplus MPCOS\n");
00478 found_possible_match = true;
00479 break;
00480 case 0x030428:
00481 printf("* JCOP31\n");
00482 found_possible_match = true;
00483 break;
00484 case 0x004820:
00485 printf("* JCOP31 v2.4.1\n");
00486 printf("* JCOP31 v2.2\n");
00487 found_possible_match = true;
00488 break;
00489 case 0x000428:
00490 printf("* JCOP31 v2.3.1\n");
00491 found_possible_match = true;
00492 break;
00493 case 0x000453:
00494 printf("* Fudan FM1208SH01\n");
00495 found_possible_match = true;
00496 break;
00497 case 0x000820:
00498 printf("* Fudan FM1208\n");
00499 found_possible_match = true;
00500 break;
00501 case 0x000238:
00502 printf("* MFC 4K emulated by Nokia 6212 Classic\n");
00503 found_possible_match = true;
00504 break;
00505 case 0x000838:
00506 printf("* MFC 4K emulated by Nokia 6131 NFC\n");
00507 found_possible_match = true;
00508 break;
00509 }
00510 if ((nai.abtAtqa[0] & 0xf0) == 0) {
00511 switch (nai.abtAtqa[1]) {
00512 case 0x02:
00513 printf("* SmartMX with Mifare 4K emulation\n");
00514 found_possible_match = true;
00515 break;
00516 case 0x04:
00517 printf("* SmartMX with Mifare 1K emulation\n");
00518 found_possible_match = true;
00519 break;
00520 case 0x48:
00521 printf("* SmartMX with 7-byte UID\n");
00522 found_possible_match = true;
00523 break;
00524 }
00525 }
00526 if (! found_possible_match) {
00527 printf("* Unknown card, sorry\n");
00528 }
00529 }
00530 }
00531
00532 void
00533 print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose)
00534 {
00535 printf (" ID (NFCID2): ");
00536 print_hex (nfi.abtId, 8);
00537 printf (" Parameter (PAD): ");
00538 print_hex (nfi.abtPad, 8);
00539 }
00540
00541 void
00542 print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose)
00543 {
00544 printf (" ATQA (SENS_RES): ");
00545 print_hex (nji.btSensRes, 2);
00546 printf (" 4-LSB JEWELID: ");
00547 print_hex (nji.btId, 4);
00548 }
00549
00550 #define PI_ISO14443_4_SUPPORTED 0x01
00551 #define PI_NAD_SUPPORTED 0x01
00552 #define PI_CID_SUPPORTED 0x02
00553 void
00554 print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose)
00555 {
00556 const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
00557 printf (" PUPI: ");
00558 print_hex (nbi.abtPupi, 4);
00559 printf (" Application Data: ");
00560 print_hex (nbi.abtApplicationData, 4);
00561 printf (" Protocol Info: ");
00562 print_hex (nbi.abtProtocolInfo, 3);
00563 if (verbose) {
00564 printf ("* Bit Rate Capability:\n");
00565 if (nbi.abtProtocolInfo[0] == 0) {
00566 printf (" * PICC supports only 106 kbits/s in both directions\n");
00567 }
00568 if (nbi.abtProtocolInfo[0] & 1<<7) {
00569 printf (" * Same bitrate in both directions mandatory\n");
00570 }
00571 if (nbi.abtProtocolInfo[0] & 1<<4) {
00572 printf (" * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n");
00573 }
00574 if (nbi.abtProtocolInfo[0] & 1<<5) {
00575 printf (" * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n");
00576 }
00577 if (nbi.abtProtocolInfo[0] & 1<<6) {
00578 printf (" * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n");
00579 }
00580 if (nbi.abtProtocolInfo[0] & 1<<0) {
00581 printf (" * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n");
00582 }
00583 if (nbi.abtProtocolInfo[0] & 1<<1) {
00584 printf (" * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n");
00585 }
00586 if (nbi.abtProtocolInfo[0] & 1<<2) {
00587 printf (" * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n");
00588 }
00589 if (nbi.abtProtocolInfo[0] & 1<<3) {
00590 printf (" * ERROR unknown value\n");
00591 }
00592 if( (nbi.abtProtocolInfo[1] & 0xf0) <= 0x80 ) {
00593 printf ("* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((nbi.abtProtocolInfo[1] & 0xf0) >> 4)]);
00594 }
00595 if((nbi.abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) {
00596 printf ("* Protocol types supported: ISO/IEC 14443-4\n");
00597 }
00598 printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((nbi.abtProtocolInfo[2] & 0xf0) >> 4))/13560.0);
00599 if((nbi.abtProtocolInfo[2] & (PI_NAD_SUPPORTED|PI_CID_SUPPORTED)) != 0) {
00600 printf ("* Frame options supported: ");
00601 if ((nbi.abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) printf ("NAD ");
00602 if ((nbi.abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) printf ("CID ");
00603 printf("\n");
00604 }
00605 }
00606 }
00607
00608 void
00609 print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose)
00610 {
00611 printf (" NFCID3: ");
00612 print_hex (ndi.abtNFCID3, 10);
00613 printf (" BS: %02x\n", ndi.btBS);
00614 printf (" BR: %02x\n", ndi.btBR);
00615 printf (" TO: %02x\n", ndi.btTO);
00616 printf (" PP: %02x\n", ndi.btPP);
00617 if (ndi.szGB) {
00618 printf ("General Bytes: ");
00619 print_hex (ndi.abtGB, ndi.szGB);
00620 }
00621 }
00622
00627 nfc_device_desc_t *
00628 parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose)
00629 {
00630 nfc_device_desc_t *pndd = 0;
00631 int arg;
00632 *szFound = 0;
00633
00634
00635 for (arg = 1; arg < argc; arg++) {
00636
00637 if (0 == strcmp (argv[arg], "--device")) {
00638
00639 if (argc > arg + 1) {
00640 char buffer[256];
00641
00642 pndd = malloc (sizeof (nfc_device_desc_t));
00643
00644 strncpy (buffer, argv[++arg], 256);
00645
00646
00647 pndd->pcDriver = (char *) malloc (256);
00648 strcpy (pndd->pcDriver, strtok (buffer, ":"));
00649
00650
00651 pndd->pcPort = (char *) malloc (256);
00652 strcpy (pndd->pcPort, strtok (NULL, ":"));
00653
00654
00655 sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed);
00656
00657 *szFound = 1;
00658 } else {
00659 errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
00660 }
00661 }
00662 if ((0 == strcmp (argv[arg], "-v")) || (0 == strcmp (argv[arg], "--verbose"))) {
00663 *verbose = true;
00664 }
00665 }
00666 return pndd;
00667 }
00668
00669 const char *
00670 str_nfc_baud_rate (const nfc_baud_rate_t nbr)
00671 {
00672 switch(nbr) {
00673 case NBR_UNDEFINED:
00674 return "undefined baud rate";
00675 break;
00676 case NBR_106:
00677 return "106 kbps";
00678 break;
00679 case NBR_212:
00680 return "212 kbps";
00681 break;
00682 case NBR_424:
00683 return "424 kbps";
00684 break;
00685 case NBR_847:
00686 return "847 kbps";
00687 break;
00688 }
00689 return "";
00690 }
00691
00692 void
00693 print_nfc_target (const nfc_target_t nt, bool verbose)
00694 {
00695 switch(nt.nm.nmt) {
00696 case NMT_ISO14443A:
00697 printf ("ISO/IEC 14443A (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
00698 print_nfc_iso14443a_info (nt.nti.nai, verbose);
00699 break;
00700 case NMT_JEWEL:
00701 printf ("Innovision Jewel (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
00702 print_nfc_jewel_info (nt.nti.nji, verbose);
00703 break;
00704 case NMT_FELICA:
00705 printf ("FeliCa (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
00706 print_nfc_felica_info (nt.nti.nfi, verbose);
00707 break;
00708 case NMT_ISO14443B:
00709 printf ("ISO/IEC 14443-4B (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
00710 print_nfc_iso14443b_info (nt.nti.nbi, verbose);
00711 break;
00712 case NMT_DEP:
00713 printf ("D.E.P. (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
00714 print_nfc_dep_info (nt.nti.ndi, verbose);
00715 break;
00716 }
00717 }
00718