如何加速Java中PC / SC阅读器上的卡缺失检测?

时间:2012-08-01 13:47:45

标签: java detection nfc smartcard rfid

我正在处理的应用程序要求尽快(最多500毫秒)检测到一张卡从现场移除。

以下是我测试检测卡片缺失所需的时间:

public static long timeToGetCardAbsent(int version) throws CardException{
    TerminalFactory factory = TerminalFactory.getDefault();

    CardTerminals terminalList = factory.terminals();
    CardTerminal ct = terminalList.list().get(0);

    long connectTime = 0, disconnectTime = 0;

    ct.waitForCardPresent(0);
    connectTime = new Date().getTime();

    ct.waitForCardAbsent(0);
    disconnectTime = new Date().getTime();

    return disconnectTime - connectTime;
}

当程序运行时,我在阅读器上点击(DESFire)非接触式卡并立即将其移除。

以下是输出:

1437
1437
1438
1437
1422

我的意思是读者(或程序?)需要差不多1.5秒才能检测到卡片不存在,这对我来说太长了。

有没有办法加快检测速度?我目前正在使用javax.smartcardio,我会在其他图书馆获得更好的结果吗?我实际上不知道我还能用什么,你有领导吗?

谢谢, GChabot

2 个答案:

答案 0 :(得分:1)

我实际上成功地改善了今天的检测时间。我正在查看that web page from "NFC Wizard"并注意到他们检测到卡片移除速度非常快。这个javascript网页通过Java applet与读者进行通信,因此它实际上只使用了我。

NFC向导的创建者SpringCard实际上为that page, under Other resources > Java and "SpringCard PC/SC SDK (ZIP archive)"的类似应用程序提供了完整的文档甚至源代码。

在浏览他们的代码时,我注意到在对卡片执行操作后,使用card.disconnect(false);功能(我曾尝试使用card.disconnect(true);,但结果与以前相同... 运气不好)。

现在我的工作就是这样:

import java.util.Date;
import javax.smartcardio.*;

public class NewMethod {
    private long connectTime = -1;
    private long disconnectTime = -1;

    private TerminalFactory factory;
    private CardTerminals terminalList;
    private CardTerminal ct;

    public NewMethod() throws CardException{
        factory = TerminalFactory.getDefault();

        terminalList = factory.terminals();
        ct = terminalList.list().get(0);
    }

    public long waitForCardPresent(){
        try {
            ct.waitForCardPresent(0);
        } catch (CardException e) { }
        return new Date().getTime();
    }

    public long waitForCardAbsent(){
        while(true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e1) { }

            try{
                ct.connect("*").disconnect(false);
            }
            catch(Exception e) {
                return new Date().getTime();
            }
        }
    }

    public void run(){
        while(true){
            connectTime = waitForCardPresent();
            disconnectTime = waitForCardAbsent();
            System.out.println((disconnectTime-connectTime));
        }
    }

    public static void main(String[] args){
        NewMethod nm;
        try {
            nm = new NewMethod();
            nm.run();
        } catch (CardException e) {
            e.printStackTrace();
        }
    }
}

(线程部分是可选的,但无论有没有,我都得到相同的结果,所以我更喜欢节省一点处理器消耗)

以下是我使用线程版本的时间:531, 437, 656, 657, 735, 657, 547, 844, 15, 766, 859, 563, 765, 562, 422, 437, 563, 562, 562, 672, 672, 16, 547, 546, 672, 15, 344 这里有无线版本:984, 547, 796, 656, 796, 718, 656, 812, 625, 781, 813, 547, 797, 532, 407, 609, 719, 328, 469, 328, 0, 546, 625, 0, 843, 703

我们可能会注意到结果非常不稳定(实际上对于线程版本来说效果更好),这可能来自我点击读卡器的方式,但我相信这不是唯一的原因。

现在看起来对我来说足够好了。我只是希望当我在我的应用程序中实际使用它时,我不会获得太大的变化。

答案 1 :(得分:0)

我在Linux上测试了一下,在Linux中,默认的PCSC守护程序是轮询驱动程序,每个400-500ms。如果我找到的PCSC Lite信息正确,则不稳定的驱动程序似乎会删除此轮询并使用其他方法。

Java方法似乎几乎立即返回,因此不太可能是罪魁祸首。尝试将PCSC实施,固件和驱动程序更新到最新版本。如果这不起作用,你就没有选择解决它。

这个答案确实让我在Linux + SCM SDI010驱动程序安装和3个固件的测试中安装了PCSC。但无论如何我想要自己的信息。如果我使用更新版本的PCSC lite,我会更新答案。