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