blob: 57b89ba7d22bedffd0896a2d4a1ec1a7cbfcaf74 [file] [log] [blame]
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05301#include "file_io.hpp"
2
Sampa Misra854e61f2019-08-22 04:36:47 -05003#include "file_io_by_type.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05304#include "file_table.hpp"
Ravi Tejace1c96f2020-10-05 23:13:01 -05005#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05006#include "xyz/openbmc_project/Common/error.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05007
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05308#include <fcntl.h>
George Liuc453e162022-12-21 17:16:23 +08009#include <libpldm/base.h>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053010#include <sys/mman.h>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <unistd.h>
14
Riya Dixit49cfb132023-03-02 04:26:53 -060015#include <phosphor-logging/lg2.hpp>
16
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053017#include <cstring>
18#include <fstream>
Sampa Misra854e61f2019-08-22 04:36:47 -050019#include <memory>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053020
Riya Dixit49cfb132023-03-02 04:26:53 -060021PHOSPHOR_LOG2_USING;
22
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053023namespace pldm
24{
Ravi Tejace1c96f2020-10-05 23:13:01 -050025using namespace pldm::responder::utils;
Sampa Misra854e61f2019-08-22 04:36:47 -050026using namespace sdbusplus::xyz::openbmc_project::Common::Error;
27
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053028namespace responder
29{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053030namespace fs = std::filesystem;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053031
32namespace dma
33{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053034/** @struct AspeedXdmaOp
35 *
36 * Structure representing XDMA operation
37 */
38struct AspeedXdmaOp
39{
40 uint64_t hostAddr; //!< the DMA address on the host side, configured by
41 //!< PCI subsystem.
42 uint32_t len; //!< the size of the transfer in bytes, it should be a
43 //!< multiple of 16 bytes
44 uint32_t upstream; //!< boolean indicating the direction of the DMA
45 //!< operation, true means a transfer from BMC to host.
46};
47
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050048constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053049
Ravi Tejace1c96f2020-10-05 23:13:01 -050050int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
51{
52 static const size_t pageSize = getpagesize();
53 uint32_t numPages = length / pageSize;
54 uint32_t pageAlignedLength = numPages * pageSize;
55
56 if (length > pageAlignedLength)
57 {
58 pageAlignedLength += pageSize;
59 }
60
61 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
62 munmap(vgaMem, pageAlignedLength);
63 };
64
65 int dmaFd = -1;
66 int rc = 0;
67 dmaFd = open(xdmaDev, O_RDWR);
68 if (dmaFd < 0)
69 {
70 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -060071 error(
Riya Dixitfc84f632024-04-06 14:00:02 -050072 "Failed to open the XDMA device for transferring remote terminus data to socket with response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -060073 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -050074 return rc;
75 }
76
77 pldm::utils::CustomFD xdmaFd(dmaFd);
78
79 void* vgaMem;
Patrick Williams6da4f912023-05-10 07:50:53 -050080 vgaMem = mmap(nullptr, pageAlignedLength, PROT_READ, MAP_SHARED, xdmaFd(),
81 0);
Ravi Tejace1c96f2020-10-05 23:13:01 -050082 if (MAP_FAILED == vgaMem)
83 {
84 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -060085 error(
Riya Dixitfc84f632024-04-06 14:00:02 -050086 "Failed to mmap the XDMA device for transferring remote terminus data to socket with response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -060087 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -050088 return rc;
89 }
90
91 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
92
93 AspeedXdmaOp xdmaOp;
94 xdmaOp.upstream = 0;
95 xdmaOp.hostAddr = address;
96 xdmaOp.len = length;
97
98 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
99 if (rc < 0)
100 {
101 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600102 error(
Manojkiran Eda2576aec2024-06-17 12:05:17 +0530103 "Failed to execute the DMA operation for transferring remote terminus data to socket at address '{ADDRESS}' and length '{LENGTH}' with response code '{RC}'",
Riya Dixitfc84f632024-04-06 14:00:02 -0500104 "RC", rc, "ADDRESS", address, "LENGTH", length);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500105 return rc;
106 }
107
108 rc = writeToUnixSocket(fd, static_cast<const char*>(vgaMemPtr.get()),
109 length);
110 if (rc < 0)
111 {
112 rc = -errno;
113 close(fd);
Riya Dixit49cfb132023-03-02 04:26:53 -0600114 error(
Manojkiran Eda2576aec2024-06-17 12:05:17 +0530115 "Failed to write to Unix socket, closing socket for transferring remote terminus data to socket with response code '{RC}'",
Riya Dixit49cfb132023-03-02 04:26:53 -0600116 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500117 return rc;
118 }
119 return 0;
120}
121
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600122int DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
123 uint64_t address, bool upstream)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530124{
125 static const size_t pageSize = getpagesize();
126 uint32_t numPages = length / pageSize;
127 uint32_t pageAlignedLength = numPages * pageSize;
128
129 if (length > pageAlignedLength)
130 {
131 pageAlignedLength += pageSize;
132 }
133
ArchanaKakani93409752022-04-19 00:36:04 -0500134 int rc = 0;
135 auto mmapCleanup = [pageAlignedLength, &rc](void* vgaMem) {
136 if (rc != -EINTR)
137 {
138 munmap(vgaMem, pageAlignedLength);
139 }
140 else
141 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600142 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500143 "Received interrupt during DMA transfer for data between BMC and remote terminus. Skipping Unmap.");
ArchanaKakani93409752022-04-19 00:36:04 -0500144 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530145 };
146
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600147 int dmaFd = -1;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600148 dmaFd = open(xdmaDev, O_RDWR);
149 if (dmaFd < 0)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530150 {
151 rc = -errno;
Riya Dixitfc84f632024-04-06 14:00:02 -0500152 error(
153 "Failed to open the XDMA device for data transfer between BMC and remote terminus with response code '{RC}'",
154 "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530155 return rc;
156 }
157
George Liu83409572019-12-24 18:42:54 +0800158 pldm::utils::CustomFD xdmaFd(dmaFd);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530159
160 void* vgaMem;
161 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
162 MAP_SHARED, xdmaFd(), 0);
163 if (MAP_FAILED == vgaMem)
164 {
165 rc = -errno;
Riya Dixitfc84f632024-04-06 14:00:02 -0500166 error(
167 "Failed to mmap the XDMA device for data transfer between BMC and remote terminus with response code '{RC}'",
168 "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530169 return rc;
170 }
171
172 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
173
174 if (upstream)
175 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600176 rc = lseek(fd, offset, SEEK_SET);
177 if (rc == -1)
178 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600179 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500180 "Failed to transfer data between BMC and remote terminus due to lseek failure with upstream '{UPSTREAM}' at offset '{OFFSET}', error number - {ERROR_NUM}",
181 "ERROR_NUM", errno, "UPSTREAM", upstream, "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600182 return rc;
183 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530184
185 // Writing to the VGA memory should be aligned at page boundary,
186 // otherwise write data into a buffer aligned at page boundary and
187 // then write to the VGA memory.
188 std::vector<char> buffer{};
189 buffer.resize(pageAlignedLength);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600190 rc = read(fd, buffer.data(), length);
191 if (rc == -1)
192 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600193 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500194 "Failed to transfer data between BMC and remote terminus with file read on upstream '{UPSTREAM}' of length '{LENGTH}' at offset '{OFFSET}' failed, error number - {ERROR_NUM}",
195 "ERROR_NUM", errno, "UPSTREAM", upstream, "LENGTH", length,
196 "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600197 return rc;
198 }
199 if (rc != static_cast<int>(length))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530200 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600201 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500202 "Failed to transfer data between BMC and remote terminus mismatched for number of characters to read on upstream '{UPSTREAM}' and the length '{LENGTH}' read and count '{RC}'",
203 "UPSTREAM", upstream, "LENGTH", length, "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530204 return -1;
205 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600206 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
207 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530208 }
209
210 AspeedXdmaOp xdmaOp;
211 xdmaOp.upstream = upstream ? 1 : 0;
212 xdmaOp.hostAddr = address;
213 xdmaOp.len = length;
214
215 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
216 if (rc < 0)
217 {
218 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600219 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500220 "Failed to execute the DMA operation on data between BMC and remote terminus for upstream '{UPSTREAM}' of length '{LENGTH}' at address '{ADDRESS}', response code '{RC}'",
221 "RC", rc, "UPSTREAM", upstream, "ADDRESS", address, "LENGTH",
222 length);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530223 return rc;
224 }
225
226 if (!upstream)
227 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600228 rc = lseek(fd, offset, SEEK_SET);
229 if (rc == -1)
Sampa Misra854e61f2019-08-22 04:36:47 -0500230 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600231 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500232 "Failed to transfer data between BMC and remote terminus due to lseek failure '{UPSTREAM}' at offset '{OFFSET}' failed, error number - {ERROR_NUM}",
233 "ERROR_NUM", errno, "UPSTREAM", upstream, "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600234 return rc;
Sampa Misra854e61f2019-08-22 04:36:47 -0500235 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600236 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
237 if (rc == -1)
238 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600239 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500240 "Failed to transfer data between BMC and remote terminus where file write upstream '{UPSTREAM}' of length '{LENGTH}' at offset '{OFFSET}' failed, error number - {ERROR_NUM}",
241 "ERROR_NUM", errno, "UPSTREAM", upstream, "LENGTH", length,
242 "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600243 return rc;
244 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530245 }
246
247 return 0;
248}
249
250} // namespace dma
251
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600252namespace oem_ibm
253{
Riya Dixit8394c452024-04-06 12:15:23 -0500254void encodeRWResponseHandler(uint8_t instance_id, uint8_t command,
255 uint8_t completion_code, uint32_t length,
256 struct pldm_msg* msg)
257{
258 int rc = encode_rw_file_memory_resp(instance_id, command, completion_code,
259 length, msg);
260 if (rc != PLDM_SUCCESS)
261 {
262 error(
263 "Failed to encode response for command {COMMAND}, response code '{RC}'",
264 "COMMAND", command, "RC", rc);
265 }
266}
267
268void encodeReadResponseHandler(uint8_t instance_id, uint8_t completion_code,
269 uint32_t length, struct pldm_msg* msg)
270{
271 int rc = encode_read_file_resp(instance_id, completion_code, length, msg);
272 if (rc != PLDM_SUCCESS)
273 {
274 error("Failed to encode read file response, response code '{RC}'", "RC",
275 rc);
276 }
277}
278
279void encodeWriteResponseHandler(uint8_t instance_id, uint8_t completion_code,
280 uint32_t length, struct pldm_msg* msg)
281{
282 int rc = encode_write_file_resp(instance_id, completion_code, length, msg);
283 if (rc != PLDM_SUCCESS)
284 {
285 error("Failed to encode write file response, response code '{RC}'",
286 "RC", rc);
287 }
288}
289
290void encodeGetFileResponseHandler(uint8_t instance_id, uint8_t completion_code,
291 uint32_t next_transfer_handle,
292 uint8_t transfer_flag,
293 const uint8_t* table_data, size_t table_size,
294 struct pldm_msg* msg)
295{
296 int rc = encode_get_file_table_resp(instance_id, completion_code,
297 next_transfer_handle, transfer_flag,
298 table_data, table_size, msg);
299 if (rc != PLDM_SUCCESS)
300 {
301 error("Failed to encode get file table response, response code '{RC}'",
302 "RC", rc);
303 }
304}
305
306void encodeRWTypeMemoryResponseHandler(uint8_t instance_id, uint8_t command,
307 uint8_t completion_code, uint32_t length,
308 struct pldm_msg* msg)
309{
310 int rc = encode_rw_file_by_type_memory_resp(instance_id, command,
311 completion_code, length, msg);
312 if (rc != PLDM_SUCCESS)
313 {
314 error(
315 "Failed to encode read/write file by type memory response, response code '{RC}'",
316 "RC", rc);
317 }
318}
319
320void encodeRWTypeResponseHandler(uint8_t instance_id, uint8_t command,
321 uint8_t completion_code, uint32_t length,
322 struct pldm_msg* msg)
323{
324 int rc = encode_rw_file_by_type_resp(instance_id, command, completion_code,
325 length, msg);
326 if (rc != PLDM_SUCCESS)
327 {
328 error(
329 "Failed to encode response for command {COMMAND}, response code '{RC}'",
330 "COMMAND", command, "RC", rc);
331 }
332}
333
334void encodeFileAckResponseHandler(uint8_t instance_id, uint8_t completion_code,
335 struct pldm_msg* msg)
336{
337 int rc = encode_file_ack_resp(instance_id, completion_code, msg);
338 if (rc != PLDM_SUCCESS)
339 {
340 error("Failed to encode file ack response, response code '{RC}'", "RC",
341 rc);
342 }
343}
344
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600345Response Handler::readFileIntoMemory(const pldm_msg* request,
346 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530347{
348 uint32_t fileHandle = 0;
349 uint32_t offset = 0;
350 uint32_t length = 0;
351 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530352
353 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
354 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530355 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
356 {
Riya Dixit8394c452024-04-06 12:15:23 -0500357 error(
358 "Failed to read file into memory as payload length '{LENGTH}' not equal to '{REQ_LENGTH}'",
359 "LENGTH", payloadLength, "REQ_LENGTH", PLDM_RW_FILE_MEM_REQ_BYTES);
360 encodeRWResponseHandler(request->hdr.instance_id,
361 PLDM_READ_FILE_INTO_MEMORY,
362 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530363 return response;
364 }
365
Riya Dixit8394c452024-04-06 12:15:23 -0500366 int responseCode = decode_rw_file_memory_req(
367 request, payloadLength, &fileHandle, &offset, &length, &address);
368 if (responseCode != PLDM_SUCCESS)
369 {
370 error(
371 "Failed to decode read file into memory request, response code '{RC}'",
372 "RC", responseCode);
373 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530374
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530375 using namespace pldm::filetable;
376 auto& table = buildFileTable(FILE_TABLE_JSON);
377 FileEntry value{};
378
379 try
380 {
381 value = table.at(fileHandle);
382 }
Patrick Williams51330582021-10-06 12:48:56 -0500383 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530384 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500385 error(
386 "File handle '{HANDLE}' does not exist in the file table, error - {ERROR}",
387 "HANDLE", fileHandle, "ERROR", e);
Riya Dixit8394c452024-04-06 12:15:23 -0500388 encodeRWResponseHandler(request->hdr.instance_id,
389 PLDM_READ_FILE_INTO_MEMORY,
390 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530391 return response;
392 }
393
394 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530395 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500396 error("File '{PATH}' and handle '{FILE_HANDLE}' with does not exist",
397 "PATH", value.fsPath, "FILE_HANDLE", fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500398 encodeRWResponseHandler(request->hdr.instance_id,
399 PLDM_READ_FILE_INTO_MEMORY,
400 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530401 return response;
402 }
403
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530404 auto fileSize = fs::file_size(value.fsPath);
Riya Dixit8394c452024-04-06 12:15:23 -0500405 if (!fileSize)
406 {
407 error(
408 "Failed to PLDM_READ_FILE_INTO_MEMORY from file {PATH} with size '{SIZE}'",
409 "PATH", value.fsPath, "SIZE", fileSize);
410 encodeRWResponseHandler(request->hdr.instance_id,
411 PLDM_READ_FILE_INTO_MEMORY,
412 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
413 return response;
414 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530415 if (offset >= fileSize)
416 {
Sagar Srinivas82257922023-07-10 08:12:22 -0500417 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500418 "Offset '{OFFSET}' exceeds file size '{SIZE}' and file handle '{FILE_HANDLE}'",
419 "OFFSET", offset, "SIZE", fileSize, "FILE_HANDLE", fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500420 encodeRWResponseHandler(request->hdr.instance_id,
421 PLDM_READ_FILE_INTO_MEMORY,
422 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530423 return response;
424 }
425
426 if (offset + length > fileSize)
427 {
428 length = fileSize - offset;
429 }
430
Riya Dixit8394c452024-04-06 12:15:23 -0500431 if (!length || length % dma::minSize)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530432 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500433 error("Packet length '{LENGTH}' is non multiple of minimum DMA size",
434 "LENGTH", length);
Riya Dixit8394c452024-04-06 12:15:23 -0500435 encodeRWResponseHandler(request->hdr.instance_id,
436 PLDM_READ_FILE_INTO_MEMORY,
437 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530438 return response;
439 }
440
441 using namespace dma;
442 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530443 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530444 offset, length, address, true,
445 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530446}
447
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600448Response Handler::writeFileFromMemory(const pldm_msg* request,
449 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530450{
451 uint32_t fileHandle = 0;
452 uint32_t offset = 0;
453 uint32_t length = 0;
454 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530455
456 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
457 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
458
459 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
460 {
Riya Dixit8394c452024-04-06 12:15:23 -0500461 error(
462 "Failed to write file from memory as payload length '{LENGTH}' not equal to '{REQ_LENGTH}'",
463 "LENGTH", payloadLength, "REQ_LENGTH", PLDM_RW_FILE_MEM_REQ_BYTES);
464 encodeRWResponseHandler(request->hdr.instance_id,
465 PLDM_WRITE_FILE_FROM_MEMORY,
466 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530467 return response;
468 }
469
Riya Dixit8394c452024-04-06 12:15:23 -0500470 int responseCode = decode_rw_file_memory_req(
471 request, payloadLength, &fileHandle, &offset, &length, &address);
472 if (responseCode != PLDM_SUCCESS)
473 {
474 error(
475 "Failed to decode write file from memory request, response code '{RC}'",
476 "RC", responseCode);
477 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530478
Riya Dixit8394c452024-04-06 12:15:23 -0500479 if (!length || length % dma::minSize)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530480 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500481 error("Packet length '{LENGTH}' is non multiple of minimum DMA size",
482 "LENGTH", length);
Riya Dixit8394c452024-04-06 12:15:23 -0500483 encodeRWResponseHandler(request->hdr.instance_id,
484 PLDM_WRITE_FILE_FROM_MEMORY,
485 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530486 return response;
487 }
488
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530489 using namespace pldm::filetable;
490 auto& table = buildFileTable(FILE_TABLE_JSON);
491 FileEntry value{};
492
493 try
494 {
495 value = table.at(fileHandle);
496 }
Patrick Williams51330582021-10-06 12:48:56 -0500497 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530498 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500499 error(
500 "File handle '{HANDLE}' does not exist in the file table, error - {ERROR}",
501 "HANDLE", fileHandle, "ERROR", e);
Riya Dixit8394c452024-04-06 12:15:23 -0500502 encodeRWResponseHandler(request->hdr.instance_id,
503 PLDM_WRITE_FILE_FROM_MEMORY,
504 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530505 return response;
506 }
507
508 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530509 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500510 error("File '{PATH}' does not exist for file handle '{FILE_HANDLE}'",
511 "PATH", value.fsPath, "FILE_HANDLE", fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500512 encodeRWResponseHandler(request->hdr.instance_id,
513 PLDM_WRITE_FILE_FROM_MEMORY,
514 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530515 return response;
516 }
517
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530518 auto fileSize = fs::file_size(value.fsPath);
Riya Dixit8394c452024-04-06 12:15:23 -0500519 if (!fileSize)
520 {
521 info(
522 "File '{PATH}' has size '{SIZE}' for command PLDM_WRITE_FILE_FROM_MEMORY",
523 "PATH", value.fsPath, "SIZE", fileSize);
524 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530525 if (offset >= fileSize)
526 {
Sagar Srinivas82257922023-07-10 08:12:22 -0500527 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500528 "Offset '{OFFSET}' exceeds file size {SIZE} for file '{PATH} and handle {FILE_HANDLE}",
529 "OFFSET", offset, "SIZE", fileSize, "PATH", value.fsPath,
530 "FILE_HANDLE", fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500531 encodeRWResponseHandler(request->hdr.instance_id,
532 PLDM_WRITE_FILE_FROM_MEMORY,
533 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530534 return response;
535 }
536
537 using namespace dma;
538 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530539 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530540 offset, length, address, false,
541 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530542}
543
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600544Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530545{
546 uint32_t transferHandle = 0;
547 uint8_t transferFlag = 0;
548 uint8_t tableType = 0;
549
550 Response response(sizeof(pldm_msg_hdr) +
551 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
552 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
553
554 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
555 {
Riya Dixit8394c452024-04-06 12:15:23 -0500556 error(
557 "Failed to get file table as payload length '{LENGTH}' not equal to required length '{REQ_LENGTH}'",
558 "LENGTH", payloadLength, "REQ_LENGTH",
559 PLDM_GET_FILE_TABLE_REQ_BYTES);
560 encodeGetFileResponseHandler(request->hdr.instance_id,
561 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr,
562 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530563 return response;
564 }
565
Zahed Hossain223a73d2019-07-04 12:46:18 -0500566 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
567 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530568 if (rc)
569 {
Riya Dixit8394c452024-04-06 12:15:23 -0500570 error("Failed to decode get file table request, response code '{RC}'",
571 "RC", rc);
572 encodeGetFileResponseHandler(request->hdr.instance_id, rc, 0, 0,
573 nullptr, 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530574 return response;
575 }
576
577 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
578 {
Riya Dixit8394c452024-04-06 12:15:23 -0500579 error(
580 "Failed to match table type '{TYPE}' with expected table type '{REQ_TYPE}'",
581 "TYPE", tableType, "REQ_TYPE", PLDM_FILE_ATTRIBUTE_TABLE);
582 encodeGetFileResponseHandler(request->hdr.instance_id,
583 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0,
584 nullptr, 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530585 return response;
586 }
587
588 using namespace pldm::filetable;
589 auto table = buildFileTable(FILE_TABLE_JSON);
590 auto attrTable = table();
591 response.resize(response.size() + attrTable.size());
592 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
593
594 if (attrTable.empty())
595 {
Riya Dixit8394c452024-04-06 12:15:23 -0500596 error("PLDM file attribute table is empty");
597 encodeGetFileResponseHandler(request->hdr.instance_id,
598 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
599 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530600 return response;
601 }
602
Riya Dixit8394c452024-04-06 12:15:23 -0500603 encodeGetFileResponseHandler(request->hdr.instance_id, PLDM_SUCCESS, 0,
604 PLDM_START_AND_END, attrTable.data(),
605 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530606 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530607}
608
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600609Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500610{
611 uint32_t fileHandle = 0;
612 uint32_t offset = 0;
613 uint32_t length = 0;
614
615 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
616 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
617
618 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
619 {
Riya Dixit8394c452024-04-06 12:15:23 -0500620 error(
621 "Failed to read file as payload length '{LENGTH}' not equal to '{REQ_LENGTH}'",
622 "LENGTH", payloadLength, "REQ_LENGTH", PLDM_READ_FILE_REQ_BYTES);
623 encodeReadResponseHandler(request->hdr.instance_id,
624 PLDM_ERROR_INVALID_LENGTH, length,
625 responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500626 return response;
627 }
628
629 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
630 &length);
631
632 if (rc)
633 {
Riya Dixit8394c452024-04-06 12:15:23 -0500634 error("Failed to decode read file request, response code '{RC}'", "RC",
635 rc);
636 encodeReadResponseHandler(request->hdr.instance_id, rc, 0, responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500637 return response;
638 }
639
640 using namespace pldm::filetable;
641 auto& table = buildFileTable(FILE_TABLE_JSON);
642 FileEntry value{};
643
644 try
645 {
646 value = table.at(fileHandle);
647 }
Patrick Williams51330582021-10-06 12:48:56 -0500648 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500649 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500650 error(
651 "File handle '{HANDLE}' does not exist in the file table, error - {ERROR}",
652 "HANDLE", fileHandle, "ERROR", e);
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500653
Riya Dixit8394c452024-04-06 12:15:23 -0500654 encodeReadResponseHandler(request->hdr.instance_id,
655 PLDM_INVALID_FILE_HANDLE, length,
656 responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500657 return response;
658 }
659
660 if (!fs::exists(value.fsPath))
661 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500662 error("File '{PATH}' and handle {FILE_HANDLE} does not exist", "PATH",
663 value.fsPath, "FILE_HANDLE", fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500664 encodeReadResponseHandler(request->hdr.instance_id,
665 PLDM_INVALID_FILE_HANDLE, length,
666 responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500667 return response;
668 }
669
670 auto fileSize = fs::file_size(value.fsPath);
Riya Dixit8394c452024-04-06 12:15:23 -0500671 if (!fileSize)
672 {
673 error("Failed to read file {PATH} with size '{SIZE}'", "PATH",
674 value.fsPath, "SIZE", fileSize);
675 encodeRWResponseHandler(request->hdr.instance_id,
676 PLDM_READ_FILE_INTO_MEMORY,
677 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
678 return response;
679 }
680
vkaverap5b914c32019-06-30 22:23:54 -0500681 if (offset >= fileSize)
682 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500683 error(
684 "Offset '{OFFSET}' exceeds file size '{SIZE}' for file '{PATH}' and file handle '{HANDLE}'",
685 "OFFSET", offset, "SIZE", fileSize, "PATH", value.fsPath, "HANDLE",
686 fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500687 encodeReadResponseHandler(request->hdr.instance_id,
688 PLDM_DATA_OUT_OF_RANGE, length, responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500689 return response;
690 }
691
692 if (offset + length > fileSize)
693 {
694 length = fileSize - offset;
695 }
696
697 response.resize(response.size() + length);
698 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
699 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
700 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
701
702 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
703 stream.seekg(offset);
704 stream.read(fileDataPos, length);
705
Riya Dixit8394c452024-04-06 12:15:23 -0500706 encodeReadResponseHandler(request->hdr.instance_id, PLDM_SUCCESS, length,
707 responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500708
709 return response;
710}
711
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600712Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500713{
714 uint32_t fileHandle = 0;
715 uint32_t offset = 0;
716 uint32_t length = 0;
717 size_t fileDataOffset = 0;
718
719 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
720 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
721
722 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
723 {
Riya Dixit8394c452024-04-06 12:15:23 -0500724 error(
725 "Failed to write file as payload length '{LENGTH}' less than '{REQ_LENGTH}'",
726 "LENGTH", payloadLength, "REQ_LENGTH", PLDM_WRITE_FILE_REQ_BYTES);
727 encodeWriteResponseHandler(request->hdr.instance_id,
728 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500729 return response;
730 }
731
732 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
733 &offset, &length, &fileDataOffset);
734
735 if (rc)
736 {
Riya Dixit8394c452024-04-06 12:15:23 -0500737 error("Failed to decode write file request, response code '{RC}'", "RC",
738 rc);
739 encodeWriteResponseHandler(request->hdr.instance_id, rc, 0,
740 responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500741 return response;
742 }
743
744 using namespace pldm::filetable;
745 auto& table = buildFileTable(FILE_TABLE_JSON);
746 FileEntry value{};
747
748 try
749 {
750 value = table.at(fileHandle);
751 }
Patrick Williams51330582021-10-06 12:48:56 -0500752 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500753 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500754 error(
755 "File handle '{HANDLE}' does not exist in the file table, error - {ERROR}",
756 "HANDLE", fileHandle, "ERROR", e);
Riya Dixit8394c452024-04-06 12:15:23 -0500757 encodeWriteResponseHandler(request->hdr.instance_id,
758 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500759 return response;
760 }
761
762 if (!fs::exists(value.fsPath))
763 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500764 error("File '{PATH}' and handle {FILE_HANDLE} does not exist", "PATH",
765 value.fsPath, "FILE_HANDLE", fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500766 encodeWriteResponseHandler(request->hdr.instance_id,
767 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500768 return response;
769 }
770
771 auto fileSize = fs::file_size(value.fsPath);
Riya Dixit8394c452024-04-06 12:15:23 -0500772
773 if (!fileSize)
774 {
775 info("File {PATH} has size '{SIZE}' for write file command", "PATH",
776 value.fsPath, "SIZE", fileSize);
777 }
778
vkaverap5b914c32019-06-30 22:23:54 -0500779 if (offset >= fileSize)
780 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500781 error(
782 "Offset '{OFFSET}' exceeds file size '{SIZE}' for file '{PATH}' and handle {FILE_HANDLE}",
783 "OFFSET", offset, "SIZE", fileSize, "PATH", value.fsPath,
784 "FILE_HANDLE", fileHandle);
Riya Dixit8394c452024-04-06 12:15:23 -0500785 encodeWriteResponseHandler(request->hdr.instance_id,
786 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500787 return response;
788 }
789
Patrick Williams6da4f912023-05-10 07:50:53 -0500790 auto fileDataPos = reinterpret_cast<const char*>(request->payload) +
791 fileDataOffset;
vkaverap5b914c32019-06-30 22:23:54 -0500792
793 std::ofstream stream(value.fsPath,
794 std::ios::in | std::ios::out | std::ios::binary);
795 stream.seekp(offset);
796 stream.write(fileDataPos, length);
797
Riya Dixit8394c452024-04-06 12:15:23 -0500798 encodeWriteResponseHandler(request->hdr.instance_id, PLDM_SUCCESS, length,
799 responsePtr);
vkaverap5b914c32019-06-30 22:23:54 -0500800
801 return response;
802}
803
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600804Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
Sampa Misra69508502020-09-08 00:08:21 -0500805 size_t payloadLength,
806 oem_platform::Handler* oemPlatformHandler)
Sampa Misra854e61f2019-08-22 04:36:47 -0500807{
808 Response response(
809 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
810 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
811
812 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
813 {
Riya Dixit8394c452024-04-06 12:15:23 -0500814 error(
815 "Failed to read file into memory as payload length '{LENGTH}' not equal to '{REQ_LENGTH}'",
816 "LENGTH", payloadLength, "REQ_LENGTH",
817 PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
818 encodeRWTypeMemoryResponseHandler(request->hdr.instance_id, cmd,
819 PLDM_ERROR_INVALID_LENGTH, 0,
820 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500821 return response;
822 }
823
824 uint16_t fileType{};
825 uint32_t fileHandle{};
826 uint32_t offset{};
827 uint32_t length{};
828 uint64_t address{};
829 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
830 &fileType, &fileHandle, &offset,
831 &length, &address);
832 if (rc != PLDM_SUCCESS)
833 {
Riya Dixit8394c452024-04-06 12:15:23 -0500834 error(
835 "Failed to decode read/write file by type memory request, response code '{RC}'",
836 "RC", rc);
837 encodeRWTypeMemoryResponseHandler(request->hdr.instance_id, cmd, rc, 0,
838 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500839 return response;
840 }
Riya Dixit8394c452024-04-06 12:15:23 -0500841 if (!length || length % dma::minSize)
Sampa Misra854e61f2019-08-22 04:36:47 -0500842 {
Riya Dixit8394c452024-04-06 12:15:23 -0500843 error(
844 "Packet length '{LENGTH}' is non multiple of minimum DMA size for command {CMD}",
845 "LENGTH", length, "CMD", cmd);
846 encodeRWTypeMemoryResponseHandler(request->hdr.instance_id, cmd,
847 PLDM_ERROR_INVALID_LENGTH, 0,
848 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500849 return response;
850 }
851
852 std::unique_ptr<FileHandler> handler{};
853 try
854 {
855 handler = getHandlerByType(fileType, fileHandle);
856 }
857 catch (const InternalFailure& e)
858 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500859 error("Unknown file type '{TYPE}', error - {ERROR} ", "TYPE", fileType,
860 "ERROR", e);
Riya Dixit8394c452024-04-06 12:15:23 -0500861 encodeRWTypeMemoryResponseHandler(request->hdr.instance_id, cmd,
862 PLDM_INVALID_FILE_TYPE, 0,
863 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500864 return response;
865 }
866
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600867 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
Sampa Misra69508502020-09-08 00:08:21 -0500868 ? handler->writeFromMemory(offset, length, address,
869 oemPlatformHandler)
870 : handler->readIntoMemory(offset, length, address,
871 oemPlatformHandler);
Riya Dixit8394c452024-04-06 12:15:23 -0500872 encodeRWTypeMemoryResponseHandler(request->hdr.instance_id, cmd, rc, length,
873 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500874 return response;
875}
876
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600877Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
878 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600879{
880 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500881 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600882}
883
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600884Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
885 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600886{
887 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500888 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600889}
890
Sampa Misra18967162020-01-14 02:31:41 -0600891Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
892{
893 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
894 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
895
Sampa Misrad823cc02020-03-24 04:53:20 -0500896 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600897 {
Riya Dixit8394c452024-04-06 12:15:23 -0500898 error(
899 "Failed to write file by type as payload length '{LENGTH}' less than '{REQ_LENGTH}'",
900 "LENGTH", payloadLength, "REQ_LENGTH",
901 PLDM_RW_FILE_BY_TYPE_REQ_BYTES);
902 encodeRWTypeResponseHandler(request->hdr.instance_id,
Sampa Misra18967162020-01-14 02:31:41 -0600903 PLDM_WRITE_FILE_BY_TYPE,
904 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
905 return response;
906 }
907 uint16_t fileType{};
908 uint32_t fileHandle{};
909 uint32_t offset{};
910 uint32_t length{};
911
912 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
913 &fileHandle, &offset, &length);
914 if (rc != PLDM_SUCCESS)
915 {
Riya Dixit8394c452024-04-06 12:15:23 -0500916 error("Failed decoded write file by type request, response code '{RC}'",
917 "RC", rc);
918 encodeRWTypeResponseHandler(request->hdr.instance_id,
Sampa Misra18967162020-01-14 02:31:41 -0600919 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
920 responsePtr);
921 return response;
922 }
923
924 std::unique_ptr<FileHandler> handler{};
925 try
926 {
927 handler = getHandlerByType(fileType, fileHandle);
928 }
929 catch (const InternalFailure& e)
930 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500931 error("Unknown file type '{TYPE}', error - {ERROR}", "TYPE", fileType,
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500932 "ERROR", e);
Riya Dixit8394c452024-04-06 12:15:23 -0500933 encodeRWTypeResponseHandler(request->hdr.instance_id,
Sampa Misra18967162020-01-14 02:31:41 -0600934 PLDM_WRITE_FILE_BY_TYPE,
935 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
936 return response;
937 }
938
939 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500940 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra69508502020-09-08 00:08:21 -0500941 offset, length, oemPlatformHandler);
Riya Dixit8394c452024-04-06 12:15:23 -0500942 encodeRWTypeResponseHandler(request->hdr.instance_id,
Sampa Misra18967162020-01-14 02:31:41 -0600943 PLDM_WRITE_FILE_BY_TYPE, rc, length,
944 responsePtr);
945 return response;
946}
947
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600948Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600949{
950 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
951 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
952
953 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
954 {
Riya Dixit8394c452024-04-06 12:15:23 -0500955 error(
956 "Failed to read file by type as payload length '{LENGTH}' less than '{REQ_LENGTH}'",
957 "LENGTH", payloadLength, "REQ_LENGTH",
958 PLDM_RW_FILE_BY_TYPE_REQ_BYTES);
959 encodeRWTypeResponseHandler(request->hdr.instance_id,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600960 PLDM_READ_FILE_BY_TYPE,
961 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
962 return response;
963 }
964 uint16_t fileType{};
965 uint32_t fileHandle{};
966 uint32_t offset{};
967 uint32_t length{};
968
969 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
970 &fileHandle, &offset, &length);
971 if (rc != PLDM_SUCCESS)
972 {
Riya Dixit8394c452024-04-06 12:15:23 -0500973 error(
974 "Failed to decode read file by type request, response code '{RC}'",
975 "RC", rc);
976 encodeRWTypeResponseHandler(request->hdr.instance_id,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600977 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
978 return response;
979 }
980
981 std::unique_ptr<FileHandler> handler{};
982 try
983 {
984 handler = getHandlerByType(fileType, fileHandle);
985 }
986 catch (const InternalFailure& e)
987 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500988 error("Unknown file type '{TYPE}', error - {ERROR}", "TYPE", fileType,
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500989 "ERROR", e);
Riya Dixit8394c452024-04-06 12:15:23 -0500990 encodeRWTypeResponseHandler(request->hdr.instance_id,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600991 PLDM_READ_FILE_BY_TYPE,
992 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
993 return response;
994 }
995
Sampa Misra69508502020-09-08 00:08:21 -0500996 rc = handler->read(offset, length, response, oemPlatformHandler);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600997 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Riya Dixit8394c452024-04-06 12:15:23 -0500998 encodeRWTypeResponseHandler(request->hdr.instance_id,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600999 PLDM_READ_FILE_BY_TYPE, rc, length,
1000 responsePtr);
1001 return response;
1002}
1003
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -06001004Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
1005{
1006 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
1007 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
1008
1009 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
1010 {
Riya Dixit8394c452024-04-06 12:15:23 -05001011 error(
1012 "Failed to do file ack as payload length '{LENGTH}' is less than '{REQ_LENGTH}'",
1013 "LENGTH", payloadLength, "REQ_LENGTH", PLDM_FILE_ACK_REQ_BYTES);
1014 encodeFileAckResponseHandler(request->hdr.instance_id,
1015 PLDM_ERROR_INVALID_LENGTH, responsePtr);
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -06001016 return response;
1017 }
1018 uint16_t fileType{};
1019 uint32_t fileHandle{};
1020 uint8_t fileStatus{};
1021
1022 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
1023 &fileHandle, &fileStatus);
1024 if (rc != PLDM_SUCCESS)
1025 {
Riya Dixit8394c452024-04-06 12:15:23 -05001026 encodeFileAckResponseHandler(request->hdr.instance_id, rc, responsePtr);
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -06001027 return response;
1028 }
1029
1030 std::unique_ptr<FileHandler> handler{};
1031 try
1032 {
1033 handler = getHandlerByType(fileType, fileHandle);
1034 }
Sampa Misra18967162020-01-14 02:31:41 -06001035
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -06001036 catch (const InternalFailure& e)
1037 {
Riya Dixitfc84f632024-04-06 14:00:02 -05001038 error("Unknown file type '{TYPE}', error - {ERROR}", "TYPE", fileType,
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -05001039 "ERROR", e);
Riya Dixit8394c452024-04-06 12:15:23 -05001040 encodeFileAckResponseHandler(request->hdr.instance_id,
1041 PLDM_INVALID_FILE_TYPE, responsePtr);
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -06001042 return response;
1043 }
1044
1045 rc = handler->fileAck(fileStatus);
Riya Dixit8394c452024-04-06 12:15:23 -05001046 encodeFileAckResponseHandler(request->hdr.instance_id, rc, responsePtr);
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -06001047 return response;
1048}
1049
George Liu89aad712020-03-12 13:34:51 +08001050Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
1051{
1052 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
1053 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
1054 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
1055 {
Riya Dixit8394c452024-04-06 12:15:23 -05001056 error(
1057 "Failed to get alert status as payload length '{LENGTH}' is less than '{REQ_LENGTH}'",
1058 "LENGTH", payloadLength, "REQ_LENGTH",
1059 PLDM_GET_ALERT_STATUS_REQ_BYTES);
George Liu89aad712020-03-12 13:34:51 +08001060 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
1061 }
1062
1063 uint8_t versionId{};
1064
1065 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
1066 if (rc != PLDM_SUCCESS)
1067 {
Riya Dixit8394c452024-04-06 12:15:23 -05001068 error("Failed to decode get alert status request, response code '{RC}'",
1069 "RC", rc);
George Liu89aad712020-03-12 13:34:51 +08001070 return CmdHandler::ccOnlyResponse(request, rc);
1071 }
1072
1073 if (versionId != 0)
1074 {
Riya Dixit8394c452024-04-06 12:15:23 -05001075 error(
1076 "Failed to get alert status due to unsupported version ID '{VERSION}'",
1077 "VERSION", versionId);
George Liu89aad712020-03-12 13:34:51 +08001078 return CmdHandler::ccOnlyResponse(request,
1079 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
1080 }
1081
1082 constexpr uint32_t rackEntry = 0xFF000030;
1083 constexpr uint32_t priCecNode = 0x00008030;
1084 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
1085 rackEntry, priCecNode, responsePtr,
1086 PLDM_GET_ALERT_STATUS_RESP_BYTES);
1087 if (rc != PLDM_SUCCESS)
1088 {
Riya Dixit8394c452024-04-06 12:15:23 -05001089 error(
1090 "Failed to encode get alert status response, response code '{RC}'",
1091 "RC", rc);
George Liu89aad712020-03-12 13:34:51 +08001092 return CmdHandler::ccOnlyResponse(request, rc);
1093 }
1094
1095 return response;
1096}
1097
Sampa Misra18967162020-01-14 02:31:41 -06001098Response Handler::newFileAvailable(const pldm_msg* request,
1099 size_t payloadLength)
1100{
1101 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
1102
1103 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
1104 {
Riya Dixit8394c452024-04-06 12:15:23 -05001105 error(
1106 "Failed new file available as payload length '{LENGTH}' is less than '{REQ_LENGTH}'",
1107 "LENGTH", payloadLength, "REQ_LENGTH", PLDM_NEW_FILE_REQ_BYTES);
Sampa Misra18967162020-01-14 02:31:41 -06001108 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
1109 }
1110 uint16_t fileType{};
1111 uint32_t fileHandle{};
1112 uint64_t length{};
1113
1114 auto rc = decode_new_file_req(request, payloadLength, &fileType,
1115 &fileHandle, &length);
1116
1117 if (rc != PLDM_SUCCESS)
1118 {
Riya Dixit8394c452024-04-06 12:15:23 -05001119 error("Failed to decode new file request, response code '{RC}'", "RC",
1120 rc);
Sampa Misra18967162020-01-14 02:31:41 -06001121 return CmdHandler::ccOnlyResponse(request, rc);
1122 }
1123
1124 std::unique_ptr<FileHandler> handler{};
1125 try
1126 {
1127 handler = getHandlerByType(fileType, fileHandle);
1128 }
1129 catch (const InternalFailure& e)
1130 {
Riya Dixitfc84f632024-04-06 14:00:02 -05001131 error("Unknown file type '{TYPE}', error - {ERROR}", "TYPE", fileType,
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -05001132 "ERROR", e);
Sampa Misra18967162020-01-14 02:31:41 -06001133 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
1134 }
1135
1136 rc = handler->newFileAvailable(length);
1137 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Riya Dixit8394c452024-04-06 12:15:23 -05001138 int responseCode = encode_new_file_resp(request->hdr.instance_id, rc,
1139 responsePtr);
1140 if (responseCode != PLDM_SUCCESS)
1141 {
1142 error(
1143 "Failed to encode new file available response, response code '{RC}'",
1144 "RC", responseCode);
1145 }
Sampa Misra18967162020-01-14 02:31:41 -06001146 return response;
1147}
1148
Deepak Kodihallibc669f12019-11-28 08:52:07 -06001149} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05301150} // namespace responder
1151} // namespace pldm