blob: e136214e63898937e1ba0bc6ed3a5cc7d8556019 [file] [log] [blame]
#include "file_io_type_vpd.hpp"
#include "libpldm/base.h"
#include "libpldm/file_io.h"
#include "common/utils.hpp"
#include <stdint.h>
#include <phosphor-logging/lg2.hpp>
#include <iostream>
PHOSPHOR_LOG2_USING;
typedef uint8_t byte;
namespace pldm
{
namespace responder
{
int keywordHandler::read(uint32_t offset, uint32_t& length, Response& response,
oem_platform::Handler* /*oemPlatformHandler*/)
{
const char* keywrdObjPath =
"/xyz/openbmc_project/inventory/system/chassis/motherboard";
const char* keywrdPropName = "PD_D";
const char* keywrdInterface = "com.ibm.ipzvpd.PSPD";
std::variant<std::vector<byte>> keywrd;
try
{
auto& bus = pldm::utils::DBusHandler::getBus();
auto service = pldm::utils::DBusHandler().getService(keywrdObjPath,
keywrdInterface);
auto method = bus.new_method_call(service.c_str(), keywrdObjPath,
"org.freedesktop.DBus.Properties",
"Get");
method.append(keywrdInterface, keywrdPropName);
auto reply = bus.call(method, dbusTimeout);
reply.read(keywrd);
}
catch (const std::exception& e)
{
error(
"Get keyword error from dbus interface :{KEYWORD_INTF} ERROR={ERR_EXCEP}",
"KEYWORD_INTF", keywrdInterface, "ERR_EXCEP", e.what());
}
uint32_t keywrdSize = std::get<std::vector<byte>>(keywrd).size();
if (length < keywrdSize)
{
error(
"length requested is less the keyword size, length:{LEN} keyword size:{KEYWORD_SIZE}",
"LEN", length, "KEYWORD_SIZE", keywrdSize);
return PLDM_ERROR_INVALID_DATA;
}
namespace fs = std::filesystem;
constexpr auto keywrdDirPath = "/tmp/pldm/";
constexpr auto keywrdFilePath = "/tmp/pldm/vpdKeywrd.bin";
if (!fs::exists(keywrdDirPath))
{
fs::create_directories(keywrdDirPath);
fs::permissions(keywrdDirPath,
fs::perms::others_read | fs::perms::owner_write);
}
std::ofstream keywrdFile(keywrdFilePath);
auto fd = open(keywrdFilePath, std::ios::out | std::ofstream::binary);
if (!keywrdFile)
{
error("VPD keyword file open error: {KEYWORD_FILE_PATH} errno: {ERR}",
"KEYWORD_FILE_PATH", keywrdFilePath, "ERR", errno);
pldm::utils::reportError(
"xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileOpenError");
return PLDM_ERROR;
}
if (offset > keywrdSize)
{
error("Offset exceeds file size, OFFSET={OFFSET} FILE_SIZE={FILE_SIZE}",
"OFFSET", offset, "FILE_SIZE", keywrdSize);
return PLDM_DATA_OUT_OF_RANGE;
}
// length of keyword data should be same as keyword data size in dbus
// object
length = static_cast<uint32_t>(keywrdSize) - offset;
auto returnCode = lseek(fd, offset, SEEK_SET);
if (returnCode == -1)
{
error("Could not find keyword data at given offset. File Seek failed");
return PLDM_ERROR;
}
keywrdFile.write((const char*)std::get<std::vector<byte>>(keywrd).data(),
keywrdSize);
if (keywrdFile.bad())
{
error("Error while writing to file: {KEYWORD_FILE_PATH}",
"KEYWORD_FILE_PATH", keywrdFilePath);
}
keywrdFile.close();
auto rc = readFile(keywrdFilePath, offset, keywrdSize, response);
fs::remove(keywrdFilePath);
if (rc)
{
error("Read error for keyword file with size: {KEYWORD_SIZE}",
"KEYWORD_SIZE", keywrdSize);
pldm::utils::reportError(
"xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileReadError");
return PLDM_ERROR;
}
return PLDM_SUCCESS;
}
} // namespace responder
} // namespace pldm