1. 簡介
什麼是 Thread 邊界路由器?
Thread 是一種以 IP 為基礎的低功率無線網狀網路通訊協定,可保護裝置之間和裝置之間的通訊。Thread 網路可根據拓撲變更,避免單點故障。
Thread 邊界路由器會將 Thread 網路連至其他 IP 網路,例如 Wi-Fi 或乙太網路。Thread 網路需要邊界路由器才能連線至其他網路。Thread 邊界路由器幾乎支援下列函式:
- Thread 和 Wi-Fi/乙太網路之間的雙向 IP 連線。
- 透過 mDNS (位於 Wi-Fi/乙太網路連結) 和 SRP (位於 Thread 網路) 進行雙向服務探索。
- 採用執行緒多層結構的基礎架構,透過 IP 連結合併 Thread 分區。
- 外部 Thread 調用器 (例如手機) 可以驗證 Thread 裝置並加入至 Thread 網路。
Google 發行的 OpenThread 邊界路由器 (OTBR) 是 Thread 邊界路由器的開放原始碼實作。
建構項目
在本程式碼研究室中,您將設定 Thread 邊界路由器,並透過邊界路由器將手機連接至 Thread 終端裝置。
課程內容
- 如何設定 OTBR
- 如何使用 OTBR 建立 Thread 網路
- 如何使用 SRP 功能建構 OpenThread CLI 裝置
- 如何透過 SRP 註冊服務
- 如何探索並連線到 Thread 端裝置。
軟硬體需求
- 一部 Raspberry Pi 3/4 裝置,以及至少具備 8 GB 能力的 SD 卡。
- 2 北歐半導體 nRF52840 開發板。
- 路由器上未啟用 IPv6 路由器通告功能的 Wi-Fi AP。
- 搭載至少 iOS 14 的 iOS 手機,或至少搭載 Android 8.1 的 Android 手機。
2. 設定 OTBR
設定 Raspberry Pi
只要按照 raspberrypi.org 的操作說明,使用 rpi-imager
工具輕鬆設定新的 Raspberry Pi 裝置,即可 (而不是使用最新的 Raspberry Pi OS 工具,請自行下載 2021-05-07-raspios-buster-armhf-lite)。如要完成本程式碼研究室中的手機步驟,您必須將 Raspberry Pi 連線至 Wi-Fi AP。請按照這份指南的說明設定無線連線。透過 SSH 登入 Raspberry Pi 十分方便,請參閱這裡的操作說明。
取得 OTBR 程式碼
登入 Raspberry Pi,然後從 GitHub 複製 ot-br-posix
:
$ git clone https://github.com/openthread/ot-br-posix.git --depth 1
建構及安裝 OTBR
OTBR 有兩個用來啟動及設定 Thread 邊界路由器的指令碼:
$ cd ot-br-posix $ ./script/bootstrap $ INFRA_IF_NAME=wlan0 ./script/setup
OTBR 適用於透過 INFRA_IF_NAME
指定的 Thread 介面和基礎架構網路介面 (例如 Wi-Fi/乙太網路)。Thread 介面是由 OTBR 本身建立,名為 wpan0
。如未明確指定 INFRA_IF_NAME
,基礎架構介面的預設值則為 wlan0
。如果使用乙太網路線連接 Raspberry Pi,請指定乙太網路介面名稱 (例如 eth0
):
$ INFRA_IF_NAME=eth0 ./script/setup
檢查 OTBR 是否已安裝成功:
$ sudo service otbr-agent status ● otbr-agent.service - Border Router Agent Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled) Active: activating (auto-restart) (Result: exit-code) since Mon 2021-03-01 05:43:38 GMT; 2s ago Process: 2444 ExecStart=/usr/sbin/otbr-agent $OTBR_AGENT_OPTS (code=exited, status=2) Main PID: 2444 (code=exited, status=2)
otbr-agent
服務應該處於無效狀態,因為這需要 RCP
方塊才能運作。
重新啟動 Raspberry Pi,即可讓變更生效。
建構及刷新 RCP 韌體
OTBR 支援無線電合作處理器 (RCP) 模式下的 15.4 無線電晶片。在此模式下,OpenThread 堆疊會在主機端執行,並透過 IEEE802.15.4 收發器傳輸/接收影格。
按照「使用 nRF52840 主機板和 OpenThread 建構 Thread 網路」程式碼研究室的步驟 4,建構及刷新 nRF52840 RCP 裝置:
$ script/build nrf52840 USB_trans
啟動 OTBR 並驗證狀態
將 nRF52840 主機板連結至 Raspberry Pi 並啟動 otbr-agent
服務:
$ sudo service otbr-agent restart
確認 otbr-agent
服務已啟用:
$ sudo service otbr-agent status ● otbr-agent.service - Border Router Agent Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2021-03-01 05:46:26 GMT; 2s ago Main PID: 2997 (otbr-agent) Tasks: 1 (limit: 4915) CGroup: /system.slice/otbr-agent.service └─2997 /usr/sbin/otbr-agent -I wpan0 -B wlan0 spinel+hdlc+uart:///dev/ttyACM0 Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Stop publishing service Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [adproxy] Stopped Mar 01 05:46:26 raspberrypi otbr-agent[2997]: PSKc is not initialized Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Check if PSKc is initialized: OK Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Initialize OpenThread Border Router Agent: OK Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Border router agent started. Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-CORE----: Notifier: StateChanged (0x00038200) [NetData PanId NetName ExtPanId] Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-PLAT----: Host netif is down
3. 建立 Thread 網路
我們提供 ot-ctl
指令來控制 otbr-agent
服務。ot-ctl
接受所有 OpenThread CLI 指令,詳情請參閱 OpenThread CLI 指南。
使用 OTBR 建立 Thread 網路:
$ sudo ot-ctl dataset init new Done $ sudo ot-ctl dataset commit active Done $ sudo ot-ctl ifconfig up Done $ sudo ot-ctl thread start Done
等待幾秒鐘,我們應該就能看到 OTBR 作為執行緒 leader
的動作,而且 Thread 網路資料中還有 off-mesh-routable
(OMR) 前置字串:
$ sudo ot-ctl state leader Done $ 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
4. 設定 SRP 用戶端端裝置
建構及刷新 OT CLI
按照「使用 nRF52840 主機板和 OpenThread 建構 Thread 網路」程式碼研究室的步驟 5,建構及刷新 nRF52840 CLI 最終裝置。
不過,CLI 節點不需要啟用 OT_COMMISSIONER
和 OT_JOINER
,而是需要 OT_SRP_CLIENT
和 OT_ECDSA
功能。
因此完整的建構作業叫用應如下所示:
$ script/build nrf52840 USB_trans -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON
加入 OTBR 網路
為了加入由 otbr-agent
服務建立的 Thread 網路,我們必須從 OTBR 裝置中取得有效作業資料集。讓我們返回 otbr-agent
指令列,取得使用中的資料集:
$ 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 上列印的資料相符。我們現在可以對 OTBR 的 OMR 位址進行連線偵測 (ping):
> 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
5. 在終端裝置上發布服務
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/乙太網路連結宣告。快來探索並觸及最終裝置吧!
6. 探索「服務」
使用手機探索服務
我們使用服務瀏覽器應用程式來探索 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 "" ...
7. 連線偵測 (ping) 裝置端
透過手機連線偵測 (ping)
以 Pixel 手機為例,我們可以找出先前註冊服務「ot-service」的 OMR 位址列於服務瀏覽器應用程式服務執行個體的詳細資料頁面中。
我們現在可以使用其他網路分析器應用程式對 OMR 位址進行連線偵測 (ping)。
很抱歉,Android 版網路分析器應用程式的 Android 版本不支援連線偵測 (ping) 公用程式的 mDNS 查詢,因此我們無法直接對主機名稱 ot-host.local
執行連線偵測 (ping) 主機名稱 (我們可透過該應用程式的 iOS 版本對主機名稱執行連線偵測)。
從 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
。
大多數發行版本的 accept_ra
預設為 1
。但可能還有其他網路 Daemon 會覆寫這個選項 (例如 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,藉此傳送路由器 Soli 訊息,以便 OTBR 將要求 RA 回應。另一個選項是在邊界路由器上重新啟動邊界路由功能:
$ sudo ot-ctl br disable Done $ sudo ot-ctl br enable Done
如要重新連上 Wi-Fi 或重新啟動乙太網路介面,請確認未使用「dhcpcd」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
) 對主機名稱 ot-host.local
進行連線偵測 (ping):
$ 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
當然,您隨時可以直接對 IPv6 位址進行連線偵測 (ping):
$ 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 ...
8. 結束裝置發布服務
如何移除從 SRP 用戶端節點註冊的地址和服務:
> srp client host remove Done
您現在不應找到 _ipps._tcp
服務。
9. 恭喜
恭喜,您已成功將 OTBR 設為 Thread 邊界路由器,以便為 Thread 端裝置提供雙向 IP 連線和服務探索功能。
後續步驟
查看一些程式碼研究室…