2011/07/31

NFCは一過性か

数年前に作業を選ぶとき、誰も選びそうになかったFeliCa。
そこから、なんとなく見続けているような気がするNFC関係のこと。

当時は「NFC」などという言葉は一般的じゃなかった。
私もFeliCaのことを知るので手一杯で、NFCという分野があることすら知らなかった。

そして今。
人口に膾炙したって程ではないけども、日本で普通の人が「NFC」と書くことも多くなっている。
Taspoのときには何も言わなかったのに、なんで今さら、という気はしなくもない。
それを言えば私だって、何を今さらってことにはなってしまうのだが。

私が知っている範囲では、Androidの影響だ。
でも、それは2.3でNFCを使えるって話が出てきたところなので、ほんの最近だ。
もっと以前に何かあったのではないだろうか。

以下、ネットの検索だけなので、間違っていたら済みません。


ISO18092は、2003年に規格化されたようだ。
14443はそれより前。
ドコモの506iCは2004年。
モバイルSuicaは2006年。

そこから5年。
国内でNFCに特に何かあったか?というと、Taspoが出たり、自動車免許が電子化されたくらいしかわからない。
でも、「Taspoを携帯電話に載せろ」とか、「免許情報を携帯電話で読みたい」という話はついぞ聞かなかったような気がする。
うーむ、よくわからん。


よくわからんが、やはり「急に」人々が口にし出したという印象はぬぐえない。
私もその部類に入るかもしれんな。
んで、長続きするかというと、よくわからん。
NFCは、決済方面か、データ交換方面か、どっちかしかないと思う。
決済方面は、個人では手が出せないので、やるならデータ交換。
データ交換って、できてしまえば、あとはアプリだけの話だ。
アプリとなると興味が持てないのだ。


まあ、それは今の私のお話。
タブレット端末を買おうとしているので、それでまた変わってくるかもしれん。
かわらんかもしれん。
しかしまあ、熱しやすく冷めやすい国民性、と言われるのはしゃくなので、冷めない程度に続けていきましょうかね。

NDEFよ、お前もか・・・

NFC Data Exchange Format。略してNDEF。
NFCでデータ交換するときのフォーマットだ。

・・・。
データ交換するための形式というのは、世の中に数多くあると思う。
「交換」といっても、同時にやりとりするわけではないので、自分から相手に渡すだけだ。
まあ確かに、RFでのデータやりとりは、なるべくさっさと済ませたい。
1byte送るのに何マイクロ秒かかるから・・・なんて計算をしょっちゅうやってるので、気持ちはよくわかる。
わかるんだけど、けっこうここら辺で使ってる通信って、速度が速いやん。
そんなに独自の形式にこだわらなくていいんじゃないのかなぁ・・・。

私としては、OBEXとかバイナリXMLとか、もう既に存在するフォーマットを使ってほしかったな。
しゃーらしいので、作業をふやさんでほしい。

まあ、個人の声が届かないから好き勝手出来るってのもあるんだけどね。


まず、NDEFには「NDEF message」がある。
NDEF messageは、1つ以上の「NDEF record」がある。

・・・
・・・・・・

なんか、どこのフォーマットも、どれもこういう形式やん。
BIFFだってDICOMだってXMLだって、バイナリやテキスト関係なく、結局のところはこういう形式にならざるを得ない。
みんな同じようなものを別の意味で持たせるので、使う人達は同じようなパーサを毎回作らなくてはならない。
なんか、ばからしい。

そんなわけで、資料を読むのはやめた。
人が作ったライブラリをいただくことにしよう。
なかったら、いるものだけ作ればいいや。

[c++]暗黙のキャスト

ここ最近、Cでしか書いていないので、C++のことはずいぶん忘れている。
ちょっと思い出していかないといかん。

Qtの本を読みながらソースを見ていくと、こんな行があった。

  newAction
->setShortcut(tr("Ctrl+N"));

Ctrlキー+Nキーを押したときに動作するのだ、ということを設定している。

私が思ったのは「Qtって、文字列に書いたら自動的にやってくれるんだねぇ」だった。
しかし、文字列ってことは、誰かがそれを解析していることになる。
解析して、「Ctrl」と「N」に分割して、それをフラグにしてうんたらかんたら、となるはずだ。
そういう処理は、私はあまりお好きではない。
できればフラグで与えてしまって終わり、としたい。
解析にコストをかける必要がないときには、なくしてしまいたい。

では、とQAction::setShortcut()の仕様を見た。

void QAction::setShortcuts ( constQList<QKeySequence> & shortcuts )

void QAction::setShortcuts (QKeySequence::StandardKey key )

この2つしかない。
暗黙で何か行われているようだ。


intやcharなどのプリミティブ型は、よく暗黙でキャストされている。
また、継承関係にあるクラスについても、よくあることだ。
そうでない場合、何かしてやらないといけないと思う。
ここら辺の記憶が曖昧なので、順に見ていこう。


まず、引数から。

tr("Ctrl+N")

QString QObject::tr ( const char * sourceText, const char * disambiguation = 0, int n = -1 )[static]

trはQObjectクラスのstatic関数で、ほぼすべてのQtクラスはQObjectを継承していると思う。
なので、QObject::をつけずにアクセスできる。
この人は、QStringオブジェクトを返している。

QAction::setShortcuts()は2つあるが、片方はいかにもコンテナって感じなので、気にしなくてよいだろう。
今回呼び出されているのは、引数がQKeySequence::StandardKey型の方のはず。。

QKeySequence::StandardKeyというのは、enumだ。
数値とQStringに互換性はないな・・・。

QKeySequenceクラスにこういうのがあった。

QKeySequence::QKeySequence ( const QString & key )

これは、なんか近いぞ。
QKeySequence::StandardKey型ではなく、QList<QKeySequence>型をとるのだろうか。

QList::QList ( const QList<T> & other )

違うな。
なにかおかしい。。。。


ここでQActionのヘッダを見ていると、こうなっていた。

void setShortcuts(const QList<QKeySequence> &shortcuts);
void setShortcuts(QKeySequence::StandardKey);

やはり、ヘルプに漏れがあるわけではないのか。。。ん?

void setShortcut(const QKeySequence &shortcut);

単数形の関数がある!
しかし、ヘルプにはなかったぞ??

ヘルプ内を検索してみると・・・関数名一覧やショートカットの説明には出てきたけれども、関数詳細には出てきていなかった。
何と言うことだ・・・・。


void setShortcut ( const QKeySequence & shortcut )


はい、こんな実装です。
つまり今回では、QStringが暗黙でQKeySequenceオブジェクトに変換(生成)されていた、というわけだ。
ヘルプで関数仕様がわかれば、たぶんネタにしてなかったお話だ。

引数の型変換ついては「プログラミング言語C++ 第3版」の「11.3.5 コンストラクタと変換」に記載されている。
パフォーマンスに影響がないなら、同じ内容の関数を引数ごとに作るよりも、オブジェクトの自動変換に任せてしまっていいんじゃないの、というところだ。


プログラミング言語C++は、読むのが難しい本だ。
「勉強するんだから原典を読まないと!」と思って買ったものの、詳細がよくわからないときにしか読んでない。
食材買いに出かけるので、本屋に寄ってみましょうかね。

2011/07/30

PaSoRi以外のR/Wに選択肢はあるだろうか

