2013年1月14日

[android]TECH_DISCOVEREDでNdefMessageが取れるのは、AndroidがNDEFとわかっているときだけのようだ

前回の記事に対する訂正だ。

FeliCa LiteでNDEFデータが113~127byteのときにはNDEF_DISCOVEREDが上がってこない、という話をした。
しかし、NDEF_DISCOVEREDを指定していてもTECH_DISCOVEREDが来ることがある、というのが前回の話。

じゃあ、TECH_DISCOVEREDが返ってきてもNDEFとして処理すればいいやん、と思ってやっていたのだが、113~127byteのNDEFデータだと、

Parcelable[] pac = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

としてもpacはnullになってしまったのだ。

やっぱり、ちゃんとAndroidが「NDEFだ」と思っているときにしか使えないようだ。
すまん、みんな。

まあ、考えてみればそうよね。。。
NDEFと認識しているから、NdefMessageを作って返しているのよね。。。


Nexus7しか今のところ発生する機種がわかっていない、今回の現象。
logcatには、こう出てくる。

D/NfcDispatcher(8422): dispatch tag: TAG: Tech [android.nfc.tech.NfcF, android.nfc.tech.Ndef] message: null

NfcDispatcherが出している。
SmartPosterだと、こういうログになった。

D/NfcDispatcher(8422): dispatch tag: TAG: Tech [android.nfc.tech.NfcF, android.nfc.tech.Ndef] message: NdefMessage [NdefRecord tnf=1 type=5370 payload=91xxx(略)]

この出力のフォーマットは、こうだ。

"dispatch tag: " + tag.toString() + " message: " + message

だから、messageがnullなのだ。

 

messageは、

  • Ndef.get(tag)がnullでないなら、ndef.getCachedNdefMessage()
  • Ndef.get(tag)がnullなら、null

のどっちかだ。
getCachedNdefMessage()は持っている値を返すだけ。
Ndef.get(tag)は、tagがTagTechnology.NDEFを持ってなかったらnullになる。

やっぱり、よくわからんな。


よくわからんので、もうちょっと値で攻めることにした。

まず、ヘッダのNDEFデータ長だけを変えてみよう。
NDEFとして読み込めるデータを、ヘッダに113byteとして登録すると・・・messageはnullになった。
では、NDEFとして読み込めないデータを、ヘッダに128byteとして登録すると・・・同じくnullだ。
つまり、NDEFかどうかはヘッダだけを見ているのではなく、データも確認しているということがわかる。
「チェックサムでは?」と思ったが、データ長が128byteのときは0x00A3、127byteのときは0x00A2と別に変わった値でもない。
(libnfc-nxpでは、uint8_tバッファをuint16_tで加算していってるので、負の数とかは関係ない。)

 

じゃあNDEFデータのせいかというと、そんなこともないと思う。
それなら、NFC-Fだけじゃなくて他のTechnologyでも発生しそうではないか。

 

何が起こっているのか確認したい気持ちと、確認しても回避するしかないやんという気持ちがあって、それに加えて「どこがどう動いているのやら」があって、調査打ち切りの方向に進んでいる。
簡単にやるなら、自分でNexus7のソースをデバッグコードを埋め込んでビルドして焼いてみる、なんだけど。。。
リカバリーで元に戻せるという話は知っているのだが、まだちょっと気が引けているのだ。

2013年1月13日

[nfc][試作]Wi-FiのStatic Handover NDEFタグを作るWindowsアプリと、読んで設定するAndroidアプリ

いろいろ制限を付けているが、動いたので記録として残しておこう。
まあ「動いた」といっても、自分で作って自分で設定するんだから、できて当たり前といえば当たり前。

 

Windowsアプリ - github(SDK for NFC Starter Kit用。この中のHandoverWifi_FeliCaLiteがそれ)

Androidアプリ

 

まあ、普通なら全部Androidでやってしまうんだろうけど、まだそこまで至ってない。
それにこれは、暗号化などは全く無し、なのだ。
自分の家用とかではなく、公共の場のようにSSIDやパスワードが貼ってあるけど入力するのがめんどくさい、という用途なのだ。

 

そう思うと、Androidで書き込むソフトはなくてもいいかな、と逃げたくなってくる。
Javaでバイトデータを扱うのがめんどくさいのだよ・・・。

[android]NDEF_DISCOVERED指定してもTECH_DISCOVEREDが来ることがあるのは仕様

