summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-12-11 11:23:20 -0600
committerMatt Spinler <spinler@us.ibm.com>2020-01-27 08:06:26 -0600
commit99196688997f16d1611229e007a443d7e1a9f760 (patch)
treea83666573f1485abe87e469a2f196d933b9518d8
parentacb7c106a0ded9b9ef96e3c39ce573c919fb9425 (diff)
downloadphosphor-logging-99196688997f16d1611229e007a443d7e1a9f760.tar.gz
phosphor-logging-99196688997f16d1611229e007a443d7e1a9f760.zip
PEL: Add HostInterface base class
This is an abstract base class that is overridden to send a command to the host (such as a hypervisor) to notify it of new PELs. The only concrete implementation is using the 'New File Available' PLDM command. Using this base class allows the PLDM aspects to be mocked in testcases that involve queuing and sending PELs. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: I830298d0fd949b4268c31c83acafe2afd90dd4cb
-rw-r--r--extensions/openpower-pels/host_interface.hpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/extensions/openpower-pels/host_interface.hpp b/extensions/openpower-pels/host_interface.hpp
new file mode 100644
index 0000000..94c984a
--- /dev/null
+++ b/extensions/openpower-pels/host_interface.hpp
@@ -0,0 +1,211 @@
+#pragma once
+
+#include "data_interface.hpp"
+
+#include <stdint.h>
+
+#include <chrono>
+#include <functional>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/source/io.hpp>
+
+namespace openpower
+{
+namespace pels
+{
+
+/**
+ * @brief Return codes from sending a command
+ */
+enum class CmdStatus
+{
+ success,
+ failure
+};
+
+/**
+ * @brief Return codes from the command response
+ */
+enum class ResponseStatus
+{
+ success,
+ failure
+};
+
+/**
+ * @class HostInterface
+ *
+ * An abstract base class for sending the 'New PEL available' command
+ * to the host. Used so that the PLDM interfaces can be mocked for
+ * testing the HostNotifier code. The response to this command is
+ * asynchronous, with the intent that other code registers a callback
+ * function to run when the response is received.
+ */
+class HostInterface
+{
+ public:
+ HostInterface() = delete;
+ virtual ~HostInterface() = default;
+ HostInterface(const HostInterface&) = default;
+ HostInterface& operator=(const HostInterface&) = default;
+ HostInterface(HostInterface&&) = default;
+ HostInterface& operator=(HostInterface&&) = default;
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] event - The sd_event object pointer
+ * @param[in] dataIface - The DataInterface object
+ */
+ HostInterface(sd_event* event, DataInterfaceBase& dataIface) :
+ _event(event), _dataIface(dataIface)
+ {
+ }
+
+ /**
+ * @brief Pure virtual function for sending the 'new PEL available'
+ * asynchronous command to the host.
+ *
+ * @param[in] id - The ID of the new PEL
+ * @param[in] size - The size of the new PEL
+ *
+ * @return CmdStatus - If the send was successful or not
+ */
+ virtual CmdStatus sendNewLogCmd(uint32_t id, uint32_t size) = 0;
+
+ /**
+ * @brief Returns the amount of time to wait before retrying after
+ * a failed send command.
+ *
+ * @return milliseconds - The amount of time to wait
+ */
+ virtual std::chrono::milliseconds getSendRetryDelay() const
+ {
+ return _defaultSendRetryDelay;
+ }
+
+ /**
+ * @brief Returns the amount of time to wait before retrying after
+ * a command receive.
+ *
+ * @return milliseconds - The amount of time to wait
+ */
+ virtual std::chrono::milliseconds getReceiveRetryDelay() const
+ {
+ return _defaultReceiveRetryDelay;
+ }
+
+ /**
+ * @brief Returns the amount of time to wait before retrying if the
+ * host firmware's PEL storage was full and it can't store
+ * any more logs until it is freed up somehow.
+ *
+ * In this class to help with mocking.
+ *
+ * @return milliseconds - The amount of time to wait
+ */
+ virtual std::chrono::milliseconds getHostFullRetryDelay() const
+ {
+ return _defaultHostFullRetryDelay;
+ }
+
+ using ResponseFunction = std::function<void(ResponseStatus)>;
+
+ /**
+ * @brief Sets the function to call on the command receive.
+ *
+ * The success/failure status is passed to the function.
+ *
+ * @param[in] func - The callback function
+ */
+ void setResponseFunction(ResponseFunction func)
+ {
+ _responseFunc = std::move(func);
+ }
+
+ /**
+ * @brief Returns the event object in use
+ *
+ * @return sdeventplus::Event& - The event object
+ */
+ sdeventplus::Event& getEvent()
+ {
+ return _event;
+ }
+
+ /**
+ * @brief Pure virtual function to cancel an in-progress command
+ *
+ * 'In progress' means after the send but before the receive
+ */
+ virtual void cancelCmd() = 0;
+
+ /**
+ * @brief Says if the command is in progress (after send/before receive)
+ *
+ * @return bool - If command is in progress
+ */
+ bool cmdInProgress() const
+ {
+ return _inProgress;
+ }
+
+ protected:
+ /**
+ * @brief Pure virtual function for implementing the asynchronous
+ * command response callback.
+ *
+ * @param[in] io - The sdeventplus IO object that the callback is
+ * invoked from.
+ * @param[in] fd - The file descriptor being used
+ * @param[in] revents - The event status bits
+ */
+ virtual void receive(sdeventplus::source::IO& io, int fd,
+ uint32_t revents) = 0;
+
+ /**
+ * @brief An optional function to call on a successful command response.
+ */
+ std::optional<ResponseFunction> _responseFunc;
+
+ /**
+ * @brief The sd_event wrapper object needed for response callbacks
+ */
+ sdeventplus::Event _event;
+
+ /**
+ * @brief The DataInterface object
+ */
+ DataInterfaceBase& _dataIface;
+
+ /**
+ * @brief Tracks status of after a command is sent and before the
+ * response is received.
+ */
+ bool _inProgress = false;
+
+ private:
+ /**
+ * @brief The default amount of time to wait before retrying
+ * a failed send.
+ *
+ * It is this value for the case where all instance IDs are used
+ * and it takes this long in the PLDM daemon for them to reset.
+ */
+ const std::chrono::milliseconds _defaultSendRetryDelay{6000};
+
+ /**
+ * @brief The default amount of time to wait
+ * before retrying after a failed receive.
+ */
+ const std::chrono::milliseconds _defaultReceiveRetryDelay{1000};
+
+ /**
+ * @brief The default amount of time to wait when the host said it
+ * was full before sending the PEL again.
+ */
+ const std::chrono::milliseconds _defaultHostFullRetryDelay{60000};
+};
+
+} // namespace pels
+} // namespace openpower
OpenPOWER on IntegriCloud