Пример #1
0
void HTTPAPIEX_Destroy(HTTPAPIEX_HANDLE handle)
{
    if (handle != NULL)
    {
        /*Codes_SRS_HTTPAPIEX_02_042: [HTTPAPIEX_Destroy shall free all the resources used by HTTAPIEX_HANDLE.]*/
        size_t i;
        size_t vectorSize;
        HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)handle;
        
        if (handleData->k == 2)
        {
            HTTPAPI_CloseConnection(handleData->httpHandle);
            HTTPAPI_Deinit();
        }
        STRING_delete(handleData->hostName);

        vectorSize = VECTOR_size(handleData->savedOptions);
        for (i = 0; i < vectorSize; i++)
        {
            HTTPAPIEX_SAVED_OPTION*savedOption = VECTOR_element(handleData->savedOptions, i);
            free((void*)savedOption->optionName);
            free((void*)savedOption->value);
        }
        VECTOR_destroy(handleData->savedOptions);

        free(handle);
    }
    else
    {
        /*Codes_SRS_HTTPAPIEX_02_043: [If parameter handle is NULL then HTTPAPIEX_Destroy shall take no action.] */
    }
}
static VECTOR_HANDLE VECTOR_copy(VECTOR_HANDLE vector)
{
    VECTOR_HANDLE new_vector = VECTOR_create(sizeof(STRING_HANDLE));

    size_t size = VECTOR_size(vector);
    for (size_t index = 0; index < size && new_vector != NULL; index++)
    {
        STRING_HANDLE* str = VECTOR_element(vector, index);
        if (str == NULL)
        {
            VECTOR_destroy(new_vector);
            new_vector = NULL;
        }
        else
        {
            STRING_HANDLE new_str = STRING_clone(*str);
            if (new_str == NULL)
            {
                VECTOR_destroy(new_vector);
                new_vector = NULL;
            }
            else
            {
                if (VECTOR_push_back(new_vector, &new_str, 1) != 0)
                {
                    STRING_delete(new_str);
                    VECTOR_destroy(new_vector);
                    new_vector = NULL;
                }
            }
        }
    }

    return new_vector;
}
Пример #3
0
void DataPublisher_DestroyTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle)
{
    /*Codes_SRS_DATA_PUBLISHER_02_025: [ If argument transactionHandle is NULL then DataPublisher_DestroyTransaction_ReportedProperties shall return. ]*/
    if (transactionHandle == NULL)
    {
        LogError("invalig argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p", transactionHandle);
    }
    else
    {
        /*Codes_SRS_DATA_PUBLISHER_02_026: [ Otherwise DataPublisher_DestroyTransaction_ReportedProperties shall free all resources associated with the reported properties transactionHandle. ]*/
        REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle;
        size_t i, nReportedProperties;
        nReportedProperties = VECTOR_size(handleData->value);
        for (i = 0;i < nReportedProperties;i++)
        {
            DATA_MARSHALLER_VALUE *value = *(DATA_MARSHALLER_VALUE**)VECTOR_element(handleData->value, i);
            Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)value->Value);
            free((void*)value->Value);
            free((void*)value->PropertyPath);
            free((void*)value);
        }
        VECTOR_destroy(handleData->value);
        free(handleData);
    }
    return;
}
void ModuleLoader_Destroy(void)
{
    if (g_module_loaders.lock != NULL)
    {
        if (Lock(g_module_loaders.lock) != LOCK_OK)
        {
            LogError("Lock failed. Proceeding with destruction anyway.");
        }
    }
    if(g_module_loaders.module_loaders != NULL)
    {
        // free all module loader resources
        size_t length = VECTOR_size(g_module_loaders.module_loaders);
        for (size_t i = 0; i < length; i++)
        {
            MODULE_LOADER* loader = *((MODULE_LOADER **)VECTOR_element(g_module_loaders.module_loaders, i));

            // NOTE: We free the configuration object even for default loaders because
            // the configuration may have been replaced by the gateway for default
            // loaders.

            /*Codes_SRS_MODULE_LOADER_13_046: [ ModuleLoader_Destroy shall invoke FreeConfiguration on every module loader's configuration field. ]*/
            if (loader->configuration != NULL)
            {
                loader->api->FreeConfiguration(loader, loader->configuration);
            }

            // if this is not a default loader then free resources allocated in
            // add_loader_from_json
            if (ModuleLoader_IsDefaultLoader(loader->name) == false)
            {
                /*Codes_SRS_MODULE_LOADER_13_047: [ ModuleLoader_Destroy shall free the loader's name and the loader itself if it is not a default loader. ]*/
                free((void *)loader->name);
                free(loader);
            }
        }

        /*Codes_SRS_MODULE_LOADER_13_048: [ ModuleLoader_Destroy shall destroy the loaders vector. ]*/
        VECTOR_destroy(g_module_loaders.module_loaders);
        g_module_loaders.module_loaders = NULL;
    }

    if (g_module_loaders.lock != NULL)
    {
        if (Unlock(g_module_loaders.lock) != LOCK_OK)
        {
            LogError("Unlock failed.");
        }

        /*Codes_SRS_MODULE_LOADER_13_045: [ ModuleLoader_Destroy shall free g_module_loaders.lock if it is not NULL. ]*/
        Lock_Deinit(g_module_loaders.lock);
        g_module_loaders.lock = NULL;
    }
}
static int VECTOR_compare(VECTOR_HANDLE vector1, VECTOR_HANDLE vector2)
{
    int result = 0;

    if (vector1 == NULL && vector2 == NULL)
    {
        result = 0;
    }
    else if (VECTOR_size(vector1) == 0 && VECTOR_size(vector2) == 0)
    {
        result = 0;
    }
    else if (vector1 == NULL)
    {
        result = __LINE__;
    }
    else if (vector2 == NULL)
    {
        result = __LINE__;
    }
    else if(VECTOR_size(vector1) != VECTOR_size(vector2))
    {
        result = __LINE__;
    }
    else
    {
        size_t size = VECTOR_size(vector1);
        for (size_t index = 0; index < size && result == 0; index++)
        {
            STRING_HANDLE* str1 = (STRING_HANDLE*)VECTOR_element(vector1, index);
            STRING_HANDLE* str2 = (STRING_HANDLE*)VECTOR_element(vector2, index);

            result = STRING_compare(*str1, *str2);
        }
    }

    return result;
}
Пример #6
0
/*
 * @brief	Walks through our mappingVector to ensure it is correct for our identity map module.
 */
