pldmtool: Add commands

Implement sending out and processing the response of the following commands : GetPDR, SetStateEffecterStates, SetDateTime

Tested:
 $ pldmtool platform GetPDR -d 0
 Encode request successfully
 Request Message:
 08 01 80 02 51 00 00 00 00 00 00 00 00 01 80 00 00 00
 On first recv(),response == request : RC = 0
 Total length: 46
 Response Message:
 08 01 00 02 51 00 02 00 00 00 00 00 00 00 01 1d 00 01 00 00 00 01 0b 00 00 13 00 00 00 01 00 21 00 00 00 00 00 00 00 00 00 01 c4 00 01 06
 Parsed Response Msg:
 recordHandle: 1
 PDRHeaderVersion: 1
 PDRType: 11
 recordChangeNumber: 0
 dataLength: 19
 PLDMTerminusHandle: 0
 effecterID: 1
 entityType: 33
 entityInstanceNumber: 0
 containerID: 0
 effecterSemanticID: 0
 effecterInit: 0
 effecterDescriptionPDR: false
 compositeEffecterCount: 1
 stateSetID: 196
 possibleStatesSize: 1
 possibleStates: 6

 $ pldmtool platform SetStateEffecterStates -d 1 1 1
 Encode request successfully
 Request Message:
 08 01 80 02 39 01 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 On first recv(),response == request : RC = 0
 Total length: 6
 Response Message:
 08 01 00 02 39 00
 SetStateEffecterStates: SUCCESS

 $ pldmtool bios SetDateTime -d 20191010080000
 Encode request successfully
 Request Message:
 08 01 80 03 0d 00 00 08 10 10 19 20
 On first recv(),response == request : RC = 0
 Total length: 6
 Response Message:
 08 01 00 03 0d 00
 SetDateTime: SUCCESS

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: Ie13c7b05937ee3f150802d33c6e3434360c0b606
diff --git a/tool/pldm_bios_cmd.cpp b/tool/pldm_bios_cmd.cpp
index 547955e..fdcc721 100644
--- a/tool/pldm_bios_cmd.cpp
+++ b/tool/pldm_bios_cmd.cpp
@@ -83,6 +83,74 @@
     }
 };
 
+class SetDateTime : public CommandInterface
+{
+  public:
+    ~SetDateTime() = default;
+    SetDateTime() = delete;
+    SetDateTime(const SetDateTime&) = delete;
+    SetDateTime(SetDateTime&&) = default;
+    SetDateTime& operator=(const SetDateTime&) = delete;
+    SetDateTime& operator=(SetDateTime&&) = default;
+
+    explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
+        CommandInterface(type, name, app)
+    {
+        app->add_option("-d,--data", tmData,
+                        "set date time data\n"
+                        "eg: YYYYMMDDHHMMSS")
+            ->required();
+    }
+
+    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
+    {
+        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+                                        sizeof(struct pldm_set_date_time_req));
+        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+        uint16_t year = 0;
+        uint8_t month = 0;
+        uint8_t day = 0;
+        uint8_t hours = 0;
+        uint8_t minutes = 0;
+        uint8_t seconds = 0;
+
+        if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
+                        &seconds))
+        {
+            std::cerr << "decode date Error: "
+                      << "tmData=" << tmData << std::endl;
+
+            return {PLDM_ERROR_INVALID_DATA, requestMsg};
+        }
+
+        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));
+
+        return {rc, requestMsg};
+    }
+
+    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
+    {
+        uint8_t completionCode = 0;
+        auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
+                                            &completionCode);
+
+        if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
+        {
+            std::cerr << "Response Message Error: "
+                      << "rc=" << rc << ",cc=" << (int)completionCode
+                      << std::endl;
+            return;
+        }
+
+        std::cout << "SetDateTime: SUCCESS" << std::endl;
+    }
+
+  private:
+    uint64_t tmData;
+};
+
 void registerCommand(CLI::App& app)
 {
     auto bios = app.add_subcommand("bios", "bios type command");
@@ -90,6 +158,11 @@
     auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
     commands.push_back(
         std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
+
+    auto setDateTime =
+        bios->add_subcommand("SetDateTime", "set host date time");
+    commands.push_back(
+        std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
 }
 
 } // namespace bios