blob: 6cb748a17d0ac7937fc1684f254b530cd332928d [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>
6#include <libpldm/pldm.h>
7
Riya Dixit49cfb132023-03-02 04:26:53 -06008#include <phosphor-logging/lg2.hpp>
9
10PHOSPHOR_LOG2_USING;
11
Jayashankar Padathdb124362021-01-28 21:12:34 -060012namespace pldm
13{
14namespace requester
15{
16namespace oem_ibm
17{
Jayashankar Padathdb124362021-01-28 21:12:34 -060018using namespace pldm::utils;
19using namespace sdbusplus::bus::match::rules;
20
Jayashankar Padathdb124362021-01-28 21:12:34 -060021static constexpr auto resDumpProgressIntf =
22 "xyz.openbmc_project.Common.Progress";
23static constexpr auto resDumpStatus =
24 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed";
25
26DbusToFileHandler::DbusToFileHandler(
Andrew Jefferya330b2f2023-05-04 14:55:37 +093027 int mctp_fd, uint8_t mctp_eid, pldm::InstanceIdDb* instanceIdDb,
Sampa Misrac0c79482021-06-02 08:01:54 -050028 sdbusplus::message::object_path resDumpCurrentObjPath,
29 pldm::requester::Handler<pldm::requester::Request>* handler) :
Jayashankar Padathdb124362021-01-28 21:12:34 -060030 mctp_fd(mctp_fd),
Andrew Jefferya330b2f2023-05-04 14:55:37 +093031 mctp_eid(mctp_eid), instanceIdDb(instanceIdDb),
Sampa Misrac0c79482021-06-02 08:01:54 -050032 resDumpCurrentObjPath(resDumpCurrentObjPath), handler(handler)
Jayashankar Padathdb124362021-01-28 21:12:34 -060033{}
34
35void DbusToFileHandler::sendNewFileAvailableCmd(uint64_t fileSize)
36{
Andrew Jefferya330b2f2023-05-04 14:55:37 +093037 if (instanceIdDb == NULL)
Jayashankar Padathdb124362021-01-28 21:12:34 -060038 {
Riya Dixit49cfb132023-03-02 04:26:53 -060039 error(
Andrew Jefferya330b2f2023-05-04 14:55:37 +093040 "Failed to send resource dump parameters as instance ID DB is not set");
Jayashankar Padathdb124362021-01-28 21:12:34 -060041 pldm::utils::reportError(
42 "xyz.openbmc_project.bmc.pldm.InternalFailure");
43 return;
44 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +093045 auto instanceId = instanceIdDb->next(mctp_eid);
Jayashankar Padathdb124362021-01-28 21:12:34 -060046 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
Jayashankar Padath79612312022-06-13 12:47:05 -050047 PLDM_NEW_FILE_REQ_BYTES);
Jayashankar Padathdb124362021-01-28 21:12:34 -060048 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
49 // Need to revisit this logic at the time of multiple resource dump support
50 uint32_t fileHandle = 1;
51
Patrick Williams6da4f912023-05-10 07:50:53 -050052 auto rc = encode_new_file_req(instanceId,
53 PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
54 fileHandle, fileSize, request);
Jayashankar Padathdb124362021-01-28 21:12:34 -060055 if (rc != PLDM_SUCCESS)
56 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093057 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -060058 error("Failed to encode_new_file_req, rc = {RC}", "RC", rc);
Jayashankar Padathdb124362021-01-28 21:12:34 -060059 return;
60 }
61
Sampa Misrac0c79482021-06-02 08:01:54 -050062 auto newFileAvailableRespHandler = [this](mctp_eid_t /*eid*/,
63 const pldm_msg* response,
64 size_t respMsgLen) {
65 if (response == nullptr || !respMsgLen)
66 {
Riya Dixit49cfb132023-03-02 04:26:53 -060067 error("Failed to receive response for NewFileAvailable command");
Sampa Misrac0c79482021-06-02 08:01:54 -050068 return;
69 }
Jayashankar Padathdb124362021-01-28 21:12:34 -060070 uint8_t completionCode{};
Sampa Misrac0c79482021-06-02 08:01:54 -050071 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
72 if (rc || completionCode)
Jayashankar Padathdb124362021-01-28 21:12:34 -060073 {
Riya Dixit49cfb132023-03-02 04:26:53 -060074 error(
75 "Failed to decode_new_file_resp or Host returned error for new_file_available rc={RC}, cc = {CC}",
76 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -050077 reportResourceDumpFailure();
Jayashankar Padathdb124362021-01-28 21:12:34 -060078 }
Sampa Misrac0c79482021-06-02 08:01:54 -050079 };
80 rc = handler->registerRequest(
81 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
82 std::move(requestMsg), std::move(newFileAvailableRespHandler));
83 if (rc)
Jayashankar Padathdb124362021-01-28 21:12:34 -060084 {
Riya Dixit49cfb132023-03-02 04:26:53 -060085 error("Failed to send NewFileAvailable Request to Host");
Sampa Misrac0c79482021-06-02 08:01:54 -050086 reportResourceDumpFailure();
87 }
88}
Jayashankar Padathdb124362021-01-28 21:12:34 -060089
Sampa Misrac0c79482021-06-02 08:01:54 -050090void DbusToFileHandler::reportResourceDumpFailure()
91{
Sampa Misrac0c79482021-06-02 08:01:54 -050092 pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
93
94 PropertyValue value{resDumpStatus};
95 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
96 "Status", "string"};
97 try
98 {
99 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
100 }
101 catch (const std::exception& e)
102 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600103 error("failed to set resource dump operation status, ERROR={ERR_EXCEP}",
104 "ERR_EXCEP", e.what());
Jayashankar Padathdb124362021-01-28 21:12:34 -0600105 }
106}
107
108void DbusToFileHandler::processNewResourceDump(
109 const std::string& vspString, const std::string& resDumpReqPass)
110{
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600111 try
112 {
113 std::string objPath = resDumpCurrentObjPath;
114 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
115 objPath.c_str(), "Status", resDumpProgressIntf);
116 const auto& curResDumpStatus = std::get<ResDumpStatus>(propVal);
117
118 if (curResDumpStatus !=
119 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
120 {
121 return;
122 }
123 }
124 catch (const sdbusplus::exception_t& e)
125 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600126 error(
127 "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}",
128 "ERR_EXCEP", e.what(), "DUMP_OBJ_PATH",
129 resDumpCurrentObjPath.str.c_str(), "DUMP_PROG_INTF",
130 resDumpProgressIntf);
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600131 }
132
Jayashankar Padathdb124362021-01-28 21:12:34 -0600133 namespace fs = std::filesystem;
134 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
135
136 if (!fs::exists(resDumpDirPath))
137 {
138 fs::create_directories(resDumpDirPath);
139 }
140
141 // Need to reconsider this logic to set the value as "1" when we have the
142 // support to handle multiple resource dumps
143 fs::path resDumpFilePath = resDumpDirPath / "1";
144
145 std::ofstream fileHandle;
146 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
147
148 if (!fileHandle)
149 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600150 error("resource dump file open error:{RES_DUMP_PATH}", "RES_DUMP_PATH",
151 resDumpFilePath);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600152 PropertyValue value{resDumpStatus};
153 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
154 "Status", "string"};
155 try
156 {
157 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
158 }
159 catch (const std::exception& e)
160 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600161 error(
162 "failed to set resource dump operation status, ERROR={ERR_EXCEP}",
163 "ERR_EXCEP", e.what());
Jayashankar Padathdb124362021-01-28 21:12:34 -0600164 }
165 return;
166 }
167
168 // Fill up the file with resource dump parameters and respective sizes
169 auto fileFunc = [&fileHandle](auto& paramBuf) {
170 uint32_t paramSize = paramBuf.size();
171 fileHandle.write((char*)&paramSize, sizeof(paramSize));
172 fileHandle << paramBuf;
173 };
174 fileFunc(vspString);
175 fileFunc(resDumpReqPass);
176
Pavithra Barithayac047f802021-11-30 01:55:03 -0600177 std::string str;
178 if (!resDumpReqPass.empty())
179 {
180 str = getAcfFileContent();
181 }
182
183 fileFunc(str);
184
Jayashankar Padathdb124362021-01-28 21:12:34 -0600185 fileHandle.close();
186 size_t fileSize = fs::file_size(resDumpFilePath);
187
188 sendNewFileAvailableCmd(fileSize);
189}
190
Pavithra Barithayac047f802021-11-30 01:55:03 -0600191std::string DbusToFileHandler::getAcfFileContent()
192{
193 std::string str;
194 static constexpr auto acfDirPath = "/etc/acf/service.acf";
195 if (fs::exists(acfDirPath))
196 {
197 std::ifstream file;
198 file.open(acfDirPath);
199 std::stringstream acfBuf;
200 acfBuf << file.rdbuf();
201 str = acfBuf.str();
202 file.close();
203 }
204 return str;
205}
206
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500207void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
208 const std::string fileHandle)
209{
210 namespace fs = std::filesystem;
211 std::string dirPath = "/var/lib/ibm/bmcweb";
212 const fs::path certDirPath = dirPath;
213
214 if (!fs::exists(certDirPath))
215 {
216 fs::create_directories(certDirPath);
217 fs::permissions(certDirPath,
218 fs::perms::others_read | fs::perms::owner_write);
219 }
220
221 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
222 std::ofstream certFile;
223
224 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
225
226 if (!certFile)
227 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600228 error("cert file open error: {CERT_PATH}", "CERT_PATH",
229 certFilePath.c_str());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500230 return;
231 }
232
233 // Add csr to file
234 certFile << csr << std::endl;
235
236 certFile.close();
237 uint32_t fileSize = fs::file_size(certFilePath);
238
239 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
240 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
241}
242
243void DbusToFileHandler::newFileAvailableSendToHost(const uint32_t fileSize,
244 const uint32_t fileHandle,
245 const uint16_t type)
246{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930247 if (instanceIdDb == NULL)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500248 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600249 error("Failed to send csr to host.");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500250 pldm::utils::reportError(
251 "xyz.openbmc_project.bmc.pldm.InternalFailure");
252 return;
253 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930254 auto instanceId = instanceIdDb->next(mctp_eid);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500255 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
256 PLDM_NEW_FILE_REQ_BYTES);
257 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
258
Patrick Williams6da4f912023-05-10 07:50:53 -0500259 auto rc = encode_new_file_req(instanceId, type, fileHandle, fileSize,
260 request);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500261 if (rc != PLDM_SUCCESS)
262 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930263 instanceIdDb->free(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600264 error("Failed to encode_new_file_req, rc = {RC}", "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500265 return;
266 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500267 auto newFileAvailableRespHandler =
268 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Sampa Misrac0c79482021-06-02 08:01:54 -0500269 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500270 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600271 error(
272 "Failed to receive response for NewFileAvailable command for vmi");
Sampa Misrac0c79482021-06-02 08:01:54 -0500273 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500274 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500275 uint8_t completionCode{};
276 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
277 if (rc || completionCode)
278 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600279 error(
280 "Failed to decode_new_file_resp for vmi, or Host returned error for new_file_available rc = {RC}, cc = {CC}",
281 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -0500282 pldm::utils::reportError(
283 "xyz.openbmc_project.bmc.pldm.InternalFailure");
284 }
285 };
286 rc = handler->registerRequest(
287 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
288 std::move(requestMsg), std::move(newFileAvailableRespHandler));
289 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500290 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600291 error("Failed to send NewFileAvailable Request to Host for vmi");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500292 pldm::utils::reportError(
293 "xyz.openbmc_project.bmc.pldm.InternalFailure");
294 }
295}
296
Jayashankar Padathdb124362021-01-28 21:12:34 -0600297} // namespace oem_ibm
298} // namespace requester
299} // namespace pldm