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 113*e5f7508bSMatt Spinler /** 114*e5f7508bSMatt Spinler * @brief Returns the amount of time to wait after the host is up 115*e5f7508bSMatt Spinler * before sending commands. 116*e5f7508bSMatt Spinler * 117*e5f7508bSMatt Spinler * In this class to help with mocking. 118*e5f7508bSMatt Spinler * 119*e5f7508bSMatt Spinler * @return milliseconds - The amount of time to wait 120*e5f7508bSMatt Spinler */ 121*e5f7508bSMatt Spinler virtual std::chrono::milliseconds getHostUpDelay() const 122*e5f7508bSMatt Spinler { 123*e5f7508bSMatt Spinler return _defaultHostUpDelay; 124*e5f7508bSMatt Spinler } 125*e5f7508bSMatt Spinler 12699196688SMatt Spinler using ResponseFunction = std::function<void(ResponseStatus)>; 12799196688SMatt Spinler 12899196688SMatt Spinler /** 12999196688SMatt Spinler * @brief Sets the function to call on the command receive. 13099196688SMatt Spinler * 13199196688SMatt Spinler * The success/failure status is passed to the function. 13299196688SMatt Spinler * 13399196688SMatt Spinler * @param[in] func - The callback function 13499196688SMatt Spinler */ 13599196688SMatt Spinler void setResponseFunction(ResponseFunction func) 13699196688SMatt Spinler { 13799196688SMatt Spinler _responseFunc = std::move(func); 13899196688SMatt Spinler } 13999196688SMatt Spinler 14099196688SMatt Spinler /** 141a44efe48SMatt Spinler * @brief Call the response function 142a44efe48SMatt Spinler * 143a44efe48SMatt Spinler * @param[in] status - The status given to the function 144a44efe48SMatt Spinler */ 145a44efe48SMatt Spinler void callResponseFunc(ResponseStatus status) 146a44efe48SMatt Spinler { 147a44efe48SMatt Spinler if (_responseFunc) 148a44efe48SMatt Spinler { 149a44efe48SMatt Spinler try 150a44efe48SMatt Spinler { 151a44efe48SMatt Spinler (*_responseFunc)(status); 152a44efe48SMatt Spinler } 153a44efe48SMatt Spinler catch (const std::exception& e) 154a44efe48SMatt Spinler { 155a44efe48SMatt Spinler using namespace phosphor::logging; 156a44efe48SMatt Spinler log<level::ERR>( 157a44efe48SMatt Spinler "Host iface response callback threw an exception", 158a44efe48SMatt Spinler entry("ERROR=%s", e.what())); 159a44efe48SMatt Spinler } 160a44efe48SMatt Spinler } 161a44efe48SMatt Spinler } 162a44efe48SMatt Spinler 163a44efe48SMatt Spinler /** 16499196688SMatt Spinler * @brief Returns the event object in use 16599196688SMatt Spinler * 16699196688SMatt Spinler * @return sdeventplus::Event& - The event object 16799196688SMatt Spinler */ 16899196688SMatt Spinler sdeventplus::Event& getEvent() 16999196688SMatt Spinler { 17099196688SMatt Spinler return _event; 17199196688SMatt Spinler } 17299196688SMatt Spinler 17399196688SMatt Spinler /** 17499196688SMatt Spinler * @brief Pure virtual function to cancel an in-progress command 17599196688SMatt Spinler * 17699196688SMatt Spinler * 'In progress' means after the send but before the receive 17799196688SMatt Spinler */ 17899196688SMatt Spinler virtual void cancelCmd() = 0; 17999196688SMatt Spinler 18099196688SMatt Spinler /** 18199196688SMatt Spinler * @brief Says if the command is in progress (after send/before receive) 18299196688SMatt Spinler * 18399196688SMatt Spinler * @return bool - If command is in progress 18499196688SMatt Spinler */ 18599196688SMatt Spinler bool cmdInProgress() const 18699196688SMatt Spinler { 18799196688SMatt Spinler return _inProgress; 18899196688SMatt Spinler } 18999196688SMatt Spinler 19099196688SMatt Spinler protected: 19199196688SMatt Spinler /** 19299196688SMatt Spinler * @brief Pure virtual function for implementing the asynchronous 19399196688SMatt Spinler * command response callback. 19499196688SMatt Spinler * 19599196688SMatt Spinler * @param[in] io - The sdeventplus IO object that the callback is 19699196688SMatt Spinler * invoked from. 19799196688SMatt Spinler * @param[in] fd - The file descriptor being used 19899196688SMatt Spinler * @param[in] revents - The event status bits 19999196688SMatt Spinler */ 20099196688SMatt Spinler virtual void receive(sdeventplus::source::IO& io, int fd, 20199196688SMatt Spinler uint32_t revents) = 0; 20299196688SMatt Spinler 20399196688SMatt Spinler /** 20499196688SMatt Spinler * @brief An optional function to call on a successful command response. 20599196688SMatt Spinler */ 20699196688SMatt Spinler std::optional<ResponseFunction> _responseFunc; 20799196688SMatt Spinler 20899196688SMatt Spinler /** 20999196688SMatt Spinler * @brief The sd_event wrapper object needed for response callbacks 21099196688SMatt Spinler */ 21199196688SMatt Spinler sdeventplus::Event _event; 21299196688SMatt Spinler 21399196688SMatt Spinler /** 21499196688SMatt Spinler * @brief The DataInterface object 21599196688SMatt Spinler */ 21699196688SMatt Spinler DataInterfaceBase& _dataIface; 21799196688SMatt Spinler 21899196688SMatt Spinler /** 21999196688SMatt Spinler * @brief Tracks status of after a command is sent and before the 22099196688SMatt Spinler * response is received. 22199196688SMatt Spinler */ 22299196688SMatt Spinler bool _inProgress = false; 22399196688SMatt Spinler 22499196688SMatt Spinler private: 22599196688SMatt Spinler /** 22699196688SMatt Spinler * @brief The default amount of time to wait before retrying 22799196688SMatt Spinler * a failed send. 22899196688SMatt Spinler */ 2293a4243a6SMatt Spinler const std::chrono::milliseconds _defaultSendRetryDelay{1000}; 23099196688SMatt Spinler 23199196688SMatt Spinler /** 23299196688SMatt Spinler * @brief The default amount of time to wait 23399196688SMatt Spinler * before retrying after a failed receive. 23499196688SMatt Spinler */ 23599196688SMatt Spinler const std::chrono::milliseconds _defaultReceiveRetryDelay{1000}; 23699196688SMatt Spinler 23799196688SMatt Spinler /** 23899196688SMatt Spinler * @brief The default amount of time to wait when the host said it 23999196688SMatt Spinler * was full before sending the PEL again. 24099196688SMatt Spinler */ 24199196688SMatt Spinler const std::chrono::milliseconds _defaultHostFullRetryDelay{60000}; 242*e5f7508bSMatt Spinler 243*e5f7508bSMatt Spinler /** 244*e5f7508bSMatt Spinler * @brief The default amount of time to wait after the host is up 245*e5f7508bSMatt Spinler * before sending up the PELs. 246*e5f7508bSMatt Spinler */ 247*e5f7508bSMatt Spinler const std::chrono::milliseconds _defaultHostUpDelay{60000}; 24899196688SMatt Spinler }; 24999196688SMatt Spinler 25099196688SMatt Spinler } // namespace pels 25199196688SMatt Spinler } // namespace openpower 252