dsp: base: Implement decode_multipart_receive_req() in terms of msgbuf

Also rework related tests so we can avoid the casting the struct
over the buffers. This is motivated by an impending patch that drops
__attribute__((packed)) from the struct definition.

Change-Id: I21386e12ea65577920237fd28ea1fd340c749f42
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/tests/dsp/base.cpp b/tests/dsp/base.cpp
index 0c10ff7..d073ac4 100644
--- a/tests/dsp/base.cpp
+++ b/tests/dsp/base.cpp
@@ -540,7 +540,7 @@
     EXPECT_EQ(tid, 1);
 }
 
-TEST(MultipartReceive, testDecodeRequestPass)
+TEST(DecodeMultipartReceiveResponse, testDecodeRequestPass)
 {
     constexpr uint8_t kPldmType = PLDM_BASE;
     constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
@@ -548,36 +548,35 @@
     constexpr uint32_t kTransferHandle = 0x10;
     constexpr uint32_t kSectionOffset = 0x0;
     constexpr uint32_t kSectionLength = 0x10;
-    uint8_t pldm_type = 0x0;
-    uint8_t flag = PLDM_GET_FIRSTPART;
+
+    PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    PLDM_MSGBUF_DEFINE_P(buf);
+    int rc;
+
+    // Header values don't matter for this test.
+    rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
+                                msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint8(buf, kPldmType);
+    pldm_msgbuf_insert_uint8(buf, kFlag);
+    pldm_msgbuf_insert_uint32(buf, kTransferCtx);
+    pldm_msgbuf_insert_uint32(buf, kTransferHandle);
+    pldm_msgbuf_insert_uint32(buf, kSectionOffset);
+    pldm_msgbuf_insert_uint32(buf, kSectionLength);
+    rc = pldm_msgbuf_complete(buf);
+    ASSERT_EQ(rc, 0);
+
+    uint8_t pldm_type;
+    uint8_t flag;
     uint32_t transfer_ctx;
     uint32_t transfer_handle;
     uint32_t section_offset;
     uint32_t section_length;
-
-    // Header values don't matter for this test.
-    pldm_msg_hdr hdr{};
-    // Assign values to the packet struct and memcpy to ensure correct byte
-    // ordering.
-    pldm_multipart_receive_req req_pkt = {
-        .pldm_type = kPldmType,
-        .transfer_opflag = kFlag,
-        .transfer_ctx = kTransferCtx,
-        .transfer_handle = kTransferHandle,
-        .section_offset = kSectionOffset,
-        .section_length = kSectionLength,
-    };
-    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    std::memcpy(req.data(), &hdr, sizeof(hdr));
-    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
-    int rc = decode_multipart_receive_req(
-        pldm_request, req.size() - hdrSize, &pldm_type, &flag, &transfer_ctx,
+    rc = decode_multipart_receive_req(
+        msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag, &transfer_ctx,
         &transfer_handle, &section_offset, &section_length);
 
-    EXPECT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(rc, PLDM_SUCCESS);
     EXPECT_EQ(pldm_type, kPldmType);
     EXPECT_EQ(flag, kFlag);
     EXPECT_EQ(transfer_ctx, kTransferCtx);
@@ -586,17 +585,16 @@
     EXPECT_EQ(section_length, kSectionLength);
 }
 
-TEST(MultipartReceive, testDecodeRequestFailNullData)
+TEST(DecodeMultipartReceiveResponse, testDecodeRequestFailNullData)
 {
     EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL,
                                            NULL, NULL),
               PLDM_ERROR_INVALID_DATA);
 }
 
-TEST(MultipartReceive, testDecodeRequestFailBadLength)
+TEST(DecodeMultipartReceiveResponse, testDecodeRequestFailBadLength)
 {
-    constexpr uint8_t kPldmType = PLDM_BASE;
-    constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
+    PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1);
     uint8_t pldm_type;
     uint8_t flag;
     uint32_t transfer_ctx;
@@ -604,133 +602,32 @@
     uint32_t section_offset;
     uint32_t section_length;
 