Nexus7で、自作NDEFタグを読み込ませようとしている。
私はACTION_NDEF_DISCOVEREDだけしか指定していないのだが、ACTION_TECH_DISCOVEREDのintentが飛んでくるので悩んでいた。

が、それは仕様だった。

i.2 高度な NFC - ソフトウェア技術ドキュメントを勝手に翻訳 (原文)

 

Categoryなどを指定せずにSmartPosterのNFCカードをかざしてみたが、やっぱりTECH_DISCOVEREDになっていた。


さて、原文を見ると「could not be mapped to a MIME or URI」とある。
翻訳されている文章だと「MIMEやURIにマップできなかった場合」と書かれているので、何となく「他にもマップできるものがあるのだろう」と読んでしまったのだが、もしかすると「MIMEかURIに」なのかもしれない。
なんでこんなことを言い出したかというと、Static HandoverのNDEFはWell-knownなNDEF Recordタイプではあるものの、MIMEでもURIでもないからだ。

ごにょごにょ考えていたが、ちゃんと書いてあった。
うん、順番に読みなさい、ということかな。

 

Static Handoverの場合、ALTERNATIVE_CARRIERを含んだHANDOVER_SELECTと、MIME(RFC2046)になる。
どうも、これらはTECH_DISCOVERED扱いになるようだ。

public static final short TNF_WELL_KNOWN = 0x01;
public static final short
TNF_MIME_MEDIA = 0x02;
public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
public static final byte[]
RTD_ALTERNATIVE_CARRIER = {0x61, 0x63}; // "ac"

 

実際にやってみると、そうなった。
だけれども、getParcelableArrayExtra()で取ってきてやると、ちゃんとNdefMessageになった(追記参照)。
ほほぅ。

 

ってことは、NDEFが113~127byteでごにょごにょ悩んでいたが、単にNDEFというintentが飛んでこないというだけで、解析する分にはどっちでもよいということなのか。

勉強になりましたわ。


追記(2013/01/14)

やっぱりだめだ・・・。

「getParcelableArrayExtra()で取ってきてやると、ちゃんとNdefMessageになった」と書いていたが、やっぱりだめっぽい。
nullになっていたのだ。

つまり、TECH_DISCOVEREDだったとしてもgetParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)がnullにならないようにするには、AndroidがNDEFとわかった上でTECH_DISCOVEREDを返す場合だけ、ということになりそうだ。

ごめーん。

[android]単にNDEF_DISCOVEREDとしただけではNDEFのintentが来ない?

今回は、私の技術不足という問題。
「役者不足」といいますか。

ひとまず、NFC-FでもNDEFとして読み込んでくれるサイズにしたデータを書き込んだカードを作った。
では、それをNDEF_DISCOVEREDでintentを飛ばしてほしい。
ほしいのだけど、自分のアプリが起動しているときだけでいいので、intent-filterはManifest.xmlには書きたくない。

こんな作りにしてみた。

@Override
protected void onResume() {
    super.onResume();
    IntentFilter[] intentFilter = new IntentFilter[] {
        new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED),
    };
    String[][] techList = new String[][] {
        {
            android.nfc.tech.NfcF.class.getName()
        }
    };
    mAdapter.enableForegroundDispatch(this, mPendingIntent, intentFilter, techList);
}

AndroidManifest.xmlにはNFCのintent-filterを置かず、res/xmlも作っていない。

かざすと、logcatにはNDEFと出てくるのだが、onNewIntent()にはTECH_DISCOVEREDとして通知されてしまう。

うーむ。

2013年1月12日

[nfc]NFC定義値が更新されていた

NFC Forumのページに「Assigned Numbers Register」というのがある。
さっき見たら更新されていたので、ご紹介を。

http://www.nfc-forum.org/specs/nfc_forum_assigned_numbers_register

 

Webページはしばしば更新されたり消えたりするので、ときどきスナップショットで記録するようにしている。
このページも以前記録していたのだが、久しぶりに見直すと変わっていた、という次第だ。
変更履歴みたいなページがあるといいんだけどねぇ。

  • SAP値「Internet Protocol」がなくなった
  • SAP値「OBEX」がなくなった
  • Well-known NDEF Record Type「Gc」は非推奨、という注釈追加
  • SAP値「Service Discovery Protocol」の説明が、v1.0からv1.1になった(というだけでURIは同じ)

"deprecated"は「非推奨」でいいのかな。

[n7]Nexus7ではFeliCa Liteで113byteのNDEFが読めないようだ

ここ最近やっている、NFC-FのNDEFがうちのNexus7で読めない件についてだ。
さっそく、コメントをいただいた(ありがとうございます)!

Nexus7を含めて4端末を見ていただいたところ、Nexus7だけがこの現象になったとのこと。
ほほぅ。
私の予想では、NXPのNFCチップを搭載した端末はすべてこうなるだろう、というものだった。
しかも、Galaxy NexusはPN65N、Nexus7はPN65なので、同じlibnfc-nxpライブラリを使っているんだろうと思う。

ということは、Android 4.2.1になってバグが混入した、ということになるんだろうか。
枯れている部分だと思っていたので、わざわざバグを入れ込む必要もなさそうだし、Nexus7にしたからって作り込むような気があまりしないのだ。

 

あとは、他の4.2.1端末で現象が発生するかどうか、というところか。
あるいはNexus7がバージョンアップしたら直るとか。

 

当面の私がやりたいのは、単にWi-FiのStatic Handover用NDEFデータを読み込みたいというだけで、頭から自分で読んでいってもなんとかなる程度のものだ。
なのだけれども、やっぱりめんどくさい。

もしNexus7のNDEFパーサが、NDEFメッセージのレコード先頭(MB=1)からレコード末尾(ME=1)までしか解析しないのであれば、NFC-Fのヘッダが持つデータ長は長めにしていても問題ないんじゃないか、という気がする。
「データはもっとあることになっているけど、ME=1だから解析はやめよう」という作りならば、だ。
今度、試してみようかね。

2013年1月1日

[n7]リセットしたらインストールエラーが直った

自作のAndroidアプリがあるのだが、なぜかそれだけエラーでインストールできなかった。
不明なエラー「-24」などといわれる。
その数字自体が不明なんじゃ!

と怒っても仕方ないので放置していた。
Ejectするアプリだったので、メディアがないNexus7ではだめなのかも、と適当に考えていた。
今日、注文していたmicroUSB Bのホストケーブルが届いた。
USBメモリを挿してインストールしてみたが・・・だめ。
まあ、そうよね。

ネットで調べてみたところ、-24の原因はよくわからんが、初期化したら直る、というものが思ったよりも多かった。
まあ、そんなにアプリもインストールしてないし、ということで、やってみた。
説明は、こちら。

やったら、直った。
えぇぇ、そうなんだぁぁぁ。。。。
でも、こういう破壊的な直し方って、製品としてはだめだと思う。
まあ、そういうのもひっくるめて値段を安くしているってことかもしれんので、否定するわけではない。
私の個人的な好みとは異なるというだけだ。
変にこういうところをがんばって高機能にする時代ではない、ということかもしれんな。

Wi-Fiダイレクトに対応したものは少ない?

Android Beamと同じくらいに採用されたWi-Fiダイレクト機能。
いつも並べて書いてあることが多いので、私はてっきりAndroid Beamと関係した機能と思い込んでいたのだが、まったく別々に使えるようだ。
Windows8でも対応したとか書いてあるので、うちのノートPCでやってみた。
・・・が、Nexus7はうちのノートPCを探すことができなかった。
ん、Windows8になってればいい、というものではない?
http://www.computerworld.jp/topics/612/164810
ハードウェアの変更まではいらないけど、ファームウェアの変更は必要そうだ。
ということは、Wi-Fiダイレクト対応のOSが載ったり、対応したデバイスドライバがあったり、というだけではだめなのだろう。
まあ、メーカーによって作りが違うから、一概には言えんだろうがね。

インテルのMy Wi-F-ダッシュボードという製品があるようだ。
よくわからんが、これをインストールすればいいのか?
うちのノートPCは4965AGNというインテルのWiFiコントローラだかなんだかが載っているのだ。
http://www.intel.co.jp/content/www/jp/ja/wireless-products/my-wifi-technology.html

プリンタは、Wi-Fiダイレクト対応、とかが出てくるのだが、普通のPCで使うような無線LAN子機でWi-Fiダイレクト対応というものがほとんど見つからなかった。
I/OデータのWN-AG300Uというやつは対応していたが、同じページにある他の子機は対応していない。
Baffaloにはマークがなかったが、わざわざ書くまでもないということなのか。。。

などと書いているうちに、My Wi-Fiダッシュボードのインストールが終わった。
「更新」をクリックすると近くのデバイスを見つけてくれるようだが・・・うちのNexus7を見つけられなかった。
Nexus7も、やはり見つけてくれない。
という以前に、My Wi-Fiダッシュボードのアプリ画面が違ってて「ワイヤレスON」という項目がないので、ちゃんと動いていないようだ。
もう疲れたので、今回はあきらめよう。

