1. บทนำ
Thread คืออะไร
Thread เป็นโปรโตคอลเครือข่าย Mesh ไร้สายที่ใช้ IP และใช้พลังงานต่ำ ซึ่งช่วยให้การสื่อสารระหว่างอุปกรณ์กับอุปกรณ์และอุปกรณ์กับระบบคลาวด์มีความปลอดภัย เครือข่าย Thread สามารถปรับให้เข้ากับการเปลี่ยนแปลงโทโพโลยีเพื่อหลีกเลี่ยงจุดเดียวที่ทำให้เกิดข้อผิดพลาด
OpenThread คืออะไร
OpenThread ที่ Google เปิดตัวเป็นการใช้งาน Thread® แบบโอเพนซอร์ส
Thread Border Router คืออะไร
Thread Border Router จะเชื่อมต่อเครือข่าย Thread กับเครือข่ายอื่นๆ ที่ใช้ IP เช่น Wi-Fi หรืออีเทอร์เน็ต เครือข่าย Thread ต้องมี Border Router เพื่อเชื่อมต่อกับเครือข่ายอื่นๆ Thread Border Router รองรับฟังก์ชันต่อไปนี้อย่างน้อย
- การเชื่อมต่อ IP แบบ 2 ทางระหว่างเครือข่าย Thread กับเครือข่าย Wi-Fi/อีเทอร์เน็ต
- การค้นพบบริการแบบ 2 ทางผ่าน mDNS (ในลิงก์ Wi-Fi/อีเทอร์เน็ต) และ SRP (ในเครือข่าย Thread)
- Thread-over-infrastructure ที่ผสานรวมพาร์ติชัน Thread ผ่านลิงก์ที่ใช้ IP
- การจัดสรร Thread ภายนอก (เช่น โทรศัพท์มือถือ) เพื่อตรวจสอบสิทธิ์และเข้าร่วมอุปกรณ์ Thread กับเครือข่าย Thread
OpenThread Border Router (OTBR) ที่ Google เปิดตัวเป็นการติดตั้งใช้งานโอเพนซอร์สของ Thread Border Router
สิ่งที่คุณจะสร้าง
ในโค้ดแล็บนี้ คุณจะได้ตั้งค่า Thread Border Router และเชื่อมต่อโทรศัพท์มือถือกับอุปกรณ์ปลายทาง Thread ผ่าน Border Router
สิ่งที่คุณจะได้เรียนรู้
- วิธีตั้งค่า OTBR
- วิธีสร้างเครือข่าย Thread ด้วย OTBR
- วิธีสร้างอุปกรณ์ CLI ของ OpenThread ด้วยฟีเจอร์ SRP
- วิธีลงทะเบียนบริการกับ SRP
- วิธีค้นหาและเข้าถึงอุปกรณ์ปลายทางของ Thread
สิ่งที่คุณต้องมี
- เวิร์กสเตชัน Linux สำหรับสร้างและแฟลช Thread RCP, OpenThread CLI และทดสอบมัลติแคสต์ IPv6
- Raspberry Pi สำหรับ Thread Border Router
- ดองเกิล USB Nordic Semiconductor nRF52840 จำนวน 2 ตัว (1 ตัวสำหรับ RCP และ 1 ตัวสำหรับอุปกรณ์ปลายทาง Thread)
- โทรศัพท์ iOS ที่ใช้ iOS 14 เป็นอย่างต่ำ หรือโทรศัพท์ Android ที่ใช้ Android 8.1 เป็นอย่างต่ำ
2. ตั้งค่า OTBR
วิธีที่เร็วที่สุดในการตั้งค่า OTBR คือการทำตามคู่มือการตั้งค่า OTBR
หลังจากตั้งค่า OTBR เสร็จแล้ว ให้ใช้ ot-ctl
เพื่อตรวจสอบว่า OTBR ทำหน้าที่เป็น leader
ของ Thread
$ sudo ot-ctl state leader Done
นอกจากนี้ ให้ตรวจสอบว่า OTBR ได้กำหนดค่าคำนำหน้า off-mesh-routable
(OMR) ในข้อมูลเครือข่าย Thread โดยอัตโนมัติ
$ sudo ot-ctl netdata show Prefixes: Prefixes: fd76:a5d1:fcb0:1707::/64 paos med 4000 Routes: fd49:7770:7fc5:0::/64 s med 4000 Services: 44970 5d c000 s 4000 44970 01 9a04b000000e10 s 4000 Done $ sudo ot-ctl ipaddr fda8:5ce9:df1e:6620:0:ff:fe00:fc11 fda8:5ce9:df1e:6620:0:0:0:fc38 fda8:5ce9:df1e:6620:0:ff:fe00:fc10 fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9 fda8:5ce9:df1e:6620:0:ff:fe00:fc00 fda8:5ce9:df1e:6620:0:ff:fe00:4000 fda8:5ce9:df1e:6620:3593:acfc:10db:1a8d fe80:0:0:0:a6:301c:3e9f:2f5b Done
3. ตั้งค่าอุปกรณ์ปลายทางของไคลเอ็นต์ SRP
สร้างและแฟลช OT CLI
ทำตามขั้นตอนที่ 5 ของCodelab สร้างเครือข่าย Thread ด้วยบอร์ด nRF52840 และ OpenThread เพื่อสร้างและแฟลชอุปกรณ์ปลายทาง CLI ของ nRF52840
แต่โหนด CLI ต้องใช้ฟีเจอร์ OT_SRP_CLIENT
และ OT_ECDSA
แทนที่จะเปิดใช้ OT_COMMISSIONER
และ OT_JOINER
ดังนั้น การเรียกใช้บิลด์แบบเต็มควรมีลักษณะดังนี้
$ script/build nrf52840 USB_trans -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON
เข้าร่วมเครือข่าย Thread
หากต้องการเข้าร่วมเครือข่าย Thread เราต้องรับชุดข้อมูลการปฏิบัติงานที่ใช้งานอยู่จากอุปกรณ์ OTBR กลับไปที่ ot-ctl
แล้วรับชุดข้อมูลที่ใช้งานอยู่
$ sudo ot-ctl dataset active -x 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff Done
กลับไปที่เซสชันหน้าจอโหนดไคลเอ็นต์ SRP แล้วตั้งค่าชุดข้อมูลที่ใช้งานอยู่
> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff Done
จากนั้นเริ่มอินเทอร์เฟซ Thread โดยทำดังนี้
> ifconfig up Done > thread start Done
รอสักครู่แล้วตรวจสอบว่าเข้าร่วมเครือข่ายเทรดสำเร็จหรือไม่ โดยทำดังนี้
> state child Done > netdata show Prefixes: fd76:a5d1:fcb0:1707::/64 paos med 4000 Routes: fd49:7770:7fc5:0::/64 s med 4000 Services: 44970 5d c000 s 4000 44970 01 9a04b000000e10 s 4000 Done > ipaddr fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 fda8:5ce9:df1e:6620:0:ff:fe00:4001 fda8:5ce9:df1e:6620:ed74:123:cc5d:74ba fe80:0:0:0:d4a9:39a0:abce:b02e Done
ตรวจสอบว่าข้อมูลเครือข่ายตรงกับข้อมูลที่พิมพ์ใน OTBR ตอนนี้เราสามารถ Ping ที่อยู่ OMR ของ OTBR ได้แล้ว
> ping fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9 Done > 16 bytes from fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9: icmp_seq=1 hlim=64 time=49ms
4. เผยแพร่บริการในอุปกรณ์ปลายทาง
มีการใช้ mDNS อย่างแพร่หลายในการเผยแพร่บริการ DNS-SD ในลิงก์เฉพาะ แต่ข้อความแบบหลายผู้รับจะใช้แบนด์วิดท์มากเกินไปและจะทำให้แบตเตอรี่ของอุปกรณ์ที่ใช้พลังงานต่ำหมดเร็ว Thread ใช้โปรโตคอล SRP แบบ Unicast เพื่อลงทะเบียนบริการกับ Border Router และอาศัย Border Router ในการโฆษณาบริการในลิงก์ Wi-Fi หรืออีเทอร์เน็ต
เราสามารถลงทะเบียนบริการด้วยคำสั่ง srp client
ไปที่เซสชันหน้าจอโหนดไคลเอ็นต์ SRP แล้วเริ่มไคลเอ็นต์ SRP โดยอัตโนมัติ
> srp client autostart enable Done
ตั้งค่าชื่อโฮสต์ที่จะโฆษณาในลิงก์ Wi-Fi/อีเทอร์เน็ต
> srp client host name ot-host Done
หากต้องการให้อุปกรณ์ในลิงก์ Wi-Fi/Ethernet เข้าถึงอุปกรณ์ปลายทางของ Thread ได้ คุณต้องประกาศที่อยู่ OMR ของอุปกรณ์ปลายทาง
> srp client host address fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 Done
สุดท้าย ให้ลงทะเบียนบริการ _ipps._tcp
ปลอม
> 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
เราได้ดำเนินการตั้งค่าทั้งหมดเสร็จสมบูรณ์แล้ว และควรมีการโฆษณาบริการ _ipps._tcp
ในลิงก์ Wi-Fi/Ethernet ได้เวลาค้นหาและเข้าถึงอุปกรณ์ปลายทางแล้ว
5. ค้นพบบริการ
ค้นพบบริการด้วยโทรศัพท์มือถือ
เราใช้แอป Service Browser เพื่อค้นหาบริการ mDNS ด้วยโทรศัพท์ Android และคุณยังค้นหาแอปที่เทียบเท่าสำหรับอุปกรณ์เคลื่อนที่ iOS ได้ด้วย เปิดแอปและบริการ _ipps._tcp
ควรจะปรากฏขึ้น
ค้นพบบริการที่มีโฮสต์ Linux
หากต้องการค้นหาบริการจากโฮสต์ Linux อื่น คุณสามารถใช้คำสั่ง avahi-browse
ได้
ติดตั้ง avahi-daemon
และ avahi-utils
$ sudo apt-get install -y avahi-daemon avahi-utils
แก้ไขบริการ
$ sudo service avahi-daemon start # Ensure the avahi daemon is started. $ avahi-browse -r _ipps._tcp + wlan0 IPv6 ot-service Secure Internet Printer local = wlan0 IPv6 ot-service Secure Internet Printer local hostname = [ot-host.local] address = [fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927] port = [12345] txt = [] ...
ค้นพบบริการที่มีโฮสต์ macOS
คุณใช้ dns-sd
ใน macOS เพื่อแก้ไขบริการได้โดยทำดังนี้
$ dns-sd -Z _ipps._tcp local. Browsing for _ipps._tcp.local. DATE: ---Sun 14 Mar 2021--- 21:31:42.125 ...STARTING... ; To direct clients to browse a different domain, substitute that domain in place of '@' lb._dns-sd._udp PTR @ ; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names. ; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local ; names with the correct fully-qualified (unicast) domain name of the target host offering the service. _ipps._tcp PTR ot-service._ipps._tcp ot-service._ipps._tcp SRV 0 0 12345 ot-host.local. ; Replace with unicast FQDN of target host ot-service._ipps._tcp TXT "" ...
6. Ping อุปกรณ์ปลายทาง
การปิงจากโทรศัพท์มือถือ
ตัวอย่างเช่น หากใช้โทรศัพท์ Pixel เราจะดูที่อยู่ OMR ของบริการ "ot-service" ที่ลงทะเบียนไว้ก่อนหน้านี้ได้ในหน้ารายละเอียดของอินสแตนซ์บริการในแอป Service Browser
ตอนนี้เราสามารถ Ping ที่อยู่ OMR ด้วยแอป Network Analyzer อื่นได้แล้ว
ขออภัย แอป Network Analyzer เวอร์ชัน Android ไม่รองรับการค้นหา mDNS สำหรับยูทิลิตี ping และเราไม่สามารถ ping ชื่อโฮสต์ ot-host.local
ได้โดยตรง (เราสามารถ ping ชื่อโฮสต์ด้วยแอปเวอร์ชัน iOS)
Ping จากโฮสต์ Linux/macOS
เราเตอร์ขอบ Thread จะส่งการโฆษณาเราเตอร์ ICMPv6 (RA) เพื่อโฆษณาส่วนนำหน้า (ผ่านตัวเลือกข้อมูลส่วนนำหน้า) และเส้นทาง (ผ่านตัวเลือกข้อมูลเส้นทาง) ในลิงก์ Wi-Fi/Ethernet
เตรียมโฮสต์ Linux
คุณต้องตรวจสอบว่าได้เปิดใช้ RA และ RIO ในโฮสต์แล้ว
net.ipv6.conf.wlan0.accept_ra
ควรมีค่าอย่างน้อย1
หากไม่ได้เปิดใช้การส่งต่อ IP และ2
ในกรณีอื่นๆnet.ipv6.conf.wlan0.accept_ra_rt_info_max_plen
ต้องไม่น้อยกว่า64
accept_ra
จะเป็น 1
โดยค่าเริ่มต้นสำหรับการเผยแพร่ส่วนใหญ่ แต่ก็อาจมีแดมอนเครือข่ายอื่นๆ ที่จะลบล้างตัวเลือกนี้ (เช่น dhcpcd
ใน Raspberry Pi จะลบล้าง accept_ra
เป็น 0
) คุณตรวจสอบค่า accept_ra
ได้โดยใช้คำสั่งต่อไปนี้
$ sudo sysctl -n net.ipv6.conf.wlan0.accept_ra 0
และตั้งค่าเป็น 1
(หรือ 2
ในกรณีที่เปิดใช้การส่งต่อ IP) โดยมีค่าดังนี้
$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra=1 Net.ipv6.conf.wlan0.accept_ra = 1
ตัวเลือก accept_ra_rt_info_max_plen
ในการจัดจำหน่าย Linux ส่วนใหญ่จะตั้งค่าเริ่มต้นเป็น 0
ให้ตั้งค่าเป็น 64
โดยใช้คำสั่งต่อไปนี้
$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen=64 net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64
การเปลี่ยนแปลงจะหายไปหลังจากรีบูตโฮสต์ เช่น ต่อท้ายคำสั่งด้านล่างไปยัง /etc/sysctl.conf
เพื่อเปิดใช้ RIO อย่างถาวร
$ net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64
การเปลี่ยนการกำหนดค่าเหล่านั้นอาจสายเกินไปเนื่องจาก OTBR ได้ส่งข้อความ RA ไปแล้ว และช่วงเวลาระหว่างข้อความ RA ที่ไม่ได้ร้องขอ 2 รายการอาจนานหลายร้อยวินาที วิธีหนึ่งคือการยกเลิกการเชื่อมต่อและเชื่อมต่อกับ Wi-Fi AP อีกครั้งเพื่อส่งข้อความ Router Solicitation เพื่อให้ OTBR ตอบกลับด้วย RA ที่ร้องขอ อีกตัวเลือกหนึ่งคือการรีสตาร์ทฟังก์ชันการกำหนดเส้นทางชายแดนใน Border Router โดยทำดังนี้
$ sudo ot-ctl br disable Done $ sudo ot-ctl br enable Done
หากคุณพยายามเชื่อมต่อ Wi-Fi อีกครั้งหรือรีสตาร์ทอินเทอร์เฟซอีเทอร์เน็ต โปรดตรวจสอบว่าไม่ได้ใช้ dhcpcd ในการจัดการเครือข่าย IPv6 ของ Wi-Fi/อีเทอร์เน็ต เนื่องจาก dhcpcd จะลบล้างตัวเลือก accept_ra
ทุกครั้งที่รีสตาร์ทอินเทอร์เฟซ และการกำหนดค่า accept_ra
จะหายไป ต่อท้ายบรรทัดด้านล่างในไฟล์การกำหนดค่า dhcpcd (เช่น /etc/dhcpcd.conf
) เพื่อปิดใช้ IPv6 ใน dhcpcd อย่างชัดเจน
noipv6 noipv6rs
คุณต้องรีบูตเพื่อให้การเปลี่ยนแปลงมีผล
เตรียมโฮสต์ macOS
accept_ra*
ทั้ง 2 ตัวเลือกจะเปิดใช้โดยค่าเริ่มต้น แต่คุณต้องอัปเกรดระบบเป็นอย่างน้อย macOS Big Sur
ปิงชื่อโฮสต์หรือที่อยู่ IPv6
ตอนนี้เราสามารถ Ping ชื่อโฮสต์ ot-host.local
ด้วยคำสั่ง ping -6
(ping6
สำหรับ macOS) ได้แล้ว
$ ping -6 ot-host.local. PING ot-host.local.(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927)) 56 data bytes 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=1 ttl=63 time=170 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=2 ttl=63 time=64.2 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=3 ttl=63 time=22.8 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=4 ttl=63 time=37.7 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=5 ttl=63 time=28.7 ms ...
คำสั่งนี้อาจไม่สำเร็จในโฮสต์ Linux ที่มีข้อผิดพลาด "Name or service not known"
เนื่องจากคำสั่ง ping
ไม่ได้แปลงชื่อ ot-host.local.
ด้วยการค้นหา mDNS เปิด /etc/nsswitch.conf
แล้วเพิ่ม mdns6_minimal
ที่บรรทัดที่ขึ้นต้นด้วย hosts
ดังนี้
hosts: files mdns4_minimal mdns6_minimal dns
แน่นอนว่าคุณสามารถ Ping ที่อยู่ IPv6 ได้โดยตรงเสมอ
$ ping -6 fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 PING fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927) 56 data bytes 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=1 ttl=63 time=32.9 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=2 ttl=63 time=27.8 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=3 ttl=63 time=29.9 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=4 ttl=63 time=73.5 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=5 ttl=63 time=26.4 ms ...
7. ยกเลิกการเผยแพร่บริการในอุปกรณ์ปลายทาง
วิธีนำที่อยู่และบริการที่ลงทะเบียนออกจากโหนดไคลเอ็นต์ SRP
> srp client host remove Done
ตอนนี้คุณไม่ควรจะค้นพบบริการ _ipps._tcp
8. ขอแสดงความยินดี
ขอแสดงความยินดี คุณตั้งค่า OTBR เป็น Thread Border Router เพื่อให้การเชื่อมต่อ IP แบบ 2 ทางและการค้นพบบริการสำหรับอุปกรณ์ปลายทาง Thread เรียบร้อยแล้ว
ขั้นตอนถัดไปคือ
ลองดู Codelab เหล่านี้