0
votes

I have created the following c program based on a provided sample in order just to get messages from iot hub :

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include "azure_c_shared_utility/shared_util_options.h"
#include "iothub_client.h"
#include "iothub_message.h"
#include "azure_c_shared_utility/threadapi.h"
#include "azure_c_shared_utility/crt_abstractions.h"
#include "azure_c_shared_utility/platform.h"
#include "iothubtransportmqtt.h"
#include "iothub_client_options.h"
#include "iothub_device_client_ll.h"
#include "iothub_device_client.h"
#include "iothub_client_sample_mqtt_esp8266.h"

/*String containing Hostname, Device Id & Device Key in the format:                         */
/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"                */
/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>"    */
static const char* connectionString = "HostName=mydevice";

static int callbackCounter;
//static char msgText[1024];
//static char propText[1024];
static bool g_continueRunning;
#define MESSAGE_COUNT 50
#define SET_TRUSTED_CERT_IN_SAMPLES
#define DOWORK_LOOP_NUM     3

#ifdef SET_TRUSTED_CERT_IN_SAMPLES
#include "certs.h"
#endif 

typedef struct EVENT_INSTANCE_TAG
{
    IOTHUB_MESSAGE_HANDLE messageHandle;
    size_t messageTrackingId;  // For tracking the messages within the user callback.
} EVENT_INSTANCE;

static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
{
    int* counter = (int*)userContextCallback;
    const char* buffer;
    size_t size;
    MAP_HANDLE mapProperties;
    const char* messageId;
    const char* correlationId;

    // Message properties
    if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL)
    {
        messageId = "<null>";
    }

    if ((correlationId = IoTHubMessage_GetCorrelationId(message)) == NULL)
    {
        correlationId = "<null>";
    }

    // Message content
    if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) != IOTHUB_MESSAGE_OK)
    {
        (void)printf("unable to retrieve the message data\r\n");
    }
    else
    {
        (void)printf("Received Message [%d]\r\n Message ID: %s\r\n Correlation ID: %s\r\n Data: <<<%.*s>>> & Size=%d\r\n", *counter, messageId, correlationId, (int)size, buffer, (int)size);
        // If we receive the work 'quit' then we stop running
        if (size == (strlen("quit") * sizeof(char)) && memcmp(buffer, "quit", size) == 0)
        {
            g_continueRunning = false;
        }
    }

    // Retrieve properties from the message
    mapProperties = IoTHubMessage_Properties(message);
    if (mapProperties != NULL)
    {
        const char*const* keys;
        const char*const* values;
        size_t propertyCount = 0;
        if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
        {
            if (propertyCount > 0)
            {
                size_t index;
                std::string uid;
                printf(" Message Properties:\r\n");
                for (index = 0; index < propertyCount; index++)
                {
                    (void)printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
                    if (std::strcmp(keys[index],"uid") == 0 )
                    {
                        uid =  values[index];
                        std::cout << "uid is " << uid << std::endl;
                    }

                }
                (void)printf("\r\n");
            }
        }
    }

    /* Some device specific action code goes here... */
    (*counter)++;
    return IOTHUBMESSAGE_ACCEPTED;
}

// static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
// {
//     EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
//     size_t id = eventInstance->messageTrackingId;

//     (void)printf("Confirmation[%d] received for message tracking id = %d with result = %s\r\n", callbackCounter, (int)id, MU_ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
//     /* Some device specific action code goes here... */
//     callbackCounter++;
//     IoTHubMessage_Destroy(eventInstance->messageHandle);
// }

static void connection_status_callback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* user_context)
{
    (void)reason;
    (void)user_context;
    // This sample DOES NOT take into consideration network outages.
    if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED)
    {
        (void)printf("The device client is connected to iothub\r\n");
    }
    else
    {
        (void)printf("The device client has been disconnected\r\n");
    }
}

void iothub_client_sample_mqtt_esp8266_run(void)
{

    IOTHUB_CLIENT_HANDLE iotHubClientHandle;
    g_continueRunning = true;
    srand((unsigned int)time(NULL));

    callbackCounter = 0;
    int receiveContext = 0;

    if (platform_init() != 0)
    {
        (void)printf("Failed to initialize the platform.\r\n");
    }
    else
    {
        if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, MQTT_Protocol)) == NULL)
        {
            (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
        }
        else
        {
            bool traceOn = true;
            IoTHubClient_SetOption(iotHubClientHandle, OPTION_LOG_TRACE, &traceOn);
            #ifdef SET_TRUSTED_CERT_IN_SAMPLES
            // For mbed add the certificate information
                  if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
                   {
                       (void)printf("failure to set option \"TrustedCerts\"\r\n");
                   }
            #endif
            (void)IoTHubDeviceClient_SetConnectionStatusCallback(iotHubClientHandle, connection_status_callback, NULL);
            /* Setting Message call back, so we can receive Commands. */
            if (IoTHubClient_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");

                while (g_continueRunning)
                {
                  ThreadAPI_Sleep(1000);
                }

            }
            IoTHubClient_Destroy(iotHubClientHandle);
        }
        platform_deinit();
    }
}

int main(void)
{
    iothub_client_sample_mqtt_esp8266_run();
    return 0;
}

Everything works fine. I get both messageid and correlationid correctly. However I'd like to receive EventEnqueuedUtcTime at my callback which is mentioned here https://docs.microsoft.com/en-us/azure/stream-analytics/stream-analytics-define-inputs#configure-an-iot-hub-as-a-data-stream-input.

Since I'm quite new at this SDK I haven't a way to achieve this. Does anyone has an idea ?

1

1 Answers

1
votes

I think you are confusing the device SDK and the service SDK. The EventEnqueuedUtcTime is available to a service side application that is reading the telemetry sent by devices to the IoT hub. I'm assuming that you expected to get that same value for a message delivered to your device via a Cloud to Device message which would be delivered to your callback function ReceiveMessageCallback. That property is not added to messages from the cloud to the device only messages from the device to the cloud.