Add signal based update

update sensors whenever there is a update in parameter
dbus sensor. This will register a signal for each dbus
sensor parameter and will calculate new value is there
is a change in any param sensor value.

Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
Change-Id: I164bbb32eea6f29a2378119cdf3ac07492758b09
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/dbusSensor.hpp b/dbusSensor.hpp
index 8ab17a2..4756cad 100644
--- a/dbusSensor.hpp
+++ b/dbusSensor.hpp
@@ -1,9 +1,12 @@
 #include "dbusUtils.hpp"
 
 #include <sdbusplus/bus.hpp>
+#include <sdbusplus/server.hpp>
 
 const char* sensorIntf = "xyz.openbmc_project.Sensor.Value";
 
+int handleDbusSignal(sd_bus_message* msg, void* usrData, sd_bus_error* err);
+
 class DbusSensor
 {
   public:
@@ -15,8 +18,12 @@
      * @param[in] bus     - Handle to system dbus
      * @param[in] path    - The Dbus path of sensor
      */
-    DbusSensor(sdbusplus::bus::bus& bus, const std::string& path) :
-        bus(bus), path(path)
+    DbusSensor(sdbusplus::bus::bus& bus, const std::string& path, void* ctx) :
+        bus(bus), path(path),
+        signal(
+            bus,
+            sdbusplus::bus::match::rules::propertiesChanged(path, sensorIntf),
+            handleDbusSignal, ctx)
     {
         servName = getService(bus, path, sensorIntf);
     }
@@ -35,4 +42,6 @@
     std::string path;
     /** @brief service name for the sensor daemon */
     std::string servName;
+    /** @brief signal for sensor value change */
+    sdbusplus::server::match::match signal;
 };
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index ac5e123..c8b70ab 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -16,6 +16,31 @@
 
 using namespace phosphor::logging;
 
+int handleDbusSignal(sd_bus_message* msg, void* usrData, sd_bus_error*)
+{
+    if (usrData == nullptr)
+    {
+        throw std::runtime_error("Invalid match");
+    }
+
+    auto sdbpMsg = sdbusplus::message::message(msg);
+    std::string msgIfce;
+    std::map<std::string, std::variant<int64_t, double, bool>> msgData;
+
+    sdbpMsg.read(msgIfce, msgData);
+
+    if (msgData.find("Value") != msgData.end())
+    {
+        using namespace phosphor::virtualSensor;
+        VirtualSensor* obj = static_cast<VirtualSensor*>(usrData);
+        // TODO(openbmc/phosphor-virtual-sensor#1): updateVirtualSensor should
+        // be changed to take the information we got from the signal, to avoid
+        // having to do numerous dbus queries.
+        obj->updateVirtualSensor();
+    }
+    return 0;
+}
+
 namespace phosphor
 {
 namespace virtualSensor
@@ -115,7 +140,8 @@
                     std::string objPath(sensorDbusPath);
                     objPath += sensorType + "/" + name;
 
-                    auto paramPtr = std::make_unique<SensorParam>(bus, objPath);
+                    auto paramPtr =
+                        std::make_unique<SensorParam>(bus, objPath, this);
                     std::string name = j["ParamName"];
                     symbols.create_variable(name);
                     paramMap.emplace(std::move(name), std::move(paramPtr));
diff --git a/virtualSensor.hpp b/virtualSensor.hpp
index 0e000e9..c8fd04c 100644
--- a/virtualSensor.hpp
+++ b/virtualSensor.hpp
@@ -51,9 +51,10 @@
      *
      * @param[in] bus     - Handle to system dbus
      * @param[in] path    - The Dbus path of sensor
+     * @param[in] ctx     - sensor context for update
      */
-    SensorParam(sdbusplus::bus::bus& bus, std::string path) :
-        dbusSensor(std::make_unique<DbusSensor>(bus, path)),
+    SensorParam(sdbusplus::bus::bus& bus, std::string path, void* ctx) :
+        dbusSensor(std::make_unique<DbusSensor>(bus, path, ctx)),
         paramType(dbusParam)
     {}