۱. مقدمه

OpenThread منتشر شده توسط گوگل، یک پیادهسازی متنباز از پروتکل شبکه Thread® است. گوگل نست (Google Nest) OpenThread را منتشر کرده است تا فناوری مورد استفاده در محصولات نست (Nest) را به طور گسترده در دسترس توسعهدهندگان قرار دهد تا توسعه محصولات برای خانههای متصل را تسریع کند.
مشخصات Thread یک پروتکل ارتباطی بیسیم دستگاه به دستگاه مبتنی بر IPv6، قابل اعتماد، امن و کممصرف را برای کاربردهای خانگی تعریف میکند. OpenThread تمام لایههای شبکه Thread شامل IPv6، 6LoWPAN، IEEE 802.15.4 را با امنیت MAC، ایجاد لینک مش و مسیریابی مش پیادهسازی میکند.
در این Codelab، شما OpenThread را روی سختافزار واقعی برنامهنویسی خواهید کرد، یک شبکه Thread ایجاد و مدیریت خواهید کرد و پیامها را بین گرهها رد و بدل خواهید کرد.

آنچه یاد خواهید گرفت
- ساخت و فلش کردن فایلهای باینری OpenThread CLI به بردهای توسعه
- ساخت یک RCP متشکل از یک دستگاه لینوکس و یک برد توسعه
- برقراری ارتباط با یک RCP با استفاده از OpenThread Daemon و
ot-ctl - مدیریت دستی گرههای Thread با GNU Screen و OpenThread CLI
- راهاندازی امن دستگاهها بر روی شبکه Thread
- نحوه عملکرد چندپخشی IPv6
- انتقال پیام بین گرههای Thread با UDP
آنچه نیاز دارید
سختافزار:
- ۳ برد توسعهی nRF52840 از شرکت Nordic Semiconductor
- ۳ کابل USB به Micro-USB برای اتصال بردها
- یک دستگاه لینوکس با حداقل ۳ پورت USB
نرمافزار:
- زنجیره ابزار گنو
- ابزارهای خط فرمان Nordic nRF5x
- نرمافزار Segger J-Link
- باز کردن
- گیت
۲. شروع کار
شبیهسازی OpenThread
قبل از شروع، شاید بخواهید OpenThread Simulation Codelab را بررسی کنید تا با مفاهیم اولیه Thread و رابط خط فرمان OpenThread آشنا شوید.
ترمینالهای پورت سریال
شما باید با نحوه اتصال به پورت سریال از طریق ترمینال آشنا باشید. این Codelab از GNU Screen استفاده میکند و یک مرور کلی از نحوه استفاده از آن ارائه میدهد، اما میتوان از هر نرمافزار ترمینال دیگری نیز استفاده کرد.
دستگاه لینوکس
این Codelab به گونهای طراحی شده است که از یک دستگاه لینوکس مبتنی بر i386 یا x86 به عنوان میزبان یک دستگاه Thread با پردازنده کمکی رادیویی (RCP) استفاده کند و تمام بردهای توسعه Thread را فلش کند. تمام مراحل روی Ubuntu 14.04.5 LTS (Trusty Tahr) آزمایش شده است.
بردهای نیمههادی نوردیک nRF52840
این Codelab از سه برد nRF52840 PDK استفاده میکند.

نصب SEGGER J-Link
ما از SEGGER J-Link برای برنامهریزی بردهای nRF52840 که دارای ماژولهای JTAG داخلی هستند استفاده میکنیم. این برنامه را روی دستگاه لینوکس خود نصب کنید.
بسته مناسب دستگاه خود را دانلود کنید و آن را در محل مناسب نصب کنید. در لینوکس این مسیر /opt/SEGGER/JLink است.
نصب ابزارهای خط فرمان nRF5x
ابزارهای خط فرمان nRF5x به شما امکان میدهند فایلهای باینری OpenThread را روی بردهای nRF52840 فلش کنید. نسخه nRF5x-Command-Line-Tools-<OS> مناسب را روی دستگاه لینوکس خود نصب کنید.
بسته استخراجشده را در پوشه ریشه قرار دهید ~/
نصب ARM GNU Toolchain
از ARM GNU Toolchain برای ساخت استفاده میشود.
توصیه میکنیم فایل فشردهی استخراجشده را در مسیر /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ در دستگاه لینوکس خود قرار دهید. برای دستورالعملهای نصب، دستورالعملهای موجود در فایل readme.txt موجود در فایل فشرده را دنبال کنید.
نصب صفحه نمایش (اختیاری)
Screen ابزاری ساده برای دسترسی به دستگاههای متصل به پورت سریال است. این Codelab از Screen استفاده میکند، اما شما میتوانید از هر برنامه ترمینال پورت سریالی که مایل هستید استفاده کنید.
$ sudo apt-get install screen
۳. کلون کردن مخازن
باز کردن
OpenThread را کلون و نصب کنید. دستورات script/bootstrap اطمینان حاصل میکنند که toolchain نصب شده و محیط به درستی پیکربندی شده است:
$ mkdir -p ~/src $ cd ~/src $ git clone --recursive https://github.com/openthread/openthread.git $ cd openthread $ ./script/bootstrap
ساخت دیمون OpenThread:
$ script/cmake-build posix -DOT_DAEMON=ON
اکنون آماده ساخت و فلش کردن OpenThread روی بردهای nRF52840 هستید.
۴. RCP Joiner را تنظیم کنید
ساخت و فلش کردن
مثال OpenThread nRF52840 را با Joiner و قابلیت USB بومی بسازید. یک دستگاه از نقش Joiner برای احراز هویت ایمن و راهاندازی در یک شبکه Thread استفاده میکند. USB بومی امکان استفاده از USB CDC ACM را به عنوان یک انتقال سریال بین nRF52840 و میزبان فراهم میکند.
همیشه ابتدا مخزن نسخههای قبلی را با اجرای دستور rm -rf build پاک کنید.
$ cd ~/src $ git clone --recursive https://github.com/openthread/ot-nrf528xx.git $ cd ot-nrf528xx $ script/build nrf52840 USB_trans
به دایرکتوری حاوی فایل باینری OpenThread RCP بروید و آن را به فرمت هگز تبدیل کنید:
$ cd ~/src/ot-nrf528xx/build/bin $ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex
کابل USB را به پورت اشکالزدایی Micro-USB کنار پین تغذیه خارجی روی برد nRF52840 وصل کنید و سپس آن را به دستگاه لینوکس وصل کنید. سوئیچ منبع تغذیه nRF روی برد nRF52840 را روی VDD تنظیم کنید. در صورت اتصال صحیح، LED5 روشن میشود.

اگر این اولین برد متصل به دستگاه لینوکس باشد، به صورت پورت سریال /dev/ttyACM0 ظاهر میشود (همه بردهای nRF52840 از ttyACM برای شناسه پورت سریال استفاده میکنند).
$ ls /dev/ttyACM* /dev/ttyACM0
به شماره سریال برد nRF52840 که برای RCP استفاده میشود توجه کنید:

به محل ابزارهای خط فرمان nRFx بروید و فایل hex مربوط به OpenThread RCP را با استفاده از شماره سریال برد، روی برد nRF52840 فلش کنید. توجه داشته باشید که اگر پرچم --verify را حذف کنید، یک پیام هشدار مشاهده خواهید کرد که به شما میگوید فرآیند فلش میتواند بدون خطا با شکست مواجه شود.
$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \
~/src/ot-nrf528xx/build/bin/ot-rcp.hex --reset
خروجی زیر پس از موفقیت تولید میشود:
Parsing hex file. Erasing user available code and UICR flash areas. Applying system reset. Checking that the area to write is not protected. Programing device. Applying system reset. Run.
روی برد برچسب «RCP» بزنید تا بعداً نقشهای برد را با هم اشتباه نگیرید.
به USB اصلی متصل شوید
از آنجا که ساخت OpenThread RCP امکان استفاده از USB CDC ACM بومی را به عنوان یک انتقال سریال فراهم میکند، شما باید از پورت USB nRF روی برد nRF52840 برای ارتباط با میزبان RCP (دستگاه لینوکس) استفاده کنید.
سر میکرو USB کابل USB را از پورت اشکالزدایی برد nRF52840 فلش شده جدا کنید، سپس آن را دوباره به پورت میکرو USB nRF USB کنار دکمه RESET وصل کنید. سوئیچ منبع تغذیه nRF را روی USB تنظیم کنید.

شروع OpenThread Damon
در طراحی RCP، از OpenThread Daemon برای ارتباط با دستگاه Thread و مدیریت آن استفاده کنید. ot-daemon با پرچم verbose -v شروع کنید تا بتوانید خروجی گزارش را مشاهده کنید و تأیید کنید که در حال اجرا است:
$ cd ~/src/openthread
$ sudo ./build/posix/src/posix/ot-daemon -v \
'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=460800'
در صورت موفقیت، ot-daemon در حالت verbose خروجی مشابه زیر تولید میکند:
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
این پنجره ترمینال را باز بگذارید تا بتوانید گزارشهای ot-daemon را مشاهده کنید.
برای ارتباط با گره RCP ot-ctl استفاده کنید. ot-ctl از همان رابط خط فرمان (CLI) برنامه OpenThread CLI استفاده میکند. بنابراین، میتوانید گرههای ot-daemon را به همان شیوه سایر دستگاههای Thread شبیهسازی شده کنترل کنید.
در پنجره ترمینال دوم، ot-ctl را اجرا کنید:
$ sudo ./build/posix/src/posix/ot-ctl >
state گره ۲ (گره RCP) که با ot-daemon شروع کردید را بررسی کنید:
> state disabled Done
۵. FTD ها را تنظیم کنید
دو گره Thread دیگر که در این Codelab استفاده شدهاند، دستگاههای Full Thread (FTD) در طراحی استاندارد System-on-Chip (SoC) هستند. یکی از دستگاهها به عنوان کمیسر (Commissioner) عمل میکند تا دستگاهها را به طور ایمن احراز هویت و به شبکه متصل کند. دستگاه دیگر به عنوان یک Joiner عمل میکند که کمیسر میتواند آن را به شبکه Thread احراز هویت کند.
ساخت و فلش کردن
مثال OpenThread FTD را برای پلتفرم nRF52840 بسازید، در حالی که نقشهای Commissioner و Joiner فعال هستند:
$ cd ~/src/ot-nrf528xx $ rm -rf build $ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON
به دایرکتوری حاوی فایل باینری OpenThread Full Thread Device (FTD) CLI بروید و آن را به فرمت هگز تبدیل کنید:
$ cd ~/src/ot-nrf528xx/build/bin $ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
کابل USB را به پورت Micro-USB کنار پین تغذیه خارجی روی برد nRF52840 وصل کنید و سپس آن را به دستگاه لینوکس وصل کنید. اگر RCP هنوز به دستگاه لینوکس متصل است، این برد جدید باید به صورت پورت سریال /dev/ttyACM1 ظاهر شود (همه بردهای nRF52840 از ttyACM برای شناسه پورت سریال استفاده میکنند).
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1
مانند قبل، شماره سریال برد nRF52840 که برای FTD استفاده میشود را یادداشت کنید:

