Host updater: implement GUARD factory reset

This commit extends the functionality of the host updater with a second
implementation of FactoryReset. This implementation is placed under the
/org/openpower/control/guard path and clears the PNOR GUARD partition.

Resolves openbmc/openbmc#2389

Change-Id: Id89aafe9211b48aee5238ff06b957fa7a99324ab
Signed-off-by: Michael Tritz <mtritz@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 502a8e0..05fbe00 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -32,6 +32,10 @@
                         "xyz.openbmc_project.State.Chassis.PowerState.Off";
 constexpr auto SYSTEMD_PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
 
+// TODO: Change paths once openbmc/openbmc#1663 is completed.
+constexpr auto MBOXD_INTERFACE = "org.openbmc.mboxd";
+constexpr auto MBOXD_PATH = "/org/openbmc/mboxd";
+
 void ItemUpdater::createActivation(sdbusplus::message::message& m)
 {
     using SVersion = server::Version;
@@ -608,6 +612,53 @@
     return target.substr(PNOR_RO_PREFIX_LEN);
 }
 
+void GardReset::reset()
+{
+    // The GARD partition is currently misspelled "GUARD." This file path will
+    // need to be updated in the future.
+    auto path = fs::path(PNOR_PRSV_ACTIVE_PATH);
+    path /= "GUARD";
+    std::vector<uint8_t> mboxdArgs;
+
+    auto dbusCall = bus.new_method_call(
+            MBOXD_INTERFACE,
+            MBOXD_PATH,
+            MBOXD_INTERFACE,
+            "cmd");
+
+    // Suspend mboxd - no args required.
+    dbusCall.append(static_cast<uint8_t>(3), mboxdArgs);
+
+    auto responseMsg = bus.call(dbusCall);
+    if (responseMsg.is_method_error())
+    {
+        log<level::ERR>("Error in mboxd suspend call");
+        elog<InternalFailure>();
+    }
+
+    if (fs::is_regular_file(path))
+    {
+        fs::remove(path);
+    }
+
+    dbusCall = bus.new_method_call(
+            MBOXD_INTERFACE,
+            MBOXD_PATH,
+            MBOXD_INTERFACE,
+            "cmd");
+
+    // Resume mboxd with arg 1, indicating that the flash is modified.
+    mboxdArgs.push_back(1);
+    dbusCall.append(static_cast<uint8_t>(4), mboxdArgs);
+
+    responseMsg = bus.call(dbusCall);
+    if (responseMsg.is_method_error())
+    {
+        log<level::ERR>("Error in mboxd resume call");
+        elog<InternalFailure>();
+    }
+}
+
 } // namespace updater
 } // namespace software
 } // namespace openpower