in sdk/src/azure/iot/az_iot_adu_client.c [526:876]
AZ_NODISCARD az_result az_iot_adu_client_parse_update_manifest(
az_iot_adu_client* client,
az_json_reader* ref_json_reader,
az_iot_adu_client_update_manifest* update_manifest)
{
_az_PRECONDITION_NOT_NULL(client);
_az_PRECONDITION_NOT_NULL(ref_json_reader);
_az_PRECONDITION_NOT_NULL(update_manifest);
(void)client;
// Initialize the update_manifest with empty values.
update_manifest->manifest_version = AZ_SPAN_EMPTY;
update_manifest->update_id.name = AZ_SPAN_EMPTY;
update_manifest->update_id.provider = AZ_SPAN_EMPTY;
update_manifest->update_id.version = AZ_SPAN_EMPTY;
update_manifest->instructions.steps_count = 0;
update_manifest->files_count = 0;
update_manifest->create_date_time = AZ_SPAN_EMPTY;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_OBJECT)
{
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
bool property_parsed = true;
if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_MANIFEST_VERSION)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->manifest_version = ref_json_reader->token.slice;
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_INSTRUCTIONS)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_STEPS)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_ARRAY);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
update_manifest->instructions.steps_count = 0;
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_ARRAY)
{
uint32_t step_index = update_manifest->instructions.steps_count;
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_OBJECT)
{
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_HANDLER)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->instructions.steps[step_index].handler
= ref_json_reader->token.slice;
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_FILES)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_ARRAY);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
update_manifest->instructions.steps[step_index].files_count = 0;
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_ARRAY)
{
// If array isn't ended and we have reached max files allowed, next would overflow.
if (update_manifest->instructions.steps[step_index].files_count
== _az_IOT_ADU_CLIENT_MAX_FILE_COUNT_PER_STEP)
{
return AZ_ERROR_NOT_ENOUGH_SPACE;
}
uint32_t file_index = update_manifest->instructions.steps[step_index].files_count;
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->instructions.steps[step_index].files[file_index]
= ref_json_reader->token.slice;
update_manifest->instructions.steps[step_index].files_count++;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(
AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_HANDLER_PROPERTIES)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_INSTALLED_CRITERIA)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->instructions.steps[step_index]
.handler_properties.installed_criteria
= ref_json_reader->token.slice;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_END_OBJECT);
}
else
{
return AZ_ERROR_JSON_INVALID_STATE;
}
}
else
{
return AZ_ERROR_JSON_INVALID_STATE;
}
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
update_manifest->instructions.steps_count++;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_END_OBJECT);
}
else
{
_az_LOG_WRITE(
AZ_LOG_IOT_ADU, AZ_SPAN_FROM_STR("Unexpected property found in ADU manifest steps:"));
_az_LOG_WRITE(AZ_LOG_IOT_ADU, ref_json_reader->token.slice);
return AZ_ERROR_JSON_INVALID_STATE;
}
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_UPDATE_ID)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_OBJECT)
{
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_PROVIDER)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->update_id.provider = ref_json_reader->token.slice;
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_NAME)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->update_id.name = ref_json_reader->token.slice;
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_VERSION)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->update_id.version = ref_json_reader->token.slice;
}
else
{
_az_LOG_WRITE(
AZ_LOG_IOT_ADU,
AZ_SPAN_FROM_STR("Unexpected property found in ADU update id object:"));
_az_LOG_WRITE(AZ_LOG_IOT_ADU, ref_json_reader->token.slice);
return AZ_ERROR_JSON_INVALID_STATE;
}
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_COMPATIBILITY)))
{
/*
* According to ADU design, the ADU service compatibility properties
* are not intended to be consumed by the ADU agent.
* To save on processing, the properties are not being exposed.
*/
_az_RETURN_IF_FAILED(az_json_reader_skip_children(ref_json_reader));
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_FILES)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_OBJECT)
{
uint32_t files_index = update_manifest->files_count;
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
// If object isn't ended and we have reached max files allowed, next would overflow.
if (files_index == _az_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT)
{
return AZ_ERROR_NOT_ENOUGH_SPACE;
}
update_manifest->files[files_index].id = ref_json_reader->token.slice;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_OBJECT)
{
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_FILE_NAME)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->files[files_index].file_name = ref_json_reader->token.slice;
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_SIZE_IN_BYTES)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_NUMBER);
_az_RETURN_IF_FAILED(az_json_token_get_int64(
&ref_json_reader->token, &update_manifest->files[files_index].size_in_bytes));
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_HASHES)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_BEGIN_OBJECT);
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
update_manifest->files[files_index].hashes_count = 0;
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_OBJECT)
{
uint32_t hashes_count = update_manifest->files[files_index].hashes_count;
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
update_manifest->files[files_index].hashes[hashes_count].hash_type
= ref_json_reader->token.slice;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->files[files_index].hashes[hashes_count].hash_value
= ref_json_reader->token.slice;
update_manifest->files[files_index].hashes_count++;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
}
/*
* Embedded C SDK will not support delta updates at this time, so relatedFiles,
* downloadHandler, and mimeType are not exposed or processed.
*/
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_RELATED_FILES)))
{
_az_RETURN_IF_FAILED(az_json_reader_skip_children(ref_json_reader));
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_DOWNLOAD_HANDLER)))
{
_az_RETURN_IF_FAILED(az_json_reader_skip_children(ref_json_reader));
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_MIME_TYPE)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
else
{
return AZ_ERROR_JSON_INVALID_STATE;
}
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
update_manifest->files_count++;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_CREATED_DATE_TIME)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
update_manifest->create_date_time = ref_json_reader->token.slice;
}
else
{
property_parsed = false;
}
if (!property_parsed)
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
_az_RETURN_IF_FAILED(az_json_reader_skip_children(ref_json_reader));
}
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
}
return AZ_OK;
}