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(); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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)"); }
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; }