2016/09/17

[android]HCE-Fのソースを少しだけ見る

HCE-F記事のアクセス件数が多いと思ったら、紹介してもらっていた。
ありがたや。

Android 7.0のNFC HCE-Fの実装について – Qiita

 

HCE-F自体は、2年くらい前からSonyの人かFeliCaNetworksの人が発表していた。
Host Card Emulation、の略でHCEで、それのNFC-F版というかFeliCa版だから、HCE-F。

私が「HCE」という単語を見たのはAndroidが最初だが、私がやっていたカードエミュレーションもジャンルとしてはHCEになる。

カードエミュレーションは「エミュレーション」なので、NFCカード以外が行うことになる。
前回の話と重複するが、NFCチップはだいたい3つに分けられる。

  1. NFCカード用のチップ
  2. NFC R/W用のチップ
  3. NFCカードエミュレーション用のチップ

1番は、普通のカードに載るタイプだ。
nimocaやSuica、NTAG203なんかもそうで、カード側にしかならない。

2番は、R/Wに載るタイプだ。
PaSoRiのようなカードリーダで使うことになる。
基本的にR/Wでの用途になるのだけど、だいたいカードエミュレーションする命令も持っていて、カードになることができる。
私がやっていたのは、これだ。
ホスト側がないと、何もできない。

3番は、携帯電話に載るタイプだ。
PN544やモバイルFeliCaチップがそれにあたる。
基本的にカードエミュレーションするようにできていて、ホスト=本体側のCPUがなくても必要な機器に電源が入っていれば自律して動くことができる・・・と思う。

 

1番目はよく売られているし、2番目も売られているけど、3番目は一般にはほぼ出回らないと思っている。
下手に出回って悪用されると、カードのふりをすることができるから、ひどいことになるからだ。
まあ、2番目のでもカードエミュレーションできるから何かできるのかもしれないが、秘密の情報を保持するセキュアエレメントにアクセスできないのだと思う。

セキュアエレメントって、それこそNFCの信用に関する生命線なので、私のような一般人にはさっぱり何だかわからないのだ。
だから、ここら辺で書いているものも、私の推測が多い。
詳しい人が見たら「ふふん」と思われそうだけど、まあいいや。


紹介記事にあったソースファイルを見ると、nfa_dm_act.cの144行目あたりに差分がある。
「T3T」は、NFC Forumの「Type 3 Tag」の略で、まあFeliCaを指すと思ってもらえばよい。
LF_T3T_IDENTIFIERS_1~16とあり、これは「Listen Mode NFC-F Discovery Parameters」のことだ。
Listen Modeは、搬送波を生成しない側なので、カード側だ。
NCI v1.1ドキュメントでは、Page 59(PDFのp.69)の表に載っている。

0-1 : System Code
2-9 : NFCID2
10-17 : (optional) PMm

まあ、このコードは初期値の設定なので、あまり意味は無い。

 

実際に使う値は、たとえばnfa_dm_cfg.cの差分になるだろう。
ce_t3t.cの差分も同じようなものだ。
2つ数字が変わっているが、これはコメントによるとPAD0らしい。
PAD0は、いわゆるPMmのICコードに当たる。

PMmについては、Sonyの技術資料を読むとよい。
Sony Japan | FeliCa | 法人のお客様 | ダウンロード
この中の「FeliCa技術方式の各種コードについて」に書かれている(数字の意味は書かれていないが)。

PAD0という名称は、NFC ForumのDigitalProtocolで使われている。
こっちはこっちで定義がないのだが、0xFFFFはNFC-DEPするデバイス用として割り当てられている。

 

値くらいだったら見るのは簡単だと思ったけど、そもそも値はAPIから与えられるので、見ていってもあまり面白くないか。。。


NfcFCardEmulationクラスのAPIを見ると、NFCID2(IDm)とSystemコードは設定できそうだ。
Serviceコードもできるのかな?
あるいは、そこから自分で実装するのか。

Systemコードはドライブに、Serviceコードはフォルダに相当する。
Sonyの技術資料にもそういう説明があったような気がするが、見つけられなかった。

だいたいのFeliCaではSystemコードが0xFE00がデフォルトになっているけど、Suicaなどのサイバネ系は0x0003を使っている。
ポーリングするコマンド(NFC ForumのDigitalProtocolでいう、SENSF_REQ)でもSystemコードを指定するが、ワイルドカードの0xFFFFを指定するとデフォルトのSystemコードが反応する。
Suica側を見たかったら、Systemコードをちゃんと指定しないと出てこない。
まあ、これはFeliCa LiteをNDEF対応したときも同じ話だ。

 

以前、HCEで訳もわからず作ったときは、HostApduServiceクラスをextensしたクラスにprocessCommandApdu()の中身を実装した。
それに相当するのは、HostNfcFServiceクラスだろう。

processCommandApdu()に相当するのはprocessNfcFPacket()か。
PCD側に値を返すときはreturnで返すところも同じだ。

APDUの場合は、引数のデータはCLAから入っていた。
NFC-Fにはそういう形式はないので、サブコマンドコード(Check=0x06、Update=0x08など)から渡されて、返す値もサブレスポンスコード(Check Res=0x07、Update Res=0x09)などとなるのだろうか。

だったら、NDEFくらいだったら簡単そうだ。


ただ。。。うちには試せる環境が無いので、確かめられない。

これをうまいこと使えて、しかもNCIがデータをチェックせずに送受信できるのであれば、実在しないFeliCaコマンドを作ることができるかもしれない。
どうなんだろう、さすがにチップ側でチェックするのかなぁ。
くぅ、だんだん試したくなってきた。。。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。