blob: d6367ba4c5cedc65de0e716faff4cbcad986004a [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"
Sampa Misra854e61f2019-08-22 04:36:47 -050013#include "xyz/openbmc_project/Common/error.hpp"
14
15#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{
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 }
49 auto rc =
50 xdmaInterface.transferDataHost(fd, offset, length, address, upstream);
51 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
52}
53
Sampa Misra854e61f2019-08-22 04:36:47 -050054int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060055 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050056 uint64_t address)
57{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060058 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060059 if (upstream)
60 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060061 fileExists = fs::exists(path);
62 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060063 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060064 std::cerr << "File does not exist. PATH=" << path.c_str() << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060065 return PLDM_INVALID_FILE_HANDLE;
66 }
67
68 size_t fileSize = fs::file_size(path);
69 if (offset >= fileSize)
70 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060071 std::cerr << "Offset exceeds file size, OFFSET=" << offset
72 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060073 return PLDM_DATA_OUT_OF_RANGE;
74 }
75 if (offset + length > fileSize)
76 {
77 length = fileSize - offset;
78 }
79 }
80
Deepak Kodihalli15211b42019-12-14 02:24:49 -060081 int flags{};
82 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -050083 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060084 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -050085 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -060086 else if (fileExists)
87 {
88 flags = O_RDWR;
89 }
90 else
91 {
92 flags = O_WRONLY;
93 }
94 int file = open(path.string().c_str(), flags);
95 if (file == -1)
96 {
97 std::cerr << "File does not exist, PATH = " << path.string() << "\n";
98 ;
99 return PLDM_ERROR;
100 }
101 utils::CustomFD fd(file);
102
103 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500104}
105
106std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
107 uint32_t fileHandle)
108{
109 switch (fileType)
110 {
111 case PLDM_FILE_TYPE_PEL:
112 {
113 return std::make_unique<PelHandler>(fileHandle);
114 break;
115 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600116 case PLDM_FILE_TYPE_LID_PERM:
117 {
118 return std::make_unique<LidHandler>(fileHandle, true);
119 break;
120 }
121 case PLDM_FILE_TYPE_LID_TEMP:
122 {
123 return std::make_unique<LidHandler>(fileHandle, false);
124 break;
125 }
Sampa Misra18967162020-01-14 02:31:41 -0600126 case PLDM_FILE_TYPE_DUMP:
127 {
128 return std::make_unique<DumpHandler>(fileHandle);
129 break;
130 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500131 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
132 case PLDM_FILE_TYPE_SIGNED_CERT:
133 case PLDM_FILE_TYPE_ROOT_CERT:
134 {
135 return std::make_unique<CertHandler>(fileHandle, fileType);
136 break;
137 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500138 default:
139 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600140 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500141 break;
142 }
143 }
144 return nullptr;
145}
146
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600147int FileHandler::readFile(const std::string& filePath, uint32_t offset,
148 uint32_t& length, Response& response)
149{
150 if (!fs::exists(filePath))
151 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600152 std::cerr << "File does not exist, HANDLE=" << fileHandle
153 << " PATH=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600154 return PLDM_INVALID_FILE_HANDLE;
155 }
156
157 size_t fileSize = fs::file_size(filePath);
158 if (offset >= fileSize)
159 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600160 std::cerr << "Offset exceeds file size, OFFSET=" << offset
161 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600162 return PLDM_DATA_OUT_OF_RANGE;
163 }
164
165 if (offset + length > fileSize)
166 {
167 length = fileSize - offset;
168 }
169
170 size_t currSize = response.size();
171 response.resize(currSize + length);
172 auto filePos = reinterpret_cast<char*>(response.data());
173 filePos += currSize;
174 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
175 if (stream)
176 {
177 stream.seekg(offset);
178 stream.read(filePos, length);
179 return PLDM_SUCCESS;
180 }
Sampa Misraaa8ae722019-12-12 03:20:40 -0600181 std::cerr << "Unable to read file, FILE=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600182 return PLDM_ERROR;
183}
184
Sampa Misra854e61f2019-08-22 04:36:47 -0500185} // namespace responder
186} // namespace pldm