3

私が取り組んでいるアプリケーションでは、カードがフィールドから取り除かれたことをできるだけ早く (最大 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

4

2 に答える 2

1

今日は実際に検出時間を大幅に改善することができました。「NFCウィザード」からそのWebページを見ていたところ、カードの取り外しを非常に高速に検出できることに気付きました。このjavascriptWebページは、Javaアプレットを介してリーダーと通信するため、実際には私が持っている以上のものを使用していません。

NFC Wizardの作成者であるSpringCardは、実際には、そのページの[その他のリソース]>[Java]および[SpringCardPC / SC SDK(ZIPアーカイブ)]で、同様のアプリケーションの完全なドキュメントとソースコードを提供しています。

彼らのコードを閲覧していると、カードで操作を行った後、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

結果が非常に不安定であることに気付くかもしれません(そして実際にはスレッドバージョンではかなり良いです)。これは私がリーダーに対してカードをタップする方法から来るかもしれませんが、これが唯一の理由ではないと思います。

今は十分に良さそうです。アプリケーションで実際に使用するときに、あまり大きな変動が生じないことを願っています。

于 2012-08-03T16:26:53.307 に答える
0

Linux で少しテストしましたが、Linux では、デフォルトの PCSC デーモンが400 ~ 500 ミリ秒ごとにドライバーをポーリングしています。私が見つけた PCSC Lite 情報が正しければ、不安定なドライバーはこのポーリングを削除し、別の方法を使用するようです。

Java メソッドはほぼ瞬時に返されるように見えるので、それが原因である可能性は低いです。PCSC の実装、ファームウェア、およびドライバーを最新バージョンに更新してみてください。それがうまくいかない場合、それを回避する選択肢はありません。

その答えには、Linux への PCSC のインストール + SCM SDI010 ドライバーのインストールと、3 つのファームウェアのテストが必要でした。とにかく自分で情報が欲しかった。新しいバージョンの PCSC lite が動作するようになったら、回答を更新します。

于 2012-08-02T21:47:49.857 に答える