blob: 34b04116de1df179a9ee735548bd0976ea7c9ac8 [file] [log] [blame]
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +05301#pragma once
2
William A. Kennington III73c2cfb2018-09-12 18:01:37 -07003#include <functional>
William A. Kennington III73c2cfb2018-09-12 18:01:37 -07004#include <optional>
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +05305#include <sdbusplus/bus.hpp>
6#include <sdbusplus/server/object.hpp>
William A. Kennington IIIf505fc02018-09-12 18:30:09 -07007#include <sdeventplus/event.hpp>
8#include <sdeventplus/utility/timer.hpp>
William A. Kennington III3bb2f402018-09-13 00:35:47 -07009#include <unordered_map>
William A. Kennington III73c2cfb2018-09-12 18:01:37 -070010#include <utility>
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053011#include <xyz/openbmc_project/State/Watchdog/server.hpp>
William A. Kennington III73c2cfb2018-09-12 18:01:37 -070012
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053013namespace phosphor
14{
15namespace watchdog
16{
William A. Kennington III3bb2f402018-09-13 00:35:47 -070017
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053018namespace Base = sdbusplus::xyz::openbmc_project::State::server;
19using WatchdogInherits = sdbusplus::server::object::object<Base::Watchdog>;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053020
21/** @class Watchdog
22 * @brief OpenBMC watchdog implementation.
23 * @details A concrete implementation for the
24 * xyz.openbmc_project.State.Watchdog DBus API.
25 */
26class Watchdog : public WatchdogInherits
27{
Patrick Venture8f6c5152018-09-11 17:45:33 -070028 public:
29 Watchdog() = delete;
30 ~Watchdog() = default;
31 Watchdog(const Watchdog&) = delete;
32 Watchdog& operator=(const Watchdog&) = delete;
33 Watchdog(Watchdog&&) = delete;
34 Watchdog& operator=(Watchdog&&) = delete;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053035
Patrick Venture8f6c5152018-09-11 17:45:33 -070036 /** @brief Type used to hold the name of a systemd target.
37 */
38 using TargetName = std::string;
William A. Kennington III1232a152018-02-02 15:57:34 -080039
William A. Kennington III3bb2f402018-09-13 00:35:47 -070040 /** @brief Type used to store the mapping of a Watchdog timeout
41 * action to a systemd target.
42 */
43 using ActionTargetMap = std::unordered_map<Action, TargetName>;
44
Patrick Venture8f6c5152018-09-11 17:45:33 -070045 /** @brief Type used to specify the parameters of a fallback watchdog
46 */
47 struct Fallback
48 {
49 Action action;
50 uint64_t interval;
51 bool always;
52 };
William A. Kennington IIId1331082018-02-27 18:47:05 -080053
Patrick Venture8f6c5152018-09-11 17:45:33 -070054 /** @brief Constructs the Watchdog object
55 *
William A. Kennington IIIf505fc02018-09-12 18:30:09 -070056 * @param[in] bus - DBus bus to attach to.
57 * @param[in] objPath - Object path to attach to.
58 * @param[in] event - reference to sdeventplus::Event loop
59 * @param[in] actionTargets - map of systemd targets called on timeout
Patrick Venture8f6c5152018-09-11 17:45:33 -070060 * @param[in] fallback
61 */
William A. Kennington IIIf505fc02018-09-12 18:30:09 -070062 Watchdog(sdbusplus::bus::bus& bus, const char* objPath,
63 const sdeventplus::Event& event,
William A. Kennington III3bb2f402018-09-13 00:35:47 -070064 ActionTargetMap&& actionTargetMap = {},
William A. Kennington III73c2cfb2018-09-12 18:01:37 -070065 std::optional<Fallback>&& fallback = std::nullopt) :
Patrick Venture8f6c5152018-09-11 17:45:33 -070066 WatchdogInherits(bus, objPath),
William A. Kennington III3bb2f402018-09-13 00:35:47 -070067 bus(bus), actionTargetMap(std::move(actionTargetMap)),
Patrick Venture8f6c5152018-09-11 17:45:33 -070068 fallback(std::move(fallback)),
69 timer(event, std::bind(&Watchdog::timeOutHandler, this))
70 {
71 // We need to poke the enable mechanism to make sure that the timer
72 // enters the fallback state if the fallback is always enabled.
73 tryFallbackOrDisable();
74 }
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053075
Patrick Venture8f6c5152018-09-11 17:45:33 -070076 /** @brief Resets the TimeRemaining to the configured Interval
77 * Optionally enables the watchdog.
78 *
79 * @param[in] enableWatchdog - Should the call enable the watchdog
80 */
81 void resetTimeRemaining(bool enableWatchdog) override;
William A. Kennington III1726df62018-04-23 10:28:28 -070082
Patrick Venture8f6c5152018-09-11 17:45:33 -070083 /** @brief Since we are overriding the setter-enabled but not the
84 * getter-enabled, we need to have this using in order to
85 * allow passthrough usage of the getter-enabled.
86 */
87 using Base::Watchdog::enabled;
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053088
Patrick Venture8f6c5152018-09-11 17:45:33 -070089 /** @brief Enable or disable watchdog
90 * If a watchdog state is changed from disable to enable,
91 * the watchdog timer is set with the default expiration
92 * interval and it starts counting down.
93 * If a watchdog is already enabled, setting @value to true
94 * has no effect.
95 *
96 * @param[in] value - 'true' to enable. 'false' to disable
97 *
98 * @return : applied value if success, previous value otherwise
99 */
100 bool enabled(bool value) override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530101
Patrick Venture8f6c5152018-09-11 17:45:33 -0700102 /** @brief Gets the remaining time before watchdog expires.
103 *
104 * @return 0 if watchdog is expired.
105 * Remaining time in milliseconds otherwise.
106 */
107 uint64_t timeRemaining() const override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530108
Patrick Venture8f6c5152018-09-11 17:45:33 -0700109 /** @brief Reset timer to expire after new timeout in milliseconds.
110 *
111 * @param[in] value - the time in milliseconds after which
112 * the watchdog will expire
113 *
114 * @return: updated timeout value if watchdog is enabled.
115 * 0 otherwise.
116 */
117 uint64_t timeRemaining(uint64_t value) override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530118
Patrick Venture8f6c5152018-09-11 17:45:33 -0700119 /** @brief Tells if the referenced timer is expired or not */
120 inline auto timerExpired() const
121 {
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700122 return timer.hasExpired();
Patrick Venture8f6c5152018-09-11 17:45:33 -0700123 }
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530124
Patrick Venture8f6c5152018-09-11 17:45:33 -0700125 /** @brief Tells if the timer is running or not */
126 inline bool timerEnabled() const
127 {
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700128 return timer.isEnabled();
Patrick Venture8f6c5152018-09-11 17:45:33 -0700129 }
William A. Kennington III0650a3f2018-03-01 10:53:25 -0800130
Patrick Venture8f6c5152018-09-11 17:45:33 -0700131 private:
132 /** @brief sdbusplus handle */
133 sdbusplus::bus::bus& bus;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530134
Patrick Venture8f6c5152018-09-11 17:45:33 -0700135 /** @brief Map of systemd units to be started when the timer expires */
William A. Kennington III3bb2f402018-09-13 00:35:47 -0700136 ActionTargetMap actionTargetMap;
Vishwanatha Subbanna3473d702017-05-30 16:38:50 +0530137
Patrick Venture8f6c5152018-09-11 17:45:33 -0700138 /** @brief Fallback timer options */
William A. Kennington III73c2cfb2018-09-12 18:01:37 -0700139 std::optional<Fallback> fallback;
William A. Kennington IIId1331082018-02-27 18:47:05 -0800140
Patrick Venture8f6c5152018-09-11 17:45:33 -0700141 /** @brief Contained timer object */
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700142 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +0530143
Patrick Venture8f6c5152018-09-11 17:45:33 -0700144 /** @brief Optional Callback handler on timer expirartion */
145 void timeOutHandler();
William A. Kennington III825f4982018-02-27 19:10:56 -0800146
Patrick Venture8f6c5152018-09-11 17:45:33 -0700147 /** @brief Attempt to enter the fallback watchdog or disables it */
148 void tryFallbackOrDisable();
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530149};
150
151} // namespace watchdog
152} // namespace phosphor