2014年8月17日

[android]Emulatorが立ち上がらんときは、Use Host GPUをチェックするとよいかもしれん

久しぶりに、Androidのエミュレータを使うことになった。
というのも、AndroidアプリをGoogle Playにアップするためにはスクリーンショットが必要なんだけど、「電話」っていうサイズのスクリーンショットがあるからだ。
うちにはNexus7しかないため、これはきっとエミュレータで実行して撮れ、ってことなのだろうと解釈している。

 

まず最初につまずいたのは、選択するAPIバージョン。
バージョンが上の方なら何でもいいじゃろう、と思い、4.4Wを選択。
今ならわかるのだけど、Wは"Wear"のW。
立ち上がったのはいいけど、ホーム画面は出てこないしアイコンは出てこないし、なんじゃこりゃ、と思って調べてわかった次第だ。

 

その次につまずいたのが、表題。
4.4.2で作ったのだけど、立ち上げても"android"のアニメーションが始まらない。
うちのマシンは遅いから、と放置していたが、さすがに5分も動かんのはおかしい。
logcatを見ると、SurfaceFlingerが「フレームバッファがない」みたいなことを言っている。
これはうちのPCが貧弱なせいか?

そう思って調べると、Stackoverflowにあった。
http://stackoverflow.com/questions/21845358/android-emulator-cant-be-started
"Use Host GPU"にチェックを入れたら?とあったので、設定を変更しなおすと、アニメーションが出た。
そういうことなんですか。。。

 

さて、最後かどうかわからないが、まだつまずいている。
またしてもNFCを使うアプリなんだけど、onCreate()でNFCを使用できるかどうかチェックしているので、エミュレータだとまったく起動できない・・・。
チェックを外せばいいんだけど、それってスクリーンショットの偽造になるのでは?

そしてもう1つ・・・。
4.4.2でGPUを使う設定にしているとDDMSでスクリーンショットが撮れないらしい。
https://code.google.com/p/android/issues/detail?id=62284

まあ、単なるスクリーンショットだから画面キャプチャでいいんだけどね。


そんなこんなして、Google Playにアプリ置きました。
https://play.google.com/store/apps/details?id=com.blogpost.hiro99ma.flfmt

Formatと書いているが、やってるのはQuick Formatみたいなものだ。
とりあえず、MIFARE Ultralight系だったら40ブロックまでは0x00で埋めようとしているし、FeliCa Lite系だったら13ブロックまでは0x00で埋めようとしている。

それはよいのだが、アプリをインストールするときに「特に権限不要」と出てきた。
いやいや、NFCの権限はいるんですけど・・・。
アプリ情報を見ると、ちゃんと「許可」欄には出てきている。
うーん、そんなものなのか?

[nfc]ISO/IEC 7816-4とJIS X6320-4

AndroidのHCE(Host-based Card Emulation)は、アプリケーションからするとISO/IEC 7816-4という分類になっている。
勉強不足なところを言いたくはないが、ISO/IEC 14443とか7816とかのことは、かなり不勉強なことを自覚している。
正直なところ、よくわかってない、といっても過言ではなかろう。

反省して、ISO/IEC 7816の和訳でもしてみようかと思ったが・・・そもそも、無料で手に入りそうな気配がない。
ネットで検索して、それっぽい感じがするサイトのHTMLを保存して実家で翻訳していた。
・・・・なぜ保存してかと言うと、実家ではブロードバンドが通らない地域だからだ。WiMAXも山を越えると入らないので、そろそろ手数料がかかっても解約を考えているくらいだし、光はおろかADSLも届かず。
携帯電話は一応入るけど、私がテザリングできる契約にないし。
ぐちぐちぐちぐち・・・・

ともかく、ISO/IEC 7816-4っぽいサイトをダウンロードして実家で訳していたのだが、最初の方で挫折した。
英和辞典がないのだ。
もうちょっと訳せると思ったんだけどね-。

その途中でふっと思い出したのだが、JIS規格は国際標準規格を取り込んでいるものも多い。
まあ、日本工業規格なんだから、当たり前といえば当たり前なんだろうが。
7816も取り込まれているんじゃなかろうか、というよりも、取り込まれているはず!

検索できる環境に戻ってきて調べると、JIS X6320-4がそれっぽい。
それがわかったので少し読んでみたが・・・難解だ。
いや、難解なのはまだ良いとしても、私が「っぽいサイト」といっていたところの内容と違う・・・。
内容が違うというか、構成が異なるため、たぶんこれが原本に近いだろうとは思うものの確信を得ることができない。
JISを疑いたくはないのだが、この職業はすべてを疑うのが定め。

 

2014年8月10日

[ios]iBeaconとMFi

