xref: /openbmc/phosphor-time-manager/bmc_epoch.hpp (revision 06df65486f1c86276cc5da6812673bbb7642e1b5)
196232827SLei YU #pragma once
296232827SLei YU 
3f1d54aecSGeorge Liu #include "manager.hpp"
4f1d54aecSGeorge Liu #include "property_change_listener.hpp"
5f1d54aecSGeorge Liu 
6f1d54aecSGeorge Liu #include <sdbusplus/bus.hpp>
7f1d54aecSGeorge 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 
18f1d54aecSGeorge Liu using EpochTimeIntf = sdbusplus::server::object_t<
19f1d54aecSGeorge Liu     sdbusplus::xyz::openbmc_project::Time::server::EpochTime>;
20f1d54aecSGeorge Liu 
2196232827SLei YU /** @class BmcEpoch
2296232827SLei YU  *  @brief OpenBMC BMC EpochTime implementation.
23f1d54aecSGeorge Liu  *  @details A concrete implementation for
24f1d54aecSGeorge Liu  * xyz.openbmc_project.Time.EpochTime DBus API for BMC's epoch time.
2596232827SLei YU  */
26f1d54aecSGeorge Liu class BmcEpoch : public EpochTimeIntf, public PropertyChangeListner
2796232827SLei YU {
2896232827SLei YU   public:
29f1d54aecSGeorge Liu     BmcEpoch(sdbusplus::bus_t& bus, const char* objPath, Manager& manager) :
30f1d54aecSGeorge Liu         EpochTimeIntf(bus, objPath), bus(bus), manager(manager)
31f1d54aecSGeorge Liu     {
32f1d54aecSGeorge Liu         initialize();
33f1d54aecSGeorge Liu     }
34f1d54aecSGeorge Liu 
35f93c405fSPavithra Barithaya     ~BmcEpoch() override;
3696232827SLei YU 
37*06df6548SPavithra Barithaya     BmcEpoch(const BmcEpoch&) = delete;
38*06df6548SPavithra Barithaya     BmcEpoch(BmcEpoch&&) = delete;
39*06df6548SPavithra Barithaya     BmcEpoch& operator=(const BmcEpoch&) = delete;
40*06df6548SPavithra Barithaya     BmcEpoch& operator=(BmcEpoch&&) = delete;
41*06df6548SPavithra Barithaya 
42f1d54aecSGeorge Liu     /** @brief Notified on time mode changed */
43f1d54aecSGeorge Liu     void onModeChanged(Mode mode) override;
44f1d54aecSGeorge Liu 
4596232827SLei YU     /**
4696232827SLei YU      * @brief Get value of Elapsed property
4796232827SLei YU      *
4896232827SLei YU      * @return The elapsed microseconds since UTC
4996232827SLei YU      **/
5096232827SLei YU     uint64_t elapsed() const override;
5196232827SLei YU 
5296232827SLei YU     /**
5396232827SLei YU      * @brief Set value of Elapsed property
5496232827SLei YU      *
5596232827SLei YU      * @param[in] value - The microseconds since UTC to set
5696232827SLei YU      * @return The updated elapsed microseconds since UTC
5796232827SLei YU      **/
5896232827SLei YU     uint64_t elapsed(uint64_t value) override;
597b218796SLei YU 
60f1d54aecSGeorge Liu   protected:
61f1d54aecSGeorge Liu     /** @brief Persistent sdbusplus DBus connection */
62f1d54aecSGeorge Liu     sdbusplus::bus_t& bus;
63f1d54aecSGeorge Liu 
64f1d54aecSGeorge Liu     /** @brief The manager to handle OpenBMC time */
65f1d54aecSGeorge Liu     Manager& manager;
66f1d54aecSGeorge Liu 
67f1d54aecSGeorge Liu     /** @brief Set current time to system
68f1d54aecSGeorge Liu      *
69f1d54aecSGeorge Liu      * This function set the time to system by invoking systemd
70f1d54aecSGeorge Liu      * org.freedesktop.timedate1's SetTime method.
71f1d54aecSGeorge Liu      *
72f1d54aecSGeorge Liu      * @param[in] timeOfDayUsec - Microseconds since UTC
73f1d54aecSGeorge Liu      *
74f1d54aecSGeorge Liu      * @return true or false to indicate if it sets time successfully
75f1d54aecSGeorge Liu      */
76f1d54aecSGeorge Liu     bool setTime(const std::chrono::microseconds& timeOfDayUsec);
77f1d54aecSGeorge Liu 
78f1d54aecSGeorge Liu     /** @brief Get current time
79f1d54aecSGeorge Liu      *
80f1d54aecSGeorge Liu      * @return Microseconds since UTC
81f1d54aecSGeorge Liu      */
82864e173eSPavithra Barithaya     static std::chrono::microseconds getTime();
83f1d54aecSGeorge Liu 
847b218796SLei YU   private:
857b218796SLei YU     /** @brief The fd for time change event */
867b218796SLei YU     int timeFd = -1;
877b218796SLei YU 
887b218796SLei YU     /** @brief Initialize timerFd related resource */
897b218796SLei YU     void initialize();
907b218796SLei YU 
917b218796SLei YU     /** @brief The callback function on system time change
927b218796SLei YU      *
937b218796SLei YU      * @param[in] es - Source of the event
947b218796SLei YU      * @param[in] fd - File descriptor of the timer
957b218796SLei YU      * @param[in] revents - Not used
967b218796SLei YU      * @param[in] userdata - User data pointer
977b218796SLei YU      */
98ab4cc6a5SGunnar Mills     static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
99ab4cc6a5SGunnar Mills                             void* userdata);
1007b218796SLei YU 
1017b218796SLei YU     /** @brief The deleter of sd_event_source */
1027b218796SLei YU     std::function<void(sd_event_source*)> sdEventSourceDeleter =
1037b218796SLei YU         [](sd_event_source* p) {
1047b218796SLei YU             if (p)
1057b218796SLei YU             {
1067b218796SLei YU                 sd_event_source_unref(p);
1077b218796SLei YU             }
1087b218796SLei YU         };
109ab4cc6a5SGunnar Mills     using SdEventSource =
110ab4cc6a5SGunnar Mills         std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;
1117b218796SLei YU 
1127b218796SLei YU     /** @brief The event source on system time change */
1137b218796SLei YU     SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};
11496232827SLei YU };
11596232827SLei YU 
116af5abc57SLei YU } // namespace time
117af5abc57SLei YU } // namespace phosphor
118