Command Router to handle commands
This class encapsulates the details regarding the execution of the
command and has routines for registering and execution of
the command.
Change-Id: Idf26e1f60f9f89aa5261fde89577ec7ddc26c096
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/command_table.cpp b/command_table.cpp
new file mode 100644
index 0000000..6550160
--- /dev/null
+++ b/command_table.cpp
@@ -0,0 +1,80 @@
+#include "command_table.hpp"
+
+#include <iomanip>
+#include <iostream>
+
+#include <host-ipmid/ipmid-api.h>
+#include "message_handler.hpp"
+#include "sessions_manager.hpp"
+
+namespace command
+{
+
+void Table::registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry)
+{
+ std::cout << "I> Registering Command" << std::hex
+ << inCommand.command << "\n";
+
+ commandTable[inCommand.command] = std::move(entry);
+}
+
+std::vector<uint8_t> Table::executeCommand(uint32_t inCommand,
+ std::vector<uint8_t>& commandData,
+ const message::Handler& handler)
+{
+ using namespace std::chrono_literals;
+
+ std::vector<uint8_t> response;
+
+ auto iterator = commandTable.find(inCommand);
+
+ if (iterator == commandTable.end())
+ {
+ std::cerr << "E> Table:: Command Not found: 0x" << std::hex << inCommand
+ << "\n";
+
+ response.resize(1);
+ response[0] = IPMI_CC_INVALID;
+ }
+ else
+ {
+ auto start = std::chrono::steady_clock::now();
+
+ response = iterator->second->executeCommand(commandData, handler);
+
+ auto end = std::chrono::steady_clock::now();
+
+ auto elapsedSeconds = std::chrono::duration_cast<std::chrono::seconds>
+ (end - start);
+
+ // If command time execution time exceeds 2 seconds, log a time
+ // exceeded message
+ if (elapsedSeconds > 2s)
+ {
+ std::cerr << "E> IPMI command timed out:Elapsed time = "
+ << elapsedSeconds.count() << "s" << "\n";
+ }
+ }
+ return response;
+}
+
+std::vector<uint8_t> NetIpmidEntry::executeCommand(
+ std::vector<uint8_t>& commandData,
+ const message::Handler& handler)
+{
+ std::vector<uint8_t> errResponse;
+
+ // Check if the command qualifies to be run prior to establishing a session
+ if (!sessionless && (handler.sessionID == session::SESSION_ZERO))
+ {
+ errResponse.resize(1);
+ errResponse[0] = IPMI_CC_INSUFFICIENT_PRIVILEGE;
+ std::cerr << "E> Table::Not enough privileges for command 0x"
+ << std::hex << command.command << "\n";
+ return errResponse;
+ }
+
+ return functor(commandData, handler);
+}
+
+} // namespace command