From 194375f2676715a0e0697bab63234a4efe39fb96 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 14 Dec 2018 02:14:33 -0800 Subject: Create libipmid and libipmid-host This starts a transition to common ipmid libraries that providers can link against. It will allow for a cleaner separation between common ipmid functionality and daemon type specific code. This is needed so we can resolve all of the symbols in the providers at link time instead of discovering bad linkage by building and running a full ipmi daemon. In future commits libraries will be packaged for libipmid and libipmid-host which provide all of the symbols used by the current set of ipmid providers. This is the first step, it just separates and renames the headers. Legacy symlinks are still kept around for compatability. It also adds stub libraries so that external users can start linking as intended. Change-Id: I6bbd7a146362012d26812a7b039d1c4075862cbd Signed-off-by: William A. Kennington III --- .gitignore | 1 + Makefile.am | 27 ++++--- app/watchdog.cpp | 2 +- app/watchdog.hpp | 2 +- app/watchdog_service.cpp | 2 +- apphandler.cpp | 2 +- chassishandler.cpp | 2 +- configure.ac | 15 +++- dcmihandler.cpp | 2 +- globalhandler.cpp | 2 +- groupext.cpp | 2 +- host-cmd-manager.hpp | 2 +- host-interface.cpp | 4 +- host-ipmid/iana.hpp | 19 ----- host-ipmid/ipmid-api.h | 155 ------------------------------------ host-ipmid/ipmid-host-cmd-utils.hpp | 51 ------------ host-ipmid/ipmid-host-cmd.hpp | 11 --- host-ipmid/oemopenbmc.hpp | 22 ----- host-ipmid/oemrouter.hpp | 83 ------------------- include/Makefile.am | 19 +++++ include/ipmid-host/cmd-utils.hpp | 51 ++++++++++++ include/ipmid-host/cmd.hpp | 10 +++ include/ipmid/api.h | 155 ++++++++++++++++++++++++++++++++++++ include/ipmid/iana.hpp | 19 +++++ include/ipmid/oemopenbmc.hpp | 22 +++++ include/ipmid/oemrouter.hpp | 83 +++++++++++++++++++ ipmid.cpp | 4 +- ipmid.hpp | 2 +- libipmid-host/Makefile.am | 8 ++ libipmid-host/libipmid-host.pc.in | 10 +++ libipmid/Makefile.am | 8 ++ libipmid/libipmid.pc.in | 10 +++ oemrouter.cpp | 2 +- read_fru_data.cpp | 2 +- selutility.cpp | 2 +- sensordatahandler.hpp | 2 +- sensorhandler.cpp | 2 +- sensorhandler.hpp | 2 +- softoff/Makefile.am | 1 - storageaddsel.cpp | 2 +- storagehandler.cpp | 2 +- systemintfcmds.cpp | 4 +- test/oemrouter_unittest.cpp | 4 +- transporthandler.cpp | 2 +- user_channel/channel_layer.hpp | 2 +- user_channel/user_layer.hpp | 2 +- user_channel/user_mgmt.cpp | 1 - user_channel/user_mgmt.hpp | 2 +- user_channel/usercommands.cpp | 2 +- 49 files changed, 458 insertions(+), 385 deletions(-) delete mode 100644 host-ipmid/iana.hpp delete mode 100644 host-ipmid/ipmid-api.h delete mode 100644 host-ipmid/ipmid-host-cmd-utils.hpp delete mode 100644 host-ipmid/ipmid-host-cmd.hpp delete mode 100644 host-ipmid/oemopenbmc.hpp delete mode 100644 host-ipmid/oemrouter.hpp create mode 100644 include/Makefile.am create mode 100644 include/ipmid-host/cmd-utils.hpp create mode 100644 include/ipmid-host/cmd.hpp create mode 100644 include/ipmid/api.h create mode 100644 include/ipmid/iana.hpp create mode 100644 include/ipmid/oemopenbmc.hpp create mode 100644 include/ipmid/oemrouter.hpp create mode 100644 libipmid-host/Makefile.am create mode 100644 libipmid-host/libipmid-host.pc.in create mode 100644 libipmid/Makefile.am create mode 100644 libipmid/libipmid.pc.in diff --git a/.gitignore b/.gitignore index 8cca7ea..92a85ba 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ Makefile.in *.lo *.la *.so* +*.pc /config.h /config.h.in~ /config.log diff --git a/Makefile.am b/Makefile.am index 39f1344..ac8449e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,8 @@ AM_DEFAULT_SOURCE_EXT = .cpp +AM_CPPFLAGS = -I$(abs_srcdir) -I$(abs_srcdir)/include +export AM_CPPFLAGS + providersdir = ${libdir}/ipmid-providers providers_LTLIBRARIES = @@ -38,6 +41,9 @@ COMMON_CXX = \ -DBOOST_ALL_NO_LIB ipmid_CXXFLAGS = $(COMMON_CXX) +ipmid_LDADD = \ + libipmid/libipmid.la \ + libipmid-host/libipmid-host.la ipmid_LDFLAGS = \ $(SYSTEMD_LIBS) \ $(libmapper_LIBS) \ @@ -94,7 +100,9 @@ XFAIL_TESTS = TESTS = $(check_PROGRAMS) -libipmi20_la_LIBADD = user_channel/libuserlayer.la +libipmi20_la_LIBADD = \ + libipmid/libipmid.la \ + user_channel/libuserlayer.la libipmi20_la_LDFLAGS = \ $(SYSTEMD_LIBS) \ $(libmapper_LIBS) \ @@ -105,7 +113,9 @@ libipmi20_la_LDFLAGS = \ libipmi20_la_CXXFLAGS = $(COMMON_CXX) providers_LTLIBRARIES += libusercmds.la -libusercmds_la_LIBADD = user_channel/libuserlayer.la +libusercmds_la_LIBADD = \ + libipmid/libipmid.la \ + user_channel/libuserlayer.la libusercmds_la_SOURCES = \ user_channel/usercommands.cpp \ user_channel/channelcommands.cpp @@ -118,6 +128,9 @@ libusercmds_la_CXXFLAGS = \ -flto providers_LTLIBRARIES += libsysintfcmds.la +libsysintfcmds_la_LIBADD = \ + libipmid/libipmid.la \ + libipmid-host/libipmid-host.la libsysintfcmds_la_SOURCES = \ systemintfcmds.cpp \ host-interface.cpp @@ -131,14 +144,8 @@ libsysintfcmds_la_LDFLAGS = \ libsysintfcmds_la_CXXFLAGS = $(COMMON_CXX) nobase_include_HEADERS = \ - host-ipmid/iana.hpp \ - user_channel/user_layer.hpp \ user_channel/channel_layer.hpp \ - host-ipmid/ipmid-api.h \ - host-ipmid/ipmid-host-cmd.hpp \ - host-ipmid/ipmid-host-cmd-utils.hpp \ - host-ipmid/oemopenbmc.hpp \ - host-ipmid/oemrouter.hpp + user_channel/user_layer.hpp # Forcing the build of self and then subdir -SUBDIRS = user_channel . test softoff +SUBDIRS = include libipmid libipmid-host user_channel . test softoff diff --git a/app/watchdog.cpp b/app/watchdog.cpp index 3d8e227..7ca465c 100644 --- a/app/watchdog.cpp +++ b/app/watchdog.cpp @@ -4,7 +4,7 @@ #include "watchdog_service.hpp" #include -#include +#include #include #include diff --git a/app/watchdog.hpp b/app/watchdog.hpp index 268ca92..767a776 100644 --- a/app/watchdog.hpp +++ b/app/watchdog.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include /** @brief The RESET watchdog IPMI command. * diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp index 769a70d..1deb58b 100644 --- a/app/watchdog_service.cpp +++ b/app/watchdog_service.cpp @@ -1,6 +1,6 @@ #include "watchdog_service.hpp" -#include +#include #include #include diff --git a/apphandler.cpp b/apphandler.cpp index f99cbe8..ac969e9 100644 --- a/apphandler.cpp +++ b/apphandler.cpp @@ -9,7 +9,7 @@ #include "utils.hpp" #include -#include +#include #include #include #include diff --git a/chassishandler.cpp b/chassishandler.cpp index 7b94189..068ad89 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/configure.ac b/configure.ac index 1f5ec66..9ee45e0 100644 --- a/configure.ac +++ b/configure.ac @@ -22,6 +22,9 @@ AS_IF([test "x$enable_softoff" != "xno"], [AC_CHECK_PROG([DIRNAME], dirname, dirname)] ) +# Make sure the pkgconfigdata is configured for automake +PKG_INSTALLDIR + # Checks for libraries. AC_CHECK_LIB([pam], [pam_start], [], [AC_MSG_ERROR([libpam not found])]) AC_CHECK_LIB([mapper], [mapper_get_service], ,[AC_MSG_ERROR([Could not find libmapper...openbmc/phosphor-objmgr package required])]) @@ -163,5 +166,15 @@ AS_IF([test "x$HOST_IPMI_LIB_PATH" == "x"], [HOST_IPMI_LIB_PATH="/usr/lib/host-i AC_DEFINE_UNQUOTED([HOST_IPMI_LIB_PATH], ["$HOST_IPMI_LIB_PATH"], [The file path to search for libraries.]) # Create configured output -AC_CONFIG_FILES([Makefile test/Makefile softoff/Makefile user_channel/Makefile]) +AC_CONFIG_FILES([ + Makefile + include/Makefile + libipmid/Makefile + libipmid/libipmid.pc + libipmid-host/Makefile + libipmid-host/libipmid-host.pc + softoff/Makefile + test/Makefile + user_channel/Makefile +]) AC_OUTPUT diff --git a/dcmihandler.cpp b/dcmihandler.cpp index 15ab26c..1c448ce 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -5,7 +5,7 @@ #include "user_channel/channel_layer.hpp" #include "utils.hpp" -#include +#include #include #include diff --git a/globalhandler.cpp b/globalhandler.cpp index f329fa9..04d57af 100644 --- a/globalhandler.cpp +++ b/globalhandler.cpp @@ -2,7 +2,7 @@ #include "utils.hpp" -#include +#include #include #include diff --git a/groupext.cpp b/groupext.cpp index 43656cd..7b4ca5e 100644 --- a/groupext.cpp +++ b/groupext.cpp @@ -1,6 +1,6 @@ #include "ipmid.hpp" -#include +#include #include diff --git a/host-cmd-manager.hpp b/host-cmd-manager.hpp index 6b56122..94cc6f1 100644 --- a/host-cmd-manager.hpp +++ b/host-cmd-manager.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/host-interface.cpp b/host-interface.cpp index 2a3e6ce..0b5f63c 100644 --- a/host-interface.cpp +++ b/host-interface.cpp @@ -6,8 +6,8 @@ #include "utils.hpp" #include -#include -#include +#include +#include #include namespace phosphor diff --git a/host-ipmid/iana.hpp b/host-ipmid/iana.hpp deleted file mode 100644 index aa9e173..0000000 --- a/host-ipmid/iana.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -namespace oem -{ -using Number = std::uint32_t; // smallest standard size >= 24. - -/* - * This is the OpenBMC IANA OEM Number - */ -constexpr Number obmcOemNumber = 49871; - -/* - * This is the Google IANA OEM Number - */ -constexpr Number googOemNumber = 11129; - -} // namespace oem diff --git a/host-ipmid/ipmid-api.h b/host-ipmid/ipmid-api.h deleted file mode 100644 index b1c078b..0000000 --- a/host-ipmid/ipmid-api.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef __HOST_IPMID_IPMI_COMMON_H__ -#define __HOST_IPMID_IPMI_COMMON_H__ - -#include - -/* - * Specifies the minimum privilege level required to execute the command - * This means the command can be executed at a given privilege level or higher - * privilege level. Those commands which can be executed via system interface - * only should use SYSTEM_INTERFACE - */ -enum CommandPrivilege -{ - PRIVILEGE_CALLBACK = 0x01, - PRIVILEGE_USER, - PRIVILEGE_OPERATOR, - PRIVILEGE_ADMIN, - PRIVILEGE_OEM, - SYSTEM_INTERFACE = 0xFF, -}; - -// length of Completion Code and its ALWAYS _1_ -#define IPMI_CC_LEN 1 - -// IPMI Net Function number as specified by IPMI V2.0 spec. -// Example : -// NETFUN_APP = (0x06 << 2), -typedef unsigned char ipmi_netfn_t; - -// IPMI Command for a Net Function number as specified by IPMI V2.0 spec. -typedef unsigned char ipmi_cmd_t; - -// Buffer containing data from sender of netfn and command as part of request -typedef void* ipmi_request_t; - -// This is the response buffer that the provider of [netfn,cmd] will send back -// to the caller. Provider will allocate the memory inside the handler and then -// will do a memcpy to this response buffer and also will set the data size -// parameter to the size of the buffer. -// EXAMPLE : -// unsigned char str[] = {0x00, 0x01, 0xFE, 0xFF, 0x0A, 0x01}; -// *data_len = 6; -// memcpy(response, &str, *data_len); -typedef void* ipmi_response_t; - -// This buffer contains any *user specific* data that is of interest only to the -// plugin. For a ipmi function router, this data is opaque. At the time of -// registering the plugin handlers, plugin may optionally allocate a memory and -// fill in whatever needed that will be of help during the actual handling of -// command. IPMID will just pass the netfn, cmd and also this data to plugins -// during the command handler invocation. -typedef void* ipmi_context_t; - -// Length of request / response buffer depending on whether the data is a -// request or a response from a plugin handler. -typedef size_t* ipmi_data_len_t; - -// Plugin function return the status code -typedef unsigned char ipmi_ret_t; - -typedef enum CommandPrivilege ipmi_cmd_privilege_t; - -// This is the callback handler that the plugin registers with IPMID. IPMI -// function router will then make a call to this callback handler with the -// necessary arguments of netfn, cmd, request, response, size and context. -typedef ipmi_ret_t (*ipmid_callback_t)(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t, - ipmi_response_t, ipmi_data_len_t, - ipmi_context_t); - -// This is the constructor function that is called into by each plugin handlers. -// When ipmi sets up the callback handlers, a call is made to this with -// information of netfn, cmd, callback handler pointer and context data. -void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t, ipmi_context_t, - ipmid_callback_t, ipmi_cmd_privilege_t); - -unsigned short reserveSel(void); -bool checkSELReservation(unsigned short id); -void cancelSELReservation(void); - -// These are the command network functions, the response -// network functions are the function + 1. So to determine -// the proper network function which issued the command -// associated with a response, subtract 1. -// Note: these are also shifted left to make room for the LUN. -enum ipmi_net_fns -{ - NETFUN_CHASSIS = 0x00, - NETFUN_BRIDGE = 0x02, - NETFUN_SENSOR = 0x04, - NETFUN_APP = 0x06, - NETFUN_FIRMWARE = 0x08, - NETFUN_STORAGE = 0x0a, - NETFUN_TRANSPORT = 0x0c, - NETFUN_GRPEXT = 0x2c, - NETFUN_OEM_GROUP = 0x2e, - NETFUN_NONE = 0x30, - NETFUN_OEM = 0x32, - NETFUN_IBM_OEM = 0x3A -}; - -// IPMI commands for net functions. Since this is to be used both by the ipmi -// function router and also the callback handler registration function, its put -// in this .H file. -enum ipmi_netfn_wild_card_cmd -{ - IPMI_CMD_WILDCARD = 0xFF, -}; - -// Return (completion) codes from a IPMI operation as needed by IPMI V2.0 spec. -enum ipmi_return_codes -{ - IPMI_CC_OK = 0x00, - IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT = 0x80, - IPMI_WDOG_CC_NOT_INIT = 0x80, - IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED = 0x80, - IPMI_CC_SYSTEM_INFO_PARAMETER_SET_READ_ONLY = 0x82, - IPMI_CC_BUSY = 0xC0, - IPMI_CC_INVALID = 0xC1, - IPMI_CC_TIMEOUT = 0xC3, - IPMI_CC_OUT_OF_SPACE = 0xC4, - IPMI_CC_INVALID_RESERVATION_ID = 0xC5, - IPMI_CC_REQ_DATA_TRUNCATED = 0xC6, - IPMI_CC_REQ_DATA_LEN_INVALID = 0xC7, - IPMI_CC_PARM_OUT_OF_RANGE = 0xC9, - IPMI_CC_REQUESTED_TOO_MANY_BYTES = 0xCA, - IPMI_CC_SENSOR_INVALID = 0xCB, - IPMI_CC_INVALID_FIELD_REQUEST = 0xCC, - IPMI_CC_ILLEGAL_COMMAND = 0xCD, - IPMI_CC_RESPONSE_ERROR = 0xCE, - IPMI_CC_INSUFFICIENT_PRIVILEGE = 0xD4, - IPMI_CC_UNSPECIFIED_ERROR = 0xFF, -}; - -// Temp solution: To detect the request source channel. -// There is no stright forward way to get the exact -// channel so we are hardcoding it to KCS in case host-ipmid -// and LAN1 for netipmid. -// we can't differentiate between LAN1 & LAN2 for netipmid in this logic. -// As our current design will not be able to support the same. This is done -// so that in all the places where ever we need to use the self channel can be -// be implemented properly and based on new architecture.this can be updated. -typedef enum -{ - interfaceKCS = 0, - interfaceLAN1 = 1, - interfaceUnknown = 0xFF -} EInterfaceIndex; - -EInterfaceIndex getInterfaceIndex(void); - -sd_bus* ipmid_get_sd_bus_connection(void); -sd_event* ipmid_get_sd_event_connection(void); -sd_bus_slot* ipmid_get_sd_bus_slot(void); - -#endif diff --git a/host-ipmid/ipmid-host-cmd-utils.hpp b/host-ipmid/ipmid-host-cmd-utils.hpp deleted file mode 100644 index e7c6dc2..0000000 --- a/host-ipmid/ipmid-host-cmd-utils.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace phosphor -{ -namespace host -{ -namespace command -{ -/** @detail After sending SMS_ATN to the Host, Host comes down and - * asks why an 'SMS_ATN` was sent. - * BMC then sends 'There is a Message to be Read` as response. - * Host then comes down asks for Message and the specified - * commands and data would go as data conforming to IPMI spec. - * - * Refer: 6.13.2 Send Message Command From System Interface - * in IPMI V2.0 spec. - */ - -/** @brief IPMI command */ -using IPMIcmd = uint8_t; - -/** @brief Data associated with command */ -using Data = uint8_t; - -/** @brief to be sent as payload when Host asks for - * the message that can be associated with the previous SMS_ATN - */ -using IpmiCmdData = std::pair; - -/** @detail Implementation specific callback function to be invoked - * conveying the status of the executed command. Specific - * implementations may then broadcast an agreed signal - */ -using CallBack = std::function; - -/** @detail Tuple encapsulating above 2 to enable using Manager by - * different implementations. Users of Manager will supply - * along with the callback handler. - * Manager will invoke the handler onveying the status of - * the command. - */ -using CommandHandler = std::tuple; - -} // namespace command -} // namespace host -} // namespace phosphor diff --git a/host-ipmid/ipmid-host-cmd.hpp b/host-ipmid/ipmid-host-cmd.hpp deleted file mode 100644 index 4fd95a9..0000000 --- a/host-ipmid/ipmid-host-cmd.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "ipmid-host-cmd-utils.hpp" - -#include -#include - -// Need this to use new sdbusplus compatible interfaces -using sdbusPtr = std::unique_ptr; -extern sdbusPtr& ipmid_get_sdbus_plus_handler(); - -// Global Host Bound Command manager -extern void ipmid_send_cmd_to_host(phosphor::host::command::CommandHandler&&); diff --git a/host-ipmid/oemopenbmc.hpp b/host-ipmid/oemopenbmc.hpp deleted file mode 100644 index 101e715..0000000 --- a/host-ipmid/oemopenbmc.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#include - -namespace oem -{ -/* - * OpenBMC OEM Extension IPMI Command codes. - */ -enum Cmd -{ - gpioCmd = 1, - i2cCmd = 2, - flashCmd = 3, - fanManualCmd = 4, - ethStatsCmd = 48, - blobTransferCmd = 128, -}; - -} // namespace oem diff --git a/host-ipmid/oemrouter.hpp b/host-ipmid/oemrouter.hpp deleted file mode 100644 index fb12750..0000000 --- a/host-ipmid/oemrouter.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include -#include - -namespace oem -{ -constexpr size_t groupMagicSize = 3; - -using Group = std::array; - -// Handler signature includes ipmi cmd to support wildcard cmd match. -// Buffers and lengths exclude the OemGroup bytes in the IPMI message. -// dataLen supplies length of reqBuf upon call, and should be set to the -// length of replyBuf upon return - conventional in this code base. -using Handler = std::function; // dataLen - -/// Router Interface class. -/// @brief Abstract Router Interface -class Router -{ - public: - virtual ~Router() - { - } - - /// Enable message routing to begin. - virtual void activate() = 0; - - /// Register a handler for given OEMNumber & cmd. - /// Use IPMI_CMD_WILDCARD to catch any unregistered cmd - /// for the given OEMNumber. - /// - /// @param[in] oen - the OEM Number. - /// @param[in] cmd - the Command. - /// @param[in] handler - the handler to call given that OEN and - /// command. - virtual void registerHandler(Number oen, ipmi_cmd_t cmd, - Handler handler) = 0; -}; - -/// Expose mutable Router for configuration & activation. -/// -/// @returns pointer to OEM Router to use. -Router* mutableRouter(); - -/// Convert a group to an OEN. -/// -/// @param[in] oeg - request buffer for IPMI command. -/// @return the OEN. -constexpr Number toOemNumber(const uint8_t oeg[groupMagicSize]) -{ - return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0]; -} - -/// Given a Group convert to an OEN. -/// -/// @param[in] oeg - OEM Group reference. -/// @return the OEN. -constexpr Number toOemNumber(const Group& oeg) -{ - return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0]; -} - -/// Given an OEN, conver to the OEM Group. -/// -/// @param[in] oen - the OEM Number. -/// @return the OEM Group. -constexpr Group toOemGroup(Number oen) -{ - return Group{static_cast(oen), static_cast(oen >> 8), - static_cast(oen >> 16)}; -} - -} // namespace oem diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..50bb399 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,19 @@ +nobase_include_HEADERS = \ + ipmid/api.h \ + ipmid/iana.hpp \ + ipmid/oemopenbmc.hpp \ + ipmid/oemrouter.hpp \ + ipmid-host/cmd.hpp \ + ipmid-host/cmd-utils.hpp + +# Eventually we will split and headers +# For now they will be the same during migration +install-data-local: + $(MKDIR_P) $(DESTDIR)$(includedir)/host-ipmid + $(LN_S) ../ipmid/iana.hpp $(DESTDIR)$(includedir)/host-ipmid/iana.hpp + $(LN_S) ../ipmid/api.h $(DESTDIR)$(includedir)/host-ipmid/ipmid-api.h + $(LN_S) ../ipmid/oemopenbmc.hpp $(DESTDIR)$(includedir)/host-ipmid/oemopenbmc.hpp + $(LN_S) ../ipmid/oemrouter.hpp $(DESTDIR)$(includedir)/host-ipmid/oemrouter.hpp + $(LN_S) ../ipmid-host/cmd.hpp $(DESTDIR)$(includedir)/host-ipmid/ipmid-host-cmd.hpp + $(LN_S) ../ipmid-host/cmd-utils.hpp $(DESTDIR)$(includedir)/host-ipmid/ipmid-host-cmd-utils.hpp + diff --git a/include/ipmid-host/cmd-utils.hpp b/include/ipmid-host/cmd-utils.hpp new file mode 100644 index 0000000..e7c6dc2 --- /dev/null +++ b/include/ipmid-host/cmd-utils.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include + +#include +#include + +namespace phosphor +{ +namespace host +{ +namespace command +{ +/** @detail After sending SMS_ATN to the Host, Host comes down and + * asks why an 'SMS_ATN` was sent. + * BMC then sends 'There is a Message to be Read` as response. + * Host then comes down asks for Message and the specified + * commands and data would go as data conforming to IPMI spec. + * + * Refer: 6.13.2 Send Message Command From System Interface + * in IPMI V2.0 spec. + */ + +/** @brief IPMI command */ +using IPMIcmd = uint8_t; + +/** @brief Data associated with command */ +using Data = uint8_t; + +/** @brief to be sent as payload when Host asks for + * the message that can be associated with the previous SMS_ATN + */ +using IpmiCmdData = std::pair; + +/** @detail Implementation specific callback function to be invoked + * conveying the status of the executed command. Specific + * implementations may then broadcast an agreed signal + */ +using CallBack = std::function; + +/** @detail Tuple encapsulating above 2 to enable using Manager by + * different implementations. Users of Manager will supply + * along with the callback handler. + * Manager will invoke the handler onveying the status of + * the command. + */ +using CommandHandler = std::tuple; + +} // namespace command +} // namespace host +} // namespace phosphor diff --git a/include/ipmid-host/cmd.hpp b/include/ipmid-host/cmd.hpp new file mode 100644 index 0000000..adea960 --- /dev/null +++ b/include/ipmid-host/cmd.hpp @@ -0,0 +1,10 @@ +#include +#include +#include + +// Need this to use new sdbusplus compatible interfaces +using sdbusPtr = std::unique_ptr; +extern sdbusPtr& ipmid_get_sdbus_plus_handler(); + +// Global Host Bound Command manager +extern void ipmid_send_cmd_to_host(phosphor::host::command::CommandHandler&&); diff --git a/include/ipmid/api.h b/include/ipmid/api.h new file mode 100644 index 0000000..b1c078b --- /dev/null +++ b/include/ipmid/api.h @@ -0,0 +1,155 @@ +#ifndef __HOST_IPMID_IPMI_COMMON_H__ +#define __HOST_IPMID_IPMI_COMMON_H__ + +#include + +/* + * Specifies the minimum privilege level required to execute the command + * This means the command can be executed at a given privilege level or higher + * privilege level. Those commands which can be executed via system interface + * only should use SYSTEM_INTERFACE + */ +enum CommandPrivilege +{ + PRIVILEGE_CALLBACK = 0x01, + PRIVILEGE_USER, + PRIVILEGE_OPERATOR, + PRIVILEGE_ADMIN, + PRIVILEGE_OEM, + SYSTEM_INTERFACE = 0xFF, +}; + +// length of Completion Code and its ALWAYS _1_ +#define IPMI_CC_LEN 1 + +// IPMI Net Function number as specified by IPMI V2.0 spec. +// Example : +// NETFUN_APP = (0x06 << 2), +typedef unsigned char ipmi_netfn_t; + +// IPMI Command for a Net Function number as specified by IPMI V2.0 spec. +typedef unsigned char ipmi_cmd_t; + +// Buffer containing data from sender of netfn and command as part of request +typedef void* ipmi_request_t; + +// This is the response buffer that the provider of [netfn,cmd] will send back +// to the caller. Provider will allocate the memory inside the handler and then +// will do a memcpy to this response buffer and also will set the data size +// parameter to the size of the buffer. +// EXAMPLE : +// unsigned char str[] = {0x00, 0x01, 0xFE, 0xFF, 0x0A, 0x01}; +// *data_len = 6; +// memcpy(response, &str, *data_len); +typedef void* ipmi_response_t; + +// This buffer contains any *user specific* data that is of interest only to the +// plugin. For a ipmi function router, this data is opaque. At the time of +// registering the plugin handlers, plugin may optionally allocate a memory and +// fill in whatever needed that will be of help during the actual handling of +// command. IPMID will just pass the netfn, cmd and also this data to plugins +// during the command handler invocation. +typedef void* ipmi_context_t; + +// Length of request / response buffer depending on whether the data is a +// request or a response from a plugin handler. +typedef size_t* ipmi_data_len_t; + +// Plugin function return the status code +typedef unsigned char ipmi_ret_t; + +typedef enum CommandPrivilege ipmi_cmd_privilege_t; + +// This is the callback handler that the plugin registers with IPMID. IPMI +// function router will then make a call to this callback handler with the +// necessary arguments of netfn, cmd, request, response, size and context. +typedef ipmi_ret_t (*ipmid_callback_t)(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t, + ipmi_response_t, ipmi_data_len_t, + ipmi_context_t); + +// This is the constructor function that is called into by each plugin handlers. +// When ipmi sets up the callback handlers, a call is made to this with +// information of netfn, cmd, callback handler pointer and context data. +void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t, ipmi_context_t, + ipmid_callback_t, ipmi_cmd_privilege_t); + +unsigned short reserveSel(void); +bool checkSELReservation(unsigned short id); +void cancelSELReservation(void); + +// These are the command network functions, the response +// network functions are the function + 1. So to determine +// the proper network function which issued the command +// associated with a response, subtract 1. +// Note: these are also shifted left to make room for the LUN. +enum ipmi_net_fns +{ + NETFUN_CHASSIS = 0x00, + NETFUN_BRIDGE = 0x02, + NETFUN_SENSOR = 0x04, + NETFUN_APP = 0x06, + NETFUN_FIRMWARE = 0x08, + NETFUN_STORAGE = 0x0a, + NETFUN_TRANSPORT = 0x0c, + NETFUN_GRPEXT = 0x2c, + NETFUN_OEM_GROUP = 0x2e, + NETFUN_NONE = 0x30, + NETFUN_OEM = 0x32, + NETFUN_IBM_OEM = 0x3A +}; + +// IPMI commands for net functions. Since this is to be used both by the ipmi +// function router and also the callback handler registration function, its put +// in this .H file. +enum ipmi_netfn_wild_card_cmd +{ + IPMI_CMD_WILDCARD = 0xFF, +}; + +// Return (completion) codes from a IPMI operation as needed by IPMI V2.0 spec. +enum ipmi_return_codes +{ + IPMI_CC_OK = 0x00, + IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT = 0x80, + IPMI_WDOG_CC_NOT_INIT = 0x80, + IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED = 0x80, + IPMI_CC_SYSTEM_INFO_PARAMETER_SET_READ_ONLY = 0x82, + IPMI_CC_BUSY = 0xC0, + IPMI_CC_INVALID = 0xC1, + IPMI_CC_TIMEOUT = 0xC3, + IPMI_CC_OUT_OF_SPACE = 0xC4, + IPMI_CC_INVALID_RESERVATION_ID = 0xC5, + IPMI_CC_REQ_DATA_TRUNCATED = 0xC6, + IPMI_CC_REQ_DATA_LEN_INVALID = 0xC7, + IPMI_CC_PARM_OUT_OF_RANGE = 0xC9, + IPMI_CC_REQUESTED_TOO_MANY_BYTES = 0xCA, + IPMI_CC_SENSOR_INVALID = 0xCB, + IPMI_CC_INVALID_FIELD_REQUEST = 0xCC, + IPMI_CC_ILLEGAL_COMMAND = 0xCD, + IPMI_CC_RESPONSE_ERROR = 0xCE, + IPMI_CC_INSUFFICIENT_PRIVILEGE = 0xD4, + IPMI_CC_UNSPECIFIED_ERROR = 0xFF, +}; + +// Temp solution: To detect the request source channel. +// There is no stright forward way to get the exact +// channel so we are hardcoding it to KCS in case host-ipmid +// and LAN1 for netipmid. +// we can't differentiate between LAN1 & LAN2 for netipmid in this logic. +// As our current design will not be able to support the same. This is done +// so that in all the places where ever we need to use the self channel can be +// be implemented properly and based on new architecture.this can be updated. +typedef enum +{ + interfaceKCS = 0, + interfaceLAN1 = 1, + interfaceUnknown = 0xFF +} EInterfaceIndex; + +EInterfaceIndex getInterfaceIndex(void); + +sd_bus* ipmid_get_sd_bus_connection(void); +sd_event* ipmid_get_sd_event_connection(void); +sd_bus_slot* ipmid_get_sd_bus_slot(void); + +#endif diff --git a/include/ipmid/iana.hpp b/include/ipmid/iana.hpp new file mode 100644 index 0000000..aa9e173 --- /dev/null +++ b/include/ipmid/iana.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace oem +{ +using Number = std::uint32_t; // smallest standard size >= 24. + +/* + * This is the OpenBMC IANA OEM Number + */ +constexpr Number obmcOemNumber = 49871; + +/* + * This is the Google IANA OEM Number + */ +constexpr Number googOemNumber = 11129; + +} // namespace oem diff --git a/include/ipmid/oemopenbmc.hpp b/include/ipmid/oemopenbmc.hpp new file mode 100644 index 0000000..b7b3a30 --- /dev/null +++ b/include/ipmid/oemopenbmc.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include + +namespace oem +{ +/* + * OpenBMC OEM Extension IPMI Command codes. + */ +enum Cmd +{ + gpioCmd = 1, + i2cCmd = 2, + flashCmd = 3, + fanManualCmd = 4, + ethStatsCmd = 48, + blobTransferCmd = 128, +}; + +} // namespace oem diff --git a/include/ipmid/oemrouter.hpp b/include/ipmid/oemrouter.hpp new file mode 100644 index 0000000..e0a9f14 --- /dev/null +++ b/include/ipmid/oemrouter.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace oem +{ +constexpr size_t groupMagicSize = 3; + +using Group = std::array; + +// Handler signature includes ipmi cmd to support wildcard cmd match. +// Buffers and lengths exclude the OemGroup bytes in the IPMI message. +// dataLen supplies length of reqBuf upon call, and should be set to the +// length of replyBuf upon return - conventional in this code base. +using Handler = std::function; // dataLen + +/// Router Interface class. +/// @brief Abstract Router Interface +class Router +{ + public: + virtual ~Router() + { + } + + /// Enable message routing to begin. + virtual void activate() = 0; + + /// Register a handler for given OEMNumber & cmd. + /// Use IPMI_CMD_WILDCARD to catch any unregistered cmd + /// for the given OEMNumber. + /// + /// @param[in] oen - the OEM Number. + /// @param[in] cmd - the Command. + /// @param[in] handler - the handler to call given that OEN and + /// command. + virtual void registerHandler(Number oen, ipmi_cmd_t cmd, + Handler handler) = 0; +}; + +/// Expose mutable Router for configuration & activation. +/// +/// @returns pointer to OEM Router to use. +Router* mutableRouter(); + +/// Convert a group to an OEN. +/// +/// @param[in] oeg - request buffer for IPMI command. +/// @return the OEN. +constexpr Number toOemNumber(const uint8_t oeg[groupMagicSize]) +{ + return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0]; +} + +/// Given a Group convert to an OEN. +/// +/// @param[in] oeg - OEM Group reference. +/// @return the OEN. +constexpr Number toOemNumber(const Group& oeg) +{ + return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0]; +} + +/// Given an OEN, conver to the OEM Group. +/// +/// @param[in] oen - the OEM Number. +/// @return the OEM Group. +constexpr Group toOemGroup(Number oen) +{ + return Group{static_cast(oen), static_cast(oen >> 8), + static_cast(oen >> 16)}; +} + +} // namespace oem diff --git a/ipmid.cpp b/ipmid.cpp index 19b88b0..e5860d0 100644 --- a/ipmid.cpp +++ b/ipmid.cpp @@ -17,9 +17,9 @@ #include #include -#include -#include #include +#include +#include #include #include #include diff --git a/ipmid.hpp b/ipmid.hpp index b59cd02..93a85b0 100644 --- a/ipmid.hpp +++ b/ipmid.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include // When the requester sends in a netfn and a command along with data, this diff --git a/libipmid-host/Makefile.am b/libipmid-host/Makefile.am new file mode 100644 index 0000000..7b8b003 --- /dev/null +++ b/libipmid-host/Makefile.am @@ -0,0 +1,8 @@ +pkgconfig_DATA = libipmid-host.pc +lib_LTLIBRARIES = libipmid-host.la +libipmid_host_la_SOURCES = +libipmid_host_la_LDFLAGS = \ + $(SDBUSPLUS_LIBS) \ + -version-info 0:0:0 -shared +libipmid_host_la_CXXFLAGS = \ + $(SDBUSPLUS_CFLAGS) diff --git a/libipmid-host/libipmid-host.pc.in b/libipmid-host/libipmid-host.pc.in new file mode 100644 index 0000000..ba842ac --- /dev/null +++ b/libipmid-host/libipmid-host.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libipmid-host +Description: IPMI Host Daemon Library +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lipmid-host diff --git a/libipmid/Makefile.am b/libipmid/Makefile.am new file mode 100644 index 0000000..e5724a8 --- /dev/null +++ b/libipmid/Makefile.am @@ -0,0 +1,8 @@ +pkgconfig_DATA = libipmid.pc +lib_LTLIBRARIES = libipmid.la +libipmid_la_SOURCES = +libipmid_la_LDFLAGS = \ + $(SYSTEMD_LIBS) \ + -version-info 0:0:0 -shared +libipmid_la_CXXFLAGS = \ + $(SYSTEMD_CFLAGS) diff --git a/libipmid/libipmid.pc.in b/libipmid/libipmid.pc.in new file mode 100644 index 0000000..9366846 --- /dev/null +++ b/libipmid/libipmid.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libipmid +Description: IPMI Daemon Library +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lipmid diff --git a/oemrouter.cpp b/oemrouter.cpp index f481970..00f66f1 100644 --- a/oemrouter.cpp +++ b/oemrouter.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/read_fru_data.cpp b/read_fru_data.cpp index 44ea11c..2bb111f 100644 --- a/read_fru_data.cpp +++ b/read_fru_data.cpp @@ -4,7 +4,7 @@ #include "types.hpp" #include "utils.hpp" -#include +#include #include #include diff --git a/selutility.cpp b/selutility.cpp index 0789be4..b9bf7ed 100644 --- a/selutility.cpp +++ b/selutility.cpp @@ -5,7 +5,7 @@ #include "types.hpp" #include "utils.hpp" -#include +#include #include #include diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp index d56aea8..9c32da9 100644 --- a/sensordatahandler.hpp +++ b/sensordatahandler.hpp @@ -4,7 +4,7 @@ #include "types.hpp" #include "utils.hpp" -#include +#include #include #include diff --git a/sensorhandler.cpp b/sensorhandler.cpp index 21677ea..3edf198 100644 --- a/sensorhandler.cpp +++ b/sensorhandler.cpp @@ -5,7 +5,7 @@ #include "types.hpp" #include "utils.hpp" -#include +#include #include #include diff --git a/sensorhandler.hpp b/sensorhandler.hpp index 5e55080..1d455f3 100644 --- a/sensorhandler.hpp +++ b/sensorhandler.hpp @@ -2,7 +2,7 @@ #include "types.hpp" -#include +#include #include // IPMI commands for net functions. diff --git a/softoff/Makefile.am b/softoff/Makefile.am index bbe7b6e..e43cfbb 100644 --- a/softoff/Makefile.am +++ b/softoff/Makefile.am @@ -1,5 +1,4 @@ AM_DEFAULT_SOURCE_EXT = .cpp -AM_CPPFLAGS = -I$(top_srcdir) sbin_PROGRAMS = phosphor-softpoweroff # Using ../ instead of $(top_srcdir) due to automake bug in version 1.15. diff --git a/storageaddsel.cpp b/storageaddsel.cpp index 1dde2a4..90d3276 100644 --- a/storageaddsel.cpp +++ b/storageaddsel.cpp @@ -4,7 +4,7 @@ #include "storagehandler.hpp" #include "types.hpp" -#include +#include #include #include diff --git a/storagehandler.cpp b/storagehandler.cpp index e142d9f..699e80c 100644 --- a/storagehandler.cpp +++ b/storagehandler.cpp @@ -8,7 +8,7 @@ #include "utils.hpp" #include -#include +#include #include #include diff --git a/systemintfcmds.cpp b/systemintfcmds.cpp index 06a46d0..d044030 100644 --- a/systemintfcmds.cpp +++ b/systemintfcmds.cpp @@ -5,10 +5,10 @@ #include "host-cmd-manager.hpp" #include "host-interface.hpp" -#include +#include #include -#include +#include void register_netfn_app_functions() __attribute__((constructor)); diff --git a/test/oemrouter_unittest.cpp b/test/oemrouter_unittest.cpp index ec79316..49a1382 100644 --- a/test/oemrouter_unittest.cpp +++ b/test/oemrouter_unittest.cpp @@ -1,7 +1,7 @@ -#include +#include #include -#include +#include #include "sample.h" diff --git a/transporthandler.cpp b/transporthandler.cpp index 14a9980..0b5a00c 100644 --- a/transporthandler.cpp +++ b/transporthandler.cpp @@ -6,7 +6,7 @@ #include "utils.hpp" #include -#include +#include #include #include diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp index a3aebb8..3a172bc 100644 --- a/user_channel/channel_layer.hpp +++ b/user_channel/channel_layer.hpp @@ -14,7 +14,7 @@ // limitations under the License. */ #pragma once -#include +#include #include diff --git a/user_channel/user_layer.hpp b/user_channel/user_layer.hpp index 7e8f185..6c8c683 100644 --- a/user_channel/user_layer.hpp +++ b/user_channel/user_layer.hpp @@ -14,7 +14,7 @@ // limitations under the License. */ #pragma once -#include +#include #include diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp index 3f82c15..0b86823 100644 --- a/user_channel/user_mgmt.cpp +++ b/user_channel/user_mgmt.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/user_channel/user_mgmt.hpp b/user_channel/user_mgmt.hpp index 0326dca..643ca93 100644 --- a/user_channel/user_mgmt.hpp +++ b/user_channel/user_mgmt.hpp @@ -16,7 +16,7 @@ #pragma once #include "user_layer.hpp" -#include +#include #include #include diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp index 507d95c..90aadb1 100644 --- a/user_channel/usercommands.cpp +++ b/user_channel/usercommands.cpp @@ -20,7 +20,7 @@ #include "channel_layer.hpp" #include "user_layer.hpp" -#include +#include #include #include -- cgit v1.2.1