tool: Refactor base type Commands

Each command will be implemented as a CLI subcommand
command handers registration process:

    CLI::App app;
    auto base = app.add_subcommand("base");
    auto GetPLDMVersion = base->add_subcommand("GetPLDMVersion");
    /* register callback for GetPLDMVersion Command */
    GetPLDMVersion->callback(exec());
    CLI11_PARSER();

Each command will be implemented as a class. To avoid duplicate,
An interface class is abstracted as the base class for commands.

CommandInterface
{
	CommandInterface(CLI::App* app){
		app->callback([&](){exec();}) //register exec() to CLI11
	}
	virtual createRequestMsg();
	virtual parseResponseMsg();
	exec(){
		createRequestMsg();
		send_recv();
		parseResponseMsg();
	}
};

GetPLDMVersion : public CommandInterface
{
	GetPLDMVersion(CLI::App *app){
		app->add_option();  // add options for this command
	}
	...
}

Then, the main is like below:

int main()
{
	CLI::App app{"PLDM requester tool for OpenBMC"};
	auto base = app.add_subcommand("base");
	auto version = base->add_subcommand("GetPLDMVersion");
	GetPLDMVersion getPLDMVersion(version);
	CLI11_PARSE(app, argc, argv);
}

Tested:

root@fp5280g2:~# pldmtool base GetPLDMTypes
Encode request successfully
Request Message:
08 01 80 00 04
Success in creating the socket : RC = 3
Success in connecting to socket : RC = 0
Success in sending message type as pldm to mctp : RC = 0
Write to socket successful : RC = 5
Total length:5
Loopback response message:
08 01 80 00 04
On first recv(),response == request : RC = 0
Total length: 14
Shutdown Socket successful :  RC = 0
Response Message:
08 01 00 00 04 00 0d 00 00 00 00 00 00 00
Supported types: 0(base) 2(platform) 3(bios)

root@fp5280g2:~# pldmtool base GetPLDMVersion -t platform
Encode request successfully
Request Message:
08 01 80 00 03 00 00 00 00 01 02
Success in creating the socket : RC = 3
Success in connecting to socket : RC = 0
Success in sending message type as pldm to mctp : RC = 0
Write to socket successful : RC = 11
Total length:11
Loopback response message:
08 01 80 00 03 00 00 00 00 01 02
On first recv(),response == request : RC = 0
Total length: 15
Shutdown Socket successful :  RC = 0
Response Message:
08 01 00 00 03 00 00 00 00 00 05 f1 f1 f1 00
Type 2(platform): 1.1.1

root@fp5280g2:~# pldmtool raw -d 0x80 0x00 0x04
Encode request successfully
Request Message:
08 01 80 00 04
Success in creating the socket : RC = 3
Success in connecting to socket : RC = 0
Success in sending message type as pldm to mctp : RC = 0
Write to socket successful : RC = 5
Total length:5
Loopback response message:
08 01 80 00 04
On first recv(),response == request : RC = 0
Total length: 14
Shutdown Socket successful :  RC = 0
Response Message:
08 01 00 00 04 00 0d 00 00 00 00 00 00 00

Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I658b2c8094e9e5d972d786b26f9f8d52bc011981
diff --git a/tool/pldm_cmd_helper.hpp b/tool/pldm_cmd_helper.hpp
index 8032c9a..a162de4 100644
--- a/tool/pldm_cmd_helper.hpp
+++ b/tool/pldm_cmd_helper.hpp
@@ -1,8 +1,5 @@
 #pragma once
 
-#ifndef PLDM_CMD_HELPER_H
-#define PLDM_CMD_HELPER_H
-
 #include "libpldmresponder/utils.hpp"
 
 #include <err.h>
@@ -10,14 +7,25 @@
 #include <sys/un.h>
 #include <unistd.h>
 
+#include <CLI/CLI.hpp>
 #include <cstring>
 #include <iomanip>
 #include <iostream>
+#include <utility>
 
 #include "libpldm/base.h"
 #include "libpldm/platform.h"
 
+namespace pldmtool
+{
+
+namespace helper
+{
+
 using namespace pldm::responder::utils;
+constexpr uint8_t PLDM_ENTITY_ID = 8;
+constexpr uint8_t MCTP_MSG_TYPE_PLDM = 1;
+constexpr uint8_t PLDM_LOCAL_INSTANCE_ID = 0;
 
 /** @brief Print the buffer
  *
@@ -39,4 +47,29 @@
 int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg,
                      std::vector<uint8_t>& responseMsg);
 
-#endif
+class CommandInterface
+{
+  public:
+    explicit CommandInterface(const char* type, const char* name,
+                              CLI::App* app) :
+        pldmType(type),
+        commandName(name)
+    {
+        app->callback([&]() { exec(); });
+    }
+    virtual ~CommandInterface() = default;
+
+    virtual std::pair<int, std::vector<uint8_t>> createRequestMsg() = 0;
+
+    virtual void parseResponseMsg(struct pldm_msg* responsePtr,
+                                  size_t payloadLength) = 0;
+
+    void exec();
+
+  private:
+    const std::string pldmType;
+    const std::string commandName;
+};
+
+} // namespace helper
+} // namespace pldmtool