Create framework for IPMI OEM extension commands

IPMI has four commands that accept "OEM Parameters". The existing IPMI
command handlers do not account for these OEM extensions. This commit
adds OEM Parameters support for the Set/Get LAN Configuration
Parameters commands.

Tested:

ipmitool raw 0xc 1 3 0xc0 0 ;; received 0x80 return code
ipmitool raw 0xc 2 3 0 0    ;; received 0x80 return code

Change-Id: I81135b6d3269cec98ffd7754a03201a74c436c11
Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
diff --git a/transporthandler.cpp b/transporthandler.cpp
index 777171c..a88e0a2 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -164,6 +164,9 @@
     CiphersuiteEntries = 23,
 };
 
+static constexpr uint8_t oemCmdStart = 192;
+static constexpr uint8_t oemCmdEnd = 255;
+
 /** @brief IPMI IP Origin Types */
 enum class IPSrc : uint8_t
 {
@@ -1067,6 +1070,60 @@
     return setStatus[channel] = SetStatus::Complete;
 }
 
+/**
+ * Define placeholder command handlers for the OEM Extension bytes for the Set
+ * LAN Configuration Parameters and Get LAN Configuration Parameters
+ * commands. Using "weak" linking allows the placeholder setLanOem/getLanOem
+ * functions below to be overridden.
+ * To create handlers for your own proprietary command set:
+ *   Create/modify a phosphor-ipmi-host Bitbake append file within your Yocto
+ *   recipe
+ *   Create C++ file(s) that define IPMI handler functions matching the
+ *     function names below (i.e. setLanOem). The default name for the
+ *     transport IPMI commands is transporthandler_oem.cpp.
+ *   Add:
+ *      EXTRA_OECONF_append = " --enable-transport-oem=yes"
+ *   Create a do_compile_prepend()/do_install_append method in your
+ *   bbappend file to copy the file to the build directory.
+ *   Add:
+ *   PROJECT_SRC_DIR := "${THISDIR}/${PN}"
+ *   # Copy the "strong" functions into the working directory, overriding the
+ *   # placeholder functions.
+ *   do_compile_prepend(){
+ *      cp -f ${PROJECT_SRC_DIR}/transporthandler_oem.cpp ${S}
+ *   }
+ *
+ *   # Clean up after complilation has completed
+ *   do_install_append(){
+ *      rm -f ${S}/transporthandler_oem.cpp
+ *   }
+ *
+ */
+
+/**
+ * Define the placeholder OEM commands as having weak linkage. Create
+ * setLanOem, and getLanOem functions in the transporthandler_oem.cpp
+ * file. The functions defined there must not have the "weak" attribute
+ * applied to them.
+ */
+RspType<> setLanOem(uint8_t channel, uint8_t parameter, message::Payload& req)
+    __attribute__((weak));
+RspType<message::Payload> getLanOem(uint8_t channel, uint8_t parameter,
+                                    uint8_t set, uint8_t block)
+    __attribute__((weak));
+
+RspType<> setLanOem(uint8_t channel, uint8_t parameter, message::Payload& req)
+{
+    req.trailingOk = true;
+    return response(ccParamNotSupported);
+}
+
+RspType<message::Payload> getLanOem(uint8_t channel, uint8_t parameter,
+                                    uint8_t set, uint8_t block)
+{
+    return response(ccParamNotSupported);
+}
+
 RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
                  message::Payload& req)
 {
@@ -1234,6 +1291,11 @@
         }
     }
 
+    if ((parameter >= oemCmdStart) && (parameter <= oemCmdEnd))
+    {
+        return setLanOem(channel, parameter, req);
+    }
+
     req.trailingOk = true;
     return response(ccParamNotSupported);
 }
@@ -1394,6 +1456,11 @@
         }
     }
 
+    if ((parameter >= oemCmdStart) && (parameter <= oemCmdEnd))
+    {
+        return getLanOem(channel, parameter, set, block);
+    }
+
     return response(ccParamNotSupported);
 }