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