xref: /openbmc/phosphor-logging/extensions/openpower-pels/host_interface.hpp (revision 0387a74ef17ca9ff30968dccf27769b79e711e70)
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