static bool IdentityMap_ValidateConfig(const VECTOR_HANDLE mappingVector)
{
	size_t mappingSize = VECTOR_size(mappingVector);
	bool mappingOk;
	if (mappingSize == 0)
	{
		/*Codes_SRS_IDMAP_17_041: [If the configuration has no vector elements, this function shall fail and return NULL.*/
		LogError("nothing for this module to do, no mapping data");
		mappingOk = false;
	}
	else
	{
		mappingOk = true;
		size_t index;
		for (index = 0; (index < mappingSize) && (mappingOk != false); index++)
		{
			IDENTITY_MAP_CONFIG * element = (IDENTITY_MAP_CONFIG *)VECTOR_element(mappingVector, index);
			if ((element->deviceId == NULL) ||
				(element->deviceKey == NULL) ||
				(element->macAddress == NULL))
			{
				/*Codes_SRS_IDMAP_17_019: [If any macAddress, deviceId or deviceKey are NULL, this function shall fail and return NULL.]*/
				LogError("Empty mapping data values, mac=%p, ID=%p, key=%p",
					element->macAddress, element->deviceId, element->deviceKey);
				mappingOk = false;
				break;
			}
			else
			{
				if (IdentityMapConfig_IsCanonicalMAC(element->macAddress) == false)
				{
					/*Codes_SRS_IDMAP_17_006: [If any macAddress string in configuration is not a MAC address in canonical form, this function shall fail and return NULL.]*/
					LogError("Non-canonical MAC Address: %s", element->macAddress);
					mappingOk = false;
					break;
				}
			}
		}
	}
	return mappingOk;
}
Пример #7
0
HTTPAPIEX_RESULT HTTPAPIEX_ExecuteRequest(HTTPAPIEX_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
    HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode,
    HTTP_HEADERS_HANDLE responseHttpHeadersHandle, BUFFER_HANDLE responseContent)
{
    HTTPAPIEX_RESULT result;
    /*Codes_SRS_HTTPAPIEX_02_006: [If parameter handle is NULL then HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.]*/
    if (handle == NULL)
    {
        result = HTTPAPIEX_INVALID_ARG;
        LOG_HTTAPIEX_ERROR();
    }
    else
    {
        /*Codes_SRS_HTTPAPIEX_02_007: [If parameter requestType does not indicate a valid request, HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.] */
        if (requestType >= COUNT_ARG(HTTPAPI_REQUEST_TYPE_VALUES))
        {
            result = HTTPAPIEX_INVALID_ARG;
            LOG_HTTAPIEX_ERROR();
        }
        else
        {
            HTTPAPIEX_HANDLE_DATA *handleData = (HTTPAPIEX_HANDLE_DATA *)handle;

            /*call to buildAll*/
            const char* toBeUsedRelativePath;
            HTTP_HEADERS_HANDLE toBeUsedRequestHttpHeadersHandle; bool isOriginalRequestHttpHeadersHandle;
            BUFFER_HANDLE toBeUsedRequestContent; bool isOriginalRequestContent;
            unsigned int* toBeUsedStatusCode;
            HTTP_HEADERS_HANDLE toBeUsedResponseHttpHeadersHandle; bool isOriginalResponseHttpHeadersHandle;
            BUFFER_HANDLE toBeUsedResponseContent;  bool isOriginalResponseContent;

            if (buildAllRequests(handleData, requestType, relativePath, requestHttpHeadersHandle, requestContent, statusCode, responseHttpHeadersHandle, responseContent,
                &toBeUsedRelativePath,
                &toBeUsedRequestHttpHeadersHandle, &isOriginalRequestHttpHeadersHandle,
                &toBeUsedRequestContent, &isOriginalRequestContent,
                &toBeUsedStatusCode,
                &toBeUsedResponseHttpHeadersHandle, &isOriginalResponseHttpHeadersHandle,
                &toBeUsedResponseContent, &isOriginalResponseContent) != 0)
            {
                result = HTTPAPIEX_ERROR;
                LOG_HTTAPIEX_ERROR();
            }
            else
            {

                /*Codes_SRS_HTTPAPIEX_02_023: [HTTPAPIEX_ExecuteRequest shall try to execute the HTTP call by ensuring the following API call sequence is respected:]*/
                /*Codes_SRS_HTTPAPIEX_02_024: [If any point in the sequence fails, HTTPAPIEX_ExecuteRequest shall attempt to recover by going back to the previous step and retrying that step.]*/
                /*Codes_SRS_HTTPAPIEX_02_025: [If the first step fails, then the sequence fails.]*/
                /*Codes_SRS_HTTPAPIEX_02_026: [A step shall be retried at most once.]*/
                /*Codes_SRS_HTTPAPIEX_02_027: [If a step has been retried then all subsequent steps shall be retried too.]*/
                bool st[3] = { false, false, false }; /*the three levels of possible failure in resilient send: HTTAPI_Init, HTTPAPI_CreateConnection, HTTPAPI_ExecuteRequest*/
                if (handleData->k == -1)
                {
                    handleData->k = 0;
                }

                do
                {
                    bool goOn;

                    if (handleData->k > 2)
                    {
                        /* error */
                        break;
                    }

                    if (st[handleData->k] == true) /*already been tried*/
                    {
                        goOn = false;
                    }
                    else
                    {
                        switch (handleData->k)
                        {
                        case 0:
                        {
                            if (HTTPAPI_Init() != HTTPAPI_OK)
                            {
                                goOn = false;
                            }
                            else
                            {
                                goOn = true;
                            }
                            break;
                        }
                        case 1:
                        {
                            if ((handleData->httpHandle = HTTPAPI_CreateConnection(STRING_c_str(handleData->hostName))) == NULL)
                            {
                                goOn = false;
                            }
                            else
                            {
                                size_t i;
                                size_t vectorSize = VECTOR_size(handleData->savedOptions);
                                for (i = 0; i < vectorSize; i++)
                                {
                                    /*Codes_SRS_HTTPAPIEX_02_035: [HTTPAPIEX_ExecuteRequest shall pass all the saved options (see HTTPAPIEX_SetOption) to the newly create HTTPAPI_HANDLE in step 2 by calling HTTPAPI_SetOption.]*/
                                    /*Codes_SRS_HTTPAPIEX_02_036: [If setting the option fails, then the failure shall be ignored.] */
                                    HTTPAPIEX_SAVED_OPTION* option = VECTOR_element(handleData->savedOptions, i);
                                    if (HTTPAPI_SetOption(handleData->httpHandle, option->optionName, option->value) != HTTPAPI_OK)
                                    {
                                        LogError("HTTPAPI_SetOption failed when called for option %s\r\n", option->optionName);
                                    }
                                }
                                goOn = true;
                            }
                            break;
                        }
                        case 2:
                        {
                            if (HTTPAPI_ExecuteRequest(handleData->httpHandle, requestType, toBeUsedRelativePath, toBeUsedRequestHttpHeadersHandle, BUFFER_u_char(toBeUsedRequestContent), BUFFER_length(toBeUsedRequestContent), toBeUsedStatusCode, toBeUsedResponseHttpHeadersHandle, toBeUsedResponseContent) != HTTPAPI_OK)
                            {
                                goOn = false;
                            }
                            else
                            {
                                goOn = true;
                            }
                            break;
                        }
                        default:
                        {
                            /*serious error*/
                            goOn = false;
                            break;
                        }
                        }
                    }

                    if (goOn)
                    {
                        if (handleData->k == 2)
                        {
                            /*Codes_SRS_HTTPAPIEX_02_028: [HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_OK when a call to HTTPAPI_ExecuteRequest has been completed successfully.]*/
                            result = HTTPAPIEX_OK;
                            goto out;
                        }
                        else
                        {
                            st[handleData->k] = true;
                            handleData->k++;
                            st[handleData->k] = false;
                        }
                    }
                    else
                    {
                        st[handleData->k] = false;
                        handleData->k--;
                        switch (handleData->k)
                        {
                        case 0:
                        {
                            HTTPAPI_Deinit();
                            break;
                        }
                        case 1:
                        {
                            HTTPAPI_CloseConnection(handleData->httpHandle);
                            handleData->httpHandle = NULL;
                            break;
                        }
                        case 2:
                        {
                            break;
                        }
                        default:
                        {
                            break;
                        }
                        }
                    }
                } while (handleData->k >= 0);
                /*Codes_SRS_HTTPAPIEX_02_029: [Otherwise, HTTAPIEX_ExecuteRequest shall return HTTPAPIEX_RECOVERYFAILED.] */
                result = HTTPAPIEX_RECOVERYFAILED;
                LogError("unable to recover sending to a working state\r\n");
            out:;
                /*in all cases, unbuild the temporaries*/
                if (isOriginalRequestContent == false)
                {
                    BUFFER_delete(toBeUsedRequestContent);
                }
                if (isOriginalRequestHttpHeadersHandle == false)
                {
                    HTTPHeaders_Free(toBeUsedRequestHttpHeadersHandle);
                }
                if (isOriginalResponseContent == false)
                {
                    BUFFER_delete(toBeUsedResponseContent);
                }
                if (isOriginalResponseHttpHeadersHandle == false)
                {
                    HTTPHeaders_Free(toBeUsedResponseHttpHeadersHandle);
                }
            }
        }
    }
    return result;
}
Пример #8
0
/*
 * @brief	Create an identity map module.
 */
