1. 簡介
什麼是 Thread?
Thread 是以 IP 為基礎的低功耗無線網狀網路通訊協定,可讓裝置之間及裝置與雲端之間安全通訊。Thread 網路可因應拓撲變化,避免單點故障。
什麼是 OpenThread?
Google 發布的 OpenThread 是 Thread® 的開放原始碼實作項目。
什麼是 Thread 邊界路由器?
Thread 邊界路由器會將 Thread 網路連線至其他以 IP 為基礎的網路,例如 Wi-Fi 或乙太網路。Thread 網路需要邊界路由器才能連線至其他網路。Thread 邊界路由器至少應支援下列功能:
- Thread 與 Wi-Fi/乙太網路之間的雙向 IP 連線。
- 透過 mDNS (在 Wi-Fi/乙太網路連結上) 和 SRP (在 Thread 網路上) 進行雙向服務探索。
- 透過 IP 型連結合併 Thread 分區的基礎架構 Thread。
- 外部 Thread 委派裝置 (例如手機),用來驗證 Thread 裝置並加入 Thread 網路。
Google 發布的 OpenThread 邊界路由器 (OTBR) 是 Thread 邊界路由器的開放原始碼實作項目。
建構項目
在本程式碼研究室中,您將設定 Thread 邊界路由器,並透過邊界路由器將手機連線至 Thread 終端裝置。
課程內容
- 如何設定 OTBR
- 如何使用 OTBR 建立 Thread 網路
- 如何使用 SRP 功能建構 OpenThread CLI 裝置
- 如何向 SRP 註冊服務
- 如何探索及連線至 Thread 終端裝置
軟硬體需求
- Linux 工作站,用於建構及刷寫 Thread RCP、OpenThread CLI,以及測試 IPv6 多點傳播。
- Raspberry Pi (做為 Thread 邊界路由器)。
- 2 個 Nordic Semiconductor nRF52840 USB Dongle (一個用於 RCP,一個用於 Thread 終端裝置)。
- 搭載 iOS 14 以上版本的 iOS 手機,或搭載 Android 8.1 以上版本的 Android 手機。
2. 設定 OTBR
如要快速設定 OTBR,請參閱 OTBR 設定指南。
OTBR 設定完成後,請使用 ot-ctl
驗證 OTBR 是否做為 Thread leader
運作。
$ sudo ot-ctl state leader Done
此外,請確認 OTBR 已在 Thread 網路資料中自動設定 off-mesh-routable
(OMR) 前置字元。
$ sudo ot-ctl netdata show Prefixes: Prefixes: fd76:a5d1:fcb0:1707::/64 paos med 4000 Routes: fd49:7770:7fc5:0::/64 s med 4000 Services: 44970 5d c000 s 4000 44970 01 9a04b000000e10 s 4000 Done $ sudo ot-ctl ipaddr fda8:5ce9:df1e:6620:0:ff:fe00:fc11 fda8:5ce9:df1e:6620:0:0:0:fc38 fda8:5ce9:df1e:6620:0:ff:fe00:fc10 fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9 fda8:5ce9:df1e:6620:0:ff:fe00:fc00 fda8:5ce9:df1e:6620:0:ff:fe00:4000 fda8:5ce9:df1e:6620:3593:acfc:10db:1a8d fe80:0:0:0:a6:301c:3e9f:2f5b Done
3. 設定 SRP 用戶端裝置
建構及刷寫 OT CLI
按照「使用 nRF52840 開發板和 OpenThread 建構 Thread 網路」程式碼研究室的步驟 5,建構並刷寫 nRF52840 CLI 終端裝置。
不過,CLI 節點需要啟用 OT_SRP_CLIENT
和 OT_ECDSA
功能,而非 OT_COMMISSIONER
和 OT_JOINER
。
因此完整的建構呼叫應如下所示:
$ script/build nrf52840 USB_trans -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON
加入 Thread 網路
如要加入 Thread 網路,我們需要從 OTBR 裝置取得有效的作業資料集。讓我們回到 ot-ctl
並取得有效資料集:
$ sudo ot-ctl dataset active -x 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff Done
返回 SRP 用戶端節點畫面工作階段,並設定有效資料集:
> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff Done
然後啟動 Thread 介面:
> ifconfig up Done > thread start Done
稍候片刻,確認加入 Thread 網路是否成功:
> state child Done > netdata show Prefixes: fd76:a5d1:fcb0:1707::/64 paos med 4000 Routes: fd49:7770:7fc5:0::/64 s med 4000 Services: 44970 5d c000 s 4000 44970 01 9a04b000000e10 s 4000 Done > ipaddr fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 fda8:5ce9:df1e:6620:0:ff:fe00:4001 fda8:5ce9:df1e:6620:ed74:123:cc5d:74ba fe80:0:0:0:d4a9:39a0:abce:b02e Done
確認網路資料與 OTBR 上印製的資料相符。我們現在可以 Ping OTBR 的 OMR 位址:
> ping fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9 Done > 16 bytes from fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9: icmp_seq=1 hlim=64 time=49ms
4. 在終端裝置上發布服務
mDNS 廣泛用於發布連結本機的 DNS-SD 服務。但多點播送訊息會耗用過多頻寬,且低功耗裝置的電池很快就會耗盡。Thread 會使用單點傳播 SRP 通訊協定向邊界路由器註冊服務,並依賴邊界路由器在 Wi-Fi 或乙太網路連結上公告服務。
我們可以使用 srp client
指令註冊服務。
前往 SRP 用戶端節點畫面工作階段,然後自動啟動 SRP 用戶端:
> srp client autostart enable Done
設定要在 Wi-Fi/乙太網路連結上放送的主機名稱:
> srp client host name ot-host Done
如要讓 Wi-Fi/乙太網路連結上的裝置連上 Thread 終端裝置,必須宣傳終端裝置的 OMR 位址:
> srp client host address fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 Done
最後,註冊虛構的 _ipps._tcp
服務:
> srp client service add ot-service _ipps._tcp 12345 Done
稍候片刻,我們應該就能看到已註冊的服務:
> srp client service instance:"ot-service", name:"_ipps._tcp", state:Registered, port:12345, priority:0, weight:0 Done
我們已完成所有設定作業,_ipps._tcp
服務應已在 Wi-Fi/乙太網路連結上宣傳。現在該來探索並連線至終端裝置了!
5. 探索服務
使用手機探索這項服務
我們使用 Service Browser 應用程式,透過 Android 手機探索 mDNS 服務,您也可以在 iOS 行動裝置上找到類似的應用程式。開啟應用程式,服務 _ipps._tcp
應該就會顯示。
透過 Linux 主機探索服務
如要從其他 Linux 主機探索服務,可以使用 avahi-browse
指令。
安裝 avahi-daemon
和 avahi-utils
:
$ sudo apt-get install -y avahi-daemon avahi-utils
解析服務:
$ sudo service avahi-daemon start # Ensure the avahi daemon is started. $ avahi-browse -r _ipps._tcp + wlan0 IPv6 ot-service Secure Internet Printer local = wlan0 IPv6 ot-service Secure Internet Printer local hostname = [ot-host.local] address = [fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927] port = [12345] txt = [] ...
透過 macOS 主機探索服務
您可以在 macOS 上使用 dns-sd
解析服務:
$ dns-sd -Z _ipps._tcp local. Browsing for _ipps._tcp.local. DATE: ---Sun 14 Mar 2021--- 21:31:42.125 ...STARTING... ; To direct clients to browse a different domain, substitute that domain in place of '@' lb._dns-sd._udp PTR @ ; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names. ; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local ; names with the correct fully-qualified (unicast) domain name of the target host offering the service. _ipps._tcp PTR ot-service._ipps._tcp ot-service._ipps._tcp SRV 0 0 12345 ot-host.local. ; Replace with unicast FQDN of target host ot-service._ipps._tcp TXT "" ...
6. Ping 終端裝置
透過手機 Ping
以 Pixel 手機為例,我們可以在 Service Browser 應用程式的服務執行個體詳細資料頁面中,找出先前註冊的「ot-service」服務 OMR 位址。
現在可以使用其他「網路分析」應用程式,對 OMR 位址執行 Ping 測試。
很抱歉,Android 版的網路分析器應用程式不支援 ping 公用程式的 mDNS 查詢,因此我們無法直接 ping 主機名稱 ot-host.local
(但可以使用 iOS 版的應用程式 ping 主機名稱)。
從 Linux/macOS 主機執行 Ping
Thread 邊界路由器會傳送 ICMPv6 路由器通告 (RA),在 Wi-Fi/乙太網路連結上通告前置字元 (透過前置字元資訊選項) 和路徑 (透過路徑資訊選項)。
準備 Linux 主機
請務必在主機上啟用 RA 和 RIO:
- 如果未啟用 IP 轉送功能,
net.ipv6.conf.wlan0.accept_ra
至少應為1
,否則應為2
。 net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen
不得小於64
。
大多數發行版本預設為 1
。accept_ra
但可能會有其他網路精靈覆寫這個選項 (例如,Raspberry Pi 上的 dhcpcd
會將 accept_ra
覆寫為 0
)。您可以使用下列指令檢查 accept_ra
值:
$ sudo sysctl -n net.ipv6.conf.wlan0.accept_ra 0
並使用下列指令將值設為 1
(如果已啟用 IP 轉送,則為 2
):
$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra=1 Net.ipv6.conf.wlan0.accept_ra = 1
在大多數 Linux 發行版本中,accept_ra_rt_info_max_plen
選項預設為 0
,請使用下列指令將其設為 64
:
$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen=64 net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64
重新啟動主機後,變更就會遺失。舉例來說,將下列指令附加至 /etc/sysctl.conf
,即可永久啟用 RIO:
$ net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64
OTBR 已開始傳送 RA 訊息,且兩則未經要求的 RA 訊息之間的時間間隔可能長達數百秒,因此可能無法變更這些設定。其中一種方式是中斷連線,然後重新連線至 Wi-Fi AP,傳送路由器請求訊息,讓 OTBR 回應所要求的 RA。你也可以重新啟動邊界路由器上的邊界路由功能:
$ sudo ot-ctl br disable Done $ sudo ot-ctl br enable Done
如果嘗試重新連線 Wi-Fi 或重新啟動乙太網路介面,請確認 dhcpcd 未用於管理 Wi-Fi/乙太網路 IPv6 網路。因為每次介面重新啟動時,dhcpcd 一律會覆寫 accept_ra
選項,導致 accept_ra
設定遺失。在 dhcpcd 設定檔 (例如 /etc/dhcpcd.conf
) 中附加下列指令行,即可在 dhcpcd 中明確停用 IPv6:
noipv6 noipv6rs
您必須重新啟動裝置,變更才會生效。
準備 macOS 主機
這兩種 accept_ra*
選項預設為啟用,但系統必須升級至 macOS Big Sur 以上版本。
對主機名稱或 IPv6 位址執行連線偵測 (ping)
現在可以使用 ping -6
指令 (macOS 為 ping6
) Ping 主機名稱 ot-host.local
:
$ ping -6 ot-host.local. PING ot-host.local.(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927)) 56 data bytes 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=1 ttl=63 time=170 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=2 ttl=63 time=64.2 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=3 ttl=63 time=22.8 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=4 ttl=63 time=37.7 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=5 ttl=63 time=28.7 ms ...
在 Linux 主機上,這個指令可能會失敗並顯示 "Name or service not known"
錯誤。這是因為 ping
指令不會透過 mDNS 查詢解析 ot-host.local.
名稱。開啟 /etc/nsswitch.conf
,並在以 hosts
開頭的行中新增 mdns6_minimal
:
hosts: files mdns4_minimal mdns6_minimal dns
當然,您隨時可以直接 Ping IPv6 位址:
$ ping -6 fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 PING fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927) 56 data bytes 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=1 ttl=63 time=32.9 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=2 ttl=63 time=27.8 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=3 ttl=63 time=29.9 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=4 ttl=63 time=73.5 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=5 ttl=63 time=26.4 ms ...
7. 終止裝置取消發布服務
如要移除從 SRP 用戶端節點註冊的位址和服務:
> srp client host remove Done
您現在不應能探索到 _ipps._tcp
服務。
8. 恭喜
恭喜!您已成功將 OTBR 設定為 Thread 邊界路由器,為 Thread 終端裝置提供雙向 IP 連線和服務探索功能。
後續步驟
查看一些程式碼研究室…