1. Введение
OpenThread — это реализация сетевого протокола Thread® с открытым исходным кодом, который представляет собой надежный и безопасный протокол беспроводной ячеистой сети, разработанный для устройств Интернета вещей (IoT). OpenThread был разработан командой Google Nest и свободно доступен сообществу разработчиков как проект с открытым исходным кодом.
Спецификация Thread устанавливает надежный, безопасный и энергоэффективный протокол беспроводной связи для устройств с ограниченными ресурсами, которые обычно встречаются в умных домах и коммерческих зданиях. OpenThread включает в себя полный объем сетевого уровня внутри Thread, например IPv6, 6LoWPAN, IEEE 802.15.4 с безопасностью MAC, установлением ячеистой связи и ячеистой маршрутизацией.
Telink интегрировала реализацию OpenThread в Zephyr RTOS, обеспечивая полную совместимость с оборудованием Telink. Исходный код для этой интеграции легко доступен на GitHub , а также он предоставляется в виде комплекта разработки программного обеспечения (SDK).
В этой лаборатории кода вы будете программировать OpenThread на реальном оборудовании, создавать сеть потоков и управлять ею, а также обмениваться сообщениями между узлами. На изображении ниже показана аппаратная установка, включающая пограничный маршрутизатор OT (OTBR) и одно устройство Thread в лаборатории кода.
Что вы узнаете
- Настроить реализацию OpenThread с помощью среды разработки Telink Zephyr.
- Чтобы собрать образцы OpenThread CLI (
ot-cli-ftd
иot-rcp
) и записать их на платы разработки Telink B91. - Чтобы настроить пограничный маршрутизатор OpenThread (OTBR) с помощью Docker на Raspberry Pi 3B+ или более поздней версии.
- Чтобы создать сеть потоков на OTBR.
- Чтобы добавить устройства в сеть Thread с помощью внешней отладки.
- Чтобы проверить связь между узлами в сети Thread с помощью CLI.
Что вам понадобится
Аппаратное обеспечение:
- Две макетные платы B91.
- Один Raspberry Pi 3B+ или выше с образом Raspbian OS.
- Машина Linux как минимум с двумя портами USB.
- Коммутатор с подключением к Интернету (или маршрутизатор) и несколько кабелей Ethernet.
Программное обеспечение:
- Инструмент записи и отладки Telink — LinuxBDT.
- Инструмент терминала последовательного порта, например PuTTY.
- Другие инструменты, такие как Git и West.
2. Предварительные условия
Концепции потоков и интерфейс командной строки OpenThread
Перед началом этой лаборатории может оказаться полезным пройти лабораторную работу по моделированию OpenThread , чтобы ознакомиться с фундаментальными концепциями потоков и интерфейсом командной строки OpenThread.
Linux-машина
Машина Linux (Ubuntu v20.04 LTS или новее) выступает в качестве машины сборки для настройки среды разработки Telink Zephyr и прошивки всех плат разработки Thread. Для выполнения этих задач машине с Linux требуются два доступных USB-порта и подключение к Интернету.
Подключение последовательного порта и терминалы
Вы можете напрямую подключить устройство к USB-порту компьютера с Linux. Кроме того, для доступа к устройствам вам понадобится терминальный инструмент последовательного порта.
В этой лаборатории для управления FTD Joiner и Raspberry Pi используется терминальный инструмент PuTTY. Он предлагает обзор его использования, но можно также использовать другое терминальное программное обеспечение.
Комплект разработчика Telink B91
Для этой лаборатории кода необходимы два набора комплектов разработки B91. На фото ниже отображен минимально необходимый набор компонентов в одном комплекте.
Один из этих комплектов будет использоваться как RCP (радиосопроцессор), а другой будет функционировать как FTD (полнопоточное устройство). Если у вас еще нет комплекта, вы можете получить более подробную информацию на официальном сайте Telink . Некоторые компоненты, которые следует использовать, следующие:
Индекс | Имя |
1 | Плата разработки Telink B91 |
2 | Доска для сжигания телинка |
3 | Антенна 2,4 ГГц |
4 | USB-кабель (от USB A до мини-USB) |
Raspberry Pi 3B+ или более поздняя версия с образом Raspbian OS
Для этой лаборатории кода требуется Raspberry Pi 3B+ или более поздней версии с образом ОС Raspbian Bullseye Lite или Raspbian Bullseye с настольным компьютером . Он подключен к Интернету через Ethernet и будет настроен в качестве хоста для пограничного маршрутизатора OpenThread (OTBR).
Сетевое подключение
Коммутатор (или маршрутизатор) с подключением к Интернету и несколько кабелей Ethernet. Они используются для подключения Raspberry Pi к машине Linux, облегчая пользовательскую настройку Raspberry Pi через хост.
LinuxBDT
Средство записи и отладки Telink (BDT) , которое применяется ко всем сериям чипов Telink, позволяет стирать и прошивать прошивку OpenThread на макетные платы Telink B91. Установите версию linuxBDT на базе X86 на свой компьютер с Linux.
Другие
- Git — за настройку среды разработки Telink Zephyr.
- West, для управления проектом Zephyr и создания двоичных файлов OpenThread.
3. Установите прошивку
Настройка среды разработки Telink Zephyr
На компьютере с Linux откройте терминал CLI и начните с выполнения следующих команд, чтобы убедиться, что ваш APT обновлен.
$ sudo apt update $ sudo apt upgrade
Как только это будет сделано, перейдите к следующим шагам.
- Установите зависимости.
Zephyr в настоящее время требует минимальных версий основных зависимостей, таких как CMake (3.20.0), Python3 (3.6) и Devicetree Compiler (1.4.6).$ wget https://apt.kitware.com/kitware-archive.sh $ sudo bash kitware-archive.sh $ sudo apt install --no-install-recommends git cmake ninja-build \ gperf ccache dfu-util device-tree-compiler python3-dev python3-pip \ python3-setuptools python3-tk python3-wheel xz-utils file make gcc \ gcc-multilib g++-multilib libsdl2-dev
Проверьте установленные версии в вашей системе, прежде чем переходить к следующим шагам. Если версии неверны, переключите зеркало APT на стабильное и актуальное зеркало или обновите эти зависимости вручную.$ cmake --version $ python3 --version $ dtc --version
- Установите запад.
Убедитесь, что$ pip3 install --user -U west $ echo 'export PATH=~/.local/bin:"$PATH"' >> ~/.bashrc $ source ~/.bashrc
~/.local/bin
находится в вашей переменной среды$PATH
. - Получите исходный код проекта Zephyr.
$ west init ~/zephyrproject $ cd ~/zephyrproject $ west update $ west blobs fetch hal_telink $ west zephyr-export
- Установите дополнительные зависимости Python для Zephyr.
$ pip3 install --user -r ~/zephyrproject/zephyr/scripts/requirements.txt
- Настройте набор инструментов Zephyr. Загрузите набор инструментов Zephyr (около 1–2 ГБ) в локальный каталог, чтобы можно было прошить большинство плат.
Загрузите Zephyr SDK и поместите его по рекомендованному пути, как показано ниже.$ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/zephyr-sdk-0.16.1_linux-x86_64.tar.xz $ wget -O - https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.1/sha256.sum | shasum --check --ignore-missing
Где [-xyz] — необязательный текст, который может быть любым, например -0.16.1. Каталог невозможно переместить после установки SDK. Затем установите набор инструментов Zephyr.$HOME/zephyr-sdk[-x.y.z] $HOME/.local/zephyr-sdk[-x.y.z] $HOME/.local/opt/zephyr-sdk[-x.y.z] $HOME/bin/zephyr-sdk[-x.y.z] /opt/zephyr-sdk[-x.y.z] /usr/zephyr-sdk[-x.y.z] /usr/local/zephyr-sdk[-x.y.z]
$ tar xvf zephyr-sdk-0.16.1_linux-x86_64.tar.xz $ cd zephyr-sdk-0.16.1 $ ./setup.sh -t riscv64-zephyr-elf -h -c
- Создайте пример Hello World. Сначала убедитесь, что официальная конфигурация проекта Zephyr верна, используя пример Hello World, а затем приступайте к настройке своего собственного проекта.
Используйте команду West build для сборки примера hello_world из корневого каталога репозитория Zephyr. Вы можете найти прошивку с именем$ cd ~/zephyrproject/zephyr $ west build -p auto -b tlsr9518adk80d samples/hello_world
zephyr.bin
вbuild/zephyr directory
. - Добавьте сценарий среды Zephyr в
~/.bashrc
. Выполните следующие команды.$ echo "source ~/zephyrproject/zephyr/zephyr-env.sh" >> ~/.bashrc $ source ~/.bashrc
- Добавьте удаленный репозиторий Telink Zephyr. Загрузите репозиторий Telink локально как ветку разработки и обновите его.
$ cd ~/zephyrproject/zephyr $ git remote add telink-semi https://github.com/telink-semi/zephyr $ git fetch telink develop $ git checkout develop $ west update $ west blobs fetch hal_telink
Для получения дополнительной информации вы можете обратиться к Zephyr Doc – Руководство по началу работы .
Настройте Телинк LinuxBDT
Загрузите инструмент Telink LinuxBDT и извлеките его в локальный каталог на вашем компьютере с Linux, например в домашний каталог ~
, что позволит выполнить прошивку на плате разработки B91.
$ cd ~ $ wget http://wiki.telink-semi.cn/tools_and_sdk/Tools/BDT/LinuxBDT.tar.bz2 $ tar -vxf LinuxBDT.tar.bz2
Подключите Burning Board к машине Linux через интерфейс USB, а затем введите следующие команды.
$ cd LinuxBDT $ sudo ./bdt lsusb -v Bus 002 Device 001: ID 1d6b:0003 xHCI Host Controller Bus 001 Device 003: ID 0bda:565a Integrated_Webcam_HD Bus 001 Device 023: ID 413c:301a Dell MS116 USB Optical Mouse Bus 001 Device 037: ID 248a:826a Telink Web Debugger v3.6 Bus 001 Device 001: ID 1d6b:0002 xHCI Host Controller
Если вы видите сообщение «Telink Web Debugger v3.6», это означает, что программатор BDT успешно подключился к машине Linux.
Компиляция прошивки
В этой кодовой лаборатории будут созданы два типа прошивки OpenThread:
-
ot-cli-ftd
, - и
ot-rcp
.
Методы компиляции следующие:
- Радиосопроцессор (
ot-rcp
)$ cd ~/zephyrproject $ rm -rf build_ot_coprocessor $ west build -b tlsr9518adk80d -d build_ot_coprocessor zephyr/samples/net/openthread/coprocessor -- -DDTC_OVERLAY_FILE="usb.overlay" -DOVERLAY_CONFIG=overlay-rcp-usb-telink.conf
- Полнофункциональное устройство потоков с интерактивной командной строкой (
ot-cli-ftd
)$ cd ~/zephyrproject $ rm -rf build_ot_cli_ftd $ west build -b tlsr9518adk80d -d build_ot_cli_ftd zephyr/samples/net/openthread/cli -- -DOVERLAY_CONFIG=overlay-telink-fixed-mac.conf -DCONFIG_OPENTHREAD_FTD=y
Прошивка
Подключите макетную плату B91 к плате записи с помощью USB-кабеля, как показано на рисунке ниже.
В командной строке выполните следующие команды для выполнения записи прошивки (на примере прошивки ot-cli-ftd
).
$ cd ~/zephyrproject/build_ot_cli_ftd/zephyr $ cp zephyr.bin ~/LinuxBDT/bin/ot-cli-ftd.bin $ cd ~/LinuxBDT $ sudo ./bdt 9518 ac Activate OK! $ sudo ./bdt 9518 wf 0 -i bin/ot-cli-ftd.bin EraseSectorsize... Total Time: 2181 ms Flash writing... [100%][-] [##################################################] File Download to Flash at address 0x000000: 491700 bytes Total Time: 30087 ms
Метод прошивки для ot-rcp
в основном такой же, как и для ot-cli-ftd
. Однако существуют различия в путях и названиях прошивок.
После прошивки отличите две макетные платы B91, пометив их соответствующим образом. Пометьте плату, прошитую с помощью ot-cli-ftd
как «FTD Joiner», а плату, прошитую с помощью ot-rcp
, как «RCP».
4. Настройте последовательную консоль для устройства FTD Joiner.
Как показано на рисунке, подключите FTD Joiner напрямую к USB-порту компьютера с Linux.
После подключения устройства FTD Joiner к компьютеру с Linux откройте PuTTY. Затем создайте новый терминал, установите информацию о последовательном порте и откройте последовательный порт.
Справочник по командной строке OpenThread находится здесь: Справочник по OpenThread CLI . Обязательно ставьте перед всеми командами префикс ot
.
Примеры:
> ot state disabled Done > ot channel 11 Done >
5. Настройте Raspberry Pi в качестве пограничного маршрутизатора OpenThread.
Пограничный маршрутизатор OpenThread — это устройство, состоящее из двух основных частей:
- Raspberry Pi содержит все службы и встроенное ПО, необходимые для работы в качестве пограничного маршрутизатора (BR).
- RCP отвечает за связь потоков.
Радиосопроцессор (RCP)
Чтобы прошить прошивку ot-rcp
, выполните те же действия, что и процесс прошивки ot-cli-ftd
. Подключите макетную плату B91 к порту USB на Raspberry Pi, как показано на рисунке ниже.
Малиновый Пи
- Убедитесь, что образ ОС Raspbian Bullseye Lite или Raspbian Bullseye с рабочим столом правильно записан на SD-карту.
- У вас есть возможность подключиться к Raspberry Pi по SSH или работать напрямую с Raspbian Desktop. В этой кодовой лаборатории будет использоваться SSH.
- Прежде чем приступить к установке OTBR Docker на следующем этапе, обязательно сначала обновите локальный репозиторий и менеджер пакетов.
$ sudo apt-get update $ sudp apt-get upgrade
Установить Докер
Если вы просто обновили локальный репозиторий и менеджер пакетов APT на предыдущем шаге, перезагрузите Raspberry Pi, а затем откройте окно терминала SSH.
- Установите Докер:
$ curl -sSL https://get.docker.com | sh
- Поместите текущую учетную запись в группу Docker, чтобы предоставить разрешение, чтобы не нужно было добавлять
sudo
перед каждой командой. Вам необходимо перезагрузить Raspberry Pi, чтобы изменения вступили в силу.$ sudo usermod -aG docker $USER
- Если Docker не запустился, запустите его:
$ sudo dockerd
- Скрипты межсетевого экрана OTBR генерируют правила внутри контейнера Docker. Перед этим выполните
modprobe
, чтобы загрузить модуль ядра iptables.$ sudo modprobe ip6table_filter
Настройте и запустите Docker
Эта кодовая лаборатория напрямую извлекает образ Docker OTBR из OpenThread Docker Hub . Этот образ был протестирован и проверен командой OpenThread.
- Загрузите последнее изображение:
$ docker pull openthread/otbr:latest
- Проверьте список изображений в контейнере Docker:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE openthread/otbr latest db081f4de15f 6 days ago 766MB
- Определите имя последовательного порта устройства RCP, проверив
/dev
,ttyACM0
указывает, что RCP правильно подключен.$ ls /dev/tty* ... /dev/ttyACM0 ...
- Запустите OTBR Docker в первый раз и укажите последовательный порт RCP (
ttyACM0
). Если вы хотите продолжить использовать этот OTBR Docker, используйте команду docker start otbr .$ docker run --name "otbr" --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" -p 8080:80 --dns=127.0.0.1 -it --volume /dev/ttyACM0:/dev/ttyACM0 --privileged openthread/otbr --radio-url spinel+hdlc+uart:///dev/ttyACM0
- Откройте новое окно терминала SSH, чтобы проверить соединение между Raspberry Pi и RCP.
$ docker exec -ti otbr sh -c "sudo ot-ctl" > state disabled Done
Дополнительные команды докера:
- Получите информацию о работающем Docker-контейнере:
$ docker ps -aq
- Остановите OTBR Docker:
$ docker stop otbr
- Удалить OTBR Docker:
$ docker rm otbr
- Перезагрузите OTBR Docker:
$ docker restart otbr
На этом этапе устройство FTD Joiner и OTBR готовы, и можно переходить к следующему шагу по построению сети Thread.
6. Создайте сеть потоков
Создайте сеть потоков на RCP
Мы используем оболочку ot-ctl на OTBR для создания сети потоков. Если вы вышли из оболочки в последнем разделе, введите следующую команду, чтобы запустить ее снова в терминале SSH:
$ docker exec -ti otbr sh -c "sudo ot-ctl"
Далее введите команды в порядке, указанном в таблице, и убедитесь, что каждый шаг дает ожидаемый результат, прежде чем переходить к следующему.
Индекс | Команда | Введение | Ожидаемый ответ | ||
1 | | Создайте новый случайный набор сетевых данных. | Сделанный | ||
2 | | Зафиксируйте новый набор данных в активном рабочем наборе данных в энергонезависимом хранилище. | Сделанный | ||
3 | | Поднимите интерфейс IPv6. | Сделанный | ||
4 | | Включите работу протокола Thread и подключитесь к сети Thread. | Сделанный | ||
Подождите 10 секунд, пока интерфейс потока заработает. | |||||
5 | | Проверьте состояние устройства. Эту команду можно вызывать несколько раз, пока она не станет ведущей и не перейдет к следующему шагу. | лидер | ||
6 | | Проверьте полный набор активных рабочих данных и запишите сетевой ключ. | Временная метка активности: 1 |
Сетевой ключ, случайно сгенерированный OTBR во время создания сети, будет использоваться, когда устройства ot-cli-ftd
присоединятся к этой сети потоков.
Добавьте FTD Joiner в Thread посредством внеполосного ввода в эксплуатацию.
Внеполосный ввод в эксплуатацию подразумевает передачу сетевых учетных данных устройствам, ожидающим подключения к сети, с помощью беспроводных методов (например, вручную введя OpenThread CLI). Введите следующие команды по порядку в последовательной консоли FTD Joiner.
Индекс | Команда | Введение | Ожидаемые ответы | ||
1 | | Для подключения устройства к сети Thread необходим только сетевой ключ. | Сделанный | ||
2 | | Зафиксируйте новый набор данных в активном рабочем наборе данных в энергонезависимом хранилище. | Сделанный | ||
3 | | Поднимите интерфейс IPv6. | Сделанный | ||
4 | | Включите работу протокола Thread и подключитесь к сети Thread. | Сделанный | ||
Подождите 20 секунд, пока устройство подключится и настроится. | |||||
5 | | Проверьте состояние устройства. | ребенок/маршрутизатор |
Топология
Введите такие команды, как ipaddr
, child table
, router table
в терминале SSH, чтобы получить ответы, подобные следующим фрагментам кода.
> ipaddr rloc fd8c:60bc:a98:c7ba:0:ff:fe00:b000 Done > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|D|N|Ver|CSL|QMsgCnt|Suprvsn| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+---+---+-------+-------+------------------+ | 1 | 0xb001 | 240 | 23 | 3 | 51 |1|1|1| 3| 0 | 0 | 129 | 82bc12fbe783468e | Done > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | Link | +----+--------+----------+-----------+-------+--------+-----+------------------+------+ | 44 | 0xb000 | 63 | 0 | 0 | 0 | 0 | 7ae354109d611f7e | 0 | Done ... > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|D|N|Ver|CSL|QMsgCnt|Suprvsn| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+---+---+-------+-------+------------------+ Done > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | Link | +----+--------+----------+-----------+-------+--------+-----+------------------+------+ | 33 | 0x8400 | 63 | 0 | 3 | 3 | 13 | e61487c1cda940a6 | 1 | | 44 | 0xb000 | 63 | 0 | 0 | 0 | 0 | 7ae354109d611f7e | 0 | Done
RLOC16
OTBR — 0xb000
, а RLOC16
FTD Joiner изначально — 0xb001
. Затем RLOC16
FTD Joiner становится 0x8400
после получения идентификатора маршрутизатора. Видно, что FTD Joiner был повышен с дочернего уровня до маршрутизатора.
Текущая сеть Thread содержит два узла, а топология показана на рисунке ниже.
7. Связь между потоковыми устройствами
ICMPv6-коммуникация
Мы используем команду ping
, чтобы проверить, могут ли устройства Thread в одной сети взаимодействовать друг с другом. Сначала используйте команду ipaddr
, чтобы получить RLOC устройства.
> ipaddr fd8c:60bc:a98:c7ba:0:ff:fe00:fc11 fdbd:7274:649c:1:1d19:9613:f705:a5af fd8c:60bc:a98:c7ba:0:ff:fe00:fc10 fd8c:60bc:a98:c7ba:0:ff:fe00:fc38 fd8c:60bc:a98:c7ba:0:ff:fe00:fc00 fd8c:60bc:a98:c7ba:0:ff:fe00:b000 # Routing Locator (RLOC) fd8c:60bc:a98:c7ba:5249:34ab:26d1:aff6 fe80:0:0:0:78e3:5410:9d61:1f7e Done
Введите следующую команду в последовательной консоли FTD Joiner, чтобы выполнить операцию ping.
> ot ping fd8c:60bc:a98:c7ba:0:ff:fe00:b000 16 bytes from fd8c:60bc:a98:c7ba:0:ff:fe00:b000: icmp_seq=1 hlim=64 time=19ms 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 19/19.0/19 ms. Done
Выходной ответ последовательного порта указывает, что сторона OTBR получила запрос ping, а FTD Joiner получил ответ ping, возвращенный OTBR. Связь между двумя устройствами прошла успешно.
UDP-коммуникация
Службы приложений, предоставляемые OpenThread, также включают UDP. Вы можете использовать UDP API для передачи информации между узлами в сети Thread или для передачи информации во внешние сети через пограничный маршрутизатор. Подробное описание UDP API OpenThread приведено в документе OpenThread CLI — пример UDP . Эта кодовая лаборатория будет использовать некоторые имеющиеся в ней API для передачи информации между OTBR и FTD Joiner.
Сначала получите Mesh-Local EID OTBR. Этот адрес также является одним из IPv6-адресов устройства Thread и может использоваться для доступа к устройствам Thread в том же разделе сети Thread.
> ipaddr mleid fd8c:60bc:a98:c7ba:5249:34ab:26d1:aff6 Done
Введите следующие команды в терминале SSH, чтобы включить OTBR UDP и привязать порт 1022 устройства.
> udp open Done > udp bind :: 1022 Done
Введите следующие команды в последовательной консоли и включите UDP FTD Joiner. Привяжите порт устройства 1022, а затем отправьте 5-байтовое сообщение hello
в OTBR.
> ot udp open Done > ot udp bind :: 1022 Done > ot udp send fd8c:60bc:a98:c7ba:5249:34ab:26d1:aff6 1022 hello Done
Терминал SSH выводит следующую информацию. OTBR получает сообщение hello
от FTD Joiner, что означает, что связь UDP прошла успешно.
> 5 bytes from fd8c:60bc:a98:c7ba:9386:63cf:19d7:5a61 1022 hello
8. Поздравления
Вы создали простую сеть потоков и проверили связь внутри этой сети.
Теперь вы знаете:
- Как создать и использовать среду разработки Telink Zephyr.
- Как собрать двоичные файлы
ot-cli-ftd
иot-rcp
, а также прошить их на платы разработки Telink B91. - Как настроить Raspberry Pi 3B+ или более поздней версии в качестве пограничного маршрутизатора OpenThread (OTBR) с помощью Docker.
- Как создать сеть Thread на OTBR.
- Как добавить устройства в сеть Thread посредством внеполосного ввода в эксплуатацию.
- Как проверить связь между узлами в сети Thread.
Дальнейшее чтение
Посетите openthread.io и GitHub , чтобы узнать о различных ресурсах OpenThread, в том числе:
- Поддерживаемые платформы — узнайте обо всех платформах, поддерживающих OpenThread.
- Сборка OpenThread — дополнительная информация о сборке и настройке OpenThread.
- Thread Primer — охватывает все концепции Thread, представленные в этой кодовой лаборатории.
Справочные документы: