Display pldmtool Base & Bios command output in JSON.

./pldmtool base GetPLDMTypes
[
    {
        "PLDM Type": "base",
        "PLDM Type Code": 0
    },
    {
        "PLDM Type": "platform",
        "PLDM Type Code": 2
    },
    {
        "PLDM Type": "bios",
        "PLDM Type Code": 3
    },
    {
        "PLDM Type": "fru",
        "PLDM Type Code": 4
    },
    {
        "PLDM Type": "oem-ibm",
        "PLDM Type Code": 63
    }
]

./pldmtool base GetPLDMVersion -t 0
{
    "Response": "1.0.0"
}

./pldmtool base GetTID
{
    "Response": 1
}

./pldmtool base GetPLDMCommands -t 0
[
    {
        "PLDM Command Code": 2,
        "PLDM Command": "GetTID"
    },
    {
        "PLDM Command Code": 3,
        "PLDM Command": "GetPLDMVersion"
    },
    {
        "PLDM Command Code": 4,
        "PLDM Command": "GetPLDMTypes"
    },
    {
        "PLDM Command Code": 5,
        "PLDM Command": "GetPLDMCommands"
    }
]

./pldmtool bios GetDateTime
{
    "Response": "2020-10-15 16:33:55"
}

./pldmtool bios GetBIOSTable -t 0
{
    "0": "Allowed",
    "1": "Disabled",
    "2": "Enabled",
    "3": "IPv4DHCP",
    "4": "IPv4Static",
    "5": "Not Allowed",
    "6": "OPAL",
    "7": "Perm",
    "8": "PowerVM",
    "9": "Temp",
    "10": "hb-hyp-switch",
    "11": "pvm-fw-boot-side",
    "12": "pvm-inband-code-update",
    "13": "pvm-os-boot-side",
    "14": "pvm-pcie-error-inject",
    "15": "pvm-stop-at-standby",
    "16": "pvm-surveillance",
    "17": "pvm-system-name",
    "18": "vmi-hostname",
    "19": "vmi-if-count",
    "20": "vmi-if0-ipv4-ipaddr",
    "21": "vmi-if0-ipv4-method",
    "22": "vmi-if0-ipv4-prefix-length",
    "23": "vmi-if1-ipv4-ipaddr",
    "24": "vmi-if1-ipv4-method",
    "25": "vmi-if1-ipv4-prefix-length",
    "26": "vmi-ipv4-gateway"
}

./pldmtool bios GetBIOSTable -t 1
[
    {
        "AttributeHandle": 0,
        "AttributeNameHandle": "17(pvm-system-name)",
        "AttributeType": "BIOSString",
        "StringType": "0x01",
        "MinimumStringLength": 0,
        "MaximumStringLength": 100,
        "DefaultStringLength": 0,
        "DefaultString": ""
    },
...
...
   {
        "AttributeHandle": 16,
        "AttributeNameHandle": "15(pvm-stop-at-standby)",
        "AttributeType": "BIOSEnumeration",
        "NumberOfPossibleValues": 2,
        "PossibleValueStringHandle[0]": "1(Disabled)",
        "PossibleValueStringHandle[1]": "2(Enabled)",
        "NumberOfDefaultValues": 1,
        "DefaultValueStringHandleIndex[0]": 1,
        "StringHandle": "2(Enabled)"
    }
]

./pldmtool bios GetBIOSTable -t 2
[
    {
        "AttributeHandle": 0,
        "AttributeType": "BIOSString",
        "CurrentStringLength": 0,
        "CurrentString": ""
    },
...
...
   {
        "AttributeHandle": 16,
        "AttributeType": "BIOSEnumeration",
        "NumberOfCurrentValues": 1,
        "CurrentValueStringHandleIndex[0]": "Enabled"
    }
]

./pldmtool bios GetBIOSAttributeCurrentValueByHandle -a pvm-pcie-error-inject
{
    "CurrentValue": "Enabled"
}

./pldmtool bios SetBIOSAttributeCurrentValue -a vmi-if0-ipv4-method -d IPv4Static
{
    "Response": "SUCCESS"
}

