blob: 7b4e83f9b8b7694ca99b67584cc6115c4bf2221d [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{
Sampa Misrac0c79482021-06-02 08:01:54 -050095 pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
96
97 PropertyValue value{resDumpStatus};
98 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
99 "Status", "string"};
100 try
101 {
102 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
103 }
104 catch (const std::exception& e)
105 {
106 std::cerr << "failed to set resource dump operation status, "
107 "ERROR="
108 << e.what() << "\n";
Jayashankar Padathdb124362021-01-28 21:12:34 -0600109 }
110}
111
112void DbusToFileHandler::processNewResourceDump(
113 const std::string& vspString, const std::string& resDumpReqPass)
114{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600115 namespace fs = std::filesystem;
116 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
117
118 if (!fs::exists(resDumpDirPath))
119 {
120 fs::create_directories(resDumpDirPath);
121 }
122
123 // Need to reconsider this logic to set the value as "1" when we have the
124 // support to handle multiple resource dumps
125 fs::path resDumpFilePath = resDumpDirPath / "1";
126
127 std::ofstream fileHandle;
128 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
129
130 if (!fileHandle)
131 {
132 std::cerr << "resource dump file open error: " << resDumpFilePath
133 << "\n";
134 PropertyValue value{resDumpStatus};
135 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
136 "Status", "string"};
137 try
138 {
139 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
140 }
141 catch (const std::exception& e)
142 {
143 std::cerr << "failed to set resource dump operation status, "
144 "ERROR="
145 << e.what() << "\n";
146 }
147 return;
148 }
149
150 // Fill up the file with resource dump parameters and respective sizes
151 auto fileFunc = [&fileHandle](auto& paramBuf) {
152 uint32_t paramSize = paramBuf.size();
153 fileHandle.write((char*)&paramSize, sizeof(paramSize));
154 fileHandle << paramBuf;
155 };
156 fileFunc(vspString);
157 fileFunc(resDumpReqPass);
158
159 fileHandle.close();
160 size_t fileSize = fs::file_size(resDumpFilePath);
161
162 sendNewFileAvailableCmd(fileSize);
163}
164
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500165void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
166 const std::string fileHandle)
167{
168 namespace fs = std::filesystem;
169 std::string dirPath = "/var/lib/ibm/bmcweb";
170 const fs::path certDirPath = dirPath;
171
172 if (!fs::exists(certDirPath))
173 {
174 fs::create_directories(certDirPath);
175 fs::permissions(certDirPath,
176 fs::perms::others_read | fs::perms::owner_write);
177 }
178
179 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
180 std::ofstream certFile;
181
182 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
183
184 if (!certFile)
185 {
186 std::cerr << "cert file open error: " << certFilePath << "\n";
187 return;
188 }
189
190 // Add csr to file
191 certFile << csr << std::endl;
192
193 certFile.close();
194 uint32_t fileSize = fs::file_size(certFilePath);
195
196 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
197 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
198}
199
200void DbusToFileHandler::newFileAvailableSendToHost(const uint32_t fileSize,
201 const uint32_t fileHandle,
202 const uint16_t type)
203{
204 if (requester == NULL)
205 {
206 std::cerr << "Failed to send csr to host.";
207 pldm::utils::reportError(
208 "xyz.openbmc_project.bmc.pldm.InternalFailure");
209 return;
210 }
211 auto instanceId = requester->getInstanceId(mctp_eid);
212 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
213 PLDM_NEW_FILE_REQ_BYTES);
214 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
215
216 auto rc =
217 encode_new_file_req(instanceId, type, fileHandle, fileSize, request);
218 if (rc != PLDM_SUCCESS)
219 {
220 requester->markFree(mctp_eid, instanceId);
221 std::cerr << "Failed to encode_new_file_req, rc = " << rc << std::endl;
222 return;
223 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500224 auto newFileAvailableRespHandler = [](mctp_eid_t /*eid*/,
225 const pldm_msg* response,
226 size_t respMsgLen) {
227 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500228 {
Sampa Misrac0c79482021-06-02 08:01:54 -0500229 std::cerr << "Failed to receive response for NewFileAvailable "
230 "command for vmi \n";
231 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500232 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500233 uint8_t completionCode{};
234 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
235 if (rc || completionCode)
236 {
237 std::cerr << "Failed to decode_new_file_resp for vmi, or"
238 << " Host returned error for new_file_available"
239 << " rc=" << rc
240 << ", cc=" << static_cast<unsigned>(completionCode)
241 << "\n";
242 pldm::utils::reportError(
243 "xyz.openbmc_project.bmc.pldm.InternalFailure");
244 }
245 };
246 rc = handler->registerRequest(
247 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
248 std::move(requestMsg), std::move(newFileAvailableRespHandler));
249 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500250 {
Sampa Misrac0c79482021-06-02 08:01:54 -0500251 std::cerr
252 << "Failed to send NewFileAvailable Request to Host for vmi \n";
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500253 pldm::utils::reportError(
254 "xyz.openbmc_project.bmc.pldm.InternalFailure");
255 }
256}
257
Jayashankar Padathdb124362021-01-28 21:12:34 -0600258} // namespace oem_ibm
259} // namespace requester
260} // namespace pldm