Added asynchronous callDbusMethod

This path added two callDbusMethod methods, one without method return
value (default return ec), and the other with method return value.

Change-Id: I16503fe24adc0f3896a861972751d532b6361ef9
Signed-off-by: George Liu <liuxiwei@ieisystem.com>
diff --git a/chassishandler.cpp b/chassishandler.cpp
index accf781..ba6be52 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -890,8 +890,8 @@
         return -1;
     }
 
-    ctx->bus->yield_method_call<void>(ctx->yield, ec, nmiObj.second,
-                                      nmiObj.first, nmiIntfName, "NMI");
+    ec = ipmi::callDbusMethod(ctx, nmiObj.second, nmiObj.first, nmiIntfName,
+                              "NMI");
     if (ec)
     {
         lg2::error("NMI call failed: {ERROR}", "ERROR", ec.message());
@@ -2280,8 +2280,8 @@
 ipmi::RspType<uint3_t, // policy support
               uint5_t  // reserved
               >
-    ipmiChassisSetPowerRestorePolicy(boost::asio::yield_context yield,
-                                     uint3_t policy, uint5_t reserved)
+    ipmiChassisSetPowerRestorePolicy(ipmi::Context::ptr ctx, uint3_t policy,
+                                     uint5_t reserved)
 {
     power_policy::DbusValue value =
         power_policy::RestorePolicy::Policy::AlwaysOff;
@@ -2313,19 +2313,13 @@
         settings::Objects& objects = chassis::internal::cache::getObjects();
         const settings::Path& powerRestoreSetting =
             objects.map.at(chassis::internal::powerRestoreIntf).front();
-        std::variant<std::string> property = convertForMessage(value);
 
-        auto sdbusp = getSdBus();
-        boost::system::error_code ec;
-        sdbusp->yield_method_call<void>(
-            yield, ec,
-            objects
-                .service(powerRestoreSetting,
-                         chassis::internal::powerRestoreIntf)
-                .c_str(),
-            powerRestoreSetting, ipmi::PROP_INTF, "Set",
-            chassis::internal::powerRestoreIntf, "PowerRestorePolicy",
-            property);
+        boost::system::error_code ec = ipmi::setDbusProperty(
+            ctx,
+            objects.service(powerRestoreSetting,
+                            chassis::internal::powerRestoreIntf),
+            powerRestoreSetting, chassis::internal::powerRestoreIntf,
+            "PowerRestorePolicy", convertForMessage(value));
         if (ec)
         {
             lg2::error("Unspecified Error");
diff --git a/dbus-sdr/sdrutils.cpp b/dbus-sdr/sdrutils.cpp
index 303a696..9523593 100644
--- a/dbus-sdr/sdrutils.cpp
+++ b/dbus-sdr/sdrutils.cpp
@@ -449,15 +449,15 @@
         return ipmiDecoratorPaths;
     }
 
+    using Paths = std::vector<std::string>;
     boost::system::error_code ec;
-    std::vector<std::string> paths =
-        (*ctx)->bus->yield_method_call<std::vector<std::string>>(
-            (*ctx)->yield, ec, "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
-            int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Decorator.Ipmi"});
+    Paths paths = ipmi::callDbusMethod<Paths>(
+        *ctx, ec, "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/", int32_t(0),
+        std::array<const char*, 1>{
+            "xyz.openbmc_project.Inventory.Decorator.Ipmi"});
+
     if (ec)
     {
         return ipmiDecoratorPaths;
diff --git a/dbus-sdr/storagecommands.cpp b/dbus-sdr/storagecommands.cpp
index 3d16344..e8c4223 100644
--- a/dbus-sdr/storagecommands.cpp
+++ b/dbus-sdr/storagecommands.cpp
@@ -26,6 +26,7 @@
 #include <ipmid/api.hpp>
 #include <ipmid/message.hpp>
 #include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
 #include <phosphor-logging/lg2.hpp>
 #include <sdbusplus/message/types.hpp>
 #include <sdbusplus/timer.hpp>
@@ -80,12 +81,8 @@
     boost::container::flat_map<sdbusplus::message::object_path, ObjectType>;
 using ManagedEntry = std::pair<sdbusplus::message::object_path, ObjectType>;
 
-constexpr static const char* selLoggerServiceName =
-    "xyz.openbmc_project.Logging.IPMI";
 constexpr static const char* fruDeviceServiceName =
     "xyz.openbmc_project.FruDevice";
-constexpr static const char* entityManagerServiceName =
-    "xyz.openbmc_project.EntityManager";
 constexpr static const size_t writeTimeoutSeconds = 10;
 constexpr static const char* chassisTypeRackMount = "23";
 constexpr static const char* chassisTypeMainServer = "17";
@@ -251,13 +248,11 @@
     cacheAddr = deviceFind->second.second;
 
     boost::system::error_code ec;
+    std::vector<uint8_t> fru = ipmi::callDbusMethod<std::vector<uint8_t>>(
+        ctx, ec, fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
+        "xyz.openbmc_project.FruDeviceManager", "GetRawFru", cacheBus,
+        cacheAddr);
 
-    std::vector<uint8_t> fru =
-        ctx->bus->yield_method_call<std::vector<uint8_t>>(
-            ctx->yield, ec, fruDeviceServiceName,
-            "/xyz/openbmc_project/FruDevice",
-            "xyz.openbmc_project.FruDeviceManager", "GetRawFru", cacheBus,
-            cacheAddr);
     if (ec)
     {
         lg2::error("Couldn't get raw fru: {ERROR}", "ERROR", ec.message());
@@ -598,9 +593,8 @@
 
     // todo: this should really use caching, this is a very inefficient lookup
     boost::system::error_code ec;
-
-    ManagedObjectType entities = ctx->bus->yield_method_call<ManagedObjectType>(
-        ctx->yield, ec, entityManagerServiceName,
+    ManagedObjectType entities = ipmi::callDbusMethod<ManagedObjectType>(
+        ctx, ec, "xyz.openbmc_project.EntityManager",
         "/xyz/openbmc_project/inventory", "org.freedesktop.DBus.ObjectManager",
         "GetManagedObjects");
 
@@ -1186,13 +1180,13 @@
     // cleared
     cancelSELReservation();
 
-    boost::system::error_code ec;
-    ctx->bus->yield_method_call<>(ctx->yield, ec, selLoggerServiceName,
-                                  "/xyz/openbmc_project/Logging/IPMI",
-                                  "xyz.openbmc_project.Logging.IPMI", "Clear");
+    boost::system::error_code ec =
+        ipmi::callDbusMethod(ctx, "xyz.openbmc_project.Logging.IPMI",
+                             "/xyz/openbmc_project/Logging/IPMI",
+                             "xyz.openbmc_project.Logging.IPMI", "Clear");
     if (ec)
     {
-        std::cerr << "error in clear SEL: " << ec << std::endl;
+        std::cerr << "error in clear SEL: " << ec.message() << std::endl;
         return ipmi::responseUnspecifiedError();
     }
 
diff --git a/include/ipmid/utils.hpp b/include/ipmid/utils.hpp
index c099da0..4547dc0 100644
--- a/include/ipmid/utils.hpp
+++ b/include/ipmid/utils.hpp
@@ -4,6 +4,7 @@
 #include <ipmid/api-types.hpp>
 #include <ipmid/message.hpp>
 #include <ipmid/types.hpp>
+#include <phosphor-logging/lg2.hpp>
 #include <sdbusplus/server.hpp>
 
 #include <chrono>
@@ -468,6 +469,31 @@
 
 } // namespace method_no_args
 
+template <typename... InputArgs>
+boost::system::error_code callDbusMethod(
+    ipmi::Context::ptr ctx, const std::string& service,
+    const std::string& objPath, const std::string& interface,
+    const std::string& method, const InputArgs&... args)
+{
+    boost::system::error_code ec;
+    ctx->bus->yield_method_call(ctx->yield, ec, service, objPath, interface,
+                                method, args...);
+
+    return ec;
+}
+
+template <typename RetType, typename... InputArgs>
+RetType callDbusMethod(ipmi::Context::ptr ctx, boost::system::error_code& ec,
+                       const std::string& service, const std::string& objPath,
+                       const std::string& interface, const std::string& method,
+                       const InputArgs&... args)
+{
+    auto rc = ctx->bus->yield_method_call<RetType>(
+        ctx->yield, ec, service, objPath, interface, method, args...);
+
+    return rc;
+}
+
 /** @brief Perform the low-level i2c bus write-read.
  *  @param[in] i2cBus - i2c bus device node name, such as /dev/i2c-2.
  *  @param[in] targetAddr - i2c device target address.
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
index 1e85a0d..f130780 100644
--- a/ipmid-new.cpp
+++ b/ipmid-new.cpp
@@ -30,6 +30,7 @@
 #include <ipmid/message.hpp>
 #include <ipmid/oemrouter.hpp>
 #include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
 #include <phosphor-logging/lg2.hpp>
 #include <sdbusplus/asio/connection.hpp>
 #include <sdbusplus/asio/object_server.hpp>
@@ -786,15 +787,14 @@
             // Responses in IPMI require a bit set.  So there ya go...
             netFn |= 0x01;
 
-            const char *dest, *path;
             constexpr const char* DBUS_INTF = "org.openbmc.HostIpmi";
 
-            dest = m.get_sender();
-            path = m.get_path();
-            boost::system::error_code ec;
-            bus->yield_method_call(yield, ec, dest, path, DBUS_INTF,
-                                   "sendMessage", seq, netFn, lun, cmd,
-                                   response->cc, response->payload.raw);
+            std::string dest = m.get_sender();
+            std::string path = m.get_path();
+            boost::system::error_code ec = ipmi::callDbusMethod(
+                ctx, dest, path, DBUS_INTF, "sendMessage", seq, netFn, lun, cmd,
+                response->cc, response->payload.raw);
+
             if (ec)
             {
                 lg2::error(