blob: ee634c9cd3b9293e432cef58aa33fdda0d92fe56 [file] [log] [blame]
John Wangd9659342020-02-27 16:46:05 +08001#include "bios_config.hpp"
2
John Wang3be70852020-02-13 15:59:04 +08003#include "bios_enum_attribute.hpp"
John Wang95e6b3c2020-02-13 09:43:24 +08004#include "bios_integer_attribute.hpp"
John Wangd9659342020-02-27 16:46:05 +08005#include "bios_string_attribute.hpp"
Sampa Misra46ece062020-03-18 07:17:44 -05006#include "bios_table.hpp"
George Liu1b180d82020-07-23 14:01:58 +08007#include "common/bios_utils.hpp"
John Wangd9659342020-02-27 16:46:05 +08008
9#include <fstream>
10#include <iostream>
11
12namespace pldm
13{
14namespace responder
15{
16namespace bios
17{
18namespace
19{
20
21constexpr auto enumJsonFile = "enum_attrs.json";
22constexpr auto stringJsonFile = "string_attrs.json";
23constexpr auto integerJsonFile = "integer_attrs.json";
24
25constexpr auto stringTableFile = "stringTable";
26constexpr auto attrTableFile = "attributeTable";
27constexpr auto attrValueTableFile = "attributeValueTable";
28
29} // namespace
30
31BIOSConfig::BIOSConfig(const char* jsonDir, const char* tableDir,
32 DBusHandler* const dbusHandler) :
33 jsonDir(jsonDir),
George Liu1b180d82020-07-23 14:01:58 +080034 tableDir(tableDir), dbusHandler(dbusHandler), isUpdateProperty(false)
John Wangd9659342020-02-27 16:46:05 +080035{
George Liu9d8921e2020-05-14 15:41:50 +080036 fs::create_directories(tableDir);
John Wangd9659342020-02-27 16:46:05 +080037 constructAttributes();
38}
39
40void BIOSConfig::buildTables()
41{
John Wangd9659342020-02-27 16:46:05 +080042 auto stringTable = buildAndStoreStringTable();
43 if (stringTable)
44 {
45 buildAndStoreAttrTables(*stringTable);
46 }
47}
48
49std::optional<Table> BIOSConfig::getBIOSTable(pldm_bios_table_types tableType)
50{
51 fs::path tablePath;
52 switch (tableType)
53 {
54 case PLDM_BIOS_STRING_TABLE:
55 tablePath = tableDir / stringTableFile;
56 break;
57 case PLDM_BIOS_ATTR_TABLE:
58 tablePath = tableDir / attrTableFile;
59 break;
60 case PLDM_BIOS_ATTR_VAL_TABLE:
61 tablePath = tableDir / attrValueTableFile;
62 break;
63 }
64 return loadTable(tablePath);
65}
66
George Liu1b180d82020-07-23 14:01:58 +080067int BIOSConfig::setBIOSTable(uint8_t tableType, const Table& table)
68{
69 fs::path stringTablePath(tableDir / stringTableFile);
70 fs::path attrTablePath(tableDir / attrTableFile);
71 fs::path attrValueTablePath(tableDir / attrValueTableFile);
72
73 if (!pldm_bios_table_checksum(table.data(), table.size()))
74 {
75 return PLDM_INVALID_BIOS_TABLE_DATA_INTEGRITY_CHECK;
76 }
77
78 if (tableType == PLDM_BIOS_STRING_TABLE)
79 {
80 storeTable(stringTablePath, table);
81 }
82 else if (tableType == PLDM_BIOS_ATTR_TABLE)
83 {
84 BIOSTable biosStringTable(stringTablePath.c_str());
85 if (biosStringTable.isEmpty())
86 {
87 return PLDM_INVALID_BIOS_TABLE_TYPE;
88 }
89
90 auto rc = checkAttributeTable(table);
91 if (rc != PLDM_SUCCESS)
92 {
93 return rc;
94 }
95
96 storeTable(attrTablePath, table);
97 }
98 else if (tableType == PLDM_BIOS_ATTR_VAL_TABLE)
99 {
100 BIOSTable biosStringTable(stringTablePath.c_str());
101 BIOSTable biosStringValueTable(attrTablePath.c_str());
102 if (biosStringTable.isEmpty() || biosStringValueTable.isEmpty())
103 {
104 return PLDM_INVALID_BIOS_TABLE_TYPE;
105 }
106
107 auto rc = checkAttributeValueTable(table);
108 if (rc != PLDM_SUCCESS)
109 {
110 return rc;
111 }
112
113 storeTable(attrValueTablePath, table);
114 isUpdateProperty = true;
115 }
116 else
117 {
118 return PLDM_INVALID_BIOS_TABLE_TYPE;
119 }
120
121 if (isUpdateProperty)
122 {
123 isUpdateProperty = false;
124 updateBaseBIOSTableProperty();
125 }
126
127 return PLDM_SUCCESS;
128}
129
130int BIOSConfig::checkAttributeTable(const Table& table)
131{
132 using namespace pldm::bios::utils;
133 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
134 for (auto entry :
135 BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(table.data(), table.size()))
136 {
137 auto attrNameHandle =
138 pldm_bios_table_attr_entry_decode_string_handle(entry);
139
140 auto stringEnty = pldm_bios_table_string_find_by_handle(
141 stringTable->data(), stringTable->size(), attrNameHandle);
142 if (stringEnty == nullptr)
143 {
144 return PLDM_INVALID_BIOS_ATTR_HANDLE;
145 }
146
147 auto attrType = static_cast<pldm_bios_attribute_type>(
148 pldm_bios_table_attr_entry_decode_attribute_type(entry));
149
150 switch (attrType)
151 {
152 case PLDM_BIOS_ENUMERATION:
153 case PLDM_BIOS_ENUMERATION_READ_ONLY:
154 {
155 auto pvNum =
156 pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
157 std::vector<uint16_t> pvHandls(pvNum);
158 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
159 entry, pvHandls.data(), pvHandls.size());
160 auto defNum =
161 pldm_bios_table_attr_entry_enum_decode_def_num(entry);
162 std::vector<uint8_t> defIndices(defNum);
163 pldm_bios_table_attr_entry_enum_decode_def_indices(
164 entry, defIndices.data(), defIndices.size());
165
166 for (size_t i = 0; i < pvHandls.size(); i++)
167 {
168 auto stringEntry = pldm_bios_table_string_find_by_handle(
169 stringTable->data(), stringTable->size(), pvHandls[i]);
170 if (stringEntry == nullptr)
171 {
172 return PLDM_INVALID_BIOS_ATTR_HANDLE;
173 }
174 }
175
176 for (size_t i = 0; i < defIndices.size(); i++)
177 {
178 auto stringEntry = pldm_bios_table_string_find_by_handle(
179 stringTable->data(), stringTable->size(),
180 pvHandls[defIndices[i]]);
181 if (stringEntry == nullptr)
182 {
183 return PLDM_INVALID_BIOS_ATTR_HANDLE;
184 }
185 }
186 break;
187 }
188 case PLDM_BIOS_INTEGER:
189 case PLDM_BIOS_INTEGER_READ_ONLY:
190 case PLDM_BIOS_STRING:
191 case PLDM_BIOS_STRING_READ_ONLY:
192 case PLDM_BIOS_PASSWORD:
193 case PLDM_BIOS_PASSWORD_READ_ONLY:
194 break;
195 default:
196 return PLDM_INVALID_BIOS_ATTR_HANDLE;
197 }
198 }
199
200 return PLDM_SUCCESS;
201}
202
203int BIOSConfig::checkAttributeValueTable(const Table& table)
204{
205 using namespace pldm::bios::utils;
206 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
207 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
208
209 baseBIOSTableMaps.clear();
210
211 for (auto tableEntry :
212 BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(table.data(), table.size()))
213 {
214 AttributeName attributeName{};
215 AttributeType attributeType{};
216 ReadonlyStatus readonlyStatus{};
217 DisplayName displayName{};
218 Description description{};
219 MenuPath menuPath{};
220 CurrentValue currentValue{};
221 DefaultValue defaultValue{};
222 Option options{};
223
224 auto attrValueHandle =
225 pldm_bios_table_attr_value_entry_decode_attribute_handle(
226 tableEntry);
227 auto attrType = static_cast<pldm_bios_attribute_type>(
228 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
229
230 auto attrEntry = pldm_bios_table_attr_find_by_handle(
231 attrTable->data(), attrTable->size(), attrValueHandle);
232 if (attrEntry == nullptr)
233 {
234 return PLDM_INVALID_BIOS_ATTR_HANDLE;
235 }
236 auto attrHandle =
237 pldm_bios_table_attr_entry_decode_attribute_handle(attrEntry);
238 auto attrNameHandle =
239 pldm_bios_table_attr_entry_decode_string_handle(attrEntry);
240
241 auto stringEntry = pldm_bios_table_string_find_by_handle(
242 stringTable->data(), stringTable->size(), attrNameHandle);
243 if (stringEntry == nullptr)
244 {
245 return PLDM_INVALID_BIOS_ATTR_HANDLE;
246 }
247 auto strLength =
248 pldm_bios_table_string_entry_decode_string_length(stringEntry);
249 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
250 pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
251 buffer.size());
252 attributeName = std::string(buffer.data(), buffer.data() + strLength);
253
254 if (!biosAttributes.empty())
255 {
256 readonlyStatus =
257 biosAttributes[attrHandle / biosAttributes.size()]->readOnly;
258 }
259
260 switch (attrType)
261 {
262 case PLDM_BIOS_ENUMERATION:
263 case PLDM_BIOS_ENUMERATION_READ_ONLY:
264 {
265 auto getValue = [](uint16_t handle,
266 const Table& table) -> std::string {
267 auto stringEntry = pldm_bios_table_string_find_by_handle(
268 table.data(), table.size(), handle);
269
270 auto strLength =
271 pldm_bios_table_string_entry_decode_string_length(
272 stringEntry);
273 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
274 pldm_bios_table_string_entry_decode_string(
275 stringEntry, buffer.data(), buffer.size());
276
277 return std::string(buffer.data(),
278 buffer.data() + strLength);
279 };
280
281 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
282 "AttributeType.Enumeration";
283
284 auto pvNum =
285 pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
286 std::vector<uint16_t> pvHandls(pvNum);
287 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
288 attrEntry, pvHandls.data(), pvHandls.size());
289
290 // get possible_value
291 for (size_t i = 0; i < pvHandls.size(); i++)
292 {
293 options.push_back(
294 std::make_tuple("xyz.openbmc_project.BIOSConfig."
295 "Manager.BoundType.OneOf",
296 getValue(pvHandls[i], *stringTable)));
297 }
298
299 auto count =
300 pldm_bios_table_attr_value_entry_enum_decode_number(
301 tableEntry);
302 std::vector<uint8_t> handles(count);
303 pldm_bios_table_attr_value_entry_enum_decode_handles(
304 tableEntry, handles.data(), handles.size());
305
306 // get current_value
307 for (size_t i = 0; i < handles.size(); i++)
308 {
309 currentValue = getValue(pvHandls[handles[i]], *stringTable);
310 }
311
312 auto defNum =
313 pldm_bios_table_attr_entry_enum_decode_def_num(attrEntry);
314 std::vector<uint8_t> defIndices(defNum);
315 pldm_bios_table_attr_entry_enum_decode_def_indices(
316 attrEntry, defIndices.data(), defIndices.size());
317
318 // get default_value
319 for (size_t i = 0; i < defIndices.size(); i++)
320 {
321 defaultValue =
322 getValue(pvHandls[defIndices[i]], *stringTable);
323 }
324
325 break;
326 }
327 case PLDM_BIOS_INTEGER:
328 case PLDM_BIOS_INTEGER_READ_ONLY:
329 {
330 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
331 "AttributeType.Integer";
332 currentValue = static_cast<int64_t>(
333 pldm_bios_table_attr_value_entry_integer_decode_cv(
334 tableEntry));
335
336 uint64_t lower, upper, def;
337 uint32_t scalar;
338 pldm_bios_table_attr_entry_integer_decode(
339 attrEntry, &lower, &upper, &scalar, &def);
340 options.push_back(
341 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
342 "BoundType.LowerBound",
343 static_cast<int64_t>(lower)));
344 options.push_back(
345 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
346 "BoundType.UpperBound",
347 static_cast<int64_t>(upper)));
348 options.push_back(
349 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
350 "BoundType.ScalarIncrement",
351 static_cast<int64_t>(scalar)));
352 defaultValue = static_cast<int64_t>(def);
353 break;
354 }
355 case PLDM_BIOS_STRING:
356 case PLDM_BIOS_STRING_READ_ONLY:
357 {
358 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
359 "AttributeType.String";
360 variable_field currentString;
361 pldm_bios_table_attr_value_entry_string_decode_string(
362 tableEntry, &currentString);
363 currentValue = std::string(
364 reinterpret_cast<const char*>(currentString.ptr),
365 currentString.length);
366 auto min = pldm_bios_table_attr_entry_string_decode_min_length(
367 attrEntry);
368 auto max = pldm_bios_table_attr_entry_string_decode_max_length(
369 attrEntry);
370 auto def =
371 pldm_bios_table_attr_entry_string_decode_def_string_length(
372 attrEntry);
373 std::vector<char> defString(def + 1);
374 pldm_bios_table_attr_entry_string_decode_def_string(
375 attrEntry, defString.data(), defString.size());
376 options.push_back(
377 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
378 "BoundType.MinStringLength",
379 static_cast<int64_t>(min)));
380 options.push_back(
381 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
382 "BoundType.MaxStringLength",
383 static_cast<int64_t>(max)));
384 defaultValue = defString.data();
385 break;
386 }
387 case PLDM_BIOS_PASSWORD:
388 case PLDM_BIOS_PASSWORD_READ_ONLY:
389 {
390 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
391 "AttributeType.Password";
392 break;
393 }
394 default:
395 return PLDM_INVALID_BIOS_ATTR_HANDLE;
396 }
397 baseBIOSTableMaps.emplace(
398 std::move(attributeName),
399 std::make_tuple(attributeType, readonlyStatus, displayName,
400 description, menuPath, currentValue, defaultValue,
401 std::move(options)));
402 }
403
404 return PLDM_SUCCESS;
405}
406
407void BIOSConfig::updateBaseBIOSTableProperty()
408{
409 constexpr static auto biosConfigPath =
410 "/xyz/openbmc_project/bios_config/manager";
411 constexpr static auto biosConfigInterface =
412 "xyz.openbmc_project.BIOSConfig.Manager";
413 constexpr static auto biosConfigPropertyName = "BaseBIOSTable";
414 constexpr static auto dbusProperties = "org.freedesktop.DBus.Properties";
415
416 if (baseBIOSTableMaps.empty())
417 {
418 return;
419 }
420
421 try
422 {
423 auto& bus = dbusHandler->getBus();
424 auto service =
425 dbusHandler->getService(biosConfigPath, biosConfigInterface);
426 auto method = bus.new_method_call(service.c_str(), biosConfigPath,
427 dbusProperties, "Set");
428 std::variant<BaseBIOSTable> value = baseBIOSTableMaps;
429 method.append(biosConfigInterface, biosConfigPropertyName, value);
430 bus.call_noreply(method);
431 }
432 catch (const std::exception& e)
433 {
434 std::cerr << "failed to update BaseBIOSTable property, ERROR="
435 << e.what() << "\n";
436 }
437}
438
John Wangd9659342020-02-27 16:46:05 +0800439void BIOSConfig::constructAttributes()
440{
441 load(jsonDir / stringJsonFile, [this](const Json& entry) {
442 constructAttribute<BIOSStringAttribute>(entry);
443 });
John Wang3be70852020-02-13 15:59:04 +0800444 load(jsonDir / integerJsonFile, [this](const Json& entry) {
John Wang95e6b3c2020-02-13 09:43:24 +0800445 constructAttribute<BIOSIntegerAttribute>(entry);
446 });
John Wang3be70852020-02-13 15:59:04 +0800447 load(jsonDir / enumJsonFile, [this](const Json& entry) {
448 constructAttribute<BIOSEnumAttribute>(entry);
449 });
John Wangd9659342020-02-27 16:46:05 +0800450}
451
452void BIOSConfig::buildAndStoreAttrTables(const Table& stringTable)
453{
454 BIOSStringTable biosStringTable(stringTable);
455
456 if (biosAttributes.empty())
457 {
458 return;
459 }
460
461 Table attrTable, attrValueTable;
462
463 for (auto& attr : biosAttributes)
464 {
465 try
466 {
467 attr->constructEntry(biosStringTable, attrTable, attrValueTable);
468 }
469 catch (const std::exception& e)
470 {
471 std::cerr << "Construct Table Entry Error, AttributeName = "
472 << attr->name << std::endl;
473 }
474 }
475
476 table::appendPadAndChecksum(attrTable);
477 table::appendPadAndChecksum(attrValueTable);
George Liu1b180d82020-07-23 14:01:58 +0800478 setBIOSTable(PLDM_BIOS_ATTR_TABLE, attrTable);
479 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, attrValueTable);
John Wangd9659342020-02-27 16:46:05 +0800480}
481
482std::optional<Table> BIOSConfig::buildAndStoreStringTable()
483{
484 std::set<std::string> strings;
485 auto handler = [&strings](const Json& entry) {
486 strings.emplace(entry.at("attribute_name"));
487 };
488
489 load(jsonDir / stringJsonFile, handler);
490 load(jsonDir / integerJsonFile, handler);
491 load(jsonDir / enumJsonFile, [&strings](const Json& entry) {
492 strings.emplace(entry.at("attribute_name"));
493 auto possibleValues = entry.at("possible_values");
494 for (auto& pv : possibleValues)
495 {
496 strings.emplace(pv);
497 }
498 });
499
500 if (strings.empty())
501 {
502 return std::nullopt;
503 }
504
505 Table table;
506 for (const auto& elem : strings)
507 {
508 table::string::constructEntry(table, elem);
509 }
510
511 table::appendPadAndChecksum(table);
George Liu1b180d82020-07-23 14:01:58 +0800512 setBIOSTable(PLDM_BIOS_STRING_TABLE, table);
John Wangd9659342020-02-27 16:46:05 +0800513 return table;
514}
515
516void BIOSConfig::storeTable(const fs::path& path, const Table& table)
517{
518 BIOSTable biosTable(path.c_str());
519 biosTable.store(table);
520}
521
522std::optional<Table> BIOSConfig::loadTable(const fs::path& path)
523{
524 BIOSTable biosTable(path.c_str());
525 if (biosTable.isEmpty())
526 {
527 return std::nullopt;
528 }
529
530 Table table;
531 biosTable.load(table);
532 return table;
533}
534
535void BIOSConfig::load(const fs::path& filePath, ParseHandler handler)
536{
537 std::ifstream file;
538 Json jsonConf;
539 if (fs::exists(filePath))
540 {
541 try
542 {
543 file.open(filePath);
544 jsonConf = Json::parse(file);
545 auto entries = jsonConf.at("entries");
546 for (auto& entry : entries)
547 {
548 try
549 {
550 handler(entry);
551 }
552 catch (const std::exception& e)
553 {
554 std::cerr
555 << "Failed to parse JSON config file(entry handler) : "
556 << filePath.c_str() << ", " << e.what() << std::endl;
557 }
558 }
559 }
560 catch (const std::exception& e)
561 {
562 std::cerr << "Failed to parse JSON config file : "
563 << filePath.c_str() << std::endl;
564 }
565 }
566}
567
John Wang8241b342020-06-05 10:49:17 +0800568int BIOSConfig::checkAttrValueToUpdate(
569 const pldm_bios_attr_val_table_entry* attrValueEntry,
570 const pldm_bios_attr_table_entry* attrEntry, Table&)
571
572{
573 auto [attrHandle, attrType] =
574 table::attribute_value::decodeHeader(attrValueEntry);
575
576 switch (attrType)
577 {
578 case PLDM_BIOS_ENUMERATION:
579 {
580 auto value =
581 table::attribute_value::decodeEnumEntry(attrValueEntry);
582 auto [pvHdls, defIndex] =
583 table::attribute::decodeEnumEntry(attrEntry);
584 assert(value.size() == 1);
585 if (value[0] >= pvHdls.size())
586 {
587 std::cerr << "Enum: Illgeal index, Index = " << (int)value[0]
588 << std::endl;
589 return PLDM_ERROR_INVALID_DATA;
590 }
591
592 return PLDM_SUCCESS;
593 }
594 case PLDM_BIOS_INTEGER:
595 {
596 auto value =
597 table::attribute_value::decodeIntegerEntry(attrValueEntry);
598 auto [lower, upper, scalar, def] =
599 table::attribute::decodeIntegerEntry(attrEntry);
600
601 if (value < lower || value > upper)
602 {
603 std::cerr << "Integer: out of bound, value = " << value
604 << std::endl;
605 return PLDM_ERROR_INVALID_DATA;
606 }
607 return PLDM_SUCCESS;
608 }
609 case PLDM_BIOS_STRING:
610 {
611 auto stringConf = table::attribute::decodeStringEntry(attrEntry);
612 auto value =
613 table::attribute_value::decodeStringEntry(attrValueEntry);
614 if (value.size() < stringConf.minLength ||
615 value.size() > stringConf.maxLength)
616 {
617 std::cerr << "String: Length error, string = " << value
618 << " length = " << value.size() << std::endl;
619 return PLDM_ERROR_INVALID_LENGTH;
620 }
621 return PLDM_SUCCESS;
622 }
623 default:
624 std::cerr << "ReadOnly or Unspported type, type = " << attrType
625 << std::endl;
626 return PLDM_ERROR;
627 };
628}
629
John Wangd9659342020-02-27 16:46:05 +0800630int BIOSConfig::setAttrValue(const void* entry, size_t size)
631{
632 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
633 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
634 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
635 if (!attrValueTable || !attrTable || !stringTable)
636 {
637 return PLDM_BIOS_TABLE_UNAVAILABLE;
638 }
639
John Wangd9659342020-02-27 16:46:05 +0800640 auto attrValueEntry =
641 reinterpret_cast<const pldm_bios_attr_val_table_entry*>(entry);
642
643 auto attrValHeader = table::attribute_value::decodeHeader(attrValueEntry);
644
645 auto attrEntry =
646 table::attribute::findByHandle(*attrTable, attrValHeader.attrHandle);
647 if (!attrEntry)
648 {
649 return PLDM_ERROR;
650 }
651
John Wang8241b342020-06-05 10:49:17 +0800652 auto rc = checkAttrValueToUpdate(attrValueEntry, attrEntry, *stringTable);
653 if (rc != PLDM_SUCCESS)
654 {
655 return rc;
656 }
657
658 auto destTable =
659 table::attribute_value::updateTable(*attrValueTable, entry, size);
660
661 if (!destTable)
662 {
663 return PLDM_ERROR;
664 }
665
John Wangd9659342020-02-27 16:46:05 +0800666 try
667 {
668 auto attrHeader = table::attribute::decodeHeader(attrEntry);
669
670 BIOSStringTable biosStringTable(*stringTable);
671 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
672
673 auto iter = std::find_if(
674 biosAttributes.begin(), biosAttributes.end(),
675 [&attrName](const auto& attr) { return attr->name == attrName; });
676
677 if (iter == biosAttributes.end())
678 {
679 return PLDM_ERROR;
680 }
681 (*iter)->setAttrValueOnDbus(attrValueEntry, attrEntry, biosStringTable);
682 }
683 catch (const std::exception& e)
684 {
685 std::cerr << "Set attribute value error: " << e.what() << std::endl;
686 return PLDM_ERROR;
687 }
688
George Liu5c3192b2020-08-13 17:35:43 +0800689 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, *destTable);
690
John Wangd9659342020-02-27 16:46:05 +0800691 return PLDM_SUCCESS;
692}
693
694void BIOSConfig::removeTables()
695{
696 try
697 {
698 fs::remove(tableDir / stringTableFile);
699 fs::remove(tableDir / attrTableFile);
700 fs::remove(tableDir / attrValueTableFile);
701 }
702 catch (const std::exception& e)
703 {
704 std::cerr << "Remove the tables error: " << e.what() << std::endl;
705 }
706}
707
Sampa Misra46ece062020-03-18 07:17:44 -0500708void BIOSConfig::processBiosAttrChangeNotification(
709 const DbusChObjProperties& chProperties, uint32_t biosAttrIndex)
710{
711 const auto& dBusMap = biosAttributes[biosAttrIndex]->getDBusMap();
712 const auto& propertyName = dBusMap->propertyName;
713 const auto& attrName = biosAttributes[biosAttrIndex]->name;
714
715 const auto it = chProperties.find(propertyName);
716 if (it == chProperties.end())
717 {
718 return;
719 }
720
721 PropertyValue newPropVal = it->second;
722 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
723 if (!stringTable.has_value())
724 {
725 std::cerr << "BIOS string table unavailable\n";
726 return;
727 }
728 BIOSStringTable biosStringTable(*stringTable);
729 uint16_t attrNameHdl{};
730 try
731 {
732 attrNameHdl = biosStringTable.findHandle(attrName);
733 }
734 catch (std::invalid_argument& e)
735 {
736 std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
737 << attrName.c_str() << "\n";
738 return;
739 }
740
741 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
742 if (!attrTable.has_value())
743 {
744 std::cerr << "Attribute table not present\n";
745 return;
746 }
747 const struct pldm_bios_attr_table_entry* tableEntry =
748 table::attribute::findByStringHandle(*attrTable, attrNameHdl);
749 if (tableEntry == nullptr)
750 {
751 std::cerr << "Attribute not found in attribute table, name= "
752 << attrName.c_str() << "name handle=" << attrNameHdl << "\n";
753 return;
754 }
755
756 auto [attrHdl, attrType, stringHdl] =
757 table::attribute::decodeHeader(tableEntry);
758
759 auto attrValueSrcTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
760
761 if (!attrValueSrcTable.has_value())
762 {
763 std::cerr << "Attribute value table not present\n";
764 return;
765 }
766
767 Table newValue;
768 auto rc = biosAttributes[biosAttrIndex]->updateAttrVal(
769 newValue, attrHdl, attrType, newPropVal);
770 if (rc != PLDM_SUCCESS)
771 {
772 std::cerr << "Could not update the attribute value table for attribute "
773 "handle="
774 << attrHdl << " and type=" << (uint32_t)attrType << "\n";
775 return;
776 }
777 auto destTable = table::attribute_value::updateTable(
778 *attrValueSrcTable, newValue.data(), newValue.size());
779 if (destTable.has_value())
780 {
781 storeTable(tableDir / attrValueTableFile, *destTable);
782 }
783}
784
John Wangd9659342020-02-27 16:46:05 +0800785} // namespace bios
786} // namespace responder
787} // namespace pldm