1. מבוא

OpenThread שפורסם על ידי Google הוא הטמעה בקוד פתוח של פרוטוקול הרשת Thread. Google Nest פרסמה את OpenThread כדי להפוך את הטכנולוגיה שמשמשת במוצרי Nest לזמינה למפתחים באופן נרחב, במטרה להאיץ את פיתוח המוצרים לבית החכם.
במפרט של Thread מוגדר פרוטוקול תקשורת אלחוטי אמין ומאובטח בין מכשירים, שמבוסס על IPv6 וצורך מעט חשמל, לשימוש באפליקציות ביתיות. OpenThread מטמיע את כל שכבות הרשת של Thread, כולל IPv6, 6LoWPAN, IEEE 802.15.4 עם אבטחת MAC, Mesh Link Establishment ו-Mesh Routing.
ב-Codelab הזה תלמדו איך לדמות רשת פרוטוקול Thread במכשירים מדומים.
מה תלמדו
- איך מגדירים את כלי ה-build של OpenThread
- איך מדמים רשת Thread
- איך מאמתים צמתים של Thread
- איך מנהלים רשת Thread באמצעות OpenThread Daemon
הדרישות
- git
- ידע בסיסי ב-Linux, ניתוב ברשת
2. הגדרת מערכת ה-build
Git
כדי להשלים את ה-Codelab הזה, צריך להשתמש ב-Git. מורידים ומתקינים אותו לפני שממשיכים.
אחרי ההתקנה, פועלים לפי ההוראות למערכת ההפעלה הספציפית כדי להוריד ולבנות את OpenThread.
XCode ל-Mac OS X
כדי להתקין ולבנות את OpenThread ב-Mac OS X, צריך את XCode.
אחרי שמתקינים את XCode, מתקינים את XCode Command Line Tools:
$ xcode-select --install
Build ב-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
שימוש ב-Windows
אם אתם מעדיפים Windows, מומלץ לנסות את גרסת Docker של ה-Codelab הזה.
3. פיתוח אפליקציות OpenThread
אחרי שההתקנה מסתיימת, יוצרים את אפליקציית OpenThread לדוגמה. ב-Codelab הזה נשתמש בדוגמה של סימולציה.
$ cd ~/src/openthread $ ./script/cmake-build simulation
עכשיו יוצרים את OpenThread Daemon:
$ ./script/cmake-build posix -DOT_DAEMON=ON
4. סימולציה של רשת Thread
אפליקציית הדוגמה שתשתמשו בה ב-Codelab הזה מדגימה אפליקציית OpenThread מינימלית שחושפת את ממשקי התצורה והניהול של OpenThread באמצעות ממשק בסיסי של שורת פקודה (CLI).
בתרגיל הזה נסביר את השלבים המינימליים שנדרשים כדי לשלוח פינג ממכשיר Thread מדומה אחד למכשיר Thread מדומה אחר.
באיור הבא מתוארת טופולוגיה בסיסית של רשת Thread. בתרגיל הזה נדמה שני צמתים בתוך העיגול הירוק: Thread Leader ו-Thread Router עם חיבור יחיד ביניהם.

