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