static void sendMsgComplete(IOTHUB_MESSAGE_LIST* iothubMsgList, PMQTTTRANSPORT_HANDLE_DATA transportState, IOTHUB_BATCHSTATE_RESULT batchResult)
{
    DLIST_ENTRY messageCompleted;
    DList_InitializeListHead(&messageCompleted);
    DList_InsertTailList(&messageCompleted, &(iothubMsgList->entry));
    IoTHubClient_LL_SendComplete(transportState->llClientHandle, &messageCompleted, batchResult);
}
예제 #2
0
int MESSAGE_QUEUE_push(MESSAGE_QUEUE_HANDLE handle, MESSAGE_HANDLE element)
{
    int result;
    if (handle == NULL || element == NULL)
    {
        /*Codes_SRS_MESSAGE_QUEUE_17_007: [ MESSAGE_QUEUE_push shall return a non-zero value if handle or element are NULL. ]*/
        LogError("invalid argument - handle(%p), element(%p).", handle, element);
        result = __LINE__;
    }
    else
    {
		MESSAGE_QUEUE_STORAGE* temp = (MESSAGE_QUEUE_STORAGE*)malloc(sizeof(MESSAGE_QUEUE_STORAGE));
        if (temp == NULL)
        {
            /*Codes_SRS_MESSAGE_QUEUE_17_009: [ MESSAGE_QUEUE_push shall return a non-zero value if any system call fails. ]*/
            LogError("malloc failed.");
            result = __LINE__;
        }
        else
        {
            DList_InitializeListHead((PDLIST_ENTRY)temp);
            temp->message = element;
            /*Codes_SRS_MESSAGE_QUEUE_17_011: [ Messages shall be pushed into the queue in a first-in-first-out order. ]*/
            DList_AppendTailList((PDLIST_ENTRY)&(handle->queue_head), (PDLIST_ENTRY)temp);
            /*Codes_SRS_MESSAGE_QUEUE_17_008: [ MESSAGE_QUEUE_push shall return zero on success. ]*/
            result = 0;
        }
    }
    return result;
}
예제 #3
0
IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_Create(const IOTHUB_CLIENT_CONFIG* config)
{
    IOTHUB_CLIENT_LL_HANDLE result;
    /*Codes_SRS_IOTHUBCLIENT_LL_02_001: [IoTHubClient_LL_Create shall return NULL if config parameter is NULL or protocol field is NULL.]*/
    if (
        (config == NULL) ||
        (config->protocol == NULL)
        )
    {
        result = NULL;
        LogError("invalid configuration (NULL detected)\r\n");
    }
    else
    {
        IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)malloc(sizeof(IOTHUB_CLIENT_LL_HANDLE_DATA));
        if (handleData == NULL)
        {
            LogError("malloc failed\r\n");
            result = NULL;
        }
        else
        {
            /*Codes_SRS_IOTHUBCLIENT_LL_02_004: [Otherwise IoTHubClient_LL_Create shall initialize a new DLIST (further called "waitingToSend") containing records with fields of the following types: IOTHUB_MESSAGE_HANDLE, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, void*.]*/
            IOTHUBTRANSPORT_CONFIG lowerLayerConfig;
            DList_InitializeListHead(&(handleData->waitingToSend));
            handleData->IoTHubTransport_SetOption = ((TRANSPORT_PROVIDER*)config->protocol())->IoTHubTransport_SetOption;
            handleData->IoTHubTransport_Create = ((TRANSPORT_PROVIDER*)config->protocol())->IoTHubTransport_Create;
            handleData->IoTHubTransport_Destroy = ((TRANSPORT_PROVIDER*)config->protocol())->IoTHubTransport_Destroy;
            handleData->IoTHubTransport_Subscribe = ((TRANSPORT_PROVIDER*)config->protocol())->IoTHubTransport_Subscribe;
            handleData->IoTHubTransport_Unsubscribe = ((TRANSPORT_PROVIDER*)config->protocol())->IoTHubTransport_Unsubscribe;
            handleData->IoTHubTransport_DoWork = ((TRANSPORT_PROVIDER*)config->protocol())->IoTHubTransport_DoWork;
            handleData->IoTHubTransport_GetSendStatus = ((TRANSPORT_PROVIDER*)config->protocol())->IoTHubTransport_GetSendStatus;
            handleData->messageCallback = NULL;
            handleData->messageUserContextCallback = NULL;
            handleData->lastMessageReceiveTime = INDEFINITE_TIME;
            /*Codes_SRS_IOTHUBCLIENT_LL_02_006: [IoTHubClient_LL_Create shall populate a structure of type IOTHUBTRANSPORT_CONFIG with the information from config parameter and the previous DLIST and shall pass that to the underlying layer _Create function.]*/
            lowerLayerConfig.upperConfig = config;
            lowerLayerConfig.waitingToSend = &(handleData->waitingToSend);
            /*Codes_SRS_IOTHUBCLIENT_LL_02_007: [If the underlaying layer _Create function fails them IoTHubClient_LL_Create shall fail and return NULL.] */
            if ((handleData->transportHandle = handleData->IoTHubTransport_Create(&lowerLayerConfig)) == NULL)
            {
                LogError("underlying transport failed\r\n");
                free(handleData);
                result = NULL;
            }
            else
            {
                /*Codes_SRS_IOTHUBCLIENT_LL_02_008: [Otherwise, IoTHubClient_LL_Create shall succeed and return a non-NULL handle.] */
                result = handleData;
            }
        }
    }

    return result;
}
예제 #4
0
MESSAGE_QUEUE_HANDLE MESSAGE_QUEUE_create()
{
	MESSAGE_QUEUE_HANDLE_DATA* result;

    result = (MESSAGE_QUEUE_HANDLE_DATA*)malloc(sizeof(MESSAGE_QUEUE_HANDLE_DATA));
    if (result == NULL)
    {
        /*Codes_SRS_MESSAGE_QUEUE_17_003: [ On a failure, MESSAGE_QUEUE_create shall return NULL. ]*/
        LogError("malloc failed.");
    }
    else
    {
        /*Codes_SRS_MESSAGE_QUEUE_17_001: [ On a successful call, MESSAGE_QUEUE_create shall return a non-NULL value in MESSAGE_QUEUE_HANDLE. ]*/
        /*Codes_SRS_MESSAGE_QUEUE_17_002: [ A newly created message queue shall be empty. ]*/
        DList_InitializeListHead((PDLIST_ENTRY)&(result->queue_head));
        result->queue_head.message = NULL;
    }
    return result;
}
예제 #5
0
IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateWithTransport(const IOTHUB_CLIENT_DEVICE_CONFIG * config)
{
    IOTHUB_CLIENT_LL_HANDLE result;
    /*Codes_SRS_IOTHUBCLIENT_LL_17_001: [IoTHubClient_LL_CreateWithTransport shall return NULL if config parameter is NULL, or protocol field is NULL or transportHandle is NULL.]*/
    if (
        (config == NULL) ||
        (config->protocol == NULL) ||
        (config->transportHandle == NULL)
        )
    {
        result = NULL;
        LogError("invalid configuration (NULL detected)");
    }
    else
    {
        /*Codes_SRS_IOTHUBCLIENT_LL_17_002: [IoTHubClient_LL_CreateWithTransport shall allocate data for the IOTHUB_CLIENT_LL_HANDLE.]*/
        IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)malloc(sizeof(IOTHUB_CLIENT_LL_HANDLE_DATA));
        if (handleData == NULL)
        {
            /*Codes_SRS_IOTHUBCLIENT_LL_17_003: [If allocation fails, the function shall fail and return NULL.] */
            LogError("malloc failed");
            result = NULL;
        }
        else
        {
            handleData->uploadToBlobHandle = NULL;
            /*Codes_SRS_IOTHUBCLIENT_LL_02_047: [ IoTHubClient_LL_CreateWithTransport shall create a TICK_COUNTER_HANDLE. ]*/
            if ((handleData->tickCounter = tickcounter_create()) == NULL)
            {
                /*Codes_SRS_IOTHUBCLIENT_LL_02_048: [ If creating the handle fails, then IoTHubClient_LL_CreateWithTransport shall fail and return NULL ]*/
                LogError("unable to get a tickcounter");
                free(handleData);
                result = NULL;
            }
            else
            {
                /*Codes_SRS_IOTHUBCLIENT_LL_17_004: [IoTHubClient_LL_CreateWithTransport shall initialize a new DLIST (further called "waitingToSend") containing records with fields of the following types: IOTHUB_MESSAGE_HANDLE, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, void*.]*/
                DList_InitializeListHead(&(handleData->waitingToSend));
                setTransportProtocol(handleData, (TRANSPORT_PROVIDER*)config->protocol());
                handleData->messageCallback = NULL;
                handleData->messageUserContextCallback = NULL;
                handleData->lastMessageReceiveTime = INDEFINITE_TIME;
                handleData->transportHandle = config->transportHandle;


                IOTHUB_DEVICE_CONFIG deviceConfig;

                deviceConfig.deviceId = config->deviceId;
                deviceConfig.deviceKey = config->deviceKey;
                deviceConfig.deviceSasToken = config->deviceSasToken;

                /*Codes_SRS_IOTHUBCLIENT_LL_17_006: [IoTHubClient_LL_CreateWithTransport shall call the transport _Register function with the IOTHUB_DEVICE_CONFIG populated structure and waitingToSend list.]*/
                if ((handleData->deviceHandle = handleData->IoTHubTransport_Register(config->transportHandle, &deviceConfig, handleData, &(handleData->waitingToSend))) == NULL)
                {
                    /*Codes_SRS_IOTHUBCLIENT_LL_17_007: [If the _Register function fails, this function shall fail and return NULL.]*/
                    LogError("Registering device in transport failed");

                    tickcounter_destroy(handleData->tickCounter);
                    free(handleData);
                    result = NULL;
                }
                else
                {
                    /*Codes_SRS_IOTHUBCLIENT_LL_17_005: [IoTHubClient_LL_CreateWithTransport shall save the transport handle and mark this transport as shared.]*/
                    handleData->isSharedTransport = true;
                    /*Codes_SRS_IOTHUBCLIENT_LL_02_042: [ By default, messages shall not timeout. ]*/
                    handleData->currentMessageTimeout = 0;
                    result = handleData;
                }
            }
        }
    }

    return result;
}
예제 #6
0
IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_Create(const IOTHUB_CLIENT_CONFIG* config)
{
    IOTHUB_CLIENT_LL_HANDLE result;
    /*Codes_SRS_IOTHUBCLIENT_LL_02_001: [IoTHubClient_LL_Create shall return NULL if config parameter is NULL or protocol field is NULL.]*/
    if( 
        (config == NULL) ||
        (config->protocol == NULL)
        )
    {
        result = NULL;
        LogError("invalid configuration (NULL detected)");
    }
    else
    {
        IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)malloc(sizeof(IOTHUB_CLIENT_LL_HANDLE_DATA));
        if (handleData == NULL)
        {
            LogError("malloc failed");
            result = NULL;
        }
        else
        {
            /*Codes_SRS_IOTHUBCLIENT_LL_02_094: [ IoTHubClient_LL_Create shall create a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE from IOTHUB_CLIENT_CONFIG. ]*/
            /*Codes_SRS_IOTHUBCLIENT_LL_02_092: [ IoTHubClient_LL_CreateFromConnectionString shall create a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE from IOTHUB_CLIENT_CONFIG. ]*/
            handleData->uploadToBlobHandle = IoTHubClient_LL_UploadToBlob_Create(config);
            if (handleData->uploadToBlobHandle == NULL)
            {
                /*Codes_SRS_IOTHUBCLIENT_LL_02_093: [ If creating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateFromConnectionString shall fail and return NULL. ]*/
                /*Codes_SRS_IOTHUBCLIENT_LL_02_095: [ If creating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_Create shall fail and return NULL. ]*/
                LogError("unable to IoTHubClient_LL_UploadToBlob_Create");
                free(handleData);
                result = NULL;
            }
            else
            {
                /*Codes_SRS_IOTHUBCLIENT_LL_02_045: [ Otherwise IoTHubClient_LL_Create shall create a new TICK_COUNTER_HANDLE ]*/
                if ((handleData->tickCounter = tickcounter_create()) == NULL)
                {
                    /*Codes_SRS_IOTHUBCLIENT_LL_02_046: [ If creating the TICK_COUNTER_HANDLE fails then IoTHubClient_LL_Create shall fail and return NULL. ]*/
                    IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
                    LogError("unable to get a tickcounter");
                    free(handleData);
                    result = NULL;
                }
                else
                {
                    /*Codes_SRS_IOTHUBCLIENT_LL_02_004: [Otherwise IoTHubClient_LL_Create shall initialize a new DLIST (further called "waitingToSend") containing records with fields of the following types: IOTHUB_MESSAGE_HANDLE, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, void*.]*/
                    IOTHUBTRANSPORT_CONFIG lowerLayerConfig;
                    DList_InitializeListHead(&(handleData->waitingToSend));
                    setTransportProtocol(handleData, (TRANSPORT_PROVIDER*)config->protocol());
                    handleData->messageCallback = NULL;
                    handleData->messageUserContextCallback = NULL;
                    handleData->lastMessageReceiveTime = INDEFINITE_TIME;
                    /*Codes_SRS_IOTHUBCLIENT_LL_02_006: [IoTHubClient_LL_Create shall populate a structure of type IOTHUBTRANSPORT_CONFIG with the information from config parameter and the previous DLIST and shall pass that to the underlying layer _Create function.]*/
                    lowerLayerConfig.upperConfig = config;
                    lowerLayerConfig.waitingToSend = &(handleData->waitingToSend);
                    /*Codes_SRS_IOTHUBCLIENT_LL_02_007: [If the underlaying layer _Create function fails them IoTHubClient_LL_Create shall fail and return NULL.] */
                    if ((handleData->transportHandle = handleData->IoTHubTransport_Create(&lowerLayerConfig)) == NULL)
                    {
                        LogError("underlying transport failed");
                        IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
                        tickcounter_destroy(handleData->tickCounter);
                        free(handleData);
                        result = NULL;
                    }
                    else
                    {
                        IOTHUB_DEVICE_CONFIG deviceConfig;

                        deviceConfig.deviceId = config->deviceId;
                        deviceConfig.deviceKey = config->deviceKey;
                        deviceConfig.deviceSasToken = config->deviceSasToken;

                        /*Codes_SRS_IOTHUBCLIENT_LL_17_008: [IoTHubClient_LL_Create shall call the transport _Register function with a populated structure of type IOTHUB_DEVICE_CONFIG and waitingToSend list.] */
                        if ((handleData->deviceHandle = handleData->IoTHubTransport_Register(handleData->transportHandle, &deviceConfig, handleData, &(handleData->waitingToSend))) == NULL)
                        {
                            /*Codes_SRS_IOTHUBCLIENT_LL_17_009: [If the _Register function fails, this function shall fail and return NULL.]*/
                            LogError("Registering device in transport failed");
                            handleData->IoTHubTransport_Destroy(handleData->transportHandle);
                            IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
                            tickcounter_destroy(handleData->tickCounter);
                            free(handleData);
                            result = NULL;
                        }
                        else
                        {
                            /*Codes_SRS_IOTHUBCLIENT_LL_02_008: [Otherwise, IoTHubClient_LL_Create shall succeed and return a non-NULL handle.] */
                            handleData->isSharedTransport = false;
                            /*Codes_SRS_IOTHUBCLIENT_LL_02_042: [ By default, messages shall not timeout. ]*/
                            handleData->currentMessageTimeout = 0;
                            result = handleData;
                        }
                    }
                }
            }
        }
    }

    return result;
}
static PMQTTTRANSPORT_HANDLE_DATA InitializeTransportHandleData(const IOTHUB_CLIENT_CONFIG* upperConfig, PDLIST_ENTRY waitingToSend)
{
    PMQTTTRANSPORT_HANDLE_DATA state = (PMQTTTRANSPORT_HANDLE_DATA)malloc(sizeof(MQTTTRANSPORT_HANDLE_DATA));
    if (state == NULL)
    {
        LogError("Could not create MQTT transport state. Memory allocation failed.\r\n");
    }
    else if ((state->device_id = STRING_construct(upperConfig->deviceId)) == NULL)
    {
        free(state);
        state = NULL;
    }
    else if ((state->device_key = STRING_construct(upperConfig->deviceKey)) == NULL)
    {
        LogError("Could not create device key for MQTT\r\n");
        STRING_delete(state->device_id);
        free(state);
        state = NULL;
    }
    else if ( (state->sasTokenSr = ConstructSasToken(upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId) ) == NULL)
    {
        LogError("Could not create Sas Token Sr String.\r\n");
        STRING_delete(state->device_key);
        STRING_delete(state->device_id);
        free(state);
        state = NULL;
    }
    else if ( (state->mqttEventTopic = ConstructEventTopic(upperConfig->deviceId) ) == NULL)
    {
        LogError("Could not create mqttEventTopic for MQTT\r\n");
        STRING_delete(state->sasTokenSr);
        STRING_delete(state->device_key);
        STRING_delete(state->device_id);
        free(state);
        state = NULL;
    }
    else if ((state->mqttMessageTopic = ConstructMessageTopic(upperConfig->deviceId) ) == NULL)
    {
        LogError("Could not create mqttMessageTopic for MQTT\r\n");
        STRING_delete(state->mqttEventTopic);
        STRING_delete(state->sasTokenSr);
        STRING_delete(state->device_key);
        STRING_delete(state->device_id);
        free(state);
        state = NULL;
    }
    else
    {
        state->mqttClient = mqtt_client_init(MqttRecvCallback, MqttOpCompleteCallback, state, defaultPrintLogFunction);
        if (state->mqttClient == NULL)
        {
            STRING_delete(state->mqttEventTopic);
            STRING_delete(state->mqttMessageTopic);
            STRING_delete(state->sasTokenSr);
            STRING_delete(state->device_key);
            STRING_delete(state->device_id);
            free(state);
            state = NULL;
        }
        else
        {
            /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_008: [The hostname shall be constructed using the iothubname and iothubSuffix.] */
            // TODO: need to strip the ssl or http or tls
            char tempAddress[DEFAULT_TEMP_STRING_LEN];
            (void)snprintf(tempAddress, DEFAULT_TEMP_STRING_LEN, "%s.%s", upperConfig->iotHubName, upperConfig->iotHubSuffix);
            if ((state->hostAddress = STRING_construct(tempAddress)) == NULL)
            {
                STRING_delete(state->mqttEventTopic);
                STRING_delete(state->mqttMessageTopic);
                STRING_delete(state->sasTokenSr);
                STRING_delete(state->device_key);
                STRING_delete(state->device_id);
                free(state);
                state = NULL;
            }
            else if ((state->configPassedThroughUsername = buildConfigForUsername(upperConfig)) == NULL)
            {
                STRING_delete(state->hostAddress);
                STRING_delete(state->mqttEventTopic);
                STRING_delete(state->mqttMessageTopic);
                STRING_delete(state->sasTokenSr);
                STRING_delete(state->device_key);
                STRING_delete(state->device_id);
                free(state);
                state = NULL;
            }
            else
            {
                /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_010: [IoTHubTransportMqtt_Create shall allocate memory to save its internal state where all topics, hostname, device_id, device_key, sasTokenSr and client handle shall be saved.] */
                DList_InitializeListHead(&(state->waitingForAck));
                state->destroyCalled = false;
                state->subscribed = false;
                state->connected = false;
                state->packetId = 1;
                state->llClientHandle = NULL;
                state->xioTransport = NULL;
                state->portNum = DEFAULT_PORT_NUMBER;
                state->waitingToSend = waitingToSend;
                state->currPacketState = CONNECT_TYPE;
            }
        }
    }
    return state;
}
예제 #8
0
MQTTAPI_HANDLE MQTTAPI_Create(const MQTTAPI_ConnectOptions* options)
{
	PMQTTTAPI_HANDLE_DATA result;

	/* Codes_SRS_MQTTAPI_04_011: [If any member of the parameter options is NULL or empty then MQTTAPI_Create shall return NULL.]  */
	if (options == NULL)
	{
		LogError("Invalid Argument. options cannot be NULL.\r\n")
		result = NULL;
	}
	else if (options->deviceId == NULL || strlen(options->deviceId) <= 0)
	{
		LogError("Invalid Argument. Device Id cannot be NULL or Empty.\r\n")
		result = NULL;
	}
	else if (options->deviceKey == NULL || strlen(options->deviceKey) <= 0)
	{
		LogError("Invalid Argument. Device Key cannot be NULL or Empty.\r\n")
		result = NULL;
	}
	else if (options->serverURI == NULL || strlen(options->serverURI) <= 0)
	{
		LogError("Invalid Argument. Device Key cannot be NULL or Empty.\r\n")
		result = NULL;
	}
	else if (options->sasTokenSr == NULL || strlen(options->sasTokenSr) <= 0)
	{
		LogError("Invalid Argument. sasTokenSr cannot be NULL or Empty.\r\n")
		result = NULL;
	}
	/* Tests_SRS_MQTTAPI_04_014: [Otherwise, MQTTAPI_Create shall return a MQTTAPI_HANDLE suitable for further calls to the module.] */
	else
	{
		result = (PMQTTTAPI_HANDLE_DATA)malloc(sizeof(MQTTTAPI_HANDLE_DATA));

		if (result != NULL)
		{
			result->connected = false;
			result->subscribed = false;
			result->dcCallback = NULL;
			result->maCallBack = NULL;
			result->maCallbackContext = NULL;
			result->subscribedTopicHandleData = NULL;
			result->sasTokenLifetime = SAS_TOKEN_DEFAULT_LIFETIME;
			result->sasRefreshLine = SAS_TOKEN_DEFAULT_REFRESH_LINE;

			DList_InitializeListHead(&(result->messagesReceived));
			DList_InitializeListHead(&(result->messagesToSend));
			DList_InitializeListHead(&(result->messagesSent));

			if ((result->LockHandle = Lock_Init()) == NULL)
			{
				LogError("Lock_Init failed\r\n");
				free(result);
				result = NULL;
			}
			/* Codes_SRS_MQTTAPI_04_012: [Parameters deviceId, deviceKey and sasTokenSr shall be saved.]  */
			else if ((result->device_id = STRING_construct(options->deviceId)) == NULL)
			{
				/* Codes_SRS_MQTTAPI_04_013: [If saving these parameters fail for any reason MQTTAPI_Create shall return NULL.] */
				LogError("Could not create deviceId String.\r\n");
				Lock_Deinit(result->LockHandle);
				free(result);
				result = NULL;
			}
			/* Codes_SRS_MQTTAPI_04_012: [Parameters deviceId, deviceKey and sasTokenSr shall be saved.]  */
			else if ((result->device_key = STRING_construct(options->deviceKey)) == NULL)
			{
				/* Codes_SRS_MQTTAPI_04_013: [If saving these parameters fail for any reason MQTTAPI_Create shall return NULL.] */
				LogError("Could not create deviceId String.\r\n");
				STRING_delete(result->device_id);
				Lock_Deinit(result->LockHandle);
				free(result);
				result = NULL;
			}
			/* Codes_SRS_MQTTAPI_04_012: [Parameters deviceId, deviceKey and sasTokenSr shall be saved.]  */
			else if ((result->sasTokenSr = STRING_construct(options->sasTokenSr)) == NULL)
			{
				LogError("Could not create sasTokenSr String.\r\n");
				STRING_delete(result->device_key);
				STRING_delete(result->device_id);
				Lock_Deinit(result->LockHandle);
				free(result);
				result = NULL;
			}
    		else if (MQTTClient_create(&result->client, options->serverURI, STRING_c_str(result->device_id),
				MQTTCLIENT_PERSISTENCE_NONE, NULL) != MQTTCLIENT_SUCCESS)
			{
				LogError("Could not create MQTT Client.\r\n");
				STRING_delete(result->sasTokenSr);
				STRING_delete(result->device_key);
				STRING_delete(result->device_id);
				Lock_Deinit(result->LockHandle);
				free(result);
				result = NULL;
			}
			/* Codes_SRS_MQTTAPI_04_004: [This function is registered when the user makes a call to MQTTAPI_SetCallbacks.] */
			/* Codes_SRS_MQTTAPI_04_005: [The context parameter is a pointer to the original value passed by MQTTAPI_SetCallbacks, which contains application-specific context.]  */
		    /* Codes_SRS_MQTTAPI_04_008: [This function is registered when the user makes a call to MQTTAPI_SetCallbacks.] */
			else if (MQTTClient_setCallbacks(result->client, result, connectionLost, msgarrvd, delivered) != MQTTCLIENT_SUCCESS)
			{
				LogError("Could not set callbacks.\r\n");
				STRING_delete(result->sasTokenSr);
				STRING_delete(result->device_key);
				STRING_delete(result->device_id);
				MQTTClient_destroy(&result->client);
				Lock_Deinit(result->LockHandle);
				free(result);
				result = NULL;
			}
			/* Codes_SRS_MQTTAPI_04_024: [MQTTAPI_Create shall call underlying library connection functions to establish connection with the server.]  */
			/* Codes_SRS_MQTTAPI_04_047: [Otherwise MQTTAPI_Create shall return a non-NULL MQTTAPI_HANDLE]  */
			else if (!checkAndTryToConnect(result))
			{
				/* Codes_SRS_MQTTAPI_04_025: [If connection fails MQTTAPI_Create shall return NULL. */
				LogError("Could not Connect to MQTT Server.\r\n");
				STRING_delete(result->sasTokenSr);
				STRING_delete(result->device_key);
				STRING_delete(result->device_id);
				MQTTClient_destroy(&result->client);
				Lock_Deinit(result->LockHandle);
				free(result);
				result = NULL;
			}

		}
		else
		{
			/* Codes_SRS_MQTTAPI_04_015: [If creating instance fails for any reason, then MQTTAPI_Create shall return NULL.]  */
			LogError("Could not create MQTT API handle data. Memory allocation failed.\r\n");
			result = NULL;
		}
	}

    return (MQTTAPI_HANDLE)result;
}
예제 #9
0
IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateWithTransport(const IOTHUB_CLIENT_DEVICE_CONFIG * config)
{
    IOTHUB_CLIENT_LL_HANDLE result;
    /*Codes_SRS_IOTHUBCLIENT_LL_17_001: [IoTHubClient_LL_CreateWithTransport shall return NULL if config parameter is NULL, or protocol field is NULL or transportHandle is NULL.]*/
    if (
        (config == NULL) ||
        (config->protocol == NULL) ||
        (config->transportHandle == NULL) ||
        /*Codes_SRS_IOTHUBCLIENT_LL_02_098: [ IoTHubClient_LL_CreateWithTransport shall fail and return NULL if both config->deviceKey AND config->deviceSasToken are NULL. ]*/
        ((config->deviceKey == NULL) && (config->deviceSasToken == NULL))
        )
    {
        result = NULL;
        LogError("invalid configuration (NULL detected)");
    }
    else
    {
        /*Codes_SRS_IOTHUBCLIENT_LL_17_002: [IoTHubClient_LL_CreateWithTransport shall allocate data for the IOTHUB_CLIENT_LL_HANDLE.]*/
        IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)malloc(sizeof(IOTHUB_CLIENT_LL_HANDLE_DATA));
        if (handleData == NULL)
        {
            /*Codes_SRS_IOTHUBCLIENT_LL_17_003: [If allocation fails, the function shall fail and return NULL.] */
            LogError("malloc failed");
            result = NULL;
        }
        else
        {
            handleData->transportHandle = config->transportHandle;
            setTransportProtocol(handleData, (TRANSPORT_PROVIDER*)config->protocol());

#ifndef DONT_USE_UPLOADTOBLOB
            const char* hostname = STRING_c_str(handleData->IoTHubTransport_GetHostname(handleData->transportHandle));
            /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClient_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
            /*the first '.' says where the iothubname finishes*/
            const char* whereIsDot = strchr(hostname, '.');
            if (whereIsDot == NULL)
            {
                /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateWithTransport shall fail and return NULL. ]*/
                LogError("unable to determine the IoTHub name");
                free(handleData);
                result = NULL;
            }
            else
            {
                /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClient_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
                char* IoTHubName = malloc(whereIsDot - hostname + 1);
                if (IoTHubName == NULL)
                {
                    /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateWithTransport shall fail and return NULL. ]*/
                    LogError("unable to malloc");
                    free(handleData);
                    result = NULL;
                }
                else
                {
                    const char* IotHubSuffix = whereIsDot + 1;
                    memcpy(IoTHubName, hostname, whereIsDot - hostname);
                    IoTHubName[whereIsDot - hostname ] = '\0';
                    
                    IOTHUB_CLIENT_CONFIG temp;
                    temp.deviceId = config->deviceId;
                    temp.deviceKey = config->deviceKey;
                    temp.deviceSasToken = config->deviceSasToken;
                    temp.iotHubName = IoTHubName;
                    temp.iotHubSuffix = IotHubSuffix;
                    temp.protocol = NULL; /*irrelevant to IoTHubClient_LL_UploadToBlob*/
                    temp.protocolGatewayHostName = NULL; /*irrelevant to IoTHubClient_LL_UploadToBlob*/

                    /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateWithTransport shall fail and return NULL. ]*/
                    handleData->uploadToBlobHandle = IoTHubClient_LL_UploadToBlob_Create(&temp);
                    if (handleData->uploadToBlobHandle == NULL)
                    {
                        /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClient_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
                        LogError("unable to IoTHubClient_LL_UploadToBlob_Create");
                        free(handleData);
                        result = NULL;
                    }
                    else
#endif
                    {
                        /*Codes_SRS_IOTHUBCLIENT_LL_02_047: [ IoTHubClient_LL_CreateWithTransport shall create a TICK_COUNTER_HANDLE. ]*/
                        if ((handleData->tickCounter = tickcounter_create()) == NULL)
                        {
                            /*Codes_SRS_IOTHUBCLIENT_LL_02_048: [ If creating the handle fails, then IoTHubClient_LL_CreateWithTransport shall fail and return NULL ]*/
                            LogError("unable to get a tickcounter");
#ifndef DONT_USE_UPLOADTOBLOB
                            IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
#endif
                            free(handleData);
                            result = NULL;
                        }
                        else
                        {
                            /*Codes_SRS_IOTHUBCLIENT_LL_17_004: [IoTHubClient_LL_CreateWithTransport shall initialize a new DLIST (further called "waitingToSend") containing records with fields of the following types: IOTHUB_MESSAGE_HANDLE, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, void*.]*/
                            DList_InitializeListHead(&(handleData->waitingToSend));
                            
                            handleData->messageCallback = NULL;
                            handleData->messageUserContextCallback = NULL;
                            handleData->lastMessageReceiveTime = INDEFINITE_TIME;
                            

                            IOTHUB_DEVICE_CONFIG deviceConfig;

                            deviceConfig.deviceId = config->deviceId;
                            deviceConfig.deviceKey = config->deviceKey;
                            deviceConfig.deviceSasToken = config->deviceSasToken;

                            /*Codes_SRS_IOTHUBCLIENT_LL_17_006: [IoTHubClient_LL_CreateWithTransport shall call the transport _Register function with the IOTHUB_DEVICE_CONFIG populated structure and waitingToSend list.]*/
                            if ((handleData->deviceHandle = handleData->IoTHubTransport_Register(config->transportHandle, &deviceConfig, handleData, &(handleData->waitingToSend))) == NULL)
                            {
                                /*Codes_SRS_IOTHUBCLIENT_LL_17_007: [If the _Register function fails, this function shall fail and return NULL.]*/
                                LogError("Registering device in transport failed");
#ifndef DONT_USE_UPLOADTOBLOB
                                IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
#endif
                                tickcounter_destroy(handleData->tickCounter);
                                free(handleData);
                                result = NULL;
                            }
                            else
                            {
                                /*Codes_SRS_IOTHUBCLIENT_LL_17_005: [IoTHubClient_LL_CreateWithTransport shall save the transport handle and mark this transport as shared.]*/
                                handleData->isSharedTransport = true;
                                /*Codes_SRS_IOTHUBCLIENT_LL_02_042: [ By default, messages shall not timeout. ]*/
                                handleData->currentMessageTimeout = 0;
                                result = handleData;
                            }
                        }
                    }
#ifndef DONT_USE_UPLOADTOBLOB
                    free(IoTHubName);
                }
            }
#endif
        }
    }

    return result;
}