Microsoft Azure IoTHub client AMQP transport

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp iothub_client_sample_amqp ... more

This library implements the AMQP transport for Microsoft Azure IoTHub client. The code is replicated from https://github.com/Azure/azure-iot-sdks

Revision:
43:3da2d93bb955
Parent:
42:c2eaa912a28c
Child:
46:c688c75b63b9
--- a/uamqp_messaging.c	Mon Sep 25 13:37:09 2017 -0700
+++ b/uamqp_messaging.c	Sat Oct 21 20:10:24 2017 +0000
@@ -24,6 +24,10 @@
 
 #define MESSAGE_ID_MAX_SIZE 128
 
+#define AMQP_DIAGNOSTIC_ID_KEY "Diagnostic-Id"
+#define AMQP_DIAGNOSTIC_CONTEXT_KEY "Correlation-Context"
+#define AMQP_DIAGNOSTIC_CREATION_TIME_UTC_KEY "creationtimeutc"
+
 static int encode_callback(void* context, const unsigned char* bytes, size_t length)
 {
     BINARY_DATA* message_body_binary = (BINARY_DATA*)context;
@@ -308,6 +312,118 @@
     return result;
 }
 
+static int add_map_item(AMQP_VALUE map, const char* name, const char* value)
+{
+    int result;
+    AMQP_VALUE amqp_value_name;
+
+    if ((amqp_value_name = amqpvalue_create_symbol(name)) == NULL)
+    {
+        LogError("Failed creating AMQP_VALUE for name");
+        result = __FAILURE__;
+    }
+    else
+    {
+        AMQP_VALUE amqp_value_value = NULL;
+
+        if (value == NULL && (amqp_value_value = amqpvalue_create_null()) == NULL)
+        {
+            LogError("Failed creating AMQP_VALUE for NULL value");
+            result = __FAILURE__;
+        }
+        else if (value != NULL && (amqp_value_value = amqpvalue_create_string(value)) == NULL)
+        {
+            LogError("Failed creating AMQP_VALUE for value");
+            result = __FAILURE__;
+        }
+        else
+        {
+            if (amqpvalue_set_map_value(map, amqp_value_name, amqp_value_value) != 0)
+            {
+                LogError("Failed adding key/value pair to map");
+                result = __FAILURE__;
+            }
+            else
+            {
+                result = RESULT_OK;
+            }
+
+            amqpvalue_destroy(amqp_value_value);
+        }
+
+        amqpvalue_destroy(amqp_value_name);
+    }
+
+    return result;
+}
+
+static int create_message_annotations_to_encode(IOTHUB_MESSAGE_HANDLE messageHandle, AMQP_VALUE *message_annotations, size_t *message_annotations_length)
+{
+    AMQP_VALUE message_annotations_map = NULL;
+    int result;
+    const IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* diagnosticData;
+
+    if ((diagnosticData = IoTHubMessage_GetDiagnosticPropertyData(messageHandle)) != NULL &&
+        diagnosticData->diagnosticId != NULL && diagnosticData->diagnosticCreationTimeUtc != NULL)
+    {
+        // Codes_SRS_UAMQP_MESSAGING_32_001: [If optional diagnostic properties are present in the iot hub message, encode them into the AMQP message as annotation properties. Errors stop processing on this message.]
+        if ((message_annotations_map = amqpvalue_create_map()) == NULL)
+        {
+            LogError("Failed amqpvalue_create_map for annotations");
+            result = __FAILURE__;
+        }
+        else
+        {
+            char* diagContextBuffer = NULL;
+
+            if (add_map_item(message_annotations_map, AMQP_DIAGNOSTIC_ID_KEY, diagnosticData->diagnosticId) != RESULT_OK)
+            {
+                LogError("Failed adding diagnostic id");
+                result = __FAILURE__;
+            }
+            else if ((diagContextBuffer = (char*)malloc(strlen(AMQP_DIAGNOSTIC_CREATION_TIME_UTC_KEY) + 1
+                + strlen(diagnosticData->diagnosticCreationTimeUtc) + 1)) == NULL)
+            {
+                LogError("Failed malloc for diagnostic context");
+                result = __FAILURE__;
+            }
+            else if (sprintf(diagContextBuffer, "%s=%s", AMQP_DIAGNOSTIC_CREATION_TIME_UTC_KEY, diagnosticData->diagnosticCreationTimeUtc) < 0)
+            {
+                LogError("Failed sprintf diagnostic context");
+                result = __FAILURE__;
+            }
+            else if (add_map_item(message_annotations_map, AMQP_DIAGNOSTIC_CONTEXT_KEY, diagContextBuffer) != RESULT_OK)
+            {
+                LogError("Failed adding diagnostic context");
+                result = __FAILURE__;
+            }
+            else if((*message_annotations = amqpvalue_create_message_annotations(message_annotations_map)) == NULL)
+            {
+                LogError("Failed creating message annotations");
+                result = __FAILURE__;
+            }
+            else if (amqpvalue_get_encoded_size(*message_annotations, message_annotations_length) != 0)
+            {
+                LogError("Failed getting size of annotations");
+                result = __FAILURE__;
+            }
+            else
+            {
+                result = RESULT_OK;
+            }
+
+            free(diagContextBuffer);
+            amqpvalue_destroy(message_annotations_map);
+        }
+    }
+    else
+    {
+        // Codes_SRS_UAMQP_MESSAGING_32_002: [If optional diagnostic properties are not present in the iot hub message, no error should happen.]
+        result = RESULT_OK;
+    }
+    
+    return result;
+}
 
 // Codes_SRS_UAMQP_MESSAGING_31_118: [Gets data associated with IOTHUB_MESSAGE_HANDLE to encode, either from underlying byte array or string format.]
 static int create_data_to_encode(IOTHUB_MESSAGE_HANDLE messageHandle, AMQP_VALUE *data_value, size_t *data_length)
