1 #pragma once
2 
3 #include "config.h"
4 
5 #include <sdbusplus/bus.hpp>
6 #include <sdeventplus/event.hpp>
7 #include <sdeventplus/utility/timer.hpp>
8 #include <xyz/openbmc_project/State/ScheduledHostTransition/server.hpp>
9 
10 class TestScheduledHostTransition;
11 
12 namespace phosphor
13 {
14 namespace state
15 {
16 namespace manager
17 {
18 
19 using Transition =
20     sdbusplus::xyz::openbmc_project::State::server::Host::Transition;
21 using ScheduledHostTransitionInherit = sdbusplus::server::object::object<
22     sdbusplus::xyz::openbmc_project::State::server::ScheduledHostTransition>;
23 
24 /** @class ScheduledHostTransition
25  *  @brief Scheduled host transition implementation.
26  *  @details A concrete implementation for
27  *  xyz.openbmc_project.State.ScheduledHostTransition
28  */
29 class ScheduledHostTransition : public ScheduledHostTransitionInherit
30 {
31   public:
32     ScheduledHostTransition(sdbusplus::bus::bus& bus, const char* objPath,
33                             const sdeventplus::Event& event) :
34         ScheduledHostTransitionInherit(bus, objPath, true),
35         bus(bus), event(event),
36         timer(event, std::bind(&ScheduledHostTransition::callback, this))
37     {
38         initialize();
39 
40         restoreScheduledValues();
41 
42         // We deferred this until we could get our property correct
43         this->emit_object_added();
44     }
45 
46     ~ScheduledHostTransition();
47 
48     /**
49      * @brief Handle with scheduled time
50      *
51      * @param[in] value - The seconds since epoch
52      * @return The time for the transition. It is the same as the input value if
53      * it is set successfully. Otherwise, it won't return value, but throw an
54      * error.
55      **/
56     uint64_t scheduledTime(uint64_t value) override;
57 
58   private:
59     friend class TestScheduledHostTransition;
60 
61     /** @brief sdbusplus bus client connection */
62     sdbusplus::bus::bus& bus;
63 
64     /** @brief sdbusplus event */
65     const sdeventplus::Event& event;
66 
67     /** @brief Timer used for host transition with seconds */
68     sdeventplus::utility::Timer<sdeventplus::ClockId::RealTime> timer;
69 
70     /** @brief The fd for time change event */
71     int timeFd = -1;
72 
73     /** @brief Get current time
74      *
75      *  @return - return current epoch time
76      */
77     std::chrono::seconds getTime();
78 
79     /** @brief Implement host transition
80      *
81      *  @return - Does not return anything. Error will result in exception
82      *            being thrown
83      */
84     void hostTransition();
85 
86     /** @brief Used by the timer to do host transition */
87     void callback();
88 
89     /** @brief Initialize timerFd related resource */
90     void initialize();
91 
92     /** @brief The callback function on system time change
93      *
94      * @param[in] es - Source of the event
95      * @param[in] fd - File descriptor of the timer
96      * @param[in] revents - Not used
97      * @param[in] userdata - User data pointer
98      */
99     static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
100                             void* userdata);
101 
102     /** @brief The deleter of sd_event_source */
103     std::function<void(sd_event_source*)> sdEventSourceDeleter =
104         [](sd_event_source* p) {
105             if (p)
106             {
107                 sd_event_source_unref(p);
108             }
109         };
110 
111     using SdEventSource =
112         std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;
113 
114     /** @brief The event source on system time change */
115     SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};
116 
117     /** @brief Handle with the process when bmc time is changed*/
118     void handleTimeUpdates();
119 
120     /** @brief Serialize the scheduled values */
121     void serializeScheduledValues();
122 
123     /** @brief Deserialize the scheduled values
124      *
125      *  @param[out] time - Deserialized scheduled time
126      *  @param[out] trans - Deserialized requested transition
127      *
128      *  @return bool - true if successful, false otherwise
129      */
130     bool deserializeScheduledValues(uint64_t& time, Transition& trans);
131 
132     /** @brief Restore scheduled time and requested transition from persisted
133      * file */
134     void restoreScheduledValues();
135 };
136 } // namespace manager
137 } // namespace state
138 } // namespace phosphor
139