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