ipmid: Add in Native OEM and Group OEM support

Add full support for the IPMI OEM NetFn and the Group OEM support as
defined in the IPMI 2.0 specification.

For now the legacy OEM router mechanism is still supported.

Change-Id: I8cc999489000c6e0daf5aad3579838e6f499ba47
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/include/ipmid/registration.hpp b/include/ipmid/registration.hpp
index 151aca1..af89bc8 100644
--- a/include/ipmid/registration.hpp
+++ b/include/ipmid/registration.hpp
@@ -27,6 +27,11 @@
 // 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
 
 /**
@@ -53,6 +58,80 @@
     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