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