Allow async_method_call to provide opt message

Real D-Bus error message will not be known through
boost::system::error_code and hence requires message::message
to be forwarded to the caller, through which any  D-Bus error
message can be read from the sd_bus_error of the message::message.

Tested:
Added the template for the same, and cross verified with
async_method_call, of which handler will accept both error_code
& message::message as argument

Change-Id: I7ecace1fb880a303dd487fa9de85c043db3413f8
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
diff --git a/sdbusplus/asio/connection.hpp b/sdbusplus/asio/connection.hpp
index 4c447f8..8dbd568 100644
--- a/sdbusplus/asio/connection.hpp
+++ b/sdbusplus/asio/connection.hpp
@@ -102,7 +102,7 @@
      *                       continuation for the async dbus method call. The
      *                       arguments to parse on the return are deduced from
      *                       the handler's signature and then passed in along
-     *                       with an error code.
+     *                       with an error code and optional message::message
      *  @param[in] service - The service to call.
      *  @param[in] objpath - The object's path for the call.
      *  @param[in] interf - The object's interface to call.
@@ -128,8 +128,20 @@
                           message::message& r) mutable {
             using FunctionTuple =
                 boost::callable_traits::args_t<MessageHandler>;
-            using UnpackType = typename utility::strip_first_arg<
-                typename utility::decay_tuple<FunctionTuple>::type>::type;
+            using FunctionTupleType =
+                typename utility::decay_tuple<FunctionTuple>::type;
+            constexpr bool returnWithMsg = []() {
+                if constexpr (std::tuple_size_v<FunctionTupleType>> 1)
+                {
+                    return std::is_same_v<
+                        std::tuple_element_t<1, FunctionTupleType>,
+                        sdbusplus::message::message>;
+                }
+                return false;
+            }();
+            using UnpackType =
+                typename utility::strip_first_n_args<returnWithMsg ? 2 : 1,
+                                                     FunctionTupleType>::type;
             UnpackType responseData;
             if (!ec)
             {
@@ -146,8 +158,19 @@
             }
             // Note.  Callback is called whether or not the unpack was
             // successful to allow the user to implement their own handling
-            auto response = std::tuple_cat(std::make_tuple(ec), responseData);
-            std::apply(handler, response);
+            if constexpr (returnWithMsg)
+            {
+                auto response = std::tuple_cat(std::make_tuple(ec),
+                                               std::forward_as_tuple(r),
+                                               std::move(responseData));
+                std::apply(handler, response);
+            }
+            else
+            {
+                auto response = std::tuple_cat(std::make_tuple(ec),
+                                               std::move(responseData));
+                std::apply(handler, response);
+            }
         });
     }