blob: 44eb5f75045ddc5dd70499603fd049384bdd83c0 [file] [log] [blame]
Jayashankar Padathdb124362021-01-28 21:12:34 -06001#include "dbus_to_file_handler.hpp"
2
3#include "libpldm/requester/pldm.h"
4#include "oem/ibm/libpldm/file_io.h"
5
6#include "common/utils.hpp"
7
8namespace pldm
9{
10namespace requester
11{
12namespace oem_ibm
13{
14
15using namespace pldm::utils;
16using namespace sdbusplus::bus::match::rules;
17
18static constexpr auto resDumpObjPath =
19 "/xyz/openbmc_project/dump/resource/entry";
20static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
21static constexpr auto resDumpProgressIntf =
22 "xyz.openbmc_project.Common.Progress";
23static constexpr auto resDumpStatus =
24 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed";
25
26DbusToFileHandler::DbusToFileHandler(
27 int mctp_fd, uint8_t mctp_eid, dbus_api::Requester* requester,
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),
31 mctp_eid(mctp_eid), requester(requester),
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{
37 if (requester == NULL)
38 {
39 std::cerr << "Failed to send resource dump parameters as requester is "
40 "not set";
41 pldm::utils::reportError(
42 "xyz.openbmc_project.bmc.pldm.InternalFailure");
43 return;
44 }
45 auto instanceId = requester->getInstanceId(mctp_eid);
46 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
47 PLDM_NEW_FILE_REQ_BYTES + fileSize);
48 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
52 auto rc =
53 encode_new_file_req(instanceId, PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
54 fileHandle, fileSize, request);
55 if (rc != PLDM_SUCCESS)
56 {
57 requester->markFree(mctp_eid, instanceId);
58 std::cerr << "Failed to encode_new_file_req, rc = " << rc << std::endl;
59 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 {
67 std::cerr
68 << "Failed to receive response for NewFileAvailable command \n";
69 return;
70 }
Jayashankar Padathdb124362021-01-28 21:12:34 -060071 uint8_t completionCode{};
Sampa Misrac0c79482021-06-02 08:01:54 -050072 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
73 if (rc || completionCode)
Jayashankar Padathdb124362021-01-28 21:12:34 -060074 {
Sampa Misrac0c79482021-06-02 08:01:54 -050075 std::cerr << "Failed to decode_new_file_resp or"
76 << " Host returned error for new_file_available"
77 << " rc=" << rc
Jayashankar Padathdb124362021-01-28 21:12:34 -060078 << ", cc=" << static_cast<unsigned>(completionCode)
Sampa Misrac0c79482021-06-02 08:01:54 -050079 << "\n";
80 reportResourceDumpFailure();
Jayashankar Padathdb124362021-01-28 21:12:34 -060081 }
Sampa Misrac0c79482021-06-02 08:01:54 -050082 };
83 rc = handler->registerRequest(
84 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
85 std::move(requestMsg), std::move(newFileAvailableRespHandler));
86 if (rc)
Jayashankar Padathdb124362021-01-28 21:12:34 -060087 {
Sampa Misrac0c79482021-06-02 08:01:54 -050088 std::cerr << "Failed to send NewFileAvailable Request to Host \n";
89 reportResourceDumpFailure();
90 }
91}
Jayashankar Padathdb124362021-01-28 21:12:34 -060092
Sampa Misrac0c79482021-06-02 08:01:54 -050093void DbusToFileHandler::reportResourceDumpFailure()
94{
95
96 pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
97
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 {
107 std::cerr << "failed to set resource dump operation status, "
108 "ERROR="
109 << e.what() << "\n";
Jayashankar Padathdb124362021-01-28 21:12:34 -0600110 }
111}
112
113void DbusToFileHandler::processNewResourceDump(
114 const std::string& vspString, const std::string& resDumpReqPass)
115{
116 // This needs special handling in later point of time. Resource dump without
117 // the vsp string is supposed to be a non-disruptive system dump.
118 if (vspString.empty())
119 {
120 std::cerr << "Empty vsp string"
121 << "\n";
122 PropertyValue value{resDumpStatus};
123 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
124 "Status", "string"};
125 try
126 {
127 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
128 }
129 catch (const std::exception& e)
130 {
131 std::cerr << "failed to set resource dump operation status, "
132 "ERROR="
133 << e.what() << "\n";
134 }
135 return;
136 }
137
138 namespace fs = std::filesystem;
139 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
140
141 if (!fs::exists(resDumpDirPath))
142 {
143 fs::create_directories(resDumpDirPath);
144 }
145
146 // Need to reconsider this logic to set the value as "1" when we have the
147 // support to handle multiple resource dumps
148 fs::path resDumpFilePath = resDumpDirPath / "1";
149
150 std::ofstream fileHandle;
151 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
152
153 if (!fileHandle)
154 {
155 std::cerr << "resource dump file open error: " << resDumpFilePath
156 << "\n";
157 PropertyValue value{resDumpStatus};
158 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
159 "Status", "string"};
160 try
161 {
162 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
163 }
164 catch (const std::exception& e)
165 {
166 std::cerr << "failed to set resource dump operation status, "
167 "ERROR="
168 << e.what() << "\n";
169 }
170 return;
171 }
172
173 // Fill up the file with resource dump parameters and respective sizes
174 auto fileFunc = [&fileHandle](auto& paramBuf) {
175 uint32_t paramSize = paramBuf.size();
176 fileHandle.write((char*)&paramSize, sizeof(paramSize));
177 fileHandle << paramBuf;
178 };
179 fileFunc(vspString);
180 fileFunc(resDumpReqPass);
181
182 fileHandle.close();
183 size_t fileSize = fs::file_size(resDumpFilePath);
184
185 sendNewFileAvailableCmd(fileSize);
186}
187
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500188void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
189 const std::string fileHandle)
190{
191 namespace fs = std::filesystem;
192 std::string dirPath = "/var/lib/ibm/bmcweb";
193 const fs::path certDirPath = dirPath;
194
195 if (!fs::exists(certDirPath))
196 {
197 fs::create_directories(certDirPath);
198 fs::permissions(certDirPath,
199 fs::perms::others_read | fs::perms::owner_write);
200 }
201
202 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
203 std::ofstream certFile;
204
205 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
206
207 if (!certFile)
208 {
209 std::cerr << "cert file open error: " << certFilePath << "\n";
210 return;
211 }
212
213 // Add csr to file
214 certFile << csr << std::endl;
215
216 certFile.close();
217 uint32_t fileSize = fs::file_size(certFilePath);
218
219 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
220 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
221}
222
223void DbusToFileHandler::newFileAvailableSendToHost(const uint32_t fileSize,
224 const uint32_t fileHandle,
225 const uint16_t type)
226{
227 if (requester == NULL)
228 {
229 std::cerr << "Failed to send csr to host.";
230 pldm::utils::reportError(
231 "xyz.openbmc_project.bmc.pldm.InternalFailure");
232 return;
233 }
234 auto instanceId = requester->getInstanceId(mctp_eid);
235 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
236 PLDM_NEW_FILE_REQ_BYTES);
237 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
238
239 auto rc =
240 encode_new_file_req(instanceId, type, fileHandle, fileSize, request);
241 if (rc != PLDM_SUCCESS)
242 {
243 requester->markFree(mctp_eid, instanceId);
244 std::cerr << "Failed to encode_new_file_req, rc = " << rc << std::endl;
245 return;
246 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500247 auto newFileAvailableRespHandler = [](mctp_eid_t /*eid*/,
248 const pldm_msg* response,
249 size_t respMsgLen) {
250 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500251 {
Sampa Misrac0c79482021-06-02 08:01:54 -0500252 std::cerr << "Failed to receive response for NewFileAvailable "
253 "command for vmi \n";
254 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500255 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500256 uint8_t completionCode{};
257 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
258 if (rc || completionCode)
259 {
260 std::cerr << "Failed to decode_new_file_resp for vmi, or"
261 << " Host returned error for new_file_available"
262 << " rc=" << rc
263 << ", cc=" << static_cast<unsigned>(completionCode)
264 << "\n";
265 pldm::utils::reportError(
266 "xyz.openbmc_project.bmc.pldm.InternalFailure");
267 }
268 };
269 rc = handler->registerRequest(
270 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
271 std::move(requestMsg), std::move(newFileAvailableRespHandler));
272 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500273 {
Sampa Misrac0c79482021-06-02 08:01:54 -0500274 std::cerr
275 << "Failed to send NewFileAvailable Request to Host for vmi \n";
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500276 pldm::utils::reportError(
277 "xyz.openbmc_project.bmc.pldm.InternalFailure");
278 }
279}
280
Jayashankar Padathdb124362021-01-28 21:12:34 -0600281} // namespace oem_ibm
282} // namespace requester
283} // namespace pldm