1 #pragma once
2 
3 #include "manager.hpp"
4 #include "property_change_listener.hpp"
5 
6 #include <sdbusplus/bus.hpp>
7 #include <xyz/openbmc_project/Time/EpochTime/server.hpp>
8 
9 #include <chrono>
10 
11 namespace phosphor
12 {
13 namespace time
14 {
15 
16 using namespace std::chrono;
17 
18 using EpochTimeIntf = sdbusplus::server::object_t<
19     sdbusplus::xyz::openbmc_project::Time::server::EpochTime>;
20 
21 /** @class BmcEpoch
22  *  @brief OpenBMC BMC EpochTime implementation.
23  *  @details A concrete implementation for
24  * xyz.openbmc_project.Time.EpochTime DBus API for BMC's epoch time.
25  */
26 class BmcEpoch : public EpochTimeIntf, public PropertyChangeListner
27 {
28   public:
29     BmcEpoch(sdbusplus::bus_t& bus, const char* objPath, Manager& manager) :
30         EpochTimeIntf(bus, objPath), bus(bus), manager(manager)
31     {
32         initialize();
33     }
34 
35     ~BmcEpoch();
36 
37     /** @brief Notified on time mode changed */
38     void onModeChanged(Mode mode) override;
39 
40     /**
41      * @brief Get value of Elapsed property
42      *
43      * @return The elapsed microseconds since UTC
44      **/
45     uint64_t elapsed() const override;
46 
47     /**
48      * @brief Set value of Elapsed property
49      *
50      * @param[in] value - The microseconds since UTC to set
51      * @return The updated elapsed microseconds since UTC
52      **/
53     uint64_t elapsed(uint64_t value) override;
54 
55   protected:
56     /** @brief Persistent sdbusplus DBus connection */
57     sdbusplus::bus_t& bus;
58 
59     /** @brief The manager to handle OpenBMC time */
60     Manager& manager;
61 
62     /** @brief Set current time to system
63      *
64      * This function set the time to system by invoking systemd
65      * org.freedesktop.timedate1's SetTime method.
66      *
67      * @param[in] timeOfDayUsec - Microseconds since UTC
68      *
69      * @return true or false to indicate if it sets time successfully
70      */
71     bool setTime(const std::chrono::microseconds& timeOfDayUsec);
72 
73     /** @brief Get current time
74      *
75      * @return Microseconds since UTC
76      */
77     static std::chrono::microseconds getTime();
78 
79   private:
80     /** @brief The fd for time change event */
81     int timeFd = -1;
82 
83     /** @brief Initialize timerFd related resource */
84     void initialize();
85 
86     /** @brief The callback function on system time change
87      *
88      * @param[in] es - Source of the event
89      * @param[in] fd - File descriptor of the timer
90      * @param[in] revents - Not used
91      * @param[in] userdata - User data pointer
92      */
93     static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
94                             void* userdata);
95 
96     /** @brief The deleter of sd_event_source */
97     std::function<void(sd_event_source*)> sdEventSourceDeleter =
98         [](sd_event_source* p) {
99             if (p)
100             {
101                 sd_event_source_unref(p);
102             }
103         };
104     using SdEventSource =
105         std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;
106 
107     /** @brief The event source on system time change */
108     SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};
109 };
110 
111 } // namespace time
112 } // namespace phosphor
113