#include "bios_integer_attribute.hpp" #include "common/utils.hpp" #include PHOSPHOR_LOG2_USING; using namespace pldm::utils; namespace pldm { namespace responder { namespace bios { BIOSIntegerAttribute::BIOSIntegerAttribute(const Json& entry, DBusHandler* const dbusHandler) : BIOSAttribute(entry, dbusHandler) { std::string attr = entry.at("attribute_name"); integerInfo.lowerBound = entry.at("lower_bound"); integerInfo.upperBound = entry.at("upper_bound"); integerInfo.scalarIncrement = entry.at("scalar_increment"); integerInfo.defaultValue = entry.at("default_value"); pldm_bios_table_attr_entry_integer_info info = { 0, readOnly, integerInfo.lowerBound, integerInfo.upperBound, integerInfo.scalarIncrement, integerInfo.defaultValue, }; const char* errmsg = nullptr; auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg); if (rc != PLDM_SUCCESS) { error( "Wrong field for integer attribute '{ATTRIBUTE}', error '{ERROR}', lower bound '{LOW_BOUND}', upper bound '{UPPER_BOUND}', default value '{DEFAULT_VALUE}' and scalar increment '{SCALAR_INCREMENT}'", "ATTRIBUTE", attr, "ERROR", errmsg, "LOW_BOUND", integerInfo.lowerBound, "UPPER_BOUND", integerInfo.upperBound, "DEFAULT_VALUE", integerInfo.defaultValue, "SCALAR_INCREMENT", integerInfo.scalarIncrement); throw std::invalid_argument("Wrong field for integer attribute"); } } void BIOSIntegerAttribute::setAttrValueOnDbus( const pldm_bios_attr_val_table_entry* attrValueEntry, const pldm_bios_attr_table_entry*, const BIOSStringTable&) { if (!dBusMap.has_value()) { return; } auto currentValue = table::attribute_value::decodeIntegerEntry(attrValueEntry); if (dBusMap->propertyType == "uint8_t") { return dbusHandler->setDbusProperty(*dBusMap, static_cast(currentValue)); } else if (dBusMap->propertyType == "uint16_t") { return dbusHandler->setDbusProperty( *dBusMap, static_cast(currentValue)); } else if (dBusMap->propertyType == "int16_t") { return dbusHandler->setDbusProperty(*dBusMap, static_cast(currentValue)); } else if (dBusMap->propertyType == "uint32_t") { return dbusHandler->setDbusProperty( *dBusMap, static_cast(currentValue)); } else if (dBusMap->propertyType == "int32_t") { return dbusHandler->setDbusProperty(*dBusMap, static_cast(currentValue)); } else if (dBusMap->propertyType == "uint64_t") { return dbusHandler->setDbusProperty(*dBusMap, currentValue); } else if (dBusMap->propertyType == "int64_t") { return dbusHandler->setDbusProperty(*dBusMap, static_cast(currentValue)); } else if (dBusMap->propertyType == "double") { return dbusHandler->setDbusProperty(*dBusMap, static_cast(currentValue)); } error("Unsupported property type '{TYPE}' on dbus", "TYPE", dBusMap->propertyType); throw std::invalid_argument("dbus type error"); } void BIOSIntegerAttribute::constructEntry( const BIOSStringTable& stringTable, Table& attrTable, Table& attrValueTable, std::optional> optAttributeValue) { pldm_bios_table_attr_entry_integer_info info = { stringTable.findHandle(name), readOnly, integerInfo.lowerBound, integerInfo.upperBound, integerInfo.scalarIncrement, integerInfo.defaultValue, }; auto attrTableEntry = table::attribute::constructIntegerEntry(attrTable, &info); auto [attrHandle, attrType, _] = table::attribute::decodeHeader(attrTableEntry); int64_t currentValue{}; if (optAttributeValue.has_value()) { auto attributeValue = optAttributeValue.value(); if (attributeValue.index() == 0) { currentValue = std::get(attributeValue); } else { currentValue = getAttrValue(); } } else { currentValue = getAttrValue(); } table::attribute_value::constructIntegerEntry(attrValueTable, attrHandle, attrType, currentValue); } uint64_t BIOSIntegerAttribute::getAttrValue(const PropertyValue& propertyValue) { uint64_t value = 0; if (dBusMap->propertyType == "uint8_t") { value = std::get(propertyValue); } else if (dBusMap->propertyType == "uint16_t") { value = std::get(propertyValue); } else if (dBusMap->propertyType == "int16_t") { value = std::get(propertyValue); } else if (dBusMap->propertyType == "uint32_t") { value = std::get(propertyValue); } else if (dBusMap->propertyType == "int32_t") { value = std::get(propertyValue); } else if (dBusMap->propertyType == "uint64_t") { value = std::get(propertyValue); } else if (dBusMap->propertyType == "int64_t") { value = std::get(propertyValue); } else if (dBusMap->propertyType == "double") { value = std::get(propertyValue); } else { error("Unsupported property type '{TYPE}' for getAttrValue", "TYPE", dBusMap->propertyType); throw std::invalid_argument("dbus type error"); } return value; } uint64_t BIOSIntegerAttribute::getAttrValue() { if (!dBusMap.has_value()) { return integerInfo.defaultValue; } try { auto propertyValue = dbusHandler->getDbusPropertyVariant( dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(), dBusMap->interface.c_str()); return getAttrValue(propertyValue); } catch (const std::exception& e) { error( "Error getting integer attribute '{ATTRIBUTE}' at path '{PATH}' and interface '{INTERFACE}' for property '{PROPERTY}', error - {ERROR}", "ATTRIBUTE", name, "PATH", dBusMap->objectPath, "INTERFACE", dBusMap->interface, "PROPERTY", dBusMap->propertyName, "ERROR", e); return integerInfo.defaultValue; } } int BIOSIntegerAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl, uint8_t attrType, const PropertyValue& newPropVal) { auto newVal = getAttrValue(newPropVal); table::attribute_value::constructIntegerEntry(newValue, attrHdl, attrType, newVal); return PLDM_SUCCESS; } void BIOSIntegerAttribute::generateAttributeEntry( const std::variant& attributevalue, Table& attrValueEntry) { attrValueEntry.resize( sizeof(pldm_bios_attr_val_table_entry) + sizeof(int64_t) - 1); auto entry = reinterpret_cast( attrValueEntry.data()); int64_t value = std::get(attributevalue); entry->attr_type = 3; memcpy(entry->value, &value, sizeof(int64_t)); } } // namespace bios } // namespace responder } // namespace pldm