Создайте сеть Thread с помощью плат nRF52840 и OpenThread.

1. Введение

26b7f4f6b3ea0700.png

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

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

В этом практическом занятии вы научитесь программировать OpenThread на реальном оборудовании, создавать и управлять сетью Thread, а также передавать сообщения между узлами.

4806d16a8c137c6d.jpeg

Что вы узнаете

  • Сборка и прошивка бинарных файлов 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 .

a6693da3ce213856.png

Для программирования плат 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 .

20a3b4b480356447.png

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

$ ls /dev/ttyACM*
/dev/ttyACM0

Обратите внимание на серийный номер платы nRF52840, используемой для RCP:

c00d519ebec7e5f0.jpeg

Перейдите в папку, где находятся инструменты командной строки 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 .

46e7b670d2464842.png

Запуск демона 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:

c00d519ebec7e5f0.jpeg

Перейдите в папку, где находятся инструменты командной строки 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 .

46e7b670d2464842.png

Проверить сборку

Убедитесь в успешной сборке, получив доступ к интерфейсу командной строки 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, и этот инструмент также позволяет разделить экран на две части в одном окне терминала. Используйте это, чтобы увидеть, как один узел реагирует на команды, отданные другому.

В идеале у вас должно быть четыре окна под рукой:

  1. служба ot-daemon / журналы
  2. RCP Joiner через ot-ctl
  3. Комиссар FTD через OpenThread CLI
  4. FTD Joiner через OpenThread CLI

Если вы хотите использовать собственную конфигурацию терминала/последовательного порта или инструмент, можете смело переходить к следующему шагу. Настройте окна терминала для всех устройств так, как вам удобнее.

Использование экрана

Для удобства использования запускайте только одну сессию Screen. У вас уже должна быть одна такая сессия, созданная при настройке обоих FTD.

Все команды в Screen начинаются с Ctrl+a.

Основные команды экрана:

Повторно подключитесь к сеансу Screen (из командной строки).

screen -r

Выйти из сеанса просмотра экрана

Ctrl+a → d

Создать новое окно в рамках сессии Screen

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. На 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, состоящая из двух узлов, как показано на этой топологической схеме:

otcodelab_top01C_2nodes.png

Топологические диаграммы

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

b75a527be4563215.png

Маршрутизаторы всегда имеют форму пятиугольника, а конечные устройства — форму круга. Числа на каждом узле представляют собой идентификатор маршрутизатора или идентификатор дочернего устройства, отображаемый в выводе 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 подключилось к сети как конечное устройство (дочернее). Вот наша обновленная топология:

otcodelab_top01C_ed01.png

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.

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, теперь должен отображаться в дочерней таблице (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 .

otcodelab_top01C.png

Сместить лидера

Лидер избирается самим собой среди всех маршрутизаторов 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

otcodelab_top02C_01.png

Проверьте дочернюю таблицу. Обратите внимание на новый 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

otcodelab_top02C_02.png

Наша сеть 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-адрес

Объем

Доставлено в

ff02::1

Локальная ссылка

Все FTD и MED

ff02::2

Локальная ссылка

Все FTD и пограничные пункты пропуска

ff03::1

Mesh-Local

Все FTD и MED

ff03::2

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 может дотянуться за один переход.

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, а второй (заканчивающийся на 943b ) — это LLA участника RCP.

otcodelab_top02C_02_LL02.png

Это означает, что соединитель 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 .

otcodelab_top02C_02_ML.png

Для подтверждения аналогичного поведения выполните команду 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

otcodelab_top02C_02_LL02.png

Обратите внимание на время отклика 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!

b915c433e7027cc7.png

Теперь вы знаете:

  • Разница между типами устройств, ролями и областями действия Thread.
  • как устройства Thread управляют своим состоянием в сети
  • Как передавать простые сообщения между узлами с использованием UDP?

Следующие шаги

В продолжение этого урока по программированию попробуйте выполнить следующие упражнения:

  • Перепрошейте плату FTD Joiner в режим MTD, используя бинарный файл ot-cli-mtd , и обратите внимание, что она никогда не обновляется до режима маршрутизатора и не пытается стать лидером.
  • Добавьте в сеть больше устройств (попробуйте другую платформу!) и нарисуйте топологию, используя таблицы маршрутизаторов и дочерних устройств, а также отправляя пинги на многоадресные адреса.
  • Используйте псипинель для управления NCP.
  • Превратите NCP в пограничный маршрутизатор с помощью OpenThread Border Router и подключите вашу сеть Thread к интернету.

Дополнительная информация

Посетите openthread.io и GitHub , чтобы найти множество ресурсов по OpenThread, в том числе:

Ссылка: