OTNS を使用してスレッド ネットワークをシミュレートする

この Codelab について
schedule30 分
subject最終更新: 2025年7月25日
account_circle作成者: Simon Lin, Colin Tan, Esko Dijk

1. はじめに

Thread メッシュ ネットワーク トポロジのイメージ

Thread と OTNS とは

Thread は、デバイス間およびデバイスとクラウド間の安全な通信を可能にする、IP ベースの低消費電力ワイヤレス メッシュ ネットワーキング プロトコルです。Thread ネットワークは、トポロジの変更に適応して単一障害点を回避できます。

Google がリリースした OpenThread は、Thread のオープンソース実装です。OpenThread は、コードサイズとメモリ フットプリントが小さいにもかかわらず、Thread 仕様で定義されているすべての機能をサポートしています。

OpenThread Network Simulator(OTNS)は、posix プラットフォームでシミュレートされた OpenThread ノードを実行して Thread ネットワークをシミュレートするために使用できます。OTNS は、シミュレートされた Thread ネットワークを可視化して操作するための使いやすいウェブ インターフェース(OTNS-Web)を提供します。スクリプトによるシミュレーション(Python を使用)も可能です。

学習内容

  • OTNS とその依存関係をインストールする
  • OTNS-CLI の基本を知る
  • OTNS-Web で OpenThread ノードを追加、移動、削除する方法
  • OTNS-Web のその他の便利な機能を使用してネットワーク シミュレーションを制御する
  • OpenThread の単一障害点がないことを確認する
  • Wireshark で OpenThread ノード間のデータ トラフィックを確認する

この Codelab では、インタラクティブな使用を目的とした OTNS-CLI と OTNS-Web に焦点を当てています。Python スクリプトなどの OTNS の他の機能については説明しません。

必要なもの

  • スレッドの概要。この Codelab で説明する内容を理解するには、スレッドの基本的なコンセプトを理解しておく必要があります。
  • Linux x86_64 または Homebrew を使用した Mac OS が望ましい。Windows WSL2 の Ubuntu バージョン 24 以降も動作しますが、設定を手動で調整する必要がある場合があります。
  • Git
  • ウェブブラウザ。OTNS-Web は、シミュレーションの表示にウェブブラウザを使用します。
  • Wireshark ネットワーク プロトコル アナライザ(省略可)。
  • Go バージョン 1.23 以降。
    • インストール スクリプトは、インストールされている Go のバージョンを確認します。
    • Go がインストールされていない場合は、パッケージ マネージャーから入手可能なバージョン >= 1.23 がインストールされます。
    • パッケージ マネージャーから入手できない場合は、手動インストールが必要です。
    • Ubuntu 24.04 以前では、Go 1.23 は自動的にサポートされません。詳細については、Ubuntu ドキュメントの Available Golang versions ページをご覧ください。snap を使用した手動インストールやその他の手順も可能です。
  • Python バージョン 3.9 以降。
    • インストール スクリプトは、インストールされている Python のバージョンを確認します。
    • Python 3 がまだインストールされていない場合は、パッケージ マネージャーから入手可能なバージョン >= 3.9 がインストールされます。
    • パッケージ マネージャーから入手できない場合は、手動インストールが必要です。

用語

「ルーター」という用語は、当初 Thread ルーターと呼ばれていた Thread メッシュ エクステンダの技術用語として使用されています。「ノード」とは、OTNS シミュレーション内のシミュレートされた OpenThread デバイスを指します。

2. インストール

OTNS コードを取得する

$ git clone https://github.com/openthread/ot-ns.git ./otns
$ cd otns

この Codelab の以降のコンソール コマンドはすべて、otns ディレクトリから実行します。

ブートストラップとインストール

bootstrap スクリプトは、依存関係(必要に応じて Python 3 や Go/Golang など)をインストールし、OTNS をインストールします。Python バージョン 3.9 以降や Go バージョン 1.23 以降など、特定の依存関係を自動的にインストールできない場合、スクリプトが停止することがあります。自動インストールでは、パッケージがオペレーティング システムの構成済みパッケージ リポジトリに存在する必要があります。

