171230efdSCarol Wang #pragma once
271230efdSCarol Wang 
371230efdSCarol Wang #include <sdbusplus/bus.hpp>
471230efdSCarol Wang #include <phosphor-logging/log.hpp>
56a5db3d3SCarol Wang #include <sdeventplus/event.hpp>
66a5db3d3SCarol Wang #include <sdeventplus/utility/timer.hpp>
771230efdSCarol Wang #include <xyz/openbmc_project/State/ScheduledHostTransition/server.hpp>
86a5db3d3SCarol Wang #include "config.h"
971230efdSCarol Wang 
104ca6f3f4SCarol Wang class TestScheduledHostTransition;
114ca6f3f4SCarol Wang 
1271230efdSCarol Wang namespace phosphor
1371230efdSCarol Wang {
1471230efdSCarol Wang namespace state
1571230efdSCarol Wang {
1671230efdSCarol Wang namespace manager
1771230efdSCarol Wang {
1871230efdSCarol Wang 
196a5db3d3SCarol Wang using Transition =
206a5db3d3SCarol Wang     sdbusplus::xyz::openbmc_project::State::server::Host::Transition;
2171230efdSCarol Wang using ScheduledHostTransitionInherit = sdbusplus::server::object::object<
2271230efdSCarol Wang     sdbusplus::xyz::openbmc_project::State::server::ScheduledHostTransition>;
2371230efdSCarol Wang 
2471230efdSCarol Wang /** @class ScheduledHostTransition
2571230efdSCarol Wang  *  @brief Scheduled host transition implementation.
2671230efdSCarol Wang  *  @details A concrete implementation for
2771230efdSCarol Wang  *  xyz.openbmc_project.State.ScheduledHostTransition
2871230efdSCarol Wang  */
2971230efdSCarol Wang class ScheduledHostTransition : public ScheduledHostTransitionInherit
3071230efdSCarol Wang {
3171230efdSCarol Wang   public:
326a5db3d3SCarol Wang     ScheduledHostTransition(sdbusplus::bus::bus& bus, const char* objPath,
336a5db3d3SCarol Wang                             const sdeventplus::Event& event) :
34*1dbbef42SCarol Wang         ScheduledHostTransitionInherit(bus, objPath, true),
35ef7abe19SCarol Wang         bus(bus), event(event),
366a5db3d3SCarol Wang         timer(event, std::bind(&ScheduledHostTransition::callback, this))
3771230efdSCarol Wang     {
38ef7abe19SCarol Wang         initialize();
39*1dbbef42SCarol Wang 
40*1dbbef42SCarol Wang         restoreScheduledValues();
41*1dbbef42SCarol Wang 
42*1dbbef42SCarol Wang         // We deferred this until we could get our property correct
43*1dbbef42SCarol Wang         this->emit_object_added();
4471230efdSCarol Wang     }
4571230efdSCarol Wang 
46ef7abe19SCarol Wang     ~ScheduledHostTransition();
4771230efdSCarol Wang 
4871230efdSCarol Wang     /**
4971230efdSCarol Wang      * @brief Handle with scheduled time
5071230efdSCarol Wang      *
5171230efdSCarol Wang      * @param[in] value - The seconds since epoch
5271230efdSCarol Wang      * @return The time for the transition. It is the same as the input value if
5371230efdSCarol Wang      * it is set successfully. Otherwise, it won't return value, but throw an
5471230efdSCarol Wang      * error.
5571230efdSCarol Wang      **/
5671230efdSCarol Wang     uint64_t scheduledTime(uint64_t value) override;
574ca6f3f4SCarol Wang 
584ca6f3f4SCarol Wang   private:
594ca6f3f4SCarol Wang     friend class TestScheduledHostTransition;
606a5db3d3SCarol Wang 
616a5db3d3SCarol Wang     /** @brief sdbusplus bus client connection */
626a5db3d3SCarol Wang     sdbusplus::bus::bus& bus;
636a5db3d3SCarol Wang 
64ef7abe19SCarol Wang     /** @brief sdbusplus event */
65ef7abe19SCarol Wang     const sdeventplus::Event& event;
66ef7abe19SCarol Wang 
676a5db3d3SCarol Wang     /** @brief Timer used for host transition with seconds */
686a5db3d3SCarol Wang     sdeventplus::utility::Timer<sdeventplus::ClockId::RealTime> timer;
696a5db3d3SCarol Wang 
70ef7abe19SCarol Wang     /** @brief The fd for time change event */
71ef7abe19SCarol Wang     int timeFd = -1;
72ef7abe19SCarol Wang 
734ca6f3f4SCarol Wang     /** @brief Get current time
744ca6f3f4SCarol Wang      *
754ca6f3f4SCarol Wang      *  @return - return current epoch time
764ca6f3f4SCarol Wang      */
774ca6f3f4SCarol Wang     std::chrono::seconds getTime();
786a5db3d3SCarol Wang 
796a5db3d3SCarol Wang     /** @brief Implement host transition
806a5db3d3SCarol Wang      *
816a5db3d3SCarol Wang      *  @return - Does not return anything. Error will result in exception
826a5db3d3SCarol Wang      *            being thrown
836a5db3d3SCarol Wang      */
846a5db3d3SCarol Wang     void hostTransition();
856a5db3d3SCarol Wang 
866a5db3d3SCarol Wang     /** @brief Used by the timer to do host transition */
876a5db3d3SCarol Wang     void callback();
88ef7abe19SCarol Wang 
89ef7abe19SCarol Wang     /** @brief Initialize timerFd related resource */
90ef7abe19SCarol Wang     void initialize();
91ef7abe19SCarol Wang 
92ef7abe19SCarol Wang     /** @brief The callback function on system time change
93ef7abe19SCarol Wang      *
94ef7abe19SCarol Wang      * @param[in] es - Source of the event
95ef7abe19SCarol Wang      * @param[in] fd - File descriptor of the timer
96ef7abe19SCarol Wang      * @param[in] revents - Not used
97ef7abe19SCarol Wang      * @param[in] userdata - User data pointer
98ef7abe19SCarol Wang      */
99ef7abe19SCarol Wang     static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
100ef7abe19SCarol Wang                             void* userdata);
101ef7abe19SCarol Wang 
102ef7abe19SCarol Wang     /** @brief The deleter of sd_event_source */
103ef7abe19SCarol Wang     std::function<void(sd_event_source*)> sdEventSourceDeleter =
104ef7abe19SCarol Wang         [](sd_event_source* p) {
105ef7abe19SCarol Wang             if (p)
106ef7abe19SCarol Wang             {
107ef7abe19SCarol Wang                 sd_event_source_unref(p);
108ef7abe19SCarol Wang             }
109ef7abe19SCarol Wang         };
110ef7abe19SCarol Wang 
111ef7abe19SCarol Wang     using SdEventSource =
112ef7abe19SCarol Wang         std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;
113ef7abe19SCarol Wang 
114ef7abe19SCarol Wang     /** @brief The event source on system time change */
115ef7abe19SCarol Wang     SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};
116ef7abe19SCarol Wang 
117ef7abe19SCarol Wang     /** @brief Handle with the process when bmc time is changed*/
118ef7abe19SCarol Wang     void handleTimeUpdates();
119*1dbbef42SCarol Wang 
120*1dbbef42SCarol Wang     /** @brief Serialize the scheduled values */
121*1dbbef42SCarol Wang     void serializeScheduledValues();
122*1dbbef42SCarol Wang 
123*1dbbef42SCarol Wang     /** @brief Deserialize the scheduled values
124*1dbbef42SCarol Wang      *
125*1dbbef42SCarol Wang      *  @param[out] time - Deserialized scheduled time
126*1dbbef42SCarol Wang      *  @param[out] trans - Deserialized requested transition
127*1dbbef42SCarol Wang      *
128*1dbbef42SCarol Wang      *  @return bool - true if successful, false otherwise
129*1dbbef42SCarol Wang      */
130*1dbbef42SCarol Wang     bool deserializeScheduledValues(uint64_t& time, Transition& trans);
131*1dbbef42SCarol Wang 
132*1dbbef42SCarol Wang     /** @brief Restore scheduled time and requested transition from persisted
133*1dbbef42SCarol Wang      * file */
134*1dbbef42SCarol Wang     void restoreScheduledValues();
13571230efdSCarol Wang };
13671230efdSCarol Wang } // namespace manager
13771230efdSCarol Wang } // namespace state
13871230efdSCarol Wang } // namespace phosphor
139