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