1 #include <libpldm/base.h> 2 #include <libpldm/pldm_types.h> 3 4 #include <array> 5 #include <cstdint> 6 #include <cstring> 7 #include <vector> 8 9 #include <gmock/gmock.h> 10 #include <gtest/gtest.h> 11 12 using testing::ElementsAreArray; 13 14 constexpr auto hdrSize = sizeof(pldm_msg_hdr); 15 16 TEST(PackPLDMMessage, BadPathTest) 17 { 18 struct pldm_header_info hdr; 19 struct pldm_header_info* hdr_ptr = NULL; 20 pldm_msg_hdr msg{}; 21 22 // PLDM header information pointer is NULL 23 auto rc = pack_pldm_header(hdr_ptr, &msg); 24 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 25 26 // PLDM message pointer is NULL 27 rc = pack_pldm_header(&hdr, nullptr); 28 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 29 30 // PLDM header information pointer and PLDM message pointer is NULL 31 rc = pack_pldm_header(hdr_ptr, nullptr); 32 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 33 34 // RESERVED message type 35 hdr.msg_type = PLDM_RESERVED; 36 rc = pack_pldm_header(&hdr, &msg); 37 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 38 39 // Instance ID out of range 40 hdr.msg_type = PLDM_REQUEST; 41 hdr.instance = 32; 42 rc = pack_pldm_header(&hdr, &msg); 43 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 44 45 // PLDM type out of range 46 hdr.msg_type = PLDM_REQUEST; 47 hdr.instance = 31; 48 hdr.pldm_type = 64; 49 rc = pack_pldm_header(&hdr, &msg); 50 EXPECT_EQ(rc, PLDM_ERROR_INVALID_PLDM_TYPE); 51 } 52 53 TEST(PackPLDMMessage, RequestMessageGoodPath) 54 { 55 struct pldm_header_info hdr; 56 pldm_msg_hdr msg{}; 57 58 // Message type is REQUEST and lower range of the field values 59 hdr.msg_type = PLDM_REQUEST; 60 hdr.instance = 0; 61 hdr.pldm_type = 0; 62 hdr.command = 0; 63 64 auto rc = pack_pldm_header(&hdr, &msg); 65 EXPECT_EQ(rc, PLDM_SUCCESS); 66 EXPECT_EQ(msg.request, 1); 67 EXPECT_EQ(msg.datagram, 0); 68 EXPECT_EQ(msg.instance_id, 0); 69 EXPECT_EQ(msg.type, 0); 70 EXPECT_EQ(msg.command, 0); 71 72 // Message type is REQUEST and upper range of the field values 73 hdr.instance = 31; 74 hdr.pldm_type = 63; 75 hdr.command = 255; 76 77 rc = pack_pldm_header(&hdr, &msg); 78 EXPECT_EQ(rc, PLDM_SUCCESS); 79 EXPECT_EQ(msg.request, 1); 80 EXPECT_EQ(msg.datagram, 0); 81 EXPECT_EQ(msg.instance_id, 31); 82 EXPECT_EQ(msg.type, 63); 83 EXPECT_EQ(msg.command, 255); 84 85 // Message type is PLDM_ASYNC_REQUEST_NOTIFY 86 hdr.msg_type = PLDM_ASYNC_REQUEST_NOTIFY; 87 88 rc = pack_pldm_header(&hdr, &msg); 89 EXPECT_EQ(rc, PLDM_SUCCESS); 90 EXPECT_EQ(msg.request, 1); 91 EXPECT_EQ(msg.datagram, 1); 92 EXPECT_EQ(msg.instance_id, 31); 93 EXPECT_EQ(msg.type, 63); 94 EXPECT_EQ(msg.command, 255); 95 } 96 97 TEST(PackPLDMMessage, ResponseMessageGoodPath) 98 { 99 struct pldm_header_info hdr; 100 pldm_msg_hdr msg{}; 101 102 // Message type is PLDM_RESPONSE and lower range of the field values 103 hdr.msg_type = PLDM_RESPONSE; 104 hdr.instance = 0; 105 hdr.pldm_type = 0; 106 hdr.command = 0; 107 108 auto rc = pack_pldm_header(&hdr, &msg); 109 EXPECT_EQ(rc, PLDM_SUCCESS); 110 EXPECT_EQ(msg.request, 0); 111 EXPECT_EQ(msg.datagram, 0); 112 EXPECT_EQ(msg.instance_id, 0); 113 EXPECT_EQ(msg.type, 0); 114 EXPECT_EQ(msg.command, 0); 115 116 // Message type is PLDM_RESPONSE and upper range of the field values 117 hdr.instance = 31; 118 hdr.pldm_type = 63; 119 hdr.command = 255; 120 121 rc = pack_pldm_header(&hdr, &msg); 122 EXPECT_EQ(rc, PLDM_SUCCESS); 123 EXPECT_EQ(msg.request, 0); 124 EXPECT_EQ(msg.datagram, 0); 125 EXPECT_EQ(msg.instance_id, 31); 126 EXPECT_EQ(msg.type, 63); 127 EXPECT_EQ(msg.command, 255); 128 } 129 130 TEST(UnpackPLDMMessage, BadPathTest) 131 { 132 struct pldm_header_info hdr; 133 134 // PLDM message pointer is NULL 135 auto rc = unpack_pldm_header(nullptr, &hdr); 136 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 137 } 138 139 TEST(UnpackPLDMMessage, RequestMessageGoodPath) 140 { 141 struct pldm_header_info hdr; 142 pldm_msg_hdr msg{}; 143 144 // Unpack PLDM request message and lower range of field values 145 msg.request = 1; 146 auto rc = unpack_pldm_header(&msg, &hdr); 147 EXPECT_EQ(rc, PLDM_SUCCESS); 148 EXPECT_EQ(hdr.msg_type, PLDM_REQUEST); 149 EXPECT_EQ(hdr.instance, 0); 150 EXPECT_EQ(hdr.pldm_type, 0); 151 EXPECT_EQ(hdr.command, 0); 152 153 // Unpack PLDM async request message and lower range of field values 154 msg.datagram = 1; 155 rc = unpack_pldm_header(&msg, &hdr); 156 EXPECT_EQ(rc, PLDM_SUCCESS); 157 EXPECT_EQ(hdr.msg_type, PLDM_ASYNC_REQUEST_NOTIFY); 158 159 // Unpack PLDM request message and upper range of field values 160 msg.datagram = 0; 161 msg.instance_id = 31; 162 msg.type = 63; 163 msg.command = 255; 164 rc = unpack_pldm_header(&msg, &hdr); 165 EXPECT_EQ(rc, PLDM_SUCCESS); 166 EXPECT_EQ(hdr.msg_type, PLDM_REQUEST); 167 EXPECT_EQ(hdr.instance, 31); 168 EXPECT_EQ(hdr.pldm_type, 63); 169 EXPECT_EQ(hdr.command, 255); 170 } 171 172 TEST(UnpackPLDMMessage, ResponseMessageGoodPath) 173 { 174 struct pldm_header_info hdr; 175 pldm_msg_hdr msg{}; 176 177 // Unpack PLDM response message and lower range of field values 178 auto rc = unpack_pldm_header(&msg, &hdr); 179 EXPECT_EQ(rc, PLDM_SUCCESS); 180 EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE); 181 EXPECT_EQ(hdr.instance, 0); 182 EXPECT_EQ(hdr.pldm_type, 0); 183 EXPECT_EQ(hdr.command, 0); 184 185 // Unpack PLDM response message and upper range of field values 186 msg.instance_id = 31; 187 msg.type = 63; 188 msg.command = 255; 189 rc = unpack_pldm_header(&msg, &hdr); 190 EXPECT_EQ(rc, PLDM_SUCCESS); 191 EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE); 192 EXPECT_EQ(hdr.instance, 31); 193 EXPECT_EQ(hdr.pldm_type, 63); 194 EXPECT_EQ(hdr.command, 255); 195 } 196 197 TEST(GetPLDMCommands, testEncodeRequest) 198 { 199 uint8_t pldmType = 0x05; 200 ver32_t version{0xff, 0xff, 0xff, 0xff}; 201 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES> 202 requestMsg{}; 203 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 204 205 auto rc = encode_get_commands_req(0, pldmType, version, request); 206 EXPECT_EQ(rc, PLDM_SUCCESS); 207 EXPECT_EQ(0, memcmp(request->payload, &pldmType, sizeof(pldmType))); 208 EXPECT_EQ(0, memcmp(request->payload + sizeof(pldmType), &version, 209 sizeof(version))); 210 } 211 212 TEST(GetPLDMCommands, testDecodeRequest) 213 { 214 uint8_t pldmType = 0x05; 215 ver32_t version{0xff, 0xff, 0xff, 0xff}; 216 uint8_t pldmTypeOut{}; 217 ver32_t versionOut{0xff, 0xff, 0xff, 0xff}; 218 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{}; 219 220 memcpy(requestMsg.data() + hdrSize, &pldmType, sizeof(pldmType)); 221 memcpy(requestMsg.data() + sizeof(pldmType) + hdrSize, &version, 222 sizeof(version)); 223 224 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 225 auto rc = decode_get_commands_req(request, requestMsg.size() - hdrSize, 226 &pldmTypeOut, &versionOut); 227 228 EXPECT_EQ(rc, PLDM_SUCCESS); 229 EXPECT_EQ(pldmTypeOut, pldmType); 230 EXPECT_EQ(0, memcmp(&versionOut, &version, sizeof(version))); 231 } 232 233 TEST(GetPLDMCommands, testEncodeResponse) 234 { 235 uint8_t completionCode = 0; 236 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES> 237 responseMsg{}; 238 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 239 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{}; 240 commands[0].byte = 1; 241 commands[1].byte = 2; 242 commands[2].byte = 3; 243 244 auto rc = 245 encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), response); 246 EXPECT_EQ(rc, PLDM_SUCCESS); 247 uint8_t* payload_ptr = response->payload; 248 EXPECT_EQ(completionCode, payload_ptr[0]); 249 EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]); 250 EXPECT_EQ(2, 251 payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte)]); 252 EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte) + 253 sizeof(commands[1].byte)]); 254 } 255 256 TEST(GetPLDMTypes, testEncodeResponse) 257 { 258 uint8_t completionCode = 0; 259 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES> 260 responseMsg{}; 261 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 262 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> types{}; 263 types[0].byte = 1; 264 types[1].byte = 2; 265 types[2].byte = 3; 266 267 auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response); 268 EXPECT_EQ(rc, PLDM_SUCCESS); 269 uint8_t* payload_ptr = response->payload; 270 EXPECT_EQ(completionCode, payload_ptr[0]); 271 EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]); 272 EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte)]); 273 EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte) + 274 sizeof(types[1].byte)]); 275 } 276 277 TEST(GetPLDMTypes, testGoodDecodeResponse) 278 { 279 std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{}; 280 responseMsg[1 + hdrSize] = 1; 281 responseMsg[2 + hdrSize] = 2; 282 responseMsg[3 + hdrSize] = 3; 283 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{}; 284 285 uint8_t completion_code; 286 responseMsg[hdrSize] = PLDM_SUCCESS; 287 288 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 289 290 auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize, 291 &completion_code, outTypes.data()); 292 293 EXPECT_EQ(rc, PLDM_SUCCESS); 294 EXPECT_EQ(completion_code, PLDM_SUCCESS); 295 EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte); 296 EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte); 297 EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte); 298 } 299 300 TEST(GetPLDMTypes, testBadDecodeResponse) 301 { 302 std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{}; 303 responseMsg[1 + hdrSize] = 1; 304 responseMsg[2 + hdrSize] = 2; 305 responseMsg[3 + hdrSize] = 3; 306 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{}; 307 308 uint8_t retcompletion_code = 0; 309 responseMsg[hdrSize] = PLDM_SUCCESS; 310 311 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 312 313 auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize - 1, 314 &retcompletion_code, outTypes.data()); 315 316 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 317 } 318 319 TEST(GetPLDMCommands, testGoodDecodeResponse) 320 { 321 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{}; 322 responseMsg[1 + hdrSize] = 1; 323 responseMsg[2 + hdrSize] = 2; 324 responseMsg[3 + hdrSize] = 3; 325 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{}; 326 327 uint8_t completion_code; 328 responseMsg[hdrSize] = PLDM_SUCCESS; 329 330 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 331 332 auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize, 333 &completion_code, outTypes.data()); 334 335 EXPECT_EQ(rc, PLDM_SUCCESS); 336 EXPECT_EQ(completion_code, PLDM_SUCCESS); 337 EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte); 338 EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte); 339 EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte); 340 } 341 342 TEST(GetPLDMCommands, testBadDecodeResponse) 343 { 344 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{}; 345 responseMsg[1 + hdrSize] = 1; 346 responseMsg[2 + hdrSize] = 2; 347 responseMsg[3 + hdrSize] = 3; 348 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{}; 349 350 uint8_t retcompletion_code = 0; 351 responseMsg[hdrSize] = PLDM_SUCCESS; 352 353 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 354 355 auto rc = 356 decode_get_commands_resp(response, responseMsg.size() - hdrSize - 1, 357 &retcompletion_code, outTypes.data()); 358 359 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 360 } 361 362 TEST(GetPLDMVersion, testGoodEncodeRequest) 363 { 364 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES> 365 requestMsg{}; 366 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 367 uint8_t pldmType = 0x03; 368 uint32_t transferHandle = 0x0; 369 uint8_t opFlag = 0x01; 370 371 auto rc = 372 encode_get_version_req(0, transferHandle, opFlag, pldmType, request); 373 EXPECT_EQ(rc, PLDM_SUCCESS); 374 EXPECT_EQ( 375 0, memcmp(request->payload, &transferHandle, sizeof(transferHandle))); 376 EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle), &opFlag, 377 sizeof(opFlag))); 378 EXPECT_EQ(0, 379 memcmp(request->payload + sizeof(transferHandle) + sizeof(opFlag), 380 &pldmType, sizeof(pldmType))); 381 } 382 383 TEST(GetPLDMVersion, testBadEncodeRequest) 384 { 385 uint8_t pldmType = 0x03; 386 uint32_t transferHandle = 0x0; 387 uint8_t opFlag = 0x01; 388 389 auto rc = 390 encode_get_version_req(0, transferHandle, opFlag, pldmType, nullptr); 391 392 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 393 } 394 395 TEST(GetPLDMVersion, testEncodeResponse) 396 { 397 uint8_t completionCode = 0; 398 uint32_t transferHandle = 0; 399 uint8_t flag = PLDM_START_AND_END; 400 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES> 401 responseMsg{}; 402 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 403 ver32_t version = {0xff, 0xff, 0xff, 0xff}; 404 405 auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END, 406 &version, sizeof(ver32_t), response); 407 408 EXPECT_EQ(rc, PLDM_SUCCESS); 409 EXPECT_EQ(completionCode, response->payload[0]); 410 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]), 411 &transferHandle, sizeof(transferHandle))); 412 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) + 413 sizeof(transferHandle), 414 &flag, sizeof(flag))); 415 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) + 416 sizeof(transferHandle) + sizeof(flag), 417 &version, sizeof(version))); 418 } 419 420 TEST(GetPLDMVersion, testDecodeRequest) 421 { 422 std::array<uint8_t, hdrSize + PLDM_GET_VERSION_REQ_BYTES> requestMsg{}; 423 uint32_t transferHandle = 0x0; 424 uint32_t retTransferHandle = 0x0; 425 uint8_t flag = PLDM_GET_FIRSTPART; 426 uint8_t retFlag = PLDM_GET_FIRSTPART; 427 uint8_t pldmType = PLDM_BASE; 428 uint8_t retType = PLDM_BASE; 429 430 memcpy(requestMsg.data() + hdrSize, &transferHandle, 431 sizeof(transferHandle)); 432 memcpy(requestMsg.data() + sizeof(transferHandle) + hdrSize, &flag, 433 sizeof(flag)); 434 memcpy(requestMsg.data() + sizeof(transferHandle) + sizeof(flag) + hdrSize, 435 &pldmType, sizeof(pldmType)); 436 437 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 438 439 auto rc = decode_get_version_req(request, requestMsg.size() - hdrSize, 440 &retTransferHandle, &retFlag, &retType); 441 442 EXPECT_EQ(rc, PLDM_SUCCESS); 443 EXPECT_EQ(transferHandle, retTransferHandle); 444 EXPECT_EQ(flag, retFlag); 445 EXPECT_EQ(pldmType, retType); 446 } 447 448 TEST(GetPLDMVersion, testDecodeResponse) 449 { 450 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES> 451 responseMsg{}; 452 uint32_t transferHandle = 0x0; 453 uint32_t retTransferHandle = 0x0; 454 uint8_t flag = PLDM_START_AND_END; 455 uint8_t retFlag = PLDM_START_AND_END; 456 uint8_t completionCode = 0; 457 ver32_t version = {0xff, 0xff, 0xff, 0xff}; 458 ver32_t versionOut; 459 uint8_t completion_code; 460 461 memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize, 462 &transferHandle, sizeof(transferHandle)); 463 memcpy(responseMsg.data() + sizeof(completionCode) + 464 sizeof(transferHandle) + hdrSize, 465 &flag, sizeof(flag)); 466 memcpy(responseMsg.data() + sizeof(completionCode) + 467 sizeof(transferHandle) + sizeof(flag) + hdrSize, 468 &version, sizeof(version)); 469 470 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 471 472 auto rc = decode_get_version_resp(response, responseMsg.size() - hdrSize, 473 &completion_code, &retTransferHandle, 474 &retFlag, &versionOut); 475 EXPECT_EQ(rc, PLDM_SUCCESS); 476 EXPECT_EQ(transferHandle, retTransferHandle); 477 EXPECT_EQ(flag, retFlag); 478 479 EXPECT_EQ(versionOut.major, version.major); 480 EXPECT_EQ(versionOut.minor, version.minor); 481 EXPECT_EQ(versionOut.update, version.update); 482 EXPECT_EQ(versionOut.alpha, version.alpha); 483 } 484 485 TEST(GetTID, testEncodeRequest) 486 { 487 pldm_msg request{}; 488 489 auto rc = encode_get_tid_req(0, &request); 490 ASSERT_EQ(rc, PLDM_SUCCESS); 491 } 492 493 TEST(GetTID, testEncodeResponse) 494 { 495 uint8_t completionCode = 0; 496 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES> 497 responseMsg{}; 498 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 499 uint8_t tid = 1; 500 501 auto rc = encode_get_tid_resp(0, PLDM_SUCCESS, tid, response); 502 EXPECT_EQ(rc, PLDM_SUCCESS); 503 uint8_t* payload = response->payload; 504 EXPECT_EQ(completionCode, payload[0]); 505 EXPECT_EQ(1, payload[sizeof(completionCode)]); 506 } 507 508 TEST(GetTID, testDecodeResponse) 509 { 510 std::array<uint8_t, hdrSize + PLDM_GET_TID_RESP_BYTES> responseMsg{}; 511 responseMsg[1 + hdrSize] = 1; 512 513 uint8_t tid; 514 uint8_t completion_code; 515 responseMsg[hdrSize] = PLDM_SUCCESS; 516 517 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 518 519 auto rc = decode_get_tid_resp(response, responseMsg.size() - hdrSize, 520 &completion_code, &tid); 521 522 EXPECT_EQ(rc, PLDM_SUCCESS); 523 EXPECT_EQ(completion_code, PLDM_SUCCESS); 524 EXPECT_EQ(tid, 1); 525 } 526 527 TEST(MultipartReceive, testDecodeRequestPass) 528 { 529 constexpr uint8_t kPldmType = PLDM_BASE; 530 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART; 531 constexpr uint32_t kTransferCtx = 0x01; 532 constexpr uint32_t kTransferHandle = 0x10; 533 constexpr uint32_t kSectionOffset = 0x0; 534 constexpr uint32_t kSectionLength = 0x10; 535 uint8_t pldm_type = 0x0; 536 uint8_t flag = PLDM_GET_FIRSTPART; 537 uint32_t transfer_ctx; 538 uint32_t transfer_handle; 539 uint32_t section_offset; 540 uint32_t section_length; 541 542 // Header values don't matter for this test. 543 pldm_msg_hdr hdr{}; 544 // Assign values to the packet struct and memcpy to ensure correct byte 545 // ordering. 546 pldm_multipart_receive_req req_pkt = { 547 .pldm_type = kPldmType, 548 .transfer_opflag = kFlag, 549 .transfer_ctx = kTransferCtx, 550 .transfer_handle = kTransferHandle, 551 .section_offset = kSectionOffset, 552 .section_length = kSectionLength, 553 }; 554 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 555 std::memcpy(req.data(), &hdr, sizeof(hdr)); 556 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 557 558 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 559 int rc = decode_multipart_receive_req( 560 pldm_request, req.size() - hdrSize, &pldm_type, &flag, &transfer_ctx, 561 &transfer_handle, §ion_offset, §ion_length); 562 563 EXPECT_EQ(rc, PLDM_SUCCESS); 564 EXPECT_EQ(pldm_type, kPldmType); 565 EXPECT_EQ(flag, kFlag); 566 EXPECT_EQ(transfer_ctx, kTransferCtx); 567 EXPECT_EQ(transfer_handle, kTransferHandle); 568 EXPECT_EQ(section_offset, kSectionOffset); 569 EXPECT_EQ(section_length, kSectionLength); 570 } 571 572 TEST(MultipartReceive, testDecodeRequestFailNullData) 573 { 574 EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL, 575 NULL, NULL), 576 PLDM_ERROR_INVALID_DATA); 577 } 578 579 TEST(MultipartReceive, testDecodeRequestFailBadLength) 580 { 581 constexpr uint8_t kPldmType = PLDM_BASE; 582 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART; 583 uint8_t pldm_type; 584 uint8_t flag; 585 uint32_t transfer_ctx; 586 uint32_t transfer_handle; 587 uint32_t section_offset; 588 uint32_t section_length; 589 590 // Header values don't matter for this test. 591 pldm_msg_hdr hdr{}; 592 // Assign values to the packet struct and memcpy to ensure correct byte 593 // ordering. 594 pldm_multipart_receive_req req_pkt{}; 595 req_pkt.pldm_type = kPldmType; 596 req_pkt.transfer_opflag = kFlag; 597 598 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 599 std::memcpy(req.data(), &hdr, sizeof(hdr)); 600 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 601 602 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 603 EXPECT_EQ(decode_multipart_receive_req( 604 pldm_request, (req.size() - hdrSize) + 1, &pldm_type, &flag, 605 &transfer_ctx, &transfer_handle, §ion_offset, 606 §ion_length), 607 PLDM_ERROR_INVALID_LENGTH); 608 } 609 610 TEST(MultipartReceive, testDecodeRequestFailBadPldmType) 611 { 612 constexpr uint8_t kPldmType = 0xff; 613 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART; 614 uint8_t pldm_type; 615 uint8_t flag; 616 uint32_t transfer_ctx; 617 uint32_t transfer_handle; 618 uint32_t section_offset; 619 uint32_t section_length; 620 621 // Header values don't matter for this test. 622 pldm_msg_hdr hdr{}; 623 // Assign values to the packet struct and memcpy to ensure correct byte 624 // ordering. 625 pldm_multipart_receive_req req_pkt{}; 626 req_pkt.pldm_type = kPldmType; 627 req_pkt.transfer_opflag = kFlag; 628 629 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 630 std::memcpy(req.data(), &hdr, sizeof(hdr)); 631 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 632 633 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 634 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 635 &pldm_type, &flag, &transfer_ctx, 636 &transfer_handle, §ion_offset, 637 §ion_length), 638 PLDM_ERROR_INVALID_PLDM_TYPE); 639 } 640 641 TEST(MultipartReceive, testDecodeRequestFailBadTransferFlag) 642 { 643 constexpr uint8_t kPldmType = PLDM_BASE; 644 constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10; 645 uint8_t pldm_type; 646 uint8_t flag; 647 uint32_t transfer_ctx; 648 uint32_t transfer_handle; 649 uint32_t section_offset; 650 uint32_t section_length; 651 652 // Header values don't matter for this test. 653 pldm_msg_hdr hdr{}; 654 // Assign values to the packet struct and memcpy to ensure correct byte 655 // ordering. 656 pldm_multipart_receive_req req_pkt{}; 657 req_pkt.pldm_type = kPldmType; 658 req_pkt.transfer_opflag = kFlag; 659 660 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 661 std::memcpy(req.data(), &hdr, sizeof(hdr)); 662 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 663 664 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 665 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 666 &pldm_type, &flag, &transfer_ctx, 667 &transfer_handle, §ion_offset, 668 §ion_length), 669 PLDM_INVALID_TRANSFER_OPERATION_FLAG); 670 } 671 672 TEST(MultipartReceive, testDecodeRequestFailBadOffset) 673 { 674 constexpr uint8_t kPldmType = PLDM_BASE; 675 constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART; 676 constexpr uint32_t kTransferHandle = 0x01; 677 constexpr uint32_t kSectionOffset = 0x0; 678 uint8_t pldm_type; 679 uint8_t flag; 680 uint32_t transfer_ctx; 681 uint32_t transfer_handle; 682 uint32_t section_offset; 683 uint32_t section_length; 684 685 // Header values don't matter for this test. 686 pldm_msg_hdr hdr{}; 687 // Assign values to the packet struct and memcpy to ensure correct byte 688 // ordering. 689 pldm_multipart_receive_req req_pkt{}; 690 req_pkt.pldm_type = kPldmType; 691 req_pkt.transfer_opflag = kFlag; 692 req_pkt.transfer_handle = kTransferHandle; 693 req_pkt.section_offset = kSectionOffset; 694 695 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 696 std::memcpy(req.data(), &hdr, sizeof(hdr)); 697 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 698 699 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 700 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 701 &pldm_type, &flag, &transfer_ctx, 702 &transfer_handle, §ion_offset, 703 §ion_length), 704 PLDM_ERROR_INVALID_DATA); 705 } 706 707 TEST(MultipartReceive, testDecodeRequestFailBadHandle) 708 { 709 constexpr uint8_t kPldmType = PLDM_BASE; 710 constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART; 711 constexpr uint32_t kSectionOffset = 0x100; 712 constexpr uint32_t kTransferHandle = 0x0; 713 uint8_t pldm_type; 714 uint8_t flag; 715 uint32_t transfer_ctx; 716 uint32_t transfer_handle; 717 uint32_t section_offset; 718 uint32_t section_length; 719 720 // Header values don't matter for this test. 721 pldm_msg_hdr hdr{}; 722 // Assign values to the packet struct and memcpy to ensure correct byte 723 // ordering. 724 pldm_multipart_receive_req req_pkt{}; 725 req_pkt.pldm_type = kPldmType; 726 req_pkt.transfer_opflag = kFlag; 727 req_pkt.transfer_handle = kTransferHandle; 728 req_pkt.section_offset = kSectionOffset; 729 730 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 731 std::memcpy(req.data(), &hdr, sizeof(hdr)); 732 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 733 734 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 735 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 736 &pldm_type, &flag, &transfer_ctx, 737 &transfer_handle, §ion_offset, 738 §ion_length), 739 PLDM_ERROR_INVALID_DATA); 740 } 741 742 TEST(CcOnlyResponse, testEncode) 743 { 744 struct pldm_msg responseMsg; 745 746 auto rc = 747 encode_cc_only_resp(0 /*instance id*/, 1 /*pldm type*/, 2 /*command*/, 748 3 /*complection code*/, &responseMsg); 749 EXPECT_EQ(rc, PLDM_SUCCESS); 750 751 auto p = reinterpret_cast<uint8_t*>(&responseMsg); 752 EXPECT_THAT(std::vector<uint8_t>(p, p + sizeof(responseMsg)), 753 ElementsAreArray({0, 1, 2, 3})); 754 755 rc = encode_cc_only_resp(PLDM_INSTANCE_MAX + 1, 1, 2, 3, &responseMsg); 756 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 757 758 rc = encode_cc_only_resp(0, 1, 2, 3, nullptr); 759 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 760 } 761 762 TEST(SetTID, testGoodEncodeRequest) 763 { 764 uint8_t instanceId = 0; 765 uint8_t tid = 0x01; 766 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{}; 767 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 768 769 auto rc = encode_set_tid_req(instanceId, tid, request); 770 ASSERT_EQ(rc, PLDM_SUCCESS); 771 772 EXPECT_EQ(request->hdr.command, PLDM_SET_TID); 773 EXPECT_EQ(request->hdr.type, PLDM_BASE); 774 EXPECT_EQ(request->hdr.request, 1); 775 EXPECT_EQ(request->hdr.datagram, 0); 776 EXPECT_EQ(request->hdr.instance_id, instanceId); 777 EXPECT_EQ(0, memcmp(request->payload, &tid, sizeof(tid))); 778 } 779 780 TEST(SetTID, testBadEncodeRequest) 781 { 782 uint8_t tid = 0x01; 783 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{}; 784 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 785 786 auto rc = encode_set_tid_req(0, tid, nullptr); 787 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 788 789 rc = encode_set_tid_req(0, 0, request); 790 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 791 792 rc = encode_set_tid_req(0, 0xff, request); 793 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 794 } 795 796 #ifdef LIBPLDM_API_TESTING 797 TEST(PldmMsgHdr, correlateSuccess) 798 { 799 static const struct pldm_msg_hdr req = { 800 .instance_id = 0, 801 .reserved = 0, 802 .datagram = 0, 803 .request = 1, 804 .type = 0, 805 .header_ver = 1, 806 .command = 0x01, 807 }; 808 static const struct pldm_msg_hdr resp = { 809 .instance_id = 0, 810 .reserved = 0, 811 .datagram = 0, 812 .request = 0, 813 .type = 0, 814 .header_ver = 1, 815 .command = 0x01, 816 }; 817 818 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true); 819 } 820 #endif 821 822 #ifdef LIBPLDM_API_TESTING 823 TEST(PldmMsgHdr, correlateFailInstanceID) 824 { 825 static const struct pldm_msg_hdr req = { 826 .instance_id = 0, 827 .reserved = 0, 828 .datagram = 0, 829 .request = 1, 830 .type = 0, 831 .header_ver = 1, 832 .command = 0x01, 833 }; 834 static const struct pldm_msg_hdr resp = { 835 .instance_id = 1, 836 .reserved = 0, 837 .datagram = 0, 838 .request = 0, 839 .type = 0, 840 .header_ver = 1, 841 .command = 0x01, 842 }; 843 844 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 845 } 846 #endif 847 848 #ifdef LIBPLDM_API_TESTING 849 TEST(PldmMsgHdr, correlateFailRequest) 850 { 851 static const struct pldm_msg_hdr req = { 852 .instance_id = 0, 853 .reserved = 0, 854 .datagram = 0, 855 .request = 1, 856 .type = 0, 857 .header_ver = 1, 858 .command = 0x01, 859 }; 860 static const struct pldm_msg_hdr resp = { 861 .instance_id = 0, 862 .reserved = 0, 863 .datagram = 0, 864 .request = 1, 865 .type = 0, 866 .header_ver = 1, 867 .command = 0x01, 868 }; 869 870 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 871 } 872 #endif 873 874 #ifdef LIBPLDM_API_TESTING 875 TEST(PldmMsgHdr, correlateFailType) 876 { 877 static const struct pldm_msg_hdr req = { 878 .instance_id = 0, 879 .reserved = 0, 880 .datagram = 0, 881 .request = 1, 882 .type = 0, 883 .header_ver = 1, 884 .command = 0x01, 885 }; 886 static const struct pldm_msg_hdr resp = { 887 .instance_id = 0, 888 .reserved = 0, 889 .datagram = 0, 890 .request = 0, 891 .type = 1, 892 .header_ver = 1, 893 .command = 0x01, 894 }; 895 896 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 897 } 898 #endif 899 900 #ifdef LIBPLDM_API_TESTING 901 TEST(PldmMsgHdr, correlateFailCommand) 902 { 903 static const struct pldm_msg_hdr req = { 904 .instance_id = 0, 905 .reserved = 0, 906 .datagram = 0, 907 .request = 1, 908 .type = 0, 909 .header_ver = 1, 910 .command = 0x01, 911 }; 912 static const struct pldm_msg_hdr resp = { 913 .instance_id = 0, 914 .reserved = 0, 915 .datagram = 0, 916 .request = 0, 917 .type = 0, 918 .header_ver = 1, 919 .command = 0x02, 920 }; 921 922 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 923 } 924 #endif 925 926 #ifdef LIBPLDM_API_TESTING 927 TEST(PldmMsgHdr, correlateFailRequestIsResponse) 928 { 929 static const struct pldm_msg_hdr req = { 930 .instance_id = 0, 931 .reserved = 0, 932 .datagram = 0, 933 .request = 0, 934 .type = 0, 935 .header_ver = 1, 936 .command = 0x01, 937 }; 938 static const struct pldm_msg_hdr resp = { 939 .instance_id = 0, 940 .reserved = 0, 941 .datagram = 0, 942 .request = 0, 943 .type = 0, 944 .header_ver = 1, 945 .command = 0x02, 946 }; 947 948 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 949 } 950 #endif 951