/*
* @brief	Republish message with new data from our matching identities.
*/
static void IdentityMap_RepublishC2D(
	IDENTITY_MAP_DATA * idModule,
	MESSAGE_HANDLE messageHandle,
	IDENTITY_MAP_CONFIG * match)
{
	CONSTMAP_HANDLE properties = Message_GetProperties(messageHandle);
	if (properties == NULL)
	{

		LogError("Could not extract message properties");
	}
	else
	{
		/*Codes_SRS_IDMAP_17_049: [ On a C2D message received, IdentityMap_Receive shall call ConstMap_CloneWriteable on the message properties. ]*/
		MAP_HANDLE newProperties = ConstMap_CloneWriteable(properties);
		if (newProperties == NULL)
		{
			/*Codes_SRS_IDMAP_17_050: [ If ConstMap_CloneWriteable fails, IdentityMap_Receive shall deallocate any resources and return. ]*/
			LogError("Could not make writeable new properties map");
		}
		else
		{
			/*Codes_SRS_IDMAP_17_051: [ IdentityMap_Receive shall call Map_AddOrUpdate with key of "macAddress" and value of found macAddress. ]*/
			if (Map_AddOrUpdate(newProperties, GW_MAC_ADDRESS_PROPERTY, match->macAddress) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_052: [ If adding macAddress fails, IdentityMap_Receive shall deallocate all resources and return. ]*/
				LogError("Could not attach %s property to message", GW_MAC_ADDRESS_PROPERTY);
			}
			/*Codes_SRS_IDMAP_17_032: [IdentityMap_Receive shall call Map_AddOrUpdate with key of "source" and value of "mapping".]*/
			else if (Map_AddOrUpdate(newProperties, GW_SOURCE_PROPERTY, GW_IDMAP_MODULE) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_033: [If adding source fails, IdentityMap_Receive shall deallocate all resources and return.]*/
				LogError("Could not attach %s property to message", GW_SOURCE_PROPERTY);
			}
			/*Codes_SRS_IDMAP_17_055: [ IdentityMap_Receive shall call Map_Delete to remove the "deviceName" property. ]*/
			else if (Map_Delete(newProperties, GW_DEVICENAME_PROPERTY) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_056: [ If deleting the device name fails, IdentityMap_Receive shall deallocate all resources and return. ]*/
				LogError("Could not remove %s property from message", GW_DEVICENAME_PROPERTY);
			}
			/*Codes_SRS_IDMAP_17_057: [ IdentityMap_Receive shall call Map_Delete to remove the "deviceKey" property. ]*/
			else if (Map_Delete(newProperties, GW_DEVICEKEY_PROPERTY) == MAP_INVALIDARG)
			{
				/*Codes_SRS_IDMAP_17_058: [ If deleting the device key does not return MAP_OK or MAP_KEYNOTFOUND, IdentityMap_Receive shall deallocate all resources and return. ]*/
				LogError("Could not remove %s property from message", GW_DEVICEKEY_PROPERTY);
			}
			else
			{
				publish_with_new_properties(newProperties, messageHandle, idModule);
			}
			Map_Destroy(newProperties);
		}
		ConstMap_Destroy(properties);
	}
}
/*
 * @brief	Republish message with new data from our matching identities.
 */
