blob: 9bd5e748228c613f2dbfeaca2a29e5907588f34b [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "config.h"
2
3#include "file_io_by_type.hpp"
4
George Liu6492f522020-06-16 10:34:05 +08005#include "libpldm/base.h"
6#include "oem/ibm/libpldm/file_io.h"
7
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05008#include "common/utils.hpp"
Sampa Misrad823cc02020-03-24 04:53:20 -05009#include "file_io_type_cert.hpp"
Sampa Misra18967162020-01-14 02:31:41 -060010#include "file_io_type_dump.hpp"
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060011#include "file_io_type_lid.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050012#include "file_io_type_pel.hpp"
Manojkiran Edad94bb832021-02-17 11:40:22 +053013#include "file_io_type_progress_src.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050014#include "xyz/openbmc_project/Common/error.hpp"
15
16#include <stdint.h>
17#include <unistd.h>
18
George Liu6492f522020-06-16 10:34:05 +080019#include <xyz/openbmc_project/Logging/Entry/server.hpp>
20
Sampa Misra854e61f2019-08-22 04:36:47 -050021#include <exception>
22#include <filesystem>
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060023#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060024#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050025#include <vector>
Sampa Misra854e61f2019-08-22 04:36:47 -050026
27namespace pldm
28{
29namespace responder
30{
31
Sampa Misra854e61f2019-08-22 04:36:47 -050032using namespace sdbusplus::xyz::openbmc_project::Common::Error;
33
Deepak Kodihalli15211b42019-12-14 02:24:49 -060034int FileHandler::transferFileData(int32_t fd, bool upstream, uint32_t offset,
35 uint32_t& length, uint64_t address)
36{
37 dma::DMA xdmaInterface;
38 while (length > dma::maxSize)
39 {
40 auto rc = xdmaInterface.transferDataHost(fd, offset, dma::maxSize,
41 address, upstream);
42 if (rc < 0)
43 {
44 return PLDM_ERROR;
45 }
46 offset += dma::maxSize;
47 length -= dma::maxSize;
48 address += dma::maxSize;
49 }
50 auto rc =
51 xdmaInterface.transferDataHost(fd, offset, length, address, upstream);
52 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
53}
54
Ravi Tejace1c96f2020-10-05 23:13:01 -050055int FileHandler::transferFileDataToSocket(int32_t fd, uint32_t& length,
56 uint64_t address)
57{
58 dma::DMA xdmaInterface;
59 while (length > dma::maxSize)
60 {
61 auto rc =
62 xdmaInterface.transferHostDataToSocket(fd, dma::maxSize, address);
63 if (rc < 0)
64 {
65 return PLDM_ERROR;
66 }
67 length -= dma::maxSize;
68 address += dma::maxSize;
69 }
70 auto rc = xdmaInterface.transferHostDataToSocket(fd, length, address);
71 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
72}
73
Sampa Misra854e61f2019-08-22 04:36:47 -050074int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060075 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050076 uint64_t address)
77{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060078 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060079 if (upstream)
80 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060081 fileExists = fs::exists(path);
82 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060083 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060084 std::cerr << "File does not exist. PATH=" << path.c_str() << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060085 return PLDM_INVALID_FILE_HANDLE;
86 }
87
88 size_t fileSize = fs::file_size(path);
89 if (offset >= fileSize)
90 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060091 std::cerr << "Offset exceeds file size, OFFSET=" << offset
92 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060093 return PLDM_DATA_OUT_OF_RANGE;
94 }
95 if (offset + length > fileSize)
96 {
97 length = fileSize - offset;
98 }
99 }
100
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600101 int flags{};
102 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -0500103 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600104 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -0500105 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600106 else if (fileExists)
107 {
108 flags = O_RDWR;
109 }
110 else
111 {
112 flags = O_WRONLY;
113 }
114 int file = open(path.string().c_str(), flags);
115 if (file == -1)
116 {
117 std::cerr << "File does not exist, PATH = " << path.string() << "\n";
118 ;
119 return PLDM_ERROR;
120 }
121 utils::CustomFD fd(file);
122
123 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500124}
125
126std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
127 uint32_t fileHandle)
128{
129 switch (fileType)
130 {
131 case PLDM_FILE_TYPE_PEL:
132 {
133 return std::make_unique<PelHandler>(fileHandle);
Sampa Misra854e61f2019-08-22 04:36:47 -0500134 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600135 case PLDM_FILE_TYPE_LID_PERM:
136 {
137 return std::make_unique<LidHandler>(fileHandle, true);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600138 }
139 case PLDM_FILE_TYPE_LID_TEMP:
140 {
141 return std::make_unique<LidHandler>(fileHandle, false);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600142 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500143 case PLDM_FILE_TYPE_LID_MARKER:
144 {
145 return std::make_unique<LidHandler>(fileHandle, false,
146 PLDM_FILE_TYPE_LID_MARKER);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500147 }
Sampa Misra18967162020-01-14 02:31:41 -0600148 case PLDM_FILE_TYPE_DUMP:
Jayashankar Padathdb124362021-01-28 21:12:34 -0600149 case PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS:
150 case PLDM_FILE_TYPE_RESOURCE_DUMP:
Sampa Misra18967162020-01-14 02:31:41 -0600151 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600152 return std::make_unique<DumpHandler>(fileHandle, fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600153 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500154 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
155 case PLDM_FILE_TYPE_SIGNED_CERT:
156 case PLDM_FILE_TYPE_ROOT_CERT:
157 {
158 return std::make_unique<CertHandler>(fileHandle, fileType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500159 }
Manojkiran Edad94bb832021-02-17 11:40:22 +0530160 case PLDM_FILE_TYPE_PROGRESS_SRC:
161 {
162 return std::make_unique<ProgressCodeHandler>(fileHandle);
163 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500164 default:
165 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600166 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500167 break;
168 }
169 }
170 return nullptr;
171}
172
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600173int FileHandler::readFile(const std::string& filePath, uint32_t offset,
174 uint32_t& length, Response& response)
175{
176 if (!fs::exists(filePath))
177 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600178 std::cerr << "File does not exist, HANDLE=" << fileHandle
179 << " PATH=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600180 return PLDM_INVALID_FILE_HANDLE;
181 }
182
183 size_t fileSize = fs::file_size(filePath);
184 if (offset >= fileSize)
185 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600186 std::cerr << "Offset exceeds file size, OFFSET=" << offset
187 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600188 return PLDM_DATA_OUT_OF_RANGE;
189 }
190
191 if (offset + length > fileSize)
192 {
193 length = fileSize - offset;
194 }
195
196 size_t currSize = response.size();
197 response.resize(currSize + length);
198 auto filePos = reinterpret_cast<char*>(response.data());
199 filePos += currSize;
200 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
201 if (stream)
202 {
203 stream.seekg(offset);
204 stream.read(filePos, length);
205 return PLDM_SUCCESS;
206 }
Sampa Misraaa8ae722019-12-12 03:20:40 -0600207 std::cerr << "Unable to read file, FILE=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600208 return PLDM_ERROR;
209}
210
Sampa Misra854e61f2019-08-22 04:36:47 -0500211} // namespace responder
212} // namespace pldm