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