Add interface exposing utility functions

Add utility functions enabling easy method calls on sdbusplus interface
binding objects.

Change-Id: Ie1d01f82604406705869fea0ec19d84c95d90474
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/manager.cpp b/manager.cpp
index b9e8ace..d3e2973 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -183,6 +183,31 @@
     _refs.erase(_root + p);
 }
 
+details::holder::Base& Manager::getInterfaceHolder(
+        const char *path, const char *interface)
+{
+    return const_cast<const Manager *>(
+            this)->getInterfaceHolder(path, interface);
+}
+
+details::holder::Base& Manager::getInterfaceHolder(
+        const char *path, const char *interface) const
+{
+    std::string p{path};
+    auto oit = _refs.find(_root + p);
+    if(oit == _refs.end())
+        throw std::runtime_error(
+                _root + p + " was not found");
+
+    auto &obj = oit->second;
+    auto iit = obj.find(interface);
+    if(iit == obj.end())
+        throw std::runtime_error(
+                "interface was not found");
+
+    return *iit->second;
+}
+
 } // namespace manager
 } // namespace inventory
 } // namespace phosphor
diff --git a/manager.hpp b/manager.hpp
index 92afd9f..6326336 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -116,6 +116,48 @@
             sdbusplus::bus::bus &, const char *);
     using Makers = std::map<std::string, MakerType>;
 
+    /** @brief Provides weak references to interface holders.
+     *
+     *  Common code for all types for the templated getInterface
+     *  methods.
+     *
+     *  @param[in] path - The DBus path for which the interface
+     *      holder instance should be provided.
+     *  @param[in] interface - The DBus interface for which the
+     *      holder instance should be provided.
+     *
+     *  @returns A weak reference to the holder instance.
+     */
+    details::holder::Base& getInterfaceHolder(
+            const char *, const char *) const;
+    details::holder::Base& getInterfaceHolder(
+            const char *, const char *);
+
+    /** @brief Provides weak references to interface holders.
+     *
+     *  @tparam T - The sdbusplus server binding interface type.
+     *
+     *  @param[in] path - The DBus path for which the interface
+     *      should be provided.
+     *  @param[in] interface - The DBus interface to obtain.
+     *
+     *  @returns A weak reference to the interface holder.
+     */
+    template<typename T>
+    auto& getInterface(const char *path, const char *interface)
+    {
+        auto &holder = getInterfaceHolder(path, interface);
+        return static_cast<
+            details::holder::Holder<T> &>(holder);
+    }
+    template<typename T>
+    auto& getInterface(const char *path, const char *interface) const
+    {
+        auto &holder = getInterfaceHolder(path, interface);
+        return static_cast<
+            const details::holder::Holder<T> &>(holder);
+    }
+
     /** @brief Provided for testing only. */
     bool _shutdown;
 
diff --git a/utils.hpp b/utils.hpp
index 2dbd3b6..4ebb2a3 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -77,6 +77,18 @@
                 std::forward<Held>(held));
     }
 
+    /** @brief Provides a weak reference to the held interface. */
+    T& get()
+    {
+        return _held;
+    }
+
+    /** @brief Provides a weak reference to the held interface. */
+    const T& get() const
+    {
+        return _held;
+    }
+
     protected:
         T _held;
 };