1. はじめに
Google Nest チームがリリースした OpenThread は、Thread® ネットワーク プロトコルのオープンソース実装です。スマートホーム製品の開発をスピードアップするために設計されたものです。Thread Specification は、家庭用および商業用ビルの用途向けに、IPv6 ベースの信頼性、安全性、省電力のワイヤレス デバイス間通信プロトコルを定義しています。
Espressif は、FreeRTOS と LwIP に基づく OpenThread スタックを移植し、デベロッパーが Thread ネットワークを迅速に構築できるようにしています。関連するソースコードは GitHub から入手できます。同時に、Espressif は RTOS に基づく Thread ボーダー ルーターも実装しています。
この Codelab では、実際のハードウェア上で OpenThread をプログラミングし、Thread ネットワークを作成して管理し、ノード間でメッセージを渡します。
学習内容
- OpenThread CLI バイナリをビルドして ESP ボードに書き込む
- ボーダー ルーターを構築し、ESP Thread ボーダー ルーターのボードにフラッシュする。
- ESP Monitor と OpenThread CLI を使用して Thread ノードを手動で管理する。
- Thread ボーダー ルーター上で Thread ネットワークを形成。
- Thread ネットワークへのデバイスのコミッショニングを保護します。
- Thread ノード間で IPv6 アドレスに ping します。
- UDP を使用して Thread ノード間でメッセージを受け渡す。
必要なもの
ハードウェア:
ソフトウェア:
- ESP-IDF.
- ESP-THREAD-BR です。
2. 開始するには
- ESP-IDF のインストール。
ESP-IDF プログラミング ガイドに沿って、ソフトウェア開発環境をインストールしてください。
- ESP Thread ボーダー ルーター SDK のクローンを作成します。
ESP-THREAD-BR は、ESP Thread ボーダー ルーターの公式 SDK です。Thread ボーダー ルーターを構築するための基本的なネットワーク機能をすべてサポートし、迅速な製品化のために豊富な製品レベルの機能を統合しています。
$ cd <your-local-workspace> $ git clone --recursive https://github.com/espressif/esp-thread-br.git
3. ビルドとフラッシュ
IEEE 802.15.4 モジュールを搭載した ESP ボードで ot-cli-ftd バイナリ ファイルをビルドしてフラッシュする方法については、ESP-IDF の例 ot_cli をご覧ください。
$ cd <your-idf-path>/examples/openthread/ot_cli $ idf.py set-target <your-board-type>
Menuconfig で Joiner 機能を有効にします。
$ idf.py menuconfig
コンポーネントの設定 >OpenThread >Joiner を有効にしてから、ビルドとフラッシュを行います。
$ idf.py -p <your-local-port> build flash monitor
ESP Thread ボーダー ルーター ボードで ot-br バイナリ ファイルをビルドしてフラッシュするには、まず RCP バイナリ ファイルをビルドする必要があります。この RCP バイナリ ファイルは、ESP Thread ボーダー ルーターボード上のデバイスに明示的に書き込む必要はありません。Border Router のバイナリ ファイルに含まれ、初回起動時(または RCP ファームウェアの変更時)に ESP32-H2 チップにフラッシュされます。詳しくは、ESP Thread BR のドキュメントをご覧ください。
$ cd <your-idf-path>/examples/openthread/ot_rcp $ idf.py set-target esp32h2 $ idf.py build $ cd <your-esp-thread-br-path>/examples/basic_thread_border_router $ idf.py set-target esp32s3
Menuconfig でコミッショナー機能を有効にします。
$ idf.py menuconfig
コンポーネントの設定 >OpenThread >コミッショナーを有効にして、ビルドしてフラッシュします。
$ idf.py -p <your-local-port> build flash monitor
4. Thread ボーダー ルーターでの Thread ネットワークを形成する
これで、ESP Thread ボーダー ルーター ボード(BR コミッショナー)で OpenThread コマンドラインを使用して Thread ネットワークを形成できるようになりました。
## BR Commissioner ## ---------------------- > dataset init new Done > dataset Active Timestamp: 1 Channel: 21 Channel Mask: 0x07fff800 Ext PAN ID: 151975d11bea97b5 Mesh Local Prefix: fd6a:b54b:d6a3:b05a::/64 Network Key: 731ab6a60a64a0a0b14b259b86b2be01 Network Name: OpenThread-1444 PAN ID: 0x1444 PSKc: 54e7f18d2575014da94db09df29c5df0 Security Policy: 672 onrc 0 Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up I (59329) OPENTHREAD: Platform UDP bound to port 49153 Done I (59329) OT_STATE: netif up
スレッド プロトコル オペレーションを開始します。
> thread start I(61709) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(62469) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(69079) OPENTHREAD:[N] RouterTable---: Allocate router id 11 I(69079) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2c00 I(69089) OPENTHREAD:[N] Mle-----------: Role detached -> leader I(69089) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 I (69099) OPENTHREAD: Platform UDP bound to port 49154
しばらく待ってから、デバイスの状態を確認します。リーダーである必要があります。
> state leader Done >
5. networkkey を使用して Thread ネットワークに接続する
この Codelab では、BR 形成のネットワークに接続するために、IEEE 802.15.4 モジュールを搭載した 2 つの ESP ボードを準備します。このセッションでは、Board1 をネットワークに追加します。
BR からネットワーク キーを取得します。
## BR Commissioner ## ---------------------- > networkkey 731ab6a60a64a0a0b14b259b86b2be01 Done >
IEEE 802.15.4 モジュールを搭載した 1 台の ESP ボード(Board1 Joiner)に、このネットワークキーを設定します。
## Board1 Joiner ## ---------------------- > dataset networkkey 731ab6a60a64a0a0b14b259b86b2be01 Done
このデータセットをアクティブなデータセットとして commit します。
> dataset commit active Done
IPv6 インターフェースを起動します。
> ifconfig up Done I (20308) OT_STATE: netif up
スレッド プロトコル オペレーションを開始します。
> thread start I(23058) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(23408) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(30028) OPENTHREAD:[N] Mle-----------: Attach attempt 1 unsuccessful, will try again in 0.288 seconds I(30328) OPENTHREAD:[N] Mle-----------: Attach attempt 2, AnyPartition I(33498) OPENTHREAD:[N] Mle-----------: Delay processing Announce - channel 21, panid 0x1444 I(33758) OPENTHREAD:[N] Mle-----------: Processing Announce - channel 21, panid 0x1444 I(33758) OPENTHREAD:[N] Mle-----------: Role detached -> disabled I(33758) OPENTHREAD:[N] Mle-----------: Role disabled -> detached I(34178) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition I(35068) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2c01 I(35068) OPENTHREAD:[N] Mle-----------: Role detached -> child
しばらく待ってから、デバイスの状態を確認します。子になっているはずです。
> state child Done
ロールを Router に設定します。
> state router Done I(51028) OPENTHREAD:[N] Mle-----------: RLOC16 2c01 -> 2800 I(51028) OPENTHREAD:[N] Mle-----------: Role child -> router I(51028) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 >
6. 安全なコミッショニングを通じて Thread ネットワークに参加
このセッションでは、セキュリティ コミッショニングを通じて Board2 をネットワークに追加します。
BR コミッショナーから PSKc と panid を入手:
## BR Commissioner ## ---------------------- > pskc 54e7f18d2575014da94db09df29c5df0 Done > panid 0x1444 Done
Board2 にネットワーク情報を構成します。
## Board2 Joiner ## ---------------------- > dataset pskc 54e7f18d2575014da94db09df29c5df0 Done > dataset panid 0x1444 Done
このデータセットをアクティブなデータセットとして commit します。
## Board2 Joiner ## ---------------------- > dataset commit active Done
IPv6 インターフェースを起動します。
## Board2 Joiner ## ---------------------- > ifconfig up Done I (29146) OT_STATE: netif up
Board2 から eui64 を取得します。
## Board2 Joiner ## ---------------------- > eui64 4831b7fffec02be1 Done
BR コミッショナーでコミッショナーを開始し、参加できるデバイスの eui64
と Joiner の認証情報(J01NME
など)を指定します。Joiner 認証情報は、すべて大文字の英数字(0 ~ 9 と A ~ Y。読みやすくするために I、O、Q、Z を除く)で構成されたデバイス固有の文字列で、長さは 6 ~ 32 文字です。
## BR Commissioner ## ---------------------- > commissioner start Commissioner: petitioning Done Commissioner: active > commissioner joiner add 4831b7fffec02be1 J01NME Done
Board2 Joiner に切り替えます。BR コミッショナーに設定した Joiner 認証情報を使用して、結合者ロールを開始します。
## Board2 Joiner ## ---------------------- > ifconfig up Done > joiner start J01NME Done
1 分ほどで、認証が成功したことを示す確認メッセージが表示されます。
## Board2 Joiner ## ---------------------- > Join success
その後、BR コミッショナーが設立した Thread ネットワークに参加できます。
スレッド プロトコル オペレーションを開始します。
> thread start I(35727) OPENTHREAD:[N] Mle-----------: Role disabled -> detached Done > I(36197) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset I(37007) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 2801 I(37007) OPENTHREAD:[N] Mle-----------: Role detached -> child
ロールを Router に設定します。
> state router Done I(46057) OPENTHREAD:[N] Mle-----------: RLOC16 2801 -> 4400 I(46057) OPENTHREAD:[N] Mle-----------: Role child -> router I(46057) OPENTHREAD:[N] Mle-----------: Partition ID 0x28b518c6 >
次に示すトポロジの Thread ネットワークが得られます。
7. Thread ノード間で IPv6 アドレスに ping を実行する
ping コマンドを使用して、任意の 2 つのボード間で通信できます。ipaddr
コマンドを使用して、各ボードの IPv6 アドレスを出力します。
## BR Commissioner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:fc00 # Leader Anycast Locator (ALOC) fd6a:b54b:d6a3:b05a:0:ff:fe00:2c00 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:a8df:eb43:63d8:bda0 # Mesh-Local EID (ML-EID) fe80:0:0:0:687c:7248:cc14:9c4d # Link-Local Address (LLA) Done >
## Board1 Joiner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:2800 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:e461:db08:c833:1248 # Mesh-Local EID (ML-EID) fe80:0:0:0:18ac:df04:4671:6a45 # Link-Local Address (LLA) Done
## Board2 Joiner ## ---------------------- > ipaddr fd6a:b54b:d6a3:b05a:0:ff:fe00:4400 # Routing Locator (RLOC) fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc # Mesh-Local EID (ML-EID) fe80:0:0:0:a8cc:1483:f696:91a2 # Link-Local Address (LLA) Done
たとえば、BR コミッショナーから Board2 MLE-ID に ping するには、BR Commissioner で次のコマンドを実行します。
## BR Commissioner ## ---------------------- > ping fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc 16 bytes from fd6a:b54b:d6a3:b05a:d7dc:8e90:9bc9:ecbc: icmp_seq=1 hlim=255 time=123ms 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 123/123.0/123 ms. Done
8. UDP を使用して Thread ノード間でメッセージを受け渡す
このセッションでは、2 つの Thread デバイス間でメッセージを送信する方法を学びます。たとえば、udp を開いてポート 20617
にバインドし、BR ですべてのアドレスをリッスンします。
## BR Commissioner ## ---------------------- > udp open Done > udp bind :: 20617 I (1298739) OPENTHREAD: Platform UDP bound to port 20617 Done
次に、Board1 から BR MLE-ID アドレスとポート 20617
にメッセージを送信します。
## Board1 Joiner ## ---------------------- > udp open Done > udp send fd6a:b54b:d6a3:b05a:a8df:eb43:63d8:bda0 20617 ESP
BR で受信したメッセージをご確認ください。
## BR Commissioner ## ---------------------- 3 bytes from fd6a:b54b:d6a3:b05a:e461:db08:c833:1248 49154 ESP
9. 完了
ESP ボードを使用して物理的な Thread ネットワークを作成できました。
学習しました。
- OpenThread CLI バイナリをビルドして ESP ボードに書き込む
- ESP Thread ボーダー ルーターのボードにフラッシュ ボーダー ルーターを設置。
- ESP Monitor と OpenThread CLI を使用して Thread ノードを手動で管理する。
- Thread ボーダー ルーター上で Thread ネットワークを形成。
- Thread ネットワークへのデバイスのコミッショニングを保護します。
- Thread ノード間で IPv6 アドレスに ping します。
- UDP を使用して Thread ノード間でメッセージを受け渡す。
関連情報
以下のような OpenThread リソースについては、openthread.io と GitHub をご覧ください。
- 対応プラットフォーム - OpenThread をサポートするすべてのプラットフォーム
- OpenThread をビルドする - OpenThread のビルドと構成の詳細
- Thread Primer — この Codelab で取り上げる Thread のコンセプトをすべてカバーします。
関連資料: