diff --git a/examples/nfc-list.c b/examples/nfc-list.c index 2a367b0..4504d1d 100644 --- a/examples/nfc-list.c +++ b/examples/nfc-list.c @@ -199,6 +199,34 @@ main (int argc, const char *argv[]) } } + nm.nmt = NMT_ISO14443B3SR; + nm.nbr = NBR_106; + // List ISO14443B-3 ST SRx family targets + if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) { + size_t n; + if (verbose || (szTargetFound > 0)) { + printf ("%d ISO14443B-3 ST SRx passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":"); + } + for (n = 0; n < szTargetFound; n++) { + print_nfc_iso14443b3sr_info (ant[n].nti.nsi, verbose); + printf ("\n"); + } + } + + nm.nmt = NMT_ISO14443B3CT; + nm.nbr = NBR_106; + // List ISO14443B-3 ASK CTx family targets + if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) { + size_t n; + if (verbose || (szTargetFound > 0)) { + printf ("%d ISO14443B-3 ASK CTx passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":"); + } + for (n = 0; n < szTargetFound; n++) { + print_nfc_iso14443b3ct_info (ant[n].nti.nci, verbose); + printf ("\n"); + } + } + nm.nmt = NMT_JEWEL; nm.nbr = NBR_106; // List Jewel targets diff --git a/examples/nfc-utils.c b/examples/nfc-utils.c index 5b5a0ad..0eb4611 100644 --- a/examples/nfc-utils.c +++ b/examples/nfc-utils.c @@ -631,6 +631,20 @@ print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose) } } +void +print_nfc_iso14443b3sr_info (const nfc_iso14443b3sr_info_t nsi, bool verbose) +{ + printf (" UID: "); + print_hex (nsi.abtUID, 8); +} + +void +print_nfc_iso14443b3ct_info (const nfc_iso14443b3ct_info_t nci, bool verbose) +{ + printf (" Data: "); + print_hex (nci.abtData, nci.szDataLen); +} + void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose) { @@ -740,6 +754,14 @@ print_nfc_target (const nfc_target_t nt, bool verbose) printf ("ISO/IEC 14443-4B' (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); print_nfc_iso14443bi_info (nt.nti.nii, verbose); break; + case NMT_ISO14443B3SR: + printf ("ISO/IEC 14443-3B ST SRx (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); + print_nfc_iso14443b3sr_info (nt.nti.nsi, verbose); + break; + case NMT_ISO14443B3CT: + printf ("ISO/IEC 14443-3B ASK CTx (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); + print_nfc_iso14443b3ct_info (nt.nti.nci, verbose); + 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, verbose); diff --git a/examples/nfc-utils.h b/examples/nfc-utils.h index 14fbe4c..9768dae 100644 --- a/examples/nfc-utils.h +++ b/examples/nfc-utils.h @@ -89,6 +89,8 @@ void print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t void print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose); void print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose); void print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose); +void print_nfc_iso14443b3sr_info (const nfc_iso14443b3sr_info_t nsi, bool verbose); +void print_nfc_iso14443b3ct_info (const nfc_iso14443b3ct_info_t nci, bool verbose); void print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose); void print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose); void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose); diff --git a/include/nfc/nfc-types.h b/include/nfc/nfc-types.h index a05a433..7bddbd4 100644 --- a/include/nfc/nfc-types.h +++ b/include/nfc/nfc-types.h @@ -243,6 +243,23 @@ typedef struct { byte_t abtAtr[33]; } nfc_iso14443bi_info_t; +/** + * @struct nfc_iso14443b3sr_info_t + * @brief NFC ISO14443-3B ST SRx tag information + */ +typedef struct { + byte_t abtUID[8]; +} nfc_iso14443b3sr_info_t; + +/** + * @struct nfc_iso14443b3ct_info_t + * @brief NFC ISO14443-3B ASK CTx tag information + */ +typedef struct { + byte_t abtData[256]; // No idea what data to expect... + size_t szDataLen; +} nfc_iso14443b3ct_info_t; + /** * @struct nfc_jewel_info_t * @brief NFC Jewel tag information @@ -261,6 +278,8 @@ typedef union { nfc_felica_info_t nfi; nfc_iso14443b_info_t nbi; nfc_iso14443bi_info_t nii; + nfc_iso14443b3sr_info_t nsi; + nfc_iso14443b3ct_info_t nci; nfc_jewel_info_t nji; nfc_dep_info_t ndi; } nfc_target_info_t; @@ -283,10 +302,12 @@ typedef enum { */ typedef enum { NMT_ISO14443A, + NMT_JEWEL, NMT_ISO14443B, NMT_ISO14443BI, // pre-ISO14443B aka ISO/IEC 14443 B' or Type B' + NMT_ISO14443B3SR, // ISO14443-3B ST SRx + NMT_ISO14443B3CT, // ISO14443-3B ASK CTx NMT_FELICA, - NMT_JEWEL, NMT_DEP, } nfc_modulation_type_t; diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 59439ae..9c3b232 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -383,12 +383,25 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData, pn53x_typ pnti->nii.btConfig = *(pbtRawData++); if (pnti->nii.btConfig & 0x40) { memcpy (pnti->nii.abtAtr, pbtRawData, szRawData - 8); - pbtRawData += szRawData - 6; + pbtRawData += szRawData - 8; pnti->nii.szAtrLen = szRawData - 8; } } break; + case NMT_ISO14443B3SR: + // Store the UID + memcpy (pnti->nsi.abtUID, pbtRawData, 8); + pbtRawData += 8; + break; + + case NMT_ISO14443B3CT: + // Store the unknown data as one blob for now + memcpy (pnti->nci.abtData, pbtRawData, szRawData); + pbtRawData += szRawData; + pnti->nci.szDataLen = szRawData; + break; + case NMT_FELICA: // We skip the first byte: its the target number (Tg) pbtRawData++; @@ -639,8 +652,6 @@ pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool b return false; } - // TODO not yet sufficient to setup TypeB, some settings are missing here... - return true; break; } @@ -683,10 +694,8 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, byte_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szTargetsData = sizeof(abtTargetsData); - if (nm.nmt == NMT_ISO14443BI) { + if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B3SR || nm.nmt == NMT_ISO14443B3CT) { // No native support in InListPassiveTarget so we do discovery by hand - byte_t abtAttrib[6]; - size_t szAttrib = sizeof(abtAttrib); if (!nfc_configure (pnd, NDO_FORCE_ISO14443_B, true)) { return false; } @@ -697,6 +706,23 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, return false; } pnd->bEasyFraming = false; + if (nm.nmt == NMT_ISO14443B3SR) { + // Some work to do before getting the UID... + byte_t abtInitiate[]="\x06\x00"; + size_t szInitiateLen = 2; + byte_t abtSelect[]="\x0e\x00"; + size_t szSelectLen = 2; + byte_t abtRx[1]; + size_t szRxLen = 1; + // Getting random Chip_ID + if (!pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen)) { + return false; + } + abtSelect[1] = abtRx[0]; + if (!pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen)) { + return false; + } + } if (!pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData)) { return false; } @@ -707,10 +733,15 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, return false; } } - memcpy(abtAttrib, abtTargetsData, szAttrib); - abtAttrib[1] = 0x0f; // ATTRIB - if (!pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttrib, NULL, NULL)) { - return false; + if (nm.nmt == NMT_ISO14443BI) { + // Select tag + byte_t abtAttrib[6]; + size_t szAttribLen = sizeof(abtAttrib); + memcpy(abtAttrib, abtTargetsData, szAttribLen); + abtAttrib[1] = 0x0f; // ATTRIB + if (!pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL)) { + return false; + } } return true; } // else: @@ -1137,6 +1168,8 @@ pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_ break; case NMT_ISO14443B: case NMT_ISO14443BI: + case NMT_ISO14443B3SR: + case NMT_ISO14443B3CT: case NMT_JEWEL: pnd->iLastError = DENOTSUP; return false; @@ -1237,6 +1270,8 @@ pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_ break; case NMT_ISO14443B: case NMT_ISO14443BI: + case NMT_ISO14443B3SR: + case NMT_ISO14443B3CT: case NMT_JEWEL: pnd->iLastError = DENOTSUP; return false; @@ -2017,6 +2052,8 @@ pn53x_nm_to_pm(const nfc_modulation_t nm) break; case NMT_ISO14443BI: + case NMT_ISO14443B3SR: + case NMT_ISO14443B3CT: case NMT_DEP: // Nothing to do... break; @@ -2117,6 +2154,8 @@ pn53x_nm_to_ptt(const nfc_modulation_t nm) break; case NMT_ISO14443BI: + case NMT_ISO14443B3SR: + case NMT_ISO14443B3CT: case NMT_DEP: // Nothing to do... break; diff --git a/libnfc/nfc.c b/libnfc/nfc.c index e78d26c..0ddcb4c 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -164,7 +164,7 @@ nfc_pick_device (void) if (!ndr->probe (pndd, 1, &szN)) { ERR ("%s probe failed", ndr->name); - szN = 0; + szN = 0; } if (szN == 0) { @@ -386,6 +386,18 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, szInitDataLen = 4; } break; + case NMT_ISO14443B3SR: { + // Get_UID + pbtInitData = (byte_t *) "\x0b"; + szInitDataLen = 1; + } + break; + case NMT_ISO14443B3CT: { + // REQT + pbtInitData = (byte_t *) "\x10"; + 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"; @@ -407,7 +419,7 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, szTargetFound++; // deselect has no effect on FeliCa and Jewel cards so we'll stop after one... // ISO/IEC 14443 B' cards are polled at 100% probability so it's not possible to detect correctly two cards at the same time - if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL) || (nm.nmt == NMT_ISO14443BI)) { + if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL) || (nm.nmt == NMT_ISO14443BI) || (nm.nmt == NMT_ISO14443B3SR) || (nm.nmt == NMT_ISO14443B3CT)) { break; } }