blob: fd0144e8b51b4805dddc1b4d5cac7a26a9c1a4be [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
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 {
60 auto rc =
61 xdmaInterface.transferHostDataToSocket(fd, dma::maxSize, address);
62 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 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060083 std::cerr << "File does not exist. PATH=" << path.c_str() << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060084 return PLDM_INVALID_FILE_HANDLE;
85 }
86
87 size_t fileSize = fs::file_size(path);
88 if (offset >= fileSize)
89 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060090 std::cerr << "Offset exceeds file size, OFFSET=" << offset
91 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060092 return PLDM_DATA_OUT_OF_RANGE;
93 }
94 if (offset + length > fileSize)
95 {
96 length = fileSize - offset;
97 }
98 }
99
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600100 int flags{};
101 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -0500102 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600103 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -0500104 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600105 else if (fileExists)
106 {
107 flags = O_RDWR;
108 }
109 else
110 {
111 flags = O_WRONLY;
112 }
113 int file = open(path.string().c_str(), flags);
114 if (file == -1)
115 {
116 std::cerr << "File does not exist, PATH = " << path.string() << "\n";
117 ;
118 return PLDM_ERROR;
119 }
120 utils::CustomFD fd(file);
121
122 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500123}
124
125std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
126 uint32_t fileHandle)
127{
128 switch (fileType)
129 {
130 case PLDM_FILE_TYPE_PEL:
131 {
132 return std::make_unique<PelHandler>(fileHandle);
Sampa Misra854e61f2019-08-22 04:36:47 -0500133 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600134 case PLDM_FILE_TYPE_LID_PERM:
135 {
136 return std::make_unique<LidHandler>(fileHandle, true);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600137 }
138 case PLDM_FILE_TYPE_LID_TEMP:
139 {
140 return std::make_unique<LidHandler>(fileHandle, false);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600141 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500142 case PLDM_FILE_TYPE_LID_MARKER:
143 {
144 return std::make_unique<LidHandler>(fileHandle, false,
145 PLDM_FILE_TYPE_LID_MARKER);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500146 }
Sampa Misra18967162020-01-14 02:31:41 -0600147 case PLDM_FILE_TYPE_DUMP:
Jayashankar Padathdb124362021-01-28 21:12:34 -0600148 case PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS:
149 case PLDM_FILE_TYPE_RESOURCE_DUMP:
Sampa Misra18967162020-01-14 02:31:41 -0600150 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600151 return std::make_unique<DumpHandler>(fileHandle, fileType);
Sampa Misra18967162020-01-14 02:31:41 -0600152 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500153 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
154 case PLDM_FILE_TYPE_SIGNED_CERT:
155 case PLDM_FILE_TYPE_ROOT_CERT:
156 {
157 return std::make_unique<CertHandler>(fileHandle, fileType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500158 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500159 default:
160 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600161 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500162 break;
163 }
164 }
165 return nullptr;
166}
167
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600168int FileHandler::readFile(const std::string& filePath, uint32_t offset,
169 uint32_t& length, Response& response)
170{
171 if (!fs::exists(filePath))
172 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600173 std::cerr << "File does not exist, HANDLE=" << fileHandle
174 << " PATH=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600175 return PLDM_INVALID_FILE_HANDLE;
176 }
177
178 size_t fileSize = fs::file_size(filePath);
179 if (offset >= fileSize)
180 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600181 std::cerr << "Offset exceeds file size, OFFSET=" << offset
182 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600183 return PLDM_DATA_OUT_OF_RANGE;
184 }
185
186 if (offset + length > fileSize)
187 {
188 length = fileSize - offset;
189 }
190
191 size_t currSize = response.size();
192 response.resize(currSize + length);
193 auto filePos = reinterpret_cast<char*>(response.data());
194 filePos += currSize;
195 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
196 if (stream)
197 {
198 stream.seekg(offset);
199 stream.read(filePos, length);
200 return PLDM_SUCCESS;
201 }
Sampa Misraaa8ae722019-12-12 03:20:40 -0600202 std::cerr << "Unable to read file, FILE=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600203 return PLDM_ERROR;
204}
205
Sampa Misra854e61f2019-08-22 04:36:47 -0500206} // namespace responder
207} // namespace pldm