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 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 204 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 205 206 auto rc = encode_get_commands_req(0, pldmType, version, request); 207 EXPECT_EQ(rc, PLDM_SUCCESS); 208 EXPECT_EQ(0, memcmp(request->payload, &pldmType, sizeof(pldmType))); 209 EXPECT_EQ(0, memcmp(request->payload + sizeof(pldmType), &version, 210 sizeof(version))); 211 } 212 213 TEST(GetPLDMCommands, testDecodeRequest) 214 { 215 uint8_t pldmType = 0x05; 216 ver32_t version{0xff, 0xff, 0xff, 0xff}; 217 uint8_t pldmTypeOut{}; 218 ver32_t versionOut{0xff, 0xff, 0xff, 0xff}; 219 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{}; 220 221 memcpy(requestMsg.data() + hdrSize, &pldmType, sizeof(pldmType)); 222 memcpy(requestMsg.data() + sizeof(pldmType) + hdrSize, &version, 223 sizeof(version)); 224 225 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 226 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 227 auto rc = decode_get_commands_req(request, requestMsg.size() - hdrSize, 228 &pldmTypeOut, &versionOut); 229 230 EXPECT_EQ(rc, PLDM_SUCCESS); 231 EXPECT_EQ(pldmTypeOut, pldmType); 232 EXPECT_EQ(0, memcmp(&versionOut, &version, sizeof(version))); 233 } 234 235 TEST(GetPLDMCommands, testEncodeResponse) 236 { 237 uint8_t completionCode = 0; 238 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES> 239 responseMsg{}; 240 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 241 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 242 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{}; 243 commands[0].byte = 1; 244 commands[1].byte = 2; 245 commands[2].byte = 3; 246 247 auto rc = 248 encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), response); 249 EXPECT_EQ(rc, PLDM_SUCCESS); 250 uint8_t* payload_ptr = response->payload; 251 EXPECT_EQ(completionCode, payload_ptr[0]); 252 EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]); 253 EXPECT_EQ(2, 254 payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte)]); 255 EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte) + 256 sizeof(commands[1].byte)]); 257 } 258 259 TEST(GetPLDMTypes, testEncodeResponse) 260 { 261 uint8_t completionCode = 0; 262 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES> 263 responseMsg{}; 264 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 265 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 266 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> types{}; 267 types[0].byte = 1; 268 types[1].byte = 2; 269 types[2].byte = 3; 270 271 auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response); 272 EXPECT_EQ(rc, PLDM_SUCCESS); 273 uint8_t* payload_ptr = response->payload; 274 EXPECT_EQ(completionCode, payload_ptr[0]); 275 EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]); 276 EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte)]); 277 EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte) + 278 sizeof(types[1].byte)]); 279 } 280 281 TEST(GetPLDMTypes, testGoodDecodeResponse) 282 { 283 std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{}; 284 responseMsg[1 + hdrSize] = 1; 285 responseMsg[2 + hdrSize] = 2; 286 responseMsg[3 + hdrSize] = 3; 287 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{}; 288 289 uint8_t completion_code; 290 responseMsg[hdrSize] = PLDM_SUCCESS; 291 292 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 293 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 294 295 auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize, 296 &completion_code, outTypes.data()); 297 298 EXPECT_EQ(rc, PLDM_SUCCESS); 299 EXPECT_EQ(completion_code, PLDM_SUCCESS); 300 EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte); 301 EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte); 302 EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte); 303 } 304 305 TEST(GetPLDMTypes, testBadDecodeResponse) 306 { 307 std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{}; 308 responseMsg[1 + hdrSize] = 1; 309 responseMsg[2 + hdrSize] = 2; 310 responseMsg[3 + hdrSize] = 3; 311 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{}; 312 313 uint8_t retcompletion_code = 0; 314 responseMsg[hdrSize] = PLDM_SUCCESS; 315 316 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 317 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 318 319 auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize - 1, 320 &retcompletion_code, outTypes.data()); 321 322 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 323 } 324 325 TEST(GetPLDMCommands, testGoodDecodeResponse) 326 { 327 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{}; 328 responseMsg[1 + hdrSize] = 1; 329 responseMsg[2 + hdrSize] = 2; 330 responseMsg[3 + hdrSize] = 3; 331 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{}; 332 333 uint8_t completion_code; 334 responseMsg[hdrSize] = PLDM_SUCCESS; 335 336 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 337 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 338 339 auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize, 340 &completion_code, outTypes.data()); 341 342 EXPECT_EQ(rc, PLDM_SUCCESS); 343 EXPECT_EQ(completion_code, PLDM_SUCCESS); 344 EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte); 345 EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte); 346 EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte); 347 } 348 349 TEST(GetPLDMCommands, testBadDecodeResponse) 350 { 351 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{}; 352 responseMsg[1 + hdrSize] = 1; 353 responseMsg[2 + hdrSize] = 2; 354 responseMsg[3 + hdrSize] = 3; 355 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{}; 356 357 uint8_t retcompletion_code = 0; 358 responseMsg[hdrSize] = PLDM_SUCCESS; 359 360 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 361 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 362 363 auto rc = 364 decode_get_commands_resp(response, responseMsg.size() - hdrSize - 1, 365 &retcompletion_code, outTypes.data()); 366 367 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 368 } 369 370 TEST(GetPLDMVersion, testGoodEncodeRequest) 371 { 372 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES> 373 requestMsg{}; 374 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 375 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 376 uint8_t pldmType = 0x03; 377 uint32_t transferHandle = 0x0; 378 uint8_t opFlag = 0x01; 379 380 auto rc = 381 encode_get_version_req(0, transferHandle, opFlag, pldmType, request); 382 EXPECT_EQ(rc, PLDM_SUCCESS); 383 EXPECT_EQ( 384 0, memcmp(request->payload, &transferHandle, sizeof(transferHandle))); 385 EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle), &opFlag, 386 sizeof(opFlag))); 387 EXPECT_EQ(0, 388 memcmp(request->payload + sizeof(transferHandle) + sizeof(opFlag), 389 &pldmType, sizeof(pldmType))); 390 } 391 392 TEST(GetPLDMVersion, testBadEncodeRequest) 393 { 394 uint8_t pldmType = 0x03; 395 uint32_t transferHandle = 0x0; 396 uint8_t opFlag = 0x01; 397 398 auto rc = 399 encode_get_version_req(0, transferHandle, opFlag, pldmType, nullptr); 400 401 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 402 } 403 404 TEST(GetPLDMVersion, testEncodeResponse) 405 { 406 uint8_t completionCode = 0; 407 uint32_t transferHandle = 0; 408 uint8_t flag = PLDM_START_AND_END; 409 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES> 410 responseMsg{}; 411 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 412 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 413 ver32_t version = {0xff, 0xff, 0xff, 0xff}; 414 415 auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END, 416 &version, sizeof(ver32_t), response); 417 418 EXPECT_EQ(rc, PLDM_SUCCESS); 419 EXPECT_EQ(completionCode, response->payload[0]); 420 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]), 421 &transferHandle, sizeof(transferHandle))); 422 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) + 423 sizeof(transferHandle), 424 &flag, sizeof(flag))); 425 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) + 426 sizeof(transferHandle) + sizeof(flag), 427 &version, sizeof(version))); 428 } 429 430 TEST(GetPLDMVersion, testDecodeRequest) 431 { 432 std::array<uint8_t, hdrSize + PLDM_GET_VERSION_REQ_BYTES> requestMsg{}; 433 uint32_t transferHandle = 0x0; 434 uint32_t retTransferHandle = 0x0; 435 uint8_t flag = PLDM_GET_FIRSTPART; 436 uint8_t retFlag = PLDM_GET_FIRSTPART; 437 uint8_t pldmType = PLDM_BASE; 438 uint8_t retType = PLDM_BASE; 439 440 memcpy(requestMsg.data() + hdrSize, &transferHandle, 441 sizeof(transferHandle)); 442 memcpy(requestMsg.data() + sizeof(transferHandle) + hdrSize, &flag, 443 sizeof(flag)); 444 memcpy(requestMsg.data() + sizeof(transferHandle) + sizeof(flag) + hdrSize, 445 &pldmType, sizeof(pldmType)); 446 447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 448 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 449 450 auto rc = decode_get_version_req(request, requestMsg.size() - hdrSize, 451 &retTransferHandle, &retFlag, &retType); 452 453 EXPECT_EQ(rc, PLDM_SUCCESS); 454 EXPECT_EQ(transferHandle, retTransferHandle); 455 EXPECT_EQ(flag, retFlag); 456 EXPECT_EQ(pldmType, retType); 457 } 458 459 TEST(GetPLDMVersion, testDecodeResponse) 460 { 461 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES> 462 responseMsg{}; 463 uint32_t transferHandle = 0x0; 464 uint32_t retTransferHandle = 0x0; 465 uint8_t flag = PLDM_START_AND_END; 466 uint8_t retFlag = PLDM_START_AND_END; 467 uint8_t completionCode = 0; 468 ver32_t version = {0xff, 0xff, 0xff, 0xff}; 469 ver32_t versionOut; 470 uint8_t completion_code; 471 472 memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize, 473 &transferHandle, sizeof(transferHandle)); 474 memcpy(responseMsg.data() + sizeof(completionCode) + 475 sizeof(transferHandle) + hdrSize, 476 &flag, sizeof(flag)); 477 memcpy(responseMsg.data() + sizeof(completionCode) + 478 sizeof(transferHandle) + sizeof(flag) + hdrSize, 479 &version, sizeof(version)); 480 481 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 482 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 483 484 auto rc = decode_get_version_resp(response, responseMsg.size() - hdrSize, 485 &completion_code, &retTransferHandle, 486 &retFlag, &versionOut); 487 EXPECT_EQ(rc, PLDM_SUCCESS); 488 EXPECT_EQ(transferHandle, retTransferHandle); 489 EXPECT_EQ(flag, retFlag); 490 491 EXPECT_EQ(versionOut.major, version.major); 492 EXPECT_EQ(versionOut.minor, version.minor); 493 EXPECT_EQ(versionOut.update, version.update); 494 EXPECT_EQ(versionOut.alpha, version.alpha); 495 } 496 497 TEST(GetTID, testEncodeRequest) 498 { 499 pldm_msg request{}; 500 501 auto rc = encode_get_tid_req(0, &request); 502 ASSERT_EQ(rc, PLDM_SUCCESS); 503 } 504 505 TEST(GetTID, testEncodeResponse) 506 { 507 uint8_t completionCode = 0; 508 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES> 509 responseMsg{}; 510 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 511 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 512 uint8_t tid = 1; 513 514 auto rc = encode_get_tid_resp(0, PLDM_SUCCESS, tid, response); 515 EXPECT_EQ(rc, PLDM_SUCCESS); 516 uint8_t* payload = response->payload; 517 EXPECT_EQ(completionCode, payload[0]); 518 EXPECT_EQ(1, payload[sizeof(completionCode)]); 519 } 520 521 TEST(GetTID, testDecodeResponse) 522 { 523 std::array<uint8_t, hdrSize + PLDM_GET_TID_RESP_BYTES> responseMsg{}; 524 responseMsg[1 + hdrSize] = 1; 525 526 uint8_t tid; 527 uint8_t completion_code; 528 responseMsg[hdrSize] = PLDM_SUCCESS; 529 530 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 531 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 532 533 auto rc = decode_get_tid_resp(response, responseMsg.size() - hdrSize, 534 &completion_code, &tid); 535 536 EXPECT_EQ(rc, PLDM_SUCCESS); 537 EXPECT_EQ(completion_code, PLDM_SUCCESS); 538 EXPECT_EQ(tid, 1); 539 } 540 541 TEST(MultipartReceive, testDecodeRequestPass) 542 { 543 constexpr uint8_t kPldmType = PLDM_BASE; 544 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART; 545 constexpr uint32_t kTransferCtx = 0x01; 546 constexpr uint32_t kTransferHandle = 0x10; 547 constexpr uint32_t kSectionOffset = 0x0; 548 constexpr uint32_t kSectionLength = 0x10; 549 uint8_t pldm_type = 0x0; 550 uint8_t flag = PLDM_GET_FIRSTPART; 551 uint32_t transfer_ctx; 552 uint32_t transfer_handle; 553 uint32_t section_offset; 554 uint32_t section_length; 555 556 // Header values don't matter for this test. 557 pldm_msg_hdr hdr{}; 558 // Assign values to the packet struct and memcpy to ensure correct byte 559 // ordering. 560 pldm_multipart_receive_req req_pkt = { 561 .pldm_type = kPldmType, 562 .transfer_opflag = kFlag, 563 .transfer_ctx = kTransferCtx, 564 .transfer_handle = kTransferHandle, 565 .section_offset = kSectionOffset, 566 .section_length = kSectionLength, 567 }; 568 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 569 std::memcpy(req.data(), &hdr, sizeof(hdr)); 570 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 571 572 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 573 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 574 int rc = decode_multipart_receive_req( 575 pldm_request, req.size() - hdrSize, &pldm_type, &flag, &transfer_ctx, 576 &transfer_handle, §ion_offset, §ion_length); 577 578 EXPECT_EQ(rc, PLDM_SUCCESS); 579 EXPECT_EQ(pldm_type, kPldmType); 580 EXPECT_EQ(flag, kFlag); 581 EXPECT_EQ(transfer_ctx, kTransferCtx); 582 EXPECT_EQ(transfer_handle, kTransferHandle); 583 EXPECT_EQ(section_offset, kSectionOffset); 584 EXPECT_EQ(section_length, kSectionLength); 585 } 586 587 TEST(MultipartReceive, testDecodeRequestFailNullData) 588 { 589 EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL, 590 NULL, NULL), 591 PLDM_ERROR_INVALID_DATA); 592 } 593 594 TEST(MultipartReceive, testDecodeRequestFailBadLength) 595 { 596 constexpr uint8_t kPldmType = PLDM_BASE; 597 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART; 598 uint8_t pldm_type; 599 uint8_t flag; 600 uint32_t transfer_ctx; 601 uint32_t transfer_handle; 602 uint32_t section_offset; 603 uint32_t section_length; 604 605 // Header values don't matter for this test. 606 pldm_msg_hdr hdr{}; 607 // Assign values to the packet struct and memcpy to ensure correct byte 608 // ordering. 609 pldm_multipart_receive_req req_pkt{}; 610 req_pkt.pldm_type = kPldmType; 611 req_pkt.transfer_opflag = kFlag; 612 613 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 614 std::memcpy(req.data(), &hdr, sizeof(hdr)); 615 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 616 617 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 618 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 619 EXPECT_EQ(decode_multipart_receive_req( 620 pldm_request, (req.size() - hdrSize) + 1, &pldm_type, &flag, 621 &transfer_ctx, &transfer_handle, §ion_offset, 622 §ion_length), 623 PLDM_ERROR_INVALID_LENGTH); 624 } 625 626 TEST(MultipartReceive, testDecodeRequestFailBadPldmType) 627 { 628 constexpr uint8_t kPldmType = 0xff; 629 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART; 630 uint8_t pldm_type; 631 uint8_t flag; 632 uint32_t transfer_ctx; 633 uint32_t transfer_handle; 634 uint32_t section_offset; 635 uint32_t section_length; 636 637 // Header values don't matter for this test. 638 pldm_msg_hdr hdr{}; 639 // Assign values to the packet struct and memcpy to ensure correct byte 640 // ordering. 641 pldm_multipart_receive_req req_pkt{}; 642 req_pkt.pldm_type = kPldmType; 643 req_pkt.transfer_opflag = kFlag; 644 645 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 646 std::memcpy(req.data(), &hdr, sizeof(hdr)); 647 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 648 649 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 650 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 651 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 652 &pldm_type, &flag, &transfer_ctx, 653 &transfer_handle, §ion_offset, 654 §ion_length), 655 PLDM_ERROR_INVALID_PLDM_TYPE); 656 } 657 658 TEST(MultipartReceive, testDecodeRequestFailBadTransferFlag) 659 { 660 constexpr uint8_t kPldmType = PLDM_BASE; 661 constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10; 662 uint8_t pldm_type; 663 uint8_t flag; 664 uint32_t transfer_ctx; 665 uint32_t transfer_handle; 666 uint32_t section_offset; 667 uint32_t section_length; 668 669 // Header values don't matter for this test. 670 pldm_msg_hdr hdr{}; 671 // Assign values to the packet struct and memcpy to ensure correct byte 672 // ordering. 673 pldm_multipart_receive_req req_pkt{}; 674 req_pkt.pldm_type = kPldmType; 675 req_pkt.transfer_opflag = kFlag; 676 677 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 678 std::memcpy(req.data(), &hdr, sizeof(hdr)); 679 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 680 681 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 682 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 683 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 684 &pldm_type, &flag, &transfer_ctx, 685 &transfer_handle, §ion_offset, 686 §ion_length), 687 PLDM_INVALID_TRANSFER_OPERATION_FLAG); 688 } 689 690 TEST(MultipartReceive, testDecodeRequestFailBadOffset) 691 { 692 constexpr uint8_t kPldmType = PLDM_BASE; 693 constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART; 694 constexpr uint32_t kTransferHandle = 0x01; 695 constexpr uint32_t kSectionOffset = 0x0; 696 uint8_t pldm_type; 697 uint8_t flag; 698 uint32_t transfer_ctx; 699 uint32_t transfer_handle; 700 uint32_t section_offset; 701 uint32_t section_length; 702 703 // Header values don't matter for this test. 704 pldm_msg_hdr hdr{}; 705 // Assign values to the packet struct and memcpy to ensure correct byte 706 // ordering. 707 pldm_multipart_receive_req req_pkt{}; 708 req_pkt.pldm_type = kPldmType; 709 req_pkt.transfer_opflag = kFlag; 710 req_pkt.transfer_handle = kTransferHandle; 711 req_pkt.section_offset = kSectionOffset; 712 713 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 714 std::memcpy(req.data(), &hdr, sizeof(hdr)); 715 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 716 717 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 718 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 719 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 720 &pldm_type, &flag, &transfer_ctx, 721 &transfer_handle, §ion_offset, 722 §ion_length), 723 PLDM_ERROR_INVALID_DATA); 724 } 725 726 TEST(MultipartReceive, testDecodeRequestFailBadHandle) 727 { 728 constexpr uint8_t kPldmType = PLDM_BASE; 729 constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART; 730 constexpr uint32_t kSectionOffset = 0x100; 731 constexpr uint32_t kTransferHandle = 0x0; 732 uint8_t pldm_type; 733 uint8_t flag; 734 uint32_t transfer_ctx; 735 uint32_t transfer_handle; 736 uint32_t section_offset; 737 uint32_t section_length; 738 739 // Header values don't matter for this test. 740 pldm_msg_hdr hdr{}; 741 // Assign values to the packet struct and memcpy to ensure correct byte 742 // ordering. 743 pldm_multipart_receive_req req_pkt{}; 744 req_pkt.pldm_type = kPldmType; 745 req_pkt.transfer_opflag = kFlag; 746 req_pkt.transfer_handle = kTransferHandle; 747 req_pkt.section_offset = kSectionOffset; 748 749 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES); 750 std::memcpy(req.data(), &hdr, sizeof(hdr)); 751 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt)); 752 753 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 754 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data()); 755 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize, 756 &pldm_type, &flag, &transfer_ctx, 757 &transfer_handle, §ion_offset, 758 §ion_length), 759 PLDM_ERROR_INVALID_DATA); 760 } 761 762 TEST(CcOnlyResponse, testEncode) 763 { 764 struct pldm_msg responseMsg; 765 766 auto rc = 767 encode_cc_only_resp(0 /*instance id*/, 1 /*pldm type*/, 2 /*command*/, 768 3 /*completion code*/, &responseMsg); 769 EXPECT_EQ(rc, PLDM_SUCCESS); 770 771 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 772 auto p = reinterpret_cast<uint8_t*>(&responseMsg); 773 EXPECT_THAT(std::vector<uint8_t>(p, p + sizeof(responseMsg)), 774 ElementsAreArray({0, 1, 2, 3})); 775 776 rc = encode_cc_only_resp(PLDM_INSTANCE_MAX + 1, 1, 2, 3, &responseMsg); 777 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 778 779 rc = encode_cc_only_resp(0, 1, 2, 3, nullptr); 780 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 781 } 782 783 TEST(SetTID, testGoodEncodeRequest) 784 { 785 uint8_t instanceId = 0; 786 uint8_t tid = 0x01; 787 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{}; 788 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 789 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 790 791 auto rc = encode_set_tid_req(instanceId, tid, request); 792 ASSERT_EQ(rc, PLDM_SUCCESS); 793 794 EXPECT_EQ(request->hdr.command, PLDM_SET_TID); 795 EXPECT_EQ(request->hdr.type, PLDM_BASE); 796 EXPECT_EQ(request->hdr.request, 1); 797 EXPECT_EQ(request->hdr.datagram, 0); 798 EXPECT_EQ(request->hdr.instance_id, instanceId); 799 EXPECT_EQ(0, memcmp(request->payload, &tid, sizeof(tid))); 800 } 801 802 TEST(SetTID, testBadEncodeRequest) 803 { 804 uint8_t tid = 0x01; 805 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{}; 806 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 807 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 808 809 auto rc = encode_set_tid_req(0, tid, nullptr); 810 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 811 812 rc = encode_set_tid_req(0, 0, request); 813 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 814 815 rc = encode_set_tid_req(0, 0xff, request); 816 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 817 } 818 819 #ifdef LIBPLDM_API_TESTING 820 TEST(PldmMsgHdr, correlateSuccess) 821 { 822 static const struct pldm_msg_hdr req = { 823 .instance_id = 0, 824 .reserved = 0, 825 .datagram = 0, 826 .request = 1, 827 .type = 0, 828 .header_ver = 1, 829 .command = 0x01, 830 }; 831 static const struct pldm_msg_hdr resp = { 832 .instance_id = 0, 833 .reserved = 0, 834 .datagram = 0, 835 .request = 0, 836 .type = 0, 837 .header_ver = 1, 838 .command = 0x01, 839 }; 840 841 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true); 842 } 843 #endif 844 845 #ifdef LIBPLDM_API_TESTING 846 TEST(PldmMsgHdr, correlateFailInstanceID) 847 { 848 static const struct pldm_msg_hdr req = { 849 .instance_id = 0, 850 .reserved = 0, 851 .datagram = 0, 852 .request = 1, 853 .type = 0, 854 .header_ver = 1, 855 .command = 0x01, 856 }; 857 static const struct pldm_msg_hdr resp = { 858 .instance_id = 1, 859 .reserved = 0, 860 .datagram = 0, 861 .request = 0, 862 .type = 0, 863 .header_ver = 1, 864 .command = 0x01, 865 }; 866 867 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 868 } 869 #endif 870 871 #ifdef LIBPLDM_API_TESTING 872 TEST(PldmMsgHdr, correlateFailRequest) 873 { 874 static const struct pldm_msg_hdr req = { 875 .instance_id = 0, 876 .reserved = 0, 877 .datagram = 0, 878 .request = 1, 879 .type = 0, 880 .header_ver = 1, 881 .command = 0x01, 882 }; 883 static const struct pldm_msg_hdr resp = { 884 .instance_id = 0, 885 .reserved = 0, 886 .datagram = 0, 887 .request = 1, 888 .type = 0, 889 .header_ver = 1, 890 .command = 0x01, 891 }; 892 893 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 894 } 895 #endif 896 897 #ifdef LIBPLDM_API_TESTING 898 TEST(PldmMsgHdr, correlateFailType) 899 { 900 static const struct pldm_msg_hdr req = { 901 .instance_id = 0, 902 .reserved = 0, 903 .datagram = 0, 904 .request = 1, 905 .type = 0, 906 .header_ver = 1, 907 .command = 0x01, 908 }; 909 static const struct pldm_msg_hdr resp = { 910 .instance_id = 0, 911 .reserved = 0, 912 .datagram = 0, 913 .request = 0, 914 .type = 1, 915 .header_ver = 1, 916 .command = 0x01, 917 }; 918 919 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 920 } 921 #endif 922 923 #ifdef LIBPLDM_API_TESTING 924 TEST(PldmMsgHdr, correlateFailCommand) 925 { 926 static const struct pldm_msg_hdr req = { 927 .instance_id = 0, 928 .reserved = 0, 929 .datagram = 0, 930 .request = 1, 931 .type = 0, 932 .header_ver = 1, 933 .command = 0x01, 934 }; 935 static const struct pldm_msg_hdr resp = { 936 .instance_id = 0, 937 .reserved = 0, 938 .datagram = 0, 939 .request = 0, 940 .type = 0, 941 .header_ver = 1, 942 .command = 0x02, 943 }; 944 945 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 946 } 947 #endif 948 949 #ifdef LIBPLDM_API_TESTING 950 TEST(PldmMsgHdr, correlateFailRequestIsResponse) 951 { 952 static const struct pldm_msg_hdr req = { 953 .instance_id = 0, 954 .reserved = 0, 955 .datagram = 0, 956 .request = 0, 957 .type = 0, 958 .header_ver = 1, 959 .command = 0x01, 960 }; 961 static const struct pldm_msg_hdr resp = { 962 .instance_id = 0, 963 .reserved = 0, 964 .datagram = 0, 965 .request = 0, 966 .type = 0, 967 .header_ver = 1, 968 .command = 0x02, 969 }; 970 971 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false); 972 } 973 #endif 974