かなり、いまさら、の話になってしまうが、AppleのiBeaconがMFiライセンスみたいな感じになるらしい。

私は全然MacとかiOSに詳しくないので、衝撃的なのかどうかすらよくわからない。
とりあえず、iBeacon端末と名乗るならばAppleの認証が必要になった、ということだと認識している。
NFC Forumに適合しないとNマークが付けられないとか、そんな感じ。

しかし、iBeaconのデータは、BLEのAdvertisingデータなので、それだけであれば誰でも流せるし、符号化されているわけでもないから読むことだってできる。
そもそも、iOS以外でも使えるものだ。
制限するのにも限度があるが、だからこそライセンス的にしようとしたのだろうか。


まあ、そういう政治的な話はあまり興味が無い。
気にしているのは、何か開発するだけの人にとって制限されることがあるのか?ということ。
特にお金的な面で・・・。
ほら、ただでさえiOS開発には毎年の更新料が必要になるじゃないか。
シミュレータ使えばいいんだろうけど、手元にiPad miniがあるのに開発に使えないというのは腹立たしい。
アプリをリリースするときだけ金がかかるのならいいんだけど、そうじゃないしねぇ。
せめて、BLE開発は追加なしでやりたいところだ。

[ios]iBeaconを受けるアプリを作ろうとした

以前、BVMCN5102(nRF51822搭載)で、NFC R/WからUUIDを指定してAdvertisingするしくみを作った。
送信するのは確認できたので、やはり受けるアプリも作りたい。
そんなわけで、久々にXcodeを使うことにした。

ネットを見ながら、CLLocationManagerDelegateだけを持つViewControllerを作った。
が、startMonitoringForRegionしてdidStartMonitoringForRegionがコールバックされるのは確認できたのだけど、startRangingBeaconsInRegionしてもdidRangeBeaconsが呼ばれないし、そもそもdidDetermineStateすら呼ばれない・・・。
あれこれ見たけど、別に悪そうなところはない。
うーむ。

一番疑わしいのが、Xcode6 beta版か、SDK8.0。
Xcode 5.1.1にして、SDK7.1にすると・・・アプリ起動時に「位置情報を使うか?」みたいなダイアログが表示されて、許可すると呼ばれるようになった。
なんだよー。
SDK8.0が怪しいのか、仕様変更なのか・・・。


送信しているProximity UUIDと、APIで指定するProximity UUIDはエンディアンがどうなるんだろう、と思っていたのだが、同じ順番で良かった。
つまり、送信側が「00112233445566778899AABBCCDDEEFF」を使っているのであれば、iOS側は「00112233-4455-6677-8899-AABBCCDDEEFF」でよいということだ。
同じにするのは当たり前やん、と思われそうだけど、Bluetoothって全体的にリトルエンディアンなので、文字列で指定するiOSの方とは逆になるんじゃなかろうかと考えていたのだ。


2014年8月9日

[felica]FeliCa Lite-Sの相互認証が通った!!

まだ・・・FeliCa Lite-SのMAC_A(W)が計算できていないのだ・・・。

基本的な注意点は、以下。

  • 内部認証時のMAC計算や、読み込み時のMAC_A(R)計算とは異なる。
    • SK2→SK1→SK2の順で3DESする
    • 初期IVはRC1(エンディアン反転)で、初期値はWCNTとブロック番号

まず、前回疑問だった、発行していないのにできるのか?については、「できる」だと考えている。
その根拠は、WCNTレジスタの説明に、1次発行作業中でもMACつき書込が正常で終わると書かれているからだ。「WCNTの動作」という表があり、WCNT==0xFFFFFFになってなければ正常に書き込めるらしい。
今は0xFFFE58とかだから、まだ大丈夫そうだ。

 

では、考えられるのはMAC不一致か、WCNT不一致か。
WCNTは、読み込んだ値をそのまま使うだけなので、考えにくい。
となると、MACが不一致、ということになる。

ここで、スターターマニュアルを読んで気付いたことがある。
カード側に必要条件があるようなのだ。

  • CKブロックにカード鍵が書いてあること
  • STATEブロックがMACつき書込に設定されていること

STATEに? MAC付き書込設定?
MCレジスタを確認すると、MC_STATE_W_MAC_Aという設定があった。
全然気にしていなかったのだが、なんか重要そうだ。


MC_STATE_W_MAC_Aに0x01を書き込むと、STATEブロック書込にMAC必要となるらしい。
つまり、今まで、外部認証の処理だと考えていたシーケンスは、実は「STATEブロックにMAC付き書込を行う」という動作をしているだけだったのだ!
はらはら(目から鱗が落ちる音)。

もし私のMAC_A(W)計算が正しかったのならば、Write without Encryptionレスポンスのステータスフラグ2が0xB2である要因として、「MAC付き書込不要なブロックに対してMAC付き書込を行った」もあるということになる。