שליחת פינג לצומת
1. צומת התחלה 1
עוברים אל הספרייה openthread ומפעילים את תהליך ה-CLI עבור מכשיר Thread מדומה באמצעות הקובץ הבינארי ot-cli-ftd.
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
הערה: אם ההודעה > לא מופיעה אחרי שמריצים את הפקודה הזו, לוחצים על enter.
קובץ הבינארי הזה מטמיע מכשיר OpenThread שמודמה על גבי POSIX. דרייבר הרדיו IEEE 802.15.4 מיושם על גבי UDP (פריימים של IEEE 802.15.4 מועברים בתוך מטען ייעודי (payload) של UDP).
הארגומנט של 1 הוא מתאר קובץ שמייצג את הסיביות הכי פחות משמעותיות של IEEE EUI-64 שמוקצה על ידי היצרן למכשיר המדומה. הערך הזה משמש גם כשמבצעים קישור ליציאת UDP לצורך הדמיה של רדיו IEEE 802.15.4 (יציאה = 9000 + מתאר קובץ). כל מופע של מכשיר Thread מדומה ב-Codelab הזה ישתמש בתיאור קובץ שונה.
הערה: כשמפעילים את התהליך של מכשיר מדומה, צריך להשתמש רק בתיאורי קבצים של 1 ומעלה, כמו שמוסבר ב-Codelab הזה. מתאר הקובץ 0 שמור לשימוש אחר.
יוצרים מערך נתונים תפעולי חדש ומבצעים commit שלו כמערך הנתונים הפעיל. מערך הנתונים התפעולי הוא ההגדרה של רשת 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:
> thread start Done
מחכים כמה שניות ומוודאים שהמכשיר הפך ל-Thread Leader. הנתב הראשי הוא המכשיר שאחראי לניהול ההקצאה של מזהה הנתב.
> state leader Done
צפייה בכתובות IPv6 שהוקצו לממשק Thread של צומת 1 (הפלט שלכם יהיה שונה):
> 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= link-local
סוגי כתובות מקומיות ברשת Mesh מסווגים באופן הבא:
- מכיל
ff:fe00= Router Locator (RLOC) - לא מכיל
ff:fe00= מזהה נקודת קצה (EID)
מזהים את ה-EID בפלט של המסוף ורושמים אותו לשימוש בהמשך. בדוגמת הפלט שלמעלה, מספר ה-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.
מגדירים את מפתח הרשת של Thread ואת מזהה ה-PAN, באמצעות אותם ערכים כמו במערך הנתונים התפעולי של צומת 1:
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
מאשרים את מערך הנתונים הזה כמערך הנתונים הפעיל:
> dataset commit active Done
פותחים את ממשק IPv6:
> ifconfig up Done
התחלת פעולה של פרוטוקול Thread:
> thread start Done
המכשיר יאותחל כילד או כילדה. מכשיר צאצא ב-Thread שווה ערך למכשיר קצה, שהוא מכשיר Thread שמשדר ומקבל תנועת נתונים מסוג unicast רק עם מכשיר אב.
> state child Done
תוך 2 דקות, המצב אמור להשתנות מ-child ל-router. נתב Thread יכול לנתב תעבורה בין מכשירים עם פרוטוקול Thread. הוא נקרא גם הורה.
> state router Done
אימות הרשת
דרך קלה לאמת את רשת האריג היא לבדוק את טבלת הנתב.
1. בדיקת הקישוריות
בצומת 2, מקבלים את RLOC16. ה-RLOC16 הוא 16 הביטים האחרונים של כתובת ה-IPv6 של ה-RLOC של המכשיר.
> rloc16 5800 Done
בצומת 1, בודקים את טבלת הניתוב של RLOC16 של צומת 2. קודם מוודאים שצומת 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 |
ה-RLOC של צומת 1, 0xa800, מופיע בטבלה, מה שמאשר שהוא מחובר לרשת ה-Mesh.
2. ביצוע פינג לצומת 1 מצומת 2
מוודאים שיש קישוריות בין שני מכשירי Thread המדומים. בצומת 2, ping מספר ה-EID שהוקצה לצומת 1:
> 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.
בדיקת הרשת
אחרי שבדקתם שאפשר לשלוח פינג בין שני מכשירי Thread מסימולציה, אתם יכולים לבדוק את רשת האריג על ידי העברה של צומת אחד למצב אופליין.
חוזרים לצומת 1 ומפסיקים את Thread:
> thread stop Done
עוברים לצומת 2 ובודקים את המצב. תוך שתי דקות, צומת 2 מזהה שהצומת הראשי (צומת 1) במצב אופליין, ואתם אמורים לראות את צומת 2 עובר להיות leader של הרשת:
> state router Done ... > state leader Done
אחרי האישור, מפסיקים את Thread ומאפסים להגדרות המקוריות את Node 2 לפני שיוצאים. איפוס להגדרות המקוריות נעשה כדי לוודא שפרטי הכניסה לרשת פרוטוקול Thread שבהם השתמשנו בתרגיל הזה לא יועברו לתרגיל הבא.
> thread stop Done > factoryreset > > exit
בנוסף, מאפסים להגדרות המקוריות ויוצאים מ-Node 1:
> factoryreset > > exit
כדי לראות את כל הפקודות הזמינות של CLI, אפשר לעיין במדריך העזר של OpenThread CLI.
5. אימות צמתים באמצעות הפעלה
בתרגיל הקודם הגדרתם רשת Thread עם שני מכשירים מדומיים ואימתתם את הקישוריות. עם זאת, ההגדרה הזו מאפשרת רק לתנועת גולשים לא מאומתת ב-IPv6 ברשת המקומית לעבור בין מכשירים. כדי לנתב תנועת IPv6 גלובלית ביניהם (ובאינטרנט דרך נתב גבול Thread), הצמתים צריכים להיות מאומתים.
כדי לבצע אימות, מכשיר אחד צריך לפעול כמרכז בקרה. ה-Commissioner הוא שרת האימות שנבחר כרגע למכשירי Thread חדשים, והוא גם הגורם שמאשר את מתן פרטי הכניסה לרשת שנדרשים כדי שהמכשירים יוכלו להצטרף לרשת.
בתרגיל הזה נשתמש באותה טופולוגיה של שני צמתים כמו קודם. לצורך אימות, המכשיר הראשי ברשת Thread ישמש כנציב, ונתב Thread ישמש כמצטרף.

1. יצירת רשת
אם ממשיכים מהתרגיל הקודם, אמורים להיות פתוחים שני חלונות טרמינל. אם לא, צריך לוודא ששני חלונות פתוחים ומוכנים לשימוש. אחד ישמש כצומת 1 והשני כצומת 2.
בצומת 1, מפעילים את תהליך ה-CLI:
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
הערה: אם ההודעה > לא מופיעה אחרי שמריצים את הפקודה הזו, לוחצים על enter.
יוצרים מערך נתונים תפעולי חדש, מבצעים commit שלו כמערך הפעיל ומתחילים שרשור:
> 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:
> thread start Done
ממתינים כמה שניות ומוודאים שהמכשיר הפך ל-Thread Leader:
> state leader Done
2. הפעלת התפקיד 'נציב'
כשעדיין נמצאים בצומת 1, מתחילים את התפקיד של הנציב:
> commissioner start Done
אפשר לאפשר לכל מצטרף (באמצעות התו הכללי *) עם אישור ההצטרפות J01NME להצטרף לרשת. מצטרף הוא מכשיר שמנהל אנושי מוסיף לרשת Thread שהופעלה.
> commissioner joiner add * J01NME Done
3. התחלת התפקיד של המצטרף
בחלון מסוף שני, יוצרים תהליך חדש של CLI. זה צומת 2.
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 2
בצומת 2, מפעילים את התפקיד Joiner באמצעות J01NME Joiner Credential.
> ifconfig up Done > joiner start J01NME Done
... מחכים כמה שניות לאישור ...
Join success
המכשיר (Node 2) הצליח לאמת את עצמו מול הרכז (Node 1) וקיבל את פרטי הכניסה לרשת Thread.
אחרי שמאמתים את Node 2, מתחילים את Thread:
> thread start Done
4. אימות של אימות הרשת
בודקים את state בצומת 2 כדי לוודא שהוא הצטרף לרשת. תוך שתי דקות, המעבר של צומת 2 הוא מ-child ל-router:
> state child Done ... > state router Done
5. איפוס ההגדרה
כדי להתכונן לתרגיל הבא, מאפסים את ההגדרה. בכל צומת, מפסיקים את Thread, מאפסים להגדרות המקוריות ויוצאים ממכשיר Thread המדומה:
> thread stop Done > factoryreset > > exit
יכול להיות שתצטרכו ללחוץ על enter כמה פעמים כדי שההנחיה > תופיע שוב אחרי פקודה factoryreset.
6. ניהול הרשת באמצעות OpenThread Daemon
בתרגיל הזה נדמה מופע אחד של CLI (מכשיר SoC Thread מוטמע יחיד) ומופע אחד של Radio Co-Processor (RCP).
ot-daemon הוא מצב של אפליקציית OpenThread Posix שמשתמשת בשקע UNIX כקלט ופלט, כך שליבת OpenThread יכולה לפעול כשירות. לקוח יכול לתקשר עם השירות הזה על ידי התחברות לשקע באמצעות ה-CLI של OpenThread כפרוטוקול.
ot-ctl הוא CLI שמוצע על ידי ot-daemon לניהול ולהגדרה של ה-RCP. באמצעות הנתונים האלה, נחבר את ה-RCP לרשת שנוצרה על ידי מכשיר Thread.
שימוש ב-ot-daemon
בתרגיל הזה נשתמש בשלושה חלונות מסוף, שמתאימים לפעולות הבאות:
- מופע CLI של מכשיר Thread מדומה (צומת 1)
- תהליך
ot-daemon - מופע של
ot-ctlCLI
אם אתם ממשיכים מהתרגיל הקודם, כבר אמורים להיות פתוחים שני חלונות טרמינל. פותחים עוד חלון כדי שיהיו שלושה חלונות טרמינל זמינים לתרגיל הזה.
1. צומת התחלה 1
בחלון הטרמינל הראשון, מפעילים את תהליך ה-CLI עבור מכשיר Thread המדומה:
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
הערה: אם ההודעה > לא מופיעה אחרי שמריצים את הפקודה הזו, לוחצים על enter.
יוצרים מערך נתונים תפעולי חדש, מבצעים commit שלו כמערך הפעיל ומתחילים שרשור:
> 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:
> thread start Done
צופים בכתובות ה-IPv6 שהוקצו לממשק Thread של צומת 1:
> 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 >
כמו שמוסבר בשלב הדמיה של רשת Thread, כתובת אחת היא link-local (fe80) ושלוש הן mesh-local (fd). ה-EID היא כתובת mesh-local שלא מכילה ff:fe00 בכתובת. בדוגמה הזו של פלט, מספר ה-EID הוא fd55:cf34:dea5:7994:460:872c:e807:c4ab.
מזהים את ה-EID הספציפי מתוך הפלט של ipaddr, שבו ישתמשו כדי לתקשר עם הצומת.
2. הפעלת ot-daemon
בחלון השני של הטרמינל, עוברים לספרייה openthread ומפעילים את ot-daemon עבור צומת RCP, שנקרא לו צומת 2. משתמשים בדגל -v verbose כדי לראות את פלט היומן ולוודא שהסקריפט פועל, וחשוב להשתמש בדגל 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 כדי להצטרף לרשת
עדיין לא הפעלנו את Node 2 (ה-RCP ot-daemon) באף רשת Thread. כאן נכנס לתמונה ot-ctl. ot-ctl משתמש באותו CLI כמו אפליקציית OpenThread CLI. לכן, אפשר לשלוט בצמתי ot-daemon באותו אופן כמו במכשירי Thread המדומים האחרים.
בחלון טרמינל שלישי, מפעילים את ot-ctl:
$ sudo ./build/posix/src/posix/ot-ctl >
הערה: אם ההודעה > לא מופיעה אחרי שמריצים את הפקודה הזו, לוחצים על enter.
תשתמשו ב-ot-ctl בחלון הטרמינל השלישי כדי לנהל את Node 2 (צומת ה-RCP) שהפעלתם בחלון הטרמינל השני באמצעות ot-daemon. בודקים את state של צומת 2:
> state disabled Done
כדי להגביל את ההצטרפות למשתתף ספציפי, מקבלים את eui64 של צומת 2:
> eui64 18b4300000000001 Done
בצומת 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) וקיבל את פרטי הכניסה לרשת Thread.
עכשיו מצטרפים לצומת 2 לרשת בפרוטוקול Thread:
> thread start Done
4. אימות של אימות הרשת
בודקים את state בצומת 2 כדי לוודא שהוא הצטרף לרשת. תוך שתי דקות, המעבר של צומת 2 הוא מ-child ל-router:
> state child Done ... > state router Done
5. אימות הקישוריות
יוצאים מ-ot-ctl באמצעות הפקודה Ctrl+D או exit, ובשורת הפקודה של המכונה המארחת, מבצעים פינג ל-Node 1 באמצעות ה-EID שלו עם הפקודה ping6. אם מופע ot-daemon RCP מצטרף לרשת Thread ומתקשר איתה בהצלחה, הפינג מצליח:
$ 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. מעולה!
הדמייתם בהצלחה את רשת ה-Thread הראשונה באמצעות OpenThread. מדהים!
ב-Codelab הזה למדתם איך:
- הגדרת כלי ה-build של OpenThread
- סימולציה של רשת Thread
- אימות של צמתי Thread
- ניהול רשת Thread באמצעות OpenThread Daemon
מידע נוסף זמין במקורות המידע הבאים: