source/azure_iot_adu_client.c (418 lines of code) (raw):
/* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License. */
#include "azure_iot_adu_client.h"
#include "azure_iot.h"
/* Kernel includes. */
#include "FreeRTOS.h"
#include "azure_iot_private.h"
#include "azure_iot_json_writer.h"
#include "azure_iot_private.h"
#include <azure/iot/az_iot_adu_client.h>
const uint8_t * AzureIoTADUModelID = ( uint8_t * ) AZ_IOT_ADU_CLIENT_AGENT_MODEL_ID;
const uint32_t AzureIoTADUModelIDLength = sizeof( AZ_IOT_ADU_CLIENT_AGENT_MODEL_ID ) - 1;
AzureIoTResult_t AzureIoTADUClient_OptionsInit( AzureIoTADUClientOptions_t * pxADUClientOptions )
{
AzureIoTResult_t xResult;
if( pxADUClientOptions == NULL )
{
AZLogError( ( "AzureIoTADUClient_OptionsInit failed: invalid argument" ) );
xResult = eAzureIoTErrorInvalidArgument;
}
else
{
memset( pxADUClientOptions, 0, sizeof( AzureIoTADUClientOptions_t ) );
xResult = eAzureIoTSuccess;
}
return xResult;
}
AzureIoTResult_t AzureIoTADUClient_Init( AzureIoTADUClient_t * pxAzureIoTADUClient,
AzureIoTADUClientOptions_t * pxADUClientOptions )
{
az_result xCoreResult;
az_iot_adu_client_options xADUOptions;
if( pxAzureIoTADUClient == NULL )
{
AZLogError( ( "AzureIoTADUClient_Init failed: invalid argument" ) );
return eAzureIoTErrorInvalidArgument;
}
memset( ( void * ) pxAzureIoTADUClient, 0, sizeof( AzureIoTADUClient_t ) );
xADUOptions = az_iot_adu_client_options_default();
if( pxADUClientOptions )
{
if( ( pxADUClientOptions->pucCompatibilityProperties != NULL ) &&
( pxADUClientOptions->ulCompatibilityPropertiesLength > 0 ) )
{
xADUOptions.device_compatibility_properties = az_span_create(
( uint8_t * ) pxADUClientOptions->pucCompatibilityProperties,
( int32_t ) pxADUClientOptions->ulCompatibilityPropertiesLength );
}
}
if( az_result_failed( xCoreResult = az_iot_adu_client_init( &pxAzureIoTADUClient->_internal.xADUClient, &xADUOptions ) ) )
{
AZLogError( ( "Failed to initialize az_iot_adu_client_init: core error=0x%08x", ( uint16_t ) xCoreResult ) );
return AzureIoT_TranslateCoreError( xCoreResult );
}
return eAzureIoTSuccess;
}
AzureIoTResult_t AzureIoTADUClient_DevicePropertiesInit( AzureIoTADUClientDeviceProperties_t * pxADUDeviceProperties )
{
AzureIoTResult_t xResult;
if( pxADUDeviceProperties == NULL )
{
AZLogError( ( "AzureIoTADUClient_DevicePropertiesInit failed: invalid argument" ) );
xResult = eAzureIoTErrorInvalidArgument;
}
else
{
memset( pxADUDeviceProperties, 0, sizeof( AzureIoTADUClientDeviceProperties_t ) );
xResult = eAzureIoTSuccess;
}
return xResult;
}
bool AzureIoTADUClient_IsADUComponent( AzureIoTADUClient_t * pxAzureIoTADUClient,
const uint8_t * pucComponentName,
uint32_t ulComponentNameLength )
{
if( pxAzureIoTADUClient == NULL )
{
AZLogError( ( "AzureIoTADUClient_IsADUComponent failed: invalid argument" ) );
return false;
}
return az_iot_adu_client_is_component_device_update( &pxAzureIoTADUClient->_internal.xADUClient,
az_span_create( ( uint8_t * ) pucComponentName, ( int32_t ) ulComponentNameLength ) );
}
static void prvCastUpdateRequest( az_iot_adu_client_update_request * pxBaseUpdateRequest,
az_iot_adu_client_update_manifest * pxBaseUpdateManifest,
AzureIoTADUUpdateRequest_t * pxUpdateRequest,
uint8_t * pucUnescapedManifest,
uint32_t ulUnescapedManifestLength )
{
pxUpdateRequest->xWorkflow.pucID = az_span_ptr( pxBaseUpdateRequest->workflow.id );
pxUpdateRequest->xWorkflow.ulIDLength = ( uint32_t ) az_span_size( pxBaseUpdateRequest->workflow.id );
pxUpdateRequest->xWorkflow.xAction = ( AzureIoTADUAction_t ) pxBaseUpdateRequest->workflow.action;
pxUpdateRequest->xWorkflow.pucRetryTimestamp = az_span_ptr( pxBaseUpdateRequest->workflow.retry_timestamp );
pxUpdateRequest->xWorkflow.ulRetryTimestampLength = ( uint32_t ) az_span_size( pxBaseUpdateRequest->workflow.retry_timestamp );
pxUpdateRequest->pucUpdateManifest = ulUnescapedManifestLength > 0 ? pucUnescapedManifest : NULL;
pxUpdateRequest->ulUpdateManifestLength = ulUnescapedManifestLength;
pxUpdateRequest->pucUpdateManifestSignature = az_span_ptr( pxBaseUpdateRequest->update_manifest_signature );
pxUpdateRequest->ulUpdateManifestSignatureLength = ( uint32_t ) az_span_size( pxBaseUpdateRequest->update_manifest_signature );
pxUpdateRequest->ulFileUrlCount = pxBaseUpdateRequest->file_urls_count;
for( uint32_t ulFileUrlIndex = 0; ulFileUrlIndex < pxBaseUpdateRequest->file_urls_count; ulFileUrlIndex++ )
{
pxUpdateRequest->pxFileUrls[ ulFileUrlIndex ].pucId = az_span_ptr( pxBaseUpdateRequest->file_urls[ ulFileUrlIndex ].id );
pxUpdateRequest->pxFileUrls[ ulFileUrlIndex ].ulIdLength = ( uint32_t ) az_span_size( pxBaseUpdateRequest->file_urls[ ulFileUrlIndex ].id );
pxUpdateRequest->pxFileUrls[ ulFileUrlIndex ].pucUrl = az_span_ptr( pxBaseUpdateRequest->file_urls[ ulFileUrlIndex ].url );
pxUpdateRequest->pxFileUrls[ ulFileUrlIndex ].ulUrlLength = ( uint32_t ) az_span_size( pxBaseUpdateRequest->file_urls[ ulFileUrlIndex ].url );
}
if( pxBaseUpdateManifest != NULL )
{
pxUpdateRequest->xUpdateManifest.xUpdateId.pucProvider = az_span_ptr( pxBaseUpdateManifest->update_id.provider );
pxUpdateRequest->xUpdateManifest.xUpdateId.ulProviderLength = ( uint32_t ) az_span_size( pxBaseUpdateManifest->update_id.provider );
pxUpdateRequest->xUpdateManifest.xUpdateId.pucName = az_span_ptr( pxBaseUpdateManifest->update_id.name );
pxUpdateRequest->xUpdateManifest.xUpdateId.ulNameLength = ( uint32_t ) az_span_size( pxBaseUpdateManifest->update_id.name );
pxUpdateRequest->xUpdateManifest.xUpdateId.pucVersion = az_span_ptr( pxBaseUpdateManifest->update_id.version );
pxUpdateRequest->xUpdateManifest.xUpdateId.ulVersionLength = ( uint32_t ) az_span_size( pxBaseUpdateManifest->update_id.version );
pxUpdateRequest->xUpdateManifest.xInstructions.ulStepsCount = pxBaseUpdateManifest->instructions.steps_count;
for( uint32_t ulStepIndex = 0; ulStepIndex < pxBaseUpdateManifest->instructions.steps_count; ulStepIndex++ )
{
pxUpdateRequest->xUpdateManifest.xInstructions.pxSteps[ ulStepIndex ].pucHandler =
az_span_ptr( pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].handler );
pxUpdateRequest->xUpdateManifest.xInstructions.pxSteps[ ulStepIndex ].ulHandlerLength =
( uint32_t ) az_span_size( pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].handler );
pxUpdateRequest->xUpdateManifest.xInstructions.pxSteps[ ulStepIndex ].pucInstalledCriteria =
az_span_ptr( pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].handler_properties.installed_criteria );
pxUpdateRequest->xUpdateManifest.xInstructions.pxSteps[ ulStepIndex ].ulInstalledCriteriaLength =
( uint32_t ) az_span_size( pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].handler_properties.installed_criteria );
pxUpdateRequest->xUpdateManifest.xInstructions.pxSteps[ ulStepIndex ].ulFilesCount =
pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].files_count;
for( uint32_t ulFileIndex = 0; ulFileIndex < pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].files_count; ulFileIndex++ )
{
pxUpdateRequest->xUpdateManifest.xInstructions.pxSteps[ ulStepIndex ].pxFiles[ ulFileIndex ].pucFileName =
az_span_ptr( pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].files[ ulFileIndex ] );
pxUpdateRequest->xUpdateManifest.xInstructions.pxSteps[ ulStepIndex ].pxFiles[ ulFileIndex ].ulFileNameLength =
( uint32_t ) az_span_size( pxBaseUpdateManifest->instructions.steps[ ulStepIndex ].files[ ulFileIndex ] );
}
}
pxUpdateRequest->xUpdateManifest.ulFilesCount = pxBaseUpdateManifest->files_count;
for( uint32_t ulFileIndex = 0; ulFileIndex < pxBaseUpdateManifest->files_count; ulFileIndex++ )
{
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].pucId =
az_span_ptr( pxBaseUpdateManifest->files[ ulFileIndex ].id );
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].ulIdLength =
( uint32_t ) az_span_size( pxBaseUpdateManifest->files[ ulFileIndex ].id );
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].pucFileName =
az_span_ptr( pxBaseUpdateManifest->files[ ulFileIndex ].file_name );
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].ulFileNameLength =
( uint32_t ) az_span_size( pxBaseUpdateManifest->files[ ulFileIndex ].file_name );
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].llSizeInBytes =
pxBaseUpdateManifest->files[ ulFileIndex ].size_in_bytes;
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].ulHashesCount =
pxBaseUpdateManifest->files[ ulFileIndex ].hashes_count;
for( uint32_t ulFileHashIndex = 0; ulFileHashIndex < pxBaseUpdateManifest->files_count; ulFileHashIndex++ )
{
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].pxHashes[ ulFileHashIndex ].pucId =
az_span_ptr( pxBaseUpdateManifest->files[ ulFileIndex ].hashes[ ulFileHashIndex ].hash_type );
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].pxHashes[ ulFileHashIndex ].ulIdLength =
( uint32_t ) az_span_size( pxBaseUpdateManifest->files[ ulFileIndex ].hashes[ ulFileHashIndex ].hash_type );
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].pxHashes[ ulFileHashIndex ].pucHash =
az_span_ptr( pxBaseUpdateManifest->files[ ulFileIndex ].hashes[ ulFileHashIndex ].hash_value );
pxUpdateRequest->xUpdateManifest.pxFiles[ ulFileIndex ].pxHashes[ ulFileHashIndex ].ulHashLength =
( uint32_t ) az_span_size( pxBaseUpdateManifest->files[ ulFileIndex ].hashes[ ulFileHashIndex ].hash_value );
}
}
pxUpdateRequest->xUpdateManifest.pucManifestVersion = az_span_ptr( pxBaseUpdateManifest->manifest_version );
pxUpdateRequest->xUpdateManifest.ulManifestVersionLength = ( uint32_t ) az_span_size( pxBaseUpdateManifest->manifest_version );
pxUpdateRequest->xUpdateManifest.pucCreateDateTime = az_span_ptr( pxBaseUpdateManifest->create_date_time );
pxUpdateRequest->xUpdateManifest.ulCreateDateTimeLength = ( uint32_t ) az_span_size( pxBaseUpdateManifest->create_date_time );
}
}
AzureIoTResult_t AzureIoTADUClient_ParseRequest( AzureIoTADUClient_t * pxAzureIoTADUClient,
AzureIoTJSONReader_t * pxReader,
AzureIoTADUUpdateRequest_t * pxAduUpdateRequest )
{
az_iot_adu_client_update_request xBaseUpdateRequest;
az_iot_adu_client_update_manifest xBaseUpdateManifest;
az_result xAzResult;
az_json_reader jr;
if( ( pxAzureIoTADUClient == NULL ) || ( pxReader == NULL ) ||
( pxAduUpdateRequest == NULL ) )
{
AZLogError( ( "AzureIoTADUClient_ParseRequest failed: invalid argument" ) );
return eAzureIoTErrorInvalidArgument;
}
xAzResult = az_iot_adu_client_parse_service_properties(
&pxAzureIoTADUClient->_internal.xADUClient,
&pxReader->_internal.xCoreReader,
&xBaseUpdateRequest );
if( az_result_failed( xAzResult ) )
{
AZLogError( ( "az_iot_adu_client_parse_service_properties failed" ) );
return AzureIoT_TranslateCoreError( xAzResult );
}
else
{
if( az_span_size( xBaseUpdateRequest.update_manifest ) > 0 )
{
/* This unescape is done in place to save space. It will modify the original payload buffer. */
xBaseUpdateRequest.update_manifest = az_json_string_unescape( xBaseUpdateRequest.update_manifest, xBaseUpdateRequest.update_manifest );
xAzResult = az_json_reader_init( &jr, xBaseUpdateRequest.update_manifest, NULL );
if( az_result_failed( xAzResult ) )
{
AZLogError( ( "az_json_reader_init failed: 0x%08x", ( uint16_t ) xAzResult ) );
return AzureIoT_TranslateCoreError( xAzResult );
}
xAzResult = az_iot_adu_client_parse_update_manifest(
&pxAzureIoTADUClient->_internal.xADUClient,
&jr,
&xBaseUpdateManifest );
if( az_result_failed( xAzResult ) )
{
AZLogError( ( "az_iot_adu_client_parse_update_manifest failed: 0x%08x", ( uint16_t ) xAzResult ) );
return AzureIoT_TranslateCoreError( xAzResult );
}
}
else
{
/*No manifest to parse */
}
prvCastUpdateRequest( &xBaseUpdateRequest,
az_span_size( xBaseUpdateRequest.update_manifest ) > 0 ? &xBaseUpdateManifest : NULL,
pxAduUpdateRequest, az_span_ptr( xBaseUpdateRequest.update_manifest ), ( uint32_t ) az_span_size( xBaseUpdateRequest.update_manifest ) );
}
return eAzureIoTSuccess;
}
AzureIoTResult_t AzureIoTADUClient_SendResponse( AzureIoTADUClient_t * pxAzureIoTADUClient,
AzureIoTHubClient_t * pxAzureIoTHubClient,
AzureIoTADURequestDecision_t xRequestDecision,
uint32_t ulPropertyVersion,
uint8_t * pucWritablePropertyResponseBuffer,
uint32_t ulWritablePropertyResponseBufferSize,
uint32_t * pulRequestId )
{
az_result xCoreResult;
AzureIoTResult_t xResult;
az_json_writer jw;
az_span xPayload;
if( ( pxAzureIoTADUClient == NULL ) || ( pxAzureIoTHubClient == NULL ) ||
( pucWritablePropertyResponseBuffer == NULL ) || ( ulWritablePropertyResponseBufferSize == 0 ) )
{
AZLogError( ( "AzureIoTADUClient_SendResponse failed: invalid argument" ) );
return eAzureIoTErrorInvalidArgument;
}
xCoreResult = az_json_writer_init( &jw, az_span_create(
pucWritablePropertyResponseBuffer,
( int32_t ) ulWritablePropertyResponseBufferSize ), NULL );
if( az_result_failed( xCoreResult ) )
{
AZLogError( ( "az_json_writer_init failed: 0x%08x", ( uint16_t ) xCoreResult ) );
return AzureIoT_TranslateCoreError( xCoreResult );
}
xCoreResult = az_iot_adu_client_get_service_properties_response(
&pxAzureIoTADUClient->_internal.xADUClient,
( int32_t ) ulPropertyVersion,
xRequestDecision == eAzureIoTADURequestDecisionAccept ? AZ_IOT_ADU_CLIENT_REQUEST_DECISION_ACCEPT : AZ_IOT_ADU_CLIENT_REQUEST_DECISION_REJECT,
&jw );
if( az_result_failed( xCoreResult ) )
{
AZLogError( ( "az_iot_adu_client_get_service_properties_response failed: 0x%08x (%d)", ( uint16_t ) xCoreResult, ( int16_t ) ulWritablePropertyResponseBufferSize ) );
return AzureIoT_TranslateCoreError( xCoreResult );
}
xPayload = az_json_writer_get_bytes_used_in_destination( &jw );
xResult = AzureIoTHubClient_SendPropertiesReported(
pxAzureIoTHubClient,
az_span_ptr( xPayload ),
( uint32_t ) az_span_size( xPayload ),
pulRequestId );
if( xResult != eAzureIoTSuccess )
{
AZLogError( ( "[ADU] Failed sending ADU writable properties response: 0x%08x", ( uint16_t ) xResult ) );
return eAzureIoTErrorPublishFailed;
}
return eAzureIoTSuccess;
}
static void prvFillBaseAduDeviceProperties( AzureIoTADUClientDeviceProperties_t * pxDeviceProperties,
az_iot_adu_client_device_properties * pxBaseAduDeviceProperties )
{
pxBaseAduDeviceProperties->manufacturer = az_span_create(
( uint8_t * ) pxDeviceProperties->ucManufacturer,
( int32_t ) pxDeviceProperties->ulManufacturerLength );
pxBaseAduDeviceProperties->model = az_span_create(
( uint8_t * ) pxDeviceProperties->ucModel,
( int32_t ) pxDeviceProperties->ulModelLength );
if( pxDeviceProperties->pxCustomProperties == NULL )
{
pxBaseAduDeviceProperties->custom_properties = NULL;
}
else
{
pxDeviceProperties->pxCustomProperties->_internal.xCustomProperties.count =
( int32_t ) pxDeviceProperties->pxCustomProperties->ulPropertyCount;
for( int32_t lPropertyIndex = 0;
lPropertyIndex < ( int32_t ) pxDeviceProperties->pxCustomProperties->ulPropertyCount;
lPropertyIndex++ )
{
pxDeviceProperties->pxCustomProperties->_internal.xCustomProperties.names[ lPropertyIndex ] =
az_span_create(
pxDeviceProperties->pxCustomProperties->pucPropertyNames[ lPropertyIndex ],
( int32_t ) pxDeviceProperties->pxCustomProperties->ulPropertyNamesLengths[ lPropertyIndex ] );
pxDeviceProperties->pxCustomProperties->_internal.xCustomProperties.values[ lPropertyIndex ] =
az_span_create(
pxDeviceProperties->pxCustomProperties->pucPropertyValues[ lPropertyIndex ],
( int32_t ) pxDeviceProperties->pxCustomProperties->ulPropertyValuesLengths[ lPropertyIndex ] );
}
pxBaseAduDeviceProperties->custom_properties =
&pxDeviceProperties->pxCustomProperties->_internal.xCustomProperties;
}
pxBaseAduDeviceProperties->update_id = az_span_create(
( uint8_t * ) pxDeviceProperties->ucCurrentUpdateId,
( int32_t ) pxDeviceProperties->ulCurrentUpdateIdLength );
pxBaseAduDeviceProperties->adu_version = AZ_SPAN_FROM_STR( AZ_IOT_ADU_CLIENT_AGENT_VERSION );
pxBaseAduDeviceProperties->delivery_optimization_agent_version = az_span_create(
( uint8_t * ) pxDeviceProperties->ucDeliveryOptimizationAgentVersion,
( int32_t ) pxDeviceProperties->ulDeliveryOptimizationAgentVersionLength );
}
static void prvFillBaseAduWorkflow( AzureIoTADUUpdateRequest_t * pxAduUpdateRequest,
az_iot_adu_client_workflow * pxBaseWorkflow )
{
if( pxAduUpdateRequest != NULL )
{
pxBaseWorkflow->action = ( az_iot_adu_client_service_action ) pxAduUpdateRequest->xWorkflow.xAction;
pxBaseWorkflow->id = az_span_create(
( uint8_t * ) pxAduUpdateRequest->xWorkflow.pucID,
( int32_t ) pxAduUpdateRequest->xWorkflow.ulIDLength );
pxBaseWorkflow->retry_timestamp = az_span_create(
( uint8_t * ) pxAduUpdateRequest->xWorkflow.pucRetryTimestamp,
( int32_t ) pxAduUpdateRequest->xWorkflow.ulRetryTimestampLength );
}
}
static void prvFillBaseAduInstallResults( AzureIoTADUClientInstallResult_t * pxUpdateResults,
az_iot_adu_client_install_result * pxBaseInstallResults )
{
memset( pxBaseInstallResults, 0, sizeof( *pxBaseInstallResults ) );
if( pxUpdateResults != NULL )
{
pxBaseInstallResults->result_code = pxUpdateResults->lResultCode;
pxBaseInstallResults->extended_result_code = pxUpdateResults->lExtendedResultCode;
if( ( pxUpdateResults->pucResultDetails != NULL ) &&
( pxUpdateResults->ulResultDetailsLength > 0 ) )
{
pxBaseInstallResults->result_details = az_span_create(
( uint8_t * ) pxUpdateResults->pucResultDetails,
( int32_t ) pxUpdateResults->ulResultDetailsLength );
}
else
{
pxBaseInstallResults->result_details = AZ_SPAN_EMPTY;
}
pxBaseInstallResults->step_results_count = ( int32_t ) pxUpdateResults->ulStepResultsCount;
for( int lIndex = 0; lIndex < ( int32_t ) pxUpdateResults->ulStepResultsCount; lIndex++ )
{
pxBaseInstallResults->step_results[ lIndex ].result_code =
( int32_t ) pxUpdateResults->pxStepResults[ lIndex ].ulResultCode;
pxBaseInstallResults->step_results[ lIndex ].extended_result_code =
( int32_t ) pxUpdateResults->pxStepResults[ lIndex ].ulExtendedResultCode;
if( ( pxUpdateResults->pxStepResults[ lIndex ].pucResultDetails != NULL ) &&
( pxUpdateResults->pxStepResults[ lIndex ].ulResultDetailsLength > 0 ) )
{
pxBaseInstallResults->step_results[ lIndex ].result_details = az_span_create(
( uint8_t * ) pxUpdateResults->pxStepResults[ lIndex ].pucResultDetails,
( int32_t ) pxUpdateResults->pxStepResults[ lIndex ].ulResultDetailsLength
);
}
else
{
pxBaseInstallResults->step_results[ lIndex ].result_details = AZ_SPAN_EMPTY;
}
}
}
}
AzureIoTResult_t AzureIoTADUClient_SendAgentState( AzureIoTADUClient_t * pxAzureIoTADUClient,
AzureIoTHubClient_t * pxAzureIoTHubClient,
AzureIoTADUClientDeviceProperties_t * pxDeviceProperties,
AzureIoTADUUpdateRequest_t * pxAduUpdateRequest,
AzureIoTADUAgentState_t xAgentState,
AzureIoTADUClientInstallResult_t * pxUpdateResults,
uint8_t * pucBuffer,
uint32_t ulBufferSize,
uint32_t * pulRequestId )
{
az_result xAzResult;
az_iot_adu_client_device_properties xBaseADUDeviceProperties;
az_iot_adu_client_workflow xBaseWorkflow;
az_iot_adu_client_install_result xInstallResult;
az_json_writer jw;
az_span xPropertiesPayload;
if( ( pxAzureIoTADUClient == NULL ) || ( pxAzureIoTHubClient == NULL ) ||
( pxDeviceProperties == NULL ) || ( pucBuffer == NULL ) || ( ulBufferSize == 0 ) )
{
AZLogError( ( "AzureIoTADUClient_SendAgentState failed: invalid argument" ) );
return eAzureIoTErrorInvalidArgument;
}
prvFillBaseAduDeviceProperties( pxDeviceProperties, &xBaseADUDeviceProperties );
prvFillBaseAduWorkflow( pxAduUpdateRequest, &xBaseWorkflow );
prvFillBaseAduInstallResults( pxUpdateResults, &xInstallResult );
xAzResult = az_json_writer_init( &jw, az_span_create( pucBuffer, ( int32_t ) ulBufferSize ), NULL );
if( az_result_failed( xAzResult ) )
{
AZLogError( ( "az_json_writer_init failed: 0x%08x", ( uint16_t ) xAzResult ) );
return AzureIoT_TranslateCoreError( xAzResult );
}
xAzResult = az_iot_adu_client_get_agent_state_payload(
&pxAzureIoTADUClient->_internal.xADUClient,
&xBaseADUDeviceProperties,
( az_iot_adu_client_agent_state ) xAgentState,
pxAduUpdateRequest != NULL ? &xBaseWorkflow : NULL,
pxUpdateResults != NULL ? &xInstallResult : NULL,
&jw );
if( az_result_failed( xAzResult ) )
{
AZLogError( ( "az_iot_adu_client_get_agent_state_payload failed: 0x%08x", ( uint16_t ) xAzResult ) );
return AzureIoT_TranslateCoreError( xAzResult );
}
xPropertiesPayload = az_json_writer_get_bytes_used_in_destination( &jw );
if( AzureIoTHubClient_SendPropertiesReported(
pxAzureIoTHubClient,
az_span_ptr( xPropertiesPayload ),
( uint32_t ) az_span_size( xPropertiesPayload ),
pulRequestId ) != eAzureIoTSuccess )
{
AZLogError( ( "[ADU] Failed sending ADU agent state." ) );
return eAzureIoTErrorPublishFailed;
}
return eAzureIoTSuccess;
}