Android Application Award 2010-11 Winter

先日、Android Application Award 2010-11 Winterの受賞/表彰式が開催された。
Android Application Award 2010-11 Winter
Android Application Award 2010-11 Winter結果発表 - ニュース:ITpro

この中で優秀賞に選ばれた「串かつ/Team串かつ」は、私がリリースした「nfc-FeliCa」の一部(AndroidNFC機能からFeliCaデバイスにコマンドをたたく部分)を内部で使用している。
nfc-felica - android 2.3 nfc access felica command - Google Project Hosting

  • 串かつの概要

インテントをFeliCa Push送信に変換するミドルウエアアプリ。「リモートインテント」「ブラウザ起動 」「メーラー起動」の3種類のFeliCa Pushメッセージに対応する。NFCの機能を使い、auの「IS03」などのFeliCa対応端末に対してFeliCa Push送信も行える。

自分の書いたライブラリィが内部で使われているということだけで、なにかこう嬉しいものだ。

おめでとう!! Team串かつ!!

nfc-felica-lib アップデート

各種バグFIXを行いました。 (thanks @zaki50!)
前回お約束したとおり、今回の修正により2.3.3系をtrunk/masterとしました。
2.3.2系はbranchとして暫く残しますが、今後保守はしない予定です。

変更点

nfc-felica-lib

・ CommandPacketクラスでコマンド長が127バイトを超えた際に例外が発生するバグをFIXしました
・ 同クラスにおいてコマンド長が255バイトを超えた場合は例外をスローするように修正しました


ソースコードは以下のリポジトリよりダウンロードできます。
nfc-felica - Google Project Hosting
nfc-felica - github social coding

nfc-felica アップデート(サンプルアプリ)

nfc-felica - android 2.3 nfc access felica command

前回はライブラリィのみでしたが、今回はアプリケーション側のアップデートを行いました。

nfc-felica

android 2.3.3用のブランチを作成しました。(githubにも同期しました。(https://github.com/Kazzz/nfc-felica/tree/2.3.3)
・ サンプルアプリケーション(NfcFeliCaReader)がandroid 2.3.3 API Level 10に対応しました
nfc foreground dispatchを有効にしました
・ それぞれの処理をAsynchTaskにカプセル化しました
・ 処理中にProgressDialogを表示するようにしました


なお、次回のアップデート時には2.3.3ブランチをマージして一本化、以前のバージョンは廃止する予定です。

nfc-felica アップデート

nfc-felicaをアップデートしました。
nfc-felica - android 2.3 nfc access felica command

主な変更は以下の通りです。

nfc-felica-lib
    • android 2.3.3のOTA開始に合わせて、2.3.3用のブランチを作成しました。(android 2.3.2以前ではコンパイルできません)
    • android.nfc.Tagクラスから@hideが取れてFeliCaはNfcFクラスで直接扱うことができるようになりました。結果リフレクションが不要になったのでNfcWrapperは除去しました。
    • FeliCaTag、FeliCaTagクラス内部のnfcTagフィールドの型をandroid.nfc.Tagクラスに変更しました

リポジトリは以下のURLからダウンロードできます。

  https://nfc-felica.googlecode.com/svn/nfc-felica/branches/nfc-felica-lib-2.3.3/

    • github

  https://github.com/Kazzz/nfc-felica-lib/tree/2.3.3


なお、nfc-felicaプロジェクトに関しては変更はありません。依存ライブラリィnfc-felica-libを差し替えることでAndroid2.3.2以前と2.3.3を切り替えることができます。

FeliCa Liteの適性

FeliCaFeliCa Liteのプロトコルをひと通り実装したが、FeliCaに比べてFeliCa Liteは劣っているということではなく、用途で使い分けるべきものだと言うことが判る。

FeliCaFeliCa Liteの違い
      FeliCa FeliCa Lite
コマンド Polling, Request Service, Request Response, Read Without Encryption, Write Without Encryption, Request System Code, Autentication1, Authentication2, Read, Write Polling, Read Without Encryption, Write Without Encryption
ファイルシステム エリア/サービス/ブロックの論理階層構造 エリアは無くサービスは固定、ブロックのみ
サービス種別 ランダム、サイクリック、パース、それぞれにリード/ライト又はリードオンリーアクセス ランダムのみリード/ライト又はリードオンリーアクセス
ユーザ領域(最大サイズ) フォーマットに依存、154ブロック以上、2〜9Kbyte 固定のスクラッチパッド領域、16byt×14ブロック(224バイト)
システム切り替え 有り 無し
セキュリティ Autentication1及びAutentication2コマンドによる相互認証(非公開) MACとIDによる片側認証
コスト フォーマットに依るが@¥1000〜 @¥300程度

この違いを見れば判るように、FeliCa Liteが優れているのはコストとシンプルさである。FeliCaの1/3程度のコスト(IDmしか使わないなら1/4以下)しかかからないため、格納するデータ容量が少なくて構わない(200バイト未満)、そもそもデータの書き込みが不要なケース、データの改ざんをリスクと考えないケースではFeliCaはオーバースペックでありFeliCa Liteの方が向いている。また、ユーザに開放されているデータブロックは固定なのでプログラミングがシンプルで簡単になる。

逆にFeliCaは複数種類のデータをある程度の量格納する、データの改ざんが許されない、データ構造から設計したいようなケースに適している。

前者は各業種で使用される在庫管理、資産管理や社員の勤怠管理等の一般的なサービスに向いていることが判るだろう。後者は言うまでもなくPASMO/SuicaEdy等の複数種類のデータ(施設、お金、時間)と個人情報の絡む複雑なシステムに向いている。

nfc-felica アップデート

nfc-felicaをアップデートしました。
nfc-felica - android 2.3 nfc access felica command

※なお、今回のアップデートに関しては、以前にコメント頂いたちきん(mokemokechicken)さんのコードをいくつか参考にさせて頂きました。
AndroidのNFC機能でFeliCaの読み書きをする (ゆめ技:ゆめみスタッフブログ)
ちきん(mokemokechicken)さん、ありがとうございました。


以下変更点。

nfc-felica
    • NFCFeliCaReader

FeliCa Liteの読みこみ/書き込みに対応しました。
FeliCa Liteのデータの書き込みのため、FeliCaLiteWriterアクティビティを追加しました。

    • FeliCa Liteの読み込み/書き込みの様子

タグ・ディスカバリのインテント処理時にFeliCaFeliCa Liteを自動的に判別します。FeliCa Liteの場合、IDm、PMmの他に、MC(MemoryConfigurationBlock)領域のダンプを行います。


FeliCa Liteで書き込みが可能な場合、「書き込み画面」ボタン押下でこの画面に遷移します。この画面(FeliCaLiteWriter)では、読み書き可能なブロックとして開放されているS_PAD(スクラッチパッド)領域のアクセス属性(R/W又はRO)と、格納されているデータをListViewに表示します。


アクセス属性がR/W(リード/ライト)のブロックに対応した行をタップすると、EditTextビューに現在のデータを表示して編集することができます。16バイト以内のデータを入力して「書きこみ」ボタンを押下することでFeliCa Liteデバイスの選択されているブロックにデータを実際に書き込みます。(UTF-8エンコードするので日本語もOKです)


書きこまれたデータが反映されています。


最初の画面(NFCFeliCaReader)に戻って再読込を行うと、書き換えたデータが読み込まれていることが分かります。(ブロックデータ、という見だしで16進数でダンプされている部分がそうです)


nfc-felica-lib
    • FeliCa仕様とNfc仕様を分離するためnet.kazzz.nfcパッケージを追加しました
    • FeliCaLibクラスからリフレクションを用いているコードをNfcWrapperに分離しました。※
    • FeliCaLibクラスにMemoryConfigurationBlockクラスを追加しました
    • FeliCaクラスをFeliCaTagクラスに変更しました。
    • FeliCaLiteTagクラスを追加しました。(polling、readWithoutEncryption、writeWithoutEncryptionメソッドを実装)
    • FeliCaTagクラス、FeliCaLiteTagクラスのルートとしてNfcTagクラスを追加しました。
    • net.kazzz.felica.commandパッケージに WriteResponseクラスを追加しました。
    • net.kazzz.utilパッケージを追加、IPredicateインタフェース及びFinder等のユーティリティを追加しました
    • その他細かいバグFix
動作確認

ライブラリィの動作確認には以下の機器を使用しています。

  ・ NFCリーダ/ライタ
   Google Nexus S ( android 2.3.2, Build GRH78C)


  ・ FeliCa PICC
   PASMO (自分で使用している定期券)


  ・ FeliCa Lite PICC
   FeliCa Liteカード RC-S886
   FeliCa Liteシール RC-S701


以上です。

android 2.3.3以降、@hideアノテーションが取れてリフレクションが不要になった際に取り除かれることを前提にしています。

追記: git版の同期が完了しました。(https://github.com/Kazzz)

FeliCa Liteデバイスに書き込み成功

ようやくできた。
FeliCa Liteは内部ブロックに読み書きのできる"スクラッチパッド"という名前の領域が確保されており、明示的にリードオンリーに初期化しなければユーザ側で自由に読み書きをすることができる。

ブロック番号 名称 有効バイト数
00h S_PAD0 16
01h S_PAD1 16
02h S_PAD2 16
03h S_PAD3 16
04h S_PAD4 16
05h S_PAD5 16
06h S_PAD6 16
07h S_PAD7 16
08h S_PAD8 16
09h S_PAD9 16
0ah S_PAD10 16
0bh S_PAD11 16
0ch S_PAD12 16
0dh S_PAD13 16

FeliCa/FeliCa Lite/FeliCa Plug 技術情報 - Sony Japan

現在クラス構成を見直しているnfc-felicaではnfcで扱うタグ情報によってクラスを継承階層にわけており、

このようにFeliCaFeliCa Liteのクラスを分割することにした。また、ルートクラスのNfcTagを含めて全てのクラスはインタフェースParcelableを実装しており、サービス間で引き渡すことができるようにしている。

新たなFeliCaLiteTagクラスによるデータのポーリング、リード、ライトは以下のようなコードとなるだろう。

NFCFeliCaReader.javaより
//FeliCa Lite polling
FeliCaLiteTag tag = new FeliCaLiteTag(this.nfcTag);
IDm idm = tag.pollingAndGetIDm();

//read block 0
ReadResponse resp = tag.readWithoutEncryption((byte)0);

//read MemoryConfigurationBlock
MemoryConfigurationBlock mb = tag.getMemoryConfigBlock(); 

//encode charactor (変数"data"に文字列が入っている)
Charset utfEncoding = Charset.forName("UTF-8");
byte[] textBytes = data.toString().getBytes(utfEncoding);

//write data to S_PAD0
WriteResponse result = tag.writeWithoutEncryption((byte)0, textBytes);
if ( result.getStatusFlag1() == 0 ) {
    //正常処理
} 

先日書いたようにFeliCa Liteはシステムコードとサービスコードが固定のため、コードパラメタが少なく、かなりすっきりしたものになるのが判るだろう。

ちなみに、上述したスクラッチパッドエリアのアクセス方法を設定しているMC(メモリコンフィグレーションブロック)をダンプすると以下のようになった。 

全てがRW (リードライト)で初期化されていることが判る。

以上、コードの変更は近いうちにリポジトリにアップできそうだ。