به محل ابزارهای خط فرمان nRFx بروید و فایل hex FTD OpenThread CLI را با استفاده از شماره سریال برد، روی برد nRF52840 فلش کنید:
$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \
~/src/ot-nrf528xx/build/bin/ot-cli-ftd.hex --reset
روی تخته برچسب «کمیسر» بزنید.
به USB اصلی متصل شوید
از آنجا که ساخت OpenThread FTD امکان استفاده از USB CDC ACM بومی را به عنوان یک انتقال سریال فراهم میکند، شما باید از پورت USB nRF روی برد nRF52840 برای ارتباط با میزبان RCP (دستگاه لینوکس) استفاده کنید.
سر میکرو USB کابل USB را از پورت اشکالزدایی برد nRF52840 فلش شده جدا کنید، سپس آن را دوباره به پورت میکرو USB nRF USB کنار دکمه RESET وصل کنید. سوئیچ منبع تغذیه nRF را روی USB تنظیم کنید.

تأیید ساخت
با دسترسی به OpenThread CLI با استفاده از GNU Screen از یک پنجره ترمینال، ساخت موفقیتآمیز را تأیید کنید.
$ screen /dev/ttyACM1
در پنجره جدید، چند بار کلید Return را روی صفحه کلید فشار دهید تا پنجره OpenThread CLI > ظاهر شود. رابط IPv6 را باز کنید و آدرسها را بررسی کنید:
> ifconfig up Done > ipaddr fe80:0:0:0:1cd6:87a9:cb9d:4b1d Done
از Ctrl+a استفاده کنید →
d برای جدا شدن از صفحه CLI کمیسر FTD و بازگشت به ترمینال لینوکس بزنید تا برد بعدی بتواند فلش شود. برای ورود مجدد به CLI در هر زمان، screen -r از خط فرمان استفاده کنید. برای دیدن لیستی از صفحههای نمایش موجود، از screen -ls استفاده کنید:
$ screen -ls
There is a screen on:
74182.ttys000.mylinuxmachine (Detached)
1 Socket in /tmp/uscreens/S-username.
راه اندازی FTD Joiner
فرآیند بالا را برای فلش کردن برد سوم nRF52840 با استفاده از فایل ot-cli-ftd.hex موجود تکرار کنید. پس از اتمام کار، حتماً برد را با استفاده از پورت USB nRF به کامپیوتر وصل کنید و سوئیچ منبع تغذیه nRF را روی VDD تنظیم کنید.
اگر دو گره دیگر هنگام اتصال این برد سوم به دستگاه لینوکس متصل باشند، باید به صورت پورت سریال /dev/ttyACM2 ظاهر شود:
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1 /dev/ttyACM2
تخته را با برچسب «وصلکننده» علامتگذاری کنید.
هنگام تأیید با استفاده از Screen، به جای ایجاد یک نمونه جدید از Screen از خط فرمان، آن را به نمونه موجود متصل کنید و یک پنجره جدید درون آن ایجاد کنید (که برای FTD Commissioner استفاده کردید):
$ screen -r
با استفاده از کلیدهای Ctrl+a → c پنجره جدید را درون Screen ایجاد کنید .
یک خط فرمان جدید ظاهر میشود. برای FTD Joiner به OpenThread CLI دسترسی پیدا کنید:
$ screen /dev/ttyACM2
در این پنجره جدید، چند بار کلید Return را روی صفحه کلید فشار دهید تا پنجره OpenThread CLI > ظاهر شود. رابط IPv6 را باز کنید و آدرسها را بررسی کنید:
> ifconfig up Done > ipaddr fe80:0:0:0:6c1e:87a2:df05:c240 Done
اکنون که رابط خط فرمان FTD Joiner در همان نمونه Screen و FTD Commissioner قرار دارد، میتوانید با استفاده از Ctrl+a → n بین آنها جابجا شوید.
از Ctrl+a استفاده کنید →
در هر زمانی برای خروج از صفحه، d .
۶. تنظیمات پنجره ترمینال
از این به بعد، شما مرتباً بین دستگاههای Thread جابجا خواهید شد، بنابراین مطمئن شوید که همه آنها فعال و به راحتی قابل دسترسی هستند. تاکنون، ما از Screen برای دسترسی به دو FTD استفاده میکردیم و این ابزار همچنین امکان تقسیم صفحه نمایش در همان پنجره ترمینال را فراهم میکند. از این ابزار برای مشاهده نحوه واکنش یک گره به دستورات صادر شده در گره دیگر استفاده کنید.
در حالت ایدهآل، باید چهار پنجره به راحتی در دسترس داشته باشید:
- سرویس / گزارشهای
ot-daemon - RCP Joiner از طریق
ot-ctl - کمیسر FTD از طریق OpenThread CLI
- FTD Joiner از طریق OpenThread CLI
اگر مایل به استفاده از پیکربندی یا ابزار ترمینال/پورت سریال خودتان هستید، میتوانید از مرحله بعدی صرف نظر کنید. پنجرههای ترمینال را برای همه دستگاهها به روشی که برای شما مناسبتر است پیکربندی کنید.
با استفاده از صفحه نمایش
برای سهولت استفاده، فقط یک جلسه Screen را شروع کنید. شما باید از قبل یکی از آنها را از زمان تنظیم هر دو FTD داشته باشید.
تمام دستورات درون Screen با Ctrl+a شروع میشوند.
دستورات پایه صفحه نمایش:
اتصال مجدد به جلسه Screen (از خط فرمان) | |
جلسه Screen را ترک کنید | Ctrl+a → |
ایجاد پنجره جدید در جلسه Screen | Ctrl+a → |
جابجایی بین پنجرهها در یک جلسه Screen | Ctrl+a → |
پنجره فعلی را در جلسه Screen ببندید | Ctrl+a → |
تقسیم صفحه
با استفاده از Screen، میتوانید ترمینال را به چندین پنجره تقسیم کنید:

دستورات موجود در screen با استفاده از Ctrl+a قابل دسترسی هستند. هر دستور باید با این ترکیب کلید دسترسی شروع شود.
اگر دقیقاً از Codelab پیروی کردهاید، باید دو پنجره (FTD Commissioner، FTD Joiner) روی یک نمونه Screen داشته باشید. برای تقسیم صفحه نمایش بین این دو، ابتدا وارد جلسه Screen موجود خود شوید:
$ screen -r
شما باید روی یکی از دستگاههای FTD باشید. این مراحل را در صفحه نمایش دنبال کنید:
- Ctrl+a →
Sبرای تقسیم پنجره به صورت افقی - Ctrl+a →
Tabبرای انتقال مکاننما به پنجره خالی جدید - Ctrl+a →
nبرای رفتن به پنجره جدید - اگر مشابه پنجره بالایی است، دوباره Ctrl+a →
nبزنید تا دستگاه FTD دیگر را مشاهده کنید.
اکنون هر دو قابل مشاهده هستند. با استفاده از Ctrl+a → Tab بین آنها جابجا شوید. توصیه میشود برای جلوگیری از سردرگمی، عنوان هر پنجره را با Ctrl+a → A تغییر دهید.
استفاده پیشرفته
برای تقسیم بیشتر صفحه به ربعها و مشاهده گزارشهای ot-daemon و RCP Joiner ot-ctl ، این سرویسها باید در همان نمونه Screen شروع شوند. برای انجام این کار، ot-daemon را متوقف کرده و از ot-ctl خارج شوید و آنها را در پنجرههای Screen جدید مجدداً راهاندازی کنید (Ctrl+a → c ).
این تنظیمات الزامی نیست و به عنوان تمرین برای کاربر گذاشته شده است.
با استفاده از دستورات زیر، پنجرهها را تقسیم و بین آنها حرکت کنید:
ایجاد پنجره جدید | Ctrl+a → |
تقسیم پنجره به صورت عمودی | کنترل+الف → |
تقسیم پنجره به صورت افقی | Ctrl+a → |
پرش به پنجره نمایش داده شده بعدی | Ctrl+a → |
پنجره نمایش داده شده را به جلو یا عقب تغییر دهید | Ctrl+a → |
تغییر نام پنجره فعلی | Ctrl+a → |
در هر زمانی با Ctrl+a → d از Screen خارج شوید و با screen -r از خط فرمان دوباره آن را وصل کنید.
برای اطلاعات بیشتر در مورد Screen، به مرجع سریع GNU Screen مراجعه کنید.
۷. شبکه Thread را ایجاد کنید
حالا که تمام پنجرهها و صفحات ترمینال خود را پیکربندی کردهاید، بیایید شبکه Thread خود را ایجاد کنیم. در FTD Commissioner ، یک Operational Dataset جدید ایجاد کنید و آن را به عنوان فعال ثبت کنید. Operational Dataset پیکربندی شبکه Thread ای است که شما ایجاد میکنید.
## FTD Commissioner ## ---------------------- > dataset init new Done > dataset Active Timestamp: 1 Channel: 11 Channel Mask: 07fff800 Ext PAN ID: c0de7ab5c0de7ab5 Mesh Local Prefix: fdc0:de7a:b5c0/64 Network Key: 1234c0de7ab51234c0de7ab51234c0de Network Name: OpenThread-c0de PAN ID: 0xc0de PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4 Security Policy: 0, onrcb Done
کلید شبکه 1234c0de7ab51234c0de7ab51234c0de را که بعداً استفاده خواهد شد، یادداشت کنید.
این مجموعه داده را به عنوان مجموعه داده فعال ثبت کنید:
> dataset commit active Done
رابط IPv6 را اجرا کنید:
> ifconfig up Done
شروع عملیات پروتکل Thread:
> thread start Done
بعد از لحظهای، وضعیت دستگاه را بررسی کنید. باید در حالت Leader باشد. همچنین RLOC16 را برای مراجعات بعدی تهیه کنید.
## FTD Commissioner ## ---------------------- > state leader Done > rloc16 0c00 Done
آدرسهای IPv6 دستگاه را بررسی کنید:
## FTD Commissioner ## ---------------------- > ipaddr fdc0:de7a:b5c0:0:0:ff:fe00:fc00 # Leader Anycast Locator (ALOC) fdc0:de7a:b5c0:0:0:ff:fe00:c00 # Routing Locator (RLOC) fdc0:de7a:b5c0:0:6394:5a75:a1ad:e5a # Mesh-Local EID (ML-EID) fe80:0:0:0:1cd6:87a9:cb9d:4b1d # Link-Local Address (LLA)
شبکهی «codelab» اکنون هنگام اسکن از سایر دستگاههای Thread قابل مشاهده است.
از ot-ctl روی RCP Joiner :
## RCP Joiner ## ---------------- > scan | PAN | MAC Address | Ch | dBm | LQI | +------+------------------+----+-----+-----+ | c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |
از OpenThread CLI در FTD Joiner :
## FTD Joiner ## ---------------- > scan | PAN | MAC Address | Ch | dBm | LQI | +------+------------------+----+-----+-----+ | c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |
اگر شبکه "codelab" در لیست ظاهر نشد، دوباره اسکن را امتحان کنید.
۸. RCP Joiner را اضافه کنید
راهاندازی نخ (Thread Commissioning) در شبکه فعال نیست، به این معنی که باید RCP Joiner را با استفاده از یک فرآیند راهاندازی خارج از باند (out-of-band) به شبکه نخی که ایجاد کردهایم اضافه کنیم.
در FTD Commissioner ، ما کلید شبکه را یادداشت کردیم، برای مثال 1234c0de7ab51234c0de7ab51234c0de . اگر نیاز دارید دوباره کلید شبکه را جستجو کنید، دستور زیر را در FTD Commissioner اجرا کنید:
## FTD Commissioner ## > dataset networkkey 1234c0de7ab51234c0de7ab51234c0de Done
در مرحله بعد، در RCP Joiner ، کلید شبکه مجموعه داده فعال آن را روی کلید شبکه کمیسر FTD تنظیم کنید:
## RCP Joiner ## ---------------- > dataset networkkey 1234c0de7ab51234c0de7ab51234c0de Done > dataset commit active Done
مجموعه دادهها را بررسی کنید تا از تنظیم صحیح آنها اطمینان حاصل شود.
## RCP Joiner ## ---------------- > dataset Network Key: 1234c0de7ab51234c0de7ab51234c0de
Thread را اجرا کنید تا RCP Joiner به شبکه "codelab" بپیوندد. چند ثانیه صبر کنید، وضعیت، RLOC16 و آدرسهای IPv6 آن را بررسی کنید:
## RCP Joiner ## ---------------- > ifconfig up Done > thread start Done > state child Done > rloc16 0c01 Done > ipaddr fdc0:de7a:b5c0:0:0:ff:fe00:0c01 # Routing Locator (RLOC) fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f # Mesh-Local EID (ML-EID) fe80:0:0:0:18e5:29b3:a638:943b # Link-Local Address (LLA) Done
آدرس IPv6 مش-محلی ( fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f ) را یادداشت کنید، بعداً از آن استفاده خواهید کرد.
به FTD Commissioner برگردید، جداول روتر و فرزند را بررسی کنید تا مطمئن شوید هر دو دستگاه بخشی از یک شبکه هستند. از RLOC16 برای شناسایی RCP Joiner استفاده کنید.
## FTD Commissioner ## ---------------------- > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+-------+--------+-----+------------------+ | 3 | 0x0c00 | 3 | 0 | 0 | 0 | 35 | 1ed687a9cb9d4b1d | Done > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|S|D|VER| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+---+------------------+ | 1 | 0x0c01 | 240 | 25 | 3 | 89 |1|1|1| 2| 1ae529b3a638943b | Done
برای تأیید اتصال، آدرس مش-لوکال RCP Joiner (آدرس مش-لوکال به دست آمده از خروجی ipaddr RCP Joiner) را پینگ کنید:
## FTD Commissioner ## ---------------------- > ping fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f > 8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=1 hlim=64 time=40ms
اکنون یک شبکه Thread متشکل از دو گره داریم که توسط این نمودار توپولوژی نشان داده شده است:

نمودارهای توپولوژی
همانطور که در ادامهی Codelab کار میکنید، هر زمان که وضعیت شبکه تغییر کند، یک نمودار توپولوژی Thread جدید نشان خواهیم داد. نقشهای گره به شرح زیر مشخص میشوند:

روترها همیشه پنج ضلعی و دستگاههای انتهایی همیشه دایره هستند. اعداد روی هر گره، بسته به نقش و وضعیت فعلی هر گره در آن زمان، نشاندهنده شناسه روتر یا شناسه فرزند نشان داده شده در خروجی CLI هستند.
۹. استخدام نصاب FTD
حالا بیایید سومین دستگاه Thread را به شبکه "codelab" اضافه کنیم. این بار قصد داریم از فرآیند راهاندازی درون باند امنتر استفاده کنیم و فقط به FTD Joiner اجازه اتصال بدهیم.
در FTD Joiner ، مقدار eui64 را دریافت کنید تا کمیسر FTD بتواند آن را شناسایی کند:
## FTD Joiner ## ---------------- > eui64 2f57d222545271f1 Done
در FTD Commissioner ، آن را اجرا کنید و eui64 دستگاهی که میتواند به آن بپیوندد را به همراه Joiner Credential، مثلاً J01NME ، مشخص کنید. Joiner Credential یک رشته مختص دستگاه است که از تمام کاراکترهای حروف بزرگ و عددی (0-9 و AY، به جز I، O، Q و Z برای خوانایی) با طول بین 6 تا 32 کاراکتر تشکیل شده است.
## FTD Commissioner ## ---------------------- > commissioner start Done > commissioner joiner add 2f57d222545271f1 J01NME Done
به FTD Joiner بروید. نقش Joiner را با اعتبارنامه Joiner که اخیراً در FTD Commissioner تنظیم کردهاید، شروع کنید:
## FTD Joiner ## ---------------- > ifconfig up Done > joiner start J01NME Done
ظرف یک دقیقه یا بیشتر، تأیید احراز هویت موفقیتآمیز را دریافت میکنید:
## FTD Joiner ## ---------------- > Join success
Thread را اجرا کنید تا FTD Joiner به شبکه "codelab" بپیوندد و بلافاصله وضعیت و RLOC16 را بررسی کنید:
## FTD Joiner ## ---------------- > thread start Done > state child Done > rloc16 0c02 Done
آدرسهای IPv6 دستگاه را بررسی کنید. توجه داشته باشید که هیچ ALOC وجود ندارد. به این دلیل است که این دستگاه Leader نیست و همچنین نقش خاصی در Anycast ندارد که نیاز به ALOC داشته باشد.
## FTD Joiner ## ---------------- > ipaddr fdc0:de7a:b5c0:0:0:ff:fe00:c02 # Routing Locator (RLOC) fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd # Mesh-Local EID (ML-EID) fe80:0:0:0:e4cd:d2d9:3249:a243 # Link-Local Address (LLA)
فوراً به کمیسر FTD بروید و جداول روتر و فرزند را بررسی کنید تا تأیید کنید که سه دستگاه در شبکه "codelab" وجود دارد:
## FTD Commissioner ## ---------------------- > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+-------+--------+-----+------------------+ | 3 | 0x0c00 | 3 | 0 | 0 | 0 | 50 | 1ed687a9cb9d4b1d | > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|S|D|N| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+-+------------------+ | 1 | 0x0c01 | 240 | 25 | 3 | 89 |1|1|1|1| 1ae529b3a638943b | | 2 | 0x0c02 | 240 | 15 | 3 | 44 |1|1|1|1| e6cdd2d93249a243 | Done
بر اساس RLOC16، FTD Joiner به عنوان یک دستگاه انتهایی (فرزند) به شبکه متصل شده است. توپولوژی بهروز شده ما به شرح زیر است:

۱۰. نخ در عمل
دستگاههای Thread در این Codelab نوع خاصی از Full Thread Device (FTD) هستند که Router Eligible End Device (REED) نامیده میشوند. این بدان معناست که آنها میتوانند به عنوان یک Router یا End Device عمل کنند و میتوانند خود را از یک End Device به یک Router ارتقا دهند.
Thread میتواند تا ۳۲ روتر را پشتیبانی کند، اما سعی میکند تعداد روترها را بین ۱۶ تا ۲۳ نگه دارد. اگر یک REED به عنوان یک دستگاه انتهایی (فرزند) متصل شود و تعداد روترها کمتر از ۱۶ باشد، پس از یک دوره زمانی تصادفی در عرض دو دقیقه، به طور خودکار خود را به یک روتر ارتقا میدهد.
اگر پس از افزودن FTD Joiner، دو فرزند در شبکه Thread خود داشتید، حداقل دو دقیقه صبر کنید و سپس جداول روتر و فرزند را در FTD Commissioner دوباره بررسی کنید:
## FTD Commissioner ## ---------------------- > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+-------+--------+-----+------------------+ | 3 | 0x0c00 | 3 | 0 | 0 | 0 | 50 | 1ed687a9cb9d4b1d | | 46 | 0xb800 | 63 | 0 | 3 | 3 | 1 | e6cdd2d93249a243 | > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|S|D|N| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+-+------------------+ | 1 | 0x0c01 | 240 | 61 | 3 | 89 |1|1|1|1| 1ae529b3a638943b | Done
دستگاه FTD Joiner (با آدرس MAC توسعهیافته = e6cdd2d93249a243 ) خود را به یک روتر ارتقا داده است. توجه داشته باشید که RLOC16 متفاوت است ( b800 به جای 0c02 ). دلیل این امر این است که RLOC16 بر اساس شناسه روتر و شناسه فرزند یک دستگاه عمل میکند. هنگامی که از دستگاه انتهایی به روتر منتقل میشود، مقادیر شناسه روتر و شناسه فرزند آن تغییر میکند و RLOC16 نیز تغییر میکند.

وضعیت جدید و RLOC16 را در FTD Joiner تأیید کنید:
## FTD Joiner ## ---------------- > state router Done > rloc16 b800 Done
تنزل رتبه FTD Joiner
شما میتوانید این رفتار را با پایین آوردن دستی FTD Joiner از یک روتر به یک دستگاه انتهایی (End Device) آزمایش کنید. وضعیت را به child تغییر دهید و RLOC16 را بررسی کنید:
## FTD Joiner ## ---------------- > state child Done > rloc16 0c03 Done

در FTD Commissioner ، FTD Joiner اکنون باید در جدول فرزند (ID = 3) ظاهر شود. حتی ممکن است در حین انتقال در هر دو جدول باشد:
## FTD Commissioner ## ---------------------- > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+-------+--------+-----+------------------+ | 3 | 0x0c00 | 3 | 0 | 0 | 0 | 50 | 1ed687a9cb9d4b1d | | 46 | 0xb800 | 63 | 0 | 3 | 3 | 1 | e6cdd2d93249a243 | > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|S|D|N| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+-+------------------+ | 1 | 0x0c01 | 240 | 61 | 3 | 89 |1|1|1|1| 1ae529b3a638943b | | 3 | 0x0c03 | 240 | 16 | 3 | 94 |1|1|1|1| e6cdd2d93249a243 | Done
پس از مدتی، به روتری با RLOC برابر با b800 تغییر خواهد کرد.

رهبر را حذف کنید
رهبر (Leader) به صورت خودجوش از بین تمام روترهای Thread انتخاب میشود. این بدان معناست که اگر رهبر فعلی از شبکه Thread حذف شود، یکی از روترهای دیگر رهبر جدید خواهد شد.
در FTD Commissioner ، Thread را ببندید تا از شبکه Thread حذف شود:
## FTD Commissioner ## ---------------------- > thread stop Done > ifconfig down Done
ظرف دو دقیقه، FTD Joiner به عنوان رهبر جدید Thread انتخاب میشود. وضعیت و آدرسهای IPv6 FTD Joiner را بررسی کنید تا موارد زیر را تأیید کنید:
## FTD Joiner ## ---------------- > state leader Done > ipaddr fdc0:de7a:b5c0:0:0:ff:fe00:fc00 # Now it has the Leader ALOC! fdc0:de7a:b5c0:0:0:ff:fe00:b800 fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd fe80:0:0:0:e4cd:d2d9:3249:a243 Done

