pldmtool : obtain PLDM Instance Id

This commit makes a dbus call and obtains the
instanceId and modifies the request message and
corresponding response message is obtained.
The loopback response message logic is removed as it
is the request message itself being received and
there is no need to specifically process this.
The code is simplified to just wait on a
matching response message.

Tested:
./pldmtool base GetPLDMTypes
& ./pldmtool base GetPLDMTypes
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: 14
Encode request successfully
Request Message:
08 01 81 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: 14
Shutdown Socket successful :  RC = 0
Response Message:
08 01 01 00 04 00 1d 00 00 00 00 00 00 00
Shutdown Socket successful :  RC = 0
Response Message:
08 01 00 00 04 00 1d 00 00 00 00 00 00 00
Supported types: 0(base) 2(platform) 3(bios) 4(fru)
Supported types: 0(base) 2(platform) 3(bios) 4(fru)

Change-Id: I688b58bdade817645321942b4a798e14e75b6021
Signed-off-by: Pavithra Barithaya <pbaritha@in.ibm.com>
diff --git a/tool/meson.build b/tool/meson.build
index 978d057..555856f 100644
--- a/tool/meson.build
+++ b/tool/meson.build
@@ -11,6 +11,6 @@
   'pldmtool',
   sources,
   implicit_include_directories: false,
-  dependencies: [libpldm, libpldmutils],
+  dependencies: [libpldm, libpldmutils, dependency('sdbusplus')],
   install: true,
   install_dir: get_option('bindir'))
diff --git a/tool/pldm_base_cmd.cpp b/tool/pldm_base_cmd.cpp
index d55195d..b1028d0 100644
--- a/tool/pldm_base_cmd.cpp
+++ b/tool/pldm_base_cmd.cpp
@@ -62,7 +62,7 @@
     {
         std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
-        auto rc = encode_get_types_req(PLDM_LOCAL_INSTANCE_ID, request);
+        auto rc = encode_get_types_req(instanceId, request);
         return {rc, requestMsg};
     }
 
@@ -130,8 +130,8 @@
                                         PLDM_GET_VERSION_REQ_BYTES);
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
 
-        auto rc = encode_get_version_req(PLDM_LOCAL_INSTANCE_ID, 0,
-                                         PLDM_GET_FIRSTPART, pldmType, request);
+        auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
+                                         pldmType, request);
         return {rc, requestMsg};
     }
 
@@ -183,7 +183,7 @@
     {
         std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
-        auto rc = encode_get_tid_req(PLDM_LOCAL_INSTANCE_ID, request);
+        auto rc = encode_get_tid_req(instanceId, request);
         return {rc, requestMsg};
     }
 
@@ -229,8 +229,8 @@
                                         PLDM_GET_COMMANDS_REQ_BYTES);
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
         ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
-        auto rc = encode_get_commands_req(PLDM_LOCAL_INSTANCE_ID, pldmType,
-                                          version, request);
+        auto rc =
+            encode_get_commands_req(instanceId, pldmType, version, request);
         return {rc, requestMsg};
     }
 
diff --git a/tool/pldm_bios_cmd.cpp b/tool/pldm_bios_cmd.cpp
index 13a8a4a..f2830a2 100644
--- a/tool/pldm_bios_cmd.cpp
+++ b/tool/pldm_bios_cmd.cpp
@@ -49,7 +49,7 @@
         std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
 
-        auto rc = encode_get_date_time_req(PLDM_LOCAL_INSTANCE_ID, request);
+        auto rc = encode_get_date_time_req(instanceId, request);
         return {rc, requestMsg};
     }
 
@@ -133,8 +133,8 @@
         }
 
         auto rc = encode_set_date_time_req(
-            PLDM_LOCAL_INSTANCE_ID, seconds, minutes, hours, day, month, year,
-            request, sizeof(struct pldm_set_date_time_req));
+            instanceId, seconds, minutes, hours, day, month, year, request,
+            sizeof(struct pldm_set_date_time_req));
 
         return {rc, requestMsg};
     }
@@ -195,8 +195,8 @@
                                         PLDM_GET_BIOS_TABLE_REQ_BYTES);
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
 
-        auto rc = encode_get_bios_table_req(
-            PLDM_LOCAL_INSTANCE_ID, 0, PLDM_GET_FIRSTPART, tableType, request);
+        auto rc = encode_get_bios_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
+                                            tableType, request);
         if (rc != PLDM_SUCCESS)
         {
             std::cerr << "Encode GetBIOSTable Error, tableType=," << tableType
diff --git a/tool/pldm_cmd_helper.cpp b/tool/pldm_cmd_helper.cpp
index bd1912c..17485cd 100644
--- a/tool/pldm_cmd_helper.cpp
+++ b/tool/pldm_cmd_helper.cpp
@@ -1,5 +1,13 @@
 #include "pldm_cmd_helper.hpp"
 
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <systemd/sd-bus.h>
+
+#include <exception>
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
+
 #include "libpldm/requester/pldm.h"
 
 namespace pldmtool
@@ -101,57 +109,31 @@
     }
     else
     {
-        // loopback response message
-        std::vector<uint8_t> loopBackRespMsg(peekedLength);
-        auto recvDataLength =
-            recv(socketFd(), reinterpret_cast<void*>(loopBackRespMsg.data()),
-                 peekedLength, 0);
-        if (recvDataLength == peekedLength)
+        auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&requestMsg[2]);
+        do
         {
-            std::cout << "Total length:" << recvDataLength << std::endl;
-            std::cout << "Loopback response message:" << std::endl;
-            printBuffer(loopBackRespMsg);
-        }
-        else
-        {
-            std::cerr << "Failure to read peeked length packet : RC = "
-                      << returnCode << "\n";
-            std::cerr << "peekedLength: " << peekedLength << "\n";
-            std::cerr << "Total length: " << recvDataLength << "\n";
-            return returnCode;
-        }
-
-        // Confirming on the first recv() the Request bit is set in
-        // pldm_msg_hdr struct. If set proceed with recv() or else, quit.
-        auto hdr = reinterpret_cast<const pldm_msg_hdr*>(&loopBackRespMsg[2]);
-        uint8_t request = hdr->request;
-        if (request == PLDM_REQUEST)
-        {
-            std::cout << "On first recv(),response == request : RC = "
-                      << returnCode << std::endl;
             ssize_t peekedLength =
                 recv(socketFd(), nullptr, 0, MSG_PEEK | MSG_TRUNC);
             responseMsg.resize(peekedLength);
-            recvDataLength =
+            auto recvDataLength =
                 recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()),
                      peekedLength, 0);
