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