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