Command Table Entry for IPMI Provider Commands

This patch defines an entry for hooking IPMI provider commands in
the command table and to execute the commands.

Change-Id: I8a8fb7c06ccc1a3c4397540419b983556b9da6c3
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/command_table.cpp b/command_table.cpp
index 6550160..a49f92c 100644
--- a/command_table.cpp
+++ b/command_table.cpp
@@ -77,4 +77,29 @@
     return functor(commandData, handler);
 }
 
+std::vector<uint8_t> ProviderIpmidEntry::executeCommand(
+        std::vector<uint8_t>& commandData,
+        const message::Handler& handler)
+{
+
+    std::vector<uint8_t> response(MAX_IPMI_BUFFER);
+    size_t respSize {};
+
+    ipmi_ret_t ipmiRC = functor(0, 0,
+                                reinterpret_cast<void*>(commandData.data()),
+                                reinterpret_cast<void*>(response.data() + 1),
+                                &respSize, NULL);
+
+    /*
+     * respSize gets you the size of the response data for the IPMI command. The
+     * first byte in a response to the IPMI command is the Completion Code.
+     * So we are inserting completion code as the first byte and incrementing
+     * the response payload size by the size of the completion code.
+     */
+    response[0] = ipmiRC;
+    response.resize(respSize + sizeof(ipmi_ret_t));
+
+    return response;
+}
+
 } // namespace command
diff --git a/command_table.hpp b/command_table.hpp
index 40e8020..7a6ee81 100644
--- a/command_table.hpp
+++ b/command_table.hpp
@@ -3,6 +3,7 @@
 #include <functional>
 #include <map>
 
+#include <host-ipmid/ipmid-api.h>
 #include "message_handler.hpp"
 
 namespace command
@@ -197,6 +198,46 @@
 };
 
 /*
+ * @class ProviderIpmidEntry
+ *
+ * ProviderIpmidEntry is used to register commands to the Command Table, that
+ * are registered by IPMI provider libraries.
+ *
+ */
+class ProviderIpmidEntry final: public Entry
+{
+    public:
+        ProviderIpmidEntry(CommandID command,
+                           ipmid_callback_t functor,
+                           session::Privilege privilege):
+            Entry(command, privilege),
+            functor(functor) {}
+
+        /**
+         * @brief Execute the command
+         *
+         * Execute the callback handler
+         *
+         * @param[in] commandData - Request Data for the command
+         * @param[in] handler - Reference to the Message Handler
+         *
+         * @return Response data for the command
+         */
+        std::vector<uint8_t> executeCommand(std::vector<uint8_t>& commandData,
+                                            const message::Handler& handler)
+                                            override;
+
+        virtual ~ProviderIpmidEntry() = default;
+        ProviderIpmidEntry(const ProviderIpmidEntry&) = default;
+        ProviderIpmidEntry& operator=(const ProviderIpmidEntry&) = default;
+        ProviderIpmidEntry(ProviderIpmidEntry&&) = default;
+        ProviderIpmidEntry& operator=(ProviderIpmidEntry&&) = default;
+
+    private:
+        ipmid_callback_t functor;
+};
+
+/*
  * @class Table
  *
  * Table keeps the IPMI command entries as a sorted associative container with