1 #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 12 typedef uint8_t byte; 13 14 namespace pldm 15 { 16 namespace responder 17 { 18 int 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 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 pldm::PelSeverity::ERROR); 75 return PLDM_ERROR; 76 } 77 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 97 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 106 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 121