sensor-cache: Use async calls in get sensor reading

Use the async calls in ipmiSensorGetSensorReading() for cached sensors.

Note that the code was using sdbusplus::message as the parameter for the
getFunc(), now it could be simplified to ipmi::PropertyMap and unify the
two cases: property update callback and getting property.

Tested: Verify the ipmi sensor list works fine.

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: If7afed410f794a5317b8d4b4965cac291a735d12
diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp
index 97d11a7..62b58a1 100644
--- a/include/ipmid/types.hpp
+++ b/include/ipmid/types.hpp
@@ -175,8 +175,8 @@
 #ifndef FEATURE_SENSORS_CACHE
     std::function<GetSensorResponse(const Info&)> getFunc;
 #else
-    std::function<std::optional<GetSensorResponse>(
-        uint8_t, const Info&, sdbusplus::message::message&)>
+    std::function<std::optional<GetSensorResponse>(uint8_t, const Info&,
+                                                   const ipmi::PropertyMap&)>
         getFunc;
 #endif
     Mutability mutability;
diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp
index d502268..949b732 100644
--- a/sensordatahandler.cpp
+++ b/sensordatahandler.cpp
@@ -205,21 +205,8 @@
 }
 #else
 std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
-                                           sdbusplus::message::message& msg)
+                                           const PropertyMap& /*properties*/)
 {
-    auto type = msg.get_type();
-    if (type == msgTypeSignal)
-    {
-        // This is signal callback
-        std::string interfaceName;
-        msg.read(interfaceName);
-        if (interfaceName != sensorInfo.sensorInterface)
-        {
-            // Not the interface we need
-            return {};
-        }
-    }
-
     // The assertion may contain multiple properties
     // So we have to get the properties from DBus anyway
     auto response = mapDbusToAssertion(sensorInfo, sensorInfo.sensorPath,
@@ -234,21 +221,8 @@
 }
 
 std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
-                                            sdbusplus::message::message& msg)
+                                            const PropertyMap& /*properties*/)
 {
-    auto type = msg.get_type();
-    if (type == msgTypeSignal)
-    {
-        // This is signal callback
-        std::string interfaceName;
-        msg.read(interfaceName);
-        if (interfaceName != sensorInfo.sensorInterface)
-        {
-            // Not the interface we need
-            return {};
-        }
-    }
-
     // The eventdata2 may contain multiple properties
     // So we have to get the properties from DBus anyway
     auto response = mapDbusToEventdata2(sensorInfo);
@@ -476,21 +450,8 @@
 #else
 
 std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
-                                           sdbusplus::message::message& msg)
+                                           const PropertyMap& /*properties*/)
 {
-    auto type = msg.get_type();
-    if (type == msgTypeSignal)
-    {
-        // This is signal callback
-        std::string interfaceName;
-        msg.read(interfaceName);
-        if (interfaceName != sensorInfo.sensorInterface)
-        {
-            // Not the interface we need
-            return {};
-        }
-    }
-
     // The assertion may contain multiple properties
     // So we have to get the properties from DBus anyway
     namespace fs = std::filesystem;
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
index 6768634..1cb2b40 100644
--- a/sensordatahandler.hpp
+++ b/sensordatahandler.hpp
@@ -30,16 +30,14 @@
 using Assertion = uint16_t;
 using Deassertion = uint16_t;
 using AssertionSet = std::pair<Assertion, Deassertion>;
-
 using Service = std::string;
 using Path = std::string;
 using Interface = std::string;
-
 using ServicePath = std::pair<Path, Service>;
-
 using Interfaces = std::vector<Interface>;
-
 using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
+using PropertyMap = ipmi::PropertyMap;
+
 using namespace phosphor::logging;
 
 /** @brief get the D-Bus service and service path
@@ -355,7 +353,7 @@
  *  @return Response for get sensor reading command.
  */
 std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
-                                           sdbusplus::message::message& msg);
+                                           const PropertyMap& properties);
 
 /**
  *  @brief Maps the Dbus info to the reading field in the Get sensor reading
@@ -368,7 +366,7 @@
  *  @return Response for get sensor reading command.
  */
 std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
-                                            sdbusplus::message::message& msg);
+                                            const PropertyMap& properties);
 
 /**
  *  @brief readingAssertion is a case where the entire assertion state field
@@ -382,30 +380,13 @@
  *  @return Response for get sensor reading command.
  */
 template <typename T>
