Google 致力于为黑人社区推动种族平等。查看具体行动

使用 OpenThread 模拟线程网络

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

1. 简介

26b7f4f6b3ea0700.png

Google 发布的 OpenThreadThread 网络协议的开源实现。Google Nest 发布了 OpenThread,让开发者广泛使用 Nest 产品中使用的技术,以加快智能互联家居产品的开发速度。

线程规范定义了适用于家居应用的基于 IPv6 的可靠、安全、低功耗的无线设备到设备通信协议。OpenThread 实现所有 Thread 网络层,包括具有 MAC 安全性的 IPv6、6LoWPAN、IEEE 802.15.4、网格链接建立和网格路由。

此 Codelab 会引导您在模拟设备上模拟线程网络。

学习内容

  • 如何设置 OpenThread 构建工具链
  • 如何模拟 Thread 网络
  • 如何对线程节点进行身份验证
  • 如何使用 OpenThread 守护程序管理 Thread 网络

所需条件

  • git
  • 具备 Linux 和网络路由方面的基础知识

2. 设置构建系统

Git

完成此 Codelab 需要 Git。请先下载并安装,然后再继续。

安装后,请按照适用于您的特定操作系统的说明下载并构建 OpenThread。

适用于 Mac OS X 的 XCode

Mac OS X 上安装和构建 OpenThread 需要使用 XCode。

安装 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
$ ./script/cmake-build simulation

现在构建 OpenThread 守护程序:

$ ./script/cmake-build posix -DOT_DAEMON=ON

4. 模拟线程网络

您将在本 Codelab 中使用的示例应用演示了一个极简 OpenThread 应用,该应用可通过基本命令行界面 (CLI) 公开 OpenThread 配置和管理界面。

本练习将向您介绍从一个模拟线程设备对一个模拟线程设备执行 ping 操作所需的最低步骤。

下图介绍了基本的 Thread 网络拓扑。在本练习中,我们将模拟绿色圆圈内的两个节点:线程主管和线程路由器,两者之间的连接均为单个连接。

6e3aa07675f902dc.png

ping 节点

1. 启动节点 1

转到 openthread 目录,并使用 ot-cli-ftd 二进制文件为模拟线程设备生成 CLI 进程。

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 1

注意:运行此命令后,如果系统未显示 > 提示,请按 enter

此二进制文件会实现基于 POSIX 模拟的 OpenThread 设备。IEEE 802.15.4 无线装置驱动程序基于 UDP 实现(IEEE 802.15.4 帧在 UDP 载荷内传递)。

1 的参数是一个文件描述符,表示针对模拟设备的“工厂分配”IEEE EUI-64 的最低有效位。在绑定至 IEEE 802.15.4 无线装置模拟(端口 = 9000 + 文件描述符)的 UDP 端口时,也会使用此值。在此 Codelab 中,模拟 Thread 设备的每个实例都将使用不同的文件描述符。

注意:在为模拟设备生成进程时,请仅使用本 Codelab 中所述的 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 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 开头 = 链接本地

网格本地地址类型会进一步分类:

  • 包含 ff:fe00 = 路由器定位器 (RLOC)
  • 不包含 ff:fe00 = 端点标识符 (EID)

确定控制台输出中的 EID,并记下此 ID 以供日后使用。在上面的示例输出中,EID 为:

fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6

2. 启动节点 2

打开新终端并导航到 openthread 目录并生成 CLI 进程。这是您的第二个模拟 Thread 设备:

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/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

设备会将自身初始化为子项。Thread Child 等同于最终设备,End Device 是仅通过父设备传输和接收单播流量的 Thread 设备。

> state
child
Done

在 2 分钟内,您应该会看到状态从 child 切换到 router。Thread Router 能够在 Thread 设备之间路由流量。也称为父级。

> state
router
Done

验证网络

验证网格网络的一种简单方法是查看路由器表。

1. 检查连接性

在 Node 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 |

表中发现 0xa800 的节点 1 的 RLOC,确认它已连接到网格。

2. 从节点 2 对节点 1 进行 ping 操作

验证两个模拟 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 提示符。

测试网络

现在,您可以在两台模拟的线程设备之间成功执行 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

请参阅 OpenThread CLI 参考文档,了解所有可用的 CLI 命令。

5. 使用“调试”对节点进行身份验证

在之前的练习中,您设置了一个包含 2 个模拟设备和一个已验证连接的 Thread 网络。但是,这只允许未经身份验证的 IPv6 链路本地流量在设备之间传递。如需在它们之间(以及通过线程边界路由器在互联网之间)路由全局 IPv6 流量,您必须对节点进行身份验证。

要进行身份验证,必须有一个设备作为专员。Commissioner 是当前当选新 Thread 设备的身份验证服务器,也是用于提供设备加入网络所需的网络凭据的授权方。

在本练习中,我们将使用与之前相同的双节点拓扑。对于身份验证,Thread Leader 将充当 Commissioner,Thread Router 作为 Joiner。

d6a67e8a0d0b5dcb.png

1. 创建网络

如果继续之前的练习,您应该已经打开了两个终端窗口。如果不能,请确保两个应用已打开并可供使用。其中一个将充当节点 1,另一个将充当节点 2。

在节点 1 中,衍生 CLI 进程:

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/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 角色:

> commissioner start
Done

允许任何具有 J01NME 联接器凭据的联接器(通过使用 * 通配符)委托到网络。联接器是由真人管理员添加到委托线程网络的设备。

> commissioner joiner add * J01NME
Done

3. 启动 Joiner 角色

在第二个终端窗口中,生成新的 CLI 进程。这是节点 2。

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 2

在 Node 2 上,使用 J01NME Joiner 凭据启用 Joiner 角色。

> ifconfig up
Done
> joiner start J01NME
Done

... 等待几秒钟进行确认 ...

Join success

作为联接者,设备(节点 2)已成功通过专员(节点 1)对自身进行身份验证,并收到线程网络凭据。

现在,节点 2 已通过身份验证,接下来可以启动线程:

> thread start
Done

4. 验证网络身份验证

检查节点 2 上的 state,验证其现已加入网络。在两分钟内,节点 2 会从 child 转换到 router

> state
child
Done
...
> state
router
Done

5. 重置配置

为了准备下一个练习,请重置配置。在每个节点上,停止线程,恢复出厂设置,然后退出模拟的线程设备:

> thread stop
Done
> factoryreset
>
> exit

使用 factoryreset 命令后,您可能需要按几次 enter 才能返回 > 提示符。

6. 使用 OpenThread 守护程序管理网络

在本练习中,我们将模拟一个 CLI 实例(单个嵌入式 SoC 线程设备)和一个无线电处理器 (RCP) 实例。

ot-daemon 是 OpenThread Posix 应用的模式,它使用 UNIX 套接字作为输入和输出,以便 OpenThread 核心可以作为服务运行。客户端可以通过使用 OpenThread CLI 作为协议连接到套接字来与此服务进行通信。

ot-ctlot-daemon 提供的用于管理和配置 RCP 的 CLI。使用此功能,我们会将 RCP 连接到 Thread 设备创建的网络。

使用 ot-daemon

本练习将使用三个终端窗口,它们对应于以下各项:

  1. 模拟 Thread 设备的 CLI 实例(节点 1)
  2. ot-daemon 个进程
  3. ot-ctl 个 CLI 实例

如果继续之前的练习,您应该已经打开了两个终端窗口。打开第三个实验,以确保此练习有 3 个终端窗口。

1. 启动节点 1

在第一个终端窗口中,为模拟 Thread 设备生成 CLI 进程:

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/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,此 ID 将用于与节点通信。

2. 启动 OT 守护程序

在第二个终端窗口中,转到 openthread 目录,然后启动 RCP 节点的 ot-daemon,我们将该节点称为节点 2。使用 -v 详细标志,以查看日志输出并确认其正在运行,并且请务必使用 sudo

$ cd ~/src/openthread
$ sudo ./build/posix/src/posix/ot-daemon -v \
    'spinel+hdlc+forkpty:///build/simulation/examples/apps/ncp/ot-rcp?forkpty-arg=2'

成功后,详细模式下的 ot-daemon 会生成类似于以下内容的输出:

ot-daemon[12463]: Running OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; POSIX; Aug 30 2022 10:55:05
ot-daemon[12463]: Thread version: 4
ot-daemon[12463]: Thread interface: wpan0
ot-daemon[12463]: RCP version: OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; SIMULATION; Aug 30 2022 10:54:10

使此终端保持打开状态并在后台运行。您无需再在其中输入任何命令。

3. 使用 ot-ctl 加入网络

我们尚未向任何 Thread 网络委托节点 2 (ot-daemon RCP)。这正是ot-ctl的用武之地。ot-ctl 使用与 OpenThread CLI 应用相同的 CLI。因此,您可以使用与其他模拟 Thread 设备相同的方式控制 ot-daemon 节点。

在第三个终端窗口中,启动 ot-ctl

$ sudo ./build/posix/src/posix/ot-ctl
>

注意:运行此命令后,如果系统未显示 > 提示,请按 enter

在此第三个终端窗口中,您将使用 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

作为联接成员,RCP(节点 2)已成功通过委员(节点 1)对自身进行身份验证,并收到线程网络凭据。

现在将 Node 2 加入 Thread 网络:

> thread start
Done

4. 验证网络身份验证

检查节点 2 上的 state,验证其现已加入网络。在两分钟内,节点 2 会从 child 转换到 router

> state
child
Done
...
> state
router
Done

5. 验证连接

使用 Ctrl+Dexit 命令退出 ot-ctl,并在主机的命令行中,通过其 EID 和 ping6 命令 ping 节点 1。如果 ot-daemon RCP 实例成功加入并连接到 Thread 网络,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 模拟您的第一个 Thread 网络。棒极了!

在此 Codelab 中,你学习了如何:

  • 设置 OpenThread 构建工具链
  • 模拟 Thread 网络
  • 对线程节点进行身份验证
  • 使用 OpenThread 守护程序管理 Thread 网络

如需了解详情,请参阅以下参考资料: