cater for property change signal to invalidate fru data

Resolves openbmc/openbmc#1560

Change-Id: I90897959dab76181a6006c372c4b60cc1bdd0c0c
Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
diff --git a/read_fru_data.cpp b/read_fru_data.cpp
index 5388926..b23498e 100644
--- a/read_fru_data.cpp
+++ b/read_fru_data.cpp
@@ -7,7 +7,6 @@
 #include "utils.hpp"
 
 extern const FruMap frus;
-
 namespace ipmi
 {
 namespace fru
@@ -15,6 +14,7 @@
 using namespace phosphor::logging;
 using InternalFailure =
         sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+std::unique_ptr<sdbusplus::bus::match_t> matchPtr(nullptr);
 
 static constexpr auto INV_INTF  = "xyz.openbmc_project.Inventory.Manager";
 static constexpr auto OBJ_PATH  = "/xyz/openbmc_project/inventory";
@@ -66,6 +66,57 @@
     return value;
 }
 
+void processFruPropChange(sdbusplus::message::message& msg)
+{
+    if(cache::fruMap.empty())
+    {
+        return;
+    }
+    std::string path = msg.get_path();
+    //trim the object base path, if found at the beginning
+    if (path.compare(0, strlen(OBJ_PATH), OBJ_PATH) == 0)
+    {
+        path.erase(0, strlen(OBJ_PATH));
+    }
+    for (auto& fru : frus)
+    {
+        bool found = false;
+        auto& fruId = fru.first;
+        auto& instanceList = fru.second;
+        for (auto& instance : instanceList)
+        {
+            if(instance.first == path)
+            {
+                found = true;
+                break;
+            }
+        }
+        if (found)
+        {
+            cache::fruMap.erase(fruId);
+            break;
+        }
+    }
+}
+
+//register for fru property change
+int registerCallbackHandler()
+{
+    if(matchPtr == nullptr)
+    {
+        using namespace sdbusplus::bus::match::rules;
+        sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+        matchPtr = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            path_namespace(OBJ_PATH) +
+            type::signal() +
+            member("PropertiesChanged") +
+            interface(PROP_INTF),
+            std::bind(processFruPropChange, std::placeholders::_1));
+    }
+    return 0;
+}
+
 /**
  * @brief Read FRU property values from Inventory
  *
diff --git a/read_fru_data.hpp b/read_fru_data.hpp
index f536cf2..d715858 100644
--- a/read_fru_data.hpp
+++ b/read_fru_data.hpp
@@ -18,5 +18,11 @@
  */
 const FruAreaData& getFruAreaData(const FRUId& fruNum);
 
+/**
+ * @brief Register callback handler into DBUS for PropertyChange events
+ *
+ * @return negative value on failure
+ */
+int registerCallbackHandler();
 } //fru
 } //ipmi
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 36e1bb4..b38e06c 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -712,6 +712,7 @@
     ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_READ_FRU_DATA, NULL,
             ipmi_storage_read_fru_data, PRIVILEGE_OPERATOR);
 
+    ipmi::fru::registerCallbackHandler();
     return;
 }