summaryrefslogtreecommitdiffstats
path: root/include/ipmid
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 /include/ipmid
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>
Diffstat (limited to 'include/ipmid')
-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
5 files changed, 362 insertions, 366 deletions
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>
OpenPOWER on IntegriCloud