blob: 692ae1b521cddac55b21b96ba22acc206926a24e [file] [log] [blame]
Tom Joseph0c6d22c2019-06-26 09:58:41 +05301#include "config.h"
2
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05303#include "file_io.hpp"
4
Sampa Misra854e61f2019-08-22 04:36:47 -05005#include "file_io_by_type.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05306#include "file_table.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05007#include "libpldmresponder/utils.hpp"
8#include "registration.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05009#include "xyz/openbmc_project/Common/error.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050010
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053011#include <fcntl.h>
12#include <sys/mman.h>
13#include <sys/stat.h>
14#include <sys/types.h>
15#include <unistd.h>
16
17#include <cstring>
18#include <fstream>
Sampa Misra854e61f2019-08-22 04:36:47 -050019#include <memory>
20#include <phosphor-logging/elog-errors.hpp>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053021#include <phosphor-logging/log.hpp>
22
23#include "libpldm/base.h"
24
25namespace pldm
26{
27
Sampa Misra854e61f2019-08-22 04:36:47 -050028using namespace phosphor::logging;
29using namespace sdbusplus::xyz::openbmc_project::Common::Error;
30
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053031namespace responder
32{
33
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050034namespace oem_ibm
35{
36
37void registerHandlers()
38{
Tom Joseph0c6d22c2019-06-26 09:58:41 +053039 registerHandler(PLDM_OEM, PLDM_GET_FILE_TABLE, std::move(getFileTable));
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050040 registerHandler(PLDM_OEM, PLDM_READ_FILE_INTO_MEMORY,
41 std::move(readFileIntoMemory));
42 registerHandler(PLDM_OEM, PLDM_WRITE_FILE_FROM_MEMORY,
43 std::move(writeFileFromMemory));
vkaverap5b914c32019-06-30 22:23:54 -050044 registerHandler(PLDM_OEM, PLDM_READ_FILE, std::move(readFile));
45 registerHandler(PLDM_OEM, PLDM_WRITE_FILE, std::move(writeFile));
Sampa Misra854e61f2019-08-22 04:36:47 -050046 registerHandler(PLDM_OEM, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
47 std::move(writeFileByTypeFromMemory));
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050048}
49
50} // namespace oem_ibm
51
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053052namespace fs = std::filesystem;
53using namespace phosphor::logging;
54
55namespace dma
56{
57
58/** @struct AspeedXdmaOp
59 *
60 * Structure representing XDMA operation
61 */
62struct AspeedXdmaOp
63{
64 uint64_t hostAddr; //!< the DMA address on the host side, configured by
65 //!< PCI subsystem.
66 uint32_t len; //!< the size of the transfer in bytes, it should be a
67 //!< multiple of 16 bytes
68 uint32_t upstream; //!< boolean indicating the direction of the DMA
69 //!< operation, true means a transfer from BMC to host.
70};
71
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050072constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053073
74int DMA::transferDataHost(const fs::path& path, uint32_t offset,
75 uint32_t length, uint64_t address, bool upstream)
76{
77 static const size_t pageSize = getpagesize();
78 uint32_t numPages = length / pageSize;
79 uint32_t pageAlignedLength = numPages * pageSize;
80
81 if (length > pageAlignedLength)
82 {
83 pageAlignedLength += pageSize;
84 }
85
86 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
87 munmap(vgaMem, pageAlignedLength);
88 };
89
90 int fd = -1;
91 int rc = 0;
92 fd = open(xdmaDev, O_RDWR);
93 if (fd < 0)
94 {
95 rc = -errno;
96 log<level::ERR>("Failed to open the XDMA device", entry("RC=%d", rc));
97 return rc;
98 }
99
100 utils::CustomFD xdmaFd(fd);
101
102 void* vgaMem;
103 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
104 MAP_SHARED, xdmaFd(), 0);
105 if (MAP_FAILED == vgaMem)
106 {
107 rc = -errno;
108 log<level::ERR>("Failed to mmap the XDMA device", entry("RC=%d", rc));
109 return rc;
110 }
111
112 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
113
114 if (upstream)
115 {
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530116 std::ifstream stream(path.string(), std::ios::in | std::ios::binary);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530117 stream.seekg(offset);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530118
119 // Writing to the VGA memory should be aligned at page boundary,
120 // otherwise write data into a buffer aligned at page boundary and
121 // then write to the VGA memory.
122 std::vector<char> buffer{};
123 buffer.resize(pageAlignedLength);
124 stream.read(buffer.data(), length);
125 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
126 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530127
128 if (static_cast<uint32_t>(stream.gcount()) != length)
129 {
130 log<level::ERR>("mismatch between number of characters to read and "
131 "the length read",
132 entry("LENGTH=%d", length),
133 entry("COUNT=%d", stream.gcount()));
134 return -1;
135 }
136 }
137
138 AspeedXdmaOp xdmaOp;
139 xdmaOp.upstream = upstream ? 1 : 0;
140 xdmaOp.hostAddr = address;
141 xdmaOp.len = length;
142
143 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
144 if (rc < 0)
145 {
146 rc = -errno;
147 log<level::ERR>("Failed to execute the DMA operation",
148 entry("RC=%d", rc), entry("UPSTREAM=%d", upstream),
149 entry("ADDRESS=%lld", address),
150 entry("LENGTH=%d", length));
151 return rc;
152 }
153
154 if (!upstream)
155 {
Sampa Misra854e61f2019-08-22 04:36:47 -0500156 std::ios_base::openmode mode = std::ios::out | std::ios::binary;
157 if (fs::exists(path))
158 {
159 mode |= std::ios::in;
160 }
161 std::ofstream stream(path.string(), mode);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530162
163 stream.seekp(offset);
164 stream.write(static_cast<const char*>(vgaMemPtr.get()), length);
165 }
166
167 return 0;
168}
169
170} // namespace dma
171
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500172Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530173{
174 uint32_t fileHandle = 0;
175 uint32_t offset = 0;
176 uint32_t length = 0;
177 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530178
179 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
180 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
181
182 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
183 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530184 encode_rw_file_memory_resp(request->hdr.instance_id,
185 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530186 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
187 return response;
188 }
189
Zahed Hossain223a73d2019-07-04 12:46:18 -0500190 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
191 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530192
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530193 using namespace pldm::filetable;
194 auto& table = buildFileTable(FILE_TABLE_JSON);
195 FileEntry value{};
196
197 try
198 {
199 value = table.at(fileHandle);
200 }
201 catch (std::exception& e)
202 {
203 log<level::ERR>("File handle does not exist in the file table",
204 entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530205 encode_rw_file_memory_resp(request->hdr.instance_id,
206 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530207 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
208 return response;
209 }
210
211 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530212 {
213 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530214 encode_rw_file_memory_resp(request->hdr.instance_id,
215 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530216 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
217 return response;
218 }
219
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530220 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530221 if (offset >= fileSize)
222 {
223 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
224 entry("FILE_SIZE=%d", fileSize));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530225 encode_rw_file_memory_resp(request->hdr.instance_id,
226 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530227 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
228 return response;
229 }
230
231 if (offset + length > fileSize)
232 {
233 length = fileSize - offset;
234 }
235
236 if (length % dma::minSize)
237 {
238 log<level::ERR>("Read length is not a multiple of DMA minSize",
239 entry("LENGTH=%d", length));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530240 encode_rw_file_memory_resp(request->hdr.instance_id,
241 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530242 PLDM_INVALID_READ_LENGTH, 0, responsePtr);
243 return response;
244 }
245
246 using namespace dma;
247 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530248 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530249 offset, length, address, true,
250 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530251}
252
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500253Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530254{
255 uint32_t fileHandle = 0;
256 uint32_t offset = 0;
257 uint32_t length = 0;
258 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530259
260 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
261 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
262
263 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
264 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530265 encode_rw_file_memory_resp(request->hdr.instance_id,
266 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530267 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
268 return response;
269 }
270
Zahed Hossain223a73d2019-07-04 12:46:18 -0500271 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
272 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530273
274 if (length % dma::minSize)
275 {
276 log<level::ERR>("Write length is not a multiple of DMA minSize",
277 entry("LENGTH=%d", length));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530278 encode_rw_file_memory_resp(request->hdr.instance_id,
279 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530280 PLDM_INVALID_WRITE_LENGTH, 0, responsePtr);
281 return response;
282 }
283
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530284 using namespace pldm::filetable;
285 auto& table = buildFileTable(FILE_TABLE_JSON);
286 FileEntry value{};
287
288 try
289 {
290 value = table.at(fileHandle);
291 }
292 catch (std::exception& e)
293 {
294 log<level::ERR>("File handle does not exist in the file table",
295 entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530296 encode_rw_file_memory_resp(request->hdr.instance_id,
297 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530298 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
299 return response;
300 }
301
302 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530303 {
304 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530305 encode_rw_file_memory_resp(request->hdr.instance_id,
306 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530307 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
308 return response;
309 }
310
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530311 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530312 if (offset >= fileSize)
313 {
314 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
315 entry("FILE_SIZE=%d", fileSize));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530316 encode_rw_file_memory_resp(request->hdr.instance_id,
317 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530318 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
319 return response;
320 }
321
322 using namespace dma;
323 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530324 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530325 offset, length, address, false,
326 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530327}
328
329Response getFileTable(const pldm_msg* request, size_t payloadLength)
330{
331 uint32_t transferHandle = 0;
332 uint8_t transferFlag = 0;
333 uint8_t tableType = 0;
334
335 Response response(sizeof(pldm_msg_hdr) +
336 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
337 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
338
339 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
340 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530341 encode_get_file_table_resp(request->hdr.instance_id,
342 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
343 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530344 return response;
345 }
346
Zahed Hossain223a73d2019-07-04 12:46:18 -0500347 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
348 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530349 if (rc)
350 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530351 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
352 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530353 return response;
354 }
355
356 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
357 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530358 encode_get_file_table_resp(request->hdr.instance_id,
359 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
360 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530361 return response;
362 }
363
364 using namespace pldm::filetable;
365 auto table = buildFileTable(FILE_TABLE_JSON);
366 auto attrTable = table();
367 response.resize(response.size() + attrTable.size());
368 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
369
370 if (attrTable.empty())
371 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530372 encode_get_file_table_resp(request->hdr.instance_id,
373 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
374 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530375 return response;
376 }
377
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530378 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
379 PLDM_START_AND_END, attrTable.data(),
380 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530381 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530382}
383
vkaverap5b914c32019-06-30 22:23:54 -0500384Response readFile(const pldm_msg* request, size_t payloadLength)
385{
386 uint32_t fileHandle = 0;
387 uint32_t offset = 0;
388 uint32_t length = 0;
389
390 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
391 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
392
393 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
394 {
395 encode_read_file_resp(request->hdr.instance_id,
396 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
397 return response;
398 }
399
400 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
401 &length);
402
403 if (rc)
404 {
405 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
406 return response;
407 }
408
409 using namespace pldm::filetable;
410 auto& table = buildFileTable(FILE_TABLE_JSON);
411 FileEntry value{};
412
413 try
414 {
415 value = table.at(fileHandle);
416 }
417 catch (std::exception& e)
418 {
419 log<level::ERR>("File handle does not exist in the file table",
420 entry("HANDLE=%d", fileHandle));
421 encode_read_file_resp(request->hdr.instance_id,
422 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
423 return response;
424 }
425
426 if (!fs::exists(value.fsPath))
427 {
428 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
429 encode_read_file_resp(request->hdr.instance_id,
430 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
431 return response;
432 }
433
434 auto fileSize = fs::file_size(value.fsPath);
435 if (offset >= fileSize)
436 {
437 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
438 entry("FILE_SIZE=%d", fileSize));
439 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
440 length, responsePtr);
441 return response;
442 }
443
444 if (offset + length > fileSize)
445 {
446 length = fileSize - offset;
447 }
448
449 response.resize(response.size() + length);
450 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
451 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
452 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
453
454 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
455 stream.seekg(offset);
456 stream.read(fileDataPos, length);
457
458 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
459 responsePtr);
460
461 return response;
462}
463
464Response writeFile(const pldm_msg* request, size_t payloadLength)
465{
466 uint32_t fileHandle = 0;
467 uint32_t offset = 0;
468 uint32_t length = 0;
469 size_t fileDataOffset = 0;
470
471 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
472 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
473
474 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
475 {
476 encode_write_file_resp(request->hdr.instance_id,
477 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
478 return response;
479 }
480
481 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
482 &offset, &length, &fileDataOffset);
483
484 if (rc)
485 {
486 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
487 return response;
488 }
489
490 using namespace pldm::filetable;
491 auto& table = buildFileTable(FILE_TABLE_JSON);
492 FileEntry value{};
493
494 try
495 {
496 value = table.at(fileHandle);
497 }
498 catch (std::exception& e)
499 {
500 log<level::ERR>("File handle does not exist in the file table",
501 entry("HANDLE=%d", fileHandle));
502 encode_write_file_resp(request->hdr.instance_id,
503 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
504 return response;
505 }
506
507 if (!fs::exists(value.fsPath))
508 {
509 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
510 encode_write_file_resp(request->hdr.instance_id,
511 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
512 return response;
513 }
514
515 auto fileSize = fs::file_size(value.fsPath);
516 if (offset >= fileSize)
517 {
518 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
519 entry("FILE_SIZE=%d", fileSize));
520 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
521 0, responsePtr);
522 return response;
523 }
524
525 auto fileDataPos =
526 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
527
528 std::ofstream stream(value.fsPath,
529 std::ios::in | std::ios::out | std::ios::binary);
530 stream.seekp(offset);
531 stream.write(fileDataPos, length);
532
533 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
534 responsePtr);
535
536 return response;
537}
538
Sampa Misra854e61f2019-08-22 04:36:47 -0500539Response writeFileByTypeFromMemory(const pldm_msg* request,
540 size_t payloadLength)
541{
542 Response response(
543 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
544 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
545
546 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
547 {
548 encode_rw_file_by_type_memory_resp(
549 request->hdr.instance_id, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
550 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
551 return response;
552 }
553
554 uint16_t fileType{};
555 uint32_t fileHandle{};
556 uint32_t offset{};
557 uint32_t length{};
558 uint64_t address{};
559 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
560 &fileType, &fileHandle, &offset,
561 &length, &address);
562 if (rc != PLDM_SUCCESS)
563 {
564 encode_rw_file_by_type_memory_resp(request->hdr.instance_id,
565 PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
566 rc, 0, responsePtr);
567 return response;
568 }
569 if (length % dma::minSize)
570 {
571 log<level::ERR>("Write length is not a multiple of DMA minSize",
572 entry("LENGTH=%d", length));
573 encode_rw_file_by_type_memory_resp(
574 request->hdr.instance_id, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
575 PLDM_INVALID_WRITE_LENGTH, 0, responsePtr);
576 return response;
577 }
578
579 std::unique_ptr<FileHandler> handler{};
580 try
581 {
582 handler = getHandlerByType(fileType, fileHandle);
583 }
584 catch (const InternalFailure& e)
585 {
586 log<level::ERR>("unknown file type ", entry("TYPE=%d", fileType));
587 encode_rw_file_by_type_memory_resp(
588 request->hdr.instance_id, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
589 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
590 return response;
591 }
592
593 rc = handler->writeFromMemory(offset, length, address);
594 encode_rw_file_by_type_memory_resp(request->hdr.instance_id,
595 PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, rc,
596 length, responsePtr);
597 return response;
598}
599
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530600} // namespace responder
601} // namespace pldm