また、シミュレーションで直接使用できるさまざまな OT ノードタイプをビルドし、基本的なテストを実行します。これらのノードビルドのため、数分かかることがあります。

$ ./script/bootstrap
....
....
OTNS installed - use 'otns' to start it.
$

スクリプトの実行中に sudo のパスワードの入力を求められることがあります。

otns が正しくインストールされていない場合

スクリプトで次のようなエラーが報告されることがあります。

....
OTNS installed - please add ~/go/bin to your PATH variable first, to use it.
$

この場合は、$PATH 変数に $(go env GOPATH)/bin を追加する必要があります。

その他のエラーが発生した場合は、GitHub の問題を作成できます。

3. OTNS を初めて実行する

otns を実行します。

$ otns
>_ ← OTNS-CLI prompt

正常に起動すると、OTNS は CLI コンソール(OTNS-CLI)に入り、ネットワークの可視化と管理用のウェブブラウザ(OTNS-Web)を起動します。

OTNS-Web ウィンドウ(起動時)

OTNS-Web で空白のページしか表示されない場合は、ブラウザで WebGL が有効になっていない可能性があります。WebGL を有効にする方法については、 https://superuser.com/a/836833 をご覧ください。

以降のセクションでは、OTNS-CLIOTNS-Web を使用して OTNS シミュレーションを管理する方法について説明します。

4. OTNS-CLI と OTNS-Web の概要

OTNS-CLI

OTNS-CLI は、OTNS シミュレーションを管理するためのコマンドライン インターフェース(CLI)です。

$ otns
>_ ← OTNS-CLI prompt

OTNS-CLI を使用してコマンドを入力できます。コマンドの完全なリストについては、OTNS CLI リファレンスをご覧ください。この Codelab で使用するコマンドはごく一部なので、ご安心ください。

CLI コマンドの概要については、help コマンドを入力します。このリストは CLI リファレンスと同じです。

> help
add             Add a node to the simulation and get the node ID.
....
....
Done
> 

特定のコマンドの詳細なヘルプを表示するには、コマンド名を使用します。次に例を示します。

> help add
add
  Add a node to the simulation and get the node ID.
  
Definition:
....
....
> 

OTNS-Web

OTNS-Web は、OTNS のネットワークの可視化と管理のツールです。シミュレートされた Thread ネットワークのノード、メッセージ、リンクを視覚的に表現します。OTNS-Web のさまざまな要素に注目してください。

OTNS-Web の要素について

5. ノードを追加する

OTNS-CLI を使用してノードを追加する

シミュレーションに Thread ルーターを追加します。

> add router
1
Done

OTNS-Web に作成されたノードが表示されます。ノードはルーターとして起動し、数秒後にリーダーになります。

リーダーロールのノードが 1 つ

シミュレーションをインタラクティブに簡単に開始できるように、新しい OpenThread ノードはデフォルトで標準のネットワーク パラメータ セットでコミッショニングされます。

OTNS-CLI を使用してノードを追加する

次に、さまざまなタイプのノードを追加します。

> add fed
2
Done
> add med
3
Done
> add sed
4
Done

ノードが 1 つのパーティションに統合されるまで数秒待ちます。OTNS-Web にノードが表示されます。

4 つのノードがある Thread ネットワーク

OTNS-Web では、ノードを選択して、ノードに関する詳細情報を含むパネルを表示することもできます。たとえば、下の図ではノード 1 が選択されています。パネルの [役割] エントリで、リーダーであることが確認できます。

4 つのノードがある Thread ネットワーク。ノード 1 が選択されている

OTNS-Web でノードを追加する

OTNS-Web を使用してノードを追加することもできます。Action BarNew Router ボタンをクリックします。選択したノードの右側にノードが作成されます。新しいルーターは既存の Thread パーティションに参加する必要があります。

ルーターが追加され、合計 5 つのノードになる

アクションバーの FED、MED、SSED、BR ボタンをクリックして、他のタイプのノードを作成することもできます。これで、合計 9 個のノードが作成されます。必要に応じて、ノードを別の位置にドラッグして、別の物理ネットワーク トポロジを作成します。

