blob: dbb4fc7dd0b0e39e11c99baf0b4dc2428616035a [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
Riya Dixit49cfb132023-03-02 04:26:53 -06007#include <phosphor-logging/lg2.hpp>
8
Adriana Kobylak6876f122019-12-12 09:49:56 -06009#include <filesystem>
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060010#include <sstream>
11#include <string>
12
Riya Dixit49cfb132023-03-02 04:26:53 -060013PHOSPHOR_LOG2_USING;
14
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060015namespace pldm
16{
17namespace responder
18{
19
Adriana Kobylak6876f122019-12-12 09:49:56 -060020namespace fs = std::filesystem;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060021
Sampa Misra3a0e3b92020-10-21 05:58:00 -050022using MarkerLIDremainingSize = uint64_t;
23
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060024/** @class LidHandler
25 *
26 * @brief Inherits and implements FileHandler. This class is used
27 * to read/write LIDs.
28 */
29class LidHandler : public FileHandler
30{
31 public:
32 /** @brief LidHandler constructor
33 */
Sampa Misra3a0e3b92020-10-21 05:58:00 -050034 LidHandler(uint32_t fileHandle, bool permSide, uint8_t lidType = 0) :
35 FileHandler(fileHandle), lidType(lidType)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060036 {
Sampa Misra69508502020-09-08 00:08:21 -050037 sideToRead = permSide ? Pside : Tside;
38 isPatchDir = false;
Adriana Kobylak76f820c2020-07-16 11:02:03 -050039 std::string dir = permSide ? LID_ALTERNATE_DIR : LID_RUNNING_DIR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060040 std::stringstream stream;
41 stream << std::hex << fileHandle;
Adriana Kobylak6876f122019-12-12 09:49:56 -060042 auto lidName = stream.str() + ".lid";
Deepak Kodihalli09b017b2020-08-26 07:37:32 -050043 std::string patchDir =
44 permSide ? LID_ALTERNATE_PATCH_DIR : LID_RUNNING_PATCH_DIR;
45 auto patch = fs::path(patchDir) / lidName;
46 if (fs::is_regular_file(patch))
Adriana Kobylak6876f122019-12-12 09:49:56 -060047 {
48 lidPath = patch;
Sampa Misra69508502020-09-08 00:08:21 -050049 isPatchDir = true;
Adriana Kobylak6876f122019-12-12 09:49:56 -060050 }
51 else
52 {
53 lidPath = std::move(dir) + '/' + lidName;
54 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060055 }
56
Sampa Misra69508502020-09-08 00:08:21 -050057 /** @brief Method to construct the LID path based on current boot side
58 * @param[in] oemPlatformHandler - OEM platform handler
59 * @return bool - true if a new path is constructed
60 */
61 bool constructLIDPath(oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060062 {
Sampa Misra69508502020-09-08 00:08:21 -050063 if (oemPlatformHandler != nullptr)
64 {
65 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
66 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
67 oemPlatformHandler);
68 std::string dir = LID_ALTERNATE_DIR;
69 if (isPatchDir)
70 {
71 dir = LID_ALTERNATE_PATCH_DIR;
72 }
73 if (oemIbmPlatformHandler->codeUpdate->fetchCurrentBootSide() ==
74 sideToRead)
75 {
76 if (isPatchDir)
77 {
78 dir = LID_RUNNING_PATCH_DIR;
79 }
80 else
81 {
82 dir = LID_RUNNING_DIR;
83 }
84 }
85 else if (oemIbmPlatformHandler->codeUpdate
86 ->isCodeUpdateInProgress())
87 {
88 return false;
89 }
90
91 std::stringstream stream;
92 stream << std::hex << fileHandle;
93 auto lidName = stream.str() + ".lid";
94 lidPath = std::move(dir) + '/' + lidName;
95 }
96 return true;
97 }
98
99 virtual int writeFromMemory(uint32_t offset, uint32_t length,
100 uint64_t address,
101 oem_platform::Handler* oemPlatformHandler)
102 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500103 int rc = PLDM_SUCCESS;
104 bool codeUpdateInProgress = false;
Sampa Misra69508502020-09-08 00:08:21 -0500105 if (oemPlatformHandler != nullptr)
106 {
107 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
108 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
109 oemPlatformHandler);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500110 codeUpdateInProgress =
111 oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress();
112 if (codeUpdateInProgress || lidType == PLDM_FILE_TYPE_LID_MARKER)
Sampa Misra69508502020-09-08 00:08:21 -0500113 {
114 std::string dir = LID_STAGING_DIR;
115 std::stringstream stream;
116 stream << std::hex << fileHandle;
117 auto lidName = stream.str() + ".lid";
118 lidPath = std::move(dir) + '/' + lidName;
119 }
120 }
Sampa Misra69508502020-09-08 00:08:21 -0500121 bool fileExists = fs::exists(lidPath);
122 int flags{};
123 if (fileExists)
124 {
125 flags = O_RDWR;
126 }
127 else
128 {
129 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
130 }
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600131 auto fd = open(lidPath.c_str(), flags, S_IRUSR);
Sampa Misra69508502020-09-08 00:08:21 -0500132 if (fd == -1)
133 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600134 error("Could not open file for writing {LID_PATH}", "LID_PATH",
135 lidPath.c_str());
Sampa Misra69508502020-09-08 00:08:21 -0500136 return PLDM_ERROR;
137 }
138 close(fd);
139
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500140 rc = transferFileData(lidPath, false, offset, length, address);
Sampa Misra69508502020-09-08 00:08:21 -0500141 if (rc != PLDM_SUCCESS)
142 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600143 error("writeFileFromMemory failed with rc= {RC}", "RC", rc);
Sampa Misra69508502020-09-08 00:08:21 -0500144 return rc;
145 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500146 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
147 {
148 markerLIDremainingSize -= length;
149 if (markerLIDremainingSize == 0)
150 {
151 pldm::responder::oem_ibm_platform::Handler*
152 oemIbmPlatformHandler = dynamic_cast<
153 pldm::responder::oem_ibm_platform::Handler*>(
154 oemPlatformHandler);
155 auto sensorId =
156 oemIbmPlatformHandler->codeUpdate->getMarkerLidSensor();
157 using namespace pldm::responder::oem_ibm_platform;
158 oemIbmPlatformHandler->sendStateSensorEvent(
159 sensorId, PLDM_STATE_SENSOR_STATE, 0, VALID, VALID);
160 // rc = validate api;
161 rc = PLDM_SUCCESS;
162 }
163 }
164 else if (codeUpdateInProgress)
165 {
166 rc = processCodeUpdateLid(lidPath);
167 }
Sampa Misra69508502020-09-08 00:08:21 -0500168 return rc;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600169 }
170
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600171 virtual int readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500172 uint64_t address,
173 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600174 {
Sampa Misra69508502020-09-08 00:08:21 -0500175 if (constructLIDPath(oemPlatformHandler))
176 {
177 return transferFileData(lidPath, true, offset, length, address);
178 }
179 return PLDM_ERROR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600180 }
181
Sampa Misra69508502020-09-08 00:08:21 -0500182 virtual int write(const char* buffer, uint32_t offset, uint32_t& length,
183 oem_platform::Handler* oemPlatformHandler)
Sampa Misra18967162020-01-14 02:31:41 -0600184 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500185 int rc = PLDM_SUCCESS;
186 bool codeUpdateInProgress = false;
Sampa Misra69508502020-09-08 00:08:21 -0500187 if (oemPlatformHandler != nullptr)
188 {
189 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
190 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
191 oemPlatformHandler);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500192 codeUpdateInProgress =
193 oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress();
194 if (codeUpdateInProgress || lidType == PLDM_FILE_TYPE_LID_MARKER)
Sampa Misra69508502020-09-08 00:08:21 -0500195 {
196 std::string dir = LID_STAGING_DIR;
197 std::stringstream stream;
198 stream << std::hex << fileHandle;
199 auto lidName = stream.str() + ".lid";
200 lidPath = std::move(dir) + '/' + lidName;
201 }
202 }
Sampa Misra69508502020-09-08 00:08:21 -0500203 bool fileExists = fs::exists(lidPath);
204 int flags{};
205 if (fileExists)
206 {
207 flags = O_RDWR;
208 size_t fileSize = fs::file_size(lidPath);
209 if (offset > fileSize)
210 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600211 error(
212 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
213 "OFFSET", offset, "FILE_SIZE", fileSize);
Sampa Misra69508502020-09-08 00:08:21 -0500214 return PLDM_DATA_OUT_OF_RANGE;
215 }
216 }
217 else
218 {
219 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
220 if (offset > 0)
221 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600222 error("Offset is non zero in a new file");
Sampa Misra69508502020-09-08 00:08:21 -0500223 return PLDM_DATA_OUT_OF_RANGE;
224 }
225 }
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600226 auto fd = open(lidPath.c_str(), flags, S_IRUSR);
Sampa Misra69508502020-09-08 00:08:21 -0500227 if (fd == -1)
228 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600229 error("could not open file {LID_PATH}", "LID_PATH",
230 lidPath.c_str());
Sampa Misra69508502020-09-08 00:08:21 -0500231 return PLDM_ERROR;
232 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500233 rc = lseek(fd, offset, SEEK_SET);
Sampa Misra69508502020-09-08 00:08:21 -0500234 if (rc == -1)
235 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600236 error("lseek failed, ERROR={ERR}, OFFSET={OFFSET}", "ERR", errno,
237 "OFFSET", offset);
Sampa Misra69508502020-09-08 00:08:21 -0500238 return PLDM_ERROR;
239 }
Sampa Misra69508502020-09-08 00:08:21 -0500240 rc = ::write(fd, buffer, length);
241 if (rc == -1)
242 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600243 error(
244 "file write failed, ERROR={ERR}, LENGTH={LEN}, OFFSET={OFFSET}",
245 "ERR", errno, "LEN", length, "OFFSET", offset);
Sampa Misra69508502020-09-08 00:08:21 -0500246 return PLDM_ERROR;
247 }
Pavithra Barithaya303387e2021-03-18 23:35:42 -0500248 else if (rc == static_cast<int>(length))
249 {
250 rc = PLDM_SUCCESS;
251 }
252 else if (rc < static_cast<int>(length))
253 {
254 rc = PLDM_ERROR;
255 }
Sampa Misra69508502020-09-08 00:08:21 -0500256 close(fd);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500257
258 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
259 {
260 markerLIDremainingSize -= length;
261 if (markerLIDremainingSize == 0)
262 {
263 pldm::responder::oem_ibm_platform::Handler*
264 oemIbmPlatformHandler = dynamic_cast<
265 pldm::responder::oem_ibm_platform::Handler*>(
266 oemPlatformHandler);
267 auto sensorId =
268 oemIbmPlatformHandler->codeUpdate->getMarkerLidSensor();
269 using namespace pldm::responder::oem_ibm_platform;
270 oemIbmPlatformHandler->sendStateSensorEvent(
271 sensorId, PLDM_STATE_SENSOR_STATE, 0, VALID, VALID);
272 // validate api
273 rc = PLDM_SUCCESS;
274 }
275 }
276 else if (codeUpdateInProgress)
277 {
278 rc = processCodeUpdateLid(lidPath);
279 }
280
Sampa Misra69508502020-09-08 00:08:21 -0500281 return rc;
Sampa Misra18967162020-01-14 02:31:41 -0600282 }
283
Sampa Misra69508502020-09-08 00:08:21 -0500284 virtual int read(uint32_t offset, uint32_t& length, Response& response,
285 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600286 {
Sampa Misra69508502020-09-08 00:08:21 -0500287 if (constructLIDPath(oemPlatformHandler))
288 {
289 return readFile(lidPath, offset, length, response);
290 }
291 return PLDM_ERROR;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600292 }
293
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600294 virtual int fileAck(uint8_t /*fileStatus*/)
295 {
296 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
297 }
298
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500299 virtual int newFileAvailable(uint64_t length)
Sampa Misra18967162020-01-14 02:31:41 -0600300
301 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500302 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
303 {
304 markerLIDremainingSize = length;
305 return PLDM_SUCCESS;
306 }
Sampa Misra18967162020-01-14 02:31:41 -0600307 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
308 }
309
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600310 /** @brief LidHandler destructor
311 */
312 ~LidHandler()
George Liu6492f522020-06-16 10:34:05 +0800313 {}
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600314
315 protected:
316 std::string lidPath;
Sampa Misra69508502020-09-08 00:08:21 -0500317 std::string sideToRead;
318 bool isPatchDir;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500319 static inline MarkerLIDremainingSize markerLIDremainingSize;
320 uint8_t lidType;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600321};
322
323} // namespace responder
324} // namespace pldm