static void setup_dev_auth_emulator_generate_credentials_mocks(const char* token_scope)
 {
     STRICT_EXPECTED_CALL(STRING_new());
     STRICT_EXPECTED_CALL(get_time(IGNORED_PTR_ARG));
     STRICT_EXPECTED_CALL(STRING_construct(token_scope));
     STRICT_EXPECTED_CALL(STRING_construct(IGNORED_PTR_ARG))
         .IgnoreArgument_psz();
     STRICT_EXPECTED_CALL(SASToken_Create(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_NUM_ARG))
         .IgnoreArgument_scope()
         .IgnoreArgument_keyName()
         .IgnoreArgument_expiry()
         .IgnoreArgument_key();
     STRICT_EXPECTED_CALL(STRING_c_str(IGNORED_PTR_ARG))
         .IgnoreArgument_handle();
     STRICT_EXPECTED_CALL(mallocAndStrcpy_s(IGNORED_PTR_ARG, IGNORED_PTR_ARG))
         .IgnoreArgument_destination()
         .IgnoreArgument_source();
     STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG))
         .IgnoreArgument_handle();
     STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG))
         .IgnoreArgument_handle();
     STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG))
         .IgnoreArgument_handle();
     STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG))
         .IgnoreArgument_handle();
 }
