blob: e5e5b5f1b8abb15727c2bfcaada382d24c82a3ab [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
Sampa Misra3a0e3b92020-10-21 05:58:00 -050019using MarkerLIDremainingSize = uint64_t;
20
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060021/** @class LidHandler
22 *
23 * @brief Inherits and implements FileHandler. This class is used
24 * to read/write LIDs.
25 */
26class LidHandler : public FileHandler
27{
28 public:
29 /** @brief LidHandler constructor
30 */
Sampa Misra3a0e3b92020-10-21 05:58:00 -050031 LidHandler(uint32_t fileHandle, bool permSide, uint8_t lidType = 0) :
32 FileHandler(fileHandle), lidType(lidType)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060033 {
Sampa Misra69508502020-09-08 00:08:21 -050034 sideToRead = permSide ? Pside : Tside;
35 isPatchDir = false;
Adriana Kobylak76f820c2020-07-16 11:02:03 -050036 std::string dir = permSide ? LID_ALTERNATE_DIR : LID_RUNNING_DIR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060037 std::stringstream stream;
38 stream << std::hex << fileHandle;
Adriana Kobylak6876f122019-12-12 09:49:56 -060039 auto lidName = stream.str() + ".lid";
Deepak Kodihalli09b017b2020-08-26 07:37:32 -050040 std::string patchDir =
41 permSide ? LID_ALTERNATE_PATCH_DIR : LID_RUNNING_PATCH_DIR;
42 auto patch = fs::path(patchDir) / lidName;
43 if (fs::is_regular_file(patch))
Adriana Kobylak6876f122019-12-12 09:49:56 -060044 {
45 lidPath = patch;
Sampa Misra69508502020-09-08 00:08:21 -050046 isPatchDir = true;
Adriana Kobylak6876f122019-12-12 09:49:56 -060047 }
48 else
49 {
50 lidPath = std::move(dir) + '/' + lidName;
51 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060052 }
53
Sampa Misra69508502020-09-08 00:08:21 -050054 /** @brief Method to construct the LID path based on current boot side
55 * @param[in] oemPlatformHandler - OEM platform handler
56 * @return bool - true if a new path is constructed
57 */
58 bool constructLIDPath(oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060059 {
Sampa Misra69508502020-09-08 00:08:21 -050060 if (oemPlatformHandler != nullptr)
61 {
62 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
63 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
64 oemPlatformHandler);
65 std::string dir = LID_ALTERNATE_DIR;
66 if (isPatchDir)
67 {
68 dir = LID_ALTERNATE_PATCH_DIR;
69 }
70 if (oemIbmPlatformHandler->codeUpdate->fetchCurrentBootSide() ==
71 sideToRead)
72 {
73 if (isPatchDir)
74 {
75 dir = LID_RUNNING_PATCH_DIR;
76 }
77 else
78 {
79 dir = LID_RUNNING_DIR;
80 }
81 }
82 else if (oemIbmPlatformHandler->codeUpdate
83 ->isCodeUpdateInProgress())
84 {
85 return false;
86 }
87
88 std::stringstream stream;
89 stream << std::hex << fileHandle;
90 auto lidName = stream.str() + ".lid";
91 lidPath = std::move(dir) + '/' + lidName;
92 }
93 return true;
94 }
95
96 virtual int writeFromMemory(uint32_t offset, uint32_t length,
97 uint64_t address,
98 oem_platform::Handler* oemPlatformHandler)
99 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500100 int rc = PLDM_SUCCESS;
101 bool codeUpdateInProgress = false;
Sampa Misra69508502020-09-08 00:08:21 -0500102 if (oemPlatformHandler != nullptr)
103 {
104 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
105 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
106 oemPlatformHandler);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500107 codeUpdateInProgress =
108 oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress();
109 if (codeUpdateInProgress || lidType == PLDM_FILE_TYPE_LID_MARKER)
Sampa Misra69508502020-09-08 00:08:21 -0500110 {
111 std::string dir = LID_STAGING_DIR;
112 std::stringstream stream;
113 stream << std::hex << fileHandle;
114 auto lidName = stream.str() + ".lid";
115 lidPath = std::move(dir) + '/' + lidName;
116 }
117 }
Sampa Misra69508502020-09-08 00:08:21 -0500118 bool fileExists = fs::exists(lidPath);
119 int flags{};
120 if (fileExists)
121 {
122 flags = O_RDWR;
123 }
124 else
125 {
126 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
127 }
128 auto fd = open(lidPath.c_str(), flags);
129 if (fd == -1)
130 {
131 std::cerr << "Could not open file for writing " << lidPath.c_str()
132 << "\n";
133 return PLDM_ERROR;
134 }
135 close(fd);
136
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500137 rc = transferFileData(lidPath, false, offset, length, address);
Sampa Misra69508502020-09-08 00:08:21 -0500138 if (rc != PLDM_SUCCESS)
139 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500140 std::cerr << "writeFileFromMemory failed with rc= " << rc << " \n";
Sampa Misra69508502020-09-08 00:08:21 -0500141 return rc;
142 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500143 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
144 {
145 markerLIDremainingSize -= length;
146 if (markerLIDremainingSize == 0)
147 {
148 pldm::responder::oem_ibm_platform::Handler*
149 oemIbmPlatformHandler = dynamic_cast<
150 pldm::responder::oem_ibm_platform::Handler*>(
151 oemPlatformHandler);
152 auto sensorId =
153 oemIbmPlatformHandler->codeUpdate->getMarkerLidSensor();
154 using namespace pldm::responder::oem_ibm_platform;
155 oemIbmPlatformHandler->sendStateSensorEvent(
156 sensorId, PLDM_STATE_SENSOR_STATE, 0, VALID, VALID);
157 // rc = validate api;
158 rc = PLDM_SUCCESS;
159 }
160 }
161 else if (codeUpdateInProgress)
162 {
163 rc = processCodeUpdateLid(lidPath);
164 }
Sampa Misra69508502020-09-08 00:08:21 -0500165 return rc;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600166 }
167
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600168 virtual int readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500169 uint64_t address,
170 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600171 {
Sampa Misra69508502020-09-08 00:08:21 -0500172 if (constructLIDPath(oemPlatformHandler))
173 {
174 return transferFileData(lidPath, true, offset, length, address);
175 }
176 return PLDM_ERROR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600177 }
178
Sampa Misra69508502020-09-08 00:08:21 -0500179 virtual int write(const char* buffer, uint32_t offset, uint32_t& length,
180 oem_platform::Handler* oemPlatformHandler)
Sampa Misra18967162020-01-14 02:31:41 -0600181 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500182 int rc = PLDM_SUCCESS;
183 bool codeUpdateInProgress = false;
Sampa Misra69508502020-09-08 00:08:21 -0500184 if (oemPlatformHandler != nullptr)
185 {
186 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
187 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
188 oemPlatformHandler);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500189 codeUpdateInProgress =
190 oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress();
191 if (codeUpdateInProgress || lidType == PLDM_FILE_TYPE_LID_MARKER)
Sampa Misra69508502020-09-08 00:08:21 -0500192 {
193 std::string dir = LID_STAGING_DIR;
194 std::stringstream stream;
195 stream << std::hex << fileHandle;
196 auto lidName = stream.str() + ".lid";
197 lidPath = std::move(dir) + '/' + lidName;
198 }
199 }
Sampa Misra69508502020-09-08 00:08:21 -0500200 bool fileExists = fs::exists(lidPath);
201 int flags{};
202 if (fileExists)
203 {
204 flags = O_RDWR;
205 size_t fileSize = fs::file_size(lidPath);
206 if (offset > fileSize)
207 {
208 std::cerr << "Offset exceeds file size, OFFSET=" << offset
209 << " FILE_SIZE=" << fileSize << "\n";
210 return PLDM_DATA_OUT_OF_RANGE;
211 }
212 }
213 else
214 {
215 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
216 if (offset > 0)
217 {
218 std::cerr << "Offset is non zero in a new file \n";
219 return PLDM_DATA_OUT_OF_RANGE;
220 }
221 }
222 auto fd = open(lidPath.c_str(), flags);
223 if (fd == -1)
224 {
225 std::cerr << "could not open file " << lidPath.c_str() << "\n";
226 return PLDM_ERROR;
227 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500228 rc = lseek(fd, offset, SEEK_SET);
Sampa Misra69508502020-09-08 00:08:21 -0500229 if (rc == -1)
230 {
231 std::cerr << "lseek failed, ERROR=" << errno
232 << ", OFFSET=" << offset << "\n";
233 return PLDM_ERROR;
234 }
Sampa Misra69508502020-09-08 00:08:21 -0500235 rc = ::write(fd, buffer, length);
236 if (rc == -1)
237 {
238 std::cerr << "file write failed, ERROR=" << errno
239 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
240 return PLDM_ERROR;
241 }
Pavithra Barithaya303387e2021-03-18 23:35:42 -0500242 else if (rc == static_cast<int>(length))
243 {
244 rc = PLDM_SUCCESS;
245 }
246 else if (rc < static_cast<int>(length))
247 {
248 rc = PLDM_ERROR;
249 }
Sampa Misra69508502020-09-08 00:08:21 -0500250 close(fd);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500251
252 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
253 {
254 markerLIDremainingSize -= length;
255 if (markerLIDremainingSize == 0)
256 {
257 pldm::responder::oem_ibm_platform::Handler*
258 oemIbmPlatformHandler = dynamic_cast<
259 pldm::responder::oem_ibm_platform::Handler*>(
260 oemPlatformHandler);
261 auto sensorId =
262 oemIbmPlatformHandler->codeUpdate->getMarkerLidSensor();
263 using namespace pldm::responder::oem_ibm_platform;
264 oemIbmPlatformHandler->sendStateSensorEvent(
265 sensorId, PLDM_STATE_SENSOR_STATE, 0, VALID, VALID);
266 // validate api
267 rc = PLDM_SUCCESS;
268 }
269 }
270 else if (codeUpdateInProgress)
271 {
272 rc = processCodeUpdateLid(lidPath);
273 }
274
Sampa Misra69508502020-09-08 00:08:21 -0500275 return rc;
Sampa Misra18967162020-01-14 02:31:41 -0600276 }
277
Sampa Misra69508502020-09-08 00:08:21 -0500278 virtual int read(uint32_t offset, uint32_t& length, Response& response,
279 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600280 {
Sampa Misra69508502020-09-08 00:08:21 -0500281 if (constructLIDPath(oemPlatformHandler))
282 {
283 return readFile(lidPath, offset, length, response);
284 }
285 return PLDM_ERROR;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600286 }
287
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600288 virtual int fileAck(uint8_t /*fileStatus*/)
289 {
290 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
291 }
292
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500293 virtual int newFileAvailable(uint64_t length)
Sampa Misra18967162020-01-14 02:31:41 -0600294
295 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500296 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
297 {
298 markerLIDremainingSize = length;
299 return PLDM_SUCCESS;
300 }
Sampa Misra18967162020-01-14 02:31:41 -0600301 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
302 }
303
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600304 /** @brief LidHandler destructor
305 */
306 ~LidHandler()
George Liu6492f522020-06-16 10:34:05 +0800307 {}
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600308
309 protected:
310 std::string lidPath;
Sampa Misra69508502020-09-08 00:08:21 -0500311 std::string sideToRead;
312 bool isPatchDir;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500313 static inline MarkerLIDremainingSize markerLIDremainingSize;
314 uint8_t lidType;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600315};
316
317} // namespace responder
318} // namespace pldm