1. はじめに
Google がリリースした OpenThread は、Thread ネットワーク プロトコルのオープンソース実装です。Google Nest は、Google Nest 製品で使用されている技術を幅広く利用できるようにし、スマートホーム製品の開発を加速させるため、OpenThread をリリースしました。
Thread 仕様は、家庭用アプリケーション向けに、IPv6 ベースの信頼性、安全性、消費電力の少ないワイヤレス デバイス間通信プロトコルを定義しています。OpenThread は、IPv6、6LoWPAN、MAC セキュリティを備えた IEEE 802.15.4、メッシュリンク確立、メッシュルーティングなど、すべての 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
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 デバイス 1 つに、別の Thread デバイスから ping を実行するために必要な最小限の手順を説明します。
下図は、基本的な Thread ネットワーク トポロジを示しています。この演習では、緑色の円内の 2 つのノード(Thread Leader と Thread Router)を 1 つの接続でシミュレートします。
ノードに ping を実行する
1. Node 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
の引数は、「factory-assigned」の最下位ビットを表すファイル記述子です。シミュレートされたデバイスでは 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 start Done
数秒待ってから、デバイスが Thread Leader になったことを確認します。リーダーは、ルーター ID の割り当てを管理するデバイスです。
> state leader Done
ノード 1 の Thread インターフェースに割り当てられた 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
= ルーター ロケータ(RLOC)を含むff:fe00
= エンドポイント識別子(EID)を含まない
コンソール出力で EID を特定し、後で使用できるようにメモしておきます。上記のサンプル出力では、EID は次のようになります。
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. Node 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 start Done
デバイスは子として初期化されます。Thread の子はエンドデバイスと同等です。エンドデバイスは、親デバイスとのみユニキャスト トラフィックを送受信する Thread デバイスです。
> state child Done
2 分以内に、child
から router
に状態が切り替わるはずです。Thread ルーターは、Thread デバイス間でトラフィックをルーティングできます。「親」とも呼ばれます。
> state router Done
ネットワークを確認する
ルーター テーブルを見ると、メッシュ ネットワークを簡単に確認できます。
1. 接続を確認する
Node 2 で RLOC16 を取得します。RLOC16 は、デバイスの RLOC IPv6 アドレスの最後の 16 ビットです。
> rloc16 5800 Done
Node 1 のルーター表で Node 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 |
テーブル内に 0xa800
のノード 1 の RLOC があり、メッシュに接続されていることを確認します。
2. ノード 2 からノード 1 に ping を実行する
シミュレートされた 2 つの Thread デバイス間の接続を検証します。Node 2 で、Node 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 つのノードをオフラインにしてメッシュ ネットワークをテストします。
Node 1 に戻り、Thread を停止します。
> thread stop Done
Node 2 に切り替えて、状態を確認します。2 分以内に、ノード 2 はリーダー(ノード 1)がオフラインであることを検出し、ノード 2 がネットワークの leader
に遷移します。
> state router Done ... > state leader Done
確認したら、終了する前に Thread を停止し、Node 2 を出荷時の設定にリセットします。この演習で使用した Thread ネットワーク認証情報が次の演習に引き継がれないようにするため、出荷時設定へのリセットが行われます。
> thread stop Done > factoryreset > > exit
また、ノード 1 を出荷時の設定にリセットして終了します。
> factoryreset > > exit
使用可能なすべての CLI コマンドについては、OpenThread CLI リファレンスをご覧ください。
5. コミッショニングでノードを認証する
前の演習では、シミュレートされた 2 台のデバイスで Thread ネットワークを設定し、接続を検証しました。ただし、これにより、認証されていない IPv6 リンクローカル トラフィックのみがデバイス間で送受信されます。グローバル IPv6 トラフィックを両者間で(および Thread ボーダー ルーター経由でインターネットに)ルーティングするには、ノードを認証する必要があります。
認証を行うには、1 つのデバイスがコミッショナーとして機能する必要があります。コミッショナーは現在、新しい Thread デバイスの認証サーバーで選ばれており、デバイスがネットワークに接続するために必要なネットワーク認証情報を提供する承認者です。
この演習では、前と同じ 2 ノード トポロジを使用します。認証については、Thread Leader はコミッショナー、Thread Router は Joiner として、
1. ネットワークの作成
前の演習から続行する場合、すでに 2 つのターミナル ウィンドウが開いているはずです。表示されていない場合は、2 つを開いて使用できることを確認します。1 つはノード 1、もう 1 つはノード 2 として動作します。
Node 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 start Done
数秒待ってから、デバイスがスレッド リーダーになっていることを確認します。
> state leader Done
2. コミッショナー ロールを開始する
まだノード 1 でコミッショナー ロールを開始します。
> commissioner start Done
J01NME
Joiner 認証情報を持つ任意の Joiner(*
ワイルドカードを使用)がネットワークへのコミッショニングを許可します。Joiner は、人間の管理者が委託した Thread ネットワークに追加するデバイスです。
> commissioner joiner add * J01NME Done
3. Joiner ロールを開始する
2 つ目のターミナル ウィンドウで、新しい CLI プロセスを生成します。これがノード 2 です。
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 2
Node 2 で、J01NME
Joiner 認証情報を使用して Joiner ロールを有効にします。
> ifconfig up Done > joiner start J01NME Done
... 確認されるまで数秒お待ちください ...
Join success
Joiner として、デバイス(ノード 2)はコミッショナー(ノード 1)で自身を正常に認証し、Thread ネットワーク認証情報を受信しました。
Node 2 が認証されたので、Thread を開始します。
> thread start Done
4. ネットワーク認証を検証する
Node 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 Thread デバイス)と 1 つの無線コプロセッサ(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 つのターミナル ウィンドウが開いているはずです。3 つ目のウィンドウを開き、この演習に使用できるターミナル ウィンドウが 3 つあることを確認します。
1. Node 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 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 >
Thread ネットワークをシミュレートするの手順で説明したように、1 つのアドレスはリンクローカル(fe80
)、3 つのアドレスはメッシュローカル(fd
)です。EID が、アドレスに ff:fe00
を含まないメッシュローカル アドレスである。このサンプル出力では、EID は fd55:cf34:dea5:7994:460:872c:e807:c4ab
です。
ipaddr
出力で、ノードとの通信に使用される特定の EID を特定します。
2. ot-daemon の起動
2 番目のターミナル ウィンドウで、openthread
ディレクトリに移動し、RCP ノード(Node 2)の 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 ノード)を管理します。Node 2 の state
を確認します。
> state disabled Done
Node 2 の eui64
を取得して、参加を特定の Joiner に制限します。
> eui64 18b4300000000001 Done
Node 1(最初のターミナル ウィンドウ)でコミッショナーを起動し、参加をその eui64 のみに制限します。
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
Node 2(3 番目のターミナル ウィンドウ)で、ネットワーク インターフェースを起動し、ネットワークに参加します。
> ifconfig up Done > joiner start J01NME Done
... 確認されるまで数秒お待ちください ...
Join success
Joiner として、RCP(ノード 2)はコミッショナー(ノード 1)で自身を正常に認証し、Thread Network 認証情報を受け取りました。
Node 2 を Thread ネットワークに参加させます。
> thread start Done
4. ネットワーク認証を検証する
Node 2 の state
をチェックして、ネットワークに参加したことを確認します。2 分以内に、ノード 2 は child
から router
に移行します。
> state child Done ... > state router Done
5. 接続を検証する
Ctrl+D または exit
コマンドを使用し、ホストマシンのコマンドラインから ping6
コマンドで EID を指定してノード 1 に ping して、ot-ctl
を終了します。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 ネットワークを管理する
詳細については、以下のリファレンスをご覧ください。