void vShadowDeviceTask()

in source/demo-tasks/shadow_device_task.c [717:821]


void vShadowDeviceTask( void * pvParameters )
{
    bool xStatus = true;
    uint32_t ulNotificationValue;
    static MQTTPublishInfo_t xPublishInfo = { 0 };
    MQTTAgentCommandInfo_t xCommandParams = { 0 };
    MQTTStatus_t xCommandAdded;

    /* A buffer containing the update document. It has static duration to prevent
     * it from being placed on the call stack. */
    static char pcUpdateDocument[ shadowexampleSHADOW_REPORTED_JSON_LENGTH + 1 ] = { 0 };

    /* Remove compiler warnings about unused parameters. */
    ( void ) pvParameters;

    /* Record the handle of this task so that the callbacks so the callbacks can
     * send a notification to this task. */
    xShadowDeviceTaskHandle = xTaskGetCurrentTaskHandle();

    /* Set up the MQTTAgentCommandInfo_t for the demo loop.
     * We do not need a completion callback here since for publishes, we expect to get a
     * response on the appropriate topics for accepted or rejected reports, and for pings
     * we do not care about the completion. */
    xCommandParams.blockTimeMs = shadowexampleMAX_COMMAND_SEND_BLOCK_TIME_MS;
    xCommandParams.cmdCompleteCallback = NULL;

    /* Set up MQTTPublishInfo_t for the update reports. */
    xPublishInfo.qos = MQTTQoS1;
    xPublishInfo.pTopicName = SHADOW_TOPIC_STRING_UPDATE( democonfigCLIENT_IDENTIFIER );
    xPublishInfo.topicNameLength = SHADOW_TOPIC_LENGTH_UPDATE( democonfigCLIENT_IDENTIFIER_LENGTH );
    xPublishInfo.pPayload = pcUpdateDocument;
    xPublishInfo.payloadLength = ( shadowexampleSHADOW_REPORTED_JSON_LENGTH + 1 );

    /* Subscribe to Shadow topics. */
    xStatus = prvSubscribeToShadowUpdateTopics();

    if( xStatus == true )
    {
        for( ; ; )
        {
            if( ulCurrentPowerOnState == ulReportedPowerOnState )
            {
                LogInfo( ( "No change in powerOn state since last report. Current state is %u.", ulCurrentPowerOnState ) );

                /* The following line is only needed for winsim. Due to an inaccurate tick rate, the connection
                 * times out as the keepalive packets are not sent at the expected interval. */
                MQTTAgent_Ping( &xGlobalMqttAgentContext,
                                &xCommandParams );
            }
            else
            {
                LogInfo( ( "PowerOn state is now %u. Sending new report.", ( unsigned int ) ulCurrentPowerOnState ) );

                /* Create a new client token and save it for use in the update accepted and rejected callbacks. */
                ulClientToken = ( xTaskGetTickCount() % 1000000 );

                /* Generate update report. */
                ( void ) memset( pcUpdateDocument,
                                 0x00,
                                 sizeof( pcUpdateDocument ) );

                snprintf( pcUpdateDocument,
                          shadowexampleSHADOW_REPORTED_JSON_LENGTH + 1,
                          shadowexampleSHADOW_REPORTED_JSON,
                          ( unsigned int ) ulCurrentPowerOnState,
                          ( long unsigned ) ulClientToken );

                /* Send update. */
                LogInfo( ( "Publishing to /update with following client token %lu.", ( long unsigned ) ulClientToken ) );
                LogDebug( ( "Publish content: %.*s", shadowexampleSHADOW_REPORTED_JSON_LENGTH, pcUpdateDocument ) );

                xCommandAdded = MQTTAgent_Publish( &xGlobalMqttAgentContext,
                                                   &xPublishInfo,
                                                   &xCommandParams );

                if( xCommandAdded != MQTTSuccess )
                {
                    LogInfo( ( "Failed to publish report to shadow." ) );
                }
                else
                {
                    /* Wait for the response to our report. When the Device shadow service receives the request it will
                     * publish a response to  the /update/accepted or update/rejected */
                    ulNotificationValue = ulTaskNotifyTake( pdFALSE, pdMS_TO_TICKS( shadowexampleMS_TO_WAIT_FOR_NOTIFICATION ) );

                    if( ulNotificationValue == 0 )
                    {
                        LogError( ( "Timed out waiting for response to report." ) );

                        /* If we time out waiting for a response and then the report is accepted, the
                         * state may be out of sync. Set the reported state as to ensure we resend the
                         * report. */
                        ulReportedPowerOnState = shadowexampleINVALID_POWERON_STATE;
                    }
                }

                /* Clear the client token */
                ulClientToken = 0;
            }

            LogDebug( ( "Sleeping until next update check." ) );
            vTaskDelay( pdMS_TO_TICKS( shadowexampleMS_BETWEEN_REPORTS ) );
        }
    }
}