2013/12/19

[nfc]HCEの動作確認をしたい (5)

実は・・・今週の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とか書いておけばトースト表示してくれるんじゃないだろうか。
興味はあるが、今回はやめておこう。
もっと気力があるときにやらないとな。

0 件のコメント:

コメントを投稿

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

注: コメントを投稿できるのは、このブログのメンバーだけです。