Microsoft Azure IoTHub client MQTT transport

Dependents:   STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more

Revision:
27:04de3c0bf1db
Parent:
26:0dae84ecce27
Child:
28:0cd355c3294e
--- a/iothubtransport_mqtt_common.c	Fri Aug 11 14:02:18 2017 -0700
+++ b/iothubtransport_mqtt_common.c	Fri Aug 25 11:22:29 2017 -0700
@@ -74,6 +74,8 @@
 
 static const char* MESSAGE_ID_PROPERTY = "mid";
 static const char* CORRELATION_ID_PROPERTY = "cid";
+static const char* CONTENT_TYPE_PROPERTY = "ct";
+static const char* CONTENT_ENCODING_PROPERTY = "ce";
 
 #define UNSUBSCRIBE_FROM_TOPIC                  0x0000
 #define SUBSCRIBE_GET_REPORTED_STATE_TOPIC      0x0001
@@ -97,6 +99,8 @@
     { "%24.uid", 7 },
     { "%24.to", 6 },
     { "%24.cid", 7 },
+    { "%24.ct", 6 },
+    { "%24.ce", 6 },
     { "devices/", 8 },
     { "iothub-operation", 16 },
     { "iothub-ack", 10 }
@@ -569,7 +573,7 @@
         {
             if (STRING_sprintf(result, "%s%%24.cid=%s", index == 0 ? "" : PROPERTY_SEPARATOR, correlation_id) != 0)
             {
-                LogError("Failed setting correlation_id.");
+                LogError("Failed setting correlation id.");
                 STRING_delete(result);
                 result = NULL;
             }
@@ -585,12 +589,46 @@
         {
             if (STRING_sprintf(result, "%s%%24.mid=%s", index == 0 ? "" : PROPERTY_SEPARATOR, msg_id) != 0)
             {
-                LogError("Failed setting correlation_id.");
+                LogError("Failed setting message id.");
+                STRING_delete(result);
+                result = NULL;
+            }
+            index++;
+        }
+    }
+
+    // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_010: [ `IoTHubTransport_MQTT_Common_DoWork` shall check for the ContentType property and if found add the `value` as a system property in the format of `$.ct=<value>` ]
+    if (result != NULL)
+    {
+        const char* content_type = IoTHubMessage_GetContentTypeSystemProperty(iothub_message_handle);
+        if (content_type != NULL)
+        {
+            if (STRING_sprintf(result, "%s%%24.%s=%s", index == 0 ? "" : PROPERTY_SEPARATOR, CONTENT_TYPE_PROPERTY, content_type) != 0)
+            {
+                LogError("Failed setting content type.");
                 STRING_delete(result);
                 result = NULL;
             }
+            index++;
         }
     }
+
+    // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_011: [ `IoTHubTransport_MQTT_Common_DoWork` shall check for the ContentEncoding property and if found add the `value` as a system property in the format of `$.ce=<value>` ]
+    if (result != NULL)
+    {
+        const char* content_encoding = IoTHubMessage_GetContentEncodingSystemProperty(iothub_message_handle);
+        if (content_encoding != NULL)
+        {
+            if (STRING_sprintf(result, "%s%%24.%s=%s", index == 0 ? "" : PROPERTY_SEPARATOR, CONTENT_ENCODING_PROPERTY, content_encoding) != 0)
+            {
+                LogError("Failed setting content encoding.");
+                STRING_delete(result);
+                result = NULL;
+            }
+            index++;
+        }
+    }
+
     return result;
 }
 
@@ -600,6 +638,7 @@
     STRING_HANDLE msgTopic = addPropertiesTouMqttMessage(mqttMsgEntry->iotHubMessageEntry->messageHandle, STRING_c_str(transport_data->topic_MqttEvent));
     if (msgTopic == NULL)
     {
+        LogError("Failed adding properties to mqtt message");
         result = __FAILURE__;
     }
     else
@@ -607,6 +646,7 @@
         MQTT_MESSAGE_HANDLE mqttMsg = mqttmessage_create(mqttMsgEntry->packet_id, STRING_c_str(msgTopic), DELIVER_AT_LEAST_ONCE, payload, len);
         if (mqttMsg == NULL)
         {
+            LogError("Failed creating mqtt message");
             result = __FAILURE__;
         }
         else
@@ -620,6 +660,7 @@
             {
                 if (mqtt_client_publish(transport_data->mqttClient, mqttMsg) != 0)
                 {
+                    LogError("Failed attempting to publish mqtt message");
                     result = __FAILURE__;
                 }
                 else
@@ -847,6 +888,7 @@
 
                                         if (propName == NULL || propValue == NULL)
                                         {
+                                            LogError("Failed allocating property name (%p) and/or value (%p)", propName, propValue);
                                             result = __FAILURE__;
                                         }
                                         else
@@ -857,22 +899,43 @@
                                             strncpy(propValue, iterator + 1, valLen);
                                             propValue[valLen] = '\0';
 
-                                            if (nameLen > 3)
+                                            if (nameLen > 2)
                                             {
-                                                if (strcmp((const char*)&propName[nameLen - 3], MESSAGE_ID_PROPERTY) == 0)
+                                                if (nameLen > 3)
                                                 {
-                                                    if (IoTHubMessage_SetMessageId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+                                                    if (strcmp((const char*)&propName[nameLen - 3], MESSAGE_ID_PROPERTY) == 0)
+                                                    {
+                                                        if (IoTHubMessage_SetMessageId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+                                                        {
+                                                            LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'messageId' property.");
+                                                            result = __FAILURE__;
+                                                        }
+                                                    }
+                                                    else if (strcmp((const char*)&propName[nameLen - 3], CORRELATION_ID_PROPERTY) == 0)
                                                     {
-                                                        LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'messageId' property.");
+                                                        if (IoTHubMessage_SetCorrelationId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+                                                        {
+                                                            LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'correlationId' property.");
+                                                            result = __FAILURE__;
+                                                        }
+                                                    }
+                                                }
+
+                                                // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_012: [ If type is IOTHUB_TYPE_TELEMETRY and the system property `$.ct` is defined, its value shall be set on the IOTHUB_MESSAGE_HANDLE's ContentType property ]
+                                                if (strcmp((const char*)&propName[nameLen - 2], CONTENT_TYPE_PROPERTY) == 0)
+                                                {
+                                                    if (IoTHubMessage_SetContentTypeSystemProperty(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+                                                    {
+                                                        LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'customContentType' property.");
                                                         result = __FAILURE__;
                                                     }
                                                 }
-
-                                                if (strcmp((const char*)&propName[nameLen - 3], CORRELATION_ID_PROPERTY) == 0)
+                                                // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_013: [ If type is IOTHUB_TYPE_TELEMETRY and the system property `$.ce` is defined, its value shall be set on the IOTHUB_MESSAGE_HANDLE's ContentEncoding property ]
+                                                else if (strcmp((const char*)&propName[nameLen - 2], CONTENT_ENCODING_PROPERTY) == 0)
                                                 {
-                                                    if (IoTHubMessage_SetCorrelationId(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
+                                                    if (IoTHubMessage_SetContentEncodingSystemProperty(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK)
                                                     {
-                                                        LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'correlationId' property.");
+                                                        LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'contentEncoding' property.");
                                                         result = __FAILURE__;
                                                     }
                                                 }
@@ -1602,7 +1665,11 @@
             {
                 if ((current_time - transport_data->mqtt_connect_time) / 1000 > (SAS_TOKEN_DEFAULT_LIFETIME*SAS_REFRESH_MULTIPLIER))
                 {
+                    /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_058: [ If the sas token has timed out IoTHubTransport_MQTT_Common_DoWork shall disconnect from the mqtt client and destroy the transport information and wait for reconnect. ] */
                     (void)mqtt_client_disconnect(transport_data->mqttClient);
+                    xio_destroy(transport_data->xioTransport);
+                    transport_data->xioTransport = NULL;
+
                     IoTHubClient_LL_ConnectionStatusCallBack(transport_data->llClientHandle, IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN);
                     transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_NOT_CONNECTED;
                     transport_data->currPacketState = UNKNOWN_TYPE;