جدول فرزند را بررسی کنید. توجه کنید که یک RLOC16 جدید وجود دارد. این RCP Joiner است، همانطور که با شناسه و Extended MAC آن مشخص شده است. برای حفظ یکپارچگی شبکه Thread، روترهای والد از FTD Commissioner به FTD Joiner تغییر یافته است. این منجر به یک RLOC16 جدید برای RCP Joiner میشود (زیرا شناسه روتر آن از ۳ به ۴۶ تغییر کرده است).
## FTD Joiner ## ---------------- > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|S|D|N| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+-+------------------+ | 1 | 0xb801 | 240 | 27 | 3 | 145 |1|1|1|1| 1ae529b3a638943b | Done
ممکن است لازم باشد چند دقیقه صبر کنید تا RCP Joiner به عنوان یک فرزند به FTD Joiner متصل شود. برای تأیید موارد زیر، وضعیت و RLOC16 را بررسی کنید:
## RCP Joiner ## -------------- > state child > rloc16 b801
کمیسر FTD را دوباره منصوب کنید
یک شبکه Thread با دو گره خیلی جالب نیست. بیایید کمیسر FTD را دوباره آنلاین کنیم.
در مورد کمیسر FTD ، تاپیک را مجدداً راهاندازی کنید:
## FTD Commissioner ## ---------------------- > ifconfig up Done > thread start Done
ظرف دو دقیقه، به طور خودکار به عنوان یک دستگاه انتهایی (End Device) به شبکهی «codelab» متصل میشود و سپس خود را به یک روتر ارتقا میدهد.
## FTD Commissioner ## ---------------------- > state router Done
برای تأیید موارد زیر، روتر و جداول فرزند را در FTD Joiner بررسی کنید:
## FTD Joiner ## ---------------- > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+-------+--------+-----+------------------+ | 3 | 0x0c00 | 63 | 0 | 3 | 3 | 0 | 1ed687a9cb9d4b1d | | 46 | 0xb800 | 46 | 0 | 0 | 0 | 15 | e6cdd2d93249a243 | > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|S|D|N| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+-+------------------+ | 1 | 0xb801 | 240 | 184 | 3 | 145 |1|1|1|1| 1ae529b3a638943b | Done

شبکه Thread ما دوباره از سه گره تشکیل شده است.
۱۱. عیبیابی
مدیریت یک شبکه Thread با چندین دستگاه در ترمینالهای مختلف یا پنجرههای Screen میتواند پیچیده باشد. در صورت بروز مشکل، از این نکات برای "تنظیم مجدد" وضعیت شبکه یا فضای کاری خود استفاده کنید.
صفحه نمایش
اگر در پیکربندی خود دچار مشکل شدید (تعداد زیاد پنجرههای Screen یا Screenهای درون Screen)، با استفاده از Ctrl+a → k پنجرههای Screen را ببندید تا زمانی که هیچ پنجرهای وجود نداشته باشد و screen -ls در خط فرمان عبارت No Sockets found را نمایش دهد. سپس پنجرههای Screen را برای هر دستگاه از نو بسازید. وضعیت دستگاهها حتی با بسته شدن Screen نیز حفظ میشود.
گرههای نخ
اگر توپولوژی شبکه Thread مطابق آنچه در این Codelab توضیح داده شده نیست، یا گرهها به دلایلی قطع میشوند (شاید به این دلیل که دستگاه لینوکسی که آنها را تغذیه میکند به حالت خواب رفته است)، بهتر است Thread را غیرفعال کنید، اعتبارنامههای شبکه را پاک کنید و دوباره از مرحله ایجاد شبکه Thread شروع کنید.
برای تنظیم مجدد FTD ها:
## FTD Commissioner or FTD Joiner ## ------------------------------------ > thread stop Done > ifconfig down Done > factoryreset Done
RCP را میتوان به همان روش از طریق ot-ctl تنظیم مجدد کرد:
## RCP Joiner ## ---------------- > thread stop Done > ifconfig down Done > factoryreset Done
۱۲. استفاده از چندپخشی
از چندپخشی برای انتقال اطلاعات به گروهی از دستگاهها به طور همزمان استفاده میشود. در یک شبکه Thread، آدرسهای خاصی برای استفاده چندپخشی با گروههای مختلف دستگاهها، بسته به دامنه، رزرو شدهاند.
آدرس IPv6 | محدوده | تحویل داده شده به |
| لینک-محلی | همه داروهای FTD و MED |
| لینک-محلی | همه FTDها و روترهای مرزی |
| شبکه محلی | همه داروهای FTD و MED |
| شبکه محلی | همه FTDها و روترهای مرزی |
از آنجایی که در این Codelab از Border Router استفاده نمیکنیم، بیایید روی دو آدرس چندپخشی FTD و MED تمرکز کنیم.
لینک-محلی
محدودهی لینک-لوکال شامل تمام رابطهای Thread قابل دسترسی توسط یک انتقال رادیویی یا یک "هاپ" واحد است. توپولوژی شبکه تعیین میکند که کدام دستگاهها به پینگ به آدرس چندپخشی ff02::1 پاسخ دهند.
پینگ ff02::1 از کمیسر FTD :
## FTD Commissioner ## ---------------------- > ping ff02::1 > 8 bytes from fe80:0:0:0:e4cd:d2d9:3249:a243: icmp_seq=2 hlim=64 time=9ms
دو دستگاه دیگر در شبکه وجود دارد (FTD Joiner و RCP Joiner)، اما کمیسر FTD فقط یک پاسخ از آدرس لینک-محلی (LLA) FTD Joiner دریافت کرده است. این بدان معناست که FTD Joiner تنها دستگاهی است که کمیسر FTD میتواند با یک گام به آن دسترسی پیدا کند.

حالا ff02::1 از FTD Joiner پینگ کنید:
## FTD Joiner ## ---------------- > ping ff02::1 > 8 bytes from fe80:0:0:0:1cd6:87a9:cb9d:4b1d: icmp_seq=1 hlim=64 time=11ms 8 bytes from fe80:0:0:0:18e5:29b3:a638:943b: icmp_seq=1 hlim=64 time=24ms
دو پاسخ! با بررسی آدرسهای IPv6 برای سایر دستگاهها، میتوانیم ببینیم که اولی (که به 4b1d ختم میشود) مربوط به LLA کمیسر FTD و دومی (که به 943b ختم میشود) مربوط به LLA عضو RCP است.

این یعنی FTD Joiner مستقیماً به هر دو FTD Commissioner و RCP Joiner متصل است که توپولوژی ما را تأیید میکند.
شبکه محلی
دامنه Mesh-Local شامل تمام رابطهای Thread قابل دسترسی در همان شبکه Thread است. بیایید پاسخهای پینگ به آدرس multicast ff03::1 را ببینیم.
پینگ ff03::1 از کمیسر FTD :
## FTD Commissioner ## ---------------------- > ping ff03::1 > 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:b800: icmp_seq=3 hlim=64 time=9ms 8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=3 hlim=64 time=68ms
این بار کمیسر FTD دو پاسخ دریافت کرد، یکی از مکانیاب مسیریابی FTD Joiner (RLOC، که به b800 ختم میشود) و دیگری از شناسه مش-محلی EID مربوط به RCP Joiner (ML-EID، که به d55f ختم میشود). دلیل این امر این است که محدوده مش-محلی کل شبکه Thread را در بر میگیرد. مهم نیست یک دستگاه در کجای شبکه باشد، در آدرس ff03::1 مشترک خواهد شد.

برای تأیید همین رفتار، ff03::1 از FTD Joiner پینگ کنید:
## FTD Joiner ## ---------------- > ping ff03::1 > 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00: icmp_seq=2 hlim=64 time=11ms 8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=2 hlim=64 time=23ms

به زمان پاسخ RCP Joiner در هر دو خروجی پینگ توجه کنید. RCP Joiner برای رسیدن به FTD Commissioner (68 میلیثانیه) زمان بسیار بیشتری نسبت به FTD Joiner (23 میلیثانیه) صرف کرد. دلیل این امر این است که RCP Joiner برای رسیدن به FTD Commissioner باید دو جهش (hop) طی کند، در حالی که FTD Joiner یک جهش (hop) نیاز دارد.
شاید متوجه شده باشید که پینگ چندپخشی مش-محلی فقط برای دو FTD با RLOC پاسخ میدهد - نه برای RCP Joiner. دلیل این امر این است که FTDها روترهای درون شبکه هستند، در حالی که RCP یک دستگاه انتهایی است.
وضعیت RCP Joiner را بررسی کنید تا موارد زیر را تأیید کنید:
## RCP Joiner ## ---------------- > state child
۱۳. ارسال پیام با UDP
یکی از سرویسهای کاربردی که OpenThread ارائه میدهد، پروتکل دادهنگار کاربر (UDP)، یک پروتکل لایه انتقال است. یک برنامه ساخته شده بر روی OpenThread میتواند از API UDP برای انتقال پیامها بین گرهها در یک شبکه Thread یا به سایر دستگاههای موجود در یک شبکه خارجی (مانند اینترنت، اگر شبکه Thread دارای یک روتر مرزی باشد) استفاده کند.
سوکتهای UDP از طریق رابط خط فرمان OpenThread در دسترس هستند. بیایید از آن برای انتقال پیام بین دو FTD استفاده کنیم.
آدرس EID مربوط به Mesh-Local را برای FTD Joiner دریافت کنید. ما از این آدرس استفاده میکنیم زیرا از هر جایی در شبکه Thread قابل دسترسی است.
## FTD Joiner ## ---------------- > ipaddr fdc0:de7a:b5c0:0:0:ff:fe00:fc00 # Leader Anycast Locator (ALOC) fdc0:de7a:b5c0:0:0:ff:fe00:b800 # Routing Locator (RLOC) fe80:0:0:0:e4cd:d2d9:3249:a243 # Link-Local Address (LLA) fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd # Mesh-Local EID (ML-EID) Done
UDP را شروع کنید و آن را به یک سوکت برای هر آدرس IPv6 متصل کنید:
## FTD Joiner ## ---------------- > udp open Done > udp bind :: 1212
به FTD Commissioner بروید، UDP را اجرا کنید و با استفاده از ML-EID آن، به سوکتی که روی FTD Joiner تنظیم کردهاید متصل شوید:
## FTD Commissioner ## ---------------------- > udp open Done > udp connect fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd 1212 Done
اتصال UDP باید بین دو گره برقرار باشد. پیامی از کمیسر FTD ارسال کنید:
## FTD Commissioner ## ---------------------- > udp send hellothere Done
در FTD Joiner ، پیام UDP دریافت شده است!
## FTD Joiner ## ---------------- > 10 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00 49153 hellothere
۱۴. تبریک میگویم!
شما یک شبکه فیزیکی Thread ایجاد کردهاید!

حالا میدانید:
- تفاوت بین انواع دستگاهها، نقشها و حوزههای Thread
- چگونه دستگاههای Thread وضعیت خود را در شبکه مدیریت میکنند
- نحوه انتقال پیامهای ساده بین گرهها با استفاده از UDP
مراحل بعدی
با تکیه بر این Codelab، تمرینهای زیر را امتحان کنید:
- برد FTD Joiner را با استفاده از فایل باینری
ot-cli-mtdبه عنوان یک MTD دوباره فلش کنید و مشاهده کنید که هرگز خود را به یک روتر ارتقا نمیدهد یا سعی نمیکند به Leader تبدیل شود. - دستگاههای بیشتری (یک پلتفرم دیگر را امتحان کنید!) به شبکه اضافه کنید و با استفاده از جداول روتر و فرزند، به همراه پینگ به آدرسهای چندپخشی، توپولوژی را ترسیم کنید.
- از پیسپینل برای کنترل NCP استفاده کنید
- با استفاده از OpenThread Border Router ، NCP را به یک Border Router تبدیل کنید و شبکه Thread خود را به اینترنت متصل کنید.
مطالعه بیشتر
برای دسترسی به منابع متنوع OpenThread، از جمله موارد زیر، به openthread.io و GitHub مراجعه کنید:
- پلتفرمهای پشتیبانیشده - تمام پلتفرمهایی که از OpenThread پشتیبانی میکنند را کشف کنید
- ساخت OpenThread — جزئیات بیشتر در مورد ساخت و پیکربندی OpenThread
- مقدمهای بر نخ - تمام مفاهیم نخ ارائه شده در این Codelab را پوشش میدهد
مرجع: