diff --git a/ChangeLog b/ChangeLog index c393e19..2880dc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,20 +16,19 @@ Improvements: - libnfc: add ISO/IEC 14443 B' aka Type B' modulation partial support - libnfc: add partial support (list) for ISO14443B-3 ST SRx & ASK CTx cards - libnfc: compile unit tests only on demand unless using --enable-debug. - - libnfc: enhance logging system, libnfc now uses the flexible log4c library to log all messages - libnfc: error handling improvements - libnfc: new function nfc_idle() to set the NFC device in idle mode - libnfc: add partial support for Sony S360 reader - libnfc: some manual test reports have been added - libnfc: list_targets support for ASK CTS512B (no anticol support yet) - libnfc: nfc_disconnect() now switches NFC device into idle before disconnecting + - libnfc: nfc_initiator_poll_target() is now available for all devices - chips/pn53x: add pn53x_data_new() function to alloc and init pn53x_data structure - chips/pn53x: add some SFR registers description - chips/pn53x: implement WriteBack cache - chips/pn53x: new pn53x_PowerDown wrapper for PowerDown (PN532) command - chips/pn53x: prints a debug trace when reading PN53x registers - chips/pn53x: set some parameters in ISO/IEC 14443A when using DEP mode (ie. SAK says ISO/IEC 18092 compliant) (Android NFC stack now detects the target as DEP) - - chips/pn53x: set ui8LastCommand in chip layer instead of driver layer - chips/pn53x: some optimisations in registers initialisation - chips/pn53x: list_passive_targets() fixed for TypeB on LoGO - chips/pn53x: pn53x_data now have a operating_mode enum to know the current running mode (initiator, target or idle) diff --git a/NEWS b/NEWS index a93bb9b..8219db3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,25 @@ +New in 1.5.1: + +API Changes + + * Types + - Communication-level errors DEIO and DETIMEOUT are now know as ECOMIO, + ECOMTIMEOUT respectively + - Common device-level errors DEINVAL and DEABORT are now know as EINVALARG, + EOPABORT respectively + - New errors: EFRAACKMISMATCH, EFRAISERRFRAME, EDEVNOTSUP and ENOTIMPL + + * Functions + - nfc_abort_command() returns a boolean + - timeout (struct timeval) pointer added to + nfc_initiator_transceive_bytes(), nfc_target_send_bytes() and + nfc_target_receive_bytes() + - timed functions nfc_initiator_transceive_bytes_timed() and + nfc_initiator_transceive_bits_timed() now takes uint32_t as cycles + pointer + - nfc_initiator_poll_targets() renamed to nfc_initiator_poll_target() and + only return one target + New in 1.5.0: Installed files diff --git a/examples/nfc-poll.c b/examples/nfc-poll.c index 2e3f268..2843654 100644 --- a/examples/nfc-poll.c +++ b/examples/nfc-poll.c @@ -97,9 +97,8 @@ main (int argc, const char *argv[]) } for (i = 0; i < szFound; i++) { - - const byte_t btPollNr = 20; - const byte_t btPeriod = 2; + const uint8_t uiPollNr = 20; + const uint8_t uiPeriod = 2; const nfc_modulation_t nmModulations[5] = { { .nmt = NMT_ISO14443A, .nbr = NBR_106 }, { .nmt = NMT_ISO14443B, .nbr = NBR_106 }, @@ -109,8 +108,7 @@ main (int argc, const char *argv[]) }; const size_t szModulations = 5; - nfc_target_t antTargets[2]; - size_t szTargetFound; + nfc_target_t nt; bool res; pnd = nfc_connect (&(pnddDevices[i])); @@ -121,28 +119,19 @@ main (int argc, const char *argv[]) } nfc_initiator_init (pnd); - // Let the reader only try once to find a tag - if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) { - nfc_perror (pnd, "nfc_configure"); - exit (EXIT_FAILURE); - } - printf ("Connected to NFC reader: %s\n", pnd->acName); - - 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); + printf ("NFC device will poll during %ld ms (%u pollings of %lu ms for %zd modulations)\n", (unsigned long) uiPollNr * szModulations * uiPeriod * 150, uiPollNr, (unsigned long) uiPeriod * 150, szModulations); + res = nfc_initiator_poll_target (pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt); 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: ", n + 1); - print_nfc_target ( antTargets[n], verbose ); - - } + print_nfc_target ( nt, verbose ); } else { - nfc_perror (pnd, "nfc_initiator_poll_targets"); - nfc_disconnect (pnd); - exit (EXIT_FAILURE); + if (pnd->iLastError) { + nfc_perror (pnd, "nfc_initiator_poll_targets"); + nfc_disconnect (pnd); + exit (EXIT_FAILURE); + } else { + printf ("No target found.\n"); + } } nfc_disconnect (pnd); } diff --git a/include/nfc/nfc.h b/include/nfc/nfc.h index 6cde485..051f691 100644 --- a/include/nfc/nfc.h +++ b/include/nfc/nfc.h @@ -74,7 +74,7 @@ extern "C" { 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 nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt); NFC_EXPORT bool nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nm, nfc_target_t ant[], const size_t szTargets, size_t * pszTargetFound); - 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_poll_target (nfc_device_t * pnd, const nfc_modulation_t * pnmTargetTypes, const size_t szTargetTypes, const uint8_t uiPollNr, const uint8_t uiPeriod, nfc_target_t * pnt); NFC_EXPORT bool nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt); NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd); NFC_EXPORT bool nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout); diff --git a/libnfc/Makefile.am b/libnfc/Makefile.am index e58779a..f596549 100644 --- a/libnfc/Makefile.am +++ b/libnfc/Makefile.am @@ -15,7 +15,9 @@ libnfc_la_SOURCES = \ mirror-subr.c \ nfc.c \ nfc-device.c \ - nfc-emulation.c + nfc-emulation.c \ + nfc-internal.c + libnfc_la_LDFLAGS = -no-undefined -version-info 2:0:0 libnfc_la_CFLAGS = @DRIVERS_CFLAGS@ libnfc_la_LIBADD = \ diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 831a01c..5d03627 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -61,8 +61,6 @@ pn53x_target_type_t pn53x_nm_to_ptt (const nfc_modulation_t nm); bool pn53x_init(nfc_device_t * pnd) { - log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "pn53x_init"); - // GetFirmwareVersion command is used to set PN53x chips type (PN531, PN532 or PN533) char abtFirmwareText[22]; if (!pn53x_get_firmware_version (pnd, abtFirmwareText)) { @@ -111,6 +109,9 @@ pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, b } PNCMD_TRACE (pbtTx[0]); + if (timeout) + log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Timeout values: %li s, %li us", timeout->tv_sec, timeout->tv_usec); + byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof(abtRx); @@ -855,10 +856,11 @@ pn53x_initiator_init (nfc_device_t * pnd) } bool -pn53x_initiator_select_passive_target (nfc_device_t * pnd, +pn53x_initiator_select_passive_target_ext (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, - nfc_target_t * pnt) + nfc_target_t * pnt, + struct timeval* timeout) { byte_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szTargetsData = sizeof(abtTargetsData); @@ -889,11 +891,11 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, byte_t abtRx[1]; size_t szRxLen = 1; // Getting random Chip_ID - if (!pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen, NULL)) { + if (!pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen, timeout)) { return false; } abtSelect[1] = abtRx[0]; - if (!pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen, NULL)) { + if (!pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen, timeout)) { return false; } } @@ -902,11 +904,11 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, byte_t abtReqt[]="\x10"; size_t szReqtLen = 1; // Getting product code / fab code & store it in output buffer after the serial nr we'll obtain later - if (!pn53x_initiator_transceive_bytes (pnd, abtReqt, szReqtLen, abtTargetsData+2, &szTargetsData, NULL) || szTargetsData != 2) { + if (!pn53x_initiator_transceive_bytes (pnd, abtReqt, szReqtLen, abtTargetsData+2, &szTargetsData, timeout) || szTargetsData != 2) { return false; } } - if (!pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData, NULL)) { + if (!pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) { return false; } if (nm.nmt == NMT_ISO14443B2CT) { @@ -914,7 +916,7 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, return false; byte_t abtRead[]="\xC4"; // Reading UID_MSB (Read address 4) size_t szReadLen = 1; - if (!pn53x_initiator_transceive_bytes (pnd, abtRead, szReadLen, abtTargetsData+4, &szTargetsData, NULL) || szTargetsData != 2) { + if (!pn53x_initiator_transceive_bytes (pnd, abtRead, szReadLen, abtTargetsData+4, &szTargetsData, timeout) || szTargetsData != 2) { return false; } szTargetsData = 6; // u16 UID_LSB, u8 prod code, u8 fab code, u16 UID_MSB @@ -932,7 +934,7 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, size_t szAttribLen = sizeof(abtAttrib); memcpy(abtAttrib, abtTargetsData, szAttribLen); abtAttrib[1] = 0x0f; // ATTRIB - if (!pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL, NULL)) { + if (!pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL, timeout)) { return false; } } @@ -945,7 +947,7 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, return false; } - if (!pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData)) + if (!pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) return false; // Make sure one tag has been found, the PN53X returns 0x00 if none was available @@ -964,29 +966,76 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, } 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) +pn53x_initiator_select_passive_target (nfc_device_t * pnd, + const nfc_modulation_t nm, + const byte_t * pbtInitData, const size_t szInitData, + nfc_target_t * pnt) { - size_t szTargetTypes = 0; - pn53x_target_type_t apttTargetTypes[32]; - for (size_t n=0; niLastError = EINVALARG; - return false; - } - apttTargetTypes[szTargetTypes] = ptt; - if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS - apttTargetTypes[szTargetTypes] = PTT_ISO14443_4A_106; - szTargetTypes++; - apttTargetTypes[szTargetTypes] = PTT_MIFARE; - } - szTargetTypes++; - } + return pn53x_initiator_select_passive_target_ext (pnd, nm, pbtInitData, szInitData, pnt, NULL); +} - return pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound); +bool +pn53x_initiator_poll_target (nfc_device_t * pnd, + const nfc_modulation_t * pnmModulations, const size_t szModulations, + const uint8_t uiPollNr, const uint8_t uiPeriod, + nfc_target_t * pnt) +{ + if (CHIP_DATA(pnd)->type == PN532) { + size_t szTargetTypes = 0; + pn53x_target_type_t apttTargetTypes[32]; + for (size_t n=0; niLastError = EINVALARG; + return false; + } + apttTargetTypes[szTargetTypes] = ptt; + if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS + apttTargetTypes[szTargetTypes] = PTT_ISO14443_4A_106; + szTargetTypes++; + apttTargetTypes[szTargetTypes] = PTT_MIFARE; + } + szTargetTypes++; + } + size_t szTargetFound = 0; + nfc_target_t ntTargets[2]; + if (!pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, uiPollNr, uiPeriod, ntTargets, &szTargetFound)) + return false; + switch (szTargetFound) { + case 1: + *pnt = ntTargets[0]; + return true; + break; + case 2: + *pnt = ntTargets[1]; // We keep the selected one + return true; + break; + default: + return false; + break; + } + } else { + pn53x_configure (pnd, NDO_INFINITE_SELECT, true); + for (size_t p=0; piLastError != ECOMTIMEOUT) + return false; + } else { + return true; + } + } + } + } + return false; } bool @@ -1992,7 +2041,8 @@ bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const pn53x_modulation_t pmInitModulation, const byte_t szMaxTargets, const byte_t * pbtInitiatorData, const size_t szInitiatorData, - byte_t * pbtTargetsData, size_t * pszTargetsData) + byte_t * pbtTargetsData, size_t * pszTargetsData, + struct timeval* timeout) { byte_t abtCmd[15] = { InListPassiveTarget }; @@ -2037,7 +2087,7 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd, if (pbtInitiatorData) memcpy (abtCmd + 3, pbtInitiatorData, szInitiatorData); - return pn53x_transceive (pnd, abtCmd, 3 + szInitiatorData, pbtTargetsData, pszTargetsData, NULL); + return pn53x_transceive (pnd, abtCmd, 3 + szInitiatorData, pbtTargetsData, pszTargetsData, timeout); } bool diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index f7323af..9f32b6f 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -280,10 +280,10 @@ 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_t * pnt); -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_poll_target (nfc_device_t * pnd, + const nfc_modulation_t * pnmModulations, const size_t szModulations, + const uint8_t uiPollNr, const uint8_t uiPeriod, + nfc_target_t * pnt); bool pn53x_initiator_select_dep_target (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, @@ -304,8 +304,7 @@ bool pn53x_initiator_deselect_target (nfc_device_t * pnd); bool pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx); bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar); bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout); -bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, - const byte_t * pbtTxPar); +bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar); bool pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout); // Error handling functions @@ -317,7 +316,8 @@ bool pn53x_SAMConfiguration (nfc_device_t * pnd, const pn532_sam_mode mode, s bool pn53x_PowerDown (nfc_device_t * pnd); 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); + const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData, + struct timeval *timeout); 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 pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes, diff --git a/libnfc/drivers/acr122.c b/libnfc/drivers/acr122.c index 68600d7..0732275 100644 --- a/libnfc/drivers/acr122.c +++ b/libnfc/drivers/acr122.c @@ -415,7 +415,7 @@ const struct nfc_driver_t acr122_driver = { .initiator_init = pn53x_initiator_init, .initiator_select_passive_target = pn53x_initiator_select_passive_target, - .initiator_poll_targets = pn53x_initiator_poll_targets, + .initiator_poll_target = pn53x_initiator_poll_target, .initiator_select_dep_target = pn53x_initiator_select_dep_target, .initiator_deselect_target = pn53x_initiator_deselect_target, .initiator_transceive_bytes = pn53x_initiator_transceive_bytes, diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index 35b2a6a..537ff29 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -508,7 +508,7 @@ const struct nfc_driver_t arygon_driver = { .initiator_init = pn53x_initiator_init, .initiator_select_passive_target = pn53x_initiator_select_passive_target, - .initiator_poll_targets = pn53x_initiator_poll_targets, + .initiator_poll_target = pn53x_initiator_poll_target, .initiator_select_dep_target = pn53x_initiator_select_dep_target, .initiator_deselect_target = pn53x_initiator_deselect_target, .initiator_transceive_bytes = pn53x_initiator_transceive_bytes, diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index b5f4aff..83c2a80 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -454,7 +454,7 @@ const struct nfc_driver_t pn532_uart_driver = { .initiator_init = pn53x_initiator_init, .initiator_select_passive_target = pn53x_initiator_select_passive_target, - .initiator_poll_targets = pn53x_initiator_poll_targets, + .initiator_poll_target = pn53x_initiator_poll_target, .initiator_select_dep_target = pn53x_initiator_select_dep_target, .initiator_deselect_target = pn53x_initiator_deselect_target, .initiator_transceive_bytes = pn53x_initiator_transceive_bytes, diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index ce3b831..664e080 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -751,7 +751,7 @@ const struct nfc_driver_t pn53x_usb_driver = { .initiator_init = pn53x_initiator_init, .initiator_select_passive_target = pn53x_initiator_select_passive_target, - .initiator_poll_targets = pn53x_initiator_poll_targets, + .initiator_poll_target = pn53x_initiator_poll_target, .initiator_select_dep_target = pn53x_initiator_select_dep_target, .initiator_deselect_target = pn53x_initiator_deselect_target, .initiator_transceive_bytes = pn53x_initiator_transceive_bytes, diff --git a/libnfc/nfc-internal.c b/libnfc/nfc-internal.c new file mode 100644 index 0000000..36da205 --- /dev/null +++ b/libnfc/nfc-internal.c @@ -0,0 +1,67 @@ +/*- + * Public platform independent Near Field Communication (NFC) library + * + * Copyright (C) 2011, Romuald Conty + * + * 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 + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see + */ + + /** + * @file nfc-internal.c + * @brief Provide some useful internal functions + */ + +#include +#include + +void +prepare_initiator_data (const nfc_modulation_t nm, byte_t **ppbtInitiatorData, size_t * pszInitiatorData) +{ + 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) + *ppbtInitiatorData = (byte_t *) "\x00"; + *pszInitiatorData = 1; + } + break; + case NMT_ISO14443BI: { + // APGEN + *ppbtInitiatorData = (byte_t *) "\x01\x0b\x3f\x80"; + *pszInitiatorData = 4; + } + break; + case NMT_ISO14443B2SR: { + // Get_UID + *ppbtInitiatorData = (byte_t *) "\x0b"; + *pszInitiatorData = 1; + } + break; + case NMT_ISO14443B2CT: { + // SELECT-ALL + *ppbtInitiatorData = (byte_t *) "\x9F\xFF\xFF"; + *pszInitiatorData = 3; + } + break; + case NMT_FELICA: { + // polling payload must be present (see ISO/IEC 18092 11.2.2.5) + *ppbtInitiatorData = (byte_t *) "\x00\xff\xff\x01\x00"; + *pszInitiatorData = 5; + } + break; + default: + *ppbtInitiatorData = NULL; + *pszInitiatorData = 0; + break; + } +} diff --git a/libnfc/nfc-internal.h b/libnfc/nfc-internal.h index f9ce952..9abc8ba 100644 --- a/libnfc/nfc-internal.h +++ b/libnfc/nfc-internal.h @@ -133,7 +133,7 @@ struct nfc_driver_t { bool (*initiator_init) (nfc_device_t * pnd); bool (*initiator_select_passive_target) (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt); - bool (*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 (*initiator_poll_target) (nfc_device_t * pnd, const nfc_modulation_t * pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t btPeriod, nfc_target_t * pnt); bool (*initiator_select_dep_target) (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt); bool (*initiator_deselect_target) (nfc_device_t * pnd); bool (*initiator_transceive_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout); @@ -158,4 +158,6 @@ void nfc_device_free (nfc_device_t *nfc_device); void iso14443_cascade_uid (const byte_t abtUID[], const size_t szUID, byte_t * pbtCascadedUID, size_t * pszCascadedUID); +void prepare_initiator_data (const nfc_modulation_t nm, byte_t **ppbtInitiatorData, size_t * pszInitiatorData); + #endif // __NFC_INTERNAL_H__ diff --git a/libnfc/nfc.c b/libnfc/nfc.c index ac51622..a6cc66a 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -325,41 +325,7 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, return false; } - 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_ISO14443BI: { - // APGEN - pbtInitData = (byte_t *) "\x01\x0b\x3f\x80"; - szInitDataLen = 4; - } - break; - case NMT_ISO14443B2SR: { - // Get_UID - pbtInitData = (byte_t *) "\x0b"; - szInitDataLen = 1; - } - break; - case NMT_ISO14443B2CT: { - // SELECT-ALL - pbtInitData = (byte_t *) "\x9F\xFF\xFF"; - szInitDataLen = 3; - } - 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; - } + prepare_initiator_data (nm, &pbtInitData, &szInitDataLen); while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt)) { nfc_initiator_deselect_target (pnd); @@ -397,19 +363,19 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, * @param pnd \a nfc_device_t struct pointer that represent currently used device * @param ppttTargetTypes array of desired target types * @param szTargetTypes \e ppttTargetTypes count - * @param btPollNr specifies the number of polling + * @param uiPollNr specifies the number of polling (0x01 – 0xFE: 1 up to 254 polling, 0xFF: Endless polling) * @note one polling is a polling for each desired target type - * @param btPeriod indicates the polling period in units of 150 ms - * @param[out] pntTargets pointer on array of 2 \a nfc_target_t (over)writables struct - * @param[out] pszTargetFound found targets count + * @param uiPeriod indicates the polling period in units of 150 ms (0x01 – 0x0F: 150ms – 2.25s) + * @note e.g. if uiPeriod=10, it will poll each desired target type during 1.5s + * @param[out] pnt pointer on \a nfc_target_t (over)writable struct */ bool -nfc_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) +nfc_initiator_poll_target (nfc_device_t * pnd, + const nfc_modulation_t * pnmModulations, const size_t szModulations, + const uint8_t uiPollNr, const uint8_t uiPeriod, + nfc_target_t * pnt) { - HAL (initiator_poll_targets, pnd, pnmModulations, szModulations, btPollNr, btPeriod, pntTargets, pszTargetFound); + HAL (initiator_poll_target, pnd, pnmModulations, szModulations, uiPollNr, uiPeriod, pnt); }