nfcpy app tolerant of USB unplug/replug?

Asked by V Naresh

hi,
I am building an app on the windows platform that needs to be continuously polling for data from an nfc reader (in a separate python thread). I'm not quite sure how to do that - I am comfortable getting nfcpy to work using ContactlessFrontend("usb:0001:2222") and then using nfc.poll, but I am not quite sure how to make it tolerant of the device itself being unplugged.

Right now, I am thinking of two while loops - one for the ContactlessFrontend call and one for the poll call, but I'm not sure if that is the right way to do it. Especially after reading the docs, it seems to me as "connect" is the right way to do it - but the examples are all one-off read/writes, not a sustained polling and handling usb unplug and replug.

I will appreciate any help on the topic - I tried searching for example code, but none that look like the one I'm talking about.

thanks!

Question information

Language:
English Edit question
Status:
Answered
For:
nfcpy Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
V Naresh (vnwarrior) said :
#1

also - I'm not sure what the right way to interact with a reader is.
I have a ACR122U and when my script is NOT running, a card touch causes a small red LED on the reader to go green and emit a beep.

when my script is running, it reads fine, but there is none of these LED/beep things happening. Should I be returning some value to ensure that ?

Revision history for this message
V Naresh (vnwarrior) said :
#2

From this gist (https://gist.github.com/nixme/2717287), it looks like I have to send "\xFF\x00\x40\xCF\x04\x03\x00\x01\x01" to get it to beep and change color. Not sure how to do it in nfcpy.

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#3

To create the nfc.ContactlessFrontend() instance a physical reader must be connected. A dumb method to wait until that comes true would be to loop around and catch the "IOError: [Errno 19] No such device" raised when no reader is found:

while True:
    try:
        clf = nfc.ContactlessFrontend( ... )
    except IOError as error:
        if error.errno != 19:
            raise error
        time.sleep(1.0)
        continue

A cleaner approach would of course be to use udev to start when the reader is plugged in.

Once a clf is ready the proper way to proceed is using connect(), again looping around to capture the individual touches.

Revision history for this message
V Naresh (vnwarrior) said :
#4

Stephen,
Thanks for the reply - I'm having yet another issue when my reader is connected. All I want to do is read a card, and wait till it is removed to read another card - NOT a continuous read. if I use "rdwr" and at some-point, if I remove the card too fast, then there is either a TimeoutError or TransmissionError.

I'm using a Type4 tag (Desfire) - is there any way I can read and wait till the card is removed before I "connect" again ? A card emulation has "on-release", but I cant use a Type4 card with it.

any suggestions.

FYI - I'm using the windows platform to build my products.

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#5

See the following snippet from the documentation. Just let the on-connect function return True and then connect() will only return after the tag is removed from the reader.

>>> import nfc
>>> def connected(tag): print tag; return True
...
>>> clf = nfc.ContactlessFrontend('usb')
>>> clf.connect(rdwr={'on-connect': connected}) # now touch a tag
Type3Tag IDm=01010501b00ac30b PMm=03014b024f4993ff SYS=12fc
True

Revision history for this message
V Naresh (vnwarrior) said :
#6

This is my script http://pastebin.ca/2495499 and this the subsequent log http://pastebin.ca/2495500

I dont think it is working quite the way you mentioned (return only after the tag is removed) fundamentally because "tag.is_present" is turning to be "false" even inside the connected(tag) function.

this probably is impacting the following piece of code:

#clf.py:424
if callback and callback(tag):
                    while not terminate() and tag.is_present:
                        time.sleep(3)

Not sure about this, just my opinion.

Revision history for this message
Stephen Tiedemann (stephen-tiedemann) said :
#7

The tag you're using is a Type4A (Mifare Desfire) that is not formatted as NDEF tag. The presence check done in nfcpy is based on reading periodically from the NDEF data partition using the commands defined by the NFC Forum for a Type 4 Tag - this naturally fails here. What you probably need to do is to run your own presence check within the connected() function, probably doing some application specific command exchange before (as necessary for your app). Afterwards return False from connected() to let clf.connect() know that the tag is gone.

For NDEF formatted tags I've checked that the code at http://pastebin.com/xDjmUNdh is working.

Can you help with this problem?

Provide an answer of your own, or ask V Naresh for more information if necessary.

To post a message you must log in.