blob: e829699ae021c43424af8af1eb8d7f86e0570499 [file] [log] [blame]
#pragma once
#include <systemd/sd-event.h>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/State/Watchdog/server.hpp>
#include "timer.hpp"
namespace phosphor
{
namespace watchdog
{
namespace Base = sdbusplus::xyz::openbmc_project::State::server;
using WatchdogInherits = sdbusplus::server::object::object<Base::Watchdog>;
/** @class Watchdog
* @brief OpenBMC watchdog implementation.
* @details A concrete implementation for the
* xyz.openbmc_project.State.Watchdog DBus API.
*/
class Watchdog : public WatchdogInherits
{
public:
Watchdog() = delete;
~Watchdog() = default;
Watchdog(const Watchdog&) = delete;
Watchdog& operator=(const Watchdog&) = delete;
Watchdog(Watchdog&&) = delete;
Watchdog& operator=(Watchdog &&) = delete;
/** @brief Type used to hold the name of a systemd target.
*/
using TargetName = std::string;
/** @brief Constructs the Watchdog object
*
* @param[in] bus - DBus bus to attach to.
* @param[in] objPath - Object path to attach to.
* @param[in] event - reference to sd_event unique pointer
* @param[in] actionTargets - map of systemd targets called on timeout
*/
Watchdog(sdbusplus::bus::bus& bus,
const char* objPath,
EventPtr& event,
std::map<Action, TargetName>&& actionTargets =
std::map<Action, TargetName>()) :
WatchdogInherits(bus, objPath),
bus(bus),
actionTargets(std::move(actionTargets)),
timer(event, std::bind(&Watchdog::timeOutHandler, this))
{
// Nothing
}
/** @brief Since we are overriding the setter-enabled but not the
* getter-enabled, we need to have this using in order to
* allow passthrough usage of the getter-enabled.
*/
using Base::Watchdog::enabled;
/** @brief Enable or disable watchdog
* If a watchdog state is changed from disable to enable,
* the watchdog timer is set with the default expiration
* interval and it starts counting down.
* If a watchdog is already enabled, setting @value to true
* has no effect.
*
* @param[in] value - 'true' to enable. 'false' to disable
*
* @return : applied value if success, previous value otherwise
*/
bool enabled(bool value) override;
/** @brief Gets the remaining time before watchdog expires.
*
* @return 0 if watchdog is disabled or expired.
* Remaining time in milliseconds otherwise.
*/
uint64_t timeRemaining() const override;
/** @brief Reset timer to expire after new timeout in milliseconds.
*
* @param[in] value - the time in milliseconds after which
* the watchdog will expire
*
* @return: updated timeout value if watchdog is enabled.
* 0 otherwise.
*/
uint64_t timeRemaining(uint64_t value) override;
/** @brief Tells if the referenced timer is expired or not */
inline auto timerExpired() const
{
return timer.expired();
}
/** @brief Tells if the timer is running or not */
inline bool timerEnabled() const
{
return timer.getEnabled() != SD_EVENT_OFF;
}
private:
/** @brief sdbusplus handle */
sdbusplus::bus::bus& bus;
/** @brief Map of systemd units to be started when the timer expires */
std::map<Action, TargetName> actionTargets;
/** @brief Contained timer object */
Timer timer;
/** @brief Optional Callback handler on timer expirartion */
void timeOutHandler();
};
} // namespace watchdog
} // namespace phosphor