1. Введение

OpenThread, выпущенный Google, — это реализация сетевого протокола Thread® с открытым исходным кодом. Компания Google Nest выпустила OpenThread, чтобы сделать технологию, используемую в продуктах Nest, широко доступной для разработчиков и ускорить разработку продуктов для «умного дома».
Спецификация Thread определяет надежный, безопасный и энергоэффективный протокол беспроводной связи между устройствами на основе IPv6 для домашних приложений. OpenThread реализует все сетевые уровни Thread, включая IPv6, 6LoWPAN, IEEE 802.15.4 с защитой MAC, установление соединения в ячеистой сети и маршрутизацию в ячеистой сети.
В этом практическом занятии вы научитесь программировать OpenThread на реальном оборудовании, создавать и управлять сетью Thread, а также передавать сообщения между узлами.

Что вы узнаете
- Сборка и прошивка бинарных файлов OpenThread CLI на платы разработки.
- Создание RCP-системы, состоящей из машины под управлением Linux и платы разработки.
- Взаимодействие с RCP с использованием демона OpenThread и
ot-ctl - Ручное управление узлами потоков с помощью GNU Screen и OpenThread CLI.
- Безопасная настройка устройств в сети Thread.
- Как работает многоадресная рассылка IPv6
- Передача сообщений между узлами Thread по протоколу UDP.
Что вам понадобится
Аппаратное обеспечение:
- 3 платы разработки Nordic Semiconductor nRF52840
- 3 кабеля USB-Micro-USB для подключения плат
- Компьютер под управлением Linux с как минимум тремя USB-портами.
Программное обеспечение:
- Набор инструментов GNU
- Инструменты командной строки Nordic nRF5x
- Программное обеспечение Segger J-Link
- OpenThread
- Гит
2. Начало работы
Моделирование OpenThread
Перед началом работы вы можете ознакомиться с практическим заданием по моделированию потоков OpenThread , чтобы понять основные понятия, связанные с потоками, и интерфейсом командной строки OpenThread.
Терминалы последовательного порта
Вы должны уметь подключаться к последовательному порту через терминал. В этом практическом занятии используется GNU Screen, и приводится обзор его использования, но можно использовать любое другое терминальное программное обеспечение.
Linux-машина
Данная практическая работа была разработана для использования машины под управлением Linux на базе i386 или x86 в качестве хоста для устройства Radio Co-Processor (RCP) Thread и для прошивки всех плат разработки Thread. Все этапы были протестированы на Ubuntu 14.04.5 LTS (Trusty Tahr).
Платы Nordic Semiconductor nRF52840
В этом практическом занятии используются три платы nRF52840 PDK .

Установите SEGGER J-Link
Для программирования плат nRF52840, имеющих встроенные модули JTAG, мы используем SEGGER J-Link. Установите его на свой компьютер под управлением Linux.
Загрузите подходящий пакет для вашей машины и установите его в нужное место. В Linux это /opt/SEGGER/JLink .
Установите инструменты командной строки nRF5x.
Инструменты командной строки nRF5x позволяют прошивать бинарные файлы OpenThread на платы nRF52840. Установите соответствующую сборку nRF5x-Command-Line-Tools-<OS> на свой компьютер с Linux.
Поместите распакованный пакет в корневую папку ~/
Установите инструментарий ARM GNU.
Для сборки используется инструментарий ARM GNU Toolchain.
Рекомендуем разместить распакованный архив в папке /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ на вашем компьютере с Linux. Инструкции по установке см. в файле readme.txt , содержащемся в архиве.
Экран установки (опционально)
Screen — это простой инструмент для доступа к устройствам, подключенным через последовательный порт. В этом практическом занятии используется 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
Собрать демон OpenThread:
$ script/cmake-build posix -DOT_DAEMON=ON
Теперь вы готовы собрать и прошить OpenThread на платы nRF52840.
4. Настройка устройства RCP Joiner
Сборка и прошивка
Создайте пример 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-кабель к отладочному порту Micro-USB, расположенному рядом с контактом внешнего питания на плате nRF52840, а затем подключите его к компьютеру под управлением Linux. Установите переключатель источника питания nRF на плате nRF52840 в положение VDD . При правильном подключении загорится светодиод LED5 .

