Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。

OpenThread での Thread ネットワークのシミュレート

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

1. はじめに

26b7f4f6b3ea0700.png

Google がリリースした OpenThread は、Thread ネットワーキング プロトコルのオープンソース実装です。Google Nest は、Google Nest 製品に採用されている技術をデベロッパーが広く利用できるように、OpenThread をリリースして、スマートホーム向けの製品開発を加速させました。

Thread 仕様は、家庭用アプリケーション向けの IPv6 ベースの信頼性と安全性に優れた低電力デバイス間通信プロトコルを定義しています。OpenThread は、IPv6、6LoWPAN、IEEE 802.15.4(MAC セキュリティ、メッシュリンク確立、メッシュ ルーティング)を含むすべての Thread ネットワーク レイヤを実装しています。

この 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 Daemon をビルドします。

$ ./script/cmake-build posix -DOT_DAEMON=ON

4. Thread ネットワークをシミュレートする

この Codelab で使用するサンプル アプリケーションには、基本的なコマンドライン インターフェース(CLI)を使用して OpenThread 構成と管理インターフェースを公開する、最小限の OpenThread アプリケーションが含まれています。

この演習では、シミュレートされた別の Thread デバイスからのシミュレートされた Thread デバイスに ping を実行するために必要な最小限の手順を説明します。

次の図は、基本的な Thread ネットワーク トポロジを示しています。この演習では、緑色の円内の 2 つのノード(Thread リーダーと 1 つの接続を持つ Thread Router)をシミュレートします。

6e3aa07675f902dc.png

ノードに 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 Radio ドライバは UDP 上に実装されます(IEEE 802.15.4 フレームは UDP ペイロード内で渡されます)。

1 の引数は、ファクトリ割り当ての最下位ビットを表すファイル記述子です。シミュレートされたデバイスの IEEE EUI-64 です。この値は、IEEE 802.15.4 無線エミュレーション用の UDP ポートにバインドする際にも使用されます(ポート = 9000 + ファイル記述子)。この 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 = mesh-local
  • 先頭が fe80 = リンクローカル

メッシュローカルのアドレスタイプはさらに以下のように分類されます。

  • ff:fe00 = Router ロケーター(RLOC)を含む
  • ff:fe00 を含まない = エンドポイント識別子(EID)

コンソール出力で 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 の子は、親デバイスとのみユニキャスト トラフィックを送受信する Thread デバイスと同等です。

> state
child
Done

2 分以内に、状態が child から router に切り替わります。Thread Router は、Thread デバイス間でトラフィックをルーティングできます。「親」とも呼ばれます。

> state
router
Done

ネットワークを確認する

メッシュ ネットワークを確認するには、Router のテーブルを確認するのが簡単です。

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 の 0xa800 の RLOC がテーブルにあり、メッシュに接続されていることを確認します。

2. ノード 2 からノード 1 に 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 を停止します。

> thread stop
Done

ノード 2 に切り替えて状態を確認します。2 分以内に、ノード 2 はリーダー(ノード 1)がオフラインになったことを検出し、ノード 2 がネットワークの leader に遷移することを確認します。

> state
router
Done
...
> state
leader
Done

確認したら、Thread を停止し、終了する前にノード 2 を出荷時の設定にリセットします。この演習で使用した Thread ネットワーク認証情報が、次の演習に引き継がれるように、出荷時の設定へのリセットが行われます。

> thread stop
Done
> factoryreset
>
> exit

また、ノード 1 を出荷時の設定にリセットしてノード 1 を終了します。

> factoryreset
>
> exit

利用可能なすべての CLI コマンドを確認するには、OpenThread CLI リファレンスをご覧ください。

5. コミッショニングでノードを認証する

前の演習では、シミュレートされた 2 つのデバイスと確認済みの接続を備えた Thread ネットワークを設定します。ただし、この方法ではデバイス間の認証がされていない IPv6 リンクローカル トラフィックのみを許可できます。グローバル IPv6 トラフィックと Thread ボーダー ルーター経由のインターネット トラフィックをルーティングするには、ノードが認証されている必要があります。

認証を行うには、1 つのデバイスがコミッショナーとして機能する必要があります。コミッショナーは、新しい Thread デバイスとして現在選出されている認証サーバーであり、デバイスがネットワークに参加するために必要なネットワーク認証情報を提供する承認者でもあります。

この演習では、前と同じ 2 ノードのトポロジを使用します。認証の場合、Thread リーダーはコミッショナーとして機能し、Thread ルーターは Joiner として機能します。

d6a67e8a0d0b5dcb.png

1. ネットワークの作成

前の演習を続ける場合は、すでに 2 つのターミナル ウィンドウが開いている必要があります。オンになっていない場合は、2 台が開いていることと、使用できる状態であることを確認します。1 つはノード 1 として機能し、もう 1 つはノード 2 として機能します。

ノード 1 で CLI プロセスを生成します。

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 1

注: このコマンドの実行後に > プロンプトが表示されない場合は、enter を押します。

新しいオペレーション データセットを作成し、アクティブなデータセットとして commit して、Thread を起動します。

> 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 ジョイナー認証情報を持つ任意のジョイナーを(* ワイルドカードを使用して)ネットワークへの commit を許可します。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 インスタンス(単一の埋め込み SoC スレッド デバイス)と 1 つの Radio Co-Processor(RCP)インスタンスをシミュレートします。

ot-daemon は、OpenThread Posix アプリのモードの 1 つで、UNIX ソケットを入力と出力として使用するため、OpenThread コアがサービスとして実行できるようになります。クライアントは、OpenThread CLI をプロトコルとして使用してソケットに接続することで、このサービスと通信できます。

ot-ctl は、RCP を管理および構成するために ot-daemon によって提供される CLI です。これを使用して、RCP を Thread デバイスによって作成されたネットワークに接続します。

ot-daemon を使用する

この演習では、次のものに対応する 3 つのターミナル ウィンドウを使用します。

  1. シミュレートされた Thread デバイスの CLI インスタンス(ノード 1)
  2. ot-daemonのプロセス
  3. ot-ctl CLI インスタンス

前の演習を続けると、すでに 2 つのターミナル ウィンドウが開いているはずです。3 分の 1 を開いて、この演習用に 3 つのターミナル ウィンドウがあることを確認します。

1. ノード 1 を起動します

最初のターミナル ウィンドウで、シミュレートされた Thread デバイスの CLI プロセスを生成します。

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 1

注: このコマンドの実行後に > プロンプトが表示されない場合は、enter を押します。

新しいオペレーション データセットを作成し、アクティブなデータセットとして commit して、Thread を起動します。

> 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 の Thread インターフェースに割り当てられた 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
>

スレッド ネットワークをシミュレートするで説明したように、1 つのアドレスはリンクローカル(fe80)で、3 つのメッシュはメッシュローカル(fd)です。EID は、メッシュのローカルアドレスで、ff:fe00 をアドレスに含めません。このサンプル出力では、EID は fd55:cf34:dea5:7994:460:872c:e807:c4ab です。

ipaddr 出力から特定の EID を特定します。この EID は、ノードとの通信に使用されます。

2. ot-daemon を起動します。

第 2 のターミナル ウィンドウで openthread ディレクトリに移動し、ノード 2 と呼ばれる RCP ノードの ot-daemon を起動します。詳細出力フラグ -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 ノードを制御できます。

第 3 のターミナル ウィンドウで、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 インスタンスがスレッド ネットワークに正常に参加してスレッド ネットワークと通信すると、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 ネットワークを管理する

詳細は、次のリファレンスをご覧ください。