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

OpenThread を使用したスレッド ネットワークのシミュレーション

1. はじめに

26b7f4f6b3ea0700.png

Google がリリースする OpenThread は、Thread ネットワーク プロトコルをオープンソースで実装したものです。Google Nest は OpenThread をリリースし、Nest 製品に使用されるテクノロジーを、スマートホーム製品の開発を加速化するためにデベロッパーが幅広く利用できるようにしました。

スレッド仕様は、IPv6 ベースの安全かつ低消費電力のデバイス間通信プロトコルをホーム アプリケーション用に定義したものです。OpenThread は、IPv6、6LoWPAN、IEEE 802.15.4 など、すべての Thread ネットワーク レイヤを MAC セキュリティ、メッシュリンク確立、メッシュ ルーティングとともに実装します。

この Codelab では、シミュレートされたデバイスでスレッド ネットワークをシミュレートする方法について説明します。

学習内容

  • OpenThread ビルド ツールチェーンの設定方法
  • スレッド ネットワークをシミュレートする方法
  • スレッドノードを認証する方法
  • OpenThread Daemon でスレッド ネットワークを管理する方法

必要なもの

  • git
  • Linux、ネットワーク ルーティングの基本的な知識

2. ビルドシステムを設定する

Git

この Codelab を完了するには Git が必要です。続行する前に、ライブラリをダウンロードしてインストールしてください。

インストールが完了したら、お使いの OS の手順に沿って OpenThread をダウンロードし、ビルドします。

Mac OS X 版 XCode

OpenMac を Mac OS X でインストールしてビルドするには、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
$ make -f examples/Makefile-simulation

次に、OpenThread デーモンをビルドします。

$ cd ~/src/openthread
$ make -f src/posix/Makefile-posix DAEMON=1

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

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

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

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

6e3aa07675f902dc.png

ノードに ping を実行する

1. ノード 1 の起動

openthread ディレクトリに移動し、ot-cli-ftd バイナリを使用してシミュレートされた Thread デバイスの CLI プロセスを生成します。

$ cd ~/src/openthread
$ ./output/simulation/bin/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 のシミュレートされたスレッド デバイスの各インスタンスは、異なるファイル記述子を使用します。

注: この Codelab に記載されているとおり、1 以上のファイル記述子は、シミュレートされたデバイスのプロセスを生成する場合にのみ使用してください。0 のファイル記述子は他の用途のために予約されています。

新しいオペレーション データセットを作成し、アクティブ データセットとして commit します。オペレーション データセットは、作成するスレッド ネットワークの構成です。

> 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 start
Done

数秒待ってから、デバイスがスレッド リーダーになったことを確認します。リーダーは、ルーター 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 = リンクローカルで始まる

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

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

後で使用できるように、コンソール出力で EID をメモしておきます。上記の出力例では、EID は次のようになります。

fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6

2. ノード 2 を起動する

新しいターミナルを開き、openthread ディレクトリに移動して、CLI プロセスを生成します。シミュレートされた 2 つ目の Thread デバイスは次のとおりです。

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 2

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

ノード 1 のオペレーション データセットと同じ値を使用して、スレッド ネットワーク キーと PAN ID を構成します。

> dataset networkkey e4344ca17d1dca2a33f064992f31f786
Done
> dataset panid 0xc169
Done

このデータセットをアクティブなデータセットとして commit します。

> dataset commit active
Done

IPv6 インターフェースを表示します。

> ifconfig up
Done

スレッド プロトコル オペレーションを開始します。

> thread start
Done

デバイスは自動的に子として初期化されます。スレッド子はエンドデバイスと同義です。エンドデバイスは、親デバイスでのみユニキャスト トラフィックを送受信するスレッド デバイスです。

> state
child
Done

2 分以内に、child から router への状態の切り替えが表示されます。スレッド ルーターは、スレッドデバイス間でトラフィックをルーティングできます。「親」とも呼ばれます。

> 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 の 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 stop
Done

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

> state
router
Done
...
> state
leader
Done

確認したら、スレッドを停止してノード 2 を出荷時の設定にリセットしてから終了します。この演習で使用した Thread ネットワークの認証情報が次の演習に継承されないようにするには、出荷時の設定にリセットします。

> thread stop
Done
> factoryreset
>
> exit

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

> factoryreset
>
> exit

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

5. コミッショニングを使用してノードを認証する

前の演習では、2 つのシミュレートされたデバイスを使用してスレッド ネットワークを設定し、接続を確認しました。ただし、認証されていない IPv6 リンクローカル トラフィックはデバイス間でしか受け渡しできません。グローバル IPv6 トラフィックを(VPC と Thread Border Router を介してインターネット間で)ルーティングするには、ノードを認証する必要があります。

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

この演習では、以前と同じ 2 ノードのトポロジを使用します。認証において、スレッド リーダーはコミッター、スレッドルーター、ジョインターとして機能します。

d6a67e8a0d0b5dcb.png

1. ネットワークの作成

前の演習から続行する場合、すでに 2 つのターミナル ウィンドウが開いているはずです。対応していない場合は、2 種類が使用可能であり、使用できる状態であることを確認してください。1 つはノード 1、もう 1 つはノード 2 として機能します。

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

$ cd ~/src/openthread
$ ./output/simulation/bin/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 start
Done

数秒待ってから、デバイスがスレッド リーダーになったことを確認します。

> state
leader
Done

2. コミッショナーの役割を開始する

ノード 1 で、コミッサー ロールを開始します。

> commissioner start
Done

* ワイルドカードを使用する J01NME いずれかの Joiner 認証情報が Networker へのコミッションを許可します。Joiner は、委託したスレッド ネットワークに人間の管理者が追加するデバイスです。

> commissioner joiner add * J01NME
Done

3. 参加者ロールを開始する

2 つ目のターミナル ウィンドウで、新しい CLI プロセスを生成します。これは Node 2 です。

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 2

ノード 2 で、J01NME Joiner Credentials を使用して Joiner のロールを有効にします。

> ifconfig up
Done
> joiner start J01NME
Done

... 数秒待ってから確認します ...

Join success

加入者として、デバイス(ノード 2)がコミッショナー(ノード 1)と正常に認証され、スレッド ネットワーク認証情報を受信しました。

ノード 2 が認証されたので、スレッドを起動します。

> thread start
Done

4.ネットワーク認証を検証する

ノード 2 の state をチェックし、ネットワークに接続されたことを確認します。2 分以内にノード 2 が child から router に移行します。

> state
child
Done
...
> state
router
Done

5. 設定をリセット

次の演習を準備するために、構成をリセットします。各ノードでスレッドを停止し、出荷時の設定にリセットして、シミュレートされたスレッド デバイスを終了します。

> thread stop
Done
> factoryreset
>
> exit

factoryreset コマンドの後に > プロンプトを元に戻すには、enter を数回押す必要があります。

6. OpenThread Daemon でネットワークを管理する

この演習では、1 つの CLI インスタンス(1 つの組み込み SoC スレッド デバイス)と 1 つの無線コプロセッサ(RCP)インスタンスをシミュレートします。

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

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

ot-daemon を使用する

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

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

前の演習から続行する場合、すでに 2 つのターミナル ウィンドウが開いているはずです。3 つ目のデバイスを開いて、この演習に使用できるターミナル ウィンドウが 3 つあることを確認します。

1. ノード 1 の起動

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

$ cd ~/src/openthread
$ ./output/simulation/bin/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 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
>

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

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

2. ot-daemon の起動

2 番目のターミナル ウィンドウで、openthread ディレクトリに移動し、RCP ノードの ot-daemon を開始します。ここでは、Node 2 とします。-v 詳細フラグを使用すると、ログ出力を表示して実行中かどうかを確認できます。

$ cd ~/src/openthread
$ ./output/posix/bin/ot-daemon -v \
    'spinel+hdlc+forkpty://output/simulation/bin/ot-rcp?forkpty-arg=2'

成功すると、詳細モードの ot-daemon によって次のような出力が生成されます。

ot-daemon[228024]: Running OPENTHREAD/20191113-00831-gfb399104; POSIX; Jun 7 2020 18:05:15
ot-daemon[228024]: Thread version: 2
ot-daemon[228024]: RCP version: OPENTHREAD/20191113-00831-gfb399104; SIMULATION; Jun 7 2020 18:06:08

このターミナルはバックグラウンドで開いたままにしてください。これ以上はコマンドを入力しません。

3. ot-ctl を使用してネットワークに参加する

ノード 2(ot-daemon RCP)はまだスレッド ネットワークに委任されていません。そこで ot-ctl の出番です。ot-ctl は OpenThread CLI アプリと同じ CLI を使用します。したがって、他のシミュレートされた Thread デバイスと同じように、ot-daemon ノードを制御できます。

3 つ目のターミナル ウィンドウで、ot-ctl を開始します。

$ ./output/posix/bin/ot-ctl
>

この 3 つ目のターミナル ウィンドウで ot-ctl を使用して、2 つ目のターミナル ウィンドウで ot-daemon から開始したノード 2(RCP ノード)を管理します。ノード 2 の state を確認します。

> state
disabled
Done

ノード 2 の eui64 を取得して、特定の Joiner に対する参加を制限します。

> eui64
18b4300000000001
Done

ノード 1(1 つ目のターミナル ウィンドウ)で Commissioner を起動し、該当する eui64 にのみコミッショニングを制限します。

> commissioner start
Done
> commissioner joiner add 18b4300000000001 J01NME
Done

ノード 2(3 つ目のターミナル ウィンドウ)でネットワーク インターフェースを起動し、ネットワークに接続します。

> ifconfig up
Done
> joiner start J01NME
Done

... 数秒待ってから確認します ...

Join success

参加ユーザーは、RCP(ノード 2)がコミッショナー(ノード 1)から認証を受け、スレッド ネットワーク認証情報を受信しました。

次に、ノード 2 を Thread ネットワークに参加させます。

> thread start
Done

4.ネットワーク認証を検証する

ノード 2 の state をチェックし、ネットワークに接続されたことを確認します。2 分以内にノード 2 が child から router に移行します。

> state
child
Done
...
> state
router
Done

5. 接続の検証

Ctrl+D キーで ot-ctl を終了し、ホストマシンのコマンドラインで Node 1 に ping を実行して、ping6 で EID を使用します。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 を使用して最初のスレッド ネットワークをシミュレーションできました。お疲れさまでした。

この Codelab では、以下について学びました。

  • OpenThread ビルド ツールチェーンを設定する
  • スレッド ネットワークをシミュレートする
  • スレッドノードを認証する
  • OpenThread Daemon で Thread ネットワークを管理する

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