1 #include "file_io.hpp" 2 3 #include <libpldm/oem/meta/file_io.h> 4 5 #include <filesystem> 6 namespace pldm::responder::oem_meta 7 { 8 9 std::unique_ptr<FileHandler> FileIOHandler::getHandlerByType( 10 [[maybe_unused]] pldm_tid_t messageTid, FileIOType fileIOType) 11 { 12 switch (fileIOType) 13 { 14 default: 15 error("Get invalid file io type {FILEIOTYPE}", "FILEIOTYPE", 16 fileIOType); 17 break; 18 } 19 return nullptr; 20 } 21 22 Response FileIOHandler::writeFileIO(pldm_tid_t tid, const pldm_msg* request, 23 size_t payloadLength) 24 { 25 static constexpr uint8_t decodeDataMaxLength = 240; 26 constexpr uint8_t decodereqlen = 27 PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH + decodeDataMaxLength; 28 alignas(struct pldm_oem_meta_file_io_write_req) unsigned char 29 reqbuf[decodereqlen]; 30 auto request_msg = new (reqbuf) pldm_oem_meta_file_io_write_req; 31 auto request_data = static_cast<uint8_t*>( 32 pldm_oem_meta_file_io_write_req_data(request_msg)); 33 34 int rc = decode_oem_meta_file_io_write_req(request, payloadLength, 35 request_msg, decodereqlen); 36 37 if (rc != 0) 38 { 39 error("Failed to decode OEM Meta write file IO request"); 40 return ccOnlyResponse(request, rc); 41 } 42 43 auto handler = 44 getHandlerByType(tid, static_cast<FileIOType>(request_msg->handle)); 45 if (!handler) 46 { 47 return ccOnlyResponse(request, PLDM_ERROR_UNSUPPORTED_PLDM_CMD); 48 } 49 50 auto data = std::span(request_data, request_msg->length); 51 52 rc = handler->write(data); 53 54 return ccOnlyResponse(request, rc); 55 } 56 57 Response FileIOHandler::readFileIO(pldm_tid_t tid, const pldm_msg* request, 58 size_t payloadLength) 59 { 60 int rc; 61 struct pldm_oem_meta_file_io_read_req request_msg = {}; 62 request_msg.version = sizeof(struct pldm_oem_meta_file_io_read_req); 63 64 rc = decode_oem_meta_file_io_read_req(request, payloadLength, &request_msg); 65 66 if (rc != 0) 67 { 68 error("Failed to decode OEM Meta read file IO request"); 69 return ccOnlyResponse(request, rc); 70 } 71 72 auto handler = 73 getHandlerByType(tid, static_cast<FileIOType>(request_msg.handle)); 74 75 if (!handler) 76 { 77 return ccOnlyResponse(request, PLDM_ERROR_UNSUPPORTED_PLDM_CMD); 78 } 79 80 size_t encoderesplen = PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE; 81 if (request_msg.option == PLDM_OEM_META_FILE_IO_READ_ATTR) 82 { 83 encoderesplen += PLDM_OEM_META_FILE_IO_READ_ATTR_INFO_LENGTH; 84 } 85 else 86 { 87 encoderesplen += PLDM_OEM_META_FILE_IO_READ_DATA_INFO_LENGTH; 88 } 89 90 std::vector<uint8_t> respbuf( 91 sizeof(struct pldm_oem_meta_file_io_read_resp) + request_msg.length); 92 auto* response_msg = new (respbuf.data()) pldm_oem_meta_file_io_read_resp; 93 94 response_msg->version = sizeof(struct pldm_oem_meta_file_io_read_resp); 95 response_msg->handle = request_msg.handle; 96 response_msg->option = request_msg.option; 97 response_msg->length = request_msg.length; 98 99 if (response_msg->option != PLDM_OEM_META_FILE_IO_READ_ATTR) 100 { 101 response_msg->info.data.transferFlag = 102 request_msg.info.data.transferFlag; 103 response_msg->info.data.offset = request_msg.info.data.offset; 104 } 105 106 rc = handler->read(response_msg); 107 108 if (rc != PLDM_SUCCESS) 109 { 110 return ccOnlyResponse(request, rc); 111 } 112 113 response_msg->completion_code = PLDM_SUCCESS; 114 encoderesplen += response_msg->length; 115 116 Response response(sizeof(pldm_msg_hdr) + encoderesplen, 0); 117 auto responseMsg = new (response.data()) pldm_msg; 118 119 rc = encode_oem_meta_file_io_read_resp( 120 request->hdr.instance_id, response_msg, 121 sizeof(struct pldm_oem_meta_file_io_read_resp) + response_msg->length, 122 responseMsg, encoderesplen); 123 124 if (rc != 0) 125 { 126 return ccOnlyResponse(request, rc); 127 } 128 129 return response; 130 } 131 132 } // namespace pldm::responder::oem_meta 133