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 ) );
}
}
}