Add LastStateChangeTime to chassis manager

This property is set to the timestamp of the last time
the chassis power state changed.  It is persisted
so it survives reboots.

Resolves openbmc/openbmc#3300

Tested:  Various incantations of power cycling, reboots,
         and AC pulls.

Change-Id: I19f244e0490bc9b921454e393989a9cbd283e2dd
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/chassis_state_manager.hpp b/chassis_state_manager.hpp
index 5532949..9a6b647 100644
--- a/chassis_state_manager.hpp
+++ b/chassis_state_manager.hpp
@@ -61,6 +61,8 @@
     {
         subscribeToSystemdSignals();
 
+        restoreChassisStateChangeTime();
+
         determineInitialState();
 
         restorePOHCounter(); // restore POHCounter from persisted file
@@ -157,6 +159,35 @@
      */
     bool deserializePOH(const fs::path& path, uint32_t& retCounter);
 
+    /** @brief Sets the LastStateChangeTime property and persists it. */
+    void setStateChangeTime();
+
+    /** @brief Serialize the last power state change time.
+     *
+     *  Save the time the state changed and the state itself.
+     *  The state needs to be saved as well so that during rediscovery
+     *  on reboots there's a way to know not to update the time again.
+     */
+    void serializeStateChangeTime();
+
+    /** @brief Deserialize the last power state change time.
+     *
+     *  @param[out] time - Deserialized time
+     *  @param[out] state - Deserialized power state
+     *
+     *  @return bool - true if successful, false otherwise.
+     */
+    bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
+
+    /** @brief Restores the power state change time.
+     *
+     *  The time is loaded into the LastStateChangeTime D-Bus property.
+     *  On the very first start after this code has been applied but
+     *  before the state has changed, the LastStateChangeTime value
+     *  will be zero.
+     */
+    void restoreChassisStateChangeTime();
+
     /** @brief Timer */
     std::unique_ptr<phosphor::state::manager::Timer> timer;
 };