diff options
Diffstat (limited to 'extensions/openpower-pels/host_interface.hpp')
-rw-r--r-- | extensions/openpower-pels/host_interface.hpp | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/extensions/openpower-pels/host_interface.hpp b/extensions/openpower-pels/host_interface.hpp new file mode 100644 index 0000000..94c984a --- /dev/null +++ b/extensions/openpower-pels/host_interface.hpp @@ -0,0 +1,211 @@ +#pragma once + +#include "data_interface.hpp" + +#include <stdint.h> + +#include <chrono> +#include <functional> +#include <sdeventplus/event.hpp> +#include <sdeventplus/source/io.hpp> + +namespace openpower +{ +namespace pels +{ + +/** + * @brief Return codes from sending a command + */ +enum class CmdStatus +{ + success, + failure +}; + +/** + * @brief Return codes from the command response + */ +enum class ResponseStatus +{ + success, + failure +}; + +/** + * @class HostInterface + * + * An abstract base class for sending the 'New PEL available' command + * to the host. Used so that the PLDM interfaces can be mocked for + * testing the HostNotifier code. The response to this command is + * asynchronous, with the intent that other code registers a callback + * function to run when the response is received. + */ +class HostInterface +{ + public: + HostInterface() = delete; + virtual ~HostInterface() = default; + HostInterface(const HostInterface&) = default; + HostInterface& operator=(const HostInterface&) = default; + HostInterface(HostInterface&&) = default; + HostInterface& operator=(HostInterface&&) = default; + + /** + * @brief Constructor + * + * @param[in] event - The sd_event object pointer + * @param[in] dataIface - The DataInterface object + */ + HostInterface(sd_event* event, DataInterfaceBase& dataIface) : + _event(event), _dataIface(dataIface) + { + } + + /** + * @brief Pure virtual function for sending the 'new PEL available' + * asynchronous command to the host. + * + * @param[in] id - The ID of the new PEL + * @param[in] size - The size of the new PEL + * + * @return CmdStatus - If the send was successful or not + */ + virtual CmdStatus sendNewLogCmd(uint32_t id, uint32_t size) = 0; + + /** + * @brief Returns the amount of time to wait before retrying after + * a failed send command. + * + * @return milliseconds - The amount of time to wait + */ + virtual std::chrono::milliseconds getSendRetryDelay() const + { + return _defaultSendRetryDelay; + } + + /** + * @brief Returns the amount of time to wait before retrying after + * a command receive. + * + * @return milliseconds - The amount of time to wait + */ + virtual std::chrono::milliseconds getReceiveRetryDelay() const + { + return _defaultReceiveRetryDelay; + } + + /** + * @brief Returns the amount of time to wait before retrying if the + * host firmware's PEL storage was full and it can't store + * any more logs until it is freed up somehow. + * + * In this class to help with mocking. + * + * @return milliseconds - The amount of time to wait + */ + virtual std::chrono::milliseconds getHostFullRetryDelay() const + { + return _defaultHostFullRetryDelay; + } + + using ResponseFunction = std::function<void(ResponseStatus)>; + + /** + * @brief Sets the function to call on the command receive. + * + * The success/failure status is passed to the function. + * + * @param[in] func - The callback function + */ + void setResponseFunction(ResponseFunction func) + { + _responseFunc = std::move(func); + } + + /** + * @brief Returns the event object in use + * + * @return sdeventplus::Event& - The event object + */ + sdeventplus::Event& getEvent() + { + return _event; + } + + /** + * @brief Pure virtual function to cancel an in-progress command + * + * 'In progress' means after the send but before the receive + */ + virtual void cancelCmd() = 0; + + /** + * @brief Says if the command is in progress (after send/before receive) + * + * @return bool - If command is in progress + */ + bool cmdInProgress() const + { + return _inProgress; + } + + protected: + /** + * @brief Pure virtual function for implementing the asynchronous + * command response callback. + * + * @param[in] io - The sdeventplus IO object that the callback is + * invoked from. + * @param[in] fd - The file descriptor being used + * @param[in] revents - The event status bits + */ + virtual void receive(sdeventplus::source::IO& io, int fd, + uint32_t revents) = 0; + + /** + * @brief An optional function to call on a successful command response. + */ + std::optional<ResponseFunction> _responseFunc; + + /** + * @brief The sd_event wrapper object needed for response callbacks + */ + sdeventplus::Event _event; + + /** + * @brief The DataInterface object + */ + DataInterfaceBase& _dataIface; + + /** + * @brief Tracks status of after a command is sent and before the + * response is received. + */ + bool _inProgress = false; + + private: + /** + * @brief The default amount of time to wait before retrying + * a failed send. + * + * It is this value for the case where all instance IDs are used + * and it takes this long in the PLDM daemon for them to reset. + */ + const std::chrono::milliseconds _defaultSendRetryDelay{6000}; + + /** + * @brief The default amount of time to wait + * before retrying after a failed receive. + */ + const std::chrono::milliseconds _defaultReceiveRetryDelay{1000}; + + /** + * @brief The default amount of time to wait when the host said it + * was full before sending the PEL again. + */ + const std::chrono::milliseconds _defaultHostFullRetryDelay{60000}; +}; + +} // namespace pels +} // namespace openpower |