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