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