blob: a4bbb4efa1110d322d360bd8d8a6b3881ae05081 [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(
210 "Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
211 "OFFSET", offset, "FILE_SIZE", fileSize);
Sampa Misra69508502020-09-08 00:08:21 -0500212 return PLDM_DATA_OUT_OF_RANGE;
213 }
214 }
215 else
216 {
217 flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC;
218 if (offset > 0)
219 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600220 error("Offset is non zero in a new file");
Sampa Misra69508502020-09-08 00:08:21 -0500221 return PLDM_DATA_OUT_OF_RANGE;
222 }
223 }
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600224 auto fd = open(lidPath.c_str(), flags, S_IRUSR);
Sampa Misra69508502020-09-08 00:08:21 -0500225 if (fd == -1)
226 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600227 error("could not open file {LID_PATH}", "LID_PATH",
228 lidPath.c_str());
Sampa Misra69508502020-09-08 00:08:21 -0500229 return PLDM_ERROR;
230 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500231 rc = lseek(fd, offset, SEEK_SET);
Sampa Misra69508502020-09-08 00:08:21 -0500232 if (rc == -1)
233 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600234 error("lseek failed, ERROR={ERR}, OFFSET={OFFSET}", "ERR", errno,
235 "OFFSET", offset);
Sampa Misra69508502020-09-08 00:08:21 -0500236 return PLDM_ERROR;
237 }
Sampa Misra69508502020-09-08 00:08:21 -0500238 rc = ::write(fd, buffer, length);
239 if (rc == -1)
240 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600241 error(
242 "file write failed, ERROR={ERR}, LENGTH={LEN}, OFFSET={OFFSET}",
243 "ERR", errno, "LEN", length, "OFFSET", offset);
Sampa Misra69508502020-09-08 00:08:21 -0500244 return PLDM_ERROR;
245 }
Pavithra Barithaya303387e2021-03-18 23:35:42 -0500246 else if (rc == static_cast<int>(length))
247 {
248 rc = PLDM_SUCCESS;
249 }
250 else if (rc < static_cast<int>(length))
251 {
252 rc = PLDM_ERROR;
253 }
Sampa Misra69508502020-09-08 00:08:21 -0500254 close(fd);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500255
256 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
257 {
258 markerLIDremainingSize -= length;
259 if (markerLIDremainingSize == 0)
260 {
261 pldm::responder::oem_ibm_platform::Handler*
262 oemIbmPlatformHandler = dynamic_cast<
263 pldm::responder::oem_ibm_platform::Handler*>(
264 oemPlatformHandler);
265 auto sensorId =
266 oemIbmPlatformHandler->codeUpdate->getMarkerLidSensor();
267 using namespace pldm::responder::oem_ibm_platform;
268 oemIbmPlatformHandler->sendStateSensorEvent(
269 sensorId, PLDM_STATE_SENSOR_STATE, 0, VALID, VALID);
270 // validate api
271 rc = PLDM_SUCCESS;
272 }
273 }
274 else if (codeUpdateInProgress)
275 {
276 rc = processCodeUpdateLid(lidPath);
277 }
278
Sampa Misra69508502020-09-08 00:08:21 -0500279 return rc;
Sampa Misra18967162020-01-14 02:31:41 -0600280 }
281
Sampa Misra69508502020-09-08 00:08:21 -0500282 virtual int read(uint32_t offset, uint32_t& length, Response& response,
283 oem_platform::Handler* oemPlatformHandler)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600284 {
Sampa Misra69508502020-09-08 00:08:21 -0500285 if (constructLIDPath(oemPlatformHandler))
286 {
287 return readFile(lidPath, offset, length, response);
288 }
289 return PLDM_ERROR;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600290 }
291
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600292 virtual int fileAck(uint8_t /*fileStatus*/)
293 {
294 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
295 }
296
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500297 virtual int newFileAvailable(uint64_t length)
Sampa Misra18967162020-01-14 02:31:41 -0600298
299 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500300 if (lidType == PLDM_FILE_TYPE_LID_MARKER)
301 {
302 markerLIDremainingSize = length;
303 return PLDM_SUCCESS;
304 }
Sampa Misra18967162020-01-14 02:31:41 -0600305 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
306 }
307
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600308 /** @brief LidHandler destructor
309 */
Patrick Williams6da4f912023-05-10 07:50:53 -0500310 ~LidHandler() {}
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600311
312 protected:
313 std::string lidPath;
Sampa Misra69508502020-09-08 00:08:21 -0500314 std::string sideToRead;
315 bool isPatchDir;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500316 static inline MarkerLIDremainingSize markerLIDremainingSize;
317 uint8_t lidType;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600318};
319
320} // namespace responder
321} // namespace pldm