Examples: more ISO14443A info decoding & verbose mode for nfc-list

This commit is contained in:
Philippe Teuwen 2010-10-19 12:50:52 +00:00
parent f249af6266
commit 2b24a0a7f5
10 changed files with 366 additions and 98 deletions

View file

@ -67,7 +67,7 @@ main (int argc, const char *argv[])
nfc_perror(pnd, "nfc_initiator_select_dep_target"); nfc_perror(pnd, "nfc_initiator_select_dep_target");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
print_nfc_target (nt); print_nfc_target (nt, false);
printf ("Sending: %s\n", abtTx); printf ("Sending: %s\n", abtTx);
if (!nfc_initiator_transceive_bytes (pnd, abtTx, sizeof(abtTx), abtRx, &szRx)) { if (!nfc_initiator_transceive_bytes (pnd, abtTx, sizeof(abtTx), abtRx, &szRx)) {

View file

@ -86,7 +86,7 @@ main (int argc, const char *argv[])
printf ("Connected to NFC device: %s\n", pnd->acName); printf ("Connected to NFC device: %s\n", pnd->acName);
printf ("NFC device will now act as: "); printf ("NFC device will now act as: ");
print_nfc_target (nt); print_nfc_target (nt, false);
printf ("Waiting for initiator request...\n"); printf ("Waiting for initiator request...\n");
if(!nfc_target_init (pnd, &nt, abtRx, &szRx)) { if(!nfc_target_init (pnd, &nt, abtRx, &szRx)) {

View file

@ -206,7 +206,7 @@ main (int argc, char *argv[])
*/ */
printf ("%s will emulate this ISO14443-A tag:\n", argv[0]); printf ("%s will emulate this ISO14443-A tag:\n", argv[0]);
print_nfc_iso14443a_info( nt.nti.nai ); print_nfc_iso14443a_info( nt.nti.nai, false );
printf ("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n"); printf ("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n");
if (!nfc_target_emulate_tag (pnd, &nt)) { if (!nfc_target_emulate_tag (pnd, &nt)) {

View file

@ -13,6 +13,11 @@ limitation of the number of tags the reader can discover.
This tool displays all available information at selection time. This tool displays all available information at selection time.
.SH OPTIONS
\fB-v\fP, \fB--verbose\fP
Verbose mode
Tries to interpret data
.SH EXAMPLE .SH EXAMPLE
For an ISO/IEC 14443-A tag (i.e.Mifare DESFire): For an ISO/IEC 14443-A tag (i.e.Mifare DESFire):
@ -20,7 +25,6 @@ For an ISO/IEC 14443-A tag (i.e.Mifare DESFire):
UID (NFCID1): 04 45 35 01 db 24 80 UID (NFCID1): 04 45 35 01 db 24 80
SAK (SEL_RES): 20 SAK (SEL_RES): 20
ATS (ATR): 75 77 81 02 80 ATS (ATR): 75 77 81 02 80
Compliant with: ISO/IEC 14443-4
.SH BUGS .SH BUGS
Please report any bugs on the Please report any bugs on the

View file

@ -55,17 +55,14 @@ main (int argc, const char *argv[])
size_t szDeviceFound; size_t szDeviceFound;
size_t szTargetFound; size_t szTargetFound;
size_t i; size_t i;
bool verbose = false;
nfc_device_desc_t *pnddDevices; nfc_device_desc_t *pnddDevices;
// Display libnfc version // Display libnfc version
acLibnfcVersion = nfc_version (); acLibnfcVersion = nfc_version ();
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion); printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
pnddDevices = parse_device_desc (argc, argv, &szDeviceFound); pnddDevices = parse_args (argc, argv, &szDeviceFound, &verbose);
if (argc > 1 && szDeviceFound == 0) {
errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
}
#ifdef HAVE_LIBUSB #ifdef HAVE_LIBUSB
# ifdef DEBUG # ifdef DEBUG
usb_set_debug (4); usb_set_debug (4);
@ -126,9 +123,11 @@ main (int argc, const char *argv[])
}; };
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) { if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n; size_t n;
printf ("%d ISO14443A passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":"); if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443A passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) { for (n = 0; n < szTargetFound; n++) {
print_nfc_iso14443a_info (ant[n].nti.nai); print_nfc_iso14443a_info (ant[n].nti.nai, verbose);
printf ("\n"); printf ("\n");
} }
} }
@ -138,10 +137,12 @@ main (int argc, const char *argv[])
// List Felica tags // List Felica tags
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) { if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n; size_t n;
printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound, if (verbose || (szTargetFound > 0)) {
(szTargetFound == 0) ? ".\n" : ":"); printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) { for (n = 0; n < szTargetFound; n++) {
print_nfc_felica_info (ant[n].nti.nfi); print_nfc_felica_info (ant[n].nti.nfi, verbose);
printf ("\n"); printf ("\n");
} }
} }
@ -149,10 +150,12 @@ main (int argc, const char *argv[])
nm.nbr = NBR_424; nm.nbr = NBR_424;
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) { if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n; size_t n;
printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound, if (verbose || (szTargetFound > 0)) {
(szTargetFound == 0) ? ".\n" : ":"); printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) { for (n = 0; n < szTargetFound; n++) {
print_nfc_felica_info (ant[n].nti.nfi); print_nfc_felica_info (ant[n].nti.nfi, verbose);
printf ("\n"); printf ("\n");
} }
} }
@ -162,9 +165,11 @@ main (int argc, const char *argv[])
// List ISO14443B targets // List ISO14443B targets
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) { if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n; size_t n;
printf ("%d ISO14443B passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":"); if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443B passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) { for (n = 0; n < szTargetFound; n++) {
print_nfc_iso14443b_info (ant[n].nti.nbi); print_nfc_iso14443b_info (ant[n].nti.nbi, verbose);
printf ("\n"); printf ("\n");
} }
} }
@ -174,9 +179,11 @@ main (int argc, const char *argv[])
// List Jewel targets // List Jewel targets
if (nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound )) { if (nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound )) {
size_t n; size_t n;
printf("%d Jewel passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":"); if (verbose || (szTargetFound > 0)) {
printf("%d Jewel passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
}
for(n=0; n<szTargetFound; n++) { for(n=0; n<szTargetFound; n++) {
print_nfc_jewel_info (ant[n].nti.nji); print_nfc_jewel_info (ant[n].nti.nji, verbose);
printf("\n"); printf("\n");
} }
} }

