blob: 783683e043e113b74da1dc2fc4acbd0f65bf4e74 [file] [log] [blame]
Varsha Kaverappae1874e82023-05-02 09:53:24 -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 = pldm::utils::DBusHandler::getBus();
31 auto service = pldm::utils::DBusHandler().getService(keywrdObjPath,
32 keywrdInterface);
33 auto method = bus.new_method_call(service.c_str(), keywrdObjPath,
34 "org.freedesktop.DBus.Properties",
35 "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 uint32_t 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
66 std::ofstream keywrdFile(keywrdFilePath);
67 auto fd = open(keywrdFilePath, std::ios::out | std::ofstream::binary);
68 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 return PLDM_ERROR;
75 }
76
77 if (offset > keywrdSize)
78 {
79 std::cerr << "Offset exceeds file size, OFFSET=" << offset
80 << " FILE_SIZE=" << keywrdSize << std::endl;
81 return PLDM_DATA_OUT_OF_RANGE;
82 }
83
84 // length of keyword data should be same as keyword data size in dbus object
85 length = static_cast<uint32_t>(keywrdSize) - offset;
86
87 auto returnCode = lseek(fd, offset, SEEK_SET);
88 if (returnCode == -1)
89 {
90 std::cerr
91 << "Could not find keyword data at given offset. File Seek failed"
92 << std::endl;
93 return PLDM_ERROR;
94 }
95
96 keywrdFile.write((const char*)std::get<std::vector<byte>>(keywrd).data(),
97 keywrdSize);
98 if (keywrdFile.bad())
99 {
100 std::cerr << "Error while writing to file: " << keywrdFilePath
101 << std::endl;
102 }
103 keywrdFile.close();
104
105 auto rc = readFile(keywrdFilePath, offset, keywrdSize, response);
106 fs::remove(keywrdFilePath);
107 if (rc)
108 {
109 std::cerr << "Read error for keyword file with size: " << keywrdSize
110 << std::endl;
111 pldm::utils::reportError(
112 "xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileReadError");
113 return PLDM_ERROR;
114 }
115 return PLDM_SUCCESS;
116}
117} // namespace responder
118} // namespace pldm