blob: 6f65b977e823f96353d8d21c143585dc28cf23f2 [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"
Sampa Misra854e61f2019-08-22 04:36:47 -05008#include "xyz/openbmc_project/Common/error.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05009
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053010#include <fcntl.h>
11#include <sys/mman.h>
12#include <sys/stat.h>
13#include <sys/types.h>
14#include <unistd.h>
15
16#include <cstring>
17#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060018#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050019#include <memory>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053020
21#include "libpldm/base.h"
22
23namespace pldm
24{
25
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{
30
31namespace fs = std::filesystem;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053032
33namespace dma
34{
35
36/** @struct AspeedXdmaOp
37 *
38 * Structure representing XDMA operation
39 */
40struct AspeedXdmaOp
41{
42 uint64_t hostAddr; //!< the DMA address on the host side, configured by
43 //!< PCI subsystem.
44 uint32_t len; //!< the size of the transfer in bytes, it should be a
45 //!< multiple of 16 bytes
46 uint32_t upstream; //!< boolean indicating the direction of the DMA
47 //!< operation, true means a transfer from BMC to host.
48};
49
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050050constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053051
52int DMA::transferDataHost(const fs::path& path, uint32_t offset,
53 uint32_t length, uint64_t address, bool upstream)
54{
55 static const size_t pageSize = getpagesize();
56 uint32_t numPages = length / pageSize;
57 uint32_t pageAlignedLength = numPages * pageSize;
58
59 if (length > pageAlignedLength)
60 {
61 pageAlignedLength += pageSize;
62 }
63
64 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
65 munmap(vgaMem, pageAlignedLength);
66 };
67
68 int fd = -1;
69 int rc = 0;
70 fd = open(xdmaDev, O_RDWR);
71 if (fd < 0)
72 {
73 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060074 std::cerr << "Failed to open the XDMA device, RC=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053075 return rc;
76 }
77
78 utils::CustomFD xdmaFd(fd);
79
80 void* vgaMem;
81 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
82 MAP_SHARED, xdmaFd(), 0);
83 if (MAP_FAILED == vgaMem)
84 {
85 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060086 std::cerr << "Failed to mmap the XDMA device, RC=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053087 return rc;
88 }
89
90 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
91
92 if (upstream)
93 {
Tom Joseph0c6d22c2019-06-26 09:58:41 +053094 std::ifstream stream(path.string(), std::ios::in | std::ios::binary);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053095 stream.seekg(offset);
Tom Joseph0c6d22c2019-06-26 09:58:41 +053096
97 // Writing to the VGA memory should be aligned at page boundary,
98 // otherwise write data into a buffer aligned at page boundary and
99 // then write to the VGA memory.
100 std::vector<char> buffer{};
101 buffer.resize(pageAlignedLength);
102 stream.read(buffer.data(), length);
103 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
104 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530105
106 if (static_cast<uint32_t>(stream.gcount()) != length)
107 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600108 std::cerr << "mismatch between number of characters to read and "
109 << "the length read, LENGTH=" << length
110 << " COUNT=" << stream.gcount() << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530111 return -1;
112 }
113 }
114
115 AspeedXdmaOp xdmaOp;
116 xdmaOp.upstream = upstream ? 1 : 0;
117 xdmaOp.hostAddr = address;
118 xdmaOp.len = length;
119
120 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
121 if (rc < 0)
122 {
123 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -0600124 std::cerr << "Failed to execute the DMA operation, RC=" << rc
125 << " UPSTREAM=" << upstream << " ADDRESS=" << address
126 << " LENGTH=" << length << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530127 return rc;
128 }
129
130 if (!upstream)
131 {
Sampa Misra854e61f2019-08-22 04:36:47 -0500132 std::ios_base::openmode mode = std::ios::out | std::ios::binary;
133 if (fs::exists(path))
134 {
135 mode |= std::ios::in;
136 }
137 std::ofstream stream(path.string(), mode);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530138
139 stream.seekp(offset);
140 stream.write(static_cast<const char*>(vgaMemPtr.get()), length);
141 }
142
143 return 0;
144}
145
146} // namespace dma
147
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600148namespace oem_ibm
149{
150
151Response Handler::readFileIntoMemory(const pldm_msg* request,
152 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530153{
154 uint32_t fileHandle = 0;
155 uint32_t offset = 0;
156 uint32_t length = 0;
157 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530158
159 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
160 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
161
162 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
163 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530164 encode_rw_file_memory_resp(request->hdr.instance_id,
165 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530166 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
167 return response;
168 }
169
Zahed Hossain223a73d2019-07-04 12:46:18 -0500170 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
171 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530172
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530173 using namespace pldm::filetable;
174 auto& table = buildFileTable(FILE_TABLE_JSON);
175 FileEntry value{};
176
177 try
178 {
179 value = table.at(fileHandle);
180 }
181 catch (std::exception& e)
182 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600183 std::cerr << "File handle does not exist in the file table, HANDLE="
184 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530185 encode_rw_file_memory_resp(request->hdr.instance_id,
186 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530187 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
188 return response;
189 }
190
191 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530192 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600193 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530194 encode_rw_file_memory_resp(request->hdr.instance_id,
195 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530196 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
197 return response;
198 }
199
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530200 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530201 if (offset >= fileSize)
202 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600203 std::cerr << "Offset exceeds file size, OFFSET=" << offset
204 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530205 encode_rw_file_memory_resp(request->hdr.instance_id,
206 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530207 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
208 return response;
209 }
210
211 if (offset + length > fileSize)
212 {
213 length = fileSize - offset;
214 }
215
216 if (length % dma::minSize)
217 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600218 std::cerr << "Read length is not a multiple of DMA minSize, LENGTH="
219 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530220 encode_rw_file_memory_resp(request->hdr.instance_id,
221 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530222 PLDM_INVALID_READ_LENGTH, 0, responsePtr);
223 return response;
224 }
225
226 using namespace dma;
227 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530228 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530229 offset, length, address, true,
230 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530231}
232
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600233Response Handler::writeFileFromMemory(const pldm_msg* request,
234 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530235{
236 uint32_t fileHandle = 0;
237 uint32_t offset = 0;
238 uint32_t length = 0;
239 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530240
241 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
242 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
243
244 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
245 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530246 encode_rw_file_memory_resp(request->hdr.instance_id,
247 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530248 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
249 return response;
250 }
251
Zahed Hossain223a73d2019-07-04 12:46:18 -0500252 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
253 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530254
255 if (length % dma::minSize)
256 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600257 std::cerr << "Write length is not a multiple of DMA minSize, LENGTH="
258 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530259 encode_rw_file_memory_resp(request->hdr.instance_id,
260 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530261 PLDM_INVALID_WRITE_LENGTH, 0, responsePtr);
262 return response;
263 }
264
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530265 using namespace pldm::filetable;
266 auto& table = buildFileTable(FILE_TABLE_JSON);
267 FileEntry value{};
268
269 try
270 {
271 value = table.at(fileHandle);
272 }
273 catch (std::exception& e)
274 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600275 std::cerr << "File handle does not exist in the file table, HANDLE="
276 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530277 encode_rw_file_memory_resp(request->hdr.instance_id,
278 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530279 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
280 return response;
281 }
282
283 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530284 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600285 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530286 encode_rw_file_memory_resp(request->hdr.instance_id,
287 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530288 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
289 return response;
290 }
291
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530292 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530293 if (offset >= fileSize)
294 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600295 std::cerr << "Offset exceeds file size, OFFSET=" << offset
296 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530297 encode_rw_file_memory_resp(request->hdr.instance_id,
298 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530299 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
300 return response;
301 }
302
303 using namespace dma;
304 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530305 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530306 offset, length, address, false,
307 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530308}
309
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600310Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530311{
312 uint32_t transferHandle = 0;
313 uint8_t transferFlag = 0;
314 uint8_t tableType = 0;
315
316 Response response(sizeof(pldm_msg_hdr) +
317 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
318 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
319
320 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
321 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530322 encode_get_file_table_resp(request->hdr.instance_id,
323 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
324 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530325 return response;
326 }
327
Zahed Hossain223a73d2019-07-04 12:46:18 -0500328 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
329 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530330 if (rc)
331 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530332 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
333 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530334 return response;
335 }
336
337 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
338 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530339 encode_get_file_table_resp(request->hdr.instance_id,
340 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
341 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530342 return response;
343 }
344
345 using namespace pldm::filetable;
346 auto table = buildFileTable(FILE_TABLE_JSON);
347 auto attrTable = table();
348 response.resize(response.size() + attrTable.size());
349 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
350
351 if (attrTable.empty())
352 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530353 encode_get_file_table_resp(request->hdr.instance_id,
354 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
355 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530356 return response;
357 }
358
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530359 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
360 PLDM_START_AND_END, attrTable.data(),
361 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530362 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530363}
364
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600365Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500366{
367 uint32_t fileHandle = 0;
368 uint32_t offset = 0;
369 uint32_t length = 0;
370
371 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
372 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
373
374 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
375 {
376 encode_read_file_resp(request->hdr.instance_id,
377 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
378 return response;
379 }
380
381 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
382 &length);
383
384 if (rc)
385 {
386 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
387 return response;
388 }
389
390 using namespace pldm::filetable;
391 auto& table = buildFileTable(FILE_TABLE_JSON);
392 FileEntry value{};
393
394 try
395 {
396 value = table.at(fileHandle);
397 }
398 catch (std::exception& e)
399 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600400 std::cerr << "File handle does not exist in the file table, HANDLE="
401 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500402 encode_read_file_resp(request->hdr.instance_id,
403 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
404 return response;
405 }
406
407 if (!fs::exists(value.fsPath))
408 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600409 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500410 encode_read_file_resp(request->hdr.instance_id,
411 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
412 return response;
413 }
414
415 auto fileSize = fs::file_size(value.fsPath);
416 if (offset >= fileSize)
417 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600418 std::cerr << "Offset exceeds file size, OFFSET=" << offset
419 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500420 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
421 length, responsePtr);
422 return response;
423 }
424
425 if (offset + length > fileSize)
426 {
427 length = fileSize - offset;
428 }
429
430 response.resize(response.size() + length);
431 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
432 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
433 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
434
435 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
436 stream.seekg(offset);
437 stream.read(fileDataPos, length);
438
439 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
440 responsePtr);
441
442 return response;
443}
444
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600445Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500446{
447 uint32_t fileHandle = 0;
448 uint32_t offset = 0;
449 uint32_t length = 0;
450 size_t fileDataOffset = 0;
451
452 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
453 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
454
455 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
456 {
457 encode_write_file_resp(request->hdr.instance_id,
458 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
459 return response;
460 }
461
462 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
463 &offset, &length, &fileDataOffset);
464
465 if (rc)
466 {
467 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
468 return response;
469 }
470
471 using namespace pldm::filetable;
472 auto& table = buildFileTable(FILE_TABLE_JSON);
473 FileEntry value{};
474
475 try
476 {
477 value = table.at(fileHandle);
478 }
479 catch (std::exception& e)
480 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600481 std::cerr << "File handle does not exist in the file table, HANDLE="
482 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500483 encode_write_file_resp(request->hdr.instance_id,
484 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
485 return response;
486 }
487
488 if (!fs::exists(value.fsPath))
489 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600490 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500491 encode_write_file_resp(request->hdr.instance_id,
492 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
493 return response;
494 }
495
496 auto fileSize = fs::file_size(value.fsPath);
497 if (offset >= fileSize)
498 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600499 std::cerr << "Offset exceeds file size, OFFSET=" << offset
500 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500501 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
502 0, responsePtr);
503 return response;
504 }
505
506 auto fileDataPos =
507 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
508
509 std::ofstream stream(value.fsPath,
510 std::ios::in | std::ios::out | std::ios::binary);
511 stream.seekp(offset);
512 stream.write(fileDataPos, length);
513
514 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
515 responsePtr);
516
517 return response;
518}
519
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600520Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
521 size_t payloadLength)
Sampa Misra854e61f2019-08-22 04:36:47 -0500522{
523 Response response(
524 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
525 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
526
527 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
528 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600529 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
530 PLDM_ERROR_INVALID_LENGTH, 0,
531 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500532 return response;
533 }
534
535 uint16_t fileType{};
536 uint32_t fileHandle{};
537 uint32_t offset{};
538 uint32_t length{};
539 uint64_t address{};
540 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
541 &fileType, &fileHandle, &offset,
542 &length, &address);
543 if (rc != PLDM_SUCCESS)
544 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600545 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
546 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500547 return response;
548 }
549 if (length % dma::minSize)
550 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600551 std::cerr << "Length is not a multiple of DMA minSize, LENGTH="
552 << length << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600553 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
554 PLDM_INVALID_WRITE_LENGTH, 0,
555 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500556 return response;
557 }
558
559 std::unique_ptr<FileHandler> handler{};
560 try
561 {
562 handler = getHandlerByType(fileType, fileHandle);
563 }
564 catch (const InternalFailure& e)
565 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600566 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600567 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
568 PLDM_INVALID_FILE_TYPE, 0,
569 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500570 return response;
571 }
572
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600573 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
574 ? handler->writeFromMemory(offset, length, address)
575 : handler->readIntoMemory(offset, length, address);
576 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500577 length, responsePtr);
578 return response;
579}
580
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600581Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
582 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600583{
584 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
585 payloadLength);
586}
587
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600588Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
589 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600590{
591 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
592 payloadLength);
593}
594
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600595Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600596{
597 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
598 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
599
600 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
601 {
602 encode_rw_file_by_type_resp(request->hdr.instance_id,
603 PLDM_READ_FILE_BY_TYPE,
604 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
605 return response;
606 }
607 uint16_t fileType{};
608 uint32_t fileHandle{};
609 uint32_t offset{};
610 uint32_t length{};
611
612 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
613 &fileHandle, &offset, &length);
614 if (rc != PLDM_SUCCESS)
615 {
616 encode_rw_file_by_type_resp(request->hdr.instance_id,
617 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
618 return response;
619 }
620
621 std::unique_ptr<FileHandler> handler{};
622 try
623 {
624 handler = getHandlerByType(fileType, fileHandle);
625 }
626 catch (const InternalFailure& e)
627 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600628 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600629 encode_rw_file_by_type_resp(request->hdr.instance_id,
630 PLDM_READ_FILE_BY_TYPE,
631 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
632 return response;
633 }
634
635 rc = handler->read(offset, length, response);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600636 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600637 encode_rw_file_by_type_resp(request->hdr.instance_id,
638 PLDM_READ_FILE_BY_TYPE, rc, length,
639 responsePtr);
640 return response;
641}
642
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600643} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530644} // namespace responder
645} // namespace pldm