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