Domanda

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!

È stato utile?

Soluzione

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 ;)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top