blob: 0614ccc7120668ba644f0badc665152f773d7073 [file] [log] [blame]
Varsha Kaverappa9eee2512022-10-28 02:46:25 -05001#include "file_io_type_vpd.hpp"
2
3#include "libpldm/base.h"
4#include "libpldm/file_io.h"
5
6#include "common/utils.hpp"
7
8#include <stdint.h>
9
10#include <iostream>
11
12typedef uint8_t byte;
13
14namespace pldm
15{
16namespace responder
17{
18int keywordHandler::read(uint32_t offset, uint32_t& length, Response& response,
19 oem_platform::Handler* /*oemPlatformHandler*/)
20{
21 const char* keywrdObjPath =
22 "/xyz/openbmc_project/inventory/system/chassis/motherboard";
23 const char* keywrdPropName = "PD_D";
24 const char* keywrdInterface = "com.ibm.ipzvpd.PSPD";
25
26 std::variant<std::vector<byte>> keywrd;
27
28 try
29 {
30 auto& bus = DBusHandler::getBus();
31 auto service = pldm::utils::DBusHandler().getService(keywrdObjPath,
32 keywrdInterface);
33 auto method =
34 bus.new_method_call(service.c_str(), keywrdObjPath,
35 "org.freedesktop.DBus.Properties", "Get");
36 method.append(keywrdInterface, keywrdPropName);
37 auto reply = bus.call(method);
38 reply.read(keywrd);
39 }
40 catch (const std::exception& e)
41 {
42 std::cerr << "Get keyword error from dbus interface : "
43 << keywrdInterface << " ERROR= " << e.what() << std::endl;
44 }
45
46 auto keywrdSize = std::get<std::vector<byte>>(keywrd).size();
47
48 if (length < keywrdSize)
49 {
50 std::cerr << "length requested is less the keyword size, length: "
51 << length << " keyword size: " << keywrdSize << std::endl;
52 return PLDM_ERROR_INVALID_DATA;
53 }
54
55 namespace fs = std::filesystem;
56 constexpr auto keywrdDirPath = "/tmp/pldm/";
57 constexpr auto keywrdFilePath = "/tmp/pldm/vpdKeywrd.bin";
58
59 if (!fs::exists(keywrdDirPath))
60 {
61 fs::create_directories(keywrdDirPath);
62 fs::permissions(keywrdDirPath,
63 fs::perms::others_read | fs::perms::owner_write);
64 }
65
Varsha Kaverappa397019d2023-04-03 02:59:05 -050066 std::ofstream keywrdFile(keywrdFilePath);
67 auto fd = open(keywrdFilePath, std::ios::out | std::ofstream::binary);
Varsha Kaverappa9eee2512022-10-28 02:46:25 -050068 if (!keywrdFile)
69 {
70 std::cerr << "VPD keyword file open error: " << keywrdFilePath
71 << " errno: " << errno << std::endl;
72 pldm::utils::reportError(
73 "xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileOpenError",
74 pldm::PelSeverity::ERROR);
75 return PLDM_ERROR;
76 }
Varsha Kaverappa397019d2023-04-03 02:59:05 -050077
78 if (offset > keywrdSize)
79 {
80 std::cerr << "Offset exceeds file size, OFFSET=" << offset
81 << " FILE_SIZE=" << keywrdSize << std::endl;
82 return PLDM_DATA_OUT_OF_RANGE;
83 }
84
85 // length of keyword data should be same as keyword data size in dbus object
86 length = static_cast<uint32_t>(keywrdSize) - offset;
87
88 auto returnCode = lseek(fd, offset, SEEK_SET);
89 if (returnCode == -1)
90 {
91 std::cerr
92 << "Could not find keyword data at given offset. File Seek failed"
93 << std::endl;
94 return PLDM_ERROR;
95 }
96
Varsha Kaverappa9eee2512022-10-28 02:46:25 -050097 keywrdFile.write((const char*)std::get<std::vector<byte>>(keywrd).data(),
98 keywrdSize);
99 if (keywrdFile.bad())
100 {
101 std::cerr << "Error while writing to file: " << keywrdFilePath
102 << std::endl;
103 }
104 keywrdFile.close();
105
Varsha Kaverappa9eee2512022-10-28 02:46:25 -0500106 auto rc = readFile(keywrdFilePath, offset, keywrdSize, response);
107 fs::remove(keywrdFilePath);
108 if (rc)
109 {
110 std::cerr << "Read error for keyword file with size: " << keywrdSize
111 << std::endl;
112 pldm::utils::reportError(
113 "xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileReadError",
114 pldm::PelSeverity::ERROR);
115 return PLDM_ERROR;
116 }
117 return PLDM_SUCCESS;
118}
119} // namespace responder
120} // namespace pldm