xref: /openbmc/phosphor-time-manager/bmc_epoch.hpp (revision f1d54aec9f6e26b0809673298760c0b40d0137c4)
196232827SLei YU #pragma once
296232827SLei YU 
3*f1d54aecSGeorge Liu #include "manager.hpp"
4*f1d54aecSGeorge Liu #include "property_change_listener.hpp"
5*f1d54aecSGeorge Liu 
6*f1d54aecSGeorge Liu #include <sdbusplus/bus.hpp>
7*f1d54aecSGeorge Liu #include <xyz/openbmc_project/Time/EpochTime/server.hpp>
896232827SLei YU 
97b218796SLei YU #include <chrono>
107b218796SLei YU 
1196232827SLei YU namespace phosphor
1296232827SLei YU {
1396232827SLei YU namespace time
1496232827SLei YU {
1596232827SLei YU 
167b218796SLei YU using namespace std::chrono;
177b218796SLei YU 
18*f1d54aecSGeorge Liu using EpochTimeIntf = sdbusplus::server::object_t<
19*f1d54aecSGeorge Liu     sdbusplus::xyz::openbmc_project::Time::server::EpochTime>;
20*f1d54aecSGeorge Liu 
2196232827SLei YU /** @class BmcEpoch
2296232827SLei YU  *  @brief OpenBMC BMC EpochTime implementation.
23*f1d54aecSGeorge Liu  *  @details A concrete implementation for
24*f1d54aecSGeorge Liu  * xyz.openbmc_project.Time.EpochTime DBus API for BMC's epoch time.
2596232827SLei YU  */
26*f1d54aecSGeorge Liu class BmcEpoch : public EpochTimeIntf, public PropertyChangeListner
2796232827SLei YU {
2896232827SLei YU   public:
29*f1d54aecSGeorge Liu     BmcEpoch(sdbusplus::bus_t& bus, const char* objPath, Manager& manager) :
30*f1d54aecSGeorge Liu         EpochTimeIntf(bus, objPath), bus(bus), manager(manager)
31*f1d54aecSGeorge Liu     {
32*f1d54aecSGeorge Liu         initialize();
33*f1d54aecSGeorge Liu     }
34*f1d54aecSGeorge Liu 
357b218796SLei YU     ~BmcEpoch();
3696232827SLei YU 
37*f1d54aecSGeorge Liu     /** @brief Notified on time mode changed */
38*f1d54aecSGeorge Liu     void onModeChanged(Mode mode) override;
39*f1d54aecSGeorge Liu 
4096232827SLei YU     /**
4196232827SLei YU      * @brief Get value of Elapsed property
4296232827SLei YU      *
4396232827SLei YU      * @return The elapsed microseconds since UTC
4496232827SLei YU      **/
4596232827SLei YU     uint64_t elapsed() const override;
4696232827SLei YU 
4796232827SLei YU     /**
4896232827SLei YU      * @brief Set value of Elapsed property
4996232827SLei YU      *
5096232827SLei YU      * @param[in] value - The microseconds since UTC to set
5196232827SLei YU      * @return The updated elapsed microseconds since UTC
5296232827SLei YU      **/
5396232827SLei YU     uint64_t elapsed(uint64_t value) override;
547b218796SLei YU 
55*f1d54aecSGeorge Liu   protected:
56*f1d54aecSGeorge Liu     /** @brief Persistent sdbusplus DBus connection */
57*f1d54aecSGeorge Liu     sdbusplus::bus_t& bus;
58*f1d54aecSGeorge Liu 
59*f1d54aecSGeorge Liu     /** @brief The manager to handle OpenBMC time */
60*f1d54aecSGeorge Liu     Manager& manager;
61*f1d54aecSGeorge Liu 
62*f1d54aecSGeorge Liu     /** @brief Set current time to system
63*f1d54aecSGeorge Liu      *
64*f1d54aecSGeorge Liu      * This function set the time to system by invoking systemd
65*f1d54aecSGeorge Liu      * org.freedesktop.timedate1's SetTime method.
66*f1d54aecSGeorge Liu      *
67*f1d54aecSGeorge Liu      * @param[in] timeOfDayUsec - Microseconds since UTC
68*f1d54aecSGeorge Liu      *
69*f1d54aecSGeorge Liu      * @return true or false to indicate if it sets time successfully
70*f1d54aecSGeorge Liu      */
71*f1d54aecSGeorge Liu     bool setTime(const std::chrono::microseconds& timeOfDayUsec);
72*f1d54aecSGeorge Liu 
73*f1d54aecSGeorge Liu     /** @brief Get current time
74*f1d54aecSGeorge Liu      *
75*f1d54aecSGeorge Liu      * @return Microseconds since UTC
76*f1d54aecSGeorge Liu      */
77*f1d54aecSGeorge Liu     std::chrono::microseconds getTime() const;
78*f1d54aecSGeorge Liu 
797b218796SLei YU   private:
807b218796SLei YU     /** @brief The fd for time change event */
817b218796SLei YU     int timeFd = -1;
827b218796SLei YU 
837b218796SLei YU     /** @brief Initialize timerFd related resource */
847b218796SLei YU     void initialize();
857b218796SLei YU 
867b218796SLei YU     /** @brief The callback function on system time change
877b218796SLei YU      *
887b218796SLei YU      * @param[in] es - Source of the event
897b218796SLei YU      * @param[in] fd - File descriptor of the timer
907b218796SLei YU      * @param[in] revents - Not used
917b218796SLei YU      * @param[in] userdata - User data pointer
927b218796SLei YU      */
93ab4cc6a5SGunnar Mills     static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
94ab4cc6a5SGunnar Mills                             void* userdata);
957b218796SLei YU 
967b218796SLei YU     /** @brief The deleter of sd_event_source */
977b218796SLei YU     std::function<void(sd_event_source*)> sdEventSourceDeleter =
987b218796SLei YU         [](sd_event_source* p) {
997b218796SLei YU             if (p)
1007b218796SLei YU             {
1017b218796SLei YU                 sd_event_source_unref(p);
1027b218796SLei YU             }
1037b218796SLei YU         };
104ab4cc6a5SGunnar Mills     using SdEventSource =
105ab4cc6a5SGunnar Mills         std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;
1067b218796SLei YU 
1077b218796SLei YU     /** @brief The event source on system time change */
1087b218796SLei YU     SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};
10996232827SLei YU };
11096232827SLei YU 
111af5abc57SLei YU } // namespace time
112af5abc57SLei YU } // namespace phosphor
113