blob: 06ced26e4b3573ee8efce4aae090e7439f8c2c17 [file] [log] [blame]
Sampa Misra854e61f2019-08-22 04:36:47 -05001#include "config.h"
2
3#include "file_io_type_pel.hpp"
4
5#include "libpldmresponder/utils.hpp"
6#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
33 static sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
34
35 try
36 {
37 auto service = getService(bus, logObjPath, logInterface);
38 auto method = bus.new_method_call(service.c_str(), logObjPath,
39 logInterface, "GetPEL");
40 method.append(fileHandle);
41 auto reply = bus.call(method);
42 sdbusplus::message::unix_fd fd{};
43 reply.read(fd);
44 auto rc = transferFileData(fd, true, offset, length, address);
45 return rc;
46 }
47 catch (const std::exception& e)
48 {
49 std::cerr << "GetPEL D-Bus call failed, PEL id = " << fileHandle
50 << ", error = " << e.what() << "\n";
51 return PLDM_ERROR;
52 }
53
54 return PLDM_SUCCESS;
Deepak Kodihallif6d3a832019-11-19 07:00:29 -060055}
56
Deepak Kodihalli15211b42019-12-14 02:24:49 -060057int PelHandler::read(uint32_t offset, uint32_t& length, Response& response)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -060058{
Deepak Kodihalli15211b42019-12-14 02:24:49 -060059 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
60 static constexpr auto logInterface = "org.open_power.Logging.PEL";
61 static sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
62
63 try
64 {
65 auto service = getService(bus, logObjPath, logInterface);
66 auto method = bus.new_method_call(service.c_str(), logObjPath,
67 logInterface, "GetPEL");
68 method.append(fileHandle);
69 auto reply = bus.call(method);
70 sdbusplus::message::unix_fd fd{};
71 reply.read(fd);
72 std::cerr << "GetPEL D-Bus call done\n";
73 off_t fileSize = lseek(fd, 0, SEEK_END);
74 if (fileSize == -1)
75 {
76 std::cerr << "file seek failed";
77 return PLDM_ERROR;
78 }
79 if (offset >= fileSize)
80 {
81 std::cerr << "Offset exceeds file size, OFFSET=" << offset
82 << " FILE_SIZE=" << fileSize << std::endl;
83 return PLDM_DATA_OUT_OF_RANGE;
84 }
85 if (offset + length > fileSize)
86 {
87 length = fileSize - offset;
88 }
89 auto rc = lseek(fd, offset, SEEK_SET);
90 if (rc == -1)
91 {
92 std::cerr << "file seek failed";
93 return PLDM_ERROR;
94 }
95 size_t currSize = response.size();
96 response.resize(currSize + length);
97 auto filePos = reinterpret_cast<char*>(response.data());
98 filePos += currSize;
99 rc = ::read(fd, filePos, length);
100 if (rc == -1)
101 {
102 std::cerr << "file read failed";
103 return PLDM_ERROR;
104 }
105 if (rc != length)
106 {
107 std::cerr << "mismatch between number of characters to read and "
108 << "the length read, LENGTH=" << length << " COUNT=" << rc
109 << std::endl;
110 return PLDM_ERROR;
111 }
112 }
113 catch (const std::exception& e)
114 {
115 std::cerr << "GetPEL D-Bus call failed";
116 return PLDM_ERROR;
117 }
118 return PLDM_SUCCESS;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600119}
120
Sampa Misra854e61f2019-08-22 04:36:47 -0500121int PelHandler::writeFromMemory(uint32_t offset, uint32_t length,
122 uint64_t address)
123{
Sampa Misraf5087a42019-12-03 04:51:36 -0600124 char tmpFile[] = "/tmp/pel.XXXXXX";
125 int fd = mkstemp(tmpFile);
126 if (fd == -1)
127 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600128 std::cerr << "failed to create a temporary pel, ERROR=" << errno
129 << "\n";
Sampa Misraf5087a42019-12-03 04:51:36 -0600130 return PLDM_ERROR;
131 }
132 close(fd);
133 fs::path path(tmpFile);
Sampa Misra854e61f2019-08-22 04:36:47 -0500134
135 auto rc = transferFileData(path, false, offset, length, address);
136 if (rc == PLDM_SUCCESS)
137 {
138 rc = storePel(path.string());
139 }
140 fs::remove(path);
141 return rc;
142}
143
144int PelHandler::storePel(std::string&& pelFileName)
145{
146 static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
147 static constexpr auto logInterface = "xyz.openbmc_project.Logging.Create";
148
149 static sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
150
151 try
152 {
153 auto service = getService(bus, logObjPath, logInterface);
154 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
155 std::map<std::string, std::string> addlData{};
156 addlData.emplace("RAWPEL", std::move(pelFileName));
157 auto severity =
158 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
159 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
160 Error);
161
162 auto method = bus.new_method_call(service.c_str(), logObjPath,
163 logInterface, "Create");
164 method.append("xyz.openbmc_project.Host.Error.Event", severity,
165 addlData);
166 bus.call_noreply(method);
167 }
168 catch (const std::exception& e)
169 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600170 std::cerr << "failed to make a d-bus call to PEL daemon, ERROR="
171 << e.what() << "\n";
Sampa Misra854e61f2019-08-22 04:36:47 -0500172 return PLDM_ERROR;
173 }
174
175 return PLDM_SUCCESS;
176}
177
178} // namespace responder
179} // namespace pldm