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