diff options
Diffstat (limited to 'softoff')
-rw-r--r-- | softoff/softoff.cpp | 12 | ||||
-rw-r--r-- | softoff/timer.cpp | 50 | ||||
-rw-r--r-- | softoff/timer.hpp | 13 |
3 files changed, 71 insertions, 4 deletions
diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp index 11298ab..49b6f26 100644 --- a/softoff/softoff.cpp +++ b/softoff/softoff.cpp @@ -13,7 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include <chrono> +#include <phosphor-logging/log.hpp> #include "softoff.hpp" +#include "config.h" namespace phosphor { namespace ipmi @@ -22,6 +25,7 @@ namespace ipmi /** @brief Send the SMS_ATN to host if value is set */ void SoftPowerOff::sendSMSAttn() { + using namespace std::chrono; auto method = bus.new_method_call(HOST_IPMI_BUS, HOST_IPMI_OBJ, HOST_IPMI_INTF, @@ -31,6 +35,14 @@ void SoftPowerOff::sendSMSAttn() // BT returns '0' on success and bus_error on failure. bus.call_noreply(method); + // Start the timer + auto time = duration_cast<microseconds>( + seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS)); + auto r = timer.startTimer(time); + if (r < 0) + { + throw std::runtime_error("Error starting timer"); + } return; } diff --git a/softoff/timer.cpp b/softoff/timer.cpp index 9e722f1..c626536 100644 --- a/softoff/timer.cpp +++ b/softoff/timer.cpp @@ -1,3 +1,4 @@ +#include <chrono> #include <phosphor-logging/log.hpp> #include "timer.hpp" namespace phosphor @@ -19,7 +20,7 @@ void Timer::initialize() // Add infinite expiration time auto r = sd_event_add_time(timeEvent, &eventSource, CLOCK_MONOTONIC, // Time base - UINT64_MAX, // Expire time - way long enough time + UINT64_MAX, // Expire time - way long time 0, // Use default event accuracy timeoutHandler, // Callback handler on timeout this); // User data @@ -32,13 +33,13 @@ void Timer::initialize() } // Disable the timer for now - r = sd_event_source_set_enabled(eventSource, SD_EVENT_OFF); + r = setTimer(SD_EVENT_OFF); if (r < 0) { log<level::ERR>("Failure to disable timer", entry("ERROR=%s", strerror(-r))); - throw std::runtime_error("Setting initial timer value failed"); + throw std::runtime_error("Disabling the timer failed"); } return; } @@ -54,5 +55,48 @@ int Timer::timeoutHandler(sd_event_source* eventSource, return 0; } +// Gets the time from steady_clock +std::chrono::microseconds Timer::getTime() +{ + using namespace std::chrono; + auto usec = steady_clock::now().time_since_epoch(); + return duration_cast<microseconds>(usec); +} + +// Enables or disables the timer +int Timer::setTimer(int action) +{ + return sd_event_source_set_enabled(eventSource, action); +} + +// Sets the time and arms the timer +int Timer::startTimer(std::chrono::microseconds timeValue) +{ + // Disable the timer + setTimer(SD_EVENT_OFF); + + // Get the current MONOTONIC time and add the delta + auto expireTime = getTime() + timeValue; + + // Set the time + auto r = sd_event_source_set_time(eventSource, expireTime.count()); + if (r < 0) + { + log<level::ERR>("Failure to set timer", + entry("ERROR=%s", strerror(-r))); + return r; + } + + // A ONESHOT timer means that when the timer goes off, + // its moves to disabled state. + r = setTimer(SD_EVENT_ONESHOT); + if (r < 0) + { + log<level::ERR>("Failure to start timer", + entry("ERROR=%s", strerror(-r))); + } + return r; +} + } // namespace ipmi } // namespace phosphor diff --git a/softoff/timer.hpp b/softoff/timer.hpp index 7c3bac2..9d597f8 100644 --- a/softoff/timer.hpp +++ b/softoff/timer.hpp @@ -38,11 +38,19 @@ class Timer } } - inline auto isExpired() + inline auto isExpired() const { return expired; } + /** @brief Starts the timer with specified expiration value. + * input is an offset from the current steady_clock + */ + int startTimer(std::chrono::microseconds usec); + + /** @brief Enables / disables the timer */ + int setTimer(int action); + private: /** @brief the sd_event structure */ sd_event* timeEvent = nullptr; @@ -76,6 +84,9 @@ class Timer */ static int timeoutHandler(sd_event_source* eventSource, uint64_t usec, void* userData); + + /** @brief Gets the current time from steady clock */ + static std::chrono::microseconds getTime(); }; } // namespace ipmi |