Add handler for pulse like Assert-DeAssert events

This change adds handler for pulse like events. Currently the changes handle DC
power on - off events. The events are then logged into the Journal.

Tested: Sent IPMI commands to switch DC power on, off, reset and verified that
the logs are updated in the Journal.

Change-Id: I2a6c4e7759015ab80512f6c3da88f950fb02a04f
Signed-off-by: Nikhil Potade <nikhil.potade@intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6569709..e843eca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,9 +11,18 @@
      log SEL records for threshold sensor events"
     OFF
 )
+
+option (
+    REDFISH_LOG_MONITOR_PULSE_EVENTS
+    "Enable logger to monitor and automatically
+     log events to Redfish for pulse type assert-deassert sensor events"
+    OFF
+)
+
 target_compile_definitions (
     sel-logger PRIVATE
     $<$<BOOL:${SEL_LOGGER_MONITOR_THRESHOLD_EVENTS}>: -DSEL_LOGGER_MONITOR_THRESHOLD_EVENTS>
+    $<$<BOOL:${REDFISH_LOG_MONITOR_PULSE_EVENTS}>: -DREDFISH_LOG_MONITOR_PULSE_EVENTS>
 )
 
 target_include_directories (sel-logger PRIVATE ${CMAKE_SOURCE_DIR})
diff --git a/include/pulse_event_monitor.hpp b/include/pulse_event_monitor.hpp
new file mode 100644
index 0000000..8b651dd
--- /dev/null
+++ b/include/pulse_event_monitor.hpp
@@ -0,0 +1,78 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include <sdbusplus/asio/object_server.hpp>
+#include <sel_logger.hpp>
+#include <sensorutils.hpp>
+
+inline static sdbusplus::bus::match::match
+    startPulseEventMonitor(std::shared_ptr<sdbusplus::asio::connection> conn)
+{
+    auto pulseEventMatcherCallback = [](sdbusplus::message::message &msg) {
+        std::string thresholdInterface;
+        boost::container::flat_map<std::string,
+                                   sdbusplus::message::variant<std::string>>
+            propertiesChanged;
+        msg.read(thresholdInterface, propertiesChanged);
+
+        if (propertiesChanged.empty())
+        {
+            return;
+        }
+
+        std::string event = propertiesChanged.begin()->first;
+
+        auto variant = sdbusplus::message::variant_ns::get_if<std::string>(
+            &propertiesChanged.begin()->second);
+
+        if (event.empty() || nullptr == variant)
+        {
+            return;
+        }
+
+        if (event == "CurrentHostState")
+        {
+            if (*variant == "xyz.openbmc_project.State.Host.HostState.Off")
+            {
+                std::string message("Host system DC power is off");
+                std::string redfishMsgId("DCPowerOff");
+
+                sd_journal_send("MESSAGE=%s", message.c_str(),
+                                "REDFISH_MESSAGE_ID=%s", redfishMsgId.c_str(),
+                                NULL);
+            }
+            else if (*variant ==
+                     "xyz.openbmc_project.State.Host.HostState.Running")
+            {
+                std::string message("Host system DC power is on");
+                std::string redfishMsgId("DCPowerOn");
+
+                sd_journal_send("MESSAGE=%s", message.c_str(),
+                                "REDFISH_MESSAGE_ID=%s", redfishMsgId.c_str(),
+                                NULL);
+            }
+        }
+    };
+
+    sdbusplus::bus::match::match pulseEventMatcher(
+        static_cast<sdbusplus::bus::bus &>(*conn),
+        "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+        "PropertiesChanged',arg0namespace='xyz.openbmc_project.State.Host'",
+        std::move(pulseEventMatcherCallback));
+
+    return pulseEventMatcher;
+}
\ No newline at end of file
diff --git a/src/sel_logger.cpp b/src/sel_logger.cpp
index 22ee2f1..6068e20 100644
--- a/src/sel_logger.cpp
+++ b/src/sel_logger.cpp
@@ -20,6 +20,7 @@
 #include <experimental/string_view>
 #include <iomanip>
 #include <iostream>
+#include <pulse_event_monitor.hpp>
 #include <sdbusplus/asio/object_server.hpp>
 #include <sel_logger.hpp>
 #include <sstream>
@@ -184,6 +185,11 @@
         startThresholdEventMonitor(conn);
 #endif
 
+#ifdef REDFISH_LOG_MONITOR_PULSE_EVENTS
+    sdbusplus::bus::match::match pulseEventMonitor =
+        startPulseEventMonitor(conn);
+#endif
+
     io.run();
 
     return 0;