Moving AssetTag and HostState under Listener

This commit moves the AssetTag and HostState change property signal and
its callback implementation from ibm-handler to Listener class.
AssetTag and HostState property change signal will be registered
through Listener class object.

Change-Id: I8679466283cbc70fc07121a0a57243572f80b483
Signed-off-by: Anupama B R <anupama.b.r1@ibm.com>
diff --git a/vpd-manager/include/listener.hpp b/vpd-manager/include/listener.hpp
index ad11152..36904f0 100644
--- a/vpd-manager/include/listener.hpp
+++ b/vpd-manager/include/listener.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "worker.hpp"
+
 #include <sdbusplus/asio/object_server.hpp>
 
 #include <memory>
@@ -24,13 +26,42 @@
 
     /**
      * @brief Constructor
-     *
+     * @param[in] i_worker - Reference to worker class object.
      * @param[in] i_asioConnection - Dbus Connection.
      */
     Listener(
+        const std::shared_ptr<Worker>& i_worker,
         const std::shared_ptr<sdbusplus::asio::connection>& i_asioConnection);
 
+    /**
+     * @brief API to register callback for Host state change.
+     *
+     */
+    void registerHostStateChangeCallback() const noexcept;
+
+    /**
+     * @brief API to register callback for "AssetTag" property change.
+     */
+    void registerAssetTagChangeCallback() const noexcept;
+
   private:
+    /**
+     * @brief API to process host state change callback.
+     *
+     * @param[in] i_msg - Callback message.
+     */
+    void hostStateChangeCallBack(sdbusplus::message_t& i_msg) const noexcept;
+
+    /**
+     * @brief Callback API to be triggered on "AssetTag" property change.
+     *
+     * @param[in] i_msg - Callback message.
+     */
+    void assetTagChangeCallback(sdbusplus::message_t& i_msg) const noexcept;
+
+    // Shared pointer to worker class
+    const std::shared_ptr<Worker>& m_worker;
+
     // Shared pointer to bus connection.
     const std::shared_ptr<sdbusplus::asio::connection>& m_asioConnection;
 };
diff --git a/vpd-manager/oem-handler/ibm_handler.cpp b/vpd-manager/oem-handler/ibm_handler.cpp
index 745fa57..293837f 100644
--- a/vpd-manager/oem-handler/ibm_handler.cpp
+++ b/vpd-manager/oem-handler/ibm_handler.cpp
@@ -2,6 +2,7 @@
 
 #include "ibm_handler.hpp"
 
+#include "listener.hpp"
 #include "parser.hpp"
 
 #include <utility/common_utility.hpp>
@@ -57,16 +58,10 @@
         }
     }
 
-    // callback to detect host state change.
-    registerHostStateChangeCallback();
-
-    // set callback to detect any asset tag change
-    registerAssetTagChangeCallback();
-
     // Instantiate Listener object
-    // ToDo: listening assetTag and HostState properties will move under
-    // Listener class
-    m_eventListener = std::make_shared<Listener>(m_asioConnection);
+    m_eventListener = std::make_shared<Listener>(m_worker, m_asioConnection);
+    m_eventListener->registerAssetTagChangeCallback();
+    m_eventListener->registerHostStateChangeCallback();
 
     // set async timer to detect if system VPD is published on D-Bus.
     SetTimerToDetectSVPDOnDbus();
@@ -79,65 +74,6 @@
         std::make_shared<GpioMonitor>(m_sysCfgJsonObj, m_worker, m_ioContext);
 }
 
-void IbmHandler::registerAssetTagChangeCallback()
-{
-    static std::shared_ptr<sdbusplus::bus::match_t> l_assetMatch =
-        std::make_shared<sdbusplus::bus::match_t>(
-            *m_asioConnection,
-            sdbusplus::bus::match::rules::propertiesChanged(
-                constants::systemInvPath, constants::assetTagInf),
-            [this](sdbusplus::message_t& l_msg) {
-                processAssetTagChangeCallback(l_msg);
-            });
-}
-
-void IbmHandler::processAssetTagChangeCallback(sdbusplus::message_t& i_msg)
-{
-    try
-    {
-        if (i_msg.is_method_error())
-        {
-            throw std::runtime_error(
-                "Error reading callback msg for asset tag.");
-        }
-
-        std::string l_objectPath;
-        types::PropertyMap l_propMap;
-        i_msg.read(l_objectPath, l_propMap);
-
-        const auto& l_itrToAssetTag = l_propMap.find("AssetTag");
-        if (l_itrToAssetTag != l_propMap.end())
-        {
-            if (auto l_assetTag =
-                    std::get_if<std::string>(&(l_itrToAssetTag->second)))
-            {
-                // Call Notify to persist the AssetTag
-                types::ObjectMap l_objectMap = {
-                    {sdbusplus::message::object_path(constants::systemInvPath),
-                     {{constants::assetTagInf, {{"AssetTag", *l_assetTag}}}}}};
-
-                // Notify PIM
-                if (!dbusUtility::callPIM(move(l_objectMap)))
-                {
-                    throw std::runtime_error(
-                        "Call to PIM failed for asset tag update.");
-                }
-            }
-        }
-        else
-        {
-            throw std::runtime_error(
-                "Could not find asset tag in callback message.");
-        }
-    }
-    catch (const std::exception& l_ex)
-    {
-        // TODO: Log PEL with below description.
-        logging::logMessage("Asset tag callback update failed with error: " +
-                            std::string(l_ex.what()));
-    }
-}
-
 void IbmHandler::SetTimerToDetectSVPDOnDbus()
 {
     try
@@ -440,73 +376,6 @@
     }
 }
 
