blob: 35a4d9c9fb07806496175521c976351346897e36 [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 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(
Pavithra Barithayad28f08c2021-12-15 03:37:14 -060041 "xyz.openbmc_project.PLDM.Error.sendNewFileAvailableCmd.SendDumpParametersFail");
Jayashankar Padathdb124362021-01-28 21:12:34 -060042 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{
Pavithra Barithayad28f08c2021-12-15 03:37:14 -060091 pldm::utils::reportError(
92 "xyz.openbmc_project.PLDM.Error.ReportResourceDumpFail",
93 pldm::PelSeverity::Warning);
Sampa Misrac0c79482021-06-02 08:01:54 -050094
95 PropertyValue value{resDumpStatus};
96 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
97 "Status", "string"};
98 try
99 {
100 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
101 }
102 catch (const std::exception& e)
103 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600104 error("failed to set resource dump operation status, ERROR={ERR_EXCEP}",
105 "ERR_EXCEP", e.what());
Jayashankar Padathdb124362021-01-28 21:12:34 -0600106 }
107}
108
109void DbusToFileHandler::processNewResourceDump(
110 const std::string& vspString, const std::string& resDumpReqPass)
111{
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600112 try
113 {
114 std::string objPath = resDumpCurrentObjPath;
115 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
116 objPath.c_str(), "Status", resDumpProgressIntf);
117 const auto& curResDumpStatus = std::get<ResDumpStatus>(propVal);
118
119 if (curResDumpStatus !=
120 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
121 {
122 return;
123 }
124 }
125 catch (const sdbusplus::exception_t& e)
126 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600127 error(
128 "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}",
129 "ERR_EXCEP", e.what(), "DUMP_OBJ_PATH",
130 resDumpCurrentObjPath.str.c_str(), "DUMP_PROG_INTF",
131 resDumpProgressIntf);
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600132 }
133
Jayashankar Padathdb124362021-01-28 21:12:34 -0600134 namespace fs = std::filesystem;
135 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
136
137 if (!fs::exists(resDumpDirPath))
138 {
139 fs::create_directories(resDumpDirPath);
140 }
141
142 // Need to reconsider this logic to set the value as "1" when we have the
143 // support to handle multiple resource dumps
144 fs::path resDumpFilePath = resDumpDirPath / "1";
145
146 std::ofstream fileHandle;
147 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
148
149 if (!fileHandle)
150 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600151 error("resource dump file open error:{RES_DUMP_PATH}", "RES_DUMP_PATH",
152 resDumpFilePath);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600153 PropertyValue value{resDumpStatus};
154 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
155 "Status", "string"};
156 try
157 {
158 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
159 }
160 catch (const std::exception& e)
161 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600162 error(
163 "failed to set resource dump operation status, ERROR={ERR_EXCEP}",
164 "ERR_EXCEP", e.what());
Jayashankar Padathdb124362021-01-28 21:12:34 -0600165 }
166 return;
167 }
168
169 // Fill up the file with resource dump parameters and respective sizes
170 auto fileFunc = [&fileHandle](auto& paramBuf) {
171 uint32_t paramSize = paramBuf.size();
172 fileHandle.write((char*)&paramSize, sizeof(paramSize));
173 fileHandle << paramBuf;
174 };
175 fileFunc(vspString);
176 fileFunc(resDumpReqPass);
177
Pavithra Barithayac047f802021-11-30 01:55:03 -0600178 std::string str;
179 if (!resDumpReqPass.empty())
180 {
181 str = getAcfFileContent();
182 }
183
184 fileFunc(str);
185
Jayashankar Padathdb124362021-01-28 21:12:34 -0600186 fileHandle.close();
187 size_t fileSize = fs::file_size(resDumpFilePath);
188
189 sendNewFileAvailableCmd(fileSize);
190}
191
Pavithra Barithayac047f802021-11-30 01:55:03 -0600192std::string DbusToFileHandler::getAcfFileContent()
193{
194 std::string str;
195 static constexpr auto acfDirPath = "/etc/acf/service.acf";
196 if (fs::exists(acfDirPath))
197 {
198 std::ifstream file;
199 file.open(acfDirPath);
200 std::stringstream acfBuf;
201 acfBuf << file.rdbuf();
202 str = acfBuf.str();
203 file.close();
204 }
205 return str;
206}
207
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500208void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
209 const std::string fileHandle)
210{
211 namespace fs = std::filesystem;
212 std::string dirPath = "/var/lib/ibm/bmcweb";
213 const fs::path certDirPath = dirPath;
214
215 if (!fs::exists(certDirPath))
216 {
217 fs::create_directories(certDirPath);
218 fs::permissions(certDirPath,
219 fs::perms::others_read | fs::perms::owner_write);
220 }
221
222 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
223 std::ofstream certFile;
224
225 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
226
227 if (!certFile)
228 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600229 error("cert file open error: {CERT_PATH}", "CERT_PATH",
230 certFilePath.c_str());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500231 return;
232 }
233
234 // Add csr to file
235 certFile << csr << std::endl;
236
237 certFile.close();
238 uint32_t fileSize = fs::file_size(certFilePath);
239
240 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
241 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
242}
243
244void DbusToFileHandler::newFileAvailableSendToHost(const uint32_t fileSize,
245 const uint32_t fileHandle,
246 const uint16_t type)
247{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930248 if (instanceIdDb == NULL)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500249 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600250 error("Failed to send csr to host.");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500251 pldm::utils::reportError(
Pavithra Barithayad28f08c2021-12-15 03:37:14 -0600252 "xyz.openbmc_project.PLDM.Error.SendFileToHostFail");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500253 return;
254 }
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930255 auto instanceId = instanceIdDb->next(mctp_eid);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500256 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
257 PLDM_NEW_FILE_REQ_BYTES);
258 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
259
Patrick Williams6da4f912023-05-10 07:50:53 -0500260 auto rc = encode_new_file_req(instanceId, type, fileHandle, fileSize,
261 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 Dixit49cfb132023-03-02 04:26:53 -0600265 error("Failed to encode_new_file_req, rc = {RC}", "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500266 return;
267 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500268 auto newFileAvailableRespHandler =
269 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
Sampa Misrac0c79482021-06-02 08:01:54 -0500270 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500271 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600272 error(
273 "Failed to receive response for NewFileAvailable command for vmi");
Sampa Misrac0c79482021-06-02 08:01:54 -0500274 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500275 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500276 uint8_t completionCode{};
277 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
278 if (rc || completionCode)
279 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600280 error(
281 "Failed to decode_new_file_resp for vmi, or Host returned error for new_file_available rc = {RC}, cc = {CC}",
282 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -0500283 pldm::utils::reportError(
Pavithra Barithayad28f08c2021-12-15 03:37:14 -0600284 "xyz.openbmc_project.PLDM.Error.DecodeNewFileResponseFail");
Sampa Misrac0c79482021-06-02 08:01:54 -0500285 }
286 };
287 rc = handler->registerRequest(
288 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
289 std::move(requestMsg), std::move(newFileAvailableRespHandler));
290 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500291 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600292 error("Failed to send NewFileAvailable Request to Host for vmi");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500293 pldm::utils::reportError(
Pavithra Barithayad28f08c2021-12-15 03:37:14 -0600294 "xyz.openbmc_project.PLDM.Error.NewFileAvailableRequestFail");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500295 }
296}
297
Jayashankar Padathdb124362021-01-28 21:12:34 -0600298} // namespace oem_ibm
299} // namespace requester
300} // namespace pldm