-    // Header values don't matter for this test.
-    pldm_msg_hdr hdr{};
-    // Assign values to the packet struct and memcpy to ensure correct byte
-    // ordering.
-    pldm_multipart_receive_req req_pkt{};
-    req_pkt.pldm_type = kPldmType;
-    req_pkt.transfer_opflag = kFlag;
-
-    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    std::memcpy(req.data(), &hdr, sizeof(hdr));
-    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
+    memset(msg, 0, PLDM_MSG_SIZE(PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1));
     EXPECT_EQ(decode_multipart_receive_req(
-                  pldm_request, (req.size() - hdrSize) + 1, &pldm_type, &flag,
+                  msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1, &pldm_type, &flag,
                   &transfer_ctx, &transfer_handle, &section_offset,
                   &section_length),
-              PLDM_ERROR_INVALID_LENGTH);
-}
-
-TEST(MultipartReceive, testDecodeRequestFailBadPldmType)
-{
-    constexpr uint8_t kPldmType = 0xff;
-    constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
-    uint8_t pldm_type;
-    uint8_t flag;
-    uint32_t transfer_ctx;
-    uint32_t transfer_handle;
-    uint32_t section_offset;
-    uint32_t section_length;
-
-    // Header values don't matter for this test.
-    pldm_msg_hdr hdr{};
-    // Assign values to the packet struct and memcpy to ensure correct byte
-    // ordering.
-    pldm_multipart_receive_req req_pkt{};
-    req_pkt.pldm_type = kPldmType;
-    req_pkt.transfer_opflag = kFlag;
-
-    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    std::memcpy(req.data(), &hdr, sizeof(hdr));
-    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
-    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
-                                           &pldm_type, &flag, &transfer_ctx,
-                                           &transfer_handle, &section_offset,
-                                           &section_length),
-              PLDM_ERROR_INVALID_PLDM_TYPE);
-}
-
-TEST(MultipartReceive, testDecodeRequestFailBadTransferFlag)
-{
-    constexpr uint8_t kPldmType = PLDM_BASE;
-    constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10;
-    uint8_t pldm_type;
-    uint8_t flag;
-    uint32_t transfer_ctx;
-    uint32_t transfer_handle;
-    uint32_t section_offset;
-    uint32_t section_length;
-
-    // Header values don't matter for this test.
-    pldm_msg_hdr hdr{};
-    // Assign values to the packet struct and memcpy to ensure correct byte
-    // ordering.
-    pldm_multipart_receive_req req_pkt{};
-    req_pkt.pldm_type = kPldmType;
-    req_pkt.transfer_opflag = kFlag;
-
-    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    std::memcpy(req.data(), &hdr, sizeof(hdr));
-    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
-    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
-                                           &pldm_type, &flag, &transfer_ctx,
-                                           &transfer_handle, &section_offset,
-                                           &section_length),
-              PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION);
-}
-
-TEST(MultipartReceive, testDecodeRequestFailBadOffset)
-{
-    constexpr uint8_t kPldmType = PLDM_BASE;
-    constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
-    constexpr uint32_t kTransferHandle = 0x01;
-    constexpr uint32_t kSectionOffset = 0x0;
-    uint8_t pldm_type;
-    uint8_t flag;
-    uint32_t transfer_ctx;
-    uint32_t transfer_handle;
-    uint32_t section_offset;
-    uint32_t section_length;
-
-    // Header values don't matter for this test.
-    pldm_msg_hdr hdr{};
-    // Assign values to the packet struct and memcpy to ensure correct byte
-    // ordering.
-    pldm_multipart_receive_req req_pkt{};
-    req_pkt.pldm_type = kPldmType;
-    req_pkt.transfer_opflag = kFlag;
-    req_pkt.transfer_handle = kTransferHandle;
-    req_pkt.section_offset = kSectionOffset;
-
-    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    std::memcpy(req.data(), &hdr, sizeof(hdr));
-    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
-    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
-                                           &pldm_type, &flag, &transfer_ctx,
-                                           &transfer_handle, &section_offset,
-                                           &section_length),
               PLDM_ERROR_INVALID_DATA);
 }
 
-TEST(MultipartReceive, testDecodeRequestFailBadHandle)
+TEST(DecodeMultipartReceiveResponse, testDecodeRequestFailBadPldmType)
 {
-    constexpr uint8_t kPldmType = PLDM_BASE;
-    constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
-    constexpr uint32_t kSectionOffset = 0x100;
-    constexpr uint32_t kTransferHandle = 0x0;
+    constexpr uint8_t kPldmType = 0xff;
+    constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
+
+    PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    PLDM_MSGBUF_DEFINE_P(buf);
+    int rc;
+
+    // Header values don't matter for this test.
+    rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
+                                msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint8(buf, kPldmType);
+    pldm_msgbuf_insert_uint8(buf, kFlag);
+    rc = pldm_msgbuf_complete(buf);
+    ASSERT_EQ(rc, 0);
+
     uint8_t pldm_type;
     uint8_t flag;
     uint32_t transfer_ctx;
@@ -738,26 +635,116 @@
     uint32_t section_offset;
     uint32_t section_length;
 
+    EXPECT_EQ(decode_multipart_receive_req(
+                  msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
+                  &transfer_ctx, &transfer_handle, &section_offset,
+                  &section_length),
+              PLDM_ERROR_INVALID_PLDM_TYPE);
+}
+
+TEST(DecodeMultipartReceiveResponse, testDecodeRequestFailBadTransferFlag)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10;
+
+    PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    PLDM_MSGBUF_DEFINE_P(buf);
+    int rc;
+
     // Header values don't matter for this test.
-    pldm_msg_hdr hdr{};
-    // Assign values to the packet struct and memcpy to ensure correct byte
-    // ordering.
-    pldm_multipart_receive_req req_pkt{};
-    req_pkt.pldm_type = kPldmType;
-    req_pkt.transfer_opflag = kFlag;
-    req_pkt.transfer_handle = kTransferHandle;
-    req_pkt.section_offset = kSectionOffset;
+    rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
+                                msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint8(buf, kPldmType);
+    pldm_msgbuf_insert_uint8(buf, kFlag);
+    rc = pldm_msgbuf_complete(buf);
+    ASSERT_EQ(rc, 0);
 
-    std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    std::memcpy(req.data(), &hdr, sizeof(hdr));
-    std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
 
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
-    EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
-                                           &pldm_type, &flag, &transfer_ctx,
-                                           &transfer_handle, &section_offset,
-                                           &section_length),
+    EXPECT_EQ(decode_multipart_receive_req(
+                  msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
+                  &transfer_ctx, &transfer_handle, &section_offset,
+                  &section_length),
+              PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION);
+}
+
+TEST(DecodeMultipartReceiveResponse, testDecodeRequestFailBadOffset)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
+    constexpr uint32_t kTransferCtx = 0x01;
+    constexpr uint32_t kTransferHandle = 0x01;
+    constexpr uint32_t kSectionOffset = 0x0;
+
+    PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    PLDM_MSGBUF_DEFINE_P(buf);
+    int rc;
+
+    // Header values don't matter for this test.
+    rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
+                                msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint8(buf, kPldmType);
+    pldm_msgbuf_insert_uint8(buf, kFlag);
+    pldm_msgbuf_insert_uint32(buf, kTransferCtx);
+    pldm_msgbuf_insert_uint32(buf, kTransferHandle);
+    pldm_msgbuf_insert_uint32(buf, kSectionOffset);
+    rc = pldm_msgbuf_complete(buf);
+    ASSERT_EQ(rc, 0);
+
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+    EXPECT_EQ(decode_multipart_receive_req(
+                  msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
+                  &transfer_ctx, &transfer_handle, &section_offset,
+                  &section_length),
+              PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(DecodeMultipartReceiveResponse, testDecodeRequestFailBadHandle)
+{
+    constexpr uint8_t kPldmType = PLDM_BASE;
+    constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
+    constexpr uint32_t kTransferCtx = 0x01;
+    constexpr uint32_t kTransferHandle = 0x0;
+    constexpr uint32_t kSectionOffset = 0x100;
+
+    PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    PLDM_MSGBUF_DEFINE_P(buf);
+    int rc;
+
+    // Header values don't matter for this test.
+    rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
+                                msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
+    ASSERT_EQ(rc, 0);
+    pldm_msgbuf_insert_uint8(buf, kPldmType);
+    pldm_msgbuf_insert_uint8(buf, kFlag);
+    pldm_msgbuf_insert_uint32(buf, kTransferCtx);
+    pldm_msgbuf_insert_uint32(buf, kTransferHandle);
+    pldm_msgbuf_insert_uint32(buf, kSectionOffset);
+    rc = pldm_msgbuf_complete(buf);
+    ASSERT_EQ(rc, 0);
+
+    uint8_t pldm_type;
+    uint8_t flag;
+    uint32_t transfer_ctx;
+    uint32_t transfer_handle;
+    uint32_t section_offset;
+    uint32_t section_length;
+    EXPECT_EQ(decode_multipart_receive_req(
+                  msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
+                  &transfer_ctx, &transfer_handle, &section_offset,
+                  &section_length),
               PLDM_ERROR_INVALID_DATA);
 }
 
@@ -1636,4 +1623,4 @@
 
     EXPECT_EQ(rc, -EOVERFLOW);
 }
-#endif
\ No newline at end of file
+#endif