blob: 2434c795a6faec01722ebc93a9edaddfef283864 [file] [log] [blame]
John Wang3be70852020-02-13 15:59:04 +08001#include "bios_enum_attribute.hpp"
2
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05003#include "common/utils.hpp"
John Wang3be70852020-02-13 15:59:04 +08004
Riya Dixit49cfb132023-03-02 04:26:53 -06005#include <phosphor-logging/lg2.hpp>
6
Riya Dixit49cfb132023-03-02 04:26:53 -06007PHOSPHOR_LOG2_USING;
8
Brad Bishop5079ac42021-08-19 18:35:06 -04009using namespace pldm::utils;
10
John Wang3be70852020-02-13 15:59:04 +080011namespace pldm
12{
13namespace responder
14{
15namespace bios
16{
John Wang3be70852020-02-13 15:59:04 +080017BIOSEnumAttribute::BIOSEnumAttribute(const Json& entry,
18 DBusHandler* const dbusHandler) :
19 BIOSAttribute(entry, dbusHandler)
20{
21 std::string attrName = entry.at("attribute_name");
22 Json pv = entry.at("possible_values");
23 for (auto& val : pv)
24 {
25 possibleValues.emplace_back(val);
26 }
27
28 std::vector<std::string> defaultValues;
29 Json dv = entry.at("default_values");
30 for (auto& val : dv)
31 {
32 defaultValues.emplace_back(val);
33 }
Sagar Srinivas7927f902023-10-09 07:53:00 -050034
35 Json vdn = entry.at("value_names");
36 for (auto& val : vdn)
37 {
38 valueDisplayNames.emplace_back(val);
39 }
John Wang3be70852020-02-13 15:59:04 +080040 assert(defaultValues.size() == 1);
41 defaultValue = defaultValues[0];
George Liudaa69232020-09-02 17:22:09 +080042 if (dBusMap.has_value())
John Wang3be70852020-02-13 15:59:04 +080043 {
44 auto dbusValues = entry.at("dbus").at("property_values");
45 buildValMap(dbusValues);
46 }
47}
48
49uint8_t BIOSEnumAttribute::getValueIndex(const std::string& value,
50 const std::vector<std::string>& pVs)
51{
Patrick Williams16c2a0a2024-08-16 15:20:59 -040052 auto iter = std::find_if(pVs.begin(), pVs.end(), [&value](const auto& v) {
53 return v == value;
54 });
John Wang3be70852020-02-13 15:59:04 +080055 if (iter == pVs.end())
56 {
57 throw std::invalid_argument("value must be one of possible value");
58 }
59 return iter - pVs.begin();
60}
61
62std::vector<uint16_t> BIOSEnumAttribute::getPossibleValuesHandle(
63 const BIOSStringTable& stringTable, const std::vector<std::string>& pVs)
64{
65 std::vector<uint16_t> possibleValuesHandle;
66 for (const auto& pv : pVs)
67 {
68 auto handle = stringTable.findHandle(pv);
69 possibleValuesHandle.push_back(handle);
70 }
71
72 return possibleValuesHandle;
73}
74
75void BIOSEnumAttribute::buildValMap(const Json& dbusVals)
76{
77 PropertyValue value;
78 size_t pos = 0;
79 for (auto it = dbusVals.begin(); it != dbusVals.end(); ++it, ++pos)
80 {
81 if (dBusMap->propertyType == "uint8_t")
82 {
83 value = static_cast<uint8_t>(it.value());
84 }
85 else if (dBusMap->propertyType == "uint16_t")
86 {
87 value = static_cast<uint16_t>(it.value());
88 }
89 else if (dBusMap->propertyType == "uint32_t")
90 {
91 value = static_cast<uint32_t>(it.value());
92 }
93 else if (dBusMap->propertyType == "uint64_t")
94 {
95 value = static_cast<uint64_t>(it.value());
96 }
97 else if (dBusMap->propertyType == "int16_t")
98 {
99 value = static_cast<int16_t>(it.value());
100 }
101 else if (dBusMap->propertyType == "int32_t")
102 {
103 value = static_cast<int32_t>(it.value());
104 }
105 else if (dBusMap->propertyType == "int64_t")
106 {
107 value = static_cast<int64_t>(it.value());
108 }
109 else if (dBusMap->propertyType == "bool")
110 {
111 value = static_cast<bool>(it.value());
112 }
113 else if (dBusMap->propertyType == "double")
114 {
115 value = static_cast<double>(it.value());
116 }
117 else if (dBusMap->propertyType == "string")
118 {
119 value = static_cast<std::string>(it.value());
120 }
121 else
122 {
Riya Dixit89644442024-03-31 05:39:59 -0500123 error("Unknown D-Bus property type '{TYPE}'", "TYPE",
Riya Dixit49cfb132023-03-02 04:26:53 -0600124 dBusMap->propertyType);
John Wang3be70852020-02-13 15:59:04 +0800125 throw std::invalid_argument("Unknown D-BUS property type");
126 }
127 valMap.emplace(value, possibleValues[pos]);
128 }
129}
130
131uint8_t BIOSEnumAttribute::getAttrValueIndex()
132{
133 auto defaultValueIndex = getValueIndex(defaultValue, possibleValues);
George Liu5bb9edb2021-08-05 20:10:32 +0800134 if (!dBusMap.has_value())
John Wang3be70852020-02-13 15:59:04 +0800135 {
136 return defaultValueIndex;
137 }
138
139 try
140 {
141 auto propValue = dbusHandler->getDbusPropertyVariant(
142 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
143 dBusMap->interface.c_str());
144 auto iter = valMap.find(propValue);
145 if (iter == valMap.end())
146 {
147 return defaultValueIndex;
148 }
149 auto currentValue = iter->second;
150 return getValueIndex(currentValue, possibleValues);
151 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500152 catch (const std::exception&)
John Wang3be70852020-02-13 15:59:04 +0800153 {
154 return defaultValueIndex;
155 }
156}
157
George Liu1244acf2020-08-14 09:11:11 +0800158uint8_t BIOSEnumAttribute::getAttrValueIndex(const PropertyValue& propValue)
159{
George Liu1244acf2020-08-14 09:11:11 +0800160 try
161 {
George Liu6d6d1e82021-02-16 11:08:55 +0800162 return getValueIndex(std::get<std::string>(propValue), possibleValues);
George Liu1244acf2020-08-14 09:11:11 +0800163 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500164 catch (const std::exception&)
George Liu1244acf2020-08-14 09:11:11 +0800165 {
George Liu6d6d1e82021-02-16 11:08:55 +0800166 return getValueIndex(defaultValue, possibleValues);
George Liu1244acf2020-08-14 09:11:11 +0800167 }
168}
169
John Wang3be70852020-02-13 15:59:04 +0800170void BIOSEnumAttribute::setAttrValueOnDbus(
171 const pldm_bios_attr_val_table_entry* attrValueEntry,
172 const pldm_bios_attr_table_entry* attrEntry,
173 const BIOSStringTable& stringTable)
174{
George Liu5bb9edb2021-08-05 20:10:32 +0800175 if (!dBusMap.has_value())
John Wang3be70852020-02-13 15:59:04 +0800176 {
177 return;
178 }
179 auto [pvHdls, _] = table::attribute::decodeEnumEntry(attrEntry);
180 auto currHdls = table::attribute_value::decodeEnumEntry(attrValueEntry);
181
182 assert(currHdls.size() == 1);
John Wang3be70852020-02-13 15:59:04 +0800183 auto valueString = stringTable.findString(pvHdls[currHdls[0]]);
184
185 auto it = std::find_if(valMap.begin(), valMap.end(),
186 [&valueString](const auto& typePair) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400187 return typePair.second == valueString;
188 });
John Wang3be70852020-02-13 15:59:04 +0800189 if (it == valMap.end())
190 {
191 return;
192 }
193
194 dbusHandler->setDbusProperty(*dBusMap, it->first);
195}
196
Sagar Srinivas7927f902023-10-09 07:53:00 -0500197void BIOSEnumAttribute::populateValueDisplayNamesMap(uint16_t attrHandle)
198{
199 for (auto& vdn : valueDisplayNames)
200 {
201 valueDisplayNamesMap[attrHandle].push_back(vdn);
202 }
203}
204
Tom Josephca7b2522020-11-18 12:27:11 +0530205void BIOSEnumAttribute::constructEntry(
206 const BIOSStringTable& stringTable, Table& attrTable, Table& attrValueTable,
207 std::optional<std::variant<int64_t, std::string>> optAttributeValue)
John Wang3be70852020-02-13 15:59:04 +0800208{
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400209 auto possibleValuesHandle =
210 getPossibleValuesHandle(stringTable, possibleValues);
John Wang3be70852020-02-13 15:59:04 +0800211 std::vector<uint8_t> defaultIndices(1, 0);
212 defaultIndices[0] = getValueIndex(defaultValue, possibleValues);
213
214 pldm_bios_table_attr_entry_enum_info info = {
215 stringTable.findHandle(name), readOnly,
216 (uint8_t)possibleValuesHandle.size(), possibleValuesHandle.data(),
Sagar Srinivas7927f902023-10-09 07:53:00 -0500217 (uint8_t)defaultIndices.size(), defaultIndices.data()};
John Wang3be70852020-02-13 15:59:04 +0800218
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400219 auto attrTableEntry =
220 table::attribute::constructEnumEntry(attrTable, &info);
Patrick Williams6da4f912023-05-10 07:50:53 -0500221 auto [attrHandle, attrType,
222 _] = table::attribute::decodeHeader(attrTableEntry);
John Wang3be70852020-02-13 15:59:04 +0800223
Sagar Srinivas7927f902023-10-09 07:53:00 -0500224 populateValueDisplayNamesMap(attrHandle);
225
John Wang3be70852020-02-13 15:59:04 +0800226 std::vector<uint8_t> currValueIndices(1, 0);
Tom Josephca7b2522020-11-18 12:27:11 +0530227
228 if (optAttributeValue.has_value())
229 {
230 auto attributeValue = optAttributeValue.value();
231 if (attributeValue.index() == 1)
232 {
233 auto currValue = std::get<std::string>(attributeValue);
234 currValueIndices[0] = getValueIndex(currValue, possibleValues);
235 }
236 else
237 {
238 currValueIndices[0] = getAttrValueIndex();
239 }
240 }
241 else
242 {
243 currValueIndices[0] = getAttrValueIndex();
244 }
John Wang3be70852020-02-13 15:59:04 +0800245
246 table::attribute_value::constructEnumEntry(attrValueTable, attrHandle,
247 attrType, currValueIndices);
248}
249
Sampa Misra46ece062020-03-18 07:17:44 -0500250int BIOSEnumAttribute::updateAttrVal(Table& newValue, uint16_t attrHdl,
251 uint8_t attrType,
252 const PropertyValue& newPropVal)
253{
254 auto iter = valMap.find(newPropVal);
255 if (iter == valMap.end())
256 {
Riya Dixit89644442024-03-31 05:39:59 -0500257 error("Failed to find index for new BIOS enum value '{VALUE}'", "VALUE",
258 std::get<std::string>(newPropVal));
Sampa Misra46ece062020-03-18 07:17:44 -0500259 return PLDM_ERROR;
260 }
261 auto currentValue = iter->second;
262 std::vector<uint8_t> handleIndices{
263 getValueIndex(currentValue, possibleValues)};
264 table::attribute_value::constructEnumEntry(newValue, attrHdl, attrType,
265 handleIndices);
266 return PLDM_SUCCESS;
267}
268
George Liu1244acf2020-08-14 09:11:11 +0800269void BIOSEnumAttribute::generateAttributeEntry(
270 const std::variant<int64_t, std::string>& attributevalue,
271 Table& attrValueEntry)
272{
273 attrValueEntry.resize(sizeof(pldm_bios_attr_val_table_entry) + 1);
274
275 auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
276 attrValueEntry.data());
277
278 std::string value = std::get<std::string>(attributevalue);
279 entry->attr_type = 0;
280 entry->value[0] = 1; // number of current values, default 1
George Liu5bb9edb2021-08-05 20:10:32 +0800281 entry->value[1] = getAttrValueIndex(value);
George Liu1244acf2020-08-14 09:11:11 +0800282}
283
John Wang3be70852020-02-13 15:59:04 +0800284} // namespace bios
285} // namespace responder
Sampa Misra46ece062020-03-18 07:17:44 -0500286} // namespace pldm