blob: 7d46a3890ec1ca7ab326816cecbda1060f4f5597 [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 }
Patrick Williams51330582021-10-06 12:48:56 -0500265 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530266 {
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 }
Patrick Williams51330582021-10-06 12:48:56 -0500357 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530358 {
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 }
Patrick Williams51330582021-10-06 12:48:56 -0500482 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500483 {
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 }
Patrick Williams51330582021-10-06 12:48:56 -0500563 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500564 {
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,
Sampa Misra69508502020-09-08 00:08:21 -0500605 size_t payloadLength,
606 oem_platform::Handler* oemPlatformHandler)
Sampa Misra854e61f2019-08-22 04:36:47 -0500607{
608 Response response(
609 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
610 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
611
612 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
613 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600614 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
615 PLDM_ERROR_INVALID_LENGTH, 0,
616 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500617 return response;
618 }
619
620 uint16_t fileType{};
621 uint32_t fileHandle{};
622 uint32_t offset{};
623 uint32_t length{};
624 uint64_t address{};
625 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
626 &fileType, &fileHandle, &offset,
627 &length, &address);
628 if (rc != PLDM_SUCCESS)
629 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600630 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
631 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500632 return response;
633 }
634 if (length % dma::minSize)
635 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600636 std::cerr << "Length is not a multiple of DMA minSize, LENGTH="
637 << length << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600638 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500639 PLDM_ERROR_INVALID_LENGTH, 0,
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600640 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500641 return response;
642 }
643
644 std::unique_ptr<FileHandler> handler{};
645 try
646 {
647 handler = getHandlerByType(fileType, fileHandle);
648 }
649 catch (const InternalFailure& e)
650 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600651 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600652 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
653 PLDM_INVALID_FILE_TYPE, 0,
654 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500655 return response;
656 }
657
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600658 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
Sampa Misra69508502020-09-08 00:08:21 -0500659 ? handler->writeFromMemory(offset, length, address,
660 oemPlatformHandler)
661 : handler->readIntoMemory(offset, length, address,
662 oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600663 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500664 length, responsePtr);
665 return response;
666}
667
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600668Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
669 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600670{
671 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500672 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600673}
674
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600675Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
676 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600677{
678 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500679 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600680}
681
Sampa Misra18967162020-01-14 02:31:41 -0600682Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
683{
684 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
685 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
686
Sampa Misrad823cc02020-03-24 04:53:20 -0500687 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600688 {
689 encode_rw_file_by_type_resp(request->hdr.instance_id,
690 PLDM_WRITE_FILE_BY_TYPE,
691 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
692 return response;
693 }
694 uint16_t fileType{};
695 uint32_t fileHandle{};
696 uint32_t offset{};
697 uint32_t length{};
698
699 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
700 &fileHandle, &offset, &length);
701 if (rc != PLDM_SUCCESS)
702 {
703 encode_rw_file_by_type_resp(request->hdr.instance_id,
704 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
705 responsePtr);
706 return response;
707 }
708
709 std::unique_ptr<FileHandler> handler{};
710 try
711 {
712 handler = getHandlerByType(fileType, fileHandle);
713 }
714 catch (const InternalFailure& e)
715 {
716 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
717 encode_rw_file_by_type_resp(request->hdr.instance_id,
718 PLDM_WRITE_FILE_BY_TYPE,
719 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
720 return response;
721 }
722
723 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500724 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra69508502020-09-08 00:08:21 -0500725 offset, length, oemPlatformHandler);
Sampa Misra18967162020-01-14 02:31:41 -0600726 encode_rw_file_by_type_resp(request->hdr.instance_id,
727 PLDM_WRITE_FILE_BY_TYPE, rc, length,
728 responsePtr);
729 return response;
730}
731
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600732Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600733{
734 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
735 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
736
737 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
738 {
739 encode_rw_file_by_type_resp(request->hdr.instance_id,
740 PLDM_READ_FILE_BY_TYPE,
741 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
742 return response;
743 }
744 uint16_t fileType{};
745 uint32_t fileHandle{};
746 uint32_t offset{};
747 uint32_t length{};
748
749 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
750 &fileHandle, &offset, &length);
751 if (rc != PLDM_SUCCESS)
752 {
753 encode_rw_file_by_type_resp(request->hdr.instance_id,
754 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
755 return response;
756 }
757
758 std::unique_ptr<FileHandler> handler{};
759 try
760 {
761 handler = getHandlerByType(fileType, fileHandle);
762 }
763 catch (const InternalFailure& e)
764 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600765 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600766 encode_rw_file_by_type_resp(request->hdr.instance_id,
767 PLDM_READ_FILE_BY_TYPE,
768 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
769 return response;
770 }
771
Sampa Misra69508502020-09-08 00:08:21 -0500772 rc = handler->read(offset, length, response, oemPlatformHandler);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600773 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600774 encode_rw_file_by_type_resp(request->hdr.instance_id,
775 PLDM_READ_FILE_BY_TYPE, rc, length,
776 responsePtr);
777 return response;
778}
779
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600780Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
781{
782 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
783 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
784
785 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
786 {
787 encode_file_ack_resp(request->hdr.instance_id,
788 PLDM_ERROR_INVALID_LENGTH, responsePtr);
789 return response;
790 }
791 uint16_t fileType{};
792 uint32_t fileHandle{};
793 uint8_t fileStatus{};
794
795 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
796 &fileHandle, &fileStatus);
797 if (rc != PLDM_SUCCESS)
798 {
799 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
800 return response;
801 }
802
803 std::unique_ptr<FileHandler> handler{};
804 try
805 {
806 handler = getHandlerByType(fileType, fileHandle);
807 }
Sampa Misra18967162020-01-14 02:31:41 -0600808
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600809 catch (const InternalFailure& e)
810 {
811 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
812 responsePtr);
813 return response;
814 }
815
816 rc = handler->fileAck(fileStatus);
817 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
818 return response;
819}
820
George Liu89aad712020-03-12 13:34:51 +0800821Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
822{
823 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
824 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
825 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
826 {
827 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
828 }
829
830 uint8_t versionId{};
831
832 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
833 if (rc != PLDM_SUCCESS)
834 {
835 return CmdHandler::ccOnlyResponse(request, rc);
836 }
837
838 if (versionId != 0)
839 {
840 return CmdHandler::ccOnlyResponse(request,
841 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
842 }
843
844 constexpr uint32_t rackEntry = 0xFF000030;
845 constexpr uint32_t priCecNode = 0x00008030;
846 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
847 rackEntry, priCecNode, responsePtr,
848 PLDM_GET_ALERT_STATUS_RESP_BYTES);
849 if (rc != PLDM_SUCCESS)
850 {
851 return CmdHandler::ccOnlyResponse(request, rc);
852 }
853
854 return response;
855}
856
Sampa Misra18967162020-01-14 02:31:41 -0600857Response Handler::newFileAvailable(const pldm_msg* request,
858 size_t payloadLength)
859{
860 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
861
862 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
863 {
864 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
865 }
866 uint16_t fileType{};
867 uint32_t fileHandle{};
868 uint64_t length{};
869
870 auto rc = decode_new_file_req(request, payloadLength, &fileType,
871 &fileHandle, &length);
872
873 if (rc != PLDM_SUCCESS)
874 {
875 return CmdHandler::ccOnlyResponse(request, rc);
876 }
877
878 std::unique_ptr<FileHandler> handler{};
879 try
880 {
881 handler = getHandlerByType(fileType, fileHandle);
882 }
883 catch (const InternalFailure& e)
884 {
885 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
886 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
887 }
888
889 rc = handler->newFileAvailable(length);
890 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
891 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr);
892 return response;
893}
894
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600895} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530896} // namespace responder
897} // namespace pldm