今日FeliCaに詳しい人と話していて、PaSoRiを開発用途で使うのはFNさんとしてはやっぱりよろしく思わないだろうなぁ、という気がしてきた。
個人で楽しむ分には気にはしないけれども、代替えがあるのかどうか考えてみた。



まず出てくるのは、RC-S620/S。
これはUARTなので、組込機器としては使いやすい。
しかしこれが製品のAndroid端末向けとなると、ちょっと話が変わってくる。
たぶん、Android製品でUARTポートを持つものはないと思う。
そうなると、USB変換しなくてはならない。
うちにはCP2102があるので、これを使えばUART-USB変換ができる。
できるのだが、今度はAndroid側でUART制御ができなくてはならない。

Linuxであれば/dev/ttyUSB0などでアクセスできる。
しかし、それは/dev/ttyUSB0へのアクセス権があるからだ。
何もしなければ、rootの人しかアクセスできないので、アプリからは使えない。
最近のAndroidでは、udevを使ってアクセス制御ができるようになっているが、どっちにせよアクセス許可がユーザにまで広げられていないとだめだ。

そして、カーネルがシリアル変換を有効にしているかどうか、ということもある。
ユーザに公開しないし使うようにしないのなら、ドライバレベルでOFFになっているかもしれない。


Androidアプリ側でUSB機器を制御することを考えると、実はドライバが対応していない方がいいのかもしれない。
ここはまだ調べていないのだが・・・。

Android3.1からは、USB Host機能が使用できるようになっている。
まあ、少なくともAPIは追加されているので、製品として使えるようにしてあるなら、使えるだろう。

カーネルがUSB Hostに対応するだけなら、ドライバが対応していればいい。
例えば、USBキーボードを挿すとそこから文字入力ができる、などというしくみはアプリではなくドライバが対応していて、Androidのプラットフォーム側が利用していると思われる。

そう考えると、ドライバとしては認識されていないUSB機器だけがAPIで制御できるのではなかろうか。
下からと上からアクセスされるのをプラットフォームはよしとすまい。
ならば、UART-USB変換がドライバとして対応されていない方が、USB Host機能を使うにはよいのかもしれない。


しれないが・・・CP2102の仕様書を読んでドライバをアプリでやるのか・・・という思いはある。
めんどくさい。
まあ、できるようになっておくと今後としてはいいのかもしれんが・・・。

結論を急がず、別の選択肢を考えてみよう。


「UARTがだめなら、最初からUSBにすればいいじゃないの」ということで登場したのかどうかわからないが、RC-S620/Uという製品がある。
シリアル版が「S」で、USB版が「U」なのだろう。
これなら、何も考えずに使えるのではなかろうか?

ネットで検索したが・・・情報が出てこない。
そもそも、一般人が入手できそうなルートが見当たらない。
なんだろう、PaSoRiとの棲み分けが難しいのだろうか。

気にはなるが、入手できないなら仕方ない。


ならば、SONYから離れざるを得まい。

と探してみたが、これもまた選択肢が少ない。
IOデータの「ピタっち」が一番近いのだが、生産中止になっている。

ACR社のものが近いと言えば近いのだが・・・開発に使っていいのかわからん。
SDK買った人ならいいよ、なのかもしれん。
それならPaSoRiも同じだよなぁ。。。



結局のところ、PaSoRiも明示的に「開発に使うな」とは書いてないのだ。
見つけていないだけかもしれんが・・・。
たぶんNGなのは、PaSoRiとの通信をモニタすることだろう。
昔のソフトにはよく「解析するな」みたいな文言が書かれていたものだ。

まあ、PaSoRiが本当に動かせてから考えるとしよう。
杞憂になってしまうのは技術者的には嫌なのだが、なんらかの理由でできないかもしれんしね。

2011/07/26

Android Marketにおいたアプリのコメントがいくつか見られん

久しぶりでございます。
忙しいので、休日はぐったりしています。
けっして、二日酔いで身動きがとれず、起きてもぼーっとして何もしてない、というわけではありませんよ。


久しぶりに、自分のAndroid Market状況を見てみた。
一番評判がいい(ダウンロードが生きてるのが多い)のは、Eject SD、というアプリ。
ただ・・・ルート化した人くらいしか動いていないような気がする・・・。
まあ、動いて役立ってる人がいるなら、いいや。

それはいいとして、コメントを見ようとしたらエラーが出た。
「現在のバージョンのアプリケーションで請求権限が使用されていないため、新しいアプリ内サービスを追加できません。」
なんだろう?
「請求権限」って、なかなか仰々しい言葉だ。

ここ1年くらい、まともに見てないからなぁ。
なにか必要な項目が増えて、それが空欄になったままなのかもしれん。

2011/07/20

DPI (2)

またまたコメントをいただきました。
ありがとうございます!


http://japanese.engadget.com/2011/05/23/honeycomb-gingerbread-ui/

なんと、DPIが大きくなると2.3のHOME画面が出てくるらしい。
ほほぅ。

DPIって、dot per inchの略だったはずだ。
つまり、1インチ中のドット数。
でも・・・インチって長さの単位だよなぁ。
なので、ドットで1インチを作るには何ドット必要になるか、ということだ。
画面の広さではなく、細かさを表すことになる。

エミュレータで見たとき、2.3とかは240dpiだけど、3.1とかは160dpiだった。
つまり、Honeycombの方が粗めになると考えていることになる。
たしかに、携帯電話の画面は小さい癖に解像度が高い。つまり、密度が高い。
だからDPI値が大きくなる。
タブレットは画面が広い分、小さめになるということだ。

なら解像度を高くすればいいやん、と思うかもしれんが、描画が重たくなる。
重たくなると使いもんにならんから、いいエンジンを積む。
いいエンジンは速いけど、それだけエネルギーを食う。
つまり、電池の持ちが悪くなる。



ソースファイルを検索してもらった
前回載せたログに「未設定だから160dpiにするね」というやつは、DisplayHardwareで出していることがわかる。
C/C++でプロパティを取ってくるときは、property_get()を使う。

Javaの場合は、SystemProperties.getXXX()で取ってくるようだ。
ここは整数値なので、getInt()なのだろう。

Javaのソースに、興味深い数値があった。
160とか240とか、さっきのDPI値ではないか。
160はMEDIUMで、240はHIGH。
これは、Android Developersにも書いてある。


むう、3.2になって、また追加があるらしい。
うちのAndroidたちは160dpiと認識されているみたいだから、そっちの影響か??
まだまだ奥が深そうだ・・・。

まあ、HOMEアプリのソースを見ればいいんだろうけど、やってもそれは週末だな。

DPI

3.2_r1を載せてもホーム画面が変わらん、と書いたら、コメントをいただいた。
いつもありがとうございます。
「DPIが関係していた、という記事を読んだような・・・」
はい、それくらいの情報があれば、見てみますわ。


とはいえ、今日はきついので、自分のところのログだけ探しておこう。
こういう作業をしていて大切なのが、dmesgとかlogcatとかのログ。
どういうときのログかということまで書いてあると、かなりよい。


■SmartQ5 : 2.3.4

