1. はじめに
Google がリリースした OpenThread は、Thread ネットワーク プロトコルのオープンソース実装です。Google Nest は、Google Nest 製品で使用されている技術を広くデベロッパーに提供し、スマートホーム製品の開発を加速させるために、OpenThread をリリースしました。
Thread 仕様は、ホーム アプリケーション向けの、IPv6 ベースの、信頼性が高く、安全で、低電力のワイヤレス デバイス間通信プロトコルを定義しています。OpenThread は、IPv6、6LoWPAN、IEEE 802.15.4 を含むすべての Thread ネットワーク レイヤ、MAC セキュリティ、メッシュリンクの確立、メッシュ ルーティングを実装します。
この Codelab では、シミュレートしたデバイスで Thread ネットワークをシミュレートする方法について説明します。
学習内容
- OpenThread ビルド ツールチェーンの設定方法
- Thread ネットワークをシミュレートする方法
- Thread ノードを認証する方法
- OpenThread Daemon を使用して Thread ネットワークを管理する方法
必要なもの
- git
- Linux、ネットワーク ルーティングの基礎知識
2. ビルドシステムをセットアップする
Git
この Codelab を完了するには Git が必要です。続行する前にダウンロードしてインストールしてください。
インストールが完了したら、お使いの OS の手順に沿って OpenThread をダウンロードしてビルドします。
Mac OS X 向け XCode
Mac OS X に OpenThread をインストールしてビルドするには XCode が必要です。
XCode をインストールしたら、XCode コマンドライン ツールをインストールします。
$ xcode-select --install
Linux / Mac OS X でビルドする場合
これらのインストール手順は、Ubuntu Server 14.04 LTS と Mac OS X Sierra 10.12.6 でテスト済みです。
OpenThread をインストールします。bootstrap
コマンドにより、ツールチェーンがインストールされ、環境が正しく構成されていることを確認します。
$ mkdir -p ~/src $ cd ~/src $ git clone --recursive https://github.com/openthread/openthread.git $ cd openthread $ ./script/bootstrap $ ./bootstrap
Windows の場合
Windows をお使いの場合は、この Codelab の Docker 版をお試しください。
3. OpenThread アプリケーションをビルドする
インストールが完了したら、サンプルの OpenThread アプリケーションをビルドします。この Codelab では、シミュレーションの例を使用します。
$ cd ~/src/openthread $ ./script/cmake-build simulation
次に、OpenThread デーモンを構築します。
$ ./script/cmake-build posix -DOT_DAEMON=ON
4. Thread ネットワークをシミュレートする
この Codelab で使用するサンプル アプリケーションは、基本的なコマンドライン インターフェース(CLI)を介して OpenThread 構成と管理インターフェースを公開する、最小限の OpenThread アプリケーションのデモを行います。
この演習では、シミュレートした別の Thread デバイスからシミュレートした Thread デバイスに対して ping を実行するために必要な最小手順について説明します。
次の図は、Thread の基本的なネットワーク トポロジを示しています。この演習では、緑色の丸で囲まれた 2 つのノード(Thread Leader と Thread Router 間)をシミュレーションします。
ノードに ping する
1. ノード 1 を起動します
openthread
ディレクトリに移動し、ot-cli-ftd
バイナリを使用してシミュレートされた Thread デバイスに対する CLI プロセスを生成します。
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
このバイナリは、POSIX の上にシミュレートされた OpenThread デバイスを実装します。IEEE 802.15.4 無線ドライバは UDP 上に実装されます(IEEE 802.15.4 フレームは UDP ペイロードで渡されます)。
1
の引数は、シミュレートされたデバイスの「ファクトリ割り当て」された IEEE EUI-64 の最下位ビットを表すファイル記述子です。この値は、IEEE 802.15.4 無線エミュレーション(ポート = 9000 + ファイル記述子)の UDP ポートにバインドする場合にも使用されます。この Codelab のシミュレートされた Thread デバイスのインスタンスでは、それぞれ異なるファイル記述子を使用します。
注: この Codelab で説明したように、1
以上のファイル記述子は、シミュレートされたデバイスのプロセスを生成する場合にのみ使用してください。0
のファイル記述子は他の用途用に予約されています。
新しいオペレーショナル データセットを作成し、アクティブなデータセットとして commit します。オペレーショナル データセットは、作成する Thread ネットワークの構成です。
> dataset init new Done > dataset Active Timestamp: 1 Channel: 20 Channel Mask: 07fff800 Ext PAN ID: d6263b6d857647da Mesh Local Prefix: fd61:2344:9a52:ede0/64 Network Key: e4344ca17d1dca2a33f064992f31f786 Network Name: OpenThread-c169 PAN ID: 0xc169 PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4 Security Policy: 0, onrcb Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
数秒待ってから、デバイスが Thread リーダーになりました。リーダーは、ルーター ID の割り当てを管理するデバイスです。
> state leader Done
ノード 1 のスレッド インターフェースに割り当てられた IPv6 アドレスを表示します(出力は異なります)。
> ipaddr fd61:2344:9a52:ede0:0:ff:fe00:fc00 fd61:2344:9a52:ede0:0:ff:fe00:5000 fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 fe80:0:0:0:94da:92ea:1353:4f3b Done
特定の IPv6 アドレスの種類に注意してください。
- 先頭が
fd
= メッシュローカル fe80
= link-local で始まる
メッシュローカルのアドレスタイプはさらに分類されます。
ff:fe00
= Router ロケーター(RLOC)を含む- 次を含まない:
ff:fe00
= エンドポイント識別子(EID)
コンソール出力で EID を特定し、後で使用するためにメモしておきます。上の出力例の EID は次のとおりです。
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. ノード 2 を起動します。
新しいターミナルを開いて、openthread
ディレクトリに移動し、CLI プロセスを生成します。シミュレーションした 2 つ目の Thread デバイスは次のとおりです。
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 2
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
ノード 1 の運用データセットと同じ値を使用して、Thread ネットワーク キーと PAN ID を構成します。
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
デバイスは自身を子として初期化します。Thread Child は、親デバイスとのみユニキャスト トラフィックを送受信する Thread デバイスに相当します。
> state child Done
2 分以内に、状態が child
から router
に切り替わります。Thread ルーターは、Thread デバイス間でトラフィックをルーティングできます。保護者とも呼ばれます。
> state router Done
ネットワークを確認する
ルーター ネットワークを確認すると、メッシュ ネットワークを簡単に確認できます。
1. 接続を確認する
ノード 2 で RLOC16 を取得します。RLOC16 は、デバイスの RLOC IPv6 アドレスの最後の 16 ビットです。
> rloc16 5800 Done
ノード 1 のルーター テーブルでノード 2 の RLOC16 を確認します。ノード 2 がルーターの状態に切り替わっていることを確認します。
> router table | ID | RLOC16 | Next Hop | Path Cost | LQI In | LQI Out | Age | Extended MAC | +----+--------+----------+----------+-------+---------+-----+------------------+ | 20 | 0x5000 | 63 | 0 | 0 | 0 | 0 | 96da92ea13534f3b | | 22 | 0x5800 | 63 | 0 | 3 | 3 | 23 | 5a4eb647eb6bc66c |
表にノード 1 の RLOC 0xa800
があり、それがメッシュに接続されていることを確認しました。
2. ノード 1 からノード 2 に対して ping を実行する
シミュレートされた 2 つの Thread デバイス間の接続を検証します。ノード 2 で、ノード 1 に割り当てられた EID を次のように作成します。ping
> ping fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 > 16 bytes from fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6: icmp_seq=1 hlim=64 time=12ms
enter
を押すと、>
CLI のプロンプトに戻ります。
ネットワークをテストする
シミュレートされた 2 つの Thread デバイス間で正常に ping が通ったので、1 つのノードをオフラインにしてメッシュ ネットワークをテストします。
ノード 1 に戻ってスレッドを停止します。
> thread stop Done
ノード 2 に切り替えて、状態を確認します。2 分以内にノード 2 によってリーダー(ノード 1)がオフラインであることが検出され、ノード 2 がネットワークの leader
に切り替わるはずです。
> state router Done ... > state leader Done
確認したら、Thread を停止し、ノード 2 を出荷時の設定にリセットしてから終了します。この演習で使用した Thread ネットワーク認証情報が次の演習に引き継がれるように、出荷時設定にリセットされています。
> thread stop Done > factoryreset > > exit
また、ノード 1 を出荷時の設定にリセットして終了します。
> factoryreset > > exit
利用可能なすべての CLI コマンドについては、OpenThread CLI リファレンスをご覧ください。
5. コミッショニングでノードを認証する
前の演習では、シミュレートされた 2 つのデバイスと確認済みの接続を備えた Thread ネットワークをセットアップしました。ただし、これでデバイス間で未認証の IPv6 リンクローカル トラフィックしか通過できなくなります。ノード間(および Thread ボーダー ルーター経由のインターネット)でグローバル IPv6 トラフィックをルーティングするには、ノードを認証する必要があります。
認証するには、1 台のデバイスがコミッショナーとして機能する必要があります。コミッショナーは、現在選択されている新しい Thread デバイス用の認証サーバーであり、デバイスがネットワークに接続するために必要なネットワーク認証情報を提供する承認者です。
この演習では、前と同じ 2 ノードのトポロジを使用します。Thread リーダーは認証の際、コミッショナーとして機能し、Thread Router は Joiner として機能します。
1. ネットワークの作成
前の演習から続行する場合は、すでに 2 つのターミナル ウィンドウが開いているはずです。2 つとも開いていない場合は、2 つを開いて開いていることを確認します。1 つはノード 1 として、もう 1 つはノード 2 として機能します。
ノード 1 で CLI プロセスを生成します。
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
新しいオペレーショナル データセットを作成し、それをアクティブなデータセットとして commit して、スレッドを開始します。
> dataset init new Done > dataset Active Timestamp: 1 Channel: 12 Channel Mask: 07fff800 Ext PAN ID: e68d05794bf13052 Mesh Local Prefix: fd7d:ddf7:877b:8756/64 Network Key: a77fe1d03b0e8028a4e13213de38080e Network Name: OpenThread-8f37 PAN ID: 0x8f37 PSKc: f9debbc1532487984b17f92cd55b21fc Security Policy: 0, onrcb Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
数秒待ってから、デバイスが Thread リーダーになったことを確認します。
> state leader Done
2. コミッショナーのロールを開始する
ノード 1 で、コミッショナーのロールを開始します。
> commissioner start Done
J01NME
ジョイナー認証情報を持つ任意のジョイナーが、*
ワイルドカードを使用してネットワークへのコミッションを許可します。Joiner は、人間が管理者によって追加された Thread ネットワークに追加されるデバイスです。
> commissioner joiner add * J01NME Done
3. Joiner のロールを開始する
第 2 のターミナル ウィンドウで、新しい CLI プロセスを生成します。これはノード 2 です。
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 2
ノード 2 で、J01NME
Joiner Credential を使用して Joiner ロールを有効にします。
> ifconfig up Done > joiner start J01NME Done
... 確認されるまで数秒お待ちください ...
Join success
Joiner として、デバイス(ノード 2)はコミッショナー(ノード 1)で自己認証され、Thread ネットワーク認証情報を受信しました。
ノード 2 が認証されたら、Thread を起動します。
> thread start Done
4. ネットワーク認証を検証する
ノード 2 の state
で、ネットワークに接続されたことを確認します。ノード 2 は 2 分以内に child
から router
に移行します。
> state child Done ... > state router Done
5. 構成をリセット
次の演習の準備として、構成をリセットします。各ノードで、Thread を停止し、出荷時の設定にリセットして、シミュレートされた Thread デバイスを終了します。
> thread stop Done > factoryreset > > exit
factoryreset
コマンドの後に >
プロンプトに戻るには、enter
を数回押す必要がある場合があります。
6. OpenThread Daemon を使用してネットワークを管理する
この演習では、1 つの CLI インスタンス(1 つの組み込み SoC スレッド デバイス)と 1 つの Radio Co-Processor(RCP)インスタンスをシミュレートします。
ot-daemon
は、OpenThread Posix アプリのモードであり、UNIX ソケットを入力および出力として使用するため、OpenThread コアはサービスとして実行できます。クライアントは、OpenThread CLI をプロトコルとして使用してソケットに接続することで、このサービスと通信できます。
ot-ctl
は、RCP を管理および構成するために ot-daemon
によって提供される CLI です。これを使用して、RCP が Thread デバイスによって作成されたネットワークに接続されます。
ot-daemon を使用する
この演習では、次の 3 つのターミナル ウィンドウを使用します。
- シミュレートされた Thread デバイスの CLI インスタンス(ノード 1)
ot-daemon
プロセスot-ctl
CLI インスタンス
前の演習から続けると、すでに 2 つのターミナル ウィンドウが開いているはずです。1/3 を開いて、この演習に使用できるターミナル ウィンドウが 3 つあることを確認します。
1. ノード 1 を起動します
最初のターミナル ウィンドウで、シミュレートされた Thread デバイスに対して CLI プロセスを生成します。
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
新しいオペレーショナル データセットを作成し、それをアクティブなデータセットとして commit して、スレッドを開始します。
> dataset init new Done > dataset Active Timestamp: 1 Channel: 13 Channel Mask: 07fff800 Ext PAN ID: 97d584bcd493b824 Mesh Local Prefix: fd55:cf34:dea5:7994/64 Network Key: ba6e886c7af50598df1115fa07658a83 Network Name: OpenThread-34e4 PAN ID: 0x34e4 PSKc: 38d6fd32c866927a4dfcc06d79ae1192 Security Policy: 0, onrcb Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done
Thread プロトコル オペレーションを開始します。
> thread start Done
ノード 1 のスレッド インターフェースに割り当てられた IPv6 アドレスを表示します。
> ipaddr fd55:cf34:dea5:7994:0:ff:fe00:fc00 fd55:cf34:dea5:7994:0:ff:fe00:d000 fd55:cf34:dea5:7994:460:872c:e807:c4ab fe80:0:0:0:9cd8:aab6:482f:4cdc Done >
Thread ネットワークをシミュレートするのステップで説明したように、1 つのアドレスはリンクローカル(fe80
)で、3 つのアドレスはメッシュローカル(fd
)です。EID は、アドレスに ff:fe00
を含まないメッシュローカル アドレスです。このサンプル出力では、EID は fd55:cf34:dea5:7994:460:872c:e807:c4ab
です。
ipaddr
出力から特定の EID を特定します。この EID は、ノードとの通信に使用されます。
2. ot-daemon を起動する
第 2 のターミナル ウィンドウで openthread
ディレクトリに移動し、RCP ノードの ot-daemon
を起動します。これをノード 2 と呼びます。-v
詳細フラグを使用すると、ログ出力を表示してログが実行中であることを確認できます。また、sudo
を使用してください。
$ cd ~/src/openthread $ sudo ./build/posix/src/posix/ot-daemon -v \ 'spinel+hdlc+forkpty://build/simulation/examples/apps/ncp/ot-rcp?forkpty-arg=2'
成功すると、詳細モードの ot-daemon
では次のような出力が生成されます。
ot-daemon[12463]: Running OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; POSIX; Aug 30 2022 10:55:05 ot-daemon[12463]: Thread version: 4 ot-daemon[12463]: Thread interface: wpan0 ot-daemon[12463]: RCP version: OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; SIMULATION; Aug 30 2022 10:54:10
このターミナルは開いたまま、バックグラウンドで実行したままにします。コマンドは入力しません。
3. ot-ctl を使用してネットワークに接続する
まだノード 2(ot-daemon
RCP)をどの Thread ネットワークにもコミッショニングしていません。ここで ot-ctl
の出番です。ot-ctl
は OpenThread CLI アプリと同じ CLI を使用するため、シミュレートされた他の Thread デバイスと同じ方法で ot-daemon
ノードを制御できます。
第三のターミナル ウィンドウで、ot-ctl
を起動します。
$ sudo ./build/posix/src/posix/ot-ctl >
注: このコマンドを実行した後に >
のプロンプトが表示されない場合は、enter
を押します。
この 3 つ目のターミナル ウィンドウで ot-ctl
を使用し、2 つ目のターミナル ウィンドウで ot-daemon
を使用して開始したノード 2(RCP ノード)を管理します。ノード 2 の state
を確認します。
> state disabled Done
ノード 2 の eui64
を取得して、参加を特定の Joiner に制限します。
> eui64 18b4300000000001 Done
ノード 1(最初のターミナル ウィンドウ)で、コミッショナーを起動して参加をその eui64 のみに制限します。
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
ノード 2(第 3 のターミナル ウィンドウ)で、ネットワーク インターフェースを起動してネットワークに接続します。
> ifconfig up Done > joiner start J01NME Done
... 確認されるまで数秒お待ちください ...
Join success
Joiner として、RCP(ノード 2)はコミッショナー(ノード 1)で自己認証され、Thread ネットワーク認証情報を受信しました。
次に、ノード 2 を Thread ネットワークに接続します。
> thread start Done
4. ネットワーク認証を検証する
ノード 2 の state
で、ネットワークに接続されたことを確認します。ノード 2 は 2 分以内に child
から router
に移行します。
> state child Done ... > state router Done
5. 接続の検証
Ctrl+D または exit
コマンドを使用して ot-ctl
を終了し、ホストマシンのコマンドラインでノード 1 に対して EID を使用して ping6
コマンドを実行するot-daemon
RCP インスタンスが正常に Thread ネットワークに参加して通信している場合、ping は成功します。
$ ping6 -c 4 fd55:cf34:dea5:7994:460:872c:e807:c4ab PING fd55:cf34:dea5:7994:460:872c:e807:c4ab (fd55:cf34:dea5:7994:460:872c:e807:c4ab): 56 data bytes 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=0 ttl=64 time=4.568 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=1 ttl=64 time=6.396 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=2 ttl=64 time=7.594 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=3 ttl=64 time=5.461 ms --- fd55:cf34:dea5:7994:460:872c:e807:c4ab ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 4.568/6.005/7.594/1.122 ms
7. 完了
OpenThread を使用して最初の Thread ネットワークが正常にシミュレートされました。でも使用できます。
この Codelab では、以下について学びました。
- OpenThread ビルド ツールチェーンを設定する
- Thread ネットワークをシミュレートする
- Thread ノードを認証する
- OpenThread Daemon を使用して Thread ネットワークを管理する
詳しくは、以下の資料をご覧ください。