Implement HostEpoch set time logic
1. When setting host epoch, follow below logic:
Mode | Owner | Set Host Time
----- | ----- | -------------
NTP | BMC | Not allowed
NTP | HOST | Not allowed
NTP | SPLIT | OK, and just save offset
NTP | BOTH | Not allowed
MANUAL| BMC | Not allowed
MANUAL| HOST | OK, and set time to BMC
MANUAL| SPLIT | OK, and just save offset
MANUAL| BOTH | OK, and set time to BMC
2. If owner is SPLIT and BMC time is changed, update the offset accordinly;
3. Use timerfd to get notified on BMC time change, and update host time
diff accordingly;
4. Add unit test cases.
Change-Id: I2d60a821f7da9b689c579ae7ab672cc37967322c
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/bmc_epoch.hpp b/bmc_epoch.hpp
index 8c841a7..228a39d 100644
--- a/bmc_epoch.hpp
+++ b/bmc_epoch.hpp
@@ -1,12 +1,17 @@
#pragma once
+#include "bmc_time_change_listener.hpp"
#include "epoch_base.hpp"
+#include <chrono>
+
namespace phosphor
{
namespace time
{
+using namespace std::chrono;
+
/** @class BmcEpoch
* @brief OpenBMC BMC EpochTime implementation.
* @details A concrete implementation for xyz.openbmc_project.Time.EpochTime
@@ -18,6 +23,7 @@
friend class TestBmcEpoch;
BmcEpoch(sdbusplus::bus::bus& bus,
const char* objPath);
+ ~BmcEpoch();
/**
* @brief Get value of Elapsed property
@@ -33,6 +39,55 @@
* @return The updated elapsed microseconds since UTC
**/
uint64_t elapsed(uint64_t value) override;
+
+ /** @brief Set the listner for bmc time change
+ *
+ * @param[in] listener - The pointer to the listener
+ */
+ void setBmcTimeChangeListener(BmcTimeChangeListener* listener);
+
+ private:
+ /** @brief The fd for time change event */
+ int timeFd = -1;
+
+ /** @brief Initialize timerFd related resource */
+ void initialize();
+
+ /** @brief Notify the listeners that bmc time is changed
+ *
+ * @param[in] time - The epoch time in microseconds to notify
+ */
+ void notifyBmcTimeChange(const microseconds& time);
+
+ /** @brief The callback function on system time change
+ *
+ * @param[in] es - Source of the event
+ * @param[in] fd - File descriptor of the timer
+ * @param[in] revents - Not used
+ * @param[in] userdata - User data pointer
+ */
+ static int onTimeChange(sd_event_source* es, int fd,
+ uint32_t revents, void* userdata);
+
+ /** @brief The reference of sdbusplus bus */
+ sdbusplus::bus::bus& bus;
+
+ /** @brief The deleter of sd_event_source */
+ std::function<void(sd_event_source*)> sdEventSourceDeleter =
+ [] (sd_event_source* p) {
+ if (p)
+ {
+ sd_event_source_unref(p);
+ }
+ };
+ using SdEventSource = std::unique_ptr<sd_event_source,
+ decltype(sdEventSourceDeleter)>;
+
+ /** @brief The event source on system time change */
+ SdEventSource timeChangeEventSource {nullptr, sdEventSourceDeleter};
+
+ /** @brief The listener for bmc time change */
+ BmcTimeChangeListener* timeChangeListener = nullptr;
};
} // namespace time