I/gralloc ( 1890): id           = s3cfb
I/gralloc ( 1890): xres = 800 px
I/gralloc ( 1890): yres = 480 px
I/gralloc ( 1890): xres_virtual = 800 px
I/gralloc ( 1890): yres_virtual = 960 px
I/gralloc ( 1890): bpp = 16
I/gralloc ( 1890): r = 11:5
I/gralloc ( 1890): g = 5:6
I/gralloc ( 1890): b = 0:5
I/gralloc ( 1890): upper_margin = 10
I/gralloc ( 1890): lower_margin = 35
I/gralloc ( 1890): left_margin = 40
I/gralloc ( 1890): right_margin = 216
I/gralloc ( 1890): pixclock = 33358920
I/gralloc ( 1890): width = 800 mm (25.400000 dpi)
I/gralloc ( 1890): height = 480 mm (25.400000 dpi)
I/gralloc ( 1890): refresh rate = 60.00 Hz
W/SurfaceFlinger( 1890): ro.sf.lcd_density not defined, using 160 dpi by default.

■BeagleBoard(C4) : 2.3.3

I/gralloc (  823): id           = LCD-8000U
I/gralloc ( 823): xres = 800 px
I/gralloc ( 823): yres = 600 px
I/gralloc ( 823): xres_virtual = 800 px
I/gralloc ( 823): yres_virtual = 1200 px
I/gralloc ( 823): bpp = 16
I/gralloc ( 823): r = 11:5
I/gralloc ( 823): g = 5:6
I/gralloc ( 823): b = 0:5
I/gralloc ( 823): width = 127 mm (160.000000 dpi)
I/gralloc ( 823): height = 95 mm (160.421051 dpi)
I/gralloc ( 823): refresh rate = 77.22 Hz
W/SurfaceFlinger( 823): ro.sf.lcd_density not defined, using 160 dpi by default.


ro.sf.lcd_densityってのがあると、それを使うみたいだ。


では、エミュレータの方を見てみよう。
といっても、これは起動設定を見ればいいや。
・・・あれ、LCD densityは160になってる。
Targetを変えていくと、どちらかといえばdensityは上がっていく。240とか。
うーむ。

よく見ると、他にも変化しているパラメータがあった。
Skinという項目で、画面解像度を示しているようだ。
これは、3.1とかだとWXGAになる。
WXGA ??

1280x768くらいの広さらしい。
うみはーひろいなーおおきーなー。

そういえば、私も画面の広さについて記事を読んだ覚えがある。
solaさんのこちら、だ。

まあ、うちのDisplayLinkでは難しいのかもね。
めんどくさくなってきたので、DVI-Dが使えるモニタを買うか、もうAcerのA500とか買うか、なんて考えてしまう。
いかんいかん、暑くて思考がよたよたしてるのだろう。

2011/07/18

librcs370の使い方

https://github.com/hirokuma/librcs370

では、適当に作ったlibrcs370の説明をします。
ほとんど動作確認していないので、動かなかったらごめんなさい。


■用途
PaSoRi RC-S370を、単なるRC-S956として扱います。


■用意するもの
PaSoRi RC-S370
zadig(Windowsの場合)
・libusb-1.0が使える環境


■準備
libusb-1.0を使えるようにする
・zadigでPaSoRiをWinUSBにしておく(Windowsの場合)


■使い方
・librcs370のインスタンスを作ります。
・open()を呼びます。PaSoRiにアクセスできるならtrueが戻ります。
・書き込みたいコマンドをwrite()し、読みたいときはread()します。
・使い終わったらclose()を呼びます。voidです。

■その他
・cygwinでしか動作させていないので、インクルードパスが特殊かもしれません。
  #include <libusb-1.0/libusb.h>
 としている箇所のパスを、環境に合わせてください。
・ACKの処理などは一切しません。
FeliCaポートの技術資料を読んで、コマンドをやりとりしたいときに使えるでしょう。
・悪いことに使わないでください。

2011/07/17

Android3.2_r1のソースにはUsbDeviceConnectionがない

今の時点では、という但し書きが必要かもしれないが、Android3.2_r1のソースにはUsbDeviceConnectionがなかった。

最初検索しようとしたのは、bulkTransfer()。
libusbを使っている箇所がなかったように見えたので、違う実装が何かあるのかもと思ったのだ。
しかし、jgrepでひっかからず。
ないのか。

では、とUsbDeviceConnectionをjgrep。
これも見つからない。
ないんだ。。。

android.git.kernel.orgのmasterにもないから、ないんだろうな。
API12が動かせる環境がほしいのだけど、そう簡単にいかないのか。
うーむ。

Android 3.2_r1にはlibusbが使われていないのか?

libusbにAndroid.mkがない、という話を書いた。
では、libusbはどうなっているのだろうか?


こういうときはcgrep。

external/qemu/
external/bluetooth/
external/libusb/
external/libmtp/
external/libusb-compat/
system/core/adb/

ほとんどヒットしない。
特に、frameworks以下にはまったくない。

うーん、この面子からすると、API 12のUSB部分は実装されてないのか、私の予想が違うのか。
むぅ・・・。

BeagleBoardにAndroid3.2_r1を入れたけど、見栄えが変わらん

BeagleBoardにAndroid3.2_r1を入れてみた。
そんなに難しいことはせず、Android3.2_r1のソースに、2.3.4で使っていたdevice/以下を入れたくらい。
音とかカメラとか、そんなデバイスは全部オフだ。

~/android-3.2_r1$ printconfig
============================================
PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=3.1.4.1.5.9.2.6.5
TARGET_PRODUCT=beagleboard
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=OPENMASTER
============================================

起動はあっさりできた。
さあ、あの黒い禍々しい?画面が出るのか・・・出ない。
いつもの、あの青い画面だ。
えー、そうなのー。




なんとなく、残念だ。
残念だというよりは、何が違うんだ??
HOMEアプリが違うだけなのかなぁ。。。

Android 3.2_r1のlibusbにはAndroid.mkがなかった

はい、タイトルどおりです。。。

Android 3.2のソースがあるのでビルドして、エミュレータまで動いた。
まあ、エミュレータだからUSBはサポートしてないですな。
しかしビルドくらいはされてるだろうとout/以下を見たけど、ない。

なにかオプションをつけないとビルドされないのかも、とexternal/libusbを見ると・・・なかった。
Android.mkがないのだ。
うーむ。。。

コミットログには、こう書かれていた。

Move the libusb source from jumper to external

なんだろうね。。

Android API12を使ったRC-S370アクセスサンプルを作ったが、動くかわからん

わからんシリーズ。
とはいえ、これは環境がないのでわからないというタイプだ。
Android APIではUSB Hostが扱えるのだけど、うちにはそんな端末がない。
USBはエミュレータも対応してないので、どうしようもないのだ。

https://github.com/hirokuma/librcs370/raw/master/TestRcs370.apk

ファイルとして保存してください。
すくなくとも、うちでアクセスするとファイルの中身がべろーんと見えます。。

そしてお願いが。。
動かした人がいらっしゃれば、コメントしていただけるとありがたいです。
タブレットを買うって選択もあるんだろうけど・・・。


ああ、説明をしてなかった。

これは、PaSoRiのRC-S370を接続したらRESETコマンドを投げて、ACKが返ってくるのを確認するアプリです。
ただそれだけなので「PaSoRi使い放題!」みたいなものではありません。


あれから、Android Marketに置きました。
動くかどうかは、相変わらずわかりません。

https://market.android.com/details?id=com.blogpost.hiro99ma.testrcs370&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5ibG9ncG9zdC5oaXJvOTltYS50ZXN0cmNzMzcwIl0.

RC-S370用の簡易ドライバ

ドライバって位置はWinUSBやlibusbが担っているけど、各種デバイスにアクセスする方法まで提供するのがドライバだ、ということになれば、今回作成したものもドライバと呼んでよかろう。

作ったのは、うちにあるPaSoRiのRC-S370にアクセスするドライバ。
アクセスするといっても、できるのは読み書きだけ。
しかも、カードへの読み書きではなくRC-S370への読み書き。

git://github.com/hirokuma/librcs370.git

つくりは至ってシンプル。
libusbでオープンした後は、バルク転送しているだけ。
土管だ。

PaSoRiってドライバを作ってはいけない、とかいう規定があったらいかんと思って取扱説明書を読んだけど、なかった。
よかったよかった。
業務用途で使えない、なんていうことは書かれてたけどね。

さて、なんでこんな土管を作ったかというと、RC-S620/Sと同じようにアクセスしたいからだ。
小さいシステムではUSBなんか用意できないからRC-S620/Sみたいなものがいいんだけど、AndroidだとUSBポートが使えるのでPaSoRiで十分だ。

Androidではlibusb-1.0系が入る準備ができている。
git://android.git.kernel.org/platform/external/libusb.git

以前はlibpafeを使うためにlibusb-0.1.12を移植していたのだが、オリジナルから持ってこれるだろう。
そのときにはlibpafeを外し、今回作ったドライバで置き換えてしまえる。
ありがとう、libpafeよ。

んで、最終的にやりたいのは、android.hardware.usbへの置き換え。
おそらく内部ではlibusbを使っているだけだと思うので、容易そうではないか。
午後からやってみるか。
まあ、やったとしても試せないんだけどね。

[github]gistってのがある

ツールの分類が「無駄話」なのは申し訳ないが・・・めんどうなのでこのままいこう。
githubのサイトにいくと「gistはじめました」みたいなことが書いてあった。
なんだかわからないので調べてみると、ちょっとしたログとかソースなどをgitで管理する手軽ツールみたいなものみたいだ。
試しに、libusb-1.0でエンドポイントを検索する部分を載せてみた。
見えるかしら?
public gistとprivate gistってのがあって、たぶんpublicだと見えるはず。。。

libusb-1.0はzadigを使うべし

前回、ドライバがunsupportedと認識されていることがわかった。
ログを追加してみると、ドライバは「libusb0」という名前になっていることがわかった。
Windowsのlibusbをインストールしたときにinf-wizardというのがあって、それを使ったからだ。
確か、libusbを使うんならオリジナルのドライバではなく、そっちを使うんだよな。

libusb-1.0のソースを見ていくと、WinUSBというドライバが出てくる。
しかし「libusb0」みたいな名前は出てこない。
WinUSBって、MicrosoftのWinUSBだろうと思って気にしていなかったのだが、私の認識が違う気がしてきた。


もう一度、libusbのページを見た。
そして気付いたのだが、libusb-1.0はwindows_backendの方なのだ。
私がinf-wizardとかなんとか言っていたのは、libusb-win32で、こっちはlibusb-0.1だ。
libusb-0.1ではドライバが「libusb0」みたいな名前だけど、libusb-1.0では「WinUSB」なのだろう。
そうなってなかったので「unsupported」と言われたわけだ。


推測だがlibusb-1.0の「WinUSB」はMicrosoftのWinUSBだと思う。
zadigというexeファイルを実行すると、自動的にドライバを置き換えてくれるけど、これはWinUSBのinfを自分で書かなくていいようにしてくれているんではないかなぁ。


zadigでドライバを置き換えると、ちゃんとlibusb_open()が動くようになった。
まあ、ちゃんと読めって話ですな。

2011/07/16

libusb_open()でLIBUSB_ERROR_NOT_SUPPORTEDが返ってくるが、わからん

わからんシリーズ。
cygwinで、libusb-1.0を使ったサンプルを書いていた。
まあ、本当はサンプルではないのだが・・・うまくいかんのでね。

libusb_init();
libusb_get_device_list();
while() {
 libusb_get_device_descriptor();
 目的のVID/PIDだったらbreak;
}
libusb_open();
libusb_free_device_list();


だいたい、こんな感じ。

その中の libusb_open() で -12が返ってくる。
ヘッダを見ると、

/** Operation not supported or unimplemented on this platform */
LIBUSB_ERROR_NOT_SUPPORTED = -12,


となっている。

そっか、cygwinではlibusb_open()はサポートされてないんだな。
うんうん。

いやいや、ちょっと待て。
libusb_open()ができんかったら、libusbは使えないも同然やん!
現在の最新版はlibusb-1.0.8なのだが、cygwinでは1.0.7+となっている。
おそらくcygwin用のパッチが当ててあるのだろう。
そんなわけで、ソースファイルはcygwinのsetup.exeを使って落としてきた。
cygwinのソースファイルは初めてなのだが、今回は/usr/srcに落とされていた。
bz2とpatchとshの3ファイル。
使い方がわからん・・・。

スクリプトをちょっと眺めると「help」というのがあった。

$ ./libusb1.0-1.0.7+gitbd62c472-1.sh help
This is the cygwin packaging script for libusb1.0-1.0.7+gitbd62c472-1.
Usage: ./libusb1.0-1.0.7+gitbd62c472-1.sh [
Options are:
 help, --help Print this message
 version, --version Print the version message
 with_logs, --logs Create logs of remaining steps
Actions are:
 prep Unpack and patch into /usr/src/libusb1.0-1.0.7+gitbd62c472
 mkdirs Make hidden directories needed during build

 conf, configure Configure the package (./configure)
 reconf Rerun configure
 build, make Build the package (make)
 check, test Run the testsuite (make check)
 clean Remove built files (make clean)
 install Install package to staging area (make install)
 list List package contents
 depend List package dependencies
 strip Strip package executables
 pkg, package Prepare the binary package libusb1.0-1.0.7+gitbd62c472-1.tar.bz2
 mkpatch Prepare the patch file libusb1.0-1.0.7+gitbd62c472-1.patch
 acceptpatch Copy patch file libusb1.0-1.0.7+gitbd62c472-1.patch to /usr/src
 spkg, src-package Prepare the source package libusb1.0-1.0.7+gitbd62c472-1-src.tar.bz2
 finish Remove source directory /usr/src/libusb1.0-1.0.7+gitbd62c472
 checksig Validate GPG signatures (requires gpg)
 first Full run for spkg (mkdirs, spkg, finish)
 almostall Full run for bin pkg, except for finish
 all Full run for bin pkg


prepを使うと、カレントディレクトリにファイルが展開された。


LIBUSB_ERROR_NOT_SUPPORTEDをgrepしてみると、何箇所かあった。
さて、このうちのどこなのか・・・。
いつもならログを埋め込んでいくところだが、ソースを見ていると既にある。
usbi_dbg()というものだが、これはログ有効ビルドをしていないと出ないらしい。

$ ./configure --enable-debug-log
$ make
$ make install


libusbのAPIにも、libusb_set_debug()というデバッグ出力を有効にするものがある。
だが、ここまでのログはさすがにビルドし直さないと出ないようだ。
大量のログが出て、libusb_open()のときにはこんなのが出ていた。

libusb:debug [libusb_open] open 3.1
libusb:debug [unsupported_open] unsupported API call for 'open' (unrecognized device driver)

ほほう。
検索すると、os/windows_usb.hにマクロがあった。

#define PRINT_UNSUPPORTED_API(fname) \
 usbi_dbg("unsupported API call for '" \
 #fname "' (unrecognized device driver)" #line); \
 return LIBUSB_ERROR_NOT_SUPPORTED;


ふんふん、引数でopenが渡されているのだな。
では「PRINT_UNSUPPORTED_API(open)」で検索。
os/windows_usb.cにあった。

static int unsupported_open(struct libusb_device_handle *dev_handle) {
 PRINT_UNSUPPORTED_API(open);
}

えっ・・・。
なんか、嫌な感じだ。
unsupported_open()は、usb_api_backend[0]の中にあった。
このusb_api_backend[0]は、unsupported_XXX()だけだ。

usb_api_backend[]は4つあって、
 usb_api_backend[0] = unsupported_XXX()
 usb_api_backend[1] = composite_XXX()
 usb_api_backend[2] = winusb_XXX()
 usb_api_backend[3] = hid_xxx()
という割り当てになっている。
まあ、関数テーブルだな。
デバイスの種類に応じて添字が決まるのだろう。

つまり、libusbでopenするデバイスはどれでも同じ処理をするのではなく、デバイスの種類に応じた処理をするということがわかる。

libusb:debug [libusb_open] open 3.1
この「3.1」は、バス番号(bus_number)とデバイス番号(device_address)なので、意味はない。



cygwinでlibusbのがコンパイルできんのはコンテキストメニューから起動させたため

前回、libusbをcygwinにsetup.exeでインストールして、アプリもコンパイルできた。

できていた。

しかし、今日やるとコンパイルエラーが出る。

[libusb-1.0.8/examples]$ gcc -o tst lsusb.c
lsusb.c:23:31: error: libusb-1.0/libusb.h: No such file or directory

/usr/includeを含めても、だめ。
/usr/include/libusb-1.0まで指定しても、だめ。
なんだこりゃ?

$ gcc --print-search-dirs
install:
c:\qtsdk\mingw\bin\../lib/gcc/mingw32/4.4.0/
・・・

あれ?

$ which gcc
/cygdrive/c/QtSDK/mingw/bin/gcc


あれれ??
cygwinで使うのに、/usr/binではないgccになってる。
なんでだろう。。。

念のため、いつも使っているcygtermではなく、"Cygwin Bash Shell"からやってみる。

$ which gcc
/usr/bin/gcc

ということは、cygtermか?
スタートメニューから"cyglaunch"を起動させると・・・ちゃんと/usr/bin/gccだ。
どうやら、コンテキストメニューから"Cygterm Here"で立ち上げるとこうなるみたい。

しかし、ファイラの「あふw」からは、同じようなことをして問題がない。
こんな設定で開いている。
C:\Program Files\teraterm\cyglaunch.exe -nocd -v CHERE_INVOKING=y -d \"%L\"

では、コンテキストメニューの設定を見てみよう。
HKEY_CURRENT_USER\Software\Classes\Folder\shell\cygterm\commandにある。
"C:\Program Files\teraterm\cyglaunch.exe" -nocd -nols -d \"%L\"

ふむ、CHERE_INVOKINGかnolsのどっちかのようだ。
ここに説明があった。
なるほど、ログインシェルを起動するとカレントディレクトリが移動してしまうから、ということか。

書き換えると、ちゃんとなりました。
そういえば、コンパイルが通った後でTeraTermの最新版をインストールし直したからな。
その辺で元に戻ったのかもしれん。

2011/07/15

cygwinでlibusb

cygwinでlibusbを使ってみたくなった。

ソースファイル一式(libusb-1.0.8.tar.bz2)をダウンロード。
解凍して、configure。

・・・OSがだめって。

こういうときは、まずsetup.exeから探してみよう。
あったあった。
libusb-1.0。
そして・・・私は既にインストール済みだった・・・。

ならば、とソースに入っていたサンプルのlsusb.cをコンパイル。

$ gcc -o lsusb lsusb.c

インクルードファイルがないと。
ソースでは<libusb/libusb.h>となっていたので、一式に入っていたlibusb.hを使おう。

$ gcc -I.. -o lsusb lsusb.c

今度はリンクで引っかかる。
-lusbでもだめだったので検索すると、libusb-1.0.aがあった。

$ gcc -I.. -o lsusb lsusb.c -lusb-1.0

これでもだめ。
うーむ。

cygwin版とソース版ではAPIに違いがあるのかも。
検索すると、/usr/include/libusb-1.0/libusb.hがあった。
そんなわけで、ソースファイルを<libusb-1.0/libusb.h>に変更。

$ gcc -o lsusb lsusb.c -lusb-1.0

おー、通った。


2011/07/13

Android 3.2_r1のソースファイルがあるらしい

あるらしいのだ。
JBQ氏がいうから、そうなのだろう。


$ repo init -u git://android.git.kernel.org/platform/manifest.git -b master -m 3.2-base.xml
$ repo sync
$ source build/envsetup.sh
$ m -j5

さて、ビルドしている間に「3.2-base.xml」のことを考えてみよう。
3.1-base.xmlなどというものがあることは、気がついていたのだけど、なんだかわからなかったのだ。android.git.kernel.orgに新しいブランチが出たかどうかは、ここで確認している。
今日は一番上に「master」があるので、一番右端にある「tree」をクリックしてみよう。
今だと、こんな画面が出てくる。


-rw-r--r-- 21776 3.0-base.xml
-rw-r--r-- 22340 3.1-base.xml
-rw-r--r-- 23240 3.2-base.xml
-rw-r--r-- 14204 default.xml

なんだかわからないけど、これを「-m」で指定するようだ。
-mはマニフェストファイルを指定するそうで、未指定では「default.xml」を使用するとのこと。
説明がちゃんとありました。



お、ビルドが正常に終わったようだ。

$ out/host/linux-x86/bin/emulator @avd12

こんなので動きました。
avd12、というのは、eclipseから「Android SDK and AVD Manager」を立ち上げて作りました。

コマンドラインでAVDを作るときは、こんなのらしい。

$ android create avd -n avdmof -t 7

mofは気にしないでくれ。暑いんでもふもふしたいだけだ。
-t 7の「7」は、APIのバージョンとかじゃなくて、「android list targets」に出てくるIDらしい。
これで作ったAVDで起動させるなら、@avdmof、ということだ。


しかし・・・タブレットになってからさっぱり使い方がわからん。
ホームボタン長押しではなく、その横にあるボタンをクリックすると実行中のアプリ一覧が出てくることは分かった。

2011/07/12

[felica]RC-S620/Sのコマンド仕様が簡易版ながらも出た

なんとなくFeliCaの技術資料ページを見に行くと、RC-S620/Sのドキュメントがあるではないか!

FeliCaポート

ちょっと気を抜いていたので、見逃すところだった。
あぶないあぶない。
資料公開に尽力された方々へ感謝します。


提供されたのは「製品仕様書<簡易版>」と「コマンドリファレンスマニュアル<簡易版>」だ。
製品仕様書は、ハードウェア周りの仕様で、なんというか納品仕様書みたいなもの(なんじゃそりゃ)。
私はこっちを見ても、あんまりピンと来ない。
が、配線なんかは書かれているので重要だ。

そしてコマンドリファレンスマニュアルは、いわゆるFeliCaコマンドの解説だ。
残念ながら、RC-S956で使えるすべてのコマンドではない。
しかしこれがあれば、自分でRC-S620/Sを買ってきて、カードのIDmを取得するところまでを自作できる。

というのも、今まではRC-S620/Sの初期化に関する資料がなかったのだ。
Arduino向けのサンプル雑誌Interfaceなどを参考にするほかなかった。
もちろん参考にしても動くのだけど、これだと「個人の趣味レベル」でしかない。
仕事でいいアイデアが出て「RC-S620/S使いましょうよ!」と言い出したとしよう。
たぶん、こう言われる。

「仕様書は?」(すぐに言われたりはしないだろうけど。。。)

もちろん、仕様書は入手できる。
しかし開発環境とセットになる(だったはず)。
少なくとも、ドキュメント単体での入手はできないだろう。
単にIDm取得くらいでいいのに、開発環境を買うとオーバースペックだ。
別に買うのに反対しているわけではないが、小さな会社だと初期投資するのが難しく・・・。

そんなわけで、SONYさんから正式な資料として出てきた意味は大きい。
もうちょっと人口に膾炙して、NFC-A/Bあたりも使えるって資料が出るといいなあ。
そんな期待をしつつ、なんか作らないかんな-、と思った私であった。

2011/07/10

[q5]現状を置く

SmartQ5の作業が進まんが、現状をgithubに置いた。


https://github.com/hirokuma/OHA-Android-2.3.4_r1.0/tree/smartq5

branchが違うので注意してくだされ。
また、これはSDカード版なので、インストールの際も気をつけてください。


busyboxのシンボリックリンクなんかが、gitでどう扱われるか知らないので、cloneして変だったらオリジナルのに置きかえてください。

本家はgithubではなくてgitoriousなので、ちと心が痛みます。。。
各フォルダごとにgitでうんたら、ってのは、めんどくさくてね。。。

[q5]マージが全然足りてない

まだQ5をやっている。

画面の件はひとまず置くとして、デバッグできないのは困る。
adbで通信するなり、telnet接続するなりしたい。
それをやるには、Coviaの設定画面から入る。
つまり、Covia版の設定アプリからいくつかマージしないといかんのだ。

適当にマージしたのだが、今度はBluetooth設定でビルドエラーが。
どうやらCovia版はHIDに対応していて、そのソースが組み入れられているようなのだ。
マージしようとあれこれやったけど、frameworks/base/core以下を修正した時はmコマンドだけではビルドが足りないみたいな感じを受けた。
たしか、更新するようなコマンドがあったのだけど・・・。
忘れたので、Bluetoothは捨てることにしたT。

では、とUSB設定をビルドすると、やはりエラーが。
IStatusBarがない、と。
ここら辺は、froyoからgingerbreadで変更になったところのように見える。
IStatusBarServiceに変更するとよさそうなのだが、今度はdrawableが足りない、と。
frameworks/base/core/resにUSBのファイルをコピーしてmビルド。。。ではだめだったので、out/target/common/Rを削除。。。でもだめだったので、commonごと削除してビルドし直した。

ようやく本命のusb_swにつきあたったが、これがどこにあるかわからない。
frameworks/base/core/jniにないし・・・と調べると、system/extras/libnetutilsにあった。
わからんわ、こりゃ・・・。

あとは、IStatusBarとIStatusBarServiceの違いを吸収すればなんとかなるのかな。
と思ったけど、なんか違うな。。。
わからんので、コメントアウトで逃げよう。

こんな感じでちまちまとしか進まないので、終わりそうな気がしなくなってきた。

2011/07/09

q5 : とりあえず2.3.4が起動する

画面が出ないのがOpenGLがらみであるならば、そのライブラリを消して、元々のライブラリに置きかえると動くのでは?

そんなわけで、copybitも含めてCovia版をコピーさせないようにしてからビルドし直した。
そしてSDカードに焼くと、起動した。
Aboutも確認したが、2.3.4だった。

まあ・・・動くよね。
基板のシリアルからは、もうlogcatなどは受け付けてくれないが、これは仕方あるまい。
それはいいけど、やはり画面描画は速くない。
電力制御もだめだ。
USBからのデバッグ出力が出せないので、なんもできん。
無線LANも使えないしね。

2.2をベースにやっていくほうが賢いのかも。

q5 : SLSI_SC6410

SmartQ5のソースファイルを見ていると、"SLSI_SC6410"というキーワードが出てくる。
SC6410というのは、SmartQ5で使われているチップだ。


どうでもいいけど、こういうときに何と呼ぶのかよくわからん。
ARMは、コアだ。
CPUでいいのかな?
今の仕事で使うものは、マイコン、と呼んでいるが、それは"CPU"だけでなく、周辺機器の機能も多分に含んでいるからだ。
まあ、メモリも外にあるし、CPUでいいかな。


SC6410というのは、SmartQ5で使われているCPUだ。
つまり"SLSI_SC6410"というのは、SC6410用に変更した箇所ですよ、といいたいのだろう。
Sは"Samsung"なのかな。

気になったのは、このマクロをどこで定義しているのか。
device/か? ・・・ない。
build/か? ・・・ない。
prebuilt/か? ・・・ない。
えーい、全部grepしてしまえ!

・・・一例をあげよう。

./external/alsa-utils/Android.mk:LOCAL_CFLAGS  += -DSLSI_S3C6410

そう、各々で指定しているのだ。
えー、そうなのー、と思った私である。

q5 : EGLのLoader

EGLの部分はいったいどこが呼ばれているんだろう?というところをやっている。

コンストラクタで/system/lib/egl/egl.cfgをオープンしている。
これがなければ、デフォルトのconfigを使う。
ログにはなかったので、これは読み込まれている。
ファイルの中身は、こうなっていた。

0 1 fimg

意味としては"dpy, impl, tag"となっている。
dpyはディスプレイ番号

さて、このegl.cfgだが、SmartQ5用に提供されている。
他にも、
  • lib/hw/copybit
  • lib/egl/egl.cfg
  • lib/egl/libEGL_fimg.so
  • lib/egl/libGLESv1_CM_fimg.so
  • lib/libGLESv1_CM_fimg.so
  • lib/libChunkAlloc.so
が提供されている。
ファイルとしてはlibGLESv2_fimg.soもあるのだが、これはコピーされていない。


Loader::open()では、いよいよライブラリをオープンしている。
ログでは、こうなっている。

D/libEGL  ( 1890): loaded /system/lib/egl/libEGL_fimg.so
D/libEGL  ( 1890): loaded /system/lib/egl/libGLESv1_CM_fimg.so

つまり、さっきのegl.cfgにあったfimgが使われているのだ。
tagってのは、そういう意味を持つようである。


さて、cnxってのは、このライブラリから持ってきているようだ。
getProcAddress()とかでエントリポイントを取得するのかな?
libEGL.soをnmで見ると。。。symbolがないのでわからない。
代わりに、自前でビルドした方を見てみる。

00003201 T eglGetConfigAttrib

これが呼ばれているんだろうな。
うーん、思ったよりも大事になってきたなあ。。

q5 : 2つのeglGetConfigAttrib()

EGLUtils::selectConfigForPixelFormat()からeglGetConfigAttrib()を呼び出している。
検索すると、eglGetConfigAttrib()は2箇所にあった。

frameworks/base/opengl/libs/EGL/egl.cppにある方が最初に呼ばれていると思う。
その中からさらに、frameworks/base/opengl/libagl/egl.cppにある方が呼ばれているのだと思う。
そしてそこから同ファイルにあるgetConfigAttrib()が呼ばれているはず。
ログ出したりして確認すればいいんだろうけど、それは予想と違ったときにしよう。

・・・違ったので確認しよう。
frameworks/base/opengl/libs/EGL/egl.cppの方は、呼ばれている。
しかしlibaglは呼ばれていない。
cnx->egl.eglGetConfigAttrib()で足取りが途切れてしまった。


たぶん、だが、opengl/libs/EGL/Loader.cppのLoader::open()あたりではないかな。

q5 : mNativeWindow.get()はFramebufferNativeWindowのアドレスを返す

前回の続き。
mNativeWindow.get()が590200という値を返しているが、これはRGB565なので4になるべきでは?
その疑問を抱いたので、調べることにした。

mNativeWindowは、FramebufferNativeWindowクラス。
frameworks/base/include/ui/FramebufferNativeWindow.hにある。
が、この中にget()はいない。
しかし、getなんていう曖昧な名前は勘弁して欲しい。。。

ここからが大変だ。
定義はこうなっている。

class FramebufferNativeWindow
    : public EGLNativeBase<
        ANativeWindow,
        FramebufferNativeWindow,
        LightRefBase >

テンプレートだ。。。

template
class EGLNativeBase : public NATIVE_TYPE, public REF

第1と第3のクラスを継承している。
第1はANativeWindow、第3はまたテンプレートだが、これはラッパのようだ。
よくわからないが、そういう書き方をするのだろう。

が、ここまでみていってもget()がない。
なんでだ??

そこでようやく、mNativeWindowの定義を見た。

sp<FramebufferNativeWindow> mNativeWindow;

なんと、spだ。
shared pointerの略なのかな? newすれどdelete不要っていう参照カウンタで管理してくれるやつだ。
で、sp<>.get()は、本体のアドレスを返す。
つまり、mNativeWindow.get()はアドレスなのだ。
それをintでデバッグ表示させていたので、数値が違ったのだな。
なんで間違ったかというと、見る関数を1つ飛ばしていたからだ。
あーあ、ばからしい。


ただしく。

init()はEGLUtils::selectConfigForNativeWindow()を呼び、その中でNATIVE_WINDOW_FORMATを取得し、その値でselectConfigForPixelFormat()を呼び出している。
値を確認すると、4。
ちゃんとしてますな。

問題なのは、eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID)が0を返すというところにある。
次はそこを見ていきましょう。

q5 : EGL

画面が出ない件の調査中。

E/SurfaceFlinger( 1888): couldn't find an EGLConfig matching the screen format

まずはこれを追っていこう。

frameworks/base/services/surfaceflinger/DisplayHardware.cppのinit()。
ここで、EGLUtils::selectConfigForNativeWindow()がエラーを返している。

EGLUtils::selectConfigForNativeWindow()はlibs/ui/EGLUtils.cppにある。
eglChooseConfig()でconfigを取得し、eglGetConfigAttrib()で属性を取得し、期待するformatと一致するconfigを探す、という動作。

ということはわかるのだが、そもそもeglChooseConfig()とかeglGetConfigAttrib()とかがわからん。
OpenGL関係っぽいことは名前からわかるのだが。。。
関数の頭にeglって書いてあるから、EGLっていうものがあるんだろう。

まずは、EGLが何なのかを知らねば。

-------------------------------------------------------------------------------------------------
EGL
OpenGL|ESのようなAPIとネイティブ環境の描画をつなぐ層みたいだ。
peer層みたいなものか。
つまり、OpenGL|ESの詳細な実装方法は知らなくても、EGLの各API仕様を満たすように実装しさえすればOpenGL|ESが動かせる、ということになる。
ネイティブとつなぐ部分だから、今回のようにハードウェア環境が違うと手を入れなくてはならないのだろう。


簡単に使い方を知りたいので検索すると、こちらのサイトが見つかった。
うん、今回の処理部分は、ここに書いてある初期化部分と同じ流れだ。
参考にして読み進めよう。


まず、eglChooseConfig()。
init()からはattribとしてEGL_SURFACE_TYPEとEGL_WINDOW_BITを指定している。
これが検索対象ということだろう。
検索値は、format、しかないな。
mNativeWindow.get()は"590200"という値。
なんだこれは・・・。

frameworks/include/ui/PixelFormat.hに定義がある。
型はint32_tで、内容はenumで定義してある。
しかし・・・590200に相当する値がない。
SmartQ5を見ると、ここが拡張されていた。
マージ漏れか。。

いや、ちょっと待て。
うちのSmartQ5はこんな感じだ。

I/gralloc ( 1888): using (fd=25)
I/gralloc ( 1888): id           = s3cfb
I/gralloc ( 1888): xres         = 800 px
I/gralloc ( 1888): yres         = 480 px
I/gralloc ( 1888): xres_virtual = 800 px
I/gralloc ( 1888): yres_virtual = 960 px
I/gralloc ( 1888): bpp          = 16
I/gralloc ( 1888): r            = 11:5
I/gralloc ( 1888): g            =  5:6
I/gralloc ( 1888): b            =  0:5
I/gralloc ( 1888): upper_margin = 10
I/gralloc ( 1888): lower_margin = 35
I/gralloc ( 1888): left_margin  = 40
I/gralloc ( 1888): right_margin = 216
I/gralloc ( 1888): pixclock     = 33358920
I/gralloc ( 1888): width        = 800 mm (25.400000 dpi)
I/gralloc ( 1888): height       = 480 mm (25.400000 dpi)
I/gralloc ( 1888): refresh rate = 60.00 Hz

RGB565なのだから、PIXEL_FORMAT_RGB_565=HAL_PIXEL_FORMAT_RGB_565=4のはずだ。
mNativeWindow.get()は何を返しているんだ?

これは別の調査としよう。

2011/07/08

「かざしてログオン」は、たぶんだませる

かざしてログオンのことが出ていたので、ちょっと思い出した。
記事で書いていたような気がしたけど、出てこなかった。。。
何かというと、だまし方だ。

同じようなことを書くことになりそうだが、まあ年寄りのことだからと我慢しておくれ。


FeliCaのカードがある。
これを出退勤のタイムスタンプ代わりにしたいとしよう。
授業の出欠でもいいし、鍵の代わりでもいい。
つまり、カードが身分証明の代わりを果たすような場合と考えてもらおう。

さて、どうやるのが一番確実だろうか?

私が一番確実だと思うのは、FeliCaカード(FeliCa Liteではなく)を使い、共通領域なり他の領域なりのシステムを割り当て、エリアを割り当て、鍵をかけたブロックが用意することだ。
たとえば、Suica。
これはサイバネ領域を使っていて、アクセスもたぶん縮退鍵などでアクセスするようなところにある。
自前の領域なので、読み書きができる。
一致した鍵を持った人が近づくと見えるコインロッカーみたいなものか(あるのか?)。


次は・・・どれだろう。
FeliCa Liteで片側認証する場合だろうか。
FeliCaでは共通領域になるだろうけど、ドコモみたいに開放しているところは少ないだろう。
もし共通領域を使うなら、前者の方法をとるだろうし。
コインロッカーの前に人がいて、鍵が自分のところのものか調べるような感じかしら。


その次は、誰でもアクセスできる領域に、自分で暗号化を掛けたデータを書き込むこと。
この場合のセキュリティは、FeliCaのものではない。
「解読できるならやってみろ」とネット上にファイルを置くようなイメージかな。


それ以下なのが、書き込みできない状態で認識する方法だ。
よくやりがちなのは、IDmを見る方法。
非常に手軽なんだけど、IDmは重複する可能性があるので危険だ。
それだけだと不安だと思えば、読み取れるブロックを読んでおく、なんて方法もある。
自前のカードを用意しない場合は、この方式しか取れない。
「住所と表札が一緒だから、きっとこの人だろう」と家に上がり込むような感じか。


「かざしてログオン」は、もちろん最後の方法となる。
IDmだけではないのだが、まあ読み取っておける情報であることには違いがない。

そしてこれだけのことがわかり、あとPaSoRiを使いこなすことができれば、だませる。
かざしてログオンだけではなく、同種の方法をとっているもの全てを、だ。

必要なのは、PaSoRiと、相手に登録されているFeliCaカード。
それとPaSoRiを操作するソフトが組めるパソコン。
Linuxとかcygwinがあれば何とかなる。
たぶん、USB Host APIが使えれば、Androidでもできるだろう。


詳細は、説明しない。
それほど親切ではないが、だいたい予想が付くんじゃなかろうかね。
今やっているSmartQ5のが落ち着いたら、それに載せてみたいものだ。

この方法が採れるのは、FeliCaというかNFC-Fというか、それだけである。
NFC-A系は、少なくともできなかったはず。
カードになったとしても、UIDを3byteしか指定できないからだ。
わざとなんかねぇ。
怖いので、個人的にはFeliCaからも一部をマスクするような制限を付けてほしいものだ。

2011/07/03

[q5]画面が出らんが、よくわからん

I/DEBUG ( 1820): #00 pc 0000314c /system/lib/libEGL.so
I/DEBUG ( 1820): #01 pc 000041fe /system/lib/libEGL.so

なので、見てみた。

$ addr2line -e libEGL.so 0000314c
frameworks/base/opengl/libs/EGL/egl.cpp:503

validate_display_config()の、ここ。

egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(config)].impl];


その前は、eglCreateWindowSurface()。
うーん。。。よくわからない。。。
もっと前に出ている、

E/SurfaceFlinger( 1888): couldn't find an EGLConfig matching the screen format

これかいな?
オリジナルと比較すると、ここのように思う。
しかし・・・どれが影響しているのかよくわからん。
来週だ、来週。

[q5]起動したっぽいが、画面が全然でらん

あれからもやっていたが、いくつか解決できた。

libcameraserviceに、命令エラーが出た。
illegal operation、だったか。
わからんが、私のlibcameraserviceはOpenCVと接続していて、それはBeagleBoard用にビルドしている。
ARMの系列が異なるから、なんかあるのかも。
とりあえず、USE_CAMERA_STUBを有効にして、カメラは捨てた。

libEGL_fimgでprelink mapがどうのこうのというエラーが出た。
SmartQ5のbuild/core/prelink-linux-arm.mapを見ると、確かに違いがある。
よくわからんなりに、マージしたら動くようになった。

Javaで数値に変換できない例外が出た。
これはinit.rcに不備があったためだ。
Gingerbreadで追加されたroをinit.rcに追加すると、進んだ。


ここまではよかった。
今起動させると、apkファイルをどんどん読んでいってるようなlogcatが確認できている。
タッチパネルは触っていないが、ボタンは動いているような感触もある。
だが・・・画面が出ない。
音が出ないのは、ALSA関係を無効にしたからなので、まあよかろう。

I/DEBUG   ( 1820): pid: 1906, tid: 1910  >>> /system/bin/bootanimation <<<
I/DEBUG   ( 1820): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr f905a660

まあ、これがすべての原因というわけではないだろうが、最初の面画が出ないのはこれだ。

I/DEBUG   ( 1820):          #00  pc 0000314c  /system/lib/libEGL.so
I/DEBUG   ( 1820):          #01  pc 000041fe  /system/lib/libEGL.so
I/DEBUG   ( 1820):          #02  pc 0000b3c4  /system/bin/bootanimation

こうなっているから、libEGL関係だろう。
ここら辺は、やりたくないんだよな。。。。
copybitをなくしてしまえば、いいのかもしれんが、それでは解決にならん。
とはいえ、どっから手をつけたものだか。。。

initでkernel panicになっていたが、init.rcの書き方が悪かった

SmartQ5だが、FLASH起動はあきらめた。
とりあえず、SDカードでブートさせよう。そっちの方がやりやすい。

そう思ってやっていたのだが、initでkernel panicが発生した。
特に書き換えたわけでもないので、変なことにはならないはず。

system/core/initにいろいろとログを追加していくと、init.rcの解析は終わっていて、それを実行している段階でおかしくなっている。
というよりも、ある地点に差し掛かると、おかしい。

どうやら、init.rcの書き方がよくなかったようだ。
引っかかっていたのは「on fs」のようなセクションの開始あたり。
init.rcは、

on XXX
    command...

のような構成になっている。
今回、on fsだったのだが、コメントアウトしていくうちにcommandが1つもなくなっていたのだ。
それでおかしくなったらしい。
on fsもコメントアウトすることで動くようになった。

ほほー。

[q5]ビルド

こんばんは。
二日酔いで昼頃起きたけど、うだうだして昼寝して夜になったので眠くない、なんてわけではありませんよ。

そんなわけで(?)、SmartQ5のビルドについてちょっと書いておこう。
以前やってたサイトのときには書いたんだけど、こっちに移ってきてからは書いてなかったと思う。
それに、ソース提供されてからの情報じゃないしね。


まず、準備。
gitとかrepoがいる。
コンパイラはAndroidに入っているものを使うので、準備しなくてよいだろう。
あと、mkimageがいる。これはu-bootを使っているからだ。
# sudo apt-get install uboot-mkimage
たぶん、こんな感じでインストールできたはず。

ソースのダウンロードができたら、あとは手順どおり。
最初は、kernelのビルドも確認した方がよいと思う。
というのは、私がkernelのビルドができていないことに気づいていなかったから。

# source myenv
# cd linux-2.6.29-s3c-smartQ5
# make zImage
# cp arch/arm/boot/zImage ../nami-smartq5-upgrade/firmware_files/zimage
# sudo ./buildfs.sh

コンパイラがない、みたいなエラーが出るときは、Makefileを変更しよう。
私は 2.3.4環境なので、こうなった。
なければ、それぞれの環境でそれっぽいものに置きかえるとよかろう。
CROSS_COMPILE  := ../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-


普通は、このくらいでよい。

# source myenv
# make
# sudo ./buildfs.sh

私は、buildspec.mkを用意し、build/envsetup.shをちょっと書き換えて使っている。
まあ、普通にビルドすればいいでしょう。
-jとか使えば、ビルドが早くなることでしょうが、CPUをガンガン使うので熱を気にしながらやってください。

# source build/envsetup.sh
# m -j5
# sudo ./buildfs.sh