LwM2M (Light weight machine to machine) — легковесный протокол между-машинного взаимодействия. Также как и MQTT протокол LWM2M имеет клиент-серверную архитектуру.
Но в отличии от первого взаимодействие осуществляется не между устройствами (как можно предположить из названия), а между устройством и сервером. Протокол разработан организацией Open Mobile Aliance (OMA) для использования в IoT (internet of things) устройствах.

LWM2M разработан специально для устройств с ограниченными ресурсами. Он позволяет выполнять обновление прошивки , считывание информации с устройства (например температуры , влажности, показателей различных датчиков), запись информации в устройство (например установку даты и времени), выполнение какого-либо действия на устройстве (например перезагрузки, обновления прошивки, сброс к заводским настройкам).

На самом верхнем прикладном уровне LWM2M использует протокол CoAP (Constrained Application Protocol) , который очень похож на протокол HTTP и благодаря этой схожести может быть легко преобразован в HTTP протокол для просмотра ресурсов устройства и управления устройством. CoAP является бинарным протоколом , работающим поверх протокола UDP. Для защиты передаваемых данных также может использовать протокол DTLS между прикладным (CoAP) и транспортным (UDP) уровнями.
Поскольку сам протокол UDP не гарантирует доставку данных , то эту функцию берет на себя прикладной протокол CoAP, в котором существуют два типа пакетов , подтверждаемые (confirmable) и не подтверждаемые (non confirmable). В ответ на подтверждаемый пакет вторая сторона обмена обязана прислать подтверждение приема (Acknowlidge), которое также может содержать полезные данные, отправляемые в ответ на запрос.

В протоколе CoAP содержаться такие-же, как и в HTTP протоколе команды GET, PUT, POST, DELETE. LWM2M поддерживает RESTful API.
LWM2M протокол оперируем такими базовыми понятиями как объект , экземпляр объекта и ресурс.

Объект представляет собой компонент устройства, например какой-либо датчик. Экземпляр объекта (как нетрудно догадаться) является конкретным экземпляром того-же объекта. Например в устройстве есть два датчика температуры и три датчика атмосферного давления, здесь объектами являются датчик температуры и давления, а экземплярами объектов являются конкретные экземпляры датчиков температуры и давления.
Ресурсами для барометра и температурного датчика в данном примере являются значения атмосферного давления и температуры, а также единицы измерения .

Это очень упрощенные примеры , предназначенные только для того , чтобы продемонстрировать основные понятия, заложенные в протокол LWM2M.
Исходя из приведенных примеров ресурсы всегда одинаковые для всех объектов.
Кроме того сами ресурсы могут иметь экземпляры.

В протоколе LWM2M определены обязательные стандартные объекты. Некоторые из них могут иметь только один экземпляр.
Доступ к объектам, их экземплярам , а также ресурсам осуществляется через древовидную структуру, подобную структуре каталогов на жестком диске компьютера. Названия таких каталогов представляют собой цифры. За каждым предопределенным объектом зарезервирован свой номер. Например объект “устройство” предоставляется под номером 3, имеет один единственный экземпляр (номер 0) и несколько ресурсов , таких как 0 — производитель, 1 — номер модели, 2 — серийный номер, 3 — версия прошивки, 4 — перезагрузка ,5 — сброс к заводским настройкам и т.д.
В таком случае , чтобы прочитать номер версии прошивки устройства необходимо обратиться к ресурсу по ссылке /3/0/3 . Очевидно , что ресурсы 4 и 5 не предназначены для чтения или записи. Их назначение — выполнение соответственно перезагрузки и сброса устройства к заводским настройкам.
Для обновления прошивки используется объект /5/0 . Среди его ресурсов содержатся 0 — пакет программного обеспечения, это собственно сам файл прошивки, который может быть загружен из сервера. Ресурс 1 представляет собой ссылку на хранящуюся на том же или любом-другом сервере прошивку. Ресурс 2 — флаг обновления, когда он установлен, то после загрузки новой версии прошивки также будет выполнено ее обновление. Ну и так далее.

Ознакомится со всеми стандартными объектами и их ресурсами вы можете в спецификации на протокол LWM2M.
В версии 1.0 протокола LWM2M определены восемь основных объектов :

  • /0 — объект безопасности. Экземпляры этого объекта содержат конфиденциальную информацию для установления защищенного соединения с серверами. Поэтому объект безопасности является скрытым объектом и не отображается через web интерфейс сервера.
  • /1 — объект сервер. Экземпляры этого объекта являются учетными записями конкретных серверов, к которым может подсоединяться ваше устройство. Основными типами серверов является сервер начальной загрузки (Bootstrap Server) и сервер управления данными (DM Server).
  • /2 — объект контроля доступа. Поскольку к вашему устройству могут иметь доступ несколько серверов, экземпляры объекта контроля доступа устанавливают права этим серверам для доступа к вашему устройству.
  • /3 — объект устройства. Этот объект имеет только один экземпляр , соответствующий вашему устройству. Содержит несколько ресурсов устройства, таких как серийный номер, название производителя и т.д.
  • /4 — объект мониторинга связи. Поскольку протокол LWM2M разрабатывался в первую очередь для мобильных устройств связи, то в единственном экземпляре объекта мониторинга связи содержаться такие ресурсы как уровень сигнала в децибелах , сетевой канал сотовой связи и т.д. Этот объект не является обязательным.
  • /5 — объект обновления прошивки. Предназначен для удаленного обновления прошивки на устройстве. Имеет только один экземпляр.
  • /6 — объект расположения. Предназначен для определения географических координат вашего устройства. Также имеет только один экземпляр.
  • /7 — объект статистики связи .Также специфический для мобильных устройств объект, который содержит статистику о количестве проходящего через устройство трафика, количество принятых/ отправленных SMS и т.д. Имеет один экземпляр.

Кроме определенных в спецификации стандартных объектов вы можете создавать свои собственные объекты, специфические для вашего устройства.
Организация OMA создала реестр объектов и ресурсов, которые имеют заранее установленные номера. Прежде чем создавать свой собственный объект с набором ресурсов вам следуют просмотреть этот реестр на наличие данного объекта.
К примеру датчик температуры в реестре OMA LwM2M имеет номер объекта 3303, а датчик атмосферного давления — 3315 . Номера ресурсов у них совпадают, поскольку эти сенсоры по сути имеют одинаковые ресурсы.
Например, чтобы получить текущее значение температуры с сенсора необходимо прочитать ресурс / 3303 / 0 / 5700 для первого (или единственного) датчика ,значение единиц измерения храниться в ресурсе / 3303 / 0 / 5701 . Если в устройстве есть второй датчик температуры, то прочитать значение с его сенсора можно по пути / 3303 / 1 / 5700 .

OMA также предоставляет редактор объектов и ресурсов, в котором вы можете зарегистрировать свой объект с набором ресурсов.

Существует несколько свободных реализаций протокола LWM2M на различных языках программирования, с реализациями серверной и клиентской части протокола.
В данной статье я хочу познакомить читателей с открытой реализацией клиентской части протокола LWM2M на языке С под названием wakaama, а также реализацией серверной части LWM2M на языке Java для Bootstrap и DM (Data Management) серверов под названием Leshan от Eclipse Foundation.

Сразу хочу подчеркнуть, что как со стороны клиентской, так и с серверной стороны существует возможность расширения количества поддерживаемых объектов за счет дописывания своих собственных.
Начнем рассмотрение с серверной части. Для быстрого начала работы необходимо загрузить исходники проекта с github — репозитория .
Все проделываемые мною шаги можно выполнять на домашнем ПК с установленной операционной системой Linux. Для демонстрации работы клиентской части протокола внутри устройства с ограниченными ресурсами я установлю LWM2M клиент на своей Raspberry Pi 3. К сожалению собрать сервер Leshan на Raspberry Pi 3 мне не удалось, поэтому серверная часть будет тестироваться на моем домашнем ПК с ОС Linux.

Клонируем репозиторий Leshan на свою домашнюю Linux машину:


$ git clone https://github.com/eclipse/leshan.git

