int prov_transport_common_mqtt_close(PROV_DEVICE_TRANSPORT_HANDLE handle)
{
    int result;
    if (handle == NULL)
    {
        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_011: [ If handle is NULL, prov_transport_common_mqtt_close shall return a non-zero value. ] */
        LogError("Invalid parameter specified handle: %p", handle);
        result = __FAILURE__;
    }
    else
    {
        PROV_TRANSPORT_MQTT_INFO* mqtt_info = (PROV_TRANSPORT_MQTT_INFO*)handle;
        BUFFER_delete(mqtt_info->ek);
        mqtt_info->ek = NULL;
        BUFFER_delete(mqtt_info->srk);
        mqtt_info->srk = NULL;
        free(mqtt_info->registration_id);
        mqtt_info->registration_id = NULL;

        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_012: [ prov_transport_common_mqtt_close shall close all connection associated with mqtt communication. ] */
        if (mqtt_client_disconnect(mqtt_info->mqtt_client, NULL, NULL) == 0)
        {
            mqtt_client_dowork(mqtt_info->mqtt_client);
        }
        xio_destroy(mqtt_info->transport_io);
        mqtt_info->transport_io = NULL;

        /* Tests_PROV_TRANSPORT_MQTT_COMMON_07_013: [ On success prov_transport_common_mqtt_close shall return a zero value. ] */
        mqtt_info->mqtt_state = MQTT_STATE_IDLE;
        result = 0;
    }
    return result;
}
Example #2
0
File: main.c Project: wuwx/simba
static int test_disconnect(struct harness_t *harness_p)
{
    BTASSERT(mqtt_client_disconnect(&client) == 0);
    BTASSERT(socket_close(&server_sock) == 0);

    return (0);
}
static void DisconnectFromClient(PMQTTTRANSPORT_HANDLE_DATA transportState)
{
    /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_013: [If the parameter subscribe is true then IoTHubTransportMqtt_Destroy shall call IoTHubTransportMqtt_Unsubscribe.] */
    if (transportState->subscribed)
    {
        IoTHubTransportMqtt_Unsubscribe(transportState);
    }

    (void)mqtt_client_disconnect(transportState->mqttClient);
    xio_destroy(transportState->xioTransport);

    transportState->connected = false;
    transportState->currPacketState = DISCONNECT_TYPE;
}
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;

        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_013: [If the parameter subscribe is true then IoTHubTransportMqtt_Destroy shall call IoTHubTransportMqtt_Unsubscribe.] */
        if (transportState->subscribed)
        {
            IoTHubTransportMqtt_Unsubscribe(handle);
        }

        //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);
        }

        (void)mqtt_client_disconnect(transportState->mqttClient);

        xio_destroy(transportState->xioTransport);

        /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_014: [IoTHubTransportMqtt_Destroy shall free all the resources currently in use.] */
        transportState->connected = false;
        transportState->currPacketState = DISCONNECT_TYPE;
        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);
    }
}
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;
            }
        }
    }
}
static void OnOperationComplete(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_RESULT actionResult, const void* msgInfo, void* callbackCtx)
{
    (void)callbackCtx;
    switch (actionResult)
    {
        case MQTT_CLIENT_ON_CONNACK:
        {
            PrintLogFunction(LOG_LINE, "ConnAck function called");
            const CONNECT_ACK* connack = (CONNECT_ACK*)msgInfo;
            SUBSCRIBE_PAYLOAD subscribe[] = {
                { TOPIC_NAME_A, DELIVER_AT_MOST_ONCE },
                { TOPIC_NAME_B, DELIVER_EXACTLY_ONCE },
            };
            if (mqtt_client_subscribe(handle, PACKET_ID_VALUE++, subscribe, sizeof(subscribe) / sizeof(subscribe[0])) != 0)
            {
                PrintLogFunction(LOG_LINE, "%d: mqtt_client_subscribe failed", __LINE__);
                g_continue = false;
            }
            break;
        }
        case MQTT_CLIENT_ON_SUBSCRIBE_ACK:
        {
            const SUBSCRIBE_ACK* suback = (SUBSCRIBE_ACK*)msgInfo;
            MQTT_MESSAGE_HANDLE msg = mqttmessage_create(PACKET_ID_VALUE++, TOPIC_NAME_A, DELIVER_EXACTLY_ONCE, APP_NAME_A, strlen(APP_NAME_A));
            if (msg == NULL)
            {
                PrintLogFunction(LOG_LINE, "%d: mqttmessage_create failed", __LINE__);
                g_continue = false;
            }
            else
            {
                if (mqtt_client_publish(handle, msg))
                {
                    PrintLogFunction(LOG_LINE, "%d: mqtt_client_publish failed", __LINE__);
                    g_continue = false;
                }
                mqttmessage_destroy(msg);
            }
            // Now send a message that will get 
            break;
        }
        case MQTT_CLIENT_ON_PUBLISH_ACK:
        {
            const PUBLISH_ACK* puback = (PUBLISH_ACK*)msgInfo;
            break;
        }
        case MQTT_CLIENT_ON_PUBLISH_RECV:
        {
            const PUBLISH_ACK* puback = (PUBLISH_ACK*)msgInfo;
            break;
        }
        case MQTT_CLIENT_ON_PUBLISH_REL:
        {
            const PUBLISH_ACK* puback = (PUBLISH_ACK*)msgInfo;
            break;
        }
        case MQTT_CLIENT_ON_PUBLISH_COMP:
        {
            const PUBLISH_ACK* puback = (PUBLISH_ACK*)msgInfo;
            // Done so send disconnect
            mqtt_client_disconnect(handle);
            break;
        }
        case MQTT_CLIENT_ON_ERROR:
        case MQTT_CLIENT_ON_DISCONNECT:
            g_continue = false;
            break;
    }
}