blob: 12e9fed40355b906b8d0fec3442ba6322a15fd6d [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"
George Liu83409572019-12-24 18:42:54 +08007#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>
11#include <sys/mman.h>
12#include <sys/stat.h>
13#include <sys/types.h>
14#include <unistd.h>
15
16#include <cstring>
17#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060018#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050019#include <memory>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053020
21#include "libpldm/base.h"
22
23namespace pldm
24{
25
Sampa Misra854e61f2019-08-22 04:36:47 -050026using namespace sdbusplus::xyz::openbmc_project::Common::Error;
27
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053028namespace responder
29{
30
31namespace fs = std::filesystem;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053032
33namespace dma
34{
35
36/** @struct AspeedXdmaOp
37 *
38 * Structure representing XDMA operation
39 */
40struct AspeedXdmaOp
41{
42 uint64_t hostAddr; //!< the DMA address on the host side, configured by
43 //!< PCI subsystem.
44 uint32_t len; //!< the size of the transfer in bytes, it should be a
45 //!< multiple of 16 bytes
46 uint32_t upstream; //!< boolean indicating the direction of the DMA
47 //!< operation, true means a transfer from BMC to host.
48};
49
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050050constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053051
Deepak Kodihalli15211b42019-12-14 02:24:49 -060052int DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
53 uint64_t address, bool upstream)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053054{
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
Deepak Kodihalli15211b42019-12-14 02:24:49 -060068 int dmaFd = -1;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053069 int rc = 0;
Deepak Kodihalli15211b42019-12-14 02:24:49 -060070 dmaFd = open(xdmaDev, O_RDWR);
71 if (dmaFd < 0)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053072 {
73 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060074 std::cerr << "Failed to open the XDMA device, RC=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053075 return rc;
76 }
77
George Liu83409572019-12-24 18:42:54 +080078 pldm::utils::CustomFD xdmaFd(dmaFd);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053079
80 void* vgaMem;
81 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
82 MAP_SHARED, xdmaFd(), 0);
83 if (MAP_FAILED == vgaMem)
84 {
85 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060086 std::cerr << "Failed to mmap the XDMA device, RC=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053087 return rc;
88 }
89
90 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
91
92 if (upstream)
93 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060094 rc = lseek(fd, offset, SEEK_SET);
95 if (rc == -1)
96 {
97 std::cerr << "lseek failed, ERROR=" << errno
98 << ", UPSTREAM=" << upstream << ", OFFSET=" << offset
99 << "\n";
100 return rc;
101 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530102
103 // Writing to the VGA memory should be aligned at page boundary,
104 // otherwise write data into a buffer aligned at page boundary and
105 // then write to the VGA memory.
106 std::vector<char> buffer{};
107 buffer.resize(pageAlignedLength);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600108 rc = read(fd, buffer.data(), length);
109 if (rc == -1)
110 {
111 std::cerr << "file read failed, ERROR=" << errno
112 << ", UPSTREAM=" << upstream << ", LENGTH=" << length
113 << ", OFFSET=" << offset << "\n";
114 return rc;
115 }
116 if (rc != static_cast<int>(length))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530117 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600118 std::cerr << "mismatch between number of characters to read and "
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600119 << "the length read, LENGTH=" << length << " COUNT=" << rc
120 << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530121 return -1;
122 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600123 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
124 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530125 }
126
127 AspeedXdmaOp xdmaOp;
128 xdmaOp.upstream = upstream ? 1 : 0;
129 xdmaOp.hostAddr = address;
130 xdmaOp.len = length;
131
132 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
133 if (rc < 0)
134 {
135 rc = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -0600136 std::cerr << "Failed to execute the DMA operation, RC=" << rc
137 << " UPSTREAM=" << upstream << " ADDRESS=" << address
138 << " LENGTH=" << length << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530139 return rc;
140 }
141
142 if (!upstream)
143 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600144 rc = lseek(fd, offset, SEEK_SET);
145 if (rc == -1)
Sampa Misra854e61f2019-08-22 04:36:47 -0500146 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600147 std::cerr << "lseek failed, ERROR=" << errno
148 << ", UPSTREAM=" << upstream << ", OFFSET=" << offset
149 << "\n";
150 return rc;
Sampa Misra854e61f2019-08-22 04:36:47 -0500151 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600152 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
153 if (rc == -1)
154 {
155 std::cerr << "file write failed, ERROR=" << errno
156 << ", UPSTREAM=" << upstream << ", LENGTH=" << length
157 << ", OFFSET=" << offset << "\n";
158 return rc;
159 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530160 }
161
162 return 0;
163}
164
165} // namespace dma
166
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600167namespace oem_ibm
168{
169
170Response Handler::readFileIntoMemory(const pldm_msg* request,
171 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530172{
173 uint32_t fileHandle = 0;
174 uint32_t offset = 0;
175 uint32_t length = 0;
176 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530177
178 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
179 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
180
181 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
182 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530183 encode_rw_file_memory_resp(request->hdr.instance_id,
184 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530185 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
186 return response;
187 }
188
Zahed Hossain223a73d2019-07-04 12:46:18 -0500189 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
190 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530191
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530192 using namespace pldm::filetable;
193 auto& table = buildFileTable(FILE_TABLE_JSON);
194 FileEntry value{};
195
196 try
197 {
198 value = table.at(fileHandle);
199 }
200 catch (std::exception& e)
201 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600202 std::cerr << "File handle does not exist in the file table, HANDLE="
203 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530204 encode_rw_file_memory_resp(request->hdr.instance_id,
205 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530206 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
207 return response;
208 }
209
210 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530211 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600212 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530213 encode_rw_file_memory_resp(request->hdr.instance_id,
214 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530215 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
216 return response;
217 }
218
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530219 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530220 if (offset >= fileSize)
221 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600222 std::cerr << "Offset exceeds file size, OFFSET=" << offset
223 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530224 encode_rw_file_memory_resp(request->hdr.instance_id,
225 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530226 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
227 return response;
228 }
229
230 if (offset + length > fileSize)
231 {
232 length = fileSize - offset;
233 }
234
235 if (length % dma::minSize)
236 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600237 std::cerr << "Read length is not a multiple of DMA minSize, LENGTH="
238 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530239 encode_rw_file_memory_resp(request->hdr.instance_id,
240 PLDM_READ_FILE_INTO_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500241 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530242 return response;
243 }
244
245 using namespace dma;
246 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530247 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530248 offset, length, address, true,
249 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530250}
251
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600252Response Handler::writeFileFromMemory(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_WRITE_FILE_FROM_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
274 if (length % dma::minSize)
275 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600276 std::cerr << "Write length is not a multiple of DMA minSize, LENGTH="
277 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530278 encode_rw_file_memory_resp(request->hdr.instance_id,
279 PLDM_WRITE_FILE_FROM_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500280 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530281 return response;
282 }
283
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530284 using namespace pldm::filetable;
285 auto& table = buildFileTable(FILE_TABLE_JSON);
286 FileEntry value{};
287
288 try
289 {
290 value = table.at(fileHandle);
291 }
292 catch (std::exception& e)
293 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600294 std::cerr << "File handle does not exist in the file table, HANDLE="
295 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530296 encode_rw_file_memory_resp(request->hdr.instance_id,
297 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530298 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
299 return response;
300 }
301
302 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530303 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600304 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530305 encode_rw_file_memory_resp(request->hdr.instance_id,
306 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530307 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
308 return response;
309 }
310
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530311 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530312 if (offset >= fileSize)
313 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600314 std::cerr << "Offset exceeds file size, OFFSET=" << offset
315 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530316 encode_rw_file_memory_resp(request->hdr.instance_id,
317 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530318 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
319 return response;
320 }
321
322 using namespace dma;
323 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530324 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530325 offset, length, address, false,
326 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530327}
328
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600329Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530330{
331 uint32_t transferHandle = 0;
332 uint8_t transferFlag = 0;
333 uint8_t tableType = 0;
334
335 Response response(sizeof(pldm_msg_hdr) +
336 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
337 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
338
339 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
340 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530341 encode_get_file_table_resp(request->hdr.instance_id,
342 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
343 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530344 return response;
345 }
346
Zahed Hossain223a73d2019-07-04 12:46:18 -0500347 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
348 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530349 if (rc)
350 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530351 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
352 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530353 return response;
354 }
355
356 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
357 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530358 encode_get_file_table_resp(request->hdr.instance_id,
359 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
360 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530361 return response;
362 }
363
364 using namespace pldm::filetable;
365 auto table = buildFileTable(FILE_TABLE_JSON);
366 auto attrTable = table();
367 response.resize(response.size() + attrTable.size());
368 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
369
370 if (attrTable.empty())
371 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530372 encode_get_file_table_resp(request->hdr.instance_id,
373 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
374 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530375 return response;
376 }
377
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530378 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
379 PLDM_START_AND_END, attrTable.data(),
380 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530381 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530382}
383
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600384Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500385{
386 uint32_t fileHandle = 0;
387 uint32_t offset = 0;
388 uint32_t length = 0;
389
390 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
391 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
392
393 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
394 {
395 encode_read_file_resp(request->hdr.instance_id,
396 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
397 return response;
398 }
399
400 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
401 &length);
402
403 if (rc)
404 {
405 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
406 return response;
407 }
408
409 using namespace pldm::filetable;
410 auto& table = buildFileTable(FILE_TABLE_JSON);
411 FileEntry value{};
412
413 try
414 {
415 value = table.at(fileHandle);
416 }
417 catch (std::exception& e)
418 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600419 std::cerr << "File handle does not exist in the file table, HANDLE="
420 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500421 encode_read_file_resp(request->hdr.instance_id,
422 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
423 return response;
424 }
425
426 if (!fs::exists(value.fsPath))
427 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600428 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500429 encode_read_file_resp(request->hdr.instance_id,
430 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
431 return response;
432 }
433
434 auto fileSize = fs::file_size(value.fsPath);
435 if (offset >= fileSize)
436 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600437 std::cerr << "Offset exceeds file size, OFFSET=" << offset
438 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500439 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
440 length, responsePtr);
441 return response;
442 }
443
444 if (offset + length > fileSize)
445 {
446 length = fileSize - offset;
447 }
448
449 response.resize(response.size() + length);
450 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
451 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
452 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
453
454 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
455 stream.seekg(offset);
456 stream.read(fileDataPos, length);
457
458 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
459 responsePtr);
460
461 return response;
462}
463
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600464Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500465{
466 uint32_t fileHandle = 0;
467 uint32_t offset = 0;
468 uint32_t length = 0;
469 size_t fileDataOffset = 0;
470
471 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
472 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
473
474 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
475 {
476 encode_write_file_resp(request->hdr.instance_id,
477 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
478 return response;
479 }
480
481 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
482 &offset, &length, &fileDataOffset);
483
484 if (rc)
485 {
486 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
487 return response;
488 }
489
490 using namespace pldm::filetable;
491 auto& table = buildFileTable(FILE_TABLE_JSON);
492 FileEntry value{};
493
494 try
495 {
496 value = table.at(fileHandle);
497 }
498 catch (std::exception& e)
499 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600500 std::cerr << "File handle does not exist in the file table, HANDLE="
501 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500502 encode_write_file_resp(request->hdr.instance_id,
503 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
504 return response;
505 }
506
507 if (!fs::exists(value.fsPath))
508 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600509 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500510 encode_write_file_resp(request->hdr.instance_id,
511 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
512 return response;
513 }
514
515 auto fileSize = fs::file_size(value.fsPath);
516 if (offset >= fileSize)
517 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600518 std::cerr << "Offset exceeds file size, OFFSET=" << offset
519 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500520 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
521 0, responsePtr);
522 return response;
523 }
524
525 auto fileDataPos =
526 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
527
528 std::ofstream stream(value.fsPath,
529 std::ios::in | std::ios::out | std::ios::binary);
530 stream.seekp(offset);
531 stream.write(fileDataPos, length);
532
533 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
534 responsePtr);
535
536 return response;
537}
538
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600539Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
540 size_t payloadLength)
Sampa Misra854e61f2019-08-22 04:36:47 -0500541{
542 Response response(
543 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
544 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
545
546 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
547 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600548 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
549 PLDM_ERROR_INVALID_LENGTH, 0,
550 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500551 return response;
552 }
553
554 uint16_t fileType{};
555 uint32_t fileHandle{};
556 uint32_t offset{};
557 uint32_t length{};
558 uint64_t address{};
559 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
560 &fileType, &fileHandle, &offset,
561 &length, &address);
562 if (rc != PLDM_SUCCESS)
563 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600564 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
565 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500566 return response;
567 }
568 if (length % dma::minSize)
569 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600570 std::cerr << "Length is not a multiple of DMA minSize, LENGTH="
571 << length << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600572 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500573 PLDM_ERROR_INVALID_LENGTH, 0,
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600574 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500575 return response;
576 }
577
578 std::unique_ptr<FileHandler> handler{};
579 try
580 {
581 handler = getHandlerByType(fileType, fileHandle);
582 }
583 catch (const InternalFailure& e)
584 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600585 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600586 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
587 PLDM_INVALID_FILE_TYPE, 0,
588 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500589 return response;
590 }
591
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600592 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
593 ? handler->writeFromMemory(offset, length, address)
594 : handler->readIntoMemory(offset, length, address);
595 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500596 length, responsePtr);
597 return response;
598}
599
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600600Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
601 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600602{
603 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
604 payloadLength);
605}
606
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600607Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
608 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600609{
610 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
611 payloadLength);
612}
613
Sampa Misra18967162020-01-14 02:31:41 -0600614Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
615{
616 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
617 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
618
Sampa Misrad823cc02020-03-24 04:53:20 -0500619 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600620 {
621 encode_rw_file_by_type_resp(request->hdr.instance_id,
622 PLDM_WRITE_FILE_BY_TYPE,
623 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
624 return response;
625 }
626 uint16_t fileType{};
627 uint32_t fileHandle{};
628 uint32_t offset{};
629 uint32_t length{};
630
631 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
632 &fileHandle, &offset, &length);
633 if (rc != PLDM_SUCCESS)
634 {
635 encode_rw_file_by_type_resp(request->hdr.instance_id,
636 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
637 responsePtr);
638 return response;
639 }
640
641 std::unique_ptr<FileHandler> handler{};
642 try
643 {
644 handler = getHandlerByType(fileType, fileHandle);
645 }
646 catch (const InternalFailure& e)
647 {
648 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
649 encode_rw_file_by_type_resp(request->hdr.instance_id,
650 PLDM_WRITE_FILE_BY_TYPE,
651 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
652 return response;
653 }
654
655 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500656 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra18967162020-01-14 02:31:41 -0600657 offset, length);
658 encode_rw_file_by_type_resp(request->hdr.instance_id,
659 PLDM_WRITE_FILE_BY_TYPE, rc, length,
660 responsePtr);
661 return response;
662}
663
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600664Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600665{
666 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
667 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
668
669 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
670 {
671 encode_rw_file_by_type_resp(request->hdr.instance_id,
672 PLDM_READ_FILE_BY_TYPE,
673 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
674 return response;
675 }
676 uint16_t fileType{};
677 uint32_t fileHandle{};
678 uint32_t offset{};
679 uint32_t length{};
680
681 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
682 &fileHandle, &offset, &length);
683 if (rc != PLDM_SUCCESS)
684 {
685 encode_rw_file_by_type_resp(request->hdr.instance_id,
686 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
687 return response;
688 }
689
690 std::unique_ptr<FileHandler> handler{};
691 try
692 {
693 handler = getHandlerByType(fileType, fileHandle);
694 }
695 catch (const InternalFailure& e)
696 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600697 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600698 encode_rw_file_by_type_resp(request->hdr.instance_id,
699 PLDM_READ_FILE_BY_TYPE,
700 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
701 return response;
702 }
703
704 rc = handler->read(offset, length, response);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600705 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600706 encode_rw_file_by_type_resp(request->hdr.instance_id,
707 PLDM_READ_FILE_BY_TYPE, rc, length,
708 responsePtr);
709 return response;
710}
711
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600712Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
713{
714 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
715 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
716
717 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
718 {
719 encode_file_ack_resp(request->hdr.instance_id,
720 PLDM_ERROR_INVALID_LENGTH, responsePtr);
721 return response;
722 }
723 uint16_t fileType{};
724 uint32_t fileHandle{};
725 uint8_t fileStatus{};
726
727 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
728 &fileHandle, &fileStatus);
729 if (rc != PLDM_SUCCESS)
730 {
731 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
732 return response;
733 }
734
735 std::unique_ptr<FileHandler> handler{};
736 try
737 {
738 handler = getHandlerByType(fileType, fileHandle);
739 }
Sampa Misra18967162020-01-14 02:31:41 -0600740
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600741 catch (const InternalFailure& e)
742 {
743 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
744 responsePtr);
745 return response;
746 }
747
748 rc = handler->fileAck(fileStatus);
749 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
750 return response;
751}
752
George Liu89aad712020-03-12 13:34:51 +0800753Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
754{
755 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
756 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
757 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
758 {
759 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
760 }
761
762 uint8_t versionId{};
763
764 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
765 if (rc != PLDM_SUCCESS)
766 {
767 return CmdHandler::ccOnlyResponse(request, rc);
768 }
769
770 if (versionId != 0)
771 {
772 return CmdHandler::ccOnlyResponse(request,
773 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
774 }
775
776 constexpr uint32_t rackEntry = 0xFF000030;
777 constexpr uint32_t priCecNode = 0x00008030;
778 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
779 rackEntry, priCecNode, responsePtr,
780 PLDM_GET_ALERT_STATUS_RESP_BYTES);
781 if (rc != PLDM_SUCCESS)
782 {
783 return CmdHandler::ccOnlyResponse(request, rc);
784 }
785
786 return response;
787}
788
Sampa Misra18967162020-01-14 02:31:41 -0600789Response Handler::newFileAvailable(const pldm_msg* request,
790 size_t payloadLength)
791{
792 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
793
794 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
795 {
796 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
797 }
798 uint16_t fileType{};
799 uint32_t fileHandle{};
800 uint64_t length{};
801
802 auto rc = decode_new_file_req(request, payloadLength, &fileType,
803 &fileHandle, &length);
804
805 if (rc != PLDM_SUCCESS)
806 {
807 return CmdHandler::ccOnlyResponse(request, rc);
808 }
809
810 std::unique_ptr<FileHandler> handler{};
811 try
812 {
813 handler = getHandlerByType(fileType, fileHandle);
814 }
815 catch (const InternalFailure& e)
816 {
817 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
818 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
819 }
820
821 rc = handler->newFileAvailable(length);
822 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
823 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr);
824 return response;
825}
826
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600827} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530828} // namespace responder
829} // namespace pldm