blob: b28b7c61dc807d0fa9bbc44c81a37db27e2af892 [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "config.h"
2
3#include "file_io_type_pel.hpp"
4
George Liu83409572019-12-24 18:42:54 +08005#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05006#include "xyz/openbmc_project/Common/error.hpp"
7
8#include <stdint.h>
9#include <systemd/sd-bus.h>
10#include <unistd.h>
11
12#include <exception>
13#include <filesystem>
Sampa Misraaa8ae722019-12-12 03:20:40 -060014#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050015#include <sdbusplus/server.hpp>
16#include <vector>
17#include <xyz/openbmc_project/Logging/Entry/server.hpp>
18
19#include "libpldm/base.h"
20#include "oem/ibm/libpldm/file_io.h"
21
22namespace pldm
23{
24namespace responder
25{
26
Deepak Kodihalli15211b42019-12-14 02:24:49 -060027int PelHandler::readIntoMemory(uint32_t offset, uint32_t& length,
28 uint64_t address)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060029{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060030 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
31 static constexpr auto logInterface = "org.open_power.Logging.PEL";
32
George Liu0e02c322020-01-01 09:41:51 +080033 auto& bus = pldm::utils::DBusHandler::getBus();
Deepak Kodihalli15211b42019-12-14 02:24:49 -060034
35 try
36 {
George Liu0e02c322020-01-01 09:41:51 +080037 auto service =
38 pldm::utils::DBusHandler().getService(logObjPath, logInterface);
Deepak Kodihalli15211b42019-12-14 02:24:49 -060039 auto method = bus.new_method_call(service.c_str(), logObjPath,
40 logInterface, "GetPEL");
41 method.append(fileHandle);
42 auto reply = bus.call(method);
43 sdbusplus::message::unix_fd fd{};
44 reply.read(fd);
45 auto rc = transferFileData(fd, true, offset, length, address);
46 return rc;
47 }
48 catch (const std::exception& e)
49 {
50 std::cerr << "GetPEL D-Bus call failed, PEL id = " << fileHandle
51 << ", error = " << e.what() << "\n";
52 return PLDM_ERROR;
53 }
54
55 return PLDM_SUCCESS;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060056}
57
Deepak Kodihalli15211b42019-12-14 02:24:49 -060058int PelHandler::read(uint32_t offset, uint32_t& length, Response& response)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060059{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060060 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
61 static constexpr auto logInterface = "org.open_power.Logging.PEL";
George Liu0e02c322020-01-01 09:41:51 +080062 auto& bus = pldm::utils::DBusHandler::getBus();
Deepak Kodihalli15211b42019-12-14 02:24:49 -060063
64 try
65 {
George Liu0e02c322020-01-01 09:41:51 +080066 auto service =
67 pldm::utils::DBusHandler().getService(logObjPath, logInterface);
Deepak Kodihalli15211b42019-12-14 02:24:49 -060068 auto method = bus.new_method_call(service.c_str(), logObjPath,
69 logInterface, "GetPEL");
70 method.append(fileHandle);
71 auto reply = bus.call(method);
72 sdbusplus::message::unix_fd fd{};
73 reply.read(fd);
Pavithraba0738b2020-01-29 08:47:51 -060074
Deepak Kodihalli15211b42019-12-14 02:24:49 -060075 off_t fileSize = lseek(fd, 0, SEEK_END);
76 if (fileSize == -1)
77 {
78 std::cerr << "file seek failed";
79 return PLDM_ERROR;
80 }
81 if (offset >= fileSize)
82 {
83 std::cerr << "Offset exceeds file size, OFFSET=" << offset
84 << " FILE_SIZE=" << fileSize << std::endl;
85 return PLDM_DATA_OUT_OF_RANGE;
86 }
87 if (offset + length > fileSize)
88 {
89 length = fileSize - offset;
90 }
91 auto rc = lseek(fd, offset, SEEK_SET);
92 if (rc == -1)
93 {
94 std::cerr << "file seek failed";
95 return PLDM_ERROR;
96 }
97 size_t currSize = response.size();
98 response.resize(currSize + length);
99 auto filePos = reinterpret_cast<char*>(response.data());
100 filePos += currSize;
101 rc = ::read(fd, filePos, length);
102 if (rc == -1)
103 {
104 std::cerr << "file read failed";
105 return PLDM_ERROR;
106 }
107 if (rc != length)
108 {
109 std::cerr << "mismatch between number of characters to read and "
110 << "the length read, LENGTH=" << length << " COUNT=" << rc
111 << std::endl;
112 return PLDM_ERROR;
113 }
114 }
115 catch (const std::exception& e)
116 {
117 std::cerr << "GetPEL D-Bus call failed";
118 return PLDM_ERROR;
119 }
120 return PLDM_SUCCESS;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600121}
122
Sampa Misra854e61f2019-08-22 04:36:47 -0500123int PelHandler::writeFromMemory(uint32_t offset, uint32_t length,
124 uint64_t address)
125{
Sampa Misraf5087a42019-12-03 04:51:36 -0600126 char tmpFile[] = "/tmp/pel.XXXXXX";
127 int fd = mkstemp(tmpFile);
128 if (fd == -1)
129 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600130 std::cerr << "failed to create a temporary pel, ERROR=" << errno
131 << "\n";
Sampa Misraf5087a42019-12-03 04:51:36 -0600132 return PLDM_ERROR;
133 }
134 close(fd);
135 fs::path path(tmpFile);
Sampa Misra854e61f2019-08-22 04:36:47 -0500136
137 auto rc = transferFileData(path, false, offset, length, address);
138 if (rc == PLDM_SUCCESS)
139 {
140 rc = storePel(path.string());
141 }
142 fs::remove(path);
143 return rc;
144}
145
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600146int PelHandler::fileAck(uint8_t /*fileStatus*/)
147{
148 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
149 static constexpr auto logInterface = "org.open_power.Logging.PEL";
George Liu0e02c322020-01-01 09:41:51 +0800150 auto& bus = pldm::utils::DBusHandler::getBus();
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600151
152 try
153 {
George Liu0e02c322020-01-01 09:41:51 +0800154 auto service =
155 pldm::utils::DBusHandler().getService(logObjPath, logInterface);
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600156 auto method = bus.new_method_call(service.c_str(), logObjPath,
157 logInterface, "HostAck");
158 method.append(fileHandle);
159 bus.call_noreply(method);
160 }
161 catch (const std::exception& e)
162 {
163 std::cerr << "HostAck D-Bus call failed";
164 return PLDM_ERROR;
165 }
166
167 return PLDM_SUCCESS;
168}
169
Sampa Misra854e61f2019-08-22 04:36:47 -0500170int PelHandler::storePel(std::string&& pelFileName)
171{
172 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
173 static constexpr auto logInterface = "xyz.openbmc_project.Logging.Create";
174
George Liu0e02c322020-01-01 09:41:51 +0800175 auto& bus = pldm::utils::DBusHandler::getBus();
Sampa Misra854e61f2019-08-22 04:36:47 -0500176
177 try
178 {
George Liu0e02c322020-01-01 09:41:51 +0800179 auto service =
180 pldm::utils::DBusHandler().getService(logObjPath, logInterface);
Sampa Misra854e61f2019-08-22 04:36:47 -0500181 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
182 std::map<std::string, std::string> addlData{};
183 addlData.emplace("RAWPEL", std::move(pelFileName));
184 auto severity =
185 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
186 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
187 Error);
188
189 auto method = bus.new_method_call(service.c_str(), logObjPath,
190 logInterface, "Create");
191 method.append("xyz.openbmc_project.Host.Error.Event", severity,
192 addlData);
193 bus.call_noreply(method);
194 }
195 catch (const std::exception& e)
196 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600197 std::cerr << "failed to make a d-bus call to PEL daemon, ERROR="
198 << e.what() << "\n";
Sampa Misra854e61f2019-08-22 04:36:47 -0500199 return PLDM_ERROR;
200 }
201
202 return PLDM_SUCCESS;
203}
204
205} // namespace responder
206} // namespace pldm