blob: 3a45f3d34d2fbcab5a336143c8ec2290be8b7686 [file] [log] [blame]
Tom Joseph52552ef2019-06-20 09:50:15 +05301#include "bios_parser.hpp"
2
John Wang0df0e042020-01-16 10:01:36 +08003#include "bios_table.hpp"
George Liu83409572019-12-24 18:42:54 +08004#include "utils.hpp"
Tom Joseph52552ef2019-06-20 09:50:15 +05305
John Wang0df0e042020-01-16 10:01:36 +08006#include <cassert>
Tom Joseph52552ef2019-06-20 09:50:15 +05307#include <filesystem>
8#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -06009#include <iostream>
Tom Joseph52552ef2019-06-20 09:50:15 +053010#include <nlohmann/json.hpp>
11#include <optional>
John Wang0df0e042020-01-16 10:01:36 +080012#include <set>
Tom Joseph52552ef2019-06-20 09:50:15 +053013
John Wang0df0e042020-01-16 10:01:36 +080014#include "libpldm/bios.h"
John Wangecb7d572019-10-17 13:38:53 +080015#include "libpldm/bios_table.h"
16
Tom Joseph52552ef2019-06-20 09:50:15 +053017namespace bios_parser
18{
19
George Liu1e44c732020-02-28 20:20:06 +080020using namespace pldm::utils;
Tom Joseph52552ef2019-06-20 09:50:15 +053021using Json = nlohmann::json;
22namespace fs = std::filesystem;
John Wang0df0e042020-01-16 10:01:36 +080023using namespace pldm::responder::bios;
Tom Joseph52552ef2019-06-20 09:50:15 +053024
Carol Wang612f35b2019-08-26 17:14:26 +080025const std::vector<Json> emptyJsonList{};
26const Json emptyJson{};
27
John Wang0df0e042020-01-16 10:01:36 +080028using AttrType = uint8_t;
29using Table = std::vector<uint8_t>;
John Wange96e7e52019-10-05 17:47:30 +080030using BIOSJsonName = std::string;
31using AttrLookup = std::map<AttrName, std::optional<DBusMapping>>;
George Liu1e44c732020-02-28 20:20:06 +080032
John Wang0df0e042020-01-16 10:01:36 +080033const std::set<std::string> SupportedDbusPropertyTypes = {
34 "bool", "uint8_t", "int16_t", "uint16_t", "int32_t",
35 "uint32_t", "int64_t", "uint64_t", "double", "string"};
36
John Wange96e7e52019-10-05 17:47:30 +080037using BIOSStringHandler =
38 std::function<int(const Json& entry, Strings& strings)>;
39using AttrLookupHandler = std::function<int(const Json& entry, AttrLookup)>;
40using typeHandler = std::function<int(const Json& entry)>;
41
42Strings BIOSStrings;
43AttrLookup BIOSAttrLookup;
44
45const Strings& getStrings()
46{
47 return BIOSStrings;
48}
49
John Wang0df0e042020-01-16 10:01:36 +080050int parseBIOSJsonFile(const fs::path& dirPath, const std::string& fileName,
Carol Wang612f35b2019-08-26 17:14:26 +080051 Json& fileData)
52{
53 int rc = 0;
54
John Wange96e7e52019-10-05 17:47:30 +080055 fs::path filePath = dirPath / fileName;
Carol Wang612f35b2019-08-26 17:14:26 +080056
57 std::ifstream jsonFile(filePath);
58 if (!jsonFile.is_open())
59 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060060 std::cerr << "BIOS config file does not exist, FILE="
61 << filePath.c_str() << "\n";
Carol Wang612f35b2019-08-26 17:14:26 +080062 rc = -1;
63 }
64 else
65 {
66 fileData = Json::parse(jsonFile, nullptr, false);
67 if (fileData.is_discarded())
68 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060069 std::cerr << "Parsing config file failed, FILE=" << filePath.c_str()
70 << "\n";
Carol Wang612f35b2019-08-26 17:14:26 +080071 rc = -1;
72 }
73 }
74
75 return rc;
76}
77
Tom Joseph52552ef2019-06-20 09:50:15 +053078namespace bios_enum
79{
80
81namespace internal
82{
83
Tom Joseph52552ef2019-06-20 09:50:15 +053084using Value = std::string;
85
John Wange96e7e52019-10-05 17:47:30 +080086/** @brief Map of DBus property value to attribute value
Tom Joseph52552ef2019-06-20 09:50:15 +053087 */
John Wange96e7e52019-10-05 17:47:30 +080088using DbusValToValMap = std::map<PropertyValue, Value>;
89
90/** @brief Map containing the DBus property value to attribute value map for the
91 * BIOS enumeration type attributes
92 */
93std::map<AttrName, DbusValToValMap> dbusValToValMaps;
Tom Joseph52552ef2019-06-20 09:50:15 +053094
95/** @brief Map containing the possible and the default values for the BIOS
96 * enumeration type attributes.
97 */
98AttrValuesMap valueMap;
99
Tom Joseph52552ef2019-06-20 09:50:15 +0530100/** @brief Populate the mapping between D-Bus property value and attribute value
101 * for the BIOS enumeration attribute.
102 *
103 * @param[in] type - type of the D-Bus property
104 * @param[in] dBusValues - json array of D-Bus property values
105 * @param[in] pv - Possible values for the BIOS enumeration attribute
Tom Joseph52552ef2019-06-20 09:50:15 +0530106 *
107 */
John Wange96e7e52019-10-05 17:47:30 +0800108DbusValToValMap populateMapping(const std::string& type, const Json& dBusValues,
109 const PossibleValues& pv)
Tom Joseph52552ef2019-06-20 09:50:15 +0530110{
111 size_t pos = 0;
112 PropertyValue value;
John Wange96e7e52019-10-05 17:47:30 +0800113 DbusValToValMap valueMap;
Tom Joseph52552ef2019-06-20 09:50:15 +0530114 for (auto it = dBusValues.begin(); it != dBusValues.end(); ++it, ++pos)
115 {
116 if (type == "uint8_t")
117 {
118 value = static_cast<uint8_t>(it.value());
119 }
120 else if (type == "uint16_t")
121 {
122 value = static_cast<uint16_t>(it.value());
123 }
124 else if (type == "uint32_t")
125 {
126 value = static_cast<uint32_t>(it.value());
127 }
128 else if (type == "uint64_t")
129 {
130 value = static_cast<uint64_t>(it.value());
131 }
132 else if (type == "int16_t")
133 {
134 value = static_cast<int16_t>(it.value());
135 }
136 else if (type == "int32_t")
137 {
138 value = static_cast<int32_t>(it.value());
139 }
140 else if (type == "int64_t")
141 {
142 value = static_cast<int64_t>(it.value());
143 }
144 else if (type == "bool")
145 {
146 value = static_cast<bool>(it.value());
147 }
148 else if (type == "double")
149 {
150 value = static_cast<double>(it.value());
151 }
152 else if (type == "string")
153 {
154 value = static_cast<std::string>(it.value());
155 }
156 else
157 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600158 std::cerr << "Unknown D-Bus property type, TYPE=" << type.c_str()
159 << "\n";
Tom Joseph52552ef2019-06-20 09:50:15 +0530160 }
161
John Wange96e7e52019-10-05 17:47:30 +0800162 valueMap.emplace(value, pv[pos]);
Tom Joseph52552ef2019-06-20 09:50:15 +0530163 }
164
John Wange96e7e52019-10-05 17:47:30 +0800165 return valueMap;
Tom Joseph52552ef2019-06-20 09:50:15 +0530166}
Tom Joseph52552ef2019-06-20 09:50:15 +0530167} // namespace internal
168
John Wange96e7e52019-10-05 17:47:30 +0800169int setupBIOSStrings(const Json& entry, Strings& strings)
Tom Joseph52552ef2019-06-20 09:50:15 +0530170{
John Wange96e7e52019-10-05 17:47:30 +0800171 Json pvs = entry.value("possible_values", emptyJsonList);
Tom Joseph52552ef2019-06-20 09:50:15 +0530172
John Wange96e7e52019-10-05 17:47:30 +0800173 for (auto& pv : pvs)
Tom Joseph52552ef2019-06-20 09:50:15 +0530174 {
John Wange96e7e52019-10-05 17:47:30 +0800175 strings.emplace_back(std::move(pv.get<std::string>()));
Tom Joseph52552ef2019-06-20 09:50:15 +0530176 }
177
John Wange96e7e52019-10-05 17:47:30 +0800178 return 0;
179}
Tom Joseph52552ef2019-06-20 09:50:15 +0530180
John Wange96e7e52019-10-05 17:47:30 +0800181int setup(const Json& entry)
182{
183 PossibleValues possibleValues;
184 DefaultValues defaultValues;
185
186 std::string attrName = entry.value("attribute_name", "");
187 Json pv = entry["possible_values"];
188 for (auto& val : pv)
Tom Joseph52552ef2019-06-20 09:50:15 +0530189 {
John Wange96e7e52019-10-05 17:47:30 +0800190 possibleValues.emplace_back(std::move(val));
Tom Joseph52552ef2019-06-20 09:50:15 +0530191 }
John Wange96e7e52019-10-05 17:47:30 +0800192 Json dv = entry["default_values"];
193 for (auto& val : dv)
Tom Joseph52552ef2019-06-20 09:50:15 +0530194 {
John Wange96e7e52019-10-05 17:47:30 +0800195 defaultValues.emplace_back(std::move(val));
Tom Joseph52552ef2019-06-20 09:50:15 +0530196 }
John Wange96e7e52019-10-05 17:47:30 +0800197 if (entry.count("dbus") != 0)
Tom Joseph52552ef2019-06-20 09:50:15 +0530198 {
John Wange96e7e52019-10-05 17:47:30 +0800199 auto dbusEntry = entry.value("dbus", emptyJson);
200 std::string propertyType = dbusEntry.value("property_type", "");
201 Json propValues = dbusEntry["property_values"];
202 internal::dbusValToValMaps.emplace(
203 attrName, internal::populateMapping(propertyType, propValues,
204 possibleValues));
Tom Joseph52552ef2019-06-20 09:50:15 +0530205 }
John Wange96e7e52019-10-05 17:47:30 +0800206 // Defaulting all the types of attributes to BIOSEnumeration
207 internal::valueMap.emplace(std::move(attrName),
208 std::make_tuple(entry.count("dbus") == 0,
209 std::move(possibleValues),
210 std::move(defaultValues)));
211 return 0;
Tom Joseph52552ef2019-06-20 09:50:15 +0530212}
213
214const AttrValuesMap& getValues()
215{
216 return internal::valueMap;
217}
218
219CurrentValues getAttrValue(const AttrName& attrName)
220{
John Wange96e7e52019-10-05 17:47:30 +0800221 const auto& dBusMap = BIOSAttrLookup.at(attrName);
Tom Joseph52552ef2019-06-20 09:50:15 +0530222 CurrentValues currentValues;
John Wang0df0e042020-01-16 10:01:36 +0800223 PropertyValue propValue;
Tom Joseph52552ef2019-06-20 09:50:15 +0530224
225 if (dBusMap == std::nullopt)
226 {
227 const auto& valueEntry = internal::valueMap.at(attrName);
228 const auto& [readOnly, possibleValues, currentValues] = valueEntry;
229 return currentValues;
230 }
231
John Wange96e7e52019-10-05 17:47:30 +0800232 const auto& dbusValToValMap = internal::dbusValToValMaps.at(attrName);
John Wang9e242422020-03-05 08:37:50 +0800233 propValue = pldm::utils::DBusHandler().getDbusPropertyVariant(
234 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
235 dBusMap->interface.c_str());
John Wang0df0e042020-01-16 10:01:36 +0800236
John Wange96e7e52019-10-05 17:47:30 +0800237 auto iter = dbusValToValMap.find(propValue);
238 if (iter != dbusValToValMap.end())
Tom Joseph52552ef2019-06-20 09:50:15 +0530239 {
240 currentValues.push_back(iter->second);
241 }
242
243 return currentValues;
244}
245
John Wang0df0e042020-01-16 10:01:36 +0800246int setAttrValue(const AttrName& attrName,
247 const pldm_bios_attr_val_table_entry* attrValueEntry,
248 const pldm_bios_attr_table_entry* attrEntry,
249 const BIOSStringTable& stringTable)
250{
251 const auto& dBusMap = BIOSAttrLookup.at(attrName);
252 if (dBusMap == std::nullopt)
253 {
254 return PLDM_SUCCESS;
255 }
256
257 uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
258 std::vector<uint16_t> pvHdls(pvNum, 0);
259 pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrEntry, pvHdls.data(),
260 pvNum);
261
262 uint8_t defNum =
263 pldm_bios_table_attr_value_entry_enum_decode_number(attrValueEntry);
264
265 assert(defNum == 1);
266
267 std::vector<uint8_t> currHdls(1, 0);
268 pldm_bios_table_attr_value_entry_enum_decode_handles(
269 attrValueEntry, currHdls.data(), currHdls.size());
270
271 auto valueString = stringTable.findString(pvHdls[currHdls[0]]);
272
273 const auto& dbusValToValMap = internal::dbusValToValMaps.at(attrName);
274
275 auto it = std::find_if(dbusValToValMap.begin(), dbusValToValMap.end(),
276 [&valueString](const auto& typePair) {
277 return typePair.second == valueString;
278 });
279 if (it == dbusValToValMap.end())
280 {
281 std::cerr << "Invalid Enum Value\n";
282 return PLDM_ERROR;
283 }
284
George Liu1e44c732020-02-28 20:20:06 +0800285 pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), it->first);
John Wang0df0e042020-01-16 10:01:36 +0800286
287 return PLDM_SUCCESS;
288}
289
Tom Joseph52552ef2019-06-20 09:50:15 +0530290} // namespace bios_enum
291
Carol Wang612f35b2019-08-26 17:14:26 +0800292namespace bios_string
293{
294
295/** @brief BIOS string types
296 */
John Wang0df0e042020-01-16 10:01:36 +0800297enum BIOSStringEncoding
Carol Wang612f35b2019-08-26 17:14:26 +0800298{
299 UNKNOWN = 0x00,
300 ASCII = 0x01,
301 HEX = 0x02,
302 UTF_8 = 0x03,
303 UTF_16LE = 0x04,
304 UTF_16BE = 0x05,
305 VENDOR_SPECIFIC = 0xFF
306};
307
308const std::map<std::string, uint8_t> strTypeMap{
309 {"Unknown", UNKNOWN},
310 {"ASCII", ASCII},
311 {"Hex", HEX},
312 {"UTF-8", UTF_8},
313 {"UTF-16LE", UTF_16LE},
314 {"UTF-16LE", UTF_16LE},
315 {"Vendor Specific", VENDOR_SPECIFIC}};
316
317namespace internal
318{
319
Carol Wang612f35b2019-08-26 17:14:26 +0800320/** @brief Map containing the possible and the default values for the BIOS
321 * string type attributes.
322 */
323AttrValuesMap valueMap;
324
Carol Wang612f35b2019-08-26 17:14:26 +0800325} // namespace internal
326
John Wangecb7d572019-10-17 13:38:53 +0800327int setup(const Json& jsonEntry)
Carol Wang612f35b2019-08-26 17:14:26 +0800328{
Carol Wang612f35b2019-08-26 17:14:26 +0800329
John Wangecb7d572019-10-17 13:38:53 +0800330 std::string attr = jsonEntry.value("attribute_name", "");
John Wange96e7e52019-10-05 17:47:30 +0800331 // Transfer string type from string to enum
John Wangecb7d572019-10-17 13:38:53 +0800332 std::string strTypeTmp = jsonEntry.value("string_type", "Unknown");
John Wange96e7e52019-10-05 17:47:30 +0800333 auto iter = strTypeMap.find(strTypeTmp);
334 if (iter == strTypeMap.end())
Carol Wang612f35b2019-08-26 17:14:26 +0800335 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600336 std::cerr << "Wrong string type, STRING_TYPE=" << strTypeTmp.c_str()
337 << " ATTRIBUTE_NAME=" << attr.c_str() << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800338 return -1;
339 }
340 uint8_t strType = iter->second;
341
John Wangecb7d572019-10-17 13:38:53 +0800342 uint16_t minStrLen = jsonEntry.value("minimum_string_length", 0);
343 uint16_t maxStrLen = jsonEntry.value("maximum_string_length", 0);
344 uint16_t defaultStrLen = jsonEntry.value("default_string_length", 0);
345 std::string defaultStr = jsonEntry.value("default_string", "");
346
347 pldm_bios_table_attr_entry_string_info info = {
348 0, /* name handle */
349 false, /* read only */
350 strType, minStrLen, maxStrLen, defaultStrLen, defaultStr.data(),
351 };
352
353 const char* errmsg;
354 auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
355 if (rc != PLDM_SUCCESS)
John Wange96e7e52019-10-05 17:47:30 +0800356 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600357 std::cerr << "Wrong filed for string attribute, ATTRIBUTE_NAME="
358 << attr.c_str() << " ERRMSG=" << errmsg
359 << " MINIMUM_STRING_LENGTH=" << minStrLen
360 << " MAXIMUM_STRING_LENGTH=" << maxStrLen
361 << " DEFAULT_STRING_LENGTH=" << defaultStrLen
362 << " DEFAULT_STRING=" << defaultStr.data() << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800363 return -1;
Carol Wang612f35b2019-08-26 17:14:26 +0800364 }
365
John Wange96e7e52019-10-05 17:47:30 +0800366 // Defaulting all the types of attributes to BIOSString
367 internal::valueMap.emplace(
368 std::move(attr),
John Wangecb7d572019-10-17 13:38:53 +0800369 std::make_tuple(jsonEntry.count("dbus") == 0, strType, minStrLen,
370 maxStrLen, defaultStrLen, std::move(defaultStr)));
Carol Wang612f35b2019-08-26 17:14:26 +0800371
John Wange96e7e52019-10-05 17:47:30 +0800372 return 0;
Carol Wang612f35b2019-08-26 17:14:26 +0800373}
374
375const AttrValuesMap& getValues()
376{
377 return internal::valueMap;
378}
Carol Wangb503f9e2019-09-02 16:34:10 +0800379
380std::string getAttrValue(const AttrName& attrName)
381{
John Wange96e7e52019-10-05 17:47:30 +0800382 const auto& dBusMap = BIOSAttrLookup.at(attrName);
Carol Wangb503f9e2019-09-02 16:34:10 +0800383 std::variant<std::string> propValue;
384
385 if (dBusMap == std::nullopt)
386 { // return default string
387 const auto& valueEntry = internal::valueMap.at(attrName);
388 return std::get<DefaultStr>(valueEntry);
389 }
390
George Liu83409572019-12-24 18:42:54 +0800391 return pldm::utils::DBusHandler().getDbusProperty<std::string>(
John Wang8b85f522019-10-17 19:28:19 +0800392 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
393 dBusMap->interface.c_str());
Carol Wangb503f9e2019-09-02 16:34:10 +0800394}
395
John Wang0df0e042020-01-16 10:01:36 +0800396std::string stringToUtf8(BIOSStringEncoding stringType,
397 const std::vector<uint8_t>& data)
398{
399 switch (stringType)
400 {
401 case ASCII:
402 case UTF_8:
403 case HEX:
404 return std::string(data.begin(), data.end());
405 case UTF_16BE:
406 case UTF_16LE: // TODO
407 return std::string(data.begin(), data.end());
408 case VENDOR_SPECIFIC:
409 throw std::invalid_argument("Vendor Specific is unsupported");
410 case UNKNOWN:
411 throw std::invalid_argument("Unknown String Type");
412 }
413 throw std::invalid_argument("String Type Error");
414}
415
416int setAttrValue(const AttrName& attrName,
417 const pldm_bios_attr_val_table_entry* attrValueEntry,
418 const pldm_bios_attr_table_entry* attrEntry,
419 const BIOSStringTable&)
420{
421 const auto& dBusMap = BIOSAttrLookup.at(attrName);
422 if (dBusMap == std::nullopt)
423 {
424 return PLDM_SUCCESS;
425 }
426
427 auto stringType =
428 pldm_bios_table_attr_entry_string_decode_string_type(attrEntry);
429
430 variable_field currentString{};
431 pldm_bios_table_attr_value_entry_string_decode_string(attrValueEntry,
432 &currentString);
433 std::vector<uint8_t> data(currentString.ptr,
434 currentString.ptr + currentString.length);
435
George Liu1e44c732020-02-28 20:20:06 +0800436 PropertyValue value =
John Wang0df0e042020-01-16 10:01:36 +0800437 stringToUtf8(static_cast<BIOSStringEncoding>(stringType), data);
George Liu1e44c732020-02-28 20:20:06 +0800438 pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
John Wang0df0e042020-01-16 10:01:36 +0800439
440 return PLDM_SUCCESS;
441}
442
Carol Wang612f35b2019-08-26 17:14:26 +0800443} // namespace bios_string
444
John Wangecb7d572019-10-17 13:38:53 +0800445namespace bios_integer
446{
447
448AttrValuesMap valueMap;
449
450int setup(const Json& jsonEntry)
451{
452
453 std::string attr = jsonEntry.value("attribute_name", "");
454 // Transfer string type from string to enum
455
456 uint64_t lowerBound = jsonEntry.value("lower_bound", 0);
457 uint64_t upperBound = jsonEntry.value("upper_bound", 0);
458 uint32_t scalarIncrement = jsonEntry.value("scalar_increment", 1);
459 uint64_t defaultValue = jsonEntry.value("default_value", 0);
460 pldm_bios_table_attr_entry_integer_info info = {
461 0, /* name handle*/
462 false, /* read only */
463 lowerBound, upperBound, scalarIncrement, defaultValue,
464 };
465 const char* errmsg = nullptr;
466 auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
467 if (rc != PLDM_SUCCESS)
468 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600469 std::cerr << "Wrong filed for integer attribute, ATTRIBUTE_NAME="
470 << attr.c_str() << " ERRMSG=" << errmsg
471 << " LOWER_BOUND=" << lowerBound
472 << " UPPER_BOUND=" << upperBound
473 << " DEFAULT_VALUE=" << defaultValue
474 << " SCALAR_INCREMENT=" << scalarIncrement << "\n";
John Wangecb7d572019-10-17 13:38:53 +0800475 return -1;
476 }
477
478 valueMap.emplace(std::move(attr),
479 std::make_tuple(jsonEntry.count("dbus") == 0, lowerBound,
480 upperBound, scalarIncrement,
481 defaultValue));
482
483 return 0;
484}
485
486const AttrValuesMap& getValues()
487{
488 return valueMap;
489}
490
491uint64_t getAttrValue(const AttrName& attrName)
492{
493 const auto& dBusMap = BIOSAttrLookup.at(attrName);
494 std::variant<std::string> propValue;
495
496 if (dBusMap == std::nullopt)
497 { // return default string
498 const auto& valueEntry = valueMap.at(attrName);
499 return std::get<AttrDefaultValue>(valueEntry);
500 }
501
George Liu83409572019-12-24 18:42:54 +0800502 return pldm::utils::DBusHandler().getDbusProperty<uint64_t>(
John Wangecb7d572019-10-17 13:38:53 +0800503 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
504 dBusMap->interface.c_str());
505}
506
John Wang0df0e042020-01-16 10:01:36 +0800507int setAttrValue(const AttrName& attrName,
508 const pldm_bios_attr_val_table_entry* attrValueEntry,
509 const pldm_bios_attr_table_entry*, const BIOSStringTable&)
510{
511 const auto& dBusMap = BIOSAttrLookup.at(attrName);
512 if (dBusMap == std::nullopt)
513 {
514 return PLDM_SUCCESS;
515 }
516
517 uint64_t currentValue =
518 pldm_bios_table_attr_value_entry_integer_decode_cv(attrValueEntry);
519
George Liu1e44c732020-02-28 20:20:06 +0800520 PropertyValue value = static_cast<uint64_t>(currentValue);
521 pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
John Wang0df0e042020-01-16 10:01:36 +0800522
523 return PLDM_SUCCESS;
524}
525
John Wangecb7d572019-10-17 13:38:53 +0800526} // namespace bios_integer
527
John Wange96e7e52019-10-05 17:47:30 +0800528const std::map<BIOSJsonName, BIOSStringHandler> BIOSStringHandlers = {
529 {bIOSEnumJson, bios_enum::setupBIOSStrings},
530};
Tom Joseph52552ef2019-06-20 09:50:15 +0530531
John Wange96e7e52019-10-05 17:47:30 +0800532const std::map<BIOSJsonName, typeHandler> BIOSTypeHandlers = {
533 {bIOSEnumJson, bios_enum::setup},
534 {bIOSStrJson, bios_string::setup},
John Wangecb7d572019-10-17 13:38:53 +0800535 {bIOSIntegerJson, bios_integer::setup},
John Wange96e7e52019-10-05 17:47:30 +0800536};
537
538void setupBIOSStrings(const BIOSJsonName& jsonName, const Json& entry,
539 Strings& strings)
540{
541 strings.emplace_back(entry.value("attribute_name", ""));
542 auto iter = BIOSStringHandlers.find(jsonName);
543 if (iter != BIOSStringHandlers.end())
544 {
545 iter->second(entry, strings);
546 }
547}
548
John Wangecb7d572019-10-17 13:38:53 +0800549void setupBIOSAttrLookup(const Json& jsonEntry, AttrLookup& lookup)
John Wange96e7e52019-10-05 17:47:30 +0800550{
551 std::optional<DBusMapping> dBusMap;
John Wangecb7d572019-10-17 13:38:53 +0800552 std::string attrName = jsonEntry.value("attribute_name", "");
John Wange96e7e52019-10-05 17:47:30 +0800553
John Wangecb7d572019-10-17 13:38:53 +0800554 if (jsonEntry.count("dbus") != 0)
John Wange96e7e52019-10-05 17:47:30 +0800555 {
John Wangecb7d572019-10-17 13:38:53 +0800556 auto dBusEntry = jsonEntry.value("dbus", emptyJson);
John Wange96e7e52019-10-05 17:47:30 +0800557 std::string objectPath = dBusEntry.value("object_path", "");
558 std::string interface = dBusEntry.value("interface", "");
559 std::string propertyName = dBusEntry.value("property_name", "");
John Wang0df0e042020-01-16 10:01:36 +0800560 std::string propertyType = dBusEntry.value("property_type", "");
561 if (!objectPath.empty() && !interface.empty() &&
562 !propertyName.empty() &&
563 (SupportedDbusPropertyTypes.find(propertyType) !=
564 SupportedDbusPropertyTypes.end()))
John Wange96e7e52019-10-05 17:47:30 +0800565 {
566 dBusMap = std::optional<DBusMapping>(
John Wang0df0e042020-01-16 10:01:36 +0800567 {objectPath, interface, propertyName, propertyType});
John Wange96e7e52019-10-05 17:47:30 +0800568 }
569 else
570 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600571 std::cerr << "Invalid dbus config, OBJPATH="
572 << dBusMap->objectPath.c_str()
573 << " INTERFACE=" << dBusMap->interface.c_str()
574 << " PROPERTY_NAME=" << dBusMap->propertyName.c_str()
John Wang0df0e042020-01-16 10:01:36 +0800575 << " PROPERTY_TYPE=" << dBusMap->propertyType.c_str()
Sampa Misraaa8ae722019-12-12 03:20:40 -0600576 << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800577 }
578 }
579 lookup.emplace(attrName, dBusMap);
580}
581
582int setupBIOSType(const BIOSJsonName& jsonName, const Json& entry)
583{
584 auto iter = BIOSTypeHandlers.find(jsonName);
585 if (iter != BIOSTypeHandlers.end())
586 {
587 iter->second(entry);
588 }
589 return 0;
590}
591
John Wangecb7d572019-10-17 13:38:53 +0800592const std::vector<BIOSJsonName> BIOSConfigFiles = {bIOSEnumJson, bIOSStrJson,
593 bIOSIntegerJson};
John Wange96e7e52019-10-05 17:47:30 +0800594
595int setupConfig(const char* dirPath)
596{
597 if (!BIOSStrings.empty() && !BIOSAttrLookup.empty())
598 {
599 return 0;
600 }
601
602 fs::path dir(dirPath);
Tom Joseph52552ef2019-06-20 09:50:15 +0530603 if (!fs::exists(dir) || fs::is_empty(dir))
604 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600605 std::cerr << "BIOS config directory does not exist or empty, DIR="
606 << dirPath << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800607 return -1;
Tom Joseph52552ef2019-06-20 09:50:15 +0530608 }
John Wange96e7e52019-10-05 17:47:30 +0800609 for (auto jsonName : BIOSConfigFiles)
Tom Joseph52552ef2019-06-20 09:50:15 +0530610 {
John Wange96e7e52019-10-05 17:47:30 +0800611 Json json;
John Wang0df0e042020-01-16 10:01:36 +0800612 if (parseBIOSJsonFile(dir, jsonName, json) < 0)
Tom Joseph52552ef2019-06-20 09:50:15 +0530613 {
Tom Joseph52552ef2019-06-20 09:50:15 +0530614 continue;
615 }
John Wange96e7e52019-10-05 17:47:30 +0800616 auto entries = json.value("entries", emptyJsonList);
Tom Joseph52552ef2019-06-20 09:50:15 +0530617 for (auto& entry : entries)
618 {
John Wange96e7e52019-10-05 17:47:30 +0800619 setupBIOSStrings(jsonName, entry, BIOSStrings);
620 setupBIOSAttrLookup(entry, BIOSAttrLookup);
621 setupBIOSType(jsonName, entry);
Tom Joseph52552ef2019-06-20 09:50:15 +0530622 }
623 }
John Wange96e7e52019-10-05 17:47:30 +0800624 if (BIOSStrings.empty())
625 { // means there is no attribute
Sampa Misraaa8ae722019-12-12 03:20:40 -0600626 std::cerr << "No attribute is found in the config directory, DIR="
627 << dirPath << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800628 return -1;
629 }
630 return 0;
Tom Joseph52552ef2019-06-20 09:50:15 +0530631}
632
John Wang0df0e042020-01-16 10:01:36 +0800633using setAttrValueHandler = std::function<int(
634 const AttrName&, const pldm_bios_attr_val_table_entry*,
635 const pldm_bios_attr_table_entry*, const BIOSStringTable&)>;
636
637const std::map<AttrType, setAttrValueHandler> SetAttrValueMap{{
638 {PLDM_BIOS_STRING, bios_string::setAttrValue},
639 {PLDM_BIOS_STRING_READ_ONLY, bios_string::setAttrValue},
640 {PLDM_BIOS_ENUMERATION, bios_enum::setAttrValue},
641 {PLDM_BIOS_ENUMERATION_READ_ONLY, bios_enum::setAttrValue},
642 {PLDM_BIOS_INTEGER, bios_integer::setAttrValue},
643 {PLDM_BIOS_INTEGER_READ_ONLY, bios_integer::setAttrValue},
644
645}};
646
647int setAttributeValueOnDbus(const variable_field* attributeData,
648 const BIOSTable& biosAttributeTable,
649 const BIOSStringTable& stringTable)
650{
651 Table attributeTable;
652 biosAttributeTable.load(attributeTable);
653 auto attrValueEntry =
654 reinterpret_cast<const pldm_bios_attr_val_table_entry*>(
655 attributeData->ptr);
656
657 auto attrType =
658 pldm_bios_table_attr_value_entry_decode_attribute_type(attrValueEntry);
659 auto attrHandle = pldm_bios_table_attr_value_entry_decode_attribute_handle(
660 attrValueEntry);
661
662 auto attrEntry = pldm_bios_table_attr_find_by_handle(
663 attributeTable.data(), attributeTable.size(), attrHandle);
664
665 assert(attrEntry != nullptr);
666
667 auto attrNameHandle =
668 pldm_bios_table_attr_entry_decode_string_handle(attrEntry);
669
670 auto attrName = stringTable.findString(attrNameHandle);
671
672 try
673 {
674 auto rc = SetAttrValueMap.at(attrType)(attrName, attrValueEntry,
675 attrEntry, stringTable);
676 return rc;
677 }
678 catch (const std::exception& e)
679 {
680 std::cerr << "setAttributeValueOnDbus Error: " << e.what() << std::endl;
681 return PLDM_ERROR;
682 }
683}
684
Tom Joseph52552ef2019-06-20 09:50:15 +0530685} // namespace bios_parser