Устанавливаем инструменты для сборки java проектов :


$ sudo apt-get update
$ sudo apt-get install maven
$ sudo apt-get install default-jdk

Собираем проект, написанный на языке Java :


$ cd /leshan
$ sudo mvn clean install

Переходим в каталог примера DM сервера и запускаем его :


$ cd leshan-server-demo/target
$ java -jar ./leshan-server-demo-1.0.0-SNAPSHOT-jar-with-dependencies.jar

Web интерфейс запущенного сервера доступен через localhost:8080, открываем в браузере :

Заходим в раздел SECURITY и создаем там новый клиент , нажав на кнопку “Add new client security configuration” .
Заполняем поля так, как показано на следующей картинке :

Выше по тексту я упоминал о реестре объектов и ресурсов, созданном OMA. Сервер Leshan также поддерживает объекты из этого реестра. Для каждого такого объекта используется xml файл с описанием содержащихся в нем ресурсов. Найти эти файлы можно по следующему пути leshan/leshan-server-demo/src/main/resources/models .
В случае создания собственного уникального объекта необходимо также создать xml файл и показать серверу где его искать через опцию командной строки -m

Теперь установим клиентскую часть LWM2M на Raspberry Pi 3.
Соединяемся с Raspberry Pi через SSH :


$ ssh pi@192.168.0.111

Загружаем исходники LWM2M клиента wakaama :


pi@raspberrypi:~ $ git clone https://github.com/eclipse/wakaama.git

Устанавливаем необходимый для сборки инструментарий :


pi@raspberrypi:~ $ sudo apt-get install cmake

Загружаем библиотеку tinydtls для использования защищенного DTLS соединения :


pi@raspberrypi:~ $cd wakaama/
pi@raspberrypi:~/wakaama$ git submodule init
pi@raspberrypi:~/wakaama$ git submodule update

Собираем LWM2M клиента :


pi@raspberrypi:~/wakaama$ mkdir client && cd client
pi@raspberrypi:~/wakaama/client $ cmake -DDTLS=1 ../examples/client
pi@raspberrypi:~/wakaama/client $ make

После сборки запускаем клиента с флагом —help , чтобы узнать опции программы :


pi@raspberrypi:~/wakaama/client $ ./lwm2mclient --help
Usage: lwm2mclient [OPTION]
Launch a LWM2M client.
Options:
-n NAME Set the endpoint name of the Client. Default: testlwm2mclient
-l PORT Set the local UDP port of the Client. Default: 56830
-h HOST Set the hostname of the LWM2M Server to connect to. Default: localhost
-p PORT Set the port of the LWM2M Server to connect to. Default: 5683
-4 Use IPv4 connection. Default: IPv6 connection
-t TIME Set the lifetime of the Client. Default: 300
-b Bootstrap requested.
-c Change battery level over time.
-i STRING Set the device management or bootstrap server PSK identity. If not set use none secure mode
-s HEXSTRING Set the device management or bootstrap server Pre-Shared-Key. If not set use none secure mode

Необходимо определить IP адрес нашего сервера, для этого на ПК с ОС Linux запускаем команду :


$ ifconfig
enp3s0: flags=4163<up,broadcast,running,multicast> mtu 1500
inet 192.168.0.104 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::6c24:71d8:b5af:e20e prefixlen 64 scopeid 0x20
ether d0:50:99:7d:15:cd txqueuelen 1000 (Ethernet)
RX packets 359057 bytes 475203522 (453.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 208986 bytes 15972748 (15.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
</up,broadcast,running,multicast>

Запускаем наш клиент на Raspberry Pi 3 :


pi@raspberrypi:~/wakaama/client $ ./lwm2mclient -n lwm2m_test_client -h 192.168.0.104 -p 5684 -4 -t 120 -i 12345 -s 3031323334


Trying to bind LWM2M Client to port 56830
LWM2M Client "lwm2m_test_client" started on port 56830
> -> State: STATE_REGISTERING
60 bytes received from [192.168.0.104]:5684
16 FE FD 00 00 00 00 00 00 00 00 00 2F 03 00 00 ............/...
23 00 00 00 00 00 00 00 23 FE FD 20 5F C6 C5 88 #.......#.. _...
22 B8 F3 64 3D 23 87 D6 50 10 ED F5 6C E0 85 EC "..d=#..P...l...
FB 8E 56 C8 D6 DE 29 79 04 2C 59 8D ..V...)y.,Y.

В разделе CLIENTS сервера leshan мы увидим нашего подключенного клиента на Raspberry Pi 3.

Для создания своего собственного сервера на основе Leshan прочитайте вот это руководство разработчика.
Дописать в клиент собственные объекты можно , открыв исходный код wakaama и проанализировав структуру кода любого из существующих объектов. Создайте свой собственный объект по образу и подобию тестового объекта, размещенного в test_object.c .


pi@raspberrypi:~/wakaama/examples/client $ tree
.
├── CMakeLists.txt
├── lwm2mclient.c
├── lwm2mclient.h
├── object_access_control.c
├── object_connectivity_moni.c
├── object_connectivity_stat.c
├── object_device.c
├── object_firmware.c
├── object_location.c
├── object_security.c
├── object_server.c
├── system_api.c
└── test_object.c


0 directories, 13 files

Я решил для примера добавить в wakaama свой объект для управления светодиодом на плате Raspberry Pi 3. Очевидно, что такой объект уже есть в списке стандартных, нужно просто поискать. Объект называется Light Control Object под номером /3311 .
Чтобы добавить мой объект Light Control Object в свой код wakaama вам нужно загрузить патч из репозитория и наложить этот патч на исходники.

  • Клонируем репозиторий :


pi@raspberrypi:~$ git clone https://github.com/PetroShevchenko/cxemotexnika.git

  • Или загружаем последние изменения, если локальная копия репозитория уже есть на вашем диске :


pi@raspberrypi:~$ cd ~/cxemotexnika
pi@raspberrypi:~/cxemotexnika $ git pull

  • Копируем патч :


pi@raspberrypi:~$ cd ~/cxemotexnika/Examples/RaspberryPi3/wakaama/
pi@raspberrypi:~/cxemotexnika/Examples/RaspberryPi3/wakaama $ cp wakaama.patch ~/wakaama

  • Накладываем патч :


pi@raspberrypi:~/cxemotexnika/Examples/RaspberryPi3/wakaama $ cd ~/wakaama
pi@raspberrypi:~/wakaama $ git apply wakaama.patch

  • Собираем клиента :


pi@raspberrypi:~/wakaama $ cd client
pi@raspberrypi:~/wakaama/client $ cmake -DDTLS=1 ../examples/client
pi@raspberrypi:~/wakaama/client $ make

  •  Запускаем на выполнение :


pi@raspberrypi:~/wakaama/client $ sudo ./lwm2mclient -n lwm2m_test_client -h 192.168.0.104 -p 5684 -4 -t 120 -i 12345 -s 3031323334

Нам придется запустить клиента с правами root, поскольку иначе не получиться обратиться к светодиоду на плате Raspberry PI 3, чтобы включить или выключить его.

Теперь мы можем управлять свечением светодиода через веб-интерфейс, задав значение true или false для ресурса /3311/0/5850.

На следующих двух картинках изображен обмен данными между клиентом и сервером по протоколу CoAP с защищенной сессией DTLS, подслушанный с помощью Wireshark.
На второй картинке виден PUT запрос от сервера, записывающий значение true в ресурс /3311/0/5850.

В случае проблем с соединением запускайте Wireshark и анализируйте CoAP пакеты.
Для дешифровки DTLS пакетов необходимо ввести PSK (3031323334) в меню Protocol Preferences — Pre-Shared-Key : 3031323334 , установив курсор на пакет Client Hello. Имейте ввиду, что Wireshark должен быть запущен раньше, чем LWM2M клиент, чтобы захватить начальное сообщение “Client Hello” от клиента.

Удачных экспериментов!

Viewed 348756 times by 54362 viewers

Last modified: 23/10/2020

Author

Comments

Write a Reply or Comment