diff options
author | Matt Spinler <spinler@us.ibm.com> | 2019-12-11 15:02:20 -0600 |
---|---|---|
committer | Matt Spinler <spinler@us.ibm.com> | 2020-01-27 08:06:26 -0600 |
commit | f869fcf81a23a8b80b110753d9c7ad8c2a3f60ae (patch) | |
tree | e5282d9601a46994621c957a8b7e8fbc0948e9f7 /extensions/openpower-pels | |
parent | a943b15b54861a0cb136a062eb822d0ba1362788 (diff) | |
download | phosphor-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/openpower-pels')
-rw-r--r-- | extensions/openpower-pels/host_notifier.cpp | 39 | ||||
-rw-r--r-- | extensions/openpower-pels/host_notifier.hpp | 41 |
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 |