Add update agent implementation
Adds an implementation of the generic update agent component. This
implements the FWU state machine that ensures that a valid update
sequence is followed.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Icf51b6527f1f84eb0f693e1629f4d2b3b075d43a
diff --git a/components/service/fwu/agent/img_dir_serializer.c b/components/service/fwu/agent/img_dir_serializer.c
new file mode 100644
index 0000000..db210bc
--- /dev/null
+++ b/components/service/fwu/agent/img_dir_serializer.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <protocols/service/fwu/packed-c/fwu_proto.h>
+#include <service/fwu/fw_store/fw_store.h>
+#include "fw_directory.h"
+#include "img_dir_serializer.h"
+
+int img_dir_serializer_serialize(
+ const struct fw_directory *fw_dir,
+ const struct fw_store *fw_store,
+ uint8_t *buf,
+ size_t buf_size,
+ size_t *data_len)
+{
+ size_t serialized_len = img_dir_serializer_get_len(fw_dir);
+
+ *data_len = 0;
+
+ if (buf_size < serialized_len)
+ return FWU_STATUS_OUT_OF_BOUNDS;
+
+ struct ts_fwu_image_directory *output = (struct ts_fwu_image_directory *)buf;
+
+ /* Clear the output buffer */
+ memset(buf, 0, serialized_len);
+
+ /* Serialize boot info */
+ const struct boot_info *boot_info = fw_directory_get_boot_info(fw_dir);
+
+ assert(boot_info);
+
+ output->directory_version = 2;
+ output->img_info_offset = offsetof(struct ts_fwu_image_directory, img_info_entry);
+ output->num_images = fw_directory_num_images(fw_dir);
+ output->correct_boot = (boot_info->active_index == boot_info->boot_index);
+ output->img_info_size = sizeof(struct ts_fwu_image_info_entry);
+ output->reserved = 0;
+
+ /* Serialize image info for each image */
+ for (size_t image_index = 0; image_index < output->num_images; image_index++) {
+
+ const struct image_info *image_info =
+ fw_directory_get_image_info(fw_dir, image_index);
+
+ assert(image_info);
+
+ memcpy(output->img_info_entry[image_index].img_type_uuid,
+ image_info->img_type_uuid.octets,
+ OSF_UUID_OCTET_LEN);
+
+ output->img_info_entry[image_index].client_permissions =
+ image_info->permissions;
+ output->img_info_entry[image_index].img_max_size =
+ image_info->max_size;
+ output->img_info_entry[image_index].lowest_accepted_version =
+ image_info->lowest_accepted_version;
+ output->img_info_entry[image_index].img_version =
+ image_info->active_version;
+ output->img_info_entry[image_index].accepted =
+ (uint32_t)fw_store_is_accepted(fw_store, image_info);
+ }
+
+ *data_len = serialized_len;
+
+ return FWU_STATUS_SUCCESS;
+}
+
+size_t img_dir_serializer_get_len(
+ const struct fw_directory *fw_dir)
+{
+ return
+ offsetof(struct ts_fwu_image_directory, img_info_entry) +
+ sizeof(struct ts_fwu_image_info_entry) * fw_directory_num_images(fw_dir);
+}