私が知っている無線のことを書いておく。
以前、同じようなことを書いたかもしれないが、気にしない・・・。
NFCって分類にしたけど、あんまり関係がない。
が、NFC Forumの「Digital Protocol」を読みながら書くと、ちょっとは関係しそうだ。
だいたいの無線パケットは、こんな構成になっている。
・・・というほど無線を扱ったことがないのだけど、まあいいや。
エンコード(encode)
パケットの前に、データの表現方法について書いておかないといかんことがわかった。
NFC-Fでいえば「6.1.1 Modulation」のところだ。
英語で書いてあるが「Manchester coding」という言葉が1行目に書いてある。無線の世界だけじゃなく、デジタルデータのやりとりの際、同じビットのデータが連続するのは好まれない(らしい)。
NFCだけでなく、USBやデジタル放送など、8b10bやマンチェスターのようなデータ変換をして、あまり0000…とか1111…のようなデータが連続しないように裏でがんばっている。NFC-Fではマンチェスターと呼ばれる変換を行っている。
こんなのだ。
http://japan.maxim-ic.com/app-notes/index.mvp/id/3435
「0」を0→1、「1」を1→0、という信号の変化で表現する。
こうすると、どうやっても同じデータが2bit分までしか連続できない。ただ、データの量が倍になってしまうのが残念だが、仕方ないところだ。
プリアンブル(pre-amble)
「こんなタイミングでデータを送信するから、うまく捉まえてね」という同期タイミングを表す。
送信する方と受信する方で通信速度を合わせていたとしても、それをどのタイミングで取得したらいいのか、というのはなかなかわからない。
電子回路であれば、クロックマスターみたいにクロックを出す人がいて、それにあわせてデータを送信/受信すればいいのだけど、無線の場合はおのおののクロックでやらないといけない。それに、無線の周波数をお互いで決めていたとしても、ノイズなどでいろんなデータが取得できてしまう。
決まった信号(ビットで0101を繰り返すだけ、など)を最初に送信することで、受信する人はその信号にがんばって同期するのだ。と書いたものの、ISO18092によると、Pollingコマンドのプリアンブルは48bitのゼロ値らしい。
ほほぅ、そういうのもあるんだな、と納得しかけたが、ちょっと違った。
デジタルなゼロ値は、マンチェスター符号に置き換えると「010101…」となるのだった。DigitalProtocolの「6.1.2 Synchronization」に同期の取り方が書いてあるが、なんか難しそうなので読んでない。
Figure 20に2つ信号の図があるが、これはビットの正転と反転を表している。
無線だけかどうか知らないけれども、データ転送ではビット反転もよく行われるように思う(なんでだろう?)。
この図のSoSがプリアンブルの部分だと思う。その下に「has a value of 48bd」とあるので、たぶんそうだろう。
続くSoFが、SYNCコードということになる。
SYNCコード(sync code)
同期が取れただけでは、どこからデータが始まるのかわからない。
また、同期を取ったと思ったけれども、実はそれが偶然ノイズだったり別の人の無線パケットだったりすることもしばしばある。それを解決するために、プリアンブルの後に送信側と受信側で取り決めた特定のデータを載せ、「プリアンブルの後にこのデータが来たら、それはうちの無線パケットですよ。次はデータが来ますよ」という取り決めをする。
それがSYNCコードとかユニークワードとか呼ばれているものだ。受信する人は、プリアンブルをビット単位で処理しながらSYNCコードが来るのを待ちわびることになる。
DigitalProtocolの「6.3.1.2」に、SoFは0xB24D、と書かれている。
「もし受信側が0x4DB2と読んだら、それはビット反転しているからそう解釈してね」というようなことも書かれている。そういうことからもわかるように、SYNCコードはどういう値でもよいわけではなく、見分けやすいような値になっている。
データ(data)
ここにようやく、送りたいデータが載せられる。
ただ無線の場合、よそからの電波やノイズなどでデータが一部壊れることがしばしばある。
壊れていないことは受信側で確認しないとわからないので、だいたいCRCみたいな確認用のデータが最後にひっつけるようにすることが多い。
チェックサムだとビット化けしていても気付かないことがあるので、CRCを使うことが多いようだ。ネットでのダウンロードだとMD5なんかがよく使われていると思うが、サイズが大きいので16bitくらいのCRCがよく使われるようだ。
DigitalProtocolの「6.4 Data and Payload Format」のEoDに、CRC_F1, CRC_F2となっていて、ここも16bitになっていることがわかる。長いデータを送信すると、それだけデータが化ける確率も高くなるので短めにしたいんだろう、という気がする。
それに、無線の送受信というのはけっこう電力を使うので、短めにしてさっさと終わらせたいというのもあるだろう。
また、無線というのが共用のものであるため、長い時間送信したりしないように法律で規制されていることが多いからかもしれない。
ポストアンブル(post-amble)
データのおしまい。
なくてもいいような気がするけど、「俺がまだ送信しているから待てよ」というキャリアセンスさせるためにやってるのかもしれん(勝手な予想)。
あと、キャリアセンス、というものがある。
情報処理の試験で「CSMA/CD」とか「CSMA/CA」とか出てくる、あれだ。
無線というのは、他の人によって妨害されやすい。
周波数が違えばだいたいいいんだけど、同じ種類の機器は同じ周波数を使うことが多いので、悪意がなくても妨害してしまうことがある。
それを避けるために、無線の衝突を避けるためのしくみをがんばって考えなくてはならない。
基本は「誰かが送信している間は自分は送信しない」だ。
送信しているかどうかは、受信しないとわからない。
LBT(Listen-before-Talk)、などと呼ばれることもある。無線を話す前に聞く、ということ。
しかし、無線を壊すのは「同じ周波数」という条件なので、上記のような無線パケットだけでなく、他の知らない機器が送信していることも考えんといかん。
なので、だいたいは「RSSI値」(受信信号強度)という、データの中身ではなく特定の周波数の無線電力を見て、一定レベルよりも大きかったら「誰かが送信している」とみなすことが多い。
電波法では、周波数ごとにこの辺も取り決められている(はず)。
FeliCa Liteなんかの「Without Encryption」ってのはここら辺のはなしだろう。
「無線パケットは暗号化してないので、受信機がいたらそのまま読み取られますよ」ということだ。
これはMIFARE ClassicやUltralightも同じだろう(NFC-Bはよく知らない・・・)。
NFC Forumでは無線に関する規格を決めているので、それにあわせて受信機を作るだけでいいのだ。
WireSharkでイーサネット上のデータを拾ってくるのと一緒だ。
FeliCa StandardやMIFAREの製品版には、NFC Forum外のプロトコルがおそらく存在し、そこではパケットデータ自体を暗号化してやりとりするような取り決めがあると思う。
考えつく方法は・・・
- 暗号化用のコマンドを作り、コマンド以降を暗号化する。
まあ、これが普通なのかな。 - SYNCコードを変えて送信する。受信する方はがんばって複数のSYNCコードを読み分けられるように作っておき、このSYNCコードなら暗号無し、このSYNCコードなら暗号有り、みたいにする。
これだと、データ部全体を暗号化できるけど、受信機が大変かも。 - 周波数自体を変える。
これだと、その周波数帯を知らない限りは受信できないのでさらに安全。
しかし、リーダライタは複数の周波数帯を使い分けないといかんので、さらに大変。
とにかく、無線である以上は傍受から逃れられない、というお話でした。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。