Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure iothub direct method support #21013

Merged
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ void MqttSubscribeLib(const char *topic) {
String realTopicString = "devices/" + String(SettingsText(SET_MQTT_CLIENT));
realTopicString += "/messages/devicebound/#";
MqttClient.subscribe(realTopicString.c_str());
MqttClient.subscribe("$iothub/methods/POST/#");
SettingsUpdateText(SET_MQTT_FULLTOPIC, SettingsText(SET_MQTT_CLIENT));
SettingsUpdateText(SET_MQTT_TOPIC, SettingsText(SET_MQTT_CLIENT));
#else
Expand Down Expand Up @@ -577,6 +578,26 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len

char topic[TOPSZ];
#ifdef USE_MQTT_AZURE_IOT
#ifdef USE_AZURE_DIRECT_METHOD
String fullTopicString = String(mqtt_topic);
int startOfMethod = fullTopicString.indexOf("methods/POST");
int endofMethod = fullTopicString.indexOf("/?$rid");
String req_id = fullTopicString.substring(endofMethod + 7);
if (startOfMethod == -1){
AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_MQTT "Azure IoT Hub message without a method."));
return;
}
String newMethod = fullTopicString.substring(startOfMethod + 12,endofMethod);
strlcpy(topic, newMethod.c_str(), sizeof(topic));
mqtt_data[data_len] = 0;
JsonParser mqtt_json_data((char*) mqtt_data);
JsonParserObject message_object = mqtt_json_data.getRootObject();
String mqtt_data_str= message_object.getStr("payload","");
data_len = mqtt_data_str.length();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No!!! data_len is the size of mqtt_data and is used to avoid buffer overflow. Changing data_len to the length of an arbitrary string received on the wire is wrong.

Remove this line.

strncpy copies the string with no more than data_len bytes, it figures out on its own the size of the source string.

strncpy(reinterpret_cast<char*>(mqtt_data),mqtt_data_str.c_str(),data_len);
mqtt_data[data_len] = 0;

#else
// for Azure, we read the topic from the property of the message
String fullTopicString = String(mqtt_topic);
String toppicUpper = fullTopicString;
Expand All @@ -593,6 +614,7 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len
return;
}
strlcpy(topic, newTopic.c_str(), sizeof(topic));
#endif
#else
strlcpy(topic, mqtt_topic, sizeof(topic));
#endif // USE_MQTT_AZURE_IOT
Expand Down Expand Up @@ -624,6 +646,11 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len
if (Mqtt.disable_logging) {
TasmotaGlobal.masterlog_level = LOG_LEVEL_NONE; // Enable logging
}
#ifdef USE_AZURE_DIRECT_METHOD // Send response for the direct method
String response_topic = "$iothub/methods/res/200/?$rid=" + req_id;
String payload = "{\"status\": \"success\"}";
MqttClient.publish(response_topic.c_str(),payload.c_str());
#endif
}

/*********************************************************************************************/
Expand Down