Manager: LastResetTime

Manager LastResetTime was added in Redfish release 2020.2.
It maps to LastRebootTime on D-Bus.

LastRebootTime on D-Bus is in epoch time, in milliseconds.
Redfish uses the ISO 8601 standard for dates.

Will be used on the OpenBMC GUI.

Tested: Validator passes.
curl -k https://$bmc/redfish/v1/Managers/bmc
...
  "LastResetTime": "2020-06-23T19:43:24+00:00",

Took the epoch time at state/bmc0/attr/LastRebootTime and verified
when converted it was the same.
GMT: Tuesday, June 23, 2020 7:43:24 PM

Change-Id: I55da7ad87ccd6021e4a8e7d522333941afe4084d
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index 756c75f..2ff65bf 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -1633,7 +1633,7 @@
                const std::vector<std::string>& params) override
     {
         res.jsonValue["@odata.id"] = "/redfish/v1/Managers/bmc";
-        res.jsonValue["@odata.type"] = "#Manager.v1_8_0.Manager";
+        res.jsonValue["@odata.type"] = "#Manager.v1_9_0.Manager";
         res.jsonValue["Id"] = "bmc";
         res.jsonValue["Name"] = "OpenBmc Manager";
         res.jsonValue["Description"] = "Baseboard Management Controller";
@@ -1712,6 +1712,8 @@
         fw_util::getActiveFwVersion(asyncResp, fw_util::bmcPurpose,
                                     "FirmwareVersion");
 
+        getLastResetTime(asyncResp);
+
         auto pids = std::make_shared<GetPIDValues>(asyncResp);
         pids->run();
 
@@ -1803,6 +1805,41 @@
         }
     }
 
+    void getLastResetTime(std::shared_ptr<AsyncResp> aResp)
+    {
+        BMCWEB_LOG_DEBUG << "Getting Manager Last Reset Time";
+
+        crow::connections::systemBus->async_method_call(
+            [aResp](const boost::system::error_code ec,
+                    std::variant<uint64_t>& lastResetTime) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
+                    return;
+                }
+
+                const uint64_t* lastResetTimePtr =
+                    std::get_if<uint64_t>(&lastResetTime);
+
+                if (!lastResetTimePtr)
+                {
+                    messages::internalError(aResp->res);
+                    return;
+                }
+                // LastRebootTime is epoch time, in milliseconds
+                // https://github.com/openbmc/phosphor-dbus-interfaces/blob/7f9a128eb9296e926422ddc312c148b625890bb6/xyz/openbmc_project/State/BMC.interface.yaml#L19
+                time_t lastResetTimeStamp =
+                    static_cast<time_t>(*lastResetTimePtr / 1000);
+
+                // Convert to ISO 8601 standard
+                aResp->res.jsonValue["LastResetTime"] =
+                    crow::utility::getDateTime(lastResetTimeStamp);
+            },
+            "xyz.openbmc_project.State.BMC", "/xyz/openbmc_project/state/bmc0",
+            "org.freedesktop.DBus.Properties", "Get",
+            "xyz.openbmc_project.State.BMC", "LastRebootTime");
+    }
+
     void setDateTime(std::shared_ptr<AsyncResp> aResp,
                      std::string datetime) const
     {