1 #include "config.h"
2 
3 #include "file_io.hpp"
4 
5 #include "file_io_by_type.hpp"
6 #include "file_table.hpp"
7 #include "libpldmresponder/utils.hpp"
8 #include "registration.hpp"
9 #include "xyz/openbmc_project/Common/error.hpp"
10 
11 #include <fcntl.h>
12 #include <sys/mman.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16 
17 #include <cstring>
18 #include <fstream>
19 #include <memory>
20 #include <phosphor-logging/elog-errors.hpp>
21 #include <phosphor-logging/log.hpp>
22 
23 #include "libpldm/base.h"
24 
25 namespace pldm
26 {
27 
28 using namespace phosphor::logging;
29 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
30 
31 namespace responder
32 {
33 
34 namespace oem_ibm
35 {
36 
37 void registerHandlers()
38 {
39     registerHandler(PLDM_OEM, PLDM_GET_FILE_TABLE, std::move(getFileTable));
40     registerHandler(PLDM_OEM, PLDM_READ_FILE_INTO_MEMORY,
41                     std::move(readFileIntoMemory));
42     registerHandler(PLDM_OEM, PLDM_WRITE_FILE_FROM_MEMORY,
43                     std::move(writeFileFromMemory));
44     registerHandler(PLDM_OEM, PLDM_READ_FILE, std::move(readFile));
45     registerHandler(PLDM_OEM, PLDM_WRITE_FILE, std::move(writeFile));
46     registerHandler(PLDM_OEM, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
47                     std::move(writeFileByTypeFromMemory));
48     registerHandler(PLDM_OEM, PLDM_READ_FILE_BY_TYPE_INTO_MEMORY,
49                     std::move(readFileByTypeIntoMemory));
50     registerHandler(PLDM_OEM, PLDM_READ_FILE_BY_TYPE,
51                     std::move(readFileByType));
52 }
53 
54 } // namespace oem_ibm
55 
56 namespace fs = std::filesystem;
57 using namespace phosphor::logging;
58 
59 namespace dma
60 {
61 
62 /** @struct AspeedXdmaOp
63  *
64  * Structure representing XDMA operation
65  */
66 struct AspeedXdmaOp
67 {
68     uint64_t hostAddr; //!< the DMA address on the host side, configured by
69                        //!< PCI subsystem.
70     uint32_t len;      //!< the size of the transfer in bytes, it should be a
71                        //!< multiple of 16 bytes
72     uint32_t upstream; //!< boolean indicating the direction of the DMA
73                        //!< operation, true means a transfer from BMC to host.
74 };
75 
76 constexpr auto xdmaDev = "/dev/aspeed-xdma";
77 
78 int DMA::transferDataHost(const fs::path& path, uint32_t offset,
79                           uint32_t length, uint64_t address, bool upstream)
80 {
81     static const size_t pageSize = getpagesize();
82     uint32_t numPages = length / pageSize;
83     uint32_t pageAlignedLength = numPages * pageSize;
84 
85     if (length > pageAlignedLength)
86     {
87         pageAlignedLength += pageSize;
88     }
89 
90     auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
91         munmap(vgaMem, pageAlignedLength);
92     };
93 
94     int fd = -1;
95     int rc = 0;
96     fd = open(xdmaDev, O_RDWR);
97     if (fd < 0)
98     {
99         rc = -errno;
100         log<level::ERR>("Failed to open the XDMA device", entry("RC=%d", rc));
101         return rc;
102     }
103 
104     utils::CustomFD xdmaFd(fd);
105 
106     void* vgaMem;
107     vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
108                   MAP_SHARED, xdmaFd(), 0);
109     if (MAP_FAILED == vgaMem)
110     {
111         rc = -errno;
112         log<level::ERR>("Failed to mmap the XDMA device", entry("RC=%d", rc));
113         return rc;
114     }
115 
116     std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
117 
118     if (upstream)
119     {
120         std::ifstream stream(path.string(), std::ios::in | std::ios::binary);
121         stream.seekg(offset);
122 
123         // Writing to the VGA memory should be aligned at page boundary,
124         // otherwise write data into a buffer aligned at page boundary and
125         // then write to the VGA memory.
126         std::vector<char> buffer{};
127         buffer.resize(pageAlignedLength);
128         stream.read(buffer.data(), length);
129         memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
130                pageAlignedLength);
131 
132         if (static_cast<uint32_t>(stream.gcount()) != length)
133         {
134             log<level::ERR>("mismatch between number of characters to read and "
135                             "the length read",
136                             entry("LENGTH=%d", length),
137                             entry("COUNT=%d", stream.gcount()));
138             return -1;
139         }
140     }
141 
142     AspeedXdmaOp xdmaOp;
143     xdmaOp.upstream = upstream ? 1 : 0;
144     xdmaOp.hostAddr = address;
145     xdmaOp.len = length;
146 
147     rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
148     if (rc < 0)
149     {
150         rc = -errno;
151         log<level::ERR>("Failed to execute the DMA operation",
152                         entry("RC=%d", rc), entry("UPSTREAM=%d", upstream),
153                         entry("ADDRESS=%lld", address),
154                         entry("LENGTH=%d", length));
155         return rc;
156     }
157 
158     if (!upstream)
159     {
160         std::ios_base::openmode mode = std::ios::out | std::ios::binary;
161         if (fs::exists(path))
162         {
163             mode |= std::ios::in;
164         }
165         std::ofstream stream(path.string(), mode);
166 
167         stream.seekp(offset);
168         stream.write(static_cast<const char*>(vgaMemPtr.get()), length);
169     }
170 
171     return 0;
172 }
173 
174 } // namespace dma
175 
176 Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength)
177 {
178     uint32_t fileHandle = 0;
179     uint32_t offset = 0;
180     uint32_t length = 0;
181     uint64_t address = 0;
182 
183     Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
184     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
185 
186     if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
187     {
188         encode_rw_file_memory_resp(request->hdr.instance_id,
189                                    PLDM_READ_FILE_INTO_MEMORY,
190                                    PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
191         return response;
192     }
193 
194     decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
195                               &length, &address);
196 
197     using namespace pldm::filetable;
198     auto& table = buildFileTable(FILE_TABLE_JSON);
199     FileEntry value{};
200 
201     try
202     {
203         value = table.at(fileHandle);
204     }
205     catch (std::exception& e)
206     {
207         log<level::ERR>("File handle does not exist in the file table",
208                         entry("HANDLE=%d", fileHandle));
209         encode_rw_file_memory_resp(request->hdr.instance_id,
210                                    PLDM_READ_FILE_INTO_MEMORY,
211                                    PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
212         return response;
213     }
214 
215     if (!fs::exists(value.fsPath))
216     {
217         log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
218         encode_rw_file_memory_resp(request->hdr.instance_id,
219                                    PLDM_READ_FILE_INTO_MEMORY,
220                                    PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
221         return response;
222     }
223 
224     auto fileSize = fs::file_size(value.fsPath);
225     if (offset >= fileSize)
226     {
227         log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
228                         entry("FILE_SIZE=%d", fileSize));
229         encode_rw_file_memory_resp(request->hdr.instance_id,
230                                    PLDM_READ_FILE_INTO_MEMORY,
231                                    PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
232         return response;
233     }
234 
235     if (offset + length > fileSize)
236     {
237         length = fileSize - offset;
238     }
239 
240     if (length % dma::minSize)
241     {
242         log<level::ERR>("Read length is not a multiple of DMA minSize",
243                         entry("LENGTH=%d", length));
244         encode_rw_file_memory_resp(request->hdr.instance_id,
245                                    PLDM_READ_FILE_INTO_MEMORY,
246                                    PLDM_INVALID_READ_LENGTH, 0, responsePtr);
247         return response;
248     }
249 
250     using namespace dma;
251     DMA intf;
252     return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
253                             offset, length, address, true,
254                             request->hdr.instance_id);
255 }
256 
257 Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength)
258 {
259     uint32_t fileHandle = 0;
260     uint32_t offset = 0;
261     uint32_t length = 0;
262     uint64_t address = 0;
263 
264     Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
265     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
266 
267     if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
268     {
269         encode_rw_file_memory_resp(request->hdr.instance_id,
270                                    PLDM_WRITE_FILE_FROM_MEMORY,
271                                    PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
272         return response;
273     }
274 
275     decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
276                               &length, &address);
277 
278     if (length % dma::minSize)
279     {
280         log<level::ERR>("Write length is not a multiple of DMA minSize",
281                         entry("LENGTH=%d", length));
282         encode_rw_file_memory_resp(request->hdr.instance_id,
283                                    PLDM_WRITE_FILE_FROM_MEMORY,
284                                    PLDM_INVALID_WRITE_LENGTH, 0, responsePtr);
285         return response;
286     }
287 
288     using namespace pldm::filetable;
289     auto& table = buildFileTable(FILE_TABLE_JSON);
290     FileEntry value{};
291 
292     try
293     {
294         value = table.at(fileHandle);
295     }
296     catch (std::exception& e)
297     {
298         log<level::ERR>("File handle does not exist in the file table",
299                         entry("HANDLE=%d", fileHandle));
300         encode_rw_file_memory_resp(request->hdr.instance_id,
301                                    PLDM_WRITE_FILE_FROM_MEMORY,
302                                    PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
303         return response;
304     }
305 
306     if (!fs::exists(value.fsPath))
307     {
308         log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
309         encode_rw_file_memory_resp(request->hdr.instance_id,
310                                    PLDM_WRITE_FILE_FROM_MEMORY,
311                                    PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
312         return response;
313     }
314 
315     auto fileSize = fs::file_size(value.fsPath);
316     if (offset >= fileSize)
317     {
318         log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
319                         entry("FILE_SIZE=%d", fileSize));
320         encode_rw_file_memory_resp(request->hdr.instance_id,
321                                    PLDM_WRITE_FILE_FROM_MEMORY,
322                                    PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
323         return response;
324     }
325 
326     using namespace dma;
327     DMA intf;
328     return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
329                             offset, length, address, false,
330                             request->hdr.instance_id);
331 }
332 
333 Response getFileTable(const pldm_msg* request, size_t payloadLength)
334 {
335     uint32_t transferHandle = 0;
336     uint8_t transferFlag = 0;
337     uint8_t tableType = 0;
338 
339     Response response(sizeof(pldm_msg_hdr) +
340                       PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
341     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
342 
343     if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
344     {
345         encode_get_file_table_resp(request->hdr.instance_id,
346                                    PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
347                                    responsePtr);
348         return response;
349     }
350 
351     auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
352                                         &transferFlag, &tableType);
353     if (rc)
354     {
355         encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
356                                    0, responsePtr);
357         return response;
358     }
359 
360     if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
361     {
362         encode_get_file_table_resp(request->hdr.instance_id,
363                                    PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
364                                    0, responsePtr);
365         return response;
366     }
367 
368     using namespace pldm::filetable;
369     auto table = buildFileTable(FILE_TABLE_JSON);
370     auto attrTable = table();
371     response.resize(response.size() + attrTable.size());
372     responsePtr = reinterpret_cast<pldm_msg*>(response.data());
373 
374     if (attrTable.empty())
375     {
376         encode_get_file_table_resp(request->hdr.instance_id,
377                                    PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
378                                    0, responsePtr);
379         return response;
380     }
381 
382     encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
383                                PLDM_START_AND_END, attrTable.data(),
384                                attrTable.size(), responsePtr);
385     return response;
386 }
387 
388 Response readFile(const pldm_msg* request, size_t payloadLength)
389 {
390     uint32_t fileHandle = 0;
391     uint32_t offset = 0;
392     uint32_t length = 0;
393 
394     Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
395     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
396 
397     if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
398     {
399         encode_read_file_resp(request->hdr.instance_id,
400                               PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
401         return response;
402     }
403 
404     auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
405                                    &length);
406 
407     if (rc)
408     {
409         encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
410         return response;
411     }
412 
413     using namespace pldm::filetable;
414     auto& table = buildFileTable(FILE_TABLE_JSON);
415     FileEntry value{};
416 
417     try
418     {
419         value = table.at(fileHandle);
420     }
421     catch (std::exception& e)
422     {
423         log<level::ERR>("File handle does not exist in the file table",
424                         entry("HANDLE=%d", fileHandle));
425         encode_read_file_resp(request->hdr.instance_id,
426                               PLDM_INVALID_FILE_HANDLE, length, responsePtr);
427         return response;
428     }
429 
430     if (!fs::exists(value.fsPath))
431     {
432         log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
433         encode_read_file_resp(request->hdr.instance_id,
434                               PLDM_INVALID_FILE_HANDLE, length, responsePtr);
435         return response;
436     }
437 
438     auto fileSize = fs::file_size(value.fsPath);
439     if (offset >= fileSize)
440     {
441         log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
442                         entry("FILE_SIZE=%d", fileSize));
443         encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
444                               length, responsePtr);
445         return response;
446     }
447 
448     if (offset + length > fileSize)
449     {
450         length = fileSize - offset;
451     }
452 
453     response.resize(response.size() + length);
454     responsePtr = reinterpret_cast<pldm_msg*>(response.data());
455     auto fileDataPos = reinterpret_cast<char*>(responsePtr);
456     fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
457 
458     std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
459     stream.seekg(offset);
460     stream.read(fileDataPos, length);
461 
462     encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
463                           responsePtr);
464 
465     return response;
466 }
467 
468 Response writeFile(const pldm_msg* request, size_t payloadLength)
469 {
470     uint32_t fileHandle = 0;
471     uint32_t offset = 0;
472     uint32_t length = 0;
473     size_t fileDataOffset = 0;
474 
475     Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
476     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
477 
478     if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
479     {
480         encode_write_file_resp(request->hdr.instance_id,
481                                PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
482         return response;
483     }
484 
485     auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
486                                     &offset, &length, &fileDataOffset);
487 
488     if (rc)
489     {
490         encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
491         return response;
492     }
493 
494     using namespace pldm::filetable;
495     auto& table = buildFileTable(FILE_TABLE_JSON);
496     FileEntry value{};
497 
498     try
499     {
500         value = table.at(fileHandle);
501     }
502     catch (std::exception& e)
503     {
504         log<level::ERR>("File handle does not exist in the file table",
505                         entry("HANDLE=%d", fileHandle));
506         encode_write_file_resp(request->hdr.instance_id,
507                                PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
508         return response;
509     }
510 
511     if (!fs::exists(value.fsPath))
512     {
513         log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
514         encode_write_file_resp(request->hdr.instance_id,
515                                PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
516         return response;
517     }
518 
519     auto fileSize = fs::file_size(value.fsPath);
520     if (offset >= fileSize)
521     {
522         log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
523                         entry("FILE_SIZE=%d", fileSize));
524         encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
525                                0, responsePtr);
526         return response;
527     }
528 
529     auto fileDataPos =
530         reinterpret_cast<const char*>(request->payload) + fileDataOffset;
531 
532     std::ofstream stream(value.fsPath,
533                          std::ios::in | std::ios::out | std::ios::binary);
534     stream.seekp(offset);
535     stream.write(fileDataPos, length);
536 
537     encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
538                            responsePtr);
539 
540     return response;
541 }
542 
543 Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
544                                 size_t payloadLength)
545 {
546     Response response(
547         sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
548     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
549 
550     if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
551     {
552         encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
553                                            PLDM_ERROR_INVALID_LENGTH, 0,
554                                            responsePtr);
555         return response;
556     }
557 
558     uint16_t fileType{};
559     uint32_t fileHandle{};
560     uint32_t offset{};
561     uint32_t length{};
562     uint64_t address{};
563     auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
564                                                 &fileType, &fileHandle, &offset,
565                                                 &length, &address);
566     if (rc != PLDM_SUCCESS)
567     {
568         encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
569                                            responsePtr);
570         return response;
571     }
572     if (length % dma::minSize)
573     {
574         log<level::ERR>("Length is not a multiple of DMA minSize",
575                         entry("LENGTH=%d", length));
576         encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
577                                            PLDM_INVALID_WRITE_LENGTH, 0,
578                                            responsePtr);
579         return response;
580     }
581 
582     std::unique_ptr<FileHandler> handler{};
583     try
584     {
585         handler = getHandlerByType(fileType, fileHandle);
586     }
587     catch (const InternalFailure& e)
588     {
589         log<level::ERR>("unknown file type ", entry("TYPE=%d", fileType));
590         encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
591                                            PLDM_INVALID_FILE_TYPE, 0,
592                                            responsePtr);
593         return response;
594     }
595 
596     rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
597              ? handler->writeFromMemory(offset, length, address)
598              : handler->readIntoMemory(offset, length, address);
599     encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
600                                        length, responsePtr);
601     return response;
602 }
603 
604 Response writeFileByTypeFromMemory(const pldm_msg* request,
605                                    size_t payloadLength)
606 {
607     return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
608                                   payloadLength);
609 }
610 
611 Response readFileByTypeIntoMemory(const pldm_msg* request, size_t payloadLength)
612 {
613     return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
614                                   payloadLength);
615 }
616 
617 Response readFileByType(const pldm_msg* request, size_t payloadLength)
618 {
619     Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
620     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
621 
622     if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
623     {
624         encode_rw_file_by_type_resp(request->hdr.instance_id,
625                                     PLDM_READ_FILE_BY_TYPE,
626                                     PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
627         return response;
628     }
629     uint16_t fileType{};
630     uint32_t fileHandle{};
631     uint32_t offset{};
632     uint32_t length{};
633 
634     auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
635                                          &fileHandle, &offset, &length);
636     if (rc != PLDM_SUCCESS)
637     {
638         encode_rw_file_by_type_resp(request->hdr.instance_id,
639                                     PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
640         return response;
641     }
642 
643     std::unique_ptr<FileHandler> handler{};
644     try
645     {
646         handler = getHandlerByType(fileType, fileHandle);
647     }
648     catch (const InternalFailure& e)
649     {
650         log<level::ERR>("unknown file type", entry("TYPE=%d", fileType));
651         encode_rw_file_by_type_resp(request->hdr.instance_id,
652                                     PLDM_READ_FILE_BY_TYPE,
653                                     PLDM_INVALID_FILE_TYPE, 0, responsePtr);
654         return response;
655     }
656 
657     rc = handler->read(offset, length, response);
658     encode_rw_file_by_type_resp(request->hdr.instance_id,
659                                 PLDM_READ_FILE_BY_TYPE, rc, length,
660                                 responsePtr);
661     return response;
662 }
663 
664 } // namespace responder
665 } // namespace pldm
666