Implement GetPLDMVersion command

This commit implements the GetPLDMVersion which is required
as part of the base PLDM support to know the version of a
given PLDM type.

Change-Id: I1bcbd938c5b6833f62e0ee2f474b04d76b6970d9
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/test/libpldm_base_test.cpp b/test/libpldm_base_test.cpp
index 04d14c0..9a37ec6 100644
--- a/test/libpldm_base_test.cpp
+++ b/test/libpldm_base_test.cpp
@@ -300,3 +300,116 @@
     ASSERT_EQ(response.payload[2], outTypes[1]);
     ASSERT_EQ(response.payload[3], outTypes[2]);
 }
+
+TEST(GetPLDMVersion, testEncodeRequest)
+{
+    std::array<uint8_t, PLDM_GET_VERSION_REQ_BYTES> requestMsg{};
+    pldm_msg request{};
+    request.body.payload = requestMsg.data();
+    request.body.payload_length = requestMsg.size();
+    uint8_t pldmType = 0x03;
+    uint32_t transferHandle = 0x0;
+    uint8_t opFlag = 0x01;
+
+    auto rc =
+        encode_get_version_req(0, transferHandle, opFlag, pldmType, &request);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(0, memcmp(request.body.payload, &transferHandle,
+                        sizeof(transferHandle)));
+    ASSERT_EQ(0, memcmp(request.body.payload + sizeof(transferHandle), &opFlag,
+                        sizeof(opFlag)));
+    ASSERT_EQ(0, memcmp(request.body.payload + sizeof(transferHandle) +
+                            sizeof(opFlag),
+                        &pldmType, sizeof(pldmType)));
+}
+
+TEST(GetPLDMVersion, testEncodeResponse)
+{
+    pldm_msg response{};
+    uint8_t completionCode = 0;
+    uint32_t transferHandle = 0;
+    uint8_t flag = PLDM_START_AND_END;
+    std::array<uint8_t, PLDM_GET_VERSION_RESP_BYTES> responseMsg{};
+    response.body.payload = responseMsg.data();
+    response.body.payload_length = responseMsg.size();
+    struct pldm_version version = {0xFF, 0xFF, 0xFF, 0xFF};
+
+    auto rc =
+        encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END,
+                                &version, sizeof(pldm_version), &response);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(completionCode, response.body.payload[0]);
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]),
+                     &transferHandle, sizeof(transferHandle)));
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]) +
+                         sizeof(transferHandle),
+                     &flag, sizeof(flag)));
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]) +
+                         sizeof(transferHandle) + sizeof(flag),
+                     &version, sizeof(version)));
+}
+
+TEST(GetPLDMVersion, testDecodeRequest)
+{
+    std::array<uint8_t, PLDM_GET_VERSION_REQ_BYTES> requestMsg{};
+    pldm_msg_payload request{};
+    request.payload = requestMsg.data();
+    request.payload_length = requestMsg.size();
+    uint32_t transferHandle = 0x0;
+    uint32_t retTransferHandle = 0x0;
+    uint8_t flag = PLDM_GET_FIRSTPART;
+    uint8_t retFlag = PLDM_GET_FIRSTPART;
+    uint8_t pldmType = PLDM_BASE;
+    uint8_t retType = PLDM_BASE;
+
+    memcpy(request.payload, &transferHandle, sizeof(transferHandle));
+    memcpy(request.payload + sizeof(transferHandle), &flag, sizeof(flag));
+    memcpy(request.payload + sizeof(transferHandle) + sizeof(flag), &pldmType,
+           sizeof(pldmType));
+
+    auto rc = decode_get_version_req(&request, &retTransferHandle, &retFlag,
+                                     &retType);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(transferHandle, retTransferHandle);
+    ASSERT_EQ(flag, retFlag);
+    ASSERT_EQ(pldmType, retType);
+}
+
+TEST(GetPLDMVersion, testDecodeResponse)
+{
+    std::array<uint8_t, PLDM_GET_VERSION_RESP_BYTES> responseMsg{};
+    pldm_msg_payload response{};
+    response.payload = responseMsg.data();
+    response.payload_length = responseMsg.size();
+    uint32_t transferHandle = 0x0;
+    uint32_t retTransferHandle = 0x0;
+    uint8_t flag = PLDM_START_AND_END;
+    uint8_t retFlag = PLDM_START_AND_END;
+    uint8_t completionCode = 0;
+    struct pldm_version version = {0xFF, 0xFF, 0xFF, 0xFF};
+    struct pldm_version versionOut;
+
+    memcpy(response.payload + sizeof(completionCode), &transferHandle,
+           sizeof(transferHandle));
+    memcpy(response.payload + sizeof(completionCode) + sizeof(transferHandle),
+           &flag, sizeof(flag));
+    memcpy(response.payload + sizeof(completionCode) + sizeof(transferHandle) +
+               sizeof(flag),
+           &version, sizeof(version));
+
+    auto rc = decode_get_version_resp(&response, &retTransferHandle, &retFlag,
+                                      &versionOut);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(transferHandle, retTransferHandle);
+    ASSERT_EQ(flag, retFlag);
+
+    ASSERT_EQ(versionOut.major, version.major);
+    ASSERT_EQ(versionOut.minor, version.minor);
+    ASSERT_EQ(versionOut.update, version.update);
+    ASSERT_EQ(versionOut.alpha, version.alpha);
+}
diff --git a/test/libpldmresponder_base_test.cpp b/test/libpldmresponder_base_test.cpp
index 2bd6ebd..a34d80f 100644
--- a/test/libpldmresponder_base_test.cpp
+++ b/test/libpldmresponder_base_test.cpp
@@ -57,3 +57,41 @@
     getPLDMCommands(&request, &response);
     ASSERT_EQ(response.body.payload[0], PLDM_ERROR_INVALID_PLDM_TYPE);
 }
+
+TEST(GetPLDMVersion, testGoodRequest)
+{
+    pldm_msg response{};
+    std::array<uint8_t, PLDM_GET_VERSION_RESP_BYTES> responseMsg{};
+    response.body.payload = responseMsg.data();
+    response.body.payload_length = responseMsg.size();
+    pldm_msg request{};
+    std::array<uint8_t, PLDM_GET_VERSION_REQ_BYTES> requestPayload{};
+    request.body.payload = requestPayload.data();
+    request.body.payload_length = requestPayload.size();
+
+    uint8_t pldmType = PLDM_BASE;
+    uint32_t transferHandle = 0x0;
+    uint8_t flag = PLDM_GET_FIRSTPART;
+    uint8_t retFlag = PLDM_START_AND_END;
+    struct pldm_version version = {0xF1, 0xF0, 0xF0, 0x00};
+
+    auto rc =
+        encode_get_version_req(0, transferHandle, flag, pldmType, &request);
+
+    ASSERT_EQ(0, rc);
+
+    getPLDMVersion(&(request.body), &response);
+
+    ASSERT_EQ(response.body.payload[0], 0);
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]),
+                     &transferHandle, sizeof(transferHandle)));
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]) +
+                         sizeof(transferHandle),
+                     &retFlag, sizeof(flag)));
+    ASSERT_EQ(0,
+              memcmp(response.body.payload + sizeof(response.body.payload[0]) +
+                         sizeof(transferHandle) + sizeof(flag),
+                     &version, sizeof(version)));
+}