Integrate update agent interface
Access existing update agent implementation via and update agent
interface. Align tests and deployments to use the new initialization
methods.
Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: I31d501fc6601be6d396ef38ef65c500ba8acdec4
diff --git a/components/app/fwu-tool/app/fwu_app.cpp b/components/app/fwu-tool/app/fwu_app.cpp
index 173afce..9613e73 100644
--- a/components/app/fwu-tool/app/fwu_app.cpp
+++ b/components/app/fwu-tool/app/fwu_app.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -31,13 +31,12 @@
: m_update_agent()
, m_fw_store()
{
- memset(&m_update_agent, 0, sizeof(m_update_agent));
memset(&m_fw_store, 0, sizeof(m_fw_store));
}
fwu_app::~fwu_app()
{
- update_agent_deinit(&m_update_agent);
+ update_agent_deinit(m_update_agent);
banked_fw_store_deinit(&m_fw_store);
fwu_deconfigure();
@@ -96,10 +95,9 @@
return -1;
}
- status = update_agent_init(&m_update_agent, boot_index, direct_fw_inspector_inspect,
- &m_fw_store);
+ m_update_agent = update_agent_init(boot_index, direct_fw_inspector_inspect, &m_fw_store);
- if (status) {
+ if (!m_update_agent) {
IMSG("update agent initialisation error %d", status);
return -1;
}
@@ -111,27 +109,31 @@
int fwu_app::update_image(const struct uuid_octets &img_type_uuid, const uint8_t *img_data,
size_t img_size)
{
- int status = update_agent_begin_staging(&m_update_agent);
+ int status = update_agent_begin_staging(m_update_agent, 0, 0, NULL);
if (status)
return status;
uint32_t stream_handle = 0;
+ uint32_t progress = 0;
+ uint32_t total_work = 0;
- status = update_agent_open(&m_update_agent, &img_type_uuid, &stream_handle);
+ status = update_agent_open(m_update_agent, &img_type_uuid, FWU_OP_TYPE_WRITE,
+ &stream_handle);
if (!status) {
- status = update_agent_write_stream(&m_update_agent, stream_handle, img_data,
+ status = update_agent_write_stream(m_update_agent, stream_handle, img_data,
img_size);
if (!status)
- status = update_agent_commit(&m_update_agent, stream_handle, false);
+ status = update_agent_commit(m_update_agent, stream_handle, false, 0,
+ &progress, &total_work);
}
if (!status)
- status = update_agent_end_staging(&m_update_agent);
+ status = update_agent_end_staging(m_update_agent);
else
- update_agent_cancel_staging(&m_update_agent);
+ update_agent_cancel_staging(m_update_agent);
return status;
}
@@ -139,7 +141,8 @@
int fwu_app::read_object(const struct uuid_octets &object_uuid, std::vector<uint8_t> &data)
{
uint32_t stream_handle = 0;
- int status = update_agent_open(&m_update_agent, &object_uuid, &stream_handle);
+ int status = update_agent_open(m_update_agent, &object_uuid, FWU_OP_TYPE_READ,
+ &stream_handle);
if (status)
return status;
@@ -150,6 +153,8 @@
size_t reported_total_len = 0;
size_t read_so_far = 0;
size_t vector_capacity = 512;
+ uint32_t progress = 0;
+ uint32_t total_work = 0;
data.resize(vector_capacity);
@@ -157,7 +162,7 @@
size_t data_len_read = 0;
size_t requested_read_len = vector_capacity - read_so_far;
- status = update_agent_read_stream(&m_update_agent, stream_handle,
+ status = update_agent_read_stream(m_update_agent, stream_handle,
&data[read_so_far], requested_read_len,
&data_len_read, &reported_total_len);
@@ -181,14 +186,15 @@
} while (!status);
- status = update_agent_commit(&m_update_agent, stream_handle, false);
+ status = update_agent_commit(m_update_agent, stream_handle, false, 0, &progress,
+ &total_work);
return status;
}
struct update_agent *fwu_app::update_agent()
{
- return &m_update_agent;
+ return m_update_agent;
}
const struct metadata_serializer *fwu_app::select_metadata_serializer(unsigned int version)
diff --git a/components/app/fwu-tool/app/fwu_app.h b/components/app/fwu-tool/app/fwu_app.h
index 8bbaa9d..c60f192 100644
--- a/components/app/fwu-tool/app/fwu_app.h
+++ b/components/app/fwu-tool/app/fwu_app.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
#include <vector>
#include "common/uuid/uuid.h"
-#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
#include "service/fwu/fw_store/banked/banked_fw_store.h"
/*
@@ -98,7 +98,7 @@
static const struct metadata_serializer *select_metadata_serializer(unsigned int version);
- struct update_agent m_update_agent;
+ struct update_agent *m_update_agent;
struct fw_store m_fw_store;
};
diff --git a/components/service/fwu/agent/update_agent.c b/components/service/fwu/agent/update_agent.c
index 2a4d19d..77037b1 100644
--- a/components/service/fwu/agent/update_agent.c
+++ b/components/service/fwu/agent/update_agent.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -17,80 +17,51 @@
#include "protocols/service/fwu/packed-c/status.h"
#include "service/fwu/fw_store/fw_store.h"
#include "service/fwu/inspector/fw_inspector.h"
+#include "trace.h"
-static bool open_image_directory(struct update_agent *update_agent, const struct uuid_octets *uuid,
- uint32_t *handle, int *status);
+/**
+ * \brief Update process states
+ *
+ * The update_agent is responsible for ensuring that only a valid update flow
+ * is followed by a client. To enforce the flow, public operations can only be
+ * used in a valid state that reflects the FWU-A behavioral model.
+ */
+enum fwu_state {
+ FWU_STATE_DEINITIALZED,
+ FWU_STATE_INITIALIZING,
+ FWU_STATE_REGULAR,
+ FWU_STATE_STAGING,
+ FWU_STATE_TRIAL_PENDING,
+ FWU_STATE_TRIAL
+};
-static bool open_fw_store_object(struct update_agent *update_agent, const struct uuid_octets *uuid,
- uint32_t *handle, int *status);
+/**
+ * \brief update_agent structure definition
+ *
+ * An update_agent instance is responsible for coordinating firmware updates applied
+ * to a fw_store. An update_agent performs a security role by enforcing that a
+ * valid flow is performed to update the fw store.
+ */
+struct generic_update_agent {
+ enum fwu_state state;
+ fw_inspector_inspect fw_inspect_method;
+ struct fw_store *fw_store;
+ struct fw_directory fw_directory;
+ struct stream_manager stream_manager;
+ uint8_t *image_dir_buf;
+ size_t image_dir_buf_size;
+};
-static bool open_fw_image(struct update_agent *update_agent, const struct uuid_octets *uuid,
- uint32_t *handle, int *status);
+static int cancel_staging(void *context);
-int update_agent_init(struct update_agent *update_agent, unsigned int boot_index,
- fw_inspector_inspect fw_inspect_method, struct fw_store *fw_store)
-{
- assert(update_agent);
- assert(fw_inspect_method);
- assert(fw_store);
-
- int status = FWU_STATUS_UNKNOWN;
-
- update_agent->state = FWU_STATE_INITIALIZING;
- update_agent->fw_inspect_method = fw_inspect_method;
- update_agent->fw_store = fw_store;
- update_agent->image_dir_buf_size = 0;
- update_agent->image_dir_buf = NULL;
-
- stream_manager_init(&update_agent->stream_manager);
-
- /* Initialize and populate the fw_directory. The fw_inspector will
- * obtain trustworthy information about the booted firmware and
- * populate the fw_directory to reflect information about the booted
- * firmware.
- */
- fw_directory_init(&update_agent->fw_directory);
-
- status = update_agent->fw_inspect_method(&update_agent->fw_directory, boot_index);
- if (status != FWU_STATUS_SUCCESS)
- return status;
-
- /* Allow the associated fw_store to synchronize its state to the
- * state of the booted firmware reflected by the fw_directory.
- */
- status = fw_store_synchronize(update_agent->fw_store, &update_agent->fw_directory,
- boot_index);
- if (status != FWU_STATUS_SUCCESS)
- return status;
-
- /* Allocate a buffer for holding the serialized image directory */
- update_agent->image_dir_buf_size = img_dir_serializer_get_len(&update_agent->fw_directory);
- update_agent->image_dir_buf = malloc(update_agent->image_dir_buf_size);
- if (!update_agent->image_dir_buf)
- return FWU_STATUS_UNKNOWN;
-
- /* Transition to initial state */
- update_agent->state = fw_store_is_trial(update_agent->fw_store) ? FWU_STATE_TRIAL :
- FWU_STATE_REGULAR;
-
- return FWU_STATUS_SUCCESS;
-}
-
-void update_agent_deinit(struct update_agent *update_agent)
-{
- update_agent->state = FWU_STATE_DEINITIALZED;
-
- free(update_agent->image_dir_buf);
- fw_directory_deinit(&update_agent->fw_directory);
- stream_manager_deinit(&update_agent->stream_manager);
-}
-
-int update_agent_begin_staging(struct update_agent *update_agent)
+static int begin_staging(void *context, uint32_t vendor_flags, uint32_t partial_update_count,
+ const struct uuid_octets *update_guid)
{
int status = FWU_STATUS_DENIED;
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
/* If already staging, any previous installation state is discarded */
- update_agent_cancel_staging(update_agent);
+ cancel_staging(update_agent);
if (update_agent->state == FWU_STATE_REGULAR) {
status = fw_store_begin_install(update_agent->fw_store);
@@ -103,9 +74,10 @@
return status;
}
-int update_agent_end_staging(struct update_agent *update_agent)
+static int end_staging(void *context)
{
int status = FWU_STATUS_DENIED;
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
if (update_agent->state == FWU_STATE_STAGING) {
/* The client is responsible for committing each installed image. If any
@@ -135,9 +107,10 @@
return status;
}
-int update_agent_cancel_staging(struct update_agent *update_agent)
+static int cancel_staging(void *context)
{
int status = FWU_STATUS_DENIED;
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
if (update_agent->state == FWU_STATE_STAGING) {
stream_manager_cancel_streams(&update_agent->stream_manager,
@@ -153,10 +126,10 @@
return status;
}
-int update_agent_accept(struct update_agent *update_agent,
- const struct uuid_octets *image_type_uuid)
+static int accept(void *context, const struct uuid_octets *image_type_uuid)
{
int status = FWU_STATUS_DENIED;
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
if (update_agent->state == FWU_STATE_TRIAL) {
const struct image_info *image_info =
@@ -181,9 +154,10 @@
return status;
}
-int update_agent_select_previous(struct update_agent *update_agent)
+static int select_previous(void *context)
{
int status = FWU_STATUS_DENIED;
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
if ((update_agent->state == FWU_STATE_TRIAL) ||
(update_agent->state == FWU_STATE_TRIAL_PENDING)) {
@@ -194,42 +168,8 @@
return status;
}
-int update_agent_open(struct update_agent *update_agent, const struct uuid_octets *uuid,
- uint32_t *handle)
-{
- int status;
-
- /* Pass UUID along a chain-of-responsibility until it's handled */
- if (!open_image_directory(update_agent, uuid, handle, &status) &&
- !open_fw_store_object(update_agent, uuid, handle, &status) &&
- !open_fw_image(update_agent, uuid, handle, &status)) {
- /* UUID not recognised */
- status = FWU_STATUS_UNKNOWN;
- }
-
- return status;
-}
-
-int update_agent_commit(struct update_agent *update_agent, uint32_t handle, bool accepted)
-{
- return stream_manager_close(&update_agent->stream_manager, handle, accepted);
-}
-
-int update_agent_write_stream(struct update_agent *update_agent, uint32_t handle,
- const uint8_t *data, size_t data_len)
-{
- return stream_manager_write(&update_agent->stream_manager, handle, data, data_len);
-}
-
-int update_agent_read_stream(struct update_agent *update_agent, uint32_t handle, uint8_t *buf,
- size_t buf_size, size_t *read_len, size_t *total_len)
-{
- return stream_manager_read(&update_agent->stream_manager, handle, buf, buf_size, read_len,
- total_len);
-}
-
-static bool open_image_directory(struct update_agent *update_agent, const struct uuid_octets *uuid,
- uint32_t *handle, int *status)
+static bool open_image_directory(struct generic_update_agent *update_agent,
+ const struct uuid_octets *uuid, uint32_t *handle, int *status)
{
struct uuid_octets target_uuid;
@@ -257,8 +197,8 @@
return false;
}
-static bool open_fw_store_object(struct update_agent *update_agent, const struct uuid_octets *uuid,
- uint32_t *handle, int *status)
+static bool open_fw_store_object(struct generic_update_agent *update_agent,
+ const struct uuid_octets *uuid, uint32_t *handle, int *status)
{
const uint8_t *exported_data;
size_t exported_data_len;
@@ -277,7 +217,7 @@
return false;
}
-static bool open_fw_image(struct update_agent *update_agent, const struct uuid_octets *uuid,
+static bool open_fw_image(struct generic_update_agent *update_agent, const struct uuid_octets *uuid,
uint32_t *handle, int *status)
{
const struct image_info *image_info =
@@ -305,3 +245,160 @@
return false;
}
+
+static int open(void *context, const struct uuid_octets *uuid, uint8_t op_type, uint32_t *handle)
+{
+ int status = FWU_STATUS_SUCCESS;
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+
+ /* Pass UUID along a chain-of-responsibility until it's handled */
+ if (!open_image_directory(update_agent, uuid, handle, &status) &&
+ !open_fw_store_object(update_agent, uuid, handle, &status) &&
+ !open_fw_image(update_agent, uuid, handle, &status)) {
+ /* UUID not recognised */
+ status = FWU_STATUS_UNKNOWN;
+ }
+
+ return status;
+}
+
+static int commit(void *context, uint32_t handle, bool accepted, uint32_t max_atomic_len,
+ uint32_t *progress, uint32_t *total_work)
+{
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+ int result = 0;
+
+ result = stream_manager_close(&update_agent->stream_manager, handle, accepted);
+ if (!result)
+ *progress = 1;
+
+ *total_work = 1;
+
+ return result;
+}
+
+static int write_stream(void *context, uint32_t handle, const uint8_t *data, size_t data_len)
+{
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+
+ return stream_manager_write(&update_agent->stream_manager, handle, data, data_len);
+}
+
+static int read_stream(void *context, uint32_t handle, uint8_t *buf, size_t buf_size,
+ size_t *read_len, size_t *total_len)
+{
+ struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+
+ return stream_manager_read(&update_agent->stream_manager, handle, buf, buf_size, read_len,
+ total_len);
+}
+
+
+static const struct update_agent_interface interface = {
+ .discover = NULL,
+ .begin_staging = begin_staging,
+ .end_staging = end_staging,
+ .cancel_staging = cancel_staging,
+ .open = open,
+ .write_stream = write_stream,
+ .read_stream = read_stream,
+ .commit = commit,
+ .accept_image = accept,
+ .select_previous = select_previous,
+};
+
+static void deinit_context(struct generic_update_agent *context)
+{
+ if (!context)
+ return;
+
+ stream_manager_deinit(&context->stream_manager);
+ fw_directory_deinit(&context->fw_directory);
+
+ if (context->image_dir_buf)
+ free(context->image_dir_buf);
+
+ free(context);
+}
+
+struct update_agent *update_agent_init(unsigned int boot_index,
+ fw_inspector_inspect fw_inspect_method,
+ struct fw_store *fw_store)
+{
+ int status = FWU_STATUS_UNKNOWN;
+ struct generic_update_agent *context = NULL;
+ struct update_agent *agent = NULL;
+
+ assert(fw_inspect_method);
+ assert(fw_store);
+
+ context = (struct generic_update_agent *)calloc(1, sizeof(*context));
+ if (!context) {
+ DMSG("Failed to allocate update agent context");
+ return NULL;
+ }
+
+ context->state = FWU_STATE_INITIALIZING;
+ context->fw_inspect_method = fw_inspect_method;
+ context->fw_store = fw_store;
+ context->image_dir_buf_size = 0;
+ context->image_dir_buf = NULL;
+
+ stream_manager_init(&context->stream_manager);
+
+ /* Initialize and populate the fw_directory. The fw_inspector will
+ * obtain trustworthy information about the booted firmware and
+ * populate the fw_directory to reflect information about the booted
+ * firmware.
+ */
+ fw_directory_init(&context->fw_directory);
+
+ status = context->fw_inspect_method(&context->fw_directory, boot_index);
+ if (status != FWU_STATUS_SUCCESS) {
+ DMSG("Failed to run FW inspect: %d", status);
+ deinit_context(context);
+ return NULL;
+ }
+
+ /* Allow the associated fw_store to synchronize its state to the
+ * state of the booted firmware reflected by the fw_directory.
+ */
+ status = fw_store_synchronize(context->fw_store, &context->fw_directory, boot_index);
+ if (status != FWU_STATUS_SUCCESS) {
+ DMSG("Failed synchronize FW store: %d", status);
+ deinit_context(context);
+ return NULL;
+ }
+
+ /* Allocate a buffer for holding the serialized image directory */
+ context->image_dir_buf_size = img_dir_serializer_get_len(&context->fw_directory);
+ context->image_dir_buf = malloc(context->image_dir_buf_size);
+ if (!context->image_dir_buf) {
+ DMSG("Failed to allocate image_dir_buf");
+ deinit_context(context);
+ return NULL;
+ }
+
+ /* Transition to initial state */
+ context->state = fw_store_is_trial(context->fw_store) ? FWU_STATE_TRIAL : FWU_STATE_REGULAR;
+
+ agent = (struct update_agent *)calloc(1, sizeof(*agent));
+ if (!agent) {
+ DMSG("Failed to allocate update_agent");
+ deinit_context(context);
+ return NULL;
+ }
+
+ agent->context = context;
+ agent->interface = &interface;
+
+ return agent;
+}
+
+void update_agent_deinit(struct update_agent *update_agent)
+{
+ struct generic_update_agent *context = (struct generic_update_agent *)update_agent->context;
+
+ deinit_context(context);
+ free(update_agent);
+}
diff --git a/components/service/fwu/agent/update_agent.h b/components/service/fwu/agent/update_agent.h
index ea214ee..9004252 100644
--- a/components/service/fwu/agent/update_agent.h
+++ b/components/service/fwu/agent/update_agent.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -15,6 +15,7 @@
#include "fw_directory.h"
#include "service/fwu/inspector/fw_inspector.h"
#include "stream_manager.h"
+#include "components/service/fwu/common/update_agent_interface.h"
#ifdef __cplusplus
extern "C" {
@@ -26,39 +27,6 @@
struct fw_store;
/**
- * \brief Update process states
- *
- * The update_agent is responsible for ensuring that only a valid update flow
- * is followed by a client. To enforce the flow, public operations can only be
- * used in a valid state that reflects the FWU-A behavioral model.
- */
-enum fwu_state {
- FWU_STATE_DEINITIALZED,
- FWU_STATE_INITIALIZING,
- FWU_STATE_REGULAR,
- FWU_STATE_STAGING,
- FWU_STATE_TRIAL_PENDING,
- FWU_STATE_TRIAL
-};
-
-/**
- * \brief update_agent structure definition
- *
- * An update_agent instance is responsible for coordinating firmware updates applied
- * to a fw_store. An update_agent performs a security role by enforcing that a
- * valid flow is performed to update the fw store.
- */
-struct update_agent {
- enum fwu_state state;
- fw_inspector_inspect fw_inspect_method;
- struct fw_store *fw_store;
- struct fw_directory fw_directory;
- struct stream_manager stream_manager;
- uint8_t *image_dir_buf;
- size_t image_dir_buf_size;
-};
-
-/**
* \brief Initialise the update_agent
*
* \param[in] update_agent The subject update_agent
@@ -66,10 +34,11 @@
* \param[in] fw_inspect_method fw_inspector inspect method
* \param[in] fw_store The fw_store to manage
*
- * \return Status (0 for success). Uses fwu protocol status codes.
+ * \return Update agent instance or NULL on error
*/
-int update_agent_init(struct update_agent *update_agent, unsigned int boot_index,
- fw_inspector_inspect fw_inspect_method, struct fw_store *fw_store);
+struct update_agent *update_agent_init(unsigned int boot_index,
+ fw_inspector_inspect fw_inspect_method,
+ struct fw_store *fw_store);
/**
* \brief De-initialise the update_agent
@@ -78,109 +47,6 @@
*/
void update_agent_deinit(struct update_agent *update_agent);
-/**
- * \brief Begin staging
- *
- * \param[in] update_agent The subject update_agent
- *
- * \return 0 on successfully transitioning to the STAGING state
- */
-int update_agent_begin_staging(struct update_agent *update_agent);
-
-/**
- * \brief End staging
- *
- * \param[in] update_agent The subject update_agent
- *
- * \return 0 on successfully transitioning to the TRIAL state
- */
-int update_agent_end_staging(struct update_agent *update_agent);
-
-/**
- * \brief Cancel staging
- *
- * \param[in] update_agent The subject update_agent
- *
- * \return 0 on successfully transitioning to the REGULAR state
- */
-int update_agent_cancel_staging(struct update_agent *update_agent);
-
-/**
- * \brief Accept an updated image
- *
- * \param[in] update_agent The subject update_agent
- * \param[in] image_type_uuid Identifies the image to accept
- *
- * \return Status (0 on success)
- */
-int update_agent_accept(struct update_agent *update_agent,
- const struct uuid_octets *image_type_uuid);
-
-/**
- * \brief Select previous version
- *
- * Revert to a previous good version (if possible).
- *
- * \param[in] update_agent The subject update_agent
- *
- * \return Status (0 on success)
- */
-int update_agent_select_previous(struct update_agent *update_agent);
-
-/**
- * \brief Open a stream for accessing an fwu stream
- *
- * Used for reading or writing data for accessing images or other fwu
- * related objects.
- *
- * \param[in] update_agent The subject update_agent
- * \param[in] uuid Identifies the object to access
- * \param[out] handle For subsequent read/write operations
- *
- * \return Status (0 on success)
- */
-int update_agent_open(struct update_agent *update_agent, const struct uuid_octets *uuid,
- uint32_t *handle);
-
-/**
- * \brief Close a stream and commit any writes to the stream
- *
- * \param[in] update_agent The subject update_agent
- * \param[in] handle The handle returned by open
- * \param[in] accepted Initial accepted state of an image
- *
- * \return Status (0 on success)
- */
-int update_agent_commit(struct update_agent *update_agent, uint32_t handle, bool accepted);
-
-/**
- * \brief Write to a previously opened stream
- *
- * \param[in] update_agent The subject update_agent
- * \param[in] handle The handle returned by open
- * \param[in] data Pointer to data
- * \param[in] data_len The data length
- *
- * \return Status (0 on success)
- */
-int update_agent_write_stream(struct update_agent *update_agent, uint32_t handle,
- const uint8_t *data, size_t data_len);
-
-/**
- * \brief Read from a previously opened stream
- *
- * \param[in] update_agent The subject update_agent
- * \param[in] handle The handle returned by open
- * \param[in] buf Pointer to buffer to copy to
- * \param[in] buf_size The size of the buffer
- * \param[out] read_len The length of data read
- * \param[out] total_len The total length of the object to read
- *
- * \return Status (0 on success)
- */
-int update_agent_read_stream(struct update_agent *update_agent, uint32_t handle, uint8_t *buf,
- size_t buf_size, size_t *read_len, size_t *total_len);
-
#ifdef __cplusplus
}
#endif
diff --git a/components/service/fwu/provider/fwu_provider.c b/components/service/fwu/provider/fwu_provider.c
index e94f653..33b744f 100644
--- a/components/service/fwu/provider/fwu_provider.c
+++ b/components/service/fwu/provider/fwu_provider.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
#include "common/uuid/uuid.h"
#include "protocols/rpc/common/packed-c/status.h"
#include "protocols/service/fwu/packed-c/opcodes.h"
-#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
#include "service/fwu/provider/serializer/fwu_provider_serializer.h"
#include "fwu_uuid.h"
@@ -84,7 +84,7 @@
{
struct fwu_provider *this_instance = (struct fwu_provider *)context;
- req->service_status = update_agent_begin_staging(this_instance->update_agent);
+ req->service_status = update_agent_begin_staging(this_instance->update_agent, 0, 0, NULL);
return RPC_SUCCESS;
}
@@ -121,7 +121,8 @@
if (rpc_status == RPC_SUCCESS) {
uint32_t handle = 0;
req->service_status =
- update_agent_open(this_instance->update_agent, &image_type_uuid, &handle);
+ update_agent_open(this_instance->update_agent, &image_type_uuid, 0,
+ &handle);
if (!req->service_status) {
struct rpc_buffer *resp_buf = &req->response;
@@ -202,12 +203,15 @@
&max_atomic_len);
if (rpc_status == RPC_SUCCESS) {
+ uint32_t progress = 0;
+ uint32_t total_work = 0;
+
req->service_status = update_agent_commit(this_instance->update_agent, handle,
- accepted);
+ accepted, 0, &progress, &total_work);
if (!req->service_status) {
struct rpc_buffer *resp_buf = &req->response;
- rpc_status = serializer->serialize_commit_resp(resp_buf, 0, 0);
+ rpc_status = serializer->serialize_commit_resp(resp_buf, progress, total_work);
}
}
@@ -226,8 +230,8 @@
rpc_status = serializer->deserialize_accept_req(req_buf, &image_type_uuid);
if (rpc_status == RPC_SUCCESS)
- req->service_status = update_agent_accept(this_instance->update_agent,
- &image_type_uuid);
+ req->service_status = update_agent_accept_image(this_instance->update_agent,
+ &image_type_uuid);
return rpc_status;
}
diff --git a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp
index 6afd0f2..ecca254 100644
--- a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp
+++ b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,9 +8,9 @@
#include <cstring>
-#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
-direct_fwu_client::direct_fwu_client(struct update_agent *update_agent)
+direct_fwu_client::direct_fwu_client(struct update_agent **update_agent)
: fwu_client()
, m_update_agent(update_agent)
, m_read_buf()
@@ -27,48 +27,51 @@
int direct_fwu_client::begin_staging(void)
{
- return update_agent_begin_staging(m_update_agent);
+ return update_agent_begin_staging(*m_update_agent, 0, 0, NULL);
}
int direct_fwu_client::end_staging(void)
{
- return update_agent_end_staging(m_update_agent);
+ return update_agent_end_staging(*m_update_agent);
}
int direct_fwu_client::cancel_staging(void)
{
- return update_agent_cancel_staging(m_update_agent);
+ return update_agent_cancel_staging(*m_update_agent);
}
int direct_fwu_client::accept(const struct uuid_octets *image_type_uuid)
{
- return update_agent_accept(m_update_agent, image_type_uuid);
+ return update_agent_accept_image(*m_update_agent, image_type_uuid);
}
int direct_fwu_client::select_previous(void)
{
- return update_agent_select_previous(m_update_agent);
+ return update_agent_select_previous(*m_update_agent);
}
int direct_fwu_client::open(const struct uuid_octets *uuid, uint32_t *handle)
{
- return update_agent_open(m_update_agent, uuid, handle);
+ return update_agent_open(*m_update_agent, uuid, 0, handle);
}
int direct_fwu_client::commit(uint32_t handle, bool accepted)
{
- return update_agent_commit(m_update_agent, handle, accepted);
+ uint32_t progress = 0;
+ uint32_t total_work = 0;
+
+ return update_agent_commit(*m_update_agent, handle, accepted, 0, &progress, &total_work);
}
int direct_fwu_client::write_stream(uint32_t handle, const uint8_t *data, size_t data_len)
{
- return update_agent_write_stream(m_update_agent, handle, data, data_len);
+ return update_agent_write_stream(*m_update_agent, handle, data, data_len);
}
int direct_fwu_client::read_stream(uint32_t handle, uint8_t *buf, size_t buf_size, size_t *read_len,
size_t *total_len)
{
- int status = update_agent_read_stream(m_update_agent, handle, m_read_buf, READ_BUF_SIZE,
+ int status = update_agent_read_stream(*m_update_agent, handle, m_read_buf, READ_BUF_SIZE,
read_len, total_len);
if (!status && buf && buf_size) {
diff --git a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h
index bfa925b..3cd332d 100644
--- a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h
+++ b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,7 +19,7 @@
*/
class direct_fwu_client : public fwu_client {
public:
- explicit direct_fwu_client(struct update_agent *update_agent);
+ explicit direct_fwu_client(struct update_agent **update_agent);
~direct_fwu_client();
int begin_staging(void);
@@ -44,7 +44,7 @@
private:
static const size_t READ_BUF_SIZE = 512;
- struct update_agent *m_update_agent;
+ struct update_agent **m_update_agent;
uint8_t m_read_buf[READ_BUF_SIZE];
};
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
index 5415cc7..7718b63 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,8 @@
#include "common/endian/le.h"
#include "media/disk/guid.h"
#include "media/volume/index/volume_index.h"
+#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
#include "service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.h"
#include "service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h"
#include "service/fwu/fw_store/banked/volume_id.h"
@@ -54,16 +56,7 @@
install_factory_images(num_locations);
- /* Initialise fwu service provider prior to boot to ensure that a
- * viable service interface exists to safely handle an incoming
- * request that occurs prior to the boot method being called.
- * Note that the update_agent is in the de-initialized state so
- * any operations will be denied.
- */
- memset(&m_update_agent, 0, sizeof(m_update_agent));
- m_update_agent.state = FWU_STATE_DEINITIALZED;
-
- m_service_iface = fwu_provider_init(&m_fwu_provider, &m_update_agent);
+ m_service_iface = fwu_provider_init(&m_fwu_provider, NULL);
fwu_provider_register_serializer(&m_fwu_provider, TS_RPC_ENCODING_PACKED_C,
packedc_fwu_provider_serializer_instance());
@@ -119,9 +112,11 @@
int status = banked_fw_store_init(&m_fw_store, select_metadata_serializer());
LONGS_EQUAL(0, status);
- status = update_agent_init(&m_update_agent, m_boot_info.boot_index,
- direct_fw_inspector_inspect, &m_fw_store);
- LONGS_EQUAL(0, status);
+ m_update_agent = update_agent_init(m_boot_info.boot_index, direct_fw_inspector_inspect,
+ &m_fw_store);
+ CHECK(m_update_agent != NULL);
+
+ m_fwu_provider.update_agent = m_update_agent;
m_is_booted = true;
}
@@ -132,9 +127,10 @@
return;
/* Ensure all install streams are closed */
- update_agent_cancel_staging(&m_update_agent);
+ update_agent_cancel_staging(m_update_agent);
- update_agent_deinit(&m_update_agent);
+ m_fwu_provider.update_agent = NULL;
+ update_agent_deinit(m_update_agent);
banked_fw_store_deinit(&m_fw_store);
m_is_booted = false;
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
index f10d2c5..8a2bde3 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,13 +15,14 @@
#include "service/block_storage/block_store/device/ram/ram_block_store.h"
#include "service/block_storage/block_store/partitioned/partitioned_block_store.h"
#include "service/fwu/agent/fw_directory.h"
-#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
#include "service/fwu/fw_store/banked/bank_scheme.h"
#include "service/fwu/fw_store/banked/banked_fw_store.h"
#include "service/fwu/installer/copy/copy_installer.h"
#include "service/fwu/installer/raw/raw_installer.h"
#include "service/fwu/provider/fwu_provider.h"
#include "service/fwu/test/fwu_client/fwu_client.h"
+#include "service/fwu/test/fwu_client/direct/direct_fwu_client.h"
#include "service/fwu/test/fwu_dut/fwu_dut.h"
#include "service/fwu/test/metadata_checker/metadata_checker.h"
@@ -119,7 +120,7 @@
struct copy_installer m_copy_installer_pool[MAX_LOCATIONS];
/* The core fwu service components */
- struct update_agent m_update_agent;
+ struct update_agent *m_update_agent;
struct fw_store m_fw_store;
struct fwu_provider m_fwu_provider;
};
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index b733d9c..f39473d 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -106,6 +106,7 @@
"components/service/block_storage/factory/client"
"components/service/block_storage/factory/rpmb"
"components/service/fwu/agent"
+ "components/service/fwu/common"
"components/service/fwu/fw_store/banked"
"components/service/fwu/fw_store/banked/metadata_serializer/v1"
"components/service/fwu/fw_store/banked/metadata_serializer/v2"
diff --git a/deployments/fwu-tool/fwu.cmake b/deployments/fwu-tool/fwu.cmake
index d9cac39..fdaa550 100644
--- a/deployments/fwu-tool/fwu.cmake
+++ b/deployments/fwu-tool/fwu.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -24,6 +24,7 @@
"components/media/volume/index"
"components/service/common/include"
"components/service/fwu/agent"
+ "components/service/fwu/common"
"components/service/fwu/config"
"components/service/fwu/config/gpt"
"components/service/fwu/fw_store/banked"
diff --git a/deployments/fwu/env/commonsp/fwu_sp.c b/deployments/fwu/env/commonsp/fwu_sp.c
index c9bf4b1..21d78b7 100644
--- a/deployments/fwu/env/commonsp/fwu_sp.c
+++ b/deployments/fwu/env/commonsp/fwu_sp.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
*/
#include <stddef.h>
@@ -45,7 +45,7 @@
struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
struct fwu_provider service_provider = { 0 };
struct rpc_service_interface *service_iface = NULL;
- struct update_agent update_agent = { 0 };
+ struct update_agent *update_agent = NULL;
struct fw_store fw_store = { 0 };
struct sp_msg req_msg = { 0 };
struct sp_msg resp_msg = { 0 };
@@ -89,14 +89,15 @@
goto fatal_error;
}
- if (update_agent_init(&update_agent, HARD_CODED_BOOT_INDEX, direct_fw_inspector_inspect,
- &fw_store)) {
+ update_agent = update_agent_init(HARD_CODED_BOOT_INDEX, direct_fw_inspector_inspect,
+ &fw_store);
+ if (!update_agent) {
EMSG("Failed to init update agent");
goto fatal_error;
}
/* Initialise the FWU service provider */
- service_iface = fwu_provider_init(&service_provider, &update_agent);
+ service_iface = fwu_provider_init(&service_provider, update_agent);
if (!service_iface) {
EMSG("Failed to init service provider");
diff --git a/deployments/fwu/fwu.cmake b/deployments/fwu/fwu.cmake
index 7276360..2a7505e 100644
--- a/deployments/fwu/fwu.cmake
+++ b/deployments/fwu/fwu.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,6 +19,7 @@
"components/media/volume/index"
"components/service/common/include"
"components/service/fwu/agent"
+ "components/service/fwu/common"
"components/service/fwu/config"
"components/service/fwu/config/gpt"
"components/service/fwu/fw_store/banked"
diff --git a/deployments/ts-service-test/linux-pc/CMakeLists.txt b/deployments/ts-service-test/linux-pc/CMakeLists.txt
index b0cd912..4ce36e2 100644
--- a/deployments/ts-service-test/linux-pc/CMakeLists.txt
+++ b/deployments/ts-service-test/linux-pc/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -97,6 +97,7 @@
"components/service/block_storage/test/service"
"components/service/common/provider"
"components/service/fwu/agent"
+ "components/service/fwu/common"
"components/service/fwu/fw_store/banked"
"components/service/fwu/fw_store/banked/metadata_serializer/v1"
"components/service/fwu/fw_store/banked/metadata_serializer/v2"