blob: 8affa8a4a50be6a5713b3f825d45f89c3e379320 [file] [log] [blame]
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06001#pragma once
2
Deepak Kodihallif6d3a832019-11-19 07:00:29 -06003#include "file_io_by_type.hpp"
4
Riya Dixit49cfb132023-03-02 04:26:53 -06005#include <phosphor-logging/lg2.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
Riya Dixit49cfb132023-03-02 04:26:53 -060011PHOSPHOR_LOG2_USING;
12
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060013namespace pldm
14{
15namespace responder
16{
17
Adriana Kobylak6876f122019-12-12 09:49:56 -060018namespace fs = std::filesystem;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060019
Sampa Misra3a0e3b92020-10-21 05:58:00 -050020using MarkerLIDremainingSize = uint64_t;
21
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060022/** @class LidHandler
23 *
24 * @brief Inherits and implements FileHandler. This class is used
25 * to read/write LIDs.
26 */
27class LidHandler : public FileHandler
28{
29 public:
30 /** @brief LidHandler constructor
31 */
Sampa Misra3a0e3b92020-10-21 05:58:00 -050032 LidHandler(uint32_t fileHandle, bool permSide, uint8_t lidType = 0) :
33 FileHandler(fileHandle), lidType(lidType)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060034 {
Sampa Misra69508502020-09-08 00:08:21 -050035 sideToRead = permSide ? Pside : Tside;
36 isPatchDir = false;
Adriana Kobylak76f820c2020-07-16 11:02:03 -050037 std::string dir = permSide ? LID_ALTERNATE_DIR : LID_RUNNING_DIR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060038 std::stringstream stream;
39 stream << std::hex << fileHandle;
Adriana Kobylak6876f122019-12-12 09:49:56 -060040 auto lidName = stream.str() + ".lid";
Patrick Williams6da4f912023-05-10 07:50:53 -050041 std::string patchDir = permSide ? LID_ALTERNATE_PATCH_DIR
42 : LID_RUNNING_PATCH_DIR;
Deepak Kodihalli09b017b2020-08-26 07:37:32 -050043 auto patch = fs::path(patchDir) / lidName;
44 if (fs::is_regular_file(patch))
Adriana Kobylak6876f122019-12-12 09:49:56 -060045 {
46 lidPath = patch;
Sampa Misra69508502020-09-08 00:08:21 -050047 isPatchDir = true;
Adriana Kobylak6876f122019-12-12 09:49:56 -060048 }
49 else
50 {
51 lidPath = std::move(dir) + '/' + lidName;
52 }
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060053 }
54
Sampa Misra69508502020-09-08 00:08:21 -050055 /** @brief Method to construct the LID path based on current boot side
56 * @param[in] oemPlatformHandler - OEM platform handler
57 * @return bool - true if a new path is constructed
58 */
59 bool constructLIDPath(oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060060 {
Sampa Misra69508502020-09-08 00:08:21 -050061 if (oemPlatformHandler != nullptr)
62 {
63 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
64 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
65 oemPlatformHandler);
66 std::string dir = LID_ALTERNATE_DIR;
67 if (isPatchDir)
68 {
69 dir = LID_ALTERNATE_PATCH_DIR;
70 }
71 if (oemIbmPlatformHandler->codeUpdate->fetchCurrentBootSide() ==
72 sideToRead)
73 {
74 if (isPatchDir)
75 {
76 dir = LID_RUNNING_PATCH_DIR;
77 }
78 else
79 {
80 dir = LID_RUNNING_DIR;
81 }
82 }
83 else if (oemIbmPlatformHandler->codeUpdate
84 ->isCodeUpdateInProgress())
85 {
86 return false;
87 }
88
89 std::stringstream stream;
90 stream << std::hex << fileHandle;
91 auto lidName = stream.str() + ".lid";
92 lidPath = std::move(dir) + '/' + lidName;
93 }
94 return true;
95 }
96
97 virtual int writeFromMemory(uint32_t offset, uint32_t length,
98 uint64_t address,
99 oem_platform::Handler* oemPlatformHandler)
100 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500101 int rc = PLDM_SUCCESS;
102 bool codeUpdateInProgress = false;
Sampa Misra69508502020-09-08 00:08:21 -0500103 if (oemPlatformHandler != nullptr)
104 {
105 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
106 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
107 oemPlatformHandler);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500108 codeUpdateInProgress =
109 oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress();
110 if (codeUpdateInProgress || lidType == PLDM_FILE_TYPE_LID_MARKER)
Sampa Misra69508502020-09-08 00:08:21 -0500111 {
112 std::string dir = LID_STAGING_DIR;
113 std::stringstream stream;
114 stream << std::hex << fileHandle;
115 auto lidName = stream.str() + ".lid";
116 lidPath = std::move(dir) + '/' + lidName;
117 }
118 }
Sampa Misra69508502020-09-08 00:08:21 -0500119 bool fileExists = fs::exists(lidPath);
120 int flags{};
121 if (fileExists)
122 {
123 flags = O_RDWR;
124 }
125 else
126 {
127 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
128 }
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600129 auto fd = open(lidPath.c_str(), flags, S_IRUSR);
Sampa Misra69508502020-09-08 00:08:21 -0500130 if (fd == -1)
131 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600132 error("Could not open file for writing {LID_PATH}", "LID_PATH",
133 lidPath.c_str());
Sampa Misra69508502020-09-08 00:08:21 -0500134 return PLDM_ERROR;
135 }
136 close(fd);
137
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500138 rc = transferFileData(lidPath, false, offset, length, address);
Sampa Misra69508502020-09-08 00:08:21 -0500139 if (rc != PLDM_SUCCESS)
140 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600141 error("writeFileFromMemory failed with rc= {RC}", "RC", rc);
Sampa Misra69508502020-09-08 00:08:21 -0500142 return rc;
143 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500144 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
145 {
146 markerLIDremainingSize -= length;
147 if (markerLIDremainingSize == 0)
148 {
149 pldm::responder::oem_ibm_platform::Handler*
150 oemIbmPlatformHandler = dynamic_cast<
151 pldm::responder::oem_ibm_platform::Handler*>(
152 oemPlatformHandler);
153 auto sensorId =
154 oemIbmPlatformHandler->codeUpdate->getMarkerLidSensor();
155 using namespace pldm::responder::oem_ibm_platform;
156 oemIbmPlatformHandler->sendStateSensorEvent(
157 sensorId, PLDM_STATE_SENSOR_STATE, 0, VALID, VALID);
158 // rc = validate api;
159 rc = PLDM_SUCCESS;
160 }
161 }
162 else if (codeUpdateInProgress)
163 {
164 rc = processCodeUpdateLid(lidPath);
165 }
Sampa Misra69508502020-09-08 00:08:21 -0500166 return rc;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600167 }
168
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600169 virtual int readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500170 uint64_t address,
171 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600172 {
Sampa Misra69508502020-09-08 00:08:21 -0500173 if (constructLIDPath(oemPlatformHandler))
174 {
175 return transferFileData(lidPath, true, offset, length, address);
176 }
177 return PLDM_ERROR;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600178 }
179
Sampa Misra69508502020-09-08 00:08:21 -0500180 virtual int write(const char* buffer, uint32_t offset, uint32_t& length,
181 oem_platform::Handler* oemPlatformHandler)
Sampa Misra18967162020-01-14 02:31:41 -0600182 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500183 int rc = PLDM_SUCCESS;
184 bool codeUpdateInProgress = false;
Sampa Misra69508502020-09-08 00:08:21 -0500185 if (oemPlatformHandler != nullptr)
186 {
187 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
188 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
189 oemPlatformHandler);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500190 codeUpdateInProgress =
191 oemIbmPlatformHandler->codeUpdate->isCodeUpdateInProgress();
192 if (codeUpdateInProgress || lidType == PLDM_FILE_TYPE_LID_MARKER)
Sampa Misra69508502020-09-08 00:08:21 -0500193 {
194 std::string dir = LID_STAGING_DIR;
195 std::stringstream stream;
196 stream << std::hex << fileHandle;
197 auto lidName = stream.str() + ".lid";
198 lidPath = std::move(dir) + '/' + lidName;
199 }
200 }
Sampa Misra69508502020-09-08 00:08:21 -0500201 bool fileExists = fs::exists(lidPath);
202 int flags{};
203 if (fileExists)
204 {
205 flags = O_RDWR;
206 size_t fileSize = fs::file_size(lidPath);
207 if (offset > fileSize)
208 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600209 error(
Sagar Srinivas82257922023-07-10 08:12:22 -0500210 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE} FILE_HANDLE{FILE_HANDLE}",
211 "OFFSET", offset, "FILE_SIZE", fileSize, "FILE_HANDLE",
212 fileHandle);
Sampa Misra69508502020-09-08 00:08:21 -0500213 return PLDM_DATA_OUT_OF_RANGE;
214 }
215 }
216 else
217 {
218 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
219 if (offset > 0)
220 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600221 error("Offset is non zero in a new file");
Sampa Misra69508502020-09-08 00:08:21 -0500222 return PLDM_DATA_OUT_OF_RANGE;
223 }
224 }
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600225 auto fd = open(lidPath.c_str(), flags, S_IRUSR);
Sampa Misra69508502020-09-08 00:08:21 -0500226 if (fd == -1)
227 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600228 error("could not open file {LID_PATH}", "LID_PATH",
229 lidPath.c_str());
Sampa Misra69508502020-09-08 00:08:21 -0500230 return PLDM_ERROR;
231 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500232 rc = lseek(fd, offset, SEEK_SET);
Sampa Misra69508502020-09-08 00:08:21 -0500233 if (rc == -1)
234 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600235 error("lseek failed, ERROR={ERR}, OFFSET={OFFSET}", "ERR", errno,
236 "OFFSET", offset);
Sampa Misra69508502020-09-08 00:08:21 -0500237 return PLDM_ERROR;
238 }
Sampa Misra69508502020-09-08 00:08:21 -0500239 rc = ::write(fd, buffer, length);
240 if (rc == -1)
241 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600242 error(
243 "file write failed, ERROR={ERR}, LENGTH={LEN}, OFFSET={OFFSET}",
244 "ERR", errno, "LEN", length, "OFFSET", offset);
Sampa Misra69508502020-09-08 00:08:21 -0500245 return PLDM_ERROR;
246 }
Pavithra Barithaya303387e2021-03-18 23:35:42 -0500247 else if (rc == static_cast<int>(length))
248 {
249 rc = PLDM_SUCCESS;
250 }
251 else if (rc < static_cast<int>(length))
252 {
253 rc = PLDM_ERROR;
254 }
Sampa Misra69508502020-09-08 00:08:21 -0500255 close(fd);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500256
257 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
258 {
259 markerLIDremainingSize -= length;
260 if (markerLIDremainingSize == 0)
261 {
262 pldm::responder::oem_ibm_platform::Handler*
263 oemIbmPlatformHandler = dynamic_cast<
264 pldm::responder::oem_ibm_platform::Handler*>(
265 oemPlatformHandler);
266 auto sensorId =
267 oemIbmPlatformHandler->codeUpdate->getMarkerLidSensor();
268 using namespace pldm::responder::oem_ibm_platform;
269 oemIbmPlatformHandler->sendStateSensorEvent(
270 sensorId, PLDM_STATE_SENSOR_STATE, 0, VALID, VALID);
271 // validate api
272 rc = PLDM_SUCCESS;
273 }
274 }
275 else if (codeUpdateInProgress)
276 {
277 rc = processCodeUpdateLid(lidPath);
278 }
279
Sampa Misra69508502020-09-08 00:08:21 -0500280 return rc;
Sampa Misra18967162020-01-14 02:31:41 -0600281 }
282
Sampa Misra69508502020-09-08 00:08:21 -0500283 virtual int read(uint32_t offset, uint32_t& length, Response& response,
284 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600285 {
Sampa Misra69508502020-09-08 00:08:21 -0500286 if (constructLIDPath(oemPlatformHandler))
287 {
288 return readFile(lidPath, offset, length, response);
289 }
290 return PLDM_ERROR;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600291 }
292
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600293 virtual int fileAck(uint8_t /*fileStatus*/)
294 {
295 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
296 }
297
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500298 virtual int newFileAvailable(uint64_t length)
Sampa Misra18967162020-01-14 02:31:41 -0600299
300 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500301 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
302 {
303 markerLIDremainingSize = length;
304 return PLDM_SUCCESS;
305 }
Sampa Misra18967162020-01-14 02:31:41 -0600306 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
307 }
308
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600309 /** @brief LidHandler destructor
310 */
Patrick Williams6da4f912023-05-10 07:50:53 -0500311 ~LidHandler() {}
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600312
313 protected:
314 std::string lidPath;
Sampa Misra69508502020-09-08 00:08:21 -0500315 std::string sideToRead;
316 bool isPatchDir;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500317 static inline MarkerLIDremainingSize markerLIDremainingSize;
318 uint8_t lidType;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600319};
320
321} // namespace responder
322} // namespace pldm