blob: 5a43bd6ae6fc03ca86611ad4f46e91293efea42c [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"
Sampa Misra854e61f2019-08-22 04:36:47 -05009#include "xyz/openbmc_project/Common/error.hpp"
10
George Liuc453e162022-12-21 17:16:23 +080011#include <libpldm/base.h>
12#include <libpldm/file_io.h>
Sampa Misra854e61f2019-08-22 04:36:47 -050013#include <stdint.h>
14#include <unistd.h>
15
Riya Dixit49cfb132023-03-02 04:26:53 -060016#include <phosphor-logging/lg2.hpp>
George Liu6492f522020-06-16 10:34:05 +080017#include <xyz/openbmc_project/Logging/Entry/server.hpp>
18
Sampa Misra854e61f2019-08-22 04:36:47 -050019#include <exception>
20#include <filesystem>
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060021#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060022#include <iostream>
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(
92 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
93 "OFFSET", offset, "FILE_SIZE", fileSize);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060094 return PLDM_DATA_OUT_OF_RANGE;
95 }
96 if (offset + length > fileSize)
97 {
98 length = fileSize - offset;
99 }
100 }
101
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600102 int flags{};
103 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -0500104 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600105 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -0500106 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600107 else if (fileExists)
108 {
109 flags = O_RDWR;
110 }
111 else
112 {
113 flags = O_WRONLY;
114 }
115 int file = open(path.string().c_str(), flags);
116 if (file == -1)
117 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600118 error("File does not exist, PATH = {FILE_PATH}", "FILE_PATH",
119 path.string());
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600120 return PLDM_ERROR;
121 }
122 utils::CustomFD fd(file);
123
124 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500125}
126
127std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
128 uint32_t fileHandle)
129{
130 switch (fileType)
131 {
132 case PLDM_FILE_TYPE_PEL:
133 {
134 return std::make_unique<PelHandler>(fileHandle);
Sampa Misra854e61f2019-08-22 04:36:47 -0500135 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600136 case PLDM_FILE_TYPE_LID_PERM:
137 {
138 return std::make_unique<LidHandler>(fileHandle, true);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600139 }
140 case PLDM_FILE_TYPE_LID_TEMP:
141 {
142 return std::make_unique<LidHandler>(fileHandle, false);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600143 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500144 case PLDM_FILE_TYPE_LID_MARKER:
145 {
146 return std::make_unique<LidHandler>(fileHandle, false,
147 PLDM_FILE_TYPE_LID_MARKER);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500148 }
Sampa Misra18967162020-01-14 02:31:41 -0600149 case PLDM_FILE_TYPE_DUMP:
Jayashankar Padathdb124362021-01-28 21:12:34 -0600150 case PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS:
151 case PLDM_FILE_TYPE_RESOURCE_DUMP:
Sampa Misra18967162020-01-14 02:31:41 -0600152 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600153 return std::make_unique<DumpHandler>(fileHandle, fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600154 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500155 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
156 case PLDM_FILE_TYPE_SIGNED_CERT:
157 case PLDM_FILE_TYPE_ROOT_CERT:
158 {
159 return std::make_unique<CertHandler>(fileHandle, fileType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500160 }
Manojkiran Edad94bb832021-02-17 11:40:22 +0530161 case PLDM_FILE_TYPE_PROGRESS_SRC:
162 {
163 return std::make_unique<ProgressCodeHandler>(fileHandle);
164 }
Manojkiran Eda6d1ee4f2022-09-10 04:21:31 -0500165 case PLDM_FILE_TYPE_LID_RUNNING:
166 {
167 return std::make_unique<LidHandler>(fileHandle, false,
168 PLDM_FILE_TYPE_LID_RUNNING);
169 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500170 default:
171 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600172 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500173 break;
174 }
175 }
176 return nullptr;
177}
178
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600179int FileHandler::readFile(const std::string& filePath, uint32_t offset,
180 uint32_t& length, Response& response)
181{
182 if (!fs::exists(filePath))
183 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600184 error("File does not exist, HANDLE={FILE_HANDLE} PATH={FILE_PATH}",
185 "FILE_HANDLE", fileHandle, "FILE_PATH", filePath.c_str());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600186 return PLDM_INVALID_FILE_HANDLE;
187 }
188
189 size_t fileSize = fs::file_size(filePath);
190 if (offset >= fileSize)
191 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600192 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
193 "OFFSET", offset, "FILE_SIZE", fileSize);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600194 return PLDM_DATA_OUT_OF_RANGE;
195 }
196
197 if (offset + length > fileSize)
198 {
199 length = fileSize - offset;
200 }
201
202 size_t currSize = response.size();
203 response.resize(currSize + length);
204 auto filePos = reinterpret_cast<char*>(response.data());
205 filePos += currSize;
206 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
207 if (stream)
208 {
209 stream.seekg(offset);
210 stream.read(filePos, length);
211 return PLDM_SUCCESS;
212 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600213 error("Unable to read file, FILE={FILE_PATH}", "FILE_PATH",
214 filePath.c_str());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600215 return PLDM_ERROR;
216}
217
Sampa Misra854e61f2019-08-22 04:36:47 -0500218} // namespace responder
219} // namespace pldm