in core/manifest/cfm/cfm_flash.c [1271:1405]
static int cfm_flash_get_next_manifest (const struct cfm *cfm, uint32_t component_id,
int manifest_type, struct cfm_manifest *allowable_manifest, bool first)
{
const struct cfm_flash *cfm_flash = (const struct cfm_flash*) cfm;
union {
struct cfm_allowable_pfm_element allowable_pfm_element;
struct cfm_allowable_id_element allowable_id_element;
} buffer;
struct cfm_allowable_pfm_element *allowable_pfm_element_ptr = &buffer.allowable_pfm_element;
struct cfm_allowable_id_element *allowable_id_element_ptr = &buffer.allowable_id_element;
struct cfm_allowable_id *allowable_id_ptr;
size_t allowable_pfm_element_len = sizeof (struct cfm_allowable_pfm_element);
size_t ids_len;
size_t offset;
uint8_t *element_entry_ptr;
int num_allowable_id;
int i_allowable_id;
int status;
if ((cfm == NULL) || (allowable_manifest == NULL)) {
return CFM_INVALID_ARGUMENT;
}
element_entry_ptr = (uint8_t*) &allowable_manifest->context;
if (first) {
*element_entry_ptr = 0;
}
else {
cfm_flash_free_manifest (cfm, allowable_manifest);
}
allowable_manifest->check_count = 0;
allowable_manifest->check = NULL;
allowable_manifest->platform_id = NULL;
// All allowable manifest elements have the same format, so use allowable PFM element containers
status = cfm_flash_get_next_element (cfm_flash, component_id,
(uint8_t**) &allowable_pfm_element_ptr, &allowable_pfm_element_len, element_entry_ptr,
manifest_type);
if (ROT_IS_ERROR (status)) {
return status;
}
allowable_manifest->manifest_index = allowable_pfm_element_ptr->port_id;
allowable_pfm_element_ptr->manifest.platform_id[
allowable_pfm_element_ptr->manifest.platform_id_len] = '\0';
allowable_manifest->platform_id =
strdup ((char*) allowable_pfm_element_ptr->manifest.platform_id);
if (allowable_manifest->platform_id == NULL) {
return CFM_NO_MEMORY;
}
status = manifest_flash_get_child_elements_info (&cfm_flash->base_flash,
cfm_flash->base_flash.hash, *element_entry_ptr, manifest_type, CFM_COMPONENT_DEVICE,
CFM_ALLOWABLE_ID, NULL, &num_allowable_id, NULL);
if (status != 0) {
goto free_manifest;
}
allowable_manifest->check_count = num_allowable_id;
allowable_manifest->check = platform_calloc (allowable_manifest->check_count,
sizeof (struct cfm_allowable_id));
if (allowable_manifest->check == NULL) {
status = CFM_NO_MEMORY;
goto free_manifest;
}
for (i_allowable_id = 0; i_allowable_id < num_allowable_id; ++i_allowable_id) {
// Read Allowable ID element
status = manifest_flash_read_element_data (&cfm_flash->base_flash,
cfm_flash->base_flash.hash, CFM_ALLOWABLE_ID, *element_entry_ptr, manifest_type, 0,
NULL, NULL, NULL, (uint8_t**) &allowable_id_element_ptr,
sizeof (struct cfm_allowable_id_element));
if (ROT_IS_ERROR (status)) {
if (status == MANIFEST_CHILD_NOT_FOUND) {
status = CFM_ENTRY_NOT_FOUND;
}
goto free_manifest;
}
if (status < (int) (sizeof (struct cfm_allowable_id_element))) {
status = CFM_MALFORMED_ALLOWABLE_ID_ENTRY;
goto free_manifest;
}
allowable_id_ptr = &allowable_manifest->check[i_allowable_id];
allowable_id_ptr->check = (enum cfm_check) allowable_id_element_ptr->check.check;
allowable_id_ptr->id_count = allowable_id_element_ptr->num_id;
offset = sizeof (struct cfm_allowable_id_element);
ids_len = allowable_id_ptr->id_count * sizeof (uint32_t);
allowable_id_ptr->allowable_id = platform_malloc (ids_len);
if (allowable_id_ptr->allowable_id == NULL) {
status = CFM_NO_MEMORY;
goto free_manifest;
}
// Read each ID
status = manifest_flash_read_element_data (&cfm_flash->base_flash,
cfm_flash->base_flash.hash, CFM_ALLOWABLE_ID, *element_entry_ptr, manifest_type, offset,
element_entry_ptr, NULL, NULL, (uint8_t**) &allowable_id_ptr->allowable_id, ids_len);
if (ROT_IS_ERROR (status)) {
goto free_manifest;
}
if (status < (int) (ids_len)) {
status = CFM_MALFORMED_ALLOWABLE_ID_ENTRY;
goto free_manifest;
}
if (allowable_id_element_ptr->check.endianness == CFM_MULTIBYTE_BIG_ENDIAN) {
for (uint8_t i_id = 0; i_id < allowable_id_ptr->id_count; i_id++) {
*((uint32_t*) &allowable_id_ptr->allowable_id[i_id]) =
SWAP_BYTES_UINT32 (allowable_id_ptr->allowable_id[i_id]);
}
}
*element_entry_ptr = *element_entry_ptr + 1;
}
return 0;
free_manifest:
cfm_flash_free_manifest (cfm, allowable_manifest);
return status;
}