xref: /openbmc/pldm/oem/meta/libpldmresponder/file_io.cpp (revision bca95a5aa082281ffac81bdbaf6a22a0cff60405)
1972381fcSSora Su #include "file_io.hpp"
2972381fcSSora Su 
3*bca95a5aSSora Su #include "file_io_type_bios_version.hpp"
49e7232b0SSora Su #include "file_io_type_post_code.hpp"
59e7232b0SSora Su 
6972381fcSSora Su #include <libpldm/oem/meta/file_io.h>
7972381fcSSora Su 
8972381fcSSora Su #include <filesystem>
9972381fcSSora Su namespace pldm::responder::oem_meta
10972381fcSSora Su {
11972381fcSSora Su 
12972381fcSSora Su std::unique_ptr<FileHandler> FileIOHandler::getHandlerByType(
13972381fcSSora Su     [[maybe_unused]] pldm_tid_t messageTid, FileIOType fileIOType)
14972381fcSSora Su {
15972381fcSSora Su     switch (fileIOType)
16972381fcSSora Su     {
179e7232b0SSora Su         case FileIOType::POST_CODE:
189e7232b0SSora Su             return std::make_unique<PostCodeHandler>(messageTid);
19*bca95a5aSSora Su         case FileIOType::BIOS_VERSION:
20*bca95a5aSSora Su             return std::make_unique<BIOSVersionHandler>(messageTid,
21*bca95a5aSSora Su                                                         dBusHandler);
22972381fcSSora Su         default:
23972381fcSSora Su             error("Get invalid file io type {FILEIOTYPE}", "FILEIOTYPE",
24972381fcSSora Su                   fileIOType);
25972381fcSSora Su             break;
26972381fcSSora Su     }
27972381fcSSora Su     return nullptr;
28972381fcSSora Su }
29972381fcSSora Su 
30972381fcSSora Su Response FileIOHandler::writeFileIO(pldm_tid_t tid, const pldm_msg* request,
31972381fcSSora Su                                     size_t payloadLength)
32972381fcSSora Su {
33972381fcSSora Su     static constexpr uint8_t decodeDataMaxLength = 240;
34972381fcSSora Su     constexpr uint8_t decodereqlen =
35972381fcSSora Su         PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH + decodeDataMaxLength;
36972381fcSSora Su     alignas(struct pldm_oem_meta_file_io_write_req) unsigned char
37972381fcSSora Su         reqbuf[decodereqlen];
38972381fcSSora Su     auto request_msg = new (reqbuf) pldm_oem_meta_file_io_write_req;
39972381fcSSora Su     auto request_data = static_cast<uint8_t*>(
40972381fcSSora Su         pldm_oem_meta_file_io_write_req_data(request_msg));
41972381fcSSora Su 
42972381fcSSora Su     int rc = decode_oem_meta_file_io_write_req(request, payloadLength,
43972381fcSSora Su                                                request_msg, decodereqlen);
44972381fcSSora Su 
45972381fcSSora Su     if (rc != 0)
46972381fcSSora Su     {
47972381fcSSora Su         error("Failed to decode OEM Meta write file IO request");
48972381fcSSora Su         return ccOnlyResponse(request, rc);
49972381fcSSora Su     }
50972381fcSSora Su 
51972381fcSSora Su     auto handler =
52972381fcSSora Su         getHandlerByType(tid, static_cast<FileIOType>(request_msg->handle));
53972381fcSSora Su     if (!handler)
54972381fcSSora Su     {
55972381fcSSora Su         return ccOnlyResponse(request, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
56972381fcSSora Su     }
57972381fcSSora Su 
58972381fcSSora Su     auto data = std::span(request_data, request_msg->length);
59972381fcSSora Su 
60972381fcSSora Su     rc = handler->write(data);
61972381fcSSora Su 
62972381fcSSora Su     return ccOnlyResponse(request, rc);
63972381fcSSora Su }
64972381fcSSora Su 
65972381fcSSora Su Response FileIOHandler::readFileIO(pldm_tid_t tid, const pldm_msg* request,
66972381fcSSora Su                                    size_t payloadLength)
67972381fcSSora Su {
68972381fcSSora Su     int rc;
69972381fcSSora Su     struct pldm_oem_meta_file_io_read_req request_msg = {};
70972381fcSSora Su     request_msg.version = sizeof(struct pldm_oem_meta_file_io_read_req);
71972381fcSSora Su 
72972381fcSSora Su     rc = decode_oem_meta_file_io_read_req(request, payloadLength, &request_msg);
73972381fcSSora Su 
74972381fcSSora Su     if (rc != 0)
75972381fcSSora Su     {
76972381fcSSora Su         error("Failed to decode OEM Meta read file IO request");
77972381fcSSora Su         return ccOnlyResponse(request, rc);
78972381fcSSora Su     }
79972381fcSSora Su 
80972381fcSSora Su     auto handler =
81972381fcSSora Su         getHandlerByType(tid, static_cast<FileIOType>(request_msg.handle));
82972381fcSSora Su 
83972381fcSSora Su     if (!handler)
84972381fcSSora Su     {
85972381fcSSora Su         return ccOnlyResponse(request, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
86972381fcSSora Su     }
87972381fcSSora Su 
88972381fcSSora Su     size_t encoderesplen = PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE;
89972381fcSSora Su     if (request_msg.option == PLDM_OEM_META_FILE_IO_READ_ATTR)
90972381fcSSora Su     {
91972381fcSSora Su         encoderesplen += PLDM_OEM_META_FILE_IO_READ_ATTR_INFO_LENGTH;
92972381fcSSora Su     }
93972381fcSSora Su     else
94972381fcSSora Su     {
95972381fcSSora Su         encoderesplen += PLDM_OEM_META_FILE_IO_READ_DATA_INFO_LENGTH;
96972381fcSSora Su     }
97972381fcSSora Su 
98972381fcSSora Su     std::vector<uint8_t> respbuf(
99972381fcSSora Su         sizeof(struct pldm_oem_meta_file_io_read_resp) + request_msg.length);
100972381fcSSora Su     auto* response_msg = new (respbuf.data()) pldm_oem_meta_file_io_read_resp;
101972381fcSSora Su 
102972381fcSSora Su     response_msg->version = sizeof(struct pldm_oem_meta_file_io_read_resp);
103972381fcSSora Su     response_msg->handle = request_msg.handle;
104972381fcSSora Su     response_msg->option = request_msg.option;
105972381fcSSora Su     response_msg->length = request_msg.length;
106972381fcSSora Su 
107972381fcSSora Su     if (response_msg->option != PLDM_OEM_META_FILE_IO_READ_ATTR)
108972381fcSSora Su     {
109972381fcSSora Su         response_msg->info.data.transferFlag =
110972381fcSSora Su             request_msg.info.data.transferFlag;
111972381fcSSora Su         response_msg->info.data.offset = request_msg.info.data.offset;
112972381fcSSora Su     }
113972381fcSSora Su 
114972381fcSSora Su     rc = handler->read(response_msg);
115972381fcSSora Su 
116972381fcSSora Su     if (rc != PLDM_SUCCESS)
117972381fcSSora Su     {
118972381fcSSora Su         return ccOnlyResponse(request, rc);
119972381fcSSora Su     }
120972381fcSSora Su 
121972381fcSSora Su     response_msg->completion_code = PLDM_SUCCESS;
122972381fcSSora Su     encoderesplen += response_msg->length;
123972381fcSSora Su 
124972381fcSSora Su     Response response(sizeof(pldm_msg_hdr) + encoderesplen, 0);
125972381fcSSora Su     auto responseMsg = new (response.data()) pldm_msg;
126972381fcSSora Su 
127972381fcSSora Su     rc = encode_oem_meta_file_io_read_resp(
128972381fcSSora Su         request->hdr.instance_id, response_msg,
129972381fcSSora Su         sizeof(struct pldm_oem_meta_file_io_read_resp) + response_msg->length,
130972381fcSSora Su         responseMsg, encoderesplen);
131972381fcSSora Su 
132972381fcSSora Su     if (rc != 0)
133972381fcSSora Su     {
134972381fcSSora Su         return ccOnlyResponse(request, rc);
135972381fcSSora Su     }
136972381fcSSora Su 
137972381fcSSora Su     return response;
138972381fcSSora Su }
139972381fcSSora Su 
140972381fcSSora Su } // namespace pldm::responder::oem_meta
141