5

私は、ACR122U102 リーダー/ライターへの CM10.1 を使用して、Nexus 7 で通常の APDU 通信をエミュレートするアプリで忙しいです。ソフトウェア カード エミュレーションに関するこのブログを見つけて、自分のデバイス (ネクサス) をカードとして表示するアプリを作成しました。今、このデバイスと ACR122u の間でメッセージをやり取りしようとしています。これまでのところ、D4 40 01 ( InDataExchangeページ 127) APDU を送信することによってのみ、nexus 7 と通信できました。私が書いているアプリケーションでは、これで十分です。

問題は、デバイスからリーダーに送信する回答にあります。transcieve 関数 (リフレクション付きのandroid.nfc.tech.IsoPcdA ) を使用して、長さ > 0 のバイト配列で応答できます。これは、通常の InDataExchange 応答のようにリーダー側に表示されます (例: D5 41 00 01 02) 03 ({01 02 03} はトランスシーブ関数に提供されるバイト配列)。しかし、応答のステータス バイトも SW バイトも制御できません (D5 41 XX と両方の SW)。ソース コード自体を除いて、この IsoPcdA クラスに関するドキュメントはありません。

私ができるようにしたいのは、XX を選択したバイトに変更し、長さ = 0 の回答を送信することです (例: D5 41 01 余分なデータなし)。出来ますか?

4

1 に答える 1

6

ここで何を達成しようとしているのか正確にはわかりません。IsoPcdA の送受信メソッドで送受信するものはすべて、完全な APDU です (ISO/IEC 7816-4 で定義されているか、ISO-DEP トランスポート プロトコル内の任意の PDU)。したがって、transceive の戻り値は完全な C-APDU (コマンド APDU) であり、transceive のバイト配列パラメーターは、ステータス ワード (SW1 | SW2) の 2 バイトを含む完全な R-APDU (応答 APDU) です。したがって、そのパラメータの最後の 2 バイトはステータス ワードです。あなたの例では、SW1 は 02 になり、SW2 は 03 になります。

PN532 NFC コントローラの InDataExchange コマンドでステータス バイトとして表示されるのは、APDU のステータス ワードではなく、PN532 NFC コントローラ内のコマンド実行のステータスです。このステータス バイトは、バッファ オーバーフロー、通信タイムアウトなどに関する情報を提供し、カード側から返されるものではありません。

編集: サンプル コード + テスト コマンド:

Galaxy Nexus (CM 10) で実行されるサンプル コード:

try {
  Class isoPcdA = Class.forName("android.nfc.tech.IsoPcdA");
  Method isoPcdA_get = isoPcdA.getDeclaredMethod("get", Tag.class);

  final IsoPcdA techIsoPcdA = (IsoPcdA)isoPcdA_get.invoke(null, tag);

  if (techIsoPcdA != null) {
    if (mWorker != null) {
      mInterrupt = true;
      mWorker.interrupt();
      try {
        mWorker.join();
      } catch (Exception e) {}
    }

    mInterrupt = false;
    mWorker = new Thread(new Runnable() {
      public void run () {
        try {
          techIsoPcdA.connect();

          byte[] command = techIsoPcdA.transceive(new byte[]{ (byte)0x90, (byte)0x00 });
          Log.d(CardEmulationTest.class.getName(), "Connected.");

          while (!mInterrupt) {
            Log.d(CardEmulationTest.class.getName(), "C-APDU=" + StringUtils.convertByteArrayToHexString(command));
            command = techIsoPcdA.transceive(command);
          }
        } catch (Exception e) {
          Log.e(CardEmulationTest.class.getName(), "Exception while communicating on IsoPcdA object", e);
        } finally {
          try {
            techIsoPcdA.close();
          } catch (Exception e) {}
        }
      }
    });

    mWorker.start();
  }
} catch (Exception e) {
  Log.e(CardEmulationTest.class.getName(), "Exception while processing IsoPcdA object", e);
}

テスト (ACR122U を使用):

InListPassivTargets (106kbps で 1 つのターゲット)

> FF00000004 D44A 0100 00
< D54B 010100046004088821310578338800 9000

DATA = 0x01 の InDataExchange

> FF00000004 D440 01 01 00
< D541 00 01 9000

そのため、カード リーダーからエラー コード 0x00 を取得し (InDataExchange コマンドのステータス。実際の応答 APDU の一部ではありません)、応答として 0x01 を取得し (これは IsoDepA 応答 APDU です)、ステータス コードとして 0x9000 を取得します。カード リーダー ラッパー APDU (実際の応答 APDU の一部ではありません)。

DATA = 0x01 0x02 の InDataExchange

> FF00000005 D440 01 0102 00
< D541 00 0102 9000

そのため、カード リーダーからエラー コード 0x00 を取得し (InDataExchange コマンドのステータス。実際の応答 APDU の一部ではありません)、応答として 0x01 0x02 を取得し (これは IsoDepA 応答 APDU です)、ステータス コードとして 0x9000 を取得します。カード リーダー ラッパー APDU 用 (実際の応答 APDU の一部ではありません)。

DATA = 0x01 0x02 0x03 の InDataExchange

> FF00000006 D440 01 010203 00
< D541 00 010203 9000

そのため、カード リーダーからエラー コード 0x00 を取得し (InDataExchange コマンドのステータス。実際の応答 APDU の一部ではありません)、応答として 0x01 0x02 0x03 を取得し (これは IsoDepA 応答 APDU です)、ステータスとして 0x9000 を取得します。カード リーダー ラッパー APDU のコード (実際の応答 APDU の一部ではありません)。

DATA = 0x01 0x02 0x03 0x04 の InDataExchange

> FF00000007 D440 01 01020304 00
< D541 00 01020304 9000

したがって、カード リーダーから 0x00 のエラー コードを取得し (InDataExchange コマンドのステータス。実際の応答 APDU の一部ではありません)、応答として 0x01 0x02 0x03 0x04 を取得し (これは IsoDepA 応答 APDU です)、0x9000 を応答として取得します。カード リーダー ラッパー APDU のステータス コード (実際の応答 APDU の一部ではありません)。

したがって、コマンド APDU として送信したデータを応答 APDU として正確に取得します (これらの APDU はいずれも ISO 7816-4 に従ってフォーマットされていないことに注意してください。フォーマット)。

0x9000のステータス コードは、ACR122U の PN532 が CCID (PC/SC) インターフェイス経由でアクセスされるときに必要なカード リーダー APDU カプセル化 ( CLA=FF INS=00 P1P2=0000 Lc [PN542 COMMAND] Le=00 ) に属します。これらは純粋なリーダー コマンドのカプセル化であり、ISO-DEP を介した通信とは関係ありません。

D440 01 [DATA]は、ISO-DEP を介してデータ (APDU など) を交換するための PN532 コマンドであり、D541 00 [DATA]は関連する応答です。

于 2013-05-27T16:55:47.090 に答える