summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am17
-rw-r--r--elog-errors.hpp67
-rw-r--r--host-interface.cpp7
-rw-r--r--host-interface.hpp28
-rw-r--r--host-services.cpp39
-rw-r--r--host-services.hpp1
-rw-r--r--ipmid.hpp1
-rw-r--r--systemintfcmds.cpp104
-rw-r--r--systemintfcmds.h2
-rw-r--r--xyz/openbmc_project/Control/Internal/Host.errors.yaml3
-rw-r--r--xyz/openbmc_project/Control/Internal/Host.metadata.yaml3
11 files changed, 187 insertions, 85 deletions
diff --git a/Makefile.am b/Makefile.am
index c9b28c2..1df5216 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,23 +43,18 @@ libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOG
libsysintfcmdsdir = ${libdir}/ipmid-providers
libsysintfcmds_LTLIBRARIES = libsysintfcmds.la
libsysintfcmds_la_SOURCES = \
- systemintfcmds.cpp
-libsysintfcmds_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) -version-info 0:0:0 -shared
-libsysintfcmds_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS)
-
-libhostservicedir = ${libdir}/ipmid-providers
-libhostservice_LTLIBRARIES = libhostservice.la
-libhostservice_la_SOURCES = \
- host-services.cpp \
+ systemintfcmds.cpp \
host-interface.cpp \
utils.cpp
-libhostservice_la_LDFLAGS = $(SYSTEMD_LIBS) \
+libsysintfcmds_la_LDFLAGS = $(SYSTEMD_LIBS) \
$(libmapper_LIBS) \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
+ $(PHOSPHOR_LOGGING_LIBS) \
-version-info 0:0:0 -shared
-libhostservice_la_CXXFLAGS = $(SYSTEMD_CFLAGS) \
+libsysintfcmds_la_CXXFLAGS = $(SYSTEMD_CFLAGS) \
+ $(libmapper_CFLAGS) \
$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
- $(libmapper_CFLAGS)
+ $(PHOSPHOR_LOGGING_CFLAGS)
nobase_include_HEADERS = \
host-ipmid/ipmid-api.h
diff --git a/elog-errors.hpp b/elog-errors.hpp
new file mode 100644
index 0000000..de74160
--- /dev/null
+++ b/elog-errors.hpp
@@ -0,0 +1,67 @@
+// This file was autogenerated. Do not edit!
+// See elog-gen.py for more details
+#pragma once
+
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <sdbusplus/exception.hpp>
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+
+
+namespace phosphor
+{
+
+namespace logging
+{
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Control
+{
+namespace Internal
+{
+namespace Host
+{
+namespace _QueueEmpty
+{
+
+
+} // namespace _QueueEmpty
+
+struct QueueEmpty : public sdbusplus::exception_t
+{
+ static constexpr auto errName = "xyz.openbmc_project.Control.Internal.Host.QueueEmpty";
+ static constexpr auto errDesc = "The host response queue is empty and it should not be!";
+ static constexpr auto L = level::ERR;
+ using metadata_types = std::tuple<>;
+
+ const char* name() const noexcept
+ {
+ return errName;
+ }
+
+ const char* description() const noexcept
+ {
+ return errDesc;
+ }
+
+ const char* what() const noexcept
+ {
+ return errName;
+ }
+};
+
+} // namespace Host
+} // namespace Internal
+} // namespace Control
+} // namespace openbmc_project
+} // namespace xyz
+
+
+} // namespace logging
+
+} // namespace phosphor
diff --git a/host-interface.cpp b/host-interface.cpp
index f485516..aa32ff0 100644
--- a/host-interface.cpp
+++ b/host-interface.cpp
@@ -1,4 +1,3 @@
-#include <queue>
#include <phosphor-logging/log.hpp>
#include <utils.hpp>
#include "host-interface.hpp"
@@ -17,17 +16,15 @@ using namespace phosphor::logging;
// When you see base:: you know we're referencing our base class
namespace base = sdbusplus::xyz::openbmc_project::Control::server;
-std::queue<base::Host::Command> workQueue{};
-
void Host::execute(base::Host::Command command)
{
log<level::INFO>("Pushing cmd on to queue",
entry("CONTROL_HOST_CMD=%s",
convertForMessage(command)));
- workQueue.push(command);
+ this->workQueue.push(command);
// If this was the only entry then send the SMS attention
- if(workQueue.size() == 1)
+ if(this->workQueue.size() == 1)
{
log<level::INFO>("Asserting SMS Attention");
diff --git a/host-interface.hpp b/host-interface.hpp
index a3b7efa..36b41d9 100644
--- a/host-interface.hpp
+++ b/host-interface.hpp
@@ -1,13 +1,18 @@
#pragma once
+#include <queue>
#include <sdbusplus/bus.hpp>
+#include <phosphor-logging/elog.hpp>
#include <xyz/openbmc_project/Control/Host/server.hpp>
+#include "elog-errors.hpp"
namespace phosphor
{
namespace host
{
+using namespace phosphor::logging;
+
/** @class Host
* @brief OpenBMC control host interface implementation.
* @details A concrete implementation for xyz.openbmc_project.Control.Host
@@ -39,10 +44,33 @@ class Host : public sdbusplus::server::object::object<
*/
void execute(Command command) override;
+ /** @brief Return the next entry in the queue
+ *
+ * Also signal that the command is complete since the interface
+ * contract is that we emit this signal once the message has been
+ * passed to the host (which is required when calling this interface)
+ *
+ */
+ Command getNextCommand()
+ {
+ if(this->workQueue.empty())
+ {
+ log<level::ERR>("Control Host work queue is empty!");
+ elog<xyz::openbmc_project::Control::Internal::Host::QueueEmpty>();
+ }
+ Command command = this->workQueue.front();
+ this->workQueue.pop();
+ this->commandComplete(command, Result::Success);
+ return command;
+ }
+
private:
/** @brief Persistent sdbusplus DBus bus connection. */
sdbusplus::bus::bus& bus;
+
+ /** @brief Queue to store the requested commands */
+ std::queue<Command> workQueue{};
};
} // namespace host
diff --git a/host-services.cpp b/host-services.cpp
deleted file mode 100644
index c78d90a..0000000
--- a/host-services.cpp
+++ /dev/null
@@ -1,39 +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"
-#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.hpp b/host-services.hpp
deleted file mode 100644
index 4c2ddad..0000000
--- a/host-services.hpp
+++ /dev/null
@@ -1 +0,0 @@
-#include <systemd/sd-bus.h>
diff --git a/ipmid.hpp b/ipmid.hpp
index 9ee75e7..aab44c0 100644
--- a/ipmid.hpp
+++ b/ipmid.hpp
@@ -2,7 +2,6 @@
#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]
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());
+}
diff --git a/systemintfcmds.h b/systemintfcmds.h
index 19526f6..d603aaa 100644
--- a/systemintfcmds.h
+++ b/systemintfcmds.h
@@ -13,6 +13,8 @@
#define SOFT_OFF 0x00
// Major command for Any kind of power ops
#define CMD_POWER 0x04
+// Major command for the heartbeat operation (verify host is alive)
+#define CMD_HEARTBEAT 0xFF
// IPMI commands used via System Interface functions.
enum ipmi_netfn_system_intf_cmds
diff --git a/xyz/openbmc_project/Control/Internal/Host.errors.yaml b/xyz/openbmc_project/Control/Internal/Host.errors.yaml
new file mode 100644
index 0000000..3c14863
--- /dev/null
+++ b/xyz/openbmc_project/Control/Internal/Host.errors.yaml
@@ -0,0 +1,3 @@
+- name: QueueEmpty
+ description: The host response queue is empty and it should not be!
+
diff --git a/xyz/openbmc_project/Control/Internal/Host.metadata.yaml b/xyz/openbmc_project/Control/Internal/Host.metadata.yaml
new file mode 100644
index 0000000..3f0b852
--- /dev/null
+++ b/xyz/openbmc_project/Control/Internal/Host.metadata.yaml
@@ -0,0 +1,3 @@
+- name: QueueEmpty
+ level: ERR
+
OpenPOWER on IntegriCloud