sensor-cache: Implement reading data

Implement reading data in property changed callback.
With sensor-cache, the sensor's property is returned by the
callback of propertiesChanged match, parse the property from the message
and generate the sensor's response.

Tested: Verify the sensors using `readingData` have valid values in
        QEMU, e.g.

        Inlet_Temp       | 20.000     | degrees C  | ok    | na        | 0.000     | 5.000     | 38.000    | 43.000    | na

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I2c6328cb6001d0daf2045d17e73773dccf55d521
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 34565a1..7e0c7dc 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -92,9 +92,7 @@
 std::map<uint8_t, std::unique_ptr<sdbusplus::bus::match::match>>
     sensorUpdatedMatches __attribute__((init_priority(101)));
 
-using SensorCacheMap =
-    std::map<uint8_t, std::optional<ipmi::sensor::GetSensorResponse>>;
-SensorCacheMap sensorCacheMap __attribute__((init_priority(101)));
+ipmi::sensor::SensorCacheMap sensorCacheMap __attribute__((init_priority(101)));
 
 void initSensorMatches()
 {
@@ -110,15 +108,21 @@
                     // TODO
                 }));
         sensorUpdatedMatches.emplace(
-            s.first,
-            std::make_unique<sdbusplus::bus::match::match>(
-                bus,
-                type::signal() + path(s.second.sensorPath) +
-                    member("PropertiesChanged"s) +
-                    interface("org.freedesktop.DBus.Properties"s),
-                [id = s.first, obj = s.second.sensorPath](auto& /*msg*/) {
-                    // TODO
-                }));
+            s.first, std::make_unique<sdbusplus::bus::match::match>(
+                         bus,
+                         type::signal() + path(s.second.sensorPath) +
+                             member("PropertiesChanged"s) +
+                             interface("org.freedesktop.DBus.Properties"s),
+                         [&s](auto& msg) {
+                             try
+                             {
+                                 s.second.getFunc(s.first, s.second, msg);
+                             }
+                             catch (const std::exception& e)
+                             {
+                                 sensorCacheMap[s.first].reset();
+                             }
+                         }));
     }
 }
 #endif
@@ -489,7 +493,30 @@
     {
 #ifdef FEATURE_SENSORS_CACHE
         // TODO
-        return ipmi::responseSuccess();
+        const auto& sensorData = sensorCacheMap[sensorNum];
+        if (!sensorData.has_value())
+        {
+            // Intitilizing with default values
+            constexpr uint8_t senReading = 0;
+            constexpr uint5_t reserved{0};
+            constexpr bool readState = true;
+            constexpr bool senScanState = false;
+            constexpr bool allEventMessageState = false;
+            constexpr uint8_t assertionStatesLsb = 0;
+            constexpr uint8_t assertionStatesMsb = 0;
+
+            return ipmi::responseSuccess(
+                senReading, reserved, readState, senScanState,
+                allEventMessageState, assertionStatesLsb, assertionStatesMsb);
+        }
+        return ipmi::responseSuccess(
+            sensorData->response.reading, uint5_t(0),
+            sensorData->response.readingOrStateUnavailable,
+            sensorData->response.scanningEnabled,
+            sensorData->response.allEventMessagesEnabled,
+            sensorData->response.thresholdLevelsStates,
+            sensorData->response.discreteReadingSensorStates);
+
 #else
         ipmi::sensor::GetSensorResponse getResponse =
             iter->second.getFunc(iter->second);