message: Add call method

The message already knows what bus it belongs to from its construction.

Change-Id: I4fa38b2e4f6aa1dc537d8f7ce923e48e54d8ab7b
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/sdbusplus/message.hpp b/include/sdbusplus/message.hpp
index 18fe883..d737939 100644
--- a/include/sdbusplus/message.hpp
+++ b/include/sdbusplus/message.hpp
@@ -363,6 +363,31 @@
         method_return();
     }
 
+    /** @brief Perform a message call.
+     *         Errors generated by this call come from underlying dbus
+     *         related errors *AND* from any method call that results
+     *         in a METHOD_ERROR. This means you do not need to check
+     *         is_method_error() on the returned message.
+     *
+     *  @param[in] m - The method_call message.
+     *  @param[in] timeout_us - The timeout for the method call.
+     *
+     *  @return The response message.
+     */
+    auto call(std::optional<SdBusDuration> timeout = std::nullopt)
+    {
+        sd_bus_error error = SD_BUS_ERROR_NULL;
+        sd_bus_message* reply = nullptr;
+        auto timeout_us = timeout ? timeout->count() : 0;
+        int r = _intf->sd_bus_call(nullptr, get(), timeout_us, &error, &reply);
+        if (r < 0)
+        {
+            throw exception::SdBusError(&error, "sd_bus_call");
+        }
+
+        return message(reply, _intf, std::false_type());
+    }
+
     friend struct sdbusplus::bus::bus;
 
     /** @brief Get a pointer to the owned 'msgp_t'.