MERGE (less-strange-types): Clean up libnfc's types.

* Old nfc_modulation_t became pn53x_modulation_t (not accessible from API);
  * Old nfc_target_type_t became pn53x_target_type_t (not accessible from API);
  * New nfc_modulation_type_t (NMT_ISO14443A, NMT_ISO14443B, NMT_JEWEL, etc.);
  * New nfc_baud_rate_t (NBR_106, NBR_212, etc.);
  * New nfc_modulation_t that contains a couple { nfc_modulation_type_t, nfc_baud_rate_t };
  * nfc_target_t now have nfc_modulation_t instead of the old strange nfc_target_type_t;
  * Move some pn53x oriented code from nfc.c to chips/pn53x.c (pn53x_initiator_select_passive_target);
  * New nfc_dep_mode_t type to handle ACTIVE/PASSIVE mode of DEP;
  * Split logical part and wrapping part for InAutoPoll;
  * Add conversion functions: nfc types to pn53x types, and vice versa;
  * examples/nfc-utils: Add print_nfc_target() and str_nfc_baud_rate() to display nfc_target_t;
  * Add manual test results.
This commit is contained in:
Romuald Conty 2010-10-14 10:28:01 +00:00
commit f559838352
21 changed files with 581 additions and 336 deletions

View file

