diff --git a/examples/doc/quick_start_example1.c b/examples/doc/quick_start_example1.c index f8dd379..22c4cc9 100644 --- a/examples/doc/quick_start_example1.c +++ b/examples/doc/quick_start_example1.c @@ -32,7 +32,7 @@ main (int argc, const char *argv[]) printf ("Connected to NFC reader: %s\n", pnd->acName); // 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 (" ATQA (SENS_RES): "); print_hex (nti.nai.abtAtqa, 2); diff --git a/examples/nfc-dep-initiator.c b/examples/nfc-dep-initiator.c index eb5f34a..b21f83c 100644 --- a/examples/nfc-dep-initiator.c +++ b/examples/nfc-dep-initiator.c @@ -62,7 +62,7 @@ main (int argc, const char *argv[]) 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"); return EXIT_FAILURE; } diff --git a/examples/nfc-dep-target.c b/examples/nfc-dep-target.c index 539bcb6..1af716e 100644 --- a/examples/nfc-dep-target.c +++ b/examples/nfc-dep-target.c @@ -66,7 +66,8 @@ main (int argc, const char *argv[]) } 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.szGB = 4, .nti.ndi.abtGB = { 0x12, 0x34, 0x56, 0x78 }, diff --git a/examples/nfc-emulate-forum-tag4.c b/examples/nfc-emulate-forum-tag4.c index 650221b..11b3c50 100644 --- a/examples/nfc-emulate-forum-tag4.c +++ b/examples/nfc-emulate-forum-tag4.c @@ -112,7 +112,8 @@ main (int argc, char *argv[]) printf ("Emulating NDEF tag now, please touch it with a second NFC device\n"); nfc_target_t nt = { - .ntt = NTT_MIFARE, + .nm.nmt = NMT_ISO14443A, + .nm.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x00, 0x04 }, .nti.nai.abtUid = { 0x08, 0x00, 0xb0, 0x0b }, .nti.nai.btSak = 0x20, diff --git a/examples/nfc-emulate-tag.c b/examples/nfc-emulate-tag.c index e5b9c81..7ea2cff 100644 --- a/examples/nfc-emulate-tag.c +++ b/examples/nfc-emulate-tag.c @@ -173,7 +173,8 @@ main (int argc, char *argv[]) // Example of a Mifare Classic Mini // Note that crypto1 is not implemented in this example nfc_target_t nt = { - .ntt = NTT_MIFARE, + .nm.nmt = NMT_ISO14443A, + .nm.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x00, 0x04 }, .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef }, .nti.nai.btSak = 0x09, @@ -183,7 +184,8 @@ main (int argc, char *argv[]) /* // Example of a FeliCa 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.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF }, .nti.nfi.abtSysCode = { 0xFF, 0xFF }, @@ -192,7 +194,8 @@ main (int argc, char *argv[]) /* // Example of a ISO14443-4 (DESfire) nfc_target_t nt = { - .ntt = NTT_MIFARE, + .nm.nmt = NMT_ISO14443A, + .nm.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x03, 0x44 }, .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef }, .nti.nai.btSak = 0x20, diff --git a/examples/nfc-emulate-uid.c b/examples/nfc-emulate-uid.c index 576d1f9..be56d0c 100644 --- a/examples/nfc-emulate-uid.c +++ b/examples/nfc-emulate-uid.c @@ -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. nfc_target_t nt = { - .ntt = NTT_MIFARE, + .nm.nmt = NMT_ISO14443A, + .nm.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x04, 0x00 }, .nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xaf }, .nti.nai.btSak = 0x20, diff --git a/examples/nfc-list.c b/examples/nfc-list.c index e20c16c..16afeae 100644 --- a/examples/nfc-list.c +++ b/examples/nfc-list.c @@ -111,13 +111,13 @@ main (int argc, const char *argv[]) nfc_target_info_t anti[MAX_TARGET_COUNT]; pnd = nfc_connect (&(pnddDevices[i])); - if (pnd == NULL) { ERR ("%s", "Unable to connect to NFC device."); return EXIT_FAILURE; } 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 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) { nfc_perror (pnd, "nfc_configure"); @@ -142,7 +142,11 @@ main (int argc, const char *argv[]) printf ("Connected to NFC device: %s\n", pnd->acName); // 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; printf ("%d ISO14443A passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":"); for (n = 0; n < szTargetFound; n++) { @@ -150,8 +154,11 @@ main (int argc, const char *argv[]) printf ("\n"); } } + + nm.nmt = NMT_FELICA; + nm.nbr = NBR_212; // 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; printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":"); @@ -160,7 +167,9 @@ main (int argc, const char *argv[]) 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; printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":"); @@ -169,8 +178,11 @@ main (int argc, const char *argv[]) printf ("\n"); } } + + nm.nmt = NMT_ISO14443B; + nm.nbr = NBR_106; // 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; printf ("%d ISO14443B passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\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 - 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; printf("%d Jewel passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":"); for(n=0; nacName); // 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"); nfc_disconnect (pnd); exit (EXIT_FAILURE); diff --git a/examples/nfc-mfultralight.c b/examples/nfc-mfultralight.c index 3ef4db1..c46da2b 100644 --- a/examples/nfc-mfultralight.c +++ b/examples/nfc-mfultralight.c @@ -47,6 +47,11 @@ static mifare_param mp; static mifareul_tag mtDump; static uint32_t uiBlocks = 0xF; +static const nfc_modulation_t nmMifare = { + .nmt = NMT_ISO14443A, + .nbr = NBR_106, +}; + static void print_success_or_failure (bool bFailure, uint32_t * uiCounter) { @@ -116,7 +121,7 @@ write_card (void) // Show if the readout went well if (bFailure) { // 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"); return false; } @@ -216,7 +221,7 @@ main (int argc, const char *argv[]) printf ("Connected to NFC device: %s\n", pnd->acName); // 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"); nfc_disconnect (pnd); return 1; diff --git a/examples/nfc-poll.c b/examples/nfc-poll.c index 5e4dd90..81e4443 100644 --- a/examples/nfc-poll.c +++ b/examples/nfc-poll.c @@ -72,8 +72,14 @@ main (int argc, const char *argv[]) const byte_t btPollNr = 20; 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 size_t szTargetTypes = 5; + const nfc_modulation_t nmModulations[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]; size_t szTargetFound; @@ -105,57 +111,15 @@ main (int argc, const char *argv[]) printf ("Connected to NFC reader: %s\n", pnd->acName); - printf ("PN532 will poll during %ld ms\n", (unsigned long) btPollNr * szTargetTypes * btPeriod * 150); - res = nfc_initiator_poll_targets (pnd, nttArray, szTargetTypes, btPollNr, btPeriod, antTargets, &szTargetFound); + printf ("PN532 will poll during %ld ms\n", (unsigned long) btPollNr * szModulations * btPeriod * 150); + res = nfc_initiator_poll_targets (pnd, nmModulations, szModulations, btPollNr, btPeriod, antTargets, &szTargetFound); if (res) { uint8_t n; printf ("%ld target(s) have been found.\n", (unsigned long) szTargetFound); for (n = 0; n < szTargetFound; n++) { - printf ("T%d: targetType=%02x ", n + 1, antTargets[n].ntt); - switch(antTargets[n].ntt) { - 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; - }; + printf ("T%d: ", n + 1); + print_nfc_target ( antTargets[n] ); + } } else { nfc_perror (pnd, "nfc_initiator_poll_targets"); diff --git a/examples/nfc-relay.c b/examples/nfc-relay.c index 90b1e4e..4550633 100644 --- a/examples/nfc-relay.c +++ b/examples/nfc-relay.c @@ -127,7 +127,8 @@ main (int argc, char *argv[]) printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n"); nfc_target_t nt = { - .ntt = NTT_MIFARE, + .nm.nmt = NMT_ISO14443A, + .nm.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x04, 0x00 }, .nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xef }, .nti.nai.btSak = 0x20, diff --git a/examples/nfc-utils.c b/examples/nfc-utils.c index 47f3e75..b2d681e 100644 --- a/examples/nfc-utils.c +++ b/examples/nfc-utils.c @@ -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. * @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; } + +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; + } +} + diff --git a/examples/nfc-utils.h b/examples/nfc-utils.h index a842c77..1497bbe 100644 --- a/examples/nfc-utils.h +++ b/examples/nfc-utils.h @@ -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_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); diff --git a/examples/pn53x-sam.c b/examples/pn53x-sam.c index 181cd37..1f3dee4 100644 --- a/examples/pn53x-sam.c +++ b/examples/pn53x-sam.c @@ -181,7 +181,11 @@ main (int argc, const char *argv[]) exit (EXIT_FAILURE); } // 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"); ERR ("%s", "Reading of SAM info failed."); return EXIT_FAILURE; @@ -198,7 +202,8 @@ main (int argc, const char *argv[]) size_t szRx; nfc_target_t nt = { - .ntt = NTT_MIFARE, + .nm.nmt = NMT_ISO14443A, + .nm.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x04, 0x00 }, .nti.nai.abtUid = { 0x08, 0xad, 0xbe, 0xaf }, .nti.nai.btSak = 0x20, diff --git a/include/nfc/nfc-types.h b/include/nfc/nfc-types.h index 5270cd5..06cf9cf 100644 --- a/include/nfc/nfc-types.h +++ b/include/nfc/nfc-types.h @@ -165,36 +165,9 @@ typedef enum { NDO_FORCE_ISO14443_A = 0x42, } 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 - * @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 { /** NFCID3 */ @@ -214,6 +187,15 @@ typedef struct { size_t szGB; } 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 * @brief NFC ISO14443A tag (MIFARE) information @@ -291,43 +273,36 @@ typedef enum { } nfc_target_mode_t; /** - * @enum nfc_target_type_t - * @brief NFC target type enumeration + * @enum nfc_baud_rate_t + * @brief NFC baud rate enumeration */ typedef enum { - /** Generic passive 106 kbps (ISO/IEC14443-4A, mifare, DEP) */ - NTT_GENERIC_PASSIVE_106 = 0x00, - /** Generic passive 212 kbps (FeliCa, DEP) */ - NTT_GENERIC_PASSIVE_212 = 0x01, - /** Generic passive 424 kbps (FeliCa, DEP) */ - NTT_GENERIC_PASSIVE_424 = 0x02, - /** Passive 106 kbps ISO/IEC14443-4B */ - NTT_ISO14443_4B_106 = 0x03, - /** Innovision Jewel tag */ - NTT_JEWEL_106 = 0x04, - /** Mifare card */ - NTT_MIFARE = 0x10, - /** FeliCa 212 kbps card */ - NTT_FELICA_212 = 0x11, - /** FeliCa 424 kbps card */ - NTT_FELICA_424 = 0x12, - /** Passive 106 kbps ISO/IEC 14443-4A */ - NTT_ISO14443_4A_106 = 0x20, - /** Passive 106 kbps ISO/IEC 14443-4B with TCL flag */ - NTT_ISO14443_4B_TCL_106 = 0x23, - /** DEP passive 106 kbps */ - NTT_DEP_PASSIVE_106 = 0x40, - /** DEP passive 212 kbps */ - NTT_DEP_PASSIVE_212 = 0x41, - /** DEP passive 424 kbps */ - NTT_DEP_PASSIVE_424 = 0x42, - /** 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; + NBR_UNDEFINED = 0, + NBR_106, + NBR_212, + NBR_424, +} nfc_baud_rate_t; + +/** + * @enum nfc_modulation_type_t + * @brief NFC modulation type enumeration + */ +typedef enum { + NMT_ISO14443A, + NMT_ISO14443B, + NMT_FELICA, + NMT_JEWEL, + NMT_DEP, +} nfc_modulation_type_t; + +/** + * @struct nfc_modulation_t + * @brief NFC modulation structure + */ +typedef struct { + nfc_modulation_type_t nmt; + nfc_baud_rate_t nbr; +} nfc_modulation_t; /** * @struct nfc_target_t @@ -335,7 +310,7 @@ typedef enum { */ typedef struct { nfc_target_info_t nti; - nfc_target_type_t ntt; + nfc_modulation_t nm; } nfc_target_t; // Reset struct alignment to default diff --git a/include/nfc/nfc.h b/include/nfc/nfc.h index ca7d58b..dff698b 100644 --- a/include/nfc/nfc.h +++ b/include/nfc/nfc.h @@ -68,16 +68,16 @@ extern "C" { /* NFC initiator: act as "reader" */ 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, - const byte_t * pbtInitData, const size_t szInitDataLen, + NFC_EXPORT bool nfc_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 * 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, 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, 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, nfc_target_info_t * pti); NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd); diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index e767cf1..ee310c7 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -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_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 pn53x_init(nfc_device_t * pnd) { @@ -369,15 +374,13 @@ pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * } 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) { uint8_t szAttribRes; - switch (ntt) { - case NTT_MIFARE: - case NTT_GENERIC_PASSIVE_106: - case NTT_ISO14443_4A_106: + switch (nmt) { + case NMT_ISO14443A: // We skip the first byte: its the target number (Tg) pbtRawData++; @@ -396,7 +399,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_ pbtRawData += pnti->nai.szUidLen; // 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. memcpy (pnti->nai.abtAts, pbtRawData, pnti->nai.szAtsLen); } else { @@ -415,8 +418,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_ } break; - case NTT_ISO14443_4B_106: - case NTT_ISO14443_4B_TCL_106: + case NMT_ISO14443B: // We skip the first byte: its the target number (Tg) pbtRawData++; @@ -442,8 +444,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_ } break; - case NTT_FELICA_212: - case NTT_FELICA_424: + case NMT_FELICA: // We skip the first byte: its the target number (Tg) pbtRawData++; @@ -461,7 +462,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_ memcpy (pnti->nfi.abtSysCode, pbtRawData, 2); } break; - case NTT_JEWEL_106: + case NMT_JEWEL: // We skip the first byte: its the target number (Tg) pbtRawData++; @@ -477,14 +478,63 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_ 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; nnc == NC_PN531) { // These modulations are not supported by pn531 pnd->iLastError = DENOTSUP; return false; } break; - case NM_ISO14443B_212: - case NM_ISO14443B_424: - case NM_ISO14443B_847: + case PM_ISO14443B_212: + case PM_ISO14443B_424: + case PM_ISO14443B_847: if(pnd->nc != NC_PN533) { // These modulations are not supported by pn531 neither pn532 pnd->iLastError = DENOTSUP; @@ -531,15 +582,15 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd, pnd->iLastError = DENOTSUP; 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). 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 szRx = MAX_FRAME_LEN; - if (pn53x_transceive (pnd, abtCmd, 4 + szInitiatorDataLen, pbtTargetsData, &szRx)) { + if (pn53x_transceive (pnd, abtCmd, 4 + szInitiatorData, pbtTargetsData, &szRx)) { *pszTargetsData = szRx; return true; } else { @@ -569,7 +620,7 @@ 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, + 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) { size_t szTxInAutoPoll, @@ -592,7 +643,7 @@ pn53x_InAutoPoll (nfc_device_t * pnd, pbtTxInAutoPoll[2] = btPollNr; pbtTxInAutoPoll[3] = btPeriod; for (n = 0; n < szTargetTypes; n++) { - pbtTxInAutoPoll[4 + n] = pnttTargetTypes[n]; + pbtTxInAutoPoll[4 + n] = ppttTargetTypes[n]; } szRx = MAX_FRAME_LEN; @@ -607,19 +658,21 @@ pn53x_InAutoPoll (nfc_device_t * pnd, byte_t *pbt = abtRx + 1; /* 1st target */ // Target type - pntTargets[0].ntt = *(pbt++); + pn53x_target_type_t ptt = *(pbt++); + pntTargets[0].nm = pn53x_ptt_to_nm(ptt); // AutoPollTargetData length 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; if (abtRx[0] > 1) { /* 2nd target */ // Target type - pntTargets[1].ntt = *(pbt++); + ptt = *(pbt++); + pntTargets[1].nm = pn53x_ptt_to_nm(ptt); // AutoPollTargetData length 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]; size_t szFwLen = sizeof (abtFw); 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)) { // 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); @@ -821,20 +874,20 @@ pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool b } 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, nfc_target_info_t * pnti) { 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 { - 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 - * @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 szPassiveInitiatorData size of pbtPassiveInitiatorData content * @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 */ 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 * pbtNFCID3i, 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)); - if (nmInitModulation == NM_ACTIVE_DEP) { - abtCmd[2] = 0x01; /* active DEP */ - } + abtCmd[2] = (ndm == NDM_ACTIVE) ? 0x01 : 0x00; + // FIXME Baud rate in D.E.P. mode is hard-wired as 106kbps abtCmd[3] = 0x00; /* baud rate = 106kbps */ 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; memcpy (abtCmd + offset, pbtPassiveInitiatorData, 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; size_t szGB = 0; - switch(nt.ntt) { - case NTT_MIFARE: - case NTT_GENERIC_PASSIVE_106: - case NTT_ISO14443_4A_106: { + switch(nt.nm.nmt) { + case NMT_ISO14443A: { // Set ATQA (SENS_RES) abtMifareParams[0] = nt.nti.nai.abtAtqa[1]; 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; - case NTT_FELICA_212: - case NTT_FELICA_424: + case NMT_FELICA: // Set NFCID2t memcpy(abtFeliCaParams, nt.nti.nfi.abtId, 8); // Set PAD @@ -1100,13 +1150,16 @@ pn53x_target_init (nfc_device_t * pnd, const nfc_target_mode_t ntm, const nfc_ta pbtFeliCaParams = abtFeliCaParams; break; - case NTT_DEP_PASSIVE_106: - case NTT_DEP_PASSIVE_212: - case NTT_DEP_PASSIVE_424: + case NMT_DEP: pbtNFCID3t = nt.nti.ndi.abtNFCID3; szGB = nt.nti.ndi.szGB; if (szGB) pbtGB = nt.nti.ndi.abtGB; 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)) { @@ -1314,3 +1367,133 @@ pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t // Everyting seems ok, 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; + } +} + diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index bab0610..9990d8f 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -90,6 +90,69 @@ # define DEISERRFRAME 0x0300/* Error frame */ # 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_transceive_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, 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); bool pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits, 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); 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); // 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, nfc_target_info_t * pnti); 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 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 size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData); bool pn53x_InDeselect (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, 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 * pbtNFCID3i, const byte_t * pbtGB, const size_t szGB, diff --git a/libnfc/nfc.c b/libnfc/nfc.c index 15d4064..ea11d44 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -262,7 +262,7 @@ nfc_initiator_init (nfc_device_t * pnd) * @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 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 szInitDataLen Length of initiator data \a pbtInitData. * @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 nfc_initiator_select_passive_target (nfc_device_t * pnd, - const nfc_modulation_t nmInitModulation, - const byte_t * pbtInitData, const size_t szInitDataLen, nfc_target_info_t * pnti) + const nfc_modulation_t nm, + const byte_t * pbtInitData, const size_t szInitData, + nfc_target_info_t * pnti) { byte_t abtInit[MAX_FRAME_LEN]; - size_t szInitLen; - - size_t szTargetsData; - byte_t abtTargetsData[MAX_FRAME_LEN]; + size_t szInit; pnd->iLastError = 0; @@ -290,13 +288,13 @@ nfc_initiator_select_passive_target (nfc_device_t * pnd, if (!pnd->bActive) return false; // TODO Put this in a function: this part is defined by ISO14443-3 (UID and Cascade levels) - switch (nmInitModulation) { - case NM_ISO14443A_106: - switch (szInitDataLen) { + switch (nm.nmt) { + case NMT_ISO14443A: + switch (szInitData) { case 7: abtInit[0] = 0x88; memcpy (abtInit + 1, pbtInitData, 7); - szInitLen = 8; + szInit = 8; break; case 10: @@ -304,78 +302,32 @@ nfc_initiator_select_passive_target (nfc_device_t * pnd, memcpy (abtInit + 1, pbtInitData, 3); abtInit[4] = 0x88; memcpy (abtInit + 5, pbtInitData + 3, 7); - szInitLen = 12; + szInit = 12; break; case 4: default: - memcpy (abtInit, pbtInitData, szInitDataLen); - szInitLen = szInitDataLen; + memcpy (abtInit, pbtInitData, szInitData); + szInit = szInitData; break; } break; default: - memcpy (abtInit, pbtInitData, szInitDataLen); - szInitLen = szInitDataLen; + memcpy (abtInit, pbtInitData, szInitData); + szInit = szInitData; break; } - if (!pn53x_InListPassiveTarget (pnd, nmInitModulation, 1, abtInit, szInitLen, 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 - 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; + return pn53x_initiator_select_passive_target (pnd, nm, abtInit, szInit, pnti); } - /** * @brief List passive or emulated tags * @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 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 szTargets Size of \a anti (will be the max targets listed) * @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. */ 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 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 nfc_configure (pnd, NDO_INFINITE_SELECT, false); - if (nmInitModulation == NM_ISO14443B_106) { - // Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3) - pbtInitData = (byte_t *) "\x00"; - szInitDataLen = 1; - } else if (nmInitModulation == NM_FELICA_212 || nmInitModulation == NM_FELICA_424) { - // polling payload must be present (see ISO/IEC 18092 11.2.2.5) - pbtInitData = (byte_t *) "\x00\xff\xff\x01\x00"; - szInitDataLen = 5; + 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) + pbtInitData = (byte_t *) "\x00"; + szInitDataLen = 1; + } + break; + case NMT_FELICA: { + // polling payload must be present (see ISO/IEC 18092 11.2.2.5) + pbtInitData = (byte_t *) "\x00\xff\xff\x01\x00"; + 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); if (szTargets > szTargetFound) { @@ -417,7 +377,7 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t n } szTargetFound++; // 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; } } @@ -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. * * @param pnd \a nfc_device_t struct pointer that represent currently used device - * @param pnttTargetTypes array of desired target types - * @param szTargetTypes pnttTargetTypes count + * @param ppttTargetTypes array of desired target types + * @param szTargetTypes ppttTargetTypes count * @param btPollNr specifies the number of polling * @note one polling is a polling for each desired target type * @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 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, nfc_target_t * pntTargets, size_t * pszTargetFound) { 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) * @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 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[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. */ 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; - return pn53x_initiator_select_dep_target (pnd, nmInitModulation, pndiInitiator, pnti); + return pn53x_initiator_select_dep_target (pnd, bActiveDep, pndiInitiator, pnti); } /** diff --git a/manual-test-results.txt b/manual-test-results.txt new file mode 100644 index 0000000..0ea0fe7 --- /dev/null +++ b/manual-test-results.txt @@ -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 diff --git a/test/test_access_storm.c b/test/test_access_storm.c index de1e715..b093aa9 100644 --- a/test/test_access_storm.c +++ b/test/test_access_storm.c @@ -56,7 +56,11 @@ test_access_storm (void) res = nfc_configure(device,NDO_ACTIVATE_FIELD,true); 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")); nfc_disconnect (device);