LLCPのCPは
CarPの略かな?
LLは
Large Lengthらしいから
きっと私たちのことよ!
ふっ、愚か者たちめ。
SNEPのSがSUZUMEだと
いうことに気付かんとは。
第1章 NFCでのデータ交換
第2章 NFC-DEPって?
第3章 LLCPって?
第4章 SNEPって?
- 1 -
第1章 NFCでのデータ交換
はじめに
通信とは、データを交換するためのルールである。だと思う。
幅広く見ていくと、すべては通信で成り立っている。あいさつだって、一種の通信だし、そもそも会話自
体が通信といってもいいだろう。本を読むのだって、本からのデータを受けとっているわけだし、テレビ
だってそうだ。
ただ、「データ交換」と銘打った場合、それは通信のためにデータ交換をするのではなく、データ交換
のために通信を行う、ということになる。この特集も、 NFC デバイス同士でデータ交換を行うためにつ
いて説明することが中心となる。
いつもと違って、今回は文章がお堅いし、冗長になるかもしれない(冗長なのはいつもか)。それは、私
が「通信」というものに弱く、理解するのに時間がかかったからだ。自信があまりない、と言い換えても
いいかもしれない。
そんなわけで、気楽に読んでほしい。なお、このドキュメントでは RC-S620/S でのやり方を書いてい
く。他のデバイスの方は適宜読み替えていただきたい。
データ交換のためのプロトコル、 DEP
NFC Forum では、 Digital Protocol でいくつかの規定を行っている。大ざっぱにいうと、以下のように
なる。
1) Technology : 無 線 通 信 の 方 式 (NFC-A, B, F)
2) Platform : メ モ リ の 方 式 (Type 1, 2, 3, 4A, 4B)
3) Protocol : デ ー タ 交 換 の 方 式(NFC-DEP, ISO-DEP)
今回の話は、 3 番目の「 Protocol 」である。 DEP 、というのは"Data Exchange Protocol"の略であ
る。データ交換プロトコル、だ。これを使えば、 NFC でデータ交換できるのである。
そう思って読み進めていたのだが・・・正直なところ、さっぱりわからなかった。かろうじてわかったの
は、 NFC-DEP は、 Technology の NFC-A か F 、 ISO-DEP は NFC-A か B 、というところまでだっ
た。
NFC-DEP は ISO-18092(NFCIP-1)由来、 ISO-DEP は ISO-14443 由来、というところまではわかっ
た。 14443 は入手しづらいが、 18092 は ECMA にもあり、 ECMA は無料ダウンロードできたので、
そこから着手することにした。
月刊 NDEF 2013 年 8 月号
- 2 -
DEP に時間がかかった私
今にして思えば、 DEP のことを調べようと思ってから、 ISO/IEC にたどりつくまでが長かった。そし
て、たどり着いてからも長かった。
言い訳をしておこう。私が持っている NFC のデバイスは、 SONY の RC-S620/S というリーダライタ
のみである。このデバイス、いや通常の我々が入手できる既成製品で扱うことができるのは、あくまで
「有線コマンド」、すなわち UART や SPI などでしか操作することができない。そして、 ISO などのドキ
ュメントで規定されているのは「無線コマンド」である。まあ、 NFC というのは無線だから仕方ないのだ
が。
パソコンを使って印刷をしたいなら、パソコンでプリンタを制御しないといけないのと同じように、 NFC
リーダライタで無線コマンドをやりとりしたいのなら、有線コマンドで NFC リーダライタを制御しないと
いけないのだ。
NFC リーダライタとのやりとりは有線コマンドになるが、そのコマンドは各社で異なる。 RC-S620/S も
そうだった。しかし、 RC-S620/S は当時コマンドのマニュアルが公開されておらず、操作方法がわか
らなかった。そのため私は「 NFC Forum に書いてあるコマンドを使えば操作できるのでは?」と思
い、時間を費やしたこともあった。そう、当時の私は、有線コマンドと無線コマンドの違いがわかってい
なかったのだ。
いろいろ調べ、 RC-S620/S の有線コマンドがわかり、ずいぶんと操作できるようになったのは比較的
最近のことだ。それでも、無線コマンドを直接操作しているわけではないので、ときどき苦戦することも
ある。
まあ、そういうものだと割り切ろう。
操作 印刷
有線 無線
NFC R/W
割り切って
忘れてしまえ
月刊 NDEF 2013 年 8 月号
- 3 -
ISO/IEC-18092 の DEP
通称、 NFCIP-1 。これを読むのは、なかなかつらい。 ISO/IEC-18092 の DEP は「 NFC-DEP 」と呼
ばれる。
図を見ていって、必要になれば文章を読む、でもよいかもしれない。以下は、 ISO/IEC-18092 を読む
ときのポイントだ。
"General initialization and single device detection flow"■
SDD(Single Device Detection"という、デバイスを特定するまでの流れだ。
Passive ルートと Active ルートがあり、 Passive は相手の無線を待つ側、 Acitve は自分で無線を出
す側だ。
ただ、これは Initiator と Target の関係とは少し異なる。通常の NFC は、 Initiator が搬送波を出し、
コマンドを出す。 Target は Initiator からのコマンドを受信し、その搬送波に載せてレスポンスを返す。
ここでの Passive と Active は通信モードのこと。 Passive は片方が無線を出して片方が受けとるとい
う今の形だが、 Active はどちらのデバイスも無線を出す。
今のところ、 NFC Forum の Digital Protocol(v1.0)では、 Passive のみサポートすることになってい
る。
何となくわかった気分になればよいか。
Activation protocol in Passive communication mode■
これが基本的な Passive での DEP(NFC-DEP)の流れになる。
SDD して、属性要求が来たなら ATR_REQ を送信し、相手からの ATR_RES で相手の属性を取得
する。通信を変更する必要があるなら、 PSL_REQ で変更。
そして、左下で DEP する。これは、中で DEP_REQ と DEP_RES を何度も繰り返す。
通信を終わりたいとき、 DSL_REQ か RLS_REQ を送信する。すると、それぞれによって違う終わり
方をする。
Activation Protocol in Active communication mode■
Active での DEP になるが、 NFC Forum では今のところサポートしていないので省略する。
流れは、 Passive とだいたい同じ。
あとは、 ATR_REQ と ATR_RES の構造を見ておけばよいだろう。見ておかないと、 RC-S620/S の
コマンドリファレンスを読んでも、どういう値を返せばいいかわからないことになる。
月刊 NDEF 2013 年 8 月号
- 4 -
第2章 NFC-DEPって?
NFC-DEP の位置づけ
NFC-DEP は NFC Forum での呼び方で、 ISO/IEC-18092 規定のデータ交換プロトコル(Data
Exchange Protocol 、略して DEP)である。なお、もう 1 つ ISO-DEP というものもあり、こちらは
ISO/IEC-14443 規定のデータ交換プロトコルとなっている。残念ながら ISO/IEC-14443 は読んだこと
がないため、 ISO-DEP については省略する。
NFC Forum では、 NDEF のデータ交換を行うために、 DEP の上位層に LLCP 、その上に SNEP と
いう層を作っている。その DEP 層として NFC-DEP を使用するようになっている。
NFC-DEP でできること
1 パケット分のデータを、 DEP_REQ / DEP_RES のペイロードに載せて送ること。
DEP_REQ や DEP_RES というのは、無線コマンドの名称である。基本的に、 Initiator が送信するの
は XXX_REQ 、それを受けた Target が返すのが XXX_RES 、となる。また、 REQ や RES がつい
ているのは無線コマンドである。
ペイロードに乗せることができるサイズは、 DEP 前の属性情報交換(ATR_REQ / ATR_RES)で相手
に通知することになる。
・・・ここまで書いてきたが、具体例がないと説明しづらい。かといって概略を書いたとしてもわかりづら
いので、いろいろあきらめて、 NFC リーダライタの RC-S620/S コマンドリファレンスマニュアルと、
ISO/IEC-18092 が手元にある前提で話を進める。なお、 RC-S620/S コマンドリファレンスマニュアル
は、 SONY 社の使用許諾を了承すればダウンロード可能。 ISO/IEC-18092 は無料ダウンロードでき
ないが、それとほぼ同等の内容である ECMA-340 であればダウンロード可能である。
NFC-DEP
LLCP
SNEP
月刊 NDEF 2013 年 8 月号
- 5 -
Passive 通信モードで、自分が Target の場合
RC-S620/S コマンドリファレンスマニュアルを参照しながら NFC-DEP をやろうとすると、自然とこの
組み合わせで実現することになる。
理由は2つ。
・コマンドリファレンスマニュアルには Initiator で DEP モードになるコマンドが書かれていない
・ NFC Foruum ドキュメント(DigitalProtocol v1.0)では、 NFC-DEP は Passive 通信モード
もちろん、 RC-S620/S で Initiator で DEP になるコマンドは存在するのだが、それは何らかの理由で
SONY 社が一般には公開していない。
ストーリー■
1. 自分が Target になって、 Initiator を待つ。
2. Initiator が Target の検索(SDD)をしたら、応答を返す。
3. DEP するなら、 Initiator が ATR_REQ を投げる。
4. 自分は ATR_REQ の中身を確認し、 ATR_RES を返す。
この手順は RC-S620/S の手順というわけではなく、 NFCIP-1 で規定されているものである。
ここまで行えば、あとは DEP_REQ / RES を使ってデータ交換するだけとなる。
では、順番に見ていこう。
1. 自分が Target になって、 Initiator を待つ
NFC R/W は、コマンドによって自分が Initiator になるか Target になるかを選択することができる。こ
こでは自分が NFC タグのような Target になり、他の R/W から検出されるのを待つ。
Target になると、自分からはデータ送信ができないような気がするかもしれないが、 LLCP 層が上位
に載り、それがデータ方向の管理などを行っているため、気にする必要はない。
Android の場合、全員が Target になってしまうと誰も Initiator 役がいなくなってしまうため、定期的に
Initiator と Target を切り替えていると思われる。
Target Initiator
月刊 NDEF 2013 年 8 月号
- 6 -
RC-S620/S は、コマンド"TgInitTarget"を使用することで Target 状態になることができる。このコマン
ドはパラメータが難しい(と私は思う)。
Table 2-1 TgInitTarget コマンドのパラメータ
Activated 制限 0x02 。おそらく「 DEP 専用モード」を表す値と思われる。
106kbpsParams Initiator が 106kbps として SDD してきたときに返す値。
SENS_RES 0x00 0x04 、などか?
NFCID1 が single というところを指定すればいい
ような気もする。
nfcid11 ~ 13 NFCID1 の下位 3byte を指定する。
SDD で NFCID1 を取得した場合、最上位の
1byte は 0x08(DEP)を返す。
SEL_RES 0x40 とするのがよいだろう。これは、 NFC-DEP
設定になっていることを意味する。
212/424kbpsParams Initiator が 212k/424kbps として SDD してきたときに返す値。
NFCID2t NFCID2(IDm)を 8byte 分指定する。
NFC-DEP 対応にするので「 0x01 0xFE 」で始ま
る 8byte とするのがよい。
PAD PAD(PMm)を 8byte 分指定する。
RFU 2byte 分の空き。となっているが、システムコード
に相当する。
NFCID3t NFCID3 を 10byte 分指定する。
Gt 汎用値。 47byte 分の指定が可能。
月刊 NDEF 2013 年 8 月号
- 7 -
いくつか補足説明をしよう。
NFC-DEP では、 NFCID3 という 10byte の値をセッション ID のようなものとして使う(というほど積極
的には使わないが)。 1 つだけルールがある。 NFC-F の場合、 NFCID2 の 8byte を前半に、残り
2byte は 0x00 で埋めた値を使う。理由は知らないが、 NFC Forum の脚注に記載があった。
ISO/IEC-18092 では、 NFCID1 とも同じような値になるようなことが書かれていた。
そして、 RC-S620/S はセキュアエレメントなどを持っていないので、固有の NFCID1 や NFCID2 が
ない。よって、使うときはだいたいランダム値を使う。セッションを張り直すたびに変更する、くらいやっ
てもよいと思う。
Gt の「 t 」は、 Target の t である。その値については、 NFC-DEP としては気にしていない。ただ、
NDEF を交換するために LLCP を使うのであれば、 Gt について決めごとがある。それについては、
LLCP のところで説明しよう。
ここまで説明を書いてみたが、それでもよくわからないのではないかと思う。自分でも、これを読まされ
て「やれ!」と言われたら、わからんだろう。
2. Initiator が Target の検索(SDD)をしたら、応答を返す
自分は Target になっているので、 Initiator からの要求がない限りは動くことができない。ここでは、
Initiator が Target を検索する手順を説明する。
「 SDD 」は、 Single Device Detection の略で、文字通り 1 枚のデバイスを検出するためのしくみだ。
これについては、 NFCIP-1 でもページを割いて説明している。
幸いなことに、 RC-S620/S のような NFC R/W を使用する場合、有線コマンドでデバイス検出を指示
すると、ある程度までは自動的に SDD を行ってくれる。例えば NFC-A の UID サイズが 4byte,
7byte, 10byte と 3 種類あり、無線コマンドとしては Tag の種類によって何度か取得を繰り返すのだ
が、このあたりも R/W が自動的に行ってくれる。
月刊 NDEF 2013 年 8 月号
- 8 -
NFC R/W に指示するのは、「 InListPassiveTarget 」という、 Passive な Target のリストを取得する
コマンドになる(リスト、と呼んではいるが、 RC-S620/S では最大 1 台までの検出になる)。パラメータ
として、通信速度(BRTY)や Initiator データ(InitiatorData)などを設定する。
コマンドリファレンスマニュアルに「 BRTY=01h / 02h の場合」と何度も書かれているように、 BRTY
には 0x01 や 0x02 以外の値も設定可能であるが、指定値以外の値を説明するのはやめておく。
NFC R/W を使ったオープンソースのプロジェクトはいろいろあるので、その実装から見ていくとよいだ
ろう。
InListPassiveTarget コマンドを使うと、 NFC-A の場合は無線コマンド「 SENS_REQ 」、 NFC-F の
場合は「 POL_REQ 」を送信する。コマンドリファレンスマニュアルの TgInitTarget にある「 TargetID
取得コマンド」である。
Target はそれを受信すると、それぞれ「 SENS_RES 」か「 POL_RES 」を返す。このときに返す値
は、 TgInitTarget であらかじめ設定した値である。 TargetID 取得コマンドが来続ける限り、 NFC
R/W は TgInitTarget の動作を続けてくれる。
Passive 通信モードの処理フローに従えば、この次のコマンドは以下のどれかになる。
ATR_REQ コマンド・
RLS_REQ コマンド・
それ以外のコマンド・
「それ以外のコマンド」は、プロプライエタリなコマンド、つまり MIFARE や FeliCa などのコマンドとみ
なす。 DEP としては、次に ATR_REQ が来ることを期待している。あるいは中断のために
RLS_REQ が来る可能性もある。
TargetID 取得コマンド以外を受信すると、 TgInitTarget は Target モードに遷移し、 Initiator からの
受信データを返す。その受信データの解析は自分で行うことになる。
Initiator待ち Target状態他コマンド
TargetID取得コマンド
月刊 NDEF 2013 年 8 月号
- 9 -
3. DEP するなら、 Initiator が ATR_REQ を投げる
ATR_REQ は属性要求コマンドで、 NFCID3 や 1 回の DEP コマンドで送受信できるバッファのサイ
ズ情報などを伝えるものである。 TgInitTarget コマンドは Target モードに遷移する際、 Initiator の
ATR_REQ パラメータを返してくれる。
Table 2-2 ATR_REQ のパラメータ
nfcid3i0 ~ 9 NFCID3 を 10byte 分指定する。
DIDi 複数 Target 時に使うようである。
LLCP では使用しないので、 0x00 。
BSi send-bit rates の略のようである。
Digital Protocol では、 0x00 。
BRi receive-bit rates の略のようである。
こちらも同じく、 0x00 。
PPi オプションパラメータ。
LRi 転送データの範囲(2bit)。
LLCP では、 11(0 ~ 254byte)。
※ NFCIP-1 では 0 ~ 255byte となっている
Gi LLCP では使用するので、 1 。
NAD LLCP では使用しないので、 0 。
Gi 汎用値。 LLCP では使用する。
月刊 NDEF 2013 年 8 月号
- 10 -
なお、これは Passive 通信モードで動作する場合の流れであり、 Active 通信モードで動作する場合
はこうではない。 Initiator は InListPassiveTarget を使わず、 ATR_REQ を送信するためのコマンド
を使う。 Target は、最初に来たコマンドが SDD 用のコマンドか、 ATR_REQ なのかを判断して、
Initiator が期待するのが Passive 通信モードなのか Active 通信モードなのかを判断することになる
(コマンドリファレンスマニュアルの図 8-3 参照)。
また、 Initiator で動かしたいときは「 InListPassiveTarget 」と「 ATR_REQ を送信するコマンド」をそ
れぞれ使うことになるが、便利なように両者が 1 つになったコマンドも存在する。これはコマンドリファ
レンスマニュアルに書かれていないので、ここでも割愛する。
4. 自分は ATR_REQ の中身を確認し、 ATR_RES を返す
ATR_REQ の値が期待するものかどうかをチェックし、期待通りであれば ATR_RES を返す。
ATR_RES のパラメータはだいたい ATR_REQ と同じであるが、 TO というパラメータが追加されてい
る。これは Initiator から DEP_REQ を受けとってから、 Target が DEP_RES を返すまでの待機時間
である。
何に使うかというと、 Target が DEP_RES を返すのに時間がかかるとき、 Initiator に対して「もうちょ
っと待って」という値を返す目安の時間だそうである。 RC-S620/S では RFConfiguration コマンドに
よって設定するので、タイムアウトすると自動的に返信してくれそうな気がする。
Initiator は ATR_RES を受信すると、同じようにパラメータ解析して、期待するものかどうかをチェック
し、問題がなければ DEP 通信を開始する。
あっさりと書いていったが、実は TgInitTarget コマンドは、デフォルトでは自動的に ATR_RES を返す
ようになっている。 ATR_REQ のパラメータをチェックして動作を変えるためには、自動で返す設定を
OFF にし、自分で別のコマンドを使って返すようにする。
SetParameters コマンドによって、 ATR_RES を自動で返さないようにできる。その設定にした場合、
ATR_REQ を受けとると、 Target モードだけど DEP モードではなく、かつ ATR_RES を返さないとい
けない、という中途半端な状態に陥る(RC-S620/S では「モード 2 」と呼ばれる。このときに
TgSetGeneralBytes コマンドで ATR_RES データを設定すると、 RC-S620/S が ATR_RES を返し
てくれる。
月刊 NDEF 2013 年 8 月号
- 11 -
Table 2-3 ATR_RES のパラメータ
nfcid3t0 ~ 9 NFCID3 を 10byte 分指定する。
DIDt 複数 Target 時に使うようである。
LLCP では使用しないので、 0x00 。
BSt send-bit rates の略のようである。
Digital Protocol では、 0x00 。
BRt receive-bit rates の略のようである。
こちらも同じく、 0x00 。
TO Target が応答を返すまでのタイムアウト時間。
RWT = (256 x 16 / fc) x 2
WT
RC-S620/S では RFConfiguration コマンドの CfgItem=82h と関連が
ある値となる(DEP モードになったら設定できないので、その前に設定
しておく)。
PPt オプションパラメータ。
LRt 転送データの範囲(2bit)。
LLCP では、 11(0 ~ 254byte)。
※ NFCIP-1 では 0 ~ 255byte となっている
Gt LLCP では使用するので、 1 。
NAD LLCP では使用しないので、 0 。
Gt 汎用値。 LLCP では使用する。
月刊 NDEF 2013 年 8 月号
- 12 -
RC-S620/S のモード■
コマンドリファレンスマニュアルを読むと、ところどころ「モード」という言葉が出てくる。
これは、 RC-S620/S がどういうモードにいるかの説明で、モードによって使用できるコマンドが変わっ
てくる。
Figure 2-1 RC-S620/S のモード
月刊 NDEF 2013 年 8 月号
- 13 -
NFC-DEP できるようになったが・・・
こ こ ま で 来 る と 、 Initiator か ら の DEP_REQ を 待 ち 受 け ら れ る よ う に な る 。 コ マ ン ド は
「 TgGetDEPData 」で、これを設定すると Initiator 待ちとなる。 Initiator から DEP_REQ を受信する
と受信データを返してくるので、内容に応じて「 TgSetDEPData 」を設定すると、 RC-S620/S が
DEP_RES を返してくれる。
タイムアウトや終了のさせ方などはあるものの、基本的にはこれだけである。
NFC-DEP で行えるのは、単なるデータを交換する、ということだけなので、どういうデータをやりとりし
たいか、とか、どうやってやりとりしたいか、のような意思はそこにない。
それを補足するため、上位層に LLCP を用意し、 Initiator と Target が対等となる通信ができるように
なっている。
対等!
月刊 NDEF 2013 年 8 月号
- 14 -
第3章 LLCPって?
LLCP の位置づけ
NFC-DEP は、データを交換するための物理的な経路のようなものである。
それに対して LLCP(Logical Link Control Protocol)は、論理的な通信と言えばよいだろうか。
「 NFC-DEP を使って、こうやって通信すればうまくいく」という決めごとである。
そういう意味では、 LLCP の上位層(今回は SNEP)からすると、 LLCP が NFC-DEP を使おうが
ISO-DEP を使おうが、あまり関係はない。 NFC Forum でのルールとしてそうなっているというだけの
ことである。
IEEE802.2 に「 LLC 副層」というものがある。このあたりに通じていると、多少理解が早いかもしれな
い。私は通じていないので、どうなのかあまり判断ができない・・・。
なお、その下位である「 MAC 副層」は NFC-DEP になる。
LLCP について1つ1つ説明していくと、かなりな量になってしまい、私が疲れる。ここでは、上位層で
ある SNEP だけのために LLCP を実装することについて考えることにする。
NRM と ABM
通常の NFC 通信では、 Initiator が要求を出し、それに対して Target が応答を返すようになってい
る。これを「 Normal Response Mode 」(NRM)と呼んでいる。
しかし LLCP では Initiator も Target も関係なく通信を行いたい。そのため、 Initiator は用がないとき
でも Target に要求を投げ、 Target がいつでも応答が返せるような状態を作り出すことにする。この
通信状態を「 Asynchrnous Balanced Mode 」(ABM)と呼んでいる。
ボールを一人が持ったままにならないようにキャッチボールを続けるようなものである。
月刊 NDEF 2013 年 8 月号
- 15 -
PDU
これから「 PDU 」という言葉がよく出てくるようになる。 Protocol Data Unit の略で、 LLCP でやりとり
するデータの単位と思ってもらえばよい。
PDU には種類がいくつかある。 4bit の数字で表すので、空きも含めて 16 まである。
SAP
「 SAP 」という言葉も出てくる。 Service Access Points の略で、「 HTTP は 80 」みたいなイメージで
思っておけばよい。 6bit の値。
Source と Destination があり、それぞれ SSAP 、 DSAP と呼ぶ。
Table 3-1 SAP 値
0x00 - 0x0F Well-known な SAP 。 NFC Forum で決めている。
0x00 : LLC Link Management component 用
0x01 : Service Discovery Protocol 用
0x04 : SNEP 用
0x10 - 0x1F SDP で見つけたときに割り振る番号?
0x20 - 0x3F LLCP より上位層で決定した番号?
正直なところ、よくわかっていない。。。
後ほど、実例で説明する。
Connectionless と Connection-oriented
大きく2つの通信がある。 Connectionless と Connection-oriented だ。 UDP と TCP の関係にあると
思っている。
ど ち ら に す る か は 、 接 続 時 に 決 定 す る 。 SNEP は Connection-oriented な の で 、 こ こ で も
Connection-oriented のみ説明する。
なお、 Connectionless の場合は UI PDU を、 Connection-oriented の場合は I PDU を使う。
月刊 NDEF 2013 年 8 月号
- 16 -
Link Activation
LLCP では、まず NFC-DEP の接続を行う。"Link Activation"と呼んでいる。
Figure 3-1 の四角で囲んだ部分が NFC-DEP の接続シーケンスとなる。
LLCP で接続する場合、 ATR_REQ の Gi および ATR_RES の Gt に特定のデータを設定する。
Figure 3-1 Link Activation Procedure
LLCP Magic Number■
0x46 0x66 0x6d 、の 3byte を設定する。文字通りマジックナンバーで意味はない(ASCII コードなら
"Ffm"になる)。
PDU■
Magic Number に続けて、 PDU が続く。お互いが使っている LLCP のバージョンを確認するため、最
低でも 1 つの PAX PDU が必要になる。
Magic Number に問題がなく、 LLCP バージョンにも問題がなければ Link Activation 完了となる。
月刊 NDEF 2013 年 8 月号
- 17 -
送信するまでの間
LLCP ド キ ュ メ ン ト で は 「 Normal Operation 」 状 態 に な る 。 こ こ か ら Connectionless か
Connection-oriented かに分かれる。ここでは Connection-oriented のみ説明する。
この段階では、まだどちらがデータを送信したいのかが決定していない。 Android 端末で言えば、端
末同士を向かい合わせて星が流れる画面になったところである。
ここでタップをすると、そちら側が送信元になる。
それまでの間何をしているかというと、 SYMM PDU をお互いに送り合っている。 NFC の通信上、
Initiator が要求を出して Target がその応答を返す、という形は崩せないが、 Initiator は SYMM
PDU の入った DEP_REQ をひたすら送ることで、 Target からデータを渡してもらえるようにしてい
る。
送信開始
送信する側は、相手からの SYMM PDU に対して CONNECT PDU を送り返す。
CONNECT PDU を受けとった方は、応答として CC PDU を返す。
Figure 3-2 Initiator から送信
月刊 NDEF 2013 年 8 月号
- 18 -
Figure 3-3 Target から送信
私が SNEP する場合、 CONNECT PDU の SSAP 、 DSAP として 0x04(SNEP)を指定し、 CC
PDU でも SSAP 、 DSAP が 0x04 を返すようにしている。
ただ、別のライブラリでテストしていたとき、 CONNECT PDU では SSAP=0x04 、 DSAP=0x01 を指
定し、 ServiceName として"urn:nfc:sn:snep"と、名前で SNEP を指定しないと動かないものがあっ
た。そうすると CC で SSAP 、 DSAP ともに 0x04 が返ってくるようになった。
このあたりはライブラリ実装依存なのか、単に私のドキュメント読み込みが甘いのか判断しづらい。
接続から送信まで
1パケットのデータを送信するシーケンスとして、 Initiator(Figure 3-4)、 Target(Figure 3-5)をそれぞ
れ示す。
データは I PDU に載せる。受けとった方は、他に送りたいデータがないかを RR PDU で確認する。
もう送るものがなければ、 DISC PDU で切断しに行く。
月刊 NDEF 2013 年 8 月号
- 19 -
Figure 3-4 Initiator から送信
月刊 NDEF 2013 年 8 月号
- 20 -
Figure 3-5 Target から送信
ただ、私はまだ I PDU を何度もやりとりする実装をしたことがない。
URL を送るような用途であれば、だいたいは I PDU を 1 回だけ送信すれば済む。そういう実装であ
れば比較的容易ということがわかっていただけるかと思う。
では I PDU に何を載せるかとなると、それが SNEP になる。
月刊 NDEF 2013 年 8 月号
- 21 -
第4章 SNEPって?
SNEP の位置づけ
NFC-DEP が物理層、 LLCP が論理層とするならば、 SNEP はアプリケーション層くらいになるだろう
か。
あまり難しく考えずに言えば、 SNEP は NDEF を送受信するためのプロトコルである。
方式
SNEP は、 Client-Server 方式の通信である。やれることは「 NDEF を送りつける(PUT)」と「 NDEF
をもらう(GET)」である。
Figure 4-1 SNEP
分割する送信も可能になっているが、パケットに載せるデータ長が 4byte あることから考えると、ほと
んど使うことはないように思う。 LLCP の I PDU に 1 回で載らないようなデータ量であれば、 LLCP
層ががんばって I PDU を分割して送信する、というしくみになるだろう。
がんばれ LLCP!!
月刊 NDEF 2013 年 8 月号
- 22 -
まとめ
NFC-DEP 、 LLCP 、 SNEP と順に見ていった。
書いていってわかったが、私の勉強不足が目立つ。 LLCP に至って
は、まだ v1.0 のドキュメントまでしか読んでおらず、現在の最新であ
る v1.1 には言及できていない。
1 年ぶりに DEP 関係を調べたのでネットも検索したが、あまりヒット
するものはなかった。確かに、 NFC の使い方としてはタグに読み書
きするのが花形のように思う。しかし、データ交換経路としての NFC
も魅力的だと思う私にとっては、もうちょっとやってる人が増えてほし
いなあ、とも感じる。
いや、今は水面下で調査や作成を行っていて、 Android 以外の端末でも NFC が標準になったときに
公開しよう、とがんばっているところかもしれない。
NFC は、サービスについてや、無線について話をすることが多く、ソフトウェア的にどうのこうのという
ところがあまり出てこないように思うので、ちょっとでも興味を持ってもらえればな、と思いましたとさ。
2013/08/17
月刊 NDEF 2013 年 8 月号

月刊NDEF 2013年8月号

  • 2.
  • 3.
    - 1 - 第1章NFCでのデータ交換 はじめに 通信とは、データを交換するためのルールである。だと思う。 幅広く見ていくと、すべては通信で成り立っている。あいさつだって、一種の通信だし、そもそも会話自 体が通信といってもいいだろう。本を読むのだって、本からのデータを受けとっているわけだし、テレビ だってそうだ。 ただ、「データ交換」と銘打った場合、それは通信のためにデータ交換をするのではなく、データ交換 のために通信を行う、ということになる。この特集も、 NFC デバイス同士でデータ交換を行うためにつ いて説明することが中心となる。 いつもと違って、今回は文章がお堅いし、冗長になるかもしれない(冗長なのはいつもか)。それは、私 が「通信」というものに弱く、理解するのに時間がかかったからだ。自信があまりない、と言い換えても いいかもしれない。 そんなわけで、気楽に読んでほしい。なお、このドキュメントでは RC-S620/S でのやり方を書いてい く。他のデバイスの方は適宜読み替えていただきたい。 データ交換のためのプロトコル、 DEP NFC Forum では、 Digital Protocol でいくつかの規定を行っている。大ざっぱにいうと、以下のように なる。 1) Technology : 無 線 通 信 の 方 式 (NFC-A, B, F) 2) Platform : メ モ リ の 方 式 (Type 1, 2, 3, 4A, 4B) 3) Protocol : デ ー タ 交 換 の 方 式(NFC-DEP, ISO-DEP) 今回の話は、 3 番目の「 Protocol 」である。 DEP 、というのは"Data Exchange Protocol"の略であ る。データ交換プロトコル、だ。これを使えば、 NFC でデータ交換できるのである。 そう思って読み進めていたのだが・・・正直なところ、さっぱりわからなかった。かろうじてわかったの は、 NFC-DEP は、 Technology の NFC-A か F 、 ISO-DEP は NFC-A か B 、というところまでだっ た。 NFC-DEP は ISO-18092(NFCIP-1)由来、 ISO-DEP は ISO-14443 由来、というところまではわかっ た。 14443 は入手しづらいが、 18092 は ECMA にもあり、 ECMA は無料ダウンロードできたので、 そこから着手することにした。 月刊 NDEF 2013 年 8 月号
  • 4.
    - 2 - DEPに時間がかかった私 今にして思えば、 DEP のことを調べようと思ってから、 ISO/IEC にたどりつくまでが長かった。そし て、たどり着いてからも長かった。 言い訳をしておこう。私が持っている NFC のデバイスは、 SONY の RC-S620/S というリーダライタ のみである。このデバイス、いや通常の我々が入手できる既成製品で扱うことができるのは、あくまで 「有線コマンド」、すなわち UART や SPI などでしか操作することができない。そして、 ISO などのドキ ュメントで規定されているのは「無線コマンド」である。まあ、 NFC というのは無線だから仕方ないのだ が。 パソコンを使って印刷をしたいなら、パソコンでプリンタを制御しないといけないのと同じように、 NFC リーダライタで無線コマンドをやりとりしたいのなら、有線コマンドで NFC リーダライタを制御しないと いけないのだ。 NFC リーダライタとのやりとりは有線コマンドになるが、そのコマンドは各社で異なる。 RC-S620/S も そうだった。しかし、 RC-S620/S は当時コマンドのマニュアルが公開されておらず、操作方法がわか らなかった。そのため私は「 NFC Forum に書いてあるコマンドを使えば操作できるのでは?」と思 い、時間を費やしたこともあった。そう、当時の私は、有線コマンドと無線コマンドの違いがわかってい なかったのだ。 いろいろ調べ、 RC-S620/S の有線コマンドがわかり、ずいぶんと操作できるようになったのは比較的 最近のことだ。それでも、無線コマンドを直接操作しているわけではないので、ときどき苦戦することも ある。 まあ、そういうものだと割り切ろう。 操作 印刷 有線 無線 NFC R/W 割り切って 忘れてしまえ 月刊 NDEF 2013 年 8 月号
  • 5.
    - 3 - ISO/IEC-18092の DEP 通称、 NFCIP-1 。これを読むのは、なかなかつらい。 ISO/IEC-18092 の DEP は「 NFC-DEP 」と呼 ばれる。 図を見ていって、必要になれば文章を読む、でもよいかもしれない。以下は、 ISO/IEC-18092 を読む ときのポイントだ。 "General initialization and single device detection flow"■ SDD(Single Device Detection"という、デバイスを特定するまでの流れだ。 Passive ルートと Active ルートがあり、 Passive は相手の無線を待つ側、 Acitve は自分で無線を出 す側だ。 ただ、これは Initiator と Target の関係とは少し異なる。通常の NFC は、 Initiator が搬送波を出し、 コマンドを出す。 Target は Initiator からのコマンドを受信し、その搬送波に載せてレスポンスを返す。 ここでの Passive と Active は通信モードのこと。 Passive は片方が無線を出して片方が受けとるとい う今の形だが、 Active はどちらのデバイスも無線を出す。 今のところ、 NFC Forum の Digital Protocol(v1.0)では、 Passive のみサポートすることになってい る。 何となくわかった気分になればよいか。 Activation protocol in Passive communication mode■ これが基本的な Passive での DEP(NFC-DEP)の流れになる。 SDD して、属性要求が来たなら ATR_REQ を送信し、相手からの ATR_RES で相手の属性を取得 する。通信を変更する必要があるなら、 PSL_REQ で変更。 そして、左下で DEP する。これは、中で DEP_REQ と DEP_RES を何度も繰り返す。 通信を終わりたいとき、 DSL_REQ か RLS_REQ を送信する。すると、それぞれによって違う終わり 方をする。 Activation Protocol in Active communication mode■ Active での DEP になるが、 NFC Forum では今のところサポートしていないので省略する。 流れは、 Passive とだいたい同じ。 あとは、 ATR_REQ と ATR_RES の構造を見ておけばよいだろう。見ておかないと、 RC-S620/S の コマンドリファレンスを読んでも、どういう値を返せばいいかわからないことになる。 月刊 NDEF 2013 年 8 月号
  • 6.
    - 4 - 第2章NFC-DEPって? NFC-DEP の位置づけ NFC-DEP は NFC Forum での呼び方で、 ISO/IEC-18092 規定のデータ交換プロトコル(Data Exchange Protocol 、略して DEP)である。なお、もう 1 つ ISO-DEP というものもあり、こちらは ISO/IEC-14443 規定のデータ交換プロトコルとなっている。残念ながら ISO/IEC-14443 は読んだこと がないため、 ISO-DEP については省略する。 NFC Forum では、 NDEF のデータ交換を行うために、 DEP の上位層に LLCP 、その上に SNEP と いう層を作っている。その DEP 層として NFC-DEP を使用するようになっている。 NFC-DEP でできること 1 パケット分のデータを、 DEP_REQ / DEP_RES のペイロードに載せて送ること。 DEP_REQ や DEP_RES というのは、無線コマンドの名称である。基本的に、 Initiator が送信するの は XXX_REQ 、それを受けた Target が返すのが XXX_RES 、となる。また、 REQ や RES がつい ているのは無線コマンドである。 ペイロードに乗せることができるサイズは、 DEP 前の属性情報交換(ATR_REQ / ATR_RES)で相手 に通知することになる。 ・・・ここまで書いてきたが、具体例がないと説明しづらい。かといって概略を書いたとしてもわかりづら いので、いろいろあきらめて、 NFC リーダライタの RC-S620/S コマンドリファレンスマニュアルと、 ISO/IEC-18092 が手元にある前提で話を進める。なお、 RC-S620/S コマンドリファレンスマニュアル は、 SONY 社の使用許諾を了承すればダウンロード可能。 ISO/IEC-18092 は無料ダウンロードでき ないが、それとほぼ同等の内容である ECMA-340 であればダウンロード可能である。 NFC-DEP LLCP SNEP 月刊 NDEF 2013 年 8 月号
  • 7.
    - 5 - Passive通信モードで、自分が Target の場合 RC-S620/S コマンドリファレンスマニュアルを参照しながら NFC-DEP をやろうとすると、自然とこの 組み合わせで実現することになる。 理由は2つ。 ・コマンドリファレンスマニュアルには Initiator で DEP モードになるコマンドが書かれていない ・ NFC Foruum ドキュメント(DigitalProtocol v1.0)では、 NFC-DEP は Passive 通信モード もちろん、 RC-S620/S で Initiator で DEP になるコマンドは存在するのだが、それは何らかの理由で SONY 社が一般には公開していない。 ストーリー■ 1. 自分が Target になって、 Initiator を待つ。 2. Initiator が Target の検索(SDD)をしたら、応答を返す。 3. DEP するなら、 Initiator が ATR_REQ を投げる。 4. 自分は ATR_REQ の中身を確認し、 ATR_RES を返す。 この手順は RC-S620/S の手順というわけではなく、 NFCIP-1 で規定されているものである。 ここまで行えば、あとは DEP_REQ / RES を使ってデータ交換するだけとなる。 では、順番に見ていこう。 1. 自分が Target になって、 Initiator を待つ NFC R/W は、コマンドによって自分が Initiator になるか Target になるかを選択することができる。こ こでは自分が NFC タグのような Target になり、他の R/W から検出されるのを待つ。 Target になると、自分からはデータ送信ができないような気がするかもしれないが、 LLCP 層が上位 に載り、それがデータ方向の管理などを行っているため、気にする必要はない。 Android の場合、全員が Target になってしまうと誰も Initiator 役がいなくなってしまうため、定期的に Initiator と Target を切り替えていると思われる。 Target Initiator 月刊 NDEF 2013 年 8 月号
  • 8.
    - 6 - RC-S620/Sは、コマンド"TgInitTarget"を使用することで Target 状態になることができる。このコマン ドはパラメータが難しい(と私は思う)。 Table 2-1 TgInitTarget コマンドのパラメータ Activated 制限 0x02 。おそらく「 DEP 専用モード」を表す値と思われる。 106kbpsParams Initiator が 106kbps として SDD してきたときに返す値。 SENS_RES 0x00 0x04 、などか? NFCID1 が single というところを指定すればいい ような気もする。 nfcid11 ~ 13 NFCID1 の下位 3byte を指定する。 SDD で NFCID1 を取得した場合、最上位の 1byte は 0x08(DEP)を返す。 SEL_RES 0x40 とするのがよいだろう。これは、 NFC-DEP 設定になっていることを意味する。 212/424kbpsParams Initiator が 212k/424kbps として SDD してきたときに返す値。 NFCID2t NFCID2(IDm)を 8byte 分指定する。 NFC-DEP 対応にするので「 0x01 0xFE 」で始ま る 8byte とするのがよい。 PAD PAD(PMm)を 8byte 分指定する。 RFU 2byte 分の空き。となっているが、システムコード に相当する。 NFCID3t NFCID3 を 10byte 分指定する。 Gt 汎用値。 47byte 分の指定が可能。 月刊 NDEF 2013 年 8 月号
  • 9.
    - 7 - いくつか補足説明をしよう。 NFC-DEPでは、 NFCID3 という 10byte の値をセッション ID のようなものとして使う(というほど積極 的には使わないが)。 1 つだけルールがある。 NFC-F の場合、 NFCID2 の 8byte を前半に、残り 2byte は 0x00 で埋めた値を使う。理由は知らないが、 NFC Forum の脚注に記載があった。 ISO/IEC-18092 では、 NFCID1 とも同じような値になるようなことが書かれていた。 そして、 RC-S620/S はセキュアエレメントなどを持っていないので、固有の NFCID1 や NFCID2 が ない。よって、使うときはだいたいランダム値を使う。セッションを張り直すたびに変更する、くらいやっ てもよいと思う。 Gt の「 t 」は、 Target の t である。その値については、 NFC-DEP としては気にしていない。ただ、 NDEF を交換するために LLCP を使うのであれば、 Gt について決めごとがある。それについては、 LLCP のところで説明しよう。 ここまで説明を書いてみたが、それでもよくわからないのではないかと思う。自分でも、これを読まされ て「やれ!」と言われたら、わからんだろう。 2. Initiator が Target の検索(SDD)をしたら、応答を返す 自分は Target になっているので、 Initiator からの要求がない限りは動くことができない。ここでは、 Initiator が Target を検索する手順を説明する。 「 SDD 」は、 Single Device Detection の略で、文字通り 1 枚のデバイスを検出するためのしくみだ。 これについては、 NFCIP-1 でもページを割いて説明している。 幸いなことに、 RC-S620/S のような NFC R/W を使用する場合、有線コマンドでデバイス検出を指示 すると、ある程度までは自動的に SDD を行ってくれる。例えば NFC-A の UID サイズが 4byte, 7byte, 10byte と 3 種類あり、無線コマンドとしては Tag の種類によって何度か取得を繰り返すのだ が、このあたりも R/W が自動的に行ってくれる。 月刊 NDEF 2013 年 8 月号
  • 10.
    - 8 - NFCR/W に指示するのは、「 InListPassiveTarget 」という、 Passive な Target のリストを取得する コマンドになる(リスト、と呼んではいるが、 RC-S620/S では最大 1 台までの検出になる)。パラメータ として、通信速度(BRTY)や Initiator データ(InitiatorData)などを設定する。 コマンドリファレンスマニュアルに「 BRTY=01h / 02h の場合」と何度も書かれているように、 BRTY には 0x01 や 0x02 以外の値も設定可能であるが、指定値以外の値を説明するのはやめておく。 NFC R/W を使ったオープンソースのプロジェクトはいろいろあるので、その実装から見ていくとよいだ ろう。 InListPassiveTarget コマンドを使うと、 NFC-A の場合は無線コマンド「 SENS_REQ 」、 NFC-F の 場合は「 POL_REQ 」を送信する。コマンドリファレンスマニュアルの TgInitTarget にある「 TargetID 取得コマンド」である。 Target はそれを受信すると、それぞれ「 SENS_RES 」か「 POL_RES 」を返す。このときに返す値 は、 TgInitTarget であらかじめ設定した値である。 TargetID 取得コマンドが来続ける限り、 NFC R/W は TgInitTarget の動作を続けてくれる。 Passive 通信モードの処理フローに従えば、この次のコマンドは以下のどれかになる。 ATR_REQ コマンド・ RLS_REQ コマンド・ それ以外のコマンド・ 「それ以外のコマンド」は、プロプライエタリなコマンド、つまり MIFARE や FeliCa などのコマンドとみ なす。 DEP としては、次に ATR_REQ が来ることを期待している。あるいは中断のために RLS_REQ が来る可能性もある。 TargetID 取得コマンド以外を受信すると、 TgInitTarget は Target モードに遷移し、 Initiator からの 受信データを返す。その受信データの解析は自分で行うことになる。 Initiator待ち Target状態他コマンド TargetID取得コマンド 月刊 NDEF 2013 年 8 月号
  • 11.
    - 9 - 3.DEP するなら、 Initiator が ATR_REQ を投げる ATR_REQ は属性要求コマンドで、 NFCID3 や 1 回の DEP コマンドで送受信できるバッファのサイ ズ情報などを伝えるものである。 TgInitTarget コマンドは Target モードに遷移する際、 Initiator の ATR_REQ パラメータを返してくれる。 Table 2-2 ATR_REQ のパラメータ nfcid3i0 ~ 9 NFCID3 を 10byte 分指定する。 DIDi 複数 Target 時に使うようである。 LLCP では使用しないので、 0x00 。 BSi send-bit rates の略のようである。 Digital Protocol では、 0x00 。 BRi receive-bit rates の略のようである。 こちらも同じく、 0x00 。 PPi オプションパラメータ。 LRi 転送データの範囲(2bit)。 LLCP では、 11(0 ~ 254byte)。 ※ NFCIP-1 では 0 ~ 255byte となっている Gi LLCP では使用するので、 1 。 NAD LLCP では使用しないので、 0 。 Gi 汎用値。 LLCP では使用する。 月刊 NDEF 2013 年 8 月号
  • 12.
    - 10 - なお、これはPassive 通信モードで動作する場合の流れであり、 Active 通信モードで動作する場合 はこうではない。 Initiator は InListPassiveTarget を使わず、 ATR_REQ を送信するためのコマンド を使う。 Target は、最初に来たコマンドが SDD 用のコマンドか、 ATR_REQ なのかを判断して、 Initiator が期待するのが Passive 通信モードなのか Active 通信モードなのかを判断することになる (コマンドリファレンスマニュアルの図 8-3 参照)。 また、 Initiator で動かしたいときは「 InListPassiveTarget 」と「 ATR_REQ を送信するコマンド」をそ れぞれ使うことになるが、便利なように両者が 1 つになったコマンドも存在する。これはコマンドリファ レンスマニュアルに書かれていないので、ここでも割愛する。 4. 自分は ATR_REQ の中身を確認し、 ATR_RES を返す ATR_REQ の値が期待するものかどうかをチェックし、期待通りであれば ATR_RES を返す。 ATR_RES のパラメータはだいたい ATR_REQ と同じであるが、 TO というパラメータが追加されてい る。これは Initiator から DEP_REQ を受けとってから、 Target が DEP_RES を返すまでの待機時間 である。 何に使うかというと、 Target が DEP_RES を返すのに時間がかかるとき、 Initiator に対して「もうちょ っと待って」という値を返す目安の時間だそうである。 RC-S620/S では RFConfiguration コマンドに よって設定するので、タイムアウトすると自動的に返信してくれそうな気がする。 Initiator は ATR_RES を受信すると、同じようにパラメータ解析して、期待するものかどうかをチェック し、問題がなければ DEP 通信を開始する。 あっさりと書いていったが、実は TgInitTarget コマンドは、デフォルトでは自動的に ATR_RES を返す ようになっている。 ATR_REQ のパラメータをチェックして動作を変えるためには、自動で返す設定を OFF にし、自分で別のコマンドを使って返すようにする。 SetParameters コマンドによって、 ATR_RES を自動で返さないようにできる。その設定にした場合、 ATR_REQ を受けとると、 Target モードだけど DEP モードではなく、かつ ATR_RES を返さないとい けない、という中途半端な状態に陥る(RC-S620/S では「モード 2 」と呼ばれる。このときに TgSetGeneralBytes コマンドで ATR_RES データを設定すると、 RC-S620/S が ATR_RES を返し てくれる。 月刊 NDEF 2013 年 8 月号
  • 13.
    - 11 - Table2-3 ATR_RES のパラメータ nfcid3t0 ~ 9 NFCID3 を 10byte 分指定する。 DIDt 複数 Target 時に使うようである。 LLCP では使用しないので、 0x00 。 BSt send-bit rates の略のようである。 Digital Protocol では、 0x00 。 BRt receive-bit rates の略のようである。 こちらも同じく、 0x00 。 TO Target が応答を返すまでのタイムアウト時間。 RWT = (256 x 16 / fc) x 2 WT RC-S620/S では RFConfiguration コマンドの CfgItem=82h と関連が ある値となる(DEP モードになったら設定できないので、その前に設定 しておく)。 PPt オプションパラメータ。 LRt 転送データの範囲(2bit)。 LLCP では、 11(0 ~ 254byte)。 ※ NFCIP-1 では 0 ~ 255byte となっている Gt LLCP では使用するので、 1 。 NAD LLCP では使用しないので、 0 。 Gt 汎用値。 LLCP では使用する。 月刊 NDEF 2013 年 8 月号
  • 14.
    - 12 - RC-S620/Sのモード■ コマンドリファレンスマニュアルを読むと、ところどころ「モード」という言葉が出てくる。 これは、 RC-S620/S がどういうモードにいるかの説明で、モードによって使用できるコマンドが変わっ てくる。 Figure 2-1 RC-S620/S のモード 月刊 NDEF 2013 年 8 月号
  • 15.
    - 13 - NFC-DEPできるようになったが・・・ こ こ ま で 来 る と 、 Initiator か ら の DEP_REQ を 待 ち 受 け ら れ る よ う に な る 。 コ マ ン ド は 「 TgGetDEPData 」で、これを設定すると Initiator 待ちとなる。 Initiator から DEP_REQ を受信する と受信データを返してくるので、内容に応じて「 TgSetDEPData 」を設定すると、 RC-S620/S が DEP_RES を返してくれる。 タイムアウトや終了のさせ方などはあるものの、基本的にはこれだけである。 NFC-DEP で行えるのは、単なるデータを交換する、ということだけなので、どういうデータをやりとりし たいか、とか、どうやってやりとりしたいか、のような意思はそこにない。 それを補足するため、上位層に LLCP を用意し、 Initiator と Target が対等となる通信ができるように なっている。 対等! 月刊 NDEF 2013 年 8 月号
  • 16.
    - 14 - 第3章LLCPって? LLCP の位置づけ NFC-DEP は、データを交換するための物理的な経路のようなものである。 それに対して LLCP(Logical Link Control Protocol)は、論理的な通信と言えばよいだろうか。 「 NFC-DEP を使って、こうやって通信すればうまくいく」という決めごとである。 そういう意味では、 LLCP の上位層(今回は SNEP)からすると、 LLCP が NFC-DEP を使おうが ISO-DEP を使おうが、あまり関係はない。 NFC Forum でのルールとしてそうなっているというだけの ことである。 IEEE802.2 に「 LLC 副層」というものがある。このあたりに通じていると、多少理解が早いかもしれな い。私は通じていないので、どうなのかあまり判断ができない・・・。 なお、その下位である「 MAC 副層」は NFC-DEP になる。 LLCP について1つ1つ説明していくと、かなりな量になってしまい、私が疲れる。ここでは、上位層で ある SNEP だけのために LLCP を実装することについて考えることにする。 NRM と ABM 通常の NFC 通信では、 Initiator が要求を出し、それに対して Target が応答を返すようになってい る。これを「 Normal Response Mode 」(NRM)と呼んでいる。 しかし LLCP では Initiator も Target も関係なく通信を行いたい。そのため、 Initiator は用がないとき でも Target に要求を投げ、 Target がいつでも応答が返せるような状態を作り出すことにする。この 通信状態を「 Asynchrnous Balanced Mode 」(ABM)と呼んでいる。 ボールを一人が持ったままにならないようにキャッチボールを続けるようなものである。 月刊 NDEF 2013 年 8 月号
  • 17.
    - 15 - PDU これから「PDU 」という言葉がよく出てくるようになる。 Protocol Data Unit の略で、 LLCP でやりとり するデータの単位と思ってもらえばよい。 PDU には種類がいくつかある。 4bit の数字で表すので、空きも含めて 16 まである。 SAP 「 SAP 」という言葉も出てくる。 Service Access Points の略で、「 HTTP は 80 」みたいなイメージで 思っておけばよい。 6bit の値。 Source と Destination があり、それぞれ SSAP 、 DSAP と呼ぶ。 Table 3-1 SAP 値 0x00 - 0x0F Well-known な SAP 。 NFC Forum で決めている。 0x00 : LLC Link Management component 用 0x01 : Service Discovery Protocol 用 0x04 : SNEP 用 0x10 - 0x1F SDP で見つけたときに割り振る番号? 0x20 - 0x3F LLCP より上位層で決定した番号? 正直なところ、よくわかっていない。。。 後ほど、実例で説明する。 Connectionless と Connection-oriented 大きく2つの通信がある。 Connectionless と Connection-oriented だ。 UDP と TCP の関係にあると 思っている。 ど ち ら に す る か は 、 接 続 時 に 決 定 す る 。 SNEP は Connection-oriented な の で 、 こ こ で も Connection-oriented のみ説明する。 なお、 Connectionless の場合は UI PDU を、 Connection-oriented の場合は I PDU を使う。 月刊 NDEF 2013 年 8 月号
  • 18.
    - 16 - LinkActivation LLCP では、まず NFC-DEP の接続を行う。"Link Activation"と呼んでいる。 Figure 3-1 の四角で囲んだ部分が NFC-DEP の接続シーケンスとなる。 LLCP で接続する場合、 ATR_REQ の Gi および ATR_RES の Gt に特定のデータを設定する。 Figure 3-1 Link Activation Procedure LLCP Magic Number■ 0x46 0x66 0x6d 、の 3byte を設定する。文字通りマジックナンバーで意味はない(ASCII コードなら "Ffm"になる)。 PDU■ Magic Number に続けて、 PDU が続く。お互いが使っている LLCP のバージョンを確認するため、最 低でも 1 つの PAX PDU が必要になる。 Magic Number に問題がなく、 LLCP バージョンにも問題がなければ Link Activation 完了となる。 月刊 NDEF 2013 年 8 月号
  • 19.
    - 17 - 送信するまでの間 LLCPド キ ュ メ ン ト で は 「 Normal Operation 」 状 態 に な る 。 こ こ か ら Connectionless か Connection-oriented かに分かれる。ここでは Connection-oriented のみ説明する。 この段階では、まだどちらがデータを送信したいのかが決定していない。 Android 端末で言えば、端 末同士を向かい合わせて星が流れる画面になったところである。 ここでタップをすると、そちら側が送信元になる。 それまでの間何をしているかというと、 SYMM PDU をお互いに送り合っている。 NFC の通信上、 Initiator が要求を出して Target がその応答を返す、という形は崩せないが、 Initiator は SYMM PDU の入った DEP_REQ をひたすら送ることで、 Target からデータを渡してもらえるようにしてい る。 送信開始 送信する側は、相手からの SYMM PDU に対して CONNECT PDU を送り返す。 CONNECT PDU を受けとった方は、応答として CC PDU を返す。 Figure 3-2 Initiator から送信 月刊 NDEF 2013 年 8 月号
  • 20.
    - 18 - Figure3-3 Target から送信 私が SNEP する場合、 CONNECT PDU の SSAP 、 DSAP として 0x04(SNEP)を指定し、 CC PDU でも SSAP 、 DSAP が 0x04 を返すようにしている。 ただ、別のライブラリでテストしていたとき、 CONNECT PDU では SSAP=0x04 、 DSAP=0x01 を指 定し、 ServiceName として"urn:nfc:sn:snep"と、名前で SNEP を指定しないと動かないものがあっ た。そうすると CC で SSAP 、 DSAP ともに 0x04 が返ってくるようになった。 このあたりはライブラリ実装依存なのか、単に私のドキュメント読み込みが甘いのか判断しづらい。 接続から送信まで 1パケットのデータを送信するシーケンスとして、 Initiator(Figure 3-4)、 Target(Figure 3-5)をそれぞ れ示す。 データは I PDU に載せる。受けとった方は、他に送りたいデータがないかを RR PDU で確認する。 もう送るものがなければ、 DISC PDU で切断しに行く。 月刊 NDEF 2013 年 8 月号
  • 21.
    - 19 - Figure3-4 Initiator から送信 月刊 NDEF 2013 年 8 月号
  • 22.
    - 20 - Figure3-5 Target から送信 ただ、私はまだ I PDU を何度もやりとりする実装をしたことがない。 URL を送るような用途であれば、だいたいは I PDU を 1 回だけ送信すれば済む。そういう実装であ れば比較的容易ということがわかっていただけるかと思う。 では I PDU に何を載せるかとなると、それが SNEP になる。 月刊 NDEF 2013 年 8 月号
  • 23.
    - 21 - 第4章SNEPって? SNEP の位置づけ NFC-DEP が物理層、 LLCP が論理層とするならば、 SNEP はアプリケーション層くらいになるだろう か。 あまり難しく考えずに言えば、 SNEP は NDEF を送受信するためのプロトコルである。 方式 SNEP は、 Client-Server 方式の通信である。やれることは「 NDEF を送りつける(PUT)」と「 NDEF をもらう(GET)」である。 Figure 4-1 SNEP 分割する送信も可能になっているが、パケットに載せるデータ長が 4byte あることから考えると、ほと んど使うことはないように思う。 LLCP の I PDU に 1 回で載らないようなデータ量であれば、 LLCP 層ががんばって I PDU を分割して送信する、というしくみになるだろう。 がんばれ LLCP!! 月刊 NDEF 2013 年 8 月号
  • 24.
    - 22 - まとめ NFC-DEP、 LLCP 、 SNEP と順に見ていった。 書いていってわかったが、私の勉強不足が目立つ。 LLCP に至って は、まだ v1.0 のドキュメントまでしか読んでおらず、現在の最新であ る v1.1 には言及できていない。 1 年ぶりに DEP 関係を調べたのでネットも検索したが、あまりヒット するものはなかった。確かに、 NFC の使い方としてはタグに読み書 きするのが花形のように思う。しかし、データ交換経路としての NFC も魅力的だと思う私にとっては、もうちょっとやってる人が増えてほし いなあ、とも感じる。 いや、今は水面下で調査や作成を行っていて、 Android 以外の端末でも NFC が標準になったときに 公開しよう、とがんばっているところかもしれない。 NFC は、サービスについてや、無線について話をすることが多く、ソフトウェア的にどうのこうのという ところがあまり出てこないように思うので、ちょっとでも興味を持ってもらえればな、と思いましたとさ。 2013/08/17 月刊 NDEF 2013 年 8 月号