@ -32,7 +32,7 @@ main (int argc, const char *argv[])
printf ("Connected to NFC reader: %s\n", pnd->acName); printf ("Connected to NFC reader: %s\n", pnd->acName);
// Poll for a ISO14443A (MIFARE) tag // Poll for a ISO14443A (MIFARE) tag
if (nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { if (nfc_initiator_select_passive_target (pnd, PM_ISO14443A_106, NULL, 0, &nti)) {
printf ("The following (NFC) ISO14443A tag was found:\n"); printf ("The following (NFC) ISO14443A tag was found:\n");
printf (" ATQA (SENS_RES): "); printf (" ATQA (SENS_RES): ");
print_hex (nti.nai.abtAtqa, 2); print_hex (nti.nai.abtAtqa, 2);

View file

@ -62,7 +62,7 @@ main (int argc, const char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if(!nfc_initiator_select_dep_target (pnd, NM_PASSIVE_DEP, NULL, &nti)) { if(!nfc_initiator_select_dep_target (pnd, NDM_PASSIVE, NULL, &nti)) {
nfc_perror(pnd, "nfc_initiator_select_dep_target"); nfc_perror(pnd, "nfc_initiator_select_dep_target");
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View file

@ -66,7 +66,8 @@ main (int argc, const char *argv[])
} }
const nfc_target_t nt = { const nfc_target_t nt = {
.ntt = NTT_DEP_PASSIVE_106, .nm.nmt = NMT_DEP,
.nm.nbr = NBR_UNDEFINED,
.nti.ndi.abtNFCID3 = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0x00, 0x00 }, .nti.ndi.abtNFCID3 = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0x00, 0x00 },
.nti.ndi.szGB = 4, .nti.ndi.szGB = 4,
.nti.ndi.abtGB = { 0x12, 0x34, 0x56, 0x78 }, .nti.ndi.abtGB = { 0x12, 0x34, 0x56, 0x78 },

View file

@ -112,7 +112,8 @@ main (int argc, char *argv[])
printf ("Emulating NDEF tag now, please touch it with a second NFC device\n"); printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
nfc_target_t nt = { nfc_target_t nt = {
.ntt = NTT_MIFARE, .nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x00, 0x04 }, .nti.nai.abtAtqa = { 0x00, 0x04 },
.nti.nai.abtUid = { 0x08, 0x00, 0xb0, 0x0b }, .nti.nai.abtUid = { 0x08, 0x00, 0xb0, 0x0b },
.nti.nai.btSak = 0x20, .nti.nai.btSak = 0x20,

View file

@ -173,7 +173,8 @@ main (int argc, char *argv[])
// Example of a Mifare Classic Mini // Example of a Mifare Classic Mini
// Note that crypto1 is not implemented in this example // Note that crypto1 is not implemented in this example
nfc_target_t nt = { nfc_target_t nt = {
.ntt = NTT_MIFARE, .nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x00, 0x04 }, .nti.nai.abtAtqa = { 0x00, 0x04 },
.nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef }, .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.nti.nai.btSak = 0x09, .nti.nai.btSak = 0x09,
@ -183,7 +184,8 @@ main (int argc, char *argv[])
/* /*
// Example of a FeliCa // Example of a FeliCa
nfc_target_t nt = { nfc_target_t nt = {
.ntt = NTT_FELICA_212, .nm.nmt = NMT_FELICA,
.nm.nbr = NBR_UNDEFINED,
.nti.nfi.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF }, .nti.nfi.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
.nti.nfi.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF }, .nti.nfi.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
.nti.nfi.abtSysCode = { 0xFF, 0xFF }, .nti.nfi.abtSysCode = { 0xFF, 0xFF },
@ -192,7 +194,8 @@ main (int argc, char *argv[])
/* /*
// Example of a ISO14443-4 (DESfire) // Example of a ISO14443-4 (DESfire)
nfc_target_t nt = { nfc_target_t nt = {
.ntt = NTT_MIFARE, .nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x03, 0x44 }, .nti.nai.abtAtqa = { 0x03, 0x44 },
.nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef }, .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.nti.nai.btSak = 0x20, .nti.nai.btSak = 0x20,

View file

@ -132,7 +132,8 @@ main (int argc, char *argv[])
// Note: We have to build a "fake" nfc_target_t in order to do exactly the same that was done before the new nfc_target_init() was introduced. // Note: We have to build a "fake" nfc_target_t in order to do exactly the same that was done before the new nfc_target_init() was introduced.
nfc_target_t nt = { nfc_target_t nt = {
.ntt = NTT_MIFARE, .nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x04, 0x00 }, .nti.nai.abtAtqa = { 0x04, 0x00 },
.nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xaf }, .nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xaf },
.nti.nai.btSak = 0x20, .nti.nai.btSak = 0x20,

View file

@ -111,13 +111,13 @@ main (int argc, const char *argv[])
nfc_target_info_t anti[MAX_TARGET_COUNT]; nfc_target_info_t anti[MAX_TARGET_COUNT];
pnd = nfc_connect (&(pnddDevices[i])); pnd = nfc_connect (&(pnddDevices[i]));
if (pnd == NULL) { if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device."); ERR ("%s", "Unable to connect to NFC device.");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
nfc_initiator_init (pnd); nfc_initiator_init (pnd);
// TODO move these conf in nfc_initiator_list_passive_targets() (without them it will not work correctly)
// Drop the field for a while // Drop the field for a while
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) { if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
nfc_perror (pnd, "nfc_configure"); nfc_perror (pnd, "nfc_configure");
@ -142,7 +142,11 @@ main (int argc, const char *argv[])
printf ("Connected to NFC device: %s\n", pnd->acName); printf ("Connected to NFC device: %s\n", pnd->acName);
// List ISO14443A targets // List ISO14443A targets
if (nfc_initiator_list_passive_targets (pnd, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &szTargetFound)) { nfc_modulation_t nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
if (nfc_initiator_list_passive_targets (pnd, nm, anti, 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" : ":"); 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++) {
@ -150,8 +154,11 @@ main (int argc, const char *argv[])
printf ("\n"); printf ("\n");
} }
} }
nm.nmt = NMT_FELICA;
nm.nbr = NBR_212;
// List Felica tags // List Felica tags
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_212, anti, MAX_TARGET_COUNT, &szTargetFound)) { if (nfc_initiator_list_passive_targets (pnd, nm, anti, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n; size_t n;
printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound, printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":"); (szTargetFound == 0) ? ".\n" : ":");
@ -160,7 +167,9 @@ main (int argc, const char *argv[])
printf ("\n"); printf ("\n");
} }
} }
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_424, anti, MAX_TARGET_COUNT, &szTargetFound)) {
nm.nbr = NBR_424;
if (nfc_initiator_list_passive_targets (pnd, nm, anti, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n; size_t n;
printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound, printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":"); (szTargetFound == 0) ? ".\n" : ":");
@ -169,8 +178,11 @@ main (int argc, const char *argv[])
printf ("\n"); printf ("\n");
} }
} }
nm.nmt = NMT_ISO14443B;
nm.nbr = NBR_106;
// List ISO14443B targets // List ISO14443B targets
if (nfc_initiator_list_passive_targets (pnd, NM_ISO14443B_106, anti, MAX_TARGET_COUNT, &szTargetFound)) { if (nfc_initiator_list_passive_targets (pnd, nm, anti, 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" : ":"); 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++) {
@ -179,8 +191,10 @@ main (int argc, const char *argv[])
} }
} }
nm.nmt = NMT_JEWEL;
nm.nbr = NBR_106;
// List Jewel targets // List Jewel targets
if (nfc_initiator_list_passive_targets(pnd, NM_JEWEL_106, anti, MAX_TARGET_COUNT, &szTargetFound )) { if (nfc_initiator_list_passive_targets(pnd, nm, anti, 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":":"); 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++) {

View file

@ -60,6 +60,11 @@ static byte_t keys[] = {
0xab, 0xcd, 0xef, 0x12, 0x34, 0x56 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
}; };
static const nfc_modulation_t nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
static size_t num_keys = sizeof (keys) / 6; static size_t num_keys = sizeof (keys) / 6;
static void static void
@ -150,7 +155,7 @@ authenticate (uint32_t uiBlock)
return true; return true;
} }
nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, mp.mpa.abtUid, 4, NULL); nfc_initiator_select_passive_target (pnd, nmMifare, mp.mpa.abtUid, 4, NULL);
} }
} }
@ -177,7 +182,7 @@ read_card (void)
// Show if the readout went well // Show if the readout went well
if (bFailure) { if (bFailure) {
// When a failure occured we need to redo the anti-collision // When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nti)) {
printf ("!\nError: tag was removed\n"); printf ("!\nError: tag was removed\n");
return false; return false;
} }
@ -242,7 +247,7 @@ write_card (void)
// Show if the readout went well // Show if the readout went well
if (bFailure) { if (bFailure) {
// When a failure occured we need to redo the anti-collision // When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nti)) {
printf ("!\nError: tag was removed\n"); printf ("!\nError: tag was removed\n");
return false; return false;
} }
@ -442,7 +447,7 @@ main (int argc, const char *argv[])
printf ("Connected to NFC reader: %s\n", pnd->acName); printf ("Connected to NFC reader: %s\n", pnd->acName);
// Try to find a MIFARE Classic tag // Try to find a MIFARE Classic tag
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nti)) {
printf ("Error: no tag was found\n"); printf ("Error: no tag was found\n");
nfc_disconnect (pnd); nfc_disconnect (pnd);
exit (EXIT_FAILURE); exit (EXIT_FAILURE);

View file

@ -47,6 +47,11 @@ static mifare_param mp;
static mifareul_tag mtDump; static mifareul_tag mtDump;
static uint32_t uiBlocks = 0xF; static uint32_t uiBlocks = 0xF;
static const nfc_modulation_t nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
static void static void
print_success_or_failure (bool bFailure, uint32_t * uiCounter) print_success_or_failure (bool bFailure, uint32_t * uiCounter)
{ {
@ -116,7 +121,7 @@ write_card (void)
// Show if the readout went well // Show if the readout went well
if (bFailure) { if (bFailure) {
// When a failure occured we need to redo the anti-collision // When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nti)) {
ERR ("tag was removed"); ERR ("tag was removed");
return false; return false;
} }
@ -216,7 +221,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);
// Try to find a MIFARE Ultralight tag // Try to find a MIFARE Ultralight tag
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nti)) {
ERR ("no tag was found\n"); ERR ("no tag was found\n");
nfc_disconnect (pnd); nfc_disconnect (pnd);
return 1; return 1;

View file

@ -72,8 +72,14 @@ main (int argc, const char *argv[])
const byte_t btPollNr = 20; const byte_t btPollNr = 20;
const byte_t btPeriod = 2; const byte_t btPeriod = 2;
const nfc_target_type_t nttArray[5] = {NTT_GENERIC_PASSIVE_106, NTT_GENERIC_PASSIVE_212, NTT_GENERIC_PASSIVE_424, NTT_ISO14443_4B_106, NTT_JEWEL_106}; const nfc_modulation_t nmModulations[5] = {
const size_t szTargetTypes = 5; { .nmt = NMT_ISO14443A, .nbr = NBR_106 },
{ .nmt = NMT_ISO14443B, .nbr = NBR_106 },
{ .nmt = NMT_FELICA, .nbr = NBR_212 },
{ .nmt = NMT_FELICA, .nbr = NBR_424 },
{ .nmt = NMT_JEWEL, .nbr = NBR_106 },
};
const size_t szModulations = 5;
nfc_target_t antTargets[2]; nfc_target_t antTargets[2];
size_t szTargetFound; size_t szTargetFound;
@ -105,57 +111,15 @@ main (int argc, const char *argv[])
printf ("Connected to NFC reader: %s\n", pnd->acName); printf ("Connected to NFC reader: %s\n", pnd->acName);
printf ("PN532 will poll during %ld ms\n", (unsigned long) btPollNr * szTargetTypes * btPeriod * 150); printf ("PN532 will poll during %ld ms\n", (unsigned long) btPollNr * szModulations * btPeriod * 150);
res = nfc_initiator_poll_targets (pnd, nttArray, szTargetTypes, btPollNr, btPeriod, antTargets, &szTargetFound); res = nfc_initiator_poll_targets (pnd, nmModulations, szModulations, btPollNr, btPeriod, antTargets, &szTargetFound);
if (res) { if (res) {
uint8_t n; uint8_t n;
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: targetType=%02x ", n + 1, antTargets[n].ntt); printf ("T%d: ", n + 1);
switch(antTargets[n].ntt) { print_nfc_target ( antTargets[n] );
case NTT_JEWEL_106:
printf ("(Innovision Jewel tag), targetData:\n");
print_nfc_jewel_info (antTargets[n].nti.nji);
break;
case NTT_MIFARE:
printf ("(Mifare card), targetData:\n");
print_nfc_iso14443a_info (antTargets[n].nti.nai);
break;
case NTT_FELICA_212:
printf ("(FeliCa 212 kbps card), targetData:\n");
print_nfc_felica_info (antTargets[n].nti.nfi);
break;
case NTT_FELICA_424:
printf ("(FeliCa 212 kbps card), targetData:\n");
print_nfc_felica_info (antTargets[n].nti.nfi);
break;
case NTT_ISO14443_4A_106:
printf ("(Passive 106 kbps ISO/IEC 14443-4A card), targetData:\n");
print_nfc_iso14443a_info (antTargets[n].nti.nai);
break;
case NTT_ISO14443_4B_TCL_106:
printf ("(Passive 106 kbps ISO/IEC 14443-4B card), targetData:\n");
print_nfc_iso14443b_info (antTargets[n].nti.nbi);
break;
case NTT_DEP_PASSIVE_106:
printf ("(DEP passive 106 kbps)\n");
break;
case NTT_DEP_PASSIVE_212:
printf ("(DEP passive 212 kbps)\n");
break;
case NTT_DEP_PASSIVE_424:
printf ("(DEP passive 424 kbps)\n");
break;
case NTT_DEP_ACTIVE_106:
printf ("(DEP active 106 kbps)\n");
break;
case NTT_DEP_ACTIVE_212:
printf ("(DEP active 212 kbps)\n");
break;
case NTT_DEP_ACTIVE_424:
printf ("(DEP active 424 kbps)\n");
break;
};
} }
} else { } else {
nfc_perror (pnd, "nfc_initiator_poll_targets"); nfc_perror (pnd, "nfc_initiator_poll_targets");

View file

@ -127,7 +127,8 @@ main (int argc, char *argv[])
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n"); printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
nfc_target_t nt = { nfc_target_t nt = {
.ntt = NTT_MIFARE, .nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x04, 0x00 }, .nti.nai.abtAtqa = { 0x04, 0x00 },
.nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xef }, .nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xef },
.nti.nai.btSak = 0x20, .nti.nai.btSak = 0x20,

View file

@ -212,60 +212,6 @@ print_nfc_dep_info (const nfc_dep_info_t ndi)
} }
} }
void print_nfc_target_type( const nfc_target_type_t ntt )
{
switch (ntt) {
case NTT_GENERIC_PASSIVE_106:
printf ("Generic passive 106 kbps (ISO/IEC14443-4A, mifare, DEP)\n");
break;
case NTT_GENERIC_PASSIVE_212:
printf ("Generic passive 212 kbps (FeliCa, DEP)\n");
break;
case NTT_GENERIC_PASSIVE_424:
printf ("Generic passive 424 kbps (FeliCa, DEP)\n");
break;
case NTT_ISO14443_4B_106:
printf ("Passive 106 kbps ISO/IEC14443-4B\n");
break;
case NTT_JEWEL_106:
printf ("Innovision Jewel tag\n");
break;
case NTT_MIFARE:
printf ("mifare card\n");
break;
case NTT_FELICA_212:
printf ("FeliCa 212 kbps card\n");
break;
case NTT_FELICA_424:
printf ("FeliCa 424 kbps card\n");
break;
case NTT_ISO14443_4A_106:
printf ("Passive 106 kbps ISO/IEC14443-4A\n");
break;
case NTT_ISO14443_4B_TCL_106:
printf ("Passive 106 kbps ISO/IEC14443-4B with TCL flag\n");
break;
case NTT_DEP_PASSIVE_106:
printf ("DEP passive 106 kbps\n");
break;
case NTT_DEP_PASSIVE_212:
printf ("DEP passive 212 kbps\n");
break;
case NTT_DEP_PASSIVE_424:
printf ("DEP passive 424 kbps\n");
break;
case NTT_DEP_ACTIVE_106:
printf ("DEP active 106 kbps\n");
break;
case NTT_DEP_ACTIVE_212:
printf ("DEP active 212 kbps\n");
break;
case NTT_DEP_ACTIVE_424:
printf ("DEP active 424 kbps\n");
break;
}
}
/** /**
* @brief Tries to parse arguments to find device descriptions. * @brief Tries to parse arguments to find device descriptions.
* @return Returns the list of found device descriptions. * @return Returns the list of found device descriptions.
@ -308,3 +254,51 @@ parse_device_desc (int argc, const char *argv[], size_t * szFound)
return pndd; return pndd;
} }
const char *
str_nfc_baud_rate (const nfc_baud_rate_t nbr)
{
switch(nbr) {
case NBR_UNDEFINED:
return "undefined baud rate";
break;
case NBR_106:
return "106 kbps";
break;
case NBR_212:
return "212 kbps";
break;
case NBR_424:
return "424 kbps";
break;
}
return "";
}
void
print_nfc_target (const nfc_target_t nt)
{
switch(nt.nm.nmt) {
case NMT_ISO14443A:
printf ("ISO/IEC 14443A (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443a_info (nt.nti.nai);
break;
case NMT_JEWEL:
printf ("Innovision Jewel (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_jewel_info (nt.nti.nji);
break;
case NMT_FELICA:
printf ("FeliCa (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_felica_info (nt.nti.nfi);
break;
case NMT_ISO14443B:
printf ("ISO/IEC 14443-4B (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443b_info (nt.nti.nbi);
break;
case NMT_DEP:
printf ("D.E.P. (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_dep_info (nt.nti.ndi);
break;
}
}

View file

@ -40,7 +40,7 @@ void print_nfc_felica_info (const nfc_felica_info_t nfi);
void print_nfc_jewel_info (const nfc_jewel_info_t nji); void print_nfc_jewel_info (const nfc_jewel_info_t nji);
void print_nfc_dep_info (const nfc_dep_info_t ndi); void print_nfc_dep_info (const nfc_dep_info_t ndi);
void print_nfc_target_type( const nfc_target_type_t ntt ); void print_nfc_target (const nfc_target_t nt);
nfc_device_desc_t *parse_device_desc (int argc, const char *argv[], size_t * szFound); nfc_device_desc_t *parse_device_desc (int argc, const char *argv[], size_t * szFound);

View file

@ -181,7 +181,11 @@ main (int argc, const char *argv[])
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// Read the SAM's info // Read the SAM's info
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) { const nfc_modulation_t nmSAM = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
if (!nfc_initiator_select_passive_target (pnd, nmSAM, NULL, 0, &nti)) {
nfc_perror (pnd, "nfc_initiator_select_passive_target"); nfc_perror (pnd, "nfc_initiator_select_passive_target");
ERR ("%s", "Reading of SAM info failed."); ERR ("%s", "Reading of SAM info failed.");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -198,7 +202,8 @@ main (int argc, const char *argv[])
size_t szRx; size_t szRx;
nfc_target_t nt = { nfc_target_t nt = {
.ntt = NTT_MIFARE, .nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x04, 0x00 }, .nti.nai.abtAtqa = { 0x04, 0x00 },
.nti.nai.abtUid = { 0x08, 0xad, 0xbe, 0xaf }, .nti.nai.abtUid = { 0x08, 0xad, 0xbe, 0xaf },
.nti.nai.btSak = 0x20, .nti.nai.btSak = 0x20,

View file

@ -165,36 +165,9 @@ typedef enum {
NDO_FORCE_ISO14443_A = 0x42, NDO_FORCE_ISO14443_A = 0x42,
} nfc_device_option_t; } nfc_device_option_t;
/**
* @enum nfc_modulation_t
* @brief NFC modulation
*/
typedef enum {
/** ISO14443-A (NXP MIFARE) http://en.wikipedia.org/wiki/MIFARE */
NM_ISO14443A_106 = 0x00,
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
NM_FELICA_212 = 0x01,
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
NM_FELICA_424 = 0x02,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531) */
NM_ISO14443B_106 = 0x03,
/** Jewel Topaz (Innovision Research & Development) (Not supported by PN531) */
NM_JEWEL_106 = 0x04,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
NM_ISO14443B_212 = 0x06,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
NM_ISO14443B_424 = 0x07,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
NM_ISO14443B_847 = 0x08,
/** Active DEP */
NM_ACTIVE_DEP,
/** Passive DEP */
NM_PASSIVE_DEP
} nfc_modulation_t;
/** /**
* @struct nfc_dep_info_t * @struct nfc_dep_info_t
* @brief NFC tag information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 * @brief NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
*/ */
typedef struct { typedef struct {
/** NFCID3 */ /** NFCID3 */
@ -214,6 +187,15 @@ typedef struct {
size_t szGB; size_t szGB;
} nfc_dep_info_t; } nfc_dep_info_t;
/**
* @enum nfc_dep_mode_t
* @brief NFC D.E.P. (Data Exchange Protocol) active/passive mode
*/
typedef enum {
NDM_PASSIVE,
NDM_ACTIVE,
} nfc_dep_mode_t;
/** /**
* @struct nfc_iso14443a_info_t * @struct nfc_iso14443a_info_t
* @brief NFC ISO14443A tag (MIFARE) information * @brief NFC ISO14443A tag (MIFARE) information
@ -291,43 +273,36 @@ typedef enum {
} nfc_target_mode_t; } nfc_target_mode_t;
/** /**
* @enum nfc_target_type_t * @enum nfc_baud_rate_t
* @brief NFC target type enumeration * @brief NFC baud rate enumeration
*/ */
typedef enum { typedef enum {
/** Generic passive 106 kbps (ISO/IEC14443-4A, mifare, DEP) */ NBR_UNDEFINED = 0,
NTT_GENERIC_PASSIVE_106 = 0x00, NBR_106,
/** Generic passive 212 kbps (FeliCa, DEP) */ NBR_212,
NTT_GENERIC_PASSIVE_212 = 0x01, NBR_424,
/** Generic passive 424 kbps (FeliCa, DEP) */ } nfc_baud_rate_t;
NTT_GENERIC_PASSIVE_424 = 0x02,
/** Passive 106 kbps ISO/IEC14443-4B */ /**
NTT_ISO14443_4B_106 = 0x03, * @enum nfc_modulation_type_t
/** Innovision Jewel tag */ * @brief NFC modulation type enumeration
NTT_JEWEL_106 = 0x04, */
/** Mifare card */ typedef enum {
NTT_MIFARE = 0x10, NMT_ISO14443A,
/** FeliCa 212 kbps card */ NMT_ISO14443B,
NTT_FELICA_212 = 0x11, NMT_FELICA,
/** FeliCa 424 kbps card */ NMT_JEWEL,
NTT_FELICA_424 = 0x12, NMT_DEP,
/** Passive 106 kbps ISO/IEC 14443-4A */ } nfc_modulation_type_t;
NTT_ISO14443_4A_106 = 0x20,
/** Passive 106 kbps ISO/IEC 14443-4B with TCL flag */ /**
NTT_ISO14443_4B_TCL_106 = 0x23, * @struct nfc_modulation_t
/** DEP passive 106 kbps */ * @brief NFC modulation structure
NTT_DEP_PASSIVE_106 = 0x40, */
/** DEP passive 212 kbps */ typedef struct {
NTT_DEP_PASSIVE_212 = 0x41, nfc_modulation_type_t nmt;
/** DEP passive 424 kbps */ nfc_baud_rate_t nbr;
NTT_DEP_PASSIVE_424 = 0x42, } nfc_modulation_t;
/** DEP active 106 kbps */
NTT_DEP_ACTIVE_106 = 0x80,
/** DEP active 212 kbps */
NTT_DEP_ACTIVE_212 = 0x81,
/** DEP active 424 kbps */
NTT_DEP_ACTIVE_424 = 0x82,
} nfc_target_type_t;
/** /**
* @struct nfc_target_t * @struct nfc_target_t
@ -335,7 +310,7 @@ typedef enum {
*/ */
typedef struct { typedef struct {
nfc_target_info_t nti; nfc_target_info_t nti;
nfc_target_type_t ntt; nfc_modulation_t nm;
} nfc_target_t; } nfc_target_t;
// Reset struct alignment to default // Reset struct alignment to default

View file

@ -68,16 +68,16 @@ extern "C" {
/* NFC initiator: act as "reader" */ /* NFC initiator: act as "reader" */
NFC_EXPORT bool nfc_initiator_init (nfc_device_t * pnd); NFC_EXPORT bool nfc_initiator_init (nfc_device_t * pnd);
NFC_EXPORT bool nfc_initiator_select_passive_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, NFC_EXPORT bool nfc_initiator_select_passive_target (nfc_device_t * pnd, const nfc_modulation_t nm,
const byte_t * pbtInitData, const size_t szInitDataLen, const byte_t * pbtInitData, const size_t szInitData,
nfc_target_info_t * pti); nfc_target_info_t * pti);
NFC_EXPORT bool nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, NFC_EXPORT bool nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nm,
nfc_target_info_t anti[], const size_t szTargets, nfc_target_info_t anti[], const size_t szTargets,
size_t * pszTargetFound); size_t * pszTargetFound);
NFC_EXPORT bool nfc_initiator_poll_targets (nfc_device_t * pnd, const nfc_target_type_t * pnttTargetTypes, NFC_EXPORT bool nfc_initiator_poll_targets (nfc_device_t * pnd, const nfc_modulation_t * pnmTargetTypes,
const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod, const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod,
nfc_target_t * pntTargets, size_t * pszTargetFound); nfc_target_t * pntTargets, size_t * pszTargetFound);
NFC_EXPORT bool nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, NFC_EXPORT bool nfc_initiator_select_dep_target (nfc_device_t * pnd, const bool bActiveDep,
const nfc_dep_info_t * pndiInitiator, const nfc_dep_info_t * pndiInitiator,
nfc_target_info_t * pti); nfc_target_info_t * pti);
NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd); NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd);

