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

nRF52840 ボードと 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 では、実際のハードウェアで OpenThread をプログラミングし、Thread ネットワークを作成して管理し、ノード間でメッセージをやり取りします。

4806d16a8c137c6d.jpeg

学習内容

  • OpenThread CLI バイナリをビルドして開発ボードにフラッシュする
  • Linux マシンと開発ボードで構成される RCP の構築
  • OpenThread Daemon と ot-ctl を使用した RCP との通信
  • GNU 画面と OpenThread CLI を使用してスレッドノードを手動で管理する
  • Thread ネットワークへのデバイスの安全なコミッション
  • IPv6 マルチキャストの仕組み
  • UDP を使用してスレッドノード間でメッセージを渡す

必要なもの

ハードウェア:

  • 3 つの北欧半導体 nRF52840 開発ボード
  • ボードを接続する USB - マイクロ USB ケーブル x 3
  • USB ポートが 3 つ以上ある Linux マシン

ソフトウェア:

  • GNU ツールチェーン
  • Nordic nRF5x コマンドライン ツール
  • Segger J-Link ソフトウェア
  • OpenThread
  • Git

2. 始める

OpenThread シミュレーション

始める前に、OpenThread シミュレーション Codelab を読んで、Thread の基本的なコンセプトと OpenThread CLI に慣れておくことをおすすめします。

シリアルポート ターミナル

ターミナルを通じてシリアルポートに接続する方法に精通している必要があります。この Codelab では、GNU Screen を使用して用途の概要を説明しますが、その他のターミナル ソフトウェアも使用できます。

Linux マシン

この Codelab は、i386 または x86 ベースの Linux マシンを使用して、Radio Co-Processor(RCP)Thread デバイスのホストとして機能し、すべての Thread 開発ボードをフラッシュするように設計されています。すべての手順は Ubuntu 14.04.5 LTS(Trusty Tahr)でテストされました。

北欧半導体 nRF52840 ボード

この Codelab では、3 つの nRF52840 PDK ボードを使用します。

a6693da3ce213856.png

SEGGER J-Link を使用して、nRF52840 ボードのプログラミングを行います。ボードは JTAG モジュールを搭載しています。これを Linux マシンにインストールします。

ご使用のマシンに適したパッケージをダウンロードし、適切な場所にインストールします。Linux では /opt/SEGGER/JLink です。

nRF5x コマンドライン ツールをインストールする

nRF5x コマンドライン ツールを使用すると、OpenThread バイナリを nRF52840 ボードにフラッシュできます。適切な nRF5x-Command-Line-Tools-<OS> ビルドを Linux マシンにインストールします。

抽出したパッケージをルートフォルダ ~/ に配置します。

ARM GNU ツールチェーンのインストール

ARM GNU ツールチェーンがビルドに使用されます。

抽出したアーカイブを Linux マシンの /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ に配置することをおすすめします。アーカイブの readme.txt ファイルに記載されているインストール手順をご参照ください。

インストール画面(省略可)

画面は、シリアルポートで接続されたデバイスにアクセスするためのシンプルなツールです。この Codelab では Screen を使用しますが、任意のシリアルポート ターミナル アプリケーションを使用することもできます。

$ sudo apt-get install screen

3. リポジトリのクローンを作成する

OpenThread

OpenThread のクローンを作成してインストールします。script/bootstrap コマンドにより、ツールチェーンがインストールされ、環境が正しく構成されていることを確認します。

$ mkdir -p ~/src
$ cd ~/src
$ git clone --recursive https://github.com/openthread/openthread.git
$ cd openthread
$ ./script/bootstrap

OpenThread デーモンのビルド:

$ script/cmake-build posix -DOT_DAEMON=ON

これで、OpenThread をビルドして nRF52840 ボードにフラッシュする準備ができました。

4. RCP Joiner を設定する

ビルドしてフラッシュする

Joiner とネイティブ USB 機能を使用して、OpenThread nRF52840 のサンプルをビルドします。デバイスは、Joiner のロールを使用して安全に認証され、Thread ネットワークへのコミッションが行われます。ネイティブ USB を使用すると、USB CDC ACM を nRF52840 とホストの間のシリアルトランスポートとして使用できます。

常に rm -rf build を実行して、以前のビルドのリポジトリを常にクリーンアップします。

$ cd ~/src
$ git clone --recursive https://github.com/openthread/ot-nrf528xx.git
$ cd ot-nrf528xx
$ script/build nrf52840 USB_trans

