blob: acf9d4a03bb49e9fbd1c0d4723cc4830adb7061c [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"
Ravi Tejace1c96f2020-10-05 23:13:01 -05007#include "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>
George Liuc453e162022-12-21 17:16:23 +080011#include <libpldm/base.h>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053012#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 Misraaa8ae722019-12-12 03:20:40 -060019#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050020#include <memory>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053021
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053022namespace pldm
23{
Ravi Tejace1c96f2020-10-05 23:13:01 -050024using namespace pldm::responder::utils;
Sampa Misra854e61f2019-08-22 04:36:47 -050025using namespace sdbusplus::xyz::openbmc_project::Common::Error;
26
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053027namespace responder
28{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053029namespace fs = std::filesystem;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053030
31namespace dma
32{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053033/** @struct AspeedXdmaOp
34 *
35 * Structure representing XDMA operation
36 */
37struct AspeedXdmaOp
38{
39 uint64_t hostAddr; //!< the DMA address on the host side, configured by
40 //!< PCI subsystem.
41 uint32_t len; //!< the size of the transfer in bytes, it should be a
42 //!< multiple of 16 bytes
43 uint32_t upstream; //!< boolean indicating the direction of the DMA
44 //!< operation, true means a transfer from BMC to host.
45};
46
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050047constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053048
Ravi Tejace1c96f2020-10-05 23:13:01 -050049int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
50{
51 static const size_t pageSize = getpagesize();
52 uint32_t numPages = length / pageSize;
53 uint32_t pageAlignedLength = numPages * pageSize;
54
55 if (length > pageAlignedLength)
56 {
57 pageAlignedLength += pageSize;
58 }
59
60 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
61 munmap(vgaMem, pageAlignedLength);
62 };
63
64 int dmaFd = -1;
65 int rc = 0;
66 dmaFd = open(xdmaDev, O_RDWR);
67 if (dmaFd < 0)
68 {
69 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -050070 std::cerr << "transferHostDataToSocket: Failed to open the XDMA device,"
71 " RC="
72 << rc << "\n";
Ravi Tejace1c96f2020-10-05 23:13:01 -050073 return rc;
74 }
75
76 pldm::utils::CustomFD xdmaFd(dmaFd);
77
78 void* vgaMem;
79 vgaMem =
80 mmap(nullptr, pageAlignedLength, PROT_READ, MAP_SHARED, xdmaFd(), 0);
81 if (MAP_FAILED == vgaMem)
82 {
83 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -050084 std::cerr << "transferHostDataToSocket: Failed to mmap the XDMA device,"
85 " RC="
86 << rc << "\n";
Ravi Tejace1c96f2020-10-05 23:13:01 -050087 return rc;
88 }
89
90 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
91
92 AspeedXdmaOp xdmaOp;
93 xdmaOp.upstream = 0;
94 xdmaOp.hostAddr = address;
95 xdmaOp.len = length;
96
97 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
98 if (rc < 0)
99 {
100 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500101 std::cerr << "transferHostDataToSocket: Failed to execute the DMA "
102 "operation, RC="
103 << rc << " ADDRESS=" << address << " LENGTH=" << length
104 << "\n";
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);
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500114 std::cerr << "transferHostDataToSocket: Closing socket as "
115 "writeToUnixSocket faile with RC="
116 << rc << std::endl;
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 {
142 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500143 << "transferDataHost: Received interrupt during DMA transfer."
144 " Skipping Unmap."
ArchanaKakani93409752022-04-19 00:36:04 -0500145 << std::endl;
146 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530147 };
148
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600149 int dmaFd = -1;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600150 dmaFd = open(xdmaDev, O_RDWR);
151 if (dmaFd < 0)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530152 {
153 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500154 std::cerr << "transferDataHost: Failed to open the XDMA device, RC="
155 << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530156 return rc;
157 }
158
George Liu83409572019-12-24 18:42:54 +0800159 pldm::utils::CustomFD xdmaFd(dmaFd);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530160
161 void* vgaMem;
162 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
163 MAP_SHARED, xdmaFd(), 0);
164 if (MAP_FAILED == vgaMem)
165 {
166 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500167 std::cerr << "transferDataHost: Failed to mmap the XDMA device, RC="
168 << rc << "\n";
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 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500179 std::cerr << "transferDataHost upstream: lseek failed, ERROR="
180 << errno << ", UPSTREAM=" << upstream
181 << ", OFFSET=" << offset << "\n";
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 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500193 std::cerr << "transferDataHost upstream: file read failed, ERROR="
194 << errno << ", UPSTREAM=" << upstream
195 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600196 return rc;
197 }
198 if (rc != static_cast<int>(length))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530199 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500200 std::cerr << "transferDataHost upstream: mismatch between number of"
201 << "characters to read and the length read, LENGTH="
202 << length << " COUNT=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530203 return -1;
204 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600205 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
206 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530207 }
208
209 AspeedXdmaOp xdmaOp;
210 xdmaOp.upstream = upstream ? 1 : 0;
211 xdmaOp.hostAddr = address;
212 xdmaOp.len = length;
213
214 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
215 if (rc < 0)
216 {
217 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500218 std::cerr << "transferDataHost: Failed to execute the DMA operation,"
219 " RC="
220 << rc << " UPSTREAM=" << upstream << " ADDRESS=" << address
Sampa Misraaa8ae722019-12-12 03:20:40 -0600221 << " LENGTH=" << length << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530222 return rc;
223 }
224
225 if (!upstream)
226 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600227 rc = lseek(fd, offset, SEEK_SET);
228 if (rc == -1)
Sampa Misra854e61f2019-08-22 04:36:47 -0500229 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500230 std::cerr << "transferDataHost downstream: lseek failed, ERROR="
231 << errno << ", UPSTREAM=" << upstream
232 << ", OFFSET=" << offset << "\n";
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600233 return rc;
Sampa Misra854e61f2019-08-22 04:36:47 -0500234 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600235 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
236 if (rc == -1)
237 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500238 std::cerr << "transferDataHost downstream: file write failed,"
239 " ERROR="
240 << errno << ", UPSTREAM=" << upstream
241 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600242 return rc;
243 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530244 }
245
246 return 0;
247}
248
249} // namespace dma
250
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600251namespace oem_ibm
252{
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600253Response Handler::readFileIntoMemory(const pldm_msg* request,
254 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530255{
256 uint32_t fileHandle = 0;
257 uint32_t offset = 0;
258 uint32_t length = 0;
259 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530260
261 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
262 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
263
264 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
265 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530266 encode_rw_file_memory_resp(request->hdr.instance_id,
267 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530268 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
269 return response;
270 }
271
Zahed Hossain223a73d2019-07-04 12:46:18 -0500272 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
273 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530274
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530275 using namespace pldm::filetable;
276 auto& table = buildFileTable(FILE_TABLE_JSON);
277 FileEntry value{};
278
279 try
280 {
281 value = table.at(fileHandle);
282 }
Patrick Williams51330582021-10-06 12:48:56 -0500283 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530284 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600285 std::cerr << "File handle does not exist in the file table, HANDLE="
286 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530287 encode_rw_file_memory_resp(request->hdr.instance_id,
288 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530289 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
290 return response;
291 }
292
293 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530294 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600295 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530296 encode_rw_file_memory_resp(request->hdr.instance_id,
297 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530298 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
299 return response;
300 }
301
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530302 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530303 if (offset >= fileSize)
304 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600305 std::cerr << "Offset exceeds file size, OFFSET=" << offset
306 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530307 encode_rw_file_memory_resp(request->hdr.instance_id,
308 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530309 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
310 return response;
311 }
312
313 if (offset + length > fileSize)
314 {
315 length = fileSize - offset;
316 }
317
318 if (length % dma::minSize)
319 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600320 std::cerr << "Read length is not a multiple of DMA minSize, LENGTH="
321 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530322 encode_rw_file_memory_resp(request->hdr.instance_id,
323 PLDM_READ_FILE_INTO_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500324 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530325 return response;
326 }
327
328 using namespace dma;
329 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530330 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530331 offset, length, address, true,
332 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530333}
334
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600335Response Handler::writeFileFromMemory(const pldm_msg* request,
336 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530337{
338 uint32_t fileHandle = 0;
339 uint32_t offset = 0;
340 uint32_t length = 0;
341 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530342
343 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
344 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
345
346 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
347 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530348 encode_rw_file_memory_resp(request->hdr.instance_id,
349 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530350 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
351 return response;
352 }
353
Zahed Hossain223a73d2019-07-04 12:46:18 -0500354 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
355 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530356
357 if (length % dma::minSize)
358 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600359 std::cerr << "Write length is not a multiple of DMA minSize, LENGTH="
360 << length << "\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,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500363 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530364 return response;
365 }
366
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530367 using namespace pldm::filetable;
368 auto& table = buildFileTable(FILE_TABLE_JSON);
369 FileEntry value{};
370
371 try
372 {
373 value = table.at(fileHandle);
374 }
Patrick Williams51330582021-10-06 12:48:56 -0500375 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530376 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600377 std::cerr << "File handle does not exist in the file table, HANDLE="
378 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530379 encode_rw_file_memory_resp(request->hdr.instance_id,
380 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530381 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
382 return response;
383 }
384
385 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530386 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600387 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530388 encode_rw_file_memory_resp(request->hdr.instance_id,
389 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530390 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
391 return response;
392 }
393
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530394 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530395 if (offset >= fileSize)
396 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600397 std::cerr << "Offset exceeds file size, OFFSET=" << offset
398 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530399 encode_rw_file_memory_resp(request->hdr.instance_id,
400 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530401 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
402 return response;
403 }
404
405 using namespace dma;
406 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530407 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530408 offset, length, address, false,
409 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530410}
411
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600412Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530413{
414 uint32_t transferHandle = 0;
415 uint8_t transferFlag = 0;
416 uint8_t tableType = 0;
417
418 Response response(sizeof(pldm_msg_hdr) +
419 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
420 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
421
422 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
423 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530424 encode_get_file_table_resp(request->hdr.instance_id,
425 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
426 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530427 return response;
428 }
429
Zahed Hossain223a73d2019-07-04 12:46:18 -0500430 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
431 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530432 if (rc)
433 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530434 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
435 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530436 return response;
437 }
438
439 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
440 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530441 encode_get_file_table_resp(request->hdr.instance_id,
442 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
443 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530444 return response;
445 }
446
447 using namespace pldm::filetable;
448 auto table = buildFileTable(FILE_TABLE_JSON);
449 auto attrTable = table();
450 response.resize(response.size() + attrTable.size());
451 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
452
453 if (attrTable.empty())
454 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530455 encode_get_file_table_resp(request->hdr.instance_id,
456 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
457 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530458 return response;
459 }
460
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530461 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
462 PLDM_START_AND_END, attrTable.data(),
463 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530464 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530465}
466
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600467Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500468{
469 uint32_t fileHandle = 0;
470 uint32_t offset = 0;
471 uint32_t length = 0;
472
473 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
474 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
475
476 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
477 {
478 encode_read_file_resp(request->hdr.instance_id,
479 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
480 return response;
481 }
482
483 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
484 &length);
485
486 if (rc)
487 {
488 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
489 return response;
490 }
491
492 using namespace pldm::filetable;
493 auto& table = buildFileTable(FILE_TABLE_JSON);
494 FileEntry value{};
495
496 try
497 {
498 value = table.at(fileHandle);
499 }
Patrick Williams51330582021-10-06 12:48:56 -0500500 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500501 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600502 std::cerr << "File handle does not exist in the file table, HANDLE="
503 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500504 encode_read_file_resp(request->hdr.instance_id,
505 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
506 return response;
507 }
508
509 if (!fs::exists(value.fsPath))
510 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600511 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500512 encode_read_file_resp(request->hdr.instance_id,
513 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
514 return response;
515 }
516
517 auto fileSize = fs::file_size(value.fsPath);
518 if (offset >= fileSize)
519 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600520 std::cerr << "Offset exceeds file size, OFFSET=" << offset
521 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500522 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
523 length, responsePtr);
524 return response;
525 }
526
527 if (offset + length > fileSize)
528 {
529 length = fileSize - offset;
530 }
531
532 response.resize(response.size() + length);
533 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
534 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
535 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
536
537 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
538 stream.seekg(offset);
539 stream.read(fileDataPos, length);
540
541 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
542 responsePtr);
543
544 return response;
545}
546
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600547Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500548{
549 uint32_t fileHandle = 0;
550 uint32_t offset = 0;
551 uint32_t length = 0;
552 size_t fileDataOffset = 0;
553
554 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
555 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
556
557 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
558 {
559 encode_write_file_resp(request->hdr.instance_id,
560 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
561 return response;
562 }
563
564 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
565 &offset, &length, &fileDataOffset);
566
567 if (rc)
568 {
569 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
570 return response;
571 }
572
573 using namespace pldm::filetable;
574 auto& table = buildFileTable(FILE_TABLE_JSON);
575 FileEntry value{};
576
577 try
578 {
579 value = table.at(fileHandle);
580 }
Patrick Williams51330582021-10-06 12:48:56 -0500581 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500582 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600583 std::cerr << "File handle does not exist in the file table, HANDLE="
584 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500585 encode_write_file_resp(request->hdr.instance_id,
586 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
587 return response;
588 }
589
590 if (!fs::exists(value.fsPath))
591 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600592 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500593 encode_write_file_resp(request->hdr.instance_id,
594 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
595 return response;
596 }
597
598 auto fileSize = fs::file_size(value.fsPath);
599 if (offset >= fileSize)
600 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600601 std::cerr << "Offset exceeds file size, OFFSET=" << offset
602 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500603 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
604 0, responsePtr);
605 return response;
606 }
607
608 auto fileDataPos =
609 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
610
611 std::ofstream stream(value.fsPath,
612 std::ios::in | std::ios::out | std::ios::binary);
613 stream.seekp(offset);
614 stream.write(fileDataPos, length);
615
616 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
617 responsePtr);
618
619 return response;
620}
621
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600622Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
Sampa Misra69508502020-09-08 00:08:21 -0500623 size_t payloadLength,
624 oem_platform::Handler* oemPlatformHandler)
Sampa Misra854e61f2019-08-22 04:36:47 -0500625{
626 Response response(
627 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
628 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
629
630 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
631 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600632 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
633 PLDM_ERROR_INVALID_LENGTH, 0,
634 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500635 return response;
636 }
637
638 uint16_t fileType{};
639 uint32_t fileHandle{};
640 uint32_t offset{};
641 uint32_t length{};
642 uint64_t address{};
643 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
644 &fileType, &fileHandle, &offset,
645 &length, &address);
646 if (rc != PLDM_SUCCESS)
647 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600648 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
649 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500650 return response;
651 }
652 if (length % dma::minSize)
653 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600654 std::cerr << "Length is not a multiple of DMA minSize, LENGTH="
655 << length << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600656 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500657 PLDM_ERROR_INVALID_LENGTH, 0,
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600658 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500659 return response;
660 }
661
662 std::unique_ptr<FileHandler> handler{};
663 try
664 {
665 handler = getHandlerByType(fileType, fileHandle);
666 }
667 catch (const InternalFailure& e)
668 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600669 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600670 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
671 PLDM_INVALID_FILE_TYPE, 0,
672 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500673 return response;
674 }
675
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600676 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
Sampa Misra69508502020-09-08 00:08:21 -0500677 ? handler->writeFromMemory(offset, length, address,
678 oemPlatformHandler)
679 : handler->readIntoMemory(offset, length, address,
680 oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600681 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500682 length, responsePtr);
683 return response;
684}
685
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600686Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
687 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600688{
689 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500690 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600691}
692
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600693Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
694 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600695{
696 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500697 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600698}
699
Sampa Misra18967162020-01-14 02:31:41 -0600700Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
701{
702 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
703 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
704
Sampa Misrad823cc02020-03-24 04:53:20 -0500705 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600706 {
707 encode_rw_file_by_type_resp(request->hdr.instance_id,
708 PLDM_WRITE_FILE_BY_TYPE,
709 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
710 return response;
711 }
712 uint16_t fileType{};
713 uint32_t fileHandle{};
714 uint32_t offset{};
715 uint32_t length{};
716
717 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
718 &fileHandle, &offset, &length);
719 if (rc != PLDM_SUCCESS)
720 {
721 encode_rw_file_by_type_resp(request->hdr.instance_id,
722 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
723 responsePtr);
724 return response;
725 }
726
727 std::unique_ptr<FileHandler> handler{};
728 try
729 {
730 handler = getHandlerByType(fileType, fileHandle);
731 }
732 catch (const InternalFailure& e)
733 {
734 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
735 encode_rw_file_by_type_resp(request->hdr.instance_id,
736 PLDM_WRITE_FILE_BY_TYPE,
737 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
738 return response;
739 }
740
741 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500742 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra69508502020-09-08 00:08:21 -0500743 offset, length, oemPlatformHandler);
Sampa Misra18967162020-01-14 02:31:41 -0600744 encode_rw_file_by_type_resp(request->hdr.instance_id,
745 PLDM_WRITE_FILE_BY_TYPE, rc, length,
746 responsePtr);
747 return response;
748}
749
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600750Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600751{
752 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
753 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
754
755 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
756 {
757 encode_rw_file_by_type_resp(request->hdr.instance_id,
758 PLDM_READ_FILE_BY_TYPE,
759 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
760 return response;
761 }
762 uint16_t fileType{};
763 uint32_t fileHandle{};
764 uint32_t offset{};
765 uint32_t length{};
766
767 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
768 &fileHandle, &offset, &length);
769 if (rc != PLDM_SUCCESS)
770 {
771 encode_rw_file_by_type_resp(request->hdr.instance_id,
772 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
773 return response;
774 }
775
776 std::unique_ptr<FileHandler> handler{};
777 try
778 {
779 handler = getHandlerByType(fileType, fileHandle);
780 }
781 catch (const InternalFailure& e)
782 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600783 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600784 encode_rw_file_by_type_resp(request->hdr.instance_id,
785 PLDM_READ_FILE_BY_TYPE,
786 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
787 return response;
788 }
789
Sampa Misra69508502020-09-08 00:08:21 -0500790 rc = handler->read(offset, length, response, oemPlatformHandler);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600791 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600792 encode_rw_file_by_type_resp(request->hdr.instance_id,
793 PLDM_READ_FILE_BY_TYPE, rc, length,
794 responsePtr);
795 return response;
796}
797
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600798Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
799{
800 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
801 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
802
803 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
804 {
805 encode_file_ack_resp(request->hdr.instance_id,
806 PLDM_ERROR_INVALID_LENGTH, responsePtr);
807 return response;
808 }
809 uint16_t fileType{};
810 uint32_t fileHandle{};
811 uint8_t fileStatus{};
812
813 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
814 &fileHandle, &fileStatus);
815 if (rc != PLDM_SUCCESS)
816 {
817 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
818 return response;
819 }
820
821 std::unique_ptr<FileHandler> handler{};
822 try
823 {
824 handler = getHandlerByType(fileType, fileHandle);
825 }
Sampa Misra18967162020-01-14 02:31:41 -0600826
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600827 catch (const InternalFailure& e)
828 {
829 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
830 responsePtr);
831 return response;
832 }
833
834 rc = handler->fileAck(fileStatus);
835 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
836 return response;
837}
838
George Liu89aad712020-03-12 13:34:51 +0800839Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
840{
841 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
842 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
843 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
844 {
845 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
846 }
847
848 uint8_t versionId{};
849
850 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
851 if (rc != PLDM_SUCCESS)
852 {
853 return CmdHandler::ccOnlyResponse(request, rc);
854 }
855
856 if (versionId != 0)
857 {
858 return CmdHandler::ccOnlyResponse(request,
859 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
860 }
861
862 constexpr uint32_t rackEntry = 0xFF000030;
863 constexpr uint32_t priCecNode = 0x00008030;
864 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
865 rackEntry, priCecNode, responsePtr,
866 PLDM_GET_ALERT_STATUS_RESP_BYTES);
867 if (rc != PLDM_SUCCESS)
868 {
869 return CmdHandler::ccOnlyResponse(request, rc);
870 }
871
872 return response;
873}
874
Sampa Misra18967162020-01-14 02:31:41 -0600875Response Handler::newFileAvailable(const pldm_msg* request,
876 size_t payloadLength)
877{
878 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
879
880 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
881 {
882 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
883 }
884 uint16_t fileType{};
885 uint32_t fileHandle{};
886 uint64_t length{};
887
888 auto rc = decode_new_file_req(request, payloadLength, &fileType,
889 &fileHandle, &length);
890
891 if (rc != PLDM_SUCCESS)
892 {
893 return CmdHandler::ccOnlyResponse(request, rc);
894 }
895
896 std::unique_ptr<FileHandler> handler{};
897 try
898 {
899 handler = getHandlerByType(fileType, fileHandle);
900 }
901 catch (const InternalFailure& e)
902 {
903 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
904 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
905 }
906
907 rc = handler->newFileAvailable(length);
908 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
909 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr);
910 return response;
911}
912
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600913} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530914} // namespace responder
915} // namespace pldm