IoTHub raw messaging client sample using AMQP

Dependencies:   iothub_client EthernetInterface NTPClient iothub_amqp_transport azure_c_shared_utility mbed-rtos mbed azure_uamqp_c wolfSSL

This sample showcases the usage of Azure IoT client libraries with the AMQP transport for sending/receiving raw messages from an IoT Hub.

iothub_client_sample_amqp.c

Committer:
AzureIoTClient
Date:
2015-09-16
Revision:
4:24cbfabe1b9d
Parent:
0:eb1c7bc1f4f1
Child:
8:5db3366b6f57

File content as of revision 4:24cbfabe1b9d:

// 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 "iothub_client.h"
#include "iothub_message.h"
#include "threadapi.h"
#include "crt_abstractions.h"
#include "iothubtransportamqp.h"

#ifdef MBED_BUILD_TIMESTAMP
#include "certs.h"
#endif // MBED_BUILD_TIMESTAMP


static const char* connectionString = "[device connection string]";
static int callbackCounter;

DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);

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

static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveNotificationCallback(IOTHUB_MESSAGE_HANDLE notificationMessage, void* userContextCallback)
{
    int* counter = (int*)userContextCallback;
    const char* buffer;
    size_t size;
    if (IoTHubMessage_GetByteArray(notificationMessage, (const unsigned char**)&buffer, &size) == IOTHUB_MESSAGE_OK)
    {
        (void)printf("Received Notification [%d] with Data: <<<%.*s>>> & Size=%d\r\n", *counter, (int)size, buffer, (int)size);
    }

    // Retrieve properties from the message
    MAP_HANDLE mapProperties = IoTHubMessage_Properties(notificationMessage);
    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)
            {
                printf("Message Properties:\r\n");
                for (size_t index = 0; index < propertyCount; index++)
                {
                    printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
                }
                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;
    (void)printf("Confirmation[%d] received for message tracking id = %d with result = %s\r\n", callbackCounter, eventInstance->messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
    /* Some device specific action code goes here... */
    callbackCounter++;
    IoTHubMessage_Destroy(eventInstance->messageHandle);
}

static char msgText[1024];
static char propText[1024];
#define MESSAGE_COUNT 5

void iothub_client_sample_amqp_run(void)
{
    IOTHUB_CLIENT_HANDLE iotHubClientHandle;

    EVENT_INSTANCE messages[MESSAGE_COUNT];

    callbackCounter = 0;
    int receiveContext = 0;

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

    if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, IoTHubTransportAmqp_ProvideTransportInterface)) == 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 Notification call back, so we can receive Commands. */
        if (IoTHubClient_SetNotificationCallback(iotHubClientHandle, ReceiveNotificationCallback, &receiveContext) != IOTHUB_CLIENT_OK)
        {
            (void)printf("ERROR: IoTHubClient_SetNotificationCallback..........FAILED!\r\n");
        }
        else
        {
            (void)printf("IoTHubClient_SetNotificationCallback...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), "Message_%d_From_IoTHubClient_Over_AMQP", i);
                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);
    }
}