הדמיה של רשת פרוטוקול Thread באמצעות OpenThread

1. מבוא

26b7f4f6b3ea0700.png

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 עם חיבור יחיד ביניהם.

6e3aa07675f902dc.png

שליחת פינג לצומת

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 ישמש כמצטרף.

d6a67e8a0d0b5dcb.png

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

בתרגיל הזה נשתמש בשלושה חלונות מסוף, שמתאימים לפעולות הבאות:

  1. מופע CLI של מכשיר Thread מדומה (צומת 1)
  2. תהליך ot-daemon
  3. מופע של ot-ctl CLI

אם אתם ממשיכים מהתרגיל הקודם, כבר אמורים להיות פתוחים שני חלונות טרמינל. פותחים עוד חלון כדי שיהיו שלושה חלונות טרמינל זמינים לתרגיל הזה.

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

מידע נוסף זמין במקורות המידע הבאים: