199196688SMatt Spinler #pragma once 299196688SMatt Spinler 399196688SMatt Spinler #include "data_interface.hpp" 499196688SMatt Spinler 5*0387a74eSLakshmi Yadlapati #include <libpldm/transport.h> 699196688SMatt Spinler #include <stdint.h> 799196688SMatt Spinler 81b41886dSMatt Spinler #include <phosphor-logging/lg2.hpp> 999196688SMatt Spinler #include <sdeventplus/event.hpp> 1099196688SMatt Spinler #include <sdeventplus/source/io.hpp> 1199196688SMatt Spinler 122544b419SPatrick Williams #include <chrono> 132544b419SPatrick Williams #include <functional> 142544b419SPatrick Williams 1599196688SMatt Spinler namespace openpower 1699196688SMatt Spinler { 1799196688SMatt Spinler namespace pels 1899196688SMatt Spinler { 1999196688SMatt Spinler 2099196688SMatt Spinler /** 2199196688SMatt Spinler * @brief Return codes from sending a command 2299196688SMatt Spinler */ 2399196688SMatt Spinler enum class CmdStatus 2499196688SMatt Spinler { 2599196688SMatt Spinler success, 2699196688SMatt Spinler failure 2799196688SMatt Spinler }; 2899196688SMatt Spinler 2999196688SMatt Spinler /** 3099196688SMatt Spinler * @brief Return codes from the command response 3199196688SMatt Spinler */ 3299196688SMatt Spinler enum class ResponseStatus 3399196688SMatt Spinler { 3499196688SMatt Spinler success, 3599196688SMatt Spinler failure 3699196688SMatt Spinler }; 3799196688SMatt Spinler 3899196688SMatt Spinler /** 3999196688SMatt Spinler * @class HostInterface 4099196688SMatt Spinler * 4199196688SMatt Spinler * An abstract base class for sending the 'New PEL available' command 4299196688SMatt Spinler * to the host. Used so that the PLDM interfaces can be mocked for 4399196688SMatt Spinler * testing the HostNotifier code. The response to this command is 4499196688SMatt Spinler * asynchronous, with the intent that other code registers a callback 4599196688SMatt Spinler * function to run when the response is received. 4699196688SMatt Spinler */ 4799196688SMatt Spinler class HostInterface 4899196688SMatt Spinler { 4999196688SMatt Spinler public: 5099196688SMatt Spinler HostInterface() = delete; 5199196688SMatt Spinler virtual ~HostInterface() = default; 5299196688SMatt Spinler HostInterface(const HostInterface&) = default; 5399196688SMatt Spinler HostInterface& operator=(const HostInterface&) = default; 5499196688SMatt Spinler HostInterface(HostInterface&&) = default; 5599196688SMatt Spinler HostInterface& operator=(HostInterface&&) = default; 5699196688SMatt Spinler 5799196688SMatt Spinler /** 5899196688SMatt Spinler * @brief Constructor 5999196688SMatt Spinler * 6099196688SMatt Spinler * @param[in] event - The sd_event object pointer 6199196688SMatt Spinler * @param[in] dataIface - The DataInterface object 6299196688SMatt Spinler */ HostInterface(sd_event * event,DataInterfaceBase & dataIface)6399196688SMatt Spinler HostInterface(sd_event* event, DataInterfaceBase& dataIface) : 6499196688SMatt Spinler _event(event), _dataIface(dataIface) 652544b419SPatrick Williams {} 6699196688SMatt Spinler 6799196688SMatt Spinler /** 6899196688SMatt Spinler * @brief Pure virtual function for sending the 'new PEL available' 6999196688SMatt Spinler * asynchronous command to the host. 7099196688SMatt Spinler * 7199196688SMatt Spinler * @param[in] id - The ID of the new PEL 7299196688SMatt Spinler * @param[in] size - The size of the new PEL 7399196688SMatt Spinler * 7499196688SMatt Spinler * @return CmdStatus - If the send was successful or not 7599196688SMatt Spinler */ 7699196688SMatt Spinler virtual CmdStatus sendNewLogCmd(uint32_t id, uint32_t size) = 0; 7799196688SMatt Spinler 7899196688SMatt Spinler /** 7999196688SMatt Spinler * @brief Returns the amount of time to wait before retrying after 8099196688SMatt Spinler * a failed send command. 8199196688SMatt Spinler * 8299196688SMatt Spinler * @return milliseconds - The amount of time to wait 8399196688SMatt Spinler */ getSendRetryDelay() const8499196688SMatt Spinler virtual std::chrono::milliseconds getSendRetryDelay() const 8599196688SMatt Spinler { 8699196688SMatt Spinler return _defaultSendRetryDelay; 8799196688SMatt Spinler } 8899196688SMatt Spinler 8999196688SMatt Spinler /** 9099196688SMatt Spinler * @brief Returns the amount of time to wait before retrying after 9199196688SMatt Spinler * a command receive. 9299196688SMatt Spinler * 9399196688SMatt Spinler * @return milliseconds - The amount of time to wait 9499196688SMatt Spinler */ getReceiveRetryDelay() const9599196688SMatt Spinler virtual std::chrono::milliseconds getReceiveRetryDelay() const 9699196688SMatt Spinler { 9799196688SMatt Spinler return _defaultReceiveRetryDelay; 9899196688SMatt Spinler } 9999196688SMatt Spinler 10099196688SMatt Spinler /** 10199196688SMatt Spinler * @brief Returns the amount of time to wait before retrying if the 10299196688SMatt Spinler * host firmware's PEL storage was full and it can't store 10399196688SMatt Spinler * any more logs until it is freed up somehow. 10499196688SMatt Spinler * 10599196688SMatt Spinler * In this class to help with mocking. 10699196688SMatt Spinler * 10799196688SMatt Spinler * @return milliseconds - The amount of time to wait 10899196688SMatt Spinler */ getHostFullRetryDelay() const10999196688SMatt Spinler virtual std::chrono::milliseconds getHostFullRetryDelay() const 11099196688SMatt Spinler { 11199196688SMatt Spinler return _defaultHostFullRetryDelay; 11299196688SMatt Spinler } 11399196688SMatt Spinler 114e5f7508bSMatt Spinler /** 115e5f7508bSMatt Spinler * @brief Returns the amount of time to wait after the host is up 116e5f7508bSMatt Spinler * before sending commands. 117e5f7508bSMatt Spinler * 118e5f7508bSMatt Spinler * In this class to help with mocking. 119e5f7508bSMatt Spinler * 120e5f7508bSMatt Spinler * @return milliseconds - The amount of time to wait 121e5f7508bSMatt Spinler */ getHostUpDelay() const122e5f7508bSMatt Spinler virtual std::chrono::milliseconds getHostUpDelay() const 123e5f7508bSMatt Spinler { 124e5f7508bSMatt Spinler return _defaultHostUpDelay; 125e5f7508bSMatt Spinler } 126e5f7508bSMatt Spinler 12799196688SMatt Spinler using ResponseFunction = std::function<void(ResponseStatus)>; 12899196688SMatt Spinler 12999196688SMatt Spinler /** 13099196688SMatt Spinler * @brief Sets the function to call on the command receive. 13199196688SMatt Spinler * 13299196688SMatt Spinler * The success/failure status is passed to the function. 13399196688SMatt Spinler * 13499196688SMatt Spinler * @param[in] func - The callback function 13599196688SMatt Spinler */ setResponseFunction(ResponseFunction func)13699196688SMatt Spinler void setResponseFunction(ResponseFunction func) 13799196688SMatt Spinler { 13899196688SMatt Spinler _responseFunc = std::move(func); 13999196688SMatt Spinler } 14099196688SMatt Spinler 14199196688SMatt Spinler /** 142a44efe48SMatt Spinler * @brief Call the response function 143a44efe48SMatt Spinler * 144a44efe48SMatt Spinler * @param[in] status - The status given to the function 145a44efe48SMatt Spinler */ callResponseFunc(ResponseStatus status)146a44efe48SMatt Spinler void callResponseFunc(ResponseStatus status) 147a44efe48SMatt Spinler { 148a44efe48SMatt Spinler if (_responseFunc) 149a44efe48SMatt Spinler { 150a44efe48SMatt Spinler try 151a44efe48SMatt Spinler { 152a44efe48SMatt Spinler (*_responseFunc)(status); 153a44efe48SMatt Spinler } 154a44efe48SMatt Spinler catch (const std::exception& e) 155a44efe48SMatt Spinler { 1561b41886dSMatt Spinler lg2::error( 1571b41886dSMatt Spinler "Host iface response callback threw an exception: {EX}", 1581b41886dSMatt Spinler "EX", e); 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 */ getEvent()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 */ cmdInProgress() const18599196688SMatt 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 199*0387a74eSLakshmi Yadlapati * @param[in] transport - The transport data pointer 20099196688SMatt Spinler */ 201*0387a74eSLakshmi Yadlapati virtual void receive(sdeventplus::source::IO& io, int fd, uint32_t revents, 202*0387a74eSLakshmi Yadlapati pldm_transport* transport) = 0; 20399196688SMatt Spinler 20499196688SMatt Spinler /** 20599196688SMatt Spinler * @brief An optional function to call on a successful command response. 20699196688SMatt Spinler */ 20799196688SMatt Spinler std::optional<ResponseFunction> _responseFunc; 20899196688SMatt Spinler 20999196688SMatt Spinler /** 21099196688SMatt Spinler * @brief The sd_event wrapper object needed for response callbacks 21199196688SMatt Spinler */ 21299196688SMatt Spinler sdeventplus::Event _event; 21399196688SMatt Spinler 21499196688SMatt Spinler /** 21599196688SMatt Spinler * @brief The DataInterface object 21699196688SMatt Spinler */ 21799196688SMatt Spinler DataInterfaceBase& _dataIface; 21899196688SMatt Spinler 21999196688SMatt Spinler /** 22099196688SMatt Spinler * @brief Tracks status of after a command is sent and before the 22199196688SMatt Spinler * response is received. 22299196688SMatt Spinler */ 22399196688SMatt Spinler bool _inProgress = false; 22499196688SMatt Spinler 22599196688SMatt Spinler private: 22699196688SMatt Spinler /** 22799196688SMatt Spinler * @brief The default amount of time to wait before retrying 22899196688SMatt Spinler * a failed send. 22999196688SMatt Spinler */ 2303a4243a6SMatt Spinler const std::chrono::milliseconds _defaultSendRetryDelay{1000}; 23199196688SMatt Spinler 23299196688SMatt Spinler /** 23399196688SMatt Spinler * @brief The default amount of time to wait 23499196688SMatt Spinler * before retrying after a failed receive. 23599196688SMatt Spinler */ 23699196688SMatt Spinler const std::chrono::milliseconds _defaultReceiveRetryDelay{1000}; 23799196688SMatt Spinler 23899196688SMatt Spinler /** 23999196688SMatt Spinler * @brief The default amount of time to wait when the host said it 24099196688SMatt Spinler * was full before sending the PEL again. 24199196688SMatt Spinler */ 24299196688SMatt Spinler const std::chrono::milliseconds _defaultHostFullRetryDelay{60000}; 243e5f7508bSMatt Spinler 244e5f7508bSMatt Spinler /** 245e5f7508bSMatt Spinler * @brief The default amount of time to wait after the host is up 246e5f7508bSMatt Spinler * before sending up the PELs. 247e5f7508bSMatt Spinler */ 248e5f7508bSMatt Spinler const std::chrono::milliseconds _defaultHostUpDelay{60000}; 24999196688SMatt Spinler }; 25099196688SMatt Spinler 25199196688SMatt Spinler } // namespace pels 25299196688SMatt Spinler } // namespace openpower 253