1. 简介
什么是 Thread?
Thread 是一种基于 IP 的低功耗无线网状网络协议,可实现安全的设备到设备通信和设备到云通信。线程网络可以适应拓扑变化,以避免单点故障。
什么是 OpenThread?
Google 发布的 OpenThread 是 Thread® 的开源实现。
什么是 OpenThread 边界路由器?
Google 发布的 OpenThread 边界路由器 (OTBR) 是 Thread 边界路由器的开源实现。
IPv6 多播
Thread 定义了一系列功能,以支持在范围大于“realm local”的多播地址跨异构网络(Thread 和 Wi-Fi/以太网段)进行多播。
Thread 边界路由器会注册其骨干路由器 (BBR) 数据集,所选的 BBR 服务是主要骨干路由器 (PBBR),负责多播入站/出站转发。
如果地址大于 Realm 本地地址,Thread 设备会发送 CoAP 消息,将多播地址注册到 PBBR(多播监听器注册,简称 MLR)。PBBR 在其外部接口上使用 MLDv2,代表其本地 Thread 网络与更广泛的 IPv6 LAN/WAN 通信,以便了解它需要监听的 IPv6 多播组。此外,只有当至少有 1 个 Thread 设备订阅了目标时,PBB 才会将多播流量转发到 Thread 网络。
对于 Thread 极简端设备,它们可能会依赖其父级来汇总多播地址并代表它们执行 MLR,或者在其父级为 Thread 1.1 时自行注册。
如需了解详情,请参阅线程规范。
构建内容
在此 Codelab 中,您将设置一个 Thread 边界路由器和两个 Thread 设备,然后在 Thread 设备和 Wi-Fi 设备上启用和验证多播功能。
学习内容
- 如何构建支持 IPv6 多播的 nRF52840 固件。
- 如何在 Thread 设备上订阅 IPv6 多播地址。
所需条件
- Linux 工作站,用于构建和刷写 Thread RCP、OpenThread CLI 以及测试 IPv6 多播。
- 用于 Thread 边界路由器的 Raspberry Pi。
- 2 个 Nordic Semiconductor nRF52840 USB 加密狗(一个用于 RCP,两个用于 Thread 端设备)。
2. 设置 OTBR
如需快速设置 OTBR,请按照 OTBR 设置指南中的说明操作。
OTBR 设置完成后,使用 ot-ctl
验证 OTBR 是否在几秒内成为主骨干路由器。
> bbr state Primary Done > bbr BBR Primary: server16: 0xF800 seqno: 21 delay: 5 secs timeout: 3600 secs Done
3. 构建和刷写 Thread 设备
使用多播构建 Thread CLI 应用,并刷写两个 nRF52840 DK 开发板。
构建 nRF52840 DK 固件
按照说明克隆项目并构建 nRF52840 固件。
$ cd ~/src/ot-nrf528xx $ rm -rf build $ script/build nrf52840 USB_trans -DOT_MLR=ON
按照“使用 nRF52840 开发板和 OpenThread 构建 Thread 网络”Codelab中的说明操作。使用 CLI 映像刷写端点设备后,请按照将第二个节点加入 Thread 网络中的说明将 Thread 设备添加到 Thread 网络。对第二个 Thread 端设备重复上述操作。
4. 订阅 IPv6 多播地址
在 nRF52840 端设备 1 上订阅 ff05::abcd:
> ipmaddr add ff05::abcd Done
验证 ff05::abcd
是否已成功订阅:
> ipmaddr ff05:0:0:0:0:0:0:abcd <--- ff05::abcd subscribed ff33:40:fdde:ad00:beef:0:0:1 ff32:40:fdde:ad00:beef:0:0:1 ff02:0:0:0:0:0:0:2 ff03:0:0:0:0:0:0:2 ff02:0:0:0:0:0:0:1 ff03:0:0:0:0:0:0:1 ff03:0:0:0:0:0:0:fc Done
在笔记本电脑上订阅 ff05::abcd:
我们需要一个 Python 脚本 subscribe6.py
来订阅笔记本电脑上的多播地址。
复制以下代码并将其保存为 subscribe6.py
:
import ctypes
import ctypes.util
import socket
import struct
import sys
libc = ctypes.CDLL(ctypes.util.find_library('c'))
ifname, group = sys.argv[1:]
addrinfo = socket.getaddrinfo(group, None)[0]
assert addrinfo[0] == socket.AF_INET6
s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0])
interface_index = libc.if_nametoindex(ifname.encode('ascii'))
mreq = group_bin + struct.pack('@I', interface_index)
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
print("Subscribed %s on interface %s." % (group, ifname))
input('Press ENTER to quit.')
运行 subscribe6.py
以在 Wi-Fi 网络接口(例如 wlan0)上订阅 ff05::abcd
:
$ sudo python3 subscribe6.py wlan0 ff05::abcd Subscribed ff05::abcd on interface wlan0. Press ENTER to quit.
下面显示了包含多播订阅的最终网络拓扑:
现在,我们已在 Thread 网络中的 nRF52840 端设备 1 和 Wi-Fi 网络中的笔记本电脑上订阅了 IPv6 多播地址,接下来将在以下部分中验证双向 IPv6 多播可单播性。
5. 验证入站 IPv6 多播
现在,我们应该能够使用 Wi-Fi 网络中的 IPv6 多播地址 ff05::abcd
同时访问 Thread 网络中的 nRF52840 端设备 1 和笔记本电脑。
通过 Wi-Fi 接口 Ping OTBR 上的 ff05::abcd:
$ ping -6 -b -t 5 -I wlan0 ff05::abcd PING ff05::abcd(ff05::abcd) from 2401:fa00:41:801:83c1:a67:ae22:5346 wlan0: 56 data bytes 64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=1 ttl=64 time=57.4 ms 64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=1 ttl=64 time=84.9 ms (DUP!) 64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=2 ttl=64 time=54.8 ms 64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=2 ttl=64 time=319 ms (DUP!) 64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=3 ttl=64 time=57.5 ms 64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=3 ttl=64 time=239 ms (DUP!) # If using MacOS, use this command. The interface is typically not "wlan0" for Mac. $ ping6 -h 5 -I wlan0 ff05::abcd
我们可以看到,OTBR 可以同时从 nRF52840 端设备 1 和笔记本电脑收到两个 ping 回复,因为它们都订阅了 ff05::abcd
。这表明,OTBR 可以将 IPv6 Ping 请求多播数据包从 Wi-Fi 网络转发到 Thread 网络。
6. 验证出站 IPv6 多播
在 nRF52840 端点设备 2 上对 ff05::abcd 进行 ping:
> ping ff05::abcd 100 10 1 108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=12 hlim=64 time=297ms 108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=12 hlim=63 time=432ms 108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=13 hlim=64 time=193ms 108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=13 hlim=63 time=306ms 108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=14 hlim=64 time=230ms 108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=14 hlim=63 time=279ms
nRF52840 端点设备 2 可以同时接收来自 nRF52840 端点设备 1 和笔记本电脑的 ping 回复。这表明,OTBR 可以将 IPv6 Ping 回复多播数据包从 Thread 网络转发到 Wi-Fi 网络。
7. 恭喜
恭喜,您已成功设置 Thread 边界路由器并验证了双向 IPv6 多播!
如需详细了解 OpenThread,请访问 openthread.io。
参考文档: