Проблема с драйвером wb-gpio

Здравствуйте.
Знакомлюсь с WB4. Пробую взаимодействовать с MQTT через драйвер mqttws31.js (со своей веб-страницы).
Обнаружил такую проблему:
Если послать команду Send, в которой Message.destinationName = “/devices/wb-gpio/controls/Relay_1/on”, а Message.payload = “” (то есть обратиться к топику, но не дать, собственно, самой команды (0 или 1)), то после этого контролер вообще игнорирует подобные команды. Не исполняет, в том числе и правильно построенные, с Message.payload = “1” или “0”. Очевидно, что эту нештатную ситуацию код драйвера не обрабатывает корректно.
После перезагрузки контролера работоспособность восстанавливается.
Кроме этого, обнаружено следующее: если на тот же топик подавать в Message.payload любые символы, кроме “0”, то драйвер воспринимает их как эквивалент “1” и включает реле. Проверял “-1”, “[”, “d”, “sdfsdf”.
На мой взгляд, такое поведение опасно. Драйвер должен принимать только “0” или “1” в качестве параметра команды, любой другой аргумент (в том числе его отсутствие) должны игнорироваться, без потери работоспособности драйвера.

P.S. Проверил статус демона wb-homa-gpio до и после подачи команды с пустым payload.
До ошибочной команды:

root@wirenboard:~# service wb-homa-gpio status
[ ok ] wb-homa-gpio is running.

После:

root@wirenboard:~# service wb-homa-gpio status
[FAIL] wb-homa-gpio is not running ... failed!

Предполагаю, что код обработки данного сообщения находится в
https://github.com/contactless/wb-homa-drivers/blob/master/wb-homa-gpio/main.cpp

Вот строки, как я понимаю, данной функции:

163   void TMQTTGpioHandler::OnMessage(const struct mosquitto_message *message)
164   {
165       string topic = message->topic;
166       string payload = static_cast<const char *>(message->payload);
167   
168   
169       const vector<string>& tokens = StringSplit(topic, '/');
170   
171       if (  (tokens.size() == 5) &&
172             (tokens[0] == "") && (tokens[1] == "devices") &&
173             (tokens[2] == MQTTConfig.Id) && (tokens[3] == "controls") &&
174             (tokens[4].find("_total") == (tokens[4].size() - 6)) )
175       {
176           int pos = tokens[4].find("_total");
177           string gpio_name = tokens[4].substr(0, pos);
178           for (TChannelDesc& channel_desc : Channels) {
179               const auto& gpio_desc = channel_desc.first;
180               const auto& gpio_handler = channel_desc.second;
181               if (gpio_desc.Name == gpio_name) {
182                   float total = stof(payload);
183                   gpio_handler->SetInitialValues(total);
184                   unsubscribe(NULL,topic.c_str());
185               }
186           }
187       }
188       if (  (tokens.size() == 6) &&
189             (tokens[0] == "") && (tokens[1] == "devices") &&
190             (tokens[2] == MQTTConfig.Id) && (tokens[3] == "controls") &&
191             (tokens[5] == "on") )
192       {
193           for (TChannelDesc& channel_desc : Channels) {
194               const auto& gpio_desc = channel_desc.first;
195               if (gpio_desc.Direction != TGpioDirection::Output)
196                   continue;
197   
198               if (tokens[4] == gpio_desc.Name) {
199                   auto& gpio_handler = *channel_desc.second;
200   
201                   int val = payload == "0" ? 0 : 1;
202                   if (gpio_handler.SetValue(val) == 0) {
203                       // echo, retained
204                       Publish(NULL, GetChannelTopic(gpio_desc), payload, 0, true);
205                   }else {
206                       cerr << "DEBUG : couldn't set value" << endl;
207                       }
208               }
209           }
210       }
211   }

В строке 201, вероятно, и находится “виновник” проблемы.
Возможно, лучше бы проверку усложнить таким образом:
Вместо “int val = payload == “0” ? 0 : 1;” сделать

"int val;
 switch (payload) {
   case "0":
     val = 0;
     break;

   case "1":
     val = 1;
     break;

   default:    //если payload имеет ошибочное значение
     continue; //прерываем эту итерацию цикла
}"

Сам я в С++ ниочём, синтаксис, возможно ошибочный, но идею, надеюсь, показал верно.

P.S. Кстати, если параметр payload должен быть равен “0” или “1”, то такую проверку логично бы делать до входа в цикл (строка 193).
Какой смысл крутить цикл, если исходный параметр ошибочен и действие всё равно нельзя выполнять?
P.S.2. Интересно бы узнать, на какой строке спотыкается драйвер, на 166 или 204.

Спасибо, переделали.

Стоит конечно сказать, что никакой проблемы это не представляло. Если вы целенаправленно пытаетесь сломать драйвера отправкой некорректных комманд, то есть ещё десяток способов это сделать. Только вот зачем?

MQTT Conventions вам запрещает слать в топик что-то отличное от 0 и 1. Поведение в таком случае не определено. Конечно драйверу не стоило вываливаться от пустого сообщения с ошибкой, как это было сейчас, но вот какое поведение правильное при получении неправильной строки - это вообще не очевидно.

Надо бы уточнить - Wiren Board MQTT Conventions. Раз документировано - будьте любезны. Хотя, лично для меня привычнее 0 и !0.

А с этим категорически не согласен. Система должна быть устойчивой к воздействиям, допустимым в рамках используемого протокола. Пусть реакция будет не определена для значений, не входящих в допустимый диапазон, но ломаться не должна.

Ошибка до сих пор не исправлена ?
Или может поправили в gpio но забыли в serial ?

root@wirenboard:~# mosquitto_pub -t /devices/wb-mr11_1/controls/K10/on -m ""
root@wirenboard:~# service wb-mqtt-serial status
[FAIL] wb-mqtt-serial is not running ... failed!
root@wirenboard:~# service wb-mqtt-serial restart

Это я не специально :smile:, просто второпях.