בניית רשת בפרוטוקול Thread עם לוחות nRF52840 ו-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.

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

4806d16a8c137c6d.jpeg

מה תלמדו

  • יצירה והעברה של קובצי הפעלה של OpenThread CLI ללוחות פיתוח
  • בניית RCP שכולל מכונת Linux ולוח פיתוח
  • תקשורת עם RCP באמצעות OpenThread Daemon ו-ot-ctl
  • ניהול ידני של צמתי Thread באמצעות GNU Screen ו-OpenThread CLI
  • הקצאת הרשאות מאובטחת למכשירים ברשת Thread
  • איך עובד שידור מרובה משתתפים ב-IPv6
  • העברת הודעות בין צמתי Thread באמצעות UDP

מה נדרש

חומרה:

  • ‫3 לוחות פיתוח Nordic Semiconductor nRF52840
  • ‫3 כבלים מ-USB למיקרו USB לחיבור הלוחות
  • מחשב Linux עם לפחות 3 יציאות USB

תוכנה:

  • GNU Toolchain
  • כלי שורת הפקודה Nordic nRF5x
  • תוכנת Segger J-Link
  • OpenThread
  • Git

2. תחילת העבודה

סימולציה של OpenThread

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

מסופי יציאה טורית

צריך לדעת איך להתחבר ליציאה טורית דרך מסוף. ב-Codelab הזה נעשה שימוש ב-GNU Screen ומוצג סקירה כללית של השימוש, אבל אפשר להשתמש בכל תוכנת טרמינל אחרת.

מכונת Linux

ה-Codelab הזה נועד לשימוש במכונת Linux מבוססת i386 או x86, שתשמש כמארח למכשיר Radio Co-Processor (RCP) Thread, ולעדכון של כל לוחות הפיתוח של Thread. כל השלבים נבדקו ב-Ubuntu 14.04.5 LTS ‏ (Trusty Tahr).

לוחות Nordic Semiconductor nRF52840

בשיעור הזה משתמשים בשלושה לוחות nRF52840 PDK.

a6693da3ce213856.png

אנחנו משתמשים ב-SEGGER J-Link כדי לתכנת את לוחות nRF52840, שיש להם מודולי JTAG מובנים. מתקינים את התוכנה הזו במחשב Linux.

מורידים את החבילה המתאימה למחשב ומתקינים אותה במיקום הנכון. ב-Linux, זה /opt/SEGGER/JLink.

התקנה של כלי שורת הפקודה nRF5x

כלי שורת הפקודה nRF5x מאפשרים להעביר את קובצי ה-binary של OpenThread ללוחות nRF52840. מתקינים את הגרסה המתאימה של nRF5x-Command-Line-Tools-<OS> במחשב Linux.

ממקמים את החבילה שחולצה בתיקיית השורש ~/

התקנה של ARM GNU Toolchain

ערכת הכלים ARM GNU משמשת לבנייה.

מומלץ למקם את הארכיון שחולץ ב-/opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ במחשב Linux. פועלים לפי ההוראות להתקנה שמפורטות בקובץ readme.txt בארכיון.

מסך ההתקנה (אופציונלי)

‫Screen הוא כלי פשוט לגישה למכשירים שמחוברים באמצעות יציאה טורית. ב-Codelab הזה נעשה שימוש ב-Screen, אבל אתם יכולים להשתמש בכל אפליקציית מסוף של יציאה טורית שתרצו.

$ sudo apt-get install screen

3. שכפול מאגרי נתונים

OpenThread

משכפלים את OpenThread ומתקינים אותו. הפקודות של script/bootstrap מוודאות ששרשרת הכלים מותקנת ושהסביבה מוגדרת בצורה תקינה:

$ mkdir -p ~/src
$ cd ~/src
$ git clone --recursive https://github.com/openthread/openthread.git
$ cd openthread
$ ./script/bootstrap

גרסת build של OpenThread Daemon:

$ script/cmake-build posix -DOT_DAEMON=ON

עכשיו אתם מוכנים לבנות את OpenThread ולהעביר אותו ללוחות nRF52840.

4. הגדרת הכלי לצירוף נתונים

בנייה והפעלה

