blob: 8bc25afd5bfc9a217fcc24dcad8748d2ebf46ed6 [file] [log] [blame]
Jayashankar Padathdb124362021-01-28 21:12:34 -06001#include "dbus_to_file_handler.hpp"
2
Jayashankar Padathdb124362021-01-28 21:12:34 -06003#include "common/utils.hpp"
4
Andrew Jeffery21f128d2024-01-15 15:34:26 +10305#include <libpldm/oem/ibm/file_io.h>
George Liuc453e162022-12-21 17:16:23 +08006
Riya Dixit49cfb132023-03-02 04:26:53 -06007#include <phosphor-logging/lg2.hpp>
8
9PHOSPHOR_LOG2_USING;
10
Jayashankar Padathdb124362021-01-28 21:12:34 -060011namespace pldm
12{
13namespace requester
14{
15namespace oem_ibm
16{
Jayashankar Padathdb124362021-01-28 21:12:34 -060017using namespace pldm::utils;
18using namespace sdbusplus::bus::match::rules;
19
Jayashankar Padathdb124362021-01-28 21:12:34 -060020static constexpr auto resDumpProgressIntf =
21 "xyz.openbmc_project.Common.Progress";
22static constexpr auto resDumpStatus =
23 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed";
24
25DbusToFileHandler::DbusToFileHandler(
Andrew Jefferyfb8d1942024-07-25 23:12:36 +093026 int /* mctp_fd */, uint8_t mctp_eid, pldm::InstanceIdDb* instanceIdDb,
Sampa Misrac0c79482021-06-02 08:01:54 -050027 sdbusplus::message::object_path resDumpCurrentObjPath,
28 pldm::requester::Handler<pldm::requester::Request>* handler) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040029 mctp_eid(mctp_eid), instanceIdDb(instanceIdDb),
30 resDumpCurrentObjPath(resDumpCurrentObjPath), handler(handler)
Jayashankar Padathdb124362021-01-28 21:12:34 -060031{}
32
33void DbusToFileHandler::sendNewFileAvailableCmd(uint64_t fileSize)
34{
Jayanth Othayoth7c14fc42024-12-17 10:24:47 -060035 if (instanceIdDb == nullptr)
Jayashankar Padathdb124362021-01-28 21:12:34 -060036 {
Riya Dixit49cfb132023-03-02 04:26:53 -060037 error(
Andrew Jefferya330b2f2023-05-04 14:55:37 +093038 "Failed to send resource dump parameters as instance ID DB is not set");
Jayashankar Padathdb124362021-01-28 21:12:34 -060039 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +053040 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Jayashankar Padathdb124362021-01-28 21:12:34 -060041 return;
42 }
Eric Yang70262ed2025-07-02 06:35:03 +000043 auto instanceIdResult =
44 pldm::utils::getInstanceId(instanceIdDb->next(mctp_eid));
45 if (!instanceIdResult)
46 {
47 return;
48 }
49 auto instanceId = instanceIdResult.value();
Patrick Williams16c2a0a2024-08-16 15:20:59 -040050 std::vector<uint8_t> requestMsg(
51 sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_REQ_BYTES);
Jayashankar Padathdb124362021-01-28 21:12:34 -060052 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
53 // Need to revisit this logic at the time of multiple resource dump support
54 uint32_t fileHandle = 1;
55
Patrick Williams16c2a0a2024-08-16 15:20:59 -040056 auto rc =
57 encode_new_file_req(instanceId, PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
58 fileHandle, fileSize, request);
Jayashankar Padathdb124362021-01-28 21:12:34 -060059 if (rc != PLDM_SUCCESS)
60 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093061 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixitfc84f632024-04-06 14:00:02 -050062 error("Failed to encode new file request with response code '{RC}'",
63 "RC", rc);
Jayashankar Padathdb124362021-01-28 21:12:34 -060064 return;
65 }
66
Sampa Misrac0c79482021-06-02 08:01:54 -050067 auto newFileAvailableRespHandler = [this](mctp_eid_t /*eid*/,
68 const pldm_msg* response,
69 size_t respMsgLen) {
70 if (response == nullptr || !respMsgLen)
71 {
Riya Dixit49cfb132023-03-02 04:26:53 -060072 error("Failed to receive response for NewFileAvailable command");
Sampa Misrac0c79482021-06-02 08:01:54 -050073 return;
74 }
Jayashankar Padathdb124362021-01-28 21:12:34 -060075 uint8_t completionCode{};
Sampa Misrac0c79482021-06-02 08:01:54 -050076 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
77 if (rc || completionCode)
Jayashankar Padathdb124362021-01-28 21:12:34 -060078 {
Riya Dixit49cfb132023-03-02 04:26:53 -060079 error(
Riya Dixitfc84f632024-04-06 14:00:02 -050080 "Failed to decode new file available response or remote terminus returned error, response code '{RC}' and completion code '{CC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050081 "RC", rc, "CC", completionCode);
Riya Dixit4f7eec82024-08-01 15:07:53 -050082 reportResourceDumpFailure("DecodeNewFileResp");
Jayashankar Padathdb124362021-01-28 21:12:34 -060083 }
Sampa Misrac0c79482021-06-02 08:01:54 -050084 };
85 rc = handler->registerRequest(
86 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
87 std::move(requestMsg), std::move(newFileAvailableRespHandler));
88 if (rc)
Jayashankar Padathdb124362021-01-28 21:12:34 -060089 {
Riya Dixitfc84f632024-04-06 14:00:02 -050090 error(
91 "Failed to send NewFileAvailable Request to Host, response code '{RC}'",
92 "RC", rc);
Riya Dixit4f7eec82024-08-01 15:07:53 -050093 reportResourceDumpFailure("NewFileAvailableRequest");
Sampa Misrac0c79482021-06-02 08:01:54 -050094 }
95}
Jayashankar Padathdb124362021-01-28 21:12:34 -060096
Riya Dixit4f7eec82024-08-01 15:07:53 -050097void DbusToFileHandler::reportResourceDumpFailure(const std::string_view& str)
Sampa Misrac0c79482021-06-02 08:01:54 -050098{
Riya Dixit4f7eec82024-08-01 15:07:53 -050099 std::string s = "xyz.openbmc_project.PLDM.Error.ReportResourceDumpFail.";
100 s += str;
101
102 pldm::utils::reportError(s.c_str());
Sampa Misrac0c79482021-06-02 08:01:54 -0500103
104 PropertyValue value{resDumpStatus};
105 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
106 "Status", "string"};
107 try
108 {
109 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
110 }
111 catch (const std::exception& e)
112 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500113 error("Failed to set resource dump operation status, error - {ERROR}",
114 "ERROR", e);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600115 }
116}
117
118void DbusToFileHandler::processNewResourceDump(
119 const std::string& vspString, const std::string& resDumpReqPass)
120{
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600121 try
122 {
123 std::string objPath = resDumpCurrentObjPath;
124 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
125 objPath.c_str(), "Status", resDumpProgressIntf);
126 const auto& curResDumpStatus = std::get<ResDumpStatus>(propVal);
127
128 if (curResDumpStatus !=
129 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
130 {
131 return;
132 }
133 }
134 catch (const sdbusplus::exception_t& e)
135 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600136 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500137 "Error '{ERROR}' found in getting current resource dump status while initiating a new resource dump with object path '{PATH}' and interface {INTERFACE}",
138 "ERROR", e, "PATH", resDumpCurrentObjPath, "INTERFACE",
Riya Dixit49cfb132023-03-02 04:26:53 -0600139 resDumpProgressIntf);
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600140 }
141
Jayashankar Padathdb124362021-01-28 21:12:34 -0600142 namespace fs = std::filesystem;
143 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
144
145 if (!fs::exists(resDumpDirPath))
146 {
147 fs::create_directories(resDumpDirPath);
148 }
149
150 // Need to reconsider this logic to set the value as "1" when we have the
151 // support to handle multiple resource dumps
152 fs::path resDumpFilePath = resDumpDirPath / "1";
153
154 std::ofstream fileHandle;
155 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
156
157 if (!fileHandle)
158 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500159 error("Failed to open resource dump file '{PATH}'", "PATH",
Riya Dixit49cfb132023-03-02 04:26:53 -0600160 resDumpFilePath);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600161 PropertyValue value{resDumpStatus};
162 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
163 "Status", "string"};
164 try
165 {
166 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
167 }
168 catch (const std::exception& e)
169 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600170 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500171 "Failed to set resource dump operation status, error - {ERROR}",
172 "ERROR", e);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600173 }
174 return;
175 }
176
177 // Fill up the file with resource dump parameters and respective sizes
178 auto fileFunc = [&fileHandle](auto& paramBuf) {
179 uint32_t paramSize = paramBuf.size();
180 fileHandle.write((char*)&paramSize, sizeof(paramSize));
181 fileHandle << paramBuf;
182 };
183 fileFunc(vspString);
184 fileFunc(resDumpReqPass);
185
Pavithra Barithayac047f802021-11-30 01:55:03 -0600186 std::string str;
187 if (!resDumpReqPass.empty())
188 {
189 str = getAcfFileContent();
190 }
191
192 fileFunc(str);
193
Jayashankar Padathdb124362021-01-28 21:12:34 -0600194 fileHandle.close();
195 size_t fileSize = fs::file_size(resDumpFilePath);
196
197 sendNewFileAvailableCmd(fileSize);
198}
199
Pavithra Barithayac047f802021-11-30 01:55:03 -0600200std::string DbusToFileHandler::getAcfFileContent()
201{
202 std::string str;
203 static constexpr auto acfDirPath = "/etc/acf/service.acf";
204 if (fs::exists(acfDirPath))
205 {
206 std::ifstream file;
207 file.open(acfDirPath);
208 std::stringstream acfBuf;
209 acfBuf << file.rdbuf();
210 str = acfBuf.str();
211 file.close();
212 }
213 return str;
214}
215
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500216void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
217 const std::string fileHandle)
218{
219 namespace fs = std::filesystem;
220 std::string dirPath = "/var/lib/ibm/bmcweb";
221 const fs::path certDirPath = dirPath;
222
223 if (!fs::exists(certDirPath))
224 {
225 fs::create_directories(certDirPath);
226 fs::permissions(certDirPath,
227 fs::perms::others_read | fs::perms::owner_write);
228 }
229
230 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
231 std::ofstream certFile;
232
233 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
234
235 if (!certFile)
236 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500237 error("Failed to open certificate file '{PATH}'", "PATH", certFilePath);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500238 return;
239 }
240
241 // Add csr to file
242 certFile << csr << std::endl;
243
244 certFile.close();
245 uint32_t fileSize = fs::file_size(certFilePath);
246
247 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
248 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
249}
250
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400251void DbusToFileHandler::newFileAvailableSendToHost(
252 const uint32_t fileSize, const uint32_t fileHandle, const uint16_t type)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500253{
Jayanth Othayoth7c14fc42024-12-17 10:24:47 -0600254 if (instanceIdDb == nullptr)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500255 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500256 error("Failed to send csr to remote terminus.");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500257 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530258 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500259 return;
260 }
Eric Yang70262ed2025-07-02 06:35:03 +0000261 auto instanceIdResult =
262 pldm::utils::getInstanceId(instanceIdDb->next(mctp_eid));
263 if (!instanceIdResult)
264 {
265 return;
266 }
267 auto instanceId = instanceIdResult.value();
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400268 std::vector<uint8_t> requestMsg(
269 sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_REQ_BYTES);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500270 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
271
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400272 auto rc =
273 encode_new_file_req(instanceId, type, fileHandle, fileSize, request);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500274 if (rc != PLDM_SUCCESS)
275 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930276 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixitfc84f632024-04-06 14:00:02 -0500277 error("Failed to encode new file request with response code '{RC}'",
278 "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500279 return;
280 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400281 auto newFileAvailableRespHandler = [](mctp_eid_t /*eid*/,
282 const pldm_msg* response,
283 size_t respMsgLen) {
Sampa Misrac0c79482021-06-02 08:01:54 -0500284 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500285 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600286 error(
287 "Failed to receive response for NewFileAvailable command for vmi");
Sampa Misrac0c79482021-06-02 08:01:54 -0500288 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500289 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500290 uint8_t completionCode{};
291 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
292 if (rc || completionCode)
293 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600294 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500295 "Failed to decode new file available response for vmi or remote terminus returned error, response code '{RC}' and completion code '{CC}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500296 "RC", rc, "CC", completionCode);
Archana Kakani73c88952025-06-02 11:01:42 -0500297 if (rc)
298 {
299 pldm::utils::reportError(
300 "xyz.openbmc_project.PLDM.Error.DecodeNewFileResponseFail");
301 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500302 }
303 };
304 rc = handler->registerRequest(
305 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
306 std::move(requestMsg), std::move(newFileAvailableRespHandler));
307 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500308 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500309 error(
310 "Failed to send NewFileAvailable Request to Host for vmi, response code '{RC}'",
311 "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500312 pldm::utils::reportError(
Riya Dixit4f7eec82024-08-01 15:07:53 -0500313 "xyz.openbmc_project.PLDM.Error.NewFileAvailableRequestFail");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500314 }
315}
316
Jayashankar Padathdb124362021-01-28 21:12:34 -0600317} // namespace oem_ibm
318} // namespace requester
319} // namespace pldm