summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVernon Mauery <vernon.mauery@linux.intel.com>2019-04-03 09:19:34 -0700
committerVernon Mauery <vernon.mauery@linux.intel.com>2019-04-08 17:24:51 +0000
commite08fbffcd9bd1976f7d26d48bf7a4c3e5843d4a8 (patch)
tree6abf67790aef9bc4d8bdf49302550941dc2230c2
parent6c90b04bc5ec1c7e868eab00da7e9774626751b2 (diff)
downloadphosphor-host-ipmid-e08fbffcd9bd1976f7d26d48bf7a4c3e5843d4a8.tar.gz
phosphor-host-ipmid-e08fbffcd9bd1976f7d26d48bf7a4c3e5843d4a8.zip
Only include ipmid/api.hpp for the new API
After some feedback from users of the new IPMI API, they wanted to see two things: 1) don't require ipmid/api.hpp and ipmid/registration.hpp to be able to write new handlers 2) only require including ipmid/api.hpp (instead of ipmid/api.h) So now, by simply including ipmid/api.hpp instead of ipmid/api.h (deprecated), handlers incorporating the new IPMI API can be written. Change-Id: I446dcce70cff03d4ecc28c658292d052485f77fc Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
-rw-r--r--app/watchdog.cpp2
-rw-r--r--app/watchdog.hpp2
-rw-r--r--app/watchdog_service.cpp3
-rw-r--r--apphandler.cpp2
-rw-r--r--chassishandler.cpp2
-rw-r--r--dcmihandler.cpp3
-rw-r--r--globalhandler.cpp3
-rw-r--r--groupext.cpp3
-rw-r--r--include/Makefile.am2
-rw-r--r--include/ipmid/api-types.hpp (renamed from include/ipmid/registration.hpp)342
-rw-r--r--include/ipmid/api.hpp208
-rw-r--r--include/ipmid/filter.hpp43
-rw-r--r--include/ipmid/handler.hpp134
-rw-r--r--include/ipmid/message.hpp1
-rw-r--r--ipmid-new.cpp1
-rw-r--r--read_fru_data.cpp3
-rw-r--r--selutility.cpp3
-rw-r--r--sensordatahandler.hpp3
-rw-r--r--sensorhandler.cpp2
-rw-r--r--sensorhandler.hpp2
-rw-r--r--storageaddsel.cpp2
-rw-r--r--storagehandler.cpp2
-rw-r--r--systemintfcmds.cpp1
-rw-r--r--transporthandler.cpp2
-rw-r--r--user_channel/channel_layer.hpp1
-rw-r--r--user_channel/usercommands.cpp2
-rw-r--r--whitelist-filter.cpp1
27 files changed, 379 insertions, 396 deletions
diff --git a/app/watchdog.cpp b/app/watchdog.cpp
index 68af65c..51ba395 100644
--- a/app/watchdog.cpp
+++ b/app/watchdog.cpp
@@ -3,9 +3,9 @@
#include "watchdog_service.hpp"
#include <endian.h>
-#include <ipmid/api.h>
#include <cstdint>
+#include <ipmid/api.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
diff --git a/app/watchdog.hpp b/app/watchdog.hpp
index 767a776..32d6f16 100644
--- a/app/watchdog.hpp
+++ b/app/watchdog.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <ipmid/api.h>
+#include <ipmid/api.hpp>
/** @brief The RESET watchdog IPMI command.
*
diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
index e65ea63..284964d 100644
--- a/app/watchdog_service.cpp
+++ b/app/watchdog_service.cpp
@@ -1,8 +1,7 @@
#include "watchdog_service.hpp"
-#include <ipmid/api.h>
-
#include <exception>
+#include <ipmid/api.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
diff --git a/apphandler.cpp b/apphandler.cpp
index 1169e07..e1779bb 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -1,5 +1,4 @@
#include <arpa/inet.h>
-#include <ipmid/api.h>
#include <limits.h>
#include <mapper.h>
#include <systemd/sd-bus.h>
@@ -15,7 +14,6 @@
#include <filesystem>
#include <fstream>
#include <ipmid/api.hpp>
-#include <ipmid/registration.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <memory>
diff --git a/chassishandler.cpp b/chassishandler.cpp
index 7ac7b7d..ef760d5 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -6,7 +6,6 @@
#include <arpa/inet.h>
#include <endian.h>
-#include <ipmid/api.h>
#include <limits.h>
#include <mapper.h>
#include <netinet/in.h>
@@ -17,6 +16,7 @@
#include <filesystem>
#include <fstream>
#include <future>
+#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <map>
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
index cb14005..3188585 100644
--- a/dcmihandler.cpp
+++ b/dcmihandler.cpp
@@ -4,11 +4,10 @@
#include "user_channel/channel_layer.hpp"
-#include <ipmid/api.h>
-
#include <bitset>
#include <cmath>
#include <fstream>
+#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
diff --git a/globalhandler.cpp b/globalhandler.cpp
index e268fd1..27409c2 100644
--- a/globalhandler.cpp
+++ b/globalhandler.cpp
@@ -1,7 +1,6 @@
#include "globalhandler.hpp"
-#include <ipmid/api.h>
-
+#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
diff --git a/groupext.cpp b/groupext.cpp
index dbfade4..5b71dde 100644
--- a/groupext.cpp
+++ b/groupext.cpp
@@ -1,6 +1,5 @@
-#include <ipmid/api.h>
-
#include <cstdio>
+#include <ipmid/api.hpp>
#define GRPEXT_GET_GROUP_CMD 0
void register_netfn_groupext_functions() __attribute__((constructor));
diff --git a/include/Makefile.am b/include/Makefile.am
index a3051dd..b7c303a 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,12 +1,12 @@
nobase_include_HEADERS = \
ipmid/api.hpp \
+ ipmid/api-types.hpp \
ipmid/filter.hpp \
ipmid/handler.hpp \
ipmid/message.hpp \
ipmid/message/pack.hpp \
ipmid/message/types.hpp \
ipmid/message/unpack.hpp \
- ipmid/registration.hpp \
ipmid/api.h \
ipmid/iana.hpp \
ipmid/oemopenbmc.hpp \
diff --git a/include/ipmid/registration.hpp b/include/ipmid/api-types.hpp
index 45391ec..c718ff4 100644
--- a/include/ipmid/registration.hpp
+++ b/include/ipmid/api-types.hpp
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright © 2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,189 +12,76 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
*/
#pragma once
-
-#include <ipmid/api.hpp>
-#include <ipmid/filter.hpp>
-#include <ipmid/handler.hpp>
+#include <cstdint>
+#include <ipmid/iana.hpp>
+#include <optional>
+#include <tuple>
namespace ipmi
{
-namespace impl
-{
-
-// IPMI command handler registration implementation
-bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
- ::ipmi::HandlerBase::ptr handler);
-bool registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
- ::ipmi::HandlerBase::ptr handler);
-bool registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
- ::ipmi::HandlerBase::ptr handler);
+using Iana = oem::Number;
-// IPMI command filter registration implementation
-void registerFilter(int prio, ::ipmi::FilterBase::ptr filter);
+using Group = uint8_t;
+constexpr Group groupPICMG = 0x00;
+constexpr Group groupDMTG = 0x01;
+constexpr Group groupSSI = 0x02;
+constexpr Group groupVSO = 0x03;
+constexpr Group groupDCMI = 0xDC;
-} // namespace impl
-
-/**
- * @brief main IPMI handler registration function
- *
- * This function should be used to register all new-style IPMI handler
- * functions. This function just passes the callback to makeHandler, which
- * creates a new wrapper object that will automatically extract the appropriate
- * parameters for the callback function as well as pack up the response.
- *
- * @param prio - priority at which to register; see api.hpp
- * @param netFn - the IPMI net function number to register
- * @param cmd - the IPMI command number to register
- * @param priv - the IPMI user privilige required for this command
- * @param handler - the callback function that will handle this request
- *
- * @return bool - success of registering the handler
+/*
+ * Set the priority as the lowest number that is necessary so
+ * it is possible that others can override it if desired.
+ * This may be linked to what level of integration the handler
+ * is being created at.
*/
-template <typename Handler>
-bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
- Handler&& handler)
-{
- auto h = ipmi::makeHandler(std::forward<Handler>(handler));
- return impl::registerHandler(prio, netFn, cmd, priv, h);
-}
+constexpr int prioOpenBmcBase = 10;
+constexpr int prioOemBase = 20;
+constexpr int prioOdmBase = 30;
+constexpr int prioCustomBase = 40;
+constexpr int prioMax = 50;
-/**
- * @brief register a IPMI OEM group handler
- *
- * From IPMI 2.0 spec Network Function Codes Table (Row 2Ch):
- * The first data byte position in requests and responses under this network
- * function identifies the defining body that specifies command functionality.
- * Software assumes that the command and completion code field positions will
- * hold command and completion code values.
- *
- * The following values are used to identify the defining body:
- * 00h PICMG - PCI Industrial Computer Manufacturer’s Group. (www.picmg.com)
- * 01h DMTF Pre-OS Working Group ASF Specification (www.dmtf.org)
- * 02h Server System Infrastructure (SSI) Forum (www.ssiforum.org)
- * 03h VITA Standards Organization (VSO) (www.vita.com)
- * DCh DCMI Specifications (www.intel.com/go/dcmi)
- * all other Reserved
- *
- * When this network function is used, the ID for the defining body occupies
- * the first data byte in a request, and the second data byte (following the
- * completion code) in a response.
- *
- * @tparam Handler - implicitly specified callback function type
- * @param prio - priority at which to register; see api.hpp
- * @param netFn - the IPMI net function number to register
- * @param cmd - the IPMI command number to register
- * @param priv - the IPMI user privilige required for this command
- * @param handler - the callback function that will handle this request
- *
- * @return bool - success of registering the handler
- *
+/*
+ * Channel IDs pulled from the IPMI 2.0 specification
*/
-template <typename Handler>
-void registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
- Handler&& handler)
-{
- auto h = ipmi::makeHandler(handler);
- impl::registerGroupHandler(prio, group, cmd, priv, h);
-}
-
-/**
- * @brief register a IPMI OEM IANA handler
- *
- * From IPMI spec Network Function Codes Table (Row 2Eh):
- * The first three data bytes of requests and responses under this network
- * function explicitly identify the OEM or non-IPMI group that specifies the
- * command functionality. While the OEM or non-IPMI group defines the
- * functional semantics for the cmd and remaining data fields, the cmd field
- * is required to hold the same value in requests and responses for a given
- * operation in order to be supported under the IPMI message handling and
- * transport mechanisms.
- *
- * When this network function is used, the IANA Enterprise Number for the
- * defining body occupies the first three data bytes in a request, and the
- * first three data bytes following the completion code position in a
- * response.
- *
- * @tparam Handler - implicitly specified callback function type
- * @param prio - priority at which to register; see api.hpp
- * @param netFn - the IPMI net function number to register
- * @param cmd - the IPMI command number to register
- * @param priv - the IPMI user privilige required for this command
- * @param handler - the callback function that will handle this request
- *
- * @return bool - success of registering the handler
- *
- */
-template <typename Handler>
-void registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
- Handler&& handler)
-{
- auto h = ipmi::makeHandler(handler);
- impl::registerOemHandler(prio, iana, cmd, priv, h);
-}
+constexpr int channelPrimaryIpmb = 0x00;
+// 0x01-0x0B Implementation specific
+// Implementation specific channel numbers are specified
+// by a configuration file external to ipmid
+// 0x0C-0x0D reserved
+constexpr int channelCurrentIface = 0x0E; // 'Present I/F'
+constexpr int channelSystemIface = 0x0F;
-/**
- * @brief IPMI command filter registration function
- *
- * This function should be used to register IPMI command filter functions.
- * This function just passes the callback to makeFilter, which creates a
- * wrapper functor object that ultimately calls the callback.
- *
- * Filters are called with a ipmi::message::Request shared_ptr on all IPMI
- * commands in priority order and each filter has the opportunity to reject the
- * command (by returning an IPMI error competion code.) If all the filters
- * return success, the actual IPMI command will be executed. Filters can reject
- * the command for any reason, based on system state, the context, the command
- * payload, etc.
- *
- * @param prio - priority at which to register; see api.hpp
- * @param filter - the callback function that will handle this request
- *
- * @return bool - success of registering the handler
+/*
+ * 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
*/
-template <typename Filter>
-void registerFilter(int prio, Filter&& filter)
+enum class Privilege : uint8_t
{
- auto f = ipmi::makeFilter(std::forward<Filter>(filter));
- impl::registerFilter(prio, f);
-}
+ None = 0x00,
+ Callback,
+ User,
+ Operator,
+ Admin,
+ Oem,
+};
-template <typename Filter>
-void registerFilter(int prio, const Filter& filter)
-{
- auto f = ipmi::makeFilter(filter);
- impl::registerFilter(prio, f);
-}
-} // namespace ipmi
+// IPMI Net Function number as specified by IPMI V2.0 spec.
+using NetFn = uint8_t;
-#ifdef ALLOW_DEPRECATED_API
-/**
- * @brief legacy IPMI handler registration function
- *
- * This function should be used to register all legacy IPMI handler
- * functions. This function just behaves just as the legacy registration
- * mechanism did, silently replacing any existing handler with a new one.
- *
- * @param netFn - the IPMI net function number to register
- * @param cmd - the IPMI command number to register
- * @param context - ignored
- * @param handler - the callback function that will handle this request
- * @param priv - the IPMI user privilige required for this command
- */
-// [[deprecated("Use ipmi::registerHandler() instead")]]
-void ipmi_register_callback(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
- ipmi_context_t context, ipmid_callback_t handler,
- ipmi_cmd_privilege_t priv);
+// IPMI Command for a Net Function number as specified by IPMI V2.0 spec.
+using Cmd = uint8_t;
-#endif /* ALLOW_DEPRECATED_API */
+// ipmi function return the status code
+using Cc = uint8_t;
// IPMI 2.0 and DCMI 1.5 standard commands, namespaced by NetFn
// OEM and non-standard commands should be defined where they are used
-namespace ipmi
-{
namespace app
{
// 0x00 reserved
@@ -439,4 +326,131 @@ constexpr Cmd cmdSetDcmiConfigParameters = 0x12;
constexpr Cmd cmdGetDcmiConfigParameters = 0x13;
} // namespace dcmi
+// 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 will be left shifted when combined with the LUN
+constexpr NetFn netFnChassis = 0x00;
+constexpr NetFn netFnBridge = 0x02;
+constexpr NetFn netFnSensor = 0x04;
+constexpr NetFn netFnApp = 0x06;
+constexpr NetFn netFnFirmware = 0x08;
+constexpr NetFn netFnStorage = 0x0A;
+constexpr NetFn netFnTransport = 0x0C;
+// reserved 0Eh..28h
+constexpr NetFn netFnGroup = 0x2C;
+constexpr NetFn netFnOem = 0x2E;
+constexpr NetFn netFnOemOne = 0x30;
+constexpr NetFn netFnOemTwo = 0x32;
+constexpr NetFn netFnOemThree = 0x34;
+constexpr NetFn netFnOemFour = 0x36;
+constexpr NetFn netFnOemFive = 0x38;
+constexpr NetFn netFnOemSix = 0x3A;
+constexpr NetFn netFnOemSeven = 0x3C;
+constexpr NetFn netFnOemEight = 0x3E;
+
+// IPMI commands for net functions. Callbacks using this should be careful to
+// parse arguments to the sub-functions and can take advantage of the built-in
+// message handling mechanism to create custom routing
+constexpr Cmd cmdWildcard = 0xFF;
+
+// IPMI standard completion codes specified by the IPMI V2.0 spec.
+//
+// This might have been an enum class, but that would make it hard for
+// OEM- and command-specific completion codes to be added elsewhere.
+//
+// Custom completion codes can be defined in individual modules for
+// command specific errors in the 0x80-0xBE range
+//
+// Alternately, OEM completion codes are in the 0x01-0x7E range
+constexpr Cc ccSuccess = 0x00;
+constexpr Cc ccBusy = 0xC0;
+constexpr Cc ccInvalidCommand = 0xC1;
+constexpr Cc ccInvalidCommandOnLun = 0xC2;
+constexpr Cc ccTimeout = 0xC2;
+constexpr Cc ccOutOfSpace = 0xC2;
+constexpr Cc ccInvalidReservationId = 0xC5;
+constexpr Cc ccReqDataTruncated = 0xC6;
+constexpr Cc ccReqDataLenInvalid = 0xC7;
+constexpr Cc ccReqDataLenExceeded = 0xC8;
+constexpr Cc ccParmOutOfRange = 0xC9;
+constexpr Cc ccRetBytesUnavailable = 0xCA;
+constexpr Cc ccSensorInvalid = 0xCB;
+constexpr Cc ccInvalidFieldRequest = 0xCC;
+constexpr Cc ccIllegalCommand = 0xCD;
+constexpr Cc ccResponseError = 0xCE;
+constexpr Cc ccDuplicateRequest = 0xCF;
+constexpr Cc ccCmdFailSdrMode = 0xD0;
+constexpr Cc ccCmdFailFwUpdMode = 0xD1;
+constexpr Cc ccCmdFailInitAgent = 0xD2;
+constexpr Cc ccDestinationUnavailable = 0xD3;
+constexpr Cc ccInsufficientPrivilege = 0xD4;
+constexpr Cc ccCommandNotAvailable = 0xD5;
+constexpr Cc ccCommandDisabled = 0xD6;
+constexpr Cc ccUnspecifiedError = 0xFF;
+
+/* ipmi often has two return types:
+ * 1. Failure: CC is non-zero; no trailing data
+ * 2. Success: CC is zero; trailing data (usually a fixed type)
+ *
+ * using ipmi::response(cc, ...), it will automatically always pack
+ * the correct type for the response without having to explicitly type out all
+ * the parameters that the function would return.
+ *
+ * To enable this feature, you just define the ipmi function as returning an
+ * ipmi::RspType which has the optional trailing data built in, with your types
+ * defined as parameters.
+ */
+
+template <typename... RetTypes>
+using RspType = std::tuple<ipmi::Cc, std::optional<std::tuple<RetTypes...>>>;
+
+/**
+ * @brief helper function to create an IPMI response tuple
+ *
+ * IPMI handlers all return a tuple with two parts: a completion code and an
+ * optional tuple containing the rest of the data to return. This helper
+ * function makes it easier by constructing that out of an arbitrary number of
+ * arguments.
+ *
+ * @param cc - the completion code for the response
+ * @param args... - the optional list of values to return
+ *
+ * @return a standard IPMI return type (as described above)
+ */
+template <typename... Args>
+static inline auto response(ipmi::Cc cc, Args&&... args)
+{
+ return std::make_tuple(cc, std::make_optional(std::make_tuple(args...)));
+}
+static inline auto response(ipmi::Cc cc)
+{
+ return std::make_tuple(cc, std::nullopt);
+}
+
+/**
+ * @brief helper function to create an IPMI success response tuple
+ *
+ * IPMI handlers all return a tuple with two parts: a completion code and an
+ * optional tuple containing the rest of the data to return. This helper
+ * function makes it easier by constructing that out of an arbitrary number of
+ * arguments. Because it is a success response, this automatically packs
+ * the completion code, without needing to explicitly pass it in.
+ *
+ * @param args... - the optional list of values to return
+ *
+ * @return a standard IPMI return type (as described above)
+ */
+template <typename... Args>
+static inline auto responseSuccess(Args&&... args)
+{
+ return std::make_tuple(ipmi::ccSuccess,
+ std::make_optional(std::make_tuple(args...)));
+}
+static inline auto responseSuccess()
+{
+ return std::make_tuple(ipmi::ccSuccess, std::nullopt);
+}
+
} // namespace ipmi
diff --git a/include/ipmid/api.hpp b/include/ipmid/api.hpp
index b825796..f4cbf13 100644
--- a/include/ipmid/api.hpp
+++ b/include/ipmid/api.hpp
@@ -17,210 +17,18 @@
#pragma once
#define ALLOW_DEPRECATED_API 1
-
-#include <ipmid/iana.hpp>
+// make it possible to ONLY include api.hpp during the transition
+#ifdef ALLOW_DEPRECATED_API
+#include <ipmid/api.h>
+#endif
+
+#include <ipmid/api-types.hpp>
+#include <ipmid/filter.hpp>
+#include <ipmid/handler.hpp>
#include <ipmid/message/types.hpp>
-#include <optional>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
-/* NOTE:
- *
- * This is intended for native C++ use. For the legacy C api, include
- * ipmid-api.h for a reduced functionality. Note that the C api is now marked
- * as deprecated and will be removed once all the internal users of it have
- * been updated to use the new C++ api.
- */
-
-namespace ipmi
-{
-
-using Iana = oem::Number;
-
-using Group = uint8_t;
-constexpr Group groupPICMG = 0x00;
-constexpr Group groupDMTG = 0x01;
-constexpr Group groupSSI = 0x02;
-constexpr Group groupVSO = 0x03;
-constexpr Group groupDCMI = 0xDC;
-
-/*
- * Set the priority as the lowest number that is necessary so
- * it is possible that others can override it if desired.
- * This may be linked to what level of integration the handler
- * is being created at.
- */
-constexpr int prioOpenBmcBase = 10;
-constexpr int prioOemBase = 20;
-constexpr int prioOdmBase = 30;
-constexpr int prioCustomBase = 40;
-constexpr int prioMax = 50;
-
-/*
- * Channel IDs pulled from the IPMI 2.0 specification
- */
-constexpr int channelPrimaryIpmb = 0x00;
-// 0x01-0x0B Implementation specific
-// Implementation specific channel numbers are specified
-// by a configuration file external to ipmid
-// 0x0C-0x0D reserved
-constexpr int channelCurrentIface = 0x0E; // 'Present I/F'
-constexpr int channelSystemIface = 0x0F;
-
-/*
- * 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 class Privilege : uint8_t
-{
- None = 0x00,
- Callback,
- User,
- Operator,
- Admin,
- Oem,
-};
-
-// IPMI Net Function number as specified by IPMI V2.0 spec.
-using NetFn = uint8_t;
-
-// IPMI Command for a Net Function number as specified by IPMI V2.0 spec.
-using Cmd = uint8_t;
-
-// ipmi function return the status code
-using Cc = uint8_t;
-
-// 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 will be left shifted when combined with the LUN
-constexpr NetFn netFnChassis = 0x00;
-constexpr NetFn netFnBridge = 0x02;
-constexpr NetFn netFnSensor = 0x04;
-constexpr NetFn netFnApp = 0x06;
-constexpr NetFn netFnFirmware = 0x08;
-constexpr NetFn netFnStorage = 0x0A;
-constexpr NetFn netFnTransport = 0x0C;
-// reserved 0Eh..28h
-constexpr NetFn netFnGroup = 0x2C;
-constexpr NetFn netFnOem = 0x2E;
-constexpr NetFn netFnOemOne = 0x30;
-constexpr NetFn netFnOemTwo = 0x32;
-constexpr NetFn netFnOemThree = 0x34;
-constexpr NetFn netFnOemFour = 0x36;
-constexpr NetFn netFnOemFive = 0x38;
-constexpr NetFn netFnOemSix = 0x3A;
-constexpr NetFn netFnOemSeven = 0x3C;
-constexpr NetFn netFnOemEight = 0x3E;
-
-// IPMI commands for net functions. Callbacks using this should be careful to
-// parse arguments to the sub-functions and can take advantage of the built-in
-// message handling mechanism to create custom routing
-constexpr Cmd cmdWildcard = 0xFF;
-
-// IPMI standard completion codes specified by the IPMI V2.0 spec.
-//
-// This might have been an enum class, but that would make it hard for
-// OEM- and command-specific completion codes to be added elsewhere.
-//
-// Custom completion codes can be defined in individual modules for
-// command specific errors in the 0x80-0xBE range
-//
-// Alternately, OEM completion codes are in the 0x01-0x7E range
-constexpr Cc ccSuccess = 0x00;
-constexpr Cc ccBusy = 0xC0;
-constexpr Cc ccInvalidCommand = 0xC1;
-constexpr Cc ccInvalidCommandOnLun = 0xC2;
-constexpr Cc ccTimeout = 0xC2;
-constexpr Cc ccOutOfSpace = 0xC2;
-constexpr Cc ccInvalidReservationId = 0xC5;
-constexpr Cc ccReqDataTruncated = 0xC6;
-constexpr Cc ccReqDataLenInvalid = 0xC7;
-constexpr Cc ccReqDataLenExceeded = 0xC8;
-constexpr Cc ccParmOutOfRange = 0xC9;
-constexpr Cc ccRetBytesUnavailable = 0xCA;
-constexpr Cc ccSensorInvalid = 0xCB;
-constexpr Cc ccInvalidFieldRequest = 0xCC;
-constexpr Cc ccIllegalCommand = 0xCD;
-constexpr Cc ccResponseError = 0xCE;
-constexpr Cc ccDuplicateRequest = 0xCF;
-constexpr Cc ccCmdFailSdrMode = 0xD0;
-constexpr Cc ccCmdFailFwUpdMode = 0xD1;
-constexpr Cc ccCmdFailInitAgent = 0xD2;
-constexpr Cc ccDestinationUnavailable = 0xD3;
-constexpr Cc ccInsufficientPrivilege = 0xD4;
-constexpr Cc ccCommandNotAvailable = 0xD5;
-constexpr Cc ccCommandDisabled = 0xD6;
-constexpr Cc ccUnspecifiedError = 0xFF;
-
-/* ipmi often has two return types:
- * 1. Failure: CC is non-zero; no trailing data
- * 2. Success: CC is zero; trailing data (usually a fixed type)
- *
- * using ipmi::response(cc, ...), it will automatically always pack
- * the correct type for the response without having to explicitly type out all
- * the parameters that the function would return.
- *
- * To enable this feature, you just define the ipmi function as returning an
- * ipmi::RspType which has the optional trailing data built in, with your types
- * defined as parameters.
- */
-
-template <typename... RetTypes>
-using RspType = std::tuple<ipmi::Cc, std::optional<std::tuple<RetTypes...>>>;
-
-/**
- * @brief helper function to create an IPMI response tuple
- *
- * IPMI handlers all return a tuple with two parts: a completion code and an
- * optional tuple containing the rest of the data to return. This helper
- * function makes it easier by constructing that out of an arbitrary number of
- * arguments.
- *
- * @param cc - the completion code for the response
- * @param args... - the optional list of values to return
- *
- * @return a standard IPMI return type (as described above)
- */
-template <typename... Args>
-static inline auto response(ipmi::Cc cc, Args&&... args)
-{
- return std::make_tuple(cc, std::make_optional(std::make_tuple(args...)));
-}
-static inline auto response(ipmi::Cc cc)
-{
- return std::make_tuple(cc, std::nullopt);
-}
-
-/**
- * @brief helper function to create an IPMI success response tuple
- *
- * IPMI handlers all return a tuple with two parts: a completion code and an
- * optional tuple containing the rest of the data to return. This helper
- * function makes it easier by constructing that out of an arbitrary number of
- * arguments. Because it is a success response, this automatically packs
- * the completion code, without needing to explicitly pass it in.
- *
- * @param args... - the optional list of values to return
- *
- * @return a standard IPMI return type (as described above)
- */
-template <typename... Args>
-static inline auto responseSuccess(Args&&... args)
-{
- return std::make_tuple(ipmi::ccSuccess,
- std::make_optional(std::make_tuple(args...)));
-}
-static inline auto responseSuccess()
-{
- return std::make_tuple(ipmi::ccSuccess, std::nullopt);
-}
-
-} // namespace ipmi
-
// any client can interact with the main asio context
std::shared_ptr<boost::asio::io_context> getIoContext();
diff --git a/include/ipmid/filter.hpp b/include/ipmid/filter.hpp
index 3cd5d21..950e3c3 100644
--- a/include/ipmid/filter.hpp
+++ b/include/ipmid/filter.hpp
@@ -17,7 +17,7 @@
#include <algorithm>
#include <boost/callable_traits.hpp>
#include <cstdint>
-#include <ipmid/api.hpp>
+#include <ipmid/api-types.hpp>
#include <ipmid/message.hpp>
#include <memory>
#include <tuple>
@@ -91,4 +91,45 @@ static inline auto makeFilter(const Filter& filter)
return makeFilter(std::forward<Filter>(lFilter));
}
+namespace impl
+{
+
+// IPMI command filter registration implementation
+void registerFilter(int prio, ::ipmi::FilterBase::ptr filter);
+
+} // namespace impl
+
+/**
+ * @brief IPMI command filter registration function
+ *
+ * This function should be used to register IPMI command filter functions.
+ * This function just passes the callback to makeFilter, which creates a
+ * wrapper functor object that ultimately calls the callback.
+ *
+ * Filters are called with a ipmi::message::Request shared_ptr on all IPMI
+ * commands in priority order and each filter has the opportunity to reject the
+ * command (by returning an IPMI error competion code.) If all the filters
+ * return success, the actual IPMI command will be executed. Filters can reject
+ * the command for any reason, based on system state, the context, the command
+ * payload, etc.
+ *
+ * @param prio - priority at which to register; see api.hpp
+ * @param filter - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ */
+template <typename Filter>
+void registerFilter(int prio, Filter&& filter)
+{
+ auto f = ipmi::makeFilter(std::forward<Filter>(filter));
+ impl::registerFilter(prio, f);
+}
+
+template <typename Filter>
+void registerFilter(int prio, const Filter& filter)
+{
+ auto f = ipmi::makeFilter(filter);
+ impl::registerFilter(prio, f);
+}
+
} // namespace ipmi
diff --git a/include/ipmid/handler.hpp b/include/ipmid/handler.hpp
index 17beb42..1421c3d 100644
--- a/include/ipmid/handler.hpp
+++ b/include/ipmid/handler.hpp
@@ -19,7 +19,7 @@
#include <boost/callable_traits.hpp>
#include <cstdint>
#include <exception>
-#include <ipmid/api.hpp>
+#include <ipmid/api-types.hpp>
#include <ipmid/message.hpp>
#include <memory>
#include <optional>
@@ -502,4 +502,136 @@ inline auto makeHandler(Handler&& handler)
return ptr;
}
+namespace impl
+{
+
+// IPMI command handler registration implementation
+bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
+ ::ipmi::HandlerBase::ptr handler);
+bool registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
+ ::ipmi::HandlerBase::ptr handler);
+bool registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
+ ::ipmi::HandlerBase::ptr handler);
+
+} // namespace impl
+
+/**
+ * @brief main IPMI handler registration function
+ *
+ * This function should be used to register all new-style IPMI handler
+ * functions. This function just passes the callback to makeHandler, which
+ * creates a new wrapper object that will automatically extract the appropriate
+ * parameters for the callback function as well as pack up the response.
+ *
+ * @param prio - priority at which to register; see api.hpp
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param priv - the IPMI user privilige required for this command
+ * @param handler - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ */
+template <typename Handler>
+bool registerHandler(int prio, NetFn netFn, Cmd cmd, Privilege priv,
+ Handler&& handler)
+{
+ auto h = ipmi::makeHandler(std::forward<Handler>(handler));
+ return impl::registerHandler(prio, netFn, cmd, priv, h);
+}
+
+/**
+ * @brief register a IPMI OEM group handler
+ *
+ * From IPMI 2.0 spec Network Function Codes Table (Row 2Ch):
+ * The first data byte position in requests and responses under this network
+ * function identifies the defining body that specifies command functionality.
+ * Software assumes that the command and completion code field positions will
+ * hold command and completion code values.
+ *
+ * The following values are used to identify the defining body:
+ * 00h PICMG - PCI Industrial Computer Manufacturer’s Group. (www.picmg.com)
+ * 01h DMTF Pre-OS Working Group ASF Specification (www.dmtf.org)
+ * 02h Server System Infrastructure (SSI) Forum (www.ssiforum.org)
+ * 03h VITA Standards Organization (VSO) (www.vita.com)
+ * DCh DCMI Specifications (www.intel.com/go/dcmi)
+ * all other Reserved
+ *
+ * When this network function is used, the ID for the defining body occupies
+ * the first data byte in a request, and the second data byte (following the
+ * completion code) in a response.
+ *
+ * @tparam Handler - implicitly specified callback function type
+ * @param prio - priority at which to register; see api.hpp
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param priv - the IPMI user privilige required for this command
+ * @param handler - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ *
+ */
+template <typename Handler>
+void registerGroupHandler(int prio, Group group, Cmd cmd, Privilege priv,
+ Handler&& handler)
+{
+ auto h = ipmi::makeHandler(handler);
+ impl::registerGroupHandler(prio, group, cmd, priv, h);
+}
+
+/**
+ * @brief register a IPMI OEM IANA handler
+ *
+ * From IPMI spec Network Function Codes Table (Row 2Eh):
+ * The first three data bytes of requests and responses under this network
+ * function explicitly identify the OEM or non-IPMI group that specifies the
+ * command functionality. While the OEM or non-IPMI group defines the
+ * functional semantics for the cmd and remaining data fields, the cmd field
+ * is required to hold the same value in requests and responses for a given
+ * operation in order to be supported under the IPMI message handling and
+ * transport mechanisms.
+ *
+ * When this network function is used, the IANA Enterprise Number for the
+ * defining body occupies the first three data bytes in a request, and the
+ * first three data bytes following the completion code position in a
+ * response.
+ *
+ * @tparam Handler - implicitly specified callback function type
+ * @param prio - priority at which to register; see api.hpp
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param priv - the IPMI user privilige required for this command
+ * @param handler - the callback function that will handle this request
+ *
+ * @return bool - success of registering the handler
+ *
+ */
+template <typename Handler>
+void registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
+ Handler&& handler)
+{
+ auto h = ipmi::makeHandler(handler);
+ impl::registerOemHandler(prio, iana, cmd, priv, h);
+}
+
} // namespace ipmi
+
+#ifdef ALLOW_DEPRECATED_API
+/**
+ * @brief legacy IPMI handler registration function
+ *
+ * This function should be used to register all legacy IPMI handler
+ * functions. This function just behaves just as the legacy registration
+ * mechanism did, silently replacing any existing handler with a new one.
+ *
+ * @param netFn - the IPMI net function number to register
+ * @param cmd - the IPMI command number to register
+ * @param context - ignored
+ * @param handler - the callback function that will handle this request
+ * @param priv - the IPMI user privilige required for this command
+ */
+// [[deprecated("Use ipmi::registerHandler() instead")]]
+void ipmi_register_callback(ipmi_netfn_t netFn, ipmi_cmd_t cmd,
+ ipmi_context_t context, ipmid_callback_t handler,
+ ipmi_cmd_privilege_t priv);
+
+#endif /* ALLOW_DEPRECATED_API */
diff --git a/include/ipmid/message.hpp b/include/ipmid/message.hpp
index e628ff0..4079eab 100644
--- a/include/ipmid/message.hpp
+++ b/include/ipmid/message.hpp
@@ -18,6 +18,7 @@
#include <algorithm>
#include <boost/asio/spawn.hpp>
#include <cstdint>
+#include <ipmid/api-types.hpp>
#include <ipmid/message/types.hpp>
#include <memory>
#include <phosphor-logging/log.hpp>
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
index 2668157..2a2d4a6 100644
--- a/ipmid-new.cpp
+++ b/ipmid-new.cpp
@@ -31,7 +31,6 @@
#include <ipmid/handler.hpp>
#include <ipmid/message.hpp>
#include <ipmid/oemrouter.hpp>
-#include <ipmid/registration.hpp>
#include <ipmid/types.hpp>
#include <map>
#include <memory>
diff --git a/read_fru_data.cpp b/read_fru_data.cpp
index 17bcfe4..1f99e20 100644
--- a/read_fru_data.cpp
+++ b/read_fru_data.cpp
@@ -2,9 +2,8 @@
#include "fruread.hpp"
-#include <ipmid/api.h>
-
#include <algorithm>
+#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <map>
diff --git a/selutility.cpp b/selutility.cpp
index 3aecb1c..97c2b2b 100644
--- a/selutility.cpp
+++ b/selutility.cpp
@@ -2,10 +2,9 @@
#include "selutility.hpp"
-#include <ipmid/api.h>
-
#include <chrono>
#include <filesystem>
+#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
index 8403a8d..6d80f9a 100644
--- a/sensordatahandler.hpp
+++ b/sensordatahandler.hpp
@@ -2,9 +2,8 @@
#include "sensorhandler.hpp"
-#include <ipmid/api.h>
-
#include <cmath>
+#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <sdbusplus/message/types.hpp>
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index cf8feaa..48546af 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -2,13 +2,13 @@
#include "fruread.hpp"
-#include <ipmid/api.h>
#include <mapper.h>
#include <systemd/sd-bus.h>
#include <bitset>
#include <cmath>
#include <cstring>
+#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
diff --git a/sensorhandler.hpp b/sensorhandler.hpp
index 21d2317..954a3ed 100644
--- a/sensorhandler.hpp
+++ b/sensorhandler.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include <ipmid/api.h>
#include <stdint.h>
+#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
// IPMI commands for net functions.
diff --git a/storageaddsel.cpp b/storageaddsel.cpp
index 5adb673..6b53f87 100644
--- a/storageaddsel.cpp
+++ b/storageaddsel.cpp
@@ -3,7 +3,6 @@
#include "sensorhandler.hpp"
#include "storagehandler.hpp"
-#include <ipmid/api.h>
#include <mapper.h>
#include <systemd/sd-bus.h>
@@ -12,6 +11,7 @@
#include <cstring>
#include <fstream>
#include <iostream>
+#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <memory>
#include <phosphor-logging/elog.hpp>
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 55e17f2..18f1357 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -7,7 +7,6 @@
#include "storageaddsel.hpp"
#include <arpa/inet.h>
-#include <ipmid/api.h>
#include <mapper.h>
#include <systemd/sd-bus.h>
@@ -16,6 +15,7 @@
#include <cstdio>
#include <cstring>
#include <filesystem>
+#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
diff --git a/systemintfcmds.cpp b/systemintfcmds.cpp
index aeded06..d298abd 100644
--- a/systemintfcmds.cpp
+++ b/systemintfcmds.cpp
@@ -8,7 +8,6 @@
#include <cstring>
#include <ipmid-host/cmd.hpp>
#include <ipmid/api.hpp>
-#include <ipmid/registration.hpp>
void register_netfn_app_functions() __attribute__((constructor));
diff --git a/transporthandler.cpp b/transporthandler.cpp
index ba0772b..59d933a 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -4,11 +4,11 @@
#include "user_channel/channel_layer.hpp"
#include <arpa/inet.h>
-#include <ipmid/api.h>
#include <chrono>
#include <filesystem>
#include <fstream>
+#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp
index b86d6bf..94570fb 100644
--- a/user_channel/channel_layer.hpp
+++ b/user_channel/channel_layer.hpp
@@ -16,7 +16,6 @@
#pragma once
#include <ipmid/api.h>
-#include <ipmid/api.hpp>
#include <ipmid/message.hpp>
#include <string>
diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp
index d0ea29f..76def4b 100644
--- a/user_channel/usercommands.cpp
+++ b/user_channel/usercommands.cpp
@@ -20,9 +20,9 @@
#include "channel_layer.hpp"
#include "user_layer.hpp"
-#include <ipmid/api.h>
#include <security/pam_appl.h>
+#include <ipmid/api.hpp>
#include <phosphor-logging/log.hpp>
#include <regex>
diff --git a/whitelist-filter.cpp b/whitelist-filter.cpp
index 1d486ca..a24ccad 100644
--- a/whitelist-filter.cpp
+++ b/whitelist-filter.cpp
@@ -1,7 +1,6 @@
#include <algorithm>
#include <array>
#include <ipmid/api.hpp>
-#include <ipmid/registration.hpp>
#include <ipmid/utils.hpp>
#include <ipmiwhitelist.hpp>
#include <phosphor-logging/elog-errors.hpp>
OpenPOWER on IntegriCloud