blob: 57e6ab8bc72045061962be3b90c883f8eeb33e39 [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
George Liuc453e162022-12-21 17:16:23 +08005#include <libpldm/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 Jefferya330b2f2023-05-04 14:55:37 +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) :
Jayashankar Padathdb124362021-01-28 21:12:34 -060029 mctp_fd(mctp_fd),
Andrew Jefferya330b2f2023-05-04 14:55:37 +093030 mctp_eid(mctp_eid), instanceIdDb(instanceIdDb),
Sampa Misrac0c79482021-06-02 08:01:54 -050031 resDumpCurrentObjPath(resDumpCurrentObjPath), handler(handler)
Jayashankar Padathdb124362021-01-28 21:12:34 -060032{}
33
34void DbusToFileHandler::sendNewFileAvailableCmd(uint64_t fileSize)
35{
Andrew Jefferya330b2f2023-05-04 14:55:37 +093036 if (instanceIdDb == NULL)
Jayashankar Padathdb124362021-01-28 21:12:34 -060037 {
Riya Dixit49cfb132023-03-02 04:26:53 -060038 error(
Andrew Jefferya330b2f2023-05-04 14:55:37 +093039 "Failed to send resource dump parameters as instance ID DB is not set");
Jayashankar Padathdb124362021-01-28 21:12:34 -060040 pldm::utils::reportError(
41 "xyz.openbmc_project.bmc.pldm.InternalFailure");
42 return;
43 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +093044 auto instanceId = instanceIdDb->next(mctp_eid);
Jayashankar Padathdb124362021-01-28 21:12:34 -060045 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
Jayashankar Padath79612312022-06-13 12:47:05 -050046 PLDM_NEW_FILE_REQ_BYTES);
Jayashankar Padathdb124362021-01-28 21:12:34 -060047 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
48 // Need to revisit this logic at the time of multiple resource dump support
49 uint32_t fileHandle = 1;
50
Patrick Williams6da4f912023-05-10 07:50:53 -050051 auto rc = encode_new_file_req(instanceId,
52 PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
53 fileHandle, fileSize, request);
Jayashankar Padathdb124362021-01-28 21:12:34 -060054 if (rc != PLDM_SUCCESS)
55 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093056 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -060057 error("Failed to encode_new_file_req, rc = {RC}", "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(
74 "Failed to decode_new_file_resp or Host returned error for new_file_available rc={RC}, cc = {CC}",
75 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -050076 reportResourceDumpFailure();
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 Dixit49cfb132023-03-02 04:26:53 -060084 error("Failed to send NewFileAvailable Request to Host");
Sampa Misrac0c79482021-06-02 08:01:54 -050085 reportResourceDumpFailure();
86 }
87}
Jayashankar Padathdb124362021-01-28 21:12:34 -060088
Sampa Misrac0c79482021-06-02 08:01:54 -050089void DbusToFileHandler::reportResourceDumpFailure()
90{
Sampa Misrac0c79482021-06-02 08:01:54 -050091 pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
92
93 PropertyValue value{resDumpStatus};
94 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
95 "Status", "string"};
96 try
97 {
98 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
99 }
100 catch (const std::exception& e)
101 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600102 error("failed to set resource dump operation status, ERROR={ERR_EXCEP}",
103 "ERR_EXCEP", e.what());
Jayashankar Padathdb124362021-01-28 21:12:34 -0600104 }
105}
106
107void DbusToFileHandler::processNewResourceDump(
108 const std::string& vspString, const std::string& resDumpReqPass)
109{
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600110 try
111 {
112 std::string objPath = resDumpCurrentObjPath;
113 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
114 objPath.c_str(), "Status", resDumpProgressIntf);
115 const auto& curResDumpStatus = std::get<ResDumpStatus>(propVal);
116
117 if (curResDumpStatus !=
118 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
119 {
120 return;
121 }
122 }
123 catch (const sdbusplus::exception_t& e)
124 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600125 error(
126 "Error {ERR_EXCEP} found in getting current resource dump status while initiating a new resource dump with objPath={DUMP_OBJ_PATH} and intf={DUMP_PROG_INTF}",
127 "ERR_EXCEP", e.what(), "DUMP_OBJ_PATH",
128 resDumpCurrentObjPath.str.c_str(), "DUMP_PROG_INTF",
129 resDumpProgressIntf);
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600130 }
131
Jayashankar Padathdb124362021-01-28 21:12:34 -0600132 namespace fs = std::filesystem;
133 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
134
135 if (!fs::exists(resDumpDirPath))
136 {
137 fs::create_directories(resDumpDirPath);
138 }
139
140 // Need to reconsider this logic to set the value as "1" when we have the
141 // support to handle multiple resource dumps
142 fs::path resDumpFilePath = resDumpDirPath / "1";
143
144 std::ofstream fileHandle;
145 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
146
147 if (!fileHandle)
148 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600149 error("resource dump file open error:{RES_DUMP_PATH}", "RES_DUMP_PATH",
150 resDumpFilePath);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600151 PropertyValue value{resDumpStatus};
152 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
153 "Status", "string"};
154 try
155 {
156 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
157 }
158 catch (const std::exception& e)
159 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600160 error(
161 "failed to set resource dump operation status, ERROR={ERR_EXCEP}",
162 "ERR_EXCEP", e.what());
Jayashankar Padathdb124362021-01-28 21:12:34 -0600163 }
164 return;
165 }
166
167 // Fill up the file with resource dump parameters and respective sizes
168 auto fileFunc = [&fileHandle](auto& paramBuf) {
169 uint32_t paramSize = paramBuf.size();
170 fileHandle.write((char*)&paramSize, sizeof(paramSize));
171 fileHandle << paramBuf;
172 };
173 fileFunc(vspString);
174 fileFunc(resDumpReqPass);
175
Pavithra Barithayac047f802021-11-30 01:55:03 -0600176 std::string str;
177 if (!resDumpReqPass.empty())
178 {
179 str = getAcfFileContent();
180 }
181
182 fileFunc(str);
183
Jayashankar Padathdb124362021-01-28 21:12:34 -0600184 fileHandle.close();
185 size_t fileSize = fs::file_size(resDumpFilePath);
186
187 sendNewFileAvailableCmd(fileSize);
188}
189
Pavithra Barithayac047f802021-11-30 01:55:03 -0600190std::string DbusToFileHandler::getAcfFileContent()
191{
192 std::string str;
193 static constexpr auto acfDirPath = "/etc/acf/service.acf";
194 if (fs::exists(acfDirPath))
195 {
196 std::ifstream file;
197 file.open(acfDirPath);
198 std::stringstream acfBuf;
199 acfBuf << file.rdbuf();
200 str = acfBuf.str();
201 file.close();
202 }
203 return str;
204}
205
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500206void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
207 const std::string fileHandle)
208{
209 namespace fs = std::filesystem;
210 std::string dirPath = "/var/lib/ibm/bmcweb";
211 const fs::path certDirPath = dirPath;
212
213 if (!fs::exists(certDirPath))
214 {
215 fs::create_directories(certDirPath);
216 fs::permissions(certDirPath,
217 fs::perms::others_read | fs::perms::owner_write);
218 }
219
220 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
221 std::ofstream certFile;
222
223 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
224
225 if (!certFile)
226 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600227 error("cert file open error: {CERT_PATH}", "CERT_PATH",
228 certFilePath.c_str());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500229 return;
230 }
231
232 // Add csr to file
233 certFile << csr << std::endl;
234
235 certFile.close();
236 uint32_t fileSize = fs::file_size(certFilePath);
237
238 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
239 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
240}
241
242void DbusToFileHandler::newFileAvailableSendToHost(const uint32_t fileSize,
243 const uint32_t fileHandle,
244 const uint16_t type)
245{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930246 if (instanceIdDb == NULL)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500247 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600248 error("Failed to send csr to host.");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500249 pldm::utils::reportError(
250 "xyz.openbmc_project.bmc.pldm.InternalFailure");
251 return;
252 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930253 auto instanceId = instanceIdDb->next(mctp_eid);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500254 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
255 PLDM_NEW_FILE_REQ_BYTES);
256 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
257
Patrick Williams6da4f912023-05-10 07:50:53 -0500258 auto rc = encode_new_file_req(instanceId, type, fileHandle, fileSize,
259 request);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500260 if (rc != PLDM_SUCCESS)
261 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930262 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600263 error("Failed to encode_new_file_req, rc = {RC}", "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500264 return;
265 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500266 auto newFileAvailableRespHandler =
267 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Sampa Misrac0c79482021-06-02 08:01:54 -0500268 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500269 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600270 error(
271 "Failed to receive response for NewFileAvailable command for vmi");
Sampa Misrac0c79482021-06-02 08:01:54 -0500272 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500273 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500274 uint8_t completionCode{};
275 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
276 if (rc || completionCode)
277 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600278 error(
279 "Failed to decode_new_file_resp for vmi, or Host returned error for new_file_available rc = {RC}, cc = {CC}",
280 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -0500281 pldm::utils::reportError(
282 "xyz.openbmc_project.bmc.pldm.InternalFailure");
283 }
284 };
285 rc = handler->registerRequest(
286 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
287 std::move(requestMsg), std::move(newFileAvailableRespHandler));
288 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500289 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600290 error("Failed to send NewFileAvailable Request to Host for vmi");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500291 pldm::utils::reportError(
292 "xyz.openbmc_project.bmc.pldm.InternalFailure");
293 }
294}
295
Jayashankar Padathdb124362021-01-28 21:12:34 -0600296} // namespace oem_ibm
297} // namespace requester
298} // namespace pldm