예제 #2
0
const char* IoTHubAccount_GetSharedAccessSignature(IOTHUB_ACCOUNT_INFO_HANDLE acctHandle)
{
    const char* result = NULL;
    IOTHUB_ACCOUNT_INFO* acctInfo = (IOTHUB_ACCOUNT_INFO*)acctHandle;
    if (acctInfo != NULL)
    {
        if (acctInfo->sharedAccessToken != NULL)
        {
            // Reuse the sharedAccessToken if it's been created already
            result = acctInfo->sharedAccessToken;
        }
        else
        {
        time_t currentTime = time(NULL);
        size_t expiry_time = (size_t)(currentTime + 3600);

        STRING_HANDLE accessKey = STRING_construct(acctInfo->sharedAccessKey);
        STRING_HANDLE iotName = STRING_construct(acctInfo->hostname);
        STRING_HANDLE keyName = STRING_construct(acctInfo->keyName);
        if (accessKey != NULL && iotName != NULL && keyName != NULL)
        {
            STRING_HANDLE sasHandle = SASToken_Create(accessKey, iotName, keyName, expiry_time);
            if (sasHandle == NULL)
            {

                result = NULL;
            }
            else
            {
                if (mallocAndStrcpy_s(&acctInfo->sharedAccessToken, STRING_c_str(sasHandle)) != 0)
                {
                    result = NULL;
                }
                else
                {
                    result = acctInfo->sharedAccessToken;
                }
                STRING_delete(sasHandle);
            }
        }
        STRING_delete(accessKey);
        STRING_delete(iotName);
        STRING_delete(keyName);
    }
    }
    else
    {
        result = NULL;
    }
    return result; 
}
예제 #3
0
static STRING_HANDLE construct_url()
{
    STRING_HANDLE result;

    /*Codes_SRS_BROKER_17_002: [ Broker_Create shall create a unique id. ]*/
    char uuid[BROKER_GUID_SIZE];
    memset(uuid, 0, BROKER_GUID_SIZE);
    if (UniqueId_Generate(uuid, BROKER_GUID_SIZE) != UNIQUEID_OK)
    {
        LogError("Unable to generate unique Id.");
        result = NULL;
    }
    else
    {
        /*Codes_SRS_BROKER_17_003: [ Broker_Create shall initialize a url consisting of "inproc://" + unique id. ]*/
        result = STRING_construct(INPROC_URL_HEAD);
        if (result == NULL)
        {
            LogError("Unable to construct url.");
        }
        else
        {
            if (STRING_concat(result, uuid) != 0)
            {
                /*Codes_SRS_BROKER_13_003: [ This function shall return NULL if an underlying API call to the platform causes an error. ]*/
                STRING_delete(result);
                LogError("Unable to append uuid to url.");
                result = NULL;
            }
        }
    }
    return result;
}
예제 #4
0
MQTTAPI_TOPIC_HANDLE MQTTAPI_Subscribe(MQTTAPI_HANDLE instance, const char* topic)
{
	PMQTTTAPI_HANDLE_DATA handle = instance;
	PMQTTAPI_TOPIC_HANDLE_DATA result;

	/* Codes_SRS_MQTTAPI_04_029: [If any of the parameters instance or topic is NULL MQTTAPI_Subscribe shall return NULL.]  */
	if (instance == NULL || topic == NULL || strlen(topic) == 0)
	{
		result = NULL;
	}
	else
	{
		if ((result = (PMQTTAPI_TOPIC_HANDLE_DATA)malloc(sizeof(MQTTAPI_TOPIC_HANDLE_DATA))) == NULL)
		{
			LogError("Memory Allocation failure to store Topic Handle Data.\r\n");
			handle->subscribed = false;
		}
		else if (checkAndTryToConnect(handle))
		{
			int rc;
			/* Codes_SRS_MQTTAPI_04_031: [MQTTAPI_Subscribe shall call underlying library methods to subscribe to the topic on the topic parameter.] */
			if ((rc = MQTTClient_subscribe(handle->client, topic, SUBSCRIBEQOS)) != MQTTCLIENT_SUCCESS)
			{
				/* Codes_SRS_MQTTAPI_04_032: [If the underlying library fails MQTTAPI_Subscribe shall return NULL] */
				LogError("Error subscribing to topic. Code is:%d \r\n", rc);
				free(result);
				result = NULL;
				handle->subscribed = false;
			}
			else
			{
				/* Codes_SRS_MQTTAPI_04_033: [Otherwise MQTTAPI_Subscribe shall return a non-NULL MQTTAPI_TOPIC_HANDLE] */
				result->mqttApiInstance = handle;
				if ((result->topicName = STRING_construct(topic)) == NULL)
				{
					LogError("Problem to save topic name.\r\n");
					free(result);
					result = NULL;
					handle->subscribed = false;
				}
				else
				{
					handle->subscribedTopicHandleData = result;
					handle->subscribed = true;
				}
			}
		}
		else
		{
			LogError("MQTT Client Not Connected. Error trying to reconect.\r\n");
			free(result);
			result = NULL;
		}
	}

	return result;
}
MODULE_LOADER_RESULT ModuleLoader_ParseBaseConfigurationFromJson(
    MODULE_LOADER_BASE_CONFIGURATION* configuration,
    const JSON_Value* json
)
{
    // The JSON is expected to be an object that has a string
    // property called "binding.path"
    MODULE_LOADER_RESULT result;

    JSON_Value_Type value_type = json_value_get_type(json);
    if (
        configuration == NULL ||
        json == NULL ||
        value_type != JSONObject
       )
    {
        LogError(
            "Invalid input arguments. "
            "configuration = %p, json = %p, json value type = %d",
            configuration,
            json,
            (json != NULL) ? value_type : 0
        );

        /*
        Codes_SRS_MODULE_LOADER_13_049: [ ModuleLoader_ParseBaseConfigurationFromJson shall return MODULE_LOADER_ERROR if configuration is NULL. ]
        Codes_SRS_MODULE_LOADER_13_050 : [ModuleLoader_ParseBaseConfigurationFromJson shall return MODULE_LOADER_ERROR if json is NULL.]
        Codes_SRS_MODULE_LOADER_13_051 : [ModuleLoader_ParseBaseConfigurationFromJson shall return MODULE_LOADER_ERROR if json is not a JSON object.]
        */
        result = MODULE_LOADER_ERROR;
    }
    else
    {
        JSON_Object* config = json_value_get_object(json);
        if (config == NULL)
        {
            LogError("json_value_get_object failed");

            /*Codes_SRS_MODULE_LOADER_13_052: [ ModuleLoader_ParseBaseConfigurationFromJson shall return MODULE_LOADER_ERROR if an underlying platform call fails. ]*/
            result = MODULE_LOADER_ERROR;
        }
        else
        {
            // It is acceptable to have binding.path be NULL.

            /*Codes_SRS_MODULE_LOADER_13_053: [ ModuleLoader_ParseBaseConfigurationFromJson shall read the value of the string attribute binding.path from the JSON object and assign to configuration->binding_path. ]*/
            const char* binding_path = json_object_get_string(config, "binding.path");
            configuration->binding_path = STRING_construct(binding_path);

            /*Codes_SRS_MODULE_LOADER_13_054: [ ModuleLoader_ParseBaseConfigurationFromJson shall return MODULE_LOADER_SUCCESS if the parsing is successful. ]*/
            result = MODULE_LOADER_SUCCESS;
        }
    }

    return result;
}
예제 #6
0
static BROKER_RESULT init_module(BROKER_MODULEINFO* module_info, const MODULE* module)
{
    BROKER_RESULT result;

    /*Codes_SRS_BROKER_13_107: The function shall assign the `module` handle to `BROKER_MODULEINFO::module`.*/
    module_info->module = (MODULE*)malloc(sizeof(MODULE));
    if (module_info->module == NULL)
    {
        LogError("Allocate module failed");
        result = BROKER_ERROR;
    }
    else
    {
        module_info->module->module_apis = module->module_apis;
        module_info->module->module_handle = module->module_handle;

        /*Codes_SRS_BROKER_13_099: [The function shall initialize BROKER_MODULEINFO::socket_lock with a valid lock handle.]*/
        module_info->socket_lock = Lock_Init();
        if (module_info->socket_lock == NULL)
        {
            /*Codes_SRS_BROKER_13_047: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/
            LogError("Lock_Init for socket lock failed");
            result = BROKER_ERROR;
        }
        else
        {
            char uuid[BROKER_GUID_SIZE];
            memset(uuid, 0, BROKER_GUID_SIZE);
            /*Codes_SRS_BROKER_17_020: [ The function shall create a unique ID used as a quit signal. ]*/
            if (UniqueId_Generate(uuid, BROKER_GUID_SIZE) != UNIQUEID_OK)
            {
                /*Codes_SRS_BROKER_13_047: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/
                LogError("Lock_Init for socket lock failed");
                Lock_Deinit(module_info->socket_lock);
                result = BROKER_ERROR;
            }
            else
            {
                module_info->quit_message_guid = STRING_construct(uuid);
                if (module_info->quit_message_guid == NULL)
                {
                    /*Codes_SRS_BROKER_13_047: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/
                    LogError("String construct failed for module guid");
                    Lock_Deinit(module_info->socket_lock);
                    result = BROKER_ERROR;
                }
                else
                {
                    result = BROKER_OK;
                }
            }
        }
    }
    return result;
}
예제 #7
0
const char* IoTHubAccount_GetEventhubAccessKey(void)
{
    char *iothub_connection_string;
    static char access_key[128];

    if ((iothub_connection_string = IoTHubAccount_GetIoTHubConnString()) != NULL)
    {
        STRING_HANDLE iothub_connection_string_str;

        if((iothub_connection_string_str = STRING_construct(iothub_connection_string)) != NULL)
        {
            STRING_TOKENIZER_HANDLE tokenizer;

            if ((tokenizer = STRING_TOKENIZER_create(iothub_connection_string_str)) != NULL)
            {
                STRING_HANDLE tokenString;

                if ((tokenString = STRING_new()) != NULL)
                {
                    STRING_HANDLE valueString;

                    if ((valueString = STRING_new()) != NULL)
                    {
                        while ((STRING_TOKENIZER_get_next_token(tokenizer, tokenString, "=") == 0))
                        {
                            char tokenValue[128];
                            strcpy(tokenValue, STRING_c_str(tokenString));

                            if (STRING_TOKENIZER_get_next_token(tokenizer, tokenString, ";") != 0)
                            {
                                break;
                            }

                            if (strcmp(tokenValue, "SharedAccessKey") == 0)
                            {
                                strcpy(access_key, STRING_c_str(tokenString));
                                break;
                            }
                        }

                        STRING_delete(valueString);
                    }

                    STRING_delete(tokenString);
                }

                STRING_TOKENIZER_destroy(tokenizer);
            }

            STRING_delete(iothub_connection_string_str);
        }
    }

    return access_key;
}
SAS_TOKEN_STATUS IoTHubClient_Auth_Is_SasToken_Valid(IOTHUB_AUTHORIZATION_HANDLE handle)
{
    SAS_TOKEN_STATUS result;
    if (handle == NULL)
    {
        /* Codes_SRS_IoTHub_Authorization_07_015: [ if handle is NULL, IoTHubClient_Auth_Is_SasToken_Valid shall return false. ] */
        LogError("Invalid Parameter handle: %p", handle);
        result = SAS_TOKEN_STATUS_FAILED;
    }
    else
    {
        if (handle->cred_type == IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN)
        {
            if (handle->device_sas_token == NULL)
            {
                /* Codes_SRS_IoTHub_Authorization_07_017: [ If the sas_token is NULL IoTHubClient_Auth_Is_SasToken_Valid shall return false. ] */
                LogError("Failure: device_sas_toke is NULL");
                result = SAS_TOKEN_STATUS_FAILED;
            }
            else
            {
                /* Codes_SRS_IoTHub_Authorization_07_018: [ otherwise IoTHubClient_Auth_Is_SasToken_Valid shall return the value returned by SASToken_Validate. ] */
                STRING_HANDLE strSasToken = STRING_construct(handle->device_sas_token);
                if (strSasToken != NULL)
                {
                    if (!SASToken_Validate(strSasToken))
                    {
                        result = SAS_TOKEN_STATUS_INVALID;
                    }
                    else
                    {
                        result = SAS_TOKEN_STATUS_VALID;
                    }
                    STRING_delete(strSasToken);
                }
                else
                {
                    LogError("Failure constructing SAS Token");
                    result = SAS_TOKEN_STATUS_FAILED;
                }
            }
        }
        else
        {
            /* Codes_SRS_IoTHub_Authorization_07_016: [ if credential type is not IOTHUB_CREDENTIAL_TYPE_SAS_TOKEN IoTHubClient_Auth_Is_SasToken_Valid shall return SAS_TOKEN_STATUS_VALID. ] */
            result = SAS_TOKEN_STATUS_VALID;
        }
    }
    return result;
}
예제 #9
0
HTTPAPIEX_HANDLE HTTPAPIEX_Create(const char* hostName)
{
    HTTPAPIEX_HANDLE result;
    /*Codes_SRS_HTTPAPIEX_02_001: [If parameter hostName is NULL then HTTPAPIEX_Create shall return NULL.]*/
    if (hostName == NULL)
    {
        LogError("invalid (NULL) parameter\r\n");
        result = NULL;
    }
    else
    {
        /*Codes_SRS_HTTPAPIEX_02_005: [If creating the handle fails for any reason, then HTTAPIEX_Create shall return NULL.] */
        HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)malloc(sizeof(HTTPAPIEX_HANDLE_DATA));
        if (handleData == NULL)
        {
            LogError("malloc failed.\r\n");
            result = NULL;
        }
        else
        {
            /*Codes_SRS_HTTPAPIEX_02_002: [Parameter hostName shall be saved.]*/
            handleData->hostName = STRING_construct(hostName);
            if (handleData->hostName == NULL)
            {
                free(handleData);
                LogError("unable to STRING_construct\r\n");
                result = NULL;
            }
            else
            {
                /*Codes_SRS_HTTPAPIEX_02_004: [Otherwise, HTTPAPIEX_Create shall return a HTTAPIEX_HANDLE suitable for further calls to the module.] */
                handleData->savedOptions = VECTOR_create(sizeof(HTTPAPIEX_SAVED_OPTION));
                if (handleData->savedOptions == NULL)
                {
                    STRING_delete(handleData->hostName);
                    free(handleData);
                    result = NULL;
                }
                else
                {
                    handleData->k = -1;
                    handleData->httpHandle = NULL;
                    result = handleData;
                }
            }
        }
    }
    return result;
}
static STRING_HANDLE buildConfigForUsername(const IOTHUB_CLIENT_CONFIG* upperConfig)
{
    STRING_HANDLE result;

    size_t len = strlen(upperConfig->iotHubName)+strlen(upperConfig->iotHubSuffix)+strlen(upperConfig->deviceId)+strlen(CLIENT_DEVICE_TYPE_PREFIX)+strlen(IOTHUB_SDK_VERSION);
    char* eventTopic = malloc(len + BUILD_CONFIG_USERNAME + 1);
    if (eventTopic == NULL)
    {
        result = NULL;
    }
    else
    {
        (void)sprintf(eventTopic, "%s.%s/%s/DeviceClientType=%s%%2F%s", upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId, CLIENT_DEVICE_TYPE_PREFIX, IOTHUB_SDK_VERSION);
        result = STRING_construct(eventTopic);
        free(eventTopic);
    }
    return result;
}
static STRING_HANDLE ConstructMessageTopic(const char* deviceId)
{
    STRING_HANDLE result;
    size_t len = strlen(deviceId);

    char* messageTopic = malloc(len + 32 + 1);
    if (messageTopic == NULL)
    {
        result = NULL;
    }
    else
    {
        (void)sprintf(messageTopic, "devices/%s/messages/devicebound/#", deviceId);
        result = STRING_construct(messageTopic);
        free(messageTopic);
    }
    return result;
}
static STRING_HANDLE ConstructEventTopic(const char* deviceId)
{
    STRING_HANDLE result;
    size_t len = strlen(deviceId);

    char* eventTopic = malloc(len + EVENT_TOPIC_DEFAULT_LEN + 1);
    if (eventTopic == NULL)
    {
        result = NULL;
    }
    else
    {
        (void)sprintf(eventTopic, "devices/%s/messages/events/", deviceId);
        result = STRING_construct(eventTopic);
        free(eventTopic);
    }
    return result;
}
예제 #13
0
IOTHUB_MESSAGE_HANDLE IoTHubMessage_CreateFromString(const char* source)
{
    IOTHUB_MESSAGE_HANDLE_DATA* result;
    if (source == NULL)
    {
        LogError("Invalid argument - source is NULL");
        result = NULL;
    }
    else
    {
        result = (IOTHUB_MESSAGE_HANDLE_DATA*)malloc(sizeof(IOTHUB_MESSAGE_HANDLE_DATA));
        if (result == NULL)
        {
            LogError("malloc failed");
            /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
            /*let it go through*/
        }
        else
        {
            memset(result, 0, sizeof(*result));
            /*Codes_SRS_IOTHUBMESSAGE_02_032: [The type of the new message shall be IOTHUBMESSAGE_STRING.] */
            result->contentType = IOTHUBMESSAGE_STRING;
            
            /*Codes_SRS_IOTHUBMESSAGE_02_027: [IoTHubMessage_CreateFromString shall call STRING_construct passing source as parameter.] */
            if ((result->value.string = STRING_construct(source)) == NULL)
            {
                LogError("STRING_construct failed");
                /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
                DestroyMessageData(result);
                result = NULL;
            }
            /*Codes_SRS_IOTHUBMESSAGE_02_028: [IoTHubMessage_CreateFromString shall call Map_Create to create the message properties.] */
            else if ((result->properties = Map_Create(ValidateAsciiCharactersFilter)) == NULL)
            {
                LogError("Map_Create for properties failed");
                /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
                DestroyMessageData(result);
                result = NULL;
            }
            /*Codes_SRS_IOTHUBMESSAGE_02_031: [Otherwise, IoTHubMessage_CreateFromString shall return a non-NULL handle.] */
        }
    }
    return result;
}
MAP_HANDLE connectionstringparser_parse_from_char(const char* connection_string)
{
    MAP_HANDLE result;
    STRING_HANDLE connString = NULL;

    /* Codes_SRS_CONNECTIONSTRINGPARSER_21_020: [connectionstringparser_parse_from_char shall create a STRING_HANDLE from the connection_string passed in as argument and parse it using the connectionstringparser_parse.]*/
    if ((connString = STRING_construct(connection_string)) == NULL)
    {
        /* Codes_SRS_CONNECTIONSTRINGPARSER_21_021: [If connectionstringparser_parse_from_char get error creating a STRING_HANDLE, it shall return NULL.]*/
        LogError("Error constructing connection String");
        result = NULL;
    }
    else
    {
        result = connectionstringparser_parse(connString);
    }

    return result;
}
static STRING_HANDLE ConstructSasToken(const char* iothubName, const char* iotHubSuffix, const char* deviceId)
{
    STRING_HANDLE result;
    size_t len = strlen(iothubName);
    len += strlen(iotHubSuffix);
    len += strlen(deviceId);

    char* sasToken = malloc(len + SAS_TOKEN_DEFAULT_LEN + 1);
    if (sasToken == NULL)
    {
        result = NULL;
    }
    else
    {
        (void)sprintf(sasToken, "%s.%s/devices/%s", iothubName, iotHubSuffix, deviceId);
        result = STRING_construct(sasToken);
        free(sasToken);
    }
    return result;
}
예제 #16
0
IOTHUB_MESSAGE_HANDLE IoTHubMessage_CreateFromString(const char* source)
{
    IOTHUB_MESSAGE_HANDLE_DATA* result;
    result = malloc(sizeof(IOTHUB_MESSAGE_HANDLE_DATA));
    if (result == NULL)
    {
        LogError("malloc failed\r\n");
        /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
        /*let it go through*/
    }
    else
    {
        /*Codes_SRS_IOTHUBMESSAGE_02_027: [IoTHubMessage_CreateFromString shall call STRING_construct passing source as parameter.] */
        if ((result->value.string = STRING_construct(source)) == NULL)
        {
            LogError("STRING_construct failed\r\n");
            /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
            free(result);
            result = NULL;
        }
        /*Codes_SRS_IOTHUBMESSAGE_02_028: [IoTHubMessage_CreateFromString shall call Map_Create to create the message properties.] */
        else if ((result->properties = Map_Create(ValidateAsciiCharactersFilter)) == NULL)
        {
            LogError("Map_Create failed\r\n");
            /*Codes_SRS_IOTHUBMESSAGE_02_029: [If there are any encountered in the execution of IoTHubMessage_CreateFromString then IoTHubMessage_CreateFromString shall return NULL.] */
            STRING_delete(result->value.string);
            free(result);
            result = NULL;
        }
        else
        {
            /*Codes_SRS_IOTHUBMESSAGE_02_031: [Otherwise, IoTHubMessage_CreateFromString shall return a non-NULL handle.] */
            /*Codes_SRS_IOTHUBMESSAGE_02_032: [The type of the new message shall be IOTHUBMESSAGE_STRING.] */
            result->contentType = IOTHUBMESSAGE_STRING;
            result->messageId = NULL;
            result->correlationId = NULL;
        }
    }
    return result;
}
예제 #17
0
STRING_HANDLE URL_EncodeString(const char* textEncode)
{
    STRING_HANDLE result;
    if (textEncode == NULL)
    {
        result = NULL;
    }
    else
    {
        STRING_HANDLE tempString = STRING_construct(textEncode);
        if (tempString == NULL)
        {
            result = NULL;
        }
        else
        {
            result = URL_Encode(tempString);
            STRING_delete(tempString);
        }
    }
    return result;
}
static STRING_HANDLE create_registration_path(const char* path_format, const char* id)
{
    STRING_HANDLE registration_path;

    if (id == NULL)
    {
        registration_path = STRING_construct(path_format);
    }
    else
    {
        STRING_HANDLE encoded_id;
        if ((encoded_id = URL_EncodeString(id)) == NULL)
        {
            LogError("Unable to URL encode ID");
            registration_path = NULL;
        }
        else
        {
            registration_path = STRING_construct_sprintf(path_format, STRING_c_str(encoded_id));
            STRING_delete(encoded_id);
        }
    }

    if (registration_path == NULL)
    {
        LogError("Failed constructing base path");
    }
    else if (STRING_sprintf(registration_path, API_VERSION_QUERY_PARAM, PROVISIONING_SERVICE_API_VERSION) != 0)
    {
        LogError("Unable to add query paramters");
        STRING_delete(registration_path);
        registration_path = NULL;
    }

    return registration_path;
}
AUTHENTICATION_HANDLE authentication_create(const AUTHENTICATION_CONFIG* config)
{
    AUTHENTICATION_HANDLE result;

    // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_001: [If parameter `config` is NULL, authentication_create() shall fail and return NULL.]
    if (config == NULL)
    {
        result = NULL;
        LogError("authentication_create failed (config is NULL)");
    }
    else if (config->authorization_module == NULL)
    {
        result = NULL;
        LogError("authentication_create failed (config->authorization_module is NULL)");
    }
    // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_004: [If `config->iothub_host_fqdn` is NULL, authentication_create() shall fail and return NULL.]
    else if (config->iothub_host_fqdn == NULL)
    {
        result = NULL;
        LogError("authentication_create failed (config->iothub_host_fqdn is NULL)");
    }
    // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_005: [If `config->on_state_changed_callback` is NULL, authentication_create() shall fail and return NULL]
    else if (config->on_state_changed_callback == NULL)
    {
        result = NULL;
        LogError("authentication_create failed (config->on_state_changed_callback is NULL)");
    }
    else
    {
        AUTHENTICATION_INSTANCE* instance;

        // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_006: [authentication_create() shall allocate memory for a new authenticate state structure AUTHENTICATION_INSTANCE.]
        if ((instance = (AUTHENTICATION_INSTANCE*)malloc(sizeof(AUTHENTICATION_INSTANCE))) == NULL)
        {
            // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_007: [If malloc() fails, authentication_create() shall fail and return NULL.]
            result = NULL;
            LogError("authentication_create failed (malloc failed)");
        }
        else
        {
            // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_123: [authentication_create() shall initialize all fields of `instance` with 0 using memset().]
            memset(instance, 0, sizeof(AUTHENTICATION_INSTANCE));

            // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_008: [authentication_create() shall save the device_id into the `instance->device_id`]
            if ((instance->device_id = IoTHubClient_Auth_Get_DeviceId(config->authorization_module) ) == NULL)
            {
                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_009: [If STRING_construct() fails, authentication_create() shall fail and return NULL]
                result = NULL;
                LogError("authentication_create failed (config->device_id could not be copied; STRING_construct failed)");
            }
            // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_016: [If provided, authentication_create() shall save a copy of `config->iothub_host_fqdn` into `instance->iothub_host_fqdn`]
            else if ((instance->iothub_host_fqdn = STRING_construct(config->iothub_host_fqdn)) == NULL)
            {
                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_017: [If STRING_clone() fails to copy `config->iothub_host_fqdn`, authentication_create() shall fail and return NULL]
                result = NULL;
                LogError("authentication_create failed (config->iothub_host_fqdn could not be copied; STRING_construct failed)");
            }
            else
            {
                instance->state = AUTHENTICATION_STATE_STOPPED;

                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_018: [authentication_create() shall save `config->on_state_changed_callback` and `config->on_state_changed_callback_context` into `instance->on_state_changed_callback` and `instance->on_state_changed_callback_context`.]
                instance->on_state_changed_callback = config->on_state_changed_callback;
                instance->on_state_changed_callback_context = config->on_state_changed_callback_context;

                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_019: [authentication_create() shall save `config->on_error_callback` and `config->on_error_callback_context` into `instance->on_error_callback` and `instance->on_error_callback_context`.]
                instance->on_error_callback = config->on_error_callback;
                instance->on_error_callback_context = config->on_error_callback_context;

                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_021: [authentication_create() shall set `instance->cbs_request_timeout_secs` with the default value of UINT32_MAX]
                instance->cbs_request_timeout_secs = DEFAULT_CBS_REQUEST_TIMEOUT_SECS;
                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_022: [authentication_create() shall set `instance->sas_token_lifetime_secs` with the default value of one hour]
                instance->sas_token_lifetime_secs = DEFAULT_SAS_TOKEN_LIFETIME_SECS;
                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_023: [authentication_create() shall set `instance->sas_token_refresh_time_secs` with the default value of 30 minutes]
                instance->sas_token_refresh_time_secs = DEFAULT_SAS_TOKEN_REFRESH_TIME_SECS;

                instance->authorization_module = config->authorization_module;

                // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_024: [If no failure occurs, authentication_create() shall return a reference to the AUTHENTICATION_INSTANCE handle]
                result = (AUTHENTICATION_HANDLE)instance;
            }

            // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_020: [If any failure occurs, authentication_create() shall free any memory it allocated previously]
            if (result == NULL)
            {
                authentication_destroy((AUTHENTICATION_HANDLE)instance);
            }
        }
    }
    
    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;
}
static void* NodeModuleLoader_ParseEntrypointFromJson(const MODULE_LOADER* loader, const JSON_Value* json)
{
    (void)loader;

    // The input is a JSON object that looks like this:
    //  "entrypoint": {
    //      "main.path": "path/to/module"
    //  }
    NODE_LOADER_ENTRYPOINT* config;
    if (json == NULL)
    {
        LogError("json is NULL");
        //Codes_SRS_NODE_MODULE_LOADER_13_011: [ NodeModuleLoader_ParseEntrypointFromJson shall return NULL if json is NULL. ]
        config = NULL;
    }
    else
    {
        // "json" must be an "object" type
        if (json_value_get_type(json) != JSONObject)
        {
            LogError("'json' is not an object value");
            //Codes_SRS_NODE_MODULE_LOADER_13_012: [ NodeModuleLoader_ParseEntrypointFromJson shall return NULL if the root json entity is not an object. ]
            config = NULL;
        }
        else
        {
            JSON_Object* entrypoint = json_value_get_object(json);
            if (entrypoint == NULL)
            {
                LogError("json_value_get_object failed");
                //Codes_SRS_NODE_MODULE_LOADER_13_013: [ NodeModuleLoader_ParseEntrypointFromJson shall return NULL if an underlying platform call fails. ]
                config = NULL;
            }
            else
            {
                //Codes_SRS_NODE_MODULE_LOADER_13_014: [ NodeModuleLoader_ParseEntrypointFromJson shall retrieve the path to the main JS file by reading the value of the attribute main.path. ]
                const char* mainPath = json_object_get_string(entrypoint, "main.path");
                if (mainPath == NULL)
                {
                    LogError("json_object_get_string for 'main.path' returned NULL");
                    //Codes_SRS_NODE_MODULE_LOADER_13_039: [ NodeModuleLoader_ParseEntrypointFromJson shall return NULL if main.path does not exist. ]
                    config = NULL;
                }
                else
                {
                    config = (NODE_LOADER_ENTRYPOINT*)malloc(sizeof(NODE_LOADER_ENTRYPOINT));
                    if (config != NULL)
                    {
                        config->mainPath = STRING_construct(mainPath);
                        if (config->mainPath == NULL)
                        {
                            LogError("STRING_construct failed");
                            free(config);
                            //Codes_SRS_NODE_MODULE_LOADER_13_013: [ NodeModuleLoader_ParseEntrypointFromJson shall return NULL if an underlying platform call fails. ]
                            config = NULL;
                        }
                        else
                        {
                            /**
                             * Everything's good.
                             */
                        }
                    }
                    else
                    {
                        //Codes_SRS_NODE_MODULE_LOADER_13_013: [ NodeModuleLoader_ParseEntrypointFromJson shall return NULL if an underlying platform call fails. ]
                        LogError("malloc failed");
                    }
                }
            }
        }
    }

    //Codes_SRS_NODE_MODULE_LOADER_13_015: [ NodeModuleLoader_ParseEntrypointFromJson shall return a non-NULL pointer to the parsed representation of the entrypoint when successful. ]
    return (void*)config;
}
예제 #22
0
MQTTAPI_RESULT MQTTAPI_PublishMessage(MQTTAPI_HANDLE instance, const char* topicName, const MQTTAPI_Message* msg, void* context)
{
	MQTTAPI_RESULT result;
	PMQTTTAPI_HANDLE_DATA mqttApiHandleData = (PMQTTTAPI_HANDLE_DATA)instance;

	/* Codes_SRS_MQTTAPI_04_038: [If any of the parameter is NULL, MQTTAPI_PublishMessage shall return MQTTAPI_INVALID_ARG.] */
	if (instance == NULL)
	{
		LogError("Invalid Argument. instance can't be null.\r\n");
		result = MQTTAPI_INVALID_ARG;
	}
	/* Codes_SRS_MQTTAPI_04_038: [If any of the parameter is NULL, MQTTAPI_PublishMessage shall return MQTTAPI_INVALID_ARG.] */
	else if (topicName == NULL || strlen(topicName) <= 0)
	{
		LogError("Invalid Argument. topicName can't be null or empty.\r\n");
		result = MQTTAPI_INVALID_ARG;
	}
	/* Codes_SRS_MQTTAPI_04_038: [If any of the parameter is NULL, MQTTAPI_PublishMessage shall return MQTTAPI_INVALID_ARG.] */
	else if (msg == NULL)
	{
		LogError("Invalid Argument. msg can't be null.\r\n");
		result = MQTTAPI_INVALID_ARG;
	}
	/* Codes_SRS_MQTTAPI_04_059: [If DeliveryCompleted callback is not set publishMessage shall return MQTTAPI_ERROR.] */
	else if (mqttApiHandleData->dcCallback == NULL)
	{
		LogError("Error Sending data, missind Delivery Completed callback to be set.\r\n");
		result = MQTTAPI_ERROR;
	}
	else
	{
		MQTTAPI_MESSAGE_SEND_LIST* mqttApiMessageEntryList; 

		/* Codes_SRS_MQTTAPI_04_039: [MQTTAPI_PublishMessage shall create structure needed to send a message to the topic described by the topicName parameter.]  */
		if ((mqttApiMessageEntryList = (MQTTAPI_MESSAGE_SEND_LIST*)malloc(sizeof(MQTTAPI_MESSAGE_SEND_LIST))) == NULL)
		{
			LogError("Memmory Allocation failure to create mqttApi Message.\r\n");
			result = MQTTAPI_ERROR;
		}
		else if ((mqttApiMessageEntryList->topicName = STRING_construct(topicName)) == NULL)
{
			LogError("Could not create topicName String.\r\n");
			free(mqttApiMessageEntryList);
			result = MQTTAPI_ERROR;
}
		else
		{
			MQTTClient_message *pubmsg = (MQTTClient_message *)malloc(sizeof(MQTTClient_message));

			if (pubmsg == NULL)
			{
				LogError("Memory Allocation Failure to create MQTTClient_message.\r\n");
				STRING_delete(mqttApiMessageEntryList->topicName);
				free(mqttApiMessageEntryList);
				result = MQTTAPI_ERROR;
			}
			else 
			{
				pubmsg->struct_id[0] = 'M';
				pubmsg->struct_id[1] = 'Q';
				pubmsg->struct_id[2] = 'T';
				pubmsg->struct_id[3] = 'M';
				pubmsg->struct_version = 0;
				pubmsg->qos = SENDMESSAGEQOS;
				pubmsg->retained = 0;
				pubmsg->dup = 0;
				pubmsg->msgid = 0;
				pubmsg->payloadlen = msg->payloadlen;

				/* Codes_SRS_MQTTAPI_04_043: [MQTTAPI_PublishMessage shall clone MQTTAPI_Message so the user can free it after calling publishMessage.]  */
				if ((pubmsg->payload = malloc(msg->payloadlen)) == NULL)
				{
					LogError("Memory Allocation Failure to create MQTTClient_message.\r\n");
					free(pubmsg);
					STRING_delete(mqttApiMessageEntryList->topicName);
					free(mqttApiMessageEntryList);
					result = MQTTAPI_ERROR;
				}
				else
{
					(void)memcpy(pubmsg->payload, msg->payload, msg->payloadlen);
					/* Codes_SRS_MQTTAPI_04_058: [If context is not NULL it shall be stored and passed to the user when received callback function is called.]  */
					mqttApiMessageEntryList->context = context;
					mqttApiMessageEntryList->messageToSend = pubmsg;
					DList_InsertHeadList(&(mqttApiHandleData->messagesToSend), &(mqttApiMessageEntryList->entry));

					/* Codes_SRS_MQTTAPI_04_048: [If the message was correctly queued (on it’s on a queue on underlying library) MQTTAPI_PublishMessage shall return MQTTAPI_OK.] */
					result = MQTTAPI_OK;
				}
			}
		}
	}

	return result;
}
예제 #23
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;
}
예제 #24
0
BLOB_RESULT Blob_UploadMultipleBlocksFromSasUri(const char* SASURI, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context, unsigned int* httpStatus, BUFFER_HANDLE httpResponse, const char* certificates, HTTP_PROXY_OPTIONS *proxyOptions)
{
    BLOB_RESULT result;
    /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
    if (SASURI == NULL)
    {
        LogError("parameter SASURI is NULL");
        result = BLOB_INVALID_ARG;
    }
    else
    {
        /*Codes_SRS_BLOB_02_002: [ If getDataCallbackEx is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
        if (getDataCallbackEx == NULL)
        {
            LogError("IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx is NULL");
            result = BLOB_INVALID_ARG;
        }
        /*the below define avoid a "condition always false" on some compilers*/
        else
        {
            /*Codes_SRS_BLOB_02_017: [ Blob_UploadMultipleBlocksFromSasUri shall copy from SASURI the hostname to a new const char* ]*/
            /*to find the hostname, the following logic is applied:*/
            /*the hostname starts at the first character after "://"*/
            /*the hostname ends at the first character before the next "/" after "://"*/
            const char* hostnameBegin = strstr(SASURI, "://");
            if (hostnameBegin == NULL)
            {
                /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                LogError("hostname cannot be determined");
                result = BLOB_INVALID_ARG;
            }
            else
            {
                hostnameBegin += 3; /*have to skip 3 characters which are "://"*/
                const char* hostnameEnd = strchr(hostnameBegin, '/');
                if (hostnameEnd == NULL)
                {
                    /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                    LogError("hostname cannot be determined");
                    result = BLOB_INVALID_ARG;
                }
                else
                {
                    size_t hostnameSize = hostnameEnd - hostnameBegin;
                    char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/
                    if (hostname == NULL)
                    {
                        /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                        LogError("oom - out of memory");
                        result = BLOB_ERROR;
                    }
                    else
                    {
                        HTTPAPIEX_HANDLE httpApiExHandle;
                        (void)memcpy(hostname, hostnameBegin, hostnameSize);
                        hostname[hostnameSize] = '\0';

                        /*Codes_SRS_BLOB_02_018: [ Blob_UploadMultipleBlocksFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
                        httpApiExHandle = HTTPAPIEX_Create(hostname);
                        if (httpApiExHandle == NULL)
                        {
                            /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR. ]*/
                            LogError("unable to create a HTTPAPIEX_HANDLE");
                            result = BLOB_ERROR;
                        }
                        else
                        {
                            if ((certificates != NULL)&& (HTTPAPIEX_SetOption(httpApiExHandle, "TrustedCerts", certificates) == HTTPAPIEX_ERROR))
                            {
                                LogError("failure in setting trusted certificates");
                                result = BLOB_ERROR;
                            }
                            else if ((proxyOptions != NULL && proxyOptions->host_address != NULL) && HTTPAPIEX_SetOption(httpApiExHandle, OPTION_HTTP_PROXY, proxyOptions) == HTTPAPIEX_ERROR)
                            {
                                LogError("failure in setting proxy options");
                                result = BLOB_ERROR;
                            }
                            else
                            {
                                /*Codes_SRS_BLOB_02_019: [ Blob_UploadMultipleBlocksFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/
                                const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/

                                /*Codes_SRS_BLOB_02_028: [ Blob_UploadMultipleBlocksFromSasUri shall construct an XML string with the following content: ]*/
                                STRING_HANDLE blockIDList = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/
                                if (blockIDList == NULL)
                                {
                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                    LogError("failed to STRING_construct");
                                    result = BLOB_HTTP_ERROR;
                                }
                                else
                                {
                                    /*Codes_SRS_BLOB_02_021: [ For every block returned by `getDataCallbackEx` the following operations shall happen: ]*/
                                    unsigned int blockID = 0; /* incremented for each new block */
                                    unsigned int isError = 0; /* set to 1 if a block upload fails or if getDataCallbackEx returns incorrect blocks to upload */
                                    unsigned int uploadOneMoreBlock = 1; /* set to 1 while getDataCallbackEx returns correct blocks to upload */
                                    unsigned char const * source; /* data set by getDataCallbackEx */
                                    size_t size; /* source size set by getDataCallbackEx */
                                    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT getDataReturnValue;

                                    do
                                    {
                                        getDataReturnValue = getDataCallbackEx(FILE_UPLOAD_OK, &source, &size, context);
                                        if (getDataReturnValue == IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT)
                                        {
                                            /*Codes_SRS_BLOB_99_004: [ If `getDataCallbackEx` returns `IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_ABORT`, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop and return `BLOB_ABORTED`. ]*/
                                            LogInfo("Upload to blob has been aborted by the user");
                                            uploadOneMoreBlock = 0;
                                            result = BLOB_ABORTED;
                                        }
                                        else if (source == NULL || size == 0)
                                        {
                                            /*Codes_SRS_BLOB_99_002: [ If the size of the block returned by `getDataCallbackEx` is 0 or if the data is NULL, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop. ]*/
                                            uploadOneMoreBlock = 0;
                                            result = BLOB_OK;
                                        }
                                        else
                                        {
                                            if (size > BLOCK_SIZE)
                                            {
                                                /*Codes_SRS_BLOB_99_001: [ If the size of the block returned by `getDataCallbackEx` is bigger than 4MB, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/
                                                LogError("tried to upload block of size %lu, max allowed size is %d", (unsigned long)size, BLOCK_SIZE);
                                                result = BLOB_INVALID_ARG;
                                                isError = 1;
                                            }
                                            else if (blockID >= MAX_BLOCK_COUNT)
                                            {
                                                /*Codes_SRS_BLOB_99_003: [ If `getDataCallbackEx` returns more than 50000 blocks, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/
                                                LogError("unable to upload more than %lu blocks in one blob", (unsigned long)MAX_BLOCK_COUNT);
                                                result = BLOB_INVALID_ARG;
                                                isError = 1;
                                            }
                                            else
                                            {
                                                /*Codes_SRS_BLOB_02_023: [ Blob_UploadMultipleBlocksFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
                                                BUFFER_HANDLE requestContent = BUFFER_create(source, size);
                                                if (requestContent == NULL)
                                                {
                                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                                    LogError("unable to BUFFER_create");
                                                    result = BLOB_ERROR;
                                                    isError = 1;
                                                }
                                                else
                                                {
                                                    result = Blob_UploadBlock(
                                                            httpApiExHandle,
                                                            relativePath,
                                                            requestContent,
                                                            blockID,
                                                            blockIDList,
                                                            httpStatus,
                                                            httpResponse);

                                                    BUFFER_delete(requestContent);
                                                }

                                                /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
                                                if (result != BLOB_OK || *httpStatus >= 300)
                                                {
                                                    LogError("unable to Blob_UploadBlock. Returned value=%d, httpStatus=%u", result, (unsigned int)*httpStatus);
                                                    isError = 1;
                                                }
                                            }
                                            blockID++;
                                        }
                                    }
                                    while(uploadOneMoreBlock && !isError);

                                    if (isError || result != BLOB_OK)
                                    {
                                        /*do nothing, it will be reported "as is"*/
                                    }
                                    else
                                    {
                                        /*complete the XML*/
                                        if (STRING_concat(blockIDList, "</BlockList>") != 0)
                                        {
                                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                            LogError("failed to STRING_concat");
                                            result = BLOB_ERROR;
                                        }
                                        else
                                        {
                                            /*Codes_SRS_BLOB_02_029: [Blob_UploadMultipleBlocksFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/
                                            STRING_HANDLE newRelativePath = STRING_construct(relativePath);
                                            if (newRelativePath == NULL)
                                            {
                                                /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                                LogError("failed to STRING_construct");
                                                result = BLOB_ERROR;
                                            }
                                            else
                                            {
                                                if (STRING_concat(newRelativePath, "&comp=blocklist") != 0)
                                                {
                                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                                    LogError("failed to STRING_concat");
                                                    result = BLOB_ERROR;
                                                }
                                                else
                                                {
                                                    /*Codes_SRS_BLOB_02_030: [ Blob_UploadMultipleBlocksFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/
                                                    const char* s = STRING_c_str(blockIDList);
                                                    BUFFER_HANDLE blockIDListAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s));
                                                    if (blockIDListAsBuffer == NULL)
                                                    {
                                                        /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                                        LogError("failed to BUFFER_create");
                                                        result = BLOB_ERROR;
                                                    }
                                                    else
                                                    {
                                                        if (HTTPAPIEX_ExecuteRequest(
                                                            httpApiExHandle,
                                                            HTTPAPI_REQUEST_PUT,
                                                            STRING_c_str(newRelativePath),
                                                            NULL,
                                                            blockIDListAsBuffer,
                                                            httpStatus,
                                                            NULL,
                                                            httpResponse
                                                        ) != HTTPAPIEX_OK)
                                                        {
                                                            /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                            LogError("unable to HTTPAPIEX_ExecuteRequest");
                                                            result = BLOB_HTTP_ERROR;
                                                        }
                                                        else
                                                        {
                                                            /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
                                                            result = BLOB_OK;
                                                        }
                                                        BUFFER_delete(blockIDListAsBuffer);
                                                    }
                                                }
                                                STRING_delete(newRelativePath);
                                            }
                                        }
                                    }
                                    STRING_delete(blockIDList);
                                }

                            }
                            HTTPAPIEX_Destroy(httpApiExHandle);
                        }
                        free(hostname);
                    }
                }
            }
        }
    }
    return result;
}
예제 #25
0
IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
{
    IOTHUB_CLIENT_LL_HANDLE result = NULL;

    /*Codes_SRS_IOTHUBCLIENT_LL_05_001: [IoTHubClient_LL_CreateFromConnectionString shall obtain the version string by a call to IoTHubClient_GetVersionString.]*/
    /*Codes_SRS_IOTHUBCLIENT_LL_05_002: [IoTHubClient_LL_CreateFromConnectionString shall print the version string to standard output.]*/
    LogInfo("IoT Hub SDK for C, version %s", IoTHubClient_GetVersionString());

    /* Codes_SRS_IOTHUBCLIENT_LL_12_003: [IoTHubClient_LL_CreateFromConnectionString shall verify the input parameter and if it is NULL then return NULL] */
    if (connectionString == NULL)
    {
        LogError("Input parameter is NULL: connectionString");
    }
    else if (protocol == NULL)
    {
        LogError("Input parameter is NULL: protocol");
    }
    else
    {
        /* Codes_SRS_IOTHUBCLIENT_LL_12_004: [IoTHubClient_LL_CreateFromConnectionString shall allocate IOTHUB_CLIENT_CONFIG structure] */
        IOTHUB_CLIENT_CONFIG* config = malloc(sizeof(IOTHUB_CLIENT_CONFIG));
        if (config == NULL)
        {
            /* Codes_SRS_IOTHUBCLIENT_LL_12_012: [If the allocation failed IoTHubClient_LL_CreateFromConnectionString  returns NULL]  */
            LogError("Malloc failed");
            return NULL;
        }
        else
        {
            STRING_TOKENIZER_HANDLE tokenizer1 = NULL;
            STRING_HANDLE connString = NULL;
            STRING_HANDLE tokenString = NULL;
            STRING_HANDLE valueString = NULL;
            STRING_HANDLE hostNameString = NULL;
            STRING_HANDLE hostSuffixString = NULL;
            STRING_HANDLE deviceIdString = NULL;
            STRING_HANDLE deviceKeyString = NULL;
            STRING_HANDLE deviceSasTokenString = NULL;
            STRING_HANDLE protocolGateway = NULL;

            config->protocol = protocol;

            config->iotHubName = NULL;
            config->iotHubSuffix = NULL;
            config->deviceId = NULL;
            config->deviceKey = NULL;
            config->deviceSasToken = NULL;

            /* Codes_SRS_IOTHUBCLIENT_LL_04_002: [If it does not, it shall pass the protocolGatewayHostName NULL.] */
            config->protocolGatewayHostName = NULL;

            if ((connString = STRING_construct(connectionString)) == NULL)
            {
                LogError("Error constructing connectiong String");
            }
            else if ((tokenizer1 = STRING_TOKENIZER_create(connString)) == NULL)
            {
                LogError("Error creating Tokenizer");
            }
            else if ((tokenString = STRING_new()) == NULL)
            {
                LogError("Error creating Token String");
            }
            else if ((valueString = STRING_new()) == NULL)
            {
                LogError("Error creating Value String");
            }
            else if ((hostNameString = STRING_new()) == NULL)
            {
                LogError("Error creating HostName String");
            }
            else if ((hostSuffixString = STRING_new()) == NULL)
            {
                LogError("Error creating HostSuffix String");
            }
            /* Codes_SRS_IOTHUBCLIENT_LL_12_005: [IoTHubClient_LL_CreateFromConnectionString shall try to parse the connectionString input parameter for the following structure: "Key1=value1;key2=value2;key3=value3..."] */
            /* Codes_SRS_IOTHUBCLIENT_LL_12_006: [IoTHubClient_LL_CreateFromConnectionString shall verify the existence of the following Key/Value pairs in the connection string: HostName, DeviceId, SharedAccessKey or SharedAccessSignature.]  */
            else
            {
                while ((STRING_TOKENIZER_get_next_token(tokenizer1, tokenString, "=") == 0))
                {
                    if (STRING_TOKENIZER_get_next_token(tokenizer1, valueString, ";") != 0)
                    {
                        LogError("Tokenizer error");
                        break;
                    }
                    else
                    {
                        if (tokenString != NULL)
                        {
                            /* Codes_SRS_IOTHUBCLIENT_LL_12_010: [IoTHubClient_LL_CreateFromConnectionString shall fill up the IOTHUB_CLIENT_CONFIG structure using the following mapping: iotHubName = Name, iotHubSuffix = Suffix, deviceId = DeviceId, deviceKey = SharedAccessKey or deviceSasToken = SharedAccessSignature] */
                            const char* s_token = STRING_c_str(tokenString);
                            if (strcmp(s_token, HOSTNAME_TOKEN) == 0)
                            {
                                /* Codes_SRS_IOTHUBCLIENT_LL_12_009: [IoTHubClient_LL_CreateFromConnectionString shall split the value of HostName to Name and Suffix using the first "." as a separator] */
                                STRING_TOKENIZER_HANDLE tokenizer2 = NULL;
                                if ((tokenizer2 = STRING_TOKENIZER_create(valueString)) == NULL)
                                {
                                    LogError("Error creating Tokenizer");
                                    break;
                                }
                                else
                                {
                                    /* Codes_SRS_IOTHUBCLIENT_LL_12_015: [If the string split failed, IoTHubClient_LL_CreateFromConnectionString returns NULL ] */
                                    if (STRING_TOKENIZER_get_next_token(tokenizer2, hostNameString, ".") != 0)
                                    {
                                        LogError("Tokenizer error");
                                        STRING_TOKENIZER_destroy(tokenizer2);
                                        break;
                                    }
                                    else
                                    {
                                        config->iotHubName = STRING_c_str(hostNameString);
                                        if (STRING_TOKENIZER_get_next_token(tokenizer2, hostSuffixString, ";") != 0)
                                        {
                                            LogError("Tokenizer error");
                                            STRING_TOKENIZER_destroy(tokenizer2);
                                            break;
                                        }
                                        else
                                        {
                                            config->iotHubSuffix = STRING_c_str(hostSuffixString);
                                        }
                                    }
                                    STRING_TOKENIZER_destroy(tokenizer2);
                                }
                            }
                            else if (strcmp(s_token, DEVICEID_TOKEN) == 0)
                            {
                                deviceIdString = STRING_clone(valueString);
                                if (deviceIdString != NULL)
                                {
                                    config->deviceId = STRING_c_str(deviceIdString);
                                }
                            }
                            else if (strcmp(s_token, DEVICEKEY_TOKEN) == 0)
                            {
                                deviceKeyString = STRING_clone(valueString);
                                if (deviceKeyString != NULL)
                                {
                                    config->deviceKey = STRING_c_str(deviceKeyString);
                                }
                            }
                            else if (strcmp(s_token, DEVICESAS_TOKEN) == 0)
                            {
                                deviceSasTokenString = STRING_clone(valueString);
                                if (deviceSasTokenString != NULL)
                                {
                                    config->deviceSasToken = STRING_c_str(deviceSasTokenString);
                                }
                            }
                            /* Codes_SRS_IOTHUBCLIENT_LL_04_001: [IoTHubClient_LL_CreateFromConnectionString shall verify the existence of key/value pair GatewayHostName. If it does exist it shall pass the value to IoTHubClient_LL_Create API.] */
                            else if (strcmp(s_token, PROTOCOL_GATEWAY_HOST) == 0)
                            {
                                protocolGateway = STRING_clone(valueString);
                                if (protocolGateway != NULL)
                                {
                                    config->protocolGatewayHostName = STRING_c_str(protocolGateway);
                                }
                            }
                        }
                    }
                }
                /* parsing is done - check the result */
                if (config->iotHubName == NULL)
                {
                    LogError("iotHubName is not found");
                }
                else if (config->iotHubSuffix == NULL)
                {
                    LogError("iotHubSuffix is not found");
                }
                else if (config->deviceId == NULL)
                {
                    LogError("deviceId is not found");
                }
                else if (config->deviceKey == NULL && config->deviceSasToken == NULL)
                {
                    LogError("deviceKey/deviceSasToken not found");
                }
                else if (config->deviceKey != NULL && config->deviceSasToken != NULL)
                {
                    LogError("Both device Key & SAS token are defined. Only one should be provided.");
                }
                else
                {
                    /* Codes_SRS_IOTHUBCLIENT_LL_12_011: [IoTHubClient_LL_CreateFromConnectionString shall call into the IoTHubClient_LL_Create API with the current structure and returns with the return value of it] */
                    
                    result = IoTHubClient_LL_Create(config);
                    if (result == NULL)
                    {
                        LogError("IoTHubClient_LL_Create failed");
                    }
                    else
                    {
                        /*return as is*/
                    }
                }
            }
            if (deviceSasTokenString != NULL)
                STRING_delete(deviceSasTokenString);
            if (deviceKeyString != NULL)
                STRING_delete(deviceKeyString);
            if (deviceIdString != NULL)
                STRING_delete(deviceIdString);
            if (hostSuffixString != NULL)
                STRING_delete(hostSuffixString);
            if (hostNameString != NULL)
                STRING_delete(hostNameString);
            if (valueString != NULL)
                STRING_delete(valueString);
            if (tokenString != NULL)
                STRING_delete(tokenString);
            if (connString != NULL)
                STRING_delete(connString);
            if (protocolGateway != NULL)
                STRING_delete(protocolGateway);

            if (tokenizer1 != NULL)
                STRING_TOKENIZER_destroy(tokenizer1);

            free(config);
        }
    }
    return result;
}
예제 #26
0
BLOB_RESULT Blob_UploadFromSasUri(const char* SASURI, const unsigned char* source, size_t size, unsigned int* httpStatus, BUFFER_HANDLE httpResponse)
{
    BLOB_RESULT result;
    /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
    if (SASURI == NULL)
    {
        LogError("parameter SASURI is NULL");
        result = BLOB_INVALID_ARG;
    }
    else
    {
        /*Codes_SRS_BLOB_02_002: [ If source is NULL and size is not zero then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
        if (
            (size > 0) &&
            (source == NULL)
            )
        {
            LogError("combination of source = %p and size = %zu is invalid", source, size);
            result = BLOB_INVALID_ARG;
        }
        /*Codes_SRS_BLOB_02_034: [ If size is bigger than 50000*4*1024*1024 then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
        else if (size > 50000ULL * 4 * 1024 * 1024) /*https://msdn.microsoft.com/en-us/library/azure/dd179467.aspx says "Each block can be a different size, up to a maximum of 4 MB, and a block blob can include a maximum of 50,000 blocks."*/
        {
            LogError("size too big (%zu)", size);
            result = BLOB_INVALID_ARG;
        }
        else
        {
            /*Codes_SRS_BLOB_02_017: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char* ]*/
            /*Codes_SRS_BLOB_02_004: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char*. ]*/
            /*to find the hostname, the following logic is applied:*/
            /*the hostname starts at the first character after "://"*/
            /*the hostname ends at the first character before the next "/" after "://"*/
            const char* hostnameBegin = strstr(SASURI, "://");
            if (hostnameBegin == NULL)
            {
                /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                LogError("hostname cannot be determined");
                result = BLOB_INVALID_ARG;
            }
            else
            {
                hostnameBegin += 3; /*have to skip 3 characters which are "://"*/
                const char* hostnameEnd = strchr(hostnameBegin, '/');
                if (hostnameEnd == NULL)
                {
                    /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                    LogError("hostname cannot be determined");
                    result = BLOB_INVALID_ARG;
                }
                else
                {
                    size_t hostnameSize = hostnameEnd - hostnameBegin;
                    char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/
                    if (hostname == NULL)
                    {
                        /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                        LogError("oom - out of memory");
                        result = BLOB_ERROR;
                    }
                    else
                    {
                        HTTPAPIEX_HANDLE httpApiExHandle;
                        memcpy(hostname, hostnameBegin, hostnameSize);
                        hostname[hostnameSize] = '\0';

                        /*Codes_SRS_BLOB_02_006: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
                        /*Codes_SRS_BLOB_02_018: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
                        httpApiExHandle = HTTPAPIEX_Create(hostname);
                        if (httpApiExHandle == NULL)
                        {
                            /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/
                            LogError("unable to create a HTTPAPIEX_HANDLE");
                            result = BLOB_ERROR;
                        }
                        else
                        {
                            /*Codes_SRS_BLOB_02_008: [ Blob_UploadFromSasUri shall compute the relative path of the request from the SASURI parameter. ]*/
                            /*Codes_SRS_BLOB_02_019: [ Blob_UploadFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/
                            const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/

                            if (size < 64 * 1024 * 1024) /*code path for sizes <64MB*/
                            {
                                /*Codes_SRS_BLOB_02_010: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
                                BUFFER_HANDLE requestBuffer = BUFFER_create(source, size);
                                if (requestBuffer == NULL)
                                {
                                    /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/
                                    LogError("unable to BUFFER_create");
                                    result = BLOB_ERROR;
                                }
                                else
                                {
                                    /*Codes_SRS_BLOB_02_009: [ Blob_UploadFromSasUri shall create an HTTP_HEADERS_HANDLE for the request HTTP headers carrying the following headers: ]*/
                                    HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc();
                                    if (requestHttpHeaders == NULL)
                                    {
                                        /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/
                                        LogError("unable to HTTPHeaders_Alloc");
                                        result = BLOB_ERROR;
                                    }
                                    else
                                    {
                                        if (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "x-ms-blob-type", "BlockBlob") != HTTP_HEADERS_OK)
                                        {
                                            /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/
                                            LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
                                            result = BLOB_ERROR;
                                        }
                                        else
                                        {
                                            /*Codes_SRS_BLOB_02_012: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest passing the parameters previously build, httpStatus and httpResponse ]*/
                                            if (HTTPAPIEX_ExecuteRequest(httpApiExHandle, HTTPAPI_REQUEST_PUT, relativePath, requestHttpHeaders, requestBuffer, httpStatus, NULL, httpResponse) != HTTPAPIEX_OK)
                                            {
                                                /*Codes_SRS_BLOB_02_013: [ If HTTPAPIEX_ExecuteRequest fails, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                LogError("failed to HTTPAPIEX_ExecuteRequest");
                                                result = BLOB_HTTP_ERROR;
                                            }
                                            else
                                            {
                                                /*Codes_SRS_BLOB_02_015: [ Otherwise, HTTPAPIEX_ExecuteRequest shall succeed and return BLOB_OK. ]*/
                                                result = BLOB_OK;
                                            }
                                        }
                                        HTTPHeaders_Free(requestHttpHeaders);
                                    }
                                    BUFFER_delete(requestBuffer);
                                }
                            }
                            else /*code path for size >= 64MB*/
                            {
                                size_t toUpload = size;
                                /*Codes_SRS_BLOB_02_028: [ Blob_UploadFromSasUri shall construct an XML string with the following content: ]*/
                                STRING_HANDLE xml = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/
                                if (xml == NULL)
                                {
                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                    LogError("failed to STRING_construct");
                                    result = BLOB_HTTP_ERROR;
                                }
                                else
                                {
                                    /*Codes_SRS_BLOB_02_021: [ For every block of 4MB the following operations shall happen: ]*/
                                    unsigned int blockID = 0;
                                    result = BLOB_ERROR;

                                    int isError = 0; /*used to cleanly exit the loop*/
                                    do
                                    {
                                        /*setting this block size*/
                                        size_t thisBlockSize = (toUpload > BLOCK_SIZE) ? BLOCK_SIZE : toUpload;
                                        /*Codes_SRS_BLOB_02_020: [ Blob_UploadFromSasUri shall construct a BASE64 encoded string from the block ID (000000... 0499999) ]*/
                                        char temp[7]; /*this will contain 000000... 049999*/
                                        if (sprintf(temp, "%6u", (unsigned int)blockID) != 6) /*produces 000000... 049999*/
                                        {
                                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                            LogError("failed to sprintf");
                                            result = BLOB_ERROR;
                                            isError = 1;
                                        }
                                        else
                                        {
                                            STRING_HANDLE blockIdString = Base64_Encode_Bytes((const unsigned char*)temp, 6);
                                            if (blockIdString == NULL)
                                            {
                                                /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                LogError("unable to Base64_Encode_Bytes");
                                                result = BLOB_ERROR;
                                                isError = 1;
                                            }
                                            else
                                            {
                                                /*add the blockId base64 encoded to the XML*/
                                                if (!(
                                                    (STRING_concat(xml, "<Latest>")==0) &&
                                                    (STRING_concat_with_STRING(xml, blockIdString)==0) &&
                                                    (STRING_concat(xml, "</Latest>") == 0)
                                                    ))
                                                {
                                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                    LogError("unable to STRING_concat");
                                                    result = BLOB_ERROR;
                                                    isError = 1;
                                                }
                                                else
                                                {
                                                    /*Codes_SRS_BLOB_02_022: [ Blob_UploadFromSasUri shall construct a new relativePath from following string: base relativePath + "&comp=block&blockid=BASE64 encoded string of blockId" ]*/
                                                    STRING_HANDLE newRelativePath = STRING_construct(relativePath);
                                                    if (newRelativePath == NULL)
                                                    {
                                                        /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                        LogError("unable to STRING_construct");
                                                        result = BLOB_ERROR;
                                                        isError = 1;
                                                    }
                                                    else
                                                    {
                                                        if (!(
                                                            (STRING_concat(newRelativePath, "&comp=block&blockid=") == 0) &&
                                                            (STRING_concat_with_STRING(newRelativePath, blockIdString) == 0)
                                                            ))
                                                        {
                                                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                            LogError("unable to STRING concatenate");
                                                            result = BLOB_ERROR;
                                                            isError = 1;
                                                        }
                                                        else
                                                        {
                                                            /*Codes_SRS_BLOB_02_023: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
                                                            BUFFER_HANDLE requestContent = BUFFER_create(source + (size - toUpload), thisBlockSize);
                                                            if (requestContent == NULL)
                                                            {
                                                                /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                                LogError("unable to BUFFER_create");
                                                                result = BLOB_ERROR;
                                                                isError = 1;
                                                            }
                                                            else
                                                            {
                                                                /*Codes_SRS_BLOB_02_024: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing httpStatus and httpResponse. ]*/
                                                                if (HTTPAPIEX_ExecuteRequest(
                                                                    httpApiExHandle,
                                                                    HTTPAPI_REQUEST_PUT,
                                                                    STRING_c_str(newRelativePath),
                                                                    NULL,
                                                                    requestContent,
                                                                    httpStatus,
                                                                    NULL,
                                                                    httpResponse) != HTTPAPIEX_OK
                                                                    )
                                                                {
                                                                    /*Codes_SRS_BLOB_02_025: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                                    LogError("unable to HTTPAPIEX_ExecuteRequest");
                                                                    result = BLOB_HTTP_ERROR;
                                                                    isError = 1;
                                                                }
                                                                else if (*httpStatus >= 300)
                                                                {
                                                                    /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/
                                                                    LogError("HTTP status from storage does not indicate success (%d)", (int)*httpStatus);
                                                                    result = BLOB_OK;
                                                                    isError = 1;
                                                                }
                                                                else
                                                                {
                                                                    /*Codes_SRS_BLOB_02_027: [ Otherwise Blob_UploadFromSasUri shall continue execution. ]*/
                                                                }
                                                                BUFFER_delete(requestContent);
                                                            }
                                                        }
                                                        STRING_delete(newRelativePath);
                                                    }
                                                }
                                                STRING_delete(blockIdString);
                                            }
                                        }

                                        blockID++;
                                        toUpload -= thisBlockSize;
                                    } while ((toUpload > 0) && !isError);

                                    if (isError)
                                    {
                                        /*do nothing, it will be reported "as is"*/
                                    }
                                    else
                                    {
                                        /*complete the XML*/
                                        if (STRING_concat(xml, "</BlockList>") != 0)
                                        {
                                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                            LogError("failed to STRING_concat");
                                            result = BLOB_ERROR;
                                        }
                                        else
                                        {
                                            /*Codes_SRS_BLOB_02_029: [Blob_UploadFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/
                                            STRING_HANDLE newRelativePath = STRING_construct(relativePath);
                                            if (newRelativePath == NULL)
                                            {
                                                /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                LogError("failed to STRING_construct");
                                                result = BLOB_ERROR;
                                            }
                                            else
                                            {
                                                if (STRING_concat(newRelativePath, "&comp=blocklist") != 0)
                                                {
                                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                    LogError("failed to STRING_concat");
                                                    result = BLOB_ERROR;
                                                }
                                                else
                                                {
                                                    /*Codes_SRS_BLOB_02_030: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/
                                                    const char* s = STRING_c_str(xml);
                                                    BUFFER_HANDLE xmlAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s));
                                                    if (xmlAsBuffer == NULL)
                                                    {
                                                        /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                                                        LogError("failed to BUFFER_create");
                                                        result = BLOB_ERROR;
                                                    }
                                                    else
                                                    {
                                                        if (HTTPAPIEX_ExecuteRequest(
                                                            httpApiExHandle,
                                                            HTTPAPI_REQUEST_PUT,
                                                            STRING_c_str(newRelativePath),
                                                            NULL,
                                                            xmlAsBuffer,
                                                            httpStatus,
                                                            NULL,
                                                            httpResponse
                                                        ) != HTTPAPIEX_OK)
                                                        {
                                                            /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                            LogError("unable to HTTPAPIEX_ExecuteRequest");
                                                            result = BLOB_HTTP_ERROR;
                                                        }
                                                        else
                                                        {
                                                            /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/
                                                            result = BLOB_OK;
                                                        }
                                                        BUFFER_delete(xmlAsBuffer);
                                                    }
                                                }
                                                STRING_delete(newRelativePath);
                                            }
                                        }
                                    }
                                    STRING_delete(xml);
                                }
                            }
                            HTTPAPIEX_Destroy(httpApiExHandle);
                        }
                        free(hostname);
                    }
                }
            }
        }
    }
    return result;
}
PROVISIONING_SERVICE_CLIENT_HANDLE prov_sc_create_from_connection_string(const char* conn_string)
{
    PROV_SERVICE_CLIENT* result;

    if (conn_string == NULL)
    {
        LogError("Input parameter is NULL: conn_string");
        result = NULL;
    }
    else
    {
        STRING_HANDLE cs_string;
        if ((cs_string = STRING_construct(conn_string)) == NULL)
        {
            LogError("STRING_construct failed");
            result = NULL;
        }
        else
        {
            MAP_HANDLE connection_string_values_map;
            if ((connection_string_values_map = connectionstringparser_parse(cs_string)) == NULL)
            {
                LogError("Tokenizing conn_string failed");
                result = NULL;
            }
            else
            {
                const char* hostname = NULL;
                const char* key_name = NULL;
                const char* key = NULL;

                if ((hostname = Map_GetValueFromKey(connection_string_values_map, IOTHUBHOSTNAME)) == NULL)
                {
                    LogError("Couldn't find %s in conn_string", IOTHUBHOSTNAME);
                    result = NULL;
                }
                else if ((key_name = Map_GetValueFromKey(connection_string_values_map, IOTHUBSHAREDACESSKEYNAME)) == NULL)
                {
                    LogError("Couldn't find %s in conn_string", IOTHUBSHAREDACESSKEYNAME);
                    result = NULL;
                }
                else if ((key = Map_GetValueFromKey(connection_string_values_map, IOTHUBSHAREDACESSKEY)) == NULL)
                {
                    LogError("Couldn't find %s in conn_string", IOTHUBSHAREDACESSKEY);
                    result = NULL;
                }
                if (hostname == NULL || key_name == NULL || key == NULL)
                {
                    LogError("invalid parameter hostname: %p, key_name: %p, key: %p", hostname, key_name, key);
                    result = NULL;
                }
                else if ((result = malloc(sizeof(PROV_SERVICE_CLIENT))) == NULL)
                {
                    LogError("Allocation of provisioning service client failed");
                    result = NULL;
                }
                else
                {
                    memset(result, 0, sizeof(PROV_SERVICE_CLIENT));
                    if (mallocAndStrcpy_s(&result->provisioning_service_uri, hostname) != 0)
                    {
                        LogError("Failure allocating of provisioning service uri");
                        prov_sc_destroy(result);
                        result = NULL;
                    }
                    else if (mallocAndStrcpy_s(&result->key_name, key_name) != 0)
                    {
                        LogError("Failure allocating of keyname");
                        prov_sc_destroy(result);
                        result = NULL;
                    }
                    else if (mallocAndStrcpy_s(&result->access_key, key) != 0)
                    {
                        LogError("Failure allocating of access key");
                        prov_sc_destroy(result);
                        result = NULL;
                    }
                    else
                    {
                        result->tracing = TRACING_STATUS_OFF;
                    }
                }
                Map_Destroy(connection_string_values_map);
            }
        }
        STRING_delete(cs_string);
    }
    return result;
}
static IOTHUB_DEVICE_METHOD_RESULT sendHttpRequestDeviceMethod(IOTHUB_SERVICE_CLIENT_DEVICE_METHOD_HANDLE serviceClientDeviceMethodHandle, IOTHUB_DEVICEMETHOD_REQUEST_MODE iotHubDeviceMethodRequestMode, const char* deviceName, BUFFER_HANDLE deviceJsonBuffer, BUFFER_HANDLE responseBuffer)
{
    IOTHUB_DEVICE_METHOD_RESULT result;

    STRING_HANDLE uriResouce;
    STRING_HANDLE accessKey;
    STRING_HANDLE keyName;
    HTTPAPIEX_SAS_HANDLE httpExApiSasHandle;
    HTTPAPIEX_HANDLE httpExApiHandle;
    HTTP_HEADERS_HANDLE httpHeader;

    if ((uriResouce = STRING_construct(serviceClientDeviceMethodHandle->hostname)) == NULL)
    {
        LogError("STRING_construct failed for uriResource");
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((accessKey = STRING_construct(serviceClientDeviceMethodHandle->sharedAccessKey)) == NULL)
    {
        LogError("STRING_construct failed for accessKey");
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((keyName = STRING_construct(serviceClientDeviceMethodHandle->keyName)) == NULL)
    {
        LogError("STRING_construct failed for keyName");
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((httpHeader = createHttpHeader()) == NULL)
    {
        LogError("HttpHeader creation failed");
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((httpExApiSasHandle = HTTPAPIEX_SAS_Create(accessKey, uriResouce, keyName)) == NULL)
    {
        LogError("HTTPAPIEX_SAS_Create failed");
        HTTPHeaders_Free(httpHeader);
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
    }
    else if ((httpExApiHandle = HTTPAPIEX_Create(serviceClientDeviceMethodHandle->hostname)) == NULL)
    {
        LogError("HTTPAPIEX_Create failed");
        HTTPAPIEX_SAS_Destroy(httpExApiSasHandle);
        HTTPHeaders_Free(httpHeader);
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
    }
    else 
    {
        HTTPAPI_REQUEST_TYPE httpApiRequestType = HTTPAPI_REQUEST_GET;
        STRING_HANDLE relativePath;
        unsigned int statusCode = 0;
        unsigned char is_error = 0;

        if (iotHubDeviceMethodRequestMode == IOTHUB_DEVICEMETHOD_REQUEST_INVOKE)
        {
            httpApiRequestType = HTTPAPI_REQUEST_POST;
        }
        else
        {
            is_error = 1;
        }

        if (is_error)
        {
            LogError("Invalid request type");
            result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
        }
        else
        {
            if ((relativePath = createRelativePath(iotHubDeviceMethodRequestMode, deviceName)) == NULL)
            {
                LogError("Failure creating relative path");
                result = IOTHUB_DEVICE_METHOD_ERROR;
            }
            else if (HTTPAPIEX_SAS_ExecuteRequest(httpExApiSasHandle, httpExApiHandle, httpApiRequestType, STRING_c_str(relativePath), httpHeader, deviceJsonBuffer, &statusCode, NULL, responseBuffer) != HTTPAPIEX_OK)
            {
                LogError("HTTPAPIEX_SAS_ExecuteRequest failed");
                STRING_delete(relativePath);
                result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
            }
            else
            {
                STRING_delete(relativePath);
                if (statusCode == 200)
                {
                    result = IOTHUB_DEVICE_METHOD_OK;
                }
                else
                {
                    LogError("Http Failure status code %d.", statusCode);
                    result = IOTHUB_DEVICE_METHOD_ERROR;
                }
            }
        }
        HTTPAPIEX_Destroy(httpExApiHandle);
        HTTPAPIEX_SAS_Destroy(httpExApiSasHandle);
        HTTPHeaders_Free(httpHeader);
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
    }
    return result;
}
STRING_HANDLE platform_get_platform_info(void)
{
    return STRING_construct("(tizenrt)");
}
예제 #30
0
BLOB_RESULT Blob_UploadBlock(
        HTTPAPIEX_HANDLE httpApiExHandle,
        const char* relativePath,
        BUFFER_HANDLE requestContent,
        unsigned int blockID,
        STRING_HANDLE blockIDList,
        unsigned int* httpStatus,
        BUFFER_HANDLE httpResponse)
{
    BLOB_RESULT result;

    if (requestContent == NULL ||
        blockIDList == NULL ||
        relativePath == NULL ||
        httpApiExHandle == NULL ||
        httpStatus == NULL ||
        httpResponse == NULL)
    {
        LogError("invalid argument detected requestContent=%p blockIDList=%p relativePath=%p httpApiExHandle=%p httpStatus=%p httpResponse=%p", requestContent, blockIDList, relativePath, httpApiExHandle, httpStatus, httpResponse);
        result = BLOB_ERROR;
    }
    else
    {
        char temp[7]; /*this will contain 000000... 049999*/
        if (sprintf(temp, "%6u", (unsigned int)blockID) != 6) /*produces 000000... 049999*/
        {
            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
            LogError("failed to sprintf");
            result = BLOB_ERROR;
        }
        else
        {
            STRING_HANDLE blockIdString = Azure_Base64_Encode_Bytes((const unsigned char*)temp, 6);
            if (blockIdString == NULL)
            {
                /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                LogError("unable to Azure_Base64_Encode_Bytes");
                result = BLOB_ERROR;
            }
            else
            {
                /*add the blockId base64 encoded to the XML*/
                if (!(
                    (STRING_concat(blockIDList, "<Latest>") == 0) &&
                    (STRING_concat_with_STRING(blockIDList, blockIdString) == 0) &&
                    (STRING_concat(blockIDList, "</Latest>") == 0)
                    ))
                {
                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                    LogError("unable to STRING_concat");
                    result = BLOB_ERROR;
                }
                else
                {
                    /*Codes_SRS_BLOB_02_022: [ Blob_UploadMultipleBlocksFromSasUri shall construct a new relativePath from following string: base relativePath + "&comp=block&blockid=BASE64 encoded string of blockId" ]*/
                    STRING_HANDLE newRelativePath = STRING_construct(relativePath);
                    if (newRelativePath == NULL)
                    {
                        /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                        LogError("unable to STRING_construct");
                        result = BLOB_ERROR;
                    }
                    else
                    {
                        if (!(
                            (STRING_concat(newRelativePath, "&comp=block&blockid=") == 0) &&
                            (STRING_concat_with_STRING(newRelativePath, blockIdString) == 0)
                            ))
                        {
                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                            LogError("unable to STRING concatenate");
                            result = BLOB_ERROR;
                        }
                        else
                        {
                            /*Codes_SRS_BLOB_02_024: [ Blob_UploadMultipleBlocksFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing httpStatus and httpResponse. ]*/
                            if (HTTPAPIEX_ExecuteRequest(
                                httpApiExHandle,
                                HTTPAPI_REQUEST_PUT,
                                STRING_c_str(newRelativePath),
                                NULL,
                                requestContent,
                                httpStatus,
                                NULL,
                                httpResponse) != HTTPAPIEX_OK
                                )
                            {
                                /*Codes_SRS_BLOB_02_025: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                LogError("unable to HTTPAPIEX_ExecuteRequest");
                                result = BLOB_HTTP_ERROR;
                            }
                            else if (*httpStatus >= 300)
                            {
                                /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
                                LogError("HTTP status from storage does not indicate success (%d)", (int)*httpStatus);
                                result = BLOB_OK;
                            }
                            else
                            {
                                /*Codes_SRS_BLOB_02_027: [ Otherwise Blob_UploadMultipleBlocksFromSasUri shall continue execution. ]*/
                                result = BLOB_OK;
                            }
                        }
                        STRING_delete(newRelativePath);
                    }
                }
                STRING_delete(blockIdString);
            }
        }
    }
    return result;
}