static void DoTimeouts(IOTHUB_CLIENT_LL_HANDLE_DATA* handleData)
{
    uint64_t nowTick;
    if (tickcounter_get_current_ms(handleData->tickCounter, &nowTick) != 0)
    {
        LogError("unable to get the current ms, timeouts will not be processed");
    }
    else
    {
        DLIST_ENTRY* currentItemInWaitingToSend = handleData->waitingToSend.Flink;
        while (currentItemInWaitingToSend != &(handleData->waitingToSend)) /*while we are not at the end of the list*/
        {
            IOTHUB_MESSAGE_LIST* fullEntry = containingRecord(currentItemInWaitingToSend, IOTHUB_MESSAGE_LIST, entry);
            /*Codes_SRS_IOTHUBCLIENT_LL_02_041: [ If more than value miliseconds have passed since the call to IoTHubClient_LL_SendEventAsync then the message callback shall be called with a status code of IOTHUB_CLIENT_CONFIRMATION_TIMEOUT. ]*/
            if ((fullEntry->ms_timesOutAfter != 0) && (fullEntry->ms_timesOutAfter < nowTick))
            {
                PDLIST_ENTRY theNext = currentItemInWaitingToSend->Flink; /*need to save the next item, because the below operations are destructive*/
                DList_RemoveEntryList(currentItemInWaitingToSend);
                if (fullEntry->callback != NULL)
                {
                    fullEntry->callback(IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT, fullEntry->context);
                }
                IoTHubMessage_Destroy(fullEntry->messageHandle); /*because it has been cloned*/
                free(fullEntry);
                currentItemInWaitingToSend = theNext;
            }
            else
            {
                currentItemInWaitingToSend = currentItemInWaitingToSend->Flink;
            }
        }
    }
}
void IoTHubClient_LL_SendComplete(IOTHUB_CLIENT_LL_HANDLE handle, PDLIST_ENTRY completed, IOTHUB_BATCHSTATE_RESULT result)
{
    /*Codes_SRS_IOTHUBCLIENT_LL_02_022: [If parameter completed is NULL, or parameter handle is NULL then IoTHubClient_LL_SendBatch shall return.]*/
    if (
        (handle == NULL) ||
        (completed == NULL)
        )
    {
        /*"shall return"*/
        LogError("invalid arg");
    }
    else
    {
        /*Codes_SRS_IOTHUBCLIENT_LL_02_027: [If parameter result is IOTHUB_BACTHSTATE_FAILED then IoTHubClient_LL_SendComplete shall call all the non-NULL callbacks with the result parameter set to IOTHUB_CLIENT_CONFIRMATION_ERROR and the context set to the context passed originally in the SendEventAsync call.] */
        /*Codes_SRS_IOTHUBCLIENT_LL_02_025: [If parameter result is IOTHUB_BATCHSTATE_SUCCESS then IoTHubClient_LL_SendComplete shall call all the non-NULL callbacks with the result parameter set to IOTHUB_CLIENT_CONFIRMATION_OK and the context set to the context passed originally in the SendEventAsync call.]*/
        IOTHUB_CLIENT_CONFIRMATION_RESULT resultToBeCalled = (result == IOTHUB_BATCHSTATE_SUCCESS) ? IOTHUB_CLIENT_CONFIRMATION_OK : IOTHUB_CLIENT_CONFIRMATION_ERROR;
        PDLIST_ENTRY oldest;
        while ((oldest = DList_RemoveHeadList(completed)) != completed)
        {
            IOTHUB_MESSAGE_LIST* messageList = (IOTHUB_MESSAGE_LIST*)containingRecord(oldest, IOTHUB_MESSAGE_LIST, entry);
            /*Codes_SRS_IOTHUBCLIENT_LL_02_026: [If any callback is NULL then there shall not be a callback call.]*/
            if (messageList->callback != NULL)
            {
                messageList->callback(resultToBeCalled, messageList->context);
            }
            IoTHubMessage_Destroy(messageList->messageHandle);
            free(messageList);
        }
    }
}
void IoTHubTransportMqtt_Destroy(TRANSPORT_HANDLE handle)
{
    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_012: [IoTHubTransportMqtt_Destroy shall do nothing if parameter handle is NULL.] */
    PMQTTTRANSPORT_HANDLE_DATA transportState = (PMQTTTRANSPORT_HANDLE_DATA)handle;
    if (transportState != NULL)
    {
        transportState->destroyCalled = true;

        DisconnectFromClient(transportState);

        //Empty the Waiting for Ack Messages.
        while (!DList_IsListEmpty(&transportState->waitingForAck))
        {
            PDLIST_ENTRY currentEntry = DList_RemoveHeadList(&transportState->waitingForAck);
            MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = containingRecord(currentEntry, MQTT_MESSAGE_DETAILS_LIST, entry);
            sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transportState, IOTHUB_BATCHSTATE_FAILED);
            free(mqttMsgEntry);
        }

        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_014: [IoTHubTransportMqtt_Destroy shall free all the resources currently in use.] */
        mqtt_client_deinit(transportState->mqttClient);
        STRING_delete(transportState->mqttEventTopic);
        STRING_delete(transportState->mqttMessageTopic);
        STRING_delete(transportState->device_id);
        STRING_delete(transportState->device_key);
        STRING_delete(transportState->sasTokenSr);
        STRING_delete(transportState->hostAddress);
        STRING_delete(transportState->configPassedThroughUsername);
        tickcounter_destroy(g_msgTickCounter);
        free(transportState);
    }
}
void IoTHubClient_LL_Destroy(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
{
    /*Codes_SRS_IOTHUBCLIENT_LL_02_009: [IoTHubClient_LL_Destroy shall do nothing if parameter iotHubClientHandle is NULL.]*/
    if (iotHubClientHandle != NULL)
    {
        PDLIST_ENTRY unsend;
        /*Codes_SRS_IOTHUBCLIENT_LL_17_010: [IoTHubClient_LL_Destroy  shall call the underlaying layer's _Unregister function] */
        IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
        handleData->IoTHubTransport_Unregister(handleData->deviceHandle);
        if (handleData->isSharedTransport == false)
        {
            /*Codes_SRS_IOTHUBCLIENT_LL_02_010: [If iotHubClientHandle was not created by IoTHubClient_LL_CreateWithTransport, IoTHubClient_LL_Destroy  shall call the underlaying layer's _Destroy function.] */
            handleData->IoTHubTransport_Destroy(handleData->transportHandle);
        }
        /*if any, remove the items currently not send*/
        while ((unsend = DList_RemoveHeadList(&(handleData->waitingToSend))) != &(handleData->waitingToSend))
        {
            IOTHUB_MESSAGE_LIST* temp = containingRecord(unsend, IOTHUB_MESSAGE_LIST, entry);
            /*Codes_SRS_IOTHUBCLIENT_LL_02_033: [Otherwise, IoTHubClient_LL_Destroy shall complete all the event message callbacks that are in the waitingToSend list with the result IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY.] */
            if (temp->callback != NULL)
            {
                temp->callback(IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY, temp->context);
            }
            IoTHubMessage_Destroy(temp->messageHandle);
            free(temp);
        }
        /*Codes_SRS_IOTHUBCLIENT_LL_17_011: [IoTHubClient_LL_Destroy  shall free the resources allocated by IoTHubClient (if any).] */
        tickcounter_destroy(handleData->tickCounter);
        IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
        free(handleData);
    }
}
Esempio n. 5
0
static void delivered(void *context, MQTTClient_deliveryToken dt)
{
	PMQTTTAPI_HANDLE_DATA transportState = (PMQTTTAPI_HANDLE_DATA)context;

	if (context != NULL)
	{
		//First try to find the message on the list. 
		PDLIST_ENTRY currentListEntry;
		currentListEntry = transportState->messagesSent.Flink;

		if (currentListEntry != NULL)
		{
			while (currentListEntry != &transportState->messagesSent)
			{
				MQTTAPI_MESSAGE_SEND_LIST *mqttMessageDetailEntry = containingRecord(currentListEntry, MQTTAPI_MESSAGE_SEND_LIST, entry);

				//Identify here if the message is the one arrived. 
				if (mqttMessageDetailEntry->dt == dt)
				{
					(void)DList_RemoveEntryList(currentListEntry); //First remove the item from Waiting for Ack List.

					if (transportState->dcCallback != NULL)
					{
						/* Codes_SRS_MQTTAPI_04_009: [The context parameter is a point to the original value passed by MQTTAPI_PublishMessage, which contains message-specific context.] */
						/* Codes_SRS_MQTTAPI_04_052: [result contains the status of the message sent by publish.] */
						transportState->dcCallback(mqttMessageDetailEntry->context, MQTTAPI_CONFIRMATION_OK);
					}

					STRING_delete(mqttMessageDetailEntry->topicName);
					MQTTClient_freeMessage(&(mqttMessageDetailEntry->messageToSend));
					free(mqttMessageDetailEntry);
					break;
				}
				currentListEntry = currentListEntry->Flink;
			}
		}
		else
		{
			LogError("Error trying to access items on messagesSEnt list. Possible not initialized List.\r\n");
		}
	}
}
extern void IoTHubTransportMqtt_DoWork(TRANSPORT_HANDLE handle, IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
{
    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_026: [IoTHubTransportMqtt_DoWork shall do nothing if parameter handle and/or iotHubClientHandle is NULL.] */
    PMQTTTRANSPORT_HANDLE_DATA transportState = (PMQTTTRANSPORT_HANDLE_DATA)handle;
    if (transportState != NULL && iotHubClientHandle != NULL)
    {
        transportState->llClientHandle = iotHubClientHandle;

        if (InitializeConnection(transportState, true) != 0)
        {
            // Don't want to flood the logs with failures here
        }
        else
        {
            if (transportState->currPacketState == CONNACK_TYPE)
            {
                (void)SubscribeToMqttProtocol(transportState);
            }
            else if (transportState->currPacketState == SUBACK_TYPE)
            {
                // Publish can be called now
                transportState->currPacketState = PUBLISH_TYPE;
            }
            else if (transportState->currPacketState == PUBLISH_TYPE)
            {
                PDLIST_ENTRY currentListEntry = transportState->waitingForAck.Flink;
                while (currentListEntry != &transportState->waitingForAck)
                {
                    MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = containingRecord(currentListEntry, MQTT_MESSAGE_DETAILS_LIST, entry);
                    DLIST_ENTRY nextListEntry;
                    nextListEntry.Flink = currentListEntry->Flink;

                    uint64_t current_ms;
                    (void)tickcounter_get_current_ms(g_msgTickCounter, &current_ms);
                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_033: [IoTHubTransportMqtt_DoWork shall iterate through the Waiting Acknowledge messages looking for any message that has been waiting longer than 2 min.]*/
                    if (((current_ms - mqttMsgEntry->msgPublishTime) / 1000) > RESEND_TIMEOUT_VALUE_MIN)
                    {
                        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_034: [If IoTHubTransportMqtt_DoWork has resent the message two times then it shall fail the message] */
                        if (mqttMsgEntry->retryCount >= MAX_SEND_RECOUNT_LIMIT)
                        {
                            (void)DList_RemoveEntryList(currentListEntry);
                            sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transportState, IOTHUB_BATCHSTATE_FAILED);
                            free(mqttMsgEntry);
                        }
                        else
                        {
                            size_t messageLength;
                            const unsigned char* messagePayload = RetrieveMessagePayload(mqttMsgEntry->iotHubMessageEntry->messageHandle, &messageLength);
                            if (messageLength == 0 || messagePayload == NULL)
                            {
                                LogError("Failure from creating Message IoTHubMessage_GetData\r\n");
                            }
                            else
                            {
                                if (publishMqttMessage(transportState, mqttMsgEntry, messagePayload, messageLength) != 0)
                                {
                                    (void)DList_RemoveEntryList(currentListEntry);
                                    sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transportState, IOTHUB_BATCHSTATE_FAILED);
                                    free(mqttMsgEntry);
                                }
                            }
                        }
                    }
                    currentListEntry = nextListEntry.Flink;
                }

                currentListEntry = transportState->waitingToSend->Flink;
                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransportMqtt_DoWork shall inspect the “waitingToSend” DLIST passed in config structure.] */
                while (currentListEntry != transportState->waitingToSend)
                {
                    IOTHUB_MESSAGE_LIST* iothubMsgList = containingRecord(currentListEntry, IOTHUB_MESSAGE_LIST, entry);
                    DLIST_ENTRY savedFromCurrentListEntry;
                    savedFromCurrentListEntry.Flink = currentListEntry->Flink;

                    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransportMqtt_DoWork shall inspect the “waitingToSend” DLIST passed in config structure.] */
                    size_t messageLength;
                    const unsigned char* messagePayload = RetrieveMessagePayload(iothubMsgList->messageHandle, &messageLength);
                    if (messageLength == 0 || messagePayload == NULL)
                    {
                        LogError("Failure result from IoTHubMessage_GetData\r\n");
                    }
                    else
                    {
                        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_029: [IoTHubTransportMqtt_DoWork shall create a MQTT_MESSAGE_HANDLE and pass this to a call to mqtt_client_publish.] */
                        MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = (MQTT_MESSAGE_DETAILS_LIST*)malloc(sizeof(MQTT_MESSAGE_DETAILS_LIST));
                        if (mqttMsgEntry == NULL)
                        {
                            LogError("Allocation Error: Failure allocating MQTT Message Detail List.\r\n");
                        }
                        else
                        {
                            mqttMsgEntry->retryCount = 0;
                            mqttMsgEntry->msgPacketId = transportState->packetId;
                            mqttMsgEntry->iotHubMessageEntry = iothubMsgList;

                            if (publishMqttMessage(transportState, mqttMsgEntry, messagePayload, messageLength) != 0)
                            {
                                (void)(DList_RemoveEntryList(currentListEntry));
                                sendMsgComplete(iothubMsgList, transportState, IOTHUB_BATCHSTATE_FAILED);
                                free(mqttMsgEntry);
                            }
                            else
                            {
                                (void)(DList_RemoveEntryList(currentListEntry));
                                DList_InsertTailList(&(transportState->waitingForAck), &(mqttMsgEntry->entry));
                            }
                        }
                    }
                    currentListEntry = savedFromCurrentListEntry.Flink;
                }
            }
            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_030: [IoTHubTransportMqtt_DoWork shall call mqtt_client_dowork everytime it is called if it is connected.] */
            mqtt_client_dowork(transportState->mqttClient);
        }
    }
}
static void MqttOpCompleteCallback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_RESULT actionResult, const void* msgInfo, void* callbackCtx)
{
    (void)handle;
    if (callbackCtx != NULL)
    {
        PMQTTTRANSPORT_HANDLE_DATA transportData = (PMQTTTRANSPORT_HANDLE_DATA)callbackCtx;

        switch (actionResult)
        {
            case MQTT_CLIENT_ON_PUBLISH_ACK:
            case MQTT_CLIENT_ON_PUBLISH_COMP:
            {
                const PUBLISH_ACK* puback = (const PUBLISH_ACK*)msgInfo;
                if (puback != NULL)
                {
                    PDLIST_ENTRY currentListEntry = transportData->waitingForAck.Flink;
                    while (currentListEntry != &transportData->waitingForAck)
                    {
                        MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = containingRecord(currentListEntry, MQTT_MESSAGE_DETAILS_LIST, entry);
                        DLIST_ENTRY saveListEntry;
                        saveListEntry.Flink = currentListEntry->Flink;

                        if (puback->packetId == mqttMsgEntry->msgPacketId)
                        {
                            (void)DList_RemoveEntryList(currentListEntry); //First remove the item from Waiting for Ack List.
                            sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transportData, IOTHUB_BATCHSTATE_SUCCESS);
                            free(mqttMsgEntry);
                        }
                        currentListEntry = saveListEntry.Flink;
                    }
                }
                break;
            }
            case MQTT_CLIENT_ON_CONNACK:
            {
                const CONNECT_ACK* connack = (const CONNECT_ACK*)msgInfo;
                if (connack != NULL)
                {
                    if (connack->returnCode == CONNECTION_ACCEPTED)
                    {
                        // The connect packet has been acked
                        transportData->currPacketState = CONNACK_TYPE;
                    }
                    else
                    {
                        LogError("Connection not accepted, return code: %d.\r\n", connack->returnCode);
                        (void)mqtt_client_disconnect(transportData->mqttClient);
                        transportData->connected = false;
                        transportData->currPacketState = PACKET_TYPE_ERROR;
                    }
                }
                else
                {
                    LogError("MQTT_CLIENT_ON_CONNACK CONNACK parameter is NULL.\r\n");
                }
                break;
            }
            case MQTT_CLIENT_ON_SUBSCRIBE_ACK:
            {
                const SUBSCRIBE_ACK* suback = (const SUBSCRIBE_ACK*)msgInfo;
                if (suback != NULL)
                {
                    if (suback->qosCount == 1)
                    {
                        // The connect packet has been acked
                        transportData->currPacketState = SUBACK_TYPE;
                    }
                    else
                    {
                        LogError("QOS count was not expected: %d.\r\n", (int)suback->qosCount);
                    }
                }
                break;
            }
            case MQTT_CLIENT_ON_PUBLISH_RECV:
            case MQTT_CLIENT_ON_PUBLISH_REL:
            {
                // Currently not used
                break;
            }
            case MQTT_CLIENT_ON_DISCONNECT:
            {
                // Close the client so we can reconnect again
                transportData->connected = false;
                transportData->currPacketState = DISCONNECT_TYPE;
                break;
            }
            case MQTT_CLIENT_ON_ERROR:
            {
                xio_close(transportData->xioTransport, NULL, NULL);
                transportData->connected = false;
                transportData->currPacketState = PACKET_TYPE_ERROR;
            }
        }
    }
}
Esempio n. 8
0
void MQTTAPI_DoWork(MQTTAPI_HANDLE instance)
{
	PMQTTTAPI_HANDLE_DATA handle = instance;

	/* Codes_SRS_MQTTAPI_04_050: [if parameter instance is NULL then MQTTAPI_DoWork shall not perform any action.] */
	if (handle != NULL)
	{

		if (!checkAndTryToConnect(handle))
		{
			LogError("Client Not Connected and could not connect.\r\n");
		}
		else
		{
			if (Lock(handle->LockHandle) == LOCK_OK)
			{

				//message
				{
					PDLIST_ENTRY received;
					while ((received = DList_RemoveHeadList(&(handle->messagesReceived))) != &(handle->messagesReceived))
					{
						MQTTAPI_MESSAGE_RECEIVED_LIST* temp = containingRecord(received, MQTTAPI_MESSAGE_RECEIVED_LIST, entry);
						if (handle->maCallBack != NULL)
						{
							if (!handle->maCallBack(handle->maCallbackContext, temp->messageReceived))
							{
								LogError("Client could not handle message, dropping it.");
							}
						}

						free(temp->messageReceived->payload);
						free(temp->messageReceived);
						free(temp);
					}
				}
				Unlock(handle->LockHandle);
			}
			else
			{
				LogError("Could not aquire lock for message.\r\n");
			}

			//Event
			{
				PDLIST_ENTRY messageToSend;
				while ((messageToSend = DList_RemoveHeadList(&(handle->messagesToSend))) != &(handle->messagesToSend))
				{
					MQTTAPI_MESSAGE_SEND_LIST* temp = containingRecord(messageToSend, MQTTAPI_MESSAGE_SEND_LIST, entry);

					if (MQTTClient_publishMessage(handle->client, STRING_c_str(temp->topicName), temp->messageToSend, &(temp->dt)) != MQTTCLIENT_SUCCESS)
					{
						handle->dcCallback(temp->context, MQTTAPI_CONFIRMATION_ERROR);
						MQTTClient_freeMessage(&(temp->messageToSend));
						free(temp->messageToSend);
						STRING_delete(temp->topicName);
						free(temp);
					}
					else
					{
						DList_InsertTailList(&(handle->messagesSent), &(temp->entry));
					}
				}
			}
		}
	}
	
}
Esempio n. 9
0
void MQTTAPI_Destroy(MQTTAPI_HANDLE instance)
{
	PMQTTTAPI_HANDLE_DATA mqttHandleData = instance;

	/* Codes_SRS_MQTTAPI_04_021: [If parameter instance is NULL then MQTTAPI_Destroy shall take no action.] */
	if (mqttHandleData != NULL)
	{
		/* Codes_SRS_MQTTAPI_04_022: [MQTTAPI_Destroy shall free all resources used by MQTTAPI_HANDLE.]  */
		STRING_delete(mqttHandleData->device_id);
		STRING_delete(mqttHandleData->device_key);
		STRING_delete(mqttHandleData->sasTokenSr);
		/* Codes_SRS_MQTTAPI_04_049: [If the instance is connected, MQTTAPI_Destroy shall disconnect the instance] */
		if (mqttHandleData->subscribed)
		{
			MQTTAPI_Unsubscribe(mqttHandleData->subscribedTopicHandleData);
		}

		if (mqttHandleData->connected)
		{
			MQTTClient_disconnect(mqttHandleData->client, 0);
		}

		/* Codes_SRS_MQTTAPI_04_053: [If there are messages to be sent MQTTAPI_Destroy shall signalize the user that the message couldn’t be sent by reason of MQTTAPI_CONFIRMATION_BECAUSE_DESTROY]  */
		{
			PDLIST_ENTRY received;
			while ((received = DList_RemoveHeadList(&(mqttHandleData->messagesReceived))) != &(mqttHandleData->messagesReceived))
			{
				MQTTAPI_MESSAGE_RECEIVED_LIST* temp = containingRecord(received, MQTTAPI_MESSAGE_RECEIVED_LIST, entry);
				if (mqttHandleData->maCallBack != NULL)
				{
					if (!mqttHandleData->maCallBack(mqttHandleData->maCallbackContext, temp->messageReceived))
					{
						LogError("Client could not handle message, dropping it.");
					}
				}

				free(temp->messageReceived->payload);
				free(temp->messageReceived);
				free(temp);
			}
		}

		{
			PDLIST_ENTRY messageToSend;
			while ((messageToSend = DList_RemoveHeadList(&(mqttHandleData->messagesToSend))) != &(mqttHandleData->messagesToSend))
			{
				MQTTAPI_MESSAGE_SEND_LIST* temp = containingRecord(messageToSend, MQTTAPI_MESSAGE_SEND_LIST, entry);

				if (mqttHandleData->dcCallback != NULL)
				{
					mqttHandleData->dcCallback(temp->context, MQTTAPI_CONFIRMATION_BECAUSE_DESTROY);
					MQTTClient_freeMessage(&(temp->messageToSend));
					free(temp->messageToSend);
					STRING_delete(temp->topicName);
					free(temp);
				}
			}
		}

		{
			PDLIST_ENTRY currentListEntry;
			while ((currentListEntry = DList_RemoveHeadList(&(mqttHandleData->messagesSent))) != &(mqttHandleData->messagesSent))
			{
				MQTTAPI_MESSAGE_SEND_LIST* temp = containingRecord(currentListEntry, MQTTAPI_MESSAGE_SEND_LIST, entry);

				if (mqttHandleData->dcCallback != NULL)
				{
					mqttHandleData->dcCallback(temp->context, MQTTAPI_CONFIRMATION_BECAUSE_DESTROY);
					MQTTClient_freeMessage(&(temp->messageToSend));
					free(temp->messageToSend);
					STRING_delete(temp->topicName);
					free(temp);
				}
			}
		}

		MQTTClient_destroy(mqttHandleData->client);
		Lock_Deinit(mqttHandleData->LockHandle);
		free(mqttHandleData);
	}
}