Add watch on D-Bus object paths

Clients specify the object paths to watch in the config yaml.

Example yaml file and parser changes are pushed in separate
patch

Callbacks are invoked based on the watch type created i.e
interfaceadded/interfaceremoved

Change-Id: Icb7b9bf4c072f8b8df33747c813a1f07b61de637
Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 23c6009..583e533 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,7 @@
 	elog.cpp \
 	main.cpp \
 	propertywatch.cpp \
+	pathwatch.cpp \
 	resolve_errors.cpp \
 	event_manager.cpp \
 	event_serialize.cpp \
diff --git a/src/pathwatch.cpp b/src/pathwatch.cpp
new file mode 100644
index 0000000..302e532
--- /dev/null
+++ b/src/pathwatch.cpp
@@ -0,0 +1 @@
+#include "pathwatchimpl.hpp"
\ No newline at end of file
diff --git a/src/pathwatch.hpp b/src/pathwatch.hpp
new file mode 100644
index 0000000..db81bec
--- /dev/null
+++ b/src/pathwatch.hpp
@@ -0,0 +1,70 @@
+/**
+ * @file PathWatch.hpp
+ * @brief Add watch for the object path for interfaces added/removed signal
+ *
+ * In general class users should include pathwatchimpl.hpp instead to avoid
+ * link failures.
+ */
+#pragma once
+
+#include "data_types.hpp"
+#include "watch.hpp"
+
+namespace phosphor
+{
+namespace dbus
+{
+namespace monitoring
+{
+
+class Callback;
+
+/** @class PathWatch
+ *  @brief Watch on object path for interfaceadded/interfaceremoved signals
+ */
+template <typename DBusInterfaceType> class PathWatch : public Watch
+{
+  public:
+    PathWatch() = delete;
+    PathWatch(const PathWatch&) = delete;
+    PathWatch(PathWatch&&) = default;
+    PathWatch& operator=(const PathWatch&) = delete;
+    PathWatch& operator=(PathWatch&&) = default;
+    virtual ~PathWatch() = default;
+    PathWatch(const std::string& path, Callback& callback) :
+        Watch(), objectPath(path), cb(callback), alreadyRan(false)
+    {
+    }
+
+    /** @brief Start the watch.
+     *
+     *  Watch start interface implementation for PathWatch.
+     */
+    void start() override;
+
+    /** @brief Run the watch callback method.
+     *
+     *  Watch callback interface implementation for PathWatch.
+     */
+    void callback(Context ctx) override;
+
+    /** @brief Run the watch callback method.
+     *
+     *  Watch callback interface implementation for PathWatch.
+     */
+    void callback(Context ctx, sdbusplus::message::message& msg) override;
+
+  protected:
+    /** @brief Path of the D-Bus object to watch for. */
+    const std::string& objectPath;
+
+    /** @brief Optional callback method. */
+    Callback& cb;
+
+    /** @brief The start method should only be invoked once. */
+    bool alreadyRan;
+};
+
+} // namespace monitoring
+} // namespace dbus
+} // namespace phosphor
diff --git a/src/pathwatchimpl.hpp b/src/pathwatchimpl.hpp
new file mode 100644
index 0000000..6be0f50
--- /dev/null
+++ b/src/pathwatchimpl.hpp
@@ -0,0 +1,53 @@
+/**
+ * @file PathWatchimpl.hpp
+ * @brief Add interfaces added watch for the specified path
+ *
+ */
+#pragma once
+
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <vector>
+#include "callback.hpp"
+#include "data_types.hpp"
+#include "pathwatch.hpp"
+
+namespace phosphor
+{
+namespace dbus
+{
+namespace monitoring
+{
+
+template <typename DBusInterfaceType> void PathWatch<DBusInterfaceType>::start()
+{
+    if (alreadyRan)
+    {
+        return;
+    }
+    // Watch for new interfaces added on this path.
+    DBusInterfaceType::addMatch(
+        sdbusplus::bus::match::rules::interfacesAdded(objectPath),
+        [this](auto& msg)
+        // *INDENT-OFF*
+        { (this->cb)(Context::SIGNAL, msg); });
+    // *INDENT-ON*
+
+    alreadyRan = true;
+}
+
+template <typename DBusInterfaceType>
+void PathWatch<DBusInterfaceType>::callback(Context ctx)
+{
+    (this->cb)(ctx);
+}
+
+template <typename DBusInterfaceType>
+void PathWatch<DBusInterfaceType>::callback(Context ctx,
+                                            sdbusplus::message::message& msg)
+{
+    (this->cb)(ctx, msg);
+}
+} // namespace monitoring
+} // namespace dbus
+} // namespace phosphor
diff --git a/src/watch.hpp b/src/watch.hpp
index 9c97b9e..a44480c 100644
--- a/src/watch.hpp
+++ b/src/watch.hpp
@@ -37,6 +37,9 @@
 
     /** @brief Invoke the callback associated with the watch. */
     virtual void callback(Context ctx) = 0;
+
+    /** @brief Invoke the callback associated with the watch. */
+    virtual void callback(Context ctx, sdbusplus::message::message& msg){};
 };
 
 } // namespace monitoring