bus: 'method_return' for responding to method-calls

Change-Id: Id959e500f3cba7f6e3b28c572ead95879bce6275
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/sdbusplus/bus.hpp b/sdbusplus/bus.hpp
index 7cb27b7..24e9211 100644
--- a/sdbusplus/bus.hpp
+++ b/sdbusplus/bus.hpp
@@ -137,6 +137,30 @@
         sd_bus_call(_bus.get(), m.get(), timeout_us, nullptr, nullptr);
     }
 
+    /** @brief Perform a 'method-return' response call.
+     *
+     *  @param[in] m - The method-return type message to send.
+     *
+     *  This is a static method on bus because:
+     *      1. The typical caller of this is from within a method callback
+     *         on an sd-bus managed object, which does not have access to
+     *         its own bus.
+     *      2. Due to header dependency, sdbusplus::message cannot create
+     *         an sdbusplus::bus itself.
+     *      3. We do not want sdbusplus::message to call sd_bus_call directly,
+     *         in order to have common error handling code with bus::call.
+     */
+    static void method_return(message::message& m)
+    {
+        auto b = bus(sd_bus_message_get_bus(m.get()));
+
+        // Need to increment the reference since 'b' will now decrement
+        // on destruction.
+        sd_bus_ref(b._bus.get());
+
+        b.call_noreply(m);
+    }
+
     private:
         details::bus _bus;
 };
@@ -162,6 +186,9 @@
     return bus(b);
 }
 
+/** Alias sdbusplus::bus::bus::method_return for convenience. */
+inline void method_return(message::message& m) { return bus::method_return(m); }
+
 
 } // namespace bus