Signed-off-by: Sridevi Ramesh <sridevra@in.ibm.com>
Change-Id: If58e2ce380efcad228e4440316cd2653eada9e73
diff --git a/pldmtool/pldm_base_cmd.cpp b/pldmtool/pldm_base_cmd.cpp
index bfcb38a..475932f 100644
--- a/pldmtool/pldm_base_cmd.cpp
+++ b/pldmtool/pldm_base_cmd.cpp
@@ -9,6 +9,8 @@
 #include "libpldm/host.h"
 #endif
 
+#include <string>
+
 namespace pldmtool
 {
 
@@ -112,25 +114,25 @@
   private:
     void printPldmTypes(std::vector<bitfield8_t>& types)
     {
-        std::cout << "Supported types:";
+        ordered_json data;
+        ordered_json jarray;
         for (int i = 0; i < PLDM_MAX_TYPES; i++)
         {
             bitfield8_t b = types[i / 8];
             if (b.byte & (1 << i % 8))
             {
-                std::cout << " " << i;
                 auto it = std::find_if(
                     pldmTypes.begin(), pldmTypes.end(),
                     [i](const auto& typePair) { return typePair.second == i; });
                 if (it != pldmTypes.end())
                 {
-
-                    std::cout << "(" << it->first << ")";
+                    jarray["PLDM Type"] = it->first;
+                    jarray["PLDM Type Code"] = i;
+                    data.emplace_back(jarray);
                 }
             }
         }
-
-        std::cout << std::endl;
+        pldmtool::helper::DisplayInJson(data);
     }
 };
 
@@ -178,16 +180,16 @@
         }
         char buffer[16] = {0};
         ver2str(&version, buffer, sizeof(buffer));
-        std::cout << "Type " << pldmType;
+        ordered_json data;
         auto it = std::find_if(
             pldmTypes.begin(), pldmTypes.end(),
             [&](const auto& typePair) { return typePair.second == pldmType; });
 
         if (it != pldmTypes.end())
         {
-            std::cout << "(" << it->first << ")";
+            data["Response"] = buffer;
         }
-        std::cout << ": " << buffer << std::endl;
+        pldmtool::helper::DisplayInJson(data);
     }
 
   private:
@@ -226,7 +228,9 @@
                       << "rc=" << rc << ",cc=" << (int)cc << "\n";
             return;
         }
-        std::cout << "TID : " << static_cast<uint32_t>(tid) << std::endl;
+        ordered_json data;
+        data["Response"] = static_cast<uint32_t>(tid);
+        pldmtool::helper::DisplayInJson(data);
     }
 };
 
@@ -279,53 +283,56 @@
     pldm_supported_types pldmType;
 
     template <typename CommandMap>
-    void printCommand(CommandMap& commandMap, int i)
+    void printCommand(CommandMap& commandMap, int i, ordered_json& jarray)
     {
         auto it = std::find_if(
             commandMap.begin(), commandMap.end(),
             [i](const auto& typePair) { return typePair.second == i; });
         if (it != commandMap.end())
         {
-            std::cout << "(" << it->first << ")";
+            jarray["PLDM Command Code"] = i;
+            jarray["PLDM Command"] = it->first;
         }
     }
 
     void printPldmCommands(std::vector<bitfield8_t>& cmdTypes,
                            pldm_supported_types pldmType)
     {
-        std::cout << "Supported Commands :";
+        ordered_json output;
         for (int i = 0; i < PLDM_MAX_CMDS_PER_TYPE; i++)
         {
+
+            ordered_json cmdinfo;
             bitfield8_t b = cmdTypes[i / 8];
             if (b.byte & (1 << i % 8))
             {
-                std::cout << " " << i;
                 switch (pldmType)
                 {
                     case PLDM_BASE:
-                        printCommand(pldmBaseCmds, i);
+                        printCommand(pldmBaseCmds, i, cmdinfo);
                         break;
                     case PLDM_PLATFORM:
-                        printCommand(pldmPlatformCmds, i);
+                        printCommand(pldmPlatformCmds, i, cmdinfo);
                         break;
                     case PLDM_BIOS:
-                        printCommand(pldmBiosCmds, i);
+                        printCommand(pldmBiosCmds, i, cmdinfo);
                         break;
                     case PLDM_FRU:
-                        printCommand(pldmFruCmds, i);
+                        printCommand(pldmFruCmds, i, cmdinfo);
                         break;
                     case PLDM_OEM:
 #ifdef OEM_IBM
-                        printCommand(pldmIBMHostCmds, i);
-                        printCommand(pldmIBMFileIOCmds, i);
+                        printCommand(pldmIBMHostCmds, i, cmdinfo);
+                        printCommand(pldmIBMFileIOCmds, i, cmdinfo);
 #endif
                         break;
                     default:
                         break;
                 }
+                output.emplace_back(cmdinfo);
             }
         }
-        std::cout << std::endl;
+        pldmtool::helper::DisplayInJson(output);
     }
 };
 
diff --git a/pldmtool/pldm_bios_cmd.cpp b/pldmtool/pldm_bios_cmd.cpp
index ba40dea..72bc715 100644
--- a/pldmtool/pldm_bios_cmd.cpp
+++ b/pldmtool/pldm_bios_cmd.cpp
@@ -68,27 +68,23 @@
                       << "rc=" << rc << ",cc=" << (int)cc << std::endl;
             return;
         }
-        std::cout << "Date & Time : " << std::endl;
-        std::cout << "YYYY-MM-DD HH:MM:SS - ";
-        std::cout << bcd2dec16(year);
-        std::cout << "-";
-        setWidth(month);
-        std::cout << "-";
-        setWidth(day);
-        std::cout << " ";
-        setWidth(hours);
-        std::cout << ":";
-        setWidth(minutes);
-        std::cout << ":";
-        setWidth(seconds);
-        std::cout << std::endl;
+
+        std::stringstream dt;
+        ordered_json data;
+        dt << bcd2dec16(year) << "-" << setWidth(month) << "-" << setWidth(day)
+           << " " << setWidth(hours) << ":" << setWidth(minutes) << ":"
+           << setWidth(seconds);
+        data["Response"] = dt.str();
+        pldmtool::helper::DisplayInJson(data);
     }
 
   private:
-    void setWidth(uint8_t data)
+    static std::string setWidth(uint8_t data)
     {
-        std::cout << std::setfill('0') << std::setw(2)
-                  << static_cast<uint32_t>(bcd2dec8(data));
+        std::stringstream s;
+        s << std::setfill('0') << std::setw(2)
+          << static_cast<uint32_t>(bcd2dec8(data));
+        return s.str();
     }
 };
 
@@ -153,7 +149,9 @@
             return;
         }
 
-        std::cout << "SetDateTime: SUCCESS" << std::endl;
+        ordered_json data;
+        data["Response"] = "SUCCESS";
+        pldmtool::helper::DisplayInJson(data);
     }
 
   private:
