1. Введение
OpenThread , выпущенный Google, представляет собой реализацию сетевого протокола Thread с открытым исходным кодом. Google Nest выпустил OpenThread, чтобы сделать технологию, используемую в продуктах Nest, широко доступной для разработчиков, чтобы ускорить разработку продуктов для подключенного дома.
Спецификация Thread определяет надежный, безопасный и маломощный протокол беспроводной связи между устройствами на основе IPv6 для домашних приложений. OpenThread реализует все сетевые уровни потоков, включая IPv6, 6LoWPAN, IEEE 802.15.4 с безопасностью MAC, установлением Mesh Link и маршрутизацией Mesh.
Этот Codelab проведет вас через моделирование сети Thread на эмулируемых устройствах с помощью Docker.
Что вы узнаете
- Как настроить цепочку инструментов сборки OpenThread
- Как смоделировать сеть потоков
- Как аутентифицировать узлы потока
- Как управлять сетью потоков с помощью OpenThread Daemon
Что вам понадобится
- Докер
- Базовые знания Linux, сетевой маршрутизации
2. Настройте Докер
Этот Codelab предназначен для использования Docker на компьютере с Linux, Mac OS X или Windows. Linux является рекомендуемой средой.
Установить Докер
Установите Docker на выбранную вами ОС.
Извлеките образ Docker
После установки Docker откройте окно терминала и извлеките openthread/environment
Docker. В этом образе представлены OpenThread и OpenThread Daemon, предварительно созданные и готовые к использованию в Codelab.
$ docker pull openthread/environment:latest
Обратите внимание, что для полной загрузки может потребоваться несколько минут.
В окне терминала запустите контейнер Docker из образа и подключитесь к его оболочке bash
:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
Обратите внимание на флаги, которые необходимы для этой лаборатории кода:
-
--sysctl net.ipv6.conf.all.disable_ipv6=0
— включает IPv6 внутри контейнера. -
--cap-add=net_admin
— включает возможность NET_ADMIN, которая позволяет вам выполнять операции, связанные с сетью, такие как добавление IP-маршрутов.
Оказавшись в контейнере, вы должны увидеть подсказку, подобную этой:
root@c0f3912a74ff:/#
В приведенном выше примере c0f3912a74ff
— это идентификатор контейнера. Идентификатор контейнера для вашего экземпляра контейнера Docker будет отличаться от идентификатора, показанного в подсказках для этой лаборатории кода.
Использование Докера
В этой Codelab предполагается, что вы знакомы с основами использования Docker. Вы должны оставаться в контейнере Docker на протяжении всей работы Codelab.
3. Смоделируйте сеть потоков
Пример приложения, которое вы будете использовать для этой Codelab, демонстрирует минимальное приложение OpenThread, которое предоставляет интерфейсы конфигурации и управления OpenThread через базовый интерфейс командной строки (CLI).
В этом упражнении вы выполните минимальные шаги, необходимые для эхо-запроса одного эмулированного устройства Thread с другого эмулированного устройства Thread.
На рисунке ниже показана базовая топология сети Thread. В этом упражнении мы будем эмулировать два узла в зеленом кружке: лидер потока и маршрутизатор потока с одним соединением между ними.
Создайте сеть
1. Запустите узел 1
Если вы еще этого не сделали, в окне терминала запустите контейнер Docker и подключитесь к его оболочке bash
:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
В контейнере Docker создайте процесс CLI для эмулируемого устройства Thread, используя двоичный файл ot-cli-ftd
.
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
Примечание. Если вы не видите приглашение >
после выполнения этой команды, нажмите enter
ВВОД.
Этот двоичный файл реализует устройство OpenThread. Радиодрайвер IEEE 802.15.4 реализован поверх UDP (кадры IEEE 802.15.4 передаются в составе полезной нагрузки UDP).
Аргумент 1
— это файловый дескриптор, представляющий младшие биты «назначенного на заводе» IEEE EUI-64 для эмулируемого устройства. Это значение также используется при привязке к порту UDP для эмуляции радиосвязи IEEE 802.15.4 (порт = 9000 + файловый дескриптор). Каждый экземпляр эмулируемого устройства Thread в Codelab будет использовать другой файловый дескриптор.
Примечание. Используйте только файловые дескрипторы 1
или выше, как указано в этой лаборатории кода, при создании процесса для эмулируемого устройства. Дескриптор файла 0
зарезервирован для другого использования.
Создайте новый рабочий набор данных и зафиксируйте его как активный. Операционный набор данных — это конфигурация создаваемой вами сети потоков.
> dataset init new Done > dataset Active Timestamp: 1 Channel: 20 Channel Mask: 07fff800 Ext PAN ID: d6263b6d857647da Mesh Local Prefix: fd61:2344:9a52:ede0/64 Network Key: e4344ca17d1dca2a33f064992f31f786 Network Name: OpenThread-c169 PAN ID: 0xc169 PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4 Security Policy: 0, onrcb Done
Зафиксируйте этот набор данных как активный:
> dataset commit active Done
Поднимите интерфейс IPv6:
> ifconfig up Done
Запустить операцию протокола Thread:
> thread start Done
Подождите несколько секунд и убедитесь, что устройство стало лидером потока. Лидер — это устройство, ответственное за управление назначением идентификатора маршрутизатора.
> state leader Done
Просмотрите IPv6-адреса, назначенные интерфейсу Thread узла 1 (вывод будет другим):
> ipaddr fd61:2344:9a52:ede0:0:ff:fe00:fc00 fd61:2344:9a52:ede0:0:ff:fe00:5000 fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 fe80:0:0:0:94da:92ea:1353:4f3b Done
Обратите внимание на определенные типы адресов IPv6:
- Начинается с
fd
= mesh-local - Начинается с
fe80
= локальная ссылка
Типы адресов Mesh-local классифицируются далее:
- Содержит
ff:fe00
= локатор маршрутизатора (RLOC) - Не содержит
ff:fe00
= идентификатор конечной точки (EID)
Определите EID в выводе консоли, запишите его для дальнейшего использования. В приведенном выше примере выходных данных EID:
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. Запустите узел 2
Откройте новый терминал и запустите оболочку bash
в запущенном в данный момент контейнере Docker, чтобы использовать его для Node 2.
$ docker exec -it codelab_otsim_ctnr bash
В этом новом приглашении bash
запустите процесс CLI с аргументом 2
. Это ваше второе эмулированное устройство Thread:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
Примечание. Если вы не видите приглашение >
после выполнения этой команды, нажмите enter
ВВОД.
Настройте сетевой ключ потока и идентификатор PAN, используя те же значения, что и в рабочем наборе данных узла 1:
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
Зафиксируйте этот набор данных как активный:
> dataset commit active Done
Поднимите интерфейс IPv6:
> ifconfig up Done
Запустить операцию протокола Thread:
> thread start Done
Устройство инициализируется как дочернее. Дочерний поток эквивалентен конечному устройству, которое представляет собой устройство потока, которое передает и получает одноадресный трафик только с родительским устройством.
> state child Done
В течение 2 минут вы должны увидеть переключение состояния с child
на router
. Маршрутизатор потоков способен маршрутизировать трафик между устройствами потоков. Его также называют Родителем.
> state router Done
Проверьте сеть
Простой способ проверить ячеистую сеть — посмотреть таблицу маршрутизатора.
1. Проверьте подключение
На узле 2 получите RLOC16. RLOC16 — это последние 16 бит IPv6-адреса RLOC устройства.
> rloc16 5800 Done
На узле 1 проверьте таблицу маршрутизаторов на наличие RLOC16 узла 2. Убедитесь, что узел 2 сначала переключился в состояние маршрутизатора.
> router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+--------+-------+---+--------------------+ | 20 | 0x5000 | 63 | 0 | 0 | 0 | 0 | 96da92ea13534f3b | | 22 | 0x5800 | 63 | 0 | 3 | 3 | 23 | 5a4eb647eb6bc66c |
RLOC узла 2, равный 0x5800
, найден в таблице, подтверждая, что он подключен к ячеистой сети.
2. Пропингуйте узел 1 с узла 2.
Проверьте подключение между двумя эмулируемыми устройствами Thread. На узле 2 ping
EID, назначенный узлу 1:
> ping fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 > 16 bytes from fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6: icmp_seq=1 hlim=64 time=12ms
Нажмите enter
, чтобы вернуться к подсказке >
CLI.
Протестируйте сеть
Теперь, когда вы можете успешно выполнить эхо-запрос между двумя эмулированными устройствами Thread, протестируйте ячеистую сеть, отключив один узел.
Вернитесь к узлу 1 и остановите поток:
> thread stop Done
Переключитесь на узел 2 и проверьте состояние. В течение двух минут узел 2 обнаруживает, что лидер (узел 1) находится в автономном режиме, и вы должны увидеть, как узел 2 становится leader
сети:
> state router Done ... > state leader Done
После подтверждения остановите Thread и сбросьте настройки Node 2 до заводских настроек, прежде чем вернуться к командной строке Docker bash
. Сброс к заводским настройкам выполняется для того, чтобы учетные данные сети Thread, которые мы использовали в этом упражнении, не переносились в следующее упражнение.
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
Возможно, вам придется нажать enter
несколько раз, чтобы вернуть приглашение >
после команды factoryreset
до заводских настроек. Не выходите из контейнера Docker.
Также сброс к заводским настройкам и выход из узла 1:
> factoryreset > > exit root@c0f3912a74ff:/#
См. Справочник по интерфейсу командной строки OpenThread , чтобы изучить все доступные команды интерфейса командной строки.
4. Аутентификация узлов с вводом в эксплуатацию
В предыдущем упражнении вы настроили сеть Thread с двумя смоделированными устройствами и проверили подключение. Однако это позволяет передавать между устройствами только локальный трафик IPv6, не прошедший проверку подлинности. Для маршрутизации глобального IPv6-трафика между ними (и Интернетом через пограничный маршрутизатор потоков) узлы должны быть аутентифицированы.
Для аутентификации одно устройство должно выступать в роли комиссара. Уполномоченный в настоящее время является выбранным сервером аутентификации для новых устройств Thread и авторизатором для предоставления сетевых учетных данных, необходимых для подключения устройств к сети.
В этом упражнении мы будем использовать ту же двухузловую топологию, что и раньше. Для аутентификации лидер потока будет выступать в роли комиссара, а маршрутизатор потока — в качестве присоединителя.
Докер
Для каждого узла (окна терминала) в оставшихся упражнениях убедитесь, что вы используете контейнер Docker со сборкой OpenThread. Если продолжить предыдущее упражнение, у вас все еще должны быть открыты два приглашения bash
в одном и том же контейнере Docker. Если нет, см. шаг « Устранение неполадок Docker » или просто повторите упражнение « Симуляция сети потока».
1. Создайте сеть
В узле 1 создайте процесс CLI:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
Примечание. Если вы не видите приглашение >
после выполнения этой команды, нажмите enter
ВВОД.
Создайте новый рабочий набор данных, зафиксируйте его как активный и запустите поток:
> dataset init new Done > dataset Active Timestamp: 1 Channel: 12 Channel Mask: 07fff800 Ext PAN ID: e68d05794bf13052 Mesh Local Prefix: fd7d:ddf7:877b:8756/64 Network Key: a77fe1d03b0e8028a4e13213de38080e Network Name: OpenThread-8f37 PAN ID: 0x8f37 PSKc: f9debbc1532487984b17f92cd55b21fc Security Policy: 0, onrcb Done
Зафиксируйте этот набор данных как активный:
> dataset commit active Done
Поднимите интерфейс IPv6:
> ifconfig up Done
Запустить операцию протокола Thread:
> thread start Done
Подождите несколько секунд и убедитесь, что устройство стало лидером потока:
> state leader Done
2. Начать роль комиссара
Находясь на узле 1, начните роль комиссара:
> commissioner start Done
Разрешить любому присоединяющемуся (используя подстановочный знак *
) с учетными данными присоединяемого J01NME
комиссию в сеть. Joiner — это устройство, добавляемое администратором-человеком во введенную в действие сеть потоков.
> commissioner joiner add * J01NME Done
3. Запустите роль Столяра
Во втором окне терминала в контейнере Docker создайте новый процесс CLI. Это узел 2.
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
На узле 2 включите роль присоединителя, используя учетные данные присоединителя J01NME
.
> ifconfig up Done > joiner start J01NME Done
... подождите несколько секунд для подтверждения ...
Join success
В качестве присоединителя устройство (узел 2) успешно аутентифицировало себя с помощью уполномоченного (узел 1) и получило учетные данные сети потоков.
Теперь, когда узел 2 аутентифицирован, запустите Thread:
> thread start Done
4. Подтвердить сетевую аутентификацию
Проверьте state
на узле 2, чтобы убедиться, что он присоединился к сети. В течение двух минут Node 2 переходит от child
к router
:
> state child Done ... > state router Done
5. Сбросить настройки
Чтобы подготовиться к следующему упражнению, сбросьте конфигурацию. На каждом узле остановите Thread, выполните сброс до заводских настроек и выйдите из эмулируемого устройства Thread:
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
Возможно, вам придется нажать enter
несколько раз, чтобы вернуть приглашение >
после команды factoryreset
до заводских настроек.
5. Управляйте сетью с помощью OpenThread Daemon
В этом упражнении мы собираемся смоделировать один экземпляр CLI (одно встроенное устройство SoC Thread) и один экземпляр Radio Co-Processor (RCP).
ot-daemon
— это режим приложения OpenThread Posix, который использует сокет UNIX в качестве ввода и вывода, чтобы ядро OpenThread могло работать как служба. Клиент может взаимодействовать с этой службой, подключившись к сокету с помощью интерфейса командной строки OpenThread в качестве протокола.
ot-ctl
— это интерфейс командной строки, предоставляемый ot-daemon
для управления и настройки RCP. Используя это, мы подключим RCP к сети, созданной устройством Thread.
Докер
Для каждого узла (окна терминала) в этом упражнении убедитесь, что вы используете контейнер Docker со сборкой OpenThread. Если вы продолжаете предыдущее упражнение, у вас должно быть уже открыто два приглашения bash
в одном и том же контейнере Docker. Если нет, см. шаг « Устранение неполадок Docker ».
Использовать ot-демон
В этом упражнении будут использоваться три окна терминала, соответствующие следующему:
- Экземпляр CLI моделируемого устройства Thread (узел 1)
-
ot-daemon
процесс - экземпляр командной строки
ot-ctl
1. Запустите узел 1
В первом окне терминала создайте процесс CLI для вашего эмулируемого устройства Thread:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
Примечание. Если вы не видите приглашение >
после выполнения этой команды, нажмите enter
ВВОД.
Создайте новый рабочий набор данных, зафиксируйте его как активный и запустите поток:
> dataset init new Done > dataset Active Timestamp: 1 Channel: 13 Channel Mask: 07fff800 Ext PAN ID: 97d584bcd493b824 Mesh Local Prefix: fd55:cf34:dea5:7994/64 Network Key: ba6e886c7af50598df1115fa07658a83 Network Name: OpenThread-34e4 PAN ID: 0x34e4 PSKc: 38d6fd32c866927a4dfcc06d79ae1192 Security Policy: 0, onrcb Done
Зафиксируйте этот набор данных как активный:
> dataset commit active Done
Поднимите интерфейс IPv6:
> ifconfig up Done
Запустить операцию протокола Thread:
> thread start Done
Просмотрите IPv6-адреса, назначенные интерфейсу Thread узла 1:
> ipaddr fd55:cf34:dea5:7994:0:ff:fe00:fc00 fd55:cf34:dea5:7994:0:ff:fe00:d000 fd55:cf34:dea5:7994:460:872c:e807:c4ab fe80:0:0:0:9cd8:aab6:482f:4cdc Done >
Как объяснялось в шаге Simulate a Thread network , один адрес является локальным для канала ( fe80
), а три — локальным для сетки ( fd
). EID — это локальный адрес сети, который не содержит ff:fe00
в адресе. В этом примере выходных данных EID равен fd55:cf34:dea5:7994:460:872c:e807:c4ab
.
Определите конкретный EID из выходных данных ipaddr
, который будет использоваться для связи с узлом.
2. Запустите ot-демон
Во втором окне терминала создайте узел устройства tun
и установите права на чтение/запись:
root@c0f3912a74ff:/# mkdir -p /dev/net && mknod /dev/net/tun c 10 200 root@c0f3912a74ff:/# chmod 600 /dev/net/tun
Это устройство используется для передачи и приема пакетов в виртуальных устройствах. Вы можете получить сообщение об ошибке, если устройство уже создано — это нормально и его можно игнорировать.
Запустите ot-daemon
для узла RCP, который мы назовем узлом 2. Используйте подробный флаг -v
, чтобы вы могли видеть вывод журнала и подтверждать, что он работает:
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-daemon -v \ 'spinel+hdlc+forkpty://openthread/build/examples/apps/ncp/ot-rcp?forkpty-arg=2'
В случае успеха ot-daemon
в подробном режиме генерирует вывод, подобный следующему:
ot-daemon[31]: Running OPENTHREAD/297a880; POSIX; Feb 1 2022 04:43:39 ot-daemon[31]: Thread version: 3 ot-daemon[31]: Thread interface: wpan0 ot-daemon[31]: RCP version: OPENTHREAD/297a880; SIMULATION; Feb 1 2022 04:42:50
Оставьте этот терминал открытым и работающим в фоновом режиме. Вы не будете вводить в него никаких дополнительных команд.
3. Используйте ot-ctl для подключения к сети
Мы еще не задействовали Node 2 ( ot-daemon
RCP) ни в одной сети Thread. Здесь на помощь приходит ot- ot-ctl
. ot-ctl
использует тот же интерфейс командной строки, что и приложение OpenThread CLI. Таким образом, вы можете управлять узлами ot-daemon
так же, как и другими имитируемыми устройствами Thread.
Откройте третье окно терминала и запустите существующий контейнер:
$ docker exec -it codelab_otsim_ctnr bash
Оказавшись в контейнере, запустите ot-ctl
:
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-ctl >
Вы будете использовать ot-ctl
в этом третьем окне терминала для управления Node 2 (узел RCP), который вы запустили во втором окне терминала с помощью ot-daemon
. Проверьте state
узла 2:
> state disabled Done
Получите eui64
Node 2, чтобы ограничить присоединение к определенному присоединителю:
> eui64 18b4300000000001 Done
На узле 1 (первое окно терминала) запустите Комиссара и ограничьте присоединение только этим eui64:
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
В третьем окне терминала откройте сетевой интерфейс для Node 2 и подключитесь к сети:
> ifconfig up Done > joiner start J01NME Done
... подождите несколько секунд для подтверждения ...
Join success
Как присоединитель, RCP (узел 2) успешно аутентифицировал себя с уполномоченным (узел 1) и получил учетные данные сети потоков.
Теперь присоедините Node 2 к сети Thread (опять же, в третьем окне терминала):
> thread start Done
4. Подтвердить сетевую аутентификацию
В третьем терминале проверьте state
узла 2, чтобы убедиться, что он присоединился к сети. В течение двух минут Node 2 переходит от child
к router
:
> state child Done ... > state router Done
5. Подтвердить подключение
В третьем окне терминала выйдите из ot-ctl
, используя либо Ctrl+D , либо команду exit
, и вернитесь в консоль bash
контейнера. С этой консоли отправьте эхо-запрос на узел 1, используя его EID с командой ping6
. Если экземпляр RCP ot-daemon
успешно присоединен к сети Thread и взаимодействует с ней, проверка связи завершается успешно:
root@c0f3912a74ff:/# ping6 -c 4 fd55:cf34:dea5:7994:460:872c:e807:c4ab PING fd55:cf34:dea5:7994:460:872c:e807:c4ab (fd55:cf34:dea5:7994:460:872c:e807:c4ab): 56 data bytes 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=0 ttl=64 time=4.568 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=1 ttl=64 time=6.396 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=2 ttl=64 time=7.594 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=3 ttl=64 time=5.461 ms --- fd55:cf34:dea5:7994:460:872c:e807:c4ab ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 4.568/6.005/7.594/1.122 ms
6. Устранение неполадок с докером
Если вы вышли из контейнера Docker
bash
, вам может потребоваться проверить, работает ли он, и перезапустить / повторно войти по мере необходимости.
Чтобы показать, какие контейнеры Docker запущены:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
Чтобы показать все контейнеры Docker (как работающие, так и остановленные):
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
Если вы не видите контейнер codelab_otsim_ctnr
в выводе какой-либо команды docker ps
, запустите ее еще раз:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
Если контейнер остановлен (перечислен в docker ps -a
, но не в docker ps
), перезапустите его:
$ docker start -i codelab_otsim_ctnr
Если контейнер Docker уже запущен (перечислен в docker ps
), повторно подключитесь к контейнеру в каждом терминале:
$ docker exec -it codelab_otsim_ctnr bash
Ошибки "Операция не разрешена"
Если при создании новых узлов OpenThread (с помощью команды mknod
) вы столкнулись с ошибкой Operation not permitted
Allowed, убедитесь, что вы используете Docker от имени пользователя root в соответствии с командами, представленными в этой лаборатории кода. Этот Codelab не поддерживает запуск Docker в режиме без рута .
7. Поздравляем!
Вы успешно смоделировали свою первую сеть Thread с помощью OpenThread. Потрясающий!
В этой лаборатории кода вы узнали, как:
- Запуск контейнера OpenThread Simulation Docker и управление им
- Смоделируйте сеть потоков
- Аутентификация узлов потока
- Управление сетью потоков с помощью OpenThread Daemon
Чтобы узнать больше о Thread и OpenThread, изучите эти ссылки:
- Учебник по теме на openthread.io
- Спецификация резьбы
- Репозиторий OpenThread GitHub
- Справочник командной строки OpenThread
- Дополнительная поддержка OpenThread Docker
Или попробуйте использовать OpenThread Border Router в контейнере Docker !