NFC 機能を提供する Android 搭載デバイスの多くは、すでに NFC カード エミュレーションをサポートしています。ほとんどの場合、カードはデバイス内のセキュア エレメントと呼ばれる別のチップによってエミュレートされます。携帯通信会社が提供する SIM カードの多くにもセキュア エレメントが含まれています。
Android 4.4 で、ホストベースのカード エミュレーションと呼ばれる、セキュア エレメントを必要としない新たなカード エミュレーションの方式が導入されました。この機能により、あらゆる Android アプリがカードをエミュレートして、NFC リーダーと直接通信できます。このドキュメントでは、Android でのホストベースのカード エミュレーション(HCE)の仕組みと、この手法を使用して NFC カードをエミュレートするアプリの開発方法について説明します。
セキュア エレメントを使用したカード エミュレーション
セキュア エレメントを使用して NFC カード エミュレーションが提供される場合、エミュレートされるカードは、Android アプリを通じてデバイス上のセキュア エレメントにプロビジョニングされます。ユーザーがデバイスを NFC 端末にかざすと、デバイス内の NFC コントローラが、リーダーからのデータをすべてセキュア エレメントに直接転送します。図 1 にこのコンセプトを示します。

図 1. セキュア エレメントを使用した NFC カード エミュレーション
セキュア エレメント自体が NFC 端末との通信を実行し、Android アプリはトランザクションに一切関与しません。トランザクションが完了した後、Android アプリはセキュア エレメントにトランザクションのステータスを直接クエリして、ユーザーに通知できます。
ホストベースのカード エミュレーション
ホストベースのカード エミュレーションを使用して NFC カードをエミュレートする場合、NFC プロトコル フレームをセキュア エレメントに転送するのではなく、Android アプリが実行されているホスト CPU にデータが転送されます。図 2 は、ホストベースのカード エミュレーションの仕組みを示しています。

図 2. セキュア エレメントを使用しない NFC カード エミュレーション
サポートされている NFC カードとプロトコル

図 3. Android の HCE プロトコル スタック
NFC 規格は数多くのプロトコルをサポートしており、エミュレートできるカードの種類もさまざまです。
Android 4.4 は、今日の市場で一般的に使用されている複数のプロトコルをサポートしています。非接触型決済カードなどの既存の非接触型カードの多くが、すでにこうしたプロトコルに基づいています。また、それ自体がリーダーとして動作する Android NFC デバイスを含む、今日の市場の数多くの NFC リーダーでも、こうしたプロトコルがサポートされています(IsoDep
クラスを参照)。これにより、Android 搭載デバイスのみを使用して、HCE に基づくエンドツーエンドの NFC ソリューションを構築してデプロイできます。
具体的には、Android 4.4 では、NFC フォーラムの ISO-DEP 仕様(ISO/IEC 14443-4 をベースとする)に基づく、ISO/IEC 7816-4 仕様の定義に従って Application Protocol Data Units(APDU)を処理するカードのエミュレートをサポートしています。Android が必須としているのは、NFC-A(ISO/IEC 14443-3 Type A)テクノロジーでの ISO-DEP のエミュレートのみです。NFC-B(ISO/IEC 14443-4 Type B)テクノロジーのサポートはオプションです。これらすべての仕様のレイヤを図 3 に示しています。
HCE サービス
Android の HCE アーキテクチャは、「HCE サービス」と呼ばれる Android Service
コンポーネントに基づいています。サービスの主な利点の 1 つは、一切のユーザー インターフェースを持たずにバックグラウンドで動作できることです。これは、ポイントカードや交通系カードといった、利用時にユーザーにアプリの起動を求めるべきでない数多くの HCE アプリに特に適しています。デバイスを NFC リーダーにかざすと、適切なサービスが(まだ動作していない場合は)起動して、バックグラウンドでトランザクションを実行します。必要であれば、そうしたサービスから追加の UI(ユーザーへの通知など)を表示することもできます。
サービスの選択
ユーザーがデバイスを NFC リーダーにかざしたときに、Android システムは、その NFC リーダーが実際に通信する必要のある HCE サービスを識別する必要があります。ここで ISO/IEC 7816-4 仕様が役立ちます。この仕様はアプリ ID(AID)を中心としてアプリを選択する方法を定義しています。AID は最大 16 バイトで構成されます。既存の NFC リーダー インフラストラクチャ向けのカードをエミュレートする場合、そうしたリーダーが予期する AID は通常、パブリックに登録されているよく知られた AID(例: Visa や MasterCard などの決済ネットワークの AID)です。
デベロッパーが自身のアプリ用に新たなリーダー インフラストラクチャをデプロイする場合は、独自の AID を登録する必要があります。AID の登録手順は、ISO/IEC 7816-5 仕様で定義されています。Android 用 HCE アプリをデプロイする場合は、他のアプリとの競合を回避するために、7816-5 に従って AID を登録することをおすすめします。
AID グループ
一部のケースにおいて、特定のアプリを実装するために 1 つの HCE サービスで複数の AID を登録することが必要な場合があります。そのようなサービスは、グループ内の AID が別のサービスに処理されることのないよう、自身をそうした複数の AID すべてのデフォルトのハンドラにする必要があります。
AID グループとは、OS で同じグループに属するとみなす必要のある AID のリストです。AID グループ内のすべての AID に対して、Android は次のいずれかを保証します。
- グループ内のすべての AID がこの HCE サービスにルーティングされる
- グループ内のどの AID もこの HCE サービスにルーティングされない(たとえば、別のサービスでもそのグループ内の AID を 1 つ以上リクエストしており、ユーザーがそちらのサービスを優先している場合)
つまり、グループ内の AID の一部が異なる複数の HCE サービスにルーティングされる可能性がある、といった中間的な状態は存在しません。
AID グループとカテゴリ
各 AID グループはカテゴリに関連付けることができます。これにより Android が HCE サービスをカテゴリ別にグループ化することができ、それによって、ユーザーが AID レベルではなくカテゴリ レベルでデフォルトを設定できます。通常、AID は一般のユーザーには無関係のため、アプリ内のユーザー向けの部分では AID を表示しないでください。
Android 4.4 では、CATEGORY_PAYMENT
(業界標準の決済アプリをカバー)と CATEGORY_OTHER
(その他すべての HCE アプリ向け)の 2 つのカテゴリをサポートしています。
注: システム内で同時に有効にできる CATEGORY_PAYMENT
カテゴリ内の AID グループは 1 つのみです。通常これは、主要なクレジット カード決済プロトコルを認識し、どの販売者でも機能するアプリになります。
特定の販売者でのみ機能するクローズド ループの決済アプリ(プリペイド カードなど)の場合は、CATEGORY_OTHER
を使用する必要があります。このカテゴリの AID グループは常にアクティブにできるほか、必要であれば AID の選択時に NFC リーダーで優先されるようにすることができます。
HCE サービスの実装
ホストベースのカード エミュレーションを使用して NFC カードをエミュレートするには、NFC トランザクションを処理する Service
コンポーネントを作成する必要があります。
HCE をサポートしているかどうかを確認する
デバイスが HCE をサポートしているかどうかは、アプリで FEATURE_NFC_HOST_CARD_EMULATION
機能を確認することによって確認できます。アプリのマニフェストで <uses-feature>
タグを使用して、アプリが HCE 機能を使用すること、また、アプリを動作させるためにその機能が必要かどうかを宣言する必要があります。
サービスの実装
Android 4.4 の Service
クラスには、HCE サービスを実装するためのベースとして使用できる HostApduService
クラスが用意されています。
したがって、最初の手順は HostApduService
の拡張です。
Kotlin
class MyHostApduService : HostApduService() { override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray { ... } override fun onDeactivated(reason: Int) { ... } }
Java
public class MyHostApduService extends HostApduService { @Override public byte[] processCommandApdu(byte[] apdu, Bundle extras) { ... } @Override public void onDeactivated(int reason) { ... } }
HostApduService
は、オーバーライドと実装が必要な 2 つの抽象メソッドを宣言します。
NFC リーダーからサービスに APDU が送信されるたびに processCommandApdu()
が呼び出されます。APDU は ISO/IEC 7816-4 仕様でも定義されています。APDU は、NFC リーダーと HCE サービスとの間で交換されるアプリケーションレベルのパケットです。このアプリケーションレベルのプロトコルは半二重です。NFC リーダーはコマンド APDU を送信し、応答 APDU が返信されるまで待機します。
注: ISO/IEC 7816-4 仕様では、独立した複数の論理チャンネル上で並行して複数の APDU の交換ができる、複数の論理チャンネルのコンセプトも定義されています。しかし、Android の HCE の実装では単一の論理チャンネルのみをサポートしているため、単一スレッドの APDU の交換が 1 つのみ存在します。
前述のとおり、Android では、リーダーが通信をリクエストしている HCE サービスを、AID を使用して特定します。通常、NFC リーダーがデバイスに送信する最初の APDU は「SELECT AID」という APDU です。この APDU には、リーダーが通信をリクエストしている AID が含まれています。Android は APDU からその AID を抽出し、HCE サービスを解決して、そのサービスに APDU を転送します。
processCommandApdu()
から応答 APDU のバイトを返すことで、応答 APDU を送信できます。このメソッドはアプリのメインスレッドで呼び出されますが、メインスレッドのブロックは避ける必要があります。そのため、応答 APDU をすぐに生成して返すことができない場合は null を返します。その後、必要な作業を別のスレッド上で実行し、作業が完了したら HostApduService
クラスに定義されている sendResponseApdu()
メソッドを使用して応答を送信します。
Android は次のいずれかの状態になるまで、リーダーからの新しい APDU をサービスに転送し続けます。
- NFC リーダーが別の「SELECT AID」APDU を送信し、OS によってその AID が別のサービスに解決される。
- NFC リーダーとデバイスとの間の NFC リンクが切断される。
いずれの場合も、クラスの onDeactivated()
の実装が、上記 2 つの状態のどちらが発生したかを示す引数を指定して呼び出されます。
既存のリーダー インフラストラクチャと連携する場合は、リーダーの予期する既存のアプリケーションレベルのプロトコルを HCE サービスに実装する必要があります。
自身で管理する新しいリーダー インフラストラクチャをデプロイする場合は、独自のプロトコルと APDU シーケンスを定義できます。通常は、交換する必要のある APDU の量とデータのサイズをできるだけ抑えてください。そうすることで、ユーザーがデバイスを NFC リーダーにかざす時間が短時間で済むようになります。妥当なデータの上限値は約 1 KB です。このサイズなら通常 300 ミリ秒以内でデータを交換できます。
マニフェストでのサービスの宣言と AID の登録
サービスは通常どおりマニフェストで宣言する必要がありますが、サービスの宣言にいくつかの項目を追加する必要があります。
まず、HostApduService
インターフェースを実装する HCE サービスであることをプラットフォームに伝えるために、サービスの宣言に SERVICE_INTERFACE
アクションのインテント フィルタを含める必要があります。
さらに、このサービスがリクエストする AID グループをプラットフォームに伝えるために、HCE サービスに関する追加情報を含んだ XML リソースを指定する SERVICE_META_DATA
<meta-data>
タグをサービスの宣言に含める必要があります。
最後に、サービスの宣言内で android:exported
属性を true に設定し、"android.permission.BIND_NFC_SERVICE"
権限を要求する必要があります。前者の属性が、外部アプリによるサービスのバインドを可能にします。その後、後者の権限によって、"android.permission.BIND_NFC_SERVICE"
権限を持つ外部アプリのみがサービスにバインドできるように強制します。"android.permission.BIND_NFC_SERVICE"
はシステム権限であるため、これによって、サービスにバインドできるのは事実上 Android OS だけになります。
HostApduService
のマニフェスト宣言の例を次に示します。
<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"/> </service>
この meta-data タグでは apduservice.xml
ファイルを指定します。そのようなファイルで、2 つの独自 AID を含んだ単一の AID グループの宣言の記述例を次に示します。
<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-filter android:name="F0394148148100"/> </aid-group> </host-apdu-service>
<host-apdu-service>
タグには <android:description>
属性を含める必要があります。この属性には、サービスの説明を、UI での表示に適したユーザー向けのわかりやすい形で指定します。requireDeviceUnlock
属性を使用すると、このサービスを呼び出して APDU を処理するにはデバイスのロック解除を必須とするように指定できます。
<host-apdu-service>
には <aid-group>
タグを含める必要があります。各 <aid-group>
タグでは、以下のようにする必要があります。
android:description
属性を含めます。この属性には、AID グループの説明を、UI での表示に適したユーザー向けのわかりやすい形で指定します。android:category
属性を設定して、その AID グループが属するカテゴリを示します(例:CATEGORY_PAYMENT
またはCATEGORY_OTHER
で定義される文字列定数)。- 各
<aid-group>
には、それぞれ 1 つの AID を含んでいる<aid-filter>
タグを 1 つ以上含める必要があります。AID は 16 進数形式で指定し、偶数個の文字を含める必要があります。
最後の注意事項として、自身を HCE サービスとして登録できるように、アプリが NFC
権限を保持していることも必要です。
AID の競合の解決
複数の HostApduService
コンポーネントが 1 台のデバイスにインストールされる場合があり、同じ AID が複数のサービスによって登録される可能性があります。Android プラットフォームは、AID がどのカテゴリに属しているかに応じて AID の競合を解決します。各カテゴリには、それぞれ異なる競合解決ポリシーが定められている場合があります。
たとえば、一部のカテゴリ(決済など)では、ユーザーが Android の設定 UI でデフォルトのサービスを選択できる場合があります。その他のカテゴリで、競合の発生時は起動するサービスを常にユーザーに確認するよう、ポリシーで定められている場合もあります。特定のカテゴリの競合解決ポリシーをクエリする方法については、getSelectionModeForCategory()
をご覧ください。
サービスがデフォルトかどうかを確認する
アプリでは、自身の HCE サービスが特定のカテゴリのデフォルト サービスかどうかを、isDefaultServiceForCategory(ComponentName, String)
API を使用して確認できます。
デフォルトのサービスではない場合は、デフォルトにするようリクエストできます。ACTION_CHANGE_DEFAULT
をご覧ください。
決済アプリ
Android では、「決済」カテゴリとして AID グループを宣言した HCE サービスを決済アプリとみなします。Android 4.4 には [タップ&ペイ] という上位レベルの [設定] メニュー項目があり、このメニュー項目ではそうした決済アプリがすべて列挙されます。ユーザーはこの設定メニューで、デバイスを支払い端末にかざしたときに呼び出されるデフォルトの決済アプリを選択できます。
決済アプリに必要なアセット
視覚性に優れた魅力的なユーザー エクスペリエンスを提供するため、HCE 決済アプリは、自身のサービスを表す追加のアセット(いわゆるサービスバナー)を提供する必要があります。
このアセットのサイズは 260x96 dp とする必要があり、メタデータ XML ファイル内で <host-apdu-service>
タグにドローアブル リソースを指定した android:apduServiceBanner
属性を追加することで指定できます。以下に例を示します。
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc" android:requireDeviceUnlock="false" android:apduServiceBanner="@drawable/my_banner"> <aid-group android:description="@string/aiddescription" android:category="payment"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </host-apdu-service>
画面オフとロック画面の動作
現在の Android の実装では、デバイスの画面がオフになると NFC コントローラとアプリケーション プロセッサが完全にオフになります。そのため、HCE サービスは画面がオフのときには機能しません。
ただし、HCE サービスをロック画面から機能させることができます。これは HCE サービスの <host-apdu-service>
タグの android:requireDeviceUnlock
属性によって制御されます。デフォルトでは、デバイスのロック解除は不要であり、デバイスがロックされていてもサービスが呼び出されます。
HCE サービスの android:requireDeviceUnlock
属性を「true」に設定した場合、ユーザーがそのサービスへと解決される AID を選択する NFC リーダーにデバイスをかざした際に、デバイスのロック解除を求めるプロンプトが表示されます。ロック解除後、Android によって、トランザクションを完了するためにユーザーにもう一度デバイスをかざすよう求めるダイアログが表示されます。このようにする必要がある理由は、ロック解除のためにユーザーが NFC リーダーからデバイスを離す場合があるためです。
セキュア エレメント カードとの共存
このセクションでは、カード エミュレーションにセキュア エレメントを使用するアプリをデプロイしたデベロッパー向けの内容を記載しています。Android における HCE の実装は、セキュア エレメントの使用を含む他のカード エミュレーションの実装方法と同時に機能するように設計されています。
注: Android では、セキュア エレメント自体と直接通信する API は提供されていません。
この共存は「AID ルーティング」という原則に基づいており、NFC コントローラが、ルーティング ルールを記した(有限の)リストで構成されるルーティング テーブルを保持します。各ルーティングルールには AID と宛先が含まれます。宛先は、Android アプリの稼働しているホスト CPU か、接続されたセキュア エレメントのいずれかです。
NFC リーダーが「SELECT AID」の APDU を送信すると、NFC コントローラはその APDU を解析して、AID がルーティング テーブル内にある AID と一致するかどうかを確認します。一致する場合、その APDU と後続の APDU はすべて、一致した AID に関連付けられている宛先に送信されます。この送信は、別の「SELECT AID」の APDU が受信されるか NFC リンクが切断されるまで続きます。
注: ISO/IEC 7816-4 では「部分一致」のコンセプトも定義されていますが、現在のところ Android HCE デバイスではサポートされていません。
このアーキテクチャを図 4 に示します。

図 4. セキュア エレメントとホストカード エミュレーションの両方で動作する Android
通常、NFC コントローラは APDU のデフォルト ルートも含んでいます。ルーティング テーブルに AID が見つからない場合は、デフォルト ルートが使用されます。この設定はデバイスによって異なる場合がありますが、Android デバイスは、アプリによって登録された AID がホストに正しく転送されるよう保証することが要求されています。
HCE サービスを実装する Android アプリやセキュア エレメントを使用する Android アプリが、ルーティング テーブルの設定について心配する必要はありません。設定は Android 側で自動的に処理されます。Android 側で認識する必要がある情報は、どの AID を HCE サービスで処理でき、どの AID をセキュア エレメントで処理できるかということだけです。どのサービスがインストールされていて、ユーザーがどのサービスを優先するよう設定しているかに基づいて、ルーティング テーブルが自動的に設定されます。
HCE サービスの AID を宣言する方法については、すでに説明しました。次のセクションでは、カード エミュレーションにセキュア エレメントを使用するアプリの AID を宣言する方法について説明します。
セキュア エレメントの AID の登録
カード エミュレーションにセキュア エレメントを使用するアプリは、マニフェストでいわゆる「オフホストサービス」を宣言できます。そのようなサービスの宣言は、HCE サービスの宣言とほぼ同じです。例外は次のとおりです。
- インテント フィルタで使用するアクションを
SERVICE_INTERFACE
に設定する必要があります。 - meta-data タグの name 属性を
SERVICE_META_DATA
に設定する必要があります。 メタデータの XML ファイルでは、
<offhost-apdu-service>
ルートタグを使用する必要があります。<service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> <intent-filter> <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/> </intent-filter> <meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/> </service>
対応する apduservice.xml
ファイルでの 2 つの AID の登録の例を次に示します。
<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc"> <aid-group android:description="@string/subscription" android:category="other"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </offhost-apdu-service>
android:requireDeviceUnlock
属性はオフホスト サービスには適用されません。これは、ホスト CPU がトランザクションに関与しないので、デバイスがロック状態のときにセキュア エレメントによるトランザクションの実行を防げないためです。
デフォルトの決済アプリとして選択可能にするために、決済アプリのオフホスト サービスにも android:apduServiceBanner
属性を使用する必要があります。
オフホスト サービスの起動
Android 自体が、「オフホスト」と宣言されたサービスを開始またはバインドすることはありません。これは、実際のトランザクションが Android サービス自体ではなく、セキュア エレメントによって実行されるためです。サービスの宣言は、単にセキュア エレメント上にある AID の登録をアプリに許可しているだけです。
HCE とセキュリティ
HCE アーキテクチャ自体がセキュリティの中核部分の 1 つを提供します。サービスは BIND_NFC_SERVICE
システム権限によって保護されているため、OS のみがサービスにバインドして通信できます。これにより、受信する APDU は実際に OS が NFC コントローラから受信した APDU であること、および、返信する APDU はすべて OS にのみ送信され、OS から NFC コントローラに APDU が直接転送されることが保証されます。
残りの中核部分は、アプリから NFC リーダーへと送信されるデータを取得する部分です。HCE の設計ではこの部分が意図的に分離されています。HCE はデータがどこから送られてきたかに関係なく、単にデータを安全に NFC コントローラに転送して NFC リーダーに送るという作業を確実に処理します。
HCE サービスで送信するデータを安全に保管、取得するために、たとえば Android アプリ サンドボックスを利用できます。Android アプリ サンドボックスでは、自身のアプリのデータが他のアプリのデータから分離されます。Android のセキュリティについて詳しくは、セキュリティに関するヒントをご覧ください。
プロトコル パラメータと詳細
このセクションでは、NFC プロトコルの衝突防止フェーズと有効化フェーズで HCE デバイスが使用するプロトコル パラメータに関心のあるデベロッパー向けの内容を記載しています。このセクションを利用して、Android HCE デバイスと互換性のあるリーダー インフラストラクチャを構築できます。
NFC-A(ISO/IEC 14443 Type A)プロトコルの衝突防止と有効化
NFC-A プロトコルの有効化の一環として、複数のフレームが交換されます。
交換の最初の部分で、HCE デバイスが UID を提示します。HCE デバイスはランダムな UID を持つと想定する必要があります。つまり、デバイスをリーダーにかざすたびに、リーダーに提示される UID はランダムに生成された UID となります。このため、NFC リーダーは、認証や識別の方法として HCE デバイスの UID に依存すべきではありません。
その後、NFC リーダーは SEL_REQ コマンドを送信して HCE デバイスを選択できます。HCE デバイスの SEL_RES 応答では、少なくともビット 6(0x20)を設定して、デバイスが ISO-DEP をサポートしていることを示す必要があります。SEL_RES 内の他のビットも設定して、たとえば NFC-DEP(p2p)プロトコルのサポートを示すこともできます。他のビットが設定されている可能性があるため、HCE デバイスと通信するリーダーでは
ISO-DEP の有効化
NFC-A プロトコルがアクティブになると、NFC リーダーによって ISO-DEP プロトコルの有効化が開始されます。NFC リーダーは「RATS」(Request for Answer To Select)コマンドを送信します。RATS の応答である ATS は HCE サービスで設定することはできず、完全に NFC コントローラによって生成されます。ただし、HCE の実装では ATS 応答に関する NFC フォーラムの要件を満たしている必要があるため、NFC リーダーは、あらゆる HFC デバイスでこうしたパラメータが NFC フォーラムの要件に沿って設定されていると当てにすることができます。
以下のセクションで、HCE デバイス上の NFC コントローラが提供する ATS 応答の個別のバイトについて詳しく説明します。
- TL: ATS 応答の長さ。20 バイトを超える長さを示すことはできません。
- T0: すべての HCE デバイスでビット 5、6、7 を設定して、ATS 応答に TA(1)、TB(1)、TC(1)が含まれていることを示す必要があります。ビット 1〜4 は FSCI を示し、最大フレームサイズを符号化します。HCE デバイスでは、FSCI の値は 0h~8h の間に設定する必要があります。
- T(A)1: リーダーとエミュレータとの間のビットレート、および非対称にできるかどうかを定義します。HCE デバイスに対するビットレートの要件または保証はありません。
- T(B)1: ビット 1~4 は、開始フレーム保護時間整数値(SFGI)を示します。HCE デバイスでは、SFGI は 8h 以下にする必要があります。ビット 5~8 はフレーム待ち時間整数値(FWI)を示し、フレーム待ち時間(FWT)を符号化します。HCE デバイスでは、FWI は 8h 以下にする必要があります。
- T(C)1: ビット 5 は、「高度なプロトコル機能」のサポート状況を示します。HCE デバイスでは「高度なプロトコル機能」をサポートしている場合と、サポートしていない場合とがあります。ビット 2 は、DID のサポート状況を示します。HCE デバイスでは DID をサポートしている場合と、サポートしていない場合とがあります。ビット 1 は、NAD のサポート状況を示します。HCE デバイスでは NAD をサポートしてはならないため、ビット 1 はゼロに設定してください。
- ヒストリカル バイト: HCE デバイスは、最大 15 バイトのヒストリカル バイトを返すことがあります。HFC サービスと通信する NFC リーダーは、ヒストリカル バイトの内容やその存在について一切想定しないようにする必要があります。
HCE デバイスの多くは、EMVCo を構成する決済ネットワークが「Contactless Communication Protocol」仕様で定めているプロトコルの要件に準拠していると考えられます。具体的には、次のとおりです。
- T0 の FSCI は 2h~8h の間でなければならない。
- T(A)1 は 0x80 に設定して、106 kbps のビットレートのみがサポートされていること、リーダーとエミュレータとの間で非対称のビットレートはサポートされていないことを示す必要がある。
- T(B)1 の FWI は 7h 以下である必要がある。
APDU データの交換
前述のように、HCE の実装では単一の論理チャンネルのみをサポートしています。別の論理チャンネル上でアプリを選択しようとしても、HCE デバイスでは機能しません。