Support config location from compatible system interface

Update reading the `Names` property from the
`xyz.openbmc_project.Configuration.IBMCompatibleSystem` interface that
contains a list of compatible subdirectories in priority order to find
the location of the configuration file to use. The first configuration
file found from checking these subdirectories is used. The order in
which configuration files are looked for remain unchanged and are:

1.) Override location: /etc/phosphor-fan-presence/[app]
2.) First config file found under one of these subdirectories
    i.e.) `Names` = "rainier-2u" "rainier"
        1.) /usr/share/phosphor-fan-presence/[app]/rainier-2u
        2.) /usr/share/phosphor-fan-presence/[app]/rainier
3.) Default location: /usr/share/phosphor-fan-presence/[app]

Tested:
    Verified location order above loads the expected config file

Change-Id: If6eb36e1a808544da0795db609658eb57db112c0
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/sdbusplus.hpp b/sdbusplus.hpp
index 703895e..3da6f93 100644
--- a/sdbusplus.hpp
+++ b/sdbusplus.hpp
@@ -210,6 +210,44 @@
         return mapperResp;
     }
 
+    /** @brief Get subtree paths from the mapper without checking response. */
+    static auto getSubTreePathsRaw(sdbusplus::bus::bus& bus,
+                                   const std::string& path,
+                                   const std::string& interface, int32_t depth)
+    {
+        using namespace std::literals::string_literals;
+
+        using Path = std::string;
+        using Intf = std::string;
+        using Intfs = std::vector<Intf>;
+        using ObjectPaths = std::vector<Path>;
+        Intfs intfs = {interface};
+
+        return callMethodAndRead<ObjectPaths>(
+            bus, "xyz.openbmc_project.ObjectMapper"s,
+            "/xyz/openbmc_project/object_mapper"s,
+            "xyz.openbmc_project.ObjectMapper"s, "GetSubTreePaths"s, path,
+            depth, intfs);
+    }
+
+    /** @brief Get subtree paths from the mapper. */
+    static auto getSubTreePaths(sdbusplus::bus::bus& bus,
+                                const std::string& path,
+                                const std::string& interface, int32_t depth)
+    {
+        auto mapperResp = getSubTreePathsRaw(bus, path, interface, depth);
+        if (mapperResp.empty())
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Empty response from mapper GetSubTreePaths",
+                phosphor::logging::entry("SUBTREE=%s", path.c_str()),
+                phosphor::logging::entry("INTERFACE=%s", interface.c_str()),
+                phosphor::logging::entry("DEPTH=%u", depth));
+            phosphor::logging::elog<detail::errors::InternalFailure>();
+        }
+        return mapperResp;
+    }
+
     /** @brief Get service from the mapper. */
     static auto getService(sdbusplus::bus::bus& bus, const std::string& path,
                            const std::string& interface)