#author("2022-05-27T11:10:56+09:00","","")
#contents

*はじめに [#u77776c8]

ZigBeeの活用事例がこの頃急激に増えてきました。

ただ残念なことに、通信規格としてのZigBeeは、今や複雑巨大なモンスターになってしまい、たとえ技術者であっても理解して使いこなすのはなかなか困難と言わざるを得ません。そこでスカイリーでは、実践的でポイントをおさえたZigBeeの解説サイトを用意することにしました。
 
概論は極力避けて仕様面を必要最小限に記述していますが、これは逆にいうと膨大なZigbee仕様も、最初に理解すべき本質的な部分はそのごく一部で十分ということです。

この解説で「ZigBeeを導入してみたけど動作がよくわからん」という「??」が少しでも解消されればと願っています。

2018/8/15~
ZigBeePRO系の最新版である「ZigBee 3.0」の解説を最終章に追加いたしました。

*ZigBeeプロトコルの歴史 [#o721d5bc]

ZigBee通信規格は2004年の発表から現在に至るまでに、仕様上の大きな改訂が何度かありました。とりわけ2007年頃策定された最新規格においてはZigBeePROフューチャーセット(通称「ZigBeePRO」)が登場し、それまでのいわゆる伝統的なZigBee規格は「ZigBeeフューチャーセット」という呼び名で区別されることになりました。

&ref(image5.PNG,nolink,image5);

ZigBeePROとZigBeeの違いを一言でいいますと、ZigBeePROではツリー型ネットワークが廃止され、メッシュネットワークのみになりました。また初期のZigBeeではスター型においてスーパーフレームを利用するいわゆるビーコンネットワークが可能でしたが、ZigBeePROではビーコンネットワークはサポートされなくなっています。したがってZigBeePROではもはやスター型とメッシュ型の区別もあまり意味がなくなり、スター型とは「コーディネータとエンドデバイスだけで構成されるメッシュネットワークである」と考えることもできます。

現在の主流はZigBeePRO規格となっており、ZigBee解説書の中にはZigBeePROで通用しない機構が解説されているものもありますので、場合によっては注意が必要です。

このWikiでは主にZigBeePROを解説しますが、ほとんどの記述がZigBeeにも当てはまります。ただし特に区別が重要な箇所については、その区別を明確にして解説しています。

*周波数 [#t2deac6f]

ZigBeeは無線規格にIEEE 802.15.を利用します。ネットワーク層以上を定義するZigBee(ZigBee Alliance)と、物理・MAC層の802.15.4(IEEE)は策定している団体が異なります。ZigBeeが無線規格に802.15.4を使わなければならない絶対的な必然性はありませんので、たとえば無線LANを使ったZigbeeというのも「論理的には」可能です。実際、PLCのような有線ネットワーク上にZigBeeプロトコルを載せて多数の機器を複雑に連携させるシステムも世の中には存在します。

IEEE 802.15.4で利用できる周波数は以下のようになっています。

-2.4GHz帯・・・世界共通
-868MHz帯・・・主にヨーロッパ
-915MHz帯・・・主にアメリカ

また各周波数には分かりやすいように連番で論理番号が割り振られています。

-868MHz帯・・・チャンネル0
-915MHz帯・・・チャンネル1-10 (906MHzから2MHz刻みで全10チャンネル)
-2.4GHz帯・・・チャンネル11-26 (2405MHzから5MHz刻みで全16チャンネル)

したがってZigBeeの説明で「チャンネル11」というときは、2405MHzを指すことになります。これらの中で特に2.4GHz帯は世界共通で利用できるため、最も多く利用されている周波数になります。

そこで2.4GHzにフォーカスした場合の周波数の使い方と、家庭やオフィスで一般的に使われるようになった無線LAN(802.11b)との比較を下図に示します。

&ref(image8.png,nolink,image8);

802.15.4は隣合うチャンネル同士で影響を与えない点がポイントです。一方で802.11bはチャンネルの占有帯域が重複しており、完全に干渉を避けるにはチャンネルを4つ開ける必要があります。802.11bとZigBee(802.15.4)は共に変調方式にDSSSを使っていますが、802.15.4は中心周波数から2MHzを使い、802.11bは22MHzを使います。

また現在、900MHz帯バージョンの802.15.4の標準化も進行しており、そう遠くない将来にサブ1GHz上で動作するZigBeeが利用可能になると考えられます。


*ネットワークとデバイスタイプ [#t2deac6f]
**デバイスタイプ [#va812dc3]
ZigBeeでは3種類のデバイスタイプが存在します。それぞれ、コーディネータ、ルータ、エンドデバイスと呼ばれます。

コーディネータはPANを開始し、セキュリティの認証やチャンネルマネージャといったネットワーク管理的役割を果たします。インターネットとZigBeeを接続するゲートウェイとしても使われることが多いです。

エンドデバイスはスリープできるタイプで、センサーなどを接続して様々なデータを収集しながら間欠動作で動きます。他デバイスの接続を受け入れる能力がなく、データは接続先のルータ、またはコーディネータに固定的に送信されます。

ルータはメッシュネットワーク能力をもったデバイスを指します(もちろんルータにセンサーを付けて運用しても良いわけですが)。いつデータの中継を依頼されるか分からないため、ルータは原則としてスリープできません。

ZigBeeデバイスは動作開始時に必ず上記3種類のどれに属するかを指定してスタートさせます。よく誤解されますが、デバイスタイプはハードウェアの性能の区別でなく、あくまで通信規格上の挙動の定義なので、エンドデバイス役の機器を、再設定することでコーディネータとして使うことも可能です。

**ネットワークの形 [#t2deac6f]

ZigBeeには図のように3つのネットワーク方式があると一般的には説明されます。

***【ネットワーク構成図】 [#tec9311d]

&ref(network.jpg,nolink,image1);

スター型は無線LAN、Bluetoothなどと同様の方式で、中央にアクセスポイント(=コーディネータ)があり、エンドデバイスもルータも直接接続します。

ツリー型はコーディネータを頂点とした階層構造です。ZigBeeではツリーの形成に「分散アドレス割り当て」というユニークな手法を採用しています。この方式では、ある特定の計算式にしたがって親が子のアドレスをアサインしていきます。その計算式はツリーの深さと子デバイスの数から重複なくアドレスを生成でき、ネットワーク全体の情報を持つことなく一意なアドレスを割り当てていくことができるようになっています。

さらに秀逸なのは、そのアドレスからツリーの深さや親デバイスを逆算できるため、ルーティングテーブルを使わなくても転送経路が確定できます。そのためネットワーク規模が大きくなってもメモリ消費量が増えないという大きな特徴をもっています。(余談ですが個人的にはこの「分散アドレス割り当て」方式こそがZigBee最大の発明の一つだと思うのですが、惜しくもZigBeePROでは廃止になってしまいました。)

最後にメッシュ型。アドレスは基本的に「乱数」で割り当てられます。よってアドレスからは転送先が分からないため、AODVと呼ばれる動的な経路構築のメカニズムを用いて通信経路を形成します。前述のように、ZigBeePROではツリー型は廃止されており、ZigBeeフューチャーセットの方で継続的にサポートされています。

以上、3つのネットワークトポロジーですが、ビーコンネットワークをサポートしなくなったZigBeePROではスター型とメッシュ型の区別も曖昧で、たとえばコーディネータとルータで構築されたスター型でも、ルータ間で通信する際はメッシュ通信によって必ずしもコーディネータを経由しないため、結果としてスター・ツリー・メッシュという3つのネットワーク構造の区別は、ZigBeePROではほとんど意味をもたなくなりました。

*アドレッシング [#p824fd21]

ここでは、非常に重要な「アドレス」について解説します。Zigbee機器は2種類のアドレス、つまりIEEE 64bitアドレス(またはロングアドレス、拡張アドレス等)と16bitアドレス(ショートアドレス、ネットワークアドレス)を使い分けます。それぞれ以下の意味を持ちます。

**IEEE 64bitアドレス [#p824fd21]
デバイスに固有の識別子。世界中のZigBeeデバイスがそれぞれ固有の64bitアドレスを持ちます。通常、機器の製造元がきちんとアドレスを管理して出荷時に付与します。ただし評価ボードなど「実験、開発用」のZigBee機器にはIEEE 64bitアドレスが付与されてないこともあります。イーサネットの48bit MACアドレスと同じ役割を果たします。

**16bitアドレス [#p824fd21]
後述するPANへの参加時に、動的にアサインされます。同じPANの中では必ず一意である必要がありますが、異なるPANであれば同じ番号が使われる可能性もあります。16bitアドレスはPANへ参加する度に異なる値がアサインされます。その意味ではDHCPで運用されているプライベートIPネットワークに似ています。

このうちZigBeeは、主に16bitアドレスを使って互いに通信します。

*PANの生成と参加 [#p824fd21]

ZigBeeネットワークの作り方を解説します。ZigBeeでは、各ネットワークはPAN IDという16ビットの識別子で区別されます。PAN IDが異なるデバイスはたとえ電波の届く範囲にいても直接通信はできません。逆にいうと、ZigBeeがネットワークを作るとは、各デバイスが同じPAN IDと周波数を共有するプロセスであるということが出来ます。

**PANの生成[コーディネータ] [#fb931340]
コーディネータはまず最初に各チャンネルの電波環境を調べ、ノイズの少ないチャンネルを検索します。同時にアクティブスキャンを行い、周囲に同様なコーディネータが存在しないか確認します。その上で、

1) PANが利用するチャンネル~
2) PANが利用するPAN ID

を決定して起動します。

PAN IDは、原則的にはランダムに生成されますが、それだといろいろと使いづらい点も多いので、事前に生成するPAN IDを指定できる製品がほとんどです。

誤解を恐れずに思い切りざっくりといってしまえば、コーディネータの仕事はたったのこれだけです。

コーディネータは1つのPANに必ず1つだけ存在し、ショートアドレスは必ず0x0000を使うと決まっています。事前に割り当て値が予測できないルータ、エンドデバイスのショートアドレスと異なり、コーディネータだけは確定してます。センサなどで取得したデータをコーディネータに周期的に送信するといったコーディネータ方向へのアプリケーションは、事前にアドレスを調べることなく動作することができるわけです。

**スキャン[ルータ・エンドデバイス] [#v26c9420]
ネットワーク参加の最初のプロセスとしてスキャンが始まります。多くの場合、各デバイスはアクティブスキャンを周期的に行いますが、その過程で周囲の端末に対して “Beacon Request”を同報します。それをキャッチした周囲の端末は “Beacon Response”を応答します。これにより周囲の端末の情報(Node Descriptor)を得ることができるわけです。

&ref(image2.PNG,nolink,image2);


2014/5/1) ビーコン応答は、宛先アドレスが省略形で、ユニキャストとは異なりましたので、記述を修正いたしました。図は古いままですのでご注意ください。

次に、スキャンによって取得した周囲の情報(Node Descriptor)の中から、参加したいネットワークのPAN IDを選択します。デバイスを個別に選択するのでなく、あくまでPAN IDを選択するという点に注意が必要です。そして更にそこから、スキャンで取得したNode Descriptorを使って、そのPAN IDに接続できそうな最寄のデバイスをピックアップし、接続過程に入ります。

**接続 [#v26c9420]
アクティブスキャンで得られたNode Descriptorの中には、ビーコンを応答してきたデバイスのIEEE 64bit アドレスが格納されています。この情報を元にして接続要求元はMAC層のAssociation request, Association Response, Data requestを行います。この過程で接続先は、接続要求してきた端末のアドレスをランダムにアサインすると同時に、自分がもっているリスト(ネイバーテーブル)に追加します。

&ref(image3.PNG,nolink,image3);

注)上の図では○で示されたデバイスがツリー形状のように書かれてますが、これは図を描くときの単なる都合で、一般には自由気ままに機器が配置されている状態を想定します。

**デバイス通知 [#lcf221bb]
接続をリクエストした相手からAssociation Responseが成功ステータスで返答されると、ネットワークへの参加は成功になります。次に、新しく参加したデバイスは、自分のIEEE 64bitアドレスとショートアドレスの対情報とデバイス属性情報を、ネットワーク全体にブロードキャストします。これはZDO層のdevice annceという特殊なメッセージによって実現されます。これによって新規にデバイスがネットワークへ参加したということを他のデバイスが知ることになります。

ここまでが、ZigbeeにおけるPAN生成とPANへの参加シーケンスの流れです。バッタもんでない、すべての正しいZigBeeデバイスは、必ずこの処理を行います。ただしこれらの処理はZigbeeハードウェアが自動で行いますので、使う側が意識することはほとんどありません。

**参加に関するいろいろ [#v26c9420]
ここまでPAN生成とPANへの参加過程を解説しました。ZigBeeがネットワークを形成する一番根本かつ重要なメカニズムの一つです。いくつか補足事項を記します。

***アクティブスキャン [#lc91191b]
アクティブスキャンは、ZigBeeの各チャンネル毎にビーコン要求をだして、しばらく待機し、また次のチャンネルで、、、というように繰り返し処理をします。このため、アクティブスキャンが完了するまでにしばらく時間がかかります。これがいわゆるZigbeeの「接続時間が長い」というやつです。通信できるようになるまでにしばらく時間がかかるなと思う時があるのは、アクティブスキャンをかけているからです。デバイスはスキャンをかけている間は原則、他の通信は行いません。

スキャンにおける各チャンネルの滞留時間は、一番短くて約30msec, 長くて約4分程度で、計算式は

15.36msec * (2^duration + 1)~
(ここで0 <= duration <= 14) 

つまり倍々に増える形で滞留時間をコントロールできます。

さて、このアクティブスキャンを迅速に行うことは可能でしょうか? これはつまり接続時間の短縮につながります。

ZigBee的な回答としては2つの手段があります。

1. 上の式におけるdurationを小さい値にする~
2.スキャンするチャンネルを全チャンネルでなく、いくつかのチャンネルに絞る

2は一般にスキャンチャンネルマスクといい、たとえばチャンネル11, 15, 19, 23だけスキャンするといった運用が可能です。当然、このチャンネルで起動しているPANだけしか発見できなくなりますが、ネットワーク形成を短縮したい場合のひとつの方法となります。

ZigBeePRO SDKでは「gnSK_APS_apsChannelMask」がチャンネルマスクに相当します。

***接続の許可・拒否 [#lc91191b]
PANへ新しいデバイスが参加してくるのを抑止するメカニズムはいくつかありますが、ここでは主要な方法を2種類あげます。

1) Association Permit (MAC層)~
2) 最大接続デバイス数、最大接続ルータ数(NWK層)

1. Association Permit~
Association PermitはMAC層のパラメータの一つで、名前の通りAssoationの発生を抑止します。このパラメータはアクティブスキャンの過程で、Beacon要求に対するBeacon応答に含まれて周囲に伝わります。アクティブスキャンをかけたルータやエンドデバイスは、Association PermitがFALSEのデバイスには接続要求してはいけないことになっています。これによってルータやコーディネータが接続してくるデバイスを制御します。

ZigBeePRO SDKでは「gnSK_MAC_macAssociationPermit」がこれにあたります。

一番よくある使い方としては、Association Permitは初期出荷状態ではオフ(接続不許可)にしておき、ボタン押下やスイッチ切り替えによって一定時間だけAssociation PermitがTRUEになるよう製品を作っておくことです。ユーザはネットワークを作りたい時だけボタンを押して接続を許可し、その間に子機の接続を完了させます。

ZigBee製品では、知らないデバイスに勝手に接続されてこられては困りますので、一般にこのようにして望むデバイスとだけPANを形成するようにします。


2. 最大接続デバイス数、最大接続ルータ数~
Association Permitが、ユーザが意図的に接続の許可・不許可を制御するために使うのに対して、これらのパラメータはネットワークをバランスよく形成するために使います。最大接続デバイス数は、そのデバイスが収容できる機器(=ルータ+エンドデバイス)の総数、最大接続ルータ数は収容できるデバイスのうちルータの数を表します。このことから「最大接続デバイス数 - 最大接続ルータ数」が、そのデバイスが収容できるエンドデバイス数になります。

ZigBeeデバイスは、自分に接続してきているデバイスの数が上のパラメータ上限に達すると、「もう上限です」ということを示すフラグをBeacon応答の中に設定します。そしてこのフラグもアクティブスキャンによって周囲に伝わります。ZigBee仕様によって、上限に達しているデバイスへは接続要求をしてはいけないことになっています。

ZigBeePRO SDKでは「gnSK_NWK_nwkMaxChildren」が最大接続デバイス数、「gnSK_NWK_nwkMaxRouters」が最大接続ルータ数に相当します。

*データ送受信 [#if254898]
PAN形成の次はデータ送受信を解説します。ZigBeeではこの2つ(PAN形成とデータ送受信)さえ理解しておけば、実用上困ることはあまりありません。

これまでの説明では、Zigbeeデバイスは周波数とPAN IDの2パラメータさえ合致していれば原則的には通信できると説明しました。ZigBeeにおいてネットワークを作るとは、周波数とPAN IDを自律分散的に共有していくプロセスに他なりません。これらはいずれも、MAC層に802.15.4を採用していることからくる制約です。

それに対してデータ送受信のルールというのはZigBeeネットワーク層以上の話になります。TCP/IPでいえばIP層から上に相当する純粋にロジカルな話です。

**ZigBeeの通信モデル [#p4ecaeef]

これまた誤解を恐れずに言えば、ZigBeeにおけるデータ通信はTCP/IPでいうところのUDPと同じです。つまり

1) 送りっぱなし~
2) 相手に届いたかは分からない~
3) 必ずパケット単位で送りあう。1パケットはヘッダ込みで127バイト。アプリケーションが使えるのは実質、90バイト弱。~
4) パケットは、届くか届かないかのどちらかであって、半分だけ届くといったことは絶対にない。~
5) 1パケット内のデータの一部がビット化けして通知されるといったことも絶対にない(よってアプリケーションでチェックサムする必要もない)。~

これを原則と考えると、ZigBeeの様々な機能はすべて上の「使いづらさ」を解消する工夫であると理解できます。

**送受信のインターフェイス [#p4ecaeef]

ZigBee仕様が規定している送信のAPIを以下に抜粋します。

 APSDE-DATA.request {
   DstAddrMode,
   DstAddress,
   DstEndpoint,
   ProfileId,
   ClusterId,
   SrcEndpoint,
   ADSULength,
   ADSU,
   TxOptions,
   RadiusCounter
 }

けっこう多いですね!(多すぎです)~
重要なので順に説明します。

*** DstAddrMode, DstAddress [#y0dd1def]

パケットの送信先アドレスを指定します。前述のように、ZigBeeのアドレスは2種類(16ビットショートアドレスか64ビット拡張アドレス)ありますが、DstAddrModeは指定したアドレスがどちらなのかを指定します。

正確にはさらに「指定なし」とか「グループ宛」といったアドレスモードがありますが、基本は16bitか64bitどちらかと考えると良いです。ここで重要なのは以下の点です。

''16bitか64bitどちらかを指定したとしても、最終的には16ビットアドレスに変換されます。''

TCP/IPならば、IPアドレスは最終的にARPやNDによって物理層の48bitアドレスに変換されれ送出されますが、ZigBeeの場合はネットワークアドレスが最終地点です。ということは、64bitアドレスを指定するより16bitを指定する方がより直接的だということです。

*** DstEndpoint, SrcEndpoint [#zc5ce69d]

エンドポイントとはZigBee特有の用語ですが、TCP/IPのポート番号だと考えると分かりやすいでしょう。HTTPならば80, FTPならば21番というように、アプリケーションが待ち受ける「受け口」のようなものがZigBeeでいうエンドポイント番号です。

0-255のうち、0番はZigBeeで予約されており、255番は全エンドポイントを意味する予約番号になっています。アプリケーションはこれ以外の番号を好きなように使って動作します。

パケットの送信側は、宛先エンドポイント番号を指定して送り出す必要があります。相手はそのエンドポイント番号で待ち受けることで、はじめて受信になります。同時に送信側がどのエンドポイント番号を使っているかをSrcEndpointに明示して相手に渡すので、受信側はどのエンドポイント番号に応答すれば良いのか知ることができます。

エンドポイントはひとつのZigBeeデバイス上で複数のアプリケーションを動作させるための工夫といえます。

&ref(layer.png,nolink,image3);

*** Profile ID [#m80d37d3]

ZigBeeでは「プロファイル」という形で交換するデータの形式と解釈を細かく定義して運用します。プロファイルの解説はここでは割愛しますが、ともかくパケット毎にそのパケットがどのプロファイル用なのかということを明示して送信します。

エンドポイントは使う番号を自由に決められましたが、プロファイル番号は自由に決められません(ただし実験や評価用は例外)。プロファイル番号にはパブリックとプライベートの二種類あり、パブリックプロファイル番号はZigBee Allianceが管理、割り当てをします。以下に代表的なパブリックプロファイル番号を上げます。

Smart Energy Profile = 0x0109~
Home Automation Profile = 0x0104~
その他、たくさん

一方で上記以外に、個別企業が自由に使えるプライベートプロファイルIDがあります。こちらはZigBee Allianceから製造者固有プロファイル(MSP)としての試験を受けて認定をもらうと、一定範囲の番号を割り当ててもらえます。

いずれにしても、ZigBeeではパケット毎にそれが属するプロファイル番号を明示して送る必要があり、逆にパケットを見ることでそれが何の目的で送信されているかを知ることができるようになっています。

***ClusterId [#u0f42afc]

クラスタ番号はZigBee独特の概念で説明が難しいですが、ざっくりいうとそのパケットが運んでいるデータの中身(意味)をあらわす識別子です。

これによってデータ受信側は、データの中身(ペイロード)を解析する''前''に、受信したデータが何なのかを知ることができます。

クラスタ番号の使い方は、製造者固有プロファイルではアプリケーションが自由に決めて運用できます。逆にパブリックプロファイルでは、クラスタ番号とそのデータの形式や単位はすべて厳密に定義されていて、それにしたがって互いに送りあう必要があります。

クラスタ番号は2バイト長で、同じプロファイル内では一意に区別される必要がありますが、異なるプロファイル間では同じクラスタ番号が使われる可能性があります。

*** ADSU, ADSULength [#p0037701]

ADSUは送信するデータ、ADSULengthはデータの長さを指定します。~
IEEE 802.15.4は1回に最大127バイトのデータを伝送しますが、ここにPHY, MAC, NWK, APS各層ヘッダとMACのチェックサムが入りますので、アプリケーションが指定できるデータ長はだいたい大きくて90バイト弱です。セキィリティイネーブルなネットワークの場合、セキュリティ用ヘッダがさらに追加されますので、指定可能なデータ長はさらに小さくなります。

最大127バイトという制約はZigBeeが無線規格にIEEE 802.15.4を採用していることからくるもので、ZigBeeそれ自体の制限ではありません。無線規格が代わればMTUも変化します。

*** TxOptions [#baa754c8]

Ackと再送制御の項で説明します。

*** RadiusCounter [#e3b382b9]

ブロードキャストの項で説明します。

***送受信のルールまとめ [#e8d863b4]

これまでは送信側の説明でしたが、最後に反対の視点で、受信側からみたデータ処理のルールを簡単に説明します。

送信されたデータの宛先16bitアドレスとPAN IDが、自端末のアドレスとPAN IDに一致するか、またはブロードキャストの場合、データ受信処理が進行します。その上で、

1) エンドポイント番号が一致しているかチェックされます。アプリケーションが待ち受けているのと異なるエンドポイント番号宛ならば、この時点で破棄されます(送信時に255番を指定した場合はすべてのエンドポイントに通知される)

2) エンドポイントが一致すると、アプリケーションに送信元アドレス、プロファイル番号、クラスタ番号と一緒に受信データが通知されます。アプリケーションはプロファイル番号を見て、受信したデータがどのプロファイルで処理されなくてはならないか決定します。

3) 次にクラスタ番号を見てデータの内容を判定します。必要ならアプリケーション側でさらにデータの内容を解析して処理します。

まとめると、Zigbeeのデータ通信は

アドレス -> エンドポイント -> プロファイル番号 -> クラスタ番号 -> 生データ(あとはアプリで勝手に処理して)

という順序でデータがより具体化されていきます。

**ブロードキャスト[#c5fc8e52]

ZigBeeでブロードキャスト(同報通信)する際は、通常、宛先を16bitアドレスで0xFFFFと指定します。これによってパケットが次々をコピーされながらネットワーク全体に波及していきます。

他にもいくつかの予約されたブロードキャストアドレスがあります。

0xFFFD: コーディネータ、ルータ、スリープしないエンドデバイス宛~
0xFFFC: コーディネータ、ルータのみ(エンドデバイスは除外)

ZigBeeはマルチホップ通信をサポートしますので、発信されたブロードキャストは常に転送される可能性を持ちます。転送を伴わない同報通信を(狭義の)ブロードキャストと呼び、転送が起こりうる同報通信をフラッディングと呼んで区別することもあります。狭義のブロードキャストとフラッディングの区別はネットワークに与える影響という点で非常に重要です。

フラッディングにおけるパケットの転送回数の上限を決めるのは、送信時に指定するBroadcast Radius(ブロードキャスト半径)です。radius = 1と指定すると、周囲のデバイスが受信した時点で「打ち止め」となり転送されません。これはつまり狭義のブロードキャストを意味します。

ブロードキャストは宛先を知る必要がないという点で非常に有用ですが、radiusは必要最小限の値にした方が安全です。

またスキャンの項で説明したビーコン要求もブロードキャストですが、これは転送されることのない1ホップのみの同報通信で発信されます。

**メッシュルーティング [#u76a66cb]

ZigBeeのメッシュルーティングは経路制御方式にAODV(Ad hoc On-Demand Distance Vector)を採用しています。特徴としては、経路が必要になった時にRoute Request(RREQ)コマンドをネットワーク全体にブロードキャストし、経路発見の対象となったデバイスがRoute Reply(RREP)というコマンドをユニキャストで応答して経路を確立します。

&ref(flooding.png,nolink,image5); ~

RREQが転送されると、転送したデバイス間のリンク品質(RSSI)値が加算されながらコマンド内に記録されます。正確にはRSSIは8段階のコスト値に丸め込まれ、RSSIが良好(品質が良い)ほどコスト値が小さくなります。このためRREQが宛先まで到達した時点で、RREQが通過したルートの総コストがわかります。RREQはフラッディングなので、可能なありとあらゆる転送経路を全解探索的に通過するという点がポイントです。当然、宛先のデバイスは、複数の経路からやってきた複数のRREQを受信することになります。

RREQ転送の簡易フローチャートを示します。

&ref(rreq.png,nolink,image5); ~

RREQの宛先、つまり経路の発見対象となったデバイスは、受信した複数のRREQから最小コストのRREQを選択して、RREPをユニキャストで応答します。各デバイスはRREQ転送の過程で、経路発見テーブルというものを形成します。これは受信したRREQの送信元と転送元(1個前のデバイス)、受信時点での総コスト、シーケンス番号などで構成されます。デバイスはRREPを受信すると、経路発見テーブルの中から対応するエントリーを見つけて、その転送元(1個手前のデバイス)を確認し、そのアドレスへRREPをユニキャストします。このようにRREQ通過の過程で形成した経路発見テーブルを利用することで、RREPを正確にRREQの逆向き方向へ返送するとができるわけです。

RREP転送の簡易フローチャートを示します。

&ref(rres.png,nolink,image5); ~

ZigBeeでは、ルーティングテーブルは基本的に「宛先アドレス」と「ネクストホップ」を2つ一組にした情報で管理します。読み方は、「宛先アドレスXへ送信したい場合は、ネクストホップNへ転送せよ」です。宛先とそのネクストホップの2個組みを距離ベクトルと呼び、距離ベクトル情報の集合でルーティングテーブルが形成されているのでAODV(Ad hoc On-Demand Distance Vector)方式と呼ばれるのです。送りたい宛先に対して、その途中経路すべてを把握しているのではなく、転送すべき次のアドレスしか把握してない点が大きな特徴です。RREQとRREPの交換で実行されるルーティングテーブルの形成過程の例を以下に示します。

&ref(rttable.png,nolink,image5); ~

SにRREPが戻ってきた時点で、D宛てにはAへ転送すればよいというルーティングテーブルが完成しています。また途中経路のA, Bでは、D方向の経路と同時にS方向(戻り方向)への経路も同時に形成できている点も注目です。

ZigBeeのメッシュルーティングではこの他にも、データの転送途中で転送エラーが発生するとルートエラー情報が通知されます。これによって経路の再構築を迅速に行うことができるなどの機構が用意されています。基本的にこれらのメカニズムはZigBeeのファームウェアが全自動で行うため、アプリケーションが意識する機会はめったにありません。

メッシュネットワーク通信は非常に奥深い技術ですが、あまり深入りすると帰ってこれなくなりますのでこの辺にしておきます。もっと知りたい!という方のために、少々古いですが昔Internet Watchに連載されていた大変優れた解説記事を紹介します。

-[[P2Pとワイヤレスの交差点:http://internet.watch.impress.co.jp/www/column/wp2p/index.htm]]

**2種類のAckと再送制御 [#c049855c]

データ送受信のところで、ZigBeeのデータ通信は届いたかを確認できないと説明しましたが、送信時にAckオプションを指定することで相手から送達確認をもらうことができます。ZigBeeでAck制御が作用する場所はMAC層とAPS層の2種類あります。

MAC層Ackは、下図のように、基本的に直接データが届く相手との間で機能します。アプリケーションがデータ送信を指示すると、MAC層のAckオプションを必ず有効にして送出しますので(ブロードキャストは例外)、隣のデバイスに限っては相手からAckが戻ったかをチェックすることで送達確認が可能です。

&ref(ack.png,nolink,image5); ~

しかしMAC層Ackはあくまで隣同士の確認ですから、2個先のデバイスに届いたかを確認することはできません。

そこでAPS層Ackを使います。APS層Ackはメッシュネットワーク上で動作し数ホップはなれた送信先からの送達確認を要求できます。送受信のインターフェイスの項で「TxOptions」というフィールドがあったと思いますが、ここに「Ack要求」のフラグを立てて送信します。

MAC層、APS層共に、相手からAckが受信できないと自動的に再送を行います。これによって少々電波状態が悪くでも確実に相手までデータを届け、また届いたということを確認できます。


APS層Ackで注意が必要なのは、APS層ACKもMAC層からみるとデータなのでAck制御の対象になるということです(ややこしいですね)。したがって図のように、上位層でデータとAck制御が発生し、その異なる階層(MAC層)でも連鎖的にデータとAck制御が発生します。そしてAPS層Ackはメッシュネットワークで作用しますから、データもしくはAck、もしくはその両方で、送信時に経路が確立してない可能性があります。この場合、経路制御が先に働きます。つまりフラッディングが発生するということで、結果的にはAck制御なしより数倍のトラフィックを発生させることになります。



*休憩 [#ae1b3815]
そろそろおなか一杯ですか?
もうすぐ終わりです。

*省電力制御 [#c28e87d6]

ZigBeeの特徴として省電力性がよくいわれますが、「省電力」の正体をもう少しよく考えてみます。

最新世代のIEEE 802.15.4準拠RF ICを見ると、だいたい送受信30-20mA typくらいが平均です。優秀なもので20mA切ります。一般にはこれを駆動する外部ホスト(マイコン)や周辺回路が必要になりますので消費電力はこれより20%くらい増えます。

ここで1000mA/hの電池で30mAずっと流せば33時間で電池がきれます。

「えっ、33時間? 3年もつんじゃ・・・???」

3年持つのはスリープさせた時の話です。

RF ICのスタンバイ待機電流は最近だと1 uA切ってますが、1 uAとして1000mA/hの電池でずっとスタンバイにさせておけば計算上は114年もちます。問題は「ずっとスタンバイ」で何の役に立つのかという話です。

要はどのくらい起床して、どのくらいスリープさせるのかといった、アプリケーションモデルを提示せずに「単三電池○○本で●●年駆動します」などというのは、ほとんど怪しいセールストークですので、記事とか製品カタログを読む際は注意してください。

でようやく本題ですが、確かに物理的特性としてのICの消費電力も重要ですが、これと同じくらい重要なのは通信規格としてどのように省電力をサポートしているかというプロトコル的な工夫、仕組みの方です。

以下にZigBeeプロトコルとしての省電力制御を説明します。

**エンドデバイスには二種類あることに注意 [#s0b43110]

ZigBeeがいくら省電力といってもデバイスを間欠動作させなければ省電力もあったもんじゃないというのは述べました。というわけでスリープできるデバイスタイプ=エンドデバイスがZigBeeにおける省電力制御の要になります。

実はエンドデバイスには、スリープタイプと非スリープタイプの2種類あります。「スリープしないエンドデバイスに一体何の意味があるんだ」と言われるとやはりその通りなわけで、普通はエンドデバイスというと暗黙のうちにスリープタイプで動作します。非スリープタイプの存在には歴史的経緯があるのですが、ともかくエンドデバイスがスリープタイプで動作する時にのみ、ZigBeeの省電力機構が作用する、という点が重要です。

**親と子 [#abf30923]

スリープ型エンドデバイスの省電力制御の理解に必要ですので、ZigBeeにおける親子の関係を少し厳密に定義します。

PAN形成のところで、PANへ参加するのにアクティブスキャンをした後、発見したデバイスに接続してアドレスの割り当てを受けると説明しました。もう少し詳しく言うと、発見したデバイスにAssociation Requestコマンドを投げて、Association Responseの応答を成功ステータスで受信すれば接続が完了します。この時点でPANの周波数、PAN IDなどが共有されます。

この時、Association RequestとResponseのやり取りをしたデバイス間を「親子」関係と呼びます。自分からみて、Association Requestの送信先が「親」、あるいは逆に、Association Responseの応答先が「子」です。あるデバイスにとって親は常にひとつ、子は複数可能です。親をもたないルータを特別にコーディネータと呼ぶ、という考え方もできます。エンドデバイスは子になれますが親にはなれません。

さてこの時、ルータはメッシュルーティング能力を持ちますから、データを送る際は経路を動的に形成して送ります。したがってルータが送るデータの経路はデバイスの親子に関係なく選択できます。ルータにとって親子関係はPANに参加する際にAssociationコマンドを送る必要があるから、というくらいの重要さしかないのです。

一方でエンドデバイスはルーティング能力を持ちませんので、データを送信する際はどこか固定の送り先に送り出す必要があります。それが「親」デバイスです。エンドデバイスは親デバイスとの接続しか内部で管理しません。エンドデバイスにとって親デバイスが重要なのは、それがデータを代わりに預かってくれるのと、エンドデバイスの代わりにルーティングを起動してくれるためです。

**ポーリングと間接送信 [#g4fd613c]

ようやくポーリングの説明ができるようになりました。エンドデバイスのスリープは非同期型で、いつでも好きなタイミングでスリープできます。このためスリープ型エンドデバイス宛にデータをおくっても、受信してくれるとは限りません。そこで親デバイスは、エンドデバイス宛てのデータをデバイス内部のバッファに一定時間ためておきます。これを間接送信モードといいます。すべてのルータとコーディネータは、自分に接続している子デバイスにスリープ型エンドデバイスが含まれているかどうかを、正しく維持管理できなくてはいけないことになっています。

アプリケーションは、データを送る相手がエンドデバイスかそうでないか意識する必要は''ありません。''直前の親デバイスが適切に判断します。
(ちなみに非スリープタイプのエンドデバイスに対しては、親はデータをバッファリングせず、直接送信で転送します)

スリープから起床したエンドデバイスは、任意のタイミングで親デバイスにデータ問い合わせます(ポーリング)問いあわせの結果、バッファリングされたデータがあれば親はそのエンドデバイス宛てに改めてデータを転送します。このようにして、データは時間差でエンドデバイスへ配信されます。

エンドデバイスが問い合わせをする間隔をポーリング周期といいます。親デバイスはデータを一定時間しかバッファリングせず、時間がすぎると消去しますので、バッファリング時間よりもポーリング周期を短く実行する必要があります。

&ref(polling.png,nolink,image5);

0xFFFF指定で送信されたブロードキャストも親デバイスはスリープしているエンドデバイスのために一定時間バッファリングします。一方で、0xFFFD指定で送信されたブロードキャストは、スリープタイプのエンドデバイスへは配信されません(つまりブロードキャスト時に親デバイスのメモリ領域を消費せずに済ませることができます)。

ルータに複数のスリープ型エンドデバイスが接続している場合、その台数分だけバッファ領域も必要になってきます。スリープ型エンドデバイスに大量のデータを送り過ぎると親のバッファ領域が足りなくなって途中から破棄され、エンドデバイスまで届かないこともでてきます。このようにスリープ型エンドデバイスの同時接続台数は親デバイスのメモリ容量に左右され、下り方向のトラフィックが発生するようなアプリケーションの設計にはある程度注意が必要です。

**親による代理応答 [#g4fd613c]

下図のようにコーディネータから数ホップ先のエンドデバイスへデータを送ろうとするとき、最初は経路が不明ですので経路発見が起動されます。つまりコーディネータからRoute Requestコマンドがブロードキャストされるわけですが、エンドデバイスはルーティング能力を持ちませんので、Route Requestコマンドを受信しても処理しません。

そのため、親デバイスのルータがエンドデバイスの代わりにRoute Requestへの応答を返さなくてはいけないことになっています。

&ref(zedrreq.png,nolink,image5);

逆にエンドデバイスからコーディネータへデータを送ることを考えてみましょう。エンドデバイスはとにかく親デバイスへ自動的にデータを送ります。しかしデータをうけとった親デバイスは数ホップ先のコーディネータへの経路を知りませんので、経路発見がここでも起動されます。コーディネータが親ルータへRoute Replyを返答することで経路が確立し、エンドデバイスとコーディネータ間の通信が成立します。

このように、非力なエンドデバイスの代わりに親ルータが一生懸命働く仕組みが、エンドデバイスの省電力化を可能にしています。単にICの消費電力が小さいというだけではないということが分かると思います。ルータってえらいですね。





*その他の機能 [#u74aab89]
これまで解説した以外にもZigBeePROは興味深い機能を数多く提供しています。そのいくつかをピックアップして紹介します。

**周波数アジリティー機能(Frequency Agility) [#k5d79638]
  
ZigBeeの周波数帯(2.4GHz)は、無線LANやBluetoothなどが共用しており、電波が干渉する可能性があります。ZigBee PROでは、通信状況を常に把握しており、干渉によって通信状況が悪くなった場合は、コーディネーターがチャンネル変更の指示を出し、干渉しないチャンネルへ移動させて、ネットワークの安定性を高めることができるようになりました。

**分割配信機能(Fragmentation) [#d95d167e]

ZigBeeは1回に最大127バイトのデータが送信可能ですが、用途(画像送信等)によっては127バイトでは小さすぎる場合もあり、「ZigBee PRO」では、127バイトより大きなデータを自動的に分割して送信し、受信側で元データに自動的に復元します。この機能により、電子証明書を送付することができ、高度なネットワークセキュリティが可能となりました。事実、フラグメンテーションはSmart Energy Profileのセキュリティ機能で使われています。

**ID コンフリクト解消機能(ID Conflict Resolution) [#ve051192]

ZigBeePROでは、1つのネットワーク内で16ビット=65565通りのアドレスをランダムに割り当てますが、万が一そのアドレスが重なってしまった場合、衝突を検出してアドレスを自ら変更することで、衝突を解決する機能が備わりました。

**メニー・トゥー・ワン機能(Many-to-one routing) [#s8c39dff]

ZigBeeでは、これまで1台ずつ経路を作る必要があったために、端末台数が多いと通信負担が大きく、たとえば、コーディネーターを中心に10台がつながっている場合は10回の経路構築が必要でした。ZigBeePROのメニー・トゥー・ワン機能は、1回の経路構築で全端末分の上り方向(コーディネータ方向)への経路が作れるようになりました。この機能を持つコーディネータを特別にコンセントレータと呼びます。

**リンク・ステータス機能(Link Status) [#v64a34dc]

一般にワイヤレス通信では、往路はOKだけど復路はNGというように、片方向だけ電波状態が悪い場合が多くあります。ZigBeePROのリンク・ステータス機能によって、往復路でそれぞれ電波状態の良い経路を選べるようになりました。

*ZigBee 3.0について [#p1e67259]

ZigBee 3.0は2014/11月にZigBee Allianceから発表され、認証済み製品が2015年から提供されはじめています。

ここではZigBeeプロトコルの観点から、3.0で何が変わったのかを紹介します。

&ref(zigbee30.jpg,nolink,image10);
(図は「Webinar_ZigBee_3-0_Launch_FINAL.pdf」P11より引用)

**ベースはZigBeePRO [#u3732973]

ZigBee3.0は後方互換性を維持しています。そのためプロトコルスタック部分で大規模な改変は特に行われていません。

ZDO, APS, NWK層以下で、フレームフォーマットの変更はなく、既存のZigBeePROとZigBee3.0デバイスは原則として相互接続できる仕様になっています。ZigBee3.0のコアプロトコルスタック部分は、ZigBeePROでいう"r21"リビジョン以降に対応します。

そのため本Wikiに書かれている内容は、ZigBee 3.0でも引き続き役に立ちます。

ZigBee 3.0で行われた主な変更点は以下の通りです。

-APS層にParent_annce/Parent_annce_respメッセージがmandatoryとして追加された
-NWK層に新規コマンドが2つ追加された
-セキュリティモデルが変更され、Standard Securityに一本化された


***ネイバーテーブルのエイジング[#vb19aa7a]

これまでのZigBeePROでは、ネイバーテーブルの内部的な管理についてあまり規定していませんでした。

特に、接続している子機(エンドデバイス)を、いつ、ルータ・コーディネータのネイバーテーブルから削除すれば良いのかの規定がなく、処理は実装依存になっていました。例えば、すでに停止して取り外されているにもかかわらず、いつまでもエンドデバイスのエントリーがルータのテーブルに残ってしまうといった現象がありました。(メモリを圧迫していしまいます)

ZigBee3.0 (ZigBeePRO r21)ではこのネイバーテーブルのメンテナンスがより詳細に規定されました。

具体的には「End Device Timeout Request」コマンドでエンドデバイスが自身のライフサイクルを親デバイスに申請し、親デバイスは「End Device Timeout Response」を応答して、その申請の許可・不許可を伝えます。

エンドデバイスの生存確認は、Poll request (MAC層のポーリング)、または「End Device Timeout Request」コマンドの周期送信で行います。

親デバイスは、これらを受信すると自身のネイバーテーブルのタイムスタンプをリフレッシュして、エンドデバイスを削除せず、保持し続けます。一定期間、上記通信がないと、離脱手順を経てエンドデバイスが親デバイスのテーブルから削除されます。


***セキュリティモデルの整理 [#q7076695]

従来のZigBeePROではHigh SecurityとStandard Securityの2種類が用意され、前者はオプション、後者が必須となっていました。High SecurityはSKKE (Symmetric-Key Key Establishment)を用いてより強固な鍵交換手順を用意していましたが、オプショナルだったためほとんど使われていません。そのためZigBee 3.0からStandard Securityに一本化されました。

Standard Securityには「Centralized」と「Distributed」の2種類のモードが用意されます。

このうち「Centralized」は、Trust Centerと呼ばれるデバイスが1つのPANに1台存在し、これがPANの暗号鍵を配布、管理する集中管理タイプで、およそコーディネータがその役割を果たします。

一方の「Distributed」は、Trust Centerがないタイプで、つまりすべてのルータがTrust Centerとして鍵の管理を行います。これは例えば鍵を予めすべてのデバイスにプリインストールしておいて、鍵の更新は都度、親デバイスとの間だけで行うような使い方が想定されています。

ZigBee3.0では、「Centralized」か「Distributed」かは利用者が選択でき、デバイスはどちらであってもネットワークを形成できるよう、両方をサポートする必要があるようです。

ただ、「Distributed」という名称は非常に複雑で高度な制御を想像させますが、規格書に詳しい記述はほとんどありません。もちろんブロックチェーンのようなメカニズムでもないです。

どちらかというと、諸事情によりTrust Centerを使わない(使えない)ZigBeeでも「セキュリティがない状態」などというのはもはや許容できないので、とりえずそういったもの全部を「Distributed」として扱っておけ、という意図が感じられます。

**Base Device Behavior [#g31227d0]

最初の図にも示した通り、ZigBee3.0には「Base Device Behavior」という新しいレイヤが、APS, ZDOと並列する形で追加されています。この「Base Device Behavior」は、ざっくり言ってしまうと「ユーザが実際に製品の箱を開けて、電源を入れて、接続して、使い始めるまでの標準的な手順」を示したガイドになります。これらを総じて「Commissioning」と呼びます。

「Base Device Behavior」では、新しいメッセージフォーマットやプロトコルレイヤが追加されているわけではありません。ZigBee PRO r21とCluster Libraryで定義されているメソッドを、「実際にどういった順序で実行して処理するか」の観点から、ユースケース毎に定義しています。

現状、Commissioningは下記4つの機能に分けて定義されます。

-Network steering
-Network formation
-Finding & binding
-Touchlink

たとえばNetwork steeringで、コーディネータは、

1) Permit Joinフラグを一定時間(bdbcMinCommissioningTime=180秒)ONにするとともに、これをMgmt_Permit_Joining_reqで同報する~
2) PAN上のルータも、同報された時間だけ接続を受け付ける状態に遷移する~
3) やがてPermit join状態が終了し、新規の接続受付は終了する~

という手順で、新規デバイスの接続を受け付けることになります。ZigBeeデバイスを新しく買ってきてコーディネータ(例えばスマートスピーカー)に接続する場合、

1) コーディネータの「セットアップ開始」ボタンを押す(あるいはなにか声で指示を出す)~
2) 上記Network steering処理が走って、PAN配下の全デバイスが接続受け入れ状態になり180秒続く~
3) その間に買ってきたデバイスの電源を入れて、接続する(この手順も「Base Device Behavior」で定義されている)~


従来、これらの動作手順は、スタック、チップセット、製品によって完全にバラバラでした。「Base Device Behavior」が定義されたことで、ユーザは、どのメーカーのZigBee製品を購入しても、似たような使い勝手で利用できるようになります。


*最後に [#mc798cf7]

本文章の文責はスカイリー・ネットワークスにあります。
書かれている内容についてZigBeeやその関連団体がなんら保証するものではありません。

ご意見、ご要望、ご指摘は「info atmark skyley.com」宛てにお寄せください。

「ZigBee」はZigBee Allianceの登録商標です。
その他の名称はそれぞれの団体または企業のトレードマークです。

Skyley Networks, Inc. all rights reserved.
http://www.skyley.com/


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS