Generate a PEL if any attentions found in hardware

analyzer::analyzeHardware() will create a PEL, if any attentions are
found in hardware, instead of requiring the caller to create the PEL.

Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: Ie5319eca56cbeba4ddc25bcb897d4d143edde742
diff --git a/analyzer/analyzer_main.cpp b/analyzer/analyzer_main.cpp
index dfeda8f..774fb0a 100644
--- a/analyzer/analyzer_main.cpp
+++ b/analyzer/analyzer_main.cpp
@@ -1,7 +1,9 @@
 #include <assert.h>
 #include <libpdbg.h>
+#include <unistd.h>
 
 #include <hei_main.hpp>
+#include <phosphor-logging/log.hpp>
 #include <util/trace.hpp>
 
 #include <algorithm>
@@ -278,7 +280,66 @@
 
 //------------------------------------------------------------------------------
 
-bool analyzeHardware(std::map<std::string, std::string>& o_errors)
+bool __logError(const std::vector<libhei::Signature>& i_sigList,
+                const libhei::IsolationData& i_isoData)
+{
+    bool attnFound = false;
+
+    // Get numerical values for the root cause.
+    uint32_t word6 = 0; // [ 0: 7]: chip target type
+                        // [ 8:31]: chip FAPI position
+                        //    uint32_t word7 = 0; // TODO: chip target info
+    uint32_t word8 = 0; // [ 0:15]: node ID
+                        // [16:23]: node instance
+                        // [24:31]: bit position
+                        //    uint32_t word9 = 0; // [ 0: 7]: attention type
+
+    if (i_sigList.empty())
+    {
+        trace::inf("No active attentions found");
+    }
+    else
+    {
+        attnFound = true;
+
+        // The root cause attention is the first in the filtered list.
+        libhei::Signature root = i_sigList.front();
+
+        word6 = __trgt(root);
+        word8 = __sig(root);
+
+        trace::inf("Root cause attention: %s 0x%0" PRIx32 " %s",
+                   __path(root.getChip()), word8, __attn(root.getAttnType()));
+    }
+
+    // Get the log data.
+    std::map<std::string, std::string> logData;
+    logData["_PID"]      = std::to_string(getpid());
+    logData["CHIP_ID"]   = std::to_string(word6);
+    logData["SIGNATURE"] = std::to_string(word8);
+
+    // Get access to logging interface and method for creating log.
+    auto bus = sdbusplus::bus::new_default_system();
+
+    // Using direct create method (for additional data)
+    auto method = bus.new_method_call(
+        "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
+        "xyz.openbmc_project.Logging.Create", "Create");
+
+    // Attach additional data
+    method.append("org.open_power.HwDiags.Error.Checkstop",
+                  "xyz.openbmc_project.Logging.Entry.Level.Error", logData);
+
+    // Log the event.
+    // TODO: Should the reply be handled?
+    bus.call(method);
+
+    return attnFound;
+}
+
+//------------------------------------------------------------------------------
+
+bool analyzeHardware()
 {
     bool attnFound = false;
 
@@ -303,25 +364,8 @@
     std::vector<libhei::Signature> sigList{isoData.getSignatureList()};
     __filterRootCause(sigList);
 
-    if (sigList.empty())
-    {
-        // Don't throw an error here because it could happen for during TI
-        // analysis. Attention Handler will need to determine if this is an
-        // actual problem.
-        trace::inf("No active attentions found");
-    }
-    else
-    {
-        attnFound = true;
-        trace::inf("Active attentions found: %d", sigList.size());
-
-        libhei::Signature root = sigList.front();
-        trace::inf("Root cause attention: %p 0x%04x%02x%02x %s",
-                   root.getChip().getChip(), root.getId(), root.getInstance(),
-                   root.getBit(), __attn(root.getAttnType()));
-
-        // TODO: generate log information
-    }
+    // Create and commit a log.
+    attnFound = __logError(sigList, isoData);
 
     // All done, clean up the isolator.
     trace::inf("Uninitializing isolator");
diff --git a/analyzer/analyzer_main.hpp b/analyzer/analyzer_main.hpp
index 951fc6b..8e67ad2 100644
--- a/analyzer/analyzer_main.hpp
+++ b/analyzer/analyzer_main.hpp
@@ -11,9 +11,6 @@
  *         chip. Then it performs all approriate RAS actions based on the active
  *         attentions.
  *
- * @param  o_errors A map for storing information about errors that were
- *                  detected by the hardware error isolator.
- *
  * @return True if an active attenion was successfully analyzed, false
  *         otherwise.
  *         For system checkstop handling:
@@ -25,6 +22,6 @@
  *            analysis could fail to find an attention and it should not be
  *            treated as a defect.
  */
-bool analyzeHardware(std::map<std::string, std::string>& i_errors);
+bool analyzeHardware();
 
 } // namespace analyzer
