通常 NFC のカードエミュレーションを利用するときは、SE(Secure Element) というのが必要で、リーダはこの人とおしゃべりをすることになっています。この人がカードの実体と言っても過言ではないわけですね。
で、SEの変わりを Android(のアプリ)側が務めましょうというのが HCE なわけです。ネットを見ると ACR122U で HCE をやってみた的な事例はたくさんありますので今回はあえてパソリを使ってみます。
HCE は TypeA を使うそうなので、SDK for NFC を使います。そうすると PC側のソースを載せるのがいかがなものかということになるわけですが、まぁ、SDK のサンプルコードをほぼそのまま使いましたということでその辺はお許しください。
Android側はネットにもたくさん情報あるのでその通りに実装しました。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.hayato.hcetest" > | |
<uses-permission android:name="android.permission.NFC" /> | |
<uses-feature android:name="android.hardware.nfc.hce" /> | |
<application | |
android:allowBackup="true" | |
android:icon="@mipmap/ic_launcher" | |
android:label="@string/app_name" | |
android:supportsRtl="true" | |
android:theme="@style/AppTheme" > | |
<service | |
android:name=".HCETestService" | |
android:enabled="true" | |
android:exported="true" | |
android:permission="android.permission.BIND_NFC_SERVICE"> | |
<intent-filter> | |
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/> | |
<category android:name="android.intent.category.DEFAULT" /> | |
</intent-filter> | |
<meta-data android:name="android.nfc.cardemulation.host_apdu_service" | |
android:resource="@xml/apduservice"/> | |
</service> | |
</application> | |
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" | |
android:description="@string/servicedesc" | |
android:requireDeviceUnlock="false"> | |
<aid-group android:description="@string/aiddescription" | |
android:category="other"> | |
<aid-filter android:name="F0010203040506"/> | |
</aid-group> | |
</host-apdu-service> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.hayato.hcetest; | |
import android.nfc.cardemulation.HostApduService; | |
import android.os.Bundle; | |
import java.util.Calendar; | |
public class HCETestService extends HostApduService { | |
public HCETestService() { | |
} | |
@Override | |
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) { | |
// SELECT のときは 90 00 を返す | |
if (commandApdu[1] == (byte)0xA4) | |
return new byte[] { (byte)0x90, 0x00 }; | |
Calendar cal = Calendar.getInstance(); | |
return new byte[] { (byte)cal.get(Calendar.HOUR_OF_DAY), (byte)cal.get(Calendar.MINUTE), (byte)cal.get(Calendar.SECOND), (byte)0x90, 0x00 }; | |
} | |
@Override | |
public void onDeactivated(int reason) { | |
} | |
} |
具体的には
■PC -> パソリ -> HCE
SELECTコマンド
0x00 0xA4 0x04 0x00 0x07 0xF0 0x01 0x02 0x03 0x04 0x05 0x06
(AID:アプリケーションIDが F0010203040506 のやつを選択という意味です。AIDは上記の apduserveice.xml 内に定義してます。これにより動作させるアプリを選択させるわけです)
■HCE -> パソリ -> PC
OK(0x90 0x00)
■PC -> パソリ -> HCE
独自コマンド
0x01 0x02 0x03
■HCE -> パソリ -> PC
時、分、秒+OK (hour minute second 0x90 0x00)
というコマンドの流れです。
これで双方を実行してパソリにAndroid端末をかざすと...
きました! 16進数表記になってますが、時、分、秒が返ってきました。
ちなみにスリープ状態でも読めるか試しましたがダメでした。
ロック画面では読めました。通常のリーダーモードよりは緩い感じですねー。
0 件のコメント:
コメントを投稿