199196688SMatt Spinler #pragma once 299196688SMatt Spinler 399196688SMatt Spinler #include "data_interface.hpp" 499196688SMatt Spinler 599196688SMatt Spinler #include <stdint.h> 699196688SMatt Spinler 799196688SMatt Spinler #include <chrono> 899196688SMatt Spinler #include <functional> 9a44efe48SMatt Spinler #include <phosphor-logging/log.hpp> 1099196688SMatt Spinler #include <sdeventplus/event.hpp> 1199196688SMatt Spinler #include <sdeventplus/source/io.hpp> 1299196688SMatt Spinler 1399196688SMatt Spinler namespace openpower 1499196688SMatt Spinler { 1599196688SMatt Spinler namespace pels 1699196688SMatt Spinler { 1799196688SMatt Spinler 1899196688SMatt Spinler /** 1999196688SMatt Spinler * @brief Return codes from sending a command 2099196688SMatt Spinler */ 2199196688SMatt Spinler enum class CmdStatus 2299196688SMatt Spinler { 2399196688SMatt Spinler success, 2499196688SMatt Spinler failure 2599196688SMatt Spinler }; 2699196688SMatt Spinler 2799196688SMatt Spinler /** 2899196688SMatt Spinler * @brief Return codes from the command response 2999196688SMatt Spinler */ 3099196688SMatt Spinler enum class ResponseStatus 3199196688SMatt Spinler { 3299196688SMatt Spinler success, 3399196688SMatt Spinler failure 3499196688SMatt Spinler }; 3599196688SMatt Spinler 3699196688SMatt Spinler /** 3799196688SMatt Spinler * @class HostInterface 3899196688SMatt Spinler * 3999196688SMatt Spinler * An abstract base class for sending the 'New PEL available' command 4099196688SMatt Spinler * to the host. Used so that the PLDM interfaces can be mocked for 4199196688SMatt Spinler * testing the HostNotifier code. The response to this command is 4299196688SMatt Spinler * asynchronous, with the intent that other code registers a callback 4399196688SMatt Spinler * function to run when the response is received. 4499196688SMatt Spinler */ 4599196688SMatt Spinler class HostInterface 4699196688SMatt Spinler { 4799196688SMatt Spinler public: 4899196688SMatt Spinler HostInterface() = delete; 4999196688SMatt Spinler virtual ~HostInterface() = default; 5099196688SMatt Spinler HostInterface(const HostInterface&) = default; 5199196688SMatt Spinler HostInterface& operator=(const HostInterface&) = default; 5299196688SMatt Spinler HostInterface(HostInterface&&) = default; 5399196688SMatt Spinler HostInterface& operator=(HostInterface&&) = default; 5499196688SMatt Spinler 5599196688SMatt Spinler /** 5699196688SMatt Spinler * @brief Constructor 5799196688SMatt Spinler * 5899196688SMatt Spinler * @param[in] event - The sd_event object pointer 5999196688SMatt Spinler * @param[in] dataIface - The DataInterface object 6099196688SMatt Spinler */ 6199196688SMatt Spinler HostInterface(sd_event* event, DataInterfaceBase& dataIface) : 6299196688SMatt Spinler _event(event), _dataIface(dataIface) 6399196688SMatt Spinler { 6499196688SMatt Spinler } 6599196688SMatt Spinler 6699196688SMatt Spinler /** 6799196688SMatt Spinler * @brief Pure virtual function for sending the 'new PEL available' 6899196688SMatt Spinler * asynchronous command to the host. 6999196688SMatt Spinler * 7099196688SMatt Spinler * @param[in] id - The ID of the new PEL 7199196688SMatt Spinler * @param[in] size - The size of the new PEL 7299196688SMatt Spinler * 7399196688SMatt Spinler * @return CmdStatus - If the send was successful or not 7499196688SMatt Spinler */ 7599196688SMatt Spinler virtual CmdStatus sendNewLogCmd(uint32_t id, uint32_t size) = 0; 7699196688SMatt Spinler 7799196688SMatt Spinler /** 7899196688SMatt Spinler * @brief Returns the amount of time to wait before retrying after 7999196688SMatt Spinler * a failed send command. 8099196688SMatt Spinler * 8199196688SMatt Spinler * @return milliseconds - The amount of time to wait 8299196688SMatt Spinler */ 8399196688SMatt Spinler virtual std::chrono::milliseconds getSendRetryDelay() const 8499196688SMatt Spinler { 8599196688SMatt Spinler return _defaultSendRetryDelay; 8699196688SMatt Spinler } 8799196688SMatt Spinler 8899196688SMatt Spinler /** 8999196688SMatt Spinler * @brief Returns the amount of time to wait before retrying after 9099196688SMatt Spinler * a command receive. 9199196688SMatt Spinler * 9299196688SMatt Spinler * @return milliseconds - The amount of time to wait 9399196688SMatt Spinler */ 9499196688SMatt Spinler virtual std::chrono::milliseconds getReceiveRetryDelay() const 9599196688SMatt Spinler { 9699196688SMatt Spinler return _defaultReceiveRetryDelay; 9799196688SMatt Spinler } 9899196688SMatt Spinler 9999196688SMatt Spinler /** 10099196688SMatt Spinler * @brief Returns the amount of time to wait before retrying if the 10199196688SMatt Spinler * host firmware's PEL storage was full and it can't store 10299196688SMatt Spinler * any more logs until it is freed up somehow. 10399196688SMatt Spinler * 10499196688SMatt Spinler * In this class to help with mocking. 10599196688SMatt Spinler * 10699196688SMatt Spinler * @return milliseconds - The amount of time to wait 10799196688SMatt Spinler */ 10899196688SMatt Spinler virtual std::chrono::milliseconds getHostFullRetryDelay() const 10999196688SMatt Spinler { 11099196688SMatt Spinler return _defaultHostFullRetryDelay; 11199196688SMatt Spinler } 11299196688SMatt Spinler 11399196688SMatt Spinler using ResponseFunction = std::function<void(ResponseStatus)>; 11499196688SMatt Spinler 11599196688SMatt Spinler /** 11699196688SMatt Spinler * @brief Sets the function to call on the command receive. 11799196688SMatt Spinler * 11899196688SMatt Spinler * The success/failure status is passed to the function. 11999196688SMatt Spinler * 12099196688SMatt Spinler * @param[in] func - The callback function 12199196688SMatt Spinler */ 12299196688SMatt Spinler void setResponseFunction(ResponseFunction func) 12399196688SMatt Spinler { 12499196688SMatt Spinler _responseFunc = std::move(func); 12599196688SMatt Spinler } 12699196688SMatt Spinler 12799196688SMatt Spinler /** 128a44efe48SMatt Spinler * @brief Call the response function 129a44efe48SMatt Spinler * 130a44efe48SMatt Spinler * @param[in] status - The status given to the function 131a44efe48SMatt Spinler */ 132a44efe48SMatt Spinler void callResponseFunc(ResponseStatus status) 133a44efe48SMatt Spinler { 134a44efe48SMatt Spinler if (_responseFunc) 135a44efe48SMatt Spinler { 136a44efe48SMatt Spinler try 137a44efe48SMatt Spinler { 138a44efe48SMatt Spinler (*_responseFunc)(status); 139a44efe48SMatt Spinler } 140a44efe48SMatt Spinler catch (const std::exception& e) 141a44efe48SMatt Spinler { 142a44efe48SMatt Spinler using namespace phosphor::logging; 143a44efe48SMatt Spinler log<level::ERR>( 144a44efe48SMatt Spinler "Host iface response callback threw an exception", 145a44efe48SMatt Spinler entry("ERROR=%s", e.what())); 146a44efe48SMatt Spinler } 147a44efe48SMatt Spinler } 148a44efe48SMatt Spinler } 149a44efe48SMatt Spinler 150a44efe48SMatt Spinler /** 15199196688SMatt Spinler * @brief Returns the event object in use 15299196688SMatt Spinler * 15399196688SMatt Spinler * @return sdeventplus::Event& - The event object 15499196688SMatt Spinler */ 15599196688SMatt Spinler sdeventplus::Event& getEvent() 15699196688SMatt Spinler { 15799196688SMatt Spinler return _event; 15899196688SMatt Spinler } 15999196688SMatt Spinler 16099196688SMatt Spinler /** 16199196688SMatt Spinler * @brief Pure virtual function to cancel an in-progress command 16299196688SMatt Spinler * 16399196688SMatt Spinler * 'In progress' means after the send but before the receive 16499196688SMatt Spinler */ 16599196688SMatt Spinler virtual void cancelCmd() = 0; 16699196688SMatt Spinler 16799196688SMatt Spinler /** 16899196688SMatt Spinler * @brief Says if the command is in progress (after send/before receive) 16999196688SMatt Spinler * 17099196688SMatt Spinler * @return bool - If command is in progress 17199196688SMatt Spinler */ 17299196688SMatt Spinler bool cmdInProgress() const 17399196688SMatt Spinler { 17499196688SMatt Spinler return _inProgress; 17599196688SMatt Spinler } 17699196688SMatt Spinler 17799196688SMatt Spinler protected: 17899196688SMatt Spinler /** 17999196688SMatt Spinler * @brief Pure virtual function for implementing the asynchronous 18099196688SMatt Spinler * command response callback. 18199196688SMatt Spinler * 18299196688SMatt Spinler * @param[in] io - The sdeventplus IO object that the callback is 18399196688SMatt Spinler * invoked from. 18499196688SMatt Spinler * @param[in] fd - The file descriptor being used 18599196688SMatt Spinler * @param[in] revents - The event status bits 18699196688SMatt Spinler */ 18799196688SMatt Spinler virtual void receive(sdeventplus::source::IO& io, int fd, 18899196688SMatt Spinler uint32_t revents) = 0; 18999196688SMatt Spinler 19099196688SMatt Spinler /** 19199196688SMatt Spinler * @brief An optional function to call on a successful command response. 19299196688SMatt Spinler */ 19399196688SMatt Spinler std::optional<ResponseFunction> _responseFunc; 19499196688SMatt Spinler 19599196688SMatt Spinler /** 19699196688SMatt Spinler * @brief The sd_event wrapper object needed for response callbacks 19799196688SMatt Spinler */ 19899196688SMatt Spinler sdeventplus::Event _event; 19999196688SMatt Spinler 20099196688SMatt Spinler /** 20199196688SMatt Spinler * @brief The DataInterface object 20299196688SMatt Spinler */ 20399196688SMatt Spinler DataInterfaceBase& _dataIface; 20499196688SMatt Spinler 20599196688SMatt Spinler /** 20699196688SMatt Spinler * @brief Tracks status of after a command is sent and before the 20799196688SMatt Spinler * response is received. 20899196688SMatt Spinler */ 20999196688SMatt Spinler bool _inProgress = false; 21099196688SMatt Spinler 21199196688SMatt Spinler private: 21299196688SMatt Spinler /** 21399196688SMatt Spinler * @brief The default amount of time to wait before retrying 21499196688SMatt Spinler * a failed send. 21599196688SMatt Spinler */ 216*3a4243a6SMatt Spinler const std::chrono::milliseconds _defaultSendRetryDelay{1000}; 21799196688SMatt Spinler 21899196688SMatt Spinler /** 21999196688SMatt Spinler * @brief The default amount of time to wait 22099196688SMatt Spinler * before retrying after a failed receive. 22199196688SMatt Spinler */ 22299196688SMatt Spinler const std::chrono::milliseconds _defaultReceiveRetryDelay{1000}; 22399196688SMatt Spinler 22499196688SMatt Spinler /** 22599196688SMatt Spinler * @brief The default amount of time to wait when the host said it 22699196688SMatt Spinler * was full before sending the PEL again. 22799196688SMatt Spinler */ 22899196688SMatt Spinler const std::chrono::milliseconds _defaultHostFullRetryDelay{60000}; 22999196688SMatt Spinler }; 23099196688SMatt Spinler 23199196688SMatt Spinler } // namespace pels 23299196688SMatt Spinler } // namespace openpower 233