blob: e076253b3fb8263c4163f8aead5a50c43dde77db [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "config.h"
2
3#include "file_io_by_type.hpp"
4
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06005#include "file_io_type_lid.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05006#include "file_io_type_pel.hpp"
George Liu83409572019-12-24 18:42:54 +08007#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05008#include "xyz/openbmc_project/Common/error.hpp"
9
10#include <stdint.h>
11#include <unistd.h>
12
13#include <exception>
14#include <filesystem>
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060015#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060016#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050017#include <vector>
18#include <xyz/openbmc_project/Logging/Entry/server.hpp>
19
20#include "libpldm/base.h"
21#include "oem/ibm/libpldm/file_io.h"
22
23namespace pldm
24{
25namespace responder
26{
27
Sampa Misra854e61f2019-08-22 04:36:47 -050028using namespace sdbusplus::xyz::openbmc_project::Common::Error;
29
Deepak Kodihalli15211b42019-12-14 02:24:49 -060030int FileHandler::transferFileData(int32_t fd, bool upstream, uint32_t offset,
31 uint32_t& length, uint64_t address)
32{
33 dma::DMA xdmaInterface;
34 while (length > dma::maxSize)
35 {
36 auto rc = xdmaInterface.transferDataHost(fd, offset, dma::maxSize,
37 address, upstream);
38 if (rc < 0)
39 {
40 return PLDM_ERROR;
41 }
42 offset += dma::maxSize;
43 length -= dma::maxSize;
44 address += dma::maxSize;
45 }
46 auto rc =
47 xdmaInterface.transferDataHost(fd, offset, length, address, upstream);
48 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
49}
50
Sampa Misra854e61f2019-08-22 04:36:47 -050051int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060052 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050053 uint64_t address)
54{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060055 bool fileExists = false;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060056 if (upstream)
57 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060058 fileExists = fs::exists(path);
59 if (!fileExists)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060060 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060061 std::cerr << "File does not exist. PATH=" << path.c_str() << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060062 return PLDM_INVALID_FILE_HANDLE;
63 }
64
65 size_t fileSize = fs::file_size(path);
66 if (offset >= fileSize)
67 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060068 std::cerr << "Offset exceeds file size, OFFSET=" << offset
69 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060070 return PLDM_DATA_OUT_OF_RANGE;
71 }
72 if (offset + length > fileSize)
73 {
74 length = fileSize - offset;
75 }
76 }
77
Deepak Kodihalli15211b42019-12-14 02:24:49 -060078 int flags{};
79 if (upstream)
Sampa Misra854e61f2019-08-22 04:36:47 -050080 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -060081 flags = O_RDONLY;
Sampa Misra854e61f2019-08-22 04:36:47 -050082 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -060083 else if (fileExists)
84 {
85 flags = O_RDWR;
86 }
87 else
88 {
89 flags = O_WRONLY;
90 }
91 int file = open(path.string().c_str(), flags);
92 if (file == -1)
93 {
94 std::cerr << "File does not exist, PATH = " << path.string() << "\n";
95 ;
96 return PLDM_ERROR;
97 }
98 utils::CustomFD fd(file);
99
100 return transferFileData(fd(), upstream, offset, length, address);
Sampa Misra854e61f2019-08-22 04:36:47 -0500101}
102
103std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
104 uint32_t fileHandle)
105{
106 switch (fileType)
107 {
108 case PLDM_FILE_TYPE_PEL:
109 {
110 return std::make_unique<PelHandler>(fileHandle);
111 break;
112 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600113 case PLDM_FILE_TYPE_LID_PERM:
114 {
115 return std::make_unique<LidHandler>(fileHandle, true);
116 break;
117 }
118 case PLDM_FILE_TYPE_LID_TEMP:
119 {
120 return std::make_unique<LidHandler>(fileHandle, false);
121 break;
122 }
Sampa Misra854e61f2019-08-22 04:36:47 -0500123 default:
124 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600125 throw InternalFailure();
Sampa Misra854e61f2019-08-22 04:36:47 -0500126 break;
127 }
128 }
129 return nullptr;
130}
131
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600132int FileHandler::readFile(const std::string& filePath, uint32_t offset,
133 uint32_t& length, Response& response)
134{
135 if (!fs::exists(filePath))
136 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600137 std::cerr << "File does not exist, HANDLE=" << fileHandle
138 << " PATH=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600139 return PLDM_INVALID_FILE_HANDLE;
140 }
141
142 size_t fileSize = fs::file_size(filePath);
143 if (offset >= fileSize)
144 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600145 std::cerr << "Offset exceeds file size, OFFSET=" << offset
146 << " FILE_SIZE=" << fileSize << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600147 return PLDM_DATA_OUT_OF_RANGE;
148 }
149
150 if (offset + length > fileSize)
151 {
152 length = fileSize - offset;
153 }
154
155 size_t currSize = response.size();
156 response.resize(currSize + length);
157 auto filePos = reinterpret_cast<char*>(response.data());
158 filePos += currSize;
159 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
160 if (stream)
161 {
162 stream.seekg(offset);
163 stream.read(filePos, length);
164 return PLDM_SUCCESS;
165 }
Sampa Misraaa8ae722019-12-12 03:20:40 -0600166 std::cerr << "Unable to read file, FILE=" << filePath.c_str() << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600167 return PLDM_ERROR;
168}
169
Sampa Misra854e61f2019-08-22 04:36:47 -0500170} // namespace responder
171} // namespace pldm