pldmtool: Implement GetFRURecordTable.

Example output:

./pldmtool fru GetFruRecordTable
FRU Record Set Identifier: 1
FRU Record Type: 254(OEM)
Number of FRU fields: 1
Encoding Type for FRU fields: 1(ASCII)
FRU Record Set Identifier: 1
FRU Record Type: 1(General)
Number of FRU fields: 2
Encoding Type for FRU fields: 1(ASCII)
        FRU Field Type: Model
        FRU Field Length: 5
        FRU Field Value: 1234A
        FRU Field Type: Serial Number
        FRU Field Length: 6
        FRU Field Value: SNR123
FRU Record Set Identifier: 1
FRU Record Type: 254(OEM)
Number of FRU fields: 15
Encoding Type for FRU fields: 1(ASCII)
...

Change-Id: I470beb708ac0ad50da9bc74f1f26295c5529fac1
Signed-off-by: Sridevi Ramesh <sridevra@in.ibm.com>
diff --git a/pldmtool/pldm_fru_cmd.cpp b/pldmtool/pldm_fru_cmd.cpp
index 8442af1..4ac0633 100644
--- a/pldmtool/pldm_fru_cmd.cpp
+++ b/pldmtool/pldm_fru_cmd.cpp
@@ -312,6 +312,54 @@
     uint8_t fieldType;
 };
 
+class GetFruRecordTable : public CommandInterface
+{
+  public:
+    ~GetFruRecordTable() = default;
+    GetFruRecordTable() = delete;
+    GetFruRecordTable(const GetFruRecordTable&) = delete;
+    GetFruRecordTable(GetFruRecordTable&&) = default;
+    GetFruRecordTable& operator=(const GetFruRecordTable&) = delete;
+    GetFruRecordTable& operator=(GetFruRecordTable&&) = default;
+
+    using CommandInterface::CommandInterface;
+    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
+    {
+        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+                                        PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
+        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+        auto rc = encode_get_fru_record_table_req(
+            instanceId, 0, PLDM_START_AND_END, request,
+            requestMsg.size() - sizeof(pldm_msg_hdr));
+        return {rc, requestMsg};
+    }
+    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
+    {
+        uint8_t cc = 0;
+        uint32_t next_data_transfer_handle = 0;
+        uint8_t transfer_flag = 0;
+        size_t fru_record_table_length = 0;
+        std::vector<uint8_t> fru_record_table_data(payloadLength);
+
+        auto rc = decode_get_fru_record_table_resp(
+            responsePtr, payloadLength, &cc, &next_data_transfer_handle,
+            &transfer_flag, fru_record_table_data.data(),
+            &fru_record_table_length);
+
+        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
+        {
+            std::cerr << "Response Message Error: "
+                      << "rc=" << rc << ",cc=" << (int)cc << std::endl;
+            return;
+        }
+
+        FRUTablePrint tablePrint(fru_record_table_data.data(),
+                                 fru_record_table_length);
+        tablePrint.print();
+    }
+};
+
 void registerCommand(CLI::App& app)
 {
     auto fru = app.add_subcommand("fru", "FRU type command");
@@ -325,6 +373,11 @@
         fru->add_subcommand("GetFRURecordByOption", "get FRU Record By Option");
     commands.push_back(std::make_unique<GetFRURecordByOption>(
         "fru", "GetFRURecordByOption", getFRURecordByOption));
+
+    auto getFruRecordTable =
+        fru->add_subcommand("GetFruRecordTable", "get FRU Record Table");
+    commands.push_back(std::make_unique<GetFruRecordTable>(
+        "fru", "GetFruRecordTable", getFruRecordTable));
 }
 
 } // namespace fru