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