Skip to content

GL.iNet OpenThread 边界路由器 Codelabs

应用场景

有两种应用场景方案:直接连接和间接连接。

  • 场景 1, 直接连接, 电脑/手机直接连接 OTBR。
  • 场景 2, 间接连接, 电脑/手机和 OTBR 连接到同一个上级 WiFi 接入点

GL.iNet OTBR 出厂默认配置为方案 1。用户需要根据自己的应用场景在 Web 管理面板 -> THREAD MESH -> 高级 -> 骨干路由器上配置骨干路由器的上级接口。

场景 1, 直接连接

电脑/手机直接连接 OTBR

direct connection

场景 2, 间接连接

电脑/手机和 OTBR 连接到同一个上级 WiFi 接入点

indirect connection

双向 IPv6 连接和基于 DNS 的服务发现

本实验使用以下拓扑图

direct connection

步骤 1: 创建一个 Thread 网络

root@GL-S200:~# uci set otbr.otbr.enable=1
root@GL-S200:~# uci commit otbr

root@GL-S200:~# ot-ctl dataset init new
Done
root@GL-S200:~# ot-ctl dataset commit active
Done
root@GL-S200:~# ot-ctl dataset active
Active Timestamp: 1
Channel: 18
Channel Mask: 0x07fff800
Ext PAN ID: a1fce8946f2f9b1d
Mesh Local Prefix: fd50:5ff6:fd1b:325b::/64
Network Key: e67446d4e450ad76cd3ad5472530d410
Network Name: OpenThread-ee97
PAN ID: 0xee97
PSKc: 42743e8b67c06353cd038520a0ab8b7f
Security Policy: 672 onrc
Done
root@GL-S200:~# ot-ctl ifconfig up
Done
root@GL-S200:~# ot-ctl thread start
Done
root@GL-S200:~# ot-ctl state
leader
Done
root@GL-S200:~# ot-ctl dataset active -x
0e080000000000010000000300001235060004001fffe00208a1fce8946f2f9b1d0708fd505ff6fd1b325b0510e67446d4e450ad76cd3ad5472530d410030f4f70656e5468726561642d656539370102ee97041042743e8b67c06353cd038520a0ab8b7f0c0402a0f7f8
Done
root@GL-S200:~# ot-ctl netdata show
Prefixes:
fd15:5b2d:647f:1::/64 paos low c400
Routes:
fd15:5b2d:647f:2:0:0::/96 sn low c400
fda1:fce8:946f:9b1d::/64 s med c400
Services:
44970 5d fd505ff6fd1b325b84ab8a51482f2df7d11f s c400
44970 01 31000500000e10 s c400
Done
root@GL-S200:~# ot-ctl ipaddr
fd50:5ff6:fd1b:325b:0:ff:fe00:fc11
fd50:5ff6:fd1b:325b:0:ff:fe00:fc38
fd15:5b2d:647f:1:4e73:fe27:fcad:9eb4
fd50:5ff6:fd1b:325b:0:ff:fe00:fc10
fd50:5ff6:fd1b:325b:0:ff:fe00:fc00
fd50:5ff6:fd1b:325b:0:ff:fe00:c400
fd50:5ff6:fd1b:325b:84ab:8a51:482f:2df7
fe80:0:0:0:3488:80b2:ca62:867d
Done

检查手机/电脑上 OTBR 的连接情况。

$ ping -6 -c1 fd15:5b2d:647f:1:4e73:fe27:fcad:9eb4
PING fd15:5b2d:647f:1:4e73:fe27:fcad:9eb4(fd15:5b2d:647f:1:4e73:fe27:fcad:9eb4) 56 data bytes
64 bytes from fd15:5b2d:647f:1:4e73:fe27:fcad:9eb4: icmp_seq=1 ttl=64 time=0.996 ms

--- fd15:5b2d:647f:1:4e73:fe27:fcad:9eb4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.996/0.996/0.996/0.000 ms

步骤 2: 配置 SRP 客户端终端设备

这里在 NRF52840 上执行。

> dataset set active 0e080000000000010000000300001235060004001fffe00208a1fce8946f2f9b1d0708fd505ff6fd1b325b0510e67446d4e450ad76cd3ad5472530d410030f4f70656e5468726561642d656539370102ee97041042743e8b67c06353cd038520a0ab8b7f0c0402a0f7f8
Done
> ifconfig up
Done
> thread start
Done
> state
child
Done
> netdata show
Prefixes:
fd15:5b2d:647f:1::/64 paos low fffe
Routes:
fd15:5b2d:647f:2:0:0::/96 sn low fffe
fda1:fce8:946f:9b1d::/64 s med fffe
Services:
44970 5d fd505ff6fd1b325b84ab8a51482f2df7d11f s fc10
44970 01 31000500000e10 s fc11
Done
> ipaddr
fd15:5b2d:647f:1:75cd:be97:fd26:f3b9
fd50:5ff6:fd1b:325b:0:ff:fe00:c401
fd50:5ff6:fd1b:325b:27af:b1fc:9225:4134
fe80:0:0:0:3873:7703:285d:38eb
Done

检查手机/电脑上的 Thread 设备的连接情况。

$ ping -6 -c1 fd15:5b2d:647f:1:75cd:be97:fd26:f3b9
PING fd15:5b2d:647f:1:75cd:be97:fd26:f3b9(fd15:5b2d:647f:1:75cd:be97:fd26:f3b9) 56 data bytes
64 bytes from fd15:5b2d:647f:1:75cd:be97:fd26:f3b9: icmp_seq=1 ttl=63 time=41.1 ms

--- fd15:5b2d:647f:1:75cd:be97:fd26:f3b9 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 41.148/41.148/41.148/0.000 ms

步骤 3: 在终端设备上发布 SRP 服务

> srp client autostart enable
Done
> srp client host name ot-host
Done
> srp client host address fd15:5b2d:647f:1:75cd:be97:fd26:f3b9
Done
> 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

步骤 4: 在 OTBR 上发现服务

root@GL-S200:~# ot-ctl srp server service
ot-service._ipps._tcp.default.service.arpa.
    deleted: false
    subtypes: (null)
    port: 12345
    priority: 0
    weight: 0
    ttl: 7200
    lease: 7200
    key-lease: 1209600
    TXT: []
    host: ot-host.default.service.arpa.
    addresses: [fd15:5b2d:647f:1:75cd:be97:fd26:f3b9]
Done
root@GL-S200:~# dns-sd -B _ipps._tcp
Browsing for _ipps._tcp
DATE: ---Wed 15 Mar 2023---
 8:41:10.598  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
 8:41:10.600  Add        3   6 local.               _ipps._tcp.          ot-service
 8:41:10.602  Add        2   7 local.               _ipps._tcp.          ot-service
^C
root@GL-S200:~# dns-sd -L ot-service _ipps._tcp.
Lookup ot-service._ipps._tcp..local
DATE: ---Wed 15 Mar 2023---
 8:41:16.522  ...STARTING...
 8:41:16.666  ot-service._ipps._tcp.local. can be reached at ot-host.local.:12345 (interface 6) Flags: 1
 8:41:16.668  ot-service._ipps._tcp.local. can be reached at ot-host.local.:12345 (interface 7)
^C
root@GL-S200:~# dns-sd -G -v6 ot-host.local.
DATE: ---Wed 15 Mar 2023---
 8:41:21.478  ...STARTING...
Timestamp     A/R    Flags if Hostname                               Address                                      TTL
 8:41:21.653  Add        3  6 ot-host.local.                         FD15:5B2D:647F:0001:75CD:BE97:FD26:F3B9%<0>  120
 8:41:21.656  Add        2  7 ot-host.local.                         FD15:5B2D:647F:0001:75CD:BE97:FD26:F3B9%<0>  120
^C
root@GL-S200:~# ping -6 -c1 fd15:5b2d:647f:1:75cd:be97:fd26:f3b9
PING fd15:5b2d:647f:1:75cd:be97:fd26:f3b9 (fd15:5b2d:647f:1:75cd:be97:fd26:f3b9): 56 data bytes
64 bytes from fd15:5b2d:647f:1:75cd:be97:fd26:f3b9: seq=0 ttl=64 time=33.375 ms

--- fd15:5b2d:647f:1:75cd:be97:fd26:f3b9 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 33.375/33.375/33.375 ms

步骤 5: 在 PC 上发现服务

在 macOS 系统上使用 dns-sd

$ dns-sd -B _ipps._tcp
Browsing for _ipps._tcp
DATE: ---Wed 15 Mar 2023---
16:42:03.955  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
16:42:03.958  Add        2   2 local.               _ipps._tcp.          ot-service

$ dns-sd -L ot-service _ipps._tcp.
Lookup ot-service._ipps._tcp..local
DATE: ---Wed 15 Mar 2023---
16:42:13.192  ...STARTING...
16:42:13.193  ot-service._ipps._tcp.local. can be reached at ot-host.local.:12345 (interface 2)

$ dns-sd -G -v6 ot-host.local.
DATE: ---Wed 15 Mar 2023---
16:42:18.168  ...STARTING...
Timestamp     A/R    Flags if Hostname                               Address                                      TTL
16:42:18.169  Add 40000002  2 ot-host.local.                         FD15:5B2D:647F:0001:75CD:BE97:FD26:F3B9%<0>  120

在 Linux 系统上 avahi-browser

$ avahi-browse -rt _ipps._tcp
+  ens33 IPv6 ot-service                                    Secure Internet Printer local
+  ens33 IPv4 ot-service                                    Secure Internet Printer local
=  ens33 IPv6 ot-service                                    Secure Internet Printer local
   hostname = [ot-host.local]
   address = [fd15:5b2d:647f:1:75cd:be97:fd26:f3b9]
   port = [12345]
   txt = []
=  ens33 IPv4 ot-service                                    Secure Internet Printer local
   hostname = [ot-host.local]
   address = [fd15:5b2d:647f:1:75cd:be97:fd26:f3b9]
   port = [12345]
   txt = []

步骤 6: 在 PC 上 Ping 终端设备的本地域名

$ ping -6 -c1 ot-host.local
PING ot-host.local(fd15:5b2d:647f:1:75cd:be97:fd26:f3b9 (fd15:5b2d:647f:1:75cd:be97:fd26:f3b9)) 56 data bytes
64 bytes from fd15:5b2d:647f:1:75cd:be97:fd26:f3b9 (fd15:5b2d:647f:1:75cd:be97:fd26:f3b9): icmp_seq=1 ttl=63 time=30.4 ms

--- ot-host.local ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 30.360/30.360/30.360/0.000 ms

如果 ping 命令返回 Name or service not known,请按如下方式修改 /etc/nsswitch.conf,然后再试一次。域名需能在 OTBR 和 PC 上解析。

hosts:          files mdns4_minimal mdns6_minimal dns

通过 NAT64 提供互联网接入

Nat64 默认已启用。创建 Thread 网络并按照双向 IPv6 连接和基于 DNS 的服务发现实验说明将 Thread 设备连接到网络后,进行以下操作。

  • 访问局域网
> ping 192.168.8.233
Pinging synthesized IPv6 address: fdf8:7dfb:4d50:2:0:0:c0a8:8e9
16 bytes from fdf8:7dfb:4d50:2:0:0:c0a8:8e9: icmp_seq=3 hlim=63 time=15ms
1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 15/15.0/15 ms.
Done
  • 访问互联网
> ping 8.8.8.8
Pinging synthesized IPv6 address: fdf8:7dfb:4d50:2:0:0:808:808
16 bytes from fdf8:7dfb:4d50:2:0:0:808:808: icmp_seq=4 hlim=47 time=75ms
1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 75/75.0/75 ms.
Done
> dns resolve4 google.com 8.8.8.8
Synthesized IPv6 DNS server address: fdf8:7dfb:4d50:2:0:0:808:808
DNS response for google.com. - fdf8:7dfb:4d50:2:0:0:8efb:dc4e TTL:127
Done
> ping fdf8:7dfb:4d50:2:0:0:8efb:dc4e
16 bytes from fdf8:7dfb:4d50:2:0:0:8efb:dc4e: icmp_seq=5 hlim=106 time=96ms
1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 96/96.0/96 ms.
Done

Matter Over Thread

本实验的拓扑结构如下图所示,其中 Matter 控制器运行在 PC 上,Matter 灯和 Matter 灯开关均使用 Silicon Labs EFR32MG24 分线板 REV 1.1 作为 Matter 设备。

matter over thread

步骤 1: 创建一个 Thread 网络

root@GL-S200:~# ot-ctl dataset init new
Done
root@GL-S200:~# ot-ctl dataset commit active
Done
root@GL-S200:~# ot-ctl dataset active
Active Timestamp: 1
Channel: 18
Channel Mask: 0x07fff800
Ext PAN ID: a1fce8946f2f9b1d
Mesh Local Prefix: fd50:5ff6:fd1b:325b::/64
Network Key: e67446d4e450ad76cd3ad5472530d410
Network Name: OpenThread-ee97
PAN ID: 0xee97
PSKc: 42743e8b67c06353cd038520a0ab8b7f
Security Policy: 672 onrc
Done
root@GL-S200:~# ot-ctl ifconfig up
Done
root@GL-S200:~# ot-ctl thread start
Done
root@GL-S200:~# ot-ctl state
leader
Done
root@GL-S200:~# ot-ctl dataset active -x
0e080000000000010000000300001235060004001fffe00208a1fce8946f2f9b1d0708fd505ff6fd1b325b0510e67446d4e450ad76cd3ad5472530d410030f4f70656e5468726561642d656539370102ee97041042743e8b67c06353cd038520a0ab8b7f0c0402a0f7f8
Done
root@GL-S200:~# ot-ctl netdata show
Prefixes:
fd15:5b2d:647f:1::/64 paos low c400
Routes:
fd15:5b2d:647f:2:0:0::/96 sn low c400
fda1:fce8:946f:9b1d::/64 s med c400
Services:
44970 5d fd505ff6fd1b325b84ab8a51482f2df7d11f s c400
44970 01 31000500000e10 s c400
Done
root@GL-S200:~# ot-ctl ipaddr
fd50:5ff6:fd1b:325b:0:ff:fe00:fc11
fd50:5ff6:fd1b:325b:0:ff:fe00:fc38
fd15:5b2d:647f:1:4e73:fe27:fcad:9eb4
fd50:5ff6:fd1b:325b:0:ff:fe00:fc10
fd50:5ff6:fd1b:325b:0:ff:fe00:fc00
fd50:5ff6:fd1b:325b:0:ff:fe00:c400
fd50:5ff6:fd1b:325b:84ab:8a51:482f:2df7
fe80:0:0:0:3488:80b2:ca62:867d
Done

步骤 2: Commissioning

指令格式:

chip-tool pairing ble-thread ${NODE_ID} hex:${DATASET} ${PIN_CODE} ${DISCRIMINATOR}
  • ${NODE_ID}:为委托设备分配一个 ID。该 ID 可以是 RCP 初始化后未使用过的任何非零值,chip-tool将使用该 ID 在该 Matter 设备上进行操作。
  • ${DATASET}: 通过运行命令 ot-ctl dataset active -x 获取。
  • ${PIN_CODE}:如果flash中未配置配对代码,则使用默认配对代码。
  • ${DISCRIMINATOR}:如果flash中未配置配对代码,则使用默认配对代码。

长按 Matter 灯上的 BT0 按钮 6 秒钟以上时,它将进入 commissioning 模式。

sudo ./out/chip-tool/chip-tool pairing ble-thread 1001 hex:0e080000000000010000000300001235060004001fffe00208a1fce8946f2f9b1d0708fd505ff6fd1b325b0510e67446d4e450ad76cd3ad5472530d410030f4f70656e5468726561642d656539370102ee97041042743e8b67c06353cd038520a0ab8b7f0c0402a0f7f8 20202021 3840

长住 Matter 灯开关的 BT0 按钮 6 秒钟以上,进入 commissioning 模式。

sudo ./out/chip-tool/chip-tool pairing ble-thread 1002 hex:0e080000000000010000000300001235060004001fffe00208a1fce8946f2f9b1d0708fd505ff6fd1b325b0510e67446d4e450ad76cd3ad5472530d410030f4f70656e5468726561642d656539370102ee97041042743e8b67c06353cd038520a0ab8b7f0c0402a0f7f8 20202021 3840

如果没有错误,指令的输出结果应如下所示:

[1678871136.912386][3259774:3259774] CHIP:DL: Inet Layer shutdown
[1678871136.912404][3259774:3259774] CHIP:DL: BLE shutdown
[1678871136.913326][3259774:3259774] CHIP:DL: System Layer shutdown

从 PC 发现 Matter 设备

$ avahi-browse -rt _matter._tcp
+ enp0s31f6 IPv6 65D508548AF4E6CD-00000000000003EA             _matter._tcp         local
+ enp0s31f6 IPv6 65D508548AF4E6CD-00000000000003E9             _matter._tcp         local
+ enp0s31f6 IPv4 65D508548AF4E6CD-00000000000003EA             _matter._tcp         local
+ enp0s31f6 IPv4 65D508548AF4E6CD-00000000000003E9             _matter._tcp         local
= enp0s31f6 IPv6 65D508548AF4E6CD-00000000000003EA             _matter._tcp         local
   hostname = [DEE6259B059B0BB6.local]
   address = [fd15:5b2d:647f:1:25b3:9abe:d387:e9aa]
   port = [5540]
   txt = ["T=0" "SAI=2000" "SII=5000"]
= enp0s31f6 IPv6 65D508548AF4E6CD-00000000000003E9             _matter._tcp         local
   hostname = [3EF840EF1D01024D.local]
   address = [fd15:5b2d:647f:1:b5be:90a6:6fde:a8dc]
   port = [5540]
   txt = ["T=0" "SAI=2000" "SII=5000"]
= enp0s31f6 IPv4 65D508548AF4E6CD-00000000000003EA             _matter._tcp         local
   hostname = [DEE6259B059B0BB6.local]
   address = [fd15:5b2d:647f:1:25b3:9abe:d387:e9aa]
   port = [5540]
   txt = ["T=0" "SAI=2000" "SII=5000"]
= enp0s31f6 IPv4 65D508548AF4E6CD-00000000000003E9             _matter._tcp         local
   hostname = [3EF840EF1D01024D.local]
   address = [fd15:5b2d:647f:1:b5be:90a6:6fde:a8dc]
   port = [5540]
   txt = ["T=0" "SAI=2000" "SII=5000"]

$ avahi-browse -rt _matterc._udp
+ enp0s31f6 IPv6 18D347F0BB27870E                              _matterc._udp        local
+ enp0s31f6 IPv4 18D347F0BB27870E                              _matterc._udp        local
= enp0s31f6 IPv6 18D347F0BB27870E                              _matterc._udp        local
   hostname = [DEE6259B059B0BB6.local]
   address = [fd15:5b2d:647f:1:25b3:9abe:d387:e9aa]
   port = [5540]
   txt = ["PI=" "PH=36" "CM=0" "D=3840" "T=0" "SAI=2000" "SII=5000" "VP=65521+32772"]
= enp0s31f6 IPv4 18D347F0BB27870E                              _matterc._udp        local
   hostname = [DEE6259B059B0BB6.local]
   address = [fd15:5b2d:647f:1:25b3:9abe:d387:e9aa]
   port = [5540]
   txt = ["PI=" "PH=36" "CM=0" "D=3840" "T=0" "SAI=2000" "SII=5000" "VP=65521+32772"]

