### RFC 7252 Одним из широко используемых протоколов для взаимодействия между IoT-устройствами (Internet of Things) или IoT-устройствами и внешней средой является протокол CoAP – Constrained Application Protocol ущественная особенность протокола СoAP – это его совместимость с протоколом HTTP, что обеспечивает при его использовании взаимодействие совокупности устройств IoT, формирующих некую сеть, с всемирной паутиной Интернет. ### Особенности CoAP Структура протокола CoAP была разработана в соответствии с REST-архитектурой. Методы: - GET – выполняет поиск ресурсов и предоставляет информацию, которая соответствует ресурсу, указанному в ссылке URI (Uniform Resource Identifier), где ресурс – это источник данных, которым, например, может являться датчик; - PUT – задает новое действие над ресурсом; - POST – отвечает за изменения действия над ресурсом; - DELETE – служит для удаления активированных возможностей ресурса. -FETCH – выполняет предоставление частичной информации о ресурсе по параметрам в запросе; - PATCH – отвечает за частичное изменение действия над ресурсом. Протокол CoAP использует UDP (User Datagram Protocol), в качестве транспортного протокола по умолчанию, что позволяет уменьшить размер служебных данных и увеличить эффективность работы. В редких случаях могут также использоваться TCP или SCTP. Так как CoAP – это протокол прикладного уровня, то в случаях, когда нужно обеспечить безопасное соединение, используется шифрование сообщений по протоколу DTLS (Datagram Transport Layer Security). DTLS работает поверх протокола UDP и служит для защиты данных на транспортном уровне (работает между уровнем приложений и транспортным уровнем). - Наименьшее сообщение CoAP имеет размер всего четыре байта. - CoAP использует два типа сообщений, запросы и ответы, используя простой двоичный формат базового заголовка. - За базовым заголовком могут следовать параметры в оптимизированном формате «тип-длина-значение». Транспортный уровень использует протокол UDP для уменьшения сетевых накладных расходов и COAP поддерживает многоадресную рассылку. - Чтобы компенсировать ненадежность передачи UDP, CoAP имеет механизм повторной передачи сообщений. - CoAP не поддерживает постоянное соединение и не имеет контрольных сообщений. Когда нет сервиса, устройству не нужно отправлять сообщения во внешние системы. ### CoAP определяет четыре режима безопасности 1. NoSec, где DTLS отключен. 2. PreSharedKey, где DTLS включен, есть список предварительно общих ключей, и каждый ключ включает список узлов, с которыми он может использоваться для связи. Устройства должны поддерживать набор шифров AES. 3. RawPublicKey, где DTLS включен и устройство использует асимметричную пару ключей без сертификата, который проверяется вне диапазона. Устройства должны поддерживать набор шифров AES и алгоритмы Elliptic Curve для обмена ключами. 4. Сертификат, где DTLS включен и устройство использует сертификаты X.509 для проверки. ### Формат сообщений протокола CoAP У протокола СоАР определено всего четыре вида сообщений: Confirmable, Non-confirmable, Acknowledgement, Reset. Все сообщения кодируются в двоичном виде. ![Структура данных буферного кэша](https://whoisdeveloper.ru/static/img/coap1.png) Версия (Version) (Ver) – двухбитное целое число, указывающее на номер версии CoAP. На данный момент существует только одна версия протокола. Тип (Type) (Т) – двухбитное целое число. Указывает на тип сообщения Confirmable (0), Non-confirmable (1), Acknowledgement (2) или Reset (3). Длина маркера (Token Length) (TKL) – четырехбитное целое число. Указывает длину поля маркера (Token) переменной длины (0–8 байт). Длины от 9 до 15 зарезервированы. Код (Code) – восьмибитное целое число, делится на трехбитный и пятибитный класс. Поле "код" записывается, как "c.dd", где "с" – это цифра от 0 до 7 для трехбитного подполя и "dd" – две цифры в диапазоне от 00 до 31 для пятибитного подполя. - Код 0.00 указывает на пустое сообщение. - Код 0.01–0.31 указывает на запрос. - Код 1.00–1.31 зарезервирован. - Код 2.00–2.31 указывает на успешный ответ. - Код 3.00–3.31 зарезервирован. - Код 4.00–4.31 указывает на ошибку клиента. - Код 5.00–5.31 указывает на ошибку сервера. - Код 6.00–7.31 зарезервирован. Значения "dd" – это фиксированные табличные величины, которые указывают в случае, если сообщение – запрос на метод запроса (например, 0.01 – это запрос GET, 0.02 – это запрос POST); в случае, если сообщение – ответ, указывают на код ответа (например, 2.05 – это ответ, содержащий запрашиваемую информацию (Content), 4.04 – это ошибка, возникающая, когда запрашиваемое устройство отсутствует или временно недоступно (Not Found)). Всю таблицу значений поля Code можно посмотреть в RFC7252, раздел 12.1.2. Идентификатор сообщения (Message ID) – шестнадцатибитное целое число, являющееся уникальным идентификатором для сообщения. Message ID идентифицирует сообщение, чтобы определить, на какой запрос пришла информация или ошибка. CoAP-устройство, отправляя сообщение Confirmable или Non-confirmable, случайным образом генерирует значение идентификатора для этого сообщения. В ответных сообщениях Acknowledgement- или Reset-идентификаторы будут те же, что и в сообщении, на которое они отвечают. За заголовком следует значение маркера (Token), которое может составлять от 0 до 8 байт, как указано в поле TKL. Значение маркера случайным образом генерируется устройством CoAP и используется в пределах одной сессии для установления соответствия запроса с ответом, т.е. происходит группировка сообщений по цепочке "запрос-ответ". Нулевое значение маркера используется, когда никакие другие маркеры не используются в устройстве, на которое отправляется запрос, или если запросы делаются последовательно и в малом количестве. Далее следуют опции (Options), в которых описываются различные параметры сообщений. Например, есть Max-Age Option, которая устанавливает максимальное время хранения информации во временной памяти, по умолчанию этот параметр равен 60 сек. Другая опция, Content-Format Option, задается в виде числа, которое устанавливает формат представления полезной нагрузки: значение 0 указывает на то, что полезная нагрузка будет текстовой, а значение 41 указывает на то, что полезная нагрузка будет в формате xml. Для адресации по URI в протоколе CoAP предусмотрены опции Uri-Host (определяет адрес интернет-хоста запрашиваемого ресурса), Uri-Port (определяет номер порта транспортного уровня запрашиваемого ресурса), Uri-Path (определяет часть пути до ресурса) и Uri-Query (определяет параметр, который запрашивает ресурс). Например: - Uri-Host = "example.net" - Uri-Port = 5683 - Uri-Path = ".well-known" - Uri-Path = "core" - Uri-Query = "login?" - coap://example.net:5683/.well-known/core/ login? В COAP используется четыре типа сообщений: - Confirmable(CON) – сообщение, содержащее запрос или ответ, требующее подтверждения и считающееся надежным. Каждое сообщение Confirmable вызывает одно ответное сообщение подтверждения или сброса; - Non-confirmable(NON) – сообщение, содержащее запрос или ответ, не требующее подтверждения и надежной передачи, так как передается регулярно (например, показания от датчика); - Acknowledgement(ACK) – сообщение, подтверждающее, что пришло сообщение Confirmable. При этом само сообщение Acknowledgement не означает успех или неудачу любого из запросов, содержащегося в сообщении Confirmable; - Reset(R) – сообщение сброса, указывающее на то, что конкретное сообщение (Confirmable или Non-confirmable) было получено, но некоторая часть текста отсутствует и невозможно правильно его обработать. Такая ситуация обычно возникает, когда принимающий узел перегружен. Вызов этого сообщения (например, путем отправления пустого сообщения Confirmable) также полезен в качестве проверки доступности узла ("CoAP ping"). ### Многоадресная рассылка Протокол CoAP поддерживает возможность послать запрос сразу группе устройств, реализуя таким образом многоадресную рассылку (multicast). В первом случае задание группы происходит по групповому IP-адресу или по полному имени хоста, т.е. FQDN (Fully Qualified Domain Name), которому в соответствии с системой DNS сопоставляется групповой IP-адрес. Во втором случае задание группы происходит через каталог ресурсов (RD – Resource Directory). RD хранит URI, по которым предоставляется доступ к датчикам. При помощи методов REST датчики регистрируются в каталоге и периодически обновляют информацию о себе. По умолчанию все узлы принадлежат к группе "All CoAP Nodes". Членам этой группы назначается широковещательный адрес: для IPv4 это адрес 224.0.1.187 [10], а для IPv6 – это адреса FF02 :: FD и FF05 :: FD, UDP-порт, по умолчанию, 5683. Для обнаружения адреса RD датчик посылает по широковещательному IP-адресу запрос с указанием типа ресурса "rt=core.rd", при этом сервер RD ответит на этот запрос, а все остальные устройства в сети его проигнорируют. Все запросы создаются с помощью формата связи CoRE (Constrained RESTful Environments) [8]. CoRE задает ссылку, по которой можно обратиться для внесения информации, поиска размещенных ресурсов и их атрибутов, связей между ресурсами в RD. По умолчанию точкой входа в каталог ресурсов является URI/"Well-Known/Core". Датчик отправляет методом REST запрос POST к RD, в который внесена информация о том, на какие запросы датчик сможет предоставить информацию, но внесение информации не обязательно, тогда датчик будет принимать любые запросы. Таким образом все датчики, которые можно использовать для многоадресной рассылки, будут внесены в RD и формирование групп будет происходить по сообщенной датчиками информации. Например, CoAP-клиент посылает запрос в RD на возможность формирования группы из датчиков. Такой запрос будет отправлен по CoAP-протоколу методом POST с URI в общем виде, который выглядит как: URI: /{+rd-group}{?gp, d, con}, где - rd-group – функция, указывающая, что необходимо сформировать группу; - gp – имя группы; - d – домен, к которому принадлежит группа; - con – контекст, используемый для установки собственного IP-адреса многоадресной рассылки для группы, в форме: // multicastaddress:port, указывать этот параметр необязательно.