blob: efe8e376e26431e6234850ef461f15e574abb10c [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"
7#include "libpldmresponder/utils.hpp"
8#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 Misra854e61f2019-08-22 04:36:47 -050016#include <phosphor-logging/elog-errors.hpp>
17#include <phosphor-logging/log.hpp>
18#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
29using namespace phosphor::logging;
30using namespace sdbusplus::xyz::openbmc_project::Common::Error;
31
32int FileHandler::transferFileData(const fs::path& path, bool upstream,
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060033 uint32_t offset, uint32_t& length,
Sampa Misra854e61f2019-08-22 04:36:47 -050034 uint64_t address)
35{
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060036 if (upstream)
37 {
38 if (!fs::exists(path))
39 {
40 log<level::ERR>("File does not exist",
41 entry("PATH=%s", path.c_str()));
42 return PLDM_INVALID_FILE_HANDLE;
43 }
44
45 size_t fileSize = fs::file_size(path);
46 if (offset >= fileSize)
47 {
48 log<level::ERR>("Offset exceeds file size",
49 entry("OFFSET=%d", offset),
50 entry("FILE_SIZE=%d", fileSize));
51 return PLDM_DATA_OUT_OF_RANGE;
52 }
53 if (offset + length > fileSize)
54 {
55 length = fileSize - offset;
56 }
57 }
58
Sampa Misra854e61f2019-08-22 04:36:47 -050059 dma::DMA xdmaInterface;
60
61 while (length > dma::maxSize)
62 {
63 auto rc = xdmaInterface.transferDataHost(path, offset, dma::maxSize,
64 address, upstream);
65 if (rc < 0)
66 {
67 return PLDM_ERROR;
68 }
69 offset += dma::maxSize;
70 length -= dma::maxSize;
71 address += dma::maxSize;
72 }
73 auto rc =
74 xdmaInterface.transferDataHost(path, offset, length, address, upstream);
75 return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
76}
77
78std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
79 uint32_t fileHandle)
80{
81 switch (fileType)
82 {
83 case PLDM_FILE_TYPE_PEL:
84 {
85 return std::make_unique<PelHandler>(fileHandle);
86 break;
87 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060088 case PLDM_FILE_TYPE_LID_PERM:
89 {
90 return std::make_unique<LidHandler>(fileHandle, true);
91 break;
92 }
93 case PLDM_FILE_TYPE_LID_TEMP:
94 {
95 return std::make_unique<LidHandler>(fileHandle, false);
96 break;
97 }
Sampa Misra854e61f2019-08-22 04:36:47 -050098 default:
99 {
100 elog<InternalFailure>();
101 break;
102 }
103 }
104 return nullptr;
105}
106
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600107int FileHandler::readFile(const std::string& filePath, uint32_t offset,
108 uint32_t& length, Response& response)
109{
110 if (!fs::exists(filePath))
111 {
112 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle),
113 entry("PATH=%s", filePath.c_str()));
114 return PLDM_INVALID_FILE_HANDLE;
115 }
116
117 size_t fileSize = fs::file_size(filePath);
118 if (offset >= fileSize)
119 {
120 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
121 entry("FILE_SIZE=%d", fileSize));
122 return PLDM_DATA_OUT_OF_RANGE;
123 }
124
125 if (offset + length > fileSize)
126 {
127 length = fileSize - offset;
128 }
129
130 size_t currSize = response.size();
131 response.resize(currSize + length);
132 auto filePos = reinterpret_cast<char*>(response.data());
133 filePos += currSize;
134 std::ifstream stream(filePath, std::ios::in | std::ios::binary);
135 if (stream)
136 {
137 stream.seekg(offset);
138 stream.read(filePos, length);
139 return PLDM_SUCCESS;
140 }
141 log<level::ERR>("Unable to read file", entry("FILE=%s", filePath.c_str()));
142 return PLDM_ERROR;
143}
144
Sampa Misra854e61f2019-08-22 04:36:47 -0500145} // namespace responder
146} // namespace pldm