NDEFに、well-known typeを指定することがある。
NFC Forum仕様書のどっかにもあるのだろうが、見つけきらん。
そしていつもブックマークしては、どこに置いたか忘れてしまうのだ。
忘れんように、残しておこう。
http://www.nfc-forum.org/specs/nfc_forum_assigned_numbers_register
NDEFに、well-known typeを指定することがある。
NFC Forum仕様書のどっかにもあるのだろうが、見つけきらん。
そしていつもブックマークしては、どこに置いたか忘れてしまうのだ。
忘れんように、残しておこう。
http://www.nfc-forum.org/specs/nfc_forum_assigned_numbers_register
今週届いたtouchanoteのタグ。
データを見る限りはNDEFだし、アクセスはUltralightっぽい。
SAK(SEL_RES)も0x00だし。
そう思ってType2タグのNDEFデータ解析方法を学んでいたのだが、疑問が出てきた。
Type 2TagドキュメントでいうところのCC(Capability Container)、Mifare UltralightでいうところのOTP(One Time Programmable)。
ここの3byte目が0x12なのだ。
3byte目は、データ部のサイズで、8倍した値がバイト数になる。
ということは、18*8=144byte。
Mifare Ultralightって、全部でも64byte。それよりも大きい。
んん??
困ったことに、このOTPはプログラマブルというくらいなので、現在の状態を表しているわけではない。
もし144byteが正しいなら、Internalな部分が16byteなので、あわせて160byte。
中途半端だ・・・が、EEPROMだからビット数だけだよと言われてしまえばわからん。
UltralightCは192byteなので、そっちの方がサイズが近い。
けど、データ部以外が48byteもあるってことになるやん。
touchanoteのホームページから、UltralightCと同じような、という記述を発見。
よく読んだ方がいいな、私は。
UltralightCであることがわかれば、あとは仕様書を探して読めばわかる。
うん、データ構造が多少異なり、データのお尻の方に認証関係のデータがある。
ここが32byte使っている。
残りの16byteは、UIDとかLockとかの4ブロックだ。
これで計算が合った。
そして、最初の目的であったNDEFの調査はできずじまいでありましたとさ。
めでたしめでたし。
しかし、どうやってUltralightとUltralightCを見分けたらいいんだろう、と思って検索すると、同じように思った人はやはりいたようだ。
http://www.libnfc.org/community/topic/218/how-to-distinguish-a-mifare-ultralight-c/
ああ、そうなんだね・・・。
Qtでコンパイルして、こんなことをいわれたときの対応。
qwineventnotifier_p.h : No such file or directory
http://developer.qt.nokia.com/forums/viewthread/12643/#68136
Qt4.8では、これでよい。
次のバージョンくらいから何とかするとかいうのを読んだ気がするが、忘れた。
NFCの中でも、関係が強いような、そうでもないような、というセキュアエレメント。
個人開発していると、あまり出てこないと思うのだ。
セキュアエレメントは、セキュアなメモリ、というイメージを持っている。
AndroidのNexusSだっけ、あれにSmartMXが載ってたと思うが、あんなの。
NFC経由の認証無しではアクセスできないメモリ、というところじゃなかろうか。
モバイルFeliCaの場合、セキュアエレメントはモバイルFeliCaチップにつながっている。
こちらの記事しか、画像がなかったのでリンクさせてもらおう。
3つあるうちの左側が、現在の形だ。
http://wirelesswire.jp/special/201101/01/report/201102170455.html
右側が、Mifareなどを採用しているメーカーの形式と言うことか。
UICC、つまりSIMにセキュアエレメントが載っていて、チップとはSWPっていうやつで通信するようになっている。
無線の部分は、FeliCaだろうとMifareだろうと、そんなに変わらない。
周波数帯は同じだし、通信速度は106kbpsの倍数になっているだけ。
符号化とかになるとソフト部分になるので、やればできる。
やってもどうしようもないのが、ハードウェアの違いだ。
図の左側だと、モバイルFeliCaチップがないとどうやってもFeliCaのセキュアエレメントにアクセスできない。
しかし右側の方式だと、SWPで通信できればFeliCaだろうとなんだろうと、SIMに載っているセキュアエレメントにアクセスすることができる。
ハードによって限界が決められ、ソフトによって制限がかけられる、という見方になるだろうか。
SWPってのは、Single Wire Protocolの略で、文字通り1本線の通信らしい。
しかも、おそろしいことに双方向通信ができるらしいのだ。
話によると、電圧で制御する方向と電流で制御する方向で双方向になるんだとか。
いやあ、すごい。
国際なんとか規格だったか、GSMAという組織があったと思う。
そこが、SEとのやりとりはSWPで、というようなことをいっているらしい。
FeliCaはそうじゃなかったので、なんとかどうとか、という記事を読んだような気がする。
ということからすると、NFCは結局のところセキュアエレメントの利権問題になってしまうだけなのか、という気もしてしまう。
それは、非常に面白くない。
いや、お金がどうのこうのは大切な要素だとは思うのだけど、そこってNFCとは直接絡んでないので別に分けてほしい。
個人の開発なんて、そういうところに入っていくことはないので、どうでもいいや、と思ってしまうのだ。
もしセキュアエレメントがみんなSIMに載って国際規格か何かのルールに沿ってアクセスできるようになったら、無線の方式がNFC-A/B/Fと3つもいらないんじゃないの、という話になりそうだ。
淘汰か多様性か、そこが問題だ。
ときどき、Android Marketにアップしているアプリに対してのコメントをいただける。
興味を持ってダウンロードし、コメントまで書いていただけるとはありがたい。
まあ、アプリがアプリだけに、少ないんだけどね・・・。
今日、コメントが入っていた。
ポルトガル語だ。
こういうときは、Excite翻訳!とやってみたが・・・わからない。
自然言語の解釈は難しいことだよ。
私が気にしているのは、アプリが動いたかどうか、だ。
なんでか知らないが、SDカードをマウント/アンマウントするだけのアプリなのだけれども、うちでは一番人気なのだ。
私だったら、SDカードなんて、ひょい、と抜いてしまうんだけどねぇ。
まあ、ライトコピー(だっけ)みたいなキャッシュだったら、やだな。
このアプリ、XOOM/XOOM2で動かない、という連絡が来ている。
持ってないのでどうしようもないと思っていたが、調べてみると「/mnt/external1」というディレクトリにマウントしてるようなことが書かれていた。
ならば、そこならいけるのかも、ということで、アプリの説明に「/mnt/external1ならいいかも」と書いておいた。
その後の、初コメントが、今回気にしているコメントだ。
星が5つついていたから、動いたはず!と思いたい。
・・・けれども、以前は「動かなかったけど、いいアイデアだよ」みたいなので5つ星だったこともあるので、そこを信用してはいかん。
うーむ。
よくエキサイト翻訳のページを見ると、ポルトガル語から英語への翻訳もある。
もしかすると、日本語の文法に当てはめるのは難しいかもしれないけど、英語ならいけたりするかも。
やってみると。。。おお、まあまあわかる。
動いて…いるのかな?
コメントを引用したいけど、なんかちょっと気が引ける。
Android Marketで、どうやってポルトガル語のコメントを出したらいいのだろうか。
https://market.android.com/details?id=com.blogpost.hiro99ma.EjectSD&feature=search_result&hl=pt_PT
これでいいのかな?
「Suicaなど対応のクラウド型マルチ決済が2012年9月までに稼働、中小店舗開拓へ 」という記事があった。
http://itpro.nikkeibp.co.jp/article/NEWS/20120221/382253/
こんなしくみかしら。
写真からすると、Android端末の下にレジ用プリンタみたいなのがあるようだが、まあいいや。
明細の印字、というのも、せっかくここまでやっているのにもったいない。
支払った感覚も受けとった感覚もないので、何か形にしたいのだろうが、そこをカバーするしくみがあるといいのだろうな。思いつかんけど。
1ページ目の下の方を読むと、ADSLみたいな固定回線を推奨しているとか。
あのAndroidは、無線LANみたいなものなのかい?
あれ、じゃあAndroidじゃなくてもいいやん。
固定回線を使うのなら、こんなんでもいいかも。
まあ、うちにBluetoothユニットがあるからそう思うだけなんだけどね。
こういう端末は、単なるPUSH端末と違って設置場所に人が常駐することだろう。
そういうところであれば、電池で動かなくてもよさそうだ。
電池で長時間動くようにソフト作るのは、大変なのだよ(しみじみ)。
届かんなー、といっていたtouchanoteが届いていた。
カナダの切手だ。
♪ラブレターフロムカナダ~、という歌が脳裏をよぎった。
10枚セットのを買って、10ドル。確か800円しなかったはず。さすが円高。
10枚と、1枚はEvernoteシール(これもタグ)だ。
残念なことに・・・私はNDEFを全部読めるようなソフトを持ってない。
NFC-Fなら、FeliCaランチャーとかでいけるんだけどね。
とりあえず、自作のMifare Ultralightリーダソフトでアクセス。
こんなのが読めた。
だから、Ultralightなのだろう。
NDEFは読めないが、バイナリデータは読める。
読んでみよう。
04-41-5F-92
1A-D9-26-80
65-48-00-00
E1-10-12-00
01-03-A0-10
44-03-13-D1
01-0F-55-01
74-6F-75-63
68-61-6E-6F
74-65-2E-63
6F-6D-FE-00
00-00-00-00
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
Ultralightは、Type2タグだ。
なので、NFCForum-TS-Type-2-Tag_1.1.pdfを開く。
p.5を開いてくれたまえ。
ここに、メモリ構造が載っている。
64byteある。
例がp.29にあるので、そっちの方がわかりやすいかも。
04-41-5F-92
最初のブロックの0~2は内部用。
赤文字は、Lock0/Lock1と呼ばれるデータ。
全部のビットが0だと、ブロック3のCC以降の読み書きが可能。
全部のビットが1だと、読み込み専用になる。
ということは、このシールは読み書きできるのだな。
E1-10-12-00
ブロック3の「CC」というのは、Capability Containerというらしい。
日本語に直訳すれば「能力容器」。
ちなみに「capability」は「けいぱびりてぃー」という発音になる。
「きゃぱびりてぃー」と読んで恥ずかしい目に会わないようにしよう(私みたいに…)。
0xE1は、NDEFのことらしい(p.21)。
01-03-A0-10
44-03-13-D1
01-0F-55-01
74-6F-75-63
68-61-6E-6F
74-65-2E-63
6F-6D-FE-00
ここら辺にデータが入っているのだろう。
めんどくさいので資料無しで推測すると、赤文字のところは文字コードっぽい。
74-6F-75-63
t o u c
68-61-6E-6F
h a n o
74-65-2E-63
t e . c
6F-6D
o m
ほら、当たった。
データの頭から解析していくのが筋ではあるのだが、今回のようにURLが入っていそうなデータならば、文字コードらしき場所を探し当ててから見てみた方が早い。
臨機応変に、ですな。
Windows版のlibusb-1.0で、CRCエラーが発生したことになっている。
わからないままにするのは嫌なので、調べることにした。
ソースは、ここから。
git://git.libusb.org/libusb-pbatard.git
libusb:error [windows_transfer_callback] detected I/O error: [23] データ エラー(巡回冗長検査 (CRC) エラー) です。
libusb:warning [do_sync_bulk_transfer] unrecognised status code 1
こんなログだ。
出るのは受信時だけで、送信時には出ていない。
ソースでは、windows_usb.cのwindows_transfer_callback()。
名前からすると、転送完了通知みたいなものだろうか。
引数でエラーが返ってきていて、それを単に出しているだけのようだ。
アンダーラインを引いたエラーの文言は、GetLastError()で取ってきているだけなので、WindowsがCRCエラーと判断しているように見える。
libusbソースを"crc"で検索しても見つからないので、そこら辺はアプリ以下でやってくれていると考えて良かろう。
しかし、SnoopyProでの通信を見る限り、エラーが発生している気配がない。
いや、SnoopyProでエラーが見えるのかどうかは知らないけれども、エラーが発生したら何かいいそうではないか。
雑誌InterfaceのUSB特集を見ると、バルクINでCRCがあるのはデータパケットのようだ。
しかし・・・Windowsがそういう低レベルのエラーを上げてくるのか?という気がする。
リトライとかしてその結果を上げてきそうだし、そのときも「データ不正」とかそんなエラーで、いちいちCRCが違っていた、なんてことは言わないんじゃないだろうか。
推測に過ぎないがね。。。
Linuxなら動くだろう、と試してみたが、あらら、動かない。
こっちは-75というエラー。
どうやら、バッファオーバーフローの意味らしい。
検索すると、受信バッファが実際のデータよりも小さいと発生するようだ。
そんなわけで、受信バッファを増やすと、LinuxもWindowsもエラーが出なくなった。
なるほどねぇ。
Windows版のlibusb-1.0を使おうとした。
USB機器を使おうとするなら、普通はドライバが必要になる。
しかし、libusbは便利なもので、VIDとPIDでアクセスすることができるようになる。
まあ、パフォーマンスなどを考えるとドライバを書いた方がいいのだろうが、libusbを使うことができるならば「libusbが動く環境ならばドライバ不要」ということができる。
さて、うちにあるUSBデバイスの1つをlibusbで動かそうとした。
いつも私はWindows XP(32bit)を使っているので、そのバイナリファイルをダウンロードした。
libusbは、大きく分けて2つある。
libusb-0.1系と、libusb-1.0系だ。
バージョンが異なるというよりも、APIが異なるので別物のイメージがある。
とはいっても、1.0系にはコンパチブル用に0.1ライブラリラッパも用意されている。
なので、0.1用に作っておけば良い。
・・・よいのだが、私は当時、最新を求めていたようだ。
linux、cygwinで動くlibusb-1.0で某デバイス向けのライブラリを作っていた。
そしてそれは期待通りに動いてくれた。
それをwin32版にすると・・・.
win32版にすると、受信でCRCエラーが発生している。
USBスニッファで見ると、エラーになるだけで、次のデータは正しく機器からは送信している。
つまり、受信側の問題みたいだ。
win32だけなのか、linuxとcygwinで偶然うまくいっているだけか。。。
タイトルが「どうだろうか」で終わっていることが"どうだろうか"なのだが、まあそこは目をつぶっておくれ。
勤怠管理、というのは、どうしても各作業者に任せるしかない。
工場現場とかであれば知らないけど、開発現場では「○○の開発にM時間N分」「××のデバッグにQ時間T分」みたいな入力をよく求められる(たぶん、工場の方がシビア)。
開発現場では、まとまった時間で作業できることもあるけど、A開発のデバッグをしている合間にB開発のドキュメントを書き、ちょっと気分転換にC開発の管理をする、ということがしばしばある。
また開発の中でも、ドキュメントを書きつつデバッグして、単体テストをやっていながらドキュメントも修正して、なんてことはしょっちゅうだ。
しかし、管理面からすると「作業していた時間をそれぞれ別に記録してくれ」と言わざるを得ない。
それをどう役立てるのかは、情報を持たせた側に依存してしまうのだが、情報が正しくなければ解析する気にもならない。
自動販売機にNFCのR/W機能が付いたおかげで分析ができるようになってきたという話が出ていたが、そういったことが進んでいくだろう。
では、私は思った。
ST1020には表現する機能があるので、とりあえずかざした時間を記録すると面白いんじゃなかろうか、と。
見たことはないのだが、放射線技師はガイガーカウンタを付けて記録するというような話を聞いた気がする。
このご時世、仕事をしている負担がかなり偏っていると思う。
そこを目視できるいい機会ではなかろうか。
そんなことから「見える勤怠!」というのを考えた。
入館管理証みたいなものに、ST1020を使う。
ちょうど電子ペーパー部分の下に広いところがあるから、そこに名前と写真を貼っておけばいいだろう。
電子ペーパー部分には、最後に入館にタッチした日時・時分と、タッチが4時間以内であれば期間を表示するのだ。
3時間、というのは、会議で午前3時間+昼食、みたいなパターンを想定したまでだ。
表示は、24時間をベースとしたグラフがいいな。
1日のうち、何時間を会社ですごしているか、というのが見えればいい。
仕事をしていてテンションが高くなると、「このまま寝なくても大丈夫だぜ!」と思ってしまうことがある。
そのときはそれでいいかもしれないが、それが何度も続くと、だいたい人間が壊れてくる。
それでいい人もいるかもしれないが、それなら目視できるようになっても問題はなかろうし、会社にいる時間が長いようであれば人生を見直した方がいいと思う(余計なお世話)。
とにかく、きっかけを与える、という事柄については、目で見えるってのは大きいと思う。
技術的には、転送時間の問題があるだろう。
画面データは2400byte。
一度に転送できるのは、176byte。
よって、14回分の転送時間が必要。
標準的なFeliCaカードなら212Kbpsだが、マンチェスターとプリアンブルなども適当に考慮して90Kbit/sくらいとすると、2秒くらいで転送になる。
2秒は、長い。
秒単位なんて大したことない、と思うかもしれないが、実際に改札などで2秒間動けないとなると、すごくストレスがたまるだろうし、背後に並んだ人がたまるだろう。
トイレなどで部屋の外に行って、また戻るたびに2秒も立ち止まると思うと、たぶんイライラして運用できないことだろう。
となると、運用を考えた方がいい。
出入り口でタッチするようなものは、レイアウト変更のみ。
長時間かざしたまま(PCに置いたまま)とかであれば・・・いや、いつ取り外されるかわからんな。
であれば、ST1020側を変更して、レイアウト変更できる部分を分割するとか。
画面200x96なので、それを10x4くらいのキャラクタブロックでアクセスできるようにして、そこへ「キャラクタ番号」みたいなものを指定できるようにしてしまうとかだ。
転送量が減れば、当然立ち止まる時間も減らせる。
St1020が内部でがんばる時間は増えるかもしれないが、そこは作り込みの方法で電池寿命が延ばせそうな気がする。
仕事する時間が増えると、ストレスがたまるのだ。
その一部を表に出すことができれば、ストレスを減らす方策が立てられるかもしれない、という希望を持っただけだ。
アイオイ・システムさんが開発、販売しているSmartTag、ST1020。
スイッチサイエンス社で個人向けにも販売されていて、何度も売り切れるほど好評。
好評なのだが、ネットで検索しても「これしてみた!」みたいな記事が見当たらない。
NFC=Near Fieldだけに、ネットに載せるなんて、と思っている人が多いのかもしれないが、盛り上げるためにも「こんなことやってるよ!」みたいな話が見たいものだ。
探し方が甘いのかなぁ。
あらすじ
NFCのことを調べている私であったが、Qtもやらなくてはならない。
「NFCのライブラリをQtで作ればいいじゃないの」
そんな声が聞こえてきたので、やることにした。
Qtでのシリアルポートアクセスに、QSerialDeviceを使うことにした。
gitoriousにあるものを使っているのだが、Qt4.8くらいになるとブランチはmasterではなく2.0を使わないとコンパイルエラーになりそうだ。
基本的にこういう外部のデバイスは、QIODeviceを継承することになる。
ファイルもそうなので、UNIX系の考え方でいいのだろう。
しかしまあ、この「デバイスをファイルとしてアクセスする」という考え方は長いこと使われているな。
アクセスを一般化させたのは、すごいと思う。
さて、私はQSerialDeviceを使って、RC-S620/Sへのライブラリを作ることにした。
GUI用に非同期化する、ということを考えなければ、比較的簡単だった。
といいつつも、実際に動かすまでには時間がかかった。
QIODeviceのことを考えず、QSerialDeviceのヘッダ定義だけでアクセスしようとしていたからだ。
具体的に言えば、virtualな関数をまったく見ていなかった、ということだ。
詳細に書いても救いにはならないなぁ。
とにかく、外部デバイス系のclassは基本的にQIODeviceのAPIで使えるように作り込もうとしている、ということだけ覚えておけば良いだろう。
QSerialDeviceだって、ボーレートやストップビットみたいなデバイス依存のAPIを追加していること以外は、QIODeviceのAPIをoverrideしているのだ。
それ以外については、作っていたC++クラスの中身はほぼそのままだ。
qmakeの文法などで困ったりはしたものの、コーディングレベルではほとんどそのまま移植できた。
おそるべし、Qt。
PaSoRi用のライブラリも作って、セットでgithubにでも置こうかと思ってたけど、USBはなかなか壁が高かった。。。。
Win32で、libusb-1.0のライブラリを使うとCRCエラーが発生してしまうのだ。
cygwinやLinuxだと動いているのにねぇ。
Qtでシリアルポートを操作できるクラスがあったので、それを使おうと考えている。
最近、Qt4.8(mingw)をインストールしたので、ビルドさせた。
.dllと.aができた。
では、サンプルを動かそう。
サンプルの.proをQtCreatorで見ると、QSerialDeviceでビルドしたものではなく、ソースをそのまま取り込んでいるようだ。
せっかくなので、ビルドした.dllで動かしたい。
QtCreatorでライブラリを使う、を参考に外部ライブラリを追加しようとしたのだが、そこでは.dllではなく.libを要求される。
.dllから.libを作るには、Microsoftのlib.exeとか.defファイルとかいるようなので、めんどくさい。
一度に何とかできないものかと調べていたが、なんかはっきりしない。
mingwのページを見ると、こういうのがあった。
dlltoolというもので、インポートライブラリを生成する、と。
そのファイル名が、どうも.aっぽい。
では、と生成された.aファイルを.libにリネームして、QtCreatorの外部ライブラリとして選択すると、うまくいった。
ビルドもできた。
ということは、単にファイル名が.aになっているだけで、.libを同じ扱いにしてもいいのかもしれない。
ここから先は、libとは関係ないことだ。
QSerialDeviceのところをよく読むと、将来的にQtSerialPortってのになるだろう、といっている。
標準に組み入れられるのであれば、そっちの方が望ましい。
Qt4.8のソースを検索したけど、なかった。。。
このリポジトリは更新しない、みたいなことを書いているけど、そのわりには更新頻度が高い。
Googleで「QtSerialPort addon」とかで検索すると「もしかしてQextSerialPort?」などと言われる始末だ。
さっき試すと、QextSerialPortもビルドできたので、どっちでもいい。
まあ、シリアルポートでやることは限られているので、I/Fもクラスが違ってもそうそう変わるものじゃないだろうから、あまり深く気にしない方がいいかな。
Sonyさんが、認証型コンセントの提案をしていた。
http://www.sony.co.jp/SonyInfo/News/Press/201202/12-023/index.html
NFCのところだけ見ていたので上記サイトを見るまで気付かなかったのだが、この提案では2つの方式があるのだ。
後者の方は、新技術らしい。
「新技術」という言葉には、どうも弱い。
コンセントって、日本語だと「壁にある電気を供給してくれるポート」みたいなものだが、英語だと"socket"とか"plug"とかになるようだ。
そもそも「コンセント」は和製英語とのこと。
英語辞書サイトによると、"socket"か"plug socket"らしい。
挿す方がplugで、挿される方がsocketということか。
FeliCa認証の場合は、plugがカード、socketがR/Wと思えば良い。
カードをかざすように、プラグをソケットに挿すのだ。
もう1つの電源ケーブルを介した認証(電力線重畳通信、という)の場合は、プラグもソケットもNFCではない。
読み取るのが難しいが、こういうことだろうか。
まず、ソケット側にR/Wのようなものがある、と。
ただしこれはRFのR/Wではなく、同じようなことを電力線(日本だと実効115V交流)で通信するようなR/Wになっている。
プラグ側は、これも同様にRF向けのカードではなく、電力線に載せられた信号に応答できるようなカード(カードじゃないけど)になっている。
力関係はRFのときと同じで、プラグ側(カード側)は電力供給されている必要がない。
通信が必要なときは、ソケット側(R/W側)が電力を供給し、ポーリングしてNFCID取得して、みたいなことをやるというのだろう。
私が知らんだけかもしれないが、こういう力関係の通信は聞いたことがない。
NFCもそうなんだけど、電源を持っていない機器と通信するために電力供給する、という考え方なのだな。
SPIだってUARTだってI2Cだって、相手は応答を返せることになっている前提だ。
NFCのやり方を、RF部分で応用するのではなく、方式として応用したってところが、そういう考え方もあるんだなー、と思ったところだ。
http://www.jp.nxp.com/products/identification_and_security/smart_label_and_tag_ics/ntag/
NXPに、NTAG、というチップがあった。
つらつら見ると、なんとなくFeliCa Plugと似た系統のような気がする。
でも、こっちはメモリ付いてるな・・・。
そして電源はRFからとるみたいだ。
うーん。。。ダウンロードはパスワード取得をしないといかんようなので、やめとこう。
急にQtだ(Qだけにね)。
私が勤めている会社にも、やれ個人目標だ、やれ啓発目標だ、なんだかんだある。
そろそろ年度末なので、やっとかんといかん。
目標は4月くらいに出すので、今の目標は昨年4月に出したものだ。
たしか、NFCとQtをそれぞれ何かやる、と書いた気がする。
(あまり細かいことは気にしない性格。)
NFCは、けっこうがんばった方じゃないかと思う。
しかしQtの方はすったりだ。
ときーどきー、くらいのペースでしかやっていない。
そんなわけで、最後の技として、QtでRC-S620/Sを扱うような簡易クラスを作ってごまかそう、と目論んでいる。
といっても、Qtから使うとか深いことを考えなければ、C++で作ったものがある。
特殊なことはあまりしていないので、Qtのシグナルとか使うことを考えなければ、そのまま動くと思う。
しかし、それではあんまりなので、せめてシリアルデバイスくらいはQtでやってやれば、マルチプラットフォームっぽい感じが出るんじゃないだろうか。
玄関に門松と餅を置いたらお正月気分が出るのと同じ理屈だ(?)。
さて、Qtにシリアルポートを操作する標準クラスがあるかというと、なさそうだった。
ユーザの人が、有志でやっているものがあるようなので、それを使わせていただこう。
私が見つけたところでは、この2つがあった。
特にどっちがどう、という思い入れもないので、動けばいい。
何も考えずにQt Creatorにproファイルを喰わせて、ビルドできる方にしよう。
はい、今回はQSerialDeviceになりました。
注意としては、src\corelib\kernel\qwineventnotifier_p.h、みたいなのがいるようなので、ソースごとダウンロードして、それっぽい場所を作ってコピーした、というところだろうか。
使い方も何も見てないけど、サンプルをビルドして動かすと、Windowsの使用中シリアルポート一覧がコンソールに出てきた。
ほほー、というくらいで、APIの使い方も、ビルドの方法すらも調べていない。
まあ、初日はそんなもんだ。
うちに来たものは、ほぼ分解される運命にある・・・。
アイオイさんのスマートタグST1020も分解しようとしたが、うちにあるマイクロトルクスレンチでは径が大きかった。
T6までしか持ってないが、もう少し小さいようだ。
当時は5本セットで千円したみたいだが、もしかしたらダイソーにあるかも。
さて、ST1020はFeliCa Plug搭載だ。
FeliCa Plugというのは、NFC Dynamic Tagとも呼んでいる製品だ。
スイッチサイエンス社からも購入可能だが、接続はSPIだ。
PCからSPI接続させたいとなると、FTDIのFT232みたいなチップを使うしかない。
(仕事で困っているので、今はFTDIチップのことは考えたくない・・・。)
SPIを使おうとしたら、SPIバスを持つチップとつなげるのが一番だろう。
私も買ってはいるが、まだ接続していない。
いつか、いつかと思いつつ・・・。
雑誌Interfaceの付録基板につなげて遊びたいところだが、なんか手が出ていない。
FeliCa Plugは、なかなか面白い製品だと思う。
NFC-Fとしての側面も持っているし、拡張FeliCaチップ(カード側)という側面もある。
拡張されたFB転送というものが興味深い。
興味深いが、まだ試していないので、書けることがない。
私もまだまだだ。
さて、今回購入したST1020(いろいろあるので、2台購入している)。
後ろを見るとCEマーキングがあるので、輸出も視野に入っているようだ。
自らRFを出すわけでもないので(なのか?)、そっち系の認証は不要なのだろう。
外面からわかるのは、そのくらいだ。
防塵防水なので、多少の水は大丈夫なのだろう。
(うちでは、水の中に沈めるような実験はしません。。。)
私がこの製品で気になったのは、NFC-Fとして動作させた方がよかったのでは?というところだ。
NDEF対応してしまうと、ユーザブロックの0番が属性情報用になるなどして、領域が減ってしまうのは確かだ。
ただ、FB転送ってものを使わないのであれば、とりあえずNFC-Fっぽいこともできるようにしておけばいいこともあるのでは、という気もする。
この辺は実際にやってないので「それはできんのだよ」かもしれないし、「NFC-Fとして認識された方が危険」なのかもしれない。
うーん、自分で調べればわかることを、調べずもせずに書くってのは、最低ですな…。
FeliCa Plugで遊ぶことができる環境はあるので、自分でも作ってみないといかん。
それはそれとして、アイオイさんのスマートタグは製品としてよくできていると思う。
自分で作れそうにないから言うわけではないが、面白味があるのがわかってきた。
とりあえず要望っぽいものを書くとしたら、ストラップを付けるような穴があったらなあー、ということかな。
いや、実際に使うかどうかは別としてね。
最近見てなかったlibnfcだが、ブランチになっていたnew APIがr1304でtrunkに反映されたらしい。
それに伴い、nfc-toolsの方も変更になっている。
私がlibnfcを気にするのは、nfc-toolsにある「libnfc-llcp」を使いたいがためだ。
DEPまでは自分で実装したけど、LLCPみたいに複雑なやつは実装したくない。
使えるならば、既存のものを使いたいのだ。
ただ、libnfcがどこまでPaSoRiをサポートしているのか、よくわからん。
PaSoRiをサポートしてLLCPが動いたっていうのは、nfcpyしか知らない。
やっぱりSonyの人がやってるからかなぁ、という気もする。
人口に膾炙している、というほどではないけど、NFC系のコマンドで一番メジャーなのはこれだろう。
昔書いたのでやめておこうとしたが、軽く流しておこう。
このコマンドは、NFC-A, B, Fのどれでも使える。
コマンド名の通り、PassiveTarget、つまりPICCというかカードというか、そういう人達のリスト化なのだろう。
ただ、RC-S620/Sでは1つのターゲットまでしかやらない。
「MaxTgは0x01」というのがそこだ。
たぶん、Maximum Targetの略だろう。
BRTYは、FeliCa系をとりあえず捉まえたいのであれば、0x01でよい。
個人資料によると、BRTYはこういう値だそうだ。
0x00 : 106Kbps type A
0x01 : 212Kbps FeliCa
0x02 : 424Kbps FeliCa
0x03 : 106Kbps type B
NFC-Aの場合はBRTYまででよい。
NFC-Bはやったことないので、よく知らん。
NFC-Fは、BRTYの次に無線コマンドに載せるパラメータが必要になっている。
見たところ、POL_REQそのものっぽい。
0x00 <システムコード2byte> <リクエストコード> <スロット>
システムコードのところはワイルドカード0xFFが使える。
けどまあ、だいたい"0xFFFF"ってやってるんじゃないだろうか。
FeliCa LiteをNFC-Fに仕立てたときは、"0xFFFF"だと期待するシステムコードにならないので、直接"0x12FC"としなくてはならない。
これは、携帯電話に載っているFeliCaチップも同様だ。
0xFFFFでやると、共通領域のシステムコードが返ってくる。サイバネ領域(だっけ?)のがいるなら、0x0003ってやらんといかん。
BRTYは、BaudRate TTYの略かなぁ。
とまあ、当たり障りのない内容になってしまった。
InListPassiveTargetを実行すると、RC-S620/Sは状態が「モード6」になる。
これは「自分はInitiatorですよ」「あんたはTargetですよ」という状態のようだ。
DEPのときは、モード6にはならないで、別のモードになる。
モード6を抜けて、初期状態のモード0に戻るコマンドは、
のどちらかみたいだ。
というわけで、次はResetコマンドにしよう。
Status:ステータス取得して、左下に表示
左側の数字:レイアウト番号変更
select:転送したい画像ファイルを指定
send:SmartTagに画像転送
register:転送されている画像を選択されているレイアウト番号に登録
昨日、SmartTagが届いた。
飲んだくれていたので、触る力もなく眠る。。。
今日は帰ってきて、動かした。
以前作ったソフトを動かしてみた。
ポーリングは、当然動く。
ステータス取得も動いた。
あとは画像転送とレイアウト設定だけしか作っていないのだが、なんかダメだ。
レイアウト設定は、結構動くのだけど、なぜかたまにだめだ。
画像転送は、Write w/o Encにタイムアウトが発生しているようだ。
CommunicateThruEXのタイムアウトは十分にあるのだけどなあ。
データを作る部分もいくつか間違っていたけど、そう大きくは間違ってないみたい。
ACKは来るから、Write w/o Enc自体は間違ってない。
ということは、SmartTagに送信したデータが今ひとつということか。
シーケンス番号とかのルールは確認しているつもりだが、洗い直さねばな。
いきなり方向転換して、RC-S620/Sで使えるコマンドの詳細説明をしていこう。
といっても、ドキュメントに書いてある以上のことは特にない。
ないのだが・・・私のネタもないのだ。
資料は、SONYさんの技術情報にある「RC-S620/Sコマンドリファレンスマニュアル<簡易版>」だ。
http://www.sony.co.jp/Products/felica/business/tech-support/index.html?j-short=tech-support#Port02
このドキュメントには4つのコマンドが説明してある。
初回は、RFConfigurationコマンドだ。
RFというのは、Radio Frequency、日本語だと「高周波」と書くことが多いが、まあだいたい無線のことを指している。
Configurationは設定だから、無線の設定コマンド、かな。
コマンドコードは0xD4、サブコマンドコードが0x32。
レスポンスコードは、0xD5、サブレスポンスコードが0x33。
これを見てわかるように、レスポンスコードはコマンドコードに1を足したもの、サブレスポンスコードはサブコマンドコードに1を足したものになっている。
「そもそも、コマンドコードとかサブコマンドコードってのは何だ?」と問われると、私もうまく答えられない。
コマンドコードは、ドキュメントに書いてある範囲では0xD4で、コマンドの違いはサブコマンドコードに現れている。
RFConfigurationコマンドは、パラメータCfgItemでさらに機能が分かれていて、それによってデータConfigurationDataも変わってくる。
たとえば、CfgItem=0x05ならば、ConfigurationData=3byteである。
以下は、ConfigurationDataが3つとも0x00のときの例である。
00 00 ff 06 fa d4 32 05 00 00 00 f5 00
そうすると、こういうレスポンスが返ってくる。
00 00 ff 02 fe d5 33 f8 00
RFConfigurationはR/Wに向けて行うコマンドだ。
使うときは、私は2つあると思っている。
起動時に、CfgItem=0x05と0x81を設定。
無線を止めたいとき(強制的に終わらせるときなど)は、CfgItem=0x01。
無線を出すときに、わざわざ使ってはいないな。
困ったことに、「こういう値にしたらいいよ」という指標がわからない。
FeliCa OSの起動時間なんてどっから仕入れればいいんだ。
うーむ。
私は、FeliCa Deveopers' BlogのArduinoサンプルを元にした。
元にしたと言うよりも、当時はこれしか情報がなく、RFConfigurationというコマンド名も知らずにまねをしたというところだ。
ここに書きたいものだが、書いていいのかどうかがよくわからん。
よいなら、追記するかもしれんが、Arduinoのソースを見た方がよいだろう。
私はその値で困っていない(と思う)。
最後に「モード遷移」というのがある。
R/Wは「モード」というものを持っている。
まあ、状態遷移と思っておくれ。
電源ON直後は、モード0。
InListPassiveTargetすると、モード6。
Resetすると、モード0に戻る。
DEPとかFALPとかでモードは変わるんだけど、このドキュメントには書かれていないので割愛。
実装するときは、RC-S620/Sとの通信路が確保できたら(UART接続か)、まず接続確認も兼ねてこのコマンドを実行することになる。
そうして次の、InListPassiveTargetコマンドを実行するのだろう。
ようやくここまで来た。
私が一番注目している、DEP関係だ。
あとこれ以外のネタとなると、RC-S620/Sの扱い方とかになってしまうのだが、これはどこまで書いていいのかよくわからない。
私としては一番書きやすいのだけど、書いていいのかどうかがそもそもわからないのだ。
当たり障りのないところから書く、という手もあるが、はてさて。
DEPは、Data Exchange Protocolの略。
データを交換するプロトコル、だ。
今までを思い出してほしいが、アクセスするのはカード相手だった。
なので、カードに書いたり、カードを読んだり。
しかしDEPは「交換」だ。
自分が送信したデータを相手が受けとり、相手が送信したデータを自分が受けとる。
カードにアクセスするだけと思っていたら、何と通信機器と化すのだ。
興奮する話ではないか!
・・・私だけか?
細かい話をすると、DEPには有名なところで2つの方式がある(私が知らないだけかもしれないが)。
1つは、NFC-DEP。
これは、ISO18092に由来するDEP方式である。
もう1つは、ISO-DEP。
これは、ISO14443に由来するDEP方式である。
残念なことに、私はISO14443のドキュメントを読んだことがないので、ISO-DEPなるものがどういう方式なのかは知らない。
しかし、NXPのPN533ドキュメントを読む限りでは、あまり深く知らなくても使えそうな気がする。
無線のプロトコルとしては、いろいろとコマンドがあったりパラメータが決まっていたりするのだが、有線のプロトコルではそこら辺をうまいことチップが吸収してくれている(と思う)。
私もPaSoRiとRC-S620/SでDEPしてみたが、案外あっさり動いた。
ただ、それがNFC-DEPで動いているのかISO-DEPで動いているのかと問われると、よくわからない。
DEPは、単なるデータのやりとりをするしくみだ。
土管みたいなものである。
土管の両側に人がいて、相手に何かを渡したかったり受け取りたかったりしたら、いくつか確認したいことが出てくるだろう。
などなど。
こういったやりとりを行うために、DEPの上位層としてLLCPというものをNFC Forumでは置いている。
Logical Link Control Protocolの略である。
最近まで知らなかったのだが、インターネットみたいなやつにもLLCってのがあるみたい。
NFC専用の言葉ではなく、ネットワーク用語と思ってもいいのだろう。
IEEE802.2のLLC副層、というものらしい。
ともかく、LLCPはNFCに特化したNFC-DEP制御用のプロトコルである。
(そう、NFC ForumのLLCPは、NFC-DEPなのだ!)
これを使うことで、NFCのInitiatorとTargetでデータ交換をできるというものだ。
しかし、それだけではまだだめだ。
もうちょっとアプリケーションよりの部分まで規定しないと、各自が勝手なルールを作ってしまい、プロトコルが乱立するのが目に見えている。
そう思ったのかどうかは知らないけれども、最近SNEPというプロトコルがNFC Forumで公開された。
Simple NDEF Exchange Protocolの略だ。
読んで文字の通り、シンプルにNDEFを交換するプロトコル、である。
これは、LLCPの上に載っかる。
LLCPの下には、DEPがいる。
そしてDEPが、相手のDEPと通信し、相手にもLLCPとSNEPがいる、という構造。
NFC ForumにSNEPのドキュメントがあるが、短い。
ページ数で20だし、本文は10ページちょっとだ。
Android Beamってのがあるが、あれはSNEPを使っている。
SNEPで送信してみて、相手が受け取れなかったらNPPで送信している。
NPPってのは、NDEF Push Protocolの略。
手元にあるPDFには「Android NDEF Push Protocol」と書いてあるので、Android用なのだろう。
NPPもLLCPの上に載っかる。
おそらく、Android 2.3.4くらいにはこれだけが載っていて、最近の4.0にはSNEPを載せているんじゃなかろうか。
NPPは、おそらく静かに消えていくのだろう。
さて、ISO-DEPが気になるかもしれない。
これは、Android(すまん、Androidの情報しか持ってないのだ)では、APIとして存在する。
あれ、NFC-DEPは?と思うかもしれんが、こっちはAPIがない。
こういう言い方もできよう。
Androidではシステム側がNFC-DEPを使用し、ISO-DEPをユーザに公開している、と。
そんなわけで、私はNFC-DEPできる端末を探しているのであった。
Android端末もできるのだけど、携帯電話は壊れるまで買い替えたくないのだ。
(私は電話の類が、あまりお好きでない。。)
SONYの「NFCアイデアソン/ハッカソン」の6ページを見て、「ああ、Type1 TagはNFC-Aでよかったんだ」、と安心した。
NFC Forumの「Digital Protocol」でも、ちゃんとそう書いてある。
あるのだけど、無線パケットのCRCが、CRC_Bになっているのだ。
用語集には、CRC_BはNFC-BのCRCって書いてあるのに。。。
まあ、そんなことを不思議に思ったけど、NFC-Bはしばらくやることはなさそうだから、忘れてしまおう。
(制御部+11ブロックのデータ部)×13+(制御部+7ブロックのデータ部)
届くのは来週か再来週だろう。
それまではやれることがない・・・と思ったら、アプリのダウンロードができるようだった。
仕様書は届くまでダウンロードできないので、ソースだけでも追っておこう。
とりあえず解析。
あってるかどうかは知らん。
仕様書の複写はいかんらしいが、まだ読んでないし、ソースも修正BSDライセンスだから解析したって問題はないと思うが。。。
こういう解析結果って、載せていいものなのかね?
ライセンスが絡むと、びくびくしていかんなぁ。
よくわからないのが、ユーザデータの扱い方。
1回で512byteまで書き込めるのだけど、アドレスはバイト単位での指定になっている。
サイズは、RFで飛ばしたWrite w/o Encに載せられる分なので、176byteまでになっている。
たぶんEEPROMへ書き込むのだろうから、1セクタ512byteくらいじゃなかろうか。
その512byteが、1回で512byteまでというところにからんでるのだと思う。
だとしたら、512byteアラインでアクセスするようにした方がいいんじゃないかなあ。
まあ、サンプルは必ずアドレス0x000からになっていたので、そこを考慮して作れってことかもしれんがね。
ソースから仕様を読み取るのは難しいですな。
int getBlocks(int bytes)
{
int ret = bytes / BLOCK_SIZE;
if((bytes % BLOCK_SIZE) > 0) {
ret++;
}
return ret;
}
int getBlocks(int bytes)
{
return (bytes + (BLOCK_SIZE - 1)) / BLOCK_SIZE;
}
(0 + 15) / 16 ===> 0だし、1~16なら
(1 + 15) / 16 ===> 1なのだ。
(16+ 15) / 16 ===> 1
(a + (n-1)) / nということになる。
さて、NFC-AなりBなりFなりの仕様を把握し、NFCカードへ書き込んだり、読み込んだりできるようになったとしよう。
その書き込みデータや読み込みデータは、どういう形式になっているだろうか?
答・・・なのかどうかわからんが、私は「書いたとおりに書けるし、読んだように読める」だと思っている。
つまり、書き込むデータを決めるのは書き込む人だし、読み込んだデータをどう扱うかも読み込んだ人次第ということだ。
しかし、それでは各人が好き勝手にやることだろう。
もちろん、それでよい場合もあるのだが、NFCカードを介してデータを交換する、すなわちお互いに意図したデータを書き、それを意図したとおりに読み出すためにはフォーマットが必要になる。
NFC Forumが決めたフォーマットが「NDEF」だ(えぬでふ、と私は呼んでいる)。
NFC Data Exchange Formatの略である。
NFCカードを使って不特定多数の人とやりとりをするならば、NDEFに従うのが無難であろう。
今のところ私は、これ以外にNFCに関するフォーマットを知らない。
人に知られたくない秘密サークル用のNFCカード(あるのか?)であれば、そのサークル内でフォーマットを決めて使えばよいだけだ。
カードをどう使うかは、自由である。
さて、そのNDEFだが、フォーマットはNFC Forumの技術文書ページからダウンロードできる。
今のところ、バージョンは1.0のようだ。
仕様書にありがちなことだが、具体例が少なくて理解がしづらい。
そういうときは、DoCoMoさんの技術ページのなかに、「iCタグリーダー」に関するものがある。
実は、iCタグリーダーはNDEF対応なのだ。
データフォーマット仕様書は、DoCoMoのiCタグリーダーで読むことができるデータという具体的な例なので、わかりやすい。
これを足がかりに理解していくといいのではなかろうか。
NDEFは単なるデータフォーマットなので、これをNFCカードにどうやって書き込むか、というのは別の話になる。
もちろん、各NFCカードに沿った書き込み方法があるのだが、それとは別に、カード内への配置やヘッダなどがカード依存になっている。
その辺りの情報もNFC Forumにあるのだが、これはNDEFのドキュメントではなくTagのドキュメントになる。
例えばNFC-Fの場合、「NFCForum-TS-Type-3-Tag_1.1」というドキュメントに書かれているのだ。
NFC Forumでは、
という分類?になっている。
用語を覚える必要はないだろうけど、なんか分け方があるんだ、くらいは知っておいてもいいのではないかな。