blob: 540937c1c342ac6badfd45281b9daa15f8940db2 [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "config.h"
2
3#include "file_io_by_type.hpp"
4
Sampa Misrad823cc02020-03-24 04:53:20 -05005#include "file_io_type_cert.hpp"
Sampa Misra18967162020-01-14 02:31:41 -06006#include "file_io_type_dump.hpp"
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06007#include "file_io_type_lid.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05008#include "file_io_type_pel.hpp"
George Liu83409572019-12-24 18:42:54 +08009#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050010#include "xyz/openbmc_project/Common/error.hpp"
11
12#include <stdint.h>
13#include <unistd.h>
14
15#include <exception>
16#include <filesystem>
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060017#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060018#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050019#include <vector>
20#include <xyz/openbmc_project/Logging/Entry/server.hpp>
21
22#include "libpldm/base.h"
23#include "oem/ibm/libpldm/file_io.h"
24
25namespace pldm
26{
27namespace responder
28{
29
Sampa Misra854e61f2019-08-22 04:36:47 -050030using namespace sdbusplus::xyz::openbmc_project::Common::Error;
31
Deepak Kodihalli15211b42019-12-14 02:24:49 -060032int FileHandler::transferFileData(int32_t fd, bool upstream, uint32_t offset,
33 uint32_t& length, uint64_t address)
34{
35 dma::DMA xdmaInterface;
36 while (length > dma::maxSize)
37 {
38 auto rc = xdmaInterface.transferDataHost(fd, offset, dma::maxSize,
39 address, upstream);
40 if (rc < 0)
41 {
42 return PLDM_ERROR;
43 }
44 offset += dma::maxSize;
45 length -= dma::maxSize;
46 address += dma::maxSize;
47 }
48 auto rc =
49 xdmaInterface.transferDataHost(fd, offset, length, address, upstream);
50 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
51}
52
Sampa Misra854e61f2019-08-22 04:36:47 -050053int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060054 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050055 uint64_t address)
56{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060057 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060058 if (upstream)
59 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060060 fileExists = fs::exists(path);
61 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060062 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060063 std::cerr << "File does not exist. PATH=" << path.c_str() << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060064 return PLDM_INVALID_FILE_HANDLE;
65 }
66
67 size_t fileSize = fs::file_size(path);
68 if (offset >= fileSize)
69 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060070 std::cerr << "Offset exceeds file size, OFFSET=" << offset
71 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060072 return PLDM_DATA_OUT_OF_RANGE;
73 }
74 if (offset + length > fileSize)
75 {
76 length = fileSize - offset;
77 }
78 }
79
Deepak Kodihalli15211b42019-12-14 02:24:49 -060080 int flags{};
81 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -050082 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060083 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -050084 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -060085 else if (fileExists)
86 {
87 flags = O_RDWR;
88 }
89 else
90 {
91 flags = O_WRONLY;
92 }
93 int file = open(path.string().c_str(), flags);
94 if (file == -1)
95 {
96 std::cerr << "File does not exist, PATH = " << path.string() << "\n";
97 ;
98 return PLDM_ERROR;
99 }
100 utils::CustomFD fd(file);
101
102 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500103}
104
105std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
106 uint32_t fileHandle)
107{
108 switch (fileType)
109 {
110 case PLDM_FILE_TYPE_PEL:
111 {
112 return std::make_unique<PelHandler>(fileHandle);
113 break;
114 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600115 case PLDM_FILE_TYPE_LID_PERM:
116 {
117 return std::make_unique<LidHandler>(fileHandle, true);
118 break;
119 }
120 case PLDM_FILE_TYPE_LID_TEMP:
121 {
122 return std::make_unique<LidHandler>(fileHandle, false);
123 break;
124 }
Sampa Misra18967162020-01-14 02:31:41 -0600125 case PLDM_FILE_TYPE_DUMP:
126 {
127 return std::make_unique<DumpHandler>(fileHandle);
128 break;
129 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500130 case PLDM_FILE_TYPE_CERT_SIGNING_REQUEST:
131 case PLDM_FILE_TYPE_SIGNED_CERT:
132 case PLDM_FILE_TYPE_ROOT_CERT:
133 {
134 return std::make_unique<CertHandler>(fileHandle, fileType);
135 break;
136 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500137 default:
138 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600139 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500140 break;
141 }
142 }
143 return nullptr;
144}
145
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600146int FileHandler::readFile(const std::string& filePath, uint32_t offset,
147 uint32_t& length, Response& response)
148{
149 if (!fs::exists(filePath))
150 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600151 std::cerr << "File does not exist, HANDLE=" << fileHandle
152 << " PATH=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600153 return PLDM_INVALID_FILE_HANDLE;
154 }
155
156 size_t fileSize = fs::file_size(filePath);
157 if (offset >= fileSize)
158 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600159 std::cerr << "Offset exceeds file size, OFFSET=" << offset
160 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600161 return PLDM_DATA_OUT_OF_RANGE;
162 }
163
164 if (offset + length > fileSize)
165 {
166 length = fileSize - offset;
167 }
168
169 size_t currSize = response.size();
170 response.resize(currSize + length);
171 auto filePos = reinterpret_cast<char*>(response.data());
172 filePos += currSize;
173 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
174 if (stream)
175 {
176 stream.seekg(offset);
177 stream.read(filePos, length);
178 return PLDM_SUCCESS;
179 }
Sampa Misraaa8ae722019-12-12 03:20:40 -0600180 std::cerr << "Unable to read file, FILE=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600181 return PLDM_ERROR;
182}
183
Sampa Misra854e61f2019-08-22 04:36:47 -0500184} // namespace responder
185} // namespace pldm