Если это первая плата, подключенная к машине под управлением Linux, она отображается как последовательный порт /dev/ttyACM0 (все платы nRF52840 используют ttyACM в качестве идентификатора последовательного порта).
$ ls /dev/ttyACM* /dev/ttyACM0
Обратите внимание на серийный номер платы nRF52840, используемой для RCP:

Перейдите в папку, где находятся инструменты командной строки nRFx, и прошейте файл OpenThread RCP в формате hex на плату 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-порту
Поскольку сборка OpenThread RCP позволяет использовать встроенный USB CDC ACM в качестве последовательного канала связи, для взаимодействия с хостом RCP (машиной Linux) необходимо использовать USB-порт nRF на плате nRF52840.
Отсоедините разъем Micro-USB USB-кабеля от отладочного порта прошитой платы nRF52840, затем снова подсоедините его к разъему Micro-USB USB на плате nRF рядом с кнопкой RESET . Установите переключатель питания nRF в положение USB .

Запуск демона OpenThread
В RCP-архитектуре используйте демон OpenThread для связи с устройством 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 .
Для связи с узлом RCP используйте ot-ctl . ot-ctl использует тот же интерфейс командной строки, что и приложение OpenThread CLI. Поэтому вы можете управлять узлами ot-daemon так же, как и другими имитируемыми устройствами Thread.
Во втором окне терминала запустите команду ot-ctl :
$ sudo ./build/posix/src/posix/ot-ctl >
Проверьте state узла 2 (узел RCP), который вы запустили с помощью ot-daemon :
> state disabled Done
5. Настройка FTD.
Два других узла Thread, используемые в этом практическом занятии, представляют собой полнофункциональные устройства Thread (FTD) на стандартной системе на кристалле (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
Перейдите в каталог, в котором находится исполняемый файл OpenThread Full Thread Device (FTD) CLI, и преобразуйте его в шестнадцатеричный формат:
$ 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, и прошейте файл OpenThread CLI FTD в формате hex на плату nRF52840, используя серийный номер платы:
$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \
~/src/ot-nrf528xx/build/bin/ot-cli-ftd.hex --reset
Напишите на доске «Комиссар».
Подключитесь к встроенному USB-порту
Поскольку сборка OpenThread FTD позволяет использовать встроенный USB CDC ACM в качестве последовательного канала связи, для взаимодействия с хостом RCP (машиной Linux) необходимо использовать USB-порт nRF на плате nRF52840.
Отсоедините разъем Micro-USB USB-кабеля от отладочного порта прошитой платы nRF52840, затем снова подсоедините его к разъему Micro-USB USB на плате nRF рядом с кнопкой RESET . Установите переключатель питания nRF в положение USB .

Проверить сборку
Убедитесь в успешной сборке, получив доступ к интерфейсу командной строки 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 и вернуться в терминал Linux для прошивки следующей платы, используйте команду `screen -r`. Для повторного входа в интерфейс командной строки используйте команду 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, используя существующую сборку ot-cli-ftd.hex . После завершения обязательно подключите плату к ПК через USB-порт nRF и установите переключатель источника питания nRF в положение VDD .
Если два других узла подключены к машине Linux одновременно с подключением этой третьей платы, то она должна отображаться как последовательный порт /dev/ttyACM2 :
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1 /dev/ttyACM2
Обозначьте доску как «Столяр».
При проверке с помощью Screen, вместо создания нового экземпляра Screen из командной строки, повторно подключитесь к существующему и создайте в нем новое окно (которое вы использовали для FTD Commissioner):
$ screen -r
Создайте новое окно в окне Screen, нажав Ctrl+a → c .
Появится новая командная строка. Получите доступ к интерфейсу командной строки OpenThread для FTD Joiner:
$ screen /dev/ttyACM2
В новом окне несколько раз нажмите клавишу Return на клавиатуре, чтобы открыть командную строку OpenThread > . Откройте интерфейс IPv6 и проверьте адреса:
> ifconfig up Done > ipaddr fe80:0:0:0:6c1e:87a2:df05:c240 Done
Теперь, когда интерфейс командной строки FTD Joiner находится в том же экземпляре Screen, что и FTD Commissioner, вы можете переключаться между ними с помощью Ctrl+a → n .
Используйте Ctrl+a →
d в любое время, чтобы выйти из экрана.
6. Настройка окна терминала
В дальнейшем вам придётся часто переключаться между устройствами Thread, поэтому убедитесь, что все они активны и легко доступны. До сих пор мы использовали Screen для доступа к двум FTD, и этот инструмент также позволяет разделить экран на две части в одном окне терминала. Используйте это, чтобы увидеть, как один узел реагирует на команды, отданные другому.
В идеале у вас должно быть четыре окна под рукой:
- служба
ot-daemon/ журналы - RCP Joiner через
ot-ctl - Комиссар FTD через OpenThread CLI
- FTD Joiner через OpenThread CLI
Если вы хотите использовать собственную конфигурацию терминала/последовательного порта или инструмент, можете смело переходить к следующему шагу. Настройте окна терминала для всех устройств так, как вам удобнее.
Использование экрана
Для удобства использования запускайте только одну сессию Screen. У вас уже должна быть одна такая сессия, созданная при настройке обоих FTD.
Все команды в Screen начинаются с Ctrl+a.
Основные команды экрана:
Повторно подключитесь к сеансу Screen (из командной строки). | |
Выйти из сеанса просмотра экрана | Ctrl+a → |
Создать новое окно в рамках сессии Screen | Ctrl+a → |
Переключайтесь между окнами в рамках одной сессии Screen. | Ctrl+a → |
Закрыть текущее окно в сеансе Screen | Ctrl+a → |
Разделенный экран
С помощью Screen можно разделить терминал на несколько окон:

Доступ к командам на screen осуществляется с помощью комбинации клавиш Ctrl+a. Каждая команда должна начинаться с этой комбинации клавиш.
Если вы точно следовали инструкциям Codelab, у вас должно быть два окна (FTD Commissioner, FTD Joiner) на одном экземпляре Screen. Чтобы разделить экран между ними, сначала войдите в текущую сессию Screen:
$ screen -r
Вы должны использовать одно из устройств FTD. Выполните следующие действия в Screen:
- Нажмите Ctrl+a →
S, чтобы разделить окно по горизонтали. - Нажмите Ctrl+a →
Tab, чтобы переместить курсор в новое пустое окно. - Нажмите Ctrl+a →
nчтобы переключиться из этого нового окна в следующее. - Если это то же самое, что и в верхнем окне, снова нажмите 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 → |
Разделить окно по вертикали | Ctrl+a → |
Разделить окно по горизонтали | Ctrl+a → |
Перейти к следующему отображаемому окну | Ctrl+a → |
Переключите отображаемое окно вперед или назад. | Ctrl+a → |
Переименуйте текущее окно | Ctrl+a → |
Выйти из Screen можно в любой момент с помощью Ctrl+a → d , а снова подключиться — с помощью команды screen -r из командной строки.
Для получения более подробной информации о Screen см. краткий справочник GNU Screen .
7. Создайте сеть потоков.
Теперь, когда у вас настроены все окна и экраны терминала, давайте создадим нашу сеть 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 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 на устройстве 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 Commissioner мы записали сетевой ключ, например, 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 Commissioner , проверьте таблицы маршрутизатора и дочерних устройств, чтобы убедиться, что оба устройства являются частью одной сети. Используйте 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 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, состоящая из двух узлов, как показано на этой топологической схеме:

Топологические диаграммы
В ходе выполнения оставшейся части Codelab мы будем показывать новую диаграмму топологии Thread всякий раз, когда изменяется состояние сети. Роли узлов обозначаются следующим образом:

Маршрутизаторы всегда имеют форму пятиугольника, а конечные устройства — форму круга. Числа на каждом узле представляют собой идентификатор маршрутизатора или идентификатор дочернего устройства, отображаемый в выводе CLI, в зависимости от текущей роли и состояния каждого узла в данный момент времени.
9. Закажите услуги столяра в компании FTD.
Теперь добавим третье устройство Thread в сеть "codelab". На этот раз мы воспользуемся более безопасным процессом внутриполосной настройки и разрешим подключение только устройству FTD Joiner.
На сайте FTD Joiner получите eui64 , чтобы комиссар FTD мог его идентифицировать:
## FTD Joiner ## ---------------- > eui64 2f57d222545271f1 Done
В FTD Commissioner запустите программу и укажите eui64 устройства, которое может подключиться, а также учетные данные участника, например, J01NME . Учетные данные участника представляют собой строку, специфичную для устройства, состоящую из буквенно-цифровых символов верхнего регистра (0-9 и AY, за исключением I, O, Q и Z для удобства чтения), длиной от 6 до 32 символов.
## FTD Commissioner ## ---------------------- > commissioner start Done > commissioner joiner add 2f57d222545271f1 J01NME Done
Переключитесь на роль FTD Joiner . Запустите роль Joiner, используя учетные данные 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 и проверьте таблицы маршрутизатора и дочерних устройств, чтобы убедиться, что в сети "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 в этом практическом занятии представляют собой особый тип полнофункциональных устройств Thread (FTD), называемых Router Eligible End Device (REED). Это означает, что они могут функционировать как маршрутизаторы или конечные устройства и могут повышать свой статус с конечного устройства до маршрутизатора.
Thread может поддерживать до 32 маршрутизаторов, но старается поддерживать их количество в пределах от 16 до 23. Если REED подключается как конечное устройство (дочернее), и количество маршрутизаторов меньше 16, то через случайный промежуток времени в течение двух минут он автоматически повышает свой статус до маршрутизатора.
Если после добавления FTD Joiner в вашей сети Thread появилось два дочерних узла, подождите не менее двух минут, а затем повторно проверьте таблицы маршрутизатора и дочерних узлов на 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.

Подтвердите новое состояние и RLOC16 в FTD Joiner :
## FTD Joiner ## ---------------- > state router Done > rloc16 b800 Done
Понизить уровень FTD Joiner
Вы можете проверить это поведение, вручную понизив статус FTD Joiner с маршрутизатора обратно до конечного устройства. Измените состояние на «дочернее» и проверьте значение RLOC16:
## FTD Joiner ## ---------------- > state child Done > rloc16 0c03 Done

Вернувшись к таблице FTD Commissioner , следует отметить, что сотрудник, присоединившийся к команде FTD, теперь должен отображаться в дочерней таблице (ID = 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. Это означает, что если текущий лидер будет удален из сети Thread, новый лидер станет одним из других маршрутизаторов.
На сервере 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

Проверьте дочернюю таблицу. Обратите внимание на новый RLOC16. Это RCP Joiner, как указано его ID и Extended MAC. Чтобы сохранить целостность сети Thread, он сменил родительский маршрутизатор, переключившись с FTD Commissioner на FTD Joiner. В результате для RCP Joiner появился новый RLOC16 (поскольку его ID маршрутизатора изменился с 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.
Сеть 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 для каждого устройства. Состояния устройств сохраняются даже после закрытия Screen.
Узлы потоков
Если сетевая топология Thread не соответствует описанной в этом руководстве, или узлы отключаются по какой-либо причине (например, из-за того, что машина 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. Использование многоадресной рассылки
Многоадресная рассылка используется для одновременной передачи информации группе устройств. В сети Thread определенные адреса резервируются для многоадресной рассылки с различными группами устройств в зависимости от области действия.
IPv6-адрес | Объем | Доставлено в |
| Локальная ссылка | Все FTD и MED |
| Локальная ссылка | Все FTD и пограничные пункты пропуска |
| Mesh-Local | Все FTD и MED |
| Mesh-Local | Все FTD и пограничные пункты пропуска |
Поскольку в этом практическом задании мы не используем пограничный маршрутизатор, давайте сосредоточимся на двух многоадресных адресах: FTD и MED.
Локальная ссылка
Область действия Link-Local включает все интерфейсы Thread, доступные по одной радиопередаче или по одному "переходу". Топология сети определяет, какие устройства отвечают на ping-запрос к многоадресному адресу 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 получил только один ответ — от локального адреса (LLA) устройства FTD Joiner. Это означает, что FTD Joiner — единственное устройство, до которого комиссар 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 напрямую соединен как с комиссаром FTD, так и с соединителем RCP, что подтверждает нашу топологию.
Mesh-Local
Область действия Mesh-Local включает все интерфейсы Thread, доступные в пределах одной сети Thread. Давайте посмотрим ответы на ping-запрос к многоадресному адресу 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 (RLOC, заканчивающегося на b800 ) и один от локального идентификатора сети RCP участника сети (ML-EID, заканчивающегося на d55f ). Это связано с тем, что локальная область действия сети охватывает всю сеть Thread. Независимо от того, где в сети находится устройство, оно будет подписано на адрес ff03::1 .

Для подтверждения аналогичного поведения выполните команду ping 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 Joiner в обоих выводах ping. RCP Joiner потребовалось гораздо больше времени, чтобы достичь FTD Commissioner (68 мс), чем FTD Joiner (23 мс). Это связано с тем, что ему приходится совершать два перехода, чтобы достичь FTD Commissioner, по сравнению с одним переходом для FTD Joiner.
Возможно, вы также заметили, что локальный многоадресный пинг в mesh-сети ответил RLOC только для двух FTD, а не для RCP Joiner. Это связано с тем, что FTD являются маршрутизаторами в сети, а RCP — конечным устройством.
Проверьте состояние устройства RCP Joiner для подтверждения:
## RCP Joiner ## ---------------- > state child
13. Отправка сообщений по протоколу UDP.
Одна из прикладных служб, предоставляемых OpenThread, — это протокол UDP (User Datagram Protocol), протокол транспортного уровня. Приложение, построенное на OpenThread, может использовать API UDP для передачи сообщений между узлами в сети Thread или другим устройствам во внешней сети (например, в интернете, если сеть Thread использует пограничный маршрутизатор).
UDP-сокеты доступны через интерфейс командной строки OpenThread. Давайте воспользуемся ими для передачи сообщений между двумя FTD.
Получите локальный EID-адрес Mesh для устройства 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, и обратите внимание, что она никогда не обновляется до режима маршрутизатора и не пытается стать лидером. - Добавьте в сеть больше устройств (попробуйте другую платформу!) и нарисуйте топологию, используя таблицы маршрутизаторов и дочерних устройств, а также отправляя пинги на многоадресные адреса.
- Используйте псипинель для управления NCP.
- Превратите NCP в пограничный маршрутизатор с помощью OpenThread Border Router и подключите вашу сеть Thread к интернету.
Дополнительная информация
Посетите openthread.io и GitHub , чтобы найти множество ресурсов по OpenThread, в том числе:
- Поддерживаемые платформы — узнайте обо всех платформах, поддерживающих OpenThread.
- Сборка OpenThread — подробная информация о сборке и настройке OpenThread.
- Введение в потоки — охватывает все концепции потоков, представленные в этом практическом занятии.
Ссылка: