#include "msgbuf.hpp" #include #include #include #include #include #include #include #include using testing::ElementsAreArray; constexpr auto hdrSize = sizeof(pldm_msg_hdr); TEST(PackPLDMMessage, BadPathTest) { struct pldm_header_info hdr; struct pldm_header_info* hdr_ptr = NULL; pldm_msg_hdr msg{}; // PLDM header information pointer is NULL auto rc = pack_pldm_header(hdr_ptr, &msg); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); // PLDM message pointer is NULL rc = pack_pldm_header(&hdr, nullptr); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); // PLDM header information pointer and PLDM message pointer is NULL rc = pack_pldm_header(hdr_ptr, nullptr); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); // RESERVED message type hdr.msg_type = PLDM_RESERVED; rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); // Instance ID out of range hdr.msg_type = PLDM_REQUEST; hdr.instance = 32; rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); // PLDM type out of range hdr.msg_type = PLDM_REQUEST; hdr.instance = 31; hdr.pldm_type = 64; rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_ERROR_INVALID_PLDM_TYPE); } TEST(PackPLDMMessage, RequestMessageGoodPath) { struct pldm_header_info hdr; pldm_msg_hdr msg{}; // Message type is REQUEST and lower range of the field values hdr.msg_type = PLDM_REQUEST; hdr.instance = 0; hdr.pldm_type = 0; hdr.command = 0; auto rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(msg.request, 1); EXPECT_EQ(msg.datagram, 0); EXPECT_EQ(msg.instance_id, 0); EXPECT_EQ(msg.type, 0); EXPECT_EQ(msg.command, 0); // Message type is REQUEST and upper range of the field values hdr.instance = 31; hdr.pldm_type = 63; hdr.command = 255; rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(msg.request, 1); EXPECT_EQ(msg.datagram, 0); EXPECT_EQ(msg.instance_id, 31); EXPECT_EQ(msg.type, 63); EXPECT_EQ(msg.command, 255); // Message type is PLDM_ASYNC_REQUEST_NOTIFY hdr.msg_type = PLDM_ASYNC_REQUEST_NOTIFY; rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(msg.request, 1); EXPECT_EQ(msg.datagram, 1); EXPECT_EQ(msg.instance_id, 31); EXPECT_EQ(msg.type, 63); EXPECT_EQ(msg.command, 255); } TEST(PackPLDMMessage, ResponseMessageGoodPath) { struct pldm_header_info hdr; pldm_msg_hdr msg{}; // Message type is PLDM_RESPONSE and lower range of the field values hdr.msg_type = PLDM_RESPONSE; hdr.instance = 0; hdr.pldm_type = 0; hdr.command = 0; auto rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(msg.request, 0); EXPECT_EQ(msg.datagram, 0); EXPECT_EQ(msg.instance_id, 0); EXPECT_EQ(msg.type, 0); EXPECT_EQ(msg.command, 0); // Message type is PLDM_RESPONSE and upper range of the field values hdr.instance = 31; hdr.pldm_type = 63; hdr.command = 255; rc = pack_pldm_header(&hdr, &msg); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(msg.request, 0); EXPECT_EQ(msg.datagram, 0); EXPECT_EQ(msg.instance_id, 31); EXPECT_EQ(msg.type, 63); EXPECT_EQ(msg.command, 255); } TEST(UnpackPLDMMessage, BadPathTest) { struct pldm_header_info hdr; // PLDM message pointer is NULL auto rc = unpack_pldm_header(nullptr, &hdr); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); } TEST(UnpackPLDMMessage, RequestMessageGoodPath) { struct pldm_header_info hdr; pldm_msg_hdr msg{}; // Unpack PLDM request message and lower range of field values msg.request = 1; auto rc = unpack_pldm_header(&msg, &hdr); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(hdr.msg_type, PLDM_REQUEST); EXPECT_EQ(hdr.instance, 0); EXPECT_EQ(hdr.pldm_type, 0); EXPECT_EQ(hdr.command, 0); // Unpack PLDM async request message and lower range of field values msg.datagram = 1; rc = unpack_pldm_header(&msg, &hdr); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(hdr.msg_type, PLDM_ASYNC_REQUEST_NOTIFY); // Unpack PLDM request message and upper range of field values msg.datagram = 0; msg.instance_id = 31; msg.type = 63; msg.command = 255; rc = unpack_pldm_header(&msg, &hdr); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(hdr.msg_type, PLDM_REQUEST); EXPECT_EQ(hdr.instance, 31); EXPECT_EQ(hdr.pldm_type, 63); EXPECT_EQ(hdr.command, 255); } TEST(UnpackPLDMMessage, ResponseMessageGoodPath) { struct pldm_header_info hdr; pldm_msg_hdr msg{}; // Unpack PLDM response message and lower range of field values auto rc = unpack_pldm_header(&msg, &hdr); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE); EXPECT_EQ(hdr.instance, 0); EXPECT_EQ(hdr.pldm_type, 0); EXPECT_EQ(hdr.command, 0); // Unpack PLDM response message and upper range of field values msg.instance_id = 31; msg.type = 63; msg.command = 255; rc = unpack_pldm_header(&msg, &hdr); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE); EXPECT_EQ(hdr.instance, 31); EXPECT_EQ(hdr.pldm_type, 63); EXPECT_EQ(hdr.command, 255); } TEST(GetPLDMCommands, testEncodeRequest) { uint8_t pldmType = 0x05; ver32_t version{0xff, 0xff, 0xff, 0xff}; std::array requestMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto request = reinterpret_cast(requestMsg.data()); auto rc = encode_get_commands_req(0, pldmType, version, request); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(0, memcmp(request->payload, &pldmType, sizeof(pldmType))); EXPECT_EQ(0, memcmp(request->payload + sizeof(pldmType), &version, sizeof(version))); } TEST(GetPLDMCommands, testDecodeRequest) { uint8_t pldmType = 0x05; ver32_t version{0xff, 0xff, 0xff, 0xff}; uint8_t pldmTypeOut{}; ver32_t versionOut{0xff, 0xff, 0xff, 0xff}; std::array requestMsg{}; memcpy(requestMsg.data() + hdrSize, &pldmType, sizeof(pldmType)); memcpy(requestMsg.data() + sizeof(pldmType) + hdrSize, &version, sizeof(version)); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto request = reinterpret_cast(requestMsg.data()); auto rc = decode_get_commands_req(request, requestMsg.size() - hdrSize, &pldmTypeOut, &versionOut); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(pldmTypeOut, pldmType); EXPECT_EQ(0, memcmp(&versionOut, &version, sizeof(version))); } TEST(GetPLDMCommands, testEncodeResponse) { uint8_t completionCode = 0; std::array responseMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); std::array commands{}; commands[0].byte = 1; commands[1].byte = 2; commands[2].byte = 3; auto rc = encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), response); EXPECT_EQ(rc, PLDM_SUCCESS); uint8_t* payload_ptr = response->payload; EXPECT_EQ(completionCode, payload_ptr[0]); EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]); EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte)]); EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte) + sizeof(commands[1].byte)]); } TEST(GetPLDMTypes, testEncodeResponse) { uint8_t completionCode = 0; std::array responseMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); std::array types{}; types[0].byte = 1; types[1].byte = 2; types[2].byte = 3; auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response); EXPECT_EQ(rc, PLDM_SUCCESS); uint8_t* payload_ptr = response->payload; EXPECT_EQ(completionCode, payload_ptr[0]); EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]); EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte)]); EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte) + sizeof(types[1].byte)]); } TEST(GetPLDMTypes, testGoodDecodeResponse) { std::array responseMsg{}; responseMsg[1 + hdrSize] = 1; responseMsg[2 + hdrSize] = 2; responseMsg[3 + hdrSize] = 3; std::array outTypes{}; uint8_t completion_code; responseMsg[hdrSize] = PLDM_SUCCESS; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize, &completion_code, outTypes.data()); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(completion_code, PLDM_SUCCESS); EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte); EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte); EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte); } TEST(GetPLDMTypes, testBadDecodeResponse) { std::array responseMsg{}; responseMsg[1 + hdrSize] = 1; responseMsg[2 + hdrSize] = 2; responseMsg[3 + hdrSize] = 3; std::array outTypes{}; uint8_t retcompletion_code = 0; responseMsg[hdrSize] = PLDM_SUCCESS; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize - 1, &retcompletion_code, outTypes.data()); EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); } TEST(GetPLDMCommands, testGoodDecodeResponse) { std::array responseMsg{}; responseMsg[1 + hdrSize] = 1; responseMsg[2 + hdrSize] = 2; responseMsg[3 + hdrSize] = 3; std::array outTypes{}; uint8_t completion_code; responseMsg[hdrSize] = PLDM_SUCCESS; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize, &completion_code, outTypes.data()); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(completion_code, PLDM_SUCCESS); EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte); EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte); EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte); } TEST(GetPLDMCommands, testBadDecodeResponse) { std::array responseMsg{}; responseMsg[1 + hdrSize] = 1; responseMsg[2 + hdrSize] = 2; responseMsg[3 + hdrSize] = 3; std::array outTypes{}; uint8_t retcompletion_code = 0; responseMsg[hdrSize] = PLDM_SUCCESS; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize - 1, &retcompletion_code, outTypes.data()); EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); } TEST(GetPLDMVersion, testGoodEncodeRequest) { std::array requestMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto request = reinterpret_cast(requestMsg.data()); uint8_t pldmType = 0x03; uint32_t transferHandle = 0x0; uint8_t opFlag = 0x01; auto rc = encode_get_version_req(0, transferHandle, opFlag, pldmType, request); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ( 0, memcmp(request->payload, &transferHandle, sizeof(transferHandle))); EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle), &opFlag, sizeof(opFlag))); EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle) + sizeof(opFlag), &pldmType, sizeof(pldmType))); } TEST(GetPLDMVersion, testBadEncodeRequest) { uint8_t pldmType = 0x03; uint32_t transferHandle = 0x0; uint8_t opFlag = 0x01; auto rc = encode_get_version_req(0, transferHandle, opFlag, pldmType, nullptr); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); } TEST(GetPLDMVersion, testEncodeResponse) { uint8_t completionCode = 0; uint32_t transferHandle = 0; uint8_t flag = PLDM_START_AND_END; std::array responseMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); ver32_t version = {0xff, 0xff, 0xff, 0xff}; auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END, &version, sizeof(ver32_t), response); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(completionCode, response->payload[0]); EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]), &transferHandle, sizeof(transferHandle))); EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) + sizeof(transferHandle), &flag, sizeof(flag))); EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) + sizeof(transferHandle) + sizeof(flag), &version, sizeof(version))); } TEST(GetPLDMVersion, testDecodeRequest) { std::array requestMsg{}; 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(requestMsg.data() + hdrSize, &transferHandle, sizeof(transferHandle)); memcpy(requestMsg.data() + sizeof(transferHandle) + hdrSize, &flag, sizeof(flag)); memcpy(requestMsg.data() + sizeof(transferHandle) + sizeof(flag) + hdrSize, &pldmType, sizeof(pldmType)); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto request = reinterpret_cast(requestMsg.data()); auto rc = decode_get_version_req(request, requestMsg.size() - hdrSize, &retTransferHandle, &retFlag, &retType); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(transferHandle, retTransferHandle); EXPECT_EQ(flag, retFlag); EXPECT_EQ(pldmType, retType); } TEST(GetPLDMVersion, testDecodeResponse) { std::array responseMsg{}; 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; ver32_t version = {0xff, 0xff, 0xff, 0xff}; ver32_t versionOut; uint8_t completion_code; memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize, &transferHandle, sizeof(transferHandle)); memcpy(responseMsg.data() + sizeof(completionCode) + sizeof(transferHandle) + hdrSize, &flag, sizeof(flag)); memcpy(responseMsg.data() + sizeof(completionCode) + sizeof(transferHandle) + sizeof(flag) + hdrSize, &version, sizeof(version)); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); auto rc = decode_get_version_resp(response, responseMsg.size() - hdrSize, &completion_code, &retTransferHandle, &retFlag, &versionOut); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(transferHandle, retTransferHandle); EXPECT_EQ(flag, retFlag); EXPECT_EQ(versionOut.major, version.major); EXPECT_EQ(versionOut.minor, version.minor); EXPECT_EQ(versionOut.update, version.update); EXPECT_EQ(versionOut.alpha, version.alpha); } TEST(GetTID, testEncodeRequest) { pldm_msg request{}; auto rc = encode_get_tid_req(0, &request); ASSERT_EQ(rc, PLDM_SUCCESS); } TEST(GetTID, testEncodeResponse) { uint8_t completionCode = 0; std::array responseMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); uint8_t tid = 1; auto rc = encode_get_tid_resp(0, PLDM_SUCCESS, tid, response); EXPECT_EQ(rc, PLDM_SUCCESS); uint8_t* payload = response->payload; EXPECT_EQ(completionCode, payload[0]); EXPECT_EQ(1, payload[sizeof(completionCode)]); } TEST(GetTID, testDecodeResponse) { std::array responseMsg{}; responseMsg[1 + hdrSize] = 1; uint8_t tid; uint8_t completion_code; responseMsg[hdrSize] = PLDM_SUCCESS; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto response = reinterpret_cast(responseMsg.data()); auto rc = decode_get_tid_resp(response, responseMsg.size() - hdrSize, &completion_code, &tid); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(completion_code, PLDM_SUCCESS); EXPECT_EQ(tid, 1); } TEST(DecodeMultipartReceiveRequest, testDecodeRequestPass) { constexpr uint8_t kPldmType = PLDM_BASE; constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART; constexpr uint32_t kTransferCtx = 0x01; constexpr uint32_t kTransferHandle = 0x10; constexpr uint32_t kSectionOffset = 0x0; constexpr uint32_t kSectionLength = 0x10; PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES); PLDM_MSGBUF_RW_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; rc = decode_multipart_receive_req( msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag, &transfer_ctx, &transfer_handle, §ion_offset, §ion_length); ASSERT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(pldm_type, kPldmType); EXPECT_EQ(flag, kFlag); EXPECT_EQ(transfer_ctx, kTransferCtx); EXPECT_EQ(transfer_handle, kTransferHandle); EXPECT_EQ(section_offset, kSectionOffset); EXPECT_EQ(section_length, kSectionLength); } TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailNullData) { EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL), PLDM_ERROR_INVALID_DATA); } TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailBadLength) { PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1); uint8_t pldm_type; uint8_t flag; uint32_t transfer_ctx; uint32_t transfer_handle; uint32_t section_offset; uint32_t section_length; memset(msg, 0, PLDM_MSG_SIZE(PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1)); EXPECT_EQ(decode_multipart_receive_req( msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1, &pldm_type, &flag, &transfer_ctx, &transfer_handle, §ion_offset, §ion_length), PLDM_ERROR_INVALID_DATA); } TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailBadPldmType) { 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_RW_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; 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_PLDM_TYPE); } TEST(DecodeMultipartReceiveRequest, 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_RW_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; 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_UNEXPECTED_TRANSFER_FLAG_OPERATION); } TEST(DecodeMultipartReceiveRequest, 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_RW_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); } #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveRequest, GoodTest) { uint8_t instance_id = 0; const struct pldm_base_multipart_receive_req req_data = { PLDM_BASE, PLDM_XFER_FIRST_PART, 0x01, 0x10, 0x00, 0x10}; static constexpr const size_t requestMsgLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES; std::array requestMsg = { PLDM_BASE, PLDM_XFER_FIRST_PART, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00}; PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength); size_t payload_length = requestMsgLength; auto rc = encode_pldm_base_multipart_receive_req( instance_id, &req_data, requestPtr, &payload_length); ASSERT_EQ(rc, 0); EXPECT_EQ( 0, memcmp(requestPtr->payload, requestMsg.data(), sizeof(requestMsg))); EXPECT_EQ(payload_length, requestMsgLength); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveRequest, BadTestUnAllocatedPtrParams) { uint8_t instance_id = 0; int rc; const struct pldm_base_multipart_receive_req req_data = { PLDM_BASE, PLDM_XFER_FIRST_PART, 0x01, 0x10, 0x00, 0x10}; static constexpr const size_t requestMsgLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES; PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength); size_t payload_length = requestMsgLength; rc = encode_pldm_base_multipart_receive_req(instance_id, nullptr, requestPtr, &payload_length); EXPECT_EQ(rc, -EINVAL); rc = encode_pldm_base_multipart_receive_req(instance_id, &req_data, nullptr, &payload_length); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveRequest, BadTestInvalidExpectedOutputMsgLength) { uint8_t instance_id = 0; int rc; const struct pldm_base_multipart_receive_req req_data = { PLDM_BASE, PLDM_XFER_FIRST_PART, 0x01, 0x10, 0x00, 0x10}; static constexpr const size_t requestMsgLength = PLDM_MULTIPART_RECEIVE_REQ_BYTES; PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength); size_t payload_length = 1; rc = encode_pldm_base_multipart_receive_req(instance_id, &req_data, requestPtr, &payload_length); EXPECT_EQ(rc, -EOVERFLOW); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeMultipartReceiveResponse, GoodTest) { uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END; uint32_t nextDataTransferHandle = 0x15; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; uint32_t dataIntegrityChecksum = 0x3C; struct pldm_base_multipart_receive_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; static constexpr const size_t payload_length = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength + sizeof(dataIntegrityChecksum); PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint8(buf, transferFlag); pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle); pldm_msgbuf_insert_uint32(buf, dataLength); rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(), dataLength); EXPECT_EQ(rc, 0); pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); uint32_t respDataIntegrityChecksum = 0; rc = decode_pldm_base_multipart_receive_resp( responseMsg, payload_length, &resp_data, &respDataIntegrityChecksum); ASSERT_EQ(rc, 0); EXPECT_EQ(resp_data.completion_code, completionCode); EXPECT_EQ(resp_data.transfer_flag, transferFlag); EXPECT_EQ(resp_data.next_transfer_handle, nextDataTransferHandle); EXPECT_EQ(resp_data.data.length, dataLength); EXPECT_EQ(0, memcmp(data.data(), resp_data.data.ptr, resp_data.data.length)); EXPECT_EQ(respDataIntegrityChecksum, dataIntegrityChecksum); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeMultipartReceiveResponse, BadTestUnAllocatedPtrParams) { uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END; uint32_t nextDataTransferHandle = 0x15; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; uint32_t dataIntegrityChecksum = 0x3C; struct pldm_base_multipart_receive_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; static constexpr const size_t payload_length = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength + sizeof(dataIntegrityChecksum); PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint8(buf, transferFlag); pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle); pldm_msgbuf_insert_uint32(buf, dataLength); rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(), dataLength); EXPECT_EQ(rc, 0); pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); uint32_t respDataIntegrityChecksum = 0; rc = decode_pldm_base_multipart_receive_resp( nullptr, payload_length, &resp_data, &respDataIntegrityChecksum); EXPECT_EQ(rc, -EINVAL); rc = decode_pldm_base_multipart_receive_resp( responseMsg, payload_length, nullptr, &respDataIntegrityChecksum); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeMultipartReceiveResponse, BadTestInvalidExpectedInputMsgLength) { uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END; uint32_t nextDataTransferHandle = 0x15; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; uint32_t dataIntegrityChecksum = 0x3C; struct pldm_base_multipart_receive_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; static constexpr const size_t payload_length = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength + sizeof(dataIntegrityChecksum); PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint8(buf, transferFlag); pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle); pldm_msgbuf_insert_uint32(buf, dataLength); rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(), dataLength); EXPECT_EQ(rc, 0); pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); uint32_t respDataIntegrityChecksum = 0; rc = decode_pldm_base_multipart_receive_resp(responseMsg, 0, &resp_data, &respDataIntegrityChecksum); EXPECT_EQ(rc, -EOVERFLOW); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeMultipartReceiveResponse, BadTestRedundantCheckSum) { uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_ACK_COMPLETION; uint32_t nextDataTransferHandle = 0x00; static constexpr const uint32_t dataLength = 0; uint32_t dataIntegrityChecksum = 0x2c; struct pldm_base_multipart_receive_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; /* * Data field is omitted in a response with ACKNOWLEDGE_COMPLETION * TransferFlag. Intentionally insert a DataIntegrityChecksum field to the * response message */ static constexpr const size_t payload_length = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength + sizeof(dataIntegrityChecksum); PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint8(buf, transferFlag); pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle); pldm_msgbuf_insert_uint32(buf, dataLength); pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); uint32_t respDataIntegrityChecksum = 0; rc = decode_pldm_base_multipart_receive_resp( responseMsg, payload_length, &resp_data, &respDataIntegrityChecksum); /* * pldm_msgbuf_complete_consumed() returns -EBADMSG as * decode_pldm_base_multipart_receive_resp() didn't consume all the input * message buffer. */ EXPECT_EQ(rc, -EBADMSG); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeMultipartReceiveResponse, BadTestMissingCheckSum) { uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END; uint32_t nextDataTransferHandle = 0x00; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; struct pldm_base_multipart_receive_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; /* * Intentionally do not insert DataIntegrityChecksum field to the response * message */ static constexpr const size_t payload_length = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength; PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint8(buf, transferFlag); pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle); pldm_msgbuf_insert_uint32(buf, dataLength); rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(), dataLength); EXPECT_EQ(rc, 0); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); uint32_t respDataIntegrityChecksum = 0; rc = decode_pldm_base_multipart_receive_resp( responseMsg, payload_length, &resp_data, &respDataIntegrityChecksum); /* * pldm_msgbuf_extract_p() returns -EOVERFLOW as * decode_pldm_base_multipart_receive_resp() tried to consume more than * the expected input message buffer. */ EXPECT_EQ(rc, -EOVERFLOW); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveResponse, GoodTestWithChecksum) { uint8_t instance_id = 0; uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START_AND_END; uint32_t nextDataTransferHandle = 0x15; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; uint32_t dataIntegrityChecksum = 0x3C; static constexpr const size_t responseMsgLength = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength + sizeof(dataIntegrityChecksum); size_t payload_length = responseMsgLength; struct variable_field payload = {data.data(), dataLength}; struct pldm_base_multipart_receive_resp resp_data = { completionCode, transferFlag, nextDataTransferHandle, payload}; std::array responseMsg = { completionCode, transferFlag, 0x15, // nextDataTransferHandle 0x00, 0x00, 0x00, 0x09, // dataLength 0x00, 0x00, 0x00, 0x1, // data 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x3c, // dataIntegrityChecksum 0x00, 0x00, 0x00}; PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength); int rc; rc = encode_base_multipart_receive_resp(instance_id, &resp_data, dataIntegrityChecksum, responsePtr, &payload_length); ASSERT_EQ(0, rc); EXPECT_EQ(0, memcmp(responsePtr->payload, responseMsg.data(), sizeof(responseMsg))); EXPECT_EQ(payload_length, responseMsgLength); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveResponse, GoodTestWithoutChecksum) { uint8_t instance_id = 0; uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_ACK_COMPLETION; uint32_t nextDataTransferHandle = 0; static constexpr const uint32_t dataLength = 0; static constexpr const size_t responseMsgLength = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength; size_t payload_length = responseMsgLength; struct variable_field payload = {nullptr, dataLength}; struct pldm_base_multipart_receive_resp resp_data = { completionCode, transferFlag, nextDataTransferHandle, payload}; std::array responseMsg = { completionCode, transferFlag, 0x00, // nextDataTransferHandle 0x00, 0x00, 0x00, 0x00, // dataLength 0x00, 0x00, 0x00}; PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength); int rc; rc = encode_base_multipart_receive_resp(instance_id, &resp_data, 0, responsePtr, &payload_length); ASSERT_EQ(0, rc); EXPECT_EQ(0, memcmp(responsePtr->payload, responseMsg.data(), sizeof(responseMsg))); EXPECT_EQ(payload_length, responseMsgLength); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveResponse, GoodTestCompletionCode) { uint8_t instance_id = 0; uint8_t completionCode = PLDM_MULTIPART_RECEIVE_NEGOTIATION_INCOMPLETE; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START; uint32_t nextDataTransferHandle = 0x16; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; static constexpr const size_t responseMsgLength = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength; size_t payload_length = responseMsgLength; struct variable_field payload = {data.data(), dataLength}; struct pldm_base_multipart_receive_resp resp_data = { completionCode, transferFlag, nextDataTransferHandle, payload}; std::array responseMsg = {completionCode}; PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength); int rc; rc = encode_base_multipart_receive_resp(instance_id, &resp_data, 0, responsePtr, &payload_length); ASSERT_EQ(0, rc); EXPECT_EQ(0, memcmp(responsePtr->payload, responseMsg.data(), sizeof(responseMsg))); EXPECT_EQ(payload_length, 1ul); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveResponse, BadTestUnAllocatedParams) { uint8_t instance_id = 0; uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START_AND_END; uint32_t nextDataTransferHandle = 0x15; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; uint32_t dataIntegrityChecksum = 0x3C; static constexpr const size_t responseMsgLength = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength + sizeof(dataIntegrityChecksum); size_t payload_length = responseMsgLength; struct variable_field payload = {data.data(), dataLength}; struct pldm_base_multipart_receive_resp resp_data = { completionCode, transferFlag, nextDataTransferHandle, payload}; PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength); int rc; rc = encode_base_multipart_receive_resp(instance_id, nullptr, dataIntegrityChecksum, responsePtr, &payload_length); EXPECT_EQ(rc, -EINVAL); rc = encode_base_multipart_receive_resp(instance_id, &resp_data, dataIntegrityChecksum, nullptr, &payload_length); EXPECT_EQ(rc, -EINVAL); rc = encode_base_multipart_receive_resp( instance_id, &resp_data, dataIntegrityChecksum, responsePtr, nullptr); EXPECT_EQ(rc, -EINVAL); resp_data.data.ptr = nullptr; rc = encode_base_multipart_receive_resp(instance_id, &resp_data, dataIntegrityChecksum, responsePtr, &payload_length); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeMultipartReceiveResponse, BadTestInvalidExpectedOutputMsgLength) { uint8_t instance_id = 0; uint8_t completionCode = PLDM_SUCCESS; uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START; uint32_t nextDataTransferHandle = 0x16; static constexpr const uint32_t dataLength = 9; std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; static constexpr const size_t responseMsgLength = PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES; size_t payload_length = responseMsgLength; struct variable_field payload = {data.data(), dataLength}; struct pldm_base_multipart_receive_resp resp_data = { completionCode, transferFlag, nextDataTransferHandle, payload}; PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength); int rc; rc = encode_base_multipart_receive_resp(instance_id, &resp_data, 0, responsePtr, &payload_length); EXPECT_EQ(rc, -EOVERFLOW); } #endif TEST(CcOnlyResponse, testEncode) { struct pldm_msg responseMsg; auto rc = encode_cc_only_resp(0 /*instance id*/, 1 /*pldm type*/, 2 /*command*/, 3 /*completion code*/, &responseMsg); EXPECT_EQ(rc, PLDM_SUCCESS); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto p = reinterpret_cast(&responseMsg); EXPECT_THAT(std::vector(p, p + sizeof(responseMsg)), ElementsAreArray({0, 1, 2, 3})); rc = encode_cc_only_resp(PLDM_INSTANCE_MAX + 1, 1, 2, 3, &responseMsg); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); rc = encode_cc_only_resp(0, 1, 2, 3, nullptr); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); } TEST(SetTID, testGoodEncodeRequest) { uint8_t instanceId = 0; uint8_t tid = 0x01; std::array requestMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto request = reinterpret_cast(requestMsg.data()); auto rc = encode_set_tid_req(instanceId, tid, request); ASSERT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(request->hdr.command, PLDM_SET_TID); EXPECT_EQ(request->hdr.type, PLDM_BASE); EXPECT_EQ(request->hdr.request, 1); EXPECT_EQ(request->hdr.datagram, 0); EXPECT_EQ(request->hdr.instance_id, instanceId); EXPECT_EQ(0, memcmp(request->payload, &tid, sizeof(tid))); } TEST(SetTID, testBadEncodeRequest) { uint8_t tid = 0x01; std::array requestMsg{}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto request = reinterpret_cast(requestMsg.data()); auto rc = encode_set_tid_req(0, tid, nullptr); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); rc = encode_set_tid_req(0, 0, request); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); rc = encode_set_tid_req(0, 0xff, request); EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); } #ifdef LIBPLDM_API_TESTING TEST(SetTID, testGoodDecodeRequest) { uint8_t tid = 0x01; uint8_t tidOut = 0x00; std::array requestMsg{}; requestMsg[sizeof(pldm_msg_hdr)] = tid; pldm_msg* request = new (requestMsg.data()) pldm_msg; auto rc = decode_set_tid_req( request, requestMsg.size() - sizeof(pldm_msg_hdr), &tidOut); EXPECT_EQ(rc, PLDM_SUCCESS); EXPECT_EQ(tid, tidOut); } #endif #ifdef LIBPLDM_API_TESTING TEST(SetTID, testBadDecodeRequestMsg) { uint8_t tid = 0x01; std::array requestMsg{}; auto rc = decode_set_tid_req( nullptr, requestMsg.size() - sizeof(pldm_msg_hdr), &tid); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(SetTID, testBadDecodeRequestTid) { std::array requestMsg{}; pldm_msg* request = new (requestMsg.data()) pldm_msg; auto rc = decode_set_tid_req( request, requestMsg.size() - sizeof(pldm_msg_hdr), nullptr); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(SetTID, testBadDecodeRequestMsgSize) { std::array requestMsg{}; pldm_msg* request = new (requestMsg.data()) pldm_msg; auto rc = decode_set_tid_req(request, -1, nullptr); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(PldmMsgHdr, correlateSuccess) { static const struct pldm_msg_hdr req = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 1, .type = 0, .header_ver = 1, .command = 0x01, }; static const struct pldm_msg_hdr resp = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 0, .type = 0, .header_ver = 1, .command = 0x01, }; ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true); } #endif #ifdef LIBPLDM_API_TESTING TEST(PldmMsgHdr, correlateFailInstanceID) { static const struct pldm_msg_hdr req = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 1, .type = 0, .header_ver = 1, .command = 0x01, }; static const struct pldm_msg_hdr resp = { .instance_id = 1, .reserved = 0, .datagram = 0, .request = 0, .type = 0, .header_ver = 1, .command = 0x01, }; ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); } #endif #ifdef LIBPLDM_API_TESTING TEST(PldmMsgHdr, correlateFailRequest) { static const struct pldm_msg_hdr req = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 1, .type = 0, .header_ver = 1, .command = 0x01, }; static const struct pldm_msg_hdr resp = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 1, .type = 0, .header_ver = 1, .command = 0x01, }; ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); } #endif #ifdef LIBPLDM_API_TESTING TEST(PldmMsgHdr, correlateFailType) { static const struct pldm_msg_hdr req = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 1, .type = 0, .header_ver = 1, .command = 0x01, }; static const struct pldm_msg_hdr resp = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 0, .type = 1, .header_ver = 1, .command = 0x01, }; ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); } #endif #ifdef LIBPLDM_API_TESTING TEST(PldmMsgHdr, correlateFailCommand) { static const struct pldm_msg_hdr req = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 1, .type = 0, .header_ver = 1, .command = 0x01, }; static const struct pldm_msg_hdr resp = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 0, .type = 0, .header_ver = 1, .command = 0x02, }; ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); } #endif #ifdef LIBPLDM_API_TESTING TEST(PldmMsgHdr, correlateFailRequestIsResponse) { static const struct pldm_msg_hdr req = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 0, .type = 0, .header_ver = 1, .command = 0x01, }; static const struct pldm_msg_hdr resp = { .instance_id = 0, .reserved = 0, .datagram = 0, .request = 0, .type = 0, .header_ver = 1, .command = 0x02, }; ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeNegotiateTransferParamsRequest, GoodTest) { uint8_t instance_id = 0; const struct pldm_base_negotiate_transfer_params_req req_data = { 0x0001, // BE 256 {{0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x81}}}; static constexpr const size_t requestMsgLength = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES; std::array requestMsg = { 0x01, 0x00, // requester_part_size = 256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81}; // requester_protocol_support = // PLDM_BASE & PLDM_FILE PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength); size_t payload_length = requestMsgLength; auto rc = encode_pldm_base_negotiate_transfer_params_req( instance_id, &req_data, requestPtr, &payload_length); ASSERT_EQ(rc, 0); EXPECT_EQ( 0, memcmp(requestPtr->payload, requestMsg.data(), sizeof(requestMsg))); EXPECT_EQ(payload_length, requestMsgLength); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeNegotiateTransferParamsRequest, BadTestUnAllocatedPtrParams) { int rc; uint8_t instance_id = 0; const struct pldm_base_negotiate_transfer_params_req req_data = { 0x0001, // BE 256 {{0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x81}}}; static constexpr const size_t requestMsgLength = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES; PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength); size_t payload_length = requestMsgLength; rc = encode_pldm_base_negotiate_transfer_params_req( instance_id, nullptr, requestPtr, &payload_length); EXPECT_EQ(rc, -EINVAL); rc = encode_pldm_base_negotiate_transfer_params_req( instance_id, &req_data, nullptr, &payload_length); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(EncodeNegotiateTransferParamsRequest, BadTestInvalidExpectedOutputMsgLength) { int rc; uint8_t instance_id = 0; const struct pldm_base_negotiate_transfer_params_req req_data = { 0x0001, // BE 256 {{0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x81}}}; PLDM_MSG_DEFINE_P(requestPtr, PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES); size_t payload_length = 1; rc = encode_pldm_base_negotiate_transfer_params_req( instance_id, &req_data, requestPtr, &payload_length); EXPECT_EQ(rc, -EOVERFLOW); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeNegotiateTransferParamsResponse, GoodTest) { uint8_t completionCode = PLDM_SUCCESS; uint16_t responderPartSize = 128; std::array responderProtocolSupport = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81}; struct pldm_base_negotiate_transfer_params_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; static constexpr const size_t payload_length = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES; PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint16(buf, responderPartSize); rc = pldm_msgbuf_insert_array_uint8( buf, sizeof(resp_data.responder_protocol_support), responderProtocolSupport.data(), sizeof(resp_data.responder_protocol_support)); EXPECT_EQ(rc, 0); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); rc = decode_pldm_base_negotiate_transfer_params_resp( responseMsg, payload_length, &resp_data); ASSERT_EQ(rc, 0); EXPECT_EQ(resp_data.completion_code, completionCode); EXPECT_EQ(resp_data.responder_part_size, responderPartSize); EXPECT_EQ(0, memcmp(responderProtocolSupport.data(), resp_data.responder_protocol_support, sizeof(resp_data.responder_protocol_support))); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeNegotiateTransferParamsResponse, BadTestUnAllocatedPtrParams) { uint8_t completionCode = PLDM_SUCCESS; uint16_t responderPartSize = 128; std::array responderProtocolSupport = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81}; struct pldm_base_negotiate_transfer_params_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; static constexpr const size_t payload_length = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES; PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint16(buf, responderPartSize); rc = pldm_msgbuf_insert_array_uint8( buf, sizeof(resp_data.responder_protocol_support), responderProtocolSupport.data(), sizeof(resp_data.responder_protocol_support)); EXPECT_EQ(rc, 0); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); rc = decode_pldm_base_negotiate_transfer_params_resp( nullptr, payload_length, &resp_data); EXPECT_EQ(rc, -EINVAL); rc = decode_pldm_base_negotiate_transfer_params_resp( responseMsg, payload_length, nullptr); EXPECT_EQ(rc, -EINVAL); } #endif #ifdef LIBPLDM_API_TESTING TEST(DecodeNegotiateTransferParamsResponse, BadTestInvalidExpectedInputMsgLength) { uint8_t completionCode = PLDM_SUCCESS; uint16_t responderPartSize = 128; std::array responderProtocolSupport = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81}; struct pldm_base_negotiate_transfer_params_resp resp_data = {}; PLDM_MSGBUF_RW_DEFINE_P(buf); int rc; static constexpr const size_t payload_length = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES; PLDM_MSG_DEFINE_P(responseMsg, payload_length); rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length); ASSERT_EQ(rc, 0); pldm_msgbuf_insert_uint8(buf, completionCode); pldm_msgbuf_insert_uint16(buf, responderPartSize); rc = pldm_msgbuf_insert_array_uint8( buf, sizeof(resp_data.responder_protocol_support), responderProtocolSupport.data(), sizeof(resp_data.responder_protocol_support)); EXPECT_EQ(rc, 0); ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); rc = decode_pldm_base_negotiate_transfer_params_resp(responseMsg, 0, &resp_data); EXPECT_EQ(rc, -EOVERFLOW); } #endif #ifdef LIBPLDM_API_TESTING TEST(NegotiateTransferParams, TestDecodeNegotiateTransferParamsReqPass) { // Prepare a sample request message uint8_t instance_id = 0x0A; uint16_t requester_part_size = 1024; // 0x0400 bitfield8_t requester_protocol_support[8]; for (int i = 0; i < 8; ++i) { requester_protocol_support[i].byte = static_cast(i + 1); } PLDM_MSG_DEFINE_P(request, PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES); // Build the request using the an appropriate API struct pldm_base_negotiate_transfer_params_req req; req.requester_part_size = requester_part_size; memcpy(req.requester_protocol_support, requester_protocol_support, sizeof(requester_protocol_support)); size_t req_payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES; ASSERT_EQ(encode_pldm_base_negotiate_transfer_params_req( instance_id, &req, request, &req_payload_len), 0); struct pldm_base_negotiate_transfer_params_req decoded_req; size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES; // Successful decode int rc = decode_pldm_base_negotiate_transfer_params_req( request, payload_len, &decoded_req); ASSERT_EQ(rc, 0); EXPECT_EQ(decoded_req.requester_part_size, requester_part_size); for (int i = 0; i < 8; ++i) { EXPECT_EQ(decoded_req.requester_protocol_support[i].byte, requester_protocol_support[i].byte); } } #endif #ifdef LIBPLDM_API_TESTING TEST(NegotiateTransferParams, TestDecodeNegotiateTransferParamsReqFail) { // Prepare a sample request message uint8_t instance_id = 0x0A; uint16_t requester_part_size = 1024; // 0x0400 bitfield8_t requester_protocol_support[8]; for (int i = 0; i < 8; ++i) { requester_protocol_support[i].byte = static_cast(i + 1); } PLDM_MSG_DEFINE_P(request, PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES); // Build the request using the an appropriate API struct pldm_base_negotiate_transfer_params_req req; req.requester_part_size = requester_part_size; memcpy(req.requester_protocol_support, requester_protocol_support, sizeof(requester_protocol_support)); size_t req_payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES; ASSERT_EQ(encode_pldm_base_negotiate_transfer_params_req( instance_id, &req, request, &req_payload_len), 0); struct pldm_base_negotiate_transfer_params_req decoded_req; size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES; int rc = 0; // Null arguments rc = decode_pldm_base_negotiate_transfer_params_req(nullptr, payload_len, &decoded_req); EXPECT_EQ(rc, -EINVAL); rc = decode_pldm_base_negotiate_transfer_params_req(request, payload_len, nullptr); EXPECT_EQ(rc, -EINVAL); // Incorrect payload length - too short rc = decode_pldm_base_negotiate_transfer_params_req( request, payload_len - 1, &decoded_req); EXPECT_EQ(rc, -EOVERFLOW); // Incorrect payload length - too long rc = decode_pldm_base_negotiate_transfer_params_req( request, payload_len + 1, &decoded_req); EXPECT_EQ(rc, -EBADMSG); } #endif #ifdef LIBPLDM_API_TESTING TEST(NegotiateTransferParams, TestEncodeNegotiateTransferParamsRespPass) { // Prepare encode parameters for a successful response uint8_t instance_id = 0x0B; uint8_t completion_code_success = PLDM_SUCCESS; uint16_t responder_part_size = 2048; // 0x0800 bitfield8_t responder_protocol_support[8]; for (int i = 0; i < 8; ++i) { responder_protocol_support[i].byte = static_cast(0xA0 + i); } struct pldm_base_negotiate_transfer_params_resp resp_params_success; resp_params_success.completion_code = completion_code_success; resp_params_success.responder_part_size = responder_part_size; memcpy(resp_params_success.responder_protocol_support, responder_protocol_support, sizeof(responder_protocol_support)); PLDM_MSG_DEFINE_P(response, PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES); size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES; // Encode success case int rc = encode_pldm_base_negotiate_transfer_params_resp( instance_id, &resp_params_success, response, &payload_len); ASSERT_EQ(rc, 0); EXPECT_EQ(response->hdr.request, PLDM_RESPONSE); EXPECT_EQ(response->hdr.instance_id, instance_id); EXPECT_EQ(response->hdr.type, PLDM_BASE); EXPECT_EQ(response->hdr.command, PLDM_NEGOTIATE_TRANSFER_PARAMETERS); // Verify the encoded response using the decode function struct pldm_base_negotiate_transfer_params_resp decoded_resp; payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES; rc = decode_pldm_base_negotiate_transfer_params_resp(response, payload_len, &decoded_resp); ASSERT_EQ(rc, 0); EXPECT_EQ(decoded_resp.completion_code, completion_code_success); EXPECT_EQ(decoded_resp.responder_part_size, responder_part_size); for (int i = 0; i < 8; ++i) { EXPECT_EQ(decoded_resp.responder_protocol_support[i].byte, responder_protocol_support[i].byte); } } TEST(NegotiateTransferParams, TestEncodeNegotiateTransferParamsRespFail) { // Prepare encode parameters uint8_t instance_id = 0x0B; uint8_t completion_code_success = PLDM_SUCCESS; uint16_t responder_part_size = 2048; // 0x0800 bitfield8_t responder_protocol_support[8]; for (int i = 0; i < 8; ++i) { responder_protocol_support[i].byte = static_cast(0xA0 + i); } struct pldm_base_negotiate_transfer_params_resp resp_params_success; resp_params_success.completion_code = completion_code_success; resp_params_success.responder_part_size = responder_part_size; memcpy(resp_params_success.responder_protocol_support, responder_protocol_support, sizeof(responder_protocol_support)); PLDM_MSG_DEFINE_P(response, PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES); size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES; int rc = 0; // Null arguments rc = encode_pldm_base_negotiate_transfer_params_resp( instance_id, nullptr, response, &payload_len); EXPECT_EQ(rc, -EINVAL); payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES; rc = encode_pldm_base_negotiate_transfer_params_resp( instance_id, &resp_params_success, nullptr, &payload_len); EXPECT_EQ(rc, -EINVAL); // Incorrect payload length payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES - 1; rc = encode_pldm_base_negotiate_transfer_params_resp( instance_id, &resp_params_success, response, &payload_len); EXPECT_EQ(rc, -EOVERFLOW); } #endif