複数の新しいノードが追加され、合計 9 個のノードが追加されました

これで、多くのノードを含む 1 つのパーティションの Thread ネットワークが作成されました。次のセクションでは、シミュレーションの速度を調整して、シミュレーションを高速で実行します。

6. 速度を調整する

現在、シミュレーションは 1X の速度で実行されているはずです。つまり、これまでのシミュレーション経過時間は、最初のノードを作成してからの実際の時間と同じです。

OTNS-CLI で速度を調整する

OTNS-CLI を使用してシミュレーションの速度を調整できます。

シミュレーション速度を 100X に設定

> speed 100
Done

ノードが以前よりも頻繁にメッセージを送信していることがわかります。

シミュレーション速度を MAX に設定

> speed max
Done

OTNS はできるだけ高速にシミュレートしようとしているため、ノードが大量のメッセージを送信していることがわかります。

シミュレーションの一時停止

> speed 0
Done

シミュレーション速度を 0 に設定すると、シミュレーションが一時停止します。

通常の速度でシミュレーションを復元する

> speed 1
Done

シミュレーション速度を 0 より大きい値に設定すると、シミュレーションが再開されます。

OTNS-Web で速度を調整する

速度調整ボタン

Action Bar の速度制御ボタン 速度調整ボタン を見つけます。ボタンには現在のシミュレーション速度が表示され、シミュレーション速度の調整やシミュレーションの一時停止/再開に使用できます。

シミュレーションを高速化する

MAX: 最大シミュレーション速度インジケーター に達するまで 速度を上げるボタン ボタンをクリックすると、シミュレーションを高速化できます。

シミュレーションを遅くする

速度を下げるボタン ボタンをクリックすると、シミュレーションの速度を落とすことができます。

シミュレーションの一時停止

シミュレーションの実行中に 一時停止ボタン ボタンをクリックすると、シミュレーションが一時停止します。ボタンが 再生ボタン に変わります。

シミュレーションを再開する

シミュレーションが一時停止している場合は、再生ボタン ボタンをクリックして再開します。ボタンが 一時停止ボタン に戻ります。

シミュレーション速度を 10X に設定

時間を節約するため、

OTNS-CLI シミュレーション速度を調整します。

10X これにより、ネットワーク内のトポロジの変更をはるかに迅速に確認できます。

> speed 10
Done

7. ラジオのオン/オフ

シミュレーションには、少なくとも 2 つのルーター(六角形)、場合によってはボーダー ルーター(正方形)、多数の子が含まれ、10 倍の速度で実行されます。

2 つのルーターの現在のリーダー(赤い枠線)を見つけて、1 回クリックして選択します。

リーダーノード 1 が選択された Thread ネットワーク

無線通信をOFF

アクションバーの ラジオ オフボタン ボタンをクリックして、リーダーノードのラジオをオフにします。リーダーは、無線をオフにしている間はメッセージを送受信できません。

他のルーターまたはボーダー ルーターが新しいリーダーになるまで、約 12 秒(シミュレーション時間では 120 秒)待ちます。

ノード 9 を新しいリーダーとして新しいパーティションが形成される

Thread ネットワークは、新しいリーダーで新しいパーティションを形成することで、リーダーの障害から自動的に復旧します。新しいパーティションには新しいパーティションの色も設定されています。

無線通信をON

ラジオがオフになっているリーダーを選択します。Action Barラジオボタン(オン) ボタンをクリックして、ラジオの接続を復元します。

Node 1 は、無線が再びオンになった後でパーティションに参加します

リーダーは、無線接続が復元されたらネットワークに再接続する必要があります。

8. ノードを移動する

OTNS を使用すると、ユーザーは OTNS-CLI または OTNS-Web を介してノードを簡単に移動できます。

OTNS-CLI を介してノードを移動する

ボーダー ルーターノード 9 を新しい場所に移動します。

> move 9 50 50
Done

OTNS-Web を使用してノードを移動する

ノード 5 をドラッグして右下に移動します。ノード 5 は他のルーターの無線範囲外になったため、新しいパーティション ID を持つ独自のパーティションを形成します。パーティション ID は、ノードをクリックしてノード情報パネルで確認できます。

ノード 5 が他のノードから離れて新しいパーティションを形成する

ノード 5 とノード 9 の間には、1 本の緑色の線が描画されています。これは、多くの場合、以前の親の子テーブルにまだ残っている子に関する古い情報が原因です。または、ノード 9 とノード 5 間の以前のルーター間リンクに関する古い情報である可能性があります。(この場合は、レンダリング バグの可能性もあります)。最終的に、適切なタイムアウト後にノードで古い情報がクリーンアップされます。

9. ノードを削除する

OTNS-CLI を使用してノードを削除する

ノード 5 を削除します。

> del 5
Done

シミュレーションからノード 5 が消えます。

ノード 5 がシミュレーションから削除される

OTNS-Web を使用してノードを削除する

ボーダー ルーターノード 9 を選択し、Action Bar削除ボタン ボタンをクリックしてノード 9 を削除します。

ボーダー ルーター ノード 9 が削除される

Node 1 が新しいパーティションのリーダーになり、残りのすべてのノードがノード 1 の子として接続されます。

10. OTNS-CLI ノード コンテキスト

OTNS-CLI は、ノードとの簡単なやり取りのためのノード コンテキスト モードを提供し、デベロッパーがノードのステータスを診断できるようにします。このモードからノード アクションを開始することもできます。

ノード コンテキスト モードを開始する

ノード 1 のノード コンテキストを入力します。

> node 1
Done
node 1>

CLI プロンプトが node 1> に変わり、現在のノード コンテキストが示されます。ノードを直接操作しているかのように、ノードで実行する OpenThread CLI コマンドを入力できます。

ノード コンテキストでコマンドを実行する

node 1> state
leader
Done
node 1> channel
11
Done
node 1> panid
0xface
Done
node 1> networkname
otns
Done
node 1> ipaddr
fdde:ad00:beef:0:0:ff:fe00:fc00
fdde:ad00:beef:0:0:ff:fe00:b400
fd00:f00d:cafe:0:2505:8719:3685:ebfb
fdde:ad00:beef:0:4fd9:b9ba:44e0:96cb
fe80:0:0:0:e86a:e07:ec97:777
Done

別のノード コンテキストに切り替える

node 1> node 2
Done
node 2> 

終了ノードのコンテキスト

node 1> exit
Done
>

ノード コンテキストを終了する別の方法として、node 0 コマンドがあります。

11. ノードログとパケット キャプチャの表示

OpenThread ノードログ

デフォルトでは、OTNS はシミュレートされたすべての OpenThread ノードの詳細なログファイルを生成します。これらは ./tmp ディレクトリで確認できます。ファイル名は 0_.log です。たとえば、ログファイルの一部を次に示します。

7616488 00:00:06.326 [I] MeshForwarder-: Received IPv6 UDP msg, len:90, chksum:5915, ecn:no, from:ca72650db7b856af, sec:no, prio:net, rss:-58.0
7616488 00:00:06.326 [I] MeshForwarder-:     src:[fe80:0:0:0:c872:650d:b7b8:56af]:19788
7616488 00:00:06.326 [I] MeshForwarder-:     dst:[ff02:0:0:0:0:0:0:1]:19788
7616488 00:00:06.326 [D] Mle-----------: Receive MLE message
7616488 00:00:06.326 [D] Mac-----------: Idle mode: Radio receiving on channel 11
7657544 00:00:06.367 [D] Mac-----------: ==============================[RX len=063]==============================
7657544 00:00:06.367 [D] Mac-----------: | 41 D8 7F CE FA FF FF 46 | 74 5A 33 9E 76 51 4E 7F | A......FtZ3.vQN. |
7657544 00:00:06.367 [D] Mac-----------: | 3B 02 F0 4D 4C 4D 4C 81 | E6 00 15 03 00 00 00 00 | ;..MLML......... |
7657544 00:00:06.367 [D] Mac-----------: | 00 00 00 01 46 86 7D FE | 06 CC DB 94 86 9C 88 0B | ....F.}......... |
7657544 00:00:06.367 [D] Mac-----------: | 1C 1E 26 9B 8D 21 2E 65 | 53 5A 43 4E A2 59 D6    | ..&..!.eSZCN.Y.  |
7657544 00:00:06.367 [D] Mac-----------: ------------------------------------------------------------------------
7657544 00:00:06.367 [I] MeshForwarder-: Received IPv6 UDP msg, len:84, chksum:81e6, ecn:no, from:4e51769e335a7446, sec:no, prio:net, rss:-48.0
7657544 00:00:06.367 [I] MeshForwarder-:     src:[fe80:0:0:0:4c51:769e:335a:7446]:19788
7657544 00:00:06.367 [I] MeshForwarder-:     dst:[ff02:0:0:0:0:0:0:2]:19788
7657544 00:00:06.367 [D] Mac-----------: Idle mode: Radio receiving on channel 11
7833912 00:00:06.543 [I] Mle-----------: AttachState ParentReq -> Idle
7833912 00:00:06.543 [N] RouterTable---: Allocate router id 12
7833912 00:00:06.543 [N] Mle-----------: RLOC16 fffe -> 3000
7833912 set node RLOC16: fffe -> 3000
7833912 00:00:06.543 [D] SubMac--------: RadioShortAddress: 0x3000
7833912 00:00:06.543 [N] Mle-----------: Role detached -> leader
7833912 00:00:06.543 [N] Mle-----------: Partition ID 0x24c35f10
7833912 00:00:06.543 [I] RouterTable---: Route table
7833912 00:00:06.543 [I] RouterTable---:     12 0x3000 - me - leader

左側には、絶対シミュレーション時間(マイクロ秒単位)が表示されます。hh:mm:ss タイムスタンプは OpenThread ノード独自のログ タイムスタンプを示します。これは絶対シミュレーション時間とは異なる場合があります。

Wireshark パケット キャプチャ

デフォルトでは、送信されたすべての IEEE 802.15.4 フレームが PCAP ファイル current.pcap にキャプチャされます。このファイルは、シミュレーション中またはシミュレーション後に Wireshark で読み取ることができます。Thread のリンクレイヤ暗号化のため、OTNS の復号鍵を正しく設定するには、Wireshark で 1 回限りの構成アクションが必要です。デフォルトでは、Wireshark によるフレームの復号を容易にするために、1 つの既知のネットワーク キーが使用されます。

以下のスクリーンショットは、Wireshark での OpenThread パケット検査の例です。

Wireshark での OpenThread パケット分析のスクリーンショット

復号鍵を構成するには、メニューで [編集] -> [設定] を選択します。次に、設定ウィンドウで [Protocols] -> [IEEE 802.15.4] を選択します。[復号鍵] の横にある [編集...] ボタンをクリックします。[+] をクリックして新しいエントリを作成し、キー 00112233445566778899aabbccddeeff(32 文字)を入力して、[Key hash] フィールドで [Thread hash] を選択します。[復号鍵インデックス] は 0 のままにします。[OK] をクリックし、再度 [OK] をクリックします。これで、OTNS PCAP ファイルが読み込まれたときに正しく復号されるはずです。

[時間] 列に表示されるタイムスタンプ(秒単位)は、OpenThread ノードログに表示される絶対シミュレーション時間の値に対応しています。これにより、ログメッセージと送受信された無線フレームを簡単に関連付けることができます。ただし、通常、値はマイクロ秒単位で同一ではありません。OpenThread スタックから無線フレームの送信がリクエストされた後、シミュレートされた IEEE 802.15.4 無線ハードウェアが遅延を追加する可能性があります。

12. 完了

おめでとうございます。最初の OTNS シミュレーションが正常に実行されました。

OTNS とその依存関係をインストールする方法を学習しました。OpenThread シミュレート ノードを使用して OTNS シミュレーションを開始しました。OTNS-CLIOTNS-Web の両方を使用して、さまざまな方法でシミュレーションを操作する方法を学習しました。

これで、OTNS の概要と、OTNS を使用して OpenThread ネットワークをシミュレートする方法を理解できました。

次のステップ

以下の Codelab をご覧ください。

リファレンス ドキュメント