blob: c57c38785852896c7558903f62c09444390cd743 [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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600306 error("Offset exceeds file size, OFFSET={OFFSTE} FILE_SIZE={FILE_SIZE}",
307 "OFFSET", offset, "FILE_SIZE", fileSize);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530308 encode_rw_file_memory_resp(request->hdr.instance_id,
309 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530310 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
311 return response;
312 }
313
314 if (offset + length > fileSize)
315 {
316 length = fileSize - offset;
317 }
318
319 if (length % dma::minSize)
320 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600321 error("Read length is not a multiple of DMA minSize, LENGTH={LEN}",
322 "LEN", length);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530323 encode_rw_file_memory_resp(request->hdr.instance_id,
324 PLDM_READ_FILE_INTO_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500325 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530326 return response;
327 }
328
329 using namespace dma;
330 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530331 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530332 offset, length, address, true,
333 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530334}
335
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600336Response Handler::writeFileFromMemory(const pldm_msg* request,
337 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530338{
339 uint32_t fileHandle = 0;
340 uint32_t offset = 0;
341 uint32_t length = 0;
342 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530343
344 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
345 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
346
347 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
348 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530349 encode_rw_file_memory_resp(request->hdr.instance_id,
350 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530351 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
352 return response;
353 }
354
Zahed Hossain223a73d2019-07-04 12:46:18 -0500355 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
356 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530357
358 if (length % dma::minSize)
359 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600360 error("Write length is not a multiple of DMA minSize, LENGTH={LEN}",
361 "LEN", length);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530362 encode_rw_file_memory_resp(request->hdr.instance_id,
363 PLDM_WRITE_FILE_FROM_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500364 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530365 return response;
366 }
367
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530368 using namespace pldm::filetable;
369 auto& table = buildFileTable(FILE_TABLE_JSON);
370 FileEntry value{};
371
372 try
373 {
374 value = table.at(fileHandle);
375 }
Patrick Williams51330582021-10-06 12:48:56 -0500376 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530377 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600378 error(
379 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
380 "FILE_HANDLE", fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530381 encode_rw_file_memory_resp(request->hdr.instance_id,
382 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530383 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
384 return response;
385 }
386
387 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530388 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600389 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
390 fileHandle);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530391 encode_rw_file_memory_resp(request->hdr.instance_id,
392 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530393 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
394 return response;
395 }
396
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530397 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530398 if (offset >= fileSize)
399 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600400 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
401 "OFFSET", offset, "FILE_SIZE", fileSize);
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530402 encode_rw_file_memory_resp(request->hdr.instance_id,
403 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530404 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
405 return response;
406 }
407
408 using namespace dma;
409 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530410 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530411 offset, length, address, false,
412 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530413}
414
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600415Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530416{
417 uint32_t transferHandle = 0;
418 uint8_t transferFlag = 0;
419 uint8_t tableType = 0;
420
421 Response response(sizeof(pldm_msg_hdr) +
422 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
423 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
424
425 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
426 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530427 encode_get_file_table_resp(request->hdr.instance_id,
428 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
429 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530430 return response;
431 }
432
Zahed Hossain223a73d2019-07-04 12:46:18 -0500433 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
434 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530435 if (rc)
436 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530437 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
438 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530439 return response;
440 }
441
442 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
443 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530444 encode_get_file_table_resp(request->hdr.instance_id,
445 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
446 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530447 return response;
448 }
449
450 using namespace pldm::filetable;
451 auto table = buildFileTable(FILE_TABLE_JSON);
452 auto attrTable = table();
453 response.resize(response.size() + attrTable.size());
454 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
455
456 if (attrTable.empty())
457 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530458 encode_get_file_table_resp(request->hdr.instance_id,
459 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
460 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530461 return response;
462 }
463
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530464 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
465 PLDM_START_AND_END, attrTable.data(),
466 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530467 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530468}
469
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600470Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500471{
472 uint32_t fileHandle = 0;
473 uint32_t offset = 0;
474 uint32_t length = 0;
475
476 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
477 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
478
479 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
480 {
481 encode_read_file_resp(request->hdr.instance_id,
482 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
483 return response;
484 }
485
486 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
487 &length);
488
489 if (rc)
490 {
491 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
492 return response;
493 }
494
495 using namespace pldm::filetable;
496 auto& table = buildFileTable(FILE_TABLE_JSON);
497 FileEntry value{};
498
499 try
500 {
501 value = table.at(fileHandle);
502 }
Patrick Williams51330582021-10-06 12:48:56 -0500503 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500504 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600505 error(
506 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
507 "FILE_HANDLE", fileHandle);
vkaverap5b914c32019-06-30 22:23:54 -0500508 encode_read_file_resp(request->hdr.instance_id,
509 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
510 return response;
511 }
512
513 if (!fs::exists(value.fsPath))
514 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600515 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
516 fileHandle);
vkaverap5b914c32019-06-30 22:23:54 -0500517 encode_read_file_resp(request->hdr.instance_id,
518 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
519 return response;
520 }
521
522 auto fileSize = fs::file_size(value.fsPath);
523 if (offset >= fileSize)
524 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600525 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
526 "OFFSET", offset, "FILE_SIZE", fileSize);
vkaverap5b914c32019-06-30 22:23:54 -0500527 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
528 length, responsePtr);
529 return response;
530 }
531
532 if (offset + length > fileSize)
533 {
534 length = fileSize - offset;
535 }
536
537 response.resize(response.size() + length);
538 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
539 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
540 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
541
542 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
543 stream.seekg(offset);
544 stream.read(fileDataPos, length);
545
546 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
547 responsePtr);
548
549 return response;
550}
551
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600552Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500553{
554 uint32_t fileHandle = 0;
555 uint32_t offset = 0;
556 uint32_t length = 0;
557 size_t fileDataOffset = 0;
558
559 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
560 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
561
562 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
563 {
564 encode_write_file_resp(request->hdr.instance_id,
565 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
566 return response;
567 }
568
569 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
570 &offset, &length, &fileDataOffset);
571
572 if (rc)
573 {
574 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
575 return response;
576 }
577
578 using namespace pldm::filetable;
579 auto& table = buildFileTable(FILE_TABLE_JSON);
580 FileEntry value{};
581
582 try
583 {
584 value = table.at(fileHandle);
585 }
Patrick Williams51330582021-10-06 12:48:56 -0500586 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500587 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600588 error(
589 "File handle does not exist in the file table, HANDLE={FILE_HANDLE}",
590 "FILE_HANDLE", fileHandle);
vkaverap5b914c32019-06-30 22:23:54 -0500591 encode_write_file_resp(request->hdr.instance_id,
592 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
593 return response;
594 }
595
596 if (!fs::exists(value.fsPath))
597 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600598 error("File does not exist, HANDLE={FILE_HANDLE}", "FILE_HANDLE",
599 fileHandle);
vkaverap5b914c32019-06-30 22:23:54 -0500600 encode_write_file_resp(request->hdr.instance_id,
601 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
602 return response;
603 }
604
605 auto fileSize = fs::file_size(value.fsPath);
606 if (offset >= fileSize)
607 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600608 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
609 "OFFSET", offset, "FILE_SIZE", fileSize);
vkaverap5b914c32019-06-30 22:23:54 -0500610 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
611 0, responsePtr);
612 return response;
613 }
614
Patrick Williams6da4f912023-05-10 07:50:53 -0500615 auto fileDataPos = reinterpret_cast<const char*>(request->payload) +
616 fileDataOffset;
vkaverap5b914c32019-06-30 22:23:54 -0500617
618 std::ofstream stream(value.fsPath,
619 std::ios::in | std::ios::out | std::ios::binary);
620 stream.seekp(offset);
621 stream.write(fileDataPos, length);
622
623 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
624 responsePtr);
625
626 return response;
627}
628
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600629Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
Sampa Misra69508502020-09-08 00:08:21 -0500630 size_t payloadLength,
631 oem_platform::Handler* oemPlatformHandler)
Sampa Misra854e61f2019-08-22 04:36:47 -0500632{
633 Response response(
634 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
635 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
636
637 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
638 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600639 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
640 PLDM_ERROR_INVALID_LENGTH, 0,
641 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500642 return response;
643 }
644
645 uint16_t fileType{};
646 uint32_t fileHandle{};
647 uint32_t offset{};
648 uint32_t length{};
649 uint64_t address{};
650 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
651 &fileType, &fileHandle, &offset,
652 &length, &address);
653 if (rc != PLDM_SUCCESS)
654 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600655 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
656 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500657 return response;
658 }
659 if (length % dma::minSize)
660 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600661 error("Length is not a multiple of DMA minSize, LENGTH={LEN}", "LEN",
662 length);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600663 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500664 PLDM_ERROR_INVALID_LENGTH, 0,
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600665 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500666 return response;
667 }
668
669 std::unique_ptr<FileHandler> handler{};
670 try
671 {
672 handler = getHandlerByType(fileType, fileHandle);
673 }
674 catch (const InternalFailure& e)
675 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600676 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600677 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
678 PLDM_INVALID_FILE_TYPE, 0,
679 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500680 return response;
681 }
682
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600683 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
Sampa Misra69508502020-09-08 00:08:21 -0500684 ? handler->writeFromMemory(offset, length, address,
685 oemPlatformHandler)
686 : handler->readIntoMemory(offset, length, address,
687 oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600688 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500689 length, responsePtr);
690 return response;
691}
692
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600693Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
694 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600695{
696 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500697 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600698}
699
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600700Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
701 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600702{
703 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500704 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600705}
706
Sampa Misra18967162020-01-14 02:31:41 -0600707Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
708{
709 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
710 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
711
Sampa Misrad823cc02020-03-24 04:53:20 -0500712 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600713 {
714 encode_rw_file_by_type_resp(request->hdr.instance_id,
715 PLDM_WRITE_FILE_BY_TYPE,
716 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
717 return response;
718 }
719 uint16_t fileType{};
720 uint32_t fileHandle{};
721 uint32_t offset{};
722 uint32_t length{};
723
724 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
725 &fileHandle, &offset, &length);
726 if (rc != PLDM_SUCCESS)
727 {
728 encode_rw_file_by_type_resp(request->hdr.instance_id,
729 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
730 responsePtr);
731 return response;
732 }
733
734 std::unique_ptr<FileHandler> handler{};
735 try
736 {
737 handler = getHandlerByType(fileType, fileHandle);
738 }
739 catch (const InternalFailure& e)
740 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600741 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600742 encode_rw_file_by_type_resp(request->hdr.instance_id,
743 PLDM_WRITE_FILE_BY_TYPE,
744 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
745 return response;
746 }
747
748 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500749 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra69508502020-09-08 00:08:21 -0500750 offset, length, oemPlatformHandler);
Sampa Misra18967162020-01-14 02:31:41 -0600751 encode_rw_file_by_type_resp(request->hdr.instance_id,
752 PLDM_WRITE_FILE_BY_TYPE, rc, length,
753 responsePtr);
754 return response;
755}
756
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600757Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600758{
759 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
760 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
761
762 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
763 {
764 encode_rw_file_by_type_resp(request->hdr.instance_id,
765 PLDM_READ_FILE_BY_TYPE,
766 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
767 return response;
768 }
769 uint16_t fileType{};
770 uint32_t fileHandle{};
771 uint32_t offset{};
772 uint32_t length{};
773
774 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
775 &fileHandle, &offset, &length);
776 if (rc != PLDM_SUCCESS)
777 {
778 encode_rw_file_by_type_resp(request->hdr.instance_id,
779 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
780 return response;
781 }
782
783 std::unique_ptr<FileHandler> handler{};
784 try
785 {
786 handler = getHandlerByType(fileType, fileHandle);
787 }
788 catch (const InternalFailure& e)
789 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600790 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600791 encode_rw_file_by_type_resp(request->hdr.instance_id,
792 PLDM_READ_FILE_BY_TYPE,
793 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
794 return response;
795 }
796
Sampa Misra69508502020-09-08 00:08:21 -0500797 rc = handler->read(offset, length, response, oemPlatformHandler);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600798 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600799 encode_rw_file_by_type_resp(request->hdr.instance_id,
800 PLDM_READ_FILE_BY_TYPE, rc, length,
801 responsePtr);
802 return response;
803}
804
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600805Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
806{
807 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
808 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
809
810 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
811 {
812 encode_file_ack_resp(request->hdr.instance_id,
813 PLDM_ERROR_INVALID_LENGTH, responsePtr);
814 return response;
815 }
816 uint16_t fileType{};
817 uint32_t fileHandle{};
818 uint8_t fileStatus{};
819
820 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
821 &fileHandle, &fileStatus);
822 if (rc != PLDM_SUCCESS)
823 {
824 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
825 return response;
826 }
827
828 std::unique_ptr<FileHandler> handler{};
829 try
830 {
831 handler = getHandlerByType(fileType, fileHandle);
832 }
Sampa Misra18967162020-01-14 02:31:41 -0600833
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600834 catch (const InternalFailure& e)
835 {
836 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
837 responsePtr);
838 return response;
839 }
840
841 rc = handler->fileAck(fileStatus);
842 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
843 return response;
844}
845
George Liu89aad712020-03-12 13:34:51 +0800846Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
847{
848 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
849 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
850 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
851 {
852 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
853 }
854
855 uint8_t versionId{};
856
857 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
858 if (rc != PLDM_SUCCESS)
859 {
860 return CmdHandler::ccOnlyResponse(request, rc);
861 }
862
863 if (versionId != 0)
864 {
865 return CmdHandler::ccOnlyResponse(request,
866 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
867 }
868
869 constexpr uint32_t rackEntry = 0xFF000030;
870 constexpr uint32_t priCecNode = 0x00008030;
871 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
872 rackEntry, priCecNode, responsePtr,
873 PLDM_GET_ALERT_STATUS_RESP_BYTES);
874 if (rc != PLDM_SUCCESS)
875 {
876 return CmdHandler::ccOnlyResponse(request, rc);
877 }
878
879 return response;
880}
881
Sampa Misra18967162020-01-14 02:31:41 -0600882Response Handler::newFileAvailable(const pldm_msg* request,
883 size_t payloadLength)
884{
885 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
886
887 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
888 {
889 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
890 }
891 uint16_t fileType{};
892 uint32_t fileHandle{};
893 uint64_t length{};
894
895 auto rc = decode_new_file_req(request, payloadLength, &fileType,
896 &fileHandle, &length);
897
898 if (rc != PLDM_SUCCESS)
899 {
900 return CmdHandler::ccOnlyResponse(request, rc);
901 }
902
903 std::unique_ptr<FileHandler> handler{};
904 try
905 {
906 handler = getHandlerByType(fileType, fileHandle);
907 }
908 catch (const InternalFailure& e)
909 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600910 error("unknown file type, TYPE={FILE_TYPE}", "FILE_TYPE", fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600911 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
912 }
913
914 rc = handler->newFileAvailable(length);
915 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
916 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr);
917 return response;
918}
919
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600920} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530921} // namespace responder
922} // namespace pldm