-            if (recvDataLength == peekedLength)
+            auto resphdr =
+                reinterpret_cast<const pldm_msg_hdr*>(&responseMsg[2]);
+            if (recvDataLength == peekedLength &&
+                resphdr->instance_id == reqhdr->instance_id &&
+                resphdr->request != PLDM_REQUEST)
             {
                 std::cout << "Total length: " << recvDataLength << std::endl;
+                break;
             }
-            else
+            else if (recvDataLength != peekedLength)
             {
                 std::cerr << "Failure to read response length packet: length = "
                           << recvDataLength << "\n";
                 return returnCode;
             }
-        }
-        else
-        {
-            std::cerr << "On first recv(),request != response : RC = "
-                      << returnCode << "\n";
-            return returnCode;
-        }
+        } while (1);
     }
 
     returnCode = shutdown(socketFd(), SHUT_RDWR);
@@ -170,6 +152,25 @@
 
 void CommandInterface::exec()
 {
+    static constexpr auto pldmObjPath = "/xyz/openbmc_project/pldm";
+    static constexpr auto pldmRequester = "xyz.openbmc_project.PLDM.Requester";
+    auto& bus = pldm::utils::DBusHandler::getBus();
+    try
+    {
+        auto service =
+            pldm::utils::DBusHandler().getService(pldmObjPath, pldmRequester);
+        auto method = bus.new_method_call(service.c_str(), pldmObjPath,
+                                          pldmRequester, "GetInstanceId");
+        method.append(mctp_eid);
+        auto reply = bus.call(method);
+        reply.read(instanceId);
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << "GetInstanceId D-Bus call failed, MCTP id = " << mctp_eid
+                  << ", error = " << e.what() << "\n";
+        return;
+    }
     auto [rc, requestMsg] = createRequestMsg();
     if (rc != PLDM_SUCCESS)
     {
diff --git a/tool/pldm_cmd_helper.hpp b/tool/pldm_cmd_helper.hpp
index 4ad46d4..bea01bd 100644
--- a/tool/pldm_cmd_helper.hpp
+++ b/tool/pldm_cmd_helper.hpp
@@ -27,7 +27,6 @@
 using namespace pldm::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
  *
@@ -56,7 +55,7 @@
     explicit CommandInterface(const char* type, const char* name,
                               CLI::App* app) :
         pldmType(type),
-        commandName(name), mctp_eid(PLDM_ENTITY_ID)
+        commandName(name), mctp_eid(PLDM_ENTITY_ID), instanceId(0)
     {
         app->add_option("-m,--mctp_eid", mctp_eid, "MCTP endpoint ID");
         app->callback([&]() { exec(); });
@@ -77,6 +76,9 @@
     const std::string pldmType;
     const std::string commandName;
     uint8_t mctp_eid;
+
+  protected:
+    uint8_t instanceId;
 };
 
 } // namespace helper
diff --git a/tool/pldm_fru_cmd.cpp b/tool/pldm_fru_cmd.cpp
index e1cf800..2638d60 100644
--- a/tool/pldm_fru_cmd.cpp
+++ b/tool/pldm_fru_cmd.cpp
@@ -35,8 +35,7 @@
         std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
 
-        auto rc = encode_get_fru_record_table_metadata_req(
-            PLDM_LOCAL_INSTANCE_ID, request);
+        auto rc = encode_get_fru_record_table_metadata_req(instanceId, request);
         return {rc, requestMsg};
     }
 
diff --git a/tool/pldm_platform_cmd.cpp b/tool/pldm_platform_cmd.cpp
index 6b1081f..6d917fa 100644
--- a/tool/pldm_platform_cmd.cpp
+++ b/tool/pldm_platform_cmd.cpp
@@ -47,7 +47,7 @@
                                         PLDM_GET_PDR_REQ_BYTES);
         auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
 
-        auto rc = encode_get_pdr_req(PLDM_LOCAL_INSTANCE_ID, recordHandle, 0,
+        auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
                                      PLDM_GET_FIRSTPART, requestCount, 0,
                                      request, PLDM_GET_PDR_REQ_BYTES);
         return {rc, requestMsg};
@@ -220,8 +220,7 @@
         }
 
         auto rc = encode_set_state_effecter_states_req(
-            PLDM_LOCAL_INSTANCE_ID, effecterId, effecterCount,
-            stateField->data(), request);
+            instanceId, effecterId, effecterCount, stateField->data(), request);
         return {rc, requestMsg};
     }