@@ -344,18 +342,19 @@
     void displayAttributeValueEntry(
         const pldm_bios_attr_val_table_entry* tableEntry,
         const std::optional<Table>& attrTable,
-        const std::optional<Table>& stringTable, bool verbose)
+        const std::optional<Table>& stringTable, bool verbose,
+        ordered_json& output)
     {
         auto attrHandle =
             pldm_bios_table_attr_value_entry_decode_attribute_handle(
                 tableEntry);
         auto attrType = static_cast<pldm_bios_attribute_type>(
             pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
+
         if (verbose)
         {
-            std::cout << "AttributeHandle: " << attrHandle << std::endl;
-            std::cout << "\tAttributeType: " << attrTypeMap.at(attrType)
-                      << std::endl;
+            output["AttributeHandle"] = attrHandle;
+            output["AttributeType"] = attrTypeMap.at(attrType);
         }
         switch (attrType)
         {
@@ -370,27 +369,21 @@
                     tableEntry, handles.data(), handles.size());
                 if (verbose)
                 {
-                    std::cout << "\tNumberOfCurrentValues: " << (int)count
-                              << std::endl;
+                    output["NumberOfCurrentValues"] = (int)count;
                 }
                 for (size_t i = 0; i < handles.size(); i++)
                 {
                     if (verbose)
                     {
-                        std::cout
-                            << "\tCurrentValueStringHandleIndex[" << i
-                            << "] = " << (int)handles[i] << ", StringHandle = "
-                            << displayEnumValueByIndex(attrHandle, handles[i],
-                                                       attrTable, stringTable)
-                            << std::endl;
+                        output["CurrentValueStringHandleIndex[" +
+                               std::to_string(i) + "]"] =
+                            displayEnumValueByIndex(attrHandle, handles[i],
+                                                    attrTable, stringTable);
                     }
                     else
                     {
-                        std::cout
-                            << "CurrentValue: "
-                            << displayEnumValueByIndex(attrHandle, handles[i],
-                                                       attrTable, stringTable)
-                            << std::endl;
+                        output["CurrentValue"] = displayEnumValueByIndex(
+                            attrHandle, handles[i], attrTable, stringTable);
                     }
                 }
                 break;
@@ -402,11 +395,11 @@
                     tableEntry);
                 if (verbose)
                 {
-                    std::cout << "\tCurrentValue: " << cv << std::endl;
+                    output["CurrentValue"] = cv;
                 }
                 else
                 {
-                    std::cout << "CurrentValue: " << cv << std::endl;
+                    output["CurrentValue"] = cv;
                 }
                 break;
             }
@@ -418,22 +411,16 @@
                     tableEntry, &currentString);
                 if (verbose)
                 {
-                    std::cout
-                        << "\tCurrentStringLength: " << currentString.length
-                        << std::endl
-                        << "\tCurrentString: "
-                        << std::string(
-                               reinterpret_cast<const char*>(currentString.ptr),
-                               currentString.length)
-                        << std::endl;
+                    output["CurrentStringLength"] = currentString.length;
+                    output["CurrentString"] = std::string(
+                        reinterpret_cast<const char*>(currentString.ptr),
+                        currentString.length);
                 }
                 else
                 {
-                    std::cout << "CurrentValue: "
-                              << std::string(reinterpret_cast<const char*>(
-                                                 currentString.ptr),
-                                             currentString.length)
-                              << std::endl;
+                    output["CurrentValue"] = std::string(
+                        reinterpret_cast<const char*>(currentString.ptr),
+                        currentString.length);
                 }
 
                 break;
@@ -509,8 +496,7 @@
             std::cerr << "GetBIOSStringTable Error" << std::endl;
             return;
         }
-        std::cout << "PLDM StringTable: " << std::endl;
-        std::cout << "BIOSStringHandle : BIOSString" << std::endl;
+        ordered_json stringdata;
 
         for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
                  stringTable->data(), stringTable->size()))
@@ -518,8 +504,9 @@
             auto strHandle =
                 pldm_bios_table_string_entry_decode_handle(tableEntry);
             auto strTableData = decodeStringFromStringEntry(tableEntry);
-            std::cout << strHandle << " : " << strTableData << std::endl;
+            stringdata[std::to_string(strHandle)] = strTableData;
         }
+        pldmtool::helper::DisplayInJson(stringdata);
     }
     void decodeAttributeTable(const std::optional<Table>& attrTable,
                               const std::optional<Table>& stringTable)
@@ -529,22 +516,25 @@
             std::cerr << "GetBIOSAttributeTable Error" << std::endl;
             return;
         }
-        std::cout << "PLDM AttributeTable: " << std::endl;
+        ordered_json output;
+
         for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
                  attrTable->data(), attrTable->size()))
         {
+            ordered_json attrdata;
+
             auto attrHandle =
                 pldm_bios_table_attr_entry_decode_attribute_handle(entry);
             auto attrNameHandle =
                 pldm_bios_table_attr_entry_decode_string_handle(entry);
             auto attrType = static_cast<pldm_bios_attribute_type>(
                 pldm_bios_table_attr_entry_decode_attribute_type(entry));
-            std::cout << "AttributeHandle: " << attrHandle
-                      << ", AttributeNameHandle: "
-                      << displayStringHandle(attrNameHandle, stringTable)
-                      << std::endl;
-            std::cout << "\tAttributeType: " << attrTypeMap.at(attrType)
-                      << std::endl;
+
+            attrdata["AttributeHandle"] = attrHandle;
+            attrdata["AttributeNameHandle"] =
+                displayStringHandle(attrNameHandle, stringTable);
+            attrdata["AttributeType"] = attrTypeMap.at(attrType);
+
             switch (attrType)
             {
                 case PLDM_BIOS_ENUMERATION:
@@ -560,27 +550,22 @@
                     std::vector<uint8_t> defIndices(defNum);
                     pldm_bios_table_attr_entry_enum_decode_def_indices(
                         entry, defIndices.data(), defIndices.size());
-                    std::cout << "\tNumberOfPossibleValues: " << (int)pvNum
-                              << std::endl;
+
+                    attrdata["NumberOfPossibleValues"] = (int)pvNum;
 
                     for (size_t i = 0; i < pvHandls.size(); i++)
                     {
-                        std::cout
-                            << "\t\tPossibleValueStringHandle"
-                            << "[" << i << "] = "
-                            << displayStringHandle(pvHandls[i], stringTable)
-                            << std::endl;
+                        attrdata["PossibleValueStringHandle[" +
+                                 std::to_string(i) + "]"] =
+                            displayStringHandle(pvHandls[i], stringTable);
                     }
-                    std::cout << "\tNumberOfDefaultValues: " << (int)defNum
-                              << std::endl;
+                    attrdata["NumberOfDefaultValues"] = (int)defNum;
                     for (size_t i = 0; i < defIndices.size(); i++)
                     {
-                        std::cout << "\t\tDefaultValueStringHandleIndex"
-                                  << "[" << i << "] = " << (int)defIndices[i]
-                                  << ", StringHandle = "
-                                  << displayStringHandle(
-                                         pvHandls[defIndices[i]], stringTable)
-                                  << std::endl;
+                        attrdata["DefaultValueStringHandleIndex[" +
+                                 std::to_string(i) + "]"] = (int)defIndices[i];
+                        attrdata["StringHandle"] = displayStringHandle(
+                            pvHandls[defIndices[i]], stringTable);
                     }
                     break;
                 }
@@ -591,10 +576,10 @@
                     uint32_t scalar;
                     pldm_bios_table_attr_entry_integer_decode(
                         entry, &lower, &upper, &scalar, &def);
-                    std::cout << "\tLowerBound: " << lower << std::endl
-                              << "\tUpperBound: " << upper << std::endl
-                              << "\tScalarIncrement: " << scalar << std::endl
-                              << "\tDefaultValue: " << def << std::endl;
+                    attrdata["LowerBound"] = lower;
+                    attrdata["UpperBound"] = upper;
+                    attrdata["ScalarIncrement"] = scalar;
+                    attrdata["DefaultValue"] = def;
                     break;
                 }
                 case PLDM_BIOS_STRING:
@@ -615,14 +600,16 @@
                     std::vector<char> defString(def + 1);
                     pldm_bios_table_attr_entry_string_decode_def_string(
                         entry, defString.data(), defString.size());
-                    std::cout
-                        << "\tStringType: 0x" << std::hex << std::setw(2)
-                        << std::setfill('0') << (int)strType << std::dec
-                        << std::setw(0) << std::endl
-                        << "\tMinimumStringLength: " << (int)min << std::endl
-                        << "\tMaximumStringLength: " << (int)max << std::endl
-                        << "\tDefaultStringLength: " << (int)def << std::endl
-                        << "\tDefaultString: " << defString.data() << std::endl;
+
+                    std::stringstream stringtype;
+                    stringtype << "0x" << std::hex << std::setw(2)
+                               << std::setfill('0') << (int)strType << std::dec
+                               << std::setw(0);
+                    attrdata["StringType"] = stringtype.str();
+                    attrdata["MinimumStringLength"] = (int)min;
+                    attrdata["MaximumStringLength"] = (int)max;
+                    attrdata["DefaultStringLength"] = (int)def;
+                    attrdata["DefaultString"] = defString.data();
                     break;
                 }
                 case PLDM_BIOS_PASSWORD:
@@ -630,7 +617,9 @@
                     std::cout << "Password attribute: Not Supported"
                               << std::endl;
             }
+            output.emplace_back(std::move(attrdata));
         }
+        pldmtool::helper::DisplayInJson(output);
     }
     void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
                                    const std::optional<Table>& attrTable,
@@ -641,13 +630,16 @@
             std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
             return;
         }
-        std::cout << "PLDM AttributeValueTable: " << std::endl;
+        ordered_json output;
         for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
                  attrValTable->data(), attrValTable->size()))
         {
-            displayAttributeValueEntry(tableEntry, attrTable, stringTable,
-                                       true);
+            ordered_json attrValueData;
+            displayAttributeValueEntry(tableEntry, attrTable, stringTable, true,
+                                       attrValueData);
+            output.emplace_back(attrValueData);
         }
+        pldmtool::helper::DisplayInJson(output);
     }
 };
 
@@ -669,7 +661,7 @@
                                                   CLI::App* app) :
         GetBIOSTableHandler(type, name, app)
     {
-        app->add_option("-a, --attribute", attrName, "pldm bios attribute name")
+        app->add_option("-a, --attribute", attrName, "pldm BIOS attribute name")
             ->required();
     }
 
@@ -734,7 +726,10 @@
             reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
                 attributeData.ptr);
 
-        displayAttributeValueEntry(tableEntry, attrTable, stringTable, false);
+        ordered_json avdata;
+        displayAttributeValueEntry(tableEntry, attrTable, stringTable, false,
+                                   avdata);
+        pldmtool::helper::DisplayInJson(avdata);
     }
 
   private:
@@ -797,7 +792,7 @@
             case PLDM_BIOS_STRING_READ_ONLY:
             case PLDM_BIOS_INTEGER_READ_ONLY:
             {
-                std::cerr << "Set  attribute error: " << attrName
+                std::cerr << "Set attribute error: " << attrName
                           << "is read only." << std::endl;
                 return;
             }
@@ -906,7 +901,9 @@
             return;
         }
 
-        std::cout << "SetBIOSAttributeCurrentValue: SUCCESS" << std::endl;
+        ordered_json data;
+        data["Response"] = "SUCCESS";
+        pldmtool::helper::DisplayInJson(data);
     }
 
   private:
diff --git a/pldmtool/pldm_cmd_helper.hpp b/pldmtool/pldm_cmd_helper.hpp
index 3ce01f3..d71d0d3 100644
--- a/pldmtool/pldm_cmd_helper.hpp
+++ b/pldmtool/pldm_cmd_helper.hpp
@@ -13,6 +13,7 @@
 #include <unistd.h>
 
 #include <CLI/CLI.hpp>
+#include <nlohmann/json.hpp>
 
 #include <cstring>
 #include <iomanip>
@@ -28,6 +29,7 @@
 using namespace pldm::utils;
 constexpr uint8_t PLDM_ENTITY_ID = 8;
 constexpr uint8_t MCTP_MSG_TYPE_PLDM = 1;
+using ordered_json = nlohmann::ordered_json;
 
 /** @brief Print the buffer
  *
@@ -57,6 +59,18 @@
         std::cout << msg << s.str() << std::endl;
     }
 }
+
+/** @brief Display in JSON format.
+ *
+ *  @param[in]  data - data to print in json
+ *
+ *  @return - None
+ */
+static inline void DisplayInJson(const ordered_json& data)
+{
+    std::cout << data.dump(4) << std::endl;
+}
+
 /** @brief MCTP socket read/recieve
  *
  *  @param[in]  requestMsg - Request message to compare against loopback