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/src/dsp/base.c b/src/dsp/base.c
index ee2cd04..7609f25 100644
--- a/src/dsp/base.c
+++ b/src/dsp/base.c
@@ -533,49 +533,52 @@
uint32_t *section_offset,
uint32_t *section_length)
{
+ PLDM_MSGBUF_DEFINE_P(buf);
+ int rc;
+
if (msg == NULL || pldm_type == NULL || transfer_opflag == NULL ||
transfer_ctx == NULL || transfer_handle == NULL ||
section_offset == NULL || section_length == NULL) {
return PLDM_ERROR_INVALID_DATA;
}
- if (payload_length != PLDM_MULTIPART_RECEIVE_REQ_BYTES) {
- return PLDM_ERROR_INVALID_LENGTH;
+ rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
+ msg->payload, payload_length);
+ if (rc) {
+ return pldm_xlate_errno(rc);
}
- struct pldm_multipart_receive_req *request =
- (struct pldm_multipart_receive_req *)msg->payload;
+ pldm_msgbuf_extract_p(buf, pldm_type);
+ pldm_msgbuf_extract_p(buf, transfer_opflag);
+ pldm_msgbuf_extract_p(buf, transfer_ctx);
+ pldm_msgbuf_extract_p(buf, transfer_handle);
+ pldm_msgbuf_extract_p(buf, section_offset);
+ pldm_msgbuf_extract_p(buf, section_length);
- if (request->pldm_type != PLDM_BASE &&
- request->pldm_type != PLDM_FILE) {
+ rc = pldm_msgbuf_complete_consumed(buf);
+ if (rc) {
+ return pldm_xlate_errno(rc);
+ }
+
+ if (*pldm_type != PLDM_BASE && *pldm_type != PLDM_FILE) {
return PLDM_ERROR_INVALID_PLDM_TYPE;
}
// Any enum value above PLDM_XFER_CURRENT_PART is invalid.
- if (request->transfer_opflag > PLDM_XFER_CURRENT_PART) {
+ if (*transfer_opflag > PLDM_XFER_CURRENT_PART) {
return PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION;
}
// A section offset of 0 is only valid on FIRST_PART or COMPLETE Xfers.
- uint32_t sec_offset = le32toh(request->section_offset);
- if (sec_offset == 0 &&
- (request->transfer_opflag != PLDM_XFER_FIRST_PART &&
- request->transfer_opflag != PLDM_XFER_COMPLETE)) {
+ if (*section_offset == 0 && (*transfer_opflag != PLDM_XFER_FIRST_PART &&
+ *transfer_opflag != PLDM_XFER_COMPLETE)) {
return PLDM_ERROR_INVALID_DATA;
}
- uint32_t handle = le32toh(request->transfer_handle);
- if (handle == 0 && request->transfer_opflag != PLDM_XFER_COMPLETE) {
+ if (*transfer_handle == 0 && *transfer_opflag != PLDM_XFER_COMPLETE) {
return PLDM_ERROR_INVALID_DATA;
}
- *pldm_type = request->pldm_type;
- *transfer_opflag = request->transfer_opflag;
- *transfer_ctx = request->transfer_ctx;
- *transfer_handle = handle;
- *section_offset = sec_offset;
- *section_length = le32toh(request->section_length);
-
return PLDM_SUCCESS;
}
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, §ion_offset, §ion_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, §ion_offset,
§ion_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, §ion_offset,
- §ion_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, §ion_offset,
- §ion_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, §ion_offset,
- §ion_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, §ion_offset,
+ §ion_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, §ion_offset,
- §ion_length),
+ EXPECT_EQ(decode_multipart_receive_req(
+ msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
+ &transfer_ctx, &transfer_handle, §ion_offset,
+ §ion_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, §ion_offset,
+ §ion_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, §ion_offset,
+ §ion_length),
PLDM_ERROR_INVALID_DATA);
}
@@ -1636,4 +1623,4 @@
EXPECT_EQ(rc, -EOVERFLOW);
}
-#endif
\ No newline at end of file
+#endif