NFCいろいろ

NFC Worldの記事に、日本語の文字が出ていたので、目立っていた。
任天堂がNFC付きポケモンのおもちゃを出す、というタイトルなのかな。
http://www.nfcworld.com/2013/03/13/323045/nintendo-to-launch-pokemon-toys-with-nfc/
Googleで検索すると、いろいろ出ていた。
NFCタグというと、カードとかシールを想像しがちだが、形にはそんなにこだわらないので、ある程度のアンテナ面積さえ確保できればいいのかな。
きっと、タグデータも自作できるようなものなのだろうけど、おもちゃ自体はそんなに高価なものでもないそうなので、家にタグが余っているような人以外は普通に買った方がうれしいだろうね。

NFCというかFeliCaというか、サイバネ関連だが、交通系ICカードが結構な範囲で相互利用できるようになる。
いつもNFCのことしか書いていないような私だが・・・あまりNFCを生活で使ってはいない。
そもそも乗り物に乗ることが少ないし、買い物も現金でやるほうが多い。
もうちょっと生活に取り入れた方がいいのかねぇ(NFCのことを書く人として、という意味で)。

私の生活であれば、福岡内の移動か、あとは出張で関東に行くときくらいか。
福岡は、JRか、市営地下鉄か、バスだ。3つしかないのでわかりやすい。
JRは、SUGOCA、だ。
市営地下鉄は、はやかけん、だ。
バスというか西鉄は、nimoca、だ。

関東が問題だ。多すぎる。
まず、飛行機を使ったとしよう。
そこから浜松町までは東京モノレールに乗ったとする。
モノレールSuica、というものがあるらしい。
モノルンと鉄道むすめはあるが、Suicaと名乗っているためか特定のキャラはいないみたいだ。
東京モノレールは、nimocaと相互利用できるとなっているので、大丈夫だ。
おっと、京急を使うかもしれない。京浜急行電鉄。
こっちは、PASMOのようだ。
PASMOも全国相互利用できるので、大丈夫だろう。
PASMOのロボット、がキャラらしい。
京浜急行は・・・というかPASMOはnimocaと相互利用できるとなっているので、大丈夫だ。
では、まず神奈川に着いたとしよう。
路線は、ここに一覧があった。
・・・多い、多すぎる。JRも、東海と東日本が入り込んでるし。
JR東日本は、Suica。あのペンギンなのだが、意外なことに専用キャラではないらしい。
JR東海は、TOICA。キャラはひよこだが、特に紹介もなにもない。
どちらも相互利用できるとなっているので、大丈夫だ。
ほかの鉄道も、PASMO範囲であればなんとかなりそうだが、細かいところは調べる気力が無い。
東京はどうだろうか。
営団地下鉄・・・ではなく、東京メトロか。会社名は「東京地下鉄株式会社」。ここもPASMOらしい。
都営地下鉄は「東京都交通局」。PASMOらしい。
ゆりかもめは「株式会社ゆりかもめ」。PASMO。

疲れた・・・。
他にもたくさんあるのだが、とても調べる気力が続かない。

[無駄話]RTDの謎

かなり無駄な話だ。
現在、NFC Forumで公開されているRTD(Record Type Definition)は4つ。
  • NFC Text RTD Technical Specification
  • NFC URI RTD Technical Specification
  • NFC Smart Poster RTD Technical Specification
  • NFC Signature RTD Technical Specification
Generic Controlは、2012年8月9日でremoved、ってことだから外した。
さらば、Generic Control・・・。

さて、そのドキュメントファイルだが、名前がこうなっている。
  • NFCForum-TS-RTD_Text_1.0.pdf
  • NFCForum-TS-RTD_URI_1.0.pdf
  • NFCForum-SmartPoster_RTD_1.0.pdf
  • NFCForum-TS-Signature_RTD-1.0.pdf
TS、は、Technical Specificationだろう。
SmartPosterにはTSが付いていないが、これは名前が長くなるのを嫌ったからか。
それよりも謎なのが、RTDを先に付けるものと、後に付けるものに分かれていること。
そしてSignatureだけはバージョンとの間がハイフンになっていること。
なんでこんなに統一感がないのだ?

と、どうでもいいことを思った。
疲れてるんだよ・・・。

急にこんなファイル名を見たのは、NFC Worldの記事にRTDって出てきてたからだ。
中身は読んでないんだけど、気が向いたら読みたいところだ。