Register new Control.Host bus in ipmid

This sets up the framework for future commits to implement
the required interfaces and signals in Control.Host

Change-Id: I43cd7d3047ed9cfbf1a01e7ba3a0310e9d47c307
Signed-off-by: Andrew Geissler <andrewg@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 409cd3f..ccdf95b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,7 +50,7 @@
 libhostservicedir = ${libdir}/ipmid-providers
 libhostservice_LTLIBRARIES = libhostservice.la
 libhostservice_la_SOURCES = \
-	host-services.c \
+	host-services.cpp \
 	host-interface.cpp
 libhostservice_la_LDFLAGS = $(SYSTEMD_LIBS) \
                             $(libmapper_LIBS) \
diff --git a/configure.ac b/configure.ac
index 882b01e..1134046 100644
--- a/configure.ac
+++ b/configure.ac
@@ -99,6 +99,19 @@
     [AC_DEFINE_UNQUOTED([IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS], [45*60], [Wait time until Host can quiesce])]
 )
 
+# Control Host Interfaces
+# Dbus service name
+AC_ARG_VAR(CONTROL_HOST_BUSNAME, [The Control Host Dbus busname to own])
+AS_IF([test "x$CONTROL_HOST_BUSNAME" == "x"],
+      [CONTROL_HOST_BUSNAME="xyz.openbmc_project.Control.Host"])
+AC_DEFINE_UNQUOTED([CONTROL_HOST_BUSNAME], ["$CONTROL_HOST_BUSNAME"], [The Control Host Dbus busname to own])
+
+# Service dbus root
+AC_ARG_VAR(CONTROL_HOST_OBJPATH, [The Control Host Dbus root])
+AS_IF([test "x$CONTROL_HOST_OBJPATH" == "x"],
+      [CONTROL_HOST_OBJPATH="/xyz/openbmc_project/control/host"])
+AC_DEFINE_UNQUOTED([CONTROL_HOST_OBJPATH], ["$CONTROL_HOST_OBJPATH"], [The Control Host Dbus root])
+
 # Create configured output
 AC_CONFIG_FILES([Makefile test/Makefile softoff/Makefile softoff/test/Makefile])
 AC_OUTPUT
diff --git a/host-interface.cpp b/host-interface.cpp
index 010eef1..5c286eb 100644
--- a/host-interface.cpp
+++ b/host-interface.cpp
@@ -5,5 +5,11 @@
 namespace host
 {
 
+void Host::execute(Command command)
+{
+    // Future commits to build on
+    return;
+}
+
 } // namespace host
 } // namepsace phosphor
diff --git a/host-interface.hpp b/host-interface.hpp
index 793a5cb..56d19d1 100644
--- a/host-interface.hpp
+++ b/host-interface.hpp
@@ -28,6 +28,15 @@
                 sdbusplus::xyz::openbmc_project::Control::server::Host>(
                         bus, objPath)
         {}
+
+        /** @brief Send input command to host
+         *
+         * Note that the command will be queued in a FIFO if other commands
+         * to the host have yet to be run
+         *
+         * @param[in] command       - Input command to execute
+         */
+        void execute(Command command) override;
 };
 
 } // namespace host
diff --git a/host-services.c b/host-services.c
deleted file mode 100644
index b0b12ae..0000000
--- a/host-services.c
+++ /dev/null
@@ -1,144 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <systemd/sd-bus.h>
-#include <mapper.h>
-#include "host-ipmid/ipmid-api.h"
-
-void register_host_services() __attribute__((constructor));
-
-// OpenBMC Host IPMI dbus framework
-const char  *object_name   =  "/org/openbmc/HostIpmi/1";
-const char  *intf_name     =  "org.openbmc.HostIpmi";
-
-//-------------------------------------------------------------------
-// Gets called by PowerOff handler when a Soft Power off is requested
-//-------------------------------------------------------------------
-static int soft_power_off(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
-{
-    int64_t bt_resp = -1;
-    int rc = 0;
-    char *bus_name = NULL;
-
-    // Steps to be taken when we get this.
-    //  1: Send a SMS_ATN to the Host
-    //  2: Host receives it and sends a GetMsgFlags IPMI command
-    //  3: IPMID app handler will respond to that with a MSgFlag with bit:0x2
-    //     set indicating we have a message for Host
-    //  4: Host sends a GetMsgBuffer command and app handler will respond to
-    //     that with a OEM-SEL with certain fields packed indicating to the
-    //     host that it do a shutdown of the partitions.
-    //  5: Host does the partition shutdown and calls Chassis Power off command
-    //  6: App handler handles the command by making a call to ChassisManager
-    //     Dbus
-
-    // Now the job is to send the SMS_ATTN.
-
-    // Req message contains the specifics about which method etc that we want to
-    // access on which bus, object
-    sd_bus_message *response = NULL;
-
-    // Error return mechanism
-    sd_bus_error bus_error = SD_BUS_ERROR_NULL;
-
-    // Gets a hook onto either a SYSTEM or SESSION bus
-    sd_bus *bus = ipmid_get_sd_bus_connection();
-    rc = mapper_get_service(bus, object_name, &bus_name);
-    if (rc < 0) {
-        fprintf(stderr, "Failed to get %s bus name: %s\n",
-                object_name, strerror(-rc));
-        goto finish;
-    }
-    rc = sd_bus_call_method(bus,             // In the System Bus
-                            bus_name,        // Service to contact
-                            object_name,     // Object path
-                            intf_name,       // Interface name
-                            "setAttention",  // Method to be called
-                            &bus_error,      // object to return error
-                            &response,       // Response buffer if any
-                            NULL);           // No input arguments
-    if(rc < 0)
-    {
-        fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);
-        goto finish;
-    }
-
-    // See if we were able to successfully raise SMS_ATN
-    rc = sd_bus_message_read(response, "x", &bt_resp);
-    if (rc < 0)
-    {
-        fprintf(stderr, "Failed to get a rc from BT for SMS_ATN: %s\n", strerror(-rc));
-        goto finish;
-    }
-
-finish:
-    sd_bus_error_free(&bus_error);
-    response = sd_bus_message_unref(response);
-    free(bus_name);
-
-    if(rc < 0)
-    {
-        return sd_bus_reply_method_return(m, "x", rc);
-    }
-    else
-    {
-        return sd_bus_reply_method_return(m, "x", bt_resp);
-    }
-}
-
-//-------------------------------------------
-// Function pointer of APIs exposed via Dbus
-//-------------------------------------------
-static const sd_bus_vtable host_services_vtable[] =
-{
-    SD_BUS_VTABLE_START(0),
-    // Takes No("") arguments -but- returns a value of type 64 bit integer("x")
-    SD_BUS_METHOD("SoftPowerOff", "", "x", &soft_power_off, SD_BUS_VTABLE_UNPRIVILEGED),
-    SD_BUS_VTABLE_END,
-};
-
-//------------------------------------------------------
-// Called by IPMID as part of the start up
-// -----------------------------------------------------
-int start_host_service(sd_bus *bus, sd_bus_slot *slot)
-{
-    int rc = 0;
-
-    /* Install the object */
-    rc = sd_bus_add_object_vtable(bus,
-                                 &slot,
-                                "/org/openbmc/HostServices",  /* object path */
-                                "org.openbmc.HostServices",   /* interface name */
-                                host_services_vtable,
-                                NULL);
-    if (rc < 0)
-    {
-        fprintf(stderr, "Failed to issue method call: %s\n", strerror(-rc));
-    }
-    else
-    {
-        /* Take one in OpenBmc */
-        rc = sd_bus_request_name(bus, "org.openbmc.HostServices", 0);
-        if (rc < 0)
-        {
-            fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-rc));
-        }
-    }
-
-    return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-
-//------------------------------------------------------
-// Callback register function
-// -----------------------------------------------------
-void register_host_services()
-{
-    // Gets a hook onto SYSTEM bus used by host-ipmid
-    sd_bus *bus = ipmid_get_sd_bus_connection();
-
-    // Gets a hook onto SYSTEM bus slot used by host-ipmid
-    sd_bus_slot *ipmid_slot = ipmid_get_sd_bus_slot();
-
-    //start_host_service(bus, ipmid_slot);
-    start_host_service(bus, ipmid_slot);
-}
diff --git a/host-services.cpp b/host-services.cpp
new file mode 100644
index 0000000..c78d90a
--- /dev/null
+++ b/host-services.cpp
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <systemd/sd-bus.h>
+#include <mapper.h>
+#include "host-ipmid/ipmid-api.h"
+#include "host-interface.hpp"
+#include <config.h>
+
+void register_host_services() __attribute__((constructor));
+
+//------------------------------------------------------
+// Callback register function
+// -----------------------------------------------------
+
+// Globals to keep the object alive during process life
+std::unique_ptr<sdbusplus::bus::bus> sdbus = nullptr;
+// TODO openbmc/openbmc#1581 - unique_ptr causes seg fault
+phosphor::host::Host* host = nullptr;
+
+void register_host_services()
+{
+    // Gets a hook onto SYSTEM bus used by host-ipmid
+    sd_bus *bus = ipmid_get_sd_bus_connection();
+
+    sdbus = std::make_unique<sdbusplus::bus::bus>(bus);
+
+    // Create new xyz.openbmc_project.host object on the bus
+    auto objPathInst = std::string{CONTROL_HOST_OBJPATH} + '0';
+
+    // Add sdbusplus ObjectManager.
+    sdbusplus::server::manager::manager objManager(*sdbus,
+                                                   objPathInst.c_str());
+
+    host = new phosphor::host::Host(*sdbus,
+                                    objPathInst.c_str());
+
+    sdbus->request_name(CONTROL_HOST_BUSNAME);
+}
diff --git a/host-services.h b/host-services.h
deleted file mode 100644
index 0d93480..0000000
--- a/host-services.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <systemd/sd-bus.h>
-
-extern "C" int start_host_service(sd_bus *, sd_bus_slot *);
diff --git a/host-services.hpp b/host-services.hpp
new file mode 100644
index 0000000..4c2ddad
--- /dev/null
+++ b/host-services.hpp
@@ -0,0 +1 @@
+#include <systemd/sd-bus.h>
diff --git a/ipmid.hpp b/ipmid.hpp
index aab44c0..9ee75e7 100644
--- a/ipmid.hpp
+++ b/ipmid.hpp
@@ -2,6 +2,7 @@
 #define __HOST_IPMID_IPMI_H__
 #include "host-ipmid/ipmid-api.h"
 #include <stdio.h>
+#include "host-services.hpp"
 
 // When the requester sends in a netfn and a command along with data, this
 // function will look for registered handlers that will handle that [netfn,cmd]