blob: 6b963d077f6016f269b406e8a100da215e561648 [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
George Liu6492f522020-06-16 10:34:05 +08005#include "libpldm/base.h"
6
Sampa Misra854e61f2019-08-22 04:36:47 -05007#include "file_io_by_type.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05308#include "file_table.hpp"
Ravi Tejace1c96f2020-10-05 23:13:01 -05009#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050010#include "xyz/openbmc_project/Common/error.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050011
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053012#include <fcntl.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
17
18#include <cstring>
19#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060020#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050021#include <memory>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053022
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{
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
Ravi Tejace1c96f2020-10-05 23:13:01 -050052int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
53{
54 static const size_t pageSize = getpagesize();
55 uint32_t numPages = length / pageSize;
56 uint32_t pageAlignedLength = numPages * pageSize;
57
58 if (length > pageAlignedLength)
59 {
60 pageAlignedLength += pageSize;
61 }
62
63 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
64 munmap(vgaMem, pageAlignedLength);
65 };
66
67 int dmaFd = -1;
68 int rc = 0;
69 dmaFd = open(xdmaDev, O_RDWR);
70 if (dmaFd < 0)
71 {
72 rc = -errno;
73 std::cerr << "Failed to open the XDMA device, RC=" << rc << "\n";
74 return rc;
75 }
76
77 pldm::utils::CustomFD xdmaFd(dmaFd);
78
79 void* vgaMem;
80 vgaMem =
81 mmap(nullptr, pageAlignedLength, PROT_READ, MAP_SHARED, xdmaFd(), 0);
82 if (MAP_FAILED == vgaMem)
83 {
84 rc = -errno;
85 std::cerr << "Failed to mmap the XDMA device, RC=" << rc << "\n";
86 return rc;
87 }
88
89 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
90
91 AspeedXdmaOp xdmaOp;
92 xdmaOp.upstream = 0;
93 xdmaOp.hostAddr = address;
94 xdmaOp.len = length;
95
96 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
97 if (rc < 0)
98 {
99 rc = -errno;
100 std::cerr << "Failed to execute the DMA operation, RC=" << rc
101 << " ADDRESS=" << address << " LENGTH=" << length << "\n";
102 return rc;
103 }
104
105 rc = writeToUnixSocket(fd, static_cast<const char*>(vgaMemPtr.get()),
106 length);
107 if (rc < 0)
108 {
109 rc = -errno;
110 close(fd);
111 std::cerr << "closing socket" << std::endl;
112 return rc;
113 }
114 return 0;
115}
116
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600117int DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
118 uint64_t address, bool upstream)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530119{
120 static const size_t pageSize = getpagesize();
121 uint32_t numPages = length / pageSize;
122 uint32_t pageAlignedLength = numPages * pageSize;
123
124 if (length > pageAlignedLength)
125 {
126 pageAlignedLength += pageSize;
127 }
128
129 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
130 munmap(vgaMem, pageAlignedLength);
131 };
132
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600133 int dmaFd = -1;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530134 int rc = 0;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600135 dmaFd = open(xdmaDev, O_RDWR);
136 if (dmaFd < 0)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530137 {
138 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -0600139 std::cerr << "Failed to open the XDMA device, RC=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530140 return rc;
141 }
142
George Liu83409572019-12-24 18:42:54 +0800143 pldm::utils::CustomFD xdmaFd(dmaFd);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530144
145 void* vgaMem;
146 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
147 MAP_SHARED, xdmaFd(), 0);
148 if (MAP_FAILED == vgaMem)
149 {
150 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -0600151 std::cerr << "Failed to mmap the XDMA device, RC=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530152 return rc;
153 }
154
155 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
156
157 if (upstream)
158 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600159 rc = lseek(fd, offset, SEEK_SET);
160 if (rc == -1)
161 {
162 std::cerr << "lseek failed, ERROR=" << errno
163 << ", UPSTREAM=" << upstream << ", OFFSET=" << offset
164 << "\n";
165 return rc;
166 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530167
168 // Writing to the VGA memory should be aligned at page boundary,
169 // otherwise write data into a buffer aligned at page boundary and
170 // then write to the VGA memory.
171 std::vector<char> buffer{};
172 buffer.resize(pageAlignedLength);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600173 rc = read(fd, buffer.data(), length);
174 if (rc == -1)
175 {
176 std::cerr << "file read failed, ERROR=" << errno
177 << ", UPSTREAM=" << upstream << ", LENGTH=" << length
178 << ", OFFSET=" << offset << "\n";
179 return rc;
180 }
181 if (rc != static_cast<int>(length))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530182 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600183 std::cerr << "mismatch between number of characters to read and "
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600184 << "the length read, LENGTH=" << length << " COUNT=" << rc
185 << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530186 return -1;
187 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600188 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
189 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530190 }
191
192 AspeedXdmaOp xdmaOp;
193 xdmaOp.upstream = upstream ? 1 : 0;
194 xdmaOp.hostAddr = address;
195 xdmaOp.len = length;
196
197 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
198 if (rc < 0)
199 {
200 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -0600201 std::cerr << "Failed to execute the DMA operation, RC=" << rc
202 << " UPSTREAM=" << upstream << " ADDRESS=" << address
203 << " LENGTH=" << length << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530204 return rc;
205 }
206
207 if (!upstream)
208 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600209 rc = lseek(fd, offset, SEEK_SET);
210 if (rc == -1)
Sampa Misra854e61f2019-08-22 04:36:47 -0500211 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600212 std::cerr << "lseek failed, ERROR=" << errno
213 << ", UPSTREAM=" << upstream << ", OFFSET=" << offset
214 << "\n";
215 return rc;
Sampa Misra854e61f2019-08-22 04:36:47 -0500216 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600217 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
218 if (rc == -1)
219 {
220 std::cerr << "file write failed, ERROR=" << errno
221 << ", UPSTREAM=" << upstream << ", LENGTH=" << length
222 << ", OFFSET=" << offset << "\n";
223 return rc;
224 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530225 }
226
227 return 0;
228}
229
230} // namespace dma
231
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600232namespace oem_ibm
233{
234
235Response Handler::readFileIntoMemory(const pldm_msg* request,
236 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530237{
238 uint32_t fileHandle = 0;
239 uint32_t offset = 0;
240 uint32_t length = 0;
241 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530242
243 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
244 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
245
246 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
247 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530248 encode_rw_file_memory_resp(request->hdr.instance_id,
249 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530250 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
251 return response;
252 }
253
Zahed Hossain223a73d2019-07-04 12:46:18 -0500254 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
255 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530256
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530257 using namespace pldm::filetable;
258 auto& table = buildFileTable(FILE_TABLE_JSON);
259 FileEntry value{};
260
261 try
262 {
263 value = table.at(fileHandle);
264 }
265 catch (std::exception& e)
266 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600267 std::cerr << "File handle does not exist in the file table, HANDLE="
268 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530269 encode_rw_file_memory_resp(request->hdr.instance_id,
270 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530271 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
272 return response;
273 }
274
275 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530276 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600277 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530278 encode_rw_file_memory_resp(request->hdr.instance_id,
279 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530280 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
281 return response;
282 }
283
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530284 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530285 if (offset >= fileSize)
286 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600287 std::cerr << "Offset exceeds file size, OFFSET=" << offset
288 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530289 encode_rw_file_memory_resp(request->hdr.instance_id,
290 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530291 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
292 return response;
293 }
294
295 if (offset + length > fileSize)
296 {
297 length = fileSize - offset;
298 }
299
300 if (length % dma::minSize)
301 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600302 std::cerr << "Read length is not a multiple of DMA minSize, LENGTH="
303 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530304 encode_rw_file_memory_resp(request->hdr.instance_id,
305 PLDM_READ_FILE_INTO_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500306 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530307 return response;
308 }
309
310 using namespace dma;
311 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530312 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530313 offset, length, address, true,
314 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530315}
316
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600317Response Handler::writeFileFromMemory(const pldm_msg* request,
318 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530319{
320 uint32_t fileHandle = 0;
321 uint32_t offset = 0;
322 uint32_t length = 0;
323 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530324
325 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
326 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
327
328 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
329 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530330 encode_rw_file_memory_resp(request->hdr.instance_id,
331 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530332 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
333 return response;
334 }
335
Zahed Hossain223a73d2019-07-04 12:46:18 -0500336 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
337 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530338
339 if (length % dma::minSize)
340 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600341 std::cerr << "Write length is not a multiple of DMA minSize, LENGTH="
342 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530343 encode_rw_file_memory_resp(request->hdr.instance_id,
344 PLDM_WRITE_FILE_FROM_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500345 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530346 return response;
347 }
348
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530349 using namespace pldm::filetable;
350 auto& table = buildFileTable(FILE_TABLE_JSON);
351 FileEntry value{};
352
353 try
354 {
355 value = table.at(fileHandle);
356 }
357 catch (std::exception& e)
358 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600359 std::cerr << "File handle does not exist in the file table, HANDLE="
360 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530361 encode_rw_file_memory_resp(request->hdr.instance_id,
362 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530363 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
364 return response;
365 }
366
367 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530368 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600369 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530370 encode_rw_file_memory_resp(request->hdr.instance_id,
371 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530372 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
373 return response;
374 }
375
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530376 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530377 if (offset >= fileSize)
378 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600379 std::cerr << "Offset exceeds file size, OFFSET=" << offset
380 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530381 encode_rw_file_memory_resp(request->hdr.instance_id,
382 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530383 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
384 return response;
385 }
386
387 using namespace dma;
388 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530389 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530390 offset, length, address, false,
391 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530392}
393
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600394Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530395{
396 uint32_t transferHandle = 0;
397 uint8_t transferFlag = 0;
398 uint8_t tableType = 0;
399
400 Response response(sizeof(pldm_msg_hdr) +
401 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
402 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
403
404 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
405 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530406 encode_get_file_table_resp(request->hdr.instance_id,
407 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
408 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530409 return response;
410 }
411
Zahed Hossain223a73d2019-07-04 12:46:18 -0500412 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
413 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530414 if (rc)
415 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530416 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
417 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530418 return response;
419 }
420
421 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
422 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530423 encode_get_file_table_resp(request->hdr.instance_id,
424 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
425 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530426 return response;
427 }
428
429 using namespace pldm::filetable;
430 auto table = buildFileTable(FILE_TABLE_JSON);
431 auto attrTable = table();
432 response.resize(response.size() + attrTable.size());
433 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
434
435 if (attrTable.empty())
436 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530437 encode_get_file_table_resp(request->hdr.instance_id,
438 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
439 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530440 return response;
441 }
442
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530443 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
444 PLDM_START_AND_END, attrTable.data(),
445 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530446 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530447}
448
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600449Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500450{
451 uint32_t fileHandle = 0;
452 uint32_t offset = 0;
453 uint32_t length = 0;
454
455 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
456 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
457
458 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
459 {
460 encode_read_file_resp(request->hdr.instance_id,
461 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
462 return response;
463 }
464
465 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
466 &length);
467
468 if (rc)
469 {
470 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
471 return response;
472 }
473
474 using namespace pldm::filetable;
475 auto& table = buildFileTable(FILE_TABLE_JSON);
476 FileEntry value{};
477
478 try
479 {
480 value = table.at(fileHandle);
481 }
482 catch (std::exception& e)
483 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600484 std::cerr << "File handle does not exist in the file table, HANDLE="
485 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500486 encode_read_file_resp(request->hdr.instance_id,
487 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
488 return response;
489 }
490
491 if (!fs::exists(value.fsPath))
492 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600493 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500494 encode_read_file_resp(request->hdr.instance_id,
495 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
496 return response;
497 }
498
499 auto fileSize = fs::file_size(value.fsPath);
500 if (offset >= fileSize)
501 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600502 std::cerr << "Offset exceeds file size, OFFSET=" << offset
503 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500504 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
505 length, responsePtr);
506 return response;
507 }
508
509 if (offset + length > fileSize)
510 {
511 length = fileSize - offset;
512 }
513
514 response.resize(response.size() + length);
515 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
516 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
517 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
518
519 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
520 stream.seekg(offset);
521 stream.read(fileDataPos, length);
522
523 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
524 responsePtr);
525
526 return response;
527}
528
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600529Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500530{
531 uint32_t fileHandle = 0;
532 uint32_t offset = 0;
533 uint32_t length = 0;
534 size_t fileDataOffset = 0;
535
536 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
537 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
538
539 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
540 {
541 encode_write_file_resp(request->hdr.instance_id,
542 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
543 return response;
544 }
545
546 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
547 &offset, &length, &fileDataOffset);
548
549 if (rc)
550 {
551 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
552 return response;
553 }
554
555 using namespace pldm::filetable;
556 auto& table = buildFileTable(FILE_TABLE_JSON);
557 FileEntry value{};
558
559 try
560 {
561 value = table.at(fileHandle);
562 }
563 catch (std::exception& e)
564 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600565 std::cerr << "File handle does not exist in the file table, HANDLE="
566 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500567 encode_write_file_resp(request->hdr.instance_id,
568 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
569 return response;
570 }
571
572 if (!fs::exists(value.fsPath))
573 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600574 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500575 encode_write_file_resp(request->hdr.instance_id,
576 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
577 return response;
578 }
579
580 auto fileSize = fs::file_size(value.fsPath);
581 if (offset >= fileSize)
582 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600583 std::cerr << "Offset exceeds file size, OFFSET=" << offset
584 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500585 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
586 0, responsePtr);
587 return response;
588 }
589
590 auto fileDataPos =
591 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
592
593 std::ofstream stream(value.fsPath,
594 std::ios::in | std::ios::out | std::ios::binary);
595 stream.seekp(offset);
596 stream.write(fileDataPos, length);
597
598 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
599 responsePtr);
600
601 return response;
602}
603
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600604Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
605 size_t payloadLength)
Sampa Misra854e61f2019-08-22 04:36:47 -0500606{
607 Response response(
608 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
609 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
610
611 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
612 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600613 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
614 PLDM_ERROR_INVALID_LENGTH, 0,
615 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500616 return response;
617 }
618
619 uint16_t fileType{};
620 uint32_t fileHandle{};
621 uint32_t offset{};
622 uint32_t length{};
623 uint64_t address{};
624 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
625 &fileType, &fileHandle, &offset,
626 &length, &address);
627 if (rc != PLDM_SUCCESS)
628 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600629 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
630 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500631 return response;
632 }
633 if (length % dma::minSize)
634 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600635 std::cerr << "Length is not a multiple of DMA minSize, LENGTH="
636 << length << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600637 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500638 PLDM_ERROR_INVALID_LENGTH, 0,
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600639 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500640 return response;
641 }
642
643 std::unique_ptr<FileHandler> handler{};
644 try
645 {
646 handler = getHandlerByType(fileType, fileHandle);
647 }
648 catch (const InternalFailure& e)
649 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600650 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600651 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
652 PLDM_INVALID_FILE_TYPE, 0,
653 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500654 return response;
655 }
656
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600657 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
658 ? handler->writeFromMemory(offset, length, address)
659 : handler->readIntoMemory(offset, length, address);
660 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500661 length, responsePtr);
662 return response;
663}
664
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600665Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
666 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600667{
668 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
669 payloadLength);
670}
671
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600672Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
673 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600674{
675 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
676 payloadLength);
677}
678
Sampa Misra18967162020-01-14 02:31:41 -0600679Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
680{
681 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
682 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
683
Sampa Misrad823cc02020-03-24 04:53:20 -0500684 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600685 {
686 encode_rw_file_by_type_resp(request->hdr.instance_id,
687 PLDM_WRITE_FILE_BY_TYPE,
688 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
689 return response;
690 }
691 uint16_t fileType{};
692 uint32_t fileHandle{};
693 uint32_t offset{};
694 uint32_t length{};
695
696 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
697 &fileHandle, &offset, &length);
698 if (rc != PLDM_SUCCESS)
699 {
700 encode_rw_file_by_type_resp(request->hdr.instance_id,
701 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
702 responsePtr);
703 return response;
704 }
705
706 std::unique_ptr<FileHandler> handler{};
707 try
708 {
709 handler = getHandlerByType(fileType, fileHandle);
710 }
711 catch (const InternalFailure& e)
712 {
713 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
714 encode_rw_file_by_type_resp(request->hdr.instance_id,
715 PLDM_WRITE_FILE_BY_TYPE,
716 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
717 return response;
718 }
719
720 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500721 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra18967162020-01-14 02:31:41 -0600722 offset, length);
723 encode_rw_file_by_type_resp(request->hdr.instance_id,
724 PLDM_WRITE_FILE_BY_TYPE, rc, length,
725 responsePtr);
726 return response;
727}
728
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600729Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600730{
731 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
732 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
733
734 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
735 {
736 encode_rw_file_by_type_resp(request->hdr.instance_id,
737 PLDM_READ_FILE_BY_TYPE,
738 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
739 return response;
740 }
741 uint16_t fileType{};
742 uint32_t fileHandle{};
743 uint32_t offset{};
744 uint32_t length{};
745
746 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
747 &fileHandle, &offset, &length);
748 if (rc != PLDM_SUCCESS)
749 {
750 encode_rw_file_by_type_resp(request->hdr.instance_id,
751 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
752 return response;
753 }
754
755 std::unique_ptr<FileHandler> handler{};
756 try
757 {
758 handler = getHandlerByType(fileType, fileHandle);
759 }
760 catch (const InternalFailure& e)
761 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600762 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600763 encode_rw_file_by_type_resp(request->hdr.instance_id,
764 PLDM_READ_FILE_BY_TYPE,
765 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
766 return response;
767 }
768
769 rc = handler->read(offset, length, response);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600770 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600771 encode_rw_file_by_type_resp(request->hdr.instance_id,
772 PLDM_READ_FILE_BY_TYPE, rc, length,
773 responsePtr);
774 return response;
775}
776
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600777Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
778{
779 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
780 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
781
782 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
783 {
784 encode_file_ack_resp(request->hdr.instance_id,
785 PLDM_ERROR_INVALID_LENGTH, responsePtr);
786 return response;
787 }
788 uint16_t fileType{};
789 uint32_t fileHandle{};
790 uint8_t fileStatus{};
791
792 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
793 &fileHandle, &fileStatus);
794 if (rc != PLDM_SUCCESS)
795 {
796 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
797 return response;
798 }
799
800 std::unique_ptr<FileHandler> handler{};
801 try
802 {
803 handler = getHandlerByType(fileType, fileHandle);
804 }
Sampa Misra18967162020-01-14 02:31:41 -0600805
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600806 catch (const InternalFailure& e)
807 {
808 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
809 responsePtr);
810 return response;
811 }
812
813 rc = handler->fileAck(fileStatus);
814 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
815 return response;
816}
817
George Liu89aad712020-03-12 13:34:51 +0800818Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
819{
820 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
821 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
822 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
823 {
824 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
825 }
826
827 uint8_t versionId{};
828
829 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
830 if (rc != PLDM_SUCCESS)
831 {
832 return CmdHandler::ccOnlyResponse(request, rc);
833 }
834
835 if (versionId != 0)
836 {
837 return CmdHandler::ccOnlyResponse(request,
838 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
839 }
840
841 constexpr uint32_t rackEntry = 0xFF000030;
842 constexpr uint32_t priCecNode = 0x00008030;
843 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
844 rackEntry, priCecNode, responsePtr,
845 PLDM_GET_ALERT_STATUS_RESP_BYTES);
846 if (rc != PLDM_SUCCESS)
847 {
848 return CmdHandler::ccOnlyResponse(request, rc);
849 }
850
851 return response;
852}
853
Sampa Misra18967162020-01-14 02:31:41 -0600854Response Handler::newFileAvailable(const pldm_msg* request,
855 size_t payloadLength)
856{
857 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
858
859 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
860 {
861 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
862 }
863 uint16_t fileType{};
864 uint32_t fileHandle{};
865 uint64_t length{};
866
867 auto rc = decode_new_file_req(request, payloadLength, &fileType,
868 &fileHandle, &length);
869
870 if (rc != PLDM_SUCCESS)
871 {
872 return CmdHandler::ccOnlyResponse(request, rc);
873 }
874
875 std::unique_ptr<FileHandler> handler{};
876 try
877 {
878 handler = getHandlerByType(fileType, fileHandle);
879 }
880 catch (const InternalFailure& e)
881 {
882 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
883 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
884 }
885
886 rc = handler->newFileAvailable(length);
887 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
888 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr);
889 return response;
890}
891
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600892} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530893} // namespace responder
894} // namespace pldm