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