View file

@ -81,6 +81,11 @@ static const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
static const byte_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; static const byte_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 }; static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
/* prototypes */
const nfc_modulation_t pn53x_ptt_to_nm( const pn53x_target_type_t ptt );
const pn53x_modulation_t pn53x_nm_to_pm(const nfc_modulation_t nm);
const pn53x_target_type_t pn53x_nm_to_ptt(const nfc_modulation_t nm);
bool bool
pn53x_init(nfc_device_t * pnd) pn53x_init(nfc_device_t * pnd)
{ {
@ -369,15 +374,13 @@ pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t *
} }
bool bool
pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt, pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData, nfc_chip_t nc, nfc_modulation_type_t nmt,
nfc_target_info_t * pnti) nfc_target_info_t * pnti)
{ {
uint8_t szAttribRes; uint8_t szAttribRes;
switch (ntt) { switch (nmt) {
case NTT_MIFARE: case NMT_ISO14443A:
case NTT_GENERIC_PASSIVE_106:
case NTT_ISO14443_4A_106:
// We skip the first byte: its the target number (Tg) // We skip the first byte: its the target number (Tg)
pbtRawData++; pbtRawData++;
@ -396,7 +399,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_
pbtRawData += pnti->nai.szUidLen; pbtRawData += pnti->nai.szUidLen;
// Did we received an optional ATS (Smardcard ATR) // Did we received an optional ATS (Smardcard ATR)
if (szDataLen > (pnti->nai.szUidLen + 5)) { if (szRawData > (pnti->nai.szUidLen + 5)) {
pnti->nai.szAtsLen = ((*(pbtRawData++)) - 1); // In pbtRawData, ATS Length byte is counted in ATS Frame. pnti->nai.szAtsLen = ((*(pbtRawData++)) - 1); // In pbtRawData, ATS Length byte is counted in ATS Frame.
memcpy (pnti->nai.abtAts, pbtRawData, pnti->nai.szAtsLen); memcpy (pnti->nai.abtAts, pbtRawData, pnti->nai.szAtsLen);
} else { } else {
@ -415,8 +418,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_
} }
break; break;
case NTT_ISO14443_4B_106: case NMT_ISO14443B:
case NTT_ISO14443_4B_TCL_106:
// We skip the first byte: its the target number (Tg) // We skip the first byte: its the target number (Tg)
pbtRawData++; pbtRawData++;
@ -442,8 +444,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_
} }
break; break;
case NTT_FELICA_212: case NMT_FELICA:
case NTT_FELICA_424:
// We skip the first byte: its the target number (Tg) // We skip the first byte: its the target number (Tg)
pbtRawData++; pbtRawData++;
@ -461,7 +462,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_
memcpy (pnti->nfi.abtSysCode, pbtRawData, 2); memcpy (pnti->nfi.abtSysCode, pbtRawData, 2);
} }
break; break;
case NTT_JEWEL_106: case NMT_JEWEL:
// We skip the first byte: its the target number (Tg) // We skip the first byte: its the target number (Tg)
pbtRawData++; pbtRawData++;
@ -477,14 +478,63 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_
return true; return true;
} }
bool
pn53x_initiator_select_passive_target (nfc_device_t * pnd,
const nfc_modulation_t nm,
const byte_t * pbtInitData, const size_t szInitData,
nfc_target_info_t * pnti)
{
size_t szTargetsData;
byte_t abtTargetsData[MAX_FRAME_LEN];
pn53x_modulation_t pm = pn53x_nm_to_pm(nm);
if (!pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData))
return false;
// Make sure one tag has been found, the PN53X returns 0x00 if none was available
if (abtTargetsData[0] == 0)
return false;
// Is a tag info struct available
if (pnti) {
// Fill the tag info struct with the values corresponding to this init modulation
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, nm.nmt, pnti)) {
return false;
}
}
return true;
}
bool
pn53x_initiator_poll_targets (nfc_device_t * pnd,
const nfc_modulation_t * pnmModulations, const size_t szModulations,
const byte_t btPollNr, const byte_t btPeriod,
nfc_target_t * pntTargets, size_t * pszTargetFound)
{
size_t szTargetTypes = 0;
pn53x_target_type_t apttTargetTypes[32];
for (size_t n=0; n<szModulations; n++) {
apttTargetTypes[szTargetTypes] = pn53x_nm_to_ptt(pnmModulations[n]);
if( apttTargetTypes[szTargetTypes] == PTT_MIFARE ) { // Hack to have ATR
apttTargetTypes[szTargetTypes] = PTT_ISO14443_4A_106;
szTargetTypes++;
apttTargetTypes[szTargetTypes] = PTT_MIFARE;
}
szTargetTypes++;
}
return pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound);
}
/** /**
* @brief C wrapper to InListPassiveTarget command * @brief C wrapper to InListPassiveTarget command
* @return true if command is successfully sent * @return true if command is successfully sent
* *
* @param pnd nfc_device_t struct pointer that represent currently used device * @param pnd nfc_device_t struct pointer that represent currently used device
* @param nmInitModulation Desired modulation * @param pmInitModulation Desired modulation
* @param pbtInitiatorData Optional initiator data used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID * @param pbtInitiatorData Optional initiator data used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID
* @param szInitiatorDataLen Length of initiator data \a pbtInitiatorData * @param szInitiatorData Length of initiator data \a pbtInitiatorData
* @param pbtTargetsData pointer on a pre-allocated byte array to receive TargetData[n] as described in pn53x user manual * @param pbtTargetsData pointer on a pre-allocated byte array to receive TargetData[n] as described in pn53x user manual
* @param pszTargetsData size_t pointer where size of \a pbtTargetsData will be written * @param pszTargetsData size_t pointer where size of \a pbtTargetsData will be written
* *
@ -493,8 +543,8 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_
*/ */
bool bool
pn53x_InListPassiveTarget (nfc_device_t * pnd, pn53x_InListPassiveTarget (nfc_device_t * pnd,
const nfc_modulation_t nmInitModulation, const byte_t szMaxTargets, const pn53x_modulation_t pmInitModulation, const byte_t szMaxTargets,
const byte_t * pbtInitiatorData, const size_t szInitiatorDataLen, const byte_t * pbtInitiatorData, const size_t szInitiatorData,
byte_t * pbtTargetsData, size_t * pszTargetsData) byte_t * pbtTargetsData, size_t * pszTargetsData)
{ {
size_t szRx; size_t szRx;
@ -504,23 +554,24 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd,
abtCmd[2] = szMaxTargets; // MaxTg abtCmd[2] = szMaxTargets; // MaxTg
// XXX Is there is a better way to do this ? // XXX Is there is a better way to do this ?
switch(nmInitModulation) { switch(pmInitModulation) {
case NM_ISO14443A_106: case PM_ISO14443A_106:
case NM_FELICA_212: case PM_FELICA_212:
case NM_FELICA_424: case PM_FELICA_424:
// all gone fine. // all gone fine.
break; break;
case NM_ISO14443B_106: case PM_ISO14443B_106:
case NM_JEWEL_106: // FIXME Some PN532 doesn't support type B !
case PM_JEWEL_106:
if(pnd->nc == NC_PN531) { if(pnd->nc == NC_PN531) {
// These modulations are not supported by pn531 // These modulations are not supported by pn531
pnd->iLastError = DENOTSUP; pnd->iLastError = DENOTSUP;
return false; return false;
} }
break; break;
case NM_ISO14443B_212: case PM_ISO14443B_212:
case NM_ISO14443B_424: case PM_ISO14443B_424:
case NM_ISO14443B_847: case PM_ISO14443B_847:
if(pnd->nc != NC_PN533) { if(pnd->nc != NC_PN533) {
// These modulations are not supported by pn531 neither pn532 // These modulations are not supported by pn531 neither pn532
pnd->iLastError = DENOTSUP; pnd->iLastError = DENOTSUP;
@ -531,15 +582,15 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd,
pnd->iLastError = DENOTSUP; pnd->iLastError = DENOTSUP;
return false; return false;
} }
abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag abtCmd[3] = pmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
// Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID). // Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID).
if (pbtInitiatorData) if (pbtInitiatorData)
memcpy (abtCmd + 4, pbtInitiatorData, szInitiatorDataLen); memcpy (abtCmd + 4, pbtInitiatorData, szInitiatorData);
// Try to find a tag, call the tranceive callback function of the current device // Try to find a tag, call the tranceive callback function of the current device
szRx = MAX_FRAME_LEN; szRx = MAX_FRAME_LEN;
if (pn53x_transceive (pnd, abtCmd, 4 + szInitiatorDataLen, pbtTargetsData, &szRx)) { if (pn53x_transceive (pnd, abtCmd, 4 + szInitiatorData, pbtTargetsData, &szRx)) {
*pszTargetsData = szRx; *pszTargetsData = szRx;
return true; return true;
} else { } else {
@ -569,7 +620,7 @@ pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target)
bool bool
pn53x_InAutoPoll (nfc_device_t * pnd, pn53x_InAutoPoll (nfc_device_t * pnd,
const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes, const pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes,
const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, size_t * pszTargetFound) const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, size_t * pszTargetFound)
{ {
size_t szTxInAutoPoll, size_t szTxInAutoPoll,
@ -592,7 +643,7 @@ pn53x_InAutoPoll (nfc_device_t * pnd,
pbtTxInAutoPoll[2] = btPollNr; pbtTxInAutoPoll[2] = btPollNr;
pbtTxInAutoPoll[3] = btPeriod; pbtTxInAutoPoll[3] = btPeriod;
for (n = 0; n < szTargetTypes; n++) { for (n = 0; n < szTargetTypes; n++) {
pbtTxInAutoPoll[4 + n] = pnttTargetTypes[n]; pbtTxInAutoPoll[4 + n] = ppttTargetTypes[n];
} }
szRx = MAX_FRAME_LEN; szRx = MAX_FRAME_LEN;
@ -607,19 +658,21 @@ pn53x_InAutoPoll (nfc_device_t * pnd,
byte_t *pbt = abtRx + 1; byte_t *pbt = abtRx + 1;
/* 1st target */ /* 1st target */
// Target type // Target type
pntTargets[0].ntt = *(pbt++); pn53x_target_type_t ptt = *(pbt++);
pntTargets[0].nm = pn53x_ptt_to_nm(ptt);
// AutoPollTargetData length // AutoPollTargetData length
ln = *(pbt++); ln = *(pbt++);
pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[0].ntt, &(pntTargets[0].nti)); pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[0].nm.nmt, &(pntTargets[0].nti));
pbt += ln; pbt += ln;
if (abtRx[0] > 1) { if (abtRx[0] > 1) {
/* 2nd target */ /* 2nd target */
// Target type // Target type
pntTargets[1].ntt = *(pbt++); ptt = *(pbt++);
pntTargets[1].nm = pn53x_ptt_to_nm(ptt);
// AutoPollTargetData length // AutoPollTargetData length
ln = *(pbt++); ln = *(pbt++);
pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[1].ntt, &(pntTargets[1].nti)); pn53x_decode_target_data (pbt, ln, pnd->nc, pntTargets[1].nm.nmt, &(pntTargets[1].nti));
} }
} }
} }
@ -700,7 +753,7 @@ pn53x_get_firmware_version (nfc_device_t * pnd)
byte_t abtFw[4]; byte_t abtFw[4];
size_t szFwLen = sizeof (abtFw); size_t szFwLen = sizeof (abtFw);
char *pcName; char *pcName;
// TODO Read more info here: there are modulation capabilities info to know if ISO14443B is supported
if (!pn53x_transceive (pnd, pncmd_get_firmware_version, 2, abtFw, &szFwLen)) { if (!pn53x_transceive (pnd, pncmd_get_firmware_version, 2, abtFw, &szFwLen)) {
// Failed to get firmware revision??, whatever...let's disconnect and clean up and return err // Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
DBG ("Failed to get firmware revision for: %s", pnd->acName); DBG ("Failed to get firmware revision for: %s", pnd->acName);
@ -821,20 +874,20 @@ pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool b
} }
bool bool
pn53x_initiator_select_dep_target(nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, pn53x_initiator_select_dep_target(nfc_device_t * pnd, const nfc_dep_mode_t ndm,
const nfc_dep_info_t * pndiInitiator, const nfc_dep_info_t * pndiInitiator,
nfc_target_info_t * pnti) nfc_target_info_t * pnti)
{ {
if (pndiInitiator) { if (pndiInitiator) {
return pn53x_InJumpForDEP (pnd, nmInitModulation, NULL, 0, pndiInitiator->abtNFCID3, pndiInitiator->abtGB, pndiInitiator->szGB, pnti); return pn53x_InJumpForDEP (pnd, ndm, NULL, 0, pndiInitiator->abtNFCID3, pndiInitiator->abtGB, pndiInitiator->szGB, pnti);
} else { } else {
return pn53x_InJumpForDEP (pnd, nmInitModulation, NULL, 0, NULL, NULL, 0, pnti); return pn53x_InJumpForDEP (pnd, ndm, NULL, 0, NULL, NULL, 0, pnti);
} }
} }
/** /**
* @brief Wrapper for InJumpForDEP command * @brief Wrapper for InJumpForDEP command
* @param nmInitModulation desired initial modulation * @param pmInitModulation desired initial modulation
* @param pbtPassiveInitiatorData NFCID1 at 106kbps (see NFCIP-1: 11.2.1.26) or Polling Request Frame's payload at 212/424kbps (see NFCIP-1: 11.2.2.5) * @param pbtPassiveInitiatorData NFCID1 at 106kbps (see NFCIP-1: 11.2.1.26) or Polling Request Frame's payload at 212/424kbps (see NFCIP-1: 11.2.2.5)
* @param szPassiveInitiatorData size of pbtPassiveInitiatorData content * @param szPassiveInitiatorData size of pbtPassiveInitiatorData content
* @param pbtNFCID3i NFCID3 of the initiator * @param pbtNFCID3i NFCID3 of the initiator
@ -843,7 +896,8 @@ pn53x_initiator_select_dep_target(nfc_device_t * pnd, const nfc_modulation_t nmI
* @param[out] pnti nfc_target_info_t which will be filled by this function * @param[out] pnti nfc_target_info_t which will be filled by this function
*/ */
bool bool
pn53x_InJumpForDEP (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, pn53x_InJumpForDEP (nfc_device_t * pnd,
const nfc_dep_mode_t ndm,
const byte_t * pbtPassiveInitiatorData, const size_t szPassiveInitiatorData, const byte_t * pbtPassiveInitiatorData, const size_t szPassiveInitiatorData,
const byte_t * pbtNFCID3i, const byte_t * pbtNFCID3i,
const byte_t * pbtGB, const size_t szGB, const byte_t * pbtGB, const size_t szGB,
@ -856,14 +910,13 @@ pn53x_InJumpForDEP (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
memcpy (abtCmd, pncmd_initiator_jump_for_dep, sizeof (pncmd_initiator_jump_for_dep)); memcpy (abtCmd, pncmd_initiator_jump_for_dep, sizeof (pncmd_initiator_jump_for_dep));
if (nmInitModulation == NM_ACTIVE_DEP) { abtCmd[2] = (ndm == NDM_ACTIVE) ? 0x01 : 0x00;
abtCmd[2] = 0x01; /* active DEP */
}
// FIXME Baud rate in D.E.P. mode is hard-wired as 106kbps // FIXME Baud rate in D.E.P. mode is hard-wired as 106kbps
abtCmd[3] = 0x00; /* baud rate = 106kbps */ abtCmd[3] = 0x00; /* baud rate = 106kbps */
offset = 5; offset = 5;
if (pbtPassiveInitiatorData && (nmInitModulation != NM_ACTIVE_DEP)) { /* can't have passive initiator data when using active mode */ if (pbtPassiveInitiatorData && (ndm == NDM_PASSIVE)) { /* can't have passive initiator data when using active mode */
abtCmd[4] |= 0x01; abtCmd[4] |= 0x01;
memcpy (abtCmd + offset, pbtPassiveInitiatorData, szPassiveInitiatorData); memcpy (abtCmd + offset, pbtPassiveInitiatorData, szPassiveInitiatorData);
offset += szPassiveInitiatorData; offset += szPassiveInitiatorData;
@ -1070,10 +1123,8 @@ pn53x_target_init (nfc_device_t * pnd, const nfc_target_mode_t ntm, const nfc_ta
const byte_t * pbtGB = NULL; const byte_t * pbtGB = NULL;
size_t szGB = 0; size_t szGB = 0;
switch(nt.ntt) { switch(nt.nm.nmt) {
case NTT_MIFARE: case NMT_ISO14443A: {
case NTT_GENERIC_PASSIVE_106:
case NTT_ISO14443_4A_106: {
// Set ATQA (SENS_RES) // Set ATQA (SENS_RES)
abtMifareParams[0] = nt.nti.nai.abtAtqa[1]; abtMifareParams[0] = nt.nti.nai.abtAtqa[1];
abtMifareParams[1] = nt.nti.nai.abtAtqa[0]; abtMifareParams[1] = nt.nti.nai.abtAtqa[0];
@ -1089,8 +1140,7 @@ pn53x_target_init (nfc_device_t * pnd, const nfc_target_mode_t ntm, const nfc_ta
} }
break; break;
case NTT_FELICA_212: case NMT_FELICA:
case NTT_FELICA_424:
// Set NFCID2t // Set NFCID2t
memcpy(abtFeliCaParams, nt.nti.nfi.abtId, 8); memcpy(abtFeliCaParams, nt.nti.nfi.abtId, 8);
// Set PAD // Set PAD
@ -1100,13 +1150,16 @@ pn53x_target_init (nfc_device_t * pnd, const nfc_target_mode_t ntm, const nfc_ta
pbtFeliCaParams = abtFeliCaParams; pbtFeliCaParams = abtFeliCaParams;
break; break;
case NTT_DEP_PASSIVE_106: case NMT_DEP:
case NTT_DEP_PASSIVE_212:
case NTT_DEP_PASSIVE_424:
pbtNFCID3t = nt.nti.ndi.abtNFCID3; pbtNFCID3t = nt.nti.ndi.abtNFCID3;
szGB = nt.nti.ndi.szGB; szGB = nt.nti.ndi.szGB;
if (szGB) pbtGB = nt.nti.ndi.abtGB; if (szGB) pbtGB = nt.nti.ndi.abtGB;
break; break;
case NMT_ISO14443B:
case NMT_JEWEL:
pnd->iLastError = DENOTSUP;
return false;
break;
} }
if(!pn53x_TgInitAsTarget(pnd, ntm, pbtMifareParams, pbtFeliCaParams, pbtNFCID3t, pbtGB, szGB, pbtRx, pszRx, NULL)) { if(!pn53x_TgInitAsTarget(pnd, ntm, pbtMifareParams, pbtFeliCaParams, pbtNFCID3t, pbtGB, szGB, pbtRx, pszRx, NULL)) {
@ -1314,3 +1367,133 @@ pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t
// Everyting seems ok, return true // Everyting seems ok, return true
return true; return true;
} }
// FIXME How to handle corner case ?
const pn53x_modulation_t
pn53x_nm_to_pm(const nfc_modulation_t nm)
{
switch(nm.nmt) {
case NMT_ISO14443A:
return PM_ISO14443A_106;
break;
case NMT_ISO14443B:
switch(nm.nbr) {
case NBR_106:
return PM_ISO14443B_106;
break;
case NBR_212:
return PM_ISO14443B_212;
break;
case NBR_424:
return PM_ISO14443B_424;
break;
case NBR_UNDEFINED:
// XXX What to do ?
break;
}
break;
case NMT_JEWEL:
return PM_JEWEL_106;
break;
case NMT_FELICA:
switch(nm.nbr) {
case NBR_212:
return PM_FELICA_212;
break;
case NBR_424:
return PM_FELICA_424;
break;
case NBR_106:
case NBR_UNDEFINED:
// XXX What to do ?
break;
}
break;
}
}
// FIXME How to handle corner case ?
const nfc_modulation_t
pn53x_ptt_to_nm( const pn53x_target_type_t ptt )
{
switch (ptt) {
case PTT_GENERIC_PASSIVE_106:
case PTT_GENERIC_PASSIVE_212:
case PTT_GENERIC_PASSIVE_424:
// XXX This should not happend, how handle it cleanly ?
break;
case PTT_MIFARE:
case PTT_ISO14443_4A_106:
return (const nfc_modulation_t){ .nmt = NMT_ISO14443A, .nbr = NBR_106 };
break;
case PTT_ISO14443_4B_106:
case PTT_ISO14443_4B_TCL_106:
return (const nfc_modulation_t){ .nmt = NMT_ISO14443B, .nbr = NBR_106 };
break;
case PTT_JEWEL_106:
return (const nfc_modulation_t){ .nmt = NMT_JEWEL, .nbr = NBR_106 };
break;
case PTT_FELICA_212:
return (const nfc_modulation_t){ .nmt = NMT_FELICA, .nbr = NBR_212 };
break;
case PTT_FELICA_424:
return (const nfc_modulation_t){ .nmt = NMT_FELICA, .nbr = NBR_424 };
break;
case PTT_DEP_PASSIVE_106:
case PTT_DEP_ACTIVE_106:
return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_106 };
break;
case PTT_DEP_PASSIVE_212:
case PTT_DEP_ACTIVE_212:
return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_212 };
break;
case PTT_DEP_PASSIVE_424:
case PTT_DEP_ACTIVE_424:
return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_424 };
break;
}
}
// FIXME How to handle corner case ?
const pn53x_target_type_t
pn53x_nm_to_ptt(const nfc_modulation_t nm)
{
switch(nm.nmt) {
case NMT_ISO14443A:
return PTT_MIFARE;
// return PTT_ISO14443_4A_106;
break;
case NMT_ISO14443B:
switch(nm.nbr) {
case NBR_106:
return PTT_ISO14443_4B_106;
break;
}
break;
case NMT_JEWEL:
return PTT_JEWEL_106;
break;
case NMT_FELICA:
switch(nm.nbr) {
case NBR_212:
return PTT_FELICA_212;
break;
case NBR_424:
return PTT_FELICA_424;
break;
}
break;
}
}

View file

@ -90,6 +90,69 @@
# define DEISERRFRAME 0x0300/* Error frame */ # define DEISERRFRAME 0x0300/* Error frame */
# define DENOTSUP 0x0400/* Not supported */ # define DENOTSUP 0x0400/* Not supported */
/* PN53x specific types */
/**
* @enum pn53x_modulation_t
* @brief NFC modulation
*/
typedef enum {
/** ISO14443-A (NXP MIFARE) http://en.wikipedia.org/wiki/MIFARE */
PM_ISO14443A_106 = 0x00,
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
PM_FELICA_212 = 0x01,
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
PM_FELICA_424 = 0x02,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531) */
PM_ISO14443B_106 = 0x03,
/** Jewel Topaz (Innovision Research & Development) (Not supported by PN531) */
PM_JEWEL_106 = 0x04,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
PM_ISO14443B_212 = 0x06,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
PM_ISO14443B_424 = 0x07,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
PM_ISO14443B_847 = 0x08,
} pn53x_modulation_t;
/**
* @enum pn53x_target_type_t
* @brief NFC target type enumeration
*/
typedef enum {
/** Generic passive 106 kbps (ISO/IEC14443-4A, mifare, DEP) */
PTT_GENERIC_PASSIVE_106 = 0x00,
/** Generic passive 212 kbps (FeliCa, DEP) */
PTT_GENERIC_PASSIVE_212 = 0x01,
/** Generic passive 424 kbps (FeliCa, DEP) */
PTT_GENERIC_PASSIVE_424 = 0x02,
/** Passive 106 kbps ISO/IEC14443-4B */
PTT_ISO14443_4B_106 = 0x03,
/** Innovision Jewel tag */
PTT_JEWEL_106 = 0x04,
/** Mifare card */
PTT_MIFARE = 0x10,
/** FeliCa 212 kbps card */
PTT_FELICA_212 = 0x11,
/** FeliCa 424 kbps card */
PTT_FELICA_424 = 0x12,
/** Passive 106 kbps ISO/IEC 14443-4A */
PTT_ISO14443_4A_106 = 0x20,
/** Passive 106 kbps ISO/IEC 14443-4B with TCL flag */
PTT_ISO14443_4B_TCL_106 = 0x23,
/** DEP passive 106 kbps */
PTT_DEP_PASSIVE_106 = 0x40,
/** DEP passive 212 kbps */
PTT_DEP_PASSIVE_212 = 0x41,
/** DEP passive 424 kbps */
PTT_DEP_PASSIVE_424 = 0x42,
/** DEP active 106 kbps */
PTT_DEP_ACTIVE_106 = 0x80,
/** DEP active 212 kbps */
PTT_DEP_ACTIVE_212 = 0x81,
/** DEP active 424 kbps */
PTT_DEP_ACTIVE_424 = 0x82,
} pn53x_target_type_t;
bool pn53x_init(nfc_device_t * pnd); bool pn53x_init(nfc_device_t * pnd);
bool pn53x_transceive_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, bool pn53x_transceive_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame,
const size_t szRxFrameLen); const size_t szRxFrameLen);
@ -105,14 +168,22 @@ bool pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byt
size_t * pszFrameBits); size_t * pszFrameBits);
bool pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits, bool pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits,
byte_t * pbtRxPar); byte_t * pbtRxPar);
bool pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt, bool pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData, nfc_chip_t nc, nfc_modulation_type_t nmt,
nfc_target_info_t * pnti); nfc_target_info_t * pnti);
bool pn53x_get_firmware_version (nfc_device_t * pnd); bool pn53x_get_firmware_version (nfc_device_t * pnd);
bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable); bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
// NFC device as Initiator functions // NFC device as Initiator functions
bool pn53x_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, bool pn53x_initiator_select_passive_target (nfc_device_t * pnd,
const nfc_modulation_t nm,
const byte_t * pbtInitData, const size_t szInitData,
nfc_target_info_t * pnti);
bool pn53x_initiator_poll_targets (nfc_device_t * pnd,
const nfc_modulation_t * pnmModulations, const size_t szModulations,
const byte_t btPollNr, const byte_t btPeriod,
nfc_target_t * pntTargets, size_t * pszTargetFound);
bool pn53x_initiator_select_dep_target (nfc_device_t * pnd, nfc_dep_mode_t ndm,
const nfc_dep_info_t * pndiInitiator, const nfc_dep_info_t * pndiInitiator,
nfc_target_info_t * pnti); nfc_target_info_t * pnti);
bool pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, bool pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
@ -135,15 +206,15 @@ static const struct chip_callbacks pn53x_callbacks_list = {
// C wrappers for PN53x commands // C wrappers for PN53x commands
bool pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value); bool pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value);
bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const pn53x_modulation_t pmInitModulation,
const byte_t szMaxTargets, const byte_t * pbtInitiatorData, const byte_t szMaxTargets, const byte_t * pbtInitiatorData,
const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData); const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData);
bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target); bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target);
bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target); bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target);
bool pn53x_InAutoPoll (nfc_device_t * pnd, const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes, bool pn53x_InAutoPoll (nfc_device_t * pnd, const pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes,
const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets,
size_t * pszTargetFound); size_t * pszTargetFound);
bool pn53x_InJumpForDEP (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, bool pn53x_InJumpForDEP (nfc_device_t * pnd, nfc_dep_mode_t ndm,
const byte_t * pbtPassiveInitiatorData, const size_t szPassiveInitiatorData, const byte_t * pbtPassiveInitiatorData, const size_t szPassiveInitiatorData,
const byte_t * pbtNFCID3i, const byte_t * pbtNFCID3i,
const byte_t * pbtGB, const size_t szGB, const byte_t * pbtGB, const size_t szGB,

View file

@ -262,7 +262,7 @@ nfc_initiator_init (nfc_device_t * pnd)
* @return Returns \c true if action was successfully performed; otherwise returns \c false. * @return Returns \c true if action was successfully performed; otherwise returns \c false.
* *
* @param pnd \a nfc_device_t struct pointer that represent currently used device * @param pnd \a nfc_device_t struct pointer that represent currently used device
* @param nmInitModulation Desired modulation * @param pmInitModulation Desired modulation
* @param pbtInitData Optional initiator data used for Felica, ISO14443B, Topaz polling or to select a specific UID in ISO14443A. * @param pbtInitData Optional initiator data used for Felica, ISO14443B, Topaz polling or to select a specific UID in ISO14443A.
* @param szInitDataLen Length of initiator data \a pbtInitData. * @param szInitDataLen Length of initiator data \a pbtInitData.
* @param[out] pnti nfc_target_info_t struct pointer which will filled if available * @param[out] pnti nfc_target_info_t struct pointer which will filled if available
@ -275,14 +275,12 @@ nfc_initiator_init (nfc_device_t * pnd)
*/ */
bool bool
nfc_initiator_select_passive_target (nfc_device_t * pnd, nfc_initiator_select_passive_target (nfc_device_t * pnd,
const nfc_modulation_t nmInitModulation, const nfc_modulation_t nm,
const byte_t * pbtInitData, const size_t szInitDataLen, nfc_target_info_t * pnti) const byte_t * pbtInitData, const size_t szInitData,
nfc_target_info_t * pnti)
{ {
byte_t abtInit[MAX_FRAME_LEN]; byte_t abtInit[MAX_FRAME_LEN];
size_t szInitLen; size_t szInit;
size_t szTargetsData;
byte_t abtTargetsData[MAX_FRAME_LEN];
pnd->iLastError = 0; pnd->iLastError = 0;
@ -290,13 +288,13 @@ nfc_initiator_select_passive_target (nfc_device_t * pnd,
if (!pnd->bActive) if (!pnd->bActive)
return false; return false;
// TODO Put this in a function: this part is defined by ISO14443-3 (UID and Cascade levels) // TODO Put this in a function: this part is defined by ISO14443-3 (UID and Cascade levels)
switch (nmInitModulation) { switch (nm.nmt) {
case NM_ISO14443A_106: case NMT_ISO14443A:
switch (szInitDataLen) { switch (szInitData) {
case 7: case 7:
abtInit[0] = 0x88; abtInit[0] = 0x88;
memcpy (abtInit + 1, pbtInitData, 7); memcpy (abtInit + 1, pbtInitData, 7);
szInitLen = 8; szInit = 8;
break; break;
case 10: case 10:
@ -304,78 +302,32 @@ nfc_initiator_select_passive_target (nfc_device_t * pnd,
memcpy (abtInit + 1, pbtInitData, 3); memcpy (abtInit + 1, pbtInitData, 3);
abtInit[4] = 0x88; abtInit[4] = 0x88;
memcpy (abtInit + 5, pbtInitData + 3, 7); memcpy (abtInit + 5, pbtInitData + 3, 7);
szInitLen = 12; szInit = 12;
break; break;
case 4: case 4:
default: default:
memcpy (abtInit, pbtInitData, szInitDataLen); memcpy (abtInit, pbtInitData, szInitData);
szInitLen = szInitDataLen; szInit = szInitData;
break; break;
} }
break; break;
default: default:
memcpy (abtInit, pbtInitData, szInitDataLen); memcpy (abtInit, pbtInitData, szInitData);
szInitLen = szInitDataLen; szInit = szInitData;
break; break;
} }
if (!pn53x_InListPassiveTarget (pnd, nmInitModulation, 1, abtInit, szInitLen, abtTargetsData, &szTargetsData)) return pn53x_initiator_select_passive_target (pnd, nm, abtInit, szInit, pnti);
return false;
// Make sure one tag has been found, the PN53X returns 0x00 if none was available
if (abtTargetsData[0] == 0)
return false;
// Is a tag info struct available
if (pnti) {
// Fill the tag info struct with the values corresponding to this init modulation
switch (nmInitModulation) {
case NM_ISO14443A_106:
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) {
return false;
} }
break;
case NM_FELICA_212:
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_FELICA_212, pnti)) {
return false;
}
break;
case NM_FELICA_424:
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_FELICA_424, pnti)) {
return false;
}
break;
case NM_ISO14443B_106:
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_ISO14443_4B_106, pnti)) {
return false;
}
break;
case NM_JEWEL_106:
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_JEWEL_106, pnti)) {
return false;
}
break;
default:
// Should not be possible, so whatever...
break;
}
}
return true;
}
/** /**
* @brief List passive or emulated tags * @brief List passive or emulated tags
* @return Returns \c true if action was successfully performed; otherwise returns \c false. * @return Returns \c true if action was successfully performed; otherwise returns \c false.
* *
* @param pnd \a nfc_device_t struct pointer that represent currently used device * @param pnd \a nfc_device_t struct pointer that represent currently used device
* @param nmInitModulation Desired modulation * @param pmInitModulation Desired modulation
* @param[out] anti array of \a nfc_target_info_t that will be filled with targets info * @param[out] anti array of \a nfc_target_info_t that will be filled with targets info
* @param szTargets Size of \a anti (will be the max targets listed) * @param szTargets Size of \a anti (will be the max targets listed)
* @param[out] pszTargetFound Pointer where target found counter will be stored * @param[out] pszTargetFound Pointer where target found counter will be stored
@ -384,7 +336,7 @@ nfc_initiator_select_passive_target (nfc_device_t * pnd,
* @note For every initial modulation type there is a different collection of information returned (in \a nfc_target_info_t pointer pti) They all fit in the data-type which is called nfc_target_info_t. This is a union which contains the tag information that belongs to the according initial modulation type. * @note For every initial modulation type there is a different collection of information returned (in \a nfc_target_info_t pointer pti) They all fit in the data-type which is called nfc_target_info_t. This is a union which contains the tag information that belongs to the according initial modulation type.
*/ */
bool bool
nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nm,
nfc_target_info_t anti[], const size_t szTargets, size_t * pszTargetFound) nfc_target_info_t anti[], const size_t szTargets, size_t * pszTargetFound)
{ {
nfc_target_info_t nti; nfc_target_info_t nti;
@ -397,17 +349,25 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t n
// Let the reader only try once to find a target // Let the reader only try once to find a target
nfc_configure (pnd, NDO_INFINITE_SELECT, false); nfc_configure (pnd, NDO_INFINITE_SELECT, false);
if (nmInitModulation == NM_ISO14443B_106) { switch (nm.nmt) {
case NMT_ISO14443B: {
// Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3) // Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
pbtInitData = (byte_t *) "\x00"; pbtInitData = (byte_t *) "\x00";
szInitDataLen = 1; szInitDataLen = 1;
} else if (nmInitModulation == NM_FELICA_212 || nmInitModulation == NM_FELICA_424) { }
break;
case NMT_FELICA: {
// polling payload must be present (see ISO/IEC 18092 11.2.2.5) // polling payload must be present (see ISO/IEC 18092 11.2.2.5)
pbtInitData = (byte_t *) "\x00\xff\xff\x01\x00"; pbtInitData = (byte_t *) "\x00\xff\xff\x01\x00";
szInitDataLen = 5; szInitDataLen = 5;
} }
break;
default:
// nothing to do
break;
}
while (nfc_initiator_select_passive_target (pnd, nmInitModulation, pbtInitData, szInitDataLen, &nti)) { while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nti)) {
nfc_initiator_deselect_target (pnd); nfc_initiator_deselect_target (pnd);
if (szTargets > szTargetFound) { if (szTargets > szTargetFound) {
@ -417,7 +377,7 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t n
} }
szTargetFound++; szTargetFound++;
// deselect has no effect on FeliCa and Jewel cards so we'll stop after one... // deselect has no effect on FeliCa and Jewel cards so we'll stop after one...
if (nmInitModulation == NM_FELICA_212 || nmInitModulation == NM_FELICA_424 || nmInitModulation == NM_JEWEL_106) { if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL)) {
break; break;
} }
} }
@ -431,8 +391,8 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t n
* @return Returns \c true if action was successfully performed; otherwise returns \c false. * @return Returns \c true if action was successfully performed; otherwise returns \c false.
* *
* @param pnd \a nfc_device_t struct pointer that represent currently used device * @param pnd \a nfc_device_t struct pointer that represent currently used device
* @param pnttTargetTypes array of desired target types * @param ppttTargetTypes array of desired target types
* @param szTargetTypes pnttTargetTypes count * @param szTargetTypes ppttTargetTypes count
* @param btPollNr specifies the number of polling * @param btPollNr specifies the number of polling
* @note one polling is a polling for each desired target type * @note one polling is a polling for each desired target type
* @param btPeriod indicates the polling period in units of 150 ms * @param btPeriod indicates the polling period in units of 150 ms
@ -441,21 +401,22 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t n
*/ */
bool bool
nfc_initiator_poll_targets (nfc_device_t * pnd, nfc_initiator_poll_targets (nfc_device_t * pnd,
const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes, const nfc_modulation_t * pnmModulations, const size_t szModulations,
const byte_t btPollNr, const byte_t btPeriod, const byte_t btPollNr, const byte_t btPeriod,
nfc_target_t * pntTargets, size_t * pszTargetFound) nfc_target_t * pntTargets, size_t * pszTargetFound)
{ {
pnd->iLastError = 0; pnd->iLastError = 0;
return pn53x_InAutoPoll (pnd, pnttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound); return pn53x_initiator_poll_targets (pnd, pnmModulations, szModulations, btPollNr, btPeriod, pntTargets, pszTargetFound);
} }
/** /**
* @brief Select a target and request active or passive mode for DEP (Data Exchange Protocol) * @brief Select a target and request active or passive mode for DEP (Data Exchange Protocol)
* @return Returns \c true if action was successfully performed; otherwise returns \c false. * @return Returns \c true if action was successfully performed; otherwise returns \c false.
* *
* @param pnd \a nfc_device_t struct pointer that represent currently used device * @param pnd \a nfc_device_t struct pointer that represent currently used device
* @param nmInitModulation desired modulation (\a NM_ACTIVE_DEP or \a NM_PASSIVE_DEP for active, respectively passive mode) * @param pmInitModulation desired modulation (\a PM_ACTIVE_DEP or \a PM_PASSIVE_DEP for active, respectively passive mode)
* @param ndiInitiator \a nfc_dep_info_t struct that contains NFCID3 and General Bytes to set to the initiator device * @param ndiInitiator \a nfc_dep_info_t struct that contains NFCID3 and General Bytes to set to the initiator device
* @param[out] pnti is a \a nfc_target_info_t struct pointer where target information will be put. * @param[out] pnti is a \a nfc_target_info_t struct pointer where target information will be put.
* *
@ -466,11 +427,11 @@ nfc_initiator_poll_targets (nfc_device_t * pnd,
* @note \a nfc_dep_info_t will be returned when the target was acquired successfully. * @note \a nfc_dep_info_t will be returned when the target was acquired successfully.
*/ */
bool bool
nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, const nfc_dep_info_t * pndiInitiator, nfc_target_info_t * pnti) nfc_initiator_select_dep_target (nfc_device_t * pnd, const bool bActiveDep, const nfc_dep_info_t * pndiInitiator, nfc_target_info_t * pnti)
{ {
pnd->iLastError = 0; pnd->iLastError = 0;
return pn53x_initiator_select_dep_target (pnd, nmInitModulation, pndiInitiator, pnti); return pn53x_initiator_select_dep_target (pnd, bActiveDep, pndiInitiator, pnti);
} }
/** /**

57
manual-test-results.txt Normal file
View file

@ -0,0 +1,57 @@
#,0# rev, program, local device, distant device, status
#,1# (to sort easily: sort -k2 -t, manual-test-results.txt)
#,2######################################################
r736, nfc-anticol, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, DESfire, OK
r736, nfc-anticol, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, MFC, OK
r736, nfc-anticol, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, UL, OK
r736, nfc-anticol, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, DESfire, OK
r736, nfc-anticol, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, MFC, OK
r736, nfc-anticol, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, UL, OK
r736, nfc-dep-initiator, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, ACS ACR 38U-CCID 00 00 / ACR122U102 - PN532 v1.4, OK
r736, nfc-dep-target, ACS ACR 38U-CCID 00 00 / ACR122U102 - PN532 v1.4, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, OK
r736, nfc-emulate-forum-tag4, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, ctrl-c & use, FAIL
r744, nfc-emulate-forum-tag4, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, Nokia 6131 NFC, OK
r736, nfc-emulate-forum-tag4, ACS ACR 38U-CCID 00 00 / ACR122U102 - PN532 v1.4, Nokia 6212 Classic, OK
r744, nfc-emulate-tag, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, Cardman 5321, OK
r744, nfc-emulate-tag, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, CardMan 5321, OK
r736, nfc-emulate-tag, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, ctrl-c & use, FAIL
r736, nfc-emulate-tag, ACS ACR 38U-CCID 00 00 / ACR122U102 - PN532 v1.4, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, OK
r736, nfc-emulate-tag, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, ACS ACR 38U-CCID 00 00 / ACR122U102 - PN532 v1.4, OK
r736, nfc-emulate-tag, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, ctrl-c & use, OK
r736, nfc-emulate-uid, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, ctrl-c & use, FAIL
r744, nfc-emulate-uid, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, emulate + ctrl-c & use, FAIL
r736, nfc-emulate-uid, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4 + nfc-anticol 2x, OK
r736, nfc-emulate-uid, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, ctrl-c & use, OK
r736, nfc-list, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, 2 DESfire, OK
r736, nfc-list, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, 2 UL, OK
r736, nfc-list, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, JCOP, OK
r736, nfc-list, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, MFC, OK
r736, nfc-list, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, topaz, OK
r736, nfc-list, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, typeB Calypso, OK
r736, nfc-list, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, ULC, OK
r736, nfc-list, ACS ACR 38U-CCID 00 00 / ACR122U102 - PN532 v1.4, DESFire, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, 2 DESfire, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, 2 UL, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, DESFire, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, JCOP, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, MFC, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, topaz, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, typeB Calypso, OK
r736, nfc-list, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, ULC, OK
r736, nfc-mfclassic r a foo, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, MFC, OK
r736, nfc-mfclassic r a foo, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, MFC, OK
r736, nfc-mfultralight r foo, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, UL, OK
r736, nfc-mfultralight r foo, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, UL, OK
r739, nfc-poll, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, 2 DESfire, OK
r739, nfc-poll, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, 2 UL, OK
r739, nfc-poll, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, JCOP, OK
r739, nfc-poll, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, MFC, OK
r739, nfc-poll, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, topaz, OK
r739, nfc-poll, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, typeB Calypso, OK
r739, nfc-poll, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, ULC, OK
r736, pn53x-diagnose, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, N/A, OK
r736, pn53x-diagnose, ACS ACR 38U-CCID 00 00 / ACR122U102 - PN532 v1.4, N/A, OK
r736, pn53x-diagnose, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, N/A, OK
r744, pn53x-sam (mode 1), Philips / PN531 - PN531 v4.2 + SAM, CardMan 5321, OK
r736, pn53x-tamashell < pn53x-tamashell-scripts/UltraLightRead.cmd, ACS ACR122U PICC Interface 00 00 / ACR122U102 - PN532 v1.4, ultralight, OK
r736, pn53x-tamashell < pn53x-tamashell-scripts/UltraLightRead.cmd, SCM Micro / SCL3711-NFC&RW - PN533 v2.7, UL, OK

View file

@ -56,7 +56,11 @@ test_access_storm (void)
res = nfc_configure(device,NDO_ACTIVATE_FIELD,true); res = nfc_configure(device,NDO_ACTIVATE_FIELD,true);
cut_assert_true (res, cut_message ("nfc_configure")); cut_assert_true (res, cut_message ("nfc_configure"));
res = nfc_initiator_list_passive_targets(device, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &target_count); const nfc_modulation_t nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
res = nfc_initiator_list_passive_targets(device, nm, anti, MAX_TARGET_COUNT, &target_count);
cut_assert_true (res, cut_message ("nfc_initiator_list_passive_targets")); cut_assert_true (res, cut_message ("nfc_initiator_list_passive_targets"));
nfc_disconnect (device); nfc_disconnect (device);