#include "bios_config.hpp" #include "bios_integer_attribute.hpp" #include "bios_string_attribute.hpp" #include #include namespace pldm { namespace responder { namespace bios { namespace { constexpr auto enumJsonFile = "enum_attrs.json"; constexpr auto stringJsonFile = "string_attrs.json"; constexpr auto integerJsonFile = "integer_attrs.json"; constexpr auto stringTableFile = "stringTable"; constexpr auto attrTableFile = "attributeTable"; constexpr auto attrValueTableFile = "attributeValueTable"; } // namespace BIOSConfig::BIOSConfig(const char* jsonDir, const char* tableDir, DBusHandler* const dbusHandler) : jsonDir(jsonDir), tableDir(tableDir), dbusHandler(dbusHandler) { constructAttributes(); } void BIOSConfig::buildTables() { fs::create_directory(tableDir); auto stringTable = buildAndStoreStringTable(); if (stringTable) { buildAndStoreAttrTables(*stringTable); } } std::optional BIOSConfig::getBIOSTable(pldm_bios_table_types tableType) { fs::path tablePath; switch (tableType) { case PLDM_BIOS_STRING_TABLE: tablePath = tableDir / stringTableFile; break; case PLDM_BIOS_ATTR_TABLE: tablePath = tableDir / attrTableFile; break; case PLDM_BIOS_ATTR_VAL_TABLE: tablePath = tableDir / attrValueTableFile; break; } return loadTable(tablePath); } void BIOSConfig::constructAttributes() { load(jsonDir / stringJsonFile, [this](const Json& entry) { constructAttribute(entry); }); load(jsonDir / stringJsonFile, [this](const Json& entry) { constructAttribute(entry); }); } void BIOSConfig::buildAndStoreAttrTables(const Table& stringTable) { BIOSStringTable biosStringTable(stringTable); if (biosAttributes.empty()) { return; } Table attrTable, attrValueTable; for (auto& attr : biosAttributes) { try { attr->constructEntry(biosStringTable, attrTable, attrValueTable); } catch (const std::exception& e) { std::cerr << "Construct Table Entry Error, AttributeName = " << attr->name << std::endl; } } table::appendPadAndChecksum(attrTable); table::appendPadAndChecksum(attrValueTable); storeTable(tableDir / attrTableFile, attrTable); storeTable(tableDir / attrValueTableFile, attrValueTable); } std::optional
BIOSConfig::buildAndStoreStringTable() { std::set strings; auto handler = [&strings](const Json& entry) { strings.emplace(entry.at("attribute_name")); }; load(jsonDir / stringJsonFile, handler); load(jsonDir / integerJsonFile, handler); load(jsonDir / enumJsonFile, [&strings](const Json& entry) { strings.emplace(entry.at("attribute_name")); auto possibleValues = entry.at("possible_values"); for (auto& pv : possibleValues) { strings.emplace(pv); } }); if (strings.empty()) { return std::nullopt; } Table table; for (const auto& elem : strings) { table::string::constructEntry(table, elem); } table::appendPadAndChecksum(table); storeTable(tableDir / stringTableFile, table); return table; } void BIOSConfig::storeTable(const fs::path& path, const Table& table) { BIOSTable biosTable(path.c_str()); biosTable.store(table); } std::optional
BIOSConfig::loadTable(const fs::path& path) { BIOSTable biosTable(path.c_str()); if (biosTable.isEmpty()) { return std::nullopt; } Table table; biosTable.load(table); return table; } void BIOSConfig::load(const fs::path& filePath, ParseHandler handler) { std::ifstream file; Json jsonConf; if (fs::exists(filePath)) { try { file.open(filePath); jsonConf = Json::parse(file); auto entries = jsonConf.at("entries"); for (auto& entry : entries) { try { handler(entry); } catch (const std::exception& e) { std::cerr << "Failed to parse JSON config file(entry handler) : " << filePath.c_str() << ", " << e.what() << std::endl; } } } catch (const std::exception& e) { std::cerr << "Failed to parse JSON config file : " << filePath.c_str() << std::endl; } } } int BIOSConfig::setAttrValue(const void* entry, size_t size) { auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE); auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE); auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE); if (!attrValueTable || !attrTable || !stringTable) { return PLDM_BIOS_TABLE_UNAVAILABLE; } auto destTable = table::attribute_value::updateTable(*attrValueTable, entry, size); if (!destTable) { return PLDM_ERROR; } auto attrValueEntry = reinterpret_cast(entry); auto attrValHeader = table::attribute_value::decodeHeader(attrValueEntry); auto attrEntry = table::attribute::findByHandle(*attrTable, attrValHeader.attrHandle); if (!attrEntry) { return PLDM_ERROR; } try { auto attrHeader = table::attribute::decodeHeader(attrEntry); BIOSStringTable biosStringTable(*stringTable); auto attrName = biosStringTable.findString(attrHeader.stringHandle); auto iter = std::find_if( biosAttributes.begin(), biosAttributes.end(), [&attrName](const auto& attr) { return attr->name == attrName; }); if (iter == biosAttributes.end()) { return PLDM_ERROR; } (*iter)->setAttrValueOnDbus(attrValueEntry, attrEntry, biosStringTable); } catch (const std::exception& e) { std::cerr << "Set attribute value error: " << e.what() << std::endl; return PLDM_ERROR; } BIOSTable biosAttrValueTable((tableDir / attrValueTableFile).c_str()); biosAttrValueTable.store(*destTable); return PLDM_SUCCESS; } void BIOSConfig::removeTables() { try { fs::remove(tableDir / stringTableFile); fs::remove(tableDir / attrTableFile); fs::remove(tableDir / attrValueTableFile); } catch (const std::exception& e) { std::cerr << "Remove the tables error: " << e.what() << std::endl; } } } // namespace bios } // namespace responder } // namespace pldm