boot settings: use the new 'one time' setting

Resolves openbmc/openbmc#2301

Change-Id: I7682de2eb1f1dc224e136735af978921bf76a12f
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/settings.cpp b/settings.cpp
index 59f9f33..f2f66a9 100644
--- a/settings.cpp
+++ b/settings.cpp
@@ -90,4 +90,57 @@
     return result.begin()->first;
 }
 
+namespace boot
+{
+
+std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
+                                         const Interface& iface)
+{
+    constexpr auto bootObjCount = 2;
+    constexpr auto oneTime = "one_time";
+    constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable";
+    constexpr auto propIntf = "org.freedesktop.DBus.Properties";
+
+    const std::vector<Path>& paths = objects.map.at(iface);
+    auto count = paths.size();
+    if (count != bootObjCount)
+    {
+        log<level::ERR>("Exactly two objects expected",
+                        entry("INTERFACE=%s", iface.c_str()),
+                        entry("COUNT=%d", count));
+        elog<InternalFailure>();
+    }
+    size_t index = 0;
+    if (std::string::npos == paths[0].rfind(oneTime))
+    {
+        index = 1;
+    }
+    const Path& oneTimeSetting = paths[index];
+    const Path& regularSetting = paths[!index];
+
+    auto method =
+        objects.bus.new_method_call(
+            objects.service(oneTimeSetting, iface).c_str(),
+            oneTimeSetting.c_str(),
+            propIntf,
+            "Get");
+    method.append(enabledIntf, "Enabled");
+    auto reply = objects.bus.call(method);
+    if (reply.is_method_error())
+    {
+        log<level::ERR>("Error in getting Enabled property",
+                        entry("OBJECT=%s", oneTimeSetting.c_str()),
+                        entry("INTERFACE=%s", iface.c_str()));
+        elog<InternalFailure>();
+    }
+
+    sdbusplus::message::variant<bool> enabled;
+    reply.read(enabled);
+    auto oneTimeEnabled = enabled.get<bool>();
+    const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting;
+    return std::make_tuple(setting, oneTimeEnabled);
+}
+
+} // namespace boot
+
 } // namespace settings
diff --git a/settings.hpp b/settings.hpp
index ec1d913..91c9930 100644
--- a/settings.hpp
+++ b/settings.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <string>
+#include <tuple>
 #include <sdbusplus/bus.hpp>
 
 namespace settings
@@ -49,4 +50,23 @@
         sdbusplus::bus::bus& bus;
 };
 
+namespace boot
+{
+
+using OneTimeEnabled = bool;
+
+/** @brief Return the one-time boot setting object path if enabled, otherwise
+ *         the regular boot setting object path.
+ *
+ * @param[in] objects - const reference to an object of type Objects
+ * @param[in] iface - boot setting interface
+ *
+ * @return A tuple - boot setting object path, a bool indicating whether the
+ *                   returned path corresponds to the one time boot setting.
+ */
+std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
+                                         const Interface& iface);
+
+} // namespace boot
+
 } // namespace settings