-std::optional<GetSensorResponse>
-    readingAssertion(uint8_t id, const Info& sensorInfo,
-                     sdbusplus::message::message& msg)
+std::optional<GetSensorResponse> readingAssertion(uint8_t id,
+                                                  const Info& sensorInfo,
+                                                  const PropertyMap& properties)
 {
-    auto type = msg.get_type();
-    if (type == msgTypeSignal)
-    {
-        // This is signal callback
-        std::string interfaceName;
-        msg.read(interfaceName);
-        if (interfaceName != sensorInfo.sensorInterface)
-        {
-            // Not the interface we need
-            return {};
-        }
-    }
-    // Now the message only contains the properties.
     GetSensorResponse response{};
-    std::map<std::string, ipmi::Value> properties;
-
     enableScanning(&response);
 
-    msg.read(properties);
-
     auto iter = properties.find(
         sensorInfo.propertyInterfaces.begin()->second.begin()->first);
     if (iter == properties.end())
@@ -435,63 +416,33 @@
  */
 template <typename T>
 std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
-                                             sdbusplus::message::message& msg)
+                                             const PropertyMap& properties)
 {
-    std::map<std::string, ipmi::Value> properties;
-    auto type = msg.get_type();
-    if (type == msgTypeSignal)
+    auto iter = properties.find("Functional");
+    if (iter != properties.end())
     {
-        // This is signal callback
-        std::string interfaceName;
-        msg.read(interfaceName);
-
-        if (interfaceName ==
-            "xyz.openbmc_project.State.Decorator.OperationalStatus")
-        {
-            msg.read(properties);
-            auto val = properties.find("Functional");
-            if (val != properties.end())
-            {
-                sensorCacheMap[id]->functional = std::get<bool>(val->second);
-            }
-            return {};
-        }
-        if (interfaceName == "xyz.openbmc_project.State.Decorator.Availability")
-        {
-            msg.read(properties);
-            auto val = properties.find("Available");
-            if (val != properties.end())
-            {
-                sensorCacheMap[id]->available = std::get<bool>(val->second);
-            }
-            return {};
-        }
-
-        if (interfaceName != sensorInfo.sensorInterface)
-        {
-            // Not the interface we need
-            return {};
-        }
-
-#ifdef UPDATE_FUNCTIONAL_ON_FAIL
-        if (sensorCacheMap[id])
-        {
-            if (!sensorCacheMap[id]->functional)
-            {
-                throw SensorFunctionalError();
-            }
-        }
-#endif
+        sensorCacheMap[id]->functional = std::get<bool>(iter->second);
     }
-    // Now the message only contains the properties.
+    iter = properties.find("Available");
+    if (iter != properties.end())
+    {
+        sensorCacheMap[id]->available = std::get<bool>(iter->second);
+    }
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+    if (sensorCacheMap[id])
+    {
+        if (!sensorCacheMap[id]->functional)
+        {
+            throw SensorFunctionalError();
+        }
+    }
+#endif
 
     GetSensorResponse response{};
 
     enableScanning(&response);
 
-    msg.read(properties);
-
-    auto iter = properties.find(
+    iter = properties.find(
         sensorInfo.propertyInterfaces.begin()->second.begin()->first);
     if (iter == properties.end())
     {
@@ -724,7 +675,7 @@
  *  @return Response for get sensor reading command.
  */
 std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
-                                           sdbusplus::message::message& msg);
+                                           const PropertyMap& properties);
 
 #endif
 
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index b82e74b..6cc34f9 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -116,7 +116,12 @@
                          [&s](auto& msg) {
                              try
                              {
-                                 s.second.getFunc(s.first, s.second, msg);
+                                 // This is signal callback
+                                 std::string interfaceName;
+                                 msg.read(interfaceName);
+                                 ipmi::PropertyMap props;
+                                 msg.read(props);
+                                 s.second.getFunc(s.first, s.second, props);
                              }
                              catch (const std::exception& e)
                              {
@@ -471,7 +476,7 @@
               uint8_t, // threshold levels states
               uint8_t  // discrete reading sensor states
               >
-    ipmiSensorGetSensorReading(uint8_t sensorNum)
+    ipmiSensorGetSensorReading(ipmi::Context::ptr& ctx, uint8_t sensorNum)
 {
     if (sensorNum == 0xFF)
     {
@@ -492,29 +497,29 @@
     try
     {
 #ifdef FEATURE_SENSORS_CACHE
-        // TODO
-        const auto& sensorData = sensorCacheMap[sensorNum];
+        auto& sensorData = sensorCacheMap[sensorNum];
         if (!sensorData.has_value())
         {
             // No cached value, try read it
-            sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+            std::string service;
+            boost::system::error_code ec;
             const auto& sensorInfo = iter->second;
-            auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
-                                            sensorInfo.sensorPath);
-            try
+            ec = ipmi::getService(ctx, sensorInfo.sensorInterface,
+                                  sensorInfo.sensorPath, service);
+            if (ec)
             {
-                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);
+                return ipmi::responseUnspecifiedError();
             }
-            catch (const std::exception& e)
+
+            ipmi::PropertyMap props;
+            ec = ipmi::getAllDbusProperties(
+                ctx, service, sensorInfo.sensorPath,
+                sensorInfo.propertyInterfaces.begin()->first, props);
+            if (ec)
             {
-                fprintf(stderr, "Failed to get sensor %s\n",
-                        sensorInfo.sensorPath.c_str());
+                fprintf(stderr, "Failed to get sensor %s, %d: %s\n",
+                        sensorInfo.sensorPath.c_str(), ec.value(),
+                        ec.message().c_str());
                 // Intitilizing with default values
                 constexpr uint8_t senReading = 0;
                 constexpr uint5_t reserved{0};
@@ -529,6 +534,7 @@
                                              assertionStatesLsb,
                                              assertionStatesMsb);
             }
+            sensorInfo.getFunc(sensorNum, sensorInfo, props);
         }
         return ipmi::responseSuccess(
             sensorData->response.reading, uint5_t(0),