@@ -373,9 +489,11 @@
 
     AMQP_VALUE message_properties = NULL;
     AMQP_VALUE application_properties = NULL;
+    AMQP_VALUE message_annotations = NULL;
     AMQP_VALUE data_value = NULL;
     size_t message_properties_length = 0;
     size_t application_properties_length = 0;
+    size_t message_annotations_length = 0;
     size_t data_length = 0;
 
     body_binary_data->bytes = NULL;
@@ -391,14 +509,19 @@
         LogError("create_application_properties_to_encode() failed");
         result = __FAILURE__;
     }
+    else if (create_message_annotations_to_encode(message_handle, &message_annotations, &message_annotations_length) != RESULT_OK)
+    {
+        LogError("create_message_annotations_to_encode() failed");
+        result = __FAILURE__;
+    }
     else if (create_data_to_encode(message_handle, &data_value, &data_length) != RESULT_OK)
     {
         LogError("create_data_to_encode() failed");
         result = __FAILURE__;
     }
-    else if ((body_binary_data->bytes = malloc(message_properties_length + application_properties_length + data_length)) == NULL)
+    else if ((body_binary_data->bytes = malloc(message_properties_length + application_properties_length + data_length + message_annotations_length)) == NULL)
     {
-        LogError("malloc of %d bytes failed", message_properties_length + application_properties_length + data_length);
+        LogError("malloc of %d bytes failed", message_properties_length + application_properties_length + data_length + message_annotations_length);
         result = __FAILURE__;
     }
     // Codes_SRS_UAMQP_MESSAGING_31_119: [Invoke underlying AMQP encode routines on data waiting to be encoded.]
@@ -412,6 +535,11 @@
         LogError("amqpvalue_encode() for application properties failed");
         result = __FAILURE__;
     }
+    else if (message_annotations_length > 0 && amqpvalue_encode(message_annotations, &encode_callback, body_binary_data) != RESULT_OK)
+    {
+        LogError("amqpvalue_encode() for message annotations failed");
+        result = __FAILURE__;
+    }
     else if (RESULT_OK != amqpvalue_encode(data_value, &encode_callback, body_binary_data))
     {
         LogError("amqpvalue_encode() for data value failed");
@@ -419,7 +547,7 @@
     }
     else
     {
-        body_binary_data->length = message_properties_length + application_properties_length + data_length;
+        body_binary_data->length = message_properties_length + application_properties_length + data_length + message_annotations_length;
         result = RESULT_OK;
     }
 
@@ -433,6 +561,11 @@
         amqpvalue_destroy(application_properties);
     }
 
