Протоколы «Интернета вещей» - CoAP

Продолжаем развлекаться с сетевыми протоколам.

CoAP (Constrained Application Protocol) — протокол прикладного уровня, предназначенный для т.н. межмашинного взаимодействия (Machine-to-Machine, M2M). Хорошо подходит для устройств с ограниченными ресурсами таких как микроконтроллеры и др. CoAP разрабатывался по образу и подобию своего предшественника, протокола HTTP, но с дополнительными фичами и улучшениями. В отличие от протокола HTTP, который является текстовым и использует ТСР, CoAP – это бинарный протокол, который работает поверх UDP, что значительно уменьшает общий размер передаваемых данных и повышает гибкость взаимодействия.

С точки зрения разработчика CoAP выглядит почти так же, как HTTP. В обоих случаях серверы предоставляют свои ресурсы по адресам URL, и клиенты обращаются к ним посредством стандартных методов, таких как GET, PUT, POST и DELETE. Архитектура REST (Representational State Transfer — «передача состояния представления»), получившая столь широкое распространение при разработке HTTP сервисов, также хорошо ложится и на CoAP сервисы.

Коды состояний (ответ сервера) CoAP в большинстве случаев аналогичны с HTTP и представляют собой целое число из трёх десятичных цифр — 2.xx успешно, 4.xx ошибка клиента, 5.xx ошибка сервера.

ДЕМО

На картинке светильник (сервер) и выключатель (клиент), оба представляют из себя независимые устройства на микроконтроллерах c ОС Contiki на борту, оба подключённы к сети. Передача данных между данными устройствами осуществляется посредством CoAP протокола. В текущей версии Contiki 3.0 по умолчанию используется Erbium (Er) REST Engine в качестве реализации CoAP.

coap.server.ipv6 | coap.client.ipv6 | исходники

screenshot

В примере с лампочками цвет задаётся / снимается методом PUT. В терминологии REST данный метод является идемпотентным, ага. Это умное слово пришло к нам из математики. Идемпотентность — свойство объекта или операции при повторном применении операции к объекту давать тот же результат, что и при первом. Операции сложения с нулём, умножения на единицу, возведения в степень ноль и пр. являются идемпотентными.

С точки зрения REST сервиса метод является идемпотентным, если повторный идентичный запрос, сделанный один или несколько раз подряд, имеет один и тот же эффект, не изменяющий состояние сервера. Создание большого количества идемпотентных запросов имеет такой же эффект, как и один запрос. В нашем случае сколько бы раз мы ни задавали например красный цвет для лампочки, она изменит свой цвет (покраснеет) только один раз при первом запросе. Корректно реализованные методы GET, PUT и DELETE идемпотентны, но не метод POST. Вот если бы мы захотели, чтобы при каждом обращении к серверу состояние лампочек менялось на противоположное (XOR), то про правилам REST такой запрос стоит реализовать через метод POST.

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

COAP

Самое время запустить наш любимый Wireshark и посмотреть что там внутри CoAP пакета. На рисунке метод PUT, который включает красные лампочки. В данном конкретном примере если мы хотим выполнить какое-то действие с лампочки, то надо использовать относительный URL сервера /actuators/leds, а собственно цвет предполагается задавать параметром color. В теле запроса mode=on включает лампочку, а mode=off выключает. Такой пример идёт в исходниках Contiki, а насколько он следует принципам REST это уже другой вопрос.

screenshot

Как видно, CoAP очень компактный протокол. Здесь наиболее интересно поле Type: Confirmable, с помощью которого разработчик приложения может контролировать надёжность доставки пакетов. Как мы знаем такая возможность изначально отсутствует у UDP протокола, но она реализована в CoAP как надстройка над UDP. Когда получателю приходит «Сonfirmable» сообщение, он всегда возвращает подтверждение. Передающая сторона, в свою очередь, повторно отправляет сообщение если подтверждение не возвращается в течение определенного периода времени, заданного по умолчанию и с каждым разом возрастающего экспоненциально, пока получатель не посылает сообщение подтверждения приема.

Для данных, которые не требуют подтверждения, достаточно классического UDP. Тогда в качестве более легкой альтернативы сообщение может быть передано с меньшей надежностью, помеченное как «Non-confirmable». Данное сообщение всегда несет либо запрос, либо ответ и не должно быть пустым.

Пожалуй отдельно стоит упомянуть симпатичное дополнение Copper для браузера Firefox, которое будет полезно при разработке CoAP приложений. С его помощью можно протестировать работу сервера отдельно от клиента. Для доступа к серверу из браузера нужно не забыть назначить дополнительный адрес abcd::1 виртуальному сетевому интерфейсу симулятора.

screenshot

Тема безопасности для «Интернета вещей» является особенно актуальной. В CoAP поддерживается шифрование, но без TCP стандартный TLS (Transport Layer Security) не может быть использован для обеспечения безопасности связи. Поэтому в CoAP используется DTLS (Datagram Transport Layer Security), который позволяет приложениям, основанным на коммуникациях посредством датаграмм, сообщаться безопасным способом, предотвращающим перехват, прослушивание, вмешательство, не нарушая защиты целостности данных или подделку содержимого сообщения.

Далее MQTT.

links

social