$ ping -6 -c1 3EF840EF1D01024D.local
PING 3EF840EF1D01024D.local(fd15:5b2d:647f:1:b5be:90a6:6fde:a8dc (fd15:5b2d:647f:1:b5be:90a6:6fde:a8dc)) 56 data bytes
64 bytes from fd15:5b2d:647f:1:b5be:90a6:6fde:a8dc (fd15:5b2d:647f:1:b5be:90a6:6fde:a8dc): icmp_seq=1 ttl=63 time=82.9 ms

--- 3EF840EF1D01024D.local ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 82.865/82.865/82.865/0.000 ms

$ ping -6 -c1 DEE6259B059B0BB6.local
PING DEE6259B059B0BB6.local(fd15:5b2d:647f:1:25b3:9abe:d387:e9aa (fd15:5b2d:647f:1:25b3:9abe:d387:e9aa)) 56 data bytes
64 bytes from fd15:5b2d:647f:1:25b3:9abe:d387:e9aa (fd15:5b2d:647f:1:25b3:9abe:d387:e9aa): icmp_seq=1 ttl=63 time=69.3 ms

--- DEE6259B059B0BB6.local ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 69.331/69.331/69.331/0.000 ms

步骤 3: 控制灯

  1. 开关灯

    指令格式 : chip-tool onoff toggle ${NODE_ID} 1

    示例:

    sudo ./out/chip-tool/chip-tool onoff toggle 1001 1
    
  2. 开灯

    指令格式 : chip-tool onoff on ${NODE_ID} 1

    示例:

    sudo ./out/chip-tool/chip-tool onoff on 1001 1
    
  3. 关灯

    指令格式 : chip-tool onoff off ${NODE_ID} 1

    示例:

    sudo ./out/chip-tool/chip-tool onoff off 1001 1
    
  4. 读取灯的状态

    指令格式 : chip-tool onoff read on-off ${NODE_ID} 1

    示例:

    sudo ./out/chip-tool/chip-tool onoff read on-off 1001 1
    

步骤 4: 通过 Matter 开关控制灯光

  1. 设置灯的 ACL,使开关能够控制它

    有关 ACL 参数的解释,请参阅 Matter Core Specification - 9.10.5.3. ACL Attribute

    指令格式 :

    sudo ./out/chip-tool/chip-tool accesscontrol write acl '[{"fabricIndex":1, "privilege":5, "authMode":2, "subjects":[112233, ${switch_node_id}], "targets":null}]' ${lighting_node_id} 0
    

    示例:

    sudo ./out/chip-tool/chip-tool accesscontrol write acl '[{"fabricIndex":1, "privilege":5, "authMode":2, "subjects":[112233, 1002], "targets":null}]' 1001 0
    
  2. 将开关与灯绑定

    指令格式 :

    sudo ./out/chip-tool/chip-tool binding write binding '[{"fabricIndex":1, "node":${lighting_node_id}, "endpoint":1, "cluster":6}]' ${switch_node_id} 1
    

    示例:

    sudo ./out/chip-tool/chip-tool binding write binding '[{"fabricIndex":1, "node":1001, "endpoint":1, "cluster":6}]' 1002 1
    

    完成上述步骤后,即可使用 Matter 开关 BTN1 控制 Matter 灯的开/关状态。

连接 Home Assistant

测试环境

  • Raspberrypi 4B, Debian GNU/Linux 11 (bullseye)
  • GL-S200

参考文档 https://www.home-assistant.io/installation/raspberrypi 在 Raspberrypi 上安装 Home Assistant。

The GL-S200 需要升级到 snapshot firmware.

注意: 由于 Thread 认证的原因,我们短期内不会在稳定固件中发布该功能。

打开 Home Assistant 管理面板, Settings -> Devices&Services -> Thread -> CONFIGURE -> ADD AN OPENTHREAD BORDER ROUTER, 输入链接http://<ip>:8081 并提交。如下图所示, 192.168.90.182 是上级路由分配的 IP。 如果 Home Assistant 是通过 WiFi / 以太网 直接连接到 GL OTBR的,您可以使用 192.168.8.1.

现在,GL.iNet OTBR 已成功添加到首选网络。


仍有问题?请访问我们的 社区论坛.