Read default power mode & IPS parameters from DBus

If the power mode or idle power saver parameters have never been set,
they will be read from a set of default parameters that are on DBus.
This allows individual systems to have different default settings.
Mode/IPS parameters moved from Settings to OCC.Control

Code verified on Everest hardware with multiple scenarios including
host reboots, BMC reboots, OCC resets.

Change-Id: Id02613455db7f382791ff37c7dc420dbea1e0906
Signed-off-by: Chris Cain <cjcain@us.ibm.com>
diff --git a/utils.cpp b/utils.cpp
index b44d477..e9ccc88 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -72,9 +72,9 @@
 /**
  * @brief Sets a given object's property value
  *
- * @param[in] object - Name of the object containing the property
+ * @param[in] objectPath - Name of the object containing the property
  * @param[in] interface - Interface name containing the property
- * @param[in] property - Property name
+ * @param[in] propertyName - Property name
  * @param[in] value - Property value
  */
 void setProperty(const std::string& objectPath, const std::string& interface,
@@ -83,23 +83,34 @@
     using namespace std::literals::string_literals;
     std::variant<std::string> varValue(std::forward<std::string>(value));
 
-    auto& bus = getBus();
-    auto service = getService(objectPath, interface);
-    if (service.empty())
+    try
     {
-        return;
+        auto& bus = getBus();
+        auto service = getService(objectPath, interface);
+        if (service.empty())
+        {
+            return;
+        }
+
+        auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
+                                          DBUS_PROPERTY_IFACE, "Set");
+        method.append(interface, propertyName, varValue);
+
+        auto reply = bus.call(method);
+        if (reply.is_method_error())
+        {
+            log<level::ERR>(
+                fmt::format("util::setProperty: Failed to set property {}",
+                            propertyName)
+                    .c_str());
+        }
     }
-
-    auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
-                                      DBUS_PROPERTY_IFACE, "Set");
-    method.append(interface, propertyName, varValue);
-
-    auto reply = bus.call(method);
-    if (reply.is_method_error())
+    catch (const std::exception& e)
     {
+        auto error = errno;
         log<level::ERR>(
-            fmt::format("util::setProperty: Failed to set property {}",
-                        propertyName)
+            fmt::format("setProperty: failed to Set {}, errno={}, what={}",
+                        propertyName.c_str(), error, e.what())
                 .c_str());
     }
 }
@@ -120,6 +131,54 @@
 
     return paths;
 }
+
+// Get the service and object path for an interface
+std::string getServiceUsingSubTree(const std::string& interface,
+                                   std::string& path)
+{
+    using Path = std::string;
+    using Intf = std::string;
+    using Serv = std::string;
+    using Intfs = std::vector<Intf>;
+    using Objects = std::map<Path, std::map<Serv, Intfs>>;
+    Serv service;
+    Objects rspObjects;
+
+    auto& bus = getBus();
+    auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
+                                      MAPPER_IFACE, "GetSubTree");
+    method.append(path, 0, std::vector{interface});
+
+    auto mapperResponseMsg = bus.call(method);
+    mapperResponseMsg.read(rspObjects);
+    if (rspObjects.empty())
+    {
+        log<level::ERR>(
+            fmt::format(
+                "util::getServiceUsingSubTree: Failed getSubTree({},0,{})",
+                path.c_str(), interface)
+                .c_str());
+    }
+    else
+    {
+        path = rspObjects.begin()->first;
+        if (!rspObjects.begin()->second.empty())
+        {
+            service = rspObjects.begin()->second.begin()->first;
+        }
+        else
+        {
+            log<level::ERR>(
+                fmt::format(
+                    "getServiceUsingSubTree: service not found for interface {} (path={})",
+                    interface, path.c_str())
+                    .c_str());
+        }
+    }
+
+    return service;
+}
+
 } // namespace utils
 } // namespace occ
 } // namespace open_power