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