xref: /openbmc/phosphor-time-manager/bmc_epoch.hpp (revision c0e77cf805dbc85608b92ec593513f111619e5b8)
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 
16f1d54aecSGeorge Liu using EpochTimeIntf = sdbusplus::server::object_t<
17f1d54aecSGeorge Liu     sdbusplus::xyz::openbmc_project::Time::server::EpochTime>;
18f1d54aecSGeorge Liu 
1996232827SLei YU /** @class BmcEpoch
2096232827SLei YU  *  @brief OpenBMC BMC EpochTime implementation.
21f1d54aecSGeorge Liu  *  @details A concrete implementation for
22f1d54aecSGeorge Liu  * xyz.openbmc_project.Time.EpochTime DBus API for BMC's epoch time.
2396232827SLei YU  */
24f1d54aecSGeorge Liu class BmcEpoch : public EpochTimeIntf, public PropertyChangeListner
2596232827SLei YU {
2696232827SLei YU   public:
BmcEpoch(sdbusplus::bus_t & bus,const char * objPath,Manager & manager)27f1d54aecSGeorge Liu     BmcEpoch(sdbusplus::bus_t& bus, const char* objPath, Manager& manager) :
28f1d54aecSGeorge Liu         EpochTimeIntf(bus, objPath), bus(bus), manager(manager)
29f1d54aecSGeorge Liu     {
30f1d54aecSGeorge Liu         initialize();
31f1d54aecSGeorge Liu     }
32f1d54aecSGeorge Liu 
33f93c405fSPavithra Barithaya     ~BmcEpoch() override;
3496232827SLei YU 
35*06df6548SPavithra Barithaya     BmcEpoch(const BmcEpoch&) = delete;
36*06df6548SPavithra Barithaya     BmcEpoch(BmcEpoch&&) = delete;
37*06df6548SPavithra Barithaya     BmcEpoch& operator=(const BmcEpoch&) = delete;
38*06df6548SPavithra Barithaya     BmcEpoch& operator=(BmcEpoch&&) = delete;
39*06df6548SPavithra Barithaya 
40f1d54aecSGeorge Liu     /** @brief Notified on time mode changed */
41f1d54aecSGeorge Liu     void onModeChanged(Mode mode) override;
42f1d54aecSGeorge Liu 
4396232827SLei YU     /**
4496232827SLei YU      * @brief Get value of Elapsed property
4596232827SLei YU      *
4696232827SLei YU      * @return The elapsed microseconds since UTC
4796232827SLei YU      **/
4896232827SLei YU     uint64_t elapsed() const override;
4996232827SLei YU 
5096232827SLei YU     /**
5196232827SLei YU      * @brief Set value of Elapsed property
5296232827SLei YU      *
5396232827SLei YU      * @param[in] value - The microseconds since UTC to set
5496232827SLei YU      * @return The updated elapsed microseconds since UTC
5596232827SLei YU      **/
5696232827SLei YU     uint64_t elapsed(uint64_t value) override;
577b218796SLei YU 
58f1d54aecSGeorge Liu   protected:
59f1d54aecSGeorge Liu     /** @brief Persistent sdbusplus DBus connection */
60f1d54aecSGeorge Liu     sdbusplus::bus_t& bus;
61f1d54aecSGeorge Liu 
62f1d54aecSGeorge Liu     /** @brief The manager to handle OpenBMC time */
63f1d54aecSGeorge Liu     Manager& manager;
64f1d54aecSGeorge Liu 
65f1d54aecSGeorge Liu     /** @brief Set current time to system
66f1d54aecSGeorge Liu      *
67f1d54aecSGeorge Liu      * This function set the time to system by invoking systemd
68f1d54aecSGeorge Liu      * org.freedesktop.timedate1's SetTime method.
69f1d54aecSGeorge Liu      *
70f1d54aecSGeorge Liu      * @param[in] timeOfDayUsec - Microseconds since UTC
71f1d54aecSGeorge Liu      *
72f1d54aecSGeorge Liu      * @return true or false to indicate if it sets time successfully
73f1d54aecSGeorge Liu      */
74f1d54aecSGeorge Liu     bool setTime(const std::chrono::microseconds& timeOfDayUsec);
75f1d54aecSGeorge Liu 
76f1d54aecSGeorge Liu     /** @brief Get current time
77f1d54aecSGeorge Liu      *
78f1d54aecSGeorge Liu      * @return Microseconds since UTC
79f1d54aecSGeorge Liu      */
80864e173eSPavithra Barithaya     static std::chrono::microseconds getTime();
81f1d54aecSGeorge Liu 
827b218796SLei YU   private:
837b218796SLei YU     /** @brief The fd for time change event */
847b218796SLei YU     int timeFd = -1;
857b218796SLei YU 
867b218796SLei YU     /** @brief Initialize timerFd related resource */
877b218796SLei YU     void initialize();
887b218796SLei YU 
897b218796SLei YU     /** @brief The callback function on system time change
907b218796SLei YU      *
917b218796SLei YU      * @param[in] es - Source of the event
927b218796SLei YU      * @param[in] fd - File descriptor of the timer
937b218796SLei YU      * @param[in] revents - Not used
947b218796SLei YU      * @param[in] userdata - User data pointer
957b218796SLei YU      */
96ab4cc6a5SGunnar Mills     static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
97ab4cc6a5SGunnar Mills                             void* userdata);
987b218796SLei YU 
997b218796SLei YU     /** @brief The deleter of sd_event_source */
1007b218796SLei YU     std::function<void(sd_event_source*)> sdEventSourceDeleter =
__anon105726ce0102(sd_event_source* p) 1017b218796SLei YU         [](sd_event_source* p) {
1027b218796SLei YU             if (p)
1037b218796SLei YU             {
1047b218796SLei YU                 sd_event_source_unref(p);
1057b218796SLei YU             }
1067b218796SLei YU         };
107ab4cc6a5SGunnar Mills     using SdEventSource =
108ab4cc6a5SGunnar Mills         std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;
1097b218796SLei YU 
1107b218796SLei YU     /** @brief The event source on system time change */
1117b218796SLei YU     SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};
11296232827SLei YU };
11396232827SLei YU 
114af5abc57SLei YU } // namespace time
115af5abc57SLei YU } // namespace phosphor
116