יוצרים את הדוגמה 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 ליציאת הניפוי באגים של מיקרו USB לצד פין החשמל החיצוני בלוח nRF52840, ואז מחברים אותו למכונת Linux. מגדירים את המתג nRF power source בלוח nRF52840 לערך VDD. כשמחברים את המכשיר בצורה נכונה, נורית LED5 נדלקת.

20a3b4b480356447.png

אם זוהי הלוח הראשון שמחובר למכונת Linux, הוא יופיע כיציאה טורית /dev/ttyACM0 (כל לוחות nRF52840 משתמשים ב-/dev/ttyACM0 כמזהה של היציאה הטורית).ttyACM

$ ls /dev/ttyACM*
/dev/ttyACM0

שימו לב למספר הסידורי של לוח nRF52840 שמשמש ל-RCP:

c00d519ebec7e5f0.jpeg

עוברים למיקום של כלי שורת הפקודה 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 מקורי

מכיוון שה-build של OpenThread RCP מאפשר שימוש ב-USB CDC ACM מקומי כהעברה טורית, צריך להשתמש ביציאת nRF USB בלוח nRF52840 כדי לתקשר עם מארח ה-RCP (מחשב Linux).

מנתקים את קצה המיקרו USB של כבל ה-USB מיציאת הניפוי באגים של לוח nRF52840 שהופעל, ואז מחברים אותו מחדש ליציאת המיקרו USB nRF USB לצד הלחצן RESET. מעבירים את המתג nRF power source (מקור המתח של nRF) למצב USB.

46e7b670d2464842.png

הפעלת דימון OpenThread

בתכנון של RCP, משתמשים ב-OpenThread Daemon כדי לתקשר עם מכשיר Thread ולנהל אותו. מפעילים את ot-daemon עם הדגל -v verbose כדי לראות את פלט היומן ולוודא שהיא פועלת:

$ cd ~/src/openthread
$ sudo ./build/posix/src/posix/ot-daemon -v \
    'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=460800'

אם הפעולה בוצעה בהצלחה, הפלט של 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

משאירים את חלון הטרמינל הזה פתוח כדי שאפשר יהיה לראות את היומנים מ-ot-daemon.

אפשר להשתמש ב-ot-ctl כדי לתקשר עם צומת ה-RCP. ‫ot-ctl משתמש באותו CLI כמו אפליקציית OpenThread CLI. לכן, אפשר לשלוט בצמתים של ot-ctl באותו אופן כמו במכשירים האחרים שמדמים Thread.ot-daemon

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

$ sudo ./build/posix/src/posix/ot-ctl
>

בודקים את state של Node 2 (צומת ה-RCP) שהתחלתם איתו ot-daemon:

> state
disabled
Done

5. הגדרת ה-FTD

שני צמתי ה-Thread האחרים שבהם נעשה שימוש ב-Codelab הם מכשירי Thread מלאים (FTD) בתכנון הסטנדרטי של System-on-Chip ‏ (SoC). מכשיר אחד מתפקד כנציב, כדי לאמת ולאשר מכשירים בצורה מאובטחת ברשת הזו. המכשיר השני מתפקד כמכשיר מצטרף שהמכשיר המקצה יכול לאמת ברשת Thread.

בנייה והפעלה

יוצרים את הדוגמה OpenThread FTD לפלטפורמת nRF52840, עם התפקידים Commissioner ו-Joiner מופעלים:

$ cd ~/src/ot-nrf528xx
$ rm -rf build
$ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON

עוברים לספרייה עם קובץ ה-CLI הבינארי של OpenThread Full Thread Device ‏ (FTD) וממירים אותו לפורמט הקסדצימלי:

$ cd ~/src/ot-nrf528xx/build/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex

מחברים את כבל ה-USB ליציאת המיקרו USB שליד פין החשמל החיצוני בלוח nRF52840, ואז מחברים אותו למכונת Linux. אם ה-RCP עדיין מחובר למכונת Linux, הלוח החדש אמור להופיע כיציאה טורית /dev/ttyACM1 (כל לוחות nRF52840 משתמשים ב-ttyACM כמזהה של היציאה הטורית).

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1

כמו קודם, מציינים את המספר הסידורי של לוח nRF52840 שמשמש ל-FTD:

c00d519ebec7e5f0.jpeg

עוברים למיקום של כלי שורת הפקודה nRFx ומבצעים Flash של קובץ ה-FTD hex של 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 build מופעלת האפשרות להשתמש ב-USB CDC ACM מקומי כהעברה טורית, צריך להשתמש ביציאת nRF USB בלוח nRF52840 כדי לתקשר עם מארח ה-RCP (מכונת Linux).

מנתקים את קצה המיקרו USB של כבל ה-USB מיציאת הניפוי באגים של לוח nRF52840 שהופעל, ואז מחברים אותו מחדש ליציאת המיקרו USB nRF USB לצד הלחצן RESET. מעבירים את המתג nRF power source (מקור המתח של nRF) למצב USB.

46e7b670d2464842.png

אימות ה-build

כדי לוודא שהבנייה הצליחה, ניגשים ל-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 Commissioner ולחזור לטרמינל של Linux כדי שאפשר יהיה להפעיל את הלוח הבא. כדי לחזור ל-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, באמצעות ה-build הקיים ot-cli-ftd.hex. בסיום, חשוב לחבר מחדש את הלוח למחשב באמצעות יציאת ה-USB של nRF ולהעביר את המתג nRF power source למצב VDD.

אם שני הצמתים האחרים מחוברים למכונת Linux כשמחברים את הלוח השלישי, הוא אמור להופיע כיציאה טורית /dev/ttyACM2:

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1  /dev/ttyACM2

נותנים ללוח את התווית Joiner (מצטרף).

כשמאמתים באמצעות Screen, במקום ליצור מופע חדש של Screen משורת הפקודה, צריך לצרף מחדש את המופע הקיים וליצור חלון חדש בתוכו (שבו השתמשתם בשביל FTD Commissioner):

$ screen -r

יוצרים את החלון החדש בתוך Screen באמצעות Ctrl+a → c.

מופיעה שורת פקודה חדשה. ניגשים אל OpenThread CLI עבור FTD Joiner:

$ screen /dev/ttyACM2

בחלון החדש, מקישים על Return במקלדת כמה פעמים כדי להציג את ההנחיה של OpenThread CLI‏ >. מציגים את ממשק IPv6 ובודקים את הכתובות:

> ifconfig up
Done
> ipaddr
fe80:0:0:0:6c1e:87a2:df05:c240
Done

עכשיו, כשה-CLI של FTD Joiner נמצא באותו מופע של Screen כמו FTD Commissioner, אפשר לעבור ביניהם באמצעות Ctrl+a → n.

משתמשים ב-Ctrl+a →

d בכל שלב כדי לצאת מ-Screen.

6. הגדרת חלון הטרמינל

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

מומלץ שיהיו לכם ארבעה חלונות זמינים:

  1. שירות / יומנים ot-daemon
  2. RCP Joiner דרך ot-ctl
  3. FTD Commissioner באמצעות OpenThread CLI
  4. FTD Joiner באמצעות OpenThread CLI

אם אתם רוצים להשתמש בכלי או בהגדרה משלכם של מסוף או יציאה טורית, אתם יכולים לדלג לשלב הבא. אתם יכולים להגדיר את חלונות הטרמינל בכל המכשירים בצורה שהכי מתאימה לכם.

שימוש במסך

כדי להקל על השימוש, מומלץ להפעיל רק סשן אחד של Screen. אמור להיות לכם אחד כזה מההגדרה של שני ה-FTD.

כל הפקודות ב-Screen מתחילות ב-Ctrl+a.

פקודות בסיסיות למסך:

חיבור מחדש לסשן Screen (משורת הפקודה)

screen -r

יציאה מהפעלת Screen

Ctrl+a → d

יצירת חלון חדש בסשן של שיתוף המסך

Ctrl+a → c

מעבר בין חלונות באותו סשן של Screen

‫Ctrl+a → n (קדימה)‫Ctrl+a → p (אחורה)

הפסקת הפעולה של החלון הנוכחי בסשן Screen

Ctrl+a → k

מסך מפוצל

באמצעות Screen, אפשר לפצל את הטרמינל לכמה חלונות:

f1cbf1258cf0a5a.png

כדי לגשת לפקודות ב-screen, משתמשים ב-Ctrl+a. כל פקודה צריכה להתחיל בשילוב מקשי הגישה הזה.

אם פעלתם בדיוק לפי ההוראות ב-Codelab, אמורים להיות לכם שני חלונות (FTD Commissioner, ‏ FTD Joiner) באותו מופע של Screen. כדי לפצל את המסך בין שני החלונות, קודם צריך להיכנס לסשן Screen הקיים:

$ screen -r

צריך להיות לכם אחד ממכשירי ה-FTD. פועלים לפי השלבים הבאים ב-Screen:

  1. ‫Ctrl+a → S כדי לפצל את החלון אופקית
  2. ‫Ctrl+a → Tab כדי להעביר את הסמן לחלון הריק החדש
  3. ‫Ctrl+a → n כדי להעביר את החלון החדש לחלון הבא
  4. אם הוא זהה לחלון העליון, לוחצים שוב על 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 → c

פיצול אנכי של החלון

Ctrl+a →

פיצול אופקי של החלון

Ctrl+a → S

מעבר לחלון המוצג הבא

Ctrl+a → Tab

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

‫Ctrl+a → n או p

שינוי השם של החלון הנוכחי

Ctrl+a → A

אפשר לצאת מ-Screen בכל שלב באמצעות Ctrl+a ‏→ d ולחבר מחדש באמצעות screen -r משורת הפקודה.

מידע נוסף על Screen זמין במדריך העזר המהיר של GNU Screen.

7. יצירת רשת Thread

אחרי שסיימתם להגדיר את כל חלונות המסוף והמסכים, אפשר ליצור את רשת Thread. ב-FTD Commissioner, יוצרים מערך נתונים תפעולי חדש ומבצעים commit שלו כמערך הנתונים הפעיל. מערך הנתונים התפעולי הוא ההגדרה של רשת 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

אחרי רגע, בודקים את מצב המכשיר. הוא צריך להיות המוביל. כדאי לשמור את 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 לא מופיעה ברשימה, נסו לסרוק שוב.

8. הוספת כלי ההצטרפות לתוכנית

הפעלת Thread לא פעילה ברשת, ולכן נצטרך להוסיף את ה-RCP Joiner לרשת Thread שיצרנו באמצעות תהליך הפעלה מחוץ לפס.

ב-FTD Commissioner, רשמנו את מפתח הרשת, לדוגמה 1234c0de7ab51234c0de7ab51234c0de. אם צריך לחפש שוב את מפתח הרשת, מריצים את הפקודה הבאה ב-FTD Commissioner:

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

בשלב הבא, ב-RCP Joiner, מגדירים את מערך הנתונים הפעיל Network Key (מפתח הרשת) למפתח הרשת של FTD Commissioner:

## 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 שמורכבת משני צמתים, כפי שמוצג בתרשים הטופולוגיה הזה:

otcodelab_top01C_2nodes.png

תרשימי טופולוגיה

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

b75a527be4563215.png

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

9. הפעלת ה-FTD Joiner

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

ב-FTD Joiner, מאתרים את eui64 כדי שהנציב של FTD יוכל לזהות אותו:

## FTD Joiner ##
----------------

> eui64
2f57d222545271f1
Done

ב-FTD Commissioner, מפעילים את ה-Commissioner ומציינים את eui64 המכשיר שיכול להצטרף, יחד עם פרטי ההצטרפות, למשל J01NME. האישור של המצטרף הוא מחרוזת ספציפית למכשיר שמורכבת מתווים אלפאנומריים באותיות רישיות (0-9 ו-A-Y, לא כולל I, ‏ O, ‏ Q ו-Z כדי לשפר את הקריאות), באורך של 6 עד 32 תווים.

## FTD Commissioner ##
----------------------

> commissioner start
Done
> commissioner joiner add 2f57d222545271f1 J01NME
Done

עוברים אל FTD 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. הסיבה לכך היא שהמכשיר הזה לא מוגדר כמכשיר הראשי, וגם לא מוגדר בו תפקיד ספציפי ל-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 Commissioner ובודקים את טבלאות הנתב והילדים כדי לוודא שקיימים שלושה מכשירים ברשת 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 מחובר לרשת כמכשיר קצה (משני). זו הטופולוגיה המעודכנת שלנו:

otcodelab_top01C_ed01.png

10. שרשור בפעולה

מכשירי Thread ב-Codelab הם סוג ספציפי של מכשיר Thread מלא (FTD) שנקרא מכשיר קצה שמתאים לנתב (REED). המשמעות היא שהם יכולים לפעול כנתב או כמכשיר קצה, ויכולים לשדרג את עצמם ממכשיר קצה לנתב.

פרוטוקול Thread יכול לתמוך בעד 32 נתבים, אבל הוא מנסה לשמור על מספר הנתבים בין 16 ל-23. אם מכשיר REED מצורף כמכשיר קצה (צאצא) ומספר הנתבים נמוך מ-16, אחרי תקופת זמן אקראית של עד שתי דקות הוא מקודם אוטומטית לנתב.

אם היו לכם שני ילדים ברשת Thread אחרי הוספת ה-FTD Joiner, צריך להמתין לפחות שתי דקות ואז לבדוק מחדש את טבלאות הנתב והצאצא ב-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.

otcodelab_top01C.png

מאשרים את המצב החדש ואת RLOC16 ב-FTD Joiner:

## FTD Joiner ##
----------------

> state
router
Done
> rloc16
b800
Done

שדרוג לאחור של FTD Joiner

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

## FTD Joiner ##
----------------

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

בחזרה אל FTD Commissioner, עכשיו FTD Joiner אמור להופיע בטבלת הצאצא (מזהה = 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.

otcodelab_top01C.png

הסרת הבכיר בארגון

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

בFTD Commissioner, משביתים את Thread כדי להסיר אותו מרשת Thread:

## FTD Commissioner ##
----------------------

> thread stop
Done
> ifconfig down
Done

תוך שתי דקות, FTD Joiner הופך למוביל השרשור החדש. כדי לוודא את הדברים הבאים, בודקים את המצב ואת כתובות ה-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

otcodelab_top02C_01.png

בודקים את טבלת הצאצא. שימו לב שיש RLOC16 חדש. זהו ה-RCP Joiner, כפי שמצוין על ידי המזהה וכתובת ה-MAC המורחבת שלו. כדי לשמור על רשת ה-Thread, הוא החליף נתבים הורים, מ-FTD Commissioner ל-FTD Joiner. התוצאה היא RLOC16 חדש עבור ה-RCP Joiner (כי מזהה הנתב שלו השתנה מ-3 ל-46).

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

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

ב-FTD Commissioner, מפעילים מחדש את Thread:

## FTD Commissioner ##
----------------------

> ifconfig up
Done
> thread start
Done

תוך שתי דקות, הוא מתחבר מחדש אוטומטית לרשת 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

otcodelab_top02C_02.png

רשת ה-Thread שלנו מורכבת שוב משלושה צמתים.

11. פתרון בעיות

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

מסך

אם אתם הולכים לאיבוד בהגדרה (יותר מדי חלונות Screen או Screens בתוך Screen), המשיכו לסגור חלונות Screen באמצעות Ctrl+a → k עד שלא יישארו חלונות, והפלט של screen -ls בשורת הפקודה יהיה No Sockets found. לאחר מכן, יוצרים מחדש חלונות של מסך לכל מכשיר. מצבי המכשיר נשמרים גם כשהמסך נסגר.

צמתים של פרוטוקול Thread

אם טופולוגיית רשת Thread לא תואמת לתיאור ב-Codelab הזה, או אם הצמתים מתנתקים מסיבה כלשהי (יכול להיות שהמחשב עם Linux שהם מחוברים אליו עבר למצב שינה), מומלץ להשבית את 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

12. שימוש ב-multicast

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

כתובת IPv6

היקף

נמסר אל

ff02::1

קישור מקומי

כל ה-FTD וה-MED

ff02::2

קישור מקומי

כל נתבי הגבולות ו-FTD

ff03::1

Mesh-Local

כל ה-FTD וה-MED

ff03::2

Mesh-Local

כל נתבי הגבולות ו-FTD

ב-Codelab הזה אנחנו לא משתמשים בנתב גבול, לכן נתמקד בשתי כתובות ה-Multicast של FTD ו-MED.

ההיקף של Link-Local כולל את כל ממשקי ה-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 Commissioner קיבל רק תגובה אחת, מכתובת Link-Local Address ‏ (LLA) של FTD Joiner. המשמעות היא שמצטרף ה-FTD הוא המכשיר היחיד שאליו יכול להגיע נציב ה-FTD בקפיצה אחת.

otcodelab_top02C_02_LL.png

עכשיו שולחים פינג 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 Commissioner, והשנייה (שמספרה מסתיים ב-943b) היא כתובת ה-LLA של RCP Joiner.

otcodelab_top02C_02_LL02.png

כלומר, רכיב ה-FTD Joiner מחובר ישירות גם לרכיב ה-FTD Commissioner וגם לרכיב ה-RCP Joiner, וכך מאומתת הטופולוגיה שלנו.

Mesh-Local

היקף 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 מקומי של רשת Mesh של ה-RCP Joiner (ML-EID, מסתיים ב-d55f). הסיבה לכך היא שההיקף המקומי של רשת ה-Mesh כולל את כל רשת ה-Thread. לא משנה איפה ברשת נמצא המכשיר, הוא יירשם לכתובת ff03::1.

otcodelab_top02C_02_ML.png

כדי לאשר את אותה התנהגות, שולחים פינג אל 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

otcodelab_top02C_02_LL02.png

שימו לב לזמן התגובה של RCP Joiner בשתי הפלטות של הפינג. הזמן שחלף עד שהרכיב RCP Joiner הגיע אל FTD Commissioner (68ms) היה ארוך בהרבה מהזמן שחלף עד שהוא הגיע אל FTD Joiner (23ms). הסיבה לכך היא שההודעה צריכה לעבור שני שלבים כדי להגיע לנציב ה-FTD, לעומת שלב אחד בהודעה של המצטרף ל-FTD.

יכול להיות ששמתם לב גם שהפינג של שידור מרובה כתובות מקומי ברשת ה-Mesh הגיב עם RLOC רק לשני ה-FTD – ולא ל-RCP Joiner. הסיבה לכך היא שמכשירי ה-FTD הם נתבים ברשת, בעוד שמכשיר ה-RCP הוא מכשיר קצה.

בודקים את הסטטוס של RCP Joiner כדי לוודא:

## RCP Joiner ##
----------------

> state
child

13. שליחת הודעות באמצעות UDP

אחד משירותי האפליקציה ש-OpenThread מספק הוא פרוטוקול User Datagram‏ (UDP), פרוטוקול של שכבת התעבורה. אפליקציה שמבוססת על OpenThread יכולה להשתמש ב-UDP API כדי להעביר הודעות בין צמתים ברשת Thread, או למכשירים אחרים ברשת חיצונית (כמו האינטרנט, אם ברשת Thread יש נתב גבולות).

שקעי UDP נחשפים דרך OpenThread CLI. נשתמש בו כדי להעביר הודעות בין שני מכשירי FTD.

מקבלים את כתובת ה-EID המקומית של הרשת עבור 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 ומתחברים לשקע שהגדרתם ב-FTD Joiner באמצעות ה-ML-EID שלו:

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

14. מעולה!

יצרתם רשת פיזית של פרוטוקול Thread!

b915c433e7027cc7.png

עכשיו אתם יודעים:

  • ההבדל בין סוגי מכשירים, תפקידים והיקפים של Thread
  • איך מכשירי Thread מנהלים את המצבים שלהם ברשת
  • איך מעבירים הודעות פשוטות בין צמתים באמצעות UDP

השלבים הבאים

אפשר לנסות את התרגילים הבאים על סמך ה-Codelab הזה:

  • מבצעים מחדש את ההפעלה של לוח ה-FTD Joiner כ-MTD באמצעות קובץ ה-ot-cli-mtd הבינארי, ורואים שהוא אף פעם לא משדרג את עצמו לנתב או מנסה להפוך ל-Leader.
  • מוסיפים עוד מכשירים (אפשר לנסות פלטפורמה אחרת!) לרשת ויוצרים סקיצה של הטופולוגיה באמצעות טבלאות של נתבים וצאצאים, ופינג לכתובות מולטיקאסט
  • שימוש ב-pyspinel לשליטה ב-NCP
  • ממירים את ה-NCP לנתב גבולות באמצעות OpenThread Border Router ומחברים את רשת Thread לאינטרנט

קריאה נוספת

באתר openthread.io וב-GitHub תוכלו למצוא מגוון משאבים של OpenThread, כולל:

  • פלטפורמות נתמכות – כאן אפשר לראות את כל הפלטפורמות שתומכות ב-OpenThread
  • Build OpenThread – פרטים נוספים על בנייה והגדרה של OpenThread
  • Thread Primer – סקירה של כל המושגים שקשורים ל-Thread שמופיעים ב-Codelab הזה

הפניה: