blob: dc575d253b4f089fd6b0e7a5009fd05c4df3b996 [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "config.h"
2
3#include "file_io_by_type.hpp"
4
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05005#include "common/utils.hpp"
Sampa Misrad823cc02020-03-24 04:53:20 -05006#include "file_io_type_cert.hpp"
Sampa Misra18967162020-01-14 02:31:41 -06007#include "file_io_type_dump.hpp"
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06008#include "file_io_type_lid.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05009#include "file_io_type_pel.hpp"
Manojkiran Edad94bb832021-02-17 11:40:22 +053010#include "file_io_type_progress_src.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050011#include "xyz/openbmc_project/Common/error.hpp"
12
George Liuc453e162022-12-21 17:16:23 +080013#include <libpldm/base.h>
14#include <libpldm/file_io.h>
Sampa Misra854e61f2019-08-22 04:36:47 -050015#include <stdint.h>
16#include <unistd.h>
17
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 Misraaa8ae722019-12-12 03:20:40 -060023#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050024#include <vector>
Sampa Misra854e61f2019-08-22 04:36:47 -050025
26namespace pldm
27{
28namespace responder
29{
Sampa Misra854e61f2019-08-22 04:36:47 -050030using namespace sdbusplus::xyz::openbmc_project::Common::Error;
31
Deepak Kodihalli15211b42019-12-14 02:24:49 -060032int FileHandler::transferFileData(int32_t fd, bool upstream, uint32_t offset,
33 uint32_t& length, uint64_t address)
34{
35 dma::DMA xdmaInterface;
36 while (length > dma::maxSize)
37 {
38 auto rc = xdmaInterface.transferDataHost(fd, offset, dma::maxSize,
39 address, upstream);
40 if (rc < 0)
41 {
42 return PLDM_ERROR;
43 }
44 offset += dma::maxSize;
45 length -= dma::maxSize;
46 address += dma::maxSize;
47 }
48 auto rc =
49 xdmaInterface.transferDataHost(fd, offset, length, address, upstream);
50 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
51}
52
Ravi Tejace1c96f2020-10-05 23:13:01 -050053int FileHandler::transferFileDataToSocket(int32_t fd, uint32_t& length,
54 uint64_t address)
55{
56 dma::DMA xdmaInterface;
57 while (length > dma::maxSize)
58 {
59 auto rc =
60 xdmaInterface.transferHostDataToSocket(fd, dma::maxSize, address);
61 if (rc < 0)
62 {
63 return PLDM_ERROR;
64 }
65 length -= dma::maxSize;
66 address += dma::maxSize;
67 }
68 auto rc = xdmaInterface.transferHostDataToSocket(fd, length, address);
69 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
70}
71
Sampa Misra854e61f2019-08-22 04:36:47 -050072int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060073 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050074 uint64_t address)
75{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060076 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060077 if (upstream)
78 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060079 fileExists = fs::exists(path);
80 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060081 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060082 std::cerr << "File does not exist. PATH=" << path.c_str() << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060083 return PLDM_INVALID_FILE_HANDLE;
84 }
85
86 size_t fileSize = fs::file_size(path);
87 if (offset >= fileSize)
88 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060089 std::cerr << "Offset exceeds file size, OFFSET=" << offset
90 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060091 return PLDM_DATA_OUT_OF_RANGE;
92 }
93 if (offset + length > fileSize)
94 {
95 length = fileSize - offset;
96 }
97 }
98
Deepak Kodihalli15211b42019-12-14 02:24:49 -060099 int flags{};
100 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -0500101 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600102 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -0500103 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600104 else if (fileExists)
105 {
106 flags = O_RDWR;
107 }
108 else
109 {
110 flags = O_WRONLY;
111 }
112 int file = open(path.string().c_str(), flags);
113 if (file == -1)
114 {
115 std::cerr << "File does not exist, PATH = " << path.string() << "\n";
116 ;
117 return PLDM_ERROR;
118 }
119 utils::CustomFD fd(file);
120
121 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500122}
123
124std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
125 uint32_t fileHandle)
126{
127 switch (fileType)
128 {
129 case PLDM_FILE_TYPE_PEL:
130 {
131 return std::make_unique<PelHandler>(fileHandle);
Sampa Misra854e61f2019-08-22 04:36:47 -0500132 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600133 case PLDM_FILE_TYPE_LID_PERM:
134 {
135 return std::make_unique<LidHandler>(fileHandle, true);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600136 }
137 case PLDM_FILE_TYPE_LID_TEMP:
138 {
139 return std::make_unique<LidHandler>(fileHandle, false);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600140 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500141 case PLDM_FILE_TYPE_LID_MARKER:
142 {
143 return std::make_unique<LidHandler>(fileHandle, false,
144 PLDM_FILE_TYPE_LID_MARKER);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500145 }
Sampa Misra18967162020-01-14 02:31:41 -0600146 case PLDM_FILE_TYPE_DUMP:
Jayashankar Padathdb124362021-01-28 21:12:34 -0600147 case PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS:
148 case PLDM_FILE_TYPE_RESOURCE_DUMP:
Sampa Misra18967162020-01-14 02:31:41 -0600149 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600150 return std::make_unique<DumpHandler>(fileHandle, fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600151 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500152 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
153 case PLDM_FILE_TYPE_SIGNED_CERT:
154 case PLDM_FILE_TYPE_ROOT_CERT:
155 {
156 return std::make_unique<CertHandler>(fileHandle, fileType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500157 }
Manojkiran Edad94bb832021-02-17 11:40:22 +0530158 case PLDM_FILE_TYPE_PROGRESS_SRC:
159 {
160 return std::make_unique<ProgressCodeHandler>(fileHandle);
161 }
Manojkiran Eda6d1ee4f2022-09-10 04:21:31 -0500162 case PLDM_FILE_TYPE_LID_RUNNING:
163 {
164 return std::make_unique<LidHandler>(fileHandle, false,
165 PLDM_FILE_TYPE_LID_RUNNING);
166 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500167 default:
168 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600169 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500170 break;
171 }
172 }
173 return nullptr;
174}
175
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600176int FileHandler::readFile(const std::string& filePath, uint32_t offset,
177 uint32_t& length, Response& response)
178{
179 if (!fs::exists(filePath))
180 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600181 std::cerr << "File does not exist, HANDLE=" << fileHandle
182 << " PATH=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600183 return PLDM_INVALID_FILE_HANDLE;
184 }
185
186 size_t fileSize = fs::file_size(filePath);
187 if (offset >= fileSize)
188 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600189 std::cerr << "Offset exceeds file size, OFFSET=" << offset
190 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600191 return PLDM_DATA_OUT_OF_RANGE;
192 }
193
194 if (offset + length > fileSize)
195 {
196 length = fileSize - offset;
197 }
198
199 size_t currSize = response.size();
200 response.resize(currSize + length);
201 auto filePos = reinterpret_cast<char*>(response.data());
202 filePos += currSize;
203 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
204 if (stream)
205 {
206 stream.seekg(offset);
207 stream.read(filePos, length);
208 return PLDM_SUCCESS;
209 }
Sampa Misraaa8ae722019-12-12 03:20:40 -0600210 std::cerr << "Unable to read file, FILE=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600211 return PLDM_ERROR;
212}
213
Sampa Misra854e61f2019-08-22 04:36:47 -0500214} // namespace responder
215} // namespace pldm