Listener: Register callback API stub

This commit implements a stub API in Listener class to register callback
for all interfaces in correlated_properties.json. This commit also
implements a stub callback API which will be triggered whenever a
property change signal is detected.

Change-Id: Ifdaa2310b397ae9616d921ba2ee657f61dce753e
Signed-off-by: Souvik Roy <souvikroyofficial10@gmail.com>
diff --git a/vpd-manager/include/constants.hpp b/vpd-manager/include/constants.hpp
index f88944c..a41192e 100644
--- a/vpd-manager/include/constants.hpp
+++ b/vpd-manager/include/constants.hpp
@@ -236,5 +236,7 @@
     "/usr/share/vpd/50003_power_vs.json";
 static constexpr auto power_vs_50001_json =
     "/usr/share/vpd/50001_power_vs.json";
+static constexpr auto correlatedPropJsonFile =
+    "/usr/share/vpd/correlated_properties.json";
 } // namespace constants
 } // namespace vpd
diff --git a/vpd-manager/include/listener.hpp b/vpd-manager/include/listener.hpp
index f387d5e..de75b8b 100644
--- a/vpd-manager/include/listener.hpp
+++ b/vpd-manager/include/listener.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "constants.hpp"
 #include "types.hpp"
 #include "worker.hpp"
 
@@ -53,6 +54,37 @@
      */
     void registerPresenceChangeCallback() noexcept;
 
+    /**
+     * @brief API to register callback for all correlated properties.
+     *
+     * This API registers properties changed callback for all the interfaces in
+     * given correlated properties JSON file.
+     *
+     * @param[in] i_correlatedPropJsonFile - File path of correlated properties
+     * JSON.
+     */
+    void registerCorrPropCallBack(
+        [[maybe_unused]] const std::string& i_correlatedPropJsonFile =
+            constants::correlatedPropJsonFile) noexcept;
+
+    /**
+     * @brief API to register properties changed callback.
+     *
+     * This API registers a properties changed callback for a specific interface
+     * under a service.
+     *
+     * @param[in] i_service - Service name.
+     * @param[in] i_interface - Interface name.
+     * @param[in] i_callBackFunction - Callback function.
+     *
+     * @throw FirmwareException
+     */
+    void registerPropChangeCallBack(
+        [[maybe_unused]] const std::string& i_service,
+        [[maybe_unused]] const std::string& i_interface,
+        [[maybe_unused]] std::function<void(sdbusplus::message_t& i_msg)>
+            i_callBackFunction);
+
   private:
     /**
      * @brief API to process host state change callback.
@@ -76,6 +108,13 @@
     void presentPropertyChangeCallback(
         sdbusplus::message_t& i_msg) const noexcept;
 
+    /**
+     * @brief API which is called when correlated property change is detected
+     *
+     * @param[in] i_msg - Callback message.
+     */
+    void correlatedPropChangedCallBack(sdbusplus::message_t& i_msg) noexcept;
+
     // Shared pointer to worker class
     const std::shared_ptr<Worker>& m_worker;
 
diff --git a/vpd-manager/oem-handler/ibm_handler.cpp b/vpd-manager/oem-handler/ibm_handler.cpp
index 45e8759..60b0ee8 100644
--- a/vpd-manager/oem-handler/ibm_handler.cpp
+++ b/vpd-manager/oem-handler/ibm_handler.cpp
@@ -171,6 +171,11 @@
             {
                 m_backupAndRestoreObj->backupAndRestore();
             }
+
+            if (m_eventListener)
+            {
+                m_eventListener->registerCorrPropCallBack();
+            }
         }
         else
         {
diff --git a/vpd-manager/src/listener.cpp b/vpd-manager/src/listener.cpp
index caceeea..333ace3 100644
--- a/vpd-manager/src/listener.cpp
+++ b/vpd-manager/src/listener.cpp
@@ -2,6 +2,8 @@
 
 #include "constants.hpp"
 #include "event_logger.hpp"
+#include "exceptions.hpp"
+#include "logger.hpp"
 #include "utility/dbus_utility.hpp"
 #include "utility/json_utility.hpp"
 
@@ -245,4 +247,65 @@
     }
 }
 
+void Listener::registerCorrPropCallBack(
+    [[maybe_unused]] const std::string& i_correlatedPropJsonFile) noexcept
+{
+    try
+    {
+        /* TODO:
+        Parse correlated_properties JSON, and register callback for all
+        interfaces under all services */
+    }
+    catch (const std::exception& l_ex)
+    {
+        EventLogger::createSyncPel(
+            EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
+            __FILE__, __FUNCTION__, 0, EventLogger::getErrorMsg(l_ex),
+            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+    }
+}
+
+void Listener::registerPropChangeCallBack(
+    [[maybe_unused]] const std::string& i_service,
+    [[maybe_unused]] const std::string& i_interface,
+    [[maybe_unused]] std::function<void(sdbusplus::message_t& i_msg)>
+        i_callBackFunction)
+{
+    try
+    {
+        /*TODO:
+        Create match object based on service name, interface and callback
+        function.
+        */
+    }
+    catch (const std::exception& l_ex)
+    {
+        throw FirmwareException(l_ex.what());
+    }
+}
+
+void Listener::correlatedPropChangedCallBack(
+    sdbusplus::message_t& i_msg) noexcept
+{
+    try
+    {
+        if (i_msg.is_method_error())
+        {
+            throw DbusException("Error in reading property change signal.");
+        }
+
+        /*TODO:
+        1. Extract interface, object path and property name from the message
+        2. Use correlated JSON to find target {object path, interface,
+        property/properties} to update*/
+    }
+    catch (const std::exception& l_ex)
+    {
+        EventLogger::createSyncPel(
+            EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
+            __FILE__, __FUNCTION__, 0, EventLogger::getErrorMsg(l_ex),
+            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+    }
+}
+
 } // namespace vpd