View file

@ -46,8 +46,11 @@ main (int argc, const char *argv[])
{ {
size_t szFound; size_t szFound;
size_t i; size_t i;
bool verbose = false;
nfc_device_desc_t *pnddDevices; nfc_device_desc_t *pnddDevices;
pnddDevices = parse_args (argc, argv, &szFound, &verbose);
// Display libnfc version // Display libnfc version
const char *acLibnfcVersion = nfc_version (); const char *acLibnfcVersion = nfc_version ();
@ -57,9 +60,11 @@ main (int argc, const char *argv[])
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion); printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) { if (szFound == 0) {
fprintf (stderr, "malloc() failed\n"); if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
return EXIT_FAILURE; fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
} }
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound); nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
@ -118,7 +123,7 @@ main (int argc, const char *argv[])
printf ("%ld target(s) have been found.\n", (unsigned long) szTargetFound); printf ("%ld target(s) have been found.\n", (unsigned long) szTargetFound);
for (n = 0; n < szTargetFound; n++) { for (n = 0; n < szTargetFound; n++) {
printf ("T%d: ", n + 1); printf ("T%d: ", n + 1);
print_nfc_target ( antTargets[n] ); print_nfc_target ( antTargets[n], verbose );
} }
} else { } else {

View file

@ -249,7 +249,7 @@ main (int argc, char *argv[])
} }
printf("Found tag:\n"); printf("Found tag:\n");
print_nfc_iso14443a_info (ntRealTarget.nti.nai); print_nfc_iso14443a_info (ntRealTarget.nti.nai, false);
if (initiator_only_mode) { if (initiator_only_mode) {
if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") != EXIT_SUCCESS) { if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") != EXIT_SUCCESS) {
fprintf (stderr, "Error while printing UID to FD4\n"); fprintf (stderr, "Error while printing UID to FD4\n");
@ -340,7 +340,7 @@ main (int argc, char *argv[])
memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk); memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk);
printf("We will emulate:\n"); printf("We will emulate:\n");
print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai); print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai, false);
// Try to open the NFC emulator device // Try to open the NFC emulator device
pndTarget = nfc_connect (&(pnddDevices[0])); pndTarget = nfc_connect (&(pnddDevices[0]));

View file

@ -1,4 +1,5 @@
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include <err.h>
#include "nfc-utils.h" #include "nfc-utils.h"
@ -97,31 +98,74 @@ print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDa
printf ("\n"); printf ("\n");
} }
#define SAK_UID_NOT_COMPLETE 0x04
#define SAK_ISO14443_4_COMPLIANT 0x20 #define SAK_ISO14443_4_COMPLIANT 0x20
#define SAK_ISO18092_COMPLIANT 0x40 #define SAK_ISO18092_COMPLIANT 0x40
void void
print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai) print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
{ {
printf (" ATQA (SENS_RES): "); printf (" ATQA (SENS_RES): ");
print_hex (nai.abtAtqa, 2); print_hex (nai.abtAtqa, 2);
if (verbose) {
printf("* UID size: ");
switch ((nai.abtAtqa[1] & 0xc0)>>6) {
case 0:
printf("single\n");
break;
case 1:
printf("double\n");
break;
case 2:
printf("triple\n");
break;
case 3:
printf("RFU\n");
break;
}
printf("* bit frame anticollision ");
switch (nai.abtAtqa[1] & 0x1f) {
case 0x01:
case 0x02:
case 0x04:
case 0x08:
case 0x10:
printf("supported\n");
break;
default:
printf("not supported\n");
break;
}
}
printf (" UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1')); printf (" UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1'));
print_hex (nai.abtUid, nai.szUidLen); print_hex (nai.abtUid, nai.szUidLen);
if (verbose) {
if (nai.abtUid[0] == 0x08) {
printf ("* Random UID\n");
}
}
printf (" SAK (SEL_RES): "); printf (" SAK (SEL_RES): ");
print_hex (&nai.btSak, 1); print_hex (&nai.btSak, 1);
if ((nai.btSak & SAK_ISO14443_4_COMPLIANT) || (nai.btSak & SAK_ISO18092_COMPLIANT)) { if (verbose) {
printf ("* Compliant with: "); if (nai.btSak & SAK_UID_NOT_COMPLETE) {
if (nai.btSak & SAK_ISO14443_4_COMPLIANT) printf ("* Warning! Cascade bit set: UID not complete\n");
printf ("ISO/IEC 14443-4 "); }
if (nai.btSak & SAK_ISO18092_COMPLIANT) if (nai.btSak & SAK_ISO14443_4_COMPLIANT) {
printf ("ISO/IEC 18092"); printf ("* Compliant with ISO/IEC 14443-4\n");
printf ("\n"); } else {
printf ("* Not compliant with ISO/IEC 14443-4\n");
}
if (nai.btSak & SAK_ISO18092_COMPLIANT) {
printf ("* Compliant with ISO/IEC 18092\n");
} else {
printf ("* Not compliant with ISO/IEC 18092\n");
}
} }
if (nai.szAtsLen) { if (nai.szAtsLen) {
printf (" ATS: "); printf (" ATS: ");
print_hex (nai.abtAts, nai.szAtsLen); print_hex (nai.abtAts, nai.szAtsLen);
} }
if (nai.szAtsLen) { if (nai.szAtsLen && verbose) {
// Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select) // Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select)
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 }; const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
printf ("* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[nai.abtAts[0] & 0x0F]); printf ("* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[nai.abtAts[0] & 0x0F]);
@ -190,6 +234,113 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai)
offset++; offset++;
if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) { if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
printf(" * Proprietary format\n"); printf(" * Proprietary format\n");
if (CIB == 0xc1) {
printf(" * Tag byte: Mifare or virtual cards of various types\n");
byte_t L = nai.abtAts[offset];
offset++;
if (L != (nai.szAtsLen - offset)) {
printf(" * Warning: Type Identification Coding length (%i)", L);
printf(" not matching Tk length (%i)\n", (nai.szAtsLen - offset));
}
if ((nai.szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
byte_t CTC = nai.abtAts[offset];
offset++;
printf(" * Chip Type: ");
switch (CTC & 0xf0) {
case 0x00:
printf("(Multiple) Virtual Cards\n");
break;
case 0x10:
printf("Mifare DESFire\n");
break;
case 0x20:
printf("Mifare Plus\n");
break;
default:
printf("RFU\n");
break;
}
printf(" * Memory size: ");
switch (CTC & 0x0f) {
case 0x00:
printf("<1 kbyte\n");
break;
case 0x01:
printf("1 kbyte\n");
break;
case 0x02:
printf("2 kbyte\n");
break;
case 0x03:
printf("4 kbyte\n");
break;
case 0x04:
printf("8 kbyte\n");
break;
case 0x0f:
printf("Unspecified\n");
break;
default:
printf("RFU\n");
break;
}
}
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
byte_t CVC = nai.abtAts[offset];
offset++;
printf(" * Chip Status: ");
switch (CVC & 0xf0) {
case 0x00:
printf("Engineering sample\n");
break;
case 0x20:
printf("Released\n");
break;
default:
printf("RFU\n");
break;
}
printf(" * Chip Generation: ");
switch (CVC & 0x0f) {
case 0x00:
printf("Generation 1\n");
break;
case 0x01:
printf("Generation 2\n");
break;
case 0x02:
printf("Generation 3\n");
break;
case 0x0f:
printf("Unspecified\n");
break;
default:
printf("RFU\n");
break;
}
}
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
byte_t VCS = nai.abtAts[offset];
offset++;
printf(" * Specifics (Virtual Card Selection):\n");
if ((VCS & 0x09) == 0x00) {
printf(" * Only VCSL supported\n");
} else if ((VCS & 0x09) == 0x01) {
printf(" * VCS, VCSL and SVC supported\n");
}
if ((VCS & 0x0e) == 0x00) {
printf(" * SL1, SL2(?), SL3 supported\n");
} else if ((VCS & 0x0e) == 0x02) {
printf(" * SL3 only card\n");
} else if ((VCS & 0x0f) == 0x0e) {
printf(" * No VCS command supported\n");
} else if ((VCS & 0x0f) == 0x0f) {
printf(" * Unspecified\n");
} else {
printf(" * RFU\n");
}
}
}
} else { } else {
if (CIB == 0x00) { if (CIB == 0x00) {
printf(" * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n"); printf(" * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n");
@ -211,10 +362,106 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai)
} }
} }
} }
if (verbose) {
printf("Fingerprinting based on ATQA & SAK values:\n");
uint32_t atqasak = 0;
atqasak += (((uint32_t)nai.abtAtqa[0] & 0xff)<<16);
atqasak += (((uint32_t)nai.abtAtqa[1] & 0xff)<<8);
atqasak += ((uint32_t)nai.btSak & 0xff);
bool found_possible_match = false;
switch (atqasak) {
case 0x000218:
printf("* Mifare Classic 4K\n");
found_possible_match = true;
break;
case 0x000408:
printf("* Mifare Classic 1K\n");
printf("* Mifare Plus (4-byte UID) 2K SL1\n");
found_possible_match = true;
break;
case 0x000409:
printf("* Mifare MINI\n");
found_possible_match = true;
break;
case 0x000410:
printf("* Mifare Plus (4-byte UID) 2K SL2\n");
found_possible_match = true;
break;
case 0x000411:
printf("* Mifare Plus (4-byte UID) 4K SL2\n");
found_possible_match = true;
break;
case 0x000418:
printf("* Mifare Plus (4-byte UID) 4K SL1\n");
found_possible_match = true;
break;
case 0x000420:
printf("* Mifare Plus (4-byte UID) 2K/4K SL3\n");
found_possible_match = true;
break;
case 0x000488:
printf("* Mifare Classic 1K Infineon\n");
found_possible_match = true;
break;
case 0x004400:
printf("* Mifare Ultralight\n");
printf("* Mifare UltralightC\n");
found_possible_match = true;
break;
case 0x004208:
case 0x004408:
printf("* Mifare Plus (7-byte UID) 2K SL1\n");
found_possible_match = true;
break;
case 0x004218:
case 0x004418:
printf("* Mifare Plus (7-byte UID) 4K SL1\n");
found_possible_match = true;
break;
case 0x004210:
case 0x004410:
printf("* Mifare Plus (7-byte UID) 2K SL2\n");
found_possible_match = true;
break;
case 0x004211:
case 0x004411:
printf("* Mifare Plus (7-byte UID) 4K SL2\n");
found_possible_match = true;
break;
case 0x004220:
case 0x004420:
printf("* Mifare Plus (7-byte UID) 2K/4K SL3\n");
found_possible_match = true;
break;
case 0x034420:
printf("* Mifare DESFire / Desfire EV1\n");
found_possible_match = true;
break;
}
if ((nai.abtAtqa[0] & 0xf0) == 0) {
switch (nai.abtAtqa[1]) {
case 0x02:
printf("* SmartMX with Mifare 4K emulation\n");
found_possible_match = true;
break;
case 0x04:
printf("* SmartMX with Mifare 1K emulation\n");
found_possible_match = true;
break;
case 0x48:
printf("* SmartMX with 7-byte UID\n");
found_possible_match = true;
break;
}
}
if (! found_possible_match) {
printf("* Unknown card, sorry\n");
}
}
} }
void void
print_nfc_felica_info (const nfc_felica_info_t nfi) print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose)
{ {
printf (" ID (NFCID2): "); printf (" ID (NFCID2): ");
print_hex (nfi.abtId, 8); print_hex (nfi.abtId, 8);
@ -223,7 +470,7 @@ print_nfc_felica_info (const nfc_felica_info_t nfi)
} }
void void
print_nfc_jewel_info (const nfc_jewel_info_t nji) print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose)
{ {
printf (" ATQA (SENS_RES): "); printf (" ATQA (SENS_RES): ");
print_hex (nji.btSensRes, 2); print_hex (nji.btSensRes, 2);
@ -235,7 +482,7 @@ print_nfc_jewel_info (const nfc_jewel_info_t nji)
#define PI_NAD_SUPPORTED 0x01 #define PI_NAD_SUPPORTED 0x01
#define PI_CID_SUPPORTED 0x02 #define PI_CID_SUPPORTED 0x02
void void
print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi) print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose)
{ {
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 }; const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
printf (" PUPI: "); printf (" PUPI: ");
@ -244,51 +491,53 @@ print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi)
print_hex (nbi.abtApplicationData, 4); print_hex (nbi.abtApplicationData, 4);
printf (" Protocol Info: "); printf (" Protocol Info: ");
print_hex (nbi.abtProtocolInfo, 3); print_hex (nbi.abtProtocolInfo, 3);
printf ("* Bit Rate Capability:\n"); if (verbose) {
if (nbi.abtProtocolInfo[0] == 0) { printf ("* Bit Rate Capability:\n");
printf (" * PICC supports only 106 kbits/s in both directions\n"); if (nbi.abtProtocolInfo[0] == 0) {
} printf (" * PICC supports only 106 kbits/s in both directions\n");
if (nbi.abtProtocolInfo[0] & 1<<7) { }
printf (" * Same bitrate in both directions mandatory\n"); if (nbi.abtProtocolInfo[0] & 1<<7) {
} printf (" * Same bitrate in both directions mandatory\n");
if (nbi.abtProtocolInfo[0] & 1<<4) { }
printf (" * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n"); if (nbi.abtProtocolInfo[0] & 1<<4) {
} printf (" * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n");
if (nbi.abtProtocolInfo[0] & 1<<5) { }
printf (" * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n"); if (nbi.abtProtocolInfo[0] & 1<<5) {
} printf (" * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n");
if (nbi.abtProtocolInfo[0] & 1<<6) { }
printf (" * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n"); if (nbi.abtProtocolInfo[0] & 1<<6) {
} printf (" * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n");
if (nbi.abtProtocolInfo[0] & 1<<0) { }
printf (" * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n"); if (nbi.abtProtocolInfo[0] & 1<<0) {
} printf (" * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n");
if (nbi.abtProtocolInfo[0] & 1<<1) { }
printf (" * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n"); if (nbi.abtProtocolInfo[0] & 1<<1) {
} printf (" * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n");
if (nbi.abtProtocolInfo[0] & 1<<2) { }
printf (" * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n"); if (nbi.abtProtocolInfo[0] & 1<<2) {
} printf (" * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n");
if (nbi.abtProtocolInfo[0] & 1<<3) { }
printf (" * ERROR unknown value\n"); if (nbi.abtProtocolInfo[0] & 1<<3) {
} printf (" * ERROR unknown value\n");
if( (nbi.abtProtocolInfo[1] & 0xf0) <= 0x80 ) { }
printf ("* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((nbi.abtProtocolInfo[1] & 0xf0) >> 4)]); if( (nbi.abtProtocolInfo[1] & 0xf0) <= 0x80 ) {
} printf ("* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((nbi.abtProtocolInfo[1] & 0xf0) >> 4)]);
if((nbi.abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) { }
printf ("* Protocol types supported: ISO/IEC 14443-4\n"); if((nbi.abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) {
} printf ("* Protocol types supported: ISO/IEC 14443-4\n");
printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((nbi.abtProtocolInfo[2] & 0xf0) >> 4))/13560.0); }
if((nbi.abtProtocolInfo[2] & (PI_NAD_SUPPORTED|PI_CID_SUPPORTED)) != 0) { printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((nbi.abtProtocolInfo[2] & 0xf0) >> 4))/13560.0);
printf ("* Frame options supported: "); if((nbi.abtProtocolInfo[2] & (PI_NAD_SUPPORTED|PI_CID_SUPPORTED)) != 0) {
if ((nbi.abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) printf ("NAD "); printf ("* Frame options supported: ");
if ((nbi.abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) printf ("CID "); if ((nbi.abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) printf ("NAD ");
printf("\n"); if ((nbi.abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) printf ("CID ");
printf("\n");
}
} }
} }
void void
print_nfc_dep_info (const nfc_dep_info_t ndi) print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose)
{ {
printf (" NFCID3: "); printf (" NFCID3: ");
print_hex (ndi.abtNFCID3, 10); print_hex (ndi.abtNFCID3, 10);
@ -307,7 +556,7 @@ print_nfc_dep_info (const nfc_dep_info_t ndi)
* @return Returns the list of found device descriptions. * @return Returns the list of found device descriptions.
*/ */
nfc_device_desc_t * nfc_device_desc_t *
parse_device_desc (int argc, const char *argv[], size_t * szFound) parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose)
{ {
nfc_device_desc_t *pndd = 0; nfc_device_desc_t *pndd = 0;
int arg; int arg;
@ -317,7 +566,7 @@ parse_device_desc (int argc, const char *argv[], size_t * szFound)
for (arg = 1; arg < argc; arg++) { for (arg = 1; arg < argc; arg++) {
if (0 == strcmp (argv[arg], "--device")) { if (0 == strcmp (argv[arg], "--device")) {
// FIXME: this device selection by command line options is terrible & does not support USB/PCSC drivers
if (argc > arg + 1) { if (argc > arg + 1) {
char buffer[256]; char buffer[256];
@ -337,11 +586,14 @@ parse_device_desc (int argc, const char *argv[], size_t * szFound)
sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed); sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed);
*szFound = 1; *szFound = 1;
} else {
errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
} }
break; }
if ((0 == strcmp (argv[arg], "-v")) || (0 == strcmp (argv[arg], "--verbose"))) {
*verbose = true;
} }
} }
return pndd; return pndd;
} }
@ -366,28 +618,28 @@ str_nfc_baud_rate (const nfc_baud_rate_t nbr)
} }
void void
print_nfc_target (const nfc_target_t nt) print_nfc_target (const nfc_target_t nt, bool verbose)
{ {
switch(nt.nm.nmt) { switch(nt.nm.nmt) {
case NMT_ISO14443A: case NMT_ISO14443A:
printf ("ISO/IEC 14443A (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); printf ("ISO/IEC 14443A (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443a_info (nt.nti.nai); print_nfc_iso14443a_info (nt.nti.nai, verbose);
break; break;
case NMT_JEWEL: case NMT_JEWEL:
printf ("Innovision Jewel (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); printf ("Innovision Jewel (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_jewel_info (nt.nti.nji); print_nfc_jewel_info (nt.nti.nji, verbose);
break; break;
case NMT_FELICA: case NMT_FELICA:
printf ("FeliCa (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); printf ("FeliCa (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_felica_info (nt.nti.nfi); print_nfc_felica_info (nt.nti.nfi, verbose);
break; break;
case NMT_ISO14443B: case NMT_ISO14443B:
printf ("ISO/IEC 14443-4B (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); printf ("ISO/IEC 14443-4B (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443b_info (nt.nti.nbi); print_nfc_iso14443b_info (nt.nti.nbi, verbose);
break; break;
case NMT_DEP: case NMT_DEP:
printf ("D.E.P. (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); printf ("D.E.P. (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_dep_info (nt.nti.ndi); print_nfc_dep_info (nt.nti.ndi, verbose);
break; break;
} }
} }

View file

@ -34,14 +34,14 @@ void print_hex (const byte_t * pbtData, const size_t szLen);
void print_hex_bits (const byte_t * pbtData, const size_t szBits); void print_hex_bits (const byte_t * pbtData, const size_t szBits);
void print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar); void print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar);
void print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai); void print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose);
void print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi); void print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose);
void print_nfc_felica_info (const nfc_felica_info_t nfi); void print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose);
void print_nfc_jewel_info (const nfc_jewel_info_t nji); void print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose);
void print_nfc_dep_info (const nfc_dep_info_t ndi); void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose);
void print_nfc_target (const nfc_target_t nt); void print_nfc_target (const nfc_target_t nt, bool verbose);
nfc_device_desc_t *parse_device_desc (int argc, const char *argv[], size_t * szFound); nfc_device_desc_t *parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose);
#endif #endif

View file

@ -192,7 +192,7 @@ main (int argc, const char *argv[])
} }
printf ("The following ISO14443A tag (SAM) was found:\n\n"); printf ("The following ISO14443A tag (SAM) was found:\n\n");
print_nfc_iso14443a_info (nt.nti.nai); print_nfc_iso14443a_info (nt.nti.nai, true);
} }
break; break;