summaryrefslogtreecommitdiffstats
path: root/watchdog.hpp
blob: e829699ae021c43424af8af1eb8d7f86e0570499 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#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
OpenPOWER on IntegriCloud