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 <wak@google.com>
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 <ipmid/api.h>
+
+#include <array>
+#include <cstdint>
+#include <functional>
+#include <ipmid/iana.hpp>
+#include <vector>
+
+namespace oem
+{
+constexpr size_t groupMagicSize = 3;
+
+using Group = std::array<uint8_t, groupMagicSize>;
+
+// 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<ipmi_ret_t(ipmi_cmd_t,     // cmd byte
+                                         const uint8_t*, // reqBuf
+                                         uint8_t*,       // replyBuf
+                                         size_t*)>;      // 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<uint8_t>(oen), static_cast<uint8_t>(oen >> 8),
+                 static_cast<uint8_t>(oen >> 16)};
+}
+
+} // namespace oem