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