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