summaryrefslogtreecommitdiffstats
path: root/systemintfcmds.cpp
diff options
context:
space:
mode:
authorAndrew Geissler <andrewg@us.ibm.com>2017-03-21 22:58:28 -0500
committerAndrew Geissler <andrewg@us.ibm.com>2017-05-09 12:50:39 -0500
commit1286637013b65a615e37d8677d75a1bba4c53e4b (patch)
treeaae064436865ce2f3d4bb44c42e52e8449294694 /systemintfcmds.cpp
parent1b9d4e5c676f5f2fd35583dc5e3459783a650578 (diff)
downloadphosphor-host-ipmid-1286637013b65a615e37d8677d75a1bba4c53e4b.tar.gz
phosphor-host-ipmid-1286637013b65a615e37d8677d75a1bba4c53e4b.zip
Implement basic queue for sending multiple commands
Sends dbus signal upon completion of command Change-Id: Ic507f35af0b38305eecd5558c55738f2d283aac5 Signed-off-by: Andrew Geissler <andrewg@us.ibm.com>
Diffstat (limited to 'systemintfcmds.cpp')
-rw-r--r--systemintfcmds.cpp104
1 files changed, 76 insertions, 28 deletions
diff --git a/systemintfcmds.cpp b/systemintfcmds.cpp
index 62d9524..999e710 100644
--- a/systemintfcmds.cpp
+++ b/systemintfcmds.cpp
@@ -1,26 +1,21 @@
#include "systemintfcmds.h"
#include "host-ipmid/ipmid-api.h"
#include "config.h"
+#include "host-interface.hpp"
#include <stdio.h>
#include <mapper.h>
void register_netfn_app_functions() __attribute__((constructor));
-//-------------------------------------------------------------------
-// Called by Host post response from Get_Message_Flags
-//-------------------------------------------------------------------
-ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request, ipmi_response_t response,
- ipmi_data_len_t data_len, ipmi_context_t context)
-{
- ipmi_ret_t rc = IPMI_CC_OK;
+using namespace sdbusplus::xyz::openbmc_project::Control::server;
- printf("IPMI APP READ EVENT command received\n");
+// Internal function to get next host command
+Host::Command getNextHostCmd();
- // TODO : For now, this is catering only to the Soft Power Off via OEM SEL
- // mechanism. If we need to make this generically used for some
- // other conditions, then we can take advantage of context pointer.
+// Notify SofPowerOff application that host is responding to command
+void notifySoftOff()
+{
constexpr auto iface = "org.freedesktop.DBus.Properties";
constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
@@ -31,9 +26,6 @@ ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
"SoftPowerOff.HostResponse.SoftOffReceived";
char *busname = nullptr;
- struct oem_sel_timestamped soft_off = {0};
- *data_len = sizeof(struct oem_sel_timestamped);
-
// Get the system bus where most system services are provided.
auto bus = ipmid_get_sd_bus_connection();
@@ -56,31 +48,58 @@ ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
}
else
{
- printf("Soft Power Off object is not available. Ignoring watchdog refresh");
+ printf("Soft Power Off object is not available. Ignoring watchdog \
+ refresh");
}
+}
+
+//-------------------------------------------------------------------
+// Called by Host post response from Get_Message_Flags
+//-------------------------------------------------------------------
+ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_request_t request, ipmi_response_t response,
+ ipmi_data_len_t data_len, ipmi_context_t context)
+{
+ ipmi_ret_t rc = IPMI_CC_OK;
+
+ printf("IPMI APP READ EVENT command received\n");
+
+ struct oem_sel_timestamped oem_sel = {0};
+ *data_len = sizeof(struct oem_sel_timestamped);
// either id[0] -or- id[1] can be filled in. We will use id[0]
- soft_off.id[0] = SEL_OEM_ID_0;
- soft_off.id[1] = SEL_OEM_ID_0;
- soft_off.type = SEL_RECORD_TYPE_OEM;
+ oem_sel.id[0] = SEL_OEM_ID_0;
+ oem_sel.id[1] = SEL_OEM_ID_0;
+ oem_sel.type = SEL_RECORD_TYPE_OEM;
// Following 3 bytes are from IANA Manufactre_Id field. See below
- soft_off.manuf_id[0]= 0x41;
- soft_off.manuf_id[1]= 0xA7;
- soft_off.manuf_id[2]= 0x00;
+ oem_sel.manuf_id[0]= 0x41;
+ oem_sel.manuf_id[1]= 0xA7;
+ oem_sel.manuf_id[2]= 0x00;
// per IPMI spec NetFuntion for OEM
- soft_off.netfun = 0x3A;
+ oem_sel.netfun = 0x3A;
- // Mechanism to kick start soft shutdown.
- soft_off.cmd = CMD_POWER;
- soft_off.data[0] = SOFT_OFF;
+ // Read from the queue to see what our response is here
+ Host::Command hCmd = getNextHostCmd();
+ switch (hCmd)
+ {
+ case Host::Command::SoftOff:
+ notifySoftOff();
+ oem_sel.cmd = CMD_POWER;
+ oem_sel.data[0] = SOFT_OFF;
+ break;
+ case Host::Command::Heartbeat:
+ oem_sel.cmd = CMD_HEARTBEAT;
+ oem_sel.data[0] = 0x00;
+ break;
+ }
// All '0xFF' since unused.
- memset(&soft_off.data[1], 0xFF, 3);
+ memset(&oem_sel.data[1], 0xFF, 3);
// Pack the actual response
- memcpy(response, &soft_off, *data_len);
+ memcpy(response, &oem_sel, *data_len);
return rc;
}
@@ -125,6 +144,13 @@ ipmi_ret_t ipmi_app_set_bmc_global_enables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
+// 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;
+
+
+#include <unistd.h>
void register_netfn_app_functions()
{
@@ -144,5 +170,27 @@ void register_netfn_app_functions()
ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS, NULL, ipmi_app_get_msg_flags,
SYSTEM_INTERFACE);
+ // 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);
+
return;
}
+
+Host::Command getNextHostCmd()
+{
+ return(host->getNextCommand());
+}
OpenPOWER on IntegriCloud