+    if (NULL != message_annotations)
+    {
+        amqpvalue_destroy(message_annotations);
+    }
+
     if (NULL != message_properties)
     {
         amqpvalue_destroy(message_properties);
@@ -441,11 +574,255 @@
     return result;
 }
 
+static int readMessageIdFromuAQMPMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, PROPERTIES_HANDLE uamqp_message_properties)
+{
+    int result;
+    AMQP_VALUE uamqp_message_property;
+
+    // Codes_SRS_UAMQP_MESSAGING_09_010: [The message-id property shall be read from the uAMQP message by calling properties_get_message_id.]
+    if (properties_get_message_id(uamqp_message_properties, &uamqp_message_property) != 0 || uamqp_message_property == NULL)
+    {
+        // Codes_SRS_UAMQP_MESSAGING_09_011: [If the uAMQP message does not contain property `message ID`, it shall be skipped as it is optional.]
+        result = RESULT_OK;
+    }
+    else
+    {
+        // Codes_SRS_UAMQP_MESSAGING_09_012: [The type of the message-id property value shall be obtained using amqpvalue_get_type().]
+        AMQP_TYPE value_type = amqpvalue_get_type(uamqp_message_property);
+
+        // Codes_SRS_UAMQP_MESSAGING_09_013: [If the type of the message-id property value is AMQP_TYPE_NULL, message_create_IoTHubMessage_from_uamqp_message() shall skip processing the message-id (as it is optional) and continue normally.]
+        if (value_type != AMQP_TYPE_NULL)
+        {
+
+            char* string_value;
+            char string_buffer[MESSAGE_ID_MAX_SIZE];
+            bool free_string_value = false;
+            
+            memset(string_buffer, 0, MESSAGE_ID_MAX_SIZE);
+
+            if (value_type == AMQP_TYPE_STRING)
+            {
+                // Codes_SRS_UAMQP_MESSAGING_09_014: [The message-id value shall be retrieved from the AMQP_VALUE as char sequence] 
+                if (amqpvalue_get_string(uamqp_message_property, (const char**)(&string_value)) != 0)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get value of uAMQP message 'message-id' property (string)");
+                    string_value = NULL;
+                }
+            }
+            else if (value_type == AMQP_TYPE_ULONG)
+            {
+                uint64_t ulong_value;
+
+                // Codes_SRS_UAMQP_MESSAGING_09_014: [The message-id value shall be retrieved from the AMQP_VALUE as char sequence] 
+                if (amqpvalue_get_ulong(uamqp_message_property, &ulong_value) != 0)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get value of uAMQP message 'message-id' property (ulong)");
+                    string_value = NULL;
+                }
+                else if (sprintf(string_buffer, "%" PRIu64, ulong_value) < 0)
+                {
+                    LogError("Failed converting 'message-id' (ulong) to string");
+                    string_value = NULL;
+                }
+                else
+                {
+                    string_value = string_buffer;
+                }
+            }
+            else if (value_type == AMQP_TYPE_UUID)
+            {
+                uuid uuid_value;
+
+                // Codes_SRS_UAMQP_MESSAGING_09_014: [The message-id value shall be retrieved from the AMQP_VALUE as char sequence] 
+                if (amqpvalue_get_uuid(uamqp_message_property, &uuid_value) != 0)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get value of uAMQP message 'message-id' property (UUID)");
+                    string_value = NULL;
+                }
+                else if ((string_value = UUID_to_string((UUID*)uuid_value)) == NULL)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get the string representation of 'message-id' UUID");
+                    string_value = NULL;
+                }
+                else
+                {
+                    free_string_value = true;
+                }
+            }
+            else
+            {
+                LogError("Unrecognized type for message-id (%d)", value_type);
+                string_value = NULL;
+            }
+
+            if (string_value != NULL)
+            {
+                // Codes_SRS_UAMQP_MESSAGING_09_016: [The message-id property shall be set on the IOTHUB_MESSAGE_HANDLE instance by calling IoTHubMessage_SetMessageId(), passing the value read from the uAMQP message.] 
+                if (IoTHubMessage_SetMessageId(iothub_message_handle, string_value) != IOTHUB_MESSAGE_OK)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_017: [If IoTHubMessage_SetMessageId fails, IoTHubMessage_CreateFromuAMQPMessage() shall fail and return immediately.] 
+                    LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'message-id' property.");
+                    result = __FAILURE__;
+                }
+                else
+                {
+                    result = RESULT_OK;
+                }
+
+                if (free_string_value)
+                {
+                    // Only certain code paths allocate this.
+                    free(string_value);
+                }
+            }
+            else
+            {
+                LogError("Unexpected null string for message-id");
+                result = __FAILURE__;
+            }
+        }
+        else
+        {
+            result = RESULT_OK;
+        }
+    }
+
+    return result;
+}
+
+static int readCorrelationIdFromuAQMPMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, PROPERTIES_HANDLE uamqp_message_properties)
+{
+    int result;
+    AMQP_VALUE uamqp_message_property;
+
+    // Codes_SRS_UAMQP_MESSAGING_09_018: [The correlation-id property shall be read from the uAMQP message by calling properties_get_correlation_id.]
+    if (properties_get_correlation_id(uamqp_message_properties, &uamqp_message_property) != 0 || uamqp_message_property == NULL)
+    {
+        // Codes_SRS_UAMQP_MESSAGING_09_019: [If the uAMQP message does not contain property `correlation ID`, it shall be skipped as it is optional.]
+        result = RESULT_OK;
+    }
+    else
+    {
+        // Codes_SRS_UAMQP_MESSAGING_09_020: [The type of the correlation-id property value shall be obtained using amqpvalue_get_type().]
+        AMQP_TYPE value_type = amqpvalue_get_type(uamqp_message_property);
+
+        // Codes_SRS_UAMQP_MESSAGING_09_021: [If the type of the correlation-id property value is AMQP_TYPE_NULL, IoTHubMessage_CreateFromuAMQPMessage() shall skip processing the correlation-id (as it is optional) and continue normally.] 
+        if (value_type != AMQP_TYPE_NULL)
+        {
+            char* string_value;
+            char string_buffer[MESSAGE_ID_MAX_SIZE];
+            bool free_string_value = false;
+            
+            memset(string_buffer, 0, MESSAGE_ID_MAX_SIZE);
+
+            if (value_type == AMQP_TYPE_STRING)
+            {
+                // Codes_SRS_UAMQP_MESSAGING_09_022: [The correlation-id value shall be retrieved from the AMQP_VALUE as char sequence] 
+                if (amqpvalue_get_string(uamqp_message_property, (const char**)(&string_value)) != 0)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get value of uAMQP message 'correlation-id' property (string)");
+                    string_value = NULL;
+                    result = __FAILURE__;
+                }
+            }
+            else if (value_type == AMQP_TYPE_ULONG)
+            {
+                uint64_t ulong_value;
+
+                // Codes_SRS_UAMQP_MESSAGING_09_022: [The correlation-id value shall be retrieved from the AMQP_VALUE as char sequence] 
+                if (amqpvalue_get_ulong(uamqp_message_property, &ulong_value) != 0)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get value of uAMQP message 'correlation-id' property (ulong)");
+                    string_value = NULL;
+                    result = __FAILURE__;
+                }
+                else if (sprintf(string_buffer, "%" PRIu64, ulong_value) < 0)
+                {
+                    LogError("Failed converting 'correlation-id' (ulong) to string");
+                    string_value = NULL;
+                    result = __FAILURE__;
+                }
+                else
+                {
+                    string_value = string_buffer;
+                }
+            }
+            else if (value_type == AMQP_TYPE_UUID)
+            {
+                uuid uuid_value;
+
+                // Codes_SRS_UAMQP_MESSAGING_09_022: [The correlation-id value shall be retrieved from the AMQP_VALUE as char sequence] 
+                if (amqpvalue_get_uuid(uamqp_message_property, &uuid_value) != 0)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get value of uAMQP message 'correlation-id' property (UUID)");
+                    string_value = NULL;
+                    result = __FAILURE__;
+                }
+                else if ((string_value = UUID_to_string((UUID*)uuid_value)) == NULL)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
+                    LogError("Failed to get the string representation of 'correlation-id' UUID");
+                    string_value = NULL;
+                    result = __FAILURE__;
+                }
+                else
+                {
+                    free_string_value = true;
+                }
+            }
+            else
+            {
+                LogError("Unrecognized type for correlation-id (%d)", value_type);
+                string_value = NULL;
+                result = __FAILURE__;
+            }
+
+            if (string_value != NULL)
+            {
+                // Codes_SRS_UAMQP_MESSAGING_09_024: [The correlation-id property shall be set on the IOTHUB_MESSAGE_HANDLE by calling IoTHubMessage_SetCorrelationId, passing the value read from the uAMQP message.] 
+                if (IoTHubMessage_SetCorrelationId(iothub_message_handle, string_value) != IOTHUB_MESSAGE_OK)
+                {
+                    // Codes_SRS_UAMQP_MESSAGING_09_025: [If IoTHubMessage_SetCorrelationId fails, IoTHubMessage_CreateFromuAMQPMessage() shall fail and return immediately.] 
+                    LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'correlation-id' property.");
+                    result = __FAILURE__;
+                }
+                else
+                {
+                    result = RESULT_OK;
+                }
+
+                if (free_string_value)
+                {
+                    // Only certain code paths allocate this.
+                    free(string_value);
+                }
+            }
+            else
+            {
+                LogError("Unexpected null string for correlation-id");
+                result = __FAILURE__;
+            }
+        }
+        else
+        {
+            result = RESULT_OK;
+        }
+    }
+
+    return result;
+}
+
 static int readPropertiesFromuAMQPMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, MESSAGE_HANDLE uamqp_message)
 {
     int result;
     PROPERTIES_HANDLE uamqp_message_properties;
-    AMQP_VALUE uamqp_message_property;
 
     // Codes_SRS_UAMQP_MESSAGING_09_008: [The uAMQP message properties shall be retrieved using message_get_properties().]
     if (message_get_properties(uamqp_message, &uamqp_message_properties) != 0)
@@ -458,200 +835,44 @@
     {
         result = RESULT_OK; // Properties 'message-id' and 'correlation-id' are optional according to the AMQP 1.0 spec.
 
-        // Codes_SRS_UAMQP_MESSAGING_09_010: [The message-id property shall be read from the uAMQP message by calling properties_get_message_id.]
-        if (properties_get_message_id(uamqp_message_properties, &uamqp_message_property) != 0 || uamqp_message_property == NULL)
+        if (readMessageIdFromuAQMPMessage(iothub_message_handle, uamqp_message_properties) != RESULT_OK)
         {
-            // Codes_SRS_UAMQP_MESSAGING_09_011: [If properties_get_message_id fails, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.]
+            LogError("Failed readMessageIdFromuAQMPMessage.");
+            result = __FAILURE__;            
+        }
+        else if (readCorrelationIdFromuAQMPMessage(iothub_message_handle, uamqp_message_properties) != RESULT_OK)
+        {
+            LogError("Failed readPropertiesFromuAMQPMessage.");
+            result = __FAILURE__;
         }
         else
         {
-            // Codes_SRS_UAMQP_MESSAGING_09_012: [The type of the message-id property value shall be obtained using amqpvalue_get_type().]
-            AMQP_TYPE value_type = amqpvalue_get_type(uamqp_message_property);
-
-            // Codes_SRS_UAMQP_MESSAGING_09_013: [If the type of the message-id property value is AMQP_TYPE_NULL, message_create_IoTHubMessage_from_uamqp_message() shall skip processing the message-id (as it is optional) and continue normally.]
-            if (value_type != AMQP_TYPE_NULL)
-            {
-
-                char* string_value;
-                char string_buffer[MESSAGE_ID_MAX_SIZE];
-			    
-                memset(string_buffer, 0, MESSAGE_ID_MAX_SIZE);
-
-                if (value_type == AMQP_TYPE_STRING)
-                {
-                    // Codes_SRS_UAMQP_MESSAGING_09_014: [The message-id value shall be retrieved from the AMQP_VALUE as char sequence] 
-                    if (amqpvalue_get_string(uamqp_message_property, (const char**)(&string_value)) != 0)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get value of uAMQP message 'message-id' property (string)");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                }
-                else if (value_type == AMQP_TYPE_ULONG)
-                {
-                    uint64_t ulong_value;
+            const char* uamqp_message_property_value = NULL;
 
-                    // Codes_SRS_UAMQP_MESSAGING_09_014: [The message-id value shall be retrieved from the AMQP_VALUE as char sequence] 
-                    if (amqpvalue_get_ulong(uamqp_message_property, &ulong_value) != 0)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get value of uAMQP message 'message-id' property (ulong)");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else if (sprintf(string_buffer, "%" PRIu64, ulong_value) < 0)
-                    {
-                        LogError("Failed converting 'message-id' (ulong) to string");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else
-                    {
-                        string_value = string_buffer;
-                    }
-                }
-                else if (value_type == AMQP_TYPE_UUID)
+            // Codes_SRS_UAMQP_MESSAGING_09_100: [If the uAMQP message contains property `content-type`, it shall be set on IOTHUB_MESSAGE_HANDLE]
+            // Codes_SRS_UAMQP_MESSAGING_31_122: [If the uAMQP message does not contain property `content-type`, it shall be skipped as it is optional]
+            if (properties_get_content_type(uamqp_message_properties, &uamqp_message_property_value) == 0 && uamqp_message_property_value != NULL)
+            {
+                if (IoTHubMessage_SetContentTypeSystemProperty(iothub_message_handle, uamqp_message_property_value) != IOTHUB_MESSAGE_OK)
                 {
-                    uuid uuid_value;
-
-                    // Codes_SRS_UAMQP_MESSAGING_09_014: [The message-id value shall be retrieved from the AMQP_VALUE as char sequence] 
-                    if (amqpvalue_get_uuid(uamqp_message_property, &uuid_value) != 0)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get value of uAMQP message 'message-id' property (UUID)");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else if ((string_value = UUID_to_string((UUID*)uuid_value)) == NULL)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_015: [If message-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get the string representation of 'message-id' UUID");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else
-                    {
-                        (void)memcpy(string_buffer, string_value, sizeof(char) * strlen(string_value));
-                        free(string_value);
-                        string_value = string_buffer;
-                    }
-                }
-                else
-                {
-                    LogError("Unrecognized type for message-id (%d)", value_type);
-                    string_value = NULL;
+                    // Codes_SRS_UAMQP_MESSAGING_09_102: [If setting the `content-type` property on IOTHUB_MESSAGE_HANDLE fails, readPropertiesFromuAMQPMessage() shall fail and return immediately.]
+                    LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'content-type' property.");
                     result = __FAILURE__;
                 }
-
-                if (string_value != NULL)
-                {
-                    // Codes_SRS_UAMQP_MESSAGING_09_016: [The message-id property shall be set on the IOTHUB_MESSAGE_HANDLE instance by calling IoTHubMessage_SetMessageId(), passing the value read from the uAMQP message.] 
-                    if (IoTHubMessage_SetMessageId(iothub_message_handle, string_value) != IOTHUB_MESSAGE_OK)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_017: [If IoTHubMessage_SetMessageId fails, IoTHubMessage_CreateFromuAMQPMessage() shall fail and return immediately.] 
-                        LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'message-id' property.");
-                        result = __FAILURE__;
-                    }
-                }
             }
-        }
-
-        // Codes_SRS_UAMQP_MESSAGING_09_018: [The correlation-id property shall be read from the uAMQP message by calling properties_get_correlation_id.]
-        if (properties_get_correlation_id(uamqp_message_properties, &uamqp_message_property) != 0 || uamqp_message_property == NULL)
-        {
-            // Codes_SRS_UAMQP_MESSAGING_09_019: [If properties_get_correlation_id() fails, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.]
-        }
-        else
-        {
-            // Codes_SRS_UAMQP_MESSAGING_09_020: [The type of the correlation-id property value shall be obtained using amqpvalue_get_type().]
-            AMQP_TYPE value_type = amqpvalue_get_type(uamqp_message_property);
-
-            // Codes_SRS_UAMQP_MESSAGING_09_021: [If the type of the correlation-id property value is AMQP_TYPE_NULL, IoTHubMessage_CreateFromuAMQPMessage() shall skip processing the correlation-id (as it is optional) and continue normally.] 
-            if (value_type != AMQP_TYPE_NULL)
-            {
-                char* string_value;
-                char string_buffer[MESSAGE_ID_MAX_SIZE];
-				
-                memset(string_buffer, 0, MESSAGE_ID_MAX_SIZE);
-
-                if (value_type == AMQP_TYPE_STRING)
-                {
-                    // Codes_SRS_UAMQP_MESSAGING_09_022: [The correlation-id value shall be retrieved from the AMQP_VALUE as char sequence] 
-                    if (amqpvalue_get_string(uamqp_message_property, (const char**)(&string_value)) != 0)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get value of uAMQP message 'correlation-id' property (string)");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                }
-                else if (value_type == AMQP_TYPE_ULONG)
-                {
-                    uint64_t ulong_value;
+            
+            uamqp_message_property_value = NULL;
 
-                    // Codes_SRS_UAMQP_MESSAGING_09_022: [The correlation-id value shall be retrieved from the AMQP_VALUE as char sequence] 
-                    if (amqpvalue_get_ulong(uamqp_message_property, &ulong_value) != 0)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get value of uAMQP message 'correlation-id' property (ulong)");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else if (sprintf(string_buffer, "%" PRIu64, ulong_value) < 0)
-                    {
-                        LogError("Failed converting 'correlation-id' (ulong) to string");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else
-                    {
-                        string_value = string_buffer;
-                    }
-                }
-                else if (value_type == AMQP_TYPE_UUID)
+            // Codes_SRS_UAMQP_MESSAGING_09_103: [If the uAMQP message contains property `content-encoding`, it shall be set on IOTHUB_MESSAGE_HANDLE]
+            // Codes_SRS_UAMQP_MESSAGING_31_123: [If the uAMQP message does not contain property `content-encoding`, it shall be skipped as it is optional]
+            if (properties_get_content_encoding(uamqp_message_properties, &uamqp_message_property_value) == 0 && uamqp_message_property_value != NULL)
+            {
+                if (IoTHubMessage_SetContentEncodingSystemProperty(iothub_message_handle, uamqp_message_property_value) != IOTHUB_MESSAGE_OK)
                 {
-                    uuid uuid_value;
-
-                    // Codes_SRS_UAMQP_MESSAGING_09_022: [The correlation-id value shall be retrieved from the AMQP_VALUE as char sequence] 
-                    if (amqpvalue_get_uuid(uamqp_message_property, &uuid_value) != 0)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get value of uAMQP message 'correlation-id' property (UUID)");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else if ((string_value = UUID_to_string((UUID*)uuid_value)) == NULL)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_023: [If correlation-id fails to be obtained, message_create_IoTHubMessage_from_uamqp_message() shall fail and return immediately.] 
-                        LogError("Failed to get the string representation of 'correlation-id' UUID");
-                        string_value = NULL;
-                        result = __FAILURE__;
-                    }
-                    else
-                    {
-                        (void)memcpy(string_buffer, string_value, sizeof(char) * strlen(string_value));
-                        free(string_value);
-                        string_value = string_buffer;
-                    }
-                }
-                else
-                {
-                    LogError("Unrecognized type for correlation-id (%d)", value_type);
-                    string_value = NULL;
+                    // Codes_SRS_UAMQP_MESSAGING_09_105: [If setting the `content-encoding` property on IOTHUB_MESSAGE_HANDLE fails, readPropertiesFromuAMQPMessage() shall fail and return immediately.]
+                    LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'content-encoding' property.");
                     result = __FAILURE__;
                 }
-
-                if (string_value != NULL)
-                {
-                    // Codes_SRS_UAMQP_MESSAGING_09_024: [The correlation-id property shall be set on the IOTHUB_MESSAGE_HANDLE by calling IoTHubMessage_SetCorrelationId, passing the value read from the uAMQP message.] 
-                    if (IoTHubMessage_SetCorrelationId(iothub_message_handle, string_value) != IOTHUB_MESSAGE_OK)
-                    {
-                        // Codes_SRS_UAMQP_MESSAGING_09_025: [If IoTHubMessage_SetCorrelationId fails, IoTHubMessage_CreateFromuAMQPMessage() shall fail and return immediately.] 
-                        LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'correlation-id' property.");
-                        result = __FAILURE__;
-                    }
-                }
             }
         }