diff --git a/examples/nfc-poll.c b/examples/nfc-poll.c index f8f30ba..4cea5d6 100644 --- a/examples/nfc-poll.c +++ b/examples/nfc-poll.c @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -101,14 +102,15 @@ main(int argc, const char *argv[]) const uint8_t uiPollNr = 20; const uint8_t uiPeriod = 2; - const nfc_modulation nmModulations[5] = { + const nfc_modulation nmModulations[6] = { { .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 }, + { .nmt = NMT_ISO14443BICLASS, .nbr = NBR_106 }, }; - const size_t szModulations = 5; + const size_t szModulations = 6; nfc_target nt; int res = 0; diff --git a/include/nfc/nfc-types.h b/include/nfc/nfc-types.h index 89ad397..6ca57a4 100644 --- a/include/nfc/nfc-types.h +++ b/include/nfc/nfc-types.h @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -234,6 +235,14 @@ typedef struct { uint8_t abtAtr[33]; } nfc_iso14443bi_info; +/** + * @struct nfc_iso14443biclass_info + * @brief NFC ISO14443BiClass tag information + */ +typedef struct { + uint8_t abtUID[8]; +} nfc_iso14443biclass_info; + /** * @struct nfc_iso14443b2sr_info * @brief NFC ISO14443-2B ST SRx tag information @@ -284,6 +293,7 @@ typedef union { nfc_jewel_info nji; nfc_barcode_info nti; // "t" for Thinfilm, "b" already used nfc_dep_info ndi; + nfc_iso14443biclass_info nic; // iclass - nbi already used } nfc_target_info; /** @@ -311,7 +321,9 @@ typedef enum { NMT_ISO14443B2SR, // ISO14443-2B ST SRx NMT_ISO14443B2CT, // ISO14443-2B ASK CTx NMT_FELICA, - NMT_DEP, // DEP should be kept last one as it's used as end-of-enum + NMT_DEP, + NMT_ISO14443BICLASS, // HID iClass 14443B mode + NMT_END_ENUM, // dummy for sizing - always should be last } nfc_modulation_type; /** diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 89af830..44b862c 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -85,7 +86,7 @@ pn53x_init(struct nfc_device *pnd) } if (!CHIP_DATA(pnd)->supported_modulation_as_initiator) { - CHIP_DATA(pnd)->supported_modulation_as_initiator = malloc(sizeof(nfc_modulation_type) * (NMT_DEP + 1)); + CHIP_DATA(pnd)->supported_modulation_as_initiator = malloc(sizeof(nfc_modulation_type) * (NMT_END_ENUM)); if (! CHIP_DATA(pnd)->supported_modulation_as_initiator) return NFC_ESOFT; int nbSupportedModulation = 0; @@ -104,6 +105,8 @@ pn53x_init(struct nfc_device *pnd) nbSupportedModulation++; CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_ISO14443B2CT; nbSupportedModulation++; + CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_ISO14443BICLASS; + nbSupportedModulation++; } if (CHIP_DATA(pnd)->type != PN531) { CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_JEWEL; @@ -575,6 +578,12 @@ pn53x_decode_target_data(const uint8_t *pbtRawData, size_t szRawData, pn53x_type memcpy(pnti->nsi.abtUID, pbtRawData, 8); break; + case NMT_ISO14443BICLASS: + // Store the UID + for(uint8_t i= 0 ; i < 8 ; ++i) + pnti->nic.abtUID[7 - i]= pbtRawData[i]; + break; + case NMT_ISO14443B2CT: // Store UID LSB memcpy(pnti->nci.abtUID, pbtRawData, 2); @@ -620,6 +629,8 @@ pn53x_decode_target_data(const uint8_t *pbtRawData, size_t szRawData, pn53x_type // Should not happend... case NMT_DEP: return NFC_ECHIP; + case NMT_END_ENUM: + break; } return NFC_SUCCESS; } @@ -1048,6 +1059,56 @@ pn53x_initiator_init(struct nfc_device *pnd) return NFC_SUCCESS; } +// iclass requires special modulation settings +void pn53x_initiator_init_iclass_modulation(struct nfc_device *pnd) +{ + // send a bunch of low level commands I reverse engineered from a working iClass reader + // original device was using a PN512 + // + // // TxModeReg - Defines the data rate and framing during transmission. + //// set bit 4 for target mode? - RxWaitRF Set to logic 1, the counter for RxWait starts only if an external RF field is detected in Target mode for NFCIP-1 or in Card Communication mode + //pn512_write_register(0x12, "\x03", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_TxMode, 0x03); + // + // // RxModeReg - Defines the data rate and framing during reception. + //pn512_write_register(0x13, "\x03", 1, false); + // addy changed to set bit 3 - RxNoErr (put data in fifo before flagging read end) + //pn512_write_register(0x13, "\x0B", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_RxMode, 0x0B); + + // ManualRCVReg - Allows manual fine tuning of the internal receiver. + //pn512_write_register(0x1d, "\x10", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_ManualRCV, 0x10); + + // RFCfgReg - Configures the receiver gain and RF level detector sensitivity. + //pn512_write_register(0x26, "\x70", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_RFCfg, 0x70); + + // GsNOffReg - Selects the conductance for the N-driver of the antenna driver pins TX1 and TX2 when the driver is switched off. + //pn512_write_register(0x23, "\x88", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_GsNOFF, 0x88); + + // GsNOnReg - Selects the conductance for the N-driver of the antenna driver pins TX1 and TX2 when the driver is switched on. + //pn512_write_register(0x27, "\xf8", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_GsNOn, 0xf8); + + // CWGsPReg - Defines the conductance of the P-driver during times of no modulation. + //pn512_write_register(0x28, "\x3f", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_CWGsP, 0x3f); + + // ModGsPReg - Defines the driver P-output conductance during modulation. + //pn512_write_register(0x29, "\x10", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_ModGsP, 0x10); + + // TReloadReg (MSB) - Describes the MSB of the 16-bit long timer reload value. + //pn512_write_register(0x2c, "\x69", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_TReloadVal_hi, 0x69); + + // TReloadReg (LSB) - Describes the LSB of the 16-bit long timer reload value. + //pn512_write_register(0x2d, "\xf0", 1, false); + pn53x_WriteRegister(pnd, PN53X_REG_CIU_TReloadVal_lo, 0xf0); +} + int pn532_initiator_init_secure_element(struct nfc_device *pnd) { @@ -1067,7 +1128,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd, nfc_target nttmp; memset(&nttmp, 0x00, sizeof(nfc_target)); - if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) { + if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT || nm.nmt == NMT_ISO14443BICLASS) { if (CHIP_DATA(pnd)->type == RCS360) { // TODO add support for RC-S360, at the moment it refuses to send raw frames without a first select pnd->last_error = NFC_ENOTIMPL; @@ -1117,15 +1178,40 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd, return res; } szTargetsData = (size_t)res; - } - - if ((res = pn53x_initiator_transceive_bytes(pnd, pbtInitData, szInitData, abtTargetsData, sizeof(abtTargetsData), timeout)) < 0) { - if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout - continue; - } else + } else if (nm.nmt == NMT_ISO14443BICLASS) { + pn53x_initiator_init_iclass_modulation(pnd); + // + // Some work to do before getting the UID... + // send ICLASS_ACTIVATE_ALL command - will get timeout as we don't expect response + uint8_t abtReqt[] = { 0x0a }; // iClass ACTIVATE_ALL + uint8_t abtAnticol[11]; + if ((res = pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout)) < 0) { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "got expected timeout on iClass activate all"); + //if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout + // continue; + //} else + // return res; + } + // do select - returned anticol contains 'handle' for tag if present + abtReqt[0]= 0x0c; // iClass SELECT + abtAnticol[0]= 0x81; // iClass ANTICOL + if ((res = pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), &abtAnticol[1], sizeof(abtAnticol) - 1, timeout)) < 0) { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "timeout on iClass anticol"); return res; + } + // write back anticol handle to get UID + if ((res = pn53x_initiator_transceive_bytes(pnd, abtAnticol, 9, abtTargetsData, 10, timeout)) < 0) { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "timeout on iClass get UID"); + return res; + } + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "iClass raw UID: %02x %02x %02x %02x %02x %02x %02x %02x", abtTargetsData[0], abtTargetsData[1], abtTargetsData[2], abtTargetsData[3], abtTargetsData[4], abtTargetsData[5], abtTargetsData[6], abtTargetsData[7]); + szTargetsData = 8; + nttmp.nm = nm; + if ((res = pn53x_decode_target_data(abtTargetsData, szTargetsData, CHIP_DATA(pnd)->type, nm.nmt, &(nttmp.nti))) < 0) { + return res; } - szTargetsData = (size_t)res; + } + if (nm.nmt == NMT_ISO14443B2CT) { if (szTargetsData != 2) return 0; // Target is not ISO14443B2CT @@ -2138,6 +2224,29 @@ static int pn53x_ISO14443B_SR_is_present(struct nfc_device *pnd) return ret; } +static int pn53x_ISO14443B_ICLASS_is_present(struct nfc_device *pnd) +{ + int timeout= 300; + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): Ping B iClass"); + pn53x_initiator_init_iclass_modulation(pnd); + // + // Some work to do before getting the UID... + // send ICLASS_ACTIVATE_ALL command - will get timeout as we don't expect response + uint8_t abtReqt[] = { 0x0a }; // iClass ACTIVATE_ALL + uint8_t abtAnticol[11]; + if (pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout) < 0) { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "got expected timeout on iClass activate all"); + } + // do select - returned anticol contains 'handle' for tag if present + abtReqt[0]= 0x0c; // iClass SELECT + abtAnticol[0]= 0x81; // iClass ANTICOL + if (pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), &abtAnticol[1], sizeof(abtAnticol) - 1, timeout) < 0) { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "timeout on iClass anticol"); + return NFC_ETGRELEASED;; + } + return NFC_SUCCESS; +} + static int pn53x_ISO14443B_CT_is_present(struct nfc_device *pnd) { int ret; @@ -2218,6 +2327,11 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt) case NMT_ISO14443B2CT: ret = pn53x_ISO14443B_CT_is_present(pnd); break; + case NMT_ISO14443BICLASS: + ret = pn53x_ISO14443B_ICLASS_is_present(pnd); + break; + case NMT_END_ENUM: + break; } if (ret == NFC_ETGRELEASED) pn53x_current_target_free(pnd); @@ -2268,8 +2382,10 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const case NMT_ISO14443BI: case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: + case NMT_ISO14443BICLASS: case NMT_JEWEL: case NMT_BARCODE: + case NMT_END_ENUM: pnd->last_error = NFC_EDEVNOTSUPP; return pnd->last_error; } @@ -2370,8 +2486,10 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const case NMT_ISO14443BI: case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: + case NMT_ISO14443BICLASS: case NMT_JEWEL: case NMT_BARCODE: + case NMT_END_ENUM: pnd->last_error = NFC_EDEVNOTSUPP; return pnd->last_error; } @@ -2525,9 +2643,12 @@ pn53x_target_receive_bytes(struct nfc_device *pnd, uint8_t *pbtRx, const size_t case NMT_ISO14443BI: case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: + case NMT_ISO14443BICLASS: case NMT_FELICA: abtCmd[0] = TgGetInitiatorCommand; break; + case NMT_END_ENUM: + break; } } else { abtCmd[0] = TgGetInitiatorCommand; @@ -2631,9 +2752,12 @@ pn53x_target_send_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, const size case NMT_ISO14443BI: case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: + case NMT_ISO14443BICLASS: case NMT_FELICA: abtCmd[0] = TgResponseToInitiator; break; + case NMT_END_ENUM: + break; } } else { abtCmd[0] = TgResponseToInitiator; @@ -3253,6 +3377,7 @@ pn53x_nm_to_pm(const nfc_modulation nm) return PM_ISO14443A_106; case NMT_ISO14443B: + case NMT_ISO14443BICLASS: switch (nm.nbr) { case NBR_106: return PM_ISO14443B_106; @@ -3292,6 +3417,7 @@ pn53x_nm_to_pm(const nfc_modulation nm) case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: case NMT_DEP: + case NMT_END_ENUM: // Nothing to do... break; } @@ -3351,6 +3477,7 @@ pn53x_nm_to_ptt(const nfc_modulation nm) // return PTT_ISO14443_4A_106; case NMT_ISO14443B: + case NMT_ISO14443BICLASS: switch (nm.nbr) { case NBR_106: return PTT_ISO14443_4B_106; @@ -3388,6 +3515,7 @@ pn53x_nm_to_ptt(const nfc_modulation nm) case NMT_ISO14443B2CT: case NMT_BARCODE: case NMT_DEP: + case NMT_END_ENUM: // Nothing to do... break; } @@ -3436,6 +3564,7 @@ pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_mode mode, const nfc_mo case NMT_ISO14443BI: case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: + case NMT_ISO14443BICLASS: *supported_br = (nfc_baud_rate *)pn532_iso14443b_supported_baud_rates; break; case NMT_JEWEL: @@ -3447,6 +3576,7 @@ pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_mode mode, const nfc_mo case NMT_DEP: *supported_br = (nfc_baud_rate *)pn53x_dep_supported_baud_rates; break; + case NMT_END_ENUM: default: return NFC_EINVARG; } diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index f236930..4d769f8 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -322,6 +323,7 @@ int pn53x_idle(struct nfc_device *pnd); // NFC device as Initiator functions int pn53x_initiator_init(struct nfc_device *pnd); +void pn53x_initiator_init_iclass_modulation(struct nfc_device *pnd); int pn532_initiator_init_secure_element(struct nfc_device *pnd); int pn53x_initiator_select_passive_target(struct nfc_device *pnd, const nfc_modulation nm, diff --git a/libnfc/nfc-internal.c b/libnfc/nfc-internal.c index d90bb87..0200aa4 100644 --- a/libnfc/nfc-internal.c +++ b/libnfc/nfc-internal.c @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -206,6 +207,8 @@ prepare_initiator_data(const nfc_modulation nm, uint8_t **ppbtInitiatorData, siz *ppbtInitiatorData = NULL; *pszInitiatorData = 0; break; + case NMT_END_ENUM: + break; } } diff --git a/libnfc/nfc.c b/libnfc/nfc.c index c06da0e..55e8926 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -206,7 +207,10 @@ int nfc_register_driver(const struct nfc_driver *ndr) { if (!ndr) + { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "nfc_register_driver returning NFC_EINVARG"); return NFC_EINVARG; + } struct nfc_driver_list *pndl = (struct nfc_driver_list *)malloc(sizeof(struct nfc_driver_list)); if (!pndl) @@ -1296,9 +1300,11 @@ nfc_device_validate_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_m if (nbr[j] == nm->nbr) return NFC_SUCCESS; } + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "nfc_device_validate_modulation returning NFC_EINVARG"); return NFC_EINVARG; } } + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "nfc_device_validate_modulation returning NFC_EINVARG"); return NFC_EINVARG; } @@ -1396,6 +1402,8 @@ str_nfc_modulation_type(const nfc_modulation_type nmt) return "Thinfilm NFC Barcode"; case NMT_DEP: return "D.E.P."; + case NMT_END_ENUM: + break; } return "???"; diff --git a/libnfc/target-subr.c b/libnfc/target-subr.c index 61cedfd..e6b143c 100644 --- a/libnfc/target-subr.c +++ b/libnfc/target-subr.c @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -609,6 +610,15 @@ snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_inf snprint_hex(dst + off, size - off, pnsi->abtUID, 8); } +void +snprint_nfc_iso14443biclass_info(char *dst, size_t size, const nfc_iso14443biclass_info *pnic, bool verbose) +{ + (void) verbose; + int off = 0; + off += snprintf(dst + off, size - off, " UID: "); + snprint_hex(dst + off, size - off, pnic->abtUID, 8); +} + void snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose) { @@ -668,12 +678,17 @@ snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose) case NMT_ISO14443B2SR: snprint_nfc_iso14443b2sr_info(dst + off, size - off, &pnt->nti.nsi, verbose); break; + case NMT_ISO14443BICLASS: + snprint_nfc_iso14443biclass_info(dst + off, size - off, &pnt->nti.nic, verbose); + break; case NMT_ISO14443B2CT: snprint_nfc_iso14443b2ct_info(dst + off, size - off, &pnt->nti.nci, verbose); break; case NMT_DEP: snprint_nfc_dep_info(dst + off, size - off, &pnt->nti.ndi, verbose); break; + case NMT_END_ENUM: + break; } } } diff --git a/libnfc/target-subr.h b/libnfc/target-subr.h index 9205d6f..633d20d 100644 --- a/libnfc/target-subr.h +++ b/libnfc/target-subr.h @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the @@ -37,6 +38,7 @@ void snprint_nfc_iso14443a_info(char *dst, size_t size, const nfc_iso14443a_i void snprint_nfc_iso14443b_info(char *dst, size_t size, const nfc_iso14443b_info *pnbi, bool verbose); void snprint_nfc_iso14443bi_info(char *dst, size_t size, const nfc_iso14443bi_info *pnii, bool verbose); void snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_info *pnsi, bool verbose); +void snprint_nfc_iso14443biclass_info(char *dst, size_t size, const nfc_iso14443biclass_info *pnic, bool verbose); void snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose); void snprint_nfc_felica_info(char *dst, size_t size, const nfc_felica_info *pnfi, bool verbose); void snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool verbose); diff --git a/utils/nfc-list.c b/utils/nfc-list.c index 55e4224..db8b395 100644 --- a/utils/nfc-list.c +++ b/utils/nfc-list.c @@ -9,6 +9,7 @@ * Copyright (C) 2012-2013 Ludovic Rousseau * See AUTHORS file for a more comprehensive list of contributors. * Additional contributors of this file: + * Copyright (C) 2020 Adam Laurie * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -71,6 +72,7 @@ print_usage(const char *progname) printf("\t 16: ISO14443B'\n"); printf("\t 32: ISO14443B-2 ST SRx\n"); printf("\t 64: ISO14443B-2 ASK CTx\n"); + printf("\t 96: ISO14443B iClass\n"); printf("\t 128: ISO14443A-3 Jewel\n"); printf("\t 256: ISO14443A-2 NFC Barcode\n"); printf("\tSo 511 (default) polls for all types.\n"); @@ -271,6 +273,22 @@ main(int argc, const char *argv[]) } } + if (mask & 0x60) { + nm.nmt = NMT_ISO14443BICLASS; + nm.nbr = NBR_106; + // List ISO14443B iClass targets + if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) { + int n; + if (verbose || (res > 0)) { + printf("%d ISO14443B iClass passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); + } + for (n = 0; n < res; n++) { + print_nfc_target(&ant[n], verbose); + printf("\n"); + } + } + } + if (mask & 0x80) { nm.nmt = NMT_JEWEL; nm.nbr = NBR_106;