blob: 0b740592e5887c1da92886ad624bd617991b13b5 [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 Wang8b85f522019-10-17 19:28:19 +0800233 propValue =
John Wang0df0e042020-01-16 10:01:36 +0800234 pldm::utils::DBusHandler().getDbusPropertyVariant<PropertyValue>(
235 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
236 dBusMap->interface.c_str());
237
John Wange96e7e52019-10-05 17:47:30 +0800238 auto iter = dbusValToValMap.find(propValue);
239 if (iter != dbusValToValMap.end())
Tom Joseph52552ef2019-06-20 09:50:15 +0530240 {
241 currentValues.push_back(iter->second);
242 }
243
244 return currentValues;
245}
246
John Wang0df0e042020-01-16 10:01:36 +0800247int setAttrValue(const AttrName& attrName,
248 const pldm_bios_attr_val_table_entry* attrValueEntry,
249 const pldm_bios_attr_table_entry* attrEntry,
250 const BIOSStringTable& stringTable)
251{
252 const auto& dBusMap = BIOSAttrLookup.at(attrName);
253 if (dBusMap == std::nullopt)
254 {
255 return PLDM_SUCCESS;
256 }
257
258 uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
259 std::vector<uint16_t> pvHdls(pvNum, 0);
260 pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrEntry, pvHdls.data(),
261 pvNum);
262
263 uint8_t defNum =
264 pldm_bios_table_attr_value_entry_enum_decode_number(attrValueEntry);
265
266 assert(defNum == 1);
267
268 std::vector<uint8_t> currHdls(1, 0);
269 pldm_bios_table_attr_value_entry_enum_decode_handles(
270 attrValueEntry, currHdls.data(), currHdls.size());
271
272 auto valueString = stringTable.findString(pvHdls[currHdls[0]]);
273
274 const auto& dbusValToValMap = internal::dbusValToValMaps.at(attrName);
275
276 auto it = std::find_if(dbusValToValMap.begin(), dbusValToValMap.end(),
277 [&valueString](const auto& typePair) {
278 return typePair.second == valueString;
279 });
280 if (it == dbusValToValMap.end())
281 {
282 std::cerr << "Invalid Enum Value\n";
283 return PLDM_ERROR;
284 }
285
George Liu1e44c732020-02-28 20:20:06 +0800286 pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), it->first);
John Wang0df0e042020-01-16 10:01:36 +0800287
288 return PLDM_SUCCESS;
289}
290
Tom Joseph52552ef2019-06-20 09:50:15 +0530291} // namespace bios_enum
292
Carol Wang612f35b2019-08-26 17:14:26 +0800293namespace bios_string
294{
295
296/** @brief BIOS string types
297 */
John Wang0df0e042020-01-16 10:01:36 +0800298enum BIOSStringEncoding
Carol Wang612f35b2019-08-26 17:14:26 +0800299{
300 UNKNOWN = 0x00,
301 ASCII = 0x01,
302 HEX = 0x02,
303 UTF_8 = 0x03,
304 UTF_16LE = 0x04,
305 UTF_16BE = 0x05,
306 VENDOR_SPECIFIC = 0xFF
307};
308
309const std::map<std::string, uint8_t> strTypeMap{
310 {"Unknown", UNKNOWN},
311 {"ASCII", ASCII},
312 {"Hex", HEX},
313 {"UTF-8", UTF_8},
314 {"UTF-16LE", UTF_16LE},
315 {"UTF-16LE", UTF_16LE},
316 {"Vendor Specific", VENDOR_SPECIFIC}};
317
318namespace internal
319{
320
Carol Wang612f35b2019-08-26 17:14:26 +0800321/** @brief Map containing the possible and the default values for the BIOS
322 * string type attributes.
323 */
324AttrValuesMap valueMap;
325
Carol Wang612f35b2019-08-26 17:14:26 +0800326} // namespace internal
327
John Wangecb7d572019-10-17 13:38:53 +0800328int setup(const Json& jsonEntry)
Carol Wang612f35b2019-08-26 17:14:26 +0800329{
Carol Wang612f35b2019-08-26 17:14:26 +0800330
John Wangecb7d572019-10-17 13:38:53 +0800331 std::string attr = jsonEntry.value("attribute_name", "");
John Wange96e7e52019-10-05 17:47:30 +0800332 // Transfer string type from string to enum
John Wangecb7d572019-10-17 13:38:53 +0800333 std::string strTypeTmp = jsonEntry.value("string_type", "Unknown");
John Wange96e7e52019-10-05 17:47:30 +0800334 auto iter = strTypeMap.find(strTypeTmp);
335 if (iter == strTypeMap.end())
Carol Wang612f35b2019-08-26 17:14:26 +0800336 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600337 std::cerr << "Wrong string type, STRING_TYPE=" << strTypeTmp.c_str()
338 << " ATTRIBUTE_NAME=" << attr.c_str() << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800339 return -1;
340 }
341 uint8_t strType = iter->second;
342
John Wangecb7d572019-10-17 13:38:53 +0800343 uint16_t minStrLen = jsonEntry.value("minimum_string_length", 0);
344 uint16_t maxStrLen = jsonEntry.value("maximum_string_length", 0);
345 uint16_t defaultStrLen = jsonEntry.value("default_string_length", 0);
346 std::string defaultStr = jsonEntry.value("default_string", "");
347
348 pldm_bios_table_attr_entry_string_info info = {
349 0, /* name handle */
350 false, /* read only */
351 strType, minStrLen, maxStrLen, defaultStrLen, defaultStr.data(),
352 };
353
354 const char* errmsg;
355 auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
356 if (rc != PLDM_SUCCESS)
John Wange96e7e52019-10-05 17:47:30 +0800357 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600358 std::cerr << "Wrong filed for string attribute, ATTRIBUTE_NAME="
359 << attr.c_str() << " ERRMSG=" << errmsg
360 << " MINIMUM_STRING_LENGTH=" << minStrLen
361 << " MAXIMUM_STRING_LENGTH=" << maxStrLen
362 << " DEFAULT_STRING_LENGTH=" << defaultStrLen
363 << " DEFAULT_STRING=" << defaultStr.data() << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800364 return -1;
Carol Wang612f35b2019-08-26 17:14:26 +0800365 }
366
John Wange96e7e52019-10-05 17:47:30 +0800367 // Defaulting all the types of attributes to BIOSString
368 internal::valueMap.emplace(
369 std::move(attr),
John Wangecb7d572019-10-17 13:38:53 +0800370 std::make_tuple(jsonEntry.count("dbus") == 0, strType, minStrLen,
371 maxStrLen, defaultStrLen, std::move(defaultStr)));
Carol Wang612f35b2019-08-26 17:14:26 +0800372
John Wange96e7e52019-10-05 17:47:30 +0800373 return 0;
Carol Wang612f35b2019-08-26 17:14:26 +0800374}
375
376const AttrValuesMap& getValues()
377{
378 return internal::valueMap;
379}
Carol Wangb503f9e2019-09-02 16:34:10 +0800380
381std::string getAttrValue(const AttrName& attrName)
382{
John Wange96e7e52019-10-05 17:47:30 +0800383 const auto& dBusMap = BIOSAttrLookup.at(attrName);
Carol Wangb503f9e2019-09-02 16:34:10 +0800384 std::variant<std::string> propValue;
385
386 if (dBusMap == std::nullopt)
387 { // return default string
388 const auto& valueEntry = internal::valueMap.at(attrName);
389 return std::get<DefaultStr>(valueEntry);
390 }
391
George Liu83409572019-12-24 18:42:54 +0800392 return pldm::utils::DBusHandler().getDbusProperty<std::string>(
John Wang8b85f522019-10-17 19:28:19 +0800393 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
394 dBusMap->interface.c_str());
Carol Wangb503f9e2019-09-02 16:34:10 +0800395}
396
John Wang0df0e042020-01-16 10:01:36 +0800397std::string stringToUtf8(BIOSStringEncoding stringType,
398 const std::vector<uint8_t>& data)
399{
400 switch (stringType)
401 {
402 case ASCII:
403 case UTF_8:
404 case HEX:
405 return std::string(data.begin(), data.end());
406 case UTF_16BE:
407 case UTF_16LE: // TODO
408 return std::string(data.begin(), data.end());
409 case VENDOR_SPECIFIC:
410 throw std::invalid_argument("Vendor Specific is unsupported");
411 case UNKNOWN:
412 throw std::invalid_argument("Unknown String Type");
413 }
414 throw std::invalid_argument("String Type Error");
415}
416
417int setAttrValue(const AttrName& attrName,
418 const pldm_bios_attr_val_table_entry* attrValueEntry,
419 const pldm_bios_attr_table_entry* attrEntry,
420 const BIOSStringTable&)
421{
422 const auto& dBusMap = BIOSAttrLookup.at(attrName);
423 if (dBusMap == std::nullopt)
424 {
425 return PLDM_SUCCESS;
426 }
427
428 auto stringType =
429 pldm_bios_table_attr_entry_string_decode_string_type(attrEntry);
430
431 variable_field currentString{};
432 pldm_bios_table_attr_value_entry_string_decode_string(attrValueEntry,
433 &currentString);
434 std::vector<uint8_t> data(currentString.ptr,
435 currentString.ptr + currentString.length);
436
George Liu1e44c732020-02-28 20:20:06 +0800437 PropertyValue value =
John Wang0df0e042020-01-16 10:01:36 +0800438 stringToUtf8(static_cast<BIOSStringEncoding>(stringType), data);
George Liu1e44c732020-02-28 20:20:06 +0800439 pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
John Wang0df0e042020-01-16 10:01:36 +0800440
441 return PLDM_SUCCESS;
442}
443
Carol Wang612f35b2019-08-26 17:14:26 +0800444} // namespace bios_string
445
John Wangecb7d572019-10-17 13:38:53 +0800446namespace bios_integer
447{
448
449AttrValuesMap valueMap;
450
451int setup(const Json& jsonEntry)
452{
453
454 std::string attr = jsonEntry.value("attribute_name", "");
455 // Transfer string type from string to enum
456
457 uint64_t lowerBound = jsonEntry.value("lower_bound", 0);
458 uint64_t upperBound = jsonEntry.value("upper_bound", 0);
459 uint32_t scalarIncrement = jsonEntry.value("scalar_increment", 1);
460 uint64_t defaultValue = jsonEntry.value("default_value", 0);
461 pldm_bios_table_attr_entry_integer_info info = {
462 0, /* name handle*/
463 false, /* read only */
464 lowerBound, upperBound, scalarIncrement, defaultValue,
465 };
466 const char* errmsg = nullptr;
467 auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
468 if (rc != PLDM_SUCCESS)
469 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600470 std::cerr << "Wrong filed for integer attribute, ATTRIBUTE_NAME="
471 << attr.c_str() << " ERRMSG=" << errmsg
472 << " LOWER_BOUND=" << lowerBound
473 << " UPPER_BOUND=" << upperBound
474 << " DEFAULT_VALUE=" << defaultValue
475 << " SCALAR_INCREMENT=" << scalarIncrement << "\n";
John Wangecb7d572019-10-17 13:38:53 +0800476 return -1;
477 }
478
479 valueMap.emplace(std::move(attr),
480 std::make_tuple(jsonEntry.count("dbus") == 0, lowerBound,
481 upperBound, scalarIncrement,
482 defaultValue));
483
484 return 0;
485}
486
487const AttrValuesMap& getValues()
488{
489 return valueMap;
490}
491
492uint64_t getAttrValue(const AttrName& attrName)
493{
494 const auto& dBusMap = BIOSAttrLookup.at(attrName);
495 std::variant<std::string> propValue;
496
497 if (dBusMap == std::nullopt)
498 { // return default string
499 const auto& valueEntry = valueMap.at(attrName);
500 return std::get<AttrDefaultValue>(valueEntry);
501 }
502
George Liu83409572019-12-24 18:42:54 +0800503 return pldm::utils::DBusHandler().getDbusProperty<uint64_t>(
John Wangecb7d572019-10-17 13:38:53 +0800504 dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
505 dBusMap->interface.c_str());
506}
507
John Wang0df0e042020-01-16 10:01:36 +0800508int setAttrValue(const AttrName& attrName,
509 const pldm_bios_attr_val_table_entry* attrValueEntry,
510 const pldm_bios_attr_table_entry*, const BIOSStringTable&)
511{
512 const auto& dBusMap = BIOSAttrLookup.at(attrName);
513 if (dBusMap == std::nullopt)
514 {
515 return PLDM_SUCCESS;
516 }
517
518 uint64_t currentValue =
519 pldm_bios_table_attr_value_entry_integer_decode_cv(attrValueEntry);
520
George Liu1e44c732020-02-28 20:20:06 +0800521 PropertyValue value = static_cast<uint64_t>(currentValue);
522 pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
John Wang0df0e042020-01-16 10:01:36 +0800523
524 return PLDM_SUCCESS;
525}
526
John Wangecb7d572019-10-17 13:38:53 +0800527} // namespace bios_integer
528
John Wange96e7e52019-10-05 17:47:30 +0800529const std::map<BIOSJsonName, BIOSStringHandler> BIOSStringHandlers = {
530 {bIOSEnumJson, bios_enum::setupBIOSStrings},
531};
Tom Joseph52552ef2019-06-20 09:50:15 +0530532
John Wange96e7e52019-10-05 17:47:30 +0800533const std::map<BIOSJsonName, typeHandler> BIOSTypeHandlers = {
534 {bIOSEnumJson, bios_enum::setup},
535 {bIOSStrJson, bios_string::setup},
John Wangecb7d572019-10-17 13:38:53 +0800536 {bIOSIntegerJson, bios_integer::setup},
John Wange96e7e52019-10-05 17:47:30 +0800537};
538
539void setupBIOSStrings(const BIOSJsonName& jsonName, const Json& entry,
540 Strings& strings)
541{
542 strings.emplace_back(entry.value("attribute_name", ""));
543 auto iter = BIOSStringHandlers.find(jsonName);
544 if (iter != BIOSStringHandlers.end())
545 {
546 iter->second(entry, strings);
547 }
548}
549
John Wangecb7d572019-10-17 13:38:53 +0800550void setupBIOSAttrLookup(const Json& jsonEntry, AttrLookup& lookup)
John Wange96e7e52019-10-05 17:47:30 +0800551{
552 std::optional<DBusMapping> dBusMap;
John Wangecb7d572019-10-17 13:38:53 +0800553 std::string attrName = jsonEntry.value("attribute_name", "");
John Wange96e7e52019-10-05 17:47:30 +0800554
John Wangecb7d572019-10-17 13:38:53 +0800555 if (jsonEntry.count("dbus") != 0)
John Wange96e7e52019-10-05 17:47:30 +0800556 {
John Wangecb7d572019-10-17 13:38:53 +0800557 auto dBusEntry = jsonEntry.value("dbus", emptyJson);
John Wange96e7e52019-10-05 17:47:30 +0800558 std::string objectPath = dBusEntry.value("object_path", "");
559 std::string interface = dBusEntry.value("interface", "");
560 std::string propertyName = dBusEntry.value("property_name", "");
John Wang0df0e042020-01-16 10:01:36 +0800561 std::string propertyType = dBusEntry.value("property_type", "");
562 if (!objectPath.empty() && !interface.empty() &&
563 !propertyName.empty() &&
564 (SupportedDbusPropertyTypes.find(propertyType) !=
565 SupportedDbusPropertyTypes.end()))
John Wange96e7e52019-10-05 17:47:30 +0800566 {
567 dBusMap = std::optional<DBusMapping>(
John Wang0df0e042020-01-16 10:01:36 +0800568 {objectPath, interface, propertyName, propertyType});
John Wange96e7e52019-10-05 17:47:30 +0800569 }
570 else
571 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600572 std::cerr << "Invalid dbus config, OBJPATH="
573 << dBusMap->objectPath.c_str()
574 << " INTERFACE=" << dBusMap->interface.c_str()
575 << " PROPERTY_NAME=" << dBusMap->propertyName.c_str()
John Wang0df0e042020-01-16 10:01:36 +0800576 << " PROPERTY_TYPE=" << dBusMap->propertyType.c_str()
Sampa Misraaa8ae722019-12-12 03:20:40 -0600577 << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800578 }
579 }
580 lookup.emplace(attrName, dBusMap);
581}
582
583int setupBIOSType(const BIOSJsonName& jsonName, const Json& entry)
584{
585 auto iter = BIOSTypeHandlers.find(jsonName);
586 if (iter != BIOSTypeHandlers.end())
587 {
588 iter->second(entry);
589 }
590 return 0;
591}
592
John Wangecb7d572019-10-17 13:38:53 +0800593const std::vector<BIOSJsonName> BIOSConfigFiles = {bIOSEnumJson, bIOSStrJson,
594 bIOSIntegerJson};
John Wange96e7e52019-10-05 17:47:30 +0800595
596int setupConfig(const char* dirPath)
597{
598 if (!BIOSStrings.empty() && !BIOSAttrLookup.empty())
599 {
600 return 0;
601 }
602
603 fs::path dir(dirPath);
Tom Joseph52552ef2019-06-20 09:50:15 +0530604 if (!fs::exists(dir) || fs::is_empty(dir))
605 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600606 std::cerr << "BIOS config directory does not exist or empty, DIR="
607 << dirPath << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800608 return -1;
Tom Joseph52552ef2019-06-20 09:50:15 +0530609 }
John Wange96e7e52019-10-05 17:47:30 +0800610 for (auto jsonName : BIOSConfigFiles)
Tom Joseph52552ef2019-06-20 09:50:15 +0530611 {
John Wange96e7e52019-10-05 17:47:30 +0800612 Json json;
John Wang0df0e042020-01-16 10:01:36 +0800613 if (parseBIOSJsonFile(dir, jsonName, json) < 0)
Tom Joseph52552ef2019-06-20 09:50:15 +0530614 {
Tom Joseph52552ef2019-06-20 09:50:15 +0530615 continue;
616 }
John Wange96e7e52019-10-05 17:47:30 +0800617 auto entries = json.value("entries", emptyJsonList);
Tom Joseph52552ef2019-06-20 09:50:15 +0530618 for (auto& entry : entries)
619 {
John Wange96e7e52019-10-05 17:47:30 +0800620 setupBIOSStrings(jsonName, entry, BIOSStrings);
621 setupBIOSAttrLookup(entry, BIOSAttrLookup);
622 setupBIOSType(jsonName, entry);
Tom Joseph52552ef2019-06-20 09:50:15 +0530623 }
624 }
John Wange96e7e52019-10-05 17:47:30 +0800625 if (BIOSStrings.empty())
626 { // means there is no attribute
Sampa Misraaa8ae722019-12-12 03:20:40 -0600627 std::cerr << "No attribute is found in the config directory, DIR="
628 << dirPath << "\n";
John Wange96e7e52019-10-05 17:47:30 +0800629 return -1;
630 }
631 return 0;
Tom Joseph52552ef2019-06-20 09:50:15 +0530632}
633
John Wang0df0e042020-01-16 10:01:36 +0800634using setAttrValueHandler = std::function<int(
635 const AttrName&, const pldm_bios_attr_val_table_entry*,
636 const pldm_bios_attr_table_entry*, const BIOSStringTable&)>;
637
638const std::map<AttrType, setAttrValueHandler> SetAttrValueMap{{
639 {PLDM_BIOS_STRING, bios_string::setAttrValue},
640 {PLDM_BIOS_STRING_READ_ONLY, bios_string::setAttrValue},
641 {PLDM_BIOS_ENUMERATION, bios_enum::setAttrValue},
642 {PLDM_BIOS_ENUMERATION_READ_ONLY, bios_enum::setAttrValue},
643 {PLDM_BIOS_INTEGER, bios_integer::setAttrValue},
644 {PLDM_BIOS_INTEGER_READ_ONLY, bios_integer::setAttrValue},
645
646}};
647
648int setAttributeValueOnDbus(const variable_field* attributeData,
649 const BIOSTable& biosAttributeTable,
650 const BIOSStringTable& stringTable)
651{
652 Table attributeTable;
653 biosAttributeTable.load(attributeTable);
654 auto attrValueEntry =
655 reinterpret_cast<const pldm_bios_attr_val_table_entry*>(
656 attributeData->ptr);
657
658 auto attrType =
659 pldm_bios_table_attr_value_entry_decode_attribute_type(attrValueEntry);
660 auto attrHandle = pldm_bios_table_attr_value_entry_decode_attribute_handle(
661 attrValueEntry);
662
663 auto attrEntry = pldm_bios_table_attr_find_by_handle(
664 attributeTable.data(), attributeTable.size(), attrHandle);
665
666 assert(attrEntry != nullptr);
667
668 auto attrNameHandle =
669 pldm_bios_table_attr_entry_decode_string_handle(attrEntry);
670
671 auto attrName = stringTable.findString(attrNameHandle);
672
673 try
674 {
675 auto rc = SetAttrValueMap.at(attrType)(attrName, attrValueEntry,
676 attrEntry, stringTable);
677 return rc;
678 }
679 catch (const std::exception& e)
680 {
681 std::cerr << "setAttributeValueOnDbus Error: " << e.what() << std::endl;
682 return PLDM_ERROR;
683 }
684}
685
Tom Joseph52552ef2019-06-20 09:50:15 +0530686} // namespace bios_parser