195e6b3c1SJohn Wang #include "bios_integer_attribute.hpp"
295e6b3c1SJohn Wang 
3d130e1a3SDeepak Kodihalli #include "common/utils.hpp"
495e6b3c1SJohn Wang 
595e6b3c1SJohn Wang namespace pldm
695e6b3c1SJohn Wang {
795e6b3c1SJohn Wang namespace responder
895e6b3c1SJohn Wang {
995e6b3c1SJohn Wang namespace bios
1095e6b3c1SJohn Wang {
1195e6b3c1SJohn Wang 
1295e6b3c1SJohn Wang BIOSIntegerAttribute::BIOSIntegerAttribute(const Json& entry,
1395e6b3c1SJohn Wang                                            DBusHandler* const dbusHandler) :
1495e6b3c1SJohn Wang     BIOSAttribute(entry, dbusHandler)
1595e6b3c1SJohn Wang {
1695e6b3c1SJohn Wang     std::string attr = entry.at("attribute_name");
1795e6b3c1SJohn Wang 
1895e6b3c1SJohn Wang     integerInfo.lowerBound = entry.at("lower_bound");
1995e6b3c1SJohn Wang     integerInfo.upperBound = entry.at("upper_bound");
2095e6b3c1SJohn Wang     integerInfo.scalarIncrement = entry.at("scalar_increment");
2195e6b3c1SJohn Wang     integerInfo.defaultValue = entry.at("default_value");
2295e6b3c1SJohn Wang     pldm_bios_table_attr_entry_integer_info info = {
2395e6b3c1SJohn Wang         0,
2495e6b3c1SJohn Wang         readOnly,
2595e6b3c1SJohn Wang         integerInfo.lowerBound,
2695e6b3c1SJohn Wang         integerInfo.upperBound,
2795e6b3c1SJohn Wang         integerInfo.scalarIncrement,
2895e6b3c1SJohn Wang         integerInfo.defaultValue,
2995e6b3c1SJohn Wang     };
3095e6b3c1SJohn Wang     const char* errmsg = nullptr;
3195e6b3c1SJohn Wang     auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
3295e6b3c1SJohn Wang     if (rc != PLDM_SUCCESS)
3395e6b3c1SJohn Wang     {
3495e6b3c1SJohn Wang         std::cerr << "Wrong filed for integer attribute, ATTRIBUTE_NAME="
3595e6b3c1SJohn Wang                   << attr.c_str() << " ERRMSG=" << errmsg
3695e6b3c1SJohn Wang                   << " LOWER_BOUND=" << integerInfo.lowerBound
3795e6b3c1SJohn Wang                   << " UPPER_BOUND=" << integerInfo.upperBound
3895e6b3c1SJohn Wang                   << " DEFAULT_VALUE=" << integerInfo.defaultValue
3995e6b3c1SJohn Wang                   << " SCALAR_INCREMENT=" << integerInfo.scalarIncrement
4095e6b3c1SJohn Wang                   << "\n";
4195e6b3c1SJohn Wang         throw std::invalid_argument("Wrong field for integer attribute");
4295e6b3c1SJohn Wang     }
4395e6b3c1SJohn Wang }
4495e6b3c1SJohn Wang 
4595e6b3c1SJohn Wang void BIOSIntegerAttribute::setAttrValueOnDbus(
4695e6b3c1SJohn Wang     const pldm_bios_attr_val_table_entry* attrValueEntry,
4795e6b3c1SJohn Wang     const pldm_bios_attr_table_entry*, const BIOSStringTable&)
4895e6b3c1SJohn Wang {
49daa6923cSGeorge Liu     if (readOnly || !dBusMap.has_value())
5095e6b3c1SJohn Wang     {
5195e6b3c1SJohn Wang         return;
5295e6b3c1SJohn Wang     }
5395e6b3c1SJohn Wang     auto currentValue =
5495e6b3c1SJohn Wang         table::attribute_value::decodeIntegerEntry(attrValueEntry);
5595e6b3c1SJohn Wang 
5695e6b3c1SJohn Wang     if (dBusMap->propertyType == "uint8_t")
5795e6b3c1SJohn Wang     {
5895e6b3c1SJohn Wang         return dbusHandler->setDbusProperty(*dBusMap,
5995e6b3c1SJohn Wang                                             static_cast<uint8_t>(currentValue));
6095e6b3c1SJohn Wang     }
6195e6b3c1SJohn Wang     else if (dBusMap->propertyType == "uint16_t")
6295e6b3c1SJohn Wang     {
6395e6b3c1SJohn Wang         return dbusHandler->setDbusProperty(
6495e6b3c1SJohn Wang             *dBusMap, static_cast<uint16_t>(currentValue));
6595e6b3c1SJohn Wang     }
6695e6b3c1SJohn Wang     else if (dBusMap->propertyType == "int16_t")
6795e6b3c1SJohn Wang     {
6895e6b3c1SJohn Wang         return dbusHandler->setDbusProperty(*dBusMap,
6995e6b3c1SJohn Wang                                             static_cast<int16_t>(currentValue));
7095e6b3c1SJohn Wang     }
7195e6b3c1SJohn Wang     else if (dBusMap->propertyType == "uint32_t")
7295e6b3c1SJohn Wang     {
7395e6b3c1SJohn Wang         return dbusHandler->setDbusProperty(
7495e6b3c1SJohn Wang             *dBusMap, static_cast<uint32_t>(currentValue));
7595e6b3c1SJohn Wang     }
7695e6b3c1SJohn Wang     else if (dBusMap->propertyType == "int32_t")
7795e6b3c1SJohn Wang     {
7895e6b3c1SJohn Wang         return dbusHandler->setDbusProperty(*dBusMap,
7995e6b3c1SJohn Wang                                             static_cast<int32_t>(currentValue));
8095e6b3c1SJohn Wang     }
8195e6b3c1SJohn Wang     else if (dBusMap->propertyType == "uint64_t")
8295e6b3c1SJohn Wang     {
8395e6b3c1SJohn Wang         return dbusHandler->setDbusProperty(*dBusMap, currentValue);
8495e6b3c1SJohn Wang     }
8595e6b3c1SJohn Wang     else if (dBusMap->propertyType == "int64_t")
8695e6b3c1SJohn Wang     {
8795e6b3c1SJohn Wang         return dbusHandler->setDbusProperty(*dBusMap,
8895e6b3c1SJohn Wang                                             static_cast<int64_t>(currentValue));
8995e6b3c1SJohn Wang     }
90aca897b7SGeorge Liu     else if (dBusMap->propertyType == "double")
91aca897b7SGeorge Liu     {
92aca897b7SGeorge Liu         return dbusHandler->setDbusProperty(*dBusMap,
93aca897b7SGeorge Liu                                             static_cast<double>(currentValue));
94aca897b7SGeorge Liu     }
9595e6b3c1SJohn Wang 
9695e6b3c1SJohn Wang     std::cerr << "Unsupported property type on dbus: " << dBusMap->propertyType
9795e6b3c1SJohn Wang               << std::endl;
9895e6b3c1SJohn Wang     throw std::invalid_argument("dbus type error");
9995e6b3c1SJohn Wang }
10095e6b3c1SJohn Wang 
10195e6b3c1SJohn Wang void BIOSIntegerAttribute::constructEntry(const BIOSStringTable& stringTable,
10295e6b3c1SJohn Wang                                           Table& attrTable,
10395e6b3c1SJohn Wang                                           Table& attrValueTable)
10495e6b3c1SJohn Wang {
10595e6b3c1SJohn Wang 
10695e6b3c1SJohn Wang     pldm_bios_table_attr_entry_integer_info info = {
10795e6b3c1SJohn Wang         stringTable.findHandle(name), readOnly,
10895e6b3c1SJohn Wang         integerInfo.lowerBound,       integerInfo.upperBound,
10995e6b3c1SJohn Wang         integerInfo.scalarIncrement,  integerInfo.defaultValue,
11095e6b3c1SJohn Wang     };
11195e6b3c1SJohn Wang 
11295e6b3c1SJohn Wang     auto attrTableEntry =
11395e6b3c1SJohn Wang         table::attribute::constructIntegerEntry(attrTable, &info);
11495e6b3c1SJohn Wang 
11595e6b3c1SJohn Wang     auto [attrHandle, attrType, _] =
11695e6b3c1SJohn Wang         table::attribute::decodeHeader(attrTableEntry);
11795e6b3c1SJohn Wang 
11895e6b3c1SJohn Wang     auto currentValue = getAttrValue();
11995e6b3c1SJohn Wang     table::attribute_value::constructIntegerEntry(attrValueTable, attrHandle,
12095e6b3c1SJohn Wang                                                   attrType, currentValue);
12195e6b3c1SJohn Wang }
12295e6b3c1SJohn Wang 
12346ece063SSampa Misra uint64_t BIOSIntegerAttribute::getAttrValue(const PropertyValue& propertyValue)
12495e6b3c1SJohn Wang {
125*081d03b6SAndrew Geissler     uint64_t value = 0;
12695e6b3c1SJohn Wang     if (dBusMap->propertyType == "uint8_t")
12795e6b3c1SJohn Wang     {
12895e6b3c1SJohn Wang         value = std::get<uint8_t>(propertyValue);
12995e6b3c1SJohn Wang     }
13095e6b3c1SJohn Wang     else if (dBusMap->propertyType == "uint16_t")
13195e6b3c1SJohn Wang     {
13295e6b3c1SJohn Wang         value = std::get<uint16_t>(propertyValue);
13395e6b3c1SJohn Wang     }
13495e6b3c1SJohn Wang     else if (dBusMap->propertyType == "int16_t")
13595e6b3c1SJohn Wang     {
13695e6b3c1SJohn Wang         value = std::get<int16_t>(propertyValue);
13795e6b3c1SJohn Wang     }
13895e6b3c1SJohn Wang     else if (dBusMap->propertyType == "uint32_t")
13995e6b3c1SJohn Wang     {
14095e6b3c1SJohn Wang         value = std::get<uint32_t>(propertyValue);
14195e6b3c1SJohn Wang     }
14295e6b3c1SJohn Wang     else if (dBusMap->propertyType == "int32_t")
14395e6b3c1SJohn Wang     {
14495e6b3c1SJohn Wang         value = std::get<int32_t>(propertyValue);
14595e6b3c1SJohn Wang     }
14695e6b3c1SJohn Wang     else if (dBusMap->propertyType == "uint64_t")
14795e6b3c1SJohn Wang     {
14895e6b3c1SJohn Wang         value = std::get<uint64_t>(propertyValue);
14995e6b3c1SJohn Wang     }
15095e6b3c1SJohn Wang     else if (dBusMap->propertyType == "int64_t")
15195e6b3c1SJohn Wang     {
15295e6b3c1SJohn Wang         value = std::get<int64_t>(propertyValue);
15395e6b3c1SJohn Wang     }
154aca897b7SGeorge Liu     else if (dBusMap->propertyType == "double")
155aca897b7SGeorge Liu     {
156aca897b7SGeorge Liu         value = std::get<double>(propertyValue);
157aca897b7SGeorge Liu     }
158*081d03b6SAndrew Geissler     else
159*081d03b6SAndrew Geissler     {
160*081d03b6SAndrew Geissler         std::cerr << "Unsupported property type for getAttrValue: "
161*081d03b6SAndrew Geissler                   << dBusMap->propertyType << std::endl;
162*081d03b6SAndrew Geissler         throw std::invalid_argument("dbus type error");
163*081d03b6SAndrew Geissler     }
16495e6b3c1SJohn Wang     return value;
16595e6b3c1SJohn Wang }
16695e6b3c1SJohn Wang 
16795e6b3c1SJohn Wang uint64_t BIOSIntegerAttribute::getAttrValue()
16895e6b3c1SJohn Wang {
169daa6923cSGeorge Liu     if (readOnly || !dBusMap.has_value())
17095e6b3c1SJohn Wang     {
17195e6b3c1SJohn Wang         return integerInfo.defaultValue;
17295e6b3c1SJohn Wang     }
17395e6b3c1SJohn Wang 
17495e6b3c1SJohn Wang     try
17595e6b3c1SJohn Wang     {
17695e6b3c1SJohn Wang         auto propertyValue = dbusHandler->getDbusPropertyVariant(
17795e6b3c1SJohn Wang             dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
17895e6b3c1SJohn Wang             dBusMap->interface.c_str());
17995e6b3c1SJohn Wang 
18095e6b3c1SJohn Wang         return getAttrValue(propertyValue);
18195e6b3c1SJohn Wang     }
18295e6b3c1SJohn Wang     catch (const std::exception& e)
18395e6b3c1SJohn Wang     {
18495e6b3c1SJohn Wang         std::cerr << "Get Integer Attribute Value Error: AttributeName = "
18595e6b3c1SJohn Wang                   << name << std::endl;
18695e6b3c1SJohn Wang         return integerInfo.defaultValue;
18795e6b3c1SJohn Wang     }
18895e6b3c1SJohn Wang }
18995e6b3c1SJohn Wang 
19046ece063SSampa Misra int BIOSIntegerAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl,
19146ece063SSampa Misra                                         uint8_t attrType,
19246ece063SSampa Misra                                         const PropertyValue& newPropVal)
19346ece063SSampa Misra {
19446ece063SSampa Misra     auto newVal = getAttrValue(newPropVal);
19546ece063SSampa Misra     table::attribute_value::constructIntegerEntry(newValue, attrHdl, attrType,
19646ece063SSampa Misra                                                   newVal);
19746ece063SSampa Misra     return PLDM_SUCCESS;
19846ece063SSampa Misra }
19946ece063SSampa Misra 
2001244acfdSGeorge Liu void BIOSIntegerAttribute::generateAttributeEntry(
2011244acfdSGeorge Liu     const std::variant<int64_t, std::string>& attributevalue,
2021244acfdSGeorge Liu     Table& attrValueEntry)
2031244acfdSGeorge Liu {
2041244acfdSGeorge Liu     attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) +
2051244acfdSGeorge Liu                           sizeof(int64_t) - 1);
2061244acfdSGeorge Liu 
2071244acfdSGeorge Liu     auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
2081244acfdSGeorge Liu         attrValueEntry.data());
2091244acfdSGeorge Liu 
2101244acfdSGeorge Liu     int64_t value = std::get<int64_t>(attributevalue);
2111244acfdSGeorge Liu     entry->attr_type = 3;
2121244acfdSGeorge Liu     memcpy(entry->value, &value, sizeof(int64_t));
2131244acfdSGeorge Liu }
2141244acfdSGeorge Liu 
21595e6b3c1SJohn Wang } // namespace bios
21695e6b3c1SJohn Wang } // namespace responder
21795e6b3c1SJohn Wang } // namespace pldm
218