diff --git a/analyzer/meson.build b/analyzer/meson.build
index 3354725..87b6fcc 100644
--- a/analyzer/meson.build
+++ b/analyzer/meson.build
@@ -1,3 +1,6 @@
+# dependency to link sdbusplus support
+sdbusplus = dependency('sdbusplus', version : '>=1.0')
+
 # gather analyzer sources to be used here and elsewhere if needed
 analyzer_src = files('analyzer_main.cpp',
                      'hei_user_interface.cpp')
@@ -6,6 +9,6 @@
 analyzer = static_library('analyzer',
                           analyzer_src,
                           include_directories : incdir,
-                          dependencies : libhei_dep,
+                          dependencies : [ libhei_dep, sdbusplus ],
                           cpp_args : test_arg,
                           install : false)
diff --git a/attn/attn_handler.cpp b/attn/attn_handler.cpp
index 04447ab..cae3da9 100644
--- a/attn/attn_handler.cpp
+++ b/attn/attn_handler.cpp
@@ -210,23 +210,12 @@
     }
     else
     {
-        // errors that were isolated
-        std::map<std::string, std::string> errors;
-
-        // analyze errors
-        if (true != analyzer::analyzeHardware(errors))
+        // Look for any attentions found in hardware. This will generate and
+        // comment a PEL if any errors are found.
+        if (true != analyzer::analyzeHardware())
         {
             rc = RC_ANALYZER_ERROR;
         }
-        else
-        {
-            std::stringstream ss;
-            ss << "Analyzer isolated " << errors.size() << " error(s)";
-            trace<level::INFO>(ss.str().c_str());
-
-            // add checkstop event to log
-            eventCheckstop(errors);
-        }
     }
 
     return rc;
diff --git a/main.cpp b/main.cpp
index 8cc06ed..5bce1a5 100644
--- a/main.cpp
+++ b/main.cpp
@@ -60,20 +60,7 @@
         // Either analyze (application mode) or daemon mode
         if (true == getCliOption(argv, argv + argc, "--analyze"))
         {
-            // errors that were isolated
-            std::map<std::string, std::string> errors;
-
-            rc = analyzer::analyzeHardware(errors); // analyze hardware
-            if (RC_SUCCESS == rc)
-            {
-                // TODO - add error processing/display
-
-                printf("analyzer isolated %i error(s)\n", (int)errors.size());
-            }
-            else
-            {
-                printf("analyzer/isolator error encountered\n");
-            }
+            rc = analyzer::analyzeHardware(); // analyze hardware
         }
         // daemon mode
         else
diff --git a/main_nl.cpp b/main_nl.cpp
index 88a5a5f..a9460de 100644
--- a/main_nl.cpp
+++ b/main_nl.cpp
@@ -45,12 +45,7 @@
         // Either analyze (application mode) or daemon mode
         if (true == getCliOption(argv, argv + argc, "--analyze"))
         {
-            // errors that were isolated
-            std::map<std::string, std::string> errors;
-
-            rc = analyzer::analyzeHardware(errors); // analyze hardware
-
-            printf("analyzer isolated %i error(s)\n", (int)errors.size());
+            rc = analyzer::analyzeHardware(); // analyze hardware
         }
         // daemon mode
         else