blob: 4091ac6e0fad3a292e88cf34599b7c536dfe336a [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{
Jayashankar Padathdb124362021-01-28 21:12:34 -060014using namespace pldm::utils;
15using namespace sdbusplus::bus::match::rules;
16
17static constexpr auto resDumpObjPath =
18 "/xyz/openbmc_project/dump/resource/entry";
19static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
20static constexpr auto resDumpProgressIntf =
21 "xyz.openbmc_project.Common.Progress";
22static constexpr auto resDumpStatus =
23 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed";
24
25DbusToFileHandler::DbusToFileHandler(
26 int mctp_fd, uint8_t mctp_eid, dbus_api::Requester* requester,
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),
30 mctp_eid(mctp_eid), requester(requester),
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{
36 if (requester == NULL)
37 {
38 std::cerr << "Failed to send resource dump parameters as requester is "
39 "not set";
40 pldm::utils::reportError(
41 "xyz.openbmc_project.bmc.pldm.InternalFailure");
42 return;
43 }
44 auto instanceId = requester->getInstanceId(mctp_eid);
45 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
46 PLDM_NEW_FILE_REQ_BYTES + fileSize);
47 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
51 auto rc =
52 encode_new_file_req(instanceId, PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
53 fileHandle, fileSize, request);
54 if (rc != PLDM_SUCCESS)
55 {
56 requester->markFree(mctp_eid, instanceId);
57 std::cerr << "Failed to encode_new_file_req, rc = " << rc << std::endl;
58 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 {
66 std::cerr
67 << "Failed to receive response for NewFileAvailable command \n";
68 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 {
Sampa Misrac0c79482021-06-02 08:01:54 -050074 std::cerr << "Failed to decode_new_file_resp or"
75 << " Host returned error for new_file_available"
76 << " rc=" << rc
Jayashankar Padathdb124362021-01-28 21:12:34 -060077 << ", cc=" << static_cast<unsigned>(completionCode)
Sampa Misrac0c79482021-06-02 08:01:54 -050078 << "\n";
79 reportResourceDumpFailure();
Jayashankar Padathdb124362021-01-28 21:12:34 -060080 }
Sampa Misrac0c79482021-06-02 08:01:54 -050081 };
82 rc = handler->registerRequest(
83 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
84 std::move(requestMsg), std::move(newFileAvailableRespHandler));
85 if (rc)
Jayashankar Padathdb124362021-01-28 21:12:34 -060086 {
Sampa Misrac0c79482021-06-02 08:01:54 -050087 std::cerr << "Failed to send NewFileAvailable Request to Host \n";
88 reportResourceDumpFailure();
89 }
90}
Jayashankar Padathdb124362021-01-28 21:12:34 -060091
Sampa Misrac0c79482021-06-02 08:01:54 -050092void DbusToFileHandler::reportResourceDumpFailure()
93{
Sampa Misrac0c79482021-06-02 08:01:54 -050094 pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
95
96 PropertyValue value{resDumpStatus};
97 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
98 "Status", "string"};
99 try
100 {
101 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
102 }
103 catch (const std::exception& e)
104 {
105 std::cerr << "failed to set resource dump operation status, "
106 "ERROR="
107 << e.what() << "\n";
Jayashankar Padathdb124362021-01-28 21:12:34 -0600108 }
109}
110
111void DbusToFileHandler::processNewResourceDump(
112 const std::string& vspString, const std::string& resDumpReqPass)
113{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600114 namespace fs = std::filesystem;
115 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
116
117 if (!fs::exists(resDumpDirPath))
118 {
119 fs::create_directories(resDumpDirPath);
120 }
121
122 // Need to reconsider this logic to set the value as "1" when we have the
123 // support to handle multiple resource dumps
124 fs::path resDumpFilePath = resDumpDirPath / "1";
125
126 std::ofstream fileHandle;
127 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
128
129 if (!fileHandle)
130 {
131 std::cerr << "resource dump file open error: " << resDumpFilePath
132 << "\n";
133 PropertyValue value{resDumpStatus};
134 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
135 "Status", "string"};
136 try
137 {
138 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
139 }
140 catch (const std::exception& e)
141 {
142 std::cerr << "failed to set resource dump operation status, "
143 "ERROR="
144 << e.what() << "\n";
145 }
146 return;
147 }
148
149 // Fill up the file with resource dump parameters and respective sizes
150 auto fileFunc = [&fileHandle](auto& paramBuf) {
151 uint32_t paramSize = paramBuf.size();
152 fileHandle.write((char*)&paramSize, sizeof(paramSize));
153 fileHandle << paramBuf;
154 };
155 fileFunc(vspString);
156 fileFunc(resDumpReqPass);
157
Pavithra Barithayac047f802021-11-30 01:55:03 -0600158 std::string str;
159 if (!resDumpReqPass.empty())
160 {
161 str = getAcfFileContent();
162 }
163
164 fileFunc(str);
165
Jayashankar Padathdb124362021-01-28 21:12:34 -0600166 fileHandle.close();
167 size_t fileSize = fs::file_size(resDumpFilePath);
168
169 sendNewFileAvailableCmd(fileSize);
170}
171
Pavithra Barithayac047f802021-11-30 01:55:03 -0600172std::string DbusToFileHandler::getAcfFileContent()
173{
174 std::string str;
175 static constexpr auto acfDirPath = "/etc/acf/service.acf";
176 if (fs::exists(acfDirPath))
177 {
178 std::ifstream file;
179 file.open(acfDirPath);
180 std::stringstream acfBuf;
181 acfBuf << file.rdbuf();
182 str = acfBuf.str();
183 file.close();
184 }
185 return str;
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