blob: 47ddf2c436641cffc4267200b68ead629f3bbc4d [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{
Andrew Jefferya330b2f2023-05-04 14:55:37 +093035 if (instanceIdDb == NULL)
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 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +093043 auto instanceId = instanceIdDb->next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -040044 std::vector<uint8_t> requestMsg(
45 sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_REQ_BYTES);
Jayashankar Padathdb124362021-01-28 21:12:34 -060046 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
47 // Need to revisit this logic at the time of multiple resource dump support
48 uint32_t fileHandle = 1;
49
Patrick Williams16c2a0a2024-08-16 15:20:59 -040050 auto rc =
51 encode_new_file_req(instanceId, PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
52 fileHandle, fileSize, request);
Jayashankar Padathdb124362021-01-28 21:12:34 -060053 if (rc != PLDM_SUCCESS)
54 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093055 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixitfc84f632024-04-06 14:00:02 -050056 error("Failed to encode new file request with response code '{RC}'",
57 "RC", rc);
Jayashankar Padathdb124362021-01-28 21:12:34 -060058 return;
59 }
60
Sampa Misrac0c79482021-06-02 08:01:54 -050061 auto newFileAvailableRespHandler = [this](mctp_eid_t /*eid*/,
62 const pldm_msg* response,
63 size_t respMsgLen) {
64 if (response == nullptr || !respMsgLen)
65 {
Riya Dixit49cfb132023-03-02 04:26:53 -060066 error("Failed to receive response for NewFileAvailable command");
Sampa Misrac0c79482021-06-02 08:01:54 -050067 return;
68 }
Jayashankar Padathdb124362021-01-28 21:12:34 -060069 uint8_t completionCode{};
Sampa Misrac0c79482021-06-02 08:01:54 -050070 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
71 if (rc || completionCode)
Jayashankar Padathdb124362021-01-28 21:12:34 -060072 {
Riya Dixit49cfb132023-03-02 04:26:53 -060073 error(
Riya Dixitfc84f632024-04-06 14:00:02 -050074 "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 -050075 "RC", rc, "CC", completionCode);
Riya Dixit4f7eec82024-08-01 15:07:53 -050076 reportResourceDumpFailure("DecodeNewFileResp");
Jayashankar Padathdb124362021-01-28 21:12:34 -060077 }
Sampa Misrac0c79482021-06-02 08:01:54 -050078 };
79 rc = handler->registerRequest(
80 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
81 std::move(requestMsg), std::move(newFileAvailableRespHandler));
82 if (rc)
Jayashankar Padathdb124362021-01-28 21:12:34 -060083 {
Riya Dixitfc84f632024-04-06 14:00:02 -050084 error(
85 "Failed to send NewFileAvailable Request to Host, response code '{RC}'",
86 "RC", rc);
Riya Dixit4f7eec82024-08-01 15:07:53 -050087 reportResourceDumpFailure("NewFileAvailableRequest");
Sampa Misrac0c79482021-06-02 08:01:54 -050088 }
89}
Jayashankar Padathdb124362021-01-28 21:12:34 -060090
Riya Dixit4f7eec82024-08-01 15:07:53 -050091void DbusToFileHandler::reportResourceDumpFailure(const std::string_view& str)
Sampa Misrac0c79482021-06-02 08:01:54 -050092{
Riya Dixit4f7eec82024-08-01 15:07:53 -050093 std::string s = "xyz.openbmc_project.PLDM.Error.ReportResourceDumpFail.";
94 s += str;
95
96 pldm::utils::reportError(s.c_str());
Sampa Misrac0c79482021-06-02 08:01:54 -050097
98 PropertyValue value{resDumpStatus};
99 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
100 "Status", "string"};
101 try
102 {
103 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
104 }
105 catch (const std::exception& e)
106 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500107 error("Failed to set resource dump operation status, error - {ERROR}",
108 "ERROR", e);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600109 }
110}
111
112void DbusToFileHandler::processNewResourceDump(
113 const std::string& vspString, const std::string& resDumpReqPass)
114{
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600115 try
116 {
117 std::string objPath = resDumpCurrentObjPath;
118 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
119 objPath.c_str(), "Status", resDumpProgressIntf);
120 const auto& curResDumpStatus = std::get<ResDumpStatus>(propVal);
121
122 if (curResDumpStatus !=
123 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
124 {
125 return;
126 }
127 }
128 catch (const sdbusplus::exception_t& e)
129 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600130 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500131 "Error '{ERROR}' found in getting current resource dump status while initiating a new resource dump with object path '{PATH}' and interface {INTERFACE}",
132 "ERROR", e, "PATH", resDumpCurrentObjPath, "INTERFACE",
Riya Dixit49cfb132023-03-02 04:26:53 -0600133 resDumpProgressIntf);
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600134 }
135
Jayashankar Padathdb124362021-01-28 21:12:34 -0600136 namespace fs = std::filesystem;
137 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
138
139 if (!fs::exists(resDumpDirPath))
140 {
141 fs::create_directories(resDumpDirPath);
142 }
143
144 // Need to reconsider this logic to set the value as "1" when we have the
145 // support to handle multiple resource dumps
146 fs::path resDumpFilePath = resDumpDirPath / "1";
147
148 std::ofstream fileHandle;
149 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
150
151 if (!fileHandle)
152 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500153 error("Failed to open resource dump file '{PATH}'", "PATH",
Riya Dixit49cfb132023-03-02 04:26:53 -0600154 resDumpFilePath);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600155 PropertyValue value{resDumpStatus};
156 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
157 "Status", "string"};
158 try
159 {
160 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
161 }
162 catch (const std::exception& e)
163 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600164 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500165 "Failed to set resource dump operation status, error - {ERROR}",
166 "ERROR", e);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600167 }
168 return;
169 }
170
171 // Fill up the file with resource dump parameters and respective sizes
172 auto fileFunc = [&fileHandle](auto& paramBuf) {
173 uint32_t paramSize = paramBuf.size();
174 fileHandle.write((char*)&paramSize, sizeof(paramSize));
175 fileHandle << paramBuf;
176 };
177 fileFunc(vspString);
178 fileFunc(resDumpReqPass);
179
Pavithra Barithayac047f802021-11-30 01:55:03 -0600180 std::string str;
181 if (!resDumpReqPass.empty())
182 {
183 str = getAcfFileContent();
184 }
185
186 fileFunc(str);
187
Jayashankar Padathdb124362021-01-28 21:12:34 -0600188 fileHandle.close();
189 size_t fileSize = fs::file_size(resDumpFilePath);
190
191 sendNewFileAvailableCmd(fileSize);
192}
193
Pavithra Barithayac047f802021-11-30 01:55:03 -0600194std::string DbusToFileHandler::getAcfFileContent()
195{
196 std::string str;
197 static constexpr auto acfDirPath = "/etc/acf/service.acf";
198 if (fs::exists(acfDirPath))
199 {
200 std::ifstream file;
201 file.open(acfDirPath);
202 std::stringstream acfBuf;
203 acfBuf << file.rdbuf();
204 str = acfBuf.str();
205 file.close();
206 }
207 return str;
208}
209
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500210void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
211 const std::string fileHandle)
212{
213 namespace fs = std::filesystem;
214 std::string dirPath = "/var/lib/ibm/bmcweb";
215 const fs::path certDirPath = dirPath;
216
217 if (!fs::exists(certDirPath))
218 {
219 fs::create_directories(certDirPath);
220 fs::permissions(certDirPath,
221 fs::perms::others_read | fs::perms::owner_write);
222 }
223
224 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
225 std::ofstream certFile;
226
227 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
228
229 if (!certFile)
230 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500231 error("Failed to open certificate file '{PATH}'", "PATH", certFilePath);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500232 return;
233 }
234
235 // Add csr to file
236 certFile << csr << std::endl;
237
238 certFile.close();
239 uint32_t fileSize = fs::file_size(certFilePath);
240
241 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
242 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
243}
244
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400245void DbusToFileHandler::newFileAvailableSendToHost(
246 const uint32_t fileSize, const uint32_t fileHandle, const uint16_t type)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500247{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930248 if (instanceIdDb == NULL)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500249 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500250 error("Failed to send csr to remote terminus.");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500251 pldm::utils::reportError(
Manojkiran Eda92fb0b52024-04-17 10:48:17 +0530252 "xyz.openbmc_project.bmc.pldm.InternalFailure");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500253 return;
254 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930255 auto instanceId = instanceIdDb->next(mctp_eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400256 std::vector<uint8_t> requestMsg(
257 sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_REQ_BYTES);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500258 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
259
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400260 auto rc =
261 encode_new_file_req(instanceId, type, fileHandle, fileSize, request);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500262 if (rc != PLDM_SUCCESS)
263 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930264 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixitfc84f632024-04-06 14:00:02 -0500265 error("Failed to encode new file request with response code '{RC}'",
266 "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500267 return;
268 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400269 auto newFileAvailableRespHandler = [](mctp_eid_t /*eid*/,
270 const pldm_msg* response,
271 size_t respMsgLen) {
Sampa Misrac0c79482021-06-02 08:01:54 -0500272 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500273 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600274 error(
275 "Failed to receive response for NewFileAvailable command for vmi");
Sampa Misrac0c79482021-06-02 08:01:54 -0500276 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500277 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500278 uint8_t completionCode{};
279 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
280 if (rc || completionCode)
281 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600282 error(
Riya Dixitfc84f632024-04-06 14:00:02 -0500283 "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 -0500284 "RC", rc, "CC", completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -0500285 pldm::utils::reportError(
Riya Dixit4f7eec82024-08-01 15:07:53 -0500286 "xyz.openbmc_project.PLDM.Error.DecodeNewFileResponseFail");
Sampa Misrac0c79482021-06-02 08:01:54 -0500287 }
288 };
289 rc = handler->registerRequest(
290 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
291 std::move(requestMsg), std::move(newFileAvailableRespHandler));
292 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500293 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500294 error(
295 "Failed to send NewFileAvailable Request to Host for vmi, response code '{RC}'",
296 "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500297 pldm::utils::reportError(
Riya Dixit4f7eec82024-08-01 15:07:53 -0500298 "xyz.openbmc_project.PLDM.Error.NewFileAvailableRequestFail");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500299 }
300}
301
Jayashankar Padathdb124362021-01-28 21:12:34 -0600302} // namespace oem_ibm
303} // namespace requester
304} // namespace pldm