blob: 0ce534d62ae1595374cdd537120578d732f41abb [file] [log] [blame]
/*
* Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FWU_STREAM_MANAGER_H
#define FWU_STREAM_MANAGER_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/**
* Manages the set of streams used by the update_agent for image installation
* and accessing other FWU related objects. A subject of stream objects is managed
* to allow for concurrent streams if needed. To defend against a badly behaved
* client that fails to close streams, if necessary, the least recently used
* open stream will be reused if necessary to prevent a denial of service attack
* where a rogue client opens streams but doesn't close them.
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Interface dependencies
*/
struct fw_store;
struct installer;
struct image_info;
/**
* The default stream subject size
*/
#ifndef FWU_STREAM_MANAGER_POOL_SIZE
#define FWU_STREAM_MANAGER_POOL_SIZE (4)
#endif
/**
* Identifier for the type of stream
*/
enum fwu_stream_type { FWU_STREAM_TYPE_NONE, FWU_STREAM_TYPE_BUFFER, FWU_STREAM_TYPE_INSTALL };
/**
* A stream context
*/
struct stream_context {
enum fwu_stream_type type;
uint32_t handle;
struct stream_context *next;
struct stream_context *prev;
union stream_variant {
/* Buffer stream variant */
struct buffer_variant {
size_t pos;
const uint8_t *data;
size_t data_len;
} buffer;
/* Install stream variant */
struct install_variant {
struct fw_store *fw_store;
struct installer *installer;
const struct image_info *image_info;
} install;
} variant;
};
/**
* The stream_manager structure.
*/
struct stream_manager {
struct stream_context contexts[FWU_STREAM_MANAGER_POOL_SIZE];
struct stream_context *free;
struct stream_context *active_head;
struct stream_context *active_tail;
uint16_t rolling_count;
};
/**
* \brief One-time initialization
*
* \param[in] subject The subject stream_manager
*/
void stream_manager_init(struct stream_manager *subject);
/**
* \brief De-initializes a stream_manager
*
* \param[in] subject The subject stream_manager
*/
void stream_manager_deinit(struct stream_manager *subject);
/**
* \brief Open a buffer stream
*
* Opens a stream for reading from a buffer containing the complete object
* to access.
*
* \param[in] subject The subject stream_manager
* \param[in] data Pointer to the buffer containing data
* \param[in] data_len The length of the data
* \param[out] stream_handle The stream handle to use for subsequent operations
*
* \return FWU status
*/
int stream_manager_open_buffer_stream(struct stream_manager *subject, const uint8_t *data,
size_t data_len, uint32_t *stream_handle);
/**
* \brief Open an install stream
*
* Open a stream for writing an image to an installer. A concrete installer
* is responsible for installing the image into storage.
*
* \param[in] subject The subject stream_manager
* \param[in] fw_store The image_info for the image to install
* \param[in] installer The installer
* \param[in] image_info The image_info corresponding to the image to install
* \param[out] stream_handle The stream_handle to use for subsequent operations
*
* \return FWU status
*/
int stream_manager_open_install_stream(struct stream_manager *subject, struct fw_store *fw_store,
struct installer *installer,
const struct image_info *image_info,
uint32_t *stream_handle);
/**
* \brief Close a previously opened stream
*
* \param[in] subject The subject stream_manager
* \param[in] stream_handle Stream handle
* \param[in] accepted The initial accepted state for an installed image
*
* \return FWU status
*/
int stream_manager_close(struct stream_manager *subject, uint32_t stream_handle, bool accepted);
/**
* \brief Cancel all streams of the specified type
*
* \param[in] subject The subject stream_manager
* \param[in] type Type of stream to cancel
*/
void stream_manager_cancel_streams(struct stream_manager *subject, enum fwu_stream_type type);
/**
* \brief Check for any open streams of the specified type
*
* \param[in] subject The subject stream_manager
* \param[in] type Type of stream to check
*
* \return True is any are open
*/
bool stream_manager_is_open_streams(const struct stream_manager *subject,
enum fwu_stream_type type);
/**
* \brief Write to a previously opened stream
*
* \param[in] subject The subject stream_manager
* \param[in] stream_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 stream_manager_write(struct stream_manager *subject, uint32_t stream_handle,
const uint8_t *data, size_t data_len);
/**
* \brief Read from a previously opened stream
*
* \param[in] subject The subject stream_manager
* \param[in] stream_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 object to read
*
* \return Status (0 on success)
*/
int stream_manager_read(struct stream_manager *subject, uint32_t handle, uint8_t *buf,
size_t buf_size, size_t *read_len, size_t *total_len);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* FWU_STREAM_MANAGER_H */