From 827d9792dd13ac42939e56fd5d2a4c5b2bda990a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 1 Feb 2014 02:32:57 +0100 Subject: [PATCH] Save & restore NP_INFINITE_SELECT status when changing it internally --- libnfc/chips/pn53x.c | 22 ++++++++++++++++++---- libnfc/nfc.c | 28 +++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 21affef..4a950f0 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -1244,6 +1244,8 @@ pn53x_initiator_poll_target(struct nfc_device *pnd, break; } } else { + bool bInfiniteSelect = pnd->bInfiniteSelect; + int result = 0; if ((res = pn53x_set_property_bool(pnd, NP_INFINITE_SELECT, true)) < 0) return res; // FIXME It does not support DEP targets @@ -1257,16 +1259,23 @@ pn53x_initiator_poll_target(struct nfc_device *pnd, if ((res = pn53x_initiator_select_passive_target_ext(pnd, pnmModulations[n], pbtInitiatorData, szInitiatorData, pnt, timeout_ms)) < 0) { if (pnd->last_error != NFC_ETIMEOUT) { - return pnd->last_error; + result = pnd->last_error; + goto end; } } else { - return res; + result = res; + goto end; } } } } while (uiPollNr == 0xff); // uiPollNr==0xff means infinite polling // We reach this point when each listing give no result, we simply have to return 0 - return 0; +end: + if (! bInfiniteSelect) { + if ((res = pn53x_set_property_bool(pnd, NP_INFINITE_SELECT, false)) < 0) + return res; + } + return result; } return NFC_ECHIP; } @@ -1822,7 +1831,7 @@ static int pn53x_ISO14443A_MFC_is_present(struct nfc_device *pnd) ret = pn53x_Diagnose06(pnd); } else { // Limitation: re-select will lose authentication of already authenticated sector - // Limitation: NP_INFINITE_SELECT will be left as FALSE (we cannot restore as we don't know what was the original state) + bool bInfiniteSelect = pnd->bInfiniteSelect; uint8_t pbtInitiatorData[12]; size_t szInitiatorData = 0; iso14443_cascade_uid(CHIP_DATA(pnd)->current_target->nti.nai.abtUid, CHIP_DATA(pnd)->current_target->nti.nai.szUidLen, pbtInitiatorData, &szInitiatorData); @@ -1833,6 +1842,11 @@ static int pn53x_ISO14443A_MFC_is_present(struct nfc_device *pnd) } else if ((ret == 0) || (ret == NFC_ETIMEOUT)) { ret = NFC_ETGRELEASED; } + if (bInfiniteSelect) { + int ret2; + if ((ret2 = pn53x_set_property_bool(pnd, NP_INFINITE_SELECT, true)) < 0) + return ret2; + } } return ret; } diff --git a/libnfc/nfc.c b/libnfc/nfc.c index dcfd409..dce7ffd 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -573,6 +573,7 @@ nfc_initiator_list_passive_targets(nfc_device *pnd, pnd->last_error = 0; // Let the reader only try once to find a tag + bool bInfiniteSelect = pnd->bInfiniteSelect; if ((res = nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false)) < 0) { return res; } @@ -603,6 +604,11 @@ nfc_initiator_list_passive_targets(nfc_device *pnd, break; } } + if (bInfiniteSelect) { + if ((res = nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, true)) < 0) { + return res; + } + } return szTargetFound; } @@ -684,18 +690,30 @@ nfc_initiator_poll_dep_target(struct nfc_device *pnd, const int period = 300; int remaining_time = timeout; int res; + int result = 0; + bool bInfiniteSelect = pnd->bInfiniteSelect; if ((res = nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, true)) < 0) return res; while (remaining_time > 0) { if ((res = nfc_initiator_select_dep_target(pnd, ndm, nbr, pndiInitiator, pnt, period)) < 0) { - if (res != NFC_ETIMEOUT) - return res; + if (res != NFC_ETIMEOUT) { + result = res; + goto end; + } + } + if (res == 1) { + result = res; + goto end; } - if (res == 1) - return res; remaining_time -= period; } - return 0; +end: + if (! bInfiniteSelect) { + if ((res = nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false)) < 0) { + return res; + } + } + return result; } /** @ingroup initiator