Question

I have 3 ACR122U NFC readers connected to a Raspberry Pi. I have a Java program that uses javax.smartcardio to interface with the readers. My program creates threads for each reader found:

List<CardTerminal> terminals = TerminalFactory.getDefault().terminals().list();
int terminalCount = terminals.size();        
System.out.println("Detected " + String.valueOf(terminalCount) + " terminal/s");
for(int i = 0; i < terminalCount; i++)
{
     System.out.println("Initiating thread :" + String.valueOf(i));
     new Thread(new AccessTerminal(i,terminals.get(i))).start();
}

Each thread class runs an AccessTerminal class which does basically the following:

System.out.println("Thread started... Waiting for card...");
cardTerminal.waitForCardPresent(0);
System.out.println("Card found");
card = cardTerminal.connect("*");
cardChannel = card.getBasicChannel();
if(authenticate())
{
     int UID = getUID();
     System.out.println("User identified as :" + String.valueOf(UID));
}
cardTerminal.waitForCardAbsent(0);

The above code runs perfectly if only 1 ACR122U is connected. It ALSO runs perfectly when I have 3 ACR122U connected to a WINDOWS machine. However if I have two or more connected to a raspberry pi, The one reader does nothing at first but if I first scan the other reader then it gets halfway to "Card found" then freezes, then I can swipe the other reader and it comes up with with a NoCardPresent Exception. Bellow is the errors.

Starting system...
Detected 2 terminal/s
Initiating thread :0
Initiating thread :1
Thread started... Waiting for card...
Thread started... Waiting for card...
Card found
Card found
Card not valid
Nov 27, 2013 1:02:01 PM livaccess.AccessTerminal run
SEVERE: null
javax.smartcardio.CardNotPresentException: No card present
    at sun.security.smartcardio.TerminalImpl.connect(TerminalImpl.java:82)
    at livaccess.AccessTerminal.run(AccessTerminal.java:41)
    at java.lang.Thread.run(Thread.java:722)
Caused by: sun.security.smartcardio.PCSCException: SCARD_W_REMOVED_CARD
    at sun.security.smartcardio.PCSC.SCardStatus(Native Method)
    at sun.security.smartcardio.CardImpl.<init>(CardImpl.java:85)
    at sun.security.smartcardio.TerminalImpl.connect(TerminalImpl.java:78)
    ... 2 more

If I do exactly the same program with the same setup on a windows machine I get the following output:

Starting system...
Detected 2 terminal/s
Initiating thread :0
Initiating thread :1
Thread started... Waiting for card...
Thread started... Waiting for card...
Card found
Card is valid
User identified as :1534
Thread started... Waiting for card...
Card found
Card is valid
User identified as :1534

In both cases I swiped the same card at both readers. Don't worry about the Card is invalid or valid, that is an irrelevant check in my code.

If someone has a solution for me I would be very great full. I have a feeling it has to do with linux not differentiating between the two usb devices.

Thanks for reading!

Was it helpful?

Solution

It seems as though the Raspberry Pi OS didn't handle the USB drivers too well using separate threads. Instead of starting a new Java thread to handle each device, I just made a single thread loop through all the devices when polling for a card.

I found more issues like the one above using the smartcard.io java package. In the end I switched to C++ libnfc library to handle my devices.

libnfc turned out to be a lot faster and more stable. Especially when dealing with multiple devices on one system.

Hope this helps someone ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top