blob: ec001faa0c0dcc51527ebc78e3bf4430c009fe98 [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
Riya Dixit49cfb132023-03-02 04:26:53 -060018#include <phosphor-logging/lg2.hpp>
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
Riya Dixit49cfb132023-03-02 04:26:53 -060027PHOSPHOR_LOG2_USING;
28
Sampa Misra854e61f2019-08-22 04:36:47 -050029namespace pldm
30{
31namespace responder
32{
Sampa Misra854e61f2019-08-22 04:36:47 -050033using namespace sdbusplus::xyz::openbmc_project::Common::Error;
34
Deepak Kodihalli15211b42019-12-14 02:24:49 -060035int FileHandler::transferFileData(int32_t fd, bool upstream, uint32_t offset,
36 uint32_t& length, uint64_t address)
37{
38 dma::DMA xdmaInterface;
39 while (length > dma::maxSize)
40 {
41 auto rc = xdmaInterface.transferDataHost(fd, offset, dma::maxSize,
42 address, upstream);
43 if (rc < 0)
44 {
45 return PLDM_ERROR;
46 }
47 offset += dma::maxSize;
48 length -= dma::maxSize;
49 address += dma::maxSize;
50 }
51 auto rc =
52 xdmaInterface.transferDataHost(fd, offset, length, address, upstream);
53 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
54}
55
Ravi Tejace1c96f2020-10-05 23:13:01 -050056int FileHandler::transferFileDataToSocket(int32_t fd, uint32_t& length,
57 uint64_t address)
58{
59 dma::DMA xdmaInterface;
60 while (length > dma::maxSize)
61 {
62 auto rc =
63 xdmaInterface.transferHostDataToSocket(fd, dma::maxSize, address);
64 if (rc < 0)
65 {
66 return PLDM_ERROR;
67 }
68 length -= dma::maxSize;
69 address += dma::maxSize;
70 }
71 auto rc = xdmaInterface.transferHostDataToSocket(fd, length, address);
72 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
73}
74
Sampa Misra854e61f2019-08-22 04:36:47 -050075int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060076 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050077 uint64_t address)
78{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060079 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060080 if (upstream)
81 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060082 fileExists = fs::exists(path);
83 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060084 {
Riya Dixit49cfb132023-03-02 04:26:53 -060085 error("File does not exist. PATH={FILE_PATH}", "FILE_PATH",
86 path.c_str());
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060087 return PLDM_INVALID_FILE_HANDLE;
88 }
89
90 size_t fileSize = fs::file_size(path);
91 if (offset >= fileSize)
92 {
Riya Dixit49cfb132023-03-02 04:26:53 -060093 error(
94 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
95 "OFFSET", offset, "FILE_SIZE", fileSize);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060096 return PLDM_DATA_OUT_OF_RANGE;
97 }
98 if (offset + length > fileSize)
99 {
100 length = fileSize - offset;
101 }
102 }
103
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600104 int flags{};
105 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -0500106 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600107 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -0500108 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600109 else if (fileExists)
110 {
111 flags = O_RDWR;
112 }
113 else
114 {
115 flags = O_WRONLY;
116 }
117 int file = open(path.string().c_str(), flags);
118 if (file == -1)
119 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600120 error("File does not exist, PATH = {FILE_PATH}", "FILE_PATH",
121 path.string());
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600122 return PLDM_ERROR;
123 }
124 utils::CustomFD fd(file);
125
126 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500127}
128
129std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
130 uint32_t fileHandle)
131{
132 switch (fileType)
133 {
134 case PLDM_FILE_TYPE_PEL:
135 {
136 return std::make_unique<PelHandler>(fileHandle);
Sampa Misra854e61f2019-08-22 04:36:47 -0500137 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600138 case PLDM_FILE_TYPE_LID_PERM:
139 {
140 return std::make_unique<LidHandler>(fileHandle, true);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600141 }
142 case PLDM_FILE_TYPE_LID_TEMP:
143 {
144 return std::make_unique<LidHandler>(fileHandle, false);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600145 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500146 case PLDM_FILE_TYPE_LID_MARKER:
147 {
148 return std::make_unique<LidHandler>(fileHandle, false,
149 PLDM_FILE_TYPE_LID_MARKER);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500150 }
Sampa Misra18967162020-01-14 02:31:41 -0600151 case PLDM_FILE_TYPE_DUMP:
Jayashankar Padathdb124362021-01-28 21:12:34 -0600152 case PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS:
153 case PLDM_FILE_TYPE_RESOURCE_DUMP:
Sampa Misra18967162020-01-14 02:31:41 -0600154 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600155 return std::make_unique<DumpHandler>(fileHandle, fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600156 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500157 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
158 case PLDM_FILE_TYPE_SIGNED_CERT:
159 case PLDM_FILE_TYPE_ROOT_CERT:
160 {
161 return std::make_unique<CertHandler>(fileHandle, fileType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500162 }
Manojkiran Edad94bb832021-02-17 11:40:22 +0530163 case PLDM_FILE_TYPE_PROGRESS_SRC:
164 {
165 return std::make_unique<ProgressCodeHandler>(fileHandle);
166 }
Manojkiran Eda6d1ee4f2022-09-10 04:21:31 -0500167 case PLDM_FILE_TYPE_LID_RUNNING:
168 {
169 return std::make_unique<LidHandler>(fileHandle, false,
170 PLDM_FILE_TYPE_LID_RUNNING);
171 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500172 default:
173 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600174 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500175 break;
176 }
177 }
178 return nullptr;
179}
180
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600181int FileHandler::readFile(const std::string& filePath, uint32_t offset,
182 uint32_t& length, Response& response)
183{
184 if (!fs::exists(filePath))
185 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600186 error("File does not exist, HANDLE={FILE_HANDLE} PATH={FILE_PATH}",
187 "FILE_HANDLE", fileHandle, "FILE_PATH", filePath.c_str());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600188 return PLDM_INVALID_FILE_HANDLE;
189 }
190
191 size_t fileSize = fs::file_size(filePath);
192 if (offset >= fileSize)
193 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600194 error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
195 "OFFSET", offset, "FILE_SIZE", fileSize);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600196 return PLDM_DATA_OUT_OF_RANGE;
197 }
198
199 if (offset + length > fileSize)
200 {
201 length = fileSize - offset;
202 }
203
204 size_t currSize = response.size();
205 response.resize(currSize + length);
206 auto filePos = reinterpret_cast<char*>(response.data());
207 filePos += currSize;
208 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
209 if (stream)
210 {
211 stream.seekg(offset);
212 stream.read(filePos, length);
213 return PLDM_SUCCESS;
214 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600215 error("Unable to read file, FILE={FILE_PATH}", "FILE_PATH",
216 filePath.c_str());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600217 return PLDM_ERROR;
218}
219
Sampa Misra854e61f2019-08-22 04:36:47 -0500220} // namespace responder
221} // namespace pldm