では、実証実験を。
・・・・・・・・・・

image

きたーーーーーー!!
Write without EncryptionまでOKで通った!!


では、外部認証へのまとめを。

  1. MC_STATE_W_MAC_Aには0x01を書き込んでおくこと
  2. STATEブロックへ書き込むときのEXT_AUTHは0x01
  3. MAC_A(W)を計算するときのEXT_AUTHは0x01

3番については?と思われるかもしれないが、FeliCa Lite-Sのユーザーズマニュアルには外部認証でのMAC(W)生成の説明に、

  • WCNT値とブロック番号とブロックデータからMAC(W)を生成
  • STATE[0]に01hを、MAC_AブロックにWとWCNT値を書き込む
  • の順で書かれているので、「じゃあMAC(W)を計算するときのSTATE[0]は、現在値なのか書き込む予定の値なのか?」で迷いが生じたのだ。
    しかし、ここまで確認した過程でわかったように、外部認証というのは「STATEレジスタへのMAC付き書込」を指しているので、計算するときは当然書き込む予定の値で行うことになる。

    あー、夏休みの宿題が終わった!

    2014年8月4日

    [nfc]NFPも同じ問題点があるのか

    HCEサンプルの動作確認をWindowsでやろうとして、うまくいったんだかいかなかったんだかという状況だ。
    とりあえず、RC-S370 + SDK for NFC Starter Kitであれば、NDEFタグとして読んでくれた。
    RC-S380 + SDK for NFC Starter Kitは、タグとしてのアクセスについてはサポートされていないと見て良かろう。

    じゃあ、RC-S380 + NFP、つまりWindows8でだったら認識してくれるか?というと、だめだった。
    例のタグ近づいた音はするものの、それっきりだ。
    Androidで動いているLLCPを見つけてしまうため、お互いがそれ以上の関係になれないのだと思う。

    それならAndroid同士だって同じではないか、ということになるが、ある意味では正しい。
    しかし、Androidでは回避策を用意している。
    内容は、こちらのブログが詳しい。
    http://brightechno.com/blog/archives/179

    つまり、Android 4.4からはReaderWriter Modeという状態を用意し、何をやってるかは知らないけれど、LLCPしようとしないようにしているのだろう。
    NFPにそういうインターフェースがあるかはわからないが、そういうモードがないとHCEをWindows8で受けるということができないんだと思う。LLCPはドライバでやるようなことが書かれているから、メーカー依存になるんだろうか・・・。

    2014年8月3日

    [felica]PaSoRiの対応

    PaSoRiと、OSと、機能の対応表を見比べていたのだが、結局こういうことか?

    image

    もう、公開されている資料からこれ以上読み取るのは私では無理!!
    間違っていたら修正するので、よろしく。

    2014年8月2日

    [nfc]RC-S380かそれ以外かをSDK for NFCで見分ける

    結局のところ、こういう実装になるのだろう。

    • RC-S380以降ならば、PC/SCなど(非SDK for NFC)を使う
    • RC-S370以前ならば、SDK for NFCを使う

    おそらくだが、ACSのようなR/Wであれば、PC/SCでアクセスできるんじゃなかろうか。
    そういう視点で行くならば、こうなるか。

  • PC/SCでやってみる
  • だめだったら、SDK for NFCでやってみる
  • つまり、SDK for NFCがレガシーデバイス用になるという見方だ。
    そちらの方が今後としては正しいのかもしれん。

    公式発表があるとありがたいのだが、業務用R/Wはサポート期間が長いことも考えると、今までの傾向からすると発表などはないだろうと思う。
    せめて、ラッパーとか用意してもらえれば・・・。

    でも、今だったらRC-S370環境のみで整備するか、RC-S380環境のみにして書き直すかのどちらかを選択するな。
    取りあえず、felicalib_nfc_open()のエラー値で判断せよ、ということになる。

    [nfc]RC-S380 + SDK for NFC Starter KitはおそらくFALP以外は使えない

    前ブログに書いたType4Aのサンプルだが、RC-S370で動かしている。
    ちょうどPCに挿さっていたのがS370だっただけなのだが、同じソフトをRC-S380で動かすとエラーになった。

    以前作っていたSDK for NFC Starter Kitのアプリを動かしてみたが、同じだ。
    エラーコードを確認するとドライバのエラーで、「APIの発行シーケンスが正しくありません」らしい。
    ???

    S370だと動くので、アプリの問題ではなくドライバに原因があるのだろう・・・
    と検索してみたら、自分のブログが引っかかった。
    正確には、ブログへのコメントだ。

    http://hiro99ma.blogspot.com/2012/12/win8ndef-writernfp.html

    「felica_nfc_library.dllは、新型RC-S380からはサポートされない」とのこと。
    このDLLは「NFCアクセスライブラリ」という。
    付属ドキュメントM575_NFCAccessLibraryFunctionOverview_1.21j.pdfのp.10には「NFCライブラリは、NFC Port-100およびFeliCaポート1.0では動作しません」とある。
    これが、コメントでいただいた内容のことだ。
    でもね。
    同じく付属のソースサンプルには「NFCPort100」というフォルダがあるのよね。
    使えないのであれば、サンプルソースも削ってほしいのだが、どうなんだろう。

     

    数年FeliCa関係のドキュメントを読んでいたので言わせてもらうと、ドキュメントが他社に比べてものすごくわかりづらい。
    わかりづらい、ではなく、ものすごくわかりづらい、だ。
    こんだけブログの記事にさせておいて申し訳ないが、私が部品を発注する立場だったらSonyのチップは選ばないだろう、というくらいの出来だ。
    英語で書いてあっても、NXPのドキュメントの方がわかりやすい。
    Sony嫌いという人もいるが、そういうところが透けて見えてるからなんじゃないかなー、とか思ってしまう。

    [nfc]HCEがキーワードらしい (2)

    NFCフォーラム自身もアプリ開発を支援、注目はHCE

    ほほぅ。
    まあ、NFCが一般的かって言われると、そうじゃないと思う。
    だいたい、技術が先行するとあんまりはやらない気がする。
    冷蔵庫ってどうやって冷やしてるの?と聞かれても私にはよくわからんのだが(わからんのかい)、冷蔵庫は便利だ。
    そんなもんだと思う。

    が、冷蔵庫が出てきた時代とも違うし、比較してもしょうが無かろう。
    それに、このサイトを見ているとわかるかもしれんが、私は応用よりも技術の基礎的なところを知る方が好きなようだ。
    なので、技術が先行しても特に気にしない。


    ならば、私も長いものに巻かれて、HCEをもう少し真面目にやってみようと思い、以前作ったサンプルを立ち上げた。
    が・・・動かない・・・・・・・。

    今回、なぜか急に私がAndroid SDK(eclipse)から、AndroidStudioに変更してみようと思った。
    HCE Sampleをビルドする前に、Wizardで新規作成したプロジェクトをビルドさせてNexus7に焼こうとしたけど、まずそこが失敗。
    理由は、[INSTALL_PARSE_FAILED_MANIFEST_MALFORMED]。
    これは別にAndroid Studioのせいではなく、package名に大文字が入っていたせいだった。
    http://stackoverflow.com/questions/12396351/how-to-fix-install-parse-failed-manifest-malformed-in-my-android-application

    これでStudioで焼けることがわかったので、HCE Sampleをインポートしてビルド。
    そしてここでもつまずく。
    どうも、Nexus7にAndroid Lを入れていたためのようだ。
    build.gradleを編集して対応できた。
    http://stackoverflow.com/questions/24437950/build-failed-after-updating-tools-for-android-l

     

    ようやくNexus7に焼くことができたけど、はて、前回はどうやって動作確認したのだか。
    Windows7 + NDEF Writerで、Type4のREADを試したけど、どうもうまくいかない。
    搬送波が出なかったり、エラーになったり。
    Windows8で試したけど、SNEPの方が反応してしまうためか、同じくだめ(Android Beamしなくても、裏ではLLCPが動き続けているログが出てる)。

    じゃあ自分で作るか・・・と思ったが、めんどくさい。
    幸い、SDK for NFC Starter Kitにコマンドライン版ではあるがType4Aを読むサンプルがあったので実行する。
    が・・・なんか「The tag is not a supported Type4 Tag」と出てくる。
    しょうが無いのでVisual Studioでデバッグすると、SmartPosterを読み込む部分がかなり決め決めで実装されていた。

    • SmartPoster内のNDEF Recordは、Shortで3つ。
    • 3つの順番は、TEXT, URI, Action

    URIとTEXTだけやっていたので、はじかれていたのだった。
    SmartPosterRecord::setPayloadData()を変更して、ようやく動いた。
    私のHCE Sampleは間違ってなかったんだ!


    とはいえ、HCEの目的からすると、端末がNDEFタグを吐き出すことではないだろう。
    なにかしら、セキュアなデータをやりとりするような、そんな緊迫した使い方がメインになるはず。
    そういうサンプルを作ってみたいけど、これはR/W側も同時に実装しないといけないのよね・・・。
    それには、メモリとしてのNFCタグではなく、Type4Aが持つデータ構造とかアクセス手段とかも知っておかないといかんような気がする。

    まあ、Android側もR/W側も自由に扱えると言うほどに熟練してないので、まずはお勉強からですかね。