2

I've bought a NFC card reader (ACS / ACR122U) that I plug in my raspberry 3 thru an USB port; I've installed swig, pcsc-tools, pcscd ,libpcsclite... The pcscd service is launched by systemctl and is bind to pcscd.socket. I can see the reader when I start nfc-scan-device and can also read the card provided with the reader when I start nfc-list Then I try to read the tag-Id using python3 and pyscard and it doesn't work. I can see the reader and launch a connection without any error message but can't read the tagID.

sudo nfc-list returns:

>nfc-list uses libnfc 1.7.1
>NFC device: ACS / ACR122U PICC Interface opened
>1 ISO14443A passive target(s) found:
>ISO/IEC 14443A (106 kbps) target:
>ATQA (SENS_RES): 00  04  
>UID (NFCID1): d6  71  c5  f0  
>SAK (SEL_RES): 08`  

the NFC card reader is thus reachable and I can even get the tag id of cards

Then I try to use it on python I've found some info there: https://pyscard.sourceforge.io/user-guide.html https://pyscard.sourceforge.io/epydoc/smartcard-module.html

I first try it within a pipenv environment but it didn't worked. I then removed pipenv to be sure it was not on the critical path...

first test

I try a basic script that can be found on pyscard doc and an most tutorials... let's call it nfcReader-1.py

from smartcard.System import readers
import sys

getuid=[0xFF, 0xCA, 0x00, 0x00, 0x00]
r = readers()
if len(r) < 1:
  print("error: No readers available!")
  sys.exit()

print("Available readers: ", r)
reader = r[0]
print("Using: ", reader)
conn = reader.createConnection()
conn.connect()
data, sw1, sw2 = conn.transmit(getuid)
if (sw1, sw2) == (0x90, 0x0):
  print("Status: The operation completed successfully.")
elif (sw1, sw2) == (0x63, 0x0):
  print("Status: The operation failed.")

print("uid={}".format(data))
conn=disconnect()
r=None  #to prevent error messages when calling sys.exit() below
sys.exit()

>Available readers:  ['ACS ACR122U PICC Interface 00 00']
>Using:  ACS ACR122U PICC Interface 00 00
>Status: The operation failed.
>uid=[]

the reader is found but I can't read the card. The transmit() method returns [0x63,x0x00] ([99,00]) which mean something weird happened It does not work neither when I type each command in python command line

SECOND TEST

I also try another way. I found this second method in the pyscard doc but the result is exacltly the same:

from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.CardConnection import CardConnection
from smartcard.util import toHexString

import sys
getuid=[0xFF, 0xCA, 0x00, 0x00, 0x00]
act = AnyCardType()
cr = CardRequest( timeout=10, cardType=act )
cs = cr.waitforcard()
cs.connection.connect()

print(toHexString( cs.connection.getATR() ))
print(cs.connection.getReader())
data, sw1, sw2 = cs.connection.transmit( cmdmap['getuid'] )
if (sw1, sw2) == (0x90, 0x0):
  print("Status: The operation completed successfully.")
elif (sw1, sw2) == (0x63, 0x0):
  print("Status: The operation failed.")

print("uid={}".format(data))
cs=None  #to prevent error message when calling sys.exit() below
sys.exit()

the response was not different:

>3B 00
>ACS ACR122U PICC Interface 00 00
>Status: The operation failed.
>uid=[]

The command I used was [0xFF,0xCA,0x00,0x00,0x00] which seems to be the one to get the tagid. The ACS reader doc (https://www.acs.com.hk/en/download-manual/419/API-ACR122U-2.04.pdf) confirms this is the correct sequence. ACS tagid sequence description

At least, I try to launch my python script using sudo in case it could help. and I change the permissions on the socket's folder (/var/run/pcscd/pcscd.comm) to 777... just in case

Do someone any idea of the way I can solve this weird problem ? thanks for your help.

David
  • 492
  • 8
  • 17
  • ...I can make the reader *beep*, using the following sequence : `[0xFF,0x00,0x40,0x00,0x04,0x01,0x00,0x03,0x03]` – David May 22 '19 at 16:50
  • To rule out a pyscard problem, you can use scriptor/gscriptor from pscsc-tools to send APDUs to your card reader. – arved May 24 '19 at 14:26
  • 1
    This is a known limitation with some versions of the ACR122U. The reader does not automatically process/enumerate tags. Instead, you will need to use the DIRECT TRANSMIT command (an APDU of the form `FF000000`) to send raw commands to the embedded PN532 chip to poll for and access tags. That's also what libnfc is doing. – Michael Roland May 28 '19 at 19:31
  • @MichaelRoland I am new to this, so can you please explain in lay terms how to do this? – Asad Mehasi Feb 21 '21 at 07:10
  • @David Did you manage to solve this? I am facing exactly the same issue. – Asad Mehasi Feb 21 '21 at 07:12
  • Never mind guys, I managed to solve the issue. – Asad Mehasi Feb 27 '21 at 12:41

1 Answers1

0

I had the same issue with an NFC card reader (ACS / ACR122U) that I just wanted to connect to the PC on Windows 10 to read the ID saved on a customer card. I manage to solve it by replacing:

  • data, sw1, sw2 = cs.connection.transmit( cmdmap['getuid'] )

with

  • data, sw1, sw2 = cs.connection.transmit(getuid)

The reason is because you have not defined cmdmap and to simply read the data, it is not even necessary.

After this I wanted to convert the data, a solution is:

  • data = toHexString(data)

Note that in my case this data was in reverse order, but that is an easy solve.

Asad Mehasi
  • 111
  • 3