1 #include "config.h" 2 3 #include "file_io.hpp" 4 5 #include "libpldm/base.h" 6 7 #include "common/utils.hpp" 8 #include "file_io_by_type.hpp" 9 #include "file_table.hpp" 10 #include "xyz/openbmc_project/Common/error.hpp" 11 12 #include <fcntl.h> 13 #include <sys/mman.h> 14 #include <sys/stat.h> 15 #include <sys/types.h> 16 #include <unistd.h> 17 18 #include <cstring> 19 #include <fstream> 20 #include <iostream> 21 #include <memory> 22 23 namespace pldm 24 { 25 26 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 27 28 namespace responder 29 { 30 31 namespace fs = std::filesystem; 32 33 namespace dma 34 { 35 36 /** @struct AspeedXdmaOp 37 * 38 * Structure representing XDMA operation 39 */ 40 struct AspeedXdmaOp 41 { 42 uint64_t hostAddr; //!< the DMA address on the host side, configured by 43 //!< PCI subsystem. 44 uint32_t len; //!< the size of the transfer in bytes, it should be a 45 //!< multiple of 16 bytes 46 uint32_t upstream; //!< boolean indicating the direction of the DMA 47 //!< operation, true means a transfer from BMC to host. 48 }; 49 50 constexpr auto xdmaDev = "/dev/aspeed-xdma"; 51 52 int DMA::transferDataHost(int fd, uint32_t offset, uint32_t length, 53 uint64_t address, bool upstream) 54 { 55 static const size_t pageSize = getpagesize(); 56 uint32_t numPages = length / pageSize; 57 uint32_t pageAlignedLength = numPages * pageSize; 58 59 if (length > pageAlignedLength) 60 { 61 pageAlignedLength += pageSize; 62 } 63 64 auto mmapCleanup = [pageAlignedLength](void* vgaMem) { 65 munmap(vgaMem, pageAlignedLength); 66 }; 67 68 int dmaFd = -1; 69 int rc = 0; 70 dmaFd = open(xdmaDev, O_RDWR); 71 if (dmaFd < 0) 72 { 73 rc = -errno; 74 std::cerr << "Failed to open the XDMA device, RC=" << rc << "\n"; 75 return rc; 76 } 77 78 pldm::utils::CustomFD xdmaFd(dmaFd); 79 80 void* vgaMem; 81 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ, 82 MAP_SHARED, xdmaFd(), 0); 83 if (MAP_FAILED == vgaMem) 84 { 85 rc = -errno; 86 std::cerr << "Failed to mmap the XDMA device, RC=" << rc << "\n"; 87 return rc; 88 } 89 90 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup); 91 92 if (upstream) 93 { 94 rc = lseek(fd, offset, SEEK_SET); 95 if (rc == -1) 96 { 97 std::cerr << "lseek failed, ERROR=" << errno 98 << ", UPSTREAM=" << upstream << ", OFFSET=" << offset 99 << "\n"; 100 return rc; 101 } 102 103 // Writing to the VGA memory should be aligned at page boundary, 104 // otherwise write data into a buffer aligned at page boundary and 105 // then write to the VGA memory. 106 std::vector<char> buffer{}; 107 buffer.resize(pageAlignedLength); 108 rc = read(fd, buffer.data(), length); 109 if (rc == -1) 110 { 111 std::cerr << "file read failed, ERROR=" << errno 112 << ", UPSTREAM=" << upstream << ", LENGTH=" << length 113 << ", OFFSET=" << offset << "\n"; 114 return rc; 115 } 116 if (rc != static_cast<int>(length)) 117 { 118 std::cerr << "mismatch between number of characters to read and " 119 << "the length read, LENGTH=" << length << " COUNT=" << rc 120 << "\n"; 121 return -1; 122 } 123 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(), 124 pageAlignedLength); 125 } 126 127 AspeedXdmaOp xdmaOp; 128 xdmaOp.upstream = upstream ? 1 : 0; 129 xdmaOp.hostAddr = address; 130 xdmaOp.len = length; 131 132 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp)); 133 if (rc < 0) 134 { 135 rc = -errno; 136 std::cerr << "Failed to execute the DMA operation, RC=" << rc 137 << " UPSTREAM=" << upstream << " ADDRESS=" << address 138 << " LENGTH=" << length << "\n"; 139 return rc; 140 } 141 142 if (!upstream) 143 { 144 rc = lseek(fd, offset, SEEK_SET); 145 if (rc == -1) 146 { 147 std::cerr << "lseek failed, ERROR=" << errno 148 << ", UPSTREAM=" << upstream << ", OFFSET=" << offset 149 << "\n"; 150 return rc; 151 } 152 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length); 153 if (rc == -1) 154 { 155 std::cerr << "file write failed, ERROR=" << errno 156 << ", UPSTREAM=" << upstream << ", LENGTH=" << length 157 << ", OFFSET=" << offset << "\n"; 158 return rc; 159 } 160 } 161 162 return 0; 163 } 164 165 } // namespace dma 166 167 namespace oem_ibm 168 { 169 170 Response Handler::readFileIntoMemory(const pldm_msg* request, 171 size_t payloadLength) 172 { 173 uint32_t fileHandle = 0; 174 uint32_t offset = 0; 175 uint32_t length = 0; 176 uint64_t address = 0; 177 178 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0); 179 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 180 181 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES) 182 { 183 encode_rw_file_memory_resp(request->hdr.instance_id, 184 PLDM_READ_FILE_INTO_MEMORY, 185 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr); 186 return response; 187 } 188 189 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset, 190 &length, &address); 191 192 using namespace pldm::filetable; 193 auto& table = buildFileTable(FILE_TABLE_JSON); 194 FileEntry value{}; 195 196 try 197 { 198 value = table.at(fileHandle); 199 } 200 catch (std::exception& e) 201 { 202 std::cerr << "File handle does not exist in the file table, HANDLE=" 203 << fileHandle << "\n"; 204 encode_rw_file_memory_resp(request->hdr.instance_id, 205 PLDM_READ_FILE_INTO_MEMORY, 206 PLDM_INVALID_FILE_HANDLE, 0, responsePtr); 207 return response; 208 } 209 210 if (!fs::exists(value.fsPath)) 211 { 212 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n"; 213 encode_rw_file_memory_resp(request->hdr.instance_id, 214 PLDM_READ_FILE_INTO_MEMORY, 215 PLDM_INVALID_FILE_HANDLE, 0, responsePtr); 216 return response; 217 } 218 219 auto fileSize = fs::file_size(value.fsPath); 220 if (offset >= fileSize) 221 { 222 std::cerr << "Offset exceeds file size, OFFSET=" << offset 223 << " FILE_SIZE=" << fileSize << "\n"; 224 encode_rw_file_memory_resp(request->hdr.instance_id, 225 PLDM_READ_FILE_INTO_MEMORY, 226 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr); 227 return response; 228 } 229 230 if (offset + length > fileSize) 231 { 232 length = fileSize - offset; 233 } 234 235 if (length % dma::minSize) 236 { 237 std::cerr << "Read length is not a multiple of DMA minSize, LENGTH=" 238 << length << "\n"; 239 encode_rw_file_memory_resp(request->hdr.instance_id, 240 PLDM_READ_FILE_INTO_MEMORY, 241 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr); 242 return response; 243 } 244 245 using namespace dma; 246 DMA intf; 247 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath, 248 offset, length, address, true, 249 request->hdr.instance_id); 250 } 251 252 Response Handler::writeFileFromMemory(const pldm_msg* request, 253 size_t payloadLength) 254 { 255 uint32_t fileHandle = 0; 256 uint32_t offset = 0; 257 uint32_t length = 0; 258 uint64_t address = 0; 259 260 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0); 261 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 262 263 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES) 264 { 265 encode_rw_file_memory_resp(request->hdr.instance_id, 266 PLDM_WRITE_FILE_FROM_MEMORY, 267 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr); 268 return response; 269 } 270 271 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset, 272 &length, &address); 273 274 if (length % dma::minSize) 275 { 276 std::cerr << "Write length is not a multiple of DMA minSize, LENGTH=" 277 << length << "\n"; 278 encode_rw_file_memory_resp(request->hdr.instance_id, 279 PLDM_WRITE_FILE_FROM_MEMORY, 280 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr); 281 return response; 282 } 283 284 using namespace pldm::filetable; 285 auto& table = buildFileTable(FILE_TABLE_JSON); 286 FileEntry value{}; 287 288 try 289 { 290 value = table.at(fileHandle); 291 } 292 catch (std::exception& e) 293 { 294 std::cerr << "File handle does not exist in the file table, HANDLE=" 295 << fileHandle << "\n"; 296 encode_rw_file_memory_resp(request->hdr.instance_id, 297 PLDM_WRITE_FILE_FROM_MEMORY, 298 PLDM_INVALID_FILE_HANDLE, 0, responsePtr); 299 return response; 300 } 301 302 if (!fs::exists(value.fsPath)) 303 { 304 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n"; 305 encode_rw_file_memory_resp(request->hdr.instance_id, 306 PLDM_WRITE_FILE_FROM_MEMORY, 307 PLDM_INVALID_FILE_HANDLE, 0, responsePtr); 308 return response; 309 } 310 311 auto fileSize = fs::file_size(value.fsPath); 312 if (offset >= fileSize) 313 { 314 std::cerr << "Offset exceeds file size, OFFSET=" << offset 315 << " FILE_SIZE=" << fileSize << "\n"; 316 encode_rw_file_memory_resp(request->hdr.instance_id, 317 PLDM_WRITE_FILE_FROM_MEMORY, 318 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr); 319 return response; 320 } 321 322 using namespace dma; 323 DMA intf; 324 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath, 325 offset, length, address, false, 326 request->hdr.instance_id); 327 } 328 329 Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength) 330 { 331 uint32_t transferHandle = 0; 332 uint8_t transferFlag = 0; 333 uint8_t tableType = 0; 334 335 Response response(sizeof(pldm_msg_hdr) + 336 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES); 337 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 338 339 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES) 340 { 341 encode_get_file_table_resp(request->hdr.instance_id, 342 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0, 343 responsePtr); 344 return response; 345 } 346 347 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle, 348 &transferFlag, &tableType); 349 if (rc) 350 { 351 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr, 352 0, responsePtr); 353 return response; 354 } 355 356 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE) 357 { 358 encode_get_file_table_resp(request->hdr.instance_id, 359 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr, 360 0, responsePtr); 361 return response; 362 } 363 364 using namespace pldm::filetable; 365 auto table = buildFileTable(FILE_TABLE_JSON); 366 auto attrTable = table(); 367 response.resize(response.size() + attrTable.size()); 368 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 369 370 if (attrTable.empty()) 371 { 372 encode_get_file_table_resp(request->hdr.instance_id, 373 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr, 374 0, responsePtr); 375 return response; 376 } 377 378 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0, 379 PLDM_START_AND_END, attrTable.data(), 380 attrTable.size(), responsePtr); 381 return response; 382 } 383 384 Response Handler::readFile(const pldm_msg* request, size_t payloadLength) 385 { 386 uint32_t fileHandle = 0; 387 uint32_t offset = 0; 388 uint32_t length = 0; 389 390 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES); 391 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 392 393 if (payloadLength != PLDM_READ_FILE_REQ_BYTES) 394 { 395 encode_read_file_resp(request->hdr.instance_id, 396 PLDM_ERROR_INVALID_LENGTH, length, responsePtr); 397 return response; 398 } 399 400 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset, 401 &length); 402 403 if (rc) 404 { 405 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr); 406 return response; 407 } 408 409 using namespace pldm::filetable; 410 auto& table = buildFileTable(FILE_TABLE_JSON); 411 FileEntry value{}; 412 413 try 414 { 415 value = table.at(fileHandle); 416 } 417 catch (std::exception& e) 418 { 419 std::cerr << "File handle does not exist in the file table, HANDLE=" 420 << fileHandle << "\n"; 421 encode_read_file_resp(request->hdr.instance_id, 422 PLDM_INVALID_FILE_HANDLE, length, responsePtr); 423 return response; 424 } 425 426 if (!fs::exists(value.fsPath)) 427 { 428 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n"; 429 encode_read_file_resp(request->hdr.instance_id, 430 PLDM_INVALID_FILE_HANDLE, length, responsePtr); 431 return response; 432 } 433 434 auto fileSize = fs::file_size(value.fsPath); 435 if (offset >= fileSize) 436 { 437 std::cerr << "Offset exceeds file size, OFFSET=" << offset 438 << " FILE_SIZE=" << fileSize << "\n"; 439 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE, 440 length, responsePtr); 441 return response; 442 } 443 444 if (offset + length > fileSize) 445 { 446 length = fileSize - offset; 447 } 448 449 response.resize(response.size() + length); 450 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 451 auto fileDataPos = reinterpret_cast<char*>(responsePtr); 452 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length); 453 454 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary); 455 stream.seekg(offset); 456 stream.read(fileDataPos, length); 457 458 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length, 459 responsePtr); 460 461 return response; 462 } 463 464 Response Handler::writeFile(const pldm_msg* request, size_t payloadLength) 465 { 466 uint32_t fileHandle = 0; 467 uint32_t offset = 0; 468 uint32_t length = 0; 469 size_t fileDataOffset = 0; 470 471 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES); 472 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 473 474 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES) 475 { 476 encode_write_file_resp(request->hdr.instance_id, 477 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr); 478 return response; 479 } 480 481 auto rc = decode_write_file_req(request, payloadLength, &fileHandle, 482 &offset, &length, &fileDataOffset); 483 484 if (rc) 485 { 486 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr); 487 return response; 488 } 489 490 using namespace pldm::filetable; 491 auto& table = buildFileTable(FILE_TABLE_JSON); 492 FileEntry value{}; 493 494 try 495 { 496 value = table.at(fileHandle); 497 } 498 catch (std::exception& e) 499 { 500 std::cerr << "File handle does not exist in the file table, HANDLE=" 501 << fileHandle << "\n"; 502 encode_write_file_resp(request->hdr.instance_id, 503 PLDM_INVALID_FILE_HANDLE, 0, responsePtr); 504 return response; 505 } 506 507 if (!fs::exists(value.fsPath)) 508 { 509 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n"; 510 encode_write_file_resp(request->hdr.instance_id, 511 PLDM_INVALID_FILE_HANDLE, 0, responsePtr); 512 return response; 513 } 514 515 auto fileSize = fs::file_size(value.fsPath); 516 if (offset >= fileSize) 517 { 518 std::cerr << "Offset exceeds file size, OFFSET=" << offset 519 << " FILE_SIZE=" << fileSize << "\n"; 520 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE, 521 0, responsePtr); 522 return response; 523 } 524 525 auto fileDataPos = 526 reinterpret_cast<const char*>(request->payload) + fileDataOffset; 527 528 std::ofstream stream(value.fsPath, 529 std::ios::in | std::ios::out | std::ios::binary); 530 stream.seekp(offset); 531 stream.write(fileDataPos, length); 532 533 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length, 534 responsePtr); 535 536 return response; 537 } 538 539 Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request, 540 size_t payloadLength) 541 { 542 Response response( 543 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0); 544 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 545 546 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES) 547 { 548 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, 549 PLDM_ERROR_INVALID_LENGTH, 0, 550 responsePtr); 551 return response; 552 } 553 554 uint16_t fileType{}; 555 uint32_t fileHandle{}; 556 uint32_t offset{}; 557 uint32_t length{}; 558 uint64_t address{}; 559 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength, 560 &fileType, &fileHandle, &offset, 561 &length, &address); 562 if (rc != PLDM_SUCCESS) 563 { 564 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0, 565 responsePtr); 566 return response; 567 } 568 if (length % dma::minSize) 569 { 570 std::cerr << "Length is not a multiple of DMA minSize, LENGTH=" 571 << length << "\n"; 572 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, 573 PLDM_ERROR_INVALID_LENGTH, 0, 574 responsePtr); 575 return response; 576 } 577 578 std::unique_ptr<FileHandler> handler{}; 579 try 580 { 581 handler = getHandlerByType(fileType, fileHandle); 582 } 583 catch (const InternalFailure& e) 584 { 585 std::cerr << "unknown file type, TYPE=" << fileType << "\n"; 586 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, 587 PLDM_INVALID_FILE_TYPE, 0, 588 responsePtr); 589 return response; 590 } 591 592 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY 593 ? handler->writeFromMemory(offset, length, address) 594 : handler->readIntoMemory(offset, length, address); 595 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 596 length, responsePtr); 597 return response; 598 } 599 600 Response Handler::writeFileByTypeFromMemory(const pldm_msg* request, 601 size_t payloadLength) 602 { 603 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request, 604 payloadLength); 605 } 606 607 Response Handler::readFileByTypeIntoMemory(const pldm_msg* request, 608 size_t payloadLength) 609 { 610 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request, 611 payloadLength); 612 } 613 614 Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength) 615 { 616 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES); 617 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 618 619 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES) 620 { 621 encode_rw_file_by_type_resp(request->hdr.instance_id, 622 PLDM_WRITE_FILE_BY_TYPE, 623 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr); 624 return response; 625 } 626 uint16_t fileType{}; 627 uint32_t fileHandle{}; 628 uint32_t offset{}; 629 uint32_t length{}; 630 631 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType, 632 &fileHandle, &offset, &length); 633 if (rc != PLDM_SUCCESS) 634 { 635 encode_rw_file_by_type_resp(request->hdr.instance_id, 636 PLDM_WRITE_FILE_BY_TYPE, rc, 0, 637 responsePtr); 638 return response; 639 } 640 641 std::unique_ptr<FileHandler> handler{}; 642 try 643 { 644 handler = getHandlerByType(fileType, fileHandle); 645 } 646 catch (const InternalFailure& e) 647 { 648 std::cerr << "unknown file type, TYPE=" << fileType << "\n"; 649 encode_rw_file_by_type_resp(request->hdr.instance_id, 650 PLDM_WRITE_FILE_BY_TYPE, 651 PLDM_INVALID_FILE_TYPE, 0, responsePtr); 652 return response; 653 } 654 655 rc = handler->write(reinterpret_cast<const char*>( 656 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES), 657 offset, length); 658 encode_rw_file_by_type_resp(request->hdr.instance_id, 659 PLDM_WRITE_FILE_BY_TYPE, rc, length, 660 responsePtr); 661 return response; 662 } 663 664 Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength) 665 { 666 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES); 667 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 668 669 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES) 670 { 671 encode_rw_file_by_type_resp(request->hdr.instance_id, 672 PLDM_READ_FILE_BY_TYPE, 673 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr); 674 return response; 675 } 676 uint16_t fileType{}; 677 uint32_t fileHandle{}; 678 uint32_t offset{}; 679 uint32_t length{}; 680 681 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType, 682 &fileHandle, &offset, &length); 683 if (rc != PLDM_SUCCESS) 684 { 685 encode_rw_file_by_type_resp(request->hdr.instance_id, 686 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr); 687 return response; 688 } 689 690 std::unique_ptr<FileHandler> handler{}; 691 try 692 { 693 handler = getHandlerByType(fileType, fileHandle); 694 } 695 catch (const InternalFailure& e) 696 { 697 std::cerr << "unknown file type, TYPE=" << fileType << "\n"; 698 encode_rw_file_by_type_resp(request->hdr.instance_id, 699 PLDM_READ_FILE_BY_TYPE, 700 PLDM_INVALID_FILE_TYPE, 0, responsePtr); 701 return response; 702 } 703 704 rc = handler->read(offset, length, response); 705 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 706 encode_rw_file_by_type_resp(request->hdr.instance_id, 707 PLDM_READ_FILE_BY_TYPE, rc, length, 708 responsePtr); 709 return response; 710 } 711 712 Response Handler::fileAck(const pldm_msg* request, size_t payloadLength) 713 { 714 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES); 715 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 716 717 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES) 718 { 719 encode_file_ack_resp(request->hdr.instance_id, 720 PLDM_ERROR_INVALID_LENGTH, responsePtr); 721 return response; 722 } 723 uint16_t fileType{}; 724 uint32_t fileHandle{}; 725 uint8_t fileStatus{}; 726 727 auto rc = decode_file_ack_req(request, payloadLength, &fileType, 728 &fileHandle, &fileStatus); 729 if (rc != PLDM_SUCCESS) 730 { 731 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr); 732 return response; 733 } 734 735 std::unique_ptr<FileHandler> handler{}; 736 try 737 { 738 handler = getHandlerByType(fileType, fileHandle); 739 } 740 741 catch (const InternalFailure& e) 742 { 743 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE, 744 responsePtr); 745 return response; 746 } 747 748 rc = handler->fileAck(fileStatus); 749 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr); 750 return response; 751 } 752 753 Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength) 754 { 755 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES); 756 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 757 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES) 758 { 759 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 760 } 761 762 uint8_t versionId{}; 763 764 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId); 765 if (rc != PLDM_SUCCESS) 766 { 767 return CmdHandler::ccOnlyResponse(request, rc); 768 } 769 770 if (versionId != 0) 771 { 772 return CmdHandler::ccOnlyResponse(request, 773 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION); 774 } 775 776 constexpr uint32_t rackEntry = 0xFF000030; 777 constexpr uint32_t priCecNode = 0x00008030; 778 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS, 779 rackEntry, priCecNode, responsePtr, 780 PLDM_GET_ALERT_STATUS_RESP_BYTES); 781 if (rc != PLDM_SUCCESS) 782 { 783 return CmdHandler::ccOnlyResponse(request, rc); 784 } 785 786 return response; 787 } 788 789 Response Handler::newFileAvailable(const pldm_msg* request, 790 size_t payloadLength) 791 { 792 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES); 793 794 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES) 795 { 796 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 797 } 798 uint16_t fileType{}; 799 uint32_t fileHandle{}; 800 uint64_t length{}; 801 802 auto rc = decode_new_file_req(request, payloadLength, &fileType, 803 &fileHandle, &length); 804 805 if (rc != PLDM_SUCCESS) 806 { 807 return CmdHandler::ccOnlyResponse(request, rc); 808 } 809 810 std::unique_ptr<FileHandler> handler{}; 811 try 812 { 813 handler = getHandlerByType(fileType, fileHandle); 814 } 815 catch (const InternalFailure& e) 816 { 817 std::cerr << "unknown file type, TYPE=" << fileType << "\n"; 818 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE); 819 } 820 821 rc = handler->newFileAvailable(length); 822 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 823 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr); 824 return response; 825 } 826 827 } // namespace oem_ibm 828 } // namespace responder 829 } // namespace pldm 830