OpenThread RCP バイナリがあるディレクトリに移動し、16 進数形式に変換します。

$ cd ~/src/ot-nrf528xx/build/bin
$ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex

nRF52840 ボードの外部電源ピンの横にあるマイクロ USB デバッグポートに USB ケーブルを接続し、Linux マシンに差し込みます。nRF52840 ボードの nRF 電源スイッチを VDD に設定します。正しく接続されていれば、LED5 はオンです。

20a3b4b480356447.png

これが Linux マシンに接続された最初のボードの場合は、シリアルポート /dev/ttyACM0 として表示されます(すべての nRF52840 ボードでシリアルポート識別子として ttyACM が使用されます)。

$ ls /dev/ttyACM*
/dev/ttyACM0

RCP で使用されている nRF52840 ボードのシリアル番号をメモします。

c00d519ebec7e5f0.jpeg

nRFx コマンドライン ツールの場所に移動し、ボードのシリアル番号を使用して OpenThread RCP 16 進数ファイルを nRF52840 ボードにフラッシュします。--verify フラグを省略すると、フラッシュ プロセスがエラーなしで失敗する可能性があることを示す警告メッセージが表示されます。

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924  --verify --chiperase --program \
       ~/src/ot-nrf528xx/build/bin/ot-rcp.hex --reset

成功すると、次の出力が生成されます。

Parsing hex file.
Erasing user available code and UICR flash areas.
Applying system reset.
Checking that the area to write is not protected.
Programing device.
Applying system reset.
Run.

ボードに「RCP」というラベルを貼り、後で取締役会の役割を混乱させないようにします。

ネイティブ USB に接続する

OpenThread RCP ビルドでは、ネイティブ USB CDC ACM をシリアル トランスポートとして使用できるため、nRF52840 ボードの nRF USB ポートを使用して RCP ホスト(Linux マシン)と通信する必要があります。

フラッシュした nRF52840 ボードのデバッグポートから USB ケーブルのマイクロ USB エンドを外し、リセットボタンの横にあるマイクロ USB nRF USB ポートに再接続します。[nRF power source] スイッチを [USB] に設定します。

46e7b670d2464842.png

OpenThread デーモンを起動

RCP 設計では、OpenThread Daemon を使用して Thread デバイスと通信し、管理します。ログ出力を表示して実行されていることを確認するには、ot-daemon-v 詳細フラグで開始します。

$ cd ~/src/openthread
$ sudo ./build/posix/src/posix/ot-daemon -v \
    'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200'

成功すると、詳細モードの 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

このターミナル ウィンドウは ot-daemon からのログを表示できるように、開いたままにしておきます。

ot-ctl を使用して RCP ノードと通信します。ot-ctl は OpenThread CLI アプリと同じ CLI を使用しているため、シミュレートされた他の Thread デバイスと同じ方法で ot-daemon ノードを制御できます。

第 2 のターミナル ウィンドウで ot-ctl を起動します。

$ sudo ./build/posix/src/posix/ot-ctl
>

ot-daemon で開始したノード 2(RCP ノード)の state を確認します。

> state
disabled
Done

5. FTD を設定する

この Codelab で使用する他の 2 つのスレッドノードは、標準のシステム オン チップ(SoC)設計のフルスレッド デバイス(FTD)です。本番環境設定では、本番環境レベルのネットワーク インターフェース ドライバである wpantund を使用して OpenThread NCP インスタンスを制御できますが、この Codelab では ot-ctl(OpenThread CLI)を使用します。

1 台のデバイスはコミッショナーとして機能し、そのネットワーク上でデバイスを安全に認証してコミッションします。もう一方のデバイスは、Joiner が Thread ネットワークに対して認証できる Joiner として機能します。

ビルドしてフラッシュする

コミッショナーとジョイナーのロールを有効にして、nRF52840 プラットフォーム用の OpenThread FTD サンプルをビルドします。

$ cd ~/src/ot-nrf528xx
$ rm -rf build
$ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON

OpenThread Full Thread Device(FTD)CLI バイナリがあるディレクトリに移動し、16 進数形式に変換します。

$ cd ~/src/ot-nrf528xx/build/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex

nRF52840 ボードの外部電源ピンの横にあるマイクロ USB ポートに USB ケーブルを接続し、Linux マシンに接続します。RCP が引き続き Linux マシンに接続されている場合、この新しいボードはシリアルポート /dev/ttyACM1 として表示されます(すべての nRF52840 ボードでシリアルポート識別子として ttyACM が使用されます)。

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1

