2013/11/24

[ble]master/slave, initiator/responder, server/client

用語が、用語が・・・。

似たような感じの言葉がよく出てくるのだが、使い分けがわかっていない。
特に、「master/slave」「initiator/responder」「server/client」は、どれも同じような感じがしつつ、やっぱり違うんだろうけど、曖昧なままごまかしてきた。

そろそろ、はっきりさせたい。


Central/Peripheral

まずは、これか。
いわゆる「デバイス側」がPeripheralで、その持ち主が「Central」というイメージだ。

Core_V4.0のp.200に「BLEのGAPは4つのroleを定義する:Broadcaster, Observer, Peripheral, Central」とある。
つまり、GAP(Generic Access Profile)の機能ということだろう。

 

Master/Slave

Core_V4.0のp.1639-1640にGAPの4roleが対応する機能一覧がある。
そのLink Layer functionalityのConnection Stateに「Slave Role/Master Role」がある。
CentralはMaster Role、PeripheralはSlave Role。
つまり、LL(Link Layer)の機能ということだろう。

AdvertisingするのがSlaveで、それを受け入れるのがMaster、と思っている。
なので、PeripheralがAdvertisingし、Centralが受け入れる、ということになる。

 

Initiator/Responder

これはまだ私の調べごとには出てこないのだが、Interface誌にでていた。
「マスタ(イニシエータ)」「スレーブ(レスポンダ)」と書いてある。

p.2130に出てきている。
これは「Conditions」の説明なので、状態というか、そういうものなのか?
Physical Link Createコマンドを受けとるとInitiatorになり、Physical Link Acceptコマンドを受けとるとResponderになるのかな。
説明が「physical link initiator/responder」だから、PHYの機能ということだろう。

PHYが一番下の階層だ。
LL(Master/Slave)はその上。
GAP(Central/Peripheral)はもっと上。

検索したけど、あんまりそれっぽいことが書かれていない。
忘れてしまうか。。。

 

Server/Client

自分で書いておいて何だが、これは「Attribute Server/Client」のことかな?
ATT serverとATT clientみたいだ。
p.141には、ATT clientがコマンド、要求、確認をATT serverに対して送信する、と書いてある。
ATT serverはそれに対して、応答、通知、指示をATT clientに送信する。

Attribute Protocolの説明なので、これはGAPと同じ階層のようだ。
また、p.141にGATT(Generic ATTribute profile)の説明もあり、ATT serverの機能を実現しているのがGATTだ、とある(optionallyでATT clientも)。
p.1637にプロファイルスタックの図があったのだけど、GAPがベースのようになっていて、そこにGATTがいるのか。

image

で、この辺でPushとかPullとかの話が出てくると思ったのだが、Core_V4.0を「Push」で検索しても引っかからない。
なんだ?
それに、CharacteristicとAttributeの区別もついていない。
「Characteristic」という属性がついたAttributeがCharacteristicってことかいな?
Characteristicのアクセスは、ReadとかWriteとかNotifyとか、そんなのだよなぁ。。。
うぅぅ。。。

[ble]BLEを試してみたい (5)

iOSはまあ何とかなりそうなので、Androidを進めていこう。
いや、うちのMac miniは遅くてイライラしてしまうのだ。
SSDにすべきかなぁ。


そうそう、スキャンして目的のデバイスを見つけることについて考えないと。
今は、デバイス名だけを見比べて、一致したらやめている。
でも、同じBLEデバイスが何台も置いてあるという状況もあるだろう。
そう考えると、デバイス名だけってのは乱暴そうだ。

ならば、デバイス一覧を表示させて、ユーザに選んでもらうしかない。
ペアリングの入力無しで、デバイスに対しても個別の設定が不要なのであれば、見つけたものをどんどん処理していけばよいだろう。
そのときは、デバイスのハードウェアアドレスで見分けるしかないのかもしれないが、外見ではどれがどのデバイスかを見分けるのは難しいだろう。
なるべく安く作りたいとしても、LEDくらいはつけておいて、自分の状態を表現できた方がよさそうに思う。

あ、デバイスを作るときのことね。


さて、スキャンした結果がコールバックされたとき、引数が3つついてくる。

onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)

deviceとrssiはいいのだが、scanRecordはなんだ?
「The content of the advertisement record offered by the remote device.」とあるので、Advertisingのときに送られてきたデータなのだろう。

RC-S390の場合、37byte返ってきているみたいだ(配列要素は62あるけど、37byteまでデータが詰まってて、残りは0x00だった)。
バイナリ値があれば解析をする・・・それが刑事の哀しい性(?)だ。

Core_V4.0の仕様書を「37」で探したところ、p.2202がそれっぽい。
「 The valid range of the Length field shall be 6 to 37 octets.」

image

image

ここのLengthだろう。
scanRecordが37byteで、それはFigure 2.2のPayloadにあたるのであれば、Figure 2.3は関係ないな。

スキャンした結果が返ってきたのならば、p.2206のSCAN_RSPになるのか。

image

AdvAはランダムだかなんだかのデバイスアドレス、ScanRspDataはAdvertiseしたホストからのデータ。
ということは、RC-S390が私に送ってくれた何かということになる。

scanRecordを眺めてみたが・・・さっぱりわからん。
最後の6byteが「PaSoRi」という文字になっているということはわかった。

SCAN_RSPでネットを調べると、私が思い違いをしているようだ。
http://reinforce-lab.github.io/blog/2013/02/07/ble-linklayer/
AdvertisingとScanは別の動作らしい。
p.2203によると、PDUの種類は7つ。

image

このうち、_INDがAdvertising PDUだそうな。
Payloadは、AdvAはどれもあり、違いはAdvDataがあったり別だったりするくらいだ。

image

で、どれもホストからのデータというくらいで、詳細は無い。
先ほどのリンクを読むと、LengthとDataが並んでいるらしい(Dataは、AD TypeとAD Dataから成る)。

Core_V4.0をAD Typeで検索すると、p.1735が出てきた。
1octのLengthと、そのLength長のData。Dataはn octのAD TypeとLength-n octのAD Data。

image

AD Typeはこちらの一覧を見るらしい。
いやあ、ここまで書かれてあると非常に助かりますわい。

で、これを見ながら解析していったのだが・・・あわない。
AdvAが無いものとして解析するとちょうどよさそうなのだ。
どうも、引数のscanRecordは、AdvertisingのパラメータとScanの結果が一緒に入ってきてるような気がする。
サイズも62byte分ということで合うし。
ということは・・・「37」って数字でそれっぽいところが引っかかったのは、単なる偶然だったのか・・・。
おそろしや・・・。

 

入っていたのは、こんな情報。

  • BR/EDR Not Supported
  • Incomplete List of 128-bit Service Class UUIDs
  • Slave Connection Interval Range : 20ms~300ms
  • Tx Power Level : 0 dBm
  • Complete Local Name : PaSoRi

