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