xref: /openbmc/phosphor-logging/extensions/openpower-pels/host_interface.hpp (revision 99196688997f16d1611229e007a443d7e1a9f760)
1*99196688SMatt Spinler #pragma once
2*99196688SMatt Spinler 
3*99196688SMatt Spinler #include "data_interface.hpp"
4*99196688SMatt Spinler 
5*99196688SMatt Spinler #include <stdint.h>
6*99196688SMatt Spinler 
7*99196688SMatt Spinler #include <chrono>
8*99196688SMatt Spinler #include <functional>
9*99196688SMatt Spinler #include <sdeventplus/event.hpp>
10*99196688SMatt Spinler #include <sdeventplus/source/io.hpp>
11*99196688SMatt Spinler 
12*99196688SMatt Spinler namespace openpower
13*99196688SMatt Spinler {
14*99196688SMatt Spinler namespace pels
15*99196688SMatt Spinler {
16*99196688SMatt Spinler 
17*99196688SMatt Spinler /**
18*99196688SMatt Spinler  * @brief Return codes from sending a command
19*99196688SMatt Spinler  */
20*99196688SMatt Spinler enum class CmdStatus
21*99196688SMatt Spinler {
22*99196688SMatt Spinler     success,
23*99196688SMatt Spinler     failure
24*99196688SMatt Spinler };
25*99196688SMatt Spinler 
26*99196688SMatt Spinler /**
27*99196688SMatt Spinler  * @brief Return codes from the command response
28*99196688SMatt Spinler  */
29*99196688SMatt Spinler enum class ResponseStatus
30*99196688SMatt Spinler {
31*99196688SMatt Spinler     success,
32*99196688SMatt Spinler     failure
33*99196688SMatt Spinler };
34*99196688SMatt Spinler 
35*99196688SMatt Spinler /**
36*99196688SMatt Spinler  * @class HostInterface
37*99196688SMatt Spinler  *
38*99196688SMatt Spinler  * An abstract base class for sending the 'New PEL available' command
39*99196688SMatt Spinler  * to the host.  Used so that the PLDM interfaces can be mocked for
40*99196688SMatt Spinler  * testing the HostNotifier code.  The response to this command is
41*99196688SMatt Spinler  * asynchronous, with the intent that other code registers a callback
42*99196688SMatt Spinler  * function to run when the response is received.
43*99196688SMatt Spinler  */
44*99196688SMatt Spinler class HostInterface
45*99196688SMatt Spinler {
46*99196688SMatt Spinler   public:
47*99196688SMatt Spinler     HostInterface() = delete;
48*99196688SMatt Spinler     virtual ~HostInterface() = default;
49*99196688SMatt Spinler     HostInterface(const HostInterface&) = default;
50*99196688SMatt Spinler     HostInterface& operator=(const HostInterface&) = default;
51*99196688SMatt Spinler     HostInterface(HostInterface&&) = default;
52*99196688SMatt Spinler     HostInterface& operator=(HostInterface&&) = default;
53*99196688SMatt Spinler 
54*99196688SMatt Spinler     /**
55*99196688SMatt Spinler      * @brief Constructor
56*99196688SMatt Spinler      *
57*99196688SMatt Spinler      * @param[in] event - The sd_event object pointer
58*99196688SMatt Spinler      * @param[in] dataIface - The DataInterface object
59*99196688SMatt Spinler      */
60*99196688SMatt Spinler     HostInterface(sd_event* event, DataInterfaceBase& dataIface) :
61*99196688SMatt Spinler         _event(event), _dataIface(dataIface)
62*99196688SMatt Spinler     {
63*99196688SMatt Spinler     }
64*99196688SMatt Spinler 
65*99196688SMatt Spinler     /**
66*99196688SMatt Spinler      * @brief Pure virtual function for sending the 'new PEL available'
67*99196688SMatt Spinler      *        asynchronous command to the host.
68*99196688SMatt Spinler      *
69*99196688SMatt Spinler      * @param[in] id - The ID of the new PEL
70*99196688SMatt Spinler      * @param[in] size - The size of the new PEL
71*99196688SMatt Spinler      *
72*99196688SMatt Spinler      * @return CmdStatus - If the send was successful or not
73*99196688SMatt Spinler      */
74*99196688SMatt Spinler     virtual CmdStatus sendNewLogCmd(uint32_t id, uint32_t size) = 0;
75*99196688SMatt Spinler 
76*99196688SMatt Spinler     /**
77*99196688SMatt Spinler      * @brief Returns the amount of time to wait before retrying after
78*99196688SMatt Spinler      *        a failed send command.
79*99196688SMatt Spinler      *
80*99196688SMatt Spinler      * @return milliseconds - The amount of time to wait
81*99196688SMatt Spinler      */
82*99196688SMatt Spinler     virtual std::chrono::milliseconds getSendRetryDelay() const
83*99196688SMatt Spinler     {
84*99196688SMatt Spinler         return _defaultSendRetryDelay;
85*99196688SMatt Spinler     }
86*99196688SMatt Spinler 
87*99196688SMatt Spinler     /**
88*99196688SMatt Spinler      * @brief Returns the amount of time to wait before retrying after
89*99196688SMatt Spinler      *        a command receive.
90*99196688SMatt Spinler      *
91*99196688SMatt Spinler      * @return milliseconds - The amount of time to wait
92*99196688SMatt Spinler      */
93*99196688SMatt Spinler     virtual std::chrono::milliseconds getReceiveRetryDelay() const
94*99196688SMatt Spinler     {
95*99196688SMatt Spinler         return _defaultReceiveRetryDelay;
96*99196688SMatt Spinler     }
97*99196688SMatt Spinler 
98*99196688SMatt Spinler     /**
99*99196688SMatt Spinler      * @brief Returns the amount of time to wait before retrying if the
100*99196688SMatt Spinler      *        host firmware's PEL storage was full and it can't store
101*99196688SMatt Spinler      *        any more logs until it is freed up somehow.
102*99196688SMatt Spinler      *
103*99196688SMatt Spinler      * In this class to help with mocking.
104*99196688SMatt Spinler      *
105*99196688SMatt Spinler      * @return milliseconds - The amount of time to wait
106*99196688SMatt Spinler      */
107*99196688SMatt Spinler     virtual std::chrono::milliseconds getHostFullRetryDelay() const
108*99196688SMatt Spinler     {
109*99196688SMatt Spinler         return _defaultHostFullRetryDelay;
110*99196688SMatt Spinler     }
111*99196688SMatt Spinler 
112*99196688SMatt Spinler     using ResponseFunction = std::function<void(ResponseStatus)>;
113*99196688SMatt Spinler 
114*99196688SMatt Spinler     /**
115*99196688SMatt Spinler      * @brief Sets the function to call on the command receive.
116*99196688SMatt Spinler      *
117*99196688SMatt Spinler      * The success/failure status is passed to the function.
118*99196688SMatt Spinler      *
119*99196688SMatt Spinler      * @param[in] func - The callback function
120*99196688SMatt Spinler      */
121*99196688SMatt Spinler     void setResponseFunction(ResponseFunction func)
122*99196688SMatt Spinler     {
123*99196688SMatt Spinler         _responseFunc = std::move(func);
124*99196688SMatt Spinler     }
125*99196688SMatt Spinler 
126*99196688SMatt Spinler     /**
127*99196688SMatt Spinler      * @brief Returns the event object in use
128*99196688SMatt Spinler      *
129*99196688SMatt Spinler      * @return sdeventplus::Event& - The event object
130*99196688SMatt Spinler      */
131*99196688SMatt Spinler     sdeventplus::Event& getEvent()
132*99196688SMatt Spinler     {
133*99196688SMatt Spinler         return _event;
134*99196688SMatt Spinler     }
135*99196688SMatt Spinler 
136*99196688SMatt Spinler     /**
137*99196688SMatt Spinler      * @brief Pure virtual function to cancel an in-progress command
138*99196688SMatt Spinler      *
139*99196688SMatt Spinler      * 'In progress' means after the send but before the receive
140*99196688SMatt Spinler      */
141*99196688SMatt Spinler     virtual void cancelCmd() = 0;
142*99196688SMatt Spinler 
143*99196688SMatt Spinler     /**
144*99196688SMatt Spinler      * @brief Says if the command is in progress (after send/before receive)
145*99196688SMatt Spinler      *
146*99196688SMatt Spinler      * @return bool - If command is in progress
147*99196688SMatt Spinler      */
148*99196688SMatt Spinler     bool cmdInProgress() const
149*99196688SMatt Spinler     {
150*99196688SMatt Spinler         return _inProgress;
151*99196688SMatt Spinler     }
152*99196688SMatt Spinler 
153*99196688SMatt Spinler   protected:
154*99196688SMatt Spinler     /**
155*99196688SMatt Spinler      * @brief Pure virtual function for implementing the asynchronous
156*99196688SMatt Spinler      *        command response callback.
157*99196688SMatt Spinler      *
158*99196688SMatt Spinler      * @param[in] io - The sdeventplus IO object that the callback is
159*99196688SMatt Spinler      *                 invoked from.
160*99196688SMatt Spinler      * @param[in] fd - The file descriptor being used
161*99196688SMatt Spinler      * @param[in] revents - The event status bits
162*99196688SMatt Spinler      */
163*99196688SMatt Spinler     virtual void receive(sdeventplus::source::IO& io, int fd,
164*99196688SMatt Spinler                          uint32_t revents) = 0;
165*99196688SMatt Spinler 
166*99196688SMatt Spinler     /**
167*99196688SMatt Spinler      * @brief An optional function to call on a successful command response.
168*99196688SMatt Spinler      */
169*99196688SMatt Spinler     std::optional<ResponseFunction> _responseFunc;
170*99196688SMatt Spinler 
171*99196688SMatt Spinler     /**
172*99196688SMatt Spinler      * @brief The sd_event wrapper object needed for response callbacks
173*99196688SMatt Spinler      */
174*99196688SMatt Spinler     sdeventplus::Event _event;
175*99196688SMatt Spinler 
176*99196688SMatt Spinler     /**
177*99196688SMatt Spinler      * @brief The DataInterface object
178*99196688SMatt Spinler      */
179*99196688SMatt Spinler     DataInterfaceBase& _dataIface;
180*99196688SMatt Spinler 
181*99196688SMatt Spinler     /**
182*99196688SMatt Spinler      * @brief Tracks status of after a command is sent and before the
183*99196688SMatt Spinler      *        response is received.
184*99196688SMatt Spinler      */
185*99196688SMatt Spinler     bool _inProgress = false;
186*99196688SMatt Spinler 
187*99196688SMatt Spinler   private:
188*99196688SMatt Spinler     /**
189*99196688SMatt Spinler      * @brief The default amount of time to wait before retrying
190*99196688SMatt Spinler      *        a failed send.
191*99196688SMatt Spinler      *
192*99196688SMatt Spinler      * It is this value for the case where all instance IDs are used
193*99196688SMatt Spinler      * and it takes this long in the PLDM daemon for them to reset.
194*99196688SMatt Spinler      */
195*99196688SMatt Spinler     const std::chrono::milliseconds _defaultSendRetryDelay{6000};
196*99196688SMatt Spinler 
197*99196688SMatt Spinler     /**
198*99196688SMatt Spinler      * @brief The default amount of time to wait
199*99196688SMatt Spinler      *        before retrying after a failed receive.
200*99196688SMatt Spinler      */
201*99196688SMatt Spinler     const std::chrono::milliseconds _defaultReceiveRetryDelay{1000};
202*99196688SMatt Spinler 
203*99196688SMatt Spinler     /**
204*99196688SMatt Spinler      * @brief The default amount of time to wait when the host said it
205*99196688SMatt Spinler      *        was full before sending the PEL again.
206*99196688SMatt Spinler      */
207*99196688SMatt Spinler     const std::chrono::milliseconds _defaultHostFullRetryDelay{60000};
208*99196688SMatt Spinler };
209*99196688SMatt Spinler 
210*99196688SMatt Spinler } // namespace pels
211*99196688SMatt Spinler } // namespace openpower
212