1. מבוא
OpenThread, שפורסם על ידי Google, הוא הטמעה בקוד פתוח של פרוטוקול הרשתות Thread®. Google Nest השיקה את OpenThread כדי להפוך את הטכנולוגיה שמשמשת במוצרי Nest לזמינה למפתחים באופן נרחב, וכך לזרז את הפיתוח של מוצרים לבית החכם.
מפרט Thread מגדיר פרוטוקול תקשורת אלחוטית מהימן, מאובטח וחסכוני מבוסס-IPv6 בין מכשירים לאפליקציות ביתיות. OpenThread מטמיע את כל שכבות הרשת של Thread, כולל IPv6, 6LoWPAN, IEEE 802.15.4 עם אבטחת MAC, יצירת קישורי רשתות וניתוב רשתות.
ב-Codelab הזה תלמדו לתכנת את OpenThread בחומרה אמיתית, ליצור ולנהל רשת Thread ולהעביר הודעות בין צמתים.
מה תלמדו
- פיתוח קובצי אימג' של OpenThread CLI והעברתם (flashing) ללוחות פיתוח
- פיתוח RCP שמורכב ממכונת Linux ומלוח פיתוח
- תקשורת עם RCP באמצעות OpenThread Daemon ו-
ot-ctl
- ניהול ידני של צמתים של Thread באמצעות GNU Screen ו-OpenThread CLI
- הפעלה מאובטחת של מכשירים ברשת Thread
- איך פועל Multicast ב-IPv6
- העברת הודעות בין צמתים של Thread באמצעות UDP
מה נדרש
חומרה:
- 3 לוחות פיתוח של Nordic Semiconductor nRF52840
- 3 כבלים מסוג USB ל-Micro-USB לחיבור הלוחות
- מחשב Linux עם לפחות 3 יציאות USB
תוכנה:
- GNU Toolchain
- כלי שורת הפקודה של Nordic nRF5x
- תוכנת Segger J-Link
- OpenThread
- Git
2. תחילת העבודה
סימולציה של OpenThread
לפני שמתחילים, מומלץ לעבור על הקודלאב של סימולציית OpenThread כדי להכיר את המושגים הבסיסיים של Thread ואת ה-CLI של OpenThread.
מסופי יציאות טוריות
צריך לדעת איך להתחבר ליציאה טורית דרך מסוף. ב-Codelab הזה נעשה שימוש ב-GNU Screen, ומופיעה סקירה כללית על השימוש בו, אבל אפשר להשתמש בכל תוכנת טרמינל אחרת.
מכונה עם Linux
קודי ה-Codelab האלה תוכננו לשימוש במכונה מבוססת-Linux מסוג i386 או x86, שתשמש כמארח למכשיר Thread עם מעבד רדיו משותף (RCP), ולפלאש את כל לוחות הפיתוח של Thread. כל השלבים נבדקו ב-Ubuntu 14.04.5 LTS (Trusty Tahr).
לוחות Nordic Semiconductor nRF52840
ב-Codelab הזה נעשה שימוש בשלוש לוחות nRF52840 PDK.
התקנת SEGGER J-Link
אנחנו משתמשים ב-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 משמשת ליצירת גרסאות build.
מומלץ להעביר את הארכיון שחולץ לתיקייה /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/
במכונת Linux. פועלים לפי ההוראות בקובץ readme.txt
של הארכיון.
מסך ההתקנה (אופציונלי)
Screen הוא כלי פשוט לגישה למכשירים שמחוברים באמצעות יציאה טורית. ב-Codelab הזה נעשה שימוש ב-Screen, אבל אפשר להשתמש בכל אפליקציית מסוף של יציאה טורית שרוצים.
$ sudo apt-get install screen
3. שכפול מאגרים
OpenThread
מעתיקים ומתקינים את OpenThread. הפקודות של script/bootstrap
מוודאות ש-toolchain מותקן והסביבה מוגדרת כראוי:
$ mkdir -p ~/src $ cd ~/src $ git clone --recursive https://github.com/openthread/openthread.git $ cd openthread $ ./script/bootstrap
פיתוח של OpenThread Daemon:
$ script/cmake-build posix -DOT_DAEMON=ON
עכשיו אתם מוכנים לפתח ולצרוב את OpenThread ללוחות nRF52840.
4. הגדרת ה-RCP Joiner
פיתוח וטעינה
פיתוח הדוגמה של OpenThread nRF52840 עם Joiner ופונקציונליות USB מקורית. המכשיר משתמש בתפקיד 'מצטרף' כדי לעבור אימות מאובטח ולהתחיל לפעול ברשת Thread. USB מקורי מאפשר להשתמש ב-USB CDC ACM ככלי להעברה טורית בין nRF52840 לבין המארח.
תמיד צריך לנקות קודם את המאגר של גרסאות build קודמות על ידי הפעלת rm -rf build
.
$ cd ~/src $ git clone --recursive https://github.com/openthread/ot-nrf528xx.git $ cd ot-nrf528xx $ script/build nrf52840 USB_trans
עוברים לספרייה עם קובץ ה-RCP הבינארי של OpenThread וממירים אותו לפורמט הקסדצימלי:
$ cd ~/src/ot-nrf528xx/build/bin $ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex
מחברים את כבל ה-USB ליציאת ניפוי הבאגים של Micro-USB ליד סיכת החשמל החיצונית בלוח nRF52840, ואז מחברים אותו למכונה של Linux. מגדירים את המתג nRF power source (מקור הכוח של nRF) בלוח nRF52840 לערך VDD. כשהחיבור תקין, נורית LED5 דולקת.
אם זו הלוחה הראשונה שמחוברת למכונת Linux, היא מופיעה כיציאה הטורית /dev/ttyACM0
(כל הלוחות מסוג nRF52840 משתמשים ב-ttyACM
כמזהה היציאה הטורית).
$ ls /dev/ttyACM* /dev/ttyACM0
מציינים את המספר הסידורי של לוח ה-nRF52840 שמשמש ל-RCP:
עוברים למיקום של כלי שורת הפקודה של nRFx ומעבירים את קובץ ה-hex של OpenThread RCP ללוח nRF52840 באמצעות המספר הסידורי של הלוח. שימו לב: אם משמיטים את הדגל --verify
, תוצג הודעת אזהרה על כך שתהליך ה-flash יכול להיכשל ללא שגיאה.
$ 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 שעבר את הפלאש, ומחברים אותו מחדש ליציאת nRF USB עם מיקרו-USB ליד הלחצן RESET. מעבירים את המתג nRF power source למצב USB.
הפעלת OpenThread Daemon
בתכנון ה-RCP, משתמשים ב-OpenThread Daemon כדי לתקשר עם מכשיר Thread ולנהל אותו. מפעילים את ot-daemon
עם הדגל -v
כדי לראות את הפלט ביומן ולאשר שהיא פועלת:
$ 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 שבו נעשה שימוש באפליקציית ה-CLI של OpenThread. לכן, אפשר לשלוט בצמתים של ot-daemon
באותו אופן שבו שולטים במכשירי Thread האחרים בסימולציה.
בחלון טרמינל שני, מפעילים את ot-ctl
:
$ sudo ./build/posix/src/posix/ot-ctl >
בודקים את state
של צומת 2 (צומת ה-RCP) שהפעלתם באמצעות ot-daemon
:
> state disabled Done
5. הגדרת ה-FTDs
שני צמתים אחרים של Thread שנעשה בהם שימוש ב-Codelab הזה הם מכשירי Full Thread Devices (FTD) בתכנון הסטנדרטי של System-on-Chip (SoC). בסביבת ייצור, אפשר להשתמש ב-wpantund
, מנהל ממשק רשת ברמת ייצור, כדי לשלוט במכונות OpenThread NCP, אבל בסדנת הקוד הזו נשתמש ב-ot-ctl
, ממשק שורת הפקודה של OpenThread.
מכשיר אחד פועל בתור המפקח, כדי לאמת מכשירים ברשת הזו ולהקצות להם תפקידים בצורה מאובטחת. המכשיר השני פועל כמכשיר שמצטרף, והנציב יכול לאמת אותו ברשת Thread.
פיתוח וטעינה
מריצים את ה-build של דוגמת OpenThread FTD לפלטפורמת nRF52840, עם התפקידים 'מפקח' ו'מצטרף' מופעלים:
$ 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 ליציאת ה-Micro-USB ליד סיכת החשמל החיצונית בלוח nRF52840, ואז מחברים אותו למכונה של Linux. אם ה-RCP עדיין מחובר למכונת Linux, הלוח החדש אמור להופיע כיציאה הטורית /dev/ttyACM1
(כל הלוחות של nRF52840 משתמשים ב-ttyACM
כמזהה היציאה הטורית).
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1
כמו קודם, מציינים את המספר הסידורי של לוח ה-nRF52840 שמשמש ל-FTD:
עוברים למיקום של כלי שורת הפקודה של nRFx, ומעבירים את קובץ ה-hex של OpenThread CLI FTD ללוח nRF52840 באמצעות מספר הלוח הסידורי:
$ cd ~/nrfjprog/ $ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \ ~/src/ot-nrf528xx/build/bin/ot-cli-ftd.hex --reset
נותנים שם 'נציב' ללוח.
חיבור ל-USB מקורי
מכיוון שה-build של OpenThread FTD מאפשר להשתמש ב-USB CDC ACM מקורי ככלי להעברה טורית, צריך להשתמש ביציאה nRF USB בלוח nRF52840 כדי לתקשר עם מארח ה-RCP (מכונה של Linux).
מנתקים את הקצה של כבל ה-USB עם מיקרו-USB מיציאת ניפוי הבאגים של לוח nRF52840 שעבר את הפלאש, ומחברים אותו מחדש ליציאת nRF USB עם מיקרו-USB ליד הלחצן RESET. מעבירים את המתג nRF power source למצב USB.
אימות ה-build
כדי לוודא שה-build הצליח, ניגשים ל-CLI של OpenThread באמצעות 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
כדי להתנתק מהמסך של FTD Commissioner CLI ולחזור לטרמינל 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
נותנים ללוח את התווית 'מרכז'.
כשמאמתים באמצעות Screen, במקום ליצור מופע חדש של Screen משורת הפקודה, צריך להתחבר מחדש למופע הקיים וליצור חלון חדש בתוכו (שמשמש את הנציב של FTD):
$ screen -r
יוצרים את החלון החדש בתוך המסך באמצעות Ctrl+a → c
.
תופיע הנחיה חדשה בשורת הפקודה. ניגשים ל-CLI של OpenThread עבור 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
מתי שרוצים כדי לצאת מהמסך.
6. הגדרת חלון הטרמינל
מעכשיו והלאה, תצטרכו לעבור בין מכשירי Thread בתדירות גבוהה, לכן חשוב לוודא שכל המכשירים פועלים ושהגישה אליהם קלה. עד עכשיו השתמשנו ב-Screen כדי לגשת לשני ה-FTD, והכלי הזה מאפשר גם מסך מפוצל באותו חלון מסוף. אפשר להשתמש באפשרות הזו כדי לראות איך צומת אחד מגיב לפקודות שהופקו בצומת אחר.
במצב אידיאלי, צריכים להיות זמינים ארבעה חלונות:
ot-daemon
service / logs- RCP Joiner דרך
ot-ctl
- נציג FTD באמצעות CLI של OpenThread
- FTD Joiner דרך OpenThread CLI
אם אתם רוצים להשתמש בכלי או בהגדרה משלכם של מסוף או יציאה טורית, אתם יכולים לדלג לשלב הבא. אתם יכולים להגדיר את חלונות המסוף בכל המכשירים בדרך שמתאימה לכם.
שימוש במסך
כדי להקל על השימוש, מומלץ להתחיל רק סשן אחד של Screen. כבר אמורה להיות לכם אחת מהן מהגדרת שני מכשירי ה-FTD.
כל הפקודות ב-Screen מתחילות ב-Ctrl+a.
פקודות בסיסיות למסך:
הצטרפות מחדש לסשן Screen (משורת הפקודה) |
|
יציאה מהסשן של שיתוף המסך | Ctrl+a → |
יצירת חלון חדש במהלך סשן המסך | Ctrl+a → |
מעבר בין חלונות באותו סשן מסך | Ctrl+a → |
סגירת החלון הנוכחי בסשן Screen | Ctrl+a → |
מסך מפוצל
בעזרת Screen אפשר לפצל את מסוף ה-Linux למספר חלונות:
כדי לגשת לפקודות ב-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
ואת ot-ctl
של RCP Joiner, צריך להפעיל את השירותים האלה באותה מופע של Screen. כדי לעשות זאת, מפסיקים את ot-daemon
ויוצאים מ-ot-ctl
, ומפעילים אותם מחדש בחלונות חדשים של Screen (Ctrl+a → c
).
ההגדרה הזו לא נדרשת, והיא נועדה רק כתרגיל למשתמש.
אפשר לפצל את המסך ולנווט בין חלונות באמצעות הפקודות הבאות:
יצירת חלון חדש | Ctrl+a → |
פיצול החלון באופן אנכי | Ctrl+a → |
פיצול חלון אופקית | Ctrl+a → |
מעבר לחלון הבא שמוצג | Ctrl+a → |
מעבר קדימה או אחורה בחלון המוצג | Ctrl+a → |
שינוי השם של החלון הנוכחי | Ctrl+a → |
אפשר לצאת מהמסך בכל שלב באמצעות Ctrl+a → d
ולחזור אליו באמצעות screen -r
בשורת הפקודה.
מידע נוסף על Screen זמין בחומר העזרה המהיר של GNU Screen.
7. יצירת רשת Thread
עכשיו, אחרי שהגדרתם את כל החלונות והמסכים של מסוף ה-SSH, נתחיל ליצור את רשת ה-Thread. ב-FTD Commissioner, יוצרים מערך נתונים תפעוליים חדש ומבצעים עליו התחייבות כמערך הפעיל. מערך הנתונים התפעולי הוא ההגדרה של רשת 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 |
מ-CLI של OpenThread ב-FTD Joiner:
## FTD Joiner ## ---------------- > scan | PAN | MAC Address | Ch | dBm | LQI | +------+------------------+----+-----+-----+ | c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |
אם הרשת codelab לא מופיעה ברשימה, מנסים לסרוק שוב.
8. הוספת ה-RCP Joiner
תהליך ההפעלה של Thread לא פעיל ברשת, כך שנצטרך להוסיף את המכשיר RCP Joiner לרשת Thread שיצרנו באמצעות תהליך הפעלה מחוץ לפס.
בנציג FTD, ציינו את מפתח הרשת, לדוגמה 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
פותחים את השרשור כדי ש-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 המקומית של רשת Mesh (fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f
כאן), כי תצטרכו אותה בהמשך.
חזרה לנציג FTD, בודקים את הטבלאות של הנתב והצאצאים כדי לוודא ששני המכשירים שייכים לאותה רשת. משתמשים ב-RLOC16 כדי לזהות את המכשיר שמצטרף ל-RCP.
## 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
שולחים הודעה ל-ping לכתובת המקומית של הרשת המשולבת של המכשיר המצטרף ל-RCP (הכתובת המקומית של הרשת המשולבת שהתקבלה מהפלט ipaddr
של המכשיר המצטרף ל-RCP) כדי לאמת את הקישוריות:
## 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 שמכילה שני צמתים, כפי שמוצג בתרשים הטופולוגיה הזה:
תרשימי טופולוגיה
במהלך שאר הקודלהב, נציג תרשים חדש של טופולוגיית השרשור בכל פעם שסטטוס הרשת ישתנה. התפקידים של הצמתים מסומנים כך:
נתבים הם תמיד חמישיונים ומכשירי קצה הם תמיד עיגולים. המספרים בכל צומת מייצגים את מזהה הנתב או מזהה הצאצא שמוצגים בפלט של CLI, בהתאם לתפקיד ולמצב הנוכחיים של כל צומת באותו זמן.
9. איך מצרפים את FTD Joiner
עכשיו נוסיף את מכשיר Thread השלישי לרשת 'codelab'. הפעם נשתמש בתהליך ההפעלה הבטוח יותר בתוך הפס, ונאפשר רק ל-FTD Joiner להצטרף.
בהצטרפות ל-FTD, מקבלים את eui64
כדי שהנציג של FTD יוכל לזהות אותו:
## FTD Joiner ## ---------------- > eui64 2f57d222545271f1 Done
ב-FTD 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
פותחים את השרשור כדי ש-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 ובודקים את המסנן ואת טבלאות הצאצאים כדי לוודא שיש שלושה מכשירים ברשת '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 צורף לרשת כמכשיר קצה (צאצא). זוהי הטופולוגיה המעודכנת שלנו:
10. שרשור בפעולה
מכשירי Thread ב-Codelab הזה הם סוג ספציפי של מכשיר Thread מלא (FTD) שנקרא מכשיר קצה מתאים לנתב (REED). המשמעות היא שהם יכולים לפעול כנתב או כמכשיר קצה, ויכולים לשדרג את עצמם ממכשיר קצה לנתב.
השרשור יכול לתמוך ב-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 (Extended MAC = e6cdd2d93249a243
) הגדיר את עצמו כנתב. שימו לב שה-RLOC16 שונה (b800
במקום 0c02
). הסיבה לכך היא שה-RLOC16 מבוסס על מזהה הנתב ומזהה הצאצא של המכשיר. כשהמכשיר עובר ממכשיר קצה לנתב, הערכים של מזהה הנתב ומזהה הצאצא משתנים, וכך גם ה-RLOC16.
מוודאים שהמצב החדש ו-RLOC16 מופיעים ב-FTD Joiner:
## FTD Joiner ## ---------------- > state router Done > rloc16 b800 Done
שדרוג לאחור של FTD Joiner
כדי לבדוק את ההתנהגות הזו, אפשר לשדרג לאחור באופן ידני את ה-FTD Joiner מנתב למכשיר קצה. משנים את המצב ל-child ובודקים את RLOC16:
## FTD Joiner ## ---------------- > state child Done > rloc16 0c03 Done
חזרה למפקח FTD, ה-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
.
הסרת הבכיר בארגון
המוביל נבחר באופן עצמאי מבין כל נתב השרשור. כלומר, אם המכשיר המוביל הנוכחי יוסר מרשת Thread, אחד מהנתבים האחרים יהפוך למכשיר המוביל החדש.
בנציג FTD, משביתים את Thread כדי להסיר אותו מרשת Thread:
## FTD Commissioner ## ---------------------- > thread stop Done > ifconfig down Done
תוך שתי דקות, המשתמש שהצטרף ל-FTD הופך ל'מנהל השרשור' החדש. בודקים את המצב ואת כתובות ה-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, כפי שמצוין במזהה ובכתובת ה-MAC המורחבת שלו. כדי לשמור על הרשת של Thread, הוא החליף את הנתב ההורה מ-FTD Commissioner ל-FTD Joiner. כתוצאה מכך, נוצר RLOC16 חדש למצטרף ה-RCP (כי מזהה הנתב שלו השתנה מ-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
יכול להיות שתצטרכו להמתין כמה דקות עד שה-Joiner של RCP יתחבר ל-Joiner של FTD כצאצא. בודקים את המצב ואת RLOC16 כדי לוודא:
## RCP Joiner ## -------------- > state child > rloc16 b801
מצרפים מחדש את הנציג של FTD
רשת Thread עם שני צמתים לא מעניינת במיוחד. ננסה לחבר את הנציב של FTD לאינטרנט.
בנציג FTD, מפעילים מחדש את השרשור:
## 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
רשת ה-Thread שלנו מורכבת שוב משלושה צמתים.
11. פתרון בעיות
ניהול רשת Thread עם כמה מכשירים בחלונות שונים של מסוף או מסך יכול להיות מורכב. אם נתקלת בבעיות, אפשר להיעזר בטיפים הבאים כדי "לאפס" את מצב הרשת או סביבת העבודה.
מסך
אם אתם לא מצליחים להבין את ההגדרות (יש יותר מדי חלונות Screen או חלונות Screen בתוך Screen), תוכלו להמשיך לסגור את חלונות Screen באמצעות Ctrl+a → k עד שלא יהיו יותר חלונות כאלה, והפלט של screen -ls
בשורת הפקודה יהיה No Sockets found
. לאחר מכן יוצרים מחדש חלונות מסך לכל מכשיר. מצבי המכשיר נשמרים גם כש-Screen מושבת.
צמתים של שרשורים
אם הטופולוגיה של רשת Thread לא תואמת לתיאור במדריך הזה, או אם צמתים מתנתקים מסיבה כלשהי (אולי כי מכונת Linux שמפעילה אותם נכנסה למצב שינה), עדיף להפסיק את Thread, לנקות את פרטי הכניסה לרשת ולהתחיל מחדש מהשלב יצירת רשת Thread.
כדי לאפס את ה-FTDs:
## 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, כתובות ספציפיות שמורות לשימוש ב-multicast עם קבוצות שונות של מכשירים, בהתאם להיקף.
כתובת IPv6 | היקף | נמסר אל |
| קישור מקומי | כל FTD ו-MED |
| קישור מקומי | כל נתבי ה-FTD ונתבי הגבולות |
| Mesh-Local | כל FTD ו-MED |
| Mesh-Local | כל נתבי ה-FTD ונתבי הגבולות |
מכיוון שלא משתמשים ב-Border Router ב-Codelab הזה, נתמקד בשתי כתובות ה-multicast של FTD ו-MED.
מקומי לקישור
ההיקף המקומי של הקישור כולל את כל ממשקי Thread שאפשר להגיע אליהם באמצעות שידור רדיו יחיד, או 'קפיצה' אחת. הטופולוגיה של הרשת קובעת אילו מכשירים יגיבו ל-ping לכתובת ה-multicast 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 קיבל רק תשובה אחת, מכתובת ה-Link-Local (LLA) של FTD Joiner. כלומר, המכשיר שמצטרף ל-FTD הוא המכשיר היחיד שאפשר להגיע אליו מהמכשיר שמפקח על 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
ההיקף Mesh-Local כולל את כל ממשקי Thread שאפשר לגשת אליהם באותה רשת Thread. נבדוק את התגובות להודעת ping לכתובת ה-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 קיבל שתי תשובות, אחת מה-RLOC (Locator ניתוב) של המכשיר שמצטרף ל-FTD (מסתיים ב-b800
) ואחת מה-ML-EID (Mesh-Local EID) של המכשיר שמצטרף ל-RCP (מסתיים ב-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 בשני הפלטים של ה-ping. זמן ההתקדמות של המאגר המאוחד של RCP אל הנציב של FTD היה ארוך בהרבה (68 אלפיות השנייה) מאשר הזמן שבו הוא הגיע למאגר המאוחד של FTD (23 אלפיות השנייה). הסיבה לכך היא שהבקשה צריכה לעבור שני קפיצות כדי להגיע ל-FTD Commissioner, לעומת קפיצה אחת ל-FTD Joiner.
יכול להיות שגם שמתם לב שה-ping של ה-multicast המקומי ברשת התגובה עם ה-RLOC רק לשני ה-FTDs – ולא למכשיר ה-RCP Joiner. הסיבה לכך היא ש-FTDs הם נתבים ברשת, בעוד ש-RCP הוא מכשיר קצה.
בודקים את הסטטוס של RCP Joiner כדי לוודא:
## RCP Joiner ## ---------------- > state child
13. שליחת הודעות באמצעות UDP
אחד משירותי האפליקציות ש-OpenThread מספק הוא User Datagram Protocol (UDP), פרוטוקול בשכבת התעבורה. אפליקציה שנוצרה על בסיס OpenThread יכולה להשתמש ב-UDP API כדי להעביר הודעות בין צמתים ברשת Thread, או למכשירים אחרים ברשת חיצונית (למשל, לאינטרנט, אם ברשת Thread יש נתב גבול).
שקעי ה-UDP נחשפים דרך ה-CLI של 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 ומתחברים לשקע שהגדרתם ב-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!
עכשיו אתם יודעים:
- ההבדל בין סוגי המכשירים, התפקידים וההיקפים של Thread
- איך מכשירים בפרוטוקול Thread מנהלים את המצבים שלהם ברשת
- איך מעבירים הודעות פשוטות בין צמתים באמצעות UDP
השלבים הבאים
אחרי שנסיים את הקודלאב הזה, נסו את התרגילים הבאים:
- מבצעים הפעלה מחדש של לוח ה-FTD Joiner כ-MTD באמצעות הקובץ הבינארי
ot-cli-mtd
, ומבחינים בכך שהוא אף פעם לא משדרג את עצמו לנתב או מנסה להפוך ל-Leader. - מוסיפים עוד מכשירים לרשת (כדאי לנסות פלטפורמה אחרת!) ומציירים את הטופולוגיה באמצעות טבלאות של נתב ושל צאצא, יחד עם פינגים לכתובות ה-multicast.
- שימוש ב-pyspinel כדי לשלוט ב-NCP
- ממירים את ה-NCP לנתב גבול באמצעות OpenThread Border Router ומחברים את רשת Thread לאינטרנט
קריאה נוספת
באתר openthread.io וב-GitHub תוכלו למצוא מגוון משאבים של OpenThread, כולל:
- פלטפורמות נתמכות – כאן תוכלו למצוא את כל הפלטפורמות שתומכות ב-OpenThread
- פיתוח OpenThread – פרטים נוספים על פיתוח והגדרה של OpenThread
- מבוא ל-Thread – מכסה את כל המושגים של Thread שמופיעים ב-Codelab הזה
מקור: