1 #include "bios_integer_attribute.hpp" 2 3 #include "common/utils.hpp" 4 5 #include <phosphor-logging/lg2.hpp> 6 7 PHOSPHOR_LOG2_USING; 8 9 using namespace pldm::utils; 10 11 namespace pldm 12 { 13 namespace responder 14 { 15 namespace bios 16 { 17 BIOSIntegerAttribute::BIOSIntegerAttribute(const Json& entry, 18 DBusHandler* const dbusHandler) : 19 BIOSAttribute(entry, dbusHandler) 20 { 21 std::string attr = entry.at("attribute_name"); 22 23 integerInfo.lowerBound = entry.at("lower_bound"); 24 integerInfo.upperBound = entry.at("upper_bound"); 25 integerInfo.scalarIncrement = entry.at("scalar_increment"); 26 integerInfo.defaultValue = entry.at("default_value"); 27 pldm_bios_table_attr_entry_integer_info info = { 28 0, 29 readOnly, 30 integerInfo.lowerBound, 31 integerInfo.upperBound, 32 integerInfo.scalarIncrement, 33 integerInfo.defaultValue, 34 }; 35 const char* errmsg = nullptr; 36 auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg); 37 if (rc != PLDM_SUCCESS) 38 { 39 error( 40 "Wrong field for integer attribute, ATTRIBUTE_NAME={ATTR_NAME} ERRMSG= {ERR_MSG} LOWER_BOUND={LOW_BOUND} UPPER_BOUND={UPPER_BOUND} DEFAULT_VALUE={DEF_VAL} SCALAR_INCREMENT={SCALAR_INCREMENT}", 41 "ATTR_NAME", attr.c_str(), "ERR_MSG", errmsg, "LOW_BOUND", 42 integerInfo.lowerBound, "UPPER_BOUND", integerInfo.upperBound, 43 "DEF_VAL", integerInfo.defaultValue, "SCALAR_INCREMENT", 44 integerInfo.scalarIncrement); 45 throw std::invalid_argument("Wrong field for integer attribute"); 46 } 47 } 48 49 void BIOSIntegerAttribute::setAttrValueOnDbus( 50 const pldm_bios_attr_val_table_entry* attrValueEntry, 51 const pldm_bios_attr_table_entry*, const BIOSStringTable&) 52 { 53 if (!dBusMap.has_value()) 54 { 55 return; 56 } 57 auto currentValue = 58 table::attribute_value::decodeIntegerEntry(attrValueEntry); 59 60 if (dBusMap->propertyType == "uint8_t") 61 { 62 return dbusHandler->setDbusProperty(*dBusMap, 63 static_cast<uint8_t>(currentValue)); 64 } 65 else if (dBusMap->propertyType == "uint16_t") 66 { 67 return dbusHandler->setDbusProperty( 68 *dBusMap, static_cast<uint16_t>(currentValue)); 69 } 70 else if (dBusMap->propertyType == "int16_t") 71 { 72 return dbusHandler->setDbusProperty(*dBusMap, 73 static_cast<int16_t>(currentValue)); 74 } 75 else if (dBusMap->propertyType == "uint32_t") 76 { 77 return dbusHandler->setDbusProperty( 78 *dBusMap, static_cast<uint32_t>(currentValue)); 79 } 80 else if (dBusMap->propertyType == "int32_t") 81 { 82 return dbusHandler->setDbusProperty(*dBusMap, 83 static_cast<int32_t>(currentValue)); 84 } 85 else if (dBusMap->propertyType == "uint64_t") 86 { 87 return dbusHandler->setDbusProperty(*dBusMap, currentValue); 88 } 89 else if (dBusMap->propertyType == "int64_t") 90 { 91 return dbusHandler->setDbusProperty(*dBusMap, 92 static_cast<int64_t>(currentValue)); 93 } 94 else if (dBusMap->propertyType == "double") 95 { 96 return dbusHandler->setDbusProperty(*dBusMap, 97 static_cast<double>(currentValue)); 98 } 99 100 error("Unsupported property type on dbus: {DBUS_PROP}", "DBUS_PROP", 101 dBusMap->propertyType); 102 throw std::invalid_argument("dbus type error"); 103 } 104 105 void BIOSIntegerAttribute::constructEntry( 106 const BIOSStringTable& stringTable, Table& attrTable, Table& attrValueTable, 107 std::optional<std::variant<int64_t, std::string>> optAttributeValue) 108 { 109 pldm_bios_table_attr_entry_integer_info info = { 110 stringTable.findHandle(name), readOnly, 111 integerInfo.lowerBound, integerInfo.upperBound, 112 integerInfo.scalarIncrement, integerInfo.defaultValue, 113 }; 114 115 auto attrTableEntry = table::attribute::constructIntegerEntry(attrTable, 116 &info); 117 118 auto [attrHandle, attrType, 119 _] = table::attribute::decodeHeader(attrTableEntry); 120 121 int64_t currentValue{}; 122 if (optAttributeValue.has_value()) 123 { 124 auto attributeValue = optAttributeValue.value(); 125 if (attributeValue.index() == 0) 126 { 127 currentValue = std::get<int64_t>(attributeValue); 128 } 129 else 130 { 131 currentValue = getAttrValue(); 132 } 133 } 134 else 135 { 136 currentValue = getAttrValue(); 137 } 138 139 table::attribute_value::constructIntegerEntry(attrValueTable, attrHandle, 140 attrType, currentValue); 141 } 142 143 uint64_t BIOSIntegerAttribute::getAttrValue(const PropertyValue& propertyValue) 144 { 145 uint64_t value = 0; 146 if (dBusMap->propertyType == "uint8_t") 147 { 148 value = std::get<uint8_t>(propertyValue); 149 } 150 else if (dBusMap->propertyType == "uint16_t") 151 { 152 value = std::get<uint16_t>(propertyValue); 153 } 154 else if (dBusMap->propertyType == "int16_t") 155 { 156 value = std::get<int16_t>(propertyValue); 157 } 158 else if (dBusMap->propertyType == "uint32_t") 159 { 160 value = std::get<uint32_t>(propertyValue); 161 } 162 else if (dBusMap->propertyType == "int32_t") 163 { 164 value = std::get<int32_t>(propertyValue); 165 } 166 else if (dBusMap->propertyType == "uint64_t") 167 { 168 value = std::get<uint64_t>(propertyValue); 169 } 170 else if (dBusMap->propertyType == "int64_t") 171 { 172 value = std::get<int64_t>(propertyValue); 173 } 174 else if (dBusMap->propertyType == "double") 175 { 176 value = std::get<double>(propertyValue); 177 } 178 else 179 { 180 error("Unsupported property type for getAttrValue: {DBUS_PROP}", 181 "DBUS_PROP", dBusMap->propertyType); 182 throw std::invalid_argument("dbus type error"); 183 } 184 return value; 185 } 186 187 uint64_t BIOSIntegerAttribute::getAttrValue() 188 { 189 if (!dBusMap.has_value()) 190 { 191 return integerInfo.defaultValue; 192 } 193 194 try 195 { 196 auto propertyValue = dbusHandler->getDbusPropertyVariant( 197 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(), 198 dBusMap->interface.c_str()); 199 200 return getAttrValue(propertyValue); 201 } 202 catch (const std::exception& e) 203 { 204 error( 205 "Error getting integer attribute '{ATTR}' from '{INTERFACE}': {ERROR}", 206 "ATTR", name, "INTERFACE", dBusMap->interface, "ERROR", e); 207 return integerInfo.defaultValue; 208 } 209 } 210 211 int BIOSIntegerAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl, 212 uint8_t attrType, 213 const PropertyValue& newPropVal) 214 { 215 auto newVal = getAttrValue(newPropVal); 216 table::attribute_value::constructIntegerEntry(newValue, attrHdl, attrType, 217 newVal); 218 return PLDM_SUCCESS; 219 } 220 221 void BIOSIntegerAttribute::generateAttributeEntry( 222 const std::variant<int64_t, std::string>& attributevalue, 223 Table& attrValueEntry) 224 { 225 attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) + 226 sizeof(int64_t) - 1); 227 228 auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>( 229 attrValueEntry.data()); 230 231 int64_t value = std::get<int64_t>(attributevalue); 232 entry->attr_type = 3; 233 memcpy(entry->value, &value, sizeof(int64_t)); 234 } 235 236 } // namespace bios 237 } // namespace responder 238 } // namespace pldm 239