diff --git a/brmdoor_nfc_daemon.py b/brmdoor_nfc_daemon.py index 116541a..7d0f721 100755 --- a/brmdoor_nfc_daemon.py +++ b/brmdoor_nfc_daemon.py @@ -127,8 +127,10 @@ class NFCScanner(object): e = threading.Event() e.wait(timeout=0.3) except NFCError, e: - #this exception happens also when scanUID times out - logging.debug("Failed to wait for RFID card: %s", e) + #this exception happens also when scanUID finds no cards + logging.debug("Failed to find RFID cards in reader's field: %s", e) + e = threading.Event() + e.wait(timeout=0.2) except KeyboardInterrupt: logging.info("Exiting on keyboard interrupt") self.nfc.close() diff --git a/nfc_smartcard.cpp b/nfc_smartcard.cpp index 64a78b7..5100d7f 100644 --- a/nfc_smartcard.cpp +++ b/nfc_smartcard.cpp @@ -104,19 +104,16 @@ std::string NFCDevice::scanUID() throw(NFCError) throw NFCError("NFC device not opened"); } - // We release GIL because otherwise it would block other threads. Since this polling is de-facto sleep and - // doesn't touch any variables, it works as a language without GIL would. - Py_BEGIN_ALLOW_THREADS - res = nfc_initiator_poll_target(_nfcDevice, _modulations, _modulationsLen, pollNr, pollPeriod, &nt); - Py_END_ALLOW_THREADS + /* nfc_initiator_poll_target works fine for USB-connected PN532 (sleeps until card is available or timeout), + * but causes 100% CPU usage on SPI-connected PN532 + */ + //res = nfc_initiator_poll_target(_nfcDevice, _modulations, _modulationsLen, pollNr, pollPeriod, &nt); + res = nfc_initiator_list_passive_targets(_nfcDevice, _modulations[0], &nt, 1); if (res < 0) { - throw NFCError("NFC polling error"); - } - - // we are not interested in non-ISO-14443A cards - if (nt.nm.nmt != NMT_ISO14443A) { - return string(); + throw NFCError("NFC list passive targets error"); + } else if (res == 0) { + throw NFCError("No card in reader's field"); } const nfc_iso14443a_info& nai = nt.nti.nai; diff --git a/nfc_smartcard.h b/nfc_smartcard.h index 3101c5d..24074ba 100644 --- a/nfc_smartcard.h +++ b/nfc_smartcard.h @@ -99,11 +99,13 @@ public: virtual ~NFCDevice(); /** - * Poll until a ISO14443A card is in the field and returns its UID. + * Read UID of a card in field. If multiple cards are found, return UID of first one. + * + * If you are polling for cards with this, include some sleep in-between the calls (e.g. 0.1 sec). * * @returns binary string containing UID or empty if non-supported card * present in reader field - * @throws NFCError if polling failed + * @throws NFCError if no cards in reader's field */ std::string scanUID() throw(NFCError);