1. 简介
Google 发布的 OpenThread 是 Thread 网络协议的开源实现。Google Nest 发布了 OpenThread,以便让开发者广泛使用 Nest 产品中使用的技术,从而加速开发智能互联家居产品。
线程规范为家庭应用定义了基于 IPv6 的可靠、低功耗的无线设备到设备通信协议。OpenThread 实现了所有线程网络层,包括 IPv6、6LoWPAN、IEEE 802.15.4(MAC 安全)、网格链接建立和网格路由。
此 Codelab 会引导您在模拟设备上模拟线程网络。
学习内容
- 如何设置 OpenThread 构建工具链
- 如何模拟线程网络
- 如何对线程节点进行身份验证
- 如何使用 OpenThread 守护程序管理线程网络
所需条件
- git
- Linux 和网络路由基础知识
2. 设置构建系统
Git
需要使用 Git 才能完成此 Codelab。请先下载并安装,再继续操作。
安装完成后,请按照适用于您的特定操作系统的说明下载 OpenThread 并进行构建。
适用于 Mac OS X 的 XCode
必须使用 XCode,才能在 Mac OS X 上安装和构建 OpenThread。
XCode 安装完毕后,安装 XCode 命令行工具:
$ xcode-select --install
在 Linux / Mac OS X 上构建
这些安装说明已在 Ubuntu Server 14.04 LTS 和 Mac OS X Sierra 10.12.6 上进行了测试。
安装 OpenThread。bootstrap
命令确保已安装工具链且环境配置正确:
$ mkdir -p ~/src $ cd ~/src $ git clone --recursive https://github.com/openthread/openthread.git $ cd openthread $ ./script/bootstrap $ ./bootstrap
使用 Windows
如果您喜欢 Windows,我们建议您试用此 Codelab 的 Docker 版本。
3.构建 OpenThread 应用
安装完成后,构建示例 OpenThread 应用。对于此 Codelab,我们使用模拟示例。
$ cd ~/src/openthread $ make -f examples/Makefile-simulation
现在构建 OpenThread 守护程序:
$ cd ~/src/openthread $ make -f src/posix/Makefile-posix DAEMON=1
4.模拟线程网络
您将在此 Codelab 中使用的示例应用演示了一个基本 OpenThread 应用,该应用通过基本命令行界面 (CLI) 公开 OpenThread 配置和管理接口。
本练习将向您介绍从一个模拟线程设备对一个模拟线程设备进行 ping 操作所需的最少步骤。
下图介绍了基本的线程网络拓扑。在本练习中,我们将模拟绿色圆圈中的两个节点:线程主节点和线程路由器,它们在它们之间具有单个连接。
Ping 节点
1. 启动节点 1
转到 openthread
目录,然后使用 ot-cli-ftd
二进制文件生成模拟线程设备的 CLI 进程。
$ cd ~/src/openthread $ ./output/simulation/bin/ot-cli-ftd 1
注意:如果在运行此命令后没有看到 >
提示,请按 enter
。
此二进制文件实现在 POSIX 上模拟的 OpenThread 设备。IEEE 802.15.4 无线驱动程序在 UDP 的基础上实现(IEEE 802.15.4 帧在 UDP 载荷内传递)。
1
的参数是一个文件描述符,表示模拟设备的“出厂分配”IEIE EUI-64 的最低有效位。绑定到 IEEE 802.15.4 无线模拟的 UDP 端口(端口 = 9000 + 文件描述符)时也会使用该值。此 Codelab 中每个模拟线程设备的实例都会使用不同的文件描述符。
注意:在为模拟设备生成进程时,只能使用此 Codelab 中所述的 1
或更大的文件描述符。0
的文件描述符已预留,供其他用途使用。
创建新的操作数据集并将其作为活动数据集提交。Operational Dataset 在您要创建的线程网络进行配置。
> 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 start Done
等待几秒钟,并验证设备是否已成为线程领导者。“领先设备”是负责管理路由器 ID 分配的设备。
> state leader Done
查看分配给节点 1 的线程接口的 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
= 端点标识符 (EID)
识别控制台输出中的 EID,并记下该 ID 以备日后使用。在上面的示例输出中,EID 为:
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. 启动节点 2
打开新终端并导航至 openthread
目录,然后生成 CLI 进程。这是您的第二个模拟线程设备:
$ cd ~/src/openthread $ ./output/simulation/bin/ot-cli-ftd 2
注意:如果在运行此命令后没有看到 >
提示,请按 enter
。
使用与节点 1 的运营数据集相同的值配置线程网络密钥和 PAN ID:
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
将此数据集作为活动数据集提交:
> dataset commit active Done
启动 IPv6 接口:
> ifconfig up Done
启动线程协议操作:
> thread start Done
设备将自己初始化为子级。线程子项相当于终端设备,而终端设备是仅通过父设备发送和接收单播流量的线程设备。
> state child Done
在 2 分钟内,您应该会看到状态从 child
变为 router
。线程路由器能够在线程设备之间路由流量。也称为父级。
> state router Done
验证网络
验证网状网络的一种简单方法是查看路由器表。
1. 检查连接
在节点 2 上,获取 RLOC16。RLOC16 是设备 RLOC IPv6 地址的最后 16 位。
> rloc16 5800 Done
在节点 1 上,检查路由器 2 的 RLOC16 路由器表。确保节点 2 首先已切换到路由器状态。
> router table | ID | RLOC16 | Next Hop | Path Cost | LQI In | LQI Out | Age | Extended MAC | +----+--------+----------+----------+-------+---------+-----+------------------+ | 20 | 0x5000 | 63 | 0 | 0 | 0 | 0 | 96da92ea13534f3b | | 22 | 0x5800 | 63 | 0 | 3 | 3 | 23 | 5a4eb647eb6bc66c |
在表格中找到了节点 1 的 0xa800
的 RLOC,以确认它已连接到网格。
2. 从节点 2 中 Ping 节点 1
验证两个模拟线程设备之间的连接。在节点 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 提示。
测试网络
现在,您可以在两个模拟线程设备之间成功进行 ping 操作,只需使一个节点离线即可测试网格网络。
返回到节点 1 并停止线程:
> thread stop Done
切换到节点 2 并检查状态。在两分钟内,节点 2 检测到主节点(节点 1)处于离线状态,您应该会看到节点 2 的转换是网络的 leader
:
> state router Done ... > state leader Done
确认后,请停止线程,然后将节点 2 恢复出厂设置,然后退出。完成恢复出厂设置操作,以确保我们在本练习中使用的线程网络凭据不会转移到下一个练习。
> thread stop Done > factoryreset > > exit
同时恢复出厂设置并退出节点 1:
> factoryreset > > exit
如需了解所有可用的 CLI 命令,请参阅 OpenThread CLI 参考。
5. 通过调试对节点进行身份验证
在上一练习中,您设置了具有两个模拟设备和已验证连接的线程网络。但是,这只允许未通过身份验证的 IPv6 链路本地流量在设备之间传递。如需在这些地址(以及通过线程边界路由器的互联网)之间路由全球 IPv6 流量,您必须对节点进行身份验证。
为了进行身份验证,一台设备必须充当专员。委员是目前选对新线程设备的身份验证服务器,授权者提供加入网络所需的网络凭据。
在本练习中,我们将使用与之前相同的双节点拓扑。对于身份验证,线程领导者将充当专员,即线程路由器成为连接者。
1. 创建网络
如果继续之前的练习,您应该已经打开了两个终端窗口。如果不是,请确保文件是打开的且可供使用。一个作为节点 1,另一个用作节点 2。
在节点 1 中,生成 CLI 进程:
$ cd ~/src/openthread $ ./output/simulation/bin/ot-cli-ftd 1
注意:如果在运行此命令后没有看到 >
提示,请按 enter
。
创建一个新的操作性数据集,将其作为活动数据集提交,然后启动线程:
> 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 start Done
等待几秒钟,并验证设备是否已成为线程领导者:
> state leader Done
2. 启动专员角色
仍在 Node 1 上,启动专员角色:
> commissioner start Done
允许任何具有 J01NME
连接器凭据的连接器(使用 *
通配符)向网络进行调试。连接符是由人类管理员添加到某个委托线程网络的设备。
> commissioner joiner add * J01NME Done
3.启动 Joiner 角色
在第二个终端窗口中,生成新的 CLI 进程。这是节点 2。
$ cd ~/src/openthread $ ./output/simulation/bin/ot-cli-ftd 2
在节点 2 上,使用 J01NME
连接器凭据启用“连接者”角色。
> ifconfig up Done > joiner start J01NME Done
... 等待几秒钟进行确认 ...
Join success
作为联接者,设备 (Node 2) 已成功通过专员 (Node 1) 验证自身身份,并且获得了线程网络凭据。
现在 Node 2 已通过身份验证,请启动线程:
> thread start Done
4.验证网络身份验证
检查节点 2 上的 state
,以验证其现已加入网络。在两分钟内,节点 2 从 child
转换到 router
:
> state child Done ... > state router Done
5. 重置配置
如需准备下一个练习,请重置配置。在每个节点上,停止线程,恢复出厂设置,然后退出模拟线程设备:
> thread stop Done > factoryreset > > exit
您可能需要按 enter
几次,才能在 factoryreset
命令之后再次显示 >
提示。
6.使用 OpenThread 守护程序管理网络
在本练习中,我们将模拟一个 CLI 实例(一个嵌入式 SoC 线程设备)和一个无线电协处理器 (RCP) 实例。
ot-daemon
是 OpenThread Posix 应用的模式,该模式使用 UNIX 套接字作为输入和输出,以便 OpenThread 核心可以作为服务运行。客户端可以使用 OpenThread CLI 作为协议连接到套接字,以便与该服务通信。
ot-ctl
是 ot-daemon
提供的 CLI,用于管理和配置 RCP。通过使用此网址,我们会将 RCP 连接到线程设备创建的网络。
使用 ot-daemon
本练习将使用三个终端窗口,分别对应于:
- 模拟线程设备的 CLI 实例(节点 1)
ot-daemon
个进程ot-ctl
CLI 实例
如果从上一练习继续,您应该已打开两个终端窗口。打开第三个终端窗口,确保您有 3 个终端窗口可用于此练习。
1. 启动节点 1
在第一个终端窗口中,生成模拟线程设备的 CLI 进程:
$ cd ~/src/openthread $ ./output/simulation/bin/ot-cli-ftd 1
注意:如果在运行此命令后没有看到 >
提示,请按 enter
。
创建一个新的操作性数据集,将其作为活动数据集提交,然后启动线程:
> 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 start Done
查看分配给节点 1 的线程接口的 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. 启动 ot-daemon
在第二个终端窗口中,转到 openthread
目录,然后为 RCP 节点启动 ot-daemon
,我们将称之为 Node 2。使用 -v
详细标志,以便查看日志输出并确认其正在运行:
$ cd ~/src/openthread $ ./output/posix/bin/ot-daemon -v \ 'spinel+hdlc+forkpty://output/simulation/bin/ot-rcp?forkpty-arg=2'
如果成功,详细模式中的 ot-daemon
会生成类似于以下内容的输出:
ot-daemon[228024]: Running OPENTHREAD/20191113-00831-gfb399104; POSIX; Jun 7 2020 18:05:15 ot-daemon[228024]: Thread version: 2 ot-daemon[228024]: RCP version: OPENTHREAD/20191113-00831-gfb399104; SIMULATION; Jun 7 2020 18:06:08
让此终端在后台运行并在后台运行。您无需在其中输入任何其他命令。
3.使用 ot-ctl 加入网络
我们尚未向任何线程网络委托节点 2 (ot-daemon
RCP)。这就是 ot-ctl
发挥作用的地方。ot-ctl
使用与 OpenThread CLI 应用相同的 CLI。因此,您可以使用与其他模拟线程设备相同的方式控制 ot-daemon
节点。
在第三个终端窗口中,启动 ot-ctl
:
$ ./output/posix/bin/ot-ctl >
您将在第三个终端窗口中使用 ot-ctl
来管理您通过 ot-daemon
从第二个终端窗口启动的节点 2(RCP 节点)。检查节点 2 的 state
:
> state disabled Done
获取节点 2 的 eui64
,以限制联接到特定联接器:
> eui64 18b4300000000001 Done
在节点 1(第一个终端窗口)上,启动专员,并将其限制为仅加入该 eui64:
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
在节点 2(第三个终端窗口)上,启动网络接口并加入网络:
> ifconfig up Done > joiner start J01NME Done
... 等待几秒钟进行确认 ...
Join success
作为联接者,RCP(节点 2)已成功向专员(节点 1)验证自身的身份并获得了线程网络凭据。
现在,将 Node 2 加入线程网络:
> thread start Done
4.验证网络身份验证
检查节点 2 上的 state
,以验证其现已加入网络。在两分钟内,节点 2 从 child
转换到 router
:
> state child Done ... > state router Done
5. 验证连接
使用 Ctrl+D 退出主机 ot-ctl
,在主机的命令行上,通过 ping6
命令使用其 EID 对 Node 1 进行 ping 操作。如果 ot-daemon
RCP 实例成功连接到线程网络并与之通信,则 ping 成功:
$ 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
7. 恭喜!
您已成功使用 OpenThread 模拟了第一个线程网络。棒极了!
在此 Codelab 中,您学习了如何执行以下操作:
- 设置 OpenThread 构建工具链
- 模拟线程网络
- 对线程节点进行身份验证
- 使用 OpenThread 守护程序管理线程网络
如需了解详情,请参阅以下内容: