blob: 531d762e76302a031f98b7877fb4720c1bc6f266 [file] [log] [blame]
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06001#pragma once
2
3#include "config.h"
4
5#include "file_io_by_type.hpp"
6
Adriana Kobylak6876f122019-12-12 09:49:56 -06007#include <filesystem>
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06008#include <sstream>
9#include <string>
10
11namespace pldm
12{
13namespace responder
14{
15
16using namespace pldm::responder::dma;
Adriana Kobylak6876f122019-12-12 09:49:56 -060017namespace fs = std::filesystem;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060018
19/** @class LidHandler
20 *
21 * @brief Inherits and implements FileHandler. This class is used
22 * to read/write LIDs.
23 */
24class LidHandler : public FileHandler
25{
26 public:
27 /** @brief LidHandler constructor
28 */
29 LidHandler(uint32_t fileHandle, bool permSide) : FileHandler(fileHandle)
30 {
Sampa Misra69508502020-09-08 00:08:21 -050031 sideToRead = permSide ? Pside : Tside;
32 isPatchDir = false;
Adriana Kobylak76f820c2020-07-16 11:02:03 -050033 std::string dir = permSide ? LID_ALTERNATE_DIR : LID_RUNNING_DIR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060034 std::stringstream stream;
35 stream << std::hex << fileHandle;
Adriana Kobylak6876f122019-12-12 09:49:56 -060036 auto lidName = stream.str() + ".lid";
Deepak Kodihalli09b017b2020-08-26 07:37:32 -050037 std::string patchDir =
38 permSide ? LID_ALTERNATE_PATCH_DIR : LID_RUNNING_PATCH_DIR;
39 auto patch = fs::path(patchDir) / lidName;
40 if (fs::is_regular_file(patch))
Adriana Kobylak6876f122019-12-12 09:49:56 -060041 {
42 lidPath = patch;
Sampa Misra69508502020-09-08 00:08:21 -050043 isPatchDir = true;
Adriana Kobylak6876f122019-12-12 09:49:56 -060044 }
45 else
46 {
47 lidPath = std::move(dir) + '/' + lidName;
48 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060049 }
50
Sampa Misra69508502020-09-08 00:08:21 -050051 /** @brief Method to construct the LID path based on current boot side
52 * @param[in] oemPlatformHandler - OEM platform handler
53 * @return bool - true if a new path is constructed
54 */
55 bool constructLIDPath(oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060056 {
Sampa Misra69508502020-09-08 00:08:21 -050057 if (oemPlatformHandler != nullptr)
58 {
59 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
60 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
61 oemPlatformHandler);
62 std::string dir = LID_ALTERNATE_DIR;
63 if (isPatchDir)
64 {
65 dir = LID_ALTERNATE_PATCH_DIR;
66 }
67 if (oemIbmPlatformHandler->codeUpdate->fetchCurrentBootSide() ==
68 sideToRead)
69 {
70 if (isPatchDir)
71 {
72 dir = LID_RUNNING_PATCH_DIR;
73 }
74 else
75 {
76 dir = LID_RUNNING_DIR;
77 }
78 }
79 else if (oemIbmPlatformHandler->codeUpdate
80 ->isCodeUpdateInProgress())
81 {
82 return false;
83 }
84
85 std::stringstream stream;
86 stream << std::hex << fileHandle;
87 auto lidName = stream.str() + ".lid";
88 lidPath = std::move(dir) + '/' + lidName;
89 }
90 return true;
91 }
92
93 virtual int writeFromMemory(uint32_t offset, uint32_t length,
94 uint64_t address,
95 oem_platform::Handler* oemPlatformHandler)
96 {
97 if (oemPlatformHandler != nullptr)
98 {
99 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
100 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
101 oemPlatformHandler);
102 if (oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress())
103 {
104 std::string dir = LID_STAGING_DIR;
105 std::stringstream stream;
106 stream << std::hex << fileHandle;
107 auto lidName = stream.str() + ".lid";
108 lidPath = std::move(dir) + '/' + lidName;
109 }
110 }
111 std::cout << "got writeFromMemory() for LID " << lidPath.c_str()
112 << " and offset " << offset << " and length " << length
113 << "\n";
114 bool fileExists = fs::exists(lidPath);
115 int flags{};
116 if (fileExists)
117 {
118 flags = O_RDWR;
119 }
120 else
121 {
122 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
123 }
124 auto fd = open(lidPath.c_str(), flags);
125 if (fd == -1)
126 {
127 std::cerr << "Could not open file for writing " << lidPath.c_str()
128 << "\n";
129 return PLDM_ERROR;
130 }
131 close(fd);
132
133 auto rc = transferFileData(lidPath, false, offset, length, address);
134 if (rc != PLDM_SUCCESS)
135 {
136 std::cout << "writeFileFromMemory failed with rc= " << rc << " \n";
137 return rc;
138 }
139 return rc;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600140 }
141
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600142 virtual int readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500143 uint64_t address,
144 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600145 {
Sampa Misra69508502020-09-08 00:08:21 -0500146 if (constructLIDPath(oemPlatformHandler))
147 {
148 return transferFileData(lidPath, true, offset, length, address);
149 }
150 return PLDM_ERROR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600151 }
152
Sampa Misra69508502020-09-08 00:08:21 -0500153 virtual int write(const char* buffer, uint32_t offset, uint32_t& length,
154 oem_platform::Handler* oemPlatformHandler)
Sampa Misra18967162020-01-14 02:31:41 -0600155 {
Sampa Misra69508502020-09-08 00:08:21 -0500156 if (oemPlatformHandler != nullptr)
157 {
158 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
159 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
160 oemPlatformHandler);
161 if (oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress())
162 {
163 std::string dir = LID_STAGING_DIR;
164 std::stringstream stream;
165 stream << std::hex << fileHandle;
166 auto lidName = stream.str() + ".lid";
167 lidPath = std::move(dir) + '/' + lidName;
168 }
169 }
170 std::cout << "got write() call for LID " << lidPath.c_str()
171 << " and offset " << offset << " and length " << length
172 << "\n";
173 bool fileExists = fs::exists(lidPath);
174 int flags{};
175 if (fileExists)
176 {
177 flags = O_RDWR;
178 size_t fileSize = fs::file_size(lidPath);
179 if (offset > fileSize)
180 {
181 std::cerr << "Offset exceeds file size, OFFSET=" << offset
182 << " FILE_SIZE=" << fileSize << "\n";
183 return PLDM_DATA_OUT_OF_RANGE;
184 }
185 }
186 else
187 {
188 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
189 if (offset > 0)
190 {
191 std::cerr << "Offset is non zero in a new file \n";
192 return PLDM_DATA_OUT_OF_RANGE;
193 }
194 }
195 auto fd = open(lidPath.c_str(), flags);
196 if (fd == -1)
197 {
198 std::cerr << "could not open file " << lidPath.c_str() << "\n";
199 return PLDM_ERROR;
200 }
201 auto rc = lseek(fd, offset, SEEK_SET);
202 if (rc == -1)
203 {
204 std::cerr << "lseek failed, ERROR=" << errno
205 << ", OFFSET=" << offset << "\n";
206 return PLDM_ERROR;
207 }
208 std::cout << "lseek returned " << rc << "\n";
209 rc = ::write(fd, buffer, length);
210 if (rc == -1)
211 {
212 std::cerr << "file write failed, ERROR=" << errno
213 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
214 return PLDM_ERROR;
215 }
216 close(fd);
217 return rc;
Sampa Misra18967162020-01-14 02:31:41 -0600218 }
219
Sampa Misra69508502020-09-08 00:08:21 -0500220 virtual int read(uint32_t offset, uint32_t& length, Response& response,
221 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600222 {
Sampa Misra69508502020-09-08 00:08:21 -0500223 if (constructLIDPath(oemPlatformHandler))
224 {
225 return readFile(lidPath, offset, length, response);
226 }
227 return PLDM_ERROR;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600228 }
229
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600230 virtual int fileAck(uint8_t /*fileStatus*/)
231 {
232 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
233 }
234
Sampa Misra18967162020-01-14 02:31:41 -0600235 virtual int newFileAvailable(uint64_t /*length*/)
236
237 {
238 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
239 }
240
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600241 /** @brief LidHandler destructor
242 */
243 ~LidHandler()
George Liu6492f522020-06-16 10:34:05 +0800244 {}
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600245
246 protected:
247 std::string lidPath;
Sampa Misra69508502020-09-08 00:08:21 -0500248 std::string sideToRead;
249 bool isPatchDir;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600250};
251
252} // namespace responder
253} // namespace pldm