Привет Хабр! Я занимаюсь разработкой электроники (благо навыки охватывают большую часть этого интереснейшего увлечения). И заказали мне как-то разработку GSM-логгера для ЖКХ.

Кроме наличия требуемых входов/выходов (в том числе 4-20 ма) и источника питания 5-30 в для датчиков, основным условием было минимизация потребления дабы иметь возможность питаться от батарей.После проработки схемотехники и печатной платы во весь рост встал вопрос о используемом протоколе. Хотелось чего-то простого и стандартного.

MQTT. Но MQTT это TCP со всеми достоинствами и недостатками. А у меня аккумулятор и срок работы от 3 месяцов. Для тестов был написан примитивный протокол поверх UDP. Но поскольку не отношу себя к пионэрам, свято уверенным, что вот сейчас за 2 дня напишут что-то удобоваримое — продолжил поиски чего-то общепринятого.

Уж не помню как — попалось мне упоминание о MQTT-SN. Протокол, наследующий семантику MQTT, но приспособленный для передачи по UDP и клиентам с батарейным питанием. Оказалось, есть такой, разработан в недрах IBM и в последующем открыт для сообщества. После прочтения описания стало понятно, что вот оно, счастье, рядом.

Но нужен брокер (так в MQTT называют сервер), привычный Mosquitto (по словам Яна Крагса от 2013) когда-нибудь сможет в MQTT-SN, но не сейчас. Зато есть RSMB, и даже в исходниках на Git-хабе.

Исходники это хорошо, надо собирать. Сборка производиться CygWin-ом в Visual Studio (которую я видел последний раз лет 5 назад). Ставим фришную версию, создаём проект и — никак. На 5-10 раз (вообще в моей жизни большую роль играет случай и упрямство) прописал правильно проект — и о, чудо, собрал таки брокера. Замечу что под Linux это действие прошло гораздо проще.

Торжественно запускаем. Обидно но не работает. Может всё-таки свой протокол это выход? Представив себе объём работы по написанию и отладке сервера и клиентов — решил нет, мой выбор — MQTT-SN. Оказалось всё просто — надо было конфигурацию прописать и указать брокеру.
Минимальная выглядит таким образом:

trace_output off                # Диагностика, можно и включить
listener 1883 INADDR_ANY        # Порт для обычного MQTT
listener 1883 INADDR_ANY mqtts  # Порт для MQTT-SN протокола

И после этого брокер заработал. Вкратце отличия MQTT-SN от классического MQTT.

  1. Протокол MQTT-SN работает поверх UDP, а не TCP как обычный. Это перекладывает ответственность за контроль доста��ки сообщений на программиста. Зато позволяет устройству расходовать меньше энергии (а для меня это важно) на поддержание канала связи через GSM.

  2. Введён новый уровень QoS (Quality of Service, качество сервиса) -1. Означающий отсутствие контроля доставки. Устройство просыпается, делает нужную работу, отсылает результаты и тут-же засыпает не ожидая подтверждения.

  3. Появились шлюзы, позволяющие агрегировавать данные от множества устройств и пересылать их брокеру.

На git-е eclipsa лежат исходники клиента MQTT-SN с примерами. Собственно надо прописать функции работы с каналом transport_xx под свои нужды. В остальном больших проблем нет (нашёл пару ошибок, надо тестировать).

К сожалению не реализована поддержка спящих клиентов. Стоят заглушки. Кто сможет бросить в авторов протокола камень — исходники доступны, помощь приветствуется.

Что хотел сказать в итоге. Потратив некоторое (небольшое время) я получил готовую инфраструктуру для дальнейшего развития проекта. Протокол позволяет использовать STM32 на 4 МГц. Я могу использовать множество клиентов на разных платформах (что нереально было-бы сделать в одиночку при написании своего протокола). Более того, имея возможность собрать брокера под Linux я разместил его на инстансе Amazon-а и мой заказчик получил решение без необходимости держать и обслуживать сервер. Стандартные решения (не всегда, но в подавляющем количестве случаев) ускоряют исполнение задачи.

Ссылки:
MQTTSN client — Eclipse
RSMB — github