-void IbmHandler::registerHostStateChangeCallback()
-{
-    static std::shared_ptr<sdbusplus::bus::match_t> l_hostState =
-        std::make_shared<sdbusplus::bus::match_t>(
-            *m_asioConnection,
-            sdbusplus::bus::match::rules::propertiesChanged(
-                constants::hostObjectPath, constants::hostInterface),
-            [this](sdbusplus::message_t& i_msg) {
-                hostStateChangeCallBack(i_msg);
-            });
-}
-
-void IbmHandler::hostStateChangeCallBack(sdbusplus::message_t& i_msg)
-{
-    try
-    {
-        if (i_msg.is_method_error())
-        {
-            throw std::runtime_error(
-                "Error reading callback message for host state");
-        }
-
-        std::string l_objectPath;
-        types::PropertyMap l_propMap;
-        i_msg.read(l_objectPath, l_propMap);
-
-        const auto l_itr = l_propMap.find("CurrentHostState");
-
-        if (l_itr == l_propMap.end())
-        {
-            throw std::runtime_error(
-                "CurrentHostState field is missing in callback message");
-        }
-
-        if (auto l_hostState = std::get_if<std::string>(&(l_itr->second)))
-        {
-            // implies system is moving from standby to power on state
-            if (*l_hostState == "xyz.openbmc_project.State.Host.HostState."
-                                "TransitioningToRunning")
-            {
-                // TODO: check for all the essential FRUs in the system.
-
-                if (m_worker.get() != nullptr)
-                {
-                    // Perform recollection.
-                    m_worker->performVpdRecollection();
-                }
-                else
-                {
-                    logging::logMessage(
-                        "Failed to get worker object, Abort re-collection");
-                }
-            }
-        }
-        else
-        {
-            throw std::runtime_error(
-                "Invalid type recieved in variant for host state.");
-        }
-    }
-    catch (const std::exception& l_ex)
-    {
-        // TODO: Log PEL.
-        logging::logMessage(l_ex.what());
-    }
-}
-
 void IbmHandler::primeSystemBlueprint()
 {
     if (m_sysCfgJsonObj.empty())
diff --git a/vpd-manager/oem-handler/ibm_handler.hpp b/vpd-manager/oem-handler/ibm_handler.hpp
index 094c139..68f021a 100644
--- a/vpd-manager/oem-handler/ibm_handler.hpp
+++ b/vpd-manager/oem-handler/ibm_handler.hpp
@@ -46,18 +46,6 @@
 
   private:
     /**
-     * @brief API to register callback for Host state change.
-     */
-    void registerHostStateChangeCallback();
-
-    /**
-     * @brief API to process host state change callback.
-     *
-     * @param[in] i_msg - Callback message.
-     */
-    void hostStateChangeCallBack(sdbusplus::message_t& i_msg);
-
-    /**
      * @brief API to set timer to detect system VPD over D-Bus.
      *
      * System VPD is required before bus name for VPD-Manager is claimed. Once
@@ -83,18 +71,6 @@
     void SetTimerToDetectVpdCollectionStatus();
 
     /**
-     * @brief API to register callback for "AssetTag" property change.
-     */
-    void registerAssetTagChangeCallback();
-
-    /**
-     * @brief Callback API to be triggered on "AssetTag" property change.
-     *
-     * @param[in] i_msg - The callback message.
-     */
-    void processAssetTagChangeCallback(sdbusplus::message_t& i_msg);
-
-    /**
      * @brief API to process VPD collection thread failed EEPROMs.
      */
     void processFailedEeproms();
diff --git a/vpd-manager/src/listener.cpp b/vpd-manager/src/listener.cpp
index d079258..736d93a 100644
--- a/vpd-manager/src/listener.cpp
+++ b/vpd-manager/src/listener.cpp
@@ -1,9 +1,166 @@
 #include "listener.hpp"
 
+#include "event_logger.hpp"
+#include "utility/dbus_utility.hpp"
+
 namespace vpd
 {
 Listener::Listener(
+    const std::shared_ptr<Worker>& i_worker,
     const std::shared_ptr<sdbusplus::asio::connection>& i_asioConnection) :
-    m_asioConnection(i_asioConnection)
+    m_worker(i_worker), m_asioConnection(i_asioConnection)
 {}
+
+void Listener::registerHostStateChangeCallback() const noexcept
+{
+    try
+    {
+        static std::shared_ptr<sdbusplus::bus::match_t> l_hostState =
+            std::make_shared<sdbusplus::bus::match_t>(
+                *m_asioConnection,
+                sdbusplus::bus::match::rules::propertiesChanged(
+                    constants::hostObjectPath, constants::hostInterface),
+                [this](sdbusplus::message_t& i_msg) {
+                    hostStateChangeCallBack(i_msg);
+                });
+    }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage(
+            "Register Host state change callback failed, reason: " +
+            std::string(l_ex.what()));
+    }
+}
+
+void Listener::hostStateChangeCallBack(
+    sdbusplus::message_t& i_msg) const noexcept
+{
+    try
+    {
+        if (i_msg.is_method_error())
+        {
+            throw std::runtime_error(
+                "Error reading callback message for host state");
+        }
+
+        std::string l_objectPath;
+        types::PropertyMap l_propMap;
+        i_msg.read(l_objectPath, l_propMap);
+
+        const auto l_itr = l_propMap.find("CurrentHostState");
+
+        if (l_itr == l_propMap.end())
+        {
+            // CurrentHostState is not found in the callback message
+            return;
+        }
+
+        if (auto l_hostState = std::get_if<std::string>(&(l_itr->second)))
+        {
+            // implies system is moving from standby to power on state
+            if (*l_hostState == "xyz.openbmc_project.State.Host.HostState."
+                                "TransitioningToRunning")
+            {
+                // TODO: check for all the essential FRUs in the system.
+
+                if (m_worker.get() != nullptr)
+                {
+                    // Perform recollection.
+                    m_worker->performVpdRecollection();
+                }
+                else
+                {
+                    logging::logMessage(
+                        "Failed to get worker object, Abort re-collection");
+                }
+            }
+        }
+        else
+        {
+            throw std::runtime_error(
+                "Invalid type recieved in variant for host state.");
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        EventLogger::createSyncPel(
+            EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
+            __FILE__, __FUNCTION__, 0,
+            "Host state change callback failed, reason: " +
+                std::string(l_ex.what()),
+            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+    }
+}
+
+void Listener::registerAssetTagChangeCallback() const noexcept
+{
+    try
+    {
+        static std::shared_ptr<sdbusplus::bus::match_t> l_assetMatch =
+            std::make_shared<sdbusplus::bus::match_t>(
+                *m_asioConnection,
+                sdbusplus::bus::match::rules::propertiesChanged(
+                    constants::systemInvPath, constants::assetTagInf),
+                [this](sdbusplus::message_t& l_msg) {
+                    assetTagChangeCallback(l_msg);
+                });
+    }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage(
+            "Register AssetTag change callback failed, reason: " +
+            std::string(l_ex.what()));
+    }
+}
+
+void Listener::assetTagChangeCallback(
+    sdbusplus::message_t& i_msg) const noexcept
+{
+    try
+    {
+        if (i_msg.is_method_error())
+        {
+            throw std::runtime_error(
+                "Error reading callback msg for asset tag.");
+        }
+
+        std::string l_objectPath;
+        types::PropertyMap l_propMap;
+        i_msg.read(l_objectPath, l_propMap);
+
+        const auto& l_itrToAssetTag = l_propMap.find("AssetTag");
+        if (l_itrToAssetTag != l_propMap.end())
+        {
+            if (auto l_assetTag =
+                    std::get_if<std::string>(&(l_itrToAssetTag->second)))
+            {
+                // Call Notify to persist the AssetTag
+                types::ObjectMap l_objectMap = {
+                    {sdbusplus::message::object_path(constants::systemInvPath),
+                     {{constants::assetTagInf, {{"AssetTag", *l_assetTag}}}}}};
+
+                // Notify PIM
+                if (!dbusUtility::callPIM(move(l_objectMap)))
+                {
+                    throw std::runtime_error(
+                        "Call to PIM failed for asset tag update.");
+                }
+            }
+        }
+        else
+        {
+            throw std::runtime_error(
+                "Could not find asset tag in callback message.");
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        EventLogger::createSyncPel(
+            EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
+            __FILE__, __FUNCTION__, 0,
+            "AssetTag update failed, reason: " + std::string(l_ex.what()),
+            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+    }
+}
+
 } // namespace vpd