libnfc 1.4.2
|
00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library examples 00003 * 00004 * Copyright (C) 2009, Roel Verdult 00005 * Copyright (C) 2010, Romuald Conty, Romain Tartière 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are met: 00009 * 1) Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * 2 )Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00019 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 * POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 * Note that this license only applies on the examples, NFC library itself is under LGPL 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 // Calculate the parity bits for the command 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 // Print the rest bits 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 // Print the rest bits, these cannot have parity bit 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 // Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select) 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) { // TA(1) present 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) { // TB(1) present 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) { // TC(1) present 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) { // Omit 2 CRC bytes 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) { // Omit 2 CRC bytes 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) { // Omit 2 CRC bytes 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 // Other matches not described in 00469 // AN MIFARE Type Identification Procedure 00470 // but seen in the field: 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 // Get commandline options 00635 for (arg = 1; arg < argc; arg++) { 00636 00637 if (0 == strcmp (argv[arg], "--device")) { 00638 // FIXME: this device selection by command line options is terrible & does not support USB/PCSC drivers 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 // Driver. 00647 pndd->pcDriver = (char *) malloc (256); 00648 strcpy (pndd->pcDriver, strtok (buffer, ":")); 00649 00650 // Port. 00651 pndd->pcPort = (char *) malloc (256); 00652 strcpy (pndd->pcPort, strtok (NULL, ":")); 00653 00654 // Speed. 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