pldmtool : add new option to pldmtool

This commit adds an option '-m' to send msg to
specific MCTP EID(the tool assumes the default
value to send the message).

Tested:
* MCTP EID is not provided or default value is
provided -
 ./pldmtool base GetPLDMTypes
or ./pldmtool base GetPLDMTypes -m 8
Encode request successfully
Request Message:
08 01 80 00 04
Success in creating the socket : RC = 4
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)

Change-Id: I1b5d7ed251af5380ef0f2b290ff15a9d25b8ba95
Signed-off-by: Pavithra Barithaya <pbaritha@in.ibm.com>
diff --git a/tool/pldm_cmd_helper.cpp b/tool/pldm_cmd_helper.cpp
index 1c03121..bd1912c 100644
--- a/tool/pldm_cmd_helper.cpp
+++ b/tool/pldm_cmd_helper.cpp
@@ -1,11 +1,12 @@
 #include "pldm_cmd_helper.hpp"
 
+#include "libpldm/requester/pldm.h"
+
 namespace pldmtool
 {
 
 namespace helper
 {
-
 /*
  * print the input buffer
  *
@@ -23,7 +24,6 @@
     }
     std::cout << tempStream.str() << std::endl;
 }
-
 /*
  * Initialize the socket, send pldm command & recieve response from socket
  *
@@ -131,7 +131,6 @@
                       << returnCode << std::endl;
             ssize_t peekedLength =
                 recv(socketFd(), nullptr, 0, MSG_PEEK | MSG_TRUNC);
-
             responseMsg.resize(peekedLength);
             recvDataLength =
                 recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()),
@@ -154,6 +153,7 @@
             return returnCode;
         }
     }
+
     returnCode = shutdown(socketFd(), SHUT_RDWR);
     if (-1 == returnCode)
     {
@@ -196,29 +196,45 @@
 int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
                                    std::vector<uint8_t>& responseMsg)
 {
-
-    // Insert the PLDM message type and EID at the begining of the request msg.
+    // Insert the PLDM message type and EID at the beginning of the
+    // msg.
     requestMsg.insert(requestMsg.begin(), MCTP_MSG_TYPE_PLDM);
-    requestMsg.insert(requestMsg.begin(), PLDM_ENTITY_ID);
+    requestMsg.insert(requestMsg.begin(), mctp_eid);
 
     std::cout << "Request Message:" << std::endl;
     printBuffer(requestMsg);
 
-    auto rc = mctpSockSendRecv(requestMsg, responseMsg);
-
-    if (rc != PLDM_SUCCESS)
+    if (mctp_eid != PLDM_ENTITY_ID)
     {
-        std::cerr << "Failed to receive from mctpSocket: RC = " << rc << "\n";
-        return rc;
+        int fd = pldm_open();
+        if (-1 == fd)
+        {
+            std::cerr << "failed to init mctp "
+                      << "\n";
+            return -1;
+        }
+        uint8_t* responseMessage = nullptr;
+        size_t responseMessageSize{};
+        pldm_send_recv(mctp_eid, fd, requestMsg.data() + 2,
+                       requestMsg.size() - 2, &responseMessage,
+                       &responseMessageSize);
+        std::cout << "Response Message:" << std::endl;
+
+        responseMsg.resize(responseMessageSize);
+        memcpy(responseMsg.data(), responseMessage, responseMsg.size());
+
+        free(responseMessage);
+        printBuffer(responseMsg);
     }
-
-    std::cout << "Response Message:" << std::endl;
-    printBuffer(responseMsg);
-
-    responseMsg.erase(responseMsg.begin(),
-                      responseMsg.begin() + 2 /* skip the mctp header */);
+    else
+    {
+        mctpSockSendRecv(requestMsg, responseMsg);
+        std::cout << "Response Message:" << std::endl;
+        printBuffer(responseMsg);
+        responseMsg.erase(responseMsg.begin(),
+                          responseMsg.begin() + 2 /* skip the mctp header */);
+    }
     return PLDM_SUCCESS;
 }
-
 } // namespace helper
 } // namespace pldmtool
diff --git a/tool/pldm_cmd_helper.hpp b/tool/pldm_cmd_helper.hpp
index 8060751..4ad46d4 100644
--- a/tool/pldm_cmd_helper.hpp
+++ b/tool/pldm_cmd_helper.hpp
@@ -51,12 +51,14 @@
 
 class CommandInterface
 {
+
   public:
     explicit CommandInterface(const char* type, const char* name,
                               CLI::App* app) :
         pldmType(type),
-        commandName(name)
+        commandName(name), mctp_eid(PLDM_ENTITY_ID)
     {
+        app->add_option("-m,--mctp_eid", mctp_eid, "MCTP endpoint ID");
         app->callback([&]() { exec(); });
     }
     virtual ~CommandInterface() = default;
@@ -74,6 +76,7 @@
   private:
     const std::string pldmType;
     const std::string commandName;
+    uint8_t mctp_eid;
 };
 
 } // namespace helper