PLDM Message Structure Change

With this change, PLDM code is optimised. The PLDM payload message
structure previously consisted of a pointer to the payload message and
the payload length, this structure is removed with this commit and the
PLDM message structure now has the PLDM header structure and an array of
size 1 whose address is the starting byte of message payload. Therefore,
pldm msg struct can represent a request/response message in contiguous
memory, thereby enabling simple casts and avoiding memcpys to get from a
uint8_t* to pldm msg or vice versa.

This commit also introduces a change to have the response handlers allocate
memory for responses. This is aligned with the message struct change, and
enables varying length responses.

Change-Id: Ia46d852b8b16bfc7cf04f38435bd4079ad33c66b
Signed-off-by: vkaverap <vkaverap@in.ibm.com>
diff --git a/test/libpldmresponder_base_test.cpp b/test/libpldmresponder_base_test.cpp
index cdd22e6..8990d22 100644
--- a/test/libpldmresponder_base_test.cpp
+++ b/test/libpldmresponder_base_test.cpp
@@ -12,62 +12,54 @@
 
 TEST(GetPLDMTypes, testGoodRequest)
 {
-    pldm_msg_payload request{};
-    pldm_msg response{};
-    std::array<uint8_t, PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
-    response.body.payload = responseMsg.data();
-    response.body.payload_length = responseMsg.size();
-    getPLDMTypes(&request, &response);
+    std::array<uint8_t, sizeof(pldm_msg_hdr)> requestPayload{};
+    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    // payload length will be 0 in this case
+    size_t requestPayloadLength = 0;
+    auto response = getPLDMTypes(request, requestPayloadLength);
     // Only base type supported at the moment
-    ASSERT_EQ(response.body.payload[0], 0);
-    ASSERT_EQ(response.body.payload[1], 1);
-    ASSERT_EQ(response.body.payload[2], 0);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    uint8_t* payload_ptr = responsePtr->payload;
+    ASSERT_EQ(payload_ptr[0], 0);
+    ASSERT_EQ(payload_ptr[1], 1);
+    ASSERT_EQ(payload_ptr[2], 0);
 }
 
 TEST(GetPLDMCommands, testGoodRequest)
 {
     // Only base type supported at the moment, and commands -
     // GetPLDMTypes, GetPLDMCommands
-    pldm_msg response{};
-    std::array<uint8_t, PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
-    response.body.payload = responseMsg.data();
-    response.body.payload_length = responseMsg.size();
-    pldm_msg_payload request{};
-    std::array<uint8_t, 5> requestPayload{};
-    request.payload = requestPayload.data();
-    request.payload_length = requestPayload.size();
-    getPLDMCommands(&request, &response);
-    ASSERT_EQ(response.body.payload[0], 0);
-    ASSERT_EQ(response.body.payload[1], 48); // 48 = 0b110000
-    ASSERT_EQ(response.body.payload[2], 0);
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
+        requestPayload{};
+    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+    auto response = getPLDMCommands(request, requestPayloadLength);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    uint8_t* payload_ptr = responsePtr->payload;
+    ASSERT_EQ(payload_ptr[0], 0);
+    ASSERT_EQ(payload_ptr[1], 48); // 48 = 0b110000
+    ASSERT_EQ(payload_ptr[2], 0);
 }
 
 TEST(GetPLDMCommands, testBadRequest)
 {
-    pldm_msg response{};
-    std::array<uint8_t, PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
-    response.body.payload = responseMsg.data();
-    response.body.payload_length = responseMsg.size();
-    pldm_msg_payload request{};
-    std::array<uint8_t, 5> requestPayload{};
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
+        requestPayload{};
+    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
 
-    request.payload = requestPayload.data();
-    request.payload[0] = 0xFF;
-    request.payload_length = requestPayload.size();
-    getPLDMCommands(&request, &response);
-    ASSERT_EQ(response.body.payload[0], PLDM_ERROR_INVALID_PLDM_TYPE);
+    request->payload[0] = 0xFF;
+    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+    auto response = getPLDMCommands(request, requestPayloadLength);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    uint8_t* payload_ptr = responsePtr->payload;
+    ASSERT_EQ(payload_ptr[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();
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
+        requestPayload{};
+    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
     uint8_t pldmType = PLDM_BASE;
     uint32_t transferHandle = 0x0;
@@ -76,61 +68,53 @@
     ver32_t version = {0xF1, 0xF0, 0xF0, 0x00};
 
     auto rc =
-        encode_get_version_req(0, transferHandle, flag, pldmType, &request);
+        encode_get_version_req(0, transferHandle, flag, pldmType, request);
 
     ASSERT_EQ(0, rc);
 
-    getPLDMVersion(&(request.body), &response);
+    auto response = getPLDMVersion(request, requestPayloadLength);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
-    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)));
+    ASSERT_EQ(responsePtr->payload[0], 0);
+    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
+                        &transferHandle, sizeof(transferHandle)));
+    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]) +
+                            sizeof(transferHandle),
+                        &retFlag, sizeof(flag)));
+    ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]) +
+                            sizeof(transferHandle) + sizeof(flag),
+                        &version, sizeof(version)));
 }
-
 TEST(GetPLDMVersion, testBadRequest)
 {
-    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{};
-
-    std::array<uint8_t, (PLDM_GET_VERSION_REQ_BYTES - 3)> requestPayloadSmall{};
-    request.body.payload = requestPayloadSmall.data();
-    request.body.payload_length = requestPayloadSmall.size();
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
+        requestPayload{};
+    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
     uint8_t pldmType = 7;
     uint32_t transferHandle = 0x0;
     uint8_t flag = PLDM_GET_FIRSTPART;
 
     auto rc =
-        encode_get_version_req(0, transferHandle, flag, pldmType, &request);
+        encode_get_version_req(0, transferHandle, flag, pldmType, request);
 
     ASSERT_EQ(0, rc);
 
-    getPLDMVersion(&(request.body), &response);
+    auto response = getPLDMVersion(request, requestPayloadLength - 1);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
-    ASSERT_EQ(response.body.payload[0], PLDM_ERROR_INVALID_LENGTH);
+    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
 
-    request.body.payload = requestPayload.data();
-    request.body.payload_length = requestPayload.size();
+    request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
-    rc = encode_get_version_req(0, transferHandle, flag, pldmType, &request);
+    rc = encode_get_version_req(0, transferHandle, flag, pldmType, request);
 
     ASSERT_EQ(0, rc);
 
-    getPLDMVersion(&(request.body), &response);
+    response = getPLDMVersion(request, requestPayloadLength);
+    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
-    ASSERT_EQ(response.body.payload[0], PLDM_ERROR_INVALID_PLDM_TYPE);
+    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_PLDM_TYPE);
 }