Receive cloud to device message in Azure starter kit device

95504669 521 Reputation points
2023-02-09T12:27:34.01+00:00

Hi. We use Avnet Azure starter kit device and we are trying to receive the c2d message from the device. How can check the c2d message in the device and is there any code sample that my azure device can use to get it? We know how to send the c2d message, but stuck in receiving it. Please let us know the ways to do it.
Thank you.

Azure Sphere
Azure Sphere
An Azure internet of things security solution including hardware, operating system, and cloud components.
156 questions
Azure IoT Hub
Azure IoT Hub
An Azure service that enables bidirectional communication between internet of things (IoT) devices and applications.
1,124 questions
{count} votes

1 answer

Sort by: Most helpful
  1. AshokPeddakotla-MSFT 27,491 Reputation points
    2023-02-17T02:12:24.9+00:00

    We know how to send the c2d message, but stuck in receiving it

    Can you share further details on what is not working? Are you seeing any specific errors while receiving the message? Are you following any documentation for the steps?

    An Azure Sphere application can interact with Azure IoT Hub to send and receive messages, manage a device twin, and receive direct method calls from an Azure IoT service application.

    The Azure IoT Device SDK for C includes an Azure IoT Hub client library that you can use in Azure Sphere applications.

    Receiving a message is an asynchronous operation. First, you register the callback to invoke when the device receives a message:

    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");
        ...
    

    The last parameter is a void pointer to whatever you want. In the sample, it's a pointer to an integer but it could be a pointer to a more complex data structure. This parameter enables the callback function to operate on shared state with the caller of this function.

    When the device receives a message, the registered callback function is invoked. This callback function retrieves:

    • The message ID and correlation ID from the message.
    • The message content.
    • Any custom properties from the message.
    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;
    
                    printf(" Message Properties:\r\n");
                    for (index = 0; index < propertyCount; index++)
                    {
                        (void)printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
                    }
                    (void)printf("\r\n");
                }
            }
        }
    
        /* Some device specific action code goes here... */
        (*counter)++;
        return IOTHUBMESSAGE_ACCEPTED;
    }
    

    Use the IoTHubMessage_GetByteArray function to retrieve the message, which in this example is a string.

    For more details, please see Azure IoT device SDK for C

    Do let us know if you have any further queries.