1. 简介

什么是 Thread 和 OTNS
Thread 是一种基于 IP 的低功耗无线网状网络协议,可实现安全的设备到设备和设备到云通信。Thread 网络可以适应拓扑变化,以避免出现单点故障。
OpenThread 是 Thread 的开源实现。尽管代码量和内存占用量很小,但 OpenThread 支持 Thread 规范中定义的所有功能。
OpenThread 网络模拟器 (OTNS) 可用于通过在 posix 平台上运行模拟的 OpenThread 节点来模拟 Thread 网络。OTNS 提供了一个易于使用的 Web 界面 (OTNS-Web),用于直观呈现和运行模拟的 Thread 网络。您还可以使用脚本模拟(使用 Python)。
学习内容
- 安装 OTNS 及其依赖项
- 了解 OTNS-CLI 的基础知识
- 如何在 OTNS-Web 中添加/移动/删除 OpenThread 节点
- 使用 OTNS-Web 的其他实用功能来控制网络模拟
- 验证 OpenThread 的无单点故障
- 在 Wireshark 中查看 OpenThread 节点之间的数据流量
此 Codelab 重点介绍 OTNS-CLI 和 OTNS-Web 的互动使用。OTNS 的其他功能(例如 Python 脚本)不在本文档的讨论范围内。
所需条件
- Thread 基础入门。您需要了解 Thread 的基本概念,才能理解此 Codelab 中讲授的内容。
- 最好是 Linux x86_64 或安装了 Homebrew 的 Mac OS。Windows WSL2 中的 Ubuntu 24 或更高版本也应该可以正常运行,但可能需要手动调整一些设置。
- Git。
- 网络浏览器。OTNS-Web 使用网络浏览器显示模拟。
- Wireshark 网络协议分析器(可选)。
- Go 1.23 或更高版本。
- 安装脚本将检查已安装的 Go 版本。
- 如果未安装 Go,则脚本将安装 >= 1.23 的版本(如果软件包管理器中提供)。
- 如果软件包管理器中未提供,则需要手动安装。
- 请注意,Ubuntu 24.04 或更低版本不支持自动安装 Go 1.23。如需了解详情,请参阅 Ubuntu 文档中的可用 Golang 版本页面。您可以手动安装、使用
snap或执行其他程序。
- Python 3.9 或更高版本。
- 安装脚本将检查已安装的 Python 版本。
- 如果尚未安装 Python 3,则脚本将安装 >= 3.9 的版本(如果软件包管理器中提供)。
- 如果软件包管理器中未提供,则需要手动安装。
术语
术语“路由器”用作 Thread 网状网络扩展器的技术术语,该扩展器最初称为 Thread 路由器。“节点”是指 OTNS 模拟中的任何模拟 OpenThread 设备。
2. 安装
获取 OTNS 代码
$ git clone https://github.com/openthread/ot-ns.git ./otns $ cd otns
此 Codelab 中的所有后续控制台命令都从 otns 目录运行。
启动和安装
bootstrap 脚本将安装依赖项(包括 Python 3 和 Go/Golang,如果需要)并安装 OTNS。请注意,如果脚本无法自动安装某些依赖项(例如 Python 版本 >= 3.9 或 Go 版本 >= 1.23),则可能会停止。自动安装需要能够在操作系统的配置软件包代码库中找到软件包。
该脚本还会构建各种 OT 节点类型,这些节点类型可以直接在模拟中使用,并执行一些基本测试。由于这些节点构建,该过程可能需要几分钟时间。
$ ./script/bootstrap .... .... OTNS installed - use 'otns' to start it. $
在执行脚本期间,系统可能会要求您输入 sudo 的密码。
如果 otns 未正确安装
脚本可能会报告如下错误:
.... OTNS installed - please add ~/go/bin to your PATH variable first, to use it. $
在这种情况下,您需要将 $(go env GOPATH)/bin 添加到 $PATH 变量。
如果出现其他错误,您可以创建 GitHub 问题。
3. 首次运行 OTNS
运行 otns:
$ otns >_ ← OTNS-CLI prompt
成功启动后,OTNS 将进入 CLI 控制台 (OTNS-CLI) 并启动网络可视化和管理工具的网络浏览器 (OTNS-Web):

如果您只能看到 OTNS-Web 的空白页面,则可能是因为您的浏览器未启用 WebGL。请参阅 https://superuser.com/a/836833,了解如何启用 WebGL。
在以下部分中,您将学习如何通过 OTNS-CLI 和 OTNS-Web 管理 OTNS 模拟。
4. 了解 OTNS-CLI 和 OTNS-Web
OTNS-CLI
OTNS-CLI 是用于管理 OTNS 模拟的命令行界面 (CLI)。
$ otns >_ ← OTNS-CLI prompt
您可以通过 OTNS-CLI 输入命令。如需查看完整的命令列表,请参阅 OTNS CLI 参考文档。请放心,在此 Codelab 中,您只会使用其中的几个命令。
输入 help 命令,查看 CLI 命令的概览。此列表与 CLI 参考文档相同。
> help add Add a node to the simulation and get the node ID. .... .... Done >
如需获取有关特定命令的更多帮助,请使用该命令的名称,例如:
> help add add Add a node to the simulation and get the node ID. Definition: .... .... >
OTNS-Web
OTNS-Web 是 OTNS 的网络可视化和管理工具。它以直观方式呈现模拟的 Thread 网络的节点、消息和链接。请注意 OTNS-Web 的各种元素:

5. 添加节点
通过 OTNS-CLI 添加节点
将网状网络扩展器(使用 router 节点类型)添加到模拟中:
> add router 1 Done
您应该会在 OTNS-Web 中看到已创建的节点。该节点最初是网状网络扩展器,并在几秒钟后成为 Leader:

为了便于以互动方式启动模拟,每个新的 OpenThread 节点默认使用一组标准网络参数进行调试。
通过 OTNS-CLI 添加更多节点
现在,我们将添加一些不同类型的节点。
> add fed 2 Done > add med 3 Done > add sed 4 Done
等待几秒钟,让节点合并到一个分区中。您应该会在 OTNS-Web 中看到这些节点:

此外,在 OTNS-Web 中,您可以选择任何节点以获取包含有关该节点的更多信息的面板。例如,在下图中,选择了节点 1。面板中的“角色”条目确认它是 Leader。

通过 OTNS-Web 添加节点
您还可以通过 OTNS-Web 添加节点。点击 Action Bar 的 New Router 按钮。您应该会在所选节点的右侧看到正在创建的节点。新的网状网络扩展器应加入现有的 Thread 分区:

此外,点击操作栏上的 FED、MED、SSED 和 BR 按钮,即可创建其他类型的节点。现在应该总共有 9 个节点。如果需要,您可以将一些节点拖动到其他位置,以创建不同的物理网络拓扑。

现在,您已创建一个包含许多节点的一个分区 Thread 网络。在下一部分中,我们将调整模拟速度,使模拟运行得更快。
6. 调整速度
目前,模拟应以 1X 速度运行,这意味着到目前为止的模拟时间与我们创建第一个节点以来的实际时间相同。
通过 OTNS-CLI 调整速度
您可以通过 OTNS-CLI 调整模拟速度。
将模拟速度设置为 100X
> speed 100 Done
您应该会看到节点发送消息的频率比以前高得多。
将模拟速度设置为 MAX
> speed max Done
现在,OTNS 会尽力以最快的速度进行模拟,因此您应该会看到节点发送大量消息。
暂停模拟
> speed 0 Done
将模拟速度设置为 0 会暂停模拟。
以正常速度恢复模拟
> speed 1 Done
将模拟速度设置为大于 0 的值会恢复模拟。
通过 OTNS-Web 调整速度
速度控制按钮
在 Action Bar 上找到速度控制按钮
。这些按钮显示当前的模拟速度,可用于调整模拟速度以及暂停/恢复模拟。
加快模拟速度
您可以点击
按钮,直到速度达到 MAX:
,从而加快模拟速度。
减慢模拟速度
您可以点击
按钮来减慢模拟速度。
暂停模拟
点击
按钮可在模拟运行时暂停模拟。该按钮将更改为
。
恢复模拟
点击
按钮可在模拟暂停时恢复模拟。该按钮将更改回
。
将模拟速度设置为 10X
为了节省时间,请使用
OTNS-CLI 将模拟速度调整为
10X ,以便我们能够更快地观察网络中的拓扑变化。
> speed 10 Done
7. 开启/关闭无线装置
现在,模拟应包含至少 2 个网状网络扩展器(六边形)、可能包含一个边界路由器(正方形)和许多子级,并以 10 倍的速度运行。
找到 2 个网状网络扩展器的当前 Leader(红色边框),然后点击以选择它:

关闭无线通信
点击操作栏上的
按钮,关闭 Leader 节点的无线通信。关闭无线通信后,Leader 将无法发送或接收消息。
等待大约 12 秒(模拟时间为 120 秒),让其他网状网络扩展器或边界路由器成为新的 Leader:

Thread 网络通过形成包含新 Leader 的新分区,自动从 Leader 故障中恢复。新分区还具有新的分区颜色。
开启无线通信
选择无线通信已关闭的 Leader。点击 Action Bar 上的
按钮,恢复无线通信连接:

恢复无线通信连接后,Leader 应重新连接到网络。
8. 移动节点
OTNS 可让用户通过 OTNS-CLI 或 OTNS-Web 轻松移动节点。
通过 OTNS-CLI 移动节点
将边界路由器节点 9 移动到新位置:
> move 9 50 50 Done
通过 OTNS-Web 移动节点
通过拖动将节点 5 一直移动到右下角。由于节点 5 现在超出了其他网状网络扩展器的无线通信覆盖范围,因此它会形成自己的分区,并具有新的分区 ID。您可以通过点击节点在节点信息面板中查看分区 ID。

请注意,节点 5 和节点 9 之间仍然绘制了一条绿线。这通常是由于有关子级的过时信息仍然保留在之前父级的子级表中。或者,这可能是有关节点 9 和节点 5 之间之前网状网络扩展器链接的过时信息。(或者,在这种情况下,甚至可能是呈现 bug。)最终,在适当的超时后,节点上的过时信息会被清除。
9. 删除节点
通过 OTNS-CLI 删除节点
删除节点 5:
> del 5 Done
节点 5 应从模拟中消失:

通过 OTNS-Web 删除节点
选择边界路由器节点 9,然后点击 Action Bar 上的
按钮,删除节点 9:

Node 1 应成为新分区的 Leader,所有剩余节点都将作为子级连接到节点 1。
10. OTNS-CLI 节点上下文
OTNS-CLI 提供节点上下文模式,以便与节点轻松互动,帮助开发者诊断节点的状态。此外,您还可以从此模式启动节点操作。
进入节点上下文模式
输入节点 1 的节点上下文:
> node 1 Done node 1>
CLI 提示符更改为 node 1>,表示当前节点上下文。您可以输入要在节点上执行的 OpenThread CLI 命令,就像直接与节点互动一样。
在节点上下文中执行命令
node 1> state leader Done node 1> channel 11 Done node 1> panid 0xface Done node 1> networkname otns Done node 1> ipaddr fdde:ad00:beef:0:0:ff:fe00:fc00 fdde:ad00:beef:0:0:ff:fe00:b400 fd00:f00d:cafe:0:2505:8719:3685:ebfb fdde:ad00:beef:0:4fd9:b9ba:44e0:96cb fe80:0:0:0:e86a:e07:ec97:777 Done
切换到其他节点上下文
node 1> node 2 Done node 2>
退出节点上下文
node 1> exit Done >
退出节点上下文的另一种方法是使用 node 0 命令。
11. 查看节点日志和数据包捕获
OpenThread 节点日志
默认情况下,OTNS 会为所有模拟的 OpenThread 节点生成详细的日志文件。您可以在 ./tmp 目录中查看这些文件。文件名为 0_。例如,下面显示了日志文件摘录:
7616488 00:00:06.326 [I] MeshForwarder-: Received IPv6 UDP msg, len:90, chksum:5915, ecn:no, from:ca72650db7b856af, sec:no, prio:net, rss:-58.0
7616488 00:00:06.326 [I] MeshForwarder-: src:[fe80:0:0:0:c872:650d:b7b8:56af]:19788
7616488 00:00:06.326 [I] MeshForwarder-: dst:[ff02:0:0:0:0:0:0:1]:19788
7616488 00:00:06.326 [D] Mle-----------: Receive MLE message
7616488 00:00:06.326 [D] Mac-----------: Idle mode: Radio receiving on channel 11
7657544 00:00:06.367 [D] Mac-----------: ==============================[RX len=063]==============================
7657544 00:00:06.367 [D] Mac-----------: | 41 D8 7F CE FA FF FF 46 | 74 5A 33 9E 76 51 4E 7F | A......FtZ3.vQN. |
7657544 00:00:06.367 [D] Mac-----------: | 3B 02 F0 4D 4C 4D 4C 81 | E6 00 15 03 00 00 00 00 | ;..MLML......... |
7657544 00:00:06.367 [D] Mac-----------: | 00 00 00 01 46 86 7D FE | 06 CC DB 94 86 9C 88 0B | ....F.}......... |
7657544 00:00:06.367 [D] Mac-----------: | 1C 1E 26 9B 8D 21 2E 65 | 53 5A 43 4E A2 59 D6 | ..&..!.eSZCN.Y. |
7657544 00:00:06.367 [D] Mac-----------: ------------------------------------------------------------------------
7657544 00:00:06.367 [I] MeshForwarder-: Received IPv6 UDP msg, len:84, chksum:81e6, ecn:no, from:4e51769e335a7446, sec:no, prio:net, rss:-48.0
7657544 00:00:06.367 [I] MeshForwarder-: src:[fe80:0:0:0:4c51:769e:335a:7446]:19788
7657544 00:00:06.367 [I] MeshForwarder-: dst:[ff02:0:0:0:0:0:0:2]:19788
7657544 00:00:06.367 [D] Mac-----------: Idle mode: Radio receiving on channel 11
7833912 00:00:06.543 [I] Mle-----------: AttachState ParentReq -> Idle
7833912 00:00:06.543 [N] RouterTable---: Allocate router id 12
7833912 00:00:06.543 [N] Mle-----------: RLOC16 fffe -> 3000
7833912 set node RLOC16: fffe -> 3000
7833912 00:00:06.543 [D] SubMac--------: RadioShortAddress: 0x3000
7833912 00:00:06.543 [N] Mle-----------: Role detached -> leader
7833912 00:00:06.543 [N] Mle-----------: Partition ID 0x24c35f10
7833912 00:00:06.543 [I] RouterTable---: Route table
7833912 00:00:06.543 [I] RouterTable---: 12 0x3000 - me - leader
左侧显示的是以微秒为单位的绝对模拟时间。hh:mm:ss 时间戳显示的是 OpenThread 节点自己的日志时间戳,该时间戳可能与绝对模拟时间不同。
Wireshark 数据包捕获
默认情况下,所有传输的 IEEE 802.15.4 帧都会捕获到 PCAP 文件 current.pcap 中。您可以在模拟期间或之后通过 Wireshark 读取此文件。由于 Thread 的链路层加密,您需要在 Wireshark 中执行一次性配置操作,以便为 OTNS 正确设置解密密钥。默认情况下,系统会使用一个众所周知的网络密钥,以便 Wireshark 轻松进行帧解密。
如需查看 Wireshark 中 OpenThread 数据包检查的示例,请参阅以下屏幕截图。

如需配置解密密钥,请在菜单中选择 Edit -> Preferences。然后在“Preferences”窗口中,选择 Protocols -> IEEE 802.15.4。点击“Decryption Keys”旁边的 Edit... 按钮。点击 + 以创建新条目,然后输入密钥 00112233445566778899aabbccddeeff(32 个字符),并在“Key hash”字段中选择“Thread hash”。“Decryption key index”可以保留为 0。然后依次点击 OK 和 OK 。现在,加载 OTNS PCAP 文件时应会正确解密。
“Time”列中显示的时间戳(以秒为单位)与 OpenThread 节点日志中显示的绝对模拟时间值相对应。这样可以更轻松地将日志消息与传输或接收的无线通信帧相关联。不过,这些值通常并不完全相同,精确到微秒:在 OpenThread 堆栈请求发送无线通信帧后,模拟的 IEEE 802.15.4 无线通信硬件可能会增加一些额外的延迟。
12. 恭喜
恭喜,您已成功执行第一个 OTNS 模拟!
您已了解如何安装 OTNS 及其依赖项。您已使用 OpenThread 模拟节点启动了 OTNS 模拟。您已了解如何通过 OTNS-CLI 和 OTNS-Web 以各种方式操纵模拟。
您现在知道 OTNS 是什么,以及如何使用 OTNS 模拟 OpenThread 网络。
接下来怎么做?
查看下列 Codelab…
- 使用 OpenThread 模拟 Thread 网络
- 在 Docker 中使用 OpenThread 模拟 Thread 网络
- 使用 nRF52840 板和 OpenThread 构建 Thread 网络