blob: 96a1c7130c15d0b743b098d0f69eaa342205d875 [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
Riya Dixit49cfb132023-03-02 04:26:53 -060017#include <phosphor-logging/lg2.hpp>
18
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053019#include <cstring>
20#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060021#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050022#include <memory>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053023
Riya Dixit49cfb132023-03-02 04:26:53 -060024PHOSPHOR_LOG2_USING;
25
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053026namespace pldm
27{
Ravi Tejace1c96f2020-10-05 23:13:01 -050028using namespace pldm::responder::utils;
Sampa Misra854e61f2019-08-22 04:36:47 -050029using namespace sdbusplus::xyz::openbmc_project::Common::Error;
30
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053031namespace responder
32{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053033namespace fs = std::filesystem;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053034
35namespace dma
36{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053037/** @struct AspeedXdmaOp
38 *
39 * Structure representing XDMA operation
40 */
41struct AspeedXdmaOp
42{
43 uint64_t hostAddr; //!< the DMA address on the host side, configured by
44 //!< PCI subsystem.
45 uint32_t len; //!< the size of the transfer in bytes, it should be a
46 //!< multiple of 16 bytes
47 uint32_t upstream; //!< boolean indicating the direction of the DMA
48 //!< operation, true means a transfer from BMC to host.
49};
50
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050051constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053052
Ravi Tejace1c96f2020-10-05 23:13:01 -050053int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
54{
55 static const size_t pageSize = getpagesize();
56 uint32_t numPages = length / pageSize;
57 uint32_t pageAlignedLength = numPages * pageSize;
58
59 if (length > pageAlignedLength)
60 {
61 pageAlignedLength += pageSize;
62 }
63
64 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
65 munmap(vgaMem, pageAlignedLength);
66 };
67
68 int dmaFd = -1;
69 int rc = 0;
70 dmaFd = open(xdmaDev, O_RDWR);
71 if (dmaFd < 0)
72 {
73 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -060074 error(
75 "transferHostDataToSocket: Failed to open the XDMA device, RC={RC}",
76 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -050077 return rc;
78 }
79
80 pldm::utils::CustomFD xdmaFd(dmaFd);
81
82 void* vgaMem;
83 vgaMem =
84 mmap(nullptr, pageAlignedLength, PROT_READ, MAP_SHARED, xdmaFd(), 0);
85 if (MAP_FAILED == vgaMem)
86 {
87 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -060088 error(
89 "transferHostDataToSocket : Failed to mmap the XDMA device, RC={RC}",
90 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -050091 return rc;
92 }
93
94 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
95
96 AspeedXdmaOp xdmaOp;
97 xdmaOp.upstream = 0;
98 xdmaOp.hostAddr = address;
99 xdmaOp.len = length;
100
101 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
102 if (rc < 0)
103 {
104 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600105 error(
106 "transferHostDataToSocket: Failed to execute the DMA operation, RC={RC} ADDRESS={ADDR} LENGTH={LEN}",
107 "RC", rc, "ADDR", address, "LEN", length);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500108 return rc;
109 }
110
111 rc = writeToUnixSocket(fd, static_cast<const char*>(vgaMemPtr.get()),
112 length);
113 if (rc < 0)
114 {
115 rc = -errno;
116 close(fd);
Riya Dixit49cfb132023-03-02 04:26:53 -0600117 error(
118 "transferHostDataToSocket: Closing socket as writeToUnixSocket faile with RC={RC}",
119 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500120 return rc;
121 }
122 return 0;
123}
124
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600125int DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
126 uint64_t address, bool upstream)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530127{
128 static const size_t pageSize = getpagesize();
129 uint32_t numPages = length / pageSize;
130 uint32_t pageAlignedLength = numPages * pageSize;
131
132 if (length > pageAlignedLength)
133 {
134 pageAlignedLength += pageSize;
135 }
136
ArchanaKakani93409752022-04-19 00:36:04 -0500137 int rc = 0;
138 auto mmapCleanup = [pageAlignedLength, &rc](void* vgaMem) {
139 if (rc != -EINTR)
140 {
141 munmap(vgaMem, pageAlignedLength);
142 }
143 else
144 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600145 error(
146 "transferDataHost: Received interrupt during DMA transfer. Skipping Unmap.");
ArchanaKakani93409752022-04-19 00:36:04 -0500147 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530148 };
149
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600150 int dmaFd = -1;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600151 dmaFd = open(xdmaDev, O_RDWR);
152 if (dmaFd < 0)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530153 {
154 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600155 error("transferDataHost : Failed to open the XDMA device, RC={RC}",
156 "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530157 return rc;
158 }
159
George Liu83409572019-12-24 18:42:54 +0800160 pldm::utils::CustomFD xdmaFd(dmaFd);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530161
162 void* vgaMem;
163 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
164 MAP_SHARED, xdmaFd(), 0);
165 if (MAP_FAILED == vgaMem)
166 {
167 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600168 error("transferDataHost : Failed to mmap the XDMA device, RC={RC}",
169 "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530170 return rc;
171 }
172
173 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
174
175 if (upstream)
176 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600177 rc = lseek(fd, offset, SEEK_SET);
178 if (rc == -1)
179 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600180 error(
181 "transferDataHost upstream : lseek failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, OFFSET={OFFSET}",
182 "ERR", errno, "UPSTREAM", upstream, "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600183 return rc;
184 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530185
186 // Writing to the VGA memory should be aligned at page boundary,
187 // otherwise write data into a buffer aligned at page boundary and
188 // then write to the VGA memory.
189 std::vector<char> buffer{};
190 buffer.resize(pageAlignedLength);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600191 rc = read(fd, buffer.data(), length);
192 if (rc == -1)
193 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600194 error(
195 "transferDataHost upstream : file read failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, LENGTH={LEN}, OFFSET={OFFSET}",
196 "ERR", errno, "UPSTREAM", upstream, "LEN", length, "OFFSET",
197 offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600198 return rc;
199 }
200 if (rc != static_cast<int>(length))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530201 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600202 error(
203 "transferDataHost upstream : mismatch between number of characters to read and the length read, LENGTH={LEN} COUNT={RC}",
204 "LEN", length, "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530205 return -1;
206 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600207 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
208 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530209 }
210
211 AspeedXdmaOp xdmaOp;
212 xdmaOp.upstream = upstream ? 1 : 0;
213 xdmaOp.hostAddr = address;
214 xdmaOp.len = length;
215
216 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
217 if (rc < 0)
218 {
219 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600220 error(
221 "transferDataHost : Failed to execute the DMA operation, RC={RC} UPSTREAM={UPSTREAM} ADDRESS={ADDR} LENGTH={LEN}",
222 "RC", rc, "UPSTREAM", upstream, "ADDR", address, "LEN", length);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530223 return rc;
224 }
225
226 if (!upstream)
227 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600228 rc = lseek(fd, offset, SEEK_SET);
229 if (rc == -1)
Sampa Misra854e61f2019-08-22 04:36:47 -0500230 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600231 error(
232 "transferDataHost downstream : lseek failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, OFFSET={OFFSET}",
233 "ERR", errno, "UPSTREAM", upstream, "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600234 return rc;
Sampa Misra854e61f2019-08-22 04:36:47 -0500235 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600236 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
237 if (rc == -1)
238 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600239 error(
240 "transferDataHost downstream : file write failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, LENGTH={LEN}, OFFSET={OFFSET}",
241 "ERR", errno, "UPSTREAM", upstream, "LEN", length, "OFFSET",
242 offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600243 return rc;
244 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530245 }
246
247 return 0;
248}
249
250} // namespace dma
251
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600252namespace oem_ibm
253{
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600254Response Handler::readFileIntoMemory(const pldm_msg* request,
255 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530256{
257 uint32_t fileHandle = 0;
258 uint32_t offset = 0;
259 uint32_t length = 0;
260 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530261
262 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
263 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
264
265 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
266 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530267 encode_rw_file_memory_resp(request->hdr.instance_id,
268 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530269 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
270 return response;
271 }
272
Zahed Hossain223a73d2019-07-04 12:46:18 -0500273 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
274 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530275
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530276 using namespace pldm::filetable;
277 auto& table = buildFileTable(FILE_TABLE_JSON);
278 FileEntry value{};
279
280 try
281 {
282 value = table.at(fileHandle);
283 }
Patrick Williams51330582021-10-06 12:48:56 -0500284 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530285 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600286 error(
287 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
288 "FILE_HANDLE", fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530289 encode_rw_file_memory_resp(request->hdr.instance_id,
290 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530291 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
292 return response;
293 }
294
295 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530296 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600297 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
298 fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530299 encode_rw_file_memory_resp(request->hdr.instance_id,
300 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530301 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
302 return response;
303 }
304
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530305 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530306 if (offset >= fileSize)
307 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600308 error("Offset exceeds file size, OFFSET={OFFSTE} FILE_SIZE={FILE_SIZE}",
309 "OFFSET", offset, "FILE_SIZE", fileSize);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530310 encode_rw_file_memory_resp(request->hdr.instance_id,
311 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530312 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
313 return response;
314 }
315
316 if (offset + length > fileSize)
317 {
318 length = fileSize - offset;
319 }
320
321 if (length % dma::minSize)
322 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600323 error("Read length is not a multiple of DMA minSize, LENGTH={LEN}",
324 "LEN", length);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530325 encode_rw_file_memory_resp(request->hdr.instance_id,
326 PLDM_READ_FILE_INTO_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500327 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530328 return response;
329 }
330
331 using namespace dma;
332 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530333 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530334 offset, length, address, true,
335 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530336}
337
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600338Response Handler::writeFileFromMemory(const pldm_msg* request,
339 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530340{
341 uint32_t fileHandle = 0;
342 uint32_t offset = 0;
343 uint32_t length = 0;
344 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530345
346 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
347 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
348
349 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
350 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530351 encode_rw_file_memory_resp(request->hdr.instance_id,
352 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530353 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
354 return response;
355 }
356
Zahed Hossain223a73d2019-07-04 12:46:18 -0500357 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
358 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530359
360 if (length % dma::minSize)
361 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600362 error("Write length is not a multiple of DMA minSize, LENGTH={LEN}",
363 "LEN", length);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530364 encode_rw_file_memory_resp(request->hdr.instance_id,
365 PLDM_WRITE_FILE_FROM_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500366 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530367 return response;
368 }
369
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530370 using namespace pldm::filetable;
371 auto& table = buildFileTable(FILE_TABLE_JSON);
372 FileEntry value{};
373
374 try
375 {
376 value = table.at(fileHandle);
377 }
Patrick Williams51330582021-10-06 12:48:56 -0500378 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530379 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600380 error(
381 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
382 "FILE_HANDLE", fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530383 encode_rw_file_memory_resp(request->hdr.instance_id,
384 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530385 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
386 return response;
387 }
388
389 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530390 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600391 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
392 fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530393 encode_rw_file_memory_resp(request->hdr.instance_id,
394 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530395 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
396 return response;
397 }
398
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530399 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530400 if (offset >= fileSize)
401 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600402 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
403 "OFFSET", offset, "FILE_SIZE", fileSize);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530404 encode_rw_file_memory_resp(request->hdr.instance_id,
405 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530406 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
407 return response;
408 }
409
410 using namespace dma;
411 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530412 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530413 offset, length, address, false,
414 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530415}
416
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600417Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530418{
419 uint32_t transferHandle = 0;
420 uint8_t transferFlag = 0;
421 uint8_t tableType = 0;
422
423 Response response(sizeof(pldm_msg_hdr) +
424 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
425 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
426
427 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
428 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530429 encode_get_file_table_resp(request->hdr.instance_id,
430 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
431 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530432 return response;
433 }
434
Zahed Hossain223a73d2019-07-04 12:46:18 -0500435 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
436 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530437 if (rc)
438 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530439 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
440 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530441 return response;
442 }
443
444 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
445 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530446 encode_get_file_table_resp(request->hdr.instance_id,
447 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
448 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530449 return response;
450 }
451
452 using namespace pldm::filetable;
453 auto table = buildFileTable(FILE_TABLE_JSON);
454 auto attrTable = table();
455 response.resize(response.size() + attrTable.size());
456 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
457
458 if (attrTable.empty())
459 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530460 encode_get_file_table_resp(request->hdr.instance_id,
461 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
462 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530463 return response;
464 }
465
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530466 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
467 PLDM_START_AND_END, attrTable.data(),
468 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530469 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530470}
471
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600472Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500473{
474 uint32_t fileHandle = 0;
475 uint32_t offset = 0;
476 uint32_t length = 0;
477
478 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
479 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
480
481 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
482 {
483 encode_read_file_resp(request->hdr.instance_id,
484 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
485 return response;
486 }
487
488 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
489 &length);
490
491 if (rc)
492 {
493 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
494 return response;
495 }
496
497 using namespace pldm::filetable;
498 auto& table = buildFileTable(FILE_TABLE_JSON);
499 FileEntry value{};
500
501 try
502 {
503 value = table.at(fileHandle);
504 }
Patrick Williams51330582021-10-06 12:48:56 -0500505 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500506 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600507 error(
508 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
509 "FILE_HANDLE", fileHandle);
vkaverap5b914c32019-06-30 22:23:54 -0500510 encode_read_file_resp(request->hdr.instance_id,
511 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
512 return response;
513 }
514
515 if (!fs::exists(value.fsPath))
516 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600517 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
518 fileHandle);
vkaverap5b914c32019-06-30 22:23:54 -0500519 encode_read_file_resp(request->hdr.instance_id,
520 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
521 return response;
522 }
523
524 auto fileSize = fs::file_size(value.fsPath);
525 if (offset >= fileSize)
526 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600527 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
528 "OFFSET", offset, "FILE_SIZE", fileSize);
vkaverap5b914c32019-06-30 22:23:54 -0500529 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
530 length, responsePtr);
531 return response;
532 }
533
534 if (offset + length > fileSize)
535 {
536 length = fileSize - offset;
537 }
538
539 response.resize(response.size() + length);
540 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
541 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
542 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
543
544 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
545 stream.seekg(offset);
546 stream.read(fileDataPos, length);
547
548 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
549 responsePtr);
550
551 return response;
552}
553
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600554Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500555{
556 uint32_t fileHandle = 0;
557 uint32_t offset = 0;
558 uint32_t length = 0;
559 size_t fileDataOffset = 0;
560
561 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
562 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
563
564 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
565 {
566 encode_write_file_resp(request->hdr.instance_id,
567 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
568 return response;
569 }
570
571 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
572 &offset, &length, &fileDataOffset);
573
574 if (rc)
575 {
576 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
577 return response;
578 }
579
580 using namespace pldm::filetable;
581 auto& table = buildFileTable(FILE_TABLE_JSON);
582 FileEntry value{};
583
584 try
585 {
586 value = table.at(fileHandle);
587 }
Patrick Williams51330582021-10-06 12:48:56 -0500588 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500589 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600590 error(
591 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
592 "FILE_HANDLE", fileHandle);
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 if (!fs::exists(value.fsPath))
599 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600600 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
601 fileHandle);
vkaverap5b914c32019-06-30 22:23:54 -0500602 encode_write_file_resp(request->hdr.instance_id,
603 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
604 return response;
605 }
606
607 auto fileSize = fs::file_size(value.fsPath);
608 if (offset >= fileSize)
609 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600610 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
611 "OFFSET", offset, "FILE_SIZE", fileSize);
vkaverap5b914c32019-06-30 22:23:54 -0500612 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
613 0, responsePtr);
614 return response;
615 }
616
617 auto fileDataPos =
618 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
619
620 std::ofstream stream(value.fsPath,
621 std::ios::in | std::ios::out | std::ios::binary);
622 stream.seekp(offset);
623 stream.write(fileDataPos, length);
624
625 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
626 responsePtr);
627
628 return response;
629}
630
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600631Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
Sampa Misra69508502020-09-08 00:08:21 -0500632 size_t payloadLength,
633 oem_platform::Handler* oemPlatformHandler)
Sampa Misra854e61f2019-08-22 04:36:47 -0500634{
635 Response response(
636 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
637 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
638
639 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
640 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600641 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
642 PLDM_ERROR_INVALID_LENGTH, 0,
643 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500644 return response;
645 }
646
647 uint16_t fileType{};
648 uint32_t fileHandle{};
649 uint32_t offset{};
650 uint32_t length{};
651 uint64_t address{};
652 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
653 &fileType, &fileHandle, &offset,
654 &length, &address);
655 if (rc != PLDM_SUCCESS)
656 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600657 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
658 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500659 return response;
660 }
661 if (length % dma::minSize)
662 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600663 error("Length is not a multiple of DMA minSize, LENGTH={LEN}", "LEN",
664 length);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600665 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500666 PLDM_ERROR_INVALID_LENGTH, 0,
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600667 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500668 return response;
669 }
670
671 std::unique_ptr<FileHandler> handler{};
672 try
673 {
674 handler = getHandlerByType(fileType, fileHandle);
675 }
676 catch (const InternalFailure& e)
677 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600678 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600679 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
680 PLDM_INVALID_FILE_TYPE, 0,
681 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500682 return response;
683 }
684
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600685 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
Sampa Misra69508502020-09-08 00:08:21 -0500686 ? handler->writeFromMemory(offset, length, address,
687 oemPlatformHandler)
688 : handler->readIntoMemory(offset, length, address,
689 oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600690 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500691 length, responsePtr);
692 return response;
693}
694
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600695Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
696 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600697{
698 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500699 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600700}
701
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600702Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
703 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600704{
705 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500706 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600707}
708
Sampa Misra18967162020-01-14 02:31:41 -0600709Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
710{
711 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
712 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
713
Sampa Misrad823cc02020-03-24 04:53:20 -0500714 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600715 {
716 encode_rw_file_by_type_resp(request->hdr.instance_id,
717 PLDM_WRITE_FILE_BY_TYPE,
718 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
719 return response;
720 }
721 uint16_t fileType{};
722 uint32_t fileHandle{};
723 uint32_t offset{};
724 uint32_t length{};
725
726 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
727 &fileHandle, &offset, &length);
728 if (rc != PLDM_SUCCESS)
729 {
730 encode_rw_file_by_type_resp(request->hdr.instance_id,
731 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
732 responsePtr);
733 return response;
734 }
735
736 std::unique_ptr<FileHandler> handler{};
737 try
738 {
739 handler = getHandlerByType(fileType, fileHandle);
740 }
741 catch (const InternalFailure& e)
742 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600743 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600744 encode_rw_file_by_type_resp(request->hdr.instance_id,
745 PLDM_WRITE_FILE_BY_TYPE,
746 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
747 return response;
748 }
749
750 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500751 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra69508502020-09-08 00:08:21 -0500752 offset, length, oemPlatformHandler);
Sampa Misra18967162020-01-14 02:31:41 -0600753 encode_rw_file_by_type_resp(request->hdr.instance_id,
754 PLDM_WRITE_FILE_BY_TYPE, rc, length,
755 responsePtr);
756 return response;
757}
758
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600759Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600760{
761 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
762 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
763
764 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
765 {
766 encode_rw_file_by_type_resp(request->hdr.instance_id,
767 PLDM_READ_FILE_BY_TYPE,
768 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
769 return response;
770 }
771 uint16_t fileType{};
772 uint32_t fileHandle{};
773 uint32_t offset{};
774 uint32_t length{};
775
776 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
777 &fileHandle, &offset, &length);
778 if (rc != PLDM_SUCCESS)
779 {
780 encode_rw_file_by_type_resp(request->hdr.instance_id,
781 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
782 return response;
783 }
784
785 std::unique_ptr<FileHandler> handler{};
786 try
787 {
788 handler = getHandlerByType(fileType, fileHandle);
789 }
790 catch (const InternalFailure& e)
791 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600792 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600793 encode_rw_file_by_type_resp(request->hdr.instance_id,
794 PLDM_READ_FILE_BY_TYPE,
795 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
796 return response;
797 }
798
Sampa Misra69508502020-09-08 00:08:21 -0500799 rc = handler->read(offset, length, response, oemPlatformHandler);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600800 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600801 encode_rw_file_by_type_resp(request->hdr.instance_id,
802 PLDM_READ_FILE_BY_TYPE, rc, length,
803 responsePtr);
804 return response;
805}
806
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600807Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
808{
809 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
810 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
811
812 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
813 {
814 encode_file_ack_resp(request->hdr.instance_id,
815 PLDM_ERROR_INVALID_LENGTH, responsePtr);
816 return response;
817 }
818 uint16_t fileType{};
819 uint32_t fileHandle{};
820 uint8_t fileStatus{};
821
822 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
823 &fileHandle, &fileStatus);
824 if (rc != PLDM_SUCCESS)
825 {
826 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
827 return response;
828 }
829
830 std::unique_ptr<FileHandler> handler{};
831 try
832 {
833 handler = getHandlerByType(fileType, fileHandle);
834 }
Sampa Misra18967162020-01-14 02:31:41 -0600835
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600836 catch (const InternalFailure& e)
837 {
838 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
839 responsePtr);
840 return response;
841 }
842
843 rc = handler->fileAck(fileStatus);
844 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
845 return response;
846}
847
George Liu89aad712020-03-12 13:34:51 +0800848Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
849{
850 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
851 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
852 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
853 {
854 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
855 }
856
857 uint8_t versionId{};
858
859 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
860 if (rc != PLDM_SUCCESS)
861 {
862 return CmdHandler::ccOnlyResponse(request, rc);
863 }
864
865 if (versionId != 0)
866 {
867 return CmdHandler::ccOnlyResponse(request,
868 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
869 }
870
871 constexpr uint32_t rackEntry = 0xFF000030;
872 constexpr uint32_t priCecNode = 0x00008030;
873 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
874 rackEntry, priCecNode, responsePtr,
875 PLDM_GET_ALERT_STATUS_RESP_BYTES);
876 if (rc != PLDM_SUCCESS)
877 {
878 return CmdHandler::ccOnlyResponse(request, rc);
879 }
880
881 return response;
882}
883
Sampa Misra18967162020-01-14 02:31:41 -0600884Response Handler::newFileAvailable(const pldm_msg* request,
885 size_t payloadLength)
886{
887 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
888
889 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
890 {
891 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
892 }
893 uint16_t fileType{};
894 uint32_t fileHandle{};
895 uint64_t length{};
896
897 auto rc = decode_new_file_req(request, payloadLength, &fileType,
898 &fileHandle, &length);
899
900 if (rc != PLDM_SUCCESS)
901 {
902 return CmdHandler::ccOnlyResponse(request, rc);
903 }
904
905 std::unique_ptr<FileHandler> handler{};
906 try
907 {
908 handler = getHandlerByType(fileType, fileHandle);
909 }
910 catch (const InternalFailure& e)
911 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600912 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600913 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
914 }
915
916 rc = handler->newFileAvailable(length);
917 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
918 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr);
919 return response;
920}
921
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600922} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530923} // namespace responder
924} // namespace pldm