1 #include "bios_integer_attribute.hpp"
2 
3 #include "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)
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 
91     std::cerr << "Unsupported property type on dbus: " << dBusMap->propertyType
92               << std::endl;
93     throw std::invalid_argument("dbus type error");
94 }
95 
96 void BIOSIntegerAttribute::constructEntry(const BIOSStringTable& stringTable,
97                                           Table& attrTable,
98                                           Table& attrValueTable)
99 {
100 
101     pldm_bios_table_attr_entry_integer_info info = {
102         stringTable.findHandle(name), readOnly,
103         integerInfo.lowerBound,       integerInfo.upperBound,
104         integerInfo.scalarIncrement,  integerInfo.defaultValue,
105     };
106 
107     auto attrTableEntry =
108         table::attribute::constructIntegerEntry(attrTable, &info);
109 
110     auto [attrHandle, attrType, _] =
111         table::attribute::decodeHeader(attrTableEntry);
112 
113     auto currentValue = getAttrValue();
114     table::attribute_value::constructIntegerEntry(attrValueTable, attrHandle,
115                                                   attrType, currentValue);
116 }
117 
118 uint64_t BIOSIntegerAttribute::getAttrValue(const PropertyValue& propertyValue)
119 {
120     uint64_t value;
121     if (dBusMap->propertyType == "uint8_t")
122     {
123         value = std::get<uint8_t>(propertyValue);
124     }
125     else if (dBusMap->propertyType == "uint16_t")
126     {
127         value = std::get<uint16_t>(propertyValue);
128     }
129     else if (dBusMap->propertyType == "int16_t")
130     {
131         value = std::get<int16_t>(propertyValue);
132     }
133     else if (dBusMap->propertyType == "uint32_t")
134     {
135         value = std::get<uint32_t>(propertyValue);
136     }
137     else if (dBusMap->propertyType == "int32_t")
138     {
139         value = std::get<int32_t>(propertyValue);
140     }
141     else if (dBusMap->propertyType == "uint64_t")
142     {
143         value = std::get<uint64_t>(propertyValue);
144     }
145     else if (dBusMap->propertyType == "int64_t")
146     {
147         value = std::get<int64_t>(propertyValue);
148     }
149     return value;
150 }
151 
152 uint64_t BIOSIntegerAttribute::getAttrValue()
153 {
154     if (readOnly)
155     {
156         return integerInfo.defaultValue;
157     }
158 
159     try
160     {
161         auto propertyValue = dbusHandler->getDbusPropertyVariant(
162             dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
163             dBusMap->interface.c_str());
164 
165         return getAttrValue(propertyValue);
166     }
167     catch (const std::exception& e)
168     {
169         std::cerr << "Get Integer Attribute Value Error: AttributeName = "
170                   << name << std::endl;
171         return integerInfo.defaultValue;
172     }
173 }
174 
175 int BIOSIntegerAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl,
176                                         uint8_t attrType,
177                                         const PropertyValue& newPropVal)
178 {
179     auto newVal = getAttrValue(newPropVal);
180     table::attribute_value::constructIntegerEntry(newValue, attrHdl, attrType,
181                                                   newVal);
182     return PLDM_SUCCESS;
183 }
184 
185 } // namespace bios
186 } // namespace responder
187 } // namespace pldm
188