blob: b01ef193ee7f9ea9d7e7e550db187530bffe2314 [file] [log] [blame]
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05301#include "file_io.hpp"
2
Sampa Misra854e61f2019-08-22 04:36:47 -05003#include "file_io_by_type.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05304#include "file_table.hpp"
Ravi Tejace1c96f2020-10-05 23:13:01 -05005#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05006#include "xyz/openbmc_project/Common/error.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05007
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05308#include <fcntl.h>
George Liuc453e162022-12-21 17:16:23 +08009#include <libpldm/base.h>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053010#include <sys/mman.h>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <unistd.h>
14
Riya Dixit49cfb132023-03-02 04:26:53 -060015#include <phosphor-logging/lg2.hpp>
16
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053017#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
Riya Dixit49cfb132023-03-02 04:26:53 -060022PHOSPHOR_LOG2_USING;
23
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053024namespace pldm
25{
Ravi Tejace1c96f2020-10-05 23:13:01 -050026using namespace pldm::responder::utils;
Sampa Misra854e61f2019-08-22 04:36:47 -050027using namespace sdbusplus::xyz::openbmc_project::Common::Error;
28
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053029namespace responder
30{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053031namespace fs = std::filesystem;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053032
33namespace dma
34{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053035/** @struct AspeedXdmaOp
36 *
37 * Structure representing XDMA operation
38 */
39struct AspeedXdmaOp
40{
41 uint64_t hostAddr; //!< the DMA address on the host side, configured by
42 //!< PCI subsystem.
43 uint32_t len; //!< the size of the transfer in bytes, it should be a
44 //!< multiple of 16 bytes
45 uint32_t upstream; //!< boolean indicating the direction of the DMA
46 //!< operation, true means a transfer from BMC to host.
47};
48
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050049constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053050
Ravi Tejace1c96f2020-10-05 23:13:01 -050051int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
52{
53 static const size_t pageSize = getpagesize();
54 uint32_t numPages = length / pageSize;
55 uint32_t pageAlignedLength = numPages * pageSize;
56
57 if (length > pageAlignedLength)
58 {
59 pageAlignedLength += pageSize;
60 }
61
62 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
63 munmap(vgaMem, pageAlignedLength);
64 };
65
66 int dmaFd = -1;
67 int rc = 0;
68 dmaFd = open(xdmaDev, O_RDWR);
69 if (dmaFd < 0)
70 {
71 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -060072 error(
73 "transferHostDataToSocket: Failed to open the XDMA device, RC={RC}",
74 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -050075 return rc;
76 }
77
78 pldm::utils::CustomFD xdmaFd(dmaFd);
79
80 void* vgaMem;
Patrick Williams6da4f912023-05-10 07:50:53 -050081 vgaMem = mmap(nullptr, pageAlignedLength, PROT_READ, MAP_SHARED, xdmaFd(),
82 0);
Ravi Tejace1c96f2020-10-05 23:13:01 -050083 if (MAP_FAILED == vgaMem)
84 {
85 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -060086 error(
87 "transferHostDataToSocket : Failed to mmap the XDMA device, RC={RC}",
88 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -050089 return rc;
90 }
91
92 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
93
94 AspeedXdmaOp xdmaOp;
95 xdmaOp.upstream = 0;
96 xdmaOp.hostAddr = address;
97 xdmaOp.len = length;
98
99 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
100 if (rc < 0)
101 {
102 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600103 error(
104 "transferHostDataToSocket: Failed to execute the DMA operation, RC={RC} ADDRESS={ADDR} LENGTH={LEN}",
105 "RC", rc, "ADDR", address, "LEN", length);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500106 return rc;
107 }
108
109 rc = writeToUnixSocket(fd, static_cast<const char*>(vgaMemPtr.get()),
110 length);
111 if (rc < 0)
112 {
113 rc = -errno;
114 close(fd);
Riya Dixit49cfb132023-03-02 04:26:53 -0600115 error(
116 "transferHostDataToSocket: Closing socket as writeToUnixSocket faile with RC={RC}",
117 "RC", rc);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500118 return rc;
119 }
120 return 0;
121}
122
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600123int DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
124 uint64_t address, bool upstream)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530125{
126 static const size_t pageSize = getpagesize();
127 uint32_t numPages = length / pageSize;
128 uint32_t pageAlignedLength = numPages * pageSize;
129
130 if (length > pageAlignedLength)
131 {
132 pageAlignedLength += pageSize;
133 }
134
ArchanaKakani93409752022-04-19 00:36:04 -0500135 int rc = 0;
136 auto mmapCleanup = [pageAlignedLength, &rc](void* vgaMem) {
137 if (rc != -EINTR)
138 {
139 munmap(vgaMem, pageAlignedLength);
140 }
141 else
142 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600143 error(
144 "transferDataHost: Received interrupt during DMA transfer. Skipping Unmap.");
ArchanaKakani93409752022-04-19 00:36:04 -0500145 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530146 };
147
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600148 int dmaFd = -1;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600149 dmaFd = open(xdmaDev, O_RDWR);
150 if (dmaFd < 0)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530151 {
152 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600153 error("transferDataHost : Failed to open the XDMA device, RC={RC}",
154 "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530155 return rc;
156 }
157
George Liu83409572019-12-24 18:42:54 +0800158 pldm::utils::CustomFD xdmaFd(dmaFd);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530159
160 void* vgaMem;
161 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
162 MAP_SHARED, xdmaFd(), 0);
163 if (MAP_FAILED == vgaMem)
164 {
165 rc = -errno;
Riya Dixit49cfb132023-03-02 04:26:53 -0600166 error("transferDataHost : Failed to mmap the XDMA device, RC={RC}",
167 "RC", rc);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530168 return rc;
169 }
170
171 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
172
173 if (upstream)
174 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600175 rc = lseek(fd, offset, SEEK_SET);
176 if (rc == -1)
177 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600178 error(
179 "transferDataHost upstream : lseek failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, OFFSET={OFFSET}",
180 "ERR", errno, "UPSTREAM", upstream, "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600181 return rc;
182 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530183
184 // Writing to the VGA memory should be aligned at page boundary,
185 // otherwise write data into a buffer aligned at page boundary and
186 // then write to the VGA memory.
187 std::vector<char> buffer{};
188 buffer.resize(pageAlignedLength);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600189 rc = read(fd, buffer.data(), length);
190 if (rc == -1)
191 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600192 error(
193 "transferDataHost upstream : file read failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, LENGTH={LEN}, OFFSET={OFFSET}",
194 "ERR", errno, "UPSTREAM", upstream, "LEN", length, "OFFSET",
195 offset);
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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600200 error(
201 "transferDataHost upstream : mismatch between number of characters to read and the length read, LENGTH={LEN} COUNT={RC}",
202 "LEN", length, "RC", rc);
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;
Riya Dixit49cfb132023-03-02 04:26:53 -0600218 error(
219 "transferDataHost : Failed to execute the DMA operation, RC={RC} UPSTREAM={UPSTREAM} ADDRESS={ADDR} LENGTH={LEN}",
220 "RC", rc, "UPSTREAM", upstream, "ADDR", address, "LEN", length);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530221 return rc;
222 }
223
224 if (!upstream)
225 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600226 rc = lseek(fd, offset, SEEK_SET);
227 if (rc == -1)
Sampa Misra854e61f2019-08-22 04:36:47 -0500228 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600229 error(
230 "transferDataHost downstream : lseek failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, OFFSET={OFFSET}",
231 "ERR", errno, "UPSTREAM", upstream, "OFFSET", offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600232 return rc;
Sampa Misra854e61f2019-08-22 04:36:47 -0500233 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600234 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
235 if (rc == -1)
236 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600237 error(
238 "transferDataHost downstream : file write failed, ERROR={ERR}, UPSTREAM={UPSTREAM}, LENGTH={LEN}, OFFSET={OFFSET}",
239 "ERR", errno, "UPSTREAM", upstream, "LEN", length, "OFFSET",
240 offset);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600241 return rc;
242 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530243 }
244
245 return 0;
246}
247
248} // namespace dma
249
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600250namespace oem_ibm
251{
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600252Response Handler::readFileIntoMemory(const pldm_msg* request,
253 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530254{
255 uint32_t fileHandle = 0;
256 uint32_t offset = 0;
257 uint32_t length = 0;
258 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530259
260 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
261 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
262
263 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
264 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530265 encode_rw_file_memory_resp(request->hdr.instance_id,
266 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530267 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
268 return response;
269 }
270
Zahed Hossain223a73d2019-07-04 12:46:18 -0500271 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
272 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530273
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530274 using namespace pldm::filetable;
275 auto& table = buildFileTable(FILE_TABLE_JSON);
276 FileEntry value{};
277
278 try
279 {
280 value = table.at(fileHandle);
281 }
Patrick Williams51330582021-10-06 12:48:56 -0500282 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530283 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600284 error(
285 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
286 "FILE_HANDLE", fileHandle);
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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600295 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
296 fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530297 encode_rw_file_memory_resp(request->hdr.instance_id,
298 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530299 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
300 return response;
301 }
302
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530303 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530304 if (offset >= fileSize)
305 {
Sagar Srinivas82257922023-07-10 08:12:22 -0500306 error(
307 "Offset exceeds file size, OFFSET={OFFSTE} FILE_SIZE={FILE_SIZE} FILE_HANDLE{FILE_HANDLE}",
308 "OFFSET", offset, "FILE_SIZE", fileSize, "FILE_HANDLE", fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530309 encode_rw_file_memory_resp(request->hdr.instance_id,
310 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530311 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
312 return response;
313 }
314
315 if (offset + length > fileSize)
316 {
317 length = fileSize - offset;
318 }
319
320 if (length % dma::minSize)
321 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600322 error("Read length is not a multiple of DMA minSize, LENGTH={LEN}",
323 "LEN", length);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530324 encode_rw_file_memory_resp(request->hdr.instance_id,
325 PLDM_READ_FILE_INTO_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500326 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530327 return response;
328 }
329
330 using namespace dma;
331 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530332 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530333 offset, length, address, true,
334 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530335}
336
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600337Response Handler::writeFileFromMemory(const pldm_msg* request,
338 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530339{
340 uint32_t fileHandle = 0;
341 uint32_t offset = 0;
342 uint32_t length = 0;
343 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530344
345 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
346 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
347
348 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
349 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530350 encode_rw_file_memory_resp(request->hdr.instance_id,
351 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530352 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
353 return response;
354 }
355
Zahed Hossain223a73d2019-07-04 12:46:18 -0500356 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
357 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530358
359 if (length % dma::minSize)
360 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600361 error("Write length is not a multiple of DMA minSize, LENGTH={LEN}",
362 "LEN", length);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530363 encode_rw_file_memory_resp(request->hdr.instance_id,
364 PLDM_WRITE_FILE_FROM_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500365 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530366 return response;
367 }
368
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530369 using namespace pldm::filetable;
370 auto& table = buildFileTable(FILE_TABLE_JSON);
371 FileEntry value{};
372
373 try
374 {
375 value = table.at(fileHandle);
376 }
Patrick Williams51330582021-10-06 12:48:56 -0500377 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530378 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600379 error(
380 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
381 "FILE_HANDLE", fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530382 encode_rw_file_memory_resp(request->hdr.instance_id,
383 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530384 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
385 return response;
386 }
387
388 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530389 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600390 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
391 fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530392 encode_rw_file_memory_resp(request->hdr.instance_id,
393 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530394 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
395 return response;
396 }
397
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530398 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530399 if (offset >= fileSize)
400 {
Sagar Srinivas82257922023-07-10 08:12:22 -0500401 error(
402 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE} FILE_HANDLE{FILE_HANDLE}",
403 "OFFSET", offset, "FILE_SIZE", fileSize, "FILE_HANDLE", fileHandle);
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
Patrick Williams6da4f912023-05-10 07:50:53 -0500617 auto fileDataPos = reinterpret_cast<const char*>(request->payload) +
618 fileDataOffset;
vkaverap5b914c32019-06-30 22:23:54 -0500619
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