callouts: implement metadata handler

Implement handler of the metadata CALLOUT_DEVICE_PATH. This handler will
convert a device path to an inventory path and call out the latter.

Change-Id: Icbf9c841884ec139f35ea2ac94648e355b421bb2
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index c9aa9f8..6ca02d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,7 @@
 	xyz/openbmc_project/Logging/Internal/Manager/server.hpp
 
 libphosphor_logging_FILES = \
-	elog.cpp
+	elog.cpp elog_meta.cpp
 libphosphor_loggingdir = ${libdir}
 libphosphor_logging_LTLIBRARIES = libphosphor_logging.la
 libphosphor_logging_la_SOURCES = $(libphosphor_logging_FILES)
@@ -35,7 +35,8 @@
 	elog-lookup.cpp \
 	elog_entry.cpp \
 	org.openbmc.Associations.cpp \
-	elog-process-metadata.cpp
+	elog-process-metadata.cpp \
+	elog_meta.cpp
 
 # Be sure to build needed files before compiling
 BUILT_SOURCES = \
diff --git a/configure.ac b/configure.ac
index 964ce08..93c3526 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,6 +63,9 @@
 AC_DEFINE(OBJ_LOGGING, "/xyz/openbmc_project/logging", [The log manager DBus object path.])
 AC_DEFINE(OBJ_INTERNAL, "/xyz/openbmc_project/logging/internal/manager", [The private log manager DBus object path.])
 AC_DEFINE(OBJ_ENTRY, "/xyz/openbmc_project/logging/entry", [The log entry DBus object path.])
+AC_DEFINE(INVENTORY_ROOT, "/xyz/openbmc_project/inventory", [The inventory root.])
+AC_DEFINE(CALLOUT_FWD_ASSOCIATION, "callout", [The name of the callout's forward association.])
+AC_DEFINE(CALLOUT_REV_ASSOCIATION, "fault", [The name of the callout's reverse association.])
 
 AC_ARG_VAR(YAML_DIR_TEST, [The path to the test error yaml files.])
 AS_IF([test "x$YAML_DIR_TEST" == "x"], \
diff --git a/elog_meta.cpp b/elog_meta.cpp
new file mode 100644
index 0000000..b7b75a1
--- /dev/null
+++ b/elog_meta.cpp
@@ -0,0 +1,51 @@
+#include "config.h"
+#include "elog_meta.hpp"
+
+namespace phosphor
+{
+namespace logging
+{
+namespace metadata
+{
+namespace associations
+{
+
+#if defined PROCESS_META
+
+template <>
+void build<xyz::openbmc_project::Common::
+           Callout::Device::CALLOUT_DEVICE_PATH>(
+    std::string&& match,
+    const std::vector<std::string>& data,
+    AssociationList& list)
+{
+    std::map<std::string, std::string> metadata;
+    parse(data, metadata);
+    auto iter = metadata.find(match);
+    if(metadata.end() != iter)
+    {
+        auto comp = [](const auto& first, const auto& second)
+        {
+            return (strcmp(std::get<0>(first), second) < 0);
+        };
+        auto callout = std::lower_bound(callouts.begin(),
+                                        callouts.end(),
+                                        (iter->second).c_str(),
+                                        comp);
+        if((callouts.end() != callout) &&
+           !strcmp((iter->second).c_str(), std::get<0>(*callout)))
+        {
+            list.emplace_back(std::make_tuple(CALLOUT_FWD_ASSOCIATION,
+                                              CALLOUT_REV_ASSOCIATION,
+                                              std::string(INVENTORY_ROOT) +
+                                              std::get<1>(*callout)));
+        }
+    }
+}
+
+#endif
+
+} // namespace associations
+} // namespace metadata
+} // namespace logging
+} // namespace phosphor
diff --git a/elog_meta.hpp b/elog_meta.hpp
index 09e3ede..632a049 100644
--- a/elog_meta.hpp
+++ b/elog_meta.hpp
@@ -100,6 +100,18 @@
     }
 }
 
+#if defined PROCESS_META
+
+template <>
+void build<xyz::openbmc_project::Common::
+           Callout::Device::CALLOUT_DEVICE_PATH>(
+    std::string&& match,
+    const std::vector<std::string>& data,
+    AssociationList& list);
+
+#endif // PROCESS_META
+
+
 } // namespace associations
 } // namespace metadata
 } // namespace logging