実は・・・今週のHCE記事だが、日曜日に書きためたものを4日に分けてスケジュール投稿する、ということをしてみた。
5日目の今日は、12/18の2時半くらいに書いている。
目がしょぼしょぼだ・・・。
さて、4回目では、Windows8.1 + PaSoRi RC-S380を使って、Type4のまねをしているNexus7のHCE動作を見てもらおうとしたが失敗したところであった。
何がいかんかというと、よくわからんバイナリを受信して、よくわからんバイナリを返している、という部分だ。
バイナリデータがある限り、我々は解析をしなくてはならない。
ましてや、NFC HACKSという本があるのに、解析しないでいることができようか(いや、解析せずにはいられない)?
そんなわけで、HACK#17「NFC Forum Type 4 Tag」を開いた。
ふむ、よく聞く「T=CL」というのは通称だったんだ、とか、EFファイルってSIMカードの構造もそうだったよな、などと思い返しつつ読んでいると、まねしようとしていたNDEFメッセージの読み込みシーケンスがそのまま書いてあった。
ふむふむ、スライドに書かれているバイナリ値は、直接やりとりしている値ではなく、意味があるところだけ抜き出しているのだな。
ならば、そのまま送るだけではダメなのは当然だ。
プログラムはスライドを参考に、データはNFC HACKSを参考にして、こんなプログラムにした。
(これはこれで省略もあるがね。)
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.util.Log;
public class HostSampleService extends HostApduService {
static enum CardStatus {
INIT,
CCFILE,
REQ_DATA,
OPEN,
LEN,
RET_DATA
}
final static byte[] SUCCESS = { (byte)0x90, (byte)0x00 };
final static byte[] REQ_DATA = {
(byte)0x00, (byte)0x0f, //CCLEN
(byte)0x20, //Mapping Version
(byte)0x00, (byte)0x40, //MLe
(byte)0x00, (byte)0x40, //MLc
//TLV(NDEF File Control)
(byte)0x04, //Tag
(byte)0x06, //LEN
(byte)0xe1, (byte)0x04, //signature
(byte)0x00, (byte)0x32, //max ndef size
(byte)0x00, //read access permission
(byte)0x00, //write access permission
//success
(byte)0x90, (byte)0x00
};
final static byte[] LEN = { (byte)0x00, (byte)0x03 };
final static byte[] RET_DATA = {
(byte)0x00, (byte)0x03, //LEN
//message
(byte)0xd0, (byte)0x00, (byte)0x00, //empty
//success
(byte)0x90, (byte)0x00
};
private final static String TAG = "HostSampleService";
private CardStatus mCardStatus = CardStatus.INIT;
@Override
public void onDeactivated(int reason) {
mCardStatus = CardStatus.INIT;
}
@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
for (int i = 0; i < commandApdu.length; i++) {
Log.d(TAG, Integer.toHexString(commandApdu[i] & 0xff));
}
switch (mCardStatus) {
case INIT:
Log.d(TAG, "init");
mCardStatus = CardStatus.CCFILE;
return SUCCESS;
case CCFILE:
Log.d(TAG, "ccfile");
mCardStatus = CardStatus.REQ_DATA;
return SUCCESS;
case REQ_DATA:
Log.d(TAG, "reqdata");
mCardStatus = CardStatus.OPEN;
return REQ_DATA;
case OPEN:
Log.d(TAG, "open");
mCardStatus = CardStatus.LEN;
return SUCCESS;
case LEN:
Log.d(TAG, "len");
mCardStatus = CardStatus.RET_DATA;
return LEN;
case RET_DATA:
Log.d(TAG, "retdata");
mCardStatus = CardStatus.INIT;
return RET_DATA;
default:
return SUCCESS;
}
}
}
これをNexus7に焼いて、PaSoRiに近づけると、Windows8.1からあのNDEFタグ検知したときに聞こえるあの音がしているではないか!
NDEFの中身がEmptyなので動作はしないけれども、ここにURIとか書いておけばトースト表示してくれるんじゃないだろうか。
興味はあるが、今回はやめておこう。
もっと気力があるときにやらないとな。