sensor-cache: Read sensor data when there is no cache

When IPMI starts and the sensor has no match callback, the sensor cache
is empty. Read the sensor data in such case and cache it.

Tested: Verify the sensor list works as expected, the first sensor
        list takes longer time, and the following sensor list takes less
        time because of the cache.

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: Icc33185b93cf21462584b3817b7c522e24b70baf
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 7e0c7dc..b82e74b 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -496,18 +496,39 @@
         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;
+            // No cached value, try read it
+            sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+            const auto& sensorInfo = iter->second;
+            auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
+                                            sensorInfo.sensorPath);
+            try
+            {
+                auto method = bus.new_method_call(
+                    service.c_str(), sensorInfo.sensorPath.c_str(),
+                    "org.freedesktop.DBus.Properties", "GetAll");
+                method.append(
+                    sensorInfo.propertyInterfaces.begin()->first.c_str());
+                auto reply = bus.call(method);
+                sensorInfo.getFunc(sensorNum, sensorInfo, reply);
+            }
+            catch (const std::exception& e)
+            {
+                fprintf(stderr, "Failed to get sensor %s\n",
+                        sensorInfo.sensorPath.c_str());
+                // 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(senReading, reserved, readState,
+                                             senScanState, allEventMessageState,
+                                             assertionStatesLsb,
+                                             assertionStatesMsb);
+            }
         }
         return ipmi::responseSuccess(
             sensorData->response.reading, uint5_t(0),