static MODULE_HANDLE IdentityMap_Create(MESSAGE_BUS_HANDLE busHandle, const void* configuration)
{
	IDENTITY_MAP_DATA* result;
	if (busHandle == NULL || configuration == NULL)
	{
		/*Codes_SRS_IDMAP_17_004: [If the busHandle is NULL, this function shall fail and return NULL.]*/
		/*Codes_SRS_IDMAP_17_005: [If the configuration is NULL, this function shall fail and return NULL.]*/
		LogError("invalid parameter (NULL).");
		result = NULL;
	}
	else
	{
		VECTOR_HANDLE mappingVector = (VECTOR_HANDLE)configuration;
		if (IdentityMap_ValidateConfig(mappingVector) == false)
		{
			LogError("unable to validate mapping table");
			result = NULL;
		}
		else
		{
			result = (IDENTITY_MAP_DATA*)malloc(sizeof(IDENTITY_MAP_DATA));
			if (result == NULL)
			{
				/*Codes_SRS_IDMAP_17_010: [If IdentityMap_Create fails to allocate a new IDENTITY_MAP_DATA structure, then this function shall fail, and return NULL.]*/
				LogError("Could not Allocate Module");
			}
			else
			{
				size_t mappingSize = VECTOR_size(mappingVector);
				/* validation ensures the vector is greater than zero */
				result->macToDevIdArray = (IDENTITY_MAP_CONFIG*)malloc(mappingSize*sizeof(IDENTITY_MAP_CONFIG));
				if (result->macToDevIdArray == NULL)
				{
					/*Codes_SRS_IDMAP_17_011: [If IdentityMap_Create fails to create memory for the macToDeviceArray, then this function shall fail and return NULL.*/
					LogError("Could not allocate mac to device mapping table");
					free(result);
					result = NULL;
				}
				else
				{
					result->devIdToMacArray = (IDENTITY_MAP_CONFIG*)malloc(mappingSize*sizeof(IDENTITY_MAP_CONFIG));
					if (result->devIdToMacArray == NULL)
					{
						/*Codes_SRS_IDMAP_17_042: [ If IdentityMap_Create fails to create memory for the deviceToMacArray, then this function shall fail and return NULL. */
						LogError("Could not allocate devicee to mac mapping table");
						free(result->macToDevIdArray);
						free(result);
						result = NULL;
					}
					else
					{

						size_t index;
						size_t failureIndex = mappingSize;
						for (index = 0; index < mappingSize; index++)
						{
							IDENTITY_MAP_CONFIG * element = (IDENTITY_MAP_CONFIG *)VECTOR_element(mappingVector, index);
							IDENTITY_MAP_CONFIG * dest = &(result->macToDevIdArray[index]);
							IDENTITYMAP_RESULT copyResult;
							copyResult = IdentityMapConfig_CopyDeep(dest, element);
							if (copyResult != IDENTITYMAP_OK)
							{
								failureIndex = index;
								break;
							}
							dest = &(result->devIdToMacArray[index]);
							copyResult = IdentityMapConfig_CopyDeep(dest, element);
							if (copyResult != IDENTITYMAP_OK)
							{
								IdentityMapConfig_Free(&(result->macToDevIdArray[index]));
								failureIndex = index;
								break;
							}
						}
						if (failureIndex < mappingSize)
						{
							/*Codes_SRS_IDMAP_17_012: [If IdentityMap_Create fails to add a MAC address triplet to the macToDeviceArray, then this function shall fail, release all resources, and return NULL.]*/
							/*Codes_SRS_IDMAP_17_043: [ If IdentityMap_Create fails to add a MAC address triplet to the deviceToMacArray, then this function shall fail, release all resources, and return NULL. */
							for (index = 0; index < failureIndex; index++)
							{
								IdentityMapConfig_Free(&(result->macToDevIdArray[index]));
								IdentityMapConfig_Free(&(result->devIdToMacArray[index]));
							}
							free(result->macToDevIdArray);
							free(result->devIdToMacArray);
							free(result);
							result = NULL;
						}
						else
						{
							/*Codes_SRS_IDMAP_17_003: [Upon success, this function shall return a valid pointer to a MODULE_HANDLE.]*/
							qsort(result->macToDevIdArray, mappingSize, sizeof(IDENTITY_MAP_CONFIG),
								IdentityMapConfig_MacCompare);
							qsort(result->devIdToMacArray, mappingSize, sizeof(IDENTITY_MAP_CONFIG),
								IdentityMapConfig_IdCompare);
							result->mappingSize = mappingSize;
							result->busHandle = busHandle;
						}
					}
				}
			}
		}
	}
	return result;
}