Legacy D-Bus interface must set yield_context

The legacy D-Bus interface was not setting the yield_context pointer
in the ipmi::Context struct. This means that a command coming in from
a legacy D-Bus interface that called a new-provider that uses the
yield_method_call function would segfault on a NULL pointer. This
change makes the legacy interface behave the same as the new
D-Bus interface by creating a new boost::coroutine for each command.

Tested-by: running a legacy ipmitool to ensure that the rewritten set
	   chassis power restore policy command worked without a
           segfault.

Change-Id: Ie45fff1fc222b9b949a9d3976bf9d1b2c29bd8f5
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
index 5eec4d1..7e77b12 100644
--- a/ipmid-new.cpp
+++ b/ipmid-new.cpp
@@ -739,29 +739,42 @@
 /* legacy alternative to executionEntry */
 void handleLegacyIpmiCommand(sdbusplus::message::message& m)
 {
-    unsigned char seq, netFn, lun, cmd;
-    std::vector<uint8_t> data;
+    // make a copy so the next two moves don't wreak havoc on the stack
+    sdbusplus::message::message b{m};
+    boost::asio::spawn(*getIoContext(), [b = std::move(b)](
+                                            boost::asio::yield_context yield) {
+        sdbusplus::message::message m{std::move(b)};
+        unsigned char seq, netFn, lun, cmd;
+        std::vector<uint8_t> data;
 
-    m.read(seq, netFn, lun, cmd, data);
+        m.read(seq, netFn, lun, cmd, data);
+        auto ctx = std::make_shared<ipmi::Context>(
+            netFn, cmd, 0, 0, ipmi::Privilege::Admin, 0, &yield);
+        auto request = std::make_shared<ipmi::message::Request>(
+            ctx, std::forward<std::vector<uint8_t>>(data));
+        ipmi::message::Response::ptr response =
+            ipmi::executeIpmiCommand(request);
 
-    auto ctx = std::make_shared<ipmi::Context>(netFn, cmd, 0, 0,
-                                               ipmi::Privilege::Admin);
-    auto request = std::make_shared<ipmi::message::Request>(
-        ctx, std::forward<std::vector<uint8_t>>(data));
-    ipmi::message::Response::ptr response = ipmi::executeIpmiCommand(request);
+        // Responses in IPMI require a bit set.  So there ya go...
+        netFn |= 0x01;
 
-    // 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";
 
-    const char *dest, *path;
-    constexpr const char* DBUS_INTF = "org.openbmc.HostIpmi";
-
-    dest = m.get_sender();
-    path = m.get_path();
-    getSdBus()->async_method_call([](boost::system::error_code ec) {}, dest,
-                                  path, DBUS_INTF, "sendMessage", seq, netFn,
-                                  lun, cmd, response->cc,
-                                  response->payload.raw);
+        dest = m.get_sender();
+        path = m.get_path();
+        boost::system::error_code ec;
+        getSdBus()->yield_method_call(yield, ec, dest, path, DBUS_INTF,
+                                      "sendMessage", seq, netFn, lun, cmd,
+                                      response->cc, response->payload.raw);
+        if (ec)
+        {
+            log<level::ERR>("Failed to send response to requestor",
+                            entry("ERROR=%s", ec.message().c_str()),
+                            entry("SENDER=%s", dest),
+                            entry("NETFN=0x%X", netFn), entry("CMD=0x%X", cmd));
+        }
+    });
 }
 
 #endif /* ALLOW_DEPRECATED_API */