前と同じように、FTD で使用されている nRF52840 ボードのシリアル番号をメモします。

c00d519ebec7e5f0.jpeg

nRFx コマンドライン ツールの場所に移動し、ボードのシリアル番号を使用して OpenThread CLI FTD 16 進数ファイルを nRF52840 ボードにフラッシュします。

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \
       ~/src/ot-nrf528xx/build/bin/ot-cli-ftd.hex --reset

ボードに「Commissioner.quot」というラベルを付けます。

ネイティブ USB に接続する

OpenThread FTD ビルドでは、ネイティブ USB CDC ACM をシリアル トランスポートとして使用できるようになるため、nRF52840 ボードの nRF USB ポートを使用して RCP ホスト(Linux マシン)と通信する必要があります。

フラッシュした nRF52840 ボードのデバッグポートから USB ケーブルのマイクロ USB エンドを外し、リセットボタンの横にあるマイクロ USB nRF USB ポートに再接続します。[nRF power source] スイッチを [USB] に設定します。

46e7b670d2464842.png

ビルドを検証する

ターミナル ウィンドウで GNU Screen を使用して OpenThread CLI にアクセスし、ビルドが成功したことを確認します。nRF52840 ボードのボーレートは 115,200 です。

$ screen /dev/ttyACM1 115200

新しいウィンドウでキーボードの Enter キーを数回押すと、OpenThread CLI の > プロンプトが表示されます。IPv6 インターフェースを起動して、アドレスを確認します。

> ifconfig up
Done
> ipaddr
fe80:0:0:0:1cd6:87a9:cb9d:4b1d
Done

Ctrl+A → を使用します

d: FTD Commissioner CLI 画面から切断して Linux ターミナルに戻り、次のボードをフラッシュできるようにします。コマンドラインから screen -r を使用すると、いつでも CLI を再入力できます。使用可能な画面のリストを表示するには、screen -ls を使用します。

$ screen -ls
There is a screen on:
        74182.ttys000.mylinuxmachine        (Detached)
1 Socket in /tmp/uscreens/S-username.

FTD Joiner を設定する

既存の ot-cli-ftd.hex ビルドを使用して、上の手順を繰り返して 3 番目の nRF52840 ボードをフラッシュします。終了したら、必ず nRF USB ポートを使用してボードを PC に再接続し、nRF 電源スイッチを VDD に設定してください。

この 3 番目のボードがアタッチされたときに、他の 2 つのノードが Linux マシンに接続されている場合は、シリアルポート /dev/ttyACM2 として表示されます。

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1  /dev/ttyACM2

ボードに「Joiner.」というラベルを付けます。

Screen を使用して確認する場合は、コマンドラインから新しい Screen のインスタンスを作成するのではなく、既存のインスタンスに再接続し、その画面(FTD コミッショナーで使用したウィンドウ)に新しいウィンドウを作成します。

$ screen -r

Ctrl+A → c キーを押して画面内に新しいウィンドウを作成します。

新しいコマンドライン プロンプトが表示されます。FTD Joiner の OpenThread CLI にアクセスします。

$ screen /dev/ttyACM2 115200

新しいウィンドウでキーボードの Return キーを数回押すと、OpenThread CLI の > プロンプトが表示されます。IPv6 インターフェースを起動して、アドレスを確認します。

> ifconfig up
Done
> ipaddr
fe80:0:0:0:6c1e:87a2:df05:c240
Done

FTD Joiner CLI が FTD Commissioner と同じ画面のインスタンスになったので、Ctrl+A → n を使用して FTD Joiner CLI を切り替えることができます。

Ctrl+A → を使用します

d 随時、スクリーンを終了できます。

6. ターミナル ウィンドウの設定

今後、Thread デバイスは頻繁に切り替わりますので、すべてのデバイスがライブでアクセスしやすい状態になっていることをご確認ください。これまでは、画面を使用して 2 つの FTD にアクセスしてきましたが、このツールでは同じターミナル ウィンドウで分割画面を表示することもできます。これを使用して、あるノードが別のノードに発行されたコマンドにどう反応するかを確認します。

理想的には、次の 4 つのウィンドウがすぐに利用できる状態にしてください。

  1. ot-daemon サービス / ログ
  2. RCP Joiner - ot-ctl
  3. FTD コミッショナー(OpenThread CLI を使用)
  4. OpenThread CLI による FTD Joiner

