171230efdSCarol Wang #pragma once
271230efdSCarol Wang 
3e426b589SAndrew Geissler #include "config.h"
4e426b589SAndrew Geissler 
5e426b589SAndrew Geissler #include <sdbusplus/bus.hpp>
66a5db3d3SCarol Wang #include <sdeventplus/event.hpp>
76a5db3d3SCarol Wang #include <sdeventplus/utility/timer.hpp>
80c2432d9SPatrick Williams #include <xyz/openbmc_project/State/Host/server.hpp>
971230efdSCarol Wang #include <xyz/openbmc_project/State/ScheduledHostTransition/server.hpp>
1071230efdSCarol Wang 
114ca6f3f4SCarol Wang class TestScheduledHostTransition;
124ca6f3f4SCarol Wang 
1371230efdSCarol Wang namespace phosphor
1471230efdSCarol Wang {
1571230efdSCarol Wang namespace state
1671230efdSCarol Wang {
1771230efdSCarol Wang namespace manager
1871230efdSCarol Wang {
1971230efdSCarol Wang 
206a5db3d3SCarol Wang using Transition =
21*7e969cb9SPatrick Williams     sdbusplus::server::xyz::openbmc_project::state::Host::Transition;
22f053e6feSPatrick Williams using ScheduledHostTransitionInherit = sdbusplus::server::object_t<
23*7e969cb9SPatrick Williams     sdbusplus::server::xyz::openbmc_project::state::ScheduledHostTransition>;
2471230efdSCarol Wang 
2571230efdSCarol Wang /** @class ScheduledHostTransition
2671230efdSCarol Wang  *  @brief Scheduled host transition implementation.
2771230efdSCarol Wang  *  @details A concrete implementation for
2871230efdSCarol Wang  *  xyz.openbmc_project.State.ScheduledHostTransition
2971230efdSCarol Wang  */
3071230efdSCarol Wang class ScheduledHostTransition : public ScheduledHostTransitionInherit
3171230efdSCarol Wang {
3271230efdSCarol Wang   public:
ScheduledHostTransition(sdbusplus::bus_t & bus,const char * objPath,size_t id,const sdeventplus::Event & event)33f053e6feSPatrick Williams     ScheduledHostTransition(sdbusplus::bus_t& bus, const char* objPath,
34211d972dSPatrick Williams                             size_t id, const sdeventplus::Event& event) :
3576070747SPatrick Williams         ScheduledHostTransitionInherit(
3676070747SPatrick Williams             bus, objPath, ScheduledHostTransition::action::defer_emit),
37211d972dSPatrick Williams         bus(bus), id(id), event(event),
38bd28f025SWilliam A. Kennington III         timer(event, [this](auto&) { callback(); })
3971230efdSCarol Wang     {
40ef7abe19SCarol Wang         initialize();
411dbbef42SCarol Wang 
421dbbef42SCarol Wang         restoreScheduledValues();
431dbbef42SCarol Wang 
441dbbef42SCarol Wang         // We deferred this until we could get our property correct
451dbbef42SCarol Wang         this->emit_object_added();
4671230efdSCarol Wang     }
4771230efdSCarol Wang 
48ef7abe19SCarol Wang     ~ScheduledHostTransition();
4971230efdSCarol Wang 
5071230efdSCarol Wang     /**
5171230efdSCarol Wang      * @brief Handle with scheduled time
5271230efdSCarol Wang      *
5371230efdSCarol Wang      * @param[in] value - The seconds since epoch
5471230efdSCarol Wang      * @return The time for the transition. It is the same as the input value if
5571230efdSCarol Wang      * it is set successfully. Otherwise, it won't return value, but throw an
5671230efdSCarol Wang      * error.
5771230efdSCarol Wang      **/
5871230efdSCarol Wang     uint64_t scheduledTime(uint64_t value) override;
594ca6f3f4SCarol Wang 
604ca6f3f4SCarol Wang   private:
614ca6f3f4SCarol Wang     friend class TestScheduledHostTransition;
626a5db3d3SCarol Wang 
636a5db3d3SCarol Wang     /** @brief sdbusplus bus client connection */
64f053e6feSPatrick Williams     sdbusplus::bus_t& bus;
656a5db3d3SCarol Wang 
66211d972dSPatrick Williams     /** @brief Host id. **/
67211d972dSPatrick Williams     const size_t id = 0;
68211d972dSPatrick Williams 
69ef7abe19SCarol Wang     /** @brief sdbusplus event */
70ef7abe19SCarol Wang     const sdeventplus::Event& event;
71ef7abe19SCarol Wang 
726a5db3d3SCarol Wang     /** @brief Timer used for host transition with seconds */
736a5db3d3SCarol Wang     sdeventplus::utility::Timer<sdeventplus::ClockId::RealTime> timer;
746a5db3d3SCarol Wang 
75ef7abe19SCarol Wang     /** @brief The fd for time change event */
76ef7abe19SCarol Wang     int timeFd = -1;
77ef7abe19SCarol Wang 
784ca6f3f4SCarol Wang     /** @brief Get current time
794ca6f3f4SCarol Wang      *
804ca6f3f4SCarol Wang      *  @return - return current epoch time
814ca6f3f4SCarol Wang      */
824ca6f3f4SCarol Wang     std::chrono::seconds getTime();
836a5db3d3SCarol Wang 
846a5db3d3SCarol Wang     /** @brief Implement host transition
856a5db3d3SCarol Wang      *
866a5db3d3SCarol Wang      *  @return - Does not return anything. Error will result in exception
876a5db3d3SCarol Wang      *            being thrown
886a5db3d3SCarol Wang      */
896a5db3d3SCarol Wang     void hostTransition();
906a5db3d3SCarol Wang 
916a5db3d3SCarol Wang     /** @brief Used by the timer to do host transition */
926a5db3d3SCarol Wang     void callback();
93ef7abe19SCarol Wang 
94ef7abe19SCarol Wang     /** @brief Initialize timerFd related resource */
95ef7abe19SCarol Wang     void initialize();
96ef7abe19SCarol Wang 
97ef7abe19SCarol Wang     /** @brief The callback function on system time change
98ef7abe19SCarol Wang      *
99ef7abe19SCarol Wang      * @param[in] es - Source of the event
100ef7abe19SCarol Wang      * @param[in] fd - File descriptor of the timer
101ef7abe19SCarol Wang      * @param[in] revents - Not used
102ef7abe19SCarol Wang      * @param[in] userdata - User data pointer
103ef7abe19SCarol Wang      */
104ef7abe19SCarol Wang     static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
105ef7abe19SCarol Wang                             void* userdata);
106ef7abe19SCarol Wang 
107ef7abe19SCarol Wang     /** @brief The deleter of sd_event_source */
108ef7abe19SCarol Wang     std::function<void(sd_event_source*)> sdEventSourceDeleter =
__anon26d1c7f80202(sd_event_source* p) 109ef7abe19SCarol Wang         [](sd_event_source* p) {
110ef7abe19SCarol Wang         if (p)
111ef7abe19SCarol Wang         {
112ef7abe19SCarol Wang             sd_event_source_unref(p);
113ef7abe19SCarol Wang         }
114ef7abe19SCarol Wang     };
115ef7abe19SCarol Wang 
116ef7abe19SCarol Wang     using SdEventSource =
117ef7abe19SCarol Wang         std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;
118ef7abe19SCarol Wang 
119ef7abe19SCarol Wang     /** @brief The event source on system time change */
120ef7abe19SCarol Wang     SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};
121ef7abe19SCarol Wang 
122ef7abe19SCarol Wang     /** @brief Handle with the process when bmc time is changed*/
123ef7abe19SCarol Wang     void handleTimeUpdates();
1241dbbef42SCarol Wang 
1251dbbef42SCarol Wang     /** @brief Serialize the scheduled values */
1261dbbef42SCarol Wang     void serializeScheduledValues();
1271dbbef42SCarol Wang 
1281dbbef42SCarol Wang     /** @brief Deserialize the scheduled values
1291dbbef42SCarol Wang      *
1301dbbef42SCarol Wang      *  @param[out] time - Deserialized scheduled time
1311dbbef42SCarol Wang      *  @param[out] trans - Deserialized requested transition
1321dbbef42SCarol Wang      *
1331dbbef42SCarol Wang      *  @return bool - true if successful, false otherwise
1341dbbef42SCarol Wang      */
1351dbbef42SCarol Wang     bool deserializeScheduledValues(uint64_t& time, Transition& trans);
1361dbbef42SCarol Wang 
1371dbbef42SCarol Wang     /** @brief Restore scheduled time and requested transition from persisted
1381dbbef42SCarol Wang      * file */
1391dbbef42SCarol Wang     void restoreScheduledValues();
14071230efdSCarol Wang };
14171230efdSCarol Wang } // namespace manager
14271230efdSCarol Wang } // namespace state
14371230efdSCarol Wang } // namespace phosphor
144