הדמיית רשת Thread עם OpenThread

1. מבוא

26b7f4f6b3ea0700.png

Openthread ש-Google פרסמה הוא קוד פתוח שמשמש את פרוטוקול הרשת Thread. גרסת Google Nest הושקה באמצעות OpenThread כדי שטכנולוגיית המוצרים של Nest תהיה זמינה באופן נרחב למפתחים כדי להאיץ את פיתוח המוצרים לבית החכם.

מפרט השרשורים מגדיר פרוטוקול תקשורת אלחוטי, מאובטח ונמוך שצורף בין מכשירים לצורך שימוש באפליקציות ביתיות. OpenThread מטמיע את כל שכבות הרשת של Thread, כולל IPv6, 6LoWPAN, IEEE 802.15.4 עם אבטחת MAC, הגדרת רשת Mesh וניתוב רשת.

ב-Codelab הזה ננחה אתכם בסימולציה של רשת שרשור במכשירים מדומים.

מה תלמדו

  • איך להגדיר את כלי הפיתוח של OpenThread
  • איך לדמות רשת של שרשור
  • איך מאמתים צמתים בשרשור
  • איך לנהל רשת Thread עם OpenThread Daemon

מה תצטרך להכין

  • Git
  • ידע בסיסי ב-Linux, ניתוב רשת

2. הגדרת מערכת ה-build

Git

יש צורך ב-Git כדי להשלים את ה-Codelab הזה. צריך להוריד ולהתקין אותו לפני שממשיכים.

לאחר ההתקנה, יש לפעול לפי ההוראות של מערכת ההפעלה הספציפית כדי להוריד ולפתח את OpenThread.

XCode ל-Mac OS X

יש צורך ב-XCode כדי להתקין ולבנות OpenThread ב-Mac OS X.

אחרי שמתקינים את XCode, מתקינים את כלי XCode Command:

$ xcode-select --install

התקנה ב-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
$ ./bootstrap

שימוש ב-Windows

אם אתם מעדיפים את Windows, מומלץ לנסות את גרסת ה-Docker של Codelab הזה.

3. יצירת האפליקציות של OpenThread

לאחר השלמת ההתקנה, בונים את אפליקציית OpenThread לדוגמה. ב-Codelab הזה אנחנו משתמשים בדוגמה לדוגמה.

$ cd ~/src/openthread
$ make -f examples/Makefile-simulation

עכשיו צרו את OpenThread Daemon:

$ cd ~/src/openthread
$ make -f src/posix/Makefile-posix DAEMON=1

4. הדמיית רשת Thread

האפליקציה לדוגמה שבה תשתמשו עבור ה-Codelab הזה מדגימה אפליקציה מינימלית של OpenThread שחושפת את ממשקי התצורה והניהול של OpenThread דרך ממשק שורת פקודה בסיסי (CLI).

התרגיל הזה כולל את שלבי התהליך המינימליים הנדרשים כדי לשלוח פינג של מכשיר אחד של סימולציה ממכשיר אחר עם הדמיה של שרשור.

התרשים הבא מתאר את הטופולוגיה הבסיסית של רשת השרשורים. לצורך התרגיל הזה, נדמות את שני הצמתים שבעיגול הירוק: מנהיג שרשורים ונתב שרשורים עם חיבור יחיד ביניהם.

6e3aa07675f902dc.png

פינג לצומת

1. התחלה של צומת 1

עוברים אל הספרייה ב-openthread ומשחזרים את תהליך ה-CLI עבור מכשיר בעל הדמיה של שרשור באמצעות הקובץ הבינארי ot-cli-ftd.

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 1

הערה: אם לא מופיעה ההודעה > אחרי הפעלת הפקודה הזו, יש להקיש על enter.

הקובץ הבינארי הזה מטמיע מכשיר Openthread שסימולציה ב-POSIX. מנהל התקן הרדיו IEEE 802.15.4 מוטמע מעל ה-UDP (IEEE 802.15.4 מועברים באמצעות מטענים ייעודיים של UDP).

הארגומנט של 1 הוא מתאר הקובץ שמייצג את הביטים הכי פחות קטנים של "fact-assigned" IEEE EUI-64 עבור המכשיר שמדמה. הערך הזה משמש גם לאיגוד יציאת UDP עבור אמולציה של IEEE 802.15.4 (יציאה = 9000 + מתאר קובץ). בכל מופע של מכשיר שרשור ב-Codelab הזה ייעשה שימוש בתיאור קובץ שונה.

הערה: יש להשתמש בתארים של קבצים מסוג 1 או יותר, כפי שמצוין ב-Codelab הזה כשמשחזרים את התהליך למכשיר שמדמה. מתאר הקובץ של 0 שמור לשימוש אחר.

יוצרים מערך נתונים תפעולי חדש ומחילים אותו כמערך הפעיל. מערך הנתונים התפעולי הוא התצורה של רשת השרשורים שאתה יוצר.

> 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

ממתינים מספר שניות ומוודאים שהמכשיר הפך למנהל השרשורים. המנהל הוא המכשיר שאחראי לניהול ההקצאה של מזהה הנתב.

> 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

סוגי כתובות מקומיות של רשתות מסווגים עוד:

  • מכיל ff:fe00 = ממקם הנתב (RLOC)
  • לא מכיל ff:fe00 = מזהה של נקודת קצה (EID)

עליך לזהות את ה-EID בפלט של המסוף כדי לרשום אותו לשימוש מאוחר יותר. בפלט לדוגמה שלמעלה, ה-EID הוא:

fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6

2. התחלת צומת 2

יש לפתוח טרמינל חדש ולנווט לספרייה של openthread ולהפיץ את תהליך ה-CLI. זהו מכשיר השרשור השני שלך:

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 2

הערה: אם לא מופיעה ההודעה > אחרי הפעלת הפקודה הזו, יש להקיש על enter.

מגדירים את מפתח הרשת של השרשור ואת מזהה ה-PAN, באמצעות אותם ערכים כמו מערך הנתונים התפעולי של צומת 1'

> dataset networkkey e4344ca17d1dca2a33f064992f31f786
Done
> dataset panid 0xc169
Done

החלת מערך הנתונים הזה כמערך הנתונים הפעיל:

> dataset commit active
Done

מציגים את ממשק IPv6:

> ifconfig up
Done

התחלת פרוטוקול Thread:

> thread start
Done

המכשיר יאתחל את עצמו כילד. חשבון Thread לילדים הוא מכשיר שווה ערך למכשיר קצה, שהוא מכשיר משרשור. הוא משדר ומקבל תנועה חד-פעמית רק בעזרת מכשיר הורה.

> state
child
Done

תוך 2 דקות יהיה אפשר לעבור מ-child ל-router. נתב שרשורי יכול לנתב את התנועה בין מכשירי שרשור. הוא נקרא גם 'הורה'.

> state
router
Done

אימות הרשת

דרך קלה לאמת את רשת הרשת היא לבדוק את טבלת הנתב.

1. בדיקת קישוריות

בצומת 2, מקבלים את ה-RLOC16. ה-RLOC16 הוא 16 הביטים האחרונים בכתובת ה-RLOC IPv6 של המכשיר.

> rloc16
5800
Done

בצומת 1, מחפשים את טבלת הנתב של Node 2's RLOC16. יש לוודא שצומת 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 של צומת 0xa800 מהטבלה, כדי לוודא שהוא מחובר לרשת.

2. פינג צומת 1 מצומת 2

יש לאמת את הקישור בין שני מכשירי השרשור בצומת 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

לחזרה אל ההודעה של ה-CLI של >, יש ללחוץ על enter.

בדיקת הרשת

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

חזרה לצומת 1 והפסקת השרשור:

> thread stop
Done

עוברים לצומת 2 ובודקים את המדינה. תוך שתי דקות, צומת 2 מזהה שהמנהיג (צומת 1) במצב אופליין, ועליך לראות את מעבר צומת 2 בתור leader של הרשת:

> state
router
Done
...
> state
leader
Done

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

> thread stop
Done
> factoryreset
>
> exit

גם איפוס להגדרות המקוריות ויציאה מצומת 1:

> factoryreset
>
> exit

בקובץ עזר של CLI פתוח אפשר לסקור את כל הפקודות הזמינות עבור CLI.

5. אימות צמתים באמצעות הזמנה

בתרגיל הקודם, הגדרתם רשת חוטים עם שני סימולציה של מכשירים וקישוריות מאומתת. עם זאת, כך ניתן לעבור בין מכשירים רק באמצעות קישור מקומי לא מאומת של IPv6. כדי לנתב תנועה בין IPv6 גלובלית (לאינטרנט באמצעות נתב גבול של שרשור), צריך לאמת את הצמתים.

כדי לאמת את הזהות שלכם, מכשיר אחד צריך לשמש כמפקח. הנציב הוא שרת האימות הנבחר עבור מכשירי Thread חדשים, והוא מאשר לספק את פרטי הכניסה לרשת הנדרשים למכשירים כדי להצטרף לרשת.

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

d6a67e8a0d0b5dcb.png

1. יצירת רשת

אם ממשיכים מהתרגיל הקודם, אמורים להיות כבר שני חלונות טרמינל פתוחים. אם לא, צריך לוודא ששניהם פתוחים ומוכנים לשימוש. אחד יוצג כצומת 1 והשני כצומת 2.

בצומת 1, צור תהליך CLI:

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 1

הערה: אם לא מופיעה ההודעה > אחרי הפעלת הפקודה הזו, יש להקיש על enter.

יוצרים מערך נתונים תפעולי חדש, מגדירים אותו כפעיל ומתחילים שרשור:

> 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

ממתינים כמה שניות ומוודאים שהמכשיר הפך למוביל בתחום השרשורים:

> state
leader
Done

2. התחלת תפקיד הנציב

בזמן שאתם נמצאים בצומת 1, יש להתחיל את תפקיד הנציב:

> commissioner start
Done

מתן הרשאה לכל חבר (באמצעות תו כללי לחיפוש *) עם פרטי הכניסה של J01NME להצטרף לרשת. התוסף 'חבר' הוא מכשיר שנוסף על ידי מנהל מערכת אנושי לרשת שרשור מאורגנת.

> commissioner joiner add * J01NME
Done

3. איך מצטרפים לתפקיד 'הצטרפות'

בחלון טרמינל שני, יוצרים תהליך CLI חדש. זהו צומת 2.

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 2

בצומת 2, מפעילים את התפקיד 'הצטרפות' באמצעות פרטי הכניסה של J01NME.

> ifconfig up
Done
> joiner start J01NME
Done

... מחכים כמה שניות לאישור ...

Join success

כהצטרפות, המכשיר (צומת 2) אימת בהצלחה את עצמו עם הנציב (צומת 1) וקיבל את פרטי הכניסה של רשת השרשורים.

עכשיו שצומת 2 אומת, פותחים את השרשור:

> thread start
Done

4. אימות אימות הרשת

יש לבדוק את state בצומת 2 כדי לוודא שהוא הצטרף לרשת. תוך שתי דקות, צומת 2 עובר מ-child ל-router:

> state
child
Done
...
> state
router
Done

5. איפוס ההגדרות האישיות

כדי להתכונן לתרגיל הבא, יש לאפס את ההגדרה. בכל צומת, מפסיקים את השרשור, מאפסים את המכשיר להגדרות המקוריות ויוצאים מהמכשיר שמדמה את השרשור:

> thread stop
Done
> factoryreset
>
> exit

ייתכן שיהיה עליך להקיש על enter כמה פעמים כדי להחזיר את ההודעה > אחרי הפקודה factoryreset.

6. ניהול הרשת באמצעות OpenThread Daemon

לצורך התרגיל הזה, נערוך הדמיה של מופע CLI אחד (מכשיר SoC Thread מוטמע) ומופע אחד של מכשיר רדיו משותף (RCP).

ot-daemon הוא מצב של אפליקציית OpenThread Posix שמשתמש בשקע UNIX כקלט ופלט, כך שרצת Core Open תוכל לפעול בתור שירות. לקוח יכול לתקשר עם השירות הזה על ידי התחברות לשקע באמצעות ה-OpenThread CLI כפרוטוקול.

ot-ctl הוא CLI שסופק על ידי ot-daemon כדי לנהל ולהגדיר את ה-RCP. לשם כך, נחבר את ה-RCP לרשת שנוצרה על ידי מכשיר השרשור.

שימוש ב-ot-daemon

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

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

אם ממשיכים מהתרגיל הקודם, מומלץ לפתוח שני חלונות של הטרמינל. פותחים שליש כדי לוודא שיש שלושה חלונות מסוף זמינים לתרגיל הזה.

1. התחלה של צומת 1

בחלון הטרמינל הראשון, מעבירים את תהליך ה-CLI למכשיר שמדמה שרשור:

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 1

הערה: אם לא מופיעה ההודעה > אחרי הפעלת הפקודה הזו, יש להקיש על enter.

יוצרים מערך נתונים תפעולי חדש, מגדירים אותו כפעיל ומתחילים שרשור:

> 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&33:

> 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
>

כפי שמוסבר בשלב סימולציה של רשת חוטים, כתובת אחת היא קישור מקומי (fe80) ושלוש הן רשת מקומית (fd). ה-EID הוא הכתובת המקומית ברשת שאינה מכילה ff:fe00 בכתובת. בפלט לדוגמה הזה, ה-EID הוא fd55:cf34:dea5:7994:460:872c:e807:c4ab.

עליך לזהות את ה-EID הספציפי מהפלט שלך ב-ipaddr, שישמש לתקשורת עם הצומת.

2. התחלת השימוש ב-daemon

בחלון הטרמינל השני, עוברים לספרייה openthread ומתחילים את ot-daemon בצומת RCP. אנחנו נפעיל את הצומת הזה מס' 2. מומלץ להשתמש בסימון דרגת המלל -v כדי לראות את פלט היומן ולאשר שהוא פועל:

$ cd ~/src/openthread
$ ./output/posix/bin/ot-daemon -v \
    'spinel+hdlc+forkpty://output/simulation/bin/ot-rcp?forkpty-arg=2'

כשהמערכת מצליחה, מערכת ot-daemon במצב דרגת מלל יוצרת פלט הדומה לזה:

ot-daemon[228024]: Running OPENTHREAD/20191113-00831-gfb399104; POSIX; Jun 7 2020 18:05:15
ot-daemon[228024]: Thread version: 2
ot-daemon[228024]: RCP version: OPENTHREAD/20191113-00831-gfb399104; SIMULATION; Jun 7 2020 18:06:08

משאירים את המסוף הזה פתוח ופועל ברקע. לא מזינים בו פקודות נוספות.

3. שימוש ב-ot-ctl כדי להצטרף לרשת

עדיין לא הזמנתם את צומת 2 (ot-daemon RCP) לרשת שרשור כלשהי. כאן נכנסים לתמונה ot-ctl. ot-ctl משתמש באותו CLI כמו האפליקציה OpenThread CLI. לכן, אפשר לשלוט בצמתים של ot-daemon באותו אופן כמו במכשירים אחרים מדומה.

בחלון טרמינל שלישי, מתחילים את ot-ctl:

$ ./output/posix/bin/ot-ctl
>

תשתמשו ב-ot-ctl בחלון הטרמינל השלישי כדי לנהל את צומת 2 (צומת ה-RCP) שהתחלת בחלון הטרמינל השני עם ot-daemon. כדאי לבדוק את state בצומת 2:

> state
disabled
Done

הורידי את צומת צומת 2&eui64, כדי להגביל את ההצטרפות למצטרפים ספציפיים:

> eui64
18b4300000000001
Done

בצומת 1 (חלון טרמינל ראשון), מפעילים את הנציב ומגבילים את ההצטרפות רק ל-eui64:

> commissioner start
Done
> commissioner joiner add 18b4300000000001 J01NME
Done

בצומת 2 (חלון מסוף שלישי), מעלים את ממשק הרשת ומצטרפים לרשת:

> ifconfig up
Done
> joiner start J01NME
Done

... מחכים כמה שניות לאישור ...

Join success

כמשתתפים, ה-RCP (צומת 2) אומת בהצלחה באמצעות הנציב (צומת 1) והוא קיבל את פרטי הכניסה לרשת שרשור.

עכשיו יש להצטרף לצומת 2 לרשת השרשורים:

> thread start
Done

4. אימות אימות הרשת

יש לבדוק את state בצומת 2 כדי לוודא שהוא הצטרף לרשת. תוך שתי דקות, צומת 2 עובר מ-child ל-router:

> state
child
Done
...
> state
router
Done

5. אימות הקישוריות

יציאה מ-ot-ctl באמצעות הפקודה Ctrl+D או exit, ובשורת הפקודה של המכונה המארחת (פינג) פינג 1, באמצעות ה-EID שלה עם הפקודה ping6. אם מופע ה-RCP של ot-daemon מחובר בהצלחה לרשת השרשור ומעביר אותה אליו, הפינג יצליח:

$ 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. מעולה!

סימנת בהצלחה את ההדמיה של רשת השרשורים הראשונה באמצעות OpenThread. נפלא!

ב-Codelab הזה למדתם איך:

  • הגדרת כלי הפיתוח של OpenThread
  • הדמיית רשת Thread
  • אימות צמתים בשרשור
  • ניהול רשת Thread עם OpenThread Daemon

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