独自のターミナル / シリアルポート構成またはツールを使用する場合は、次のステップに進んでください。すべてのデバイスのターミナル ウィンドウを最適な方法で構成できます。

画面の使用

使いやすくするために、スクリーン セッションは 1 回だけ開始してください。両方の FTD を設定するときに、すでにいずれか 1 つが必要です。

画面内のすべてのコマンドは、Ctrl+A で始まります。

基本的なスクリーン コマンド:

(コマンドラインから)Screen セッションに再接続する

screen -r

Screen セッションから退出する

Ctrl+A → d

Screen セッション内に新しいウィンドウを作成する

Ctrl+A → c

同じスクリーン セッションでウィンドウを切り替える

Ctrl+A → n(前へ)Ctrl+a → p(戻る)

Screen セッションで現在のウィンドウを強制終了する

Ctrl+A → k

画面の分割

Screen を使用すると、ターミナルを複数のウィンドウに分割できます。

f1cbf1258cf0a5a.png

screen 内のコマンドは、Ctrl+A を使用してアクセスします。どのコマンドもこのアクセスキーの組み合わせで始める必要があります。

Codelab を正確にたどっている場合は、同じ Screen インスタンスに 2 つのウィンドウ(FTD コミッショナー、FTD Joiner)が必要です。画面を 2 つに分けるには、まず既存の Screen セッションを入力します。

$ screen -r

いずれかの FTD デバイスを使用している必要があります。画面で次の手順を行います。

  1. Ctrl+A → S: ウィンドウを水平方向に分割
  2. Ctrl+A → Tab: カーソルを新しい空白ウィンドウに移動します
  3. Ctrl+A → n キーで新しいウィンドウを新しいウィンドウに切り替える
  4. 最前面のウィンドウと同じ場合は、Ctrl+A → n で他の FTD デバイスを表示できます

両方とも表示されるようになりました。Ctrl+A → Tab キーで切り替えます。混乱を避けるために、各ウィンドウは Ctrl+A → A でタイトルを変更することをおすすめします。

上級者向け

画面をさらに分割して ot-daemon ログと RCP Joiner ot-ctl を表示するには、これらのサービスを同じ Screen インスタンス内で起動する必要があります。そのためには、ot-daemon を停止して ot-ctl を終了し、新しいスクリーン ウィンドウ内で再起動します(Ctrl+a → c)。

この設定は必須ではなく、ユーザーの演習用に残しておきます。

ウィンドウを分割して移動するには、次のコマンドを使用します。

新しいウィンドウを作成

Ctrl+A → c

ウィンドウを縦に分割

Ctrl+A →

ウィンドウを横に分割

Ctrl+A → S

次に表示されるウィンドウに移動

Ctrl+A → Tab

表示されたウィンドウを前後に切り替える

Ctrl+A → n または p

現在のウィンドウの名前を変更

Ctrl+A → A

Ctrl+A → d を押すと、いつでも画面から抜けて、コマンドラインから screen -r で再接続できます。

Screen について詳しくは、GNU Screen に関するクイック リファレンスをご覧ください。

7. Thread ネットワークを作成する

すべてのターミナル ウィンドウと画面を設定したので、Thread ネットワークを作成します。FTD コミッショナーで、新しい運用データセットを作成し、アクティブなデータセットとして commit します。オペレーション データセットは、作成する Thread ネットワークの構成です。

## FTD Commissioner ##
----------------------

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 11
Channel Mask: 07fff800
Ext PAN ID: c0de7ab5c0de7ab5
Mesh Local Prefix: fdc0:de7a:b5c0/64
Network Key: 1234c0de7ab51234c0de7ab51234c0de
Network Name: OpenThread-c0de
PAN ID: 0xc0de
PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4
Security Policy: 0, onrcb
Done

後で使用するネットワーク キー 1234c0de7ab51234c0de7ab51234c0de をメモします。

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

> dataset commit active
Done

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

> ifconfig up
Done

Thread プロトコル オペレーションの開始:

> thread start
Done

しばらくしてから、デバイスの状態を確認します。「リーダー」になるべきです。また、後で参照するために RLOC16 を取得します。

## FTD Commissioner ##
----------------------

> state
leader
Done
> rloc16
0c00
Done

デバイスの IPv6 アドレスを確認します。

## FTD Commissioner ##
----------------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:c00         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:6394:5a75:a1ad:e5a    # Mesh-Local EID (ML-EID)
fe80:0:0:0:1cd6:87a9:cb9d:4b1d         # Link-Local Address (LLA)

他の Thread デバイスからスキャンすると、Codelab が表示されます。

RCP Joinerot-ctl から実行します。

## RCP Joiner ##
----------------

> scan
| PAN  | MAC Address      | Ch | dBm | LQI |
+------+------------------+----+-----+-----+
| c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |

FTD Joiner の OpenThread CLI から:

## FTD Joiner ##
----------------

> scan
| PAN  | MAC Address      | Ch | dBm | LQI |
+------+------------------+----+-----+-----+
| c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |

リストに「Codelab」ネットワークが表示されない場合は、もう一度スキャンしてみてください。

8. RCP Joiner を追加する

このネットワークでコミッショニングがアクティブになっていないため、先ほど作成した Thread ネットワークに RCP Joiner を追加する必要があります。

FTD コミッショナーで、ネットワーク キーをメモしました(例: 1234c0de7ab51234c0de7ab51234c0de)。ネットワーク キーを再度検索する必要がある場合は、FTD Commissioner で次のコマンドを実行します。

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

次に、RCP Joiner で、アクティブ データセットのネットワーク キーを FTD Commissioner Network Key に設定します。

## RCP Joiner ##
----------------

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

データセットが正しく設定されていることを確認します。

## RCP Joiner ##
----------------

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

Thread を起動して、RCP Joiner が &coder を介してネットワークに接続します。数秒待ってから、状態 RLOC16 とその IPv6 アドレスを確認します。

## RCP Joiner ##
----------------

> ifconfig up
Done
> thread start
Done
> state
child
Done
> rloc16
0c01
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:0c01         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f    # Mesh-Local EID (ML-EID)
fe80:0:0:0:18e5:29b3:a638:943b          # Link-Local Address (LLA)
Done

メッシュローカル IPv6 アドレスをメモします(ここでは fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f)。後で使用します。

FTD コミッショナーに戻り、ルーターと子テーブルをチェックして、両方のデバイスが同じネットワークに含まれていることを確認します。RLOC16 を使用して RCP Joiner を識別します。

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  35 | 1ed687a9cb9d4b1d |

Done
> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|VER| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+---+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|  2| 1ae529b3a638943b |
Done

RCP Joiner のメッシュローカル アドレス(RCP Joiner の ipaddr 出力から取得したメッシュローカル アドレス)に ping して接続を確認します。

## FTD Commissioner ##
----------------------

> ping fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f
> 8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=1 hlim=64 time=40ms

次のトポロジ図は、2 つのノードで構成されるスレッド ネットワークを示しています。

otcodelab_top01C_2nodes.png

トポロジ図

この Codelab の残りの部分では、ネットワークの状態が変わるたびに、新しい Thread トポロジの図が表示されます。ノードロールは次のように示されます。

b75a527be4563215.png

ルーターは常に五角形で、エンドデバイスは常に円です。各ノード上の数字は、各ノードの現在の役割と状態に応じて、CLI 出力に表示される Router ID または子 ID を表します。

9. FTD ジョイナーをコミッションする

ここで、3 つ目の Thread デバイスを &labt;codelab" ネットワークに追加しましょう。今回は、より安全な帯域内コミッショニング プロセスを使用し、FTD ジョイナーにのみ参加を許可します。

FTD Joinereui64 を取得し、FTD Commissioner が ID を確認します。

## FTD Joiner ##
----------------

> eui64
2f57d222545271f1
Done

FTD コミッショナーでコミッショナーを起動し、参加可能なデバイスの eui64 と、Joiner の認証情報(J01NME など)を指定します。Joiner Credential はデバイス固有の文字列で、すべて大文字の英数字(0 ~ 9 と A ~ Y で、読みやすくするために I、O、Q、Z は除く)です。長さは 6 ~ 32 文字です。

## FTD Commissioner ##
----------------------

> commissioner start
Done
> commissioner joiner add 2f57d222545271f1 J01NME
Done

FTD Joiner に切り替えます。FTD コミッショナーで設定した Joiner Credential で Joiner のロールを開始します。

## FTD Joiner ##
----------------

> ifconfig up
Done
> joiner start J01NME
Done

1 分以内に、認証が成功したことを伝える確認メッセージが表示されます。

## FTD Joiner ##
----------------

>
Join success

Thread を起動して、FTD Joiner が &codelab" ネットワークに接続し、すぐに状態と RLOC16 を確認します。

## FTD Joiner ##
----------------

> thread start
Done
> state
child
Done
> rloc16
0c02
Done

デバイスの IPv6 アドレスを確認します。ALOC がないことにご注意ください。このデバイスはリーダーではなく、ALOC を必要とするエニーキャスト固有のロールを持たないため。

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:c02         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)

すぐに FTD コミッショナーに切り替え、ルーターと子のテーブルをチェックして、&Codet ネットワークに 3 つのデバイスが存在することを確認します。

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   2 | 0x0c02 |        240 |         15 |     3 |   44 |1|1|1|1| e6cdd2d93249a243 |
Done

RLOC16 に基づいて、FTD Joiner はエンドデバイス(子)としてネットワークに接続されています。更新されたトポロジは次のとおりです。

otcodelab_top01C_ed01.png

10. スレッドの実例

この Codelab の Thread デバイスは、Router Eligible End Device(REED)と呼ばれる特定の種類のフルスレッド デバイス(FTD)です。つまり、これは Router またはエンドデバイスのいずれかとして機能し、エンドデバイスから Router に昇格できます。

Thread は最大 32 台の Router に対応できますが、Router 数は 16 ~ 23 に保たれます。REED がエンドデバイス(子)として接続され、ルーターの数が 16 未満の場合は、2 分後にランダムな時間が経過すると自動的に Router に昇格されます。

FTD Joiner を追加した後に Thread ネットワークに 2 つの子がある場合は、2 分以上待ってから、FTD Commissioner でルーターと子テーブルを再確認します。

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
Done

FTD Joiner(拡張 MAC = e6cdd2d93249a243)は Router に昇格しました。RLOC16 が異なることに注意してください(0c02 ではなく b800)。RLOC16 はデバイスのルーター ID と子 ID に基づいているためです。エンドデバイスから Router に移行すると、Router ID と子 ID の値が変更され、RLOC16 も変更されます。

otcodelab_top01C.png

FTD Joiner で新しいステータスと RLOC16 を確認します。

## FTD Joiner ##
----------------

> state
router
Done
> rloc16
b800
Done

FTD Joiner をダウングレードする

この動作をテストするには、Router からエンドデバイスに FTD Joiner を手動でダウングレードします。状態を子に変更し、RLOC16 を確認します。

## FTD Joiner ##
----------------

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

FTD Commissioner に戻ると、子テーブル(FTD Joiner)が子テーブルに表示されます(ID = 3)。移行中であっても、以下の両方のケースが存在する可能性があります。

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   3 | 0x0c03 |        240 |         16 |     3 |   94 |1|1|1|1| e6cdd2d93249a243 |
Done

しばらくすると、RLOC が b800 の Router に戻ります。

otcodelab_top01C.png

リーダーを削除する

リーダーは、すべての Thread Router の中で自動的に選択されます。つまり、現在のリーダーが Thread ネットワークから削除されると、他の Router の 1 つが新しいリーダーになります。

FTD コミッショナーで、Thread をシャットダウンして Thread ネットワークから削除します。

## FTD Commissioner ##
----------------------

> thread stop
Done
> ifconfig down
Done

2 分以内に FTD Joiner が新しい Thread リーダーになります。FTD Joiner の状態と IPv6 アドレスを確認して、以下を確認します。

## FTD Joiner ##
----------------

> state
leader
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00       # Now it has the Leader ALOC!
fdc0:de7a:b5c0:0:0:ff:fe00:b800
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd
fe80:0:0:0:e4cd:d2d9:3249:a243
Done

otcodelab_top02C_01.png

子テーブルを確認します。ここには新しい RLOC16 があります。これは RCP Joiner です。ID と拡張 MAC で示されます。Thread ネットワークをまとめるために、親ルーターを FTD Joiner から FTD Joiner に変更しました。これにより、RCP Joiner の新しい RLOC16 が作成されます(ルーター ID が 3 から 46 に変更されているため)。

## FTD Joiner ##
----------------

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |         27 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

RCP Joiner が FTD Joiner に子として接続されるまで数分かかる場合があります。状態と RLOC16 で以下の点を確認します。

## RCP Joiner ##
--------------

> state
child
> rloc16
b801

FTD コミッショナーを再接続する

2 つのノードを持つ Thread ネットワークはそれほど楽しいものではありません。FTD コミッショナーをオンラインに戻しましょう。

FTD コミッショナーで、Thread を再起動します。

## FTD Commissioner ##
----------------------

> ifconfig up
Done
> thread start
Done

2 分以内に自動的に「Codelab」エンドデバイスとしてネットワークに再接続され、ルーターに昇格します。

## FTD Commissioner ##
----------------------

> state
router
Done

FTD Joiner のルーターと子テーブルで以下を確認します。

## FTD Joiner ##
----------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |       63 |         0 |     3 |      3 |   0 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       46 |         0 |     0 |      0 |  15 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |        184 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

otcodelab_top02C_02.png

この Thread ネットワークも 3 つのノードで構成されています。

11. トラブルシューティング

異なるターミナルやスクリーン ウィンドウで複数のデバイスを使用する Thread ネットワークの管理は、複雑な作業になることがあります。問題が発生した場合は、これらのヒントを使用してネットワークやワークスペースの状態を「リセット」してください。

画面

構成(たとえば、画面ウィンドウが多すぎるか、画面内の画面)が見つからなくなった場合は、Ctrl+A → K キーで画面ウィンドウが強制終了されなくなって、コマンドラインの screen -lsNo Sockets found が出力されます。次に、各画面のスクリーン ウィンドウを再作成します。画面が強制終了された場合でもデバイスの状態は保持されます。

スレッドノード

Thread ネットワーク トポロジがこの Codelab の説明と異なる、またはなんらかの理由でノードが切断される(おそらく Linux マシンからスリープ状態に切り替わったため)場合は、Thread を停止してネットワーク認証情報をクリアしてから、Thread ネットワークの作成の手順から最初からやり直してください。

FTD をリセットするには:

## FTD Commissioner or FTD Joiner ##
------------------------------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

RCP は、ot-ctl を介して同じ方法でリセットできます。

## RCP Joiner ##
----------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

12. マルチキャストの使用

マルチキャストは、デバイスのグループに情報を一度に伝えるために使用されます。Thread ネットワークでは、スコープに応じて、特定のアドレスがさまざまなデバイス グループでマルチキャスト用に予約されます。

IPv6 アドレス

スコープ

配送先

ff02::1

リンクローカル

すべての FTD と MED

ff02::2

リンクローカル

すべての FTD とボーダー ルーター

ff03::1

メッシュローカル

すべての FTD と MED

ff03::2

メッシュローカル

すべての FTD とボーダー ルーター

この Codelab ではボーダー ルーターを使用していないため、ここでは 2 つの FTD マルチポート アドレスと MED マルチキャスト アドレスに焦点を当てます。

リンクローカル スコープは、単一の無線通信で到達可能なすべてのスレッド インターフェース、または単一の「ホップ」ホップで構成されるすべてのスレッド インターフェースで構成されます。ネットワーク トポロジは、ff02::1 マルチキャスト アドレスへの ping に応答するデバイスを指定します。

FTD コミッショナーから ff02::1 に ping します。

## FTD Commissioner ##
----------------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:e4cd:d2d9:3249:a243: icmp_seq=2 hlim=64 time=9ms

ネットワーク内には 2 つのデバイス(FTD Joiner と RCP Joiner)がありますが、FTD Commissioner は FTD Joiner のリンクローカル アドレス(LLA)からのレスポンスを 1 つだけ受け取りました。つまり、FTD コミッショナーが 1 つのホップでアクセスできる唯一のデバイスは FTD Joiner です。

otcodelab_top02C_02_LL.png

FTD Joiner から ff02::1 に ping を実行します。

## FTD Joiner ##
----------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:1cd6:87a9:cb9d:4b1d: icmp_seq=1 hlim=64 time=11ms
8 bytes from fe80:0:0:0:18e5:29b3:a638:943b: icmp_seq=1 hlim=64 time=24ms

2 つの回答があります他のデバイスの IPv6 アドレスを確認すると、最初のアドレス(末尾が 4b1d)は FTD コミッショナーの LLA、2 番目のアドレス(943b の末尾)は RCP Joiner の LLA であることがわかります。

otcodelab_top02C_02_LL02.png

つまり、FTD Joiner は FTD Commissioner と RCP Joiner の両方に直接接続されており、FTD Joiner がトポロジーを確認することになります。

メッシュローカル

メッシュローカル スコープは、同じ Thread ネットワーク内で到達可能なすべての Thread インターフェースで構成されます。ff03::1 マルチキャスト アドレスに対する ping に対するレスポンスを確認してみましょう。

FTD コミッショナーから ff03::1 に ping します。

## FTD Commissioner ##
----------------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:b800: icmp_seq=3 hlim=64 time=9ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=3 hlim=64 time=68ms

今回、FTD コミッショナーは 2 つのレスポンスを受信しました。1 つは FTD Joiner のルーティング ロケーター(RLOC、末尾は b800)と RCP Joiner の Mesh-Local EID(ML-EID、末尾は d55f)です。メッシュのローカル スコープが Thread ネットワーク全体で構成されているためです。デバイスがネットワーク内のどこにあるかにかかわらず、デバイスは ff03::1 アドレスに登録されます。

otcodelab_top02C_02_ML.png

FTD Joiner から ff03::1 を ping して、同じ動作を確認します。

## FTD Joiner ##
----------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00: icmp_seq=2 hlim=64 time=11ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=2 hlim=64 time=23ms

otcodelab_top02C_02_LL02.png

両方の ping 出力で RCP Joiner の応答時間をメモします。RCP Joiner への FTD コミッショナーへの到達にかかった時間は 68 ミリ秒であり、FTD コネクターへの到達に要した時間(23 ミリ秒)よりはるかに長い時間です。FTD コミッショナーに 1 回ホップするときと比べて、FTD コミッショナーには 2 回ホップしなければならないからです。

また、メッシュローカル マルチキャスト ping が RCP Joiner ではなく 2 つの FTD についてのみ RLOC で応答していることにお気づきでしょうか。これは、FTD はネットワーク内のルーターで、RCP はエンドデバイスであるためです。

RCP Joiner の状態を確認します。

## RCP Joiner ##
----------------

> state
child

13. UDP を使用してメッセージを送信する

OpenThread が提供するアプリケーション サービスの 1 つに、Transport Layer プロトコルである User Datagram Protocol(UDP)があります。OpenThread 上に構築されたアプリケーションの場合、UDP API を使用して、Thread ネットワーク内のノード間や、外部ネットワーク(Thread ネットワークがボーダー ルーターを備えている場合はインターネットなど)内の他のデバイスにメッセージを渡すことができます。

UDP ソケットは OpenThread CLI を介して公開されます。2 つの FTD 間でメッセージを渡すために使用します。

FTD Joiner のメッシュローカル EID アドレスを取得します。このアドレスは、Thread ネットワーク内のどこからでもアクセスできるため、使用します。

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:b800        # Routing Locator (RLOC)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
Done

UDP を起動し、任意の IPv6 アドレスのソケットにバインドします。

## FTD Joiner ##
----------------

> udp open
Done
> udp bind :: 1212

FTD コミッショナーに切り替えて UDP を開始し、ML-EID を使用して FTD Joiner で設定したソケットに接続します。

## FTD Commissioner ##
----------------------

> udp open
Done
> udp connect fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd 1212
Done

UDP 接続は 2 つのノード間で存続する必要があります。FTD コミッショナーからメッセージを送信します。

## FTD Commissioner ##
----------------------

> udp send hellothere
Done

FTD Joiner で UDP メッセージが受信されました。

## FTD Joiner ##
----------------

> 10 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00 49153 hellothere

14. 完了

これで、物理スレッド ネットワークが作成されました。

b915c433e7027cc7.png

次のことを学びました。

  • Thread デバイスの種類、ロール、スコープの違い
  • Thread デバイスがネットワーク内の状態を管理する方法
  • UDP を使用してノード間で単純なメッセージを渡す方法

次のステップ

この Codelab で学んだことを活かして、以下の演習を行います。

  • ot-cli-mtd バイナリを使用して、FTD Joiner ボードを MTD として再フラッシュし、Router にアップグレードしたり、リーダーになろうとしたりしていないことを確認します。
  • ネットワークにデバイスを追加して(別のプラットフォームを試す)、ルーターと子テーブル、マルチキャスト アドレスへの ping を使用してトポロジをスケッチします。
  • pyspinel を使用して NCP を管理する
  • OpenThread Border Router を使用して NCP をボーダー ルーターに変換し、Thread ネットワークをインターネットに接続する

参考資料

openthread.ioGitHub では、以下を含む、さまざまな OpenThread リソースをご確認いただけます。

関連資料: