Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mqtt_message.c Source File

mqtt_message.c

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
00003 
00004 #include <stdlib.h>
00005 #include "azure_umqtt_c/mqtt_message.h"
00006 #include "azure_c_shared_utility/optimize_size.h"
00007 #include "azure_c_shared_utility/gballoc.h"
00008 #include "azure_c_shared_utility/xlogging.h"
00009 
00010 typedef struct MQTT_MESSAGE_TAG
00011 {
00012     uint16_t packetId;
00013     QOS_VALUE qosInfo;
00014 
00015     char* topicName;
00016     APP_PAYLOAD appPayload;
00017 
00018     const char* const_topic_name;
00019     APP_PAYLOAD const_payload;
00020 
00021     bool isDuplicateMsg;
00022     bool isMessageRetained;
00023 } MQTT_MESSAGE;
00024 
00025 MQTT_MESSAGE_HANDLE mqttmessage_create_in_place(uint16_t packetId, const char* topicName, QOS_VALUE qosValue, const uint8_t* appMsg, size_t appMsgLength)
00026 {
00027     /* Codes_SRS_MQTTMESSAGE_07_026: [If the parameters topicName is NULL then mqttmessage_create_in_place shall return NULL.].] */
00028     MQTT_MESSAGE* result;
00029     if (topicName == NULL)
00030     {
00031         LogError("Invalid Parameter topicName: %p, packetId: %d.", topicName, packetId);
00032         result = NULL;
00033     }
00034     else
00035     {
00036         result = malloc(sizeof(MQTT_MESSAGE));
00037         if (result != NULL)
00038         {
00039             memset(result, 0, sizeof(MQTT_MESSAGE) );
00040             result->const_topic_name = topicName;
00041 
00042             result->packetId = packetId;
00043             result->isDuplicateMsg = false;
00044             result->isMessageRetained = false;
00045             result->qosInfo = qosValue;
00046 
00047             /* Codes_SRS_MQTTMESSAGE_07_027: [mqttmessage_create_in_place shall use the a pointer to topicName or appMsg .] */
00048             result->const_payload.length = appMsgLength;
00049             if (result->const_payload.length > 0)
00050             {
00051                 result->const_payload.message = (uint8_t*)appMsg;
00052             }
00053         }
00054         else
00055         {
00056             /* Codes_SRS_MQTTMESSAGE_07_028: [If any memory allocation fails mqttmessage_create_in_place shall free any allocated memory and return NULL.] */
00057             LogError("Failure unable to allocate MQTT Message.");
00058         }
00059     }
00060     /* Codes_SRS_MQTTMESSAGE_07_029: [ Upon success, mqttmessage_create_in_place shall return a NON-NULL MQTT_MESSAGE_HANDLE value.] */
00061     return (MQTT_MESSAGE_HANDLE)result;
00062 }
00063 
00064 MQTT_MESSAGE_HANDLE mqttmessage_create(uint16_t packetId, const char* topicName, QOS_VALUE qosValue, const uint8_t* appMsg, size_t appMsgLength)
00065 {
00066     /* Codes_SRS_MQTTMESSAGE_07_001:[If the parameters topicName is NULL is zero then mqttmessage_create shall return NULL.] */
00067     MQTT_MESSAGE* result;
00068     if (topicName == NULL)
00069     {
00070         LogError("Invalid Parameter topicName: %p, packetId: %d.", topicName, packetId);
00071         result = NULL;
00072     }
00073     else
00074     {
00075         /* Codes_SRS_MQTTMESSAGE_07_002: [mqttmessage_create shall allocate and copy the topicName and appMsg parameters.] */
00076         result = malloc(sizeof(MQTT_MESSAGE));
00077         if (result != NULL)
00078         {
00079             memset(result, 0, sizeof(MQTT_MESSAGE));
00080             if (mallocAndStrcpy_s(&result->topicName, topicName) != 0)
00081             {
00082                 /* Codes_SRS_MQTTMESSAGE_07_003: [If any memory allocation fails mqttmessage_create shall free any allocated memory and return NULL.] */
00083                 LogError("Failure allocating topic name");
00084                 free(result);
00085                 result = NULL;
00086             }
00087             else
00088             {
00089                 result->packetId = packetId;
00090                 result->isDuplicateMsg = false;
00091                 result->isMessageRetained = false;
00092                 result->qosInfo = qosValue;
00093 
00094                 /* Codes_SRS_MQTTMESSAGE_07_002: [mqttmessage_create shall allocate and copy the topicName and appMsg parameters.] */
00095                 result->appPayload.length = appMsgLength;
00096                 if (result->appPayload.length > 0)
00097                 {
00098                     result->appPayload.message = malloc(appMsgLength);
00099                     if (result->appPayload.message == NULL)
00100                     {
00101                         /* Codes_SRS_MQTTMESSAGE_07_003: [If any memory allocation fails mqttmessage_create shall free any allocated memory and return NULL.] */
00102                         LogError("Failure allocating message value of %uz", appMsgLength);
00103                         free(result->topicName);
00104                         free(result);
00105                         result = NULL;
00106                     }
00107                     else
00108                     {
00109                         (void)memcpy(result->appPayload.message, appMsg, appMsgLength);
00110                     }
00111                 }
00112                 else
00113                 {
00114                     result->appPayload.message = NULL;
00115                 }
00116             }
00117         }
00118     }
00119     /* Codes_SRS_MQTTMESSAGE_07_004: [If mqttmessage_createMessage succeeds the it shall return a NON-NULL MQTT_MESSAGE_HANDLE value.] */
00120     return (MQTT_MESSAGE_HANDLE)result;
00121 }
00122 
00123 void mqttmessage_destroy(MQTT_MESSAGE_HANDLE handle)
00124 {
00125     MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00126     /* Codes_SRS_MQTTMESSAGE_07_005: [If the handle parameter is NULL then mqttmessage_destroyMessage shall do nothing] */
00127     if (msgInfo != NULL)
00128     {
00129         /* Codes_SRS_MQTTMESSAGE_07_006: [mqttmessage_destroyMessage shall free all resources associated with the MQTT_MESSAGE_HANDLE value] */
00130         if (msgInfo->topicName != NULL)
00131         {
00132             free(msgInfo->topicName);
00133         }
00134         if (msgInfo->appPayload.message != NULL)
00135         {
00136             free(msgInfo->appPayload.message);
00137         }
00138         free(msgInfo);
00139     }
00140 }
00141 
00142 MQTT_MESSAGE_HANDLE mqttmessage_clone(MQTT_MESSAGE_HANDLE handle)
00143 {
00144     MQTT_MESSAGE_HANDLE result;
00145     if (handle == NULL)
00146     {
00147         /* Codes_SRS_MQTTMESSAGE_07_007: [If handle parameter is NULL then mqttmessage_clone shall return NULL.] */
00148         LogError("Invalid Parameter handle: %p.", handle);
00149         result = NULL;
00150     }
00151     else
00152     {
00153         /* Codes_SRS_MQTTMESSAGE_07_008: [mqttmessage_clone shall create a new MQTT_MESSAGE_HANDLE with data content identical of the handle value.] */
00154         MQTT_MESSAGE* mqtt_message = (MQTT_MESSAGE*)handle;
00155         result = mqttmessage_create(mqtt_message->packetId, mqtt_message->topicName, mqtt_message->qosInfo, mqtt_message->appPayload.message, mqtt_message->appPayload.length);
00156         if (result != NULL)
00157         {
00158             (void)mqttmessage_setIsDuplicateMsg(result, mqtt_message->isDuplicateMsg);
00159             (void)mqttmessage_setIsRetained(result, mqtt_message->isMessageRetained);
00160         }
00161     }
00162     return result;
00163 }
00164 
00165 uint16_t mqttmessage_getPacketId(MQTT_MESSAGE_HANDLE handle)
00166 {
00167     uint16_t result;
00168     if (handle == NULL)
00169     {
00170         /* Codes_SRS_MQTTMESSAGE_07_010: [If handle is NULL then mqttmessage_getPacketId shall return 0.] */
00171         LogError("Invalid Parameter handle: %p.", handle);
00172         result = 0;
00173     }
00174     else
00175     {
00176         /* Codes_SRS_MQTTMESSAGE_07_011: [mqttmessage_getPacketId shall return the packetId value contained in MQTT_MESSAGE_HANDLE handle.] */
00177         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00178         result = msgInfo->packetId;
00179     }
00180     return result;
00181 }
00182 
00183 const char* mqttmessage_getTopicName(MQTT_MESSAGE_HANDLE handle)
00184 {
00185     const char* result;
00186     if (handle == NULL)
00187     {
00188         /* Codes_SRS_MQTTMESSAGE_07_012: [If handle is NULL then mqttmessage_getTopicName shall return a NULL string.] */
00189         LogError("Invalid Parameter handle: %p.", handle);
00190         result = NULL;
00191     }
00192     else
00193     {
00194         /* Codes_SRS_MQTTMESSAGE_07_013: [mqttmessage_getTopicName shall return the topicName contained in MQTT_MESSAGE_HANDLE handle.] */
00195         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00196         if (msgInfo->topicName == NULL)
00197         {
00198             result = msgInfo->const_topic_name;
00199         }
00200         else
00201         {
00202             result = msgInfo->topicName;
00203         }
00204     }
00205     return result;
00206 }
00207 
00208 QOS_VALUE mqttmessage_getQosType(MQTT_MESSAGE_HANDLE handle)
00209 {
00210     QOS_VALUE result;
00211     if (handle == NULL)
00212     {
00213         /* Codes_SRS_MQTTMESSAGE_07_014: [If handle is NULL then mqttmessage_getQosType shall return the default DELIVER_AT_MOST_ONCE value.] */
00214         LogError("Invalid Parameter handle: %p.", handle);
00215         result = DELIVER_AT_MOST_ONCE;
00216     }
00217     else
00218     {
00219         /* Codes_SRS_MQTTMESSAGE_07_015: [mqttmessage_getQosType shall return the QOS Type value contained in MQTT_MESSAGE_HANDLE handle.] */
00220         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00221         result = msgInfo->qosInfo;
00222     }
00223     return result;
00224 }
00225 
00226 bool mqttmessage_getIsDuplicateMsg(MQTT_MESSAGE_HANDLE handle)
00227 {
00228     bool result;
00229     if (handle == NULL)
00230     {
00231         /* Codes_SRS_MQTTMESSAGE_07_016: [If handle is NULL then mqttmessage_getIsDuplicateMsg shall return false.] */
00232         LogError("Invalid Parameter handle: %p.", handle);
00233         result = false;
00234     }
00235     else
00236     {
00237         /* Codes_SRS_MQTTMESSAGE_07_017: [mqttmessage_getIsDuplicateMsg shall return the isDuplicateMsg value contained in MQTT_MESSAGE_HANDLE handle.] */
00238         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00239         result = msgInfo->isDuplicateMsg;
00240     }
00241     return result;
00242 }
00243 
00244 bool mqttmessage_getIsRetained(MQTT_MESSAGE_HANDLE handle)
00245 {
00246     bool result;
00247     if (handle == NULL)
00248     {
00249         /* Codes_SRS_MQTTMESSAGE_07_018: [If handle is NULL then mqttmessage_getIsRetained shall return false.] */
00250         LogError("Invalid Parameter handle: %p.", handle);
00251         result = false;
00252     }
00253     else
00254     {
00255         /* Codes_SRS_MQTTMESSAGE_07_019: [mqttmessage_getIsRetained shall return the isRetained value contained in MQTT_MESSAGE_HANDLE handle.] */
00256         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00257         result = msgInfo->isMessageRetained;
00258     }
00259     return result;
00260 }
00261 
00262 int mqttmessage_setIsDuplicateMsg(MQTT_MESSAGE_HANDLE handle, bool duplicateMsg)
00263 {
00264     int result;
00265     /* Codes_SRS_MQTTMESSAGE_07_022: [If handle is NULL then mqttmessage_setIsDuplicateMsg shall return a non-zero value.] */
00266     if (handle == NULL)
00267     {
00268         LogError("Invalid Parameter handle: %p.", handle);
00269         result = __FAILURE__;
00270     }
00271     else
00272     {
00273         /* Codes_SRS_MQTTMESSAGE_07_023: [mqttmessage_setIsDuplicateMsg shall store the duplicateMsg value in the MQTT_MESSAGE_HANDLE handle.] */
00274         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00275         msgInfo->isDuplicateMsg = duplicateMsg;
00276         result = 0;
00277     }
00278     return result;
00279 }
00280 
00281 int mqttmessage_setIsRetained(MQTT_MESSAGE_HANDLE handle, bool retainMsg)
00282 {
00283     int result;
00284     /* Codes_SRS_MQTTMESSAGE_07_024: [If handle is NULL then mqttmessage_setIsRetained shall return a non-zero value.] */
00285     if (handle == NULL)
00286     {
00287         LogError("Invalid Parameter handle: %p.", handle);
00288         result = __FAILURE__;
00289     }
00290     else
00291     {
00292         /* Codes_SRS_MQTTMESSAGE_07_025: [mqttmessage_setIsRetained shall store the retainMsg value in the MQTT_MESSAGE_HANDLE handle.] */
00293         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00294         msgInfo->isMessageRetained = retainMsg;
00295         result = 0;
00296     }
00297     return result;
00298 }
00299 
00300 const APP_PAYLOAD* mqttmessage_getApplicationMsg(MQTT_MESSAGE_HANDLE handle)
00301 {
00302     const APP_PAYLOAD* result;
00303     if (handle == NULL)
00304     {
00305         /* Codes_SRS_MQTTMESSAGE_07_020: [If handle is NULL or if msgLen is 0 then mqttmessage_getApplicationMsg shall return NULL.] */
00306         LogError("Invalid Parameter handle: %p.", handle);
00307         result = NULL;
00308     }
00309     else
00310     {
00311         /* Codes_SRS_MQTTMESSAGE_07_021: [mqttmessage_getApplicationMsg shall return the applicationMsg value contained in MQTT_MESSAGE_HANDLE handle and the length of the appMsg in the msgLen parameter.] */
00312         MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
00313         if (msgInfo->const_payload.length > 0)
00314         {
00315             result = &msgInfo->const_payload;
00316         }
00317         else
00318         {
00319             result = &msgInfo->appPayload;
00320         }
00321     }
00322     return result;
00323 }