1. 簡介
Google 釋出的 OpenThread 是 Thread 網路通訊協定的開放原始碼實作。Google Nest 已推出 OpenThread,讓開發人員能夠廣泛使用 Nest 產品採用的技術,藉此加快智慧聯網家庭的產品開發速度。
Thread 規格定義了以 IPv6 為基礎的可靠、安全且低功耗的無線裝置對裝置通訊通訊協定,適用於家用應用程式。OpenThread 執行所有 Thread 網絡層,包括 IPv6、6LoWPAN、IEEE 802.15.4,具有 MAC 安全、網絡鏈路建立和網格路由。
這個程式碼研究室將逐步引導您使用 Docker 模擬裝置中的 Thread 網路。
課程內容
- 如何設定 OpenThread 建構工具鍊
- 如何模擬 Thread 網路
- 如何驗證 Thread 節點
- 如何使用 OpenThread Daemon 管理 Thread 網路
軟硬體需求
- Docker
- Linux、網路轉送的基本知識
2. 設定 Docker
本程式碼研究室可在 Linux、Mac OS X 或 Windows 電腦上使用 Docker。建議您使用 Linux。
安裝 Docker
在您選擇的作業系統上安裝 Docker。
提取 Docker 映像檔
安裝 Docker 後,請開啟終端機視窗,然後提取 openthread/environment
Docker 映像檔。這個映像檔具備預先建構且可用於此程式碼研究室的 OpenThread 和 OpenThread Daemon。
$ docker pull openthread/environment:latest
請注意,下載作業可能需要幾分鐘才能完成。
在終端機視窗中,從映像檔啟動 Docker 容器並連線到其 bash
殼層:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
請注意此程式碼研究室所需的標記:
--sysctl net.ipv6.conf.all.disable_ipv6=0
:這會啟用容器中的 IPv6--cap-add=net_admin
:啟用 NET_ADMIN 功能,可讓您執行網路相關作業,例如新增 IP 路徑
進入容器後,您應該會看到類似以下的提示:
root@c0f3912a74ff:/#
在上述範例中,c0f3912a74ff
是容器 ID。Docker 容器執行個體的容器 ID 會與這個程式碼研究室提示中顯示的容器 ID 不同。
使用 Docker
本程式碼研究室假設您已瞭解使用 Docker 的基本概念。程式碼的整個容器中應留在 Docker 容器中。
3. 模擬 Thread 網路
您將使用這個程式碼研究室的範例應用程式示範一個最低的 OpenThread 應用程式,透過基本指令列介面 (CLI) 來公開 OpenThread 設定和管理介面。
本練習將帶你完成幾個基本步驟,從另一個模擬的 Thread 裝置對一個模擬的 Thread 裝置進行連線偵測。
下圖說明基本的 Thread 網路拓撲。這次練習時,我們將模擬綠色圓圈中的兩個節點:Thread 領導者和 Thread Router,而兩者之間僅有一個連線。
建立網路
1. 啟動節點 1
如果您尚未完成這項作業,請在終端機視窗中啟動 Docker 容器並連線到其 bash
殼層:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
在 Docker 容器中,使用 ot-cli-ftd
二進位檔為模擬的 Thread 裝置產生 CLI 程序。
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
注意:如果在執行指令後沒有看到 >
提示,請按下 enter
。
這個二進位檔會實作 OpenThread 裝置。IEEE 802.15.4 收音機驅動程序在 UDP 之上執行(IEEE 802.15.4 幀通過 UDP 有效負荷)。
1
的引數是檔案描述元,代表「恢復原廠設定」的最重要位元。對於模擬裝置來說,IEEE EUI-64。綁定用於 IEEE 802.15.4 電縮模擬的 UDP 端口(端口 = 9000 + 文件描述符)時,也使用的值。在這個程式碼研究室中,模擬 Thread 裝置的每個執行個體都會使用不同的檔案描述元。
注意:為模擬裝置執行程序時,您只能使用本程式碼研究室所述的 1
或以上檔案描述元。0
檔案描述元會保留供其他用途使用。
建立新的作業資料集,並將它當做使用中的資料集。作業資料集是您正在建立的 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
將這個資料集做為使用中的資料集:
> dataset commit active Done
啟動 IPv6 介面:
> ifconfig up Done
啟動 Thread 通訊協定作業:
> thread start Done
稍等幾秒鐘,確認裝置已成為 Thread 領導者。「領導者」是指負責處理路由器 ID 指派作業的裝置。
> state leader Done
查看分配到 Node 1's 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
= link-local
網格本機位址類型會進一步分類:
- 包含
ff:fe00
= 路由器定位器 (RLOC) - 不包含
ff:fe00
= 端點 ID (EID)
請在主控台輸出內容中找出 EID,並記下該 ID 供日後使用。在上述範例輸出中,EID 為:
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. 啟動節點 2
開啟新終端機,並在執行中的 Docker 容器中執行 bash
殼層,以便用於節點 2。
$ docker exec -it codelab_otsim_ctnr bash
在這個新的 bash
提示中,使用引數 2
來分割 CLI 程序。這是您第二個模擬的 Thread 裝置:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
注意:如果在執行指令後沒有看到 >
提示,請按下 enter
。
使用與 Node 1's 作業資料集相同的值來設定執行緒網路金鑰和 PAN ID:
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
將這個資料集做為使用中的資料集:
> dataset commit active Done
啟動 IPv6 介面:
> ifconfig up Done
啟動 Thread 通訊協定作業:
> thread start Done
裝置會自行初始化為子項。Thread Child 等同於最終裝置,也就是僅透過家長裝置傳輸及接收單向流量的 Thread 裝置。
> state child Done
2 分鐘內,您應該會在「child
」狀態切換至「router
」。Thread 路由器可在 Thread 裝置之間轉送流量。也稱為「上層」。
> state router Done
驗證網路
如要驗證網狀網路,最簡單的方法是查看路由器表格。
1. 檢查連線狀態
在節點 2 上取得 RLOC16。RLOC16 是設備的 RLOC IPv6 地址的最後 16 位。
> rloc16 5800 Done
在 Node 1 上,檢查 Node 2's RLOC16 的路由器表。請確認節點 2 已先切換至路由器狀態。
> router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+--------+-------+---+--------------------+ | 20 | 0x5000 | 63 | 0 | 0 | 0 | 0 | 96da92ea13534f3b | | 22 | 0x5800 | 63 | 0 | 3 | 3 | 23 | 5a4eb647eb6bc66c |
表格中有 0x5800
的節點 2 的 RLOC,表示該節點已連上網狀網路。
2. 從節點 2 連線節點 1
驗證兩個模擬 Thread 裝置之間的連線。在節點 2 中,ping
指派給節點 1 的 EID:
> 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 提示。
測試網路
現在您可以成功對兩部模擬的 Thread 裝置進行連線偵測 (ping),先將一個節點設為可測試,以便測試網狀網路。
返回節點 1 並停止執行緒:
> thread stop Done
切換至節點 2 並查看狀態。在兩分鐘內,節點 2 偵測到主要節點 (節點 1) 處於離線狀態,您應該會看到節點 2 的轉場效果是網路的 leader
:
> state router Done ... > state leader Done
確認後,請停止 Thread 並將節點 2 恢復原廠設定,然後再返回 Docker bash
提示。手機已恢復原廠設定,以確保這項練習作業所使用的 Thread 網路憑證不會移轉至下一個練習階段。
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
在 factoryreset
指令過後,您可能需要按 enter
幾次才能恢復顯示 >
提示。請勿結束 Docker 容器。
一併將節點恢復原廠設定並結束節點 1:
> factoryreset > > exit root@c0f3912a74ff:/#
請參閱 OpenThread CLI 參考資料來探索所有可用的 CLI 指令。
4. 使用佣金驗證節點
在先前的練習中,您建立了 Thread 網路,其中包含兩部模擬裝置和經過驗證的連線。不過,這種做法只會允許未經驗證的 IPv6 連結本機流量在裝置之間傳送。如要在兩者之間傳輸全域 IPv6 流量 (並透過 Thread 邊界路由器進行網際網路),您必須驗證節點。
只有一部裝置可以做為佣金,才能進行驗證。委員是目前選擇的新 Thread 裝置驗證伺服器,以及提供裝置加入網路所需的網路憑證的授權服務供應商。
在本練習中,我們會採用與之前相同的雙節點拓撲。驗證時,執行緒主管將擔任顧問,是 Thread 路由器中的一員。
Docker
針對其餘練習中的每個節點 (終端機視窗),請確認您執行的是包含 OpenThread 版本的 Docker 容器。如果繼續先前的練習,同一個 Docker 容器中應該仍會出現兩個 bash
提示。否則,請參閱 Docker 疑難排解步驟,或是直接重做 Simulate a Thread network 練習。
1. 建立網路
在節點 1 中,啟動 CLI 程序:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
注意:如果在執行指令後沒有看到 >
提示,請按下 enter
。
建立新的作業資料集,將其視為使用中的資料集並啟動 Thread:
> 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
將這個資料集做為使用中的資料集:
> dataset commit active Done
啟動 IPv6 介面:
> ifconfig up Done
啟動 Thread 通訊協定作業:
> thread start Done
稍等幾秒鐘,確認裝置已成為 Thread 領導者:
> state leader Done
2. 啟動「主持人」角色
在 Node 1 上,啟動啟動器角色:
> commissioner start Done
允許具有 J01NME
聯結憑證的所有加入者 (使用 *
萬用字元) 連線至網路。「人機」是一種由真人管理員新增至已委託 Thread Network 的裝置。
> commissioner joiner add * J01NME Done
3. 啟動「加入者」角色
在第二個終端機視窗中,在 Docker 容器中啟動新的 CLI 程序。這是 Node 2。
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
在節點 2 上,使用 J01NME
連接者憑證啟用彙整者角色。
> ifconfig up Done > joiner start J01NME Done
... 請稍候片刻確認 ...
Join success
As a Joiner, the device (Node 2) has successfully authenticated itself with the Commissioner (Node 1) and received the Thread Network credentials.
由於節點 2 已完成驗證,請啟動 Thread:
> thread start Done
4. 驗證網路驗證
請查看節點 2 上的 state
,以驗證節點是否已加入該網路。節點 2 會在兩分鐘內從 child
轉換到 router
:
> state child Done ... > state router Done
5. 重新設定
為準備下一項運動,請重設設定。在每個節點上停止 Thread 並將恢復原廠設定,然後結束模擬的 Thread 裝置:
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
在 factoryreset
指令過後,您可能需要按 enter
幾次才能恢復顯示 >
提示。
5. 使用 OpenThread Daemon 管理網路
在本練習中,我們將模擬一個 CLI 執行個體 (單一內嵌 SoC Thread 裝置) 和一個無線電輔助處理器 (RCP) 執行個體。
ot-daemon
是 OpenThread Posix 應用程式的模式,使用 UNIX 通訊端做為輸入和輸出方式,讓 OpenThread 以服務形式執行。用戶端可以使用 OpenThread CLI 做為通訊協定,來連線至通訊端。
ot-ctl
是由 ot-daemon
提供的 CLI,可管理及設定 RCP。使用這項功能時,我們會將 RCP 連接到 Thread 裝置所建立的網路。
Docker
針對此練習中的每個節點 (終端機視窗),請確認您執行的是包含 OpenThread 版本的 Docker 容器。如果繼續先前的練習,同一個 Docker 容器中應有 bash
個提示已開啟。如果沒有,請參閱 Docker 疑難排解步驟。
使用 Dam-ememon
這個運動將使用三個終端機視窗,對應的內容如下:
- 模擬 Thread 裝置的 CLI 執行個體 (節點 1)
ot-daemon
項程序ot-ctl
個 CLI 執行個體
1. 啟動節點 1
在第一個終端機視窗中,為模擬的 Thread 裝置啟動 CLI 程序:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
注意:如果在執行指令後沒有看到 >
提示,請按下 enter
。
建立新的作業資料集,將其視為使用中的資料集並啟動 Thread:
> 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
將這個資料集做為使用中的資料集:
> dataset commit active Done
啟動 IPv6 介面:
> ifconfig up Done
啟動 Thread 通訊協定作業:
> thread start Done
查看分配到 Node 1's 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 >
如模擬執行緒網路一節所述,一個位址是連結本機 (fe80
),而三個位址是網狀本機 (fd
)。EID 是網狀位址中,地址中不包含 ff:fe00
。這個範例輸出中的 EID 為 fd55:cf34:dea5:7994:460:872c:e807:c4ab
。
找出 ipaddr
輸出內容中用於指定與節點通訊的特定 EID。
2. 啟動 Da-ememon
在第二個終端機視窗中,建立 tun
裝置節點並設定讀取/寫入權限:
root@c0f3912a74ff:/# mkdir -p /dev/net && mknod /dev/net/tun c 10 200 root@c0f3912a74ff:/# chmod 600 /dev/net/tun
這個裝置是用來在虛擬裝置上進行封包傳輸和接收作業。如果裝置已建立完成,系統會顯示錯誤訊息,這是正常現象,您可以予以忽略。
啟動 RCP 節點的 ot-daemon
,我們將呼叫 Node 2。使用 -v
詳細標記以便查看記錄輸出內容並確認執行中:
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-daemon -v \ 'spinel+hdlc+forkpty://openthread/build/examples/apps/ncp/ot-rcp?forkpty-arg=2'
如果成功,詳細模式中的 ot-daemon
會產生類似以下的輸出內容:
ot-daemon[31]: Running OPENTHREAD/297a880; POSIX; Feb 1 2022 04:43:39 ot-daemon[31]: Thread version: 3 ot-daemon[31]: Thread interface: wpan0 ot-daemon[31]: RCP version: OPENTHREAD/297a880; SIMULATION; Feb 1 2022 04:42:50
將這個終端機保持開啟,在背景中執行。因此,請勿在其中輸入其他指令。
3. 使用 ot-ctl 加入網路
我們尚未將節點 2 (ot-daemon
RCP) 委任給任何 Thread 網路。這時「ot-ctl
」就能派上用場。ot-ctl
使用與 OpenThread CLI 應用程式相同的 CLI。因此,您可以控制 ot-daemon
節點,方法與其他模擬的 Thread 裝置相同。
開啟第三個終端機視窗並執行現有的容器:
$ docker exec -it codelab_otsim_ctnr bash
進入容器後,啟動 ot-ctl
:
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-ctl >
您將使用這個第三個終端機視窗中的 ot-ctl
,管理您在 ot-daemon
與第二個終端機視窗中開始的節點 2 (RCP 節點)。檢查節點 2 的 state
:
> state disabled Done
取得節點 2 的 eui64
,以限制合併到特定彙整器:
> eui64 18b4300000000001 Done
在 Node 1(第一端子窗口)上,啟動 Commissioner,限制只為那 eui64 加入:
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
在第三個終端機視窗中,開啟節點 2 的網路介面並加入網路:
> ifconfig up Done > joiner start J01NME Done
... 請稍候片刻確認 ...
Join success
As a Joiner, the RCP (Node 2) has successfully authenticated itself with the Commissioner (Node 1) and received the Thread Network credentials.
現在將 Node 2 加入 Thread 網路 (再次在第三個終端機視窗中):
> thread start Done
4. 驗證網路驗證
在第三個終端機中,查看節點 2 上的 state
,確認該網路現已加入網路。節點 2 會在兩分鐘內從 child
轉換到 router
:
> state child Done ... > state router Done
5. 驗證連線
在第三個終端機視窗中,使用 Ctrl+D 或 exit
指令退出 ot-ctl
,然後返回容器的 bash
主控台。使用此控制台,在 ping6
命令中使用其 EID 連接 Node 1。如果 ot-daemon
RCP 執行個體已成功加入並與 Thread 網路通訊,則連線偵測 (ping) 成功:
root@c0f3912a74ff:/# 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
6. Docker 疑難排解
如果您已退出 Docker 容器
bash
提示,您可能需要檢查它是否正在運作並重新啟動/視需要重新輸入。
顯示正在執行的 Docker 容器:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
如要顯示所有 Docker 容器 (正在執行和已停止):
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
如果您未在任一 docker ps
指令的輸出中看到「codelab_otsim_ctnr
」容器,請再次執行容器:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
如果容器已停止 (已列於 docker ps -a
,而非 docker ps
),請重新啟動容器:
$ docker start -i codelab_otsim_ctnr
如果 Docker 容器已在執行中 (列在 docker ps
中),請在每個終端機中重新連線至容器:
$ docker exec -it codelab_otsim_ctnr bash
「不允許操作」錯誤
如果您在建立新的 OpenThread 節點 (使用 mknod
指令) 時遇到 Operation not permitted
錯誤,請務必按照本程式碼研究室提供的指令,以根使用者的身分執行 Docker。這個程式碼研究室不支援在無根模式中執行 Docker。
7. 恭喜!
您已成功使用 OpenThread 模擬第一個執行緒網路。太棒了!
在這個程式碼研究室中,您已學到以下內容:
- 啟動及管理 OpenThread 模擬 Docker 容器
- 模擬 Thread 網路
- 驗證 Thread 節點
- 透過 OpenThread Daemon 管理 Thread 網路
如要進一步瞭解 Thread 和 OpenThread,請參閱以下參考資料:
- openthread.io 中的 Thread Primer
- 執行緒規格
- OpenThread GitHub 存放區
- OpenThread CLI 參考資料
- 其他 OpenThread Docker 支援
或者,您也可以嘗試在 Docker 容器中使用 OpenThread Border Router!