blob: 2ecc3d9ceb472b335255e6070462043b198ae06b [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "config.h"
2
3#include "file_io_by_type.hpp"
4
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"
George Liu83409572019-12-24 18:42:54 +08008#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05009#include "xyz/openbmc_project/Common/error.hpp"
10
11#include <stdint.h>
12#include <unistd.h>
13
14#include <exception>
15#include <filesystem>
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060016#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060017#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050018#include <vector>
19#include <xyz/openbmc_project/Logging/Entry/server.hpp>
20
21#include "libpldm/base.h"
22#include "oem/ibm/libpldm/file_io.h"
23
24namespace pldm
25{
26namespace responder
27{
28
Sampa Misra854e61f2019-08-22 04:36:47 -050029using namespace sdbusplus::xyz::openbmc_project::Common::Error;
30
Deepak Kodihalli15211b42019-12-14 02:24:49 -060031int FileHandler::transferFileData(int32_t fd, bool upstream, uint32_t offset,
32 uint32_t& length, uint64_t address)
33{
34 dma::DMA xdmaInterface;
35 while (length > dma::maxSize)
36 {
37 auto rc = xdmaInterface.transferDataHost(fd, offset, dma::maxSize,
38 address, upstream);
39 if (rc < 0)
40 {
41 return PLDM_ERROR;
42 }
43 offset += dma::maxSize;
44 length -= dma::maxSize;
45 address += dma::maxSize;
46 }
47 auto rc =
48 xdmaInterface.transferDataHost(fd, offset, length, address, upstream);
49 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
50}
51
Sampa Misra854e61f2019-08-22 04:36:47 -050052int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060053 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050054 uint64_t address)
55{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060056 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060057 if (upstream)
58 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060059 fileExists = fs::exists(path);
60 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060061 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060062 std::cerr << "File does not exist. PATH=" << path.c_str() << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060063 return PLDM_INVALID_FILE_HANDLE;
64 }
65
66 size_t fileSize = fs::file_size(path);
67 if (offset >= fileSize)
68 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060069 std::cerr << "Offset exceeds file size, OFFSET=" << offset
70 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060071 return PLDM_DATA_OUT_OF_RANGE;
72 }
73 if (offset + length > fileSize)
74 {
75 length = fileSize - offset;
76 }
77 }
78
Deepak Kodihalli15211b42019-12-14 02:24:49 -060079 int flags{};
80 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -050081 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060082 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -050083 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -060084 else if (fileExists)
85 {
86 flags = O_RDWR;
87 }
88 else
89 {
90 flags = O_WRONLY;
91 }
92 int file = open(path.string().c_str(), flags);
93 if (file == -1)
94 {
95 std::cerr << "File does not exist, PATH = " << path.string() << "\n";
96 ;
97 return PLDM_ERROR;
98 }
99 utils::CustomFD fd(file);
100
101 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500102}
103
104std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
105 uint32_t fileHandle)
106{
107 switch (fileType)
108 {
109 case PLDM_FILE_TYPE_PEL:
110 {
111 return std::make_unique<PelHandler>(fileHandle);
112 break;
113 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600114 case PLDM_FILE_TYPE_LID_PERM:
115 {
116 return std::make_unique<LidHandler>(fileHandle, true);
117 break;
118 }
119 case PLDM_FILE_TYPE_LID_TEMP:
120 {
121 return std::make_unique<LidHandler>(fileHandle, false);
122 break;
123 }
Sampa Misra18967162020-01-14 02:31:41 -0600124 case PLDM_FILE_TYPE_DUMP:
125 {
126 return std::make_unique<DumpHandler>(fileHandle);
127 break;
128 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500129 default:
130 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600131 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500132 break;
133 }
134 }
135 return nullptr;
136}
137
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600138int FileHandler::readFile(const std::string& filePath, uint32_t offset,
139 uint32_t& length, Response& response)
140{
141 if (!fs::exists(filePath))
142 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600143 std::cerr << "File does not exist, HANDLE=" << fileHandle
144 << " PATH=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600145 return PLDM_INVALID_FILE_HANDLE;
146 }
147
148 size_t fileSize = fs::file_size(filePath);
149 if (offset >= fileSize)
150 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600151 std::cerr << "Offset exceeds file size, OFFSET=" << offset
152 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600153 return PLDM_DATA_OUT_OF_RANGE;
154 }
155
156 if (offset + length > fileSize)
157 {
158 length = fileSize - offset;
159 }
160
161 size_t currSize = response.size();
162 response.resize(currSize + length);
163 auto filePos = reinterpret_cast<char*>(response.data());
164 filePos += currSize;
165 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
166 if (stream)
167 {
168 stream.seekg(offset);
169 stream.read(filePos, length);
170 return PLDM_SUCCESS;
171 }
Sampa Misraaa8ae722019-12-12 03:20:40 -0600172 std::cerr << "Unable to read file, FILE=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600173 return PLDM_ERROR;
174}
175
Sampa Misra854e61f2019-08-22 04:36:47 -0500176} // namespace responder
177} // namespace pldm