1 #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 12 namespace openpower 13 { 14 namespace pels 15 { 16 17 /** 18 * @brief Return codes from sending a command 19 */ 20 enum class CmdStatus 21 { 22 success, 23 failure 24 }; 25 26 /** 27 * @brief Return codes from the command response 28 */ 29 enum 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 */ 44 class 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 212