summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-12-11 15:02:20 -0600
committerMatt Spinler <spinler@us.ibm.com>2020-01-27 08:06:26 -0600
commitf869fcf81a23a8b80b110753d9c7ad8c2a3f60ae (patch)
treee5282d9601a46994621c957a8b7e8fbc0948e9f7 /extensions
parenta943b15b54861a0cb136a062eb822d0ba1362788 (diff)
downloadphosphor-logging-f869fcf81a23a8b80b110753d9c7ad8c2a3f60ae.tar.gz
phosphor-logging-f869fcf81a23a8b80b110753d9c7ad8c2a3f60ae.zip
PEL: Fill in host command response handler
If notifying the host of a new PEL was successful, then it will modify the PEL's host transmission state to 'sent' and add it to the list of sent PELs. If there was a failure, then a timer will be started so a retry can be done. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: I77000c603a18726d4cdbb3920ca349e69198fb7f
Diffstat (limited to 'extensions')
-rw-r--r--extensions/openpower-pels/host_notifier.cpp39
-rw-r--r--extensions/openpower-pels/host_notifier.hpp41
2 files changed, 79 insertions, 1 deletions
diff --git a/extensions/openpower-pels/host_notifier.cpp b/extensions/openpower-pels/host_notifier.cpp
index 2956b66..b935f7e 100644
--- a/extensions/openpower-pels/host_notifier.cpp
+++ b/extensions/openpower-pels/host_notifier.cpp
@@ -27,7 +27,9 @@ using namespace phosphor::logging;
HostNotifier::HostNotifier(Repository& repo, DataInterfaceBase& dataIface,
std::unique_ptr<HostInterface> hostIface) :
_repo(repo),
- _dataIface(dataIface), _hostIface(std::move(hostIface))
+ _dataIface(dataIface), _hostIface(std::move(hostIface)),
+ _retryTimer(_hostIface->getEvent(),
+ std::bind(std::mem_fn(&HostNotifier::retryTimerExpired), this))
{
// Subscribe to be told about new PELs.
_repo.subscribeToAdds(subscriptionName,
@@ -130,6 +132,41 @@ void HostNotifier::hostStateChange(bool hostUp)
void HostNotifier::commandResponse(ResponseStatus status)
{
+ auto id = _inProgressPEL;
+ _inProgressPEL = 0;
+
+ if (status == ResponseStatus::success)
+ {
+ _retryCount = 0;
+
+ _sentPELs.push_back(id);
+
+ _repo.setPELHostTransState(id, TransmissionState::sent);
+
+ if (!_pelQueue.empty())
+ {
+ doNewLogNotify();
+ }
+ }
+ else
+ {
+ log<level::ERR>("PLDM command response failure",
+ entry("PEL_ID=0x%X", id));
+ // Retry
+ _pelQueue.push_front(id);
+ _retryTimer.restartOnce(_hostIface->getReceiveRetryDelay());
+ }
+}
+
+void HostNotifier::retryTimerExpired()
+{
+ if (_dataIface.isHostUp())
+ {
+ log<level::INFO>("Attempting command retry",
+ entry("PEL_ID=0x%X", _pelQueue.front()));
+ _retryCount++;
+ doNewLogNotify();
+ }
}
} // namespace openpower::pels
diff --git a/extensions/openpower-pels/host_notifier.hpp b/extensions/openpower-pels/host_notifier.hpp
index 19ed64d..8436e06 100644
--- a/extensions/openpower-pels/host_notifier.hpp
+++ b/extensions/openpower-pels/host_notifier.hpp
@@ -5,6 +5,8 @@
#include "repository.hpp"
#include <deque>
+#include <sdeventplus/clock.hpp>
+#include <sdeventplus/utility/timer.hpp>
namespace openpower::pels
{
@@ -102,11 +104,26 @@ class HostNotifier
* @brief The callback function invoked after the asynchronous
* PLDM receive function is complete.
*
+ * If the command was successful, the state of that PEL will
+ * be set to 'sent', and the next send will be triggered.
+ *
+ * If the command failed, a retry timer will be started so it
+ * can be sent again.
+ *
* @param[in] status - The response status
*/
void commandResponse(ResponseStatus status);
/**
+ * @brief The function called when the command failure retry
+ * time is up.
+ *
+ * It will issue a send of the previous PEL and increment the
+ * retry count.
+ */
+ void retryTimerExpired();
+
+ /**
* @brief The PEL repository object
*/
Repository& _repo;
@@ -125,6 +142,30 @@ class HostNotifier
* @brief The list of PEL IDs that need to be sent.
*/
std::deque<uint32_t> _pelQueue;
+
+ /**
+ * @brief The list of IDs that were sent, but not acked yet.
+ *
+ * These move back to _pelQueue on a power off.
+ */
+ std::vector<uint32_t> _sentPELs;
+
+ /**
+ * @brief The ID the PEL where the notification has
+ * been kicked off but the asynchronous response
+ * hasn't been received yet.
+ */
+ uint32_t _inProgressPEL = 0;
+
+ /**
+ * @brief The command retry count
+ */
+ size_t _retryCount = 0;
+
+ /**
+ * @brief The command retry timer.
+ */
+ sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _retryTimer;
};
} // namespace openpower::pels
OpenPOWER on IntegriCloud