A small footprint MQTT library

Dependents:   STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more

Revision:
18:6d13ad04e8a0
Parent:
17:73ae81ce481d
Child:
19:e283dcf26037
--- a/mqtt_client.c	Fri Jul 14 16:38:15 2017 -0700
+++ b/mqtt_client.c	Fri Aug 11 14:02:56 2017 -0700
@@ -250,7 +250,7 @@
     }
 }
 
-static void logOutgoingingRawTrace(MQTT_CLIENT* mqtt_client, const uint8_t* data, size_t length)
+static void logOutgoingRawTrace(MQTT_CLIENT* mqtt_client, const uint8_t* data, size_t length)
 {
     if (mqtt_client != NULL && data != NULL && length > 0 && mqtt_client->rawBytesTrace)
     {
@@ -325,7 +325,7 @@
         }
         else
         {
-            logOutgoingingRawTrace(mqtt_client, (const uint8_t*)data, length);
+            logOutgoingRawTrace(mqtt_client, (const uint8_t*)data, length);
         }
     }
     return result;
@@ -416,60 +416,135 @@
 
 static void clear_mqtt_options(MQTT_CLIENT* mqtt_client)
 {
-    free(mqtt_client->mqttOptions.clientId);
-    mqtt_client->mqttOptions.clientId = NULL;
-    free(mqtt_client->mqttOptions.willTopic);
-    mqtt_client->mqttOptions.willTopic = NULL;
-    free(mqtt_client->mqttOptions.willMessage);
-    mqtt_client->mqttOptions.willMessage = NULL;
-    free(mqtt_client->mqttOptions.username);
-    mqtt_client->mqttOptions.username = NULL;
-    free(mqtt_client->mqttOptions.password);
-    mqtt_client->mqttOptions.password = NULL;
+    if (mqtt_client->mqttOptions.clientId != NULL)
+    {
+        free(mqtt_client->mqttOptions.clientId);
+        mqtt_client->mqttOptions.clientId = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.willTopic != NULL)
+    {
+        free(mqtt_client->mqttOptions.willTopic);
+        mqtt_client->mqttOptions.willTopic = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.willMessage != NULL)
+    {
+        free(mqtt_client->mqttOptions.willMessage);
+        mqtt_client->mqttOptions.willMessage = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.username != NULL)
+    {
+        free(mqtt_client->mqttOptions.username);
+        mqtt_client->mqttOptions.username = NULL;
+    }
+
+    if (mqtt_client->mqttOptions.password != NULL)
+    {
+        free(mqtt_client->mqttOptions.password);
+        mqtt_client->mqttOptions.password = NULL;
+    }
 }
 
 static int cloneMqttOptions(MQTT_CLIENT* mqtt_client, const MQTT_CLIENT_OPTIONS* mqttOptions)
 {
     int result = 0;
+
     if (mqttOptions->clientId != NULL)
     {
-        if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.clientId, mqttOptions->clientId) != 0)
+        char* clientId;
+
+        if (mallocAndStrcpy_s(&clientId, mqttOptions->clientId) != 0)
         {
             result = __FAILURE__;
             LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s clientId");
         }
+        else
+        {
+            if (mqtt_client->mqttOptions.clientId != NULL)
+            {
+                free(mqtt_client->mqttOptions.clientId);
+            }
+
+            mqtt_client->mqttOptions.clientId = clientId;
+        }
     }
     if (result == 0 && mqttOptions->willTopic != NULL)
     {
-        if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.willTopic, mqttOptions->willTopic) != 0)
+        char* willTopic;
+
+        if (mallocAndStrcpy_s(&willTopic, mqttOptions->willTopic) != 0)
         {
             result = __FAILURE__;
             LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s willTopic");
         }
+        else
+        {
+            if (mqtt_client->mqttOptions.willTopic != NULL)
+            {
+                free(mqtt_client->mqttOptions.willTopic);
+            }
+
+            mqtt_client->mqttOptions.willTopic = willTopic;
+        }
     }
     if (result == 0 && mqttOptions->willMessage != NULL)
     {
-        if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.willMessage, mqttOptions->willMessage) != 0)
+        char* willMessage;
+
+        if (mallocAndStrcpy_s(&willMessage, mqttOptions->willMessage) != 0)
         {
             LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s willMessage");
             result = __FAILURE__;
         }
+        else
+        {
+            if (mqtt_client->mqttOptions.willMessage != NULL)
+            {
+                free(mqtt_client->mqttOptions.willMessage);
+            }
+
+            mqtt_client->mqttOptions.willMessage = willMessage;
+        }
     }
     if (result == 0 && mqttOptions->username != NULL)
     {
-        if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.username, mqttOptions->username) != 0)
+        char* username;
+
+        if (mallocAndStrcpy_s(&username, mqttOptions->username) != 0)
         {
             LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s username");
             result = __FAILURE__;
         }
+        else
+        {
+            if (mqtt_client->mqttOptions.username != NULL)
+            {
+                free(mqtt_client->mqttOptions.username);
+            }
+
+            mqtt_client->mqttOptions.username = username;
+        }
     }
     if (result == 0 && mqttOptions->password != NULL)
     {
-        if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.password, mqttOptions->password) != 0)
+        char* password;
+
+        if (mallocAndStrcpy_s(&password, mqttOptions->password) != 0)
         {
             LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s password");
             result = __FAILURE__;
         }
+        else
+        {
+            if (mqtt_client->mqttOptions.password != NULL)
+            {
+                free(mqtt_client->mqttOptions.password);
+            }
+
+            mqtt_client->mqttOptions.password = password;
+        }
     }
     if (result == 0)
     {
@@ -750,7 +825,6 @@
 
                         /*Codes_SRS_MQTT_CLIENT_07_031: [If the actionResult parameter is of type UNSUBACK_TYPE then the msgInfo value shall be a UNSUBSCRIBE_ACK structure.]*/
                         UNSUBSCRIBE_ACK unsuback = { 0 };
-                        iterator += VARIABLE_HEADER_OFFSET;
                         unsuback.packetId = byteutil_read_uint16(&iterator, len);
 
                         if (mqtt_client->logTrace)
@@ -765,13 +839,17 @@
                 }
                 case PINGRESP_TYPE:
                     mqtt_client->timeSincePing = 0;
-                    // Ping responses do not get forwarded
                     if (mqtt_client->logTrace)
                     {
                         STRING_HANDLE trace_log = STRING_construct_sprintf("PINGRESP");
                         log_incoming_trace(mqtt_client, trace_log);
                         STRING_delete(trace_log);
                     }
+                    // Forward ping response to operation callback 
+                    if (mqtt_client->fnOperationCallback)
+                    {
+                        mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_PING_RESPONSE, NULL, mqtt_client->ctx);
+                    }
                     break;
                 default:
                     break;
@@ -854,6 +932,7 @@
         MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
         tickcounter_destroy(mqtt_client->packetTickCntr);
         mqtt_codec_destroy(mqtt_client->codec_handle);
+        clear_mqtt_options(mqtt_client);
         free(mqtt_client);
     }
 }