static void IdentityMap_RepublishD2C(
	IDENTITY_MAP_DATA * idModule,
	MESSAGE_HANDLE messageHandle,
	IDENTITY_MAP_CONFIG * match)
{
	CONSTMAP_HANDLE properties = Message_GetProperties(messageHandle);
	if (properties == NULL)
	{

		LogError("Could not extract message properties");
	}
	else
	{
		/*Codes_SRS_IDMAP_17_026: [On a message which passes all checks, IdentityMap_Receive shall call ConstMap_CloneWriteable on the message properties.]*/
		MAP_HANDLE newProperties = ConstMap_CloneWriteable(properties);
		if (newProperties == NULL)
		{
			/*Codes_SRS_IDMAP_17_027: [If ConstMap_CloneWriteable fails, IdentityMap_Receive shall deallocate any resources and return.] */
			LogError("Could not make writeable new properties map");
		}
		else
		{
			/*Codes_SRS_IDMAP_17_028: [IdentityMap_Receive shall call Map_AddOrUpdate with key of "deviceName" and value of found deviceId.]*/
			if (Map_AddOrUpdate(newProperties, GW_DEVICENAME_PROPERTY, match->deviceId) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_029: [If adding deviceName fails,IdentityMap_Receive shall deallocate all resources and return.]*/
				LogError("Could not attach %s property to message", GW_DEVICENAME_PROPERTY);
			}
			/*Codes_SRS_IDMAP_17_030: [IdentityMap_Receive shall call Map_AddOrUpdate with key of "deviceKey" and value of found deviceKey.]*/
			else if (Map_AddOrUpdate(newProperties, GW_DEVICEKEY_PROPERTY, match->deviceKey) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_031: [If adding deviceKey fails, IdentityMap_Receive shall deallocate all resources and return.]*/
				LogError("Could not attach %s property to message", GW_DEVICEKEY_PROPERTY);
			}
			/*Codes_SRS_IDMAP_17_032: [IdentityMap_Receive shall call Map_AddOrUpdate with key of "source" and value of "mapping".]*/
			else if (Map_AddOrUpdate(newProperties, GW_SOURCE_PROPERTY, GW_IDMAP_MODULE) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_033: [If adding source fails, IdentityMap_Receive shall deallocate all resources and return.]*/
				LogError("Could not attach %s property to message", GW_SOURCE_PROPERTY);
			}
			/*Codes_SRS_IDMAP_17_053: [ IdentityMap_Receive shall call Map_Delete to remove the "macAddress" property. ]*/
			else if (Map_Delete(newProperties, GW_MAC_ADDRESS_PROPERTY) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_054: [ If deleting the MAC Address fails, IdentityMap_Receive shall deallocate all resources and return. ]*/
				LogError("Could not remove %s property from message", GW_MAC_ADDRESS_PROPERTY);
			}
			else
			{
				publish_with_new_properties(newProperties, messageHandle, idModule);
			}
			Map_Destroy(newProperties);
		}
		ConstMap_Destroy(properties);
	}
}
static void sendMessage(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size, ContosoAnemometer *myWeather)
{
    static unsigned int messageTrackingId;
    IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
    if (messageHandle == NULL)
    {
        printf("unable to create a new IoTHubMessage\r\n");
    }
    else
    {
        MAP_HANDLE propMap = IoTHubMessage_Properties(messageHandle);
        (void)sprintf_s(propText, sizeof(propText), myWeather->Temperature > 28 ? "true" : "false");
        if (Map_AddOrUpdate(propMap, "temperatureAlert", propText) != MAP_OK)
        {
            (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
        }

        if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)(uintptr_t)messageTrackingId) != IOTHUB_CLIENT_OK)
        {
            printf("failed to hand over the message to IoTHubClient");
        }
        else
        {
            printf("IoTHubClient accepted the message for delivery\r\n");
        }
        IoTHubMessage_Destroy(messageHandle);
    }
    messageTrackingId++;
}
void iothub_client_sample_http_send_one_msg(IOTHUB_CLIENT_HANDLE iothubClient, EVENT_INSTANCE *message, int messageNumber)
{
    if ((message->messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
    {
        (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
    }
    else
    {
        MAP_HANDLE propMap;

        message->messageTrackingId = messageNumber;

        propMap = IoTHubMessage_Properties(message->messageHandle);
        sprintf_s(propText, sizeof(propText), "PropMsg_%d", messageNumber);
        if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
        {
            (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
        }

        if (IoTHubClient_SendEventAsync(iothubClient, message->messageHandle, SendConfirmationCallback, message) != IOTHUB_CLIENT_OK)
        {
            (void)printf("ERROR: IoTHubClient_LL_SendEventAsync to device [%p]..........FAILED!\r\n", iothubClient);
        }
        else
        {
            (void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub, device [%p].\r\n", messageNumber, iothubClient);
        }
    }
}
static int create_events(EVENT_INSTANCE* events, const char* deviceId)
{
    int result = 0;

    srand((unsigned int)time(NULL));
    double avgWindSpeed = 10.0;
    double minTemperature = 20.0;
    double minHumidity = 60.0;
    double temperature = 0;
    double humidity = 0;

    int i;
    for (i = 0; i < MESSAGE_COUNT; i++)
    {
        temperature = minTemperature + (rand() % 10);
        humidity = minHumidity +  (rand() % 20);
        if (sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f,\"temperature\":%.2f,\"humidity\":%.2f}", avgWindSpeed + (rand() % 4 + 2), temperature, humidity) == 0)
        {
            (void)printf("ERROR: failed creating event message for device %s\r\n", deviceId);
            result = MU_FAILURE;
        }
        else if ((events[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
        {
            (void)printf("ERROR: failed creating the IOTHUB_MESSAGE_HANDLE for device %s\r\n", deviceId);
            result = MU_FAILURE;
        }
        else
        {
            MAP_HANDLE propMap;

            if ((propMap = IoTHubMessage_Properties(events[i].messageHandle)) == NULL)
            {
                (void)printf("ERROR: failed getting device %s's message property map\r\n", deviceId);
                result = MU_FAILURE;
            }
            else if (sprintf_s(propText, sizeof(propText), temperature > 28 ? "true" : "false") == 0)
            {
                (void)printf("ERROR: sprintf_s failed for device %s's message property\r\n", deviceId);
                result = MU_FAILURE;
            }
            else if (Map_AddOrUpdate(propMap, "temperatureAlert", propText) != MAP_OK)
            {
                (void)printf("ERROR: Map_AddOrUpdate failed for device %s\r\n", deviceId);
                result = MU_FAILURE;
            }
            else
            {
                events[i].deviceId = deviceId;
                events[i].messageTrackingId = i;
                result = 0;
            }
        }
    }

    return result;
}
/*
* @brief	Republish message with new data from our matching identities.
*/
static void IdentityMap_RepublishC2D(
	IDENTITY_MAP_DATA * idModule,
	MESSAGE_HANDLE messageHandle,
	IDENTITY_MAP_CONFIG * match)
{
	CONSTMAP_HANDLE properties = Message_GetProperties(messageHandle);
	if (properties == NULL)
	{

		LogError("Could not extract message properties");
	}
	else
	{
		/*Codes_SRS_IDMAP_17_049: [ On a C2D message received, IdentityMap_Receive shall call ConstMap_CloneWriteable on the message properties. ]*/
		MAP_HANDLE newProperties = ConstMap_CloneWriteable(properties);
		if (newProperties == NULL)
		{
			/*Codes_SRS_IDMAP_17_050: [ If ConstMap_CloneWriteable fails, IdentityMap_Receive shall deallocate any resources and return. ]*/
			LogError("Could not make writeable new properties map");
		}
		else
		{
			/*Codes_SRS_IDMAP_17_051: [ IdentityMap_Receive shall call Map_AddOrUpdate with key of "macAddress" and value of found macAddress. ]*/
			if (Map_AddOrUpdate(newProperties, GW_MAC_ADDRESS_PROPERTY, match->macAddress) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_052: [ If adding macAddress fails, IdentityMap_Receive shall deallocate all resources and return. ]*/
				LogError("Could not attach MAC address property to message");
			}
			/*Codes_SRS_IDMAP_17_032: [IdentityMap_Receive shall call Map_AddOrUpdate with key of "source" and value of "mapping".]*/
			else if (Map_AddOrUpdate(newProperties, GW_SOURCE_PROPERTY, GW_IDMAP_MODULE) != MAP_OK)
			{
				/*Codes_SRS_IDMAP_17_033: [If adding source fails, IdentityMap_Receive shall deallocate all resources and return.]*/
				LogError("Could not attach source property to message");
			}
			else
			{
				publish_with_new_properties(newProperties, messageHandle, idModule);
			}
			Map_Destroy(newProperties);
		}
		ConstMap_Destroy(properties);
	}
}
IOTHUB_MESSAGE_RESULT IoTHubMessage_SetProperty(IOTHUB_MESSAGE_HANDLE msg_handle, const char* key, const char* value)
{
    IOTHUB_MESSAGE_RESULT result;
    if (msg_handle == NULL || key == NULL || value == NULL)
    {
        LogError("invalid parameter (NULL) to IoTHubMessage_SetProperty iotHubMessageHandle=%p, key=%p, value=%p", msg_handle, key, value);
        result = IOTHUB_MESSAGE_INVALID_ARG;
    }
    else
    {
        if (Map_AddOrUpdate(msg_handle->properties, key, value) != MAP_OK)
        {
            LogError("Failure adding property to internal map");
            result = IOTHUB_MESSAGE_ERROR;
        }
        else
        {
            result = IOTHUB_MESSAGE_OK;
        }
    }
    return result;
}
void iothub_client_sample_http_run(void)
{
    IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle;

    EVENT_INSTANCE messages[MESSAGE_COUNT];
    double avgWindSpeed = 10.0;
    int receiveContext = 0;
    g_continueRunning = true;

    srand((unsigned int)time(NULL));

    callbackCounter = 0;

    if (platform_init() != 0)
    {
        printf("Failed to initialize the platform.\r\n");
    }
    else
    {
        (void)printf("Starting the IoTHub client sample HTTP x509...\r\n");

        if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol)) == NULL)
        {
            (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
        }
        else
        {
            unsigned int timeout = 241000;
            // Because it can poll "after 9 seconds" polls will happen effectively // at ~10 seconds.
            // Note that for scalabilty, the default value of minimumPollingTime
            // is 25 minutes. For more information, see:
            // https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
            unsigned int minimumPollingTime = 9;
            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "timeout", &timeout) != IOTHUB_CLIENT_OK)
            {
                printf("failure to set option \"timeout\"\r\n");
            }

            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
            {
                printf("failure to set option \"MinimumPollingTime\"\r\n");
            }

            /*this brings in x509 privateKey and certificate*/
            if (
                (IoTHubClient_LL_SetOption(iotHubClientHandle, "x509certificate", x509certificate) != IOTHUB_CLIENT_OK) ||
                (IoTHubClient_LL_SetOption(iotHubClientHandle, "x509privatekey", x509privatekey) != IOTHUB_CLIENT_OK)
                )
            {
                printf("failure to set options for x509, aborting\r\n");
            }
            else
            {

#ifdef MBED_BUILD_TIMESTAMP
                // For mbed add the certificate information
                if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
                {
                    printf("failure to set option \"TrustedCerts\"\r\n");
                }
#endif // MBED_BUILD_TIMESTAMP

                /* Setting Message call back, so we can receive Commands. */
                if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
                {
                    (void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
                }
                else
                {
                    (void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");

                    /* Now that we are ready to receive commands, let's send some messages */
                    size_t iterator = 0;
                    do
                    {
                        if (iterator < MESSAGE_COUNT)
                        {
                            sprintf_s(msgText, sizeof(msgText), "{\"deviceId\": \"myFirstDevice\",\"windSpeed\": %.2f}", avgWindSpeed + (rand() % 4 + 2));
                            if ((messages[iterator].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                            {
                                (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                            }
                            else
                            {
                                MAP_HANDLE propMap;

                                messages[iterator].messageTrackingId = iterator;

                                propMap = IoTHubMessage_Properties(messages[iterator].messageHandle);
                                sprintf_s(propText, sizeof(propText), "PropMsg_%d", iterator);
                                if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
                                {
                                    (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                                }

                                if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[iterator].messageHandle, SendConfirmationCallback, &messages[iterator]) != IOTHUB_CLIENT_OK)
                                {
                                    (void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
                                }
                                else
                                {
                                    (void)printf("IoTHubClient_LL_SendEventAsync accepted message [%zu] for transmission to IoT Hub.\r\n", iterator);
                                }

                            }
                        }
                        IoTHubClient_LL_DoWork(iotHubClientHandle);
                        ThreadAPI_Sleep(1);

                        iterator++;
                    } while (g_continueRunning);

                    (void)printf("iothub_client_sample_mqtt has gotten quit message, call DoWork %d more time to complete final sending...\r\n", DOWORK_LOOP_NUM);
                    for (size_t index = 0; index < DOWORK_LOOP_NUM; index++)
                    {
                        IoTHubClient_LL_DoWork(iotHubClientHandle);
                        ThreadAPI_Sleep(1);
                    }
                }
            }
            IoTHubClient_LL_Destroy(iotHubClientHandle);
        }
        platform_deinit();
    }
}
void iothub_client_sample_amqp_websockets_run(void)
{
    IOTHUB_CLIENT_HANDLE iotHubClientHandle;

    EVENT_INSTANCE messages[MESSAGE_COUNT];

    srand((unsigned int)time(NULL));
    double avgWindSpeed = 10.0;
    double minTemperature = 20.0;
    double minHumidity = 60.0;
    double temperature = 0;
    double humidity = 0;

    callbackCounter = 0;
    int receiveContext = 0;

    (void)printf("Starting the IoTHub client sample AMQP over WebSockets...\r\n");
	
	if (platform_init() != 0)
	{
		(void)printf("ERROR: failed initializing the platform.\r\n");
	}
    else if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol_over_WebSocketsTls)) == NULL)
    {
        (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
        platform_deinit();
    }
    else
    {
        // For mbed add the certificate information
        if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
        {
            printf("failure to set option \"TrustedCerts\"\r\n");
        }

        /* Setting Message call back, so we can receive Commands. */
        if (IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
        {
            (void)printf("ERROR: IoTHubClient_SetMessageCallback..........FAILED!\r\n");
        }
        else
        {
            (void)printf("IoTHubClient_SetMessageCallback...successful.\r\n");

            /* Now that we are ready to receive commands, let's send some messages */
            for (size_t i = 0; i < MESSAGE_COUNT; i++)
            {
                temperature = minTemperature + (rand() % 10);
                humidity = minHumidity +  (rand() % 20);
                sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f,\"temperature\":%.2f,\"humidity\":%.2f}", avgWindSpeed + (rand() % 4 + 2), temperature, humidity);
                if ((messages[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                {
                    (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                }
                else
                {
                    messages[i].messageTrackingId = (int)i;
                    
                    MAP_HANDLE propMap = IoTHubMessage_Properties(messages[i].messageHandle);
                    (void)sprintf_s(propText, sizeof(propText), temperature > 28 ? "true" : "false");
                    if (Map_AddOrUpdate(propMap, "temperatureAlert", propText) != MAP_OK)
                    {
                        (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                    }

                    if (IoTHubClient_SendEventAsync(iotHubClientHandle, messages[i].messageHandle, SendConfirmationCallback, &messages[i]) != IOTHUB_CLIENT_OK)
                    {
                        (void)printf("ERROR: IoTHubClient_SendEventAsync..........FAILED!\r\n");
                    }
                    else
                    {
                        (void)printf("IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.\r\n");
                    }
                }
            }

            /* Wait for Commands. */
            (void)printf("Press any key to exit the application. \r\n");
            (void)getchar();
        }
        
        IoTHubClient_Destroy(iotHubClientHandle);
        platform_deinit();
    }
}
static int SimulatorModule_thread(void * context)
{
    int thread_result;
    SIMULATOR_MODULE_HANDLE * module = (SIMULATOR_MODULE_HANDLE *)context;
    MESSAGE_CONFIG message_to_send;

    thread_result = SimulatorModule_create_message(module, &message_to_send);
    if (thread_result != 0)
    {
        LogError("unable to continue with simulation");
        if (message_to_send.sourceProperties != NULL)
        {
            Map_Destroy(message_to_send.sourceProperties);
        }
        if (message_to_send.source != NULL)
        {
            free( (void*)message_to_send.source);
        }
    }
    else
    {
        using HrClock = std::chrono::high_resolution_clock;
        using MicroSeconds = std::chrono::microseconds;
        long long time_to_wait = module->message_delay * 1000;

        size_t messages_produced = 0;
        thread_result = 0;
        while (module->thread_flag)
        {
            std::chrono::time_point<HrClock, MicroSeconds> t1 = std::chrono::time_point_cast<MicroSeconds>(HrClock::now());
            auto t1_as_int = t1.time_since_epoch().count();
            std::string t1_as_string = std::to_string(t1_as_int);
            messages_produced++;
            std::string messages_produced_as_string = std::to_string(messages_produced);
            if (Map_AddOrUpdate(message_to_send.sourceProperties, "timestamp", t1_as_string.c_str()) != MAP_OK)
            {
                LogError("Unable to update timestamp in message");
                module->thread_flag = false;
                thread_result = -__LINE__;
                break;
            }
            else if (Map_AddOrUpdate(message_to_send.sourceProperties, "sequence number", messages_produced_as_string.c_str()) != MAP_OK)
            {
                LogError("Unable to update sequence number in message");
                module->thread_flag = false;
                thread_result = -__LINE__;
                break;
            }
            else
            {
                MESSAGE_HANDLE next_message = Message_Create(&message_to_send);
                if (next_message == NULL)
                {
                    LogError("Unable to create next message");
                    module->thread_flag = false;
                    thread_result = -__LINE__;
                    break;
                }
                else
                {
                    if (Broker_Publish(module->broker, module, next_message) != BROKER_OK)
                    {
                        LogError("Unable to publish message");
                        module->thread_flag = false;
                        thread_result = -__LINE__;
                        break;
                    }
                    else
                    {
                        Message_Destroy(next_message);
                        std::chrono::time_point<HrClock, MicroSeconds> t2 = std::chrono::time_point_cast<MicroSeconds>(HrClock::now());
                        auto time_to_publish = t2.time_since_epoch().count() - t1_as_int;
                        if (time_to_publish < time_to_wait)
                        {
                            unsigned int remaining_time = static_cast<unsigned int>((time_to_wait - time_to_publish)/1000);
                            ThreadAPI_Sleep(remaining_time);
                        }
                    }
                }
            }
        }
        if (message_to_send.sourceProperties != NULL)
        {
            Map_Destroy(message_to_send.sourceProperties);
        }
        if (message_to_send.source != NULL)
        {
            free((void*)message_to_send.source);
        }
    }
    return thread_result;
}
void iothub_client_sample_mqtt_run(void)
{
    IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle;

    EVENT_INSTANCE messages[MESSAGE_COUNT];

    g_continueRunning = true;
    srand((unsigned int)time(NULL));
    double avgWindSpeed = 10.0;
    
    callbackCounter = 0;
    int receiveContext = 0;

    if (platform_init() != 0)
    {
        (void)printf("Failed to initialize the platform.\r\n");
    }
    else
    {
        if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, MQTT_Protocol)) == NULL)
        {
            (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
        }
        else
        {
            bool traceOn = true;
            IoTHubClient_LL_SetOption(iotHubClientHandle, "logtrace", &traceOn);

#ifdef MBED_BUILD_TIMESTAMP
            // For mbed add the certificate information
            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
            {
                printf("failure to set option \"TrustedCerts\"\r\n");
            }
#endif // MBED_BUILD_TIMESTAMP

            /* Setting Message call back, so we can receive Commands. */
            if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
            {
                (void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
            }
            else
            {
                (void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");

                /* Now that we are ready to receive commands, let's send some messages */
                size_t iterator = 0;
                do
                {
                    if (iterator < MESSAGE_COUNT)
                    {
                        sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f}", avgWindSpeed + (rand() % 4 + 2));
                        if ((messages[iterator].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                        {
                            (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                        }
                        else
                        {
                            messages[iterator].messageTrackingId = iterator;
                            MAP_HANDLE propMap = IoTHubMessage_Properties(messages[iterator].messageHandle);
                            sprintf_s(propText, sizeof(propText), "PropMsg_%d", iterator);
                            if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
                            {
                                (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                            }

                            if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[iterator].messageHandle, SendConfirmationCallback, &messages[iterator]) != IOTHUB_CLIENT_OK)
                            {
                                (void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
                            }
                            else
                            {
                                (void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub.\r\n", (int)iterator);
                            }
                        }
                    }
                    IoTHubClient_LL_DoWork(iotHubClientHandle);
                    ThreadAPI_Sleep(1);

                    iterator++;
                } while (g_continueRunning);

                (void)printf("iothub_client_sample_mqtt has gotten quit message, call DoWork %d more time to complete final sending...\r\n", DOWORK_LOOP_NUM);
                for (size_t index = 0; index < DOWORK_LOOP_NUM; index++)
                {
                    IoTHubClient_LL_DoWork(iotHubClientHandle);
                    ThreadAPI_Sleep(1);
                }
            }
            IoTHubClient_LL_Destroy(iotHubClientHandle);
        }
        platform_deinit();
    }
}
void iothub_client_sample_http_run(void)
{
    IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle;

    EVENT_INSTANCE messages[MESSAGE_COUNT];

    srand((unsigned int)time(NULL));
    double avgWindSpeed = 10.0;

    callbackCounter = 0;
    int receiveContext = 0;

    (void)printf("Starting the IoTHub client sample HTTP...\r\n");

    if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol)) == NULL)
    {
        (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
    }
    else
    {
        unsigned int timeout = 241000;
        if (IoTHubClient_LL_SetOption(iotHubClientHandle, "timeout", &timeout) != IOTHUB_CLIENT_OK)
        {
            printf("failure to set option \"timeout\"\r\n");
        }

        unsigned int minimumPollingTime = 9; /*because it can poll "after 9 seconds" polls will happen effectively at ~10 seconds*/
        if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
        {
            printf("failure to set option \"MinimumPollingTime\"\r\n");
        }

#ifdef MBED_BUILD_TIMESTAMP
        // For mbed add the certificate information
        if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
        {
            printf("failure to set option \"TrustedCerts\"\r\n");
        }
#endif // MBED_BUILD_TIMESTAMP

        /* Setting Message call back, so we can receive Commands. */
        if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
        {
            (void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
        }
        else
        {
            (void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");

            /* Now that we are ready to receive commands, let's send some messages */
            for (int i = 0; i < MESSAGE_COUNT; i++)
            {
                sprintf_s(msgText, sizeof(msgText), "{\"deviceId\": \"myFirstDevice\",\"windSpeed\": %.2f}", avgWindSpeed + (rand() % 4 + 2));
                if ((messages[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                {
                    (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                }
                else
                {
                    messages[i].messageTrackingId = i;

                    MAP_HANDLE propMap = IoTHubMessage_Properties(messages[i].messageHandle);
                    sprintf_s(propText, sizeof(propText), "PropMsg_%d", i);
                    if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
                    {
                        (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                    }

                    if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[i].messageHandle, SendConfirmationCallback, &messages[i]) != IOTHUB_CLIENT_OK)
                    {
                        (void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
                    }
                    else
                    {
                        (void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub.\r\n", i);
                    }
                    
                }
            }
        }

        /* Wait for Commands. */
        while (1)
        {
            IoTHubClient_LL_DoWork(iotHubClientHandle);
            ThreadAPI_Sleep(1);
        }

        IoTHubClient_LL_Destroy(iotHubClientHandle);
    }
}
/*Codes_SRS_HTTP_HEADERS_99_012:[ Calling this API shall record a header from name and value parameters.]*/
static HTTP_HEADERS_RESULT headers_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE handle, const char* name, const char* value, bool replace)
{
    HTTP_HEADERS_RESULT result;
    /*Codes_SRS_HTTP_HEADERS_99_014:[ The function shall return when the handle is not valid or when name parameter is NULL or when value parameter is NULL.]*/
    if (
        (handle == NULL) ||
        (name == NULL) ||
        (value == NULL)
        )
    {
        result = HTTP_HEADERS_INVALID_ARG;
        LogError("invalid arg (NULL) , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result));
    }
    else
    {
        /*Codes_SRS_HTTP_HEADERS_99_036:[ If name contains the characters outside character codes 33 to 126 then the return value shall be HTTP_HEADERS_INVALID_ARG]*/
        /*Codes_SRS_HTTP_HEADERS_99_031:[ If name contains the character ":" then the return value shall be HTTP_HEADERS_INVALID_ARG.]*/
        size_t i;
        size_t nameLen = strlen(name);
        for (i = 0; i < nameLen; i++)
        {
            if ((name[i] < 33) || (126 < name[i]) || (name[i] == ':'))
            {
                break;
            }
        }

        if (i < nameLen)
        {
            result = HTTP_HEADERS_INVALID_ARG;
            LogError("(result = %s)", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result));
        }
        else
        {
            HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle;
            const char* existingValue = Map_GetValueFromKey(handleData->headers, name);
            /*eat up the whitespaces from value, as per RFC 2616, chapter 4.2 "The field value MAY be preceded by any amount of LWS, though a single SP is preferred."*/
            /*Codes_SRS_HTTP_HEADERS_02_002: [The LWS from the beginning of the value shall not be stored.] */
            while ((value[0] == ' ') || (value[0] == '\t') || (value[0] == '\r') || (value[0] == '\n'))
            {
                value++;
            }

            if (!replace && (existingValue != NULL))
            {
                char* newValue = (char*)malloc(strlen(existingValue) + COMMA_AND_SPACE_LENGTH + strlen(value) + 1);
                if (newValue == NULL)
                {
                    /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/
                    result = HTTP_HEADERS_ALLOC_FAILED;
                    LogError("failed to malloc , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result));
                }
                else
                {
                    /*Codes_SRS_HTTP_HEADERS_99_017:[ If the name already exists in the collection of headers, the function shall concatenate the new value after the existing value, separated by a comma and a space as in: old-value+", "+new-value.]*/
                    (void)strcpy(newValue, existingValue);
                    (void)strcat(newValue, COMMA_AND_SPACE);
                    (void)strcat(newValue, value);

                    /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/
                    if (Map_AddOrUpdate(handleData->headers, name, newValue) != MAP_OK)
                    {
                        /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/
                        result = HTTP_HEADERS_ERROR;
                        LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result));
                    }
                    else
                    {
                        /*Codes_SRS_HTTP_HEADERS_99_013:[ The function shall return HTTP_HEADERS_OK when execution is successful.]*/
                        result = HTTP_HEADERS_OK;
                    }
                    free(newValue);
                }
            }
            else
            {
                /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/
                if (Map_AddOrUpdate(handleData->headers, name, value) != MAP_OK)
                {
                    /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/
                    result = HTTP_HEADERS_ALLOC_FAILED;
                    LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result));
                }
                else
                {
                    result = HTTP_HEADERS_OK;
                }
            }
        }
    }

    return result;
}
static void RecvMessage(IOTHUB_PROVISIONED_DEVICE* deviceToUse)
{
    // arrange
    IOTHUB_CLIENT_HANDLE iotHubClientHandle;

    IOTHUB_SERVICE_CLIENT_AUTH_HANDLE iotHubServiceClientHandle;
    IOTHUB_MESSAGING_CLIENT_HANDLE iotHubMessagingHandle;
    IOTHUB_MESSAGING_RESULT iotHubMessagingResult;
    IOTHUB_MESSAGE_RESULT iotHubMessageResult;

    EXPECTED_RECEIVE_DATA* receiveUserContext;
    IOTHUB_MESSAGE_HANDLE messageHandle;

    // act
    IoTHub_Init();

    // Create Service Client
    iotHubServiceClientHandle = IoTHubServiceClientAuth_CreateFromConnectionString(IoTHubAccount_GetIoTHubConnString(g_iothubAcctInfo1));
    ASSERT_IS_NOT_NULL(iotHubServiceClientHandle, "Could not initialize IoTHubServiceClient to send C2D messages to the device");

    iotHubMessagingHandle = IoTHubMessaging_Create(iotHubServiceClientHandle);
    ASSERT_IS_NOT_NULL(iotHubMessagingHandle, "Could not initialize IoTHubMessaging to send C2D messages to the device");

    iotHubMessagingResult = IoTHubMessaging_Open(iotHubMessagingHandle, openCompleteCallback, (void*)"Context string for open");
    ASSERT_ARE_EQUAL(int, IOTHUB_MESSAGING_OK, iotHubMessagingResult);

    // Create user context and message
    receiveUserContext = ReceiveUserContext_Create();
    ASSERT_IS_NOT_NULL(receiveUserContext, "Could not create receive user context");

    messageHandle = IoTHubMessage_CreateFromString(MSG_CONTENT1);

    ASSERT_IS_NOT_NULL(messageHandle, "Could not create IoTHubMessage to send C2D messages to the device");

    iotHubMessageResult = IoTHubMessage_SetMessageId(messageHandle, MSG_ID1);
    ASSERT_ARE_EQUAL(int, IOTHUB_MESSAGING_OK, iotHubMessageResult);

    iotHubMessageResult = IoTHubMessage_SetCorrelationId(messageHandle, MSG_CORRELATION_ID1);
    ASSERT_ARE_EQUAL(int, IOTHUB_MESSAGING_OK, iotHubMessageResult);

    MAP_HANDLE mapHandle = IoTHubMessage_Properties(messageHandle);
    for (size_t i = 0; i < MSG_PROP_COUNT; i++)
    {
        if (Map_AddOrUpdate(mapHandle, MSG_PROP_KEYS[i], MSG_PROP_VALS[i]) != MAP_OK)
        {
            (void)printf("ERROR: Map_AddOrUpdate failed for property %zu!\r\n", i);
        }
    }

    iotHubMessagingResult = IoTHubMessaging_SendAsync(iotHubMessagingHandle, deviceToUse->deviceId, messageHandle, sendCompleteCallback, receiveUserContext);
    ASSERT_ARE_EQUAL(int, IOTHUB_MESSAGING_OK, iotHubMessagingResult, "IoTHubMessaging_SendAsync failed, could not send C2D message to the device");
    iotHubClientHandle = IoTHubClient_CreateFromConnectionString(deviceToUse->connectionString, HTTP_Protocol);
    ASSERT_IS_NOT_NULL(iotHubClientHandle, "Failure creating Iothub Client");

    if (deviceToUse->howToCreate == IOTHUB_ACCOUNT_AUTH_X509) {
        IOTHUB_CLIENT_RESULT result;
        result = IoTHubClient_SetOption(iotHubClientHandle, OPTION_X509_CERT, deviceToUse->certificate);
        ASSERT_ARE_EQUAL(IOTHUB_CLIENT_RESULT, IOTHUB_CLIENT_OK, result, "Could not set the device x509 certificate");
        result = IoTHubClient_SetOption(iotHubClientHandle, OPTION_X509_PRIVATE_KEY, deviceToUse->primaryAuthentication);
        ASSERT_ARE_EQUAL(IOTHUB_CLIENT_RESULT, IOTHUB_CLIENT_OK, result, "Could not set the device x509 privateKey");
    }

    IOTHUB_CLIENT_RESULT result = IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, receiveUserContext);
    ASSERT_ARE_EQUAL(IOTHUB_CLIENT_RESULT, IOTHUB_CLIENT_OK, result, "Failure setting message callback");

    unsigned int minimumPollingTime = 1; /*because it should not wait*/
    if (IoTHubClient_SetOption(iotHubClientHandle, OPTION_MIN_POLLING_TIME, &minimumPollingTime) != IOTHUB_CLIENT_OK)
    {
        printf("failure to set option \"MinimumPollingTime\"\r\n");
    }

    time_t beginOperation, nowTime;
    beginOperation = time(NULL);
    while (
        (
        (nowTime = time(NULL)),
            (difftime(nowTime, beginOperation) < MAX_CLOUD_TRAVEL_TIME) //time box
            )
        )
    {
        if (Lock(receiveUserContext->lock) != LOCK_OK)
        {
            ASSERT_FAIL("unable ot lock");
        }
        else
        {
            if (receiveUserContext->wasFound)
            {
                (void)Unlock(receiveUserContext->lock);
                break;
            }
            (void)Unlock(receiveUserContext->lock);
        }
        ThreadAPI_Sleep(100);
    }

    // assert
    ASSERT_IS_TRUE(receiveUserContext->wasFound, "Failure retrieving message that was sent to IotHub."); // was found is written by the callback...

    // cleanup
    IoTHubMessage_Destroy(messageHandle);
    IoTHubMessaging_Close(iotHubMessagingHandle);
    IoTHubMessaging_Destroy(iotHubMessagingHandle);
    IoTHubServiceClientAuth_Destroy(iotHubServiceClientHandle);

    IoTHubClient_Destroy(iotHubClientHandle);
    ReceiveUserContext_Destroy(receiveUserContext);
}
Exemple #15
0
int SendBatch_Sample(void)
{
    int result;
    time_t t = time(&t);
    (void)printf("Starting the EventHub Client SendBatch Sample (%s)...\r\n", EventHubClient_GetVersionString() ); 

    if (platform_init() != 0)
    {
        (void)printf("ERROR: Failed initializing platform!\r\n");
        result = 1;
    }
    else
    {
        //Create an Array of EventData so we can send these data batched.
        EVENTDATA_HANDLE eventDataList[NUM_OF_MSG_TO_SEND];

        size_t index;
        for (index = 0; index < NUM_OF_MSG_TO_SEND; index++)
        {
            char msgContent[BUFFER_SIZE];
            size_t msgLength = sprintf_s(msgContent, BUFFER_SIZE, "{\"messageId\":%ul, \"timeValue\":%I64d, \"name\":\"SendBatch_Sample\"}", index, t);

            if ((eventDataList[index] = EventData_CreateWithNewMemory((const unsigned char*)msgContent, msgLength)) == NULL)
            {
                (void)printf("ERROR: EventData_CreateWithNewMemory returned NULL!\r\n");
                result = 1;
                break;
            }
        }

        if (index == NUM_OF_MSG_TO_SEND)
        {
            EVENTHUBCLIENT_HANDLE eventHubClientHandle = EventHubClient_CreateFromConnectionString(connectionString, eventHubPath);
            if (eventHubClientHandle == NULL)
            {
                (void)printf("ERROR: EventHubClient_CreateFromConnectionString returned NULL!\r\n");
                result = 1;
            }
            else
            {
                for (size_t i = 0; i < NUM_OF_MSG_TO_SEND; i++)
                {
                    EventData_SetPartitionKey(eventDataList[i], PARTITION_KEY_INFO);
                }


                MAP_HANDLE mapProperties = EventData_Properties(eventDataList[0]);
                if (mapProperties != NULL)
                {
                    if ((Map_AddOrUpdate(mapProperties, "SendBatch_HL_1", TEST_STRING_VALUE_1) != MAP_OK) ||
                        (Map_AddOrUpdate(mapProperties, "SendBatch_HL_2", TEST_STRING_VALUE_2) != MAP_OK)
                        )
                    {
                        (void)printf("ERROR: Map_AddOrUpdate failed!\r\n");
                    }
                }

                //Send all 3 data created above on the same call (Batched)
                if (EventHubClient_SendBatch(eventHubClientHandle, eventDataList, NUM_OF_MSG_TO_SEND) != EVENTHUBCLIENT_OK)
                {
                    (void)printf("ERROR: EventHubClient_SendBatch failed!\r\n");
                    result = 1;
                }
                else
                {
                    (void)printf("EventHubClient_SendBatch.......Successful\r\n");
                    result = 0;
                }
                EventHubClient_Destroy(eventHubClientHandle);
            }
        }
        for (size_t i = 0; i < index; i++)
        {
            EventData_Destroy(eventDataList[i]);
        }

        platform_init();
    }

    return result;
}
void simplesample_http_run(void)
{
    if (platform_init() != 0)
    {
        printf("Failed to initialize the platform.\r\n");
    }
    else
    {
        if (serializer_init(NULL) != SERIALIZER_OK)
        {
            (void)printf("Failed on serializer_init\r\n");
        }
        else
        {
            IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol);
            int avgWindSpeed = 10;
            float minTemperature = 20.0;
            float minHumidity = 60.0;

            srand((unsigned int)time(NULL));

            if (iotHubClientHandle == NULL)
            {
                (void)printf("Failed on IoTHubClient_LL_Create\r\n");
            }
            else
            {
                // Because it can poll "after 9 seconds" polls will happen 
                // effectively at ~10 seconds.
                // Note that for scalabilty, the default value of minimumPollingTime
                // is 25 minutes. For more information, see:
                // https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
                unsigned int minimumPollingTime = 9;
                ContosoAnemometer* myWeather;

                if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
                {
                    printf("failure to set option \"MinimumPollingTime\"\r\n");
                }

#ifdef SET_TRUSTED_CERT_IN_SAMPLES
                // For mbed add the certificate information
                if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
                {
                    (void)printf("failure to set option \"TrustedCerts\"\r\n");
                }
#endif // SET_TRUSTED_CERT_IN_SAMPLES

                myWeather = CREATE_MODEL_INSTANCE(WeatherStation, ContosoAnemometer);
                if (myWeather == NULL)
                {
                    (void)printf("Failed on CREATE_MODEL_INSTANCE\r\n");
                }
                else
                {
                    if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, IoTHubMessage, myWeather) != IOTHUB_CLIENT_OK)
                    {
                        printf("unable to IoTHubClient_SetMessageCallback\r\n");
                    }
                    else
                    {
                        myWeather->DeviceId = "myFirstDevice";
                        myWeather->WindSpeed = avgWindSpeed + (rand() % 4 + 2);
                        myWeather->Temperature = minTemperature + (rand() % 10);
                        myWeather->Humidity = minHumidity + (rand() % 20);
                        {
                            unsigned char* destination;
                            size_t destinationSize;
                            if (SERIALIZE(&destination, &destinationSize, myWeather->DeviceId, myWeather->WindSpeed, myWeather->Temperature, myWeather->Humidity) != CODEFIRST_OK)
                            {
                                (void)printf("Failed to serialize\r\n");
                            }
                            else
                            {
                                IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(destination, destinationSize);
                                if (messageHandle == NULL)
                                {
                                    printf("unable to create a new IoTHubMessage\r\n");
                                }
                                else
                                {
                                    MAP_HANDLE propMap = IoTHubMessage_Properties(messageHandle);
                                    (void)sprintf_s(propText, sizeof(propText), myWeather->Temperature > 28 ? "true" : "false");
                                    if (Map_AddOrUpdate(propMap, "temperatureAlert", propText) != MAP_OK)
                                    {
                                        printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                                    }

                                    if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)1) != IOTHUB_CLIENT_OK)
                                    {
                                        printf("failed to hand over the message to IoTHubClient");
                                    }
                                    else
                                    {
                                        printf("IoTHubClient accepted the message for delivery\r\n");
                                    }

                                    IoTHubMessage_Destroy(messageHandle);
                                }
                                free(destination);
                            }
                        }

                        /* wait for commands */
                        while (1)
                        {
                            IoTHubClient_LL_DoWork(iotHubClientHandle);
                            ThreadAPI_Sleep(100);
                        }
                    }

                    DESTROY_MODEL_INSTANCE(myWeather);
                }
                IoTHubClient_LL_Destroy(iotHubClientHandle);
            }
            serializer_deinit();
        }
        platform_deinit();
    }
}
void iothub_client_sample_amqp_run(void)
{
    IOTHUB_CLIENT_HANDLE iotHubClientHandle;

    EVENT_INSTANCE messages[MESSAGE_COUNT];

    srand((unsigned int)time(NULL));
    double avgWindSpeed = 10.0;

    callbackCounter = 0;
    int receiveContext = 0;

    (void)printf("Starting the IoTHub client sample AMQP...\r\n");
    
    if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol)) == NULL)
    {
        (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
    }
    else
    {
#ifdef MBED_BUILD_TIMESTAMP
        // For mbed add the certificate information
        if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
        {
            printf("failure to set option \"TrustedCerts\"\r\n");
        }
#endif // MBED_BUILD_TIMESTAMP

        /* Setting Message call back, so we can receive Commands. */
        if (IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
        {
            (void)printf("ERROR: IoTHubClient_SetMessageCallback..........FAILED!\r\n");
        }
        else
        {
            (void)printf("IoTHubClient_SetMessageCallback...successful.\r\n");

            /* Now that we are ready to receive commands, let's send some messages */
            for (size_t i = 0; i < MESSAGE_COUNT; i++)
            {
                sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":\"myFirstDevice\",\"windSpeed\":%.2f}", avgWindSpeed+(rand()%4+2) );
                if ((messages[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                {
                    (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                }
                else
                {
                    messages[i].messageTrackingId = i;
                    
                    MAP_HANDLE propMap = IoTHubMessage_Properties(messages[i].messageHandle);
                    sprintf_s(propText, sizeof(propText), "PropMsg_%d", i);
                    if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
                    {
                        (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                    }

                    if (IoTHubClient_SendEventAsync(iotHubClientHandle, messages[i].messageHandle, SendConfirmationCallback, &messages[i]) != IOTHUB_CLIENT_OK)
                    {
                        (void)printf("ERROR: IoTHubClient_SendEventAsync..........FAILED!\r\n");
                    }
                    else
                    {
                        (void)printf("IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub.\r\n");
                    }
                }
            }

            /* Wait for Commands. */
            (void)printf("Press any key to exit the application. \r\n");
            (void)getchar();
        }
        
        IoTHubClient_Destroy(iotHubClientHandle);
    }
}
void iothub_client_sample_http_run(void)
{
    IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle;

    EVENT_INSTANCE messages[MESSAGE_COUNT];
    double avgWindSpeed = 10.0;
    int receiveContext = 0;
    char tpmConnectionString[256] = "";
    uint tpmConnectionStringSize = 0;

    srand((unsigned int)time(NULL));

    callbackCounter = 0;

    if (platform_init() != 0)
    {
        printf("Failed to initialize the platform.\r\n");
    }
    else
    {
        (void)printf("Starting the IoTHub client sample HTTP...\r\n");

        if((LimpetReadURI(0, tpmConnectionString, sizeof(tpmConnectionString), &tpmConnectionStringSize) != 0) ||
           (!strcat(tpmConnectionString, ";SharedAccessKey=Limpet(0)")))
        {
            (void)printf("ERROR: ConnectionString could not be read from TPM!\r\n");
        }
//        else if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol)) == NULL)
        else if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(tpmConnectionString, HTTP_Protocol)) == NULL)
        {
            (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
        }
        else
        {
            unsigned int timeout = 241000;
            // Because it can poll "after 9 seconds" polls will happen effectively // at ~10 seconds.
            // Note that for scalabilty, the default value of minimumPollingTime
            // is 25 minutes. For more information, see:
            // https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
            unsigned int minimumPollingTime = 9;
//            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "timeout", &timeout) != IOTHUB_CLIENT_OK)
//            {
//                printf("failure to set option \"timeout\"\r\n");
//            }

            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
            {
                printf("failure to set option \"MinimumPollingTime\"\r\n");
            }

#ifdef MBED_BUILD_TIMESTAMP
            // For mbed add the certificate information
            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
            {
                printf("failure to set option \"TrustedCerts\"\r\n");
            }
#endif // MBED_BUILD_TIMESTAMP

            /* Setting Message call back, so we can receive Commands. */
            if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
            {
                (void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
            }
            else
            {
                int i;

                (void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");

                /* Now that we are ready to receive commands, let's send some messages */
                for (i = 0; i < MESSAGE_COUNT; i++)
                {
                    sprintf_s(msgText, sizeof(msgText), "{\"deviceId\": \"myFirstDevice\",\"windSpeed\": %.2f}", avgWindSpeed + (rand() % 4 + 2));
                    if ((messages[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
                    {
                        (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
                    }
                    else
                    {
                        MAP_HANDLE propMap;

                        messages[i].messageTrackingId = i;

                        propMap = IoTHubMessage_Properties(messages[i].messageHandle);
                        sprintf_s(propText, sizeof(propText), "PropMsg_%d", i);
                        if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
                        {
                            (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
                        }

                        if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[i].messageHandle, SendConfirmationCallback, &messages[i]) != IOTHUB_CLIENT_OK)
                        {
                            (void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
                        }
                        else
                        {
                            (void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub.\r\n", i);
                        }

                    }
                }
            }

            /* Wait for Commands. */
            while (1)
            {
                IoTHubClient_LL_DoWork(iotHubClientHandle);
            }

            IoTHubClient_LL_Destroy(iotHubClientHandle);
        }
        platform_deinit();
    }
}
void iothub_messaging_ll_sample_run(void)
{
    xlogging_set_log_function(consolelogger_log);

    if (platform_init() != 0)
    {
        (void)printf("Failed to initialize the platform.\r\n");
    }
    else
    {
        (void)printf("Calling IoTHubServiceClientAuth_CreateFromConnectionString with connection string\n");
        iotHubServiceClientHandle = IoTHubServiceClientAuth_CreateFromConnectionString(connectionString);
        if (iotHubServiceClientHandle == NULL)
        {
            (void)printf("IoTHubServiceClientAuth_CreateFromConnectionString failed\n");
        }
        else
        {
            (void)printf("Service Client Authentication handle has been created successfully\n");

            (void)printf("Creating Messaging...\n");
            iotHubMessagingHandle = IoTHubMessaging_LL_Create(iotHubServiceClientHandle);
            if (iotHubMessagingHandle == NULL)
            {
                (void)printf("IoTHubMessaging_LL_Create failed\n");
            }
            else
            {
                (void)printf("Messaging has been created successfully\n");
                (void)printf("Opening Messaging...\n");

                iotHubMessagingResult = IoTHubMessaging_LL_SetFeedbackMessageCallback(iotHubMessagingHandle, feedbackReceivedCallback, "Context string for feedback");
                if (iotHubMessagingResult != IOTHUB_MESSAGING_OK)
                {
                    (void)printf("IoTHubMessaging_LL_SetFeedbackMessageCallback failed\n");
                }
                else
                {
                    iotHubMessagingResult = IoTHubMessaging_LL_Open(iotHubMessagingHandle, openCompleteCallback, "Context string for open");
                    if (iotHubMessagingResult != IOTHUB_MESSAGING_OK)
                    {
                        (void)printf("IoTHubMessaging_LL_Open failed\n");
                    }
                    else
                    {
                        for (int i = 0; i < MESSAGE_COUNT; i++)
                        {
                            double avgWindSpeed = 10.0;
                            static char msgText[1024];
                            sprintf_s(msgText, sizeof(msgText), "{\"deviceId\":%s,\"windSpeed\":%.2f, \"i\":%d}", deviceId, avgWindSpeed + (rand() % 4 + 2), i);
                            IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText));
                            if (messageHandle == NULL)
                            {
                                (void)printf("IoTHubMessage_CreateFromByteArray failed\n");
                                break;
                            }
                            else
                            {
                                IOTHUB_MESSAGE_RESULT iotHubMessageResult;
                                const char* MSG_ID = "Sample_MessageId";
                                const char* MSG_CORRELATION_ID = "Sample_MessageCorrelationId";
                                const char* MSG_PROP_KEYS[3] = { "Sample_Key1", "Sample_Key2", "Sample_Key3" };
                                const char* MSG_PROP_VALS[3] = { "Sample_Val1", "Sample_Val2", "Sample_Val3" };

                                iotHubMessageResult = IoTHubMessage_SetMessageId(messageHandle, MSG_ID);
                                if (iotHubMessageResult != IOTHUB_MESSAGE_OK)
                                {
                                    (void)printf("IoTHubMessage_SetMessageId failed. Exiting...\n");
                                    IoTHubMessage_Destroy(messageHandle);
                                    break;
                                }
                                else
                                {
                                    iotHubMessageResult = IoTHubMessage_SetCorrelationId(messageHandle, MSG_CORRELATION_ID);
                                    if (iotHubMessageResult != IOTHUB_MESSAGE_OK)
                                    {
                                        (void)printf("IoTHubMessage_SetCorrelationId failed. Exiting...\n");
                                        IoTHubMessage_Destroy(messageHandle);
                                        break;
                                    }
                                    else
                                    {
                                        MAP_HANDLE mapHandle = IoTHubMessage_Properties(messageHandle);
                                        for (size_t j = 0; j < 3; j++)
                                        {
                                            if (Map_AddOrUpdate(mapHandle, MSG_PROP_KEYS[j], MSG_PROP_VALS[j]) != MAP_OK)
                                            {
                                                (void)printf("ERROR: Map_AddOrUpdate failed for property %zu!\r\n", j);
                                            }
                                        }

                                        iotHubMessagingResult = IoTHubMessaging_LL_Send(iotHubMessagingHandle, deviceId, messageHandle, sendCompleteCallback, NULL);
                                        if (iotHubMessagingResult != IOTHUB_MESSAGING_OK)
                                        {
                                            (void)printf("IoTHubMessaging_LL_Send failed\n");
                                        }
                                        else
                                        {
                                            (void)printf("IoTHubMessaging_LL_Send accepted data for transmission to IoT Hub.\r\n");
                                        }
                                    }
                                }
                            }
                            IoTHubMessage_Destroy(messageHandle);
                        }

                        feedbackCount = 0;
                        while (feedbackCount < MESSAGE_COUNT)
                        {
                            IoTHubMessaging_LL_DoWork(iotHubMessagingHandle);
                            ThreadAPI_Sleep(1);
                        }

                        /* Wait for user to press a key. */
                        (void)printf("Press any key to exit the application. \r\n");
                        (void)getchar();

                        IoTHubMessaging_LL_Close(iotHubMessagingHandle);
                    }
                }
                (void)printf("Calling IoTHubMessaging_LL_Destroy...\n");
                IoTHubMessaging_LL_Destroy(iotHubMessagingHandle);
            }
            (void)printf("Calling IoTHubServiceClientAuth_Destroy...\n");
            IoTHubServiceClientAuth_Destroy(iotHubServiceClientHandle);
        }
        platform_deinit();
    }
}