BluetoothDevice.getName()に入ってるのは、このLocal Nameなのかな。
このデータをアプリがどのくらい管理しないといかんのかはわからないが、あまり気にしなくてもよさそうな気はする。

 

さて、次はConnectionだ。
Androidのサンプルはなんか難しいので、こちらを見てやっていくことにする。
http://blog.fenrir-inc.com/jp/2013/10/bluetooth-le-android.html

[java]コールバックしてToastを出したい

半分Java、半分Androidだ。

まず、コールバックしたい。
こちらはJavaだ。

コールバックする側interfaceを作っておき、コールバックしてほしい人はそのインスタンスを作り、中身を作っておく。
そしてコールバックする側に渡す。
コールバックする側は、そのメソッドを呼ぶだけ。

 

// コールバックする側がinterfaceを作っておき、
public interface callback {
    public void onResult(int result);
}

--------------

    //コールバックしてほしい人はそのインスタンスを作り、
    //中身を作っておく
    private xxClass.callback mCallback = new xxx.callback() {
        @Override
        public void onResult(int result) {
            Log.d(TAG, "callbacked");
        }
    };

//そしてコールバックする側に渡す
{
    xxClass xx = new xxClass();
    xx.function(mCallback);
}

--------------

//コールバックする側は、そのメソッドを呼ぶだけ
void function(callback cb) {
  cb.onResult(0);
}

--------------

interfaceじゃなくてabstractってのでやろうとしたけど、なんかダメだった。
気が向いたらちゃんと調べよう。


コールバックした先でToastを表示したい。
こっちはAndroidだ。

やったんだけど、コンテキストが違うせいか、コンパイルで怒られた。

The method makeText(Context, CharSequence, int) in the type Toast is not applicable for the arguments (new BleUtils.scanResultCallback(){}, String, int)

BleUtils.scanResultCallbackは、上でいうところのxxClass.callbackだ。
Log.d()は使えたんだけど、Toastはだめだって。
まあ、画面に何か出すんだから、UIコンテキストじゃないとダメなのかな(追求してない)。

これは確か、BLEのサンプルで何かやっていた。

    @Override
    public void onLeScan(final BluetoothDevice device, int rssi,
            byte[] scanRecord) {
      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          mLeDeviceListAdapter.addDevice(device);
          mLeDeviceListAdapter.notifyDataSetChanged();
        }
      });
    }

このrunOnUiThreadってのがそれっぽいようだ。
が、同じようにしてみたけど、やはり怒られる。
うーむ。

あれだ、コンテキストが違うので、第1引数をthisってしてもだめなようだ。
getApplicationContext()とすると、エラーが消えた(参照:モバイル開発系(K))。
そうかそうか。

もう1つ。
コールバックの引数で文言を変えたい。
このときは、仮引数の宣言をfinalにするとよいようだ。
スタック渡しだからダメなんだろうと思っていたんだけど、Javaだから「まだ使います」って言っておけばよいということなのかね。

 

これでようやく、BLEの検索結果を戻せるところまで来た。
https://github.com/hirokuma/BleTest

[ble]RC-S390は定期的にAdvertisingしているようだ

試していて気付いたのだが、RC-S390をAdvertisingにしなくても、ペアリングをしていなくても、スキャンはできているような気がする。
いや、そもそもRC-S390は自分で作ってるわけでもないので、どこでAdvertisingになっているかなんてわかるはずもない。

と思ったのだけど・・・やっぱり、AdvertisingじゃないとCentralはスキャンできないんじゃないかと思う。
だって、他に方法がなさそうだから。
iPad miniにインストールしているPaSoRiアプリも、RC-S390のボタンを長押ししなくてもペアリングしにいこうとする。
じゃあ、そのときNexus7の設定アプリから見えてるかというと、見えない。
RC-S390の青LEDが点滅するモードになると、設定アプリから見える。
うーむ・・・。

 

まず、RC-S390の使い方を把握しておこう。
ボタンを2秒長押しすると、電源のON/OFFができる。
見分け方は、

  • 電源がONになった・・・通信状態ランプ(青LED)が3回点滅
  • 電源がOFFになった・・・通信状態ランプ(青LED)とバッテリー残量ランプ(橙LED)が1秒点灯

だ。
では、2秒長押ししてみよう。
うん、両LEDが点灯したから、電源OFFだ。
では再度2秒長押ししたら・・・あれ、また両LEDが点灯したぞ・・・。
さらに長く押したら、青LEDが点滅し始め、LightBlueが検出した。

つまり、一度ペアリングさせないと電源がONにできないという仕様なんだな。
まあ、製品としてはそうか。

LightBlueが反応したので情報を見てみると、ペアリングを要求された。
要求はされたのだが、サービス一覧は取得できたみたいだ。
このとき、Nexus7の昨日作ったスキャンアプリは検出できなくなっている(PaSoRiは青LED点滅中)。
ペアリング要求をキャンセルしても、Nexus7からは検出できない。
BlueLightで「PaSoRi」をタップしてDisconnectすると、Nexus7からも見えるようになった。
Nexus7からペアリングすると、青LED点滅は消えた。
この状態でボタンを2秒長押しすると、両LEDが点灯。つまり電源OFF。
もう一度2秒長押しすると、青LEDが3回点滅。つまり電源ON。
BlueLightでスキャンすると、PaSoRiが見えている。

 

わかったことをまとめよう

  • PaSoRiが誰ともペアリングしていない場合、電源のONだけをすることはできない
  • ペアリングしていなくて青LED点滅しているとき、誰もConnectしていなければAdvertisingしている
  • 誰かがConnectすると、Advertisingしない(当たり前)
  • Connectionするとペアリングの要求を行う。ペアリングしなくてもサービスとキャラクタリスティックの一覧は取得できるみたいだ(まだBLE仕様をわかってない)
  • ペアリングすると、ボタンで電源のON/OFFができるようになる
  • 電源OFFのときは、スキャンしても検出できない(当たり前)
  • 電源ONにすると、スキャンして検出できる。

ってことは、ペアリングして電源ONなら、ConnectionしていないときはAdvertisingしてるってことか。
それはUndirectedでやっているので、ペアリングしていない人でもスキャンできてしまうのかな。
ペアリングしている人にだけAdvertisingする方がよさそうではあるが、別の端末で使いたいときに面倒になるのかな?
いや、それなら5秒長押ししたときにだけUndirectedなAdvertisingにすればよさそうなものだが。
まあ、ここはまだ私が仕様をよくわかっていないせいかもしれんので、わかってから考えよう。

 

いつだかの推測で、相手がいなくてもConnection状態を維持しているのでは?と書いていたが、そうではなく、Connectionしてない間はAdvertisingしているので、それをアプリが捉まえている、という動作なのだろう。

image

2013/11/23

[ble]BLEを試してみたい (4)

さて、Androidでデバイスのスキャンまでできたので、iOSで同じところまでやってみよう。

https://github.com/hirokuma/BleTest_ios

こっちは、あれこれ参考にさせていただいた。
というのも、iOSアプリのしくみがよくわからんかったからだ。
プロジェクト管理に回るっていうのはこういうことなのね・・・という一抹の寂しさを感じる瞬間である。

それはいいとして、今回はまったのはここだ。

mCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

みんな「self」って書いてるけど、型は「id<CBCentralManagerDelegate>」なのだ。 ってことは、selfと言ってはいるけれども、なんか継承しているはずだ。

結果としては、ここを参考にした。 
https://github.com/reinforce-lab/CoreBluetooth_samples/blob/master/BSHSBTPT01_samples/first_sample/KeyFobSample/KeyFobController.m

mファイルに@interfaceを書き、 @interface xxx() <CBCentralManagerDelegate>

のような形にして、selfに持たせた。
まあ、selfじゃなくてもいいんだけど、さっき書いたAndroid版と同じようにしたかったので、なるべく閉じたファイルにしたかったのだな。


しくみがわからんかっただけで、今のところ実装量はiOSの方が少ない。
と思ったが、まだiOS版はスキャンの停止を組み込んでなかった。
これからですな。。。

[ble]BLEを試してみたい (3)

Androidのサンプルを見ながら作っていたのだが、私が知らない小技があって(というよりも、私が知らなさすぎるだけだが)、もうちょっとシンプルな作りにしたいと思った。

で、結局こちらを参考にさせていただいた。
http://blog.fenrir-inc.com/jp/2013/10/bluetooth-le-android.html

Activityに突っ込んでしまうと、他のアプリを作るときに持ってくるのが面倒になるので、別のクラスを作ってそこにBLE操作関係を置くようにした。
https://github.com/hirokuma/BleTest/blob/master/src/com/blogpost/hiro99ma/bleutils/BleUtils.java

動かすと、アプリ起動などと同時にスキャンを行う。
スキャンしたデバイス名は、logcatに出てくる。
うちにはRC-S390しかないのだが、ちゃんと「PaSoRi」が出てきた。

 

サンプルを見ていてよくわからなかったのが、BluetoothAdapter.isEnabled()を2回呼んでいるところ。
なんだろう?
絶妙なタイミングで呼び出された場合を警戒しているのか?

これで、基本的なスキャンのところまではできたんだけど、スキャン結果をコールバックするところが無い。
理由は簡単で、やり方を調べていないからだ。
まあ、これからだな。

[ble]BLEを試してみたい (2)

Android4.4のUSBデバッグアイコンが、いつも気になる。
キットカットなんだろうとは思うけど、なんか、なかなか、ねぇ。

image

  • チョーク4本
  • いかだ
  • お風呂のふた
  • 本の背表紙

4.4も、最初はKがつくパイの名前だったと思う。KがつくパイといえばKidney Pieが思いつくんだけど、あれはお菓子じゃなくて料理なのかな?


では、サンプルソースもあることだし、まねをしながら同じようなアプリを作ってみよう。
作りながらメモを書いていくだけなので、途中で間違ってしまう可能性有りだ。
ちゃんとした説明は、以下のページがよさそうだった。
【連載】Bluetooth LE (5) Android 4.3 で Bluetooth LE 機器を使う

じゃあ書かんでいいやん、と思われるだろうが、勉強の一環だ。

 

AndroidManifest

まずは、Android Manifestだろう。
uses-featureとuses-permissionを追加するようだ。

image

android.hardware.bluetooth_le

 

image

android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN

それぞれ、通信許可と検索許可らしい。
ペアリングが済んでいたらADMINはいらないのかな? まあ後で試そう。

いつも思うのだが、uses-permissionはコンボボックスで選択できるのに、uses-featureはテキスト入力なので、うろ覚えで選択ができない。
こっちもコンボボックスにしてくれないものか。

サンプルではServiceがあるので、そのための記述があるけど、まあ後で考えよう。

 

BLE peripheralのスキャン(の下調べ)

まず、対象の機器を探そう。
RC-S390はボタンを長押しすると「私はここよ!」みたいなモードになるらしい。
たぶん、これが「Advertising」という状態なんだろう。
Interface誌の説明では、Advertisingとかはリンク層の動作らしい。
まだGATTとかのアプリは絡んでこない。

Advertising→Connecting、という流れだそうな。
Core_V4.0[zip]を見ると、p.2263に状態の一覧らしきものがあった。

  • Standby
  • Advertising
  • Scanning
  • Initiating
  • Connection

まず最初はStandby。
Initial Setup→Random Device Address→White Lists、という過程を経ないとadvertising/scanning/initiatingにできなさそうだ。
PDFでは、Host A/LL Aだけがやってるけど、これはHost B/LL Bでも同じなのかな?
どちらかがCentralで、どちらかがPeripheralになると思うのだが。。。

Advertisingは「by enabling advertising」とあるので、Standby状態から「advertisingになりたい」という要求を受けないと遷移しないのだろう。
RC-S390では、そのトリガがボタンの長押しということか。
UndirectedとDirectedの2種類があるらしい。PDFのシーケンス図を見ると、Undirectedでは"Advert"が飛んでいるが、Directedだと"LL_DIRECT_IND"が飛んでいる。。。何を見たらいいんだ。。。

 

PDFのp.1639にGAPと機能の必須/オプションみたいな表がある。
GAPは、Generic Access Profileの略らしいが、もうこの際細かいことはどうでもよい。
PeripheralとかCentralという文字が出てきてるので、この表を見ると何かわかりそうな気がする。

  • StandbyはCentralもPeripheralも必須
  • AdvertisingはPeripheral必須
  • ScanningはCentral必須
  • InitiatingもCentral必須
  • Connectionは、CentralはMaster必須、PeripheralはSlave必須

ということらしい(MはMandatoryだろうけど、Eはなんだろう。。。)。
Advertisingに2種類あると書いたが、Undirectedが必須で、Directedはオプショナル(なんかタイプが44つあるみたいで、Connectable undirected eventってのが必須)。
後で出てくるScannningも、Activeは必須(正確にはC1)で、Passiveはオプショナル。
(でも「オプショナル」っていいつつ、普通載せるけど、ってことあるしなぁ。。)

 

さて、基礎知識を身につけたところで、再挑戦。
Standbyは、CentralもPeripheralも実施する。
そしてPeripheralはAdvertisingを開始し、CentralはScanningを開始。
CentralがScanningしてPeripheralを見つけたら、Initiatingする。
Initiatingは、PeripheralとしてはAdvertに対してCONNECT_REQが返ってくる動作に見えるようだ。そこまで含めて"Advertising"ということか。
Initiatingが終わると、接続完了ってことで、たぶんConnection状態になるんだと思う。

調べるのが面倒なので推測だが、Connection状態になると、「切断」ってやらない限りは接続が切れないようになってるんじゃなかろうか。
そうじゃないと、RC-S390をつなげたiPad miniが電源とか切ってても、アプリを起動したらAdvertisingしなくても使えるようになることの説明がつかない。
まあ、相手がいなかったら切断するってしくみにすることもできるんだろうけど、プロトコルとして制約がないってことなんじゃなかろうか。
ほら、NFCのLLCPだと一定時間内に応答がなかったら切断シーケンスに入るから、それとは違うということをいいたいのだよ。

 

脱線したが、スキャン動作は、ペアリングとは別として「必要」ということだ。
じゃあペアリングはなんなんだ? なくてもよいのか??
これもInterface誌にあった。
リンク層の接続はAdvertisingとかでやるが、ペアリングはもう少し上の層での認証接続とのことだ。通信する相手が正しいかどうかの確認を行うということか。
だから、ペアリングしなくてもRC-S390は見えたが、サービス取得などができなかったということのは、まだ接続してよい相手として認められていなかったからだろう。
なお、Interface誌の説明ではペアリングにも4種類あり、自動で承認するタイプもあるんだって。
へー。

 

また脱線してしまった。。。
長くなりすぎたので、今回はここまで。

2013/11/17

AutoHotkeyでbindがloopするときは$を使う

なんのことやら、という人には関係が無いメモ。
私はAutoHotkeyで、こんな割り当てを使っている。
  • Ctrl+F・・・右矢印
  • Ctrl+B・・・左矢印
  • Ctrl+N・・・下矢印
  • Ctrl+P・・・上矢印
  • Ctrl+H・・・Backspace
  • 全角/半角・・・Esc
Emacsか何かの配置みたいだ。私はEmacs使いじゃないのだけど、矢印まで指を動かすのが面倒なので、そこだけ使っている。
で、それはいいのだけど、検索がめんどくさい。
Ctrl+Fを使うんだろうけど、別のに割り当ててるからだ。
じゃあ、Ctrl+Shift+Fに割り当てようか、と思ったのだが、スクリプトがぐるぐる回って、だめなのだ。
そういうときは、$を使うらしい。
^h::Send,{backspace}
$^f::Send,{right}
^b::Send,{left}
^n::Send,{down}
^p::Send,{up}
sc029::Send,{Esc}
$^+f::Send,^f

2013/11/16

[nfc]Type2のカードエミュレーション(PCD)

Proximity Coupling Device。略してPCD。
なんのことやらって感じだが、NFCのR/Wはこう呼ばれている。
NFC Laboの用語集にも書いてあるのよ。

Android4.4のHCEは、Type4のカードエミュレーションらしい(まだ動かせてないので)。
私がよく使っている、RC-S620/SやRC-S370、あるいはNXPのPN533、PN532などでもカードエミュレーションできる。
そこで行っているのは、Type2やType3のカードエミュレーションだ。
先に言っておくと、これは私から見た範囲の話だ。
手近にあるカードが、Type2とType3しかないので、それ以外を調べていないのだ。

 

さて、RC-S620/S・・・というか、RC-S956チップやPN532チップでは、Type2のカードエミュレーションができる。
また、Type3のカードエミュレーションもできる。
「Type2」とおおざっぱに書いたが、実はいくつか細かな製品分岐がある。
それは、NFCID1のサイズだ。
Type2のNFCIDサイズは、Single、Double、Tripleの3種類がある。
それぞれ、4byte、7byte、10byteだ。
NXPのコマンド仕様書は無料でダウンロードできるので見てみると、Cascade、という言葉で説明してある。
まず、基本は4byte。
続きがあるなら、さらに続けて3byte。
まだあるなら、もう3byte。
4+3+3で10byte、というわけだ。

RC-S956, PN532系の場合、カードエミュレーションで実現できるNFCIDは、4byteまでだ。
しかも、先頭1byteが固定なので、実質は3byteが可変。SEL_RESも0x40固定。
ここが、NFCID2が8byteまるまる変更できるのと異なる点だ。
なんでもエミュレーションできるNFCID2に比べ、制約があるのだ。

まあ、そもそもNFCID1が4byteのやつは、すたれている[pdf]。
PCDでNFCID1が7byteとか10byteのって知らないので(私が知らんだけか)、もともと影響が少ない。
少ないというか、Type2の完全なエミュレーションをする機能がRC-S956やPN533にはない、というべきか。

これは私の知っている情報だけなので、企業でNDA契約とかすると、「実はこのオプションがありまして」なんてことはあるのかもしれない(ないと思うけど)。

が、これはあくまで、SONYやNXPのチップを使った場合だ。
自分で13.56MHzの送受信ができる装置を作れば、このあたりは暗号化がかかっているわけでもないので、ソフトだけで簡単に実現できそうだ。
製品のPCDチップがよい点は、NFCの取り決めをだいたいチップが吸収してくれているという点だ。
そんなに通信速度が速いわけでもないので、NFC周波数での送受信と少々の演算パワーさえあれば、このあたりは簡単に偽造できるのだ。
「そんなチップがあるのか?」といわれると知らないのだけど、無線のチップなんてたくさんあるんだから、探せばあるんじゃなかろうかね。

 

だから、だ。
NFCのセキュリティについてはやーやーいわれているのだ。
FeliCaが世界標準にならなかったのも関係ありそうだし、HCEでソフトからカードエミュレーションができるようになったといっても安心できないのも、そういう理由からだ。
しょせん、誰かが読めるように作ったデータは、どうにかすれば他人も読めるはずなのだ。
銀行のパスワードが、定期的に変更する+ワンタイムパスワード、のような形式になってきているのも、パスワードは破られるのが当然という考え方が根底にあるんだと思う。
パスワードの組み合わせが1億通りあります!とかいっても、1発目で当たったら意味ないし。

脱線してしまったが、Type2のNFCIDは、Type3よりもまねしにくい、ということは説明できたんじゃなかろうか。

[ble]BLEを試してみたい (1)

とりあえず、手を動かしてBLEを試してみたい。
なるべく手元にある環境でやれないものか。

調べたところでは、iOSとAndroidで可能らしい。
Androidは4.3からの対応で、「どの機種でも対応」というわけではないらしい。

幸い、Nexus7(2013)は対応しているようだ。
Nexus7(2012)のAndroid 4.4 Factory Imageがあったので「もしかしたら」と試してみたが、やはりだめなようだ。
ハードなのかドライバなのか知らんけど、まあ深追いすまい。
もちろん、iPad mini(iOS7)も、使える。あ、旧型の方ね(呼び方がわからん)。

Nexus7(2013)でやるか、旧iPad miniでやるか。
まあ、両方やるか。


Android4.3のサンプルに「BluetoothLeGatt」というサンプルがあるようなので、動かしてみる。

image

起動させると、PaSoRi RC-S390が出てきた。

image

まだペアリングさせていないので、これはペアリングさせるときも出てくる端末情報を出しているだけか。
このとき、ペアリングしているのはiPad miniとだったのだが、デバイスの有無の検索はいつでもできるのかな?
こういう基礎的なところがわかっていない・・・。

PaSoRiをタップすると、こんな画面が出てくる。

image

あれ、コネクトしてる??
スクリーンショットを撮る前は切断状態だったのだが・・・。
あ、今見たら接続していた。
とはいえ、これ以上は何もできないようだ。
ここから先はペアリングがいるということか。

 

今度は、SettingsアプリのBluetooth設定からデバイスの検索を行った。
・・・出てこない。
そう、説明書によると、ペアリングを行うときにはPaSoRiのボタンを5秒以上押す、となっているのだ。

まず、iPad miniの設定画面からPaSoRiを切断。
念のためこの状態でNexus7から検索をかけ、やはり表示されないことを確認した。
では、PaSoRiのボタンを長押しして、ペアリング状態にしよう・・・と長押ししたのだが、どうもこの場合には「電源断」になるようだ。
気を取り直してもう一度長押しし、青LEDが点滅する状態にする。
そしてNexus7から検索すると、今度は出てきた。

image

PaSoRiをタップすると、「ペアとして設定中・・・」が表示されて・・・進まない。
あれ、さっきはペアリングできたのに。。。

気を取り直して、Bluetoothを無効にして、もう一度有効にしてからPaSoRiをタップすると、ペアリングのPIN入力画面が表示された。
やれやれ。
ここでPaSoRiに貼ってある番号を入力すると、ペアリングができた。

再度サンプルに戻って、CONNECTをタップすると、情報が表示された。

image

うーん、iPad miniのLightBlueで見たときより、初めの2サービスが増えている。
あまりにもデフォルト過ぎるサービスか何かで表示させなかったのだろうか?

ともかく、Nexus7(2013)+Android4.4ではBLEが使えることがわかった(4.3からだろうけど)。

[nfc][hce]ATRがFeliCaで返ってくる?

Android 4.4のHCE(Host Card Emulation)がどうしても気になる。
SDK for NFC Starter Kitのサンプルでは、そもそもどうやって動くのかがわからない。
もっと何か、解析的なツールはないものか・・・。

どうやら、NDEF WriterがType4Aに対応しているらしい。
よし、とやってみたが・・・まあ、動かんわな。
最初は「タグが正しくない」みたいなエラーだったのだけど、何度かやるとPaSoRiが応答しないというようなメッセージになってしまった。
うーむ。

よくわからないので、自己診断をしてみよう。
PaSoRiのドライバには、診断ツールも入っているのだ。
やってみると、特に問題は無いらしい。
よかった。

せっかくなので、診断ログを見てみると・・・ATRという文字があった。
確かこれは、ATtRibuteとかそんなのの略だったよな?
これが返ってくるのはカードをPaSoRiにかざしたまま診断したときだ。
つまり、これはカードを読んだ結果らしい。

Nexus7をかざすと、ちゃんと成功で返ってきている。
ということは、やはりNexus7を何らかのタグとしてはわかってくれているみたいだ。

ATRは、こんな数字だった。

3B8F8001804F0CA00000030611FFDF0000000059

なんか、わからんね。
解析しよう。


http://en.wikipedia.org/wiki/Answer_to_reset

ここと、Interface誌2012年4月号のPC/SC資料を読みながら解析した。
途中から、PC/SCの資料がないとわからなかったので、そこはpcsc3_v2.01.09_sup.pdfを読んだ。

3B:TS
    Direct Convention
8F:T0
    8:TD1, TC1, TB1, TA1の順。TD1のみ有り。
    F:historical bytes。15バイト。
80:TD1
    8:TD2, TC2, TB2, TA2の順。TD2のみ有り。
    0:T=0(character-oriented)
        T=0...character-oriented protocol
        T=1...block-oriented protocol
01:TD2
    0:TD3, TC3, TB3, TA3の順。どれも無し。
    1:T=1(block-oriented)

804F0CA00000030611FFDF00000000:historical bytes
 
   80:カテゴリ・インジケータ
    4F:アプリケーション識別子の存在インジケータ
    0C:長さ
        A000000306:RID(この値は、PC/SC WorkgroupのAIDらしい)
        11:SS(pcsc3_v2_01_08_sup.pdfに表がある)
            FeliCa
        FFDF:NN
             RFU
        00000000:RFU

59:TCK
    チェックサムみたいなやつ。

メモ書きをそのまま貼り付けた。

よくわからないけど、FeliCaと見ているのか?
でも、その次のNNは変な値が入っている。PC/SCにはちゃんとFeliCaの定義値があるというのに。

ちなみに、MIFARE Ultralight-Cをかざした場合はこうなった。

03:SS
        ISO 14443A part3
003A:NN
        MIFARE Ultralight C

うん、SSもNNもあってる。

ちゃんとFeliCaをかざすと、診断結果はこうなる。

カードとの通信(PC/SC): OK
  ATR        : 3B8F8001804F0CA00000030611003B0000000042
  Target Name    : FeliCa
  Target Type    : FeliCa
  Baud Rate    : PCD->PICC : 424, PICC->PCD : 424

これがNexus7をかざすと、こうなる。

カードとの通信(PC/SC->FeliCa): OK

うーむ。
これはAndroid BeamをOFFにしたときの値。
Android BeamをONにすると、こうなる。

カードとの通信(PC/SC): OK
  ATR        : 3B8F8001804F0CA00000030611FFDF0000000059
  Target Name    : FeliCa NFC-DEP Target
  Target Type    : FeliCa(NFC-DEP Target)
  Baud Rate    : PCD->PICC : 424, PICC->PCD : 424

そう、さっきはこの値を解析したのだな。
ログにも出ているが、DEPでターゲット側になったときの情報なのだろう。
NNもRFUな値になっているが、実はNFC-DEPの値かもしれんな。

じゃあ・・・そうじゃないときのATRは取れてないということになる。
と何度か繰り返すと、Android BeamをOFFにしていてもNFC-DEP Targetになってることがあった。
よくわからんので、Nexus7(2012)をかざすと、NFC-DEP Targetになった。
もう、さっぱりわからん・・・。

[hce]Nexus7(2013)をAndroid4.4にしてみたが、HCEがよくわからん

わからんシリーズだ。

Nexus7(2013)のAndroid 4.4 Factory ImageがGoogleから出ていたので、インストールした。
そうすると、設定メニューに「タップ&ペイ」という項目が増えていた。
なんとなく、HCEできそうだ!

SDK for NFC Starter Kitのサンプルに、Type4Tag.exeというものがあり、なんとなくType4を読んでくれそうだ。
試してみたが・・・よくわからん。
Type4Tag.exeは、PaSoRiになにも置いていないと「タグを置け」と出るし、Type2とかのタグを置くと「それは違う」と出してくれる。
Nexus7(2012)をかざしてみたのだが、「タグを置け」の方だった。
Nexus7(2013)をかざすと「それは違う」と出てくる。

「それは違う」というのは私の言葉で、正確には「Failed to access to the tag.」と出る。
アクセスに失敗した、というわけだ。
そういうことからすると、なんらかのカードエミュレーションをしているように見えるのだが・・・。

何を気にしているかというと、HCEのサンプルアプリなどを動かさなくても動作が変わらないからだ。
HCEって、アプリがなくても何かしら動いているのかいな?
それにしては、logcatに何も出てこないのだが・・・。
もう少し、「何か来たけどAIDが違うのではじきました」とか出てくれれば安心なのだが。

Android Beamでターゲットになったときが反応しているのかと思って、Beamだけ止めてみたのだが、やはり変わらない。
スクリーンがロック状態になると、「タグを置け」になる。
裏で動くんなら、ロック状態でも動いてほしい気はするのだが・・・。

Type4 Tagが手元にないので、Type4Tag.exeがどう動くのかわかっていないというのもよろしくない。
かといって、手軽に買えるところもないしなあ、うーむ。

よくわからん、という状況で、代案が出てこない私であった。

2013/11/10

[ble]BLEのPaSoRiを作るなら、どうやるとよかろうか

RC-S390が、iOSで使えるPaSoRiとして出ている。
が、開発キットは一般向けではないとのこと(電脳羊さんより)。

むー、それは仕方ない。
「あるものは使いなさい、ないものは作りなさい」の世代としては、作らざるを得ない。
手持ちでできるとするなら、こんな感じか?

image

いや・・・これはちょっとないな。
せっかくBLEで消費電力を抑えようとしているのに、RC-S370だとUSBなので、5Vもいるじゃないか。
RC-S620/SならUARTだし、sleepするようなコマンドもあるのでよいかもしれんが、それでもきついか。
(私のイメージだと、UARTもまだ電気を食う気がしている。)

そういえば、I2C版のが展示会で出てたという記事を見たことがあったけど、どうなったんだろう?
個人的にはSPIの方がデバッグしやすくて好きなんだけど、トラブったりしなければ配線が楽だ。

そういうことを考え出すと、やはり作るのは難しいなあ。

[ble]知りたいところだけ調べる (3)

Characteristicについて、もう少し調べておこう。

LightBlueで見ると、Characteristicのアクセス方法がいくつかあるのがわかった。
ReadとかWriteとか。
一覧が欲しいと思ったが、なかなか出てこなかった。。。
コアバージョン 4.0(pdf)の、p.1898にある「Table 3.5 Characteristic Properties bit field」がそれらしい。

Properties Value
Broadcast 0x01
Read 0x02
Write Without Response 0x04
Write 0x08
Notify 0x10
Indicate 0x20
Authenticated Signed Writes 0x40
Extended Properties 0x80

ざっと説明を読んだところだと、ClientがServerに対して要求をかけるシーケンスになっていた。
ClientがRead要求をかけると、Serverから読んだ値が返ってくる、というような。

ReadとWriteはわかるとして、NotifyとIndicateはなんだ?
Notifyは、ServerからClientへCharacteristic ValueをNotifyする手段のようだ。
Indicateも、ServerからClientへCharacteristic ValueをIndicateする手段のようだ。
Notifyは通知、Indicateは指示。
つまり、Notifyは「こんな値です」と教える手段で、Indicateは「値を教えろ」と要求する手段ということなのだろう。

RC-S390はPeripheralで、iPad miniがCentralという立ち位置なのだが、CharacteristicのアクセスとしてはRC-S390が「Server」で、iPad miniが「Client」ということになりそうだ。

[ble]知りたいところだけ調べる (2)

忘れず、続けよう。

BLEの構成は、こんな感じみたいだ。
仕様として、物理層との接続にHCIを使うようになっているとかなんとか。
ワンチップでBLEを実現したマイコンがあれば、あんまり関係ないかも。

image


うちには、Nexus7(2013)とiPad miniでBLEが使える。
なんでも、Androidは親だけで、iOSは親にも子にもなれるとか。
ならば、iOSで子を作って、Androidでそれを見てみるのがいいのかもしれん。
が、まだ知識が浅いので、BLEの子製品と、アプリでBLEのアクセスができるものがあるので、それでやってみよう。
うちにあるBLEの子製品は、RC-S390だけなので、これを見る。

iOSにLightBlueというアプリがあり、これがいいそうだ。
使い方はよくわからないけど、デバイスを見つけて、サービスを見て、そのキャラクタリスティックを見る、という扱いのようだ。

デバイスとしては、PaSoRiが1つ見える。
サービスは2つあり、1つは「Device Information」、もう一つは数字だけしか出てこない。
このDevice Informationサービスは、標準サービス?みたいなもののようで、略称は「DIS」らしい。

ちなみに、上の図は雑誌Interfaceを読みながら描いたのだが、さっきのリンク先にも図があるな。
少し違うけど、まあ深くは考えまい。

 

さて、DISの技術書があるので見てみよう。
これを読むと、DISには8つのCharacteristicがあることになっている。
RC-S390には4つだけCharacteristicsがあった。ということは、全部載せないといけないというものでもないのか?
でもPDFには「C.1 (Mandatory to support at least one)」となっているから、載ってないといかんのではないだろうか。
あるいは「この中の最低1つは」というat least oneなのかしら。
英語が弱いのが哀しい・・・。

でも、後者の意味なら、表としては書き方がよくない。
8つのCharacteristicの1つ1つに「C.1」と書くのではなく、セルを1つに結合してから書かないとわからん。
表の上にある英文に「one or more of the characteristics」とあるから、やっぱり後者なのか。

気を取り直して。
LightBlueには、Device Informationサービスと一緒に0x180AというUUIDが書かれていた。
この数字は「Bluetooth Core Specification v4.0」で規定しているそうだ。
ページがあった。割り当てられた数字のページがあるのはありがたい。

クリックすると、その詳細が見られた。
Readが"Mandatory"になっとるやん・・・。
いや、これは「Characteristicとして存在するなら、ReadはMandatoryだよ」という意味なんだろう。
きっとそうなんだ。

このあたりは、秘匿する情報ではないようなので、RC-S390の値を載せておこう。

  • Manufactuerer Name String : AirPaSoRi
  • Model Number String : ModelNumber01
  • Firmware Revision String : Firmware01
  • Software Revision String : Software01

まあ、特にどうということのない文字列だ。
そういえばiPad miniとペアリングしたとき、名前が「PaSoRi」と出てきた。
これは、Device Informationサービスから取得した名前ではないということだ。
ペアリングしないと使えないから、ペアリング作業の前に検索したら見える名前なんだろう。
深入りすまい。

先ほどサービスが2つ、と書いたが、そのもう1つの方がRC-S390を扱うためのサービスなのだろう。
この中には、7つのCharacteristicがある。
サービスが標準じゃないので、このCharacteristicも標準じゃない。
つまり、なんだかわからない、ということだ。
ははは。

これで終わっては寂しいので、もう少しCharacteristicについて調べましょうかね。

[nfc]最近

本業が忙しくて、記憶が無い。
NFCのことも記憶から遠ざかって、私ってNFCのことやってたんだっけ、くらいなところまで来てしまった。
思えば遠くへ来たもんだ。
まあ、それでは寂しいので、最近のNFCを振り返っておこう。



NFC Forum

2013年7月に技術書が更新されて以来、そのままだ。
一番下に「Last updated」があるので、そこの日付を覚えておくとよかろう。
ドキュメントが追加されたが、関係があるのは一部の人々だろう。
まあ、NFCのドキュメントが全部更新されたとしても、関係があるのは一部の人なんだけど・・・。
デバイスの認証が、「Certification」と「Plugfests」になった。
Plugfestsは、英語だと「辛口紹介」みたいなものらしい。
「ここのR/W使えない、ぺぺぺっ」みたいなことを言われるんだろうか。



Android

KitKatこと4.4になって、Host Card Emulationがサポートされるようになった。
imageframeworks/base/core/res/res/drawable-nodpi/platlogo.png
ハードがNFCをサポートしているのであれば、HCE対応は可能だとは思う。
やるかどうかは別だけど。
Hostは、自分(NFCチップなど)ではなく、自分を操作してくれる親方のこと。
メインCPUとか。
通常のカードエミュレーションは、特に規定は無いのだけど、目的からして、だいたいNFCチップとかSecure Elementとか、そういうNFCに関するところががんばり、ホストは感知しない事が多い。
というのも、ホストががんばると言うことは、ホストがやるべき作業時間に他のことをすると言うことであり、業務割込、みたいなことになってしまうからだ。
そして、このホストさんは非常に高給取り(電力を使う)なので、お金を支払う側(電池)からすると、なるべく温存しておきたいところなのだ。
NFC専用のチップなどはそれを心得ているので、必要最低限のことをさらっとこなしてくれる。
その代償として、ホストさんは何があったか知ることがない、というところだ。
PaSoRiやPN532とかでカードエミュレーションするときもそうなのだけど、カードエミュレーションする前提になっていないNFCチップは、ホストががんばってあげることになる。
ホストさんは、自分でNFCタグを読むことができないので、周辺機器から「読んだんだけど」って結果をもらってから動くことになる。
「ああ、R/Wさんから要求が来たので、返事をしなくてはならないわ、いそいそ」。
LLCPでターゲットになったときの動作と似ているのだが、あれは基本的に「対等」なので、そこまで気にしなくてよいのだが、カードエミュレーションとなると、相手が望む通りに動かないと、相手も動けなくなってしまうのだ。動けなくなるというか、相手からすると「対象のカードではない」と思うだけになるのだが。
例を出そう。
昨年だったか一昨年だったか、RC-S620/Sのカードエミュレーション機能を試すために、かざしてログオン、というソフトに対して使うことができるかどうか調べたことがあった。
結果としては対応できたのだが、そのためにはカードとして相手が期待する動作をしないとまったく意味をなさなかった。
まあ、当たり前といえば当たり前なんだけど。



iOS

iOSがNFC対応したわけではないが、iOS向けのPaSoRiが出た。
最近の傾向では、デバイス発売と同時にあれこれソフトも一緒に出すものだと思うのだけど、そういうのがないせいで、急速に冷えてしまった気がする。
アプセサリ、という言葉もあるけど、ハードとソフトをメーカが同時に提供するよりも、ハードとハードをアクセスするためのAPIを提供したほうが、評判がいいんでないかな、と思った。
まあ、RC-S390のSonyとしての方向性がよくわからないから、買う方はためらうわな。
もうちょっと、ソフト主体でホームページを作った方が、一般受けはすると思う。

2013/11/06

[android]HCEはMIFARE DESFireみたいな動きをするのか

Android4.4 のHCEは、まだうちでは動かせていない。
情報だけで妄想しよう。

ISO/IEC 7816-4、というのが、一番上のプロトコルスタックになっている。
通信関係は詳しくないのだが、「プロトコルスタック」というのは、一番上の層が素のデータに近く、下の層に行くにしたがって層のしきたりでデータを包んでいく、というイメージだ。
だからプロトコルスタックが薄い方がデータサイズなどは小さくなるけど、別に好きでそうしているわけではなく、汎用性とか安全性とかを考えた末にスタックが積まれていくものだと思っている。

なので、HCEがユーザに取りあえず見えるのはISO/IEC 7816-4だろう。
ICカードというかメモリカードというか、その辺って昔からアクセスのルールがあったように思う。
10年くらい前にSIMのメモリアクセスを調べたときに、EFなんとかってのがあるのを見てそう思ったのだ。

まあ、それはともかくとして、ISO/IEC 7816-4というのは「一般的な」アクセス方式というかプロトコルらしい。
NFCだと、Type4が相当するようだ。
HCEが標準でサポートしているのはNFC-Aなので、TechnologyがNFC-A、PlatformがType4となると、該当するのはType4Aとなる(Type4Bというのもあるが、これはNFC-B)。

持ってないけど、Type4Aは、タグで言えばMIFARE DESFireだろう。
私にとって、DESFireはFeliCa Standardと同じくらいの位置づけだと思っている(勝手な思いだが)。

MIFARE Ultralight C  ----- FeliCa Lite(/S)
MIFARE DESFire       ----- FeliCa Standard

こんなイメージがある。

Ultralight CもLiteも、決済系に使うにはセキュリティが弱いと思っている。
Ultralight Cはセキュアなアクセスができるけど(ドキュメントは申請が必要なので、見たことない)、無線区間は平文なんじゃないか・・・となんとなく思っている。
これはまったく根拠がないので、間違っていたら教えてほしいところだ。
私がそう思う根拠は、「それにしてはタグの値段が安い」というだけのことだ。

Liteは、少なくとも無線区間は平文だ。
領域をRead Onlyにすることはできるけど、セキュアなアクセスはできない。
Lite/Sになると双方向認証っぽいものがあるのだけど、どちらにしても無線区間は平文だ。
傍受すれば解読はたやすい。

DESFireになると、全然わからない。
使ったことないし、見たこともない。
しかし、NFC-Aで決済と言えばDESFire、というイメージがある。

同じく、FeliCaも決済系ならばStandardだ。
これは、FeliCa Standardのファイルシステムが、フォルダを降りるごとに鍵が必要だったりするためだと思う(そういうアクセスは自分でできないので、読んだ情報だけ)。
交通関係はスピードが要求されるので(特に東京か)、そのフォルダを一気に駆け下りる縮退鍵なんてものもあり、いろいろ考慮されている。
まあ、そのせいか、「悪い人じゃないんだけど、お付き合いするにはちょっと・・・」という感じで、あまり世界的には広がっていない。


さて、HCEだが、読んでる感じからすると、Type4Aっぽいと思う。
Type4Aは、カードの検出まで終わったら、あとはISO-DEPを使ってデータ交換するらしい。
そう、AndroidではAPIが提供されていたものの、なんだかよくわからないあいつだ。

このISO-DEPについては、PN532のドキュメントにある情報がわかりやすいのではないか。
もちろん、PN544やPN65、MFCが持つような機能は、NFC R/Wチップが持つ機能とは異なる。
が、規格として決まっているところについては読みやすいんじゃなかろうかね。

私もそのうち読みたいものだ。

2013/11/03

[android]4.4からはCardEmulationができるそうな (3)

最終回だ。

Nexus7(2012)で、KitKatを動かしてみて、できるかどうか試そうとした。
結果としては、動いていない。
これは、実装がわるいのだか、作られているROMイメージに含まれていないのか、そこはわかっていない。
AOSPっぽいので、やはりドライバが対応しないといかんのかな、とは思う。

では、今のところKitKatにきっちり対応しているのはNexus5だけか。
けっこう手頃な値段とは言え、これのためだけに購入するのはなぁ。。。
Nexus7も、もう少ししたらKitKat対応が入るらしい。
それまで待った方がよさそうなところだ。

[android]4.4からはCardEmulationができるそうな (2)

http://developer.android.com/guide/topics/connectivity/nfc/hce.html

HCE and Security、という項目がある。
読んだ感じからすると、Android内の話みたいだ。NFCコントローラなどから読み込んだデータがそのまま渡されるよ、とか、そんなことを言ってるんじゃなかろうか・・・。
英語が自信持って読めないので、違ってたらすまん。

どんなにアプリががんばっても、所詮は無線で、しかもプロトコルが決まっているのだから、外部にリーダーを置けば読むことができるだろう。
FeliCaだと「Without Encryption」ってコマンド名のものは、無線区間が平文で流れますよ、大丈夫ですか、ということだ。

じゃあ、HCEはどうかというと、それは調べないと知らないからわからない。


さて、なんとなく概略がわかってきたような気がするので試してみたいのだが、まだまだそれには知識が必要なようだ。

まず、何をどうしたらどうなるの?がわかっていない。
カードエミュレーションだから、相手になるのはリーダライタだ。
PaSoRiでいけるのか?というところだが、これはRC-S380であれば少なくとも大丈夫なはずだ。
なぜなら、RC-S380はNFC Forumの認証試験に通ってるからだ(v1.2)。

HCEは、ISO/IEC 7816-4, ISO/IEC 14443-4で動く(という表現でいいのかわからんが)ようだ。
標準は、NFC-AでISO-DEPするらしい。NFC-Bはoptionalだそうな。

ISO/IEC 7816でNFC-Aといえば、NFC ForumでいえばType4Aに相当するみたいだ。
うーん、タグを持ってないのでまったく見てもいなかったな・・・。
日本では使ってないんじゃないかねぇ。

Interface誌2012年4月号を読みながら勉強しているところだが、PC/SCなんかも関係しているというか、似ているというか含んでいるというか、そんな立ち位置らしい。
載っているのはアプリがリーダライタを使うときの目線で、C-APDU(Command APDU)をリーダライタに投げると、その応答としてR-APDU(Response APDU)が返ってくる、というものらしい。

となると、PaSoRi側もなんかソフトを作らんと試せないんだろうな。
あー、めんどくさい。

[android]4.4からはCardEmulationができるそうな (1)

久々に風邪ひいてるみたいで、意識が遠のいてます。。。

まあ、それはともかくとして、KitKatことAndroid4.4からはNFCのカードエミュレーションができるらしい。
うひゃっほう。

とりあえず、資料だけ眺めることにした。
http://developer.android.com/guide/topics/connectivity/nfc/hce.html
Host Card Emulation、の略らしい。
だいたい「Host」とつくと、メインCPUとかがからんでくるものだ。

通常の・・・というか、例えばおサイフケータイが実現しているFeliCaでのカードエミュレーションは、「Host」はからまない(データについては)。
相手と、FeliCaチップを介してSecure Elementというものがお話をしている感じだ。

しかしHCEは、例えばPaSoRiがカードのふりをしているのと近いように見える。
SonyのRC-S620/Sリファレンスマニュアルなどを読むとわかる。
わかるというか、ターゲットになる時の処理がいろいろと書かれているのだが、カードエミュレーションのことに触れないように触れないように書かれている。
ISO/IEC-18092とあわせて読むと、理解が深まることであろう。
興味がある方は、フローを見比べるとよかでしょう。


ざっと読んだ感じだと、R/Wモードの時と違い、ロック状態でもHCEの検知くらいまではやってくれるようだ。
Card Emulationするときは、だいたい電力を最小限に抑えたい場合が多い。 おサイフケータイを見たらわかるが、あれは常に動作しているものだ。
それがばんばん電気を使ってたら、すぐに電池がなくなって「いらんよ」となるだろう。

それを避けるため、だいたい「搬送波検知」というしくみがある。
13.56MHzの搬送波を検知すると、ホストマイコンとかに割り込みを通知して「何か来たけん、電力をくれんかね」という信号を出すのだ。
FeliCa Plugなんかもそうなってる(だから、搬送波が出てるようなところにCard Emulationする端末を置いておくと、電池消費が激しくなるはず)。

たぶん、ここもそういうしくみを使ってるんじゃないかな。
ただ、それで勝手に動いてしまわれても困るからか、ダイアログを出してユーザに通知し、許可を求めるようにするみたいだ。
USB Hostも、そうだったような気がする。
なんでもかんでも起こしてしまわないように、AIDを登録しておいて、一致したAIDじゃなかったら無視する、みたいになっているように読んだ。

「じゃあ、そのAIDってなんだ?」となるが、まだ読んでない。
 早くもCross Referenceがあったので、使わせていただいた。

http://tools.oesf.biz/android-4.4.0_r1.0/xref/cts/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceUtils.java
     15     public static final String PPSE_AID = "325041592E5359532E4444463031";
     16     public static final String MC_AID = "A0000000041010";
     17 
     18     public static final String TRANSPORT_AID = "F001020304";
     19     public static final String ACCESS_AID = "F005060708";

うーん、よくわからんですな。
まあ、これはまたお楽しみで残しておきましょう。