blob: 9826fdb80ff51d709a6fe06ae17cc8ad2d99ded8 [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "file_io_by_type.hpp"
2
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05003#include "common/utils.hpp"
Sampa Misrad823cc02020-03-24 04:53:20 -05004#include "file_io_type_cert.hpp"
Sampa Misra18967162020-01-14 02:31:41 -06005#include "file_io_type_dump.hpp"
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06006#include "file_io_type_lid.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05007#include "file_io_type_pel.hpp"
Manojkiran Edad94bb832021-02-17 11:40:22 +05308#include "file_io_type_progress_src.hpp"
Varsha Kaverappae1874e82023-05-02 09:53:24 -05009#include "file_io_type_vpd.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050010#include "xyz/openbmc_project/Common/error.hpp"
11
George Liuc453e162022-12-21 17:16:23 +080012#include <libpldm/base.h>
Andrew Jeffery21f128d2024-01-15 15:34:26 +103013#include <libpldm/oem/ibm/file_io.h>
Sampa Misra854e61f2019-08-22 04:36:47 -050014#include <stdint.h>
15#include <unistd.h>
16
Riya Dixit49cfb132023-03-02 04:26:53 -060017#include <phosphor-logging/lg2.hpp>
George Liu6492f522020-06-16 10:34:05 +080018#include <xyz/openbmc_project/Logging/Entry/server.hpp>
19
Sampa Misra854e61f2019-08-22 04:36:47 -050020#include <exception>
21#include <filesystem>
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060022#include <fstream>
Sampa Misra854e61f2019-08-22 04:36:47 -050023#include <vector>
Sampa Misra854e61f2019-08-22 04:36:47 -050024
Riya Dixit49cfb132023-03-02 04:26:53 -060025PHOSPHOR_LOG2_USING;
26
Sampa Misra854e61f2019-08-22 04:36:47 -050027namespace pldm
28{
29namespace responder
30{
Sampa Misra854e61f2019-08-22 04:36:47 -050031using namespace sdbusplus::xyz::openbmc_project::Common::Error;
32
Deepak Kodihalli15211b42019-12-14 02:24:49 -060033int FileHandler::transferFileData(int32_t fd, bool upstream, uint32_t offset,
34 uint32_t& length, uint64_t address)
35{
36 dma::DMA xdmaInterface;
37 while (length > dma::maxSize)
38 {
39 auto rc = xdmaInterface.transferDataHost(fd, offset, dma::maxSize,
40 address, upstream);
41 if (rc < 0)
42 {
43 return PLDM_ERROR;
44 }
45 offset += dma::maxSize;
46 length -= dma::maxSize;
47 address += dma::maxSize;
48 }
Patrick Williams6da4f912023-05-10 07:50:53 -050049 auto rc = xdmaInterface.transferDataHost(fd, offset, length, address,
50 upstream);
Deepak Kodihalli15211b42019-12-14 02:24:49 -060051 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
52}
53
Ravi Tejace1c96f2020-10-05 23:13:01 -050054int FileHandler::transferFileDataToSocket(int32_t fd, uint32_t& length,
55 uint64_t address)
56{
57 dma::DMA xdmaInterface;
58 while (length > dma::maxSize)
59 {
Patrick Williams6da4f912023-05-10 07:50:53 -050060 auto rc = xdmaInterface.transferHostDataToSocket(fd, dma::maxSize,
61 address);
Ravi Tejace1c96f2020-10-05 23:13:01 -050062 if (rc < 0)
63 {
64 return PLDM_ERROR;
65 }
66 length -= dma::maxSize;
67 address += dma::maxSize;
68 }
69 auto rc = xdmaInterface.transferHostDataToSocket(fd, length, address);
70 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
71}
72
Sampa Misra854e61f2019-08-22 04:36:47 -050073int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060074 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050075 uint64_t address)
76{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060077 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060078 if (upstream)
79 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060080 fileExists = fs::exists(path);
81 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060082 {
Riya Dixit49cfb132023-03-02 04:26:53 -060083 error("File does not exist. PATH={FILE_PATH}", "FILE_PATH",
84 path.c_str());
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 {
Riya Dixit49cfb132023-03-02 04:26:53 -060091 error(
Sagar Srinivas82257922023-07-10 08:12:22 -050092 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}, FILE_HANDLE={FILE_HANDLE}",
93 "OFFSET", offset, "FILE_SIZE", fileSize, "FILE_HANDLE",
94 fileHandle);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060095 return PLDM_DATA_OUT_OF_RANGE;
96 }
97 if (offset + length > fileSize)
98 {
99 length = fileSize - offset;
100 }
101 }
102
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600103 int flags{};
104 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -0500105 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600106 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -0500107 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600108 else if (fileExists)
109 {
110 flags = O_RDWR;
111 }
112 else
113 {
114 flags = O_WRONLY;
115 }
116 int file = open(path.string().c_str(), flags);
117 if (file == -1)
118 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600119 error("File does not exist, PATH = {FILE_PATH}", "FILE_PATH",
120 path.string());
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600121 return PLDM_ERROR;
122 }
123 utils::CustomFD fd(file);
124
125 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500126}
127
128std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
129 uint32_t fileHandle)
130{
131 switch (fileType)
132 {
133 case PLDM_FILE_TYPE_PEL:
134 {
135 return std::make_unique<PelHandler>(fileHandle);
Sampa Misra854e61f2019-08-22 04:36:47 -0500136 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600137 case PLDM_FILE_TYPE_LID_PERM:
138 {
139 return std::make_unique<LidHandler>(fileHandle, true);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600140 }
141 case PLDM_FILE_TYPE_LID_TEMP:
142 {
143 return std::make_unique<LidHandler>(fileHandle, false);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600144 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500145 case PLDM_FILE_TYPE_LID_MARKER:
146 {
147 return std::make_unique<LidHandler>(fileHandle, false,
148 PLDM_FILE_TYPE_LID_MARKER);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500149 }
Sampa Misra18967162020-01-14 02:31:41 -0600150 case PLDM_FILE_TYPE_DUMP:
Jayashankar Padathdb124362021-01-28 21:12:34 -0600151 case PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS:
152 case PLDM_FILE_TYPE_RESOURCE_DUMP:
Sampa Misra18967162020-01-14 02:31:41 -0600153 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600154 return std::make_unique<DumpHandler>(fileHandle, fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600155 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500156 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
157 case PLDM_FILE_TYPE_SIGNED_CERT:
158 case PLDM_FILE_TYPE_ROOT_CERT:
159 {
160 return std::make_unique<CertHandler>(fileHandle, fileType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500161 }
Manojkiran Edad94bb832021-02-17 11:40:22 +0530162 case PLDM_FILE_TYPE_PROGRESS_SRC:
163 {
164 return std::make_unique<ProgressCodeHandler>(fileHandle);
165 }
Manojkiran Eda6d1ee4f2022-09-10 04:21:31 -0500166 case PLDM_FILE_TYPE_LID_RUNNING:
167 {
168 return std::make_unique<LidHandler>(fileHandle, false,
169 PLDM_FILE_TYPE_LID_RUNNING);
170 }
Varsha Kaverappae1874e82023-05-02 09:53:24 -0500171 case PLDM_FILE_TYPE_PSPD_VPD_PDD_KEYWORD:
172 {
173 return std::make_unique<keywordHandler>(fileHandle, fileType);
174 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500175 default:
176 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600177 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500178 break;
179 }
180 }
181 return nullptr;
182}
183
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600184int FileHandler::readFile(const std::string& filePath, uint32_t offset,
185 uint32_t& length, Response& response)
186{
187 if (!fs::exists(filePath))
188 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600189 error("File does not exist, HANDLE={FILE_HANDLE} PATH={FILE_PATH}",
190 "FILE_HANDLE", fileHandle, "FILE_PATH", filePath.c_str());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600191 return PLDM_INVALID_FILE_HANDLE;
192 }
193
194 size_t fileSize = fs::file_size(filePath);
195 if (offset >= fileSize)
196 {
Sagar Srinivas82257922023-07-10 08:12:22 -0500197 error(
198 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE} FILE_HANDLE={FILE_HANDLE}",
199 "OFFSET", offset, "FILE_SIZE", fileSize, "FILE_HANDLE", fileHandle);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600200 return PLDM_DATA_OUT_OF_RANGE;
201 }
202
203 if (offset + length > fileSize)
204 {
205 length = fileSize - offset;
206 }
207
208 size_t currSize = response.size();
209 response.resize(currSize + length);
210 auto filePos = reinterpret_cast<char*>(response.data());
211 filePos += currSize;
212 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
213 if (stream)
214 {
215 stream.seekg(offset);
216 stream.read(filePos, length);
217 return PLDM_SUCCESS;
218 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600219 error("Unable to read file, FILE={FILE_PATH}", "FILE_PATH",
220 filePath.c_str());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600221 return PLDM_ERROR;
222}
223
Sampa Misra854e61f2019-08-22 04:36:47 -0500224} // namespace responder
225} // namespace pldm