blob: e4800fbafca28cc333c52f9821d5a490c601fdfa [file] [log] [blame]
Sora Su972381f2025-07-18 18:11:26 +08001#include "file_io.hpp"
2
3#include <libpldm/oem/meta/file_io.h>
4
5#include <filesystem>
6namespace pldm::responder::oem_meta
7{
8
9std::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
22Response 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
57Response 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