#pragma once #include "data_interface.hpp" #include #include #include #include #include #include #include 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; } /** * @brief Returns the amount of time to wait after the host is up * before sending commands. * * In this class to help with mocking. * * @return milliseconds - The amount of time to wait */ virtual std::chrono::milliseconds getHostUpDelay() const { return _defaultHostUpDelay; } using ResponseFunction = std::function; /** * @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 Call the response function * * @param[in] status - The status given to the function */ void callResponseFunc(ResponseStatus status) { if (_responseFunc) { try { (*_responseFunc)(status); } catch (const std::exception& e) { lg2::error( "Host iface response callback threw an exception: {EX}", "EX", e); } } } /** * @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 * @param[in] transport - The transport data pointer */ virtual void receive(sdeventplus::source::IO& io, int fd, uint32_t revents, pldm_transport* transport) = 0; /** * @brief An optional function to call on a successful command response. */ std::optional _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. */ const std::chrono::milliseconds _defaultSendRetryDelay{1000}; /** * @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}; /** * @brief The default amount of time to wait after the host is up * before sending up the PELs. */ const std::chrono::milliseconds _defaultHostUpDelay{60000}; }; } // namespace pels } // namespace openpower