3

現在、Galaxy s4 の HCE 実装に取り​​組んでいます。私は 7816-4 をサポートする Omnikey 5321-cl リーダーを持っています。私のアンドロイドクラスは次のようになります:

public class NfcHceService extends HostApduService{
private int counter         = 0;

@Override
public void onStart(android.content.Intent intent, int startId)
{
    new Thread(new Runnable() {

        @Override
        public void run()
        {
            while (true)
            {
                Log.d("HCE", String.valueOf(counter));
                counter++;
                try
                {
                    Thread.sleep(1000);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }).run();
}

@Override
public byte[] processCommandApdu(byte[] apdu, Bundle extras)
{
    byte[] response = null;
    if (apdu[2] == 0xA4)
    {
        // return selecting applet
        response = new byte[] { (byte) 0x90, 0x00 };

    }
    return response;
}

@Override
public void onDeactivated(int reason)
{
    android.os.Debug.waitForDebugger();
    Log.d("HCE", "onDeactivated");

}

}

そして、私の読者クラスは次のようになります。

private static final byte[] CLA_INS_P1_P2   = { 0x00, (byte) 0xA4, 0x04, 0x00 };
private static final byte[] AID_ANDROID     = { (byte) 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

private static byte[] createSelectAidApdu(byte[] aid)
{
    byte[] result = new byte[6 + aid.length];
    System.arraycopy(CLA_INS_P1_P2, 0, result, 0, CLA_INS_P1_P2.length);
    result[4] = (byte) (aid.length);
    System.arraycopy(aid, 0, result, 5, aid.length);
    result[result.length - 1] = 10;
    return result;
}

public static void Create_MF() throws CardException
{

    // --Variable declaration
    Card card = null;
    ResponseAPDU answer = null;
    // ---------------------------------------------

    // --1--Establish connection with the smart card
    TerminalFactory factory = TerminalFactory.getDefault();
    List<CardTerminal> terminals = factory.terminals().list();
    // Use the first terminal
    CardTerminal terminal = terminals.get(1);
    // Connect with the card
    card = terminal.connect("*");
    CardChannel channel = card.getBasicChannel();
    // ---------------------------------------------

    byte[] selectAidApdu = createSelectAidApdu(AID_ANDROID);

    answer = channel.transmit(new CommandAPDU(selectAidApdu));

hce サービスの私の AID は F0010203040506 です。

私の問題は、Android デバイスで次のような正しい Select APDU を取得することです。

> RX: Type 4 Tag Command (13 bytes)
  CLA:0x00
  INS:0xA4(Select)
  P1:0x04(Name)
  P2:0x00(First or Only)
  LC:0x07(7)
  Data(7 bytes)
   00: f0 01 02 03 04 05 06
  Le:0x0A(10)

しかし、応答コード 6A82 が返されます。私が理解しているように、これはデバイスがサービスを見つけられないことを意味します。しかし、私はその理由を理解していません。誰でも助けることができますか?

マニフェスト:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hce"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
    android:minSdkVersion="19"
    android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" />
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <service
        android:name=".NfcHceService"
        android:exported="false"
        android:permission="android.permission.BIND_NFC_SERVICE" >
        <intent-filter>
            <action android:name="android.nfc.cardemulation.HOST_APDU_SERVICE" />
        </intent-filter>
        <meta-data
            android:name="android.nfc.cardemulation.host_apdu_service"
            android:resource="@xml/hce_service" />
    </service>
</application>

そしてxmlファイル:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/my_app_hce_service" >
<aid-group
    android:category="other"
    android:description="@string/my_app_aid_group" >
    <aid-filter android:name="F0010203040506" />
</aid-group></host-apdu-service>

アップデート

public static void Create_MF() throws CardException
{

    // --Variable declaration
    Card card = null;
    ResponseAPDU answer = null;
    // ---------------------------------------------

    // --1--Establish connection with the smart card
    TerminalFactory factory = TerminalFactory.getDefault();
    List<CardTerminal> terminals = factory.terminals().list();
    // Use the first terminal
    CardTerminal terminal = terminals.get(1);
    // Connect with the card
    card = terminal.connect("*");
    CardChannel channel = card.getBasicChannel();
    // ---------------------------------------------

    byte[] selectAidApdu = { 0x00, (byte) 0xA4, 0x04, 0x00, 0x07, (byte) 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; // createSelectAidApdu(AID_ANDROID);

    answer = channel.transmit(new CommandAPDU(selectAidApdu));}

更新 2

isDefaultServiceForAid() を実装しようとしました。しかし、私がそれを正しく使用しているかどうか、そしてそれが私が望むことをするかどうかはわかりません.

    CardEmulation card = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(this));
    ComponentName comp = new ComponentName(getApplicationContext(), NfcHceService.class);
    boolean tmp = card.isDefaultServiceForAid(comp, "F0010203040506");

サービスの AID を本当にテストするのか、それとも何か別のことをするのか? マニフェストで宣言されている hce_service.xml で指定した AID を使用してサービスにアクセスできるかどうかをテストしたいと考えています。

4

4 に答える 4

1

エラー6A82は を意味しfile not foundます。

この場合、選択している AID が存在しないことを意味します。

これはおそらく、選択f0 01 02 03 04 05 06している AID と AndroidManifest.xml で指定されているAID が一致していないことが原因です。

ISO 7816 リファレンスはこちら

アップデート:

更新されたコードを調べると、APDU の末尾に別のバイトを追加しているように見えます0x10。関数から次の行を削除してみてくださいcreateSelectAidApdu()

result[result.length - 1] = 10;

また、最後のバイトを 10 に設定した理由がわかりません。これは 10 進数で 16 に相当します。最後のバイトは、多くの場合、ターゲット デバイスから期待/要求されるデータ量を指定するために使用されることに注意してください。select application コマンドの場合のように、常に必要というわけではありません。

于 2014-07-07T09:53:53.500 に答える
0

AIDの選択は問題ないと思います。Android に AID 用のアプリがない場合、Android は何もせず、エラー コードも送受信しません。

問題は、アプリがメッセージとして null を返すため、おそらく Android がエラー コードを返すことにあると思われます。

次の if ステートメントは、apdu[2] が実際には (バイト) 0x04 であるため、否定的なテストを行います。apdu[1] は (バイト) 0xA4 になります。

byte[] response = null;
if (apdu[2] == 0xA4)
{
    // return selecting applet
    response = new byte[] { (byte) 0x90, 0x00 };

}
return response;
于 2014-11-05T23:25:37.410 に答える
0

私はちょうど同様の問題を抱えていました.私のAIDは両端で正しいのですが、サービスはまだ見つかりませんでした.

公式のHCE ページには、次のスニペットがあります。

<service android:name=".MyHostApduService" android:exported="true"
     android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
    <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
</intent-filter>
<meta-data android:name="android.nfc.cardemulation.host_apdu_service"
           android:resource="@xml/apduservice"/>

タグ<intent-filter>が付いていないことに気づきました。<category>これを追加したところ、突然私のサービスが見つかりました! 下記参照:

<intent-filter>
    <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
    <!-- category required!!! this was not included in official android HCE documentation -->
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
于 2016-11-11T17:17:56.397 に答える