blob: e655ea31d055394d0f964dc18b19cb04cda26854 [file] [log] [blame]
Sridevi Ramesh98576432019-11-27 10:10:28 -06001#include "pldm_bios_cmd.hpp"
2
George Liu6492f522020-06-16 10:34:05 +08003#include "libpldm/bios_table.h"
4#include "libpldm/utils.h"
5
John Wangb754eee2020-02-15 16:10:25 +08006#include "bios_utils.hpp"
Sridevi Ramesh98576432019-11-27 10:10:28 -06007#include "pldm_cmd_helper.hpp"
John Wangb754eee2020-02-15 16:10:25 +08008#include "utils.hpp"
9
10#include <map>
11#include <optional>
Sridevi Ramesh98576432019-11-27 10:10:28 -060012
Sridevi Ramesh98576432019-11-27 10:10:28 -060013namespace pldmtool
14{
15
16namespace bios
17{
18
19namespace
20{
21
22using namespace pldmtool::helper;
John Wangb754eee2020-02-15 16:10:25 +080023using namespace pldm::bios::utils;
Sridevi Ramesh98576432019-11-27 10:10:28 -060024
25std::vector<std::unique_ptr<CommandInterface>> commands;
26
Sridevi Rameshcdfe1142020-01-31 05:42:50 -060027const std::map<const char*, pldm_bios_table_types> pldmBIOSTableTypes{
28 {"StringTable", PLDM_BIOS_STRING_TABLE},
29 {"AttributeTable", PLDM_BIOS_ATTR_TABLE},
30 {"AttributeValueTable", PLDM_BIOS_ATTR_VAL_TABLE},
31};
32
Sridevi Ramesh98576432019-11-27 10:10:28 -060033} // namespace
34
35class GetDateTime : public CommandInterface
36{
37 public:
38 ~GetDateTime() = default;
39 GetDateTime() = delete;
40 GetDateTime(const GetDateTime&) = delete;
41 GetDateTime(GetDateTime&&) = default;
42 GetDateTime& operator=(const GetDateTime&) = delete;
43 GetDateTime& operator=(GetDateTime&&) = default;
44
45 using CommandInterface::CommandInterface;
46
47 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
48 {
49 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
50 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
51
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060052 auto rc = encode_get_date_time_req(instanceId, request);
Sridevi Ramesh98576432019-11-27 10:10:28 -060053 return {rc, requestMsg};
54 }
55
56 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
57 {
58 uint8_t cc = 0;
59
60 uint8_t seconds, minutes, hours, day, month;
61 uint16_t year;
62 auto rc =
63 decode_get_date_time_resp(responsePtr, payloadLength, &cc, &seconds,
64 &minutes, &hours, &day, &month, &year);
65 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
66 {
67 std::cerr << "Response Message Error: "
68 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
69 return;
70 }
71 std::cout << "Date & Time : " << std::endl;
Sridevi Ramesh213a8552020-02-03 00:59:30 -060072 std::cout << "YYYY-MM-DD HH:MM:SS - ";
73 std::cout << bcd2dec16(year);
Sridevi Ramesh98576432019-11-27 10:10:28 -060074 std::cout << "-";
75 setWidth(month);
Sridevi Ramesh213a8552020-02-03 00:59:30 -060076 std::cout << "-";
77 setWidth(day);
78 std::cout << " ";
Sridevi Ramesh98576432019-11-27 10:10:28 -060079 setWidth(hours);
80 std::cout << ":";
81 setWidth(minutes);
82 std::cout << ":";
83 setWidth(seconds);
84 std::cout << std::endl;
85 }
86
87 private:
88 void setWidth(uint8_t data)
89 {
90 std::cout << std::setfill('0') << std::setw(2)
91 << static_cast<uint32_t>(bcd2dec8(data));
92 }
93};
94
George Liud6649362019-11-27 19:06:51 +080095class SetDateTime : public CommandInterface
96{
97 public:
98 ~SetDateTime() = default;
99 SetDateTime() = delete;
100 SetDateTime(const SetDateTime&) = delete;
101 SetDateTime(SetDateTime&&) = default;
102 SetDateTime& operator=(const SetDateTime&) = delete;
103 SetDateTime& operator=(SetDateTime&&) = default;
104
105 explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
106 CommandInterface(type, name, app)
107 {
108 app->add_option("-d,--data", tmData,
109 "set date time data\n"
110 "eg: YYYYMMDDHHMMSS")
111 ->required();
112 }
113
114 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
115 {
116 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
117 sizeof(struct pldm_set_date_time_req));
118 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
119 uint16_t year = 0;
120 uint8_t month = 0;
121 uint8_t day = 0;
122 uint8_t hours = 0;
123 uint8_t minutes = 0;
124 uint8_t seconds = 0;
125
126 if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
127 &seconds))
128 {
129 std::cerr << "decode date Error: "
130 << "tmData=" << tmData << std::endl;
131
132 return {PLDM_ERROR_INVALID_DATA, requestMsg};
133 }
134
135 auto rc = encode_set_date_time_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600136 instanceId, seconds, minutes, hours, day, month, year, request,
137 sizeof(struct pldm_set_date_time_req));
George Liud6649362019-11-27 19:06:51 +0800138
139 return {rc, requestMsg};
140 }
141
142 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
143 {
144 uint8_t completionCode = 0;
145 auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
146 &completionCode);
147
148 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
149 {
150 std::cerr << "Response Message Error: "
151 << "rc=" << rc << ",cc=" << (int)completionCode
152 << std::endl;
153 return;
154 }
155
156 std::cout << "SetDateTime: SUCCESS" << std::endl;
157 }
158
159 private:
160 uint64_t tmData;
161};
162
Adair Li4dd11a72020-04-24 14:52:59 +0800163class GetBIOSTableHandler : public CommandInterface
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600164{
165 public:
Adair Li4dd11a72020-04-24 14:52:59 +0800166 ~GetBIOSTableHandler() = default;
167 GetBIOSTableHandler() = delete;
168 GetBIOSTableHandler(const GetBIOSTableHandler&) = delete;
169 GetBIOSTableHandler(GetBIOSTableHandler&&) = delete;
170 GetBIOSTableHandler& operator=(const GetBIOSTableHandler&) = delete;
171 GetBIOSTableHandler& operator=(GetBIOSTableHandler&&) = delete;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600172
John Wangb754eee2020-02-15 16:10:25 +0800173 using Table = std::vector<uint8_t>;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600174
Adair Li4dd11a72020-04-24 14:52:59 +0800175 using CommandInterface::CommandInterface;
176
177 static inline const std::map<pldm_bios_attribute_type, const char*>
178 attrTypeMap = {
179 {PLDM_BIOS_ENUMERATION, "BIOSEnumeration"},
180 {PLDM_BIOS_ENUMERATION_READ_ONLY, "BIOSEnumerationReadOnly"},
181 {PLDM_BIOS_STRING, "BIOSString"},
182 {PLDM_BIOS_STRING_READ_ONLY, "BIOSStringReadOnly"},
183 {PLDM_BIOS_PASSWORD, "BIOSPassword"},
184 {PLDM_BIOS_PASSWORD_READ_ONLY, "BIOSPasswordReadOnly"},
185 {PLDM_BIOS_INTEGER, "BIOSInteger"},
186 {PLDM_BIOS_INTEGER_READ_ONLY, "BIOSIntegerReadOnly"},
187
188 };
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600189
190 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
191 {
John Wangb754eee2020-02-15 16:10:25 +0800192 return {PLDM_ERROR, {}};
193 }
Adair Li4dd11a72020-04-24 14:52:59 +0800194
John Wangb754eee2020-02-15 16:10:25 +0800195 void parseResponseMsg(pldm_msg*, size_t) override
George Liu6492f522020-06-16 10:34:05 +0800196 {}
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600197
John Wangb754eee2020-02-15 16:10:25 +0800198 std::optional<Table> getBIOSTable(pldm_bios_table_types tableType)
199 {
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600200 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
201 PLDM_GET_BIOS_TABLE_REQ_BYTES);
202 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
203
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600204 auto rc = encode_get_bios_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
205 tableType, request);
John Wangb754eee2020-02-15 16:10:25 +0800206 if (rc != PLDM_SUCCESS)
207 {
208 std::cerr << "Encode GetBIOSTable Error, tableType=," << tableType
209 << " ,rc=" << rc << std::endl;
210 return std::nullopt;
211 }
212 std::vector<uint8_t> responseMsg;
213 rc = pldmSendRecv(requestMsg, responseMsg);
214 if (rc != PLDM_SUCCESS)
215 {
216 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
217 return std::nullopt;
218 }
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600219
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600220 uint8_t cc = 0, transferFlag = 0;
221 uint32_t nextTransferHandle = 0;
222 size_t bios_table_offset;
John Wangb754eee2020-02-15 16:10:25 +0800223 auto responsePtr =
224 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
225 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600226
John Wangb754eee2020-02-15 16:10:25 +0800227 rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc,
228 &nextTransferHandle, &transferFlag,
229 &bios_table_offset);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600230
231 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
232 {
John Wangb754eee2020-02-15 16:10:25 +0800233 std::cerr << "GetBIOSTable Response Error: tableType=" << tableType
234 << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
235 return std::nullopt;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600236 }
237 auto tableData =
238 reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset);
John Wangb754eee2020-02-15 16:10:25 +0800239 auto tableSize = payloadLength - sizeof(nextTransferHandle) -
240 sizeof(transferFlag) - sizeof(cc);
241 return std::make_optional<Table>(tableData, tableData + tableSize);
242 }
243
Adair Lice041e22020-05-09 17:27:43 +0800244 const pldm_bios_attr_table_entry*
245 findAttrEntryByName(const std::string& name, const Table& attrTable,
246 const Table& stringTable)
John Wangb754eee2020-02-15 16:10:25 +0800247 {
Adair Li4dd11a72020-04-24 14:52:59 +0800248 auto stringEntry = pldm_bios_table_string_find_by_string(
249 stringTable.data(), stringTable.size(), name.c_str());
250 if (stringEntry == nullptr)
John Wangb754eee2020-02-15 16:10:25 +0800251 {
Adair Lice041e22020-05-09 17:27:43 +0800252 std::cout << "StringTable initialize failed" << std::endl;
253 return nullptr;
Adair Li4dd11a72020-04-24 14:52:59 +0800254 }
John Wangb754eee2020-02-15 16:10:25 +0800255
Adair Li4dd11a72020-04-24 14:52:59 +0800256 auto nameHandle =
257 pldm_bios_table_string_entry_decode_handle(stringEntry);
John Wangb754eee2020-02-15 16:10:25 +0800258
Adair Li4dd11a72020-04-24 14:52:59 +0800259 for (auto attr : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable.data(),
260 attrTable.size()))
261 {
262 auto attrNameHandle =
263 pldm_bios_table_attr_entry_decode_string_handle(attr);
264 if (attrNameHandle == nameHandle)
265 {
Adair Lice041e22020-05-09 17:27:43 +0800266 return attr;
John Wangb754eee2020-02-15 16:10:25 +0800267 }
268 }
Adair Lice041e22020-05-09 17:27:43 +0800269 return nullptr;
270 }
271
272 std::optional<uint16_t> findAttrHandleByName(const std::string& name,
273 const Table& attrTable,
274 const Table& stringTable)
275 {
276 auto attribute = findAttrEntryByName(name, attrTable, stringTable);
277 if (attribute == nullptr)
278 {
279 return std::nullopt;
280 }
281
282 return pldm_bios_table_attr_entry_decode_attribute_handle(attribute);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600283 }
284
John Wangb754eee2020-02-15 16:10:25 +0800285 std::string decodeStringFromStringEntry(
286 const pldm_bios_string_table_entry* stringEntry)
287 {
288 auto strLength =
289 pldm_bios_table_string_entry_decode_string_length(stringEntry);
290 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
291 pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
292 buffer.size());
293
294 return std::string(buffer.data(), buffer.data() + strLength);
295 }
296
297 std::string displayStringHandle(uint16_t handle,
Adair Li4dd11a72020-04-24 14:52:59 +0800298 const std::optional<Table>& stringTable,
299 bool displayHandle = true)
John Wangb754eee2020-02-15 16:10:25 +0800300 {
301 std::string displayString = std::to_string(handle);
302 if (!stringTable)
303 {
304 return displayString;
305 }
306 auto stringEntry = pldm_bios_table_string_find_by_handle(
307 stringTable->data(), stringTable->size(), handle);
308 if (stringEntry == nullptr)
309 {
310 return displayString;
311 }
312
Adair Li4dd11a72020-04-24 14:52:59 +0800313 auto decodedStr = decodeStringFromStringEntry(stringEntry);
314 if (!displayHandle)
315 {
316 return decodedStr;
317 }
318
319 return displayString + "(" + decodedStr + ")";
John Wangb754eee2020-02-15 16:10:25 +0800320 }
321
322 std::string displayEnumValueByIndex(uint16_t attrHandle, uint8_t index,
323 const std::optional<Table>& attrTable,
324 const std::optional<Table>& stringTable)
325 {
326 std::string displayString;
327 if (!attrTable)
328 {
329 return displayString;
330 }
331
332 auto attrEntry = pldm_bios_table_attr_find_by_handle(
333 attrTable->data(), attrTable->size(), attrHandle);
334 if (attrEntry == nullptr)
335 {
336 return displayString;
337 }
338 auto pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
339 std::vector<uint16_t> pvHandls(pvNum);
340 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
341 attrEntry, pvHandls.data(), pvHandls.size());
Adair Li4dd11a72020-04-24 14:52:59 +0800342 return displayStringHandle(pvHandls[index], stringTable, false);
John Wangb754eee2020-02-15 16:10:25 +0800343 }
344
Adair Li4dd11a72020-04-24 14:52:59 +0800345 void displayAttributeValueEntry(
346 const pldm_bios_attr_val_table_entry* tableEntry,
347 const std::optional<Table>& attrTable,
348 const std::optional<Table>& stringTable)
349 {
350 auto attrHandle =
351 pldm_bios_table_attr_value_entry_decode_attribute_handle(
352 tableEntry);
353 auto attrType = static_cast<pldm_bios_attribute_type>(
354 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
355 switch (attrType)
356 {
357 case PLDM_BIOS_ENUMERATION:
358 case PLDM_BIOS_ENUMERATION_READ_ONLY:
359 {
360 auto count =
361 pldm_bios_table_attr_value_entry_enum_decode_number(
362 tableEntry);
363 std::vector<uint8_t> handles(count);
364 pldm_bios_table_attr_value_entry_enum_decode_handles(
365 tableEntry, handles.data(), handles.size());
366 for (size_t i = 0; i < handles.size(); i++)
367 {
368 std::cout << "CurrentValue: "
369 << displayEnumValueByIndex(attrHandle, handles[i],
370 attrTable, stringTable)
371 << std::endl;
372 }
373 break;
374 }
375 case PLDM_BIOS_INTEGER:
376 case PLDM_BIOS_INTEGER_READ_ONLY:
377 {
378 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(
379 tableEntry);
380 std::cout << "CurrentValue: " << cv << std::endl;
381 break;
382 }
383 case PLDM_BIOS_STRING:
384 case PLDM_BIOS_STRING_READ_ONLY:
385 {
386 variable_field currentString;
387 pldm_bios_table_attr_value_entry_string_decode_string(
388 tableEntry, &currentString);
389 std::cout << "CurrentValue: "
390 << std::string(reinterpret_cast<const char*>(
391 currentString.ptr),
392 currentString.length)
393 << std::endl;
394
395 break;
396 }
397 case PLDM_BIOS_PASSWORD:
398 case PLDM_BIOS_PASSWORD_READ_ONLY:
399 {
400 std::cout << "Password attribute: Not Supported" << std::endl;
401 break;
402 }
403 }
404 }
405};
406
407class GetBIOSTable : public GetBIOSTableHandler
408{
409 public:
410 ~GetBIOSTable() = default;
411 GetBIOSTable() = delete;
412 GetBIOSTable(const GetBIOSTable&) = delete;
413 GetBIOSTable(GetBIOSTable&&) = default;
414 GetBIOSTable& operator=(const GetBIOSTable&) = delete;
415 GetBIOSTable& operator=(GetBIOSTable&&) = default;
416
417 using Table = std::vector<uint8_t>;
418
419 explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
420 GetBIOSTableHandler(type, name, app)
421 {
422 app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
423 ->required()
424 ->transform(
425 CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
426 }
427
428 void exec() override
429 {
430 switch (pldmBIOSTableType)
431 {
432 case PLDM_BIOS_STRING_TABLE:
433 {
434 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
435 decodeStringTable(stringTable);
436 break;
437 }
438 case PLDM_BIOS_ATTR_TABLE:
439 {
440 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
441 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
442
443 decodeAttributeTable(attrTable, stringTable);
444 break;
445 }
446 case PLDM_BIOS_ATTR_VAL_TABLE:
447 {
448 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
449 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
450 auto attrValTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
451
452 decodeAttributeValueTable(attrValTable, attrTable, stringTable);
453 break;
454 }
455 }
456 }
457
458 private:
459 pldm_bios_table_types pldmBIOSTableType;
460
John Wangb754eee2020-02-15 16:10:25 +0800461 void decodeStringTable(const std::optional<Table>& stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600462 {
John Wangb754eee2020-02-15 16:10:25 +0800463 if (!stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600464 {
John Wangb754eee2020-02-15 16:10:25 +0800465 std::cerr << "GetBIOSStringTable Error" << std::endl;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600466 return;
467 }
John Wangb754eee2020-02-15 16:10:25 +0800468 std::cout << "PLDM StringTable: " << std::endl;
469 std::cout << "BIOSStringHandle : BIOSString" << std::endl;
470
471 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
472 stringTable->data(), stringTable->size()))
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600473 {
John Wangb754eee2020-02-15 16:10:25 +0800474 auto strHandle =
475 pldm_bios_table_string_entry_decode_handle(tableEntry);
476 auto strTableData = decodeStringFromStringEntry(tableEntry);
477 std::cout << strHandle << " : " << strTableData << std::endl;
478 }
479 }
480 void decodeAttributeTable(const std::optional<Table>& attrTable,
481 const std::optional<Table>& stringTable)
482 {
John Wangb754eee2020-02-15 16:10:25 +0800483 if (!stringTable)
484 {
485 std::cerr << "GetBIOSAttributeTable Error" << std::endl;
486 return;
487 }
488 std::cout << "PLDM AttributeTable: " << std::endl;
489 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
490 attrTable->data(), attrTable->size()))
491 {
492 auto attrHandle =
493 pldm_bios_table_attr_entry_decode_attribute_handle(entry);
494 auto attrNameHandle =
495 pldm_bios_table_attr_entry_decode_string_handle(entry);
496 auto attrType = static_cast<pldm_bios_attribute_type>(
497 pldm_bios_table_attr_entry_decode_attribute_type(entry));
498 std::cout << "AttributeHandle: " << attrHandle
499 << ", AttributeNameHandle: "
500 << displayStringHandle(attrNameHandle, stringTable)
501 << std::endl;
502 std::cout << "\tAttributeType: " << attrTypeMap.at(attrType)
503 << std::endl;
504 switch (attrType)
505 {
506 case PLDM_BIOS_ENUMERATION:
507 case PLDM_BIOS_ENUMERATION_READ_ONLY:
508 {
509 auto pvNum =
510 pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
511 std::vector<uint16_t> pvHandls(pvNum);
512 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
513 entry, pvHandls.data(), pvHandls.size());
514 auto defNum =
515 pldm_bios_table_attr_entry_enum_decode_def_num(entry);
516 std::vector<uint8_t> defIndices(defNum);
517 pldm_bios_table_attr_entry_enum_decode_def_indices(
518 entry, defIndices.data(), defIndices.size());
519 std::cout << "\tNumberOfPossibleValues: " << (int)pvNum
520 << std::endl;
521
522 for (size_t i = 0; i < pvHandls.size(); i++)
523 {
524 std::cout
525 << "\t\tPossibleValueStringHandle"
526 << "[" << i << "] = "
527 << displayStringHandle(pvHandls[i], stringTable)
528 << std::endl;
529 }
530 std::cout << "\tNumberOfDefaultValues: " << (int)defNum
531 << std::endl;
532 for (size_t i = 0; i < defIndices.size(); i++)
533 {
534 std::cout << "\t\tDefaultValueStringHandleIndex"
535 << "[" << i << "] = " << (int)defIndices[i]
536 << ", StringHandle = "
537 << displayStringHandle(
538 pvHandls[defIndices[i]], stringTable)
539 << std::endl;
540 }
541 break;
542 }
543 case PLDM_BIOS_INTEGER:
544 case PLDM_BIOS_INTEGER_READ_ONLY:
545 {
546 uint64_t lower, upper, def;
547 uint32_t scalar;
548 pldm_bios_table_attr_entry_integer_decode(
549 entry, &lower, &upper, &scalar, &def);
550 std::cout << "\tLowerBound: " << lower << std::endl
551 << "\tUpperBound: " << upper << std::endl
552 << "\tScalarIncrement: " << scalar << std::endl
553 << "\tDefaultValue: " << def << std::endl;
554 break;
555 }
556 case PLDM_BIOS_STRING:
557 case PLDM_BIOS_STRING_READ_ONLY:
558 {
559 auto strType =
560 pldm_bios_table_attr_entry_string_decode_string_type(
561 entry);
562 auto min =
563 pldm_bios_table_attr_entry_string_decode_min_length(
564 entry);
565 auto max =
566 pldm_bios_table_attr_entry_string_decode_max_length(
567 entry);
568 auto def =
569 pldm_bios_table_attr_entry_string_decode_def_string_length(
570 entry);
571 std::vector<char> defString(def + 1);
572 pldm_bios_table_attr_entry_string_decode_def_string(
573 entry, defString.data(), defString.size());
574 std::cout
575 << "\tStringType: 0x" << std::hex << std::setw(2)
576 << std::setfill('0') << (int)strType << std::dec
577 << std::setw(0) << std::endl
578 << "\tMinimumStringLength: " << (int)min << std::endl
579 << "\tMaximumStringLength: " << (int)max << std::endl
580 << "\tDefaultStringLength: " << (int)def << std::endl
581 << "\tDefaultString: " << defString.data() << std::endl;
582 break;
583 }
584 case PLDM_BIOS_PASSWORD:
585 case PLDM_BIOS_PASSWORD_READ_ONLY:
586 std::cout << "Password attribute: Not Supported"
587 << std::endl;
588 }
589 }
590 }
591 void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
592 const std::optional<Table>& attrTable,
593 const std::optional<Table>& stringTable)
594 {
John Wangb754eee2020-02-15 16:10:25 +0800595 if (!attrValTable)
596 {
597 std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
598 return;
599 }
600 std::cout << "PLDM AttributeValueTable: " << std::endl;
601 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
602 attrValTable->data(), attrValTable->size()))
603 {
Adair Li4dd11a72020-04-24 14:52:59 +0800604 displayAttributeValueEntry(tableEntry, attrTable, stringTable);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600605 }
606 }
607};
608
Adair Li4dd11a72020-04-24 14:52:59 +0800609class GetBIOSAttributeCurrentValueByHandle : public GetBIOSTableHandler
610{
611 public:
612 ~GetBIOSAttributeCurrentValueByHandle() = default;
613 GetBIOSAttributeCurrentValueByHandle(
614 const GetBIOSAttributeCurrentValueByHandle&) = delete;
615 GetBIOSAttributeCurrentValueByHandle(
616 GetBIOSAttributeCurrentValueByHandle&&) = delete;
617 GetBIOSAttributeCurrentValueByHandle&
618 operator=(const GetBIOSAttributeCurrentValueByHandle&) = delete;
619 GetBIOSAttributeCurrentValueByHandle&
620 operator=(GetBIOSAttributeCurrentValueByHandle&&) = delete;
621
622 explicit GetBIOSAttributeCurrentValueByHandle(const char* type,
623 const char* name,
624 CLI::App* app) :
625 GetBIOSTableHandler(type, name, app)
626 {
627 app->add_option("-a, --attribute", attrName, "pldm bios attribute name")
628 ->required();
629 }
630
631 void exec()
632 {
633 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
634 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
635
636 if (!stringTable || !attrTable)
637 {
638 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
639 return;
640 }
641
642 auto handle = findAttrHandleByName(attrName, *attrTable, *stringTable);
643
644 std::vector<uint8_t> requestMsg(
645 sizeof(pldm_msg_hdr) +
646 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES);
647 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
648
649 auto rc = encode_get_bios_attribute_current_value_by_handle_req(
650 instanceId, 0, PLDM_GET_FIRSTPART, *handle, request);
651 if (rc != PLDM_SUCCESS)
652 {
653 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
654 return;
655 }
656
657 std::vector<uint8_t> responseMsg;
658 rc = pldmSendRecv(requestMsg, responseMsg);
659 if (rc != PLDM_SUCCESS)
660 {
661 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
662 return;
663 }
664
665 uint8_t cc = 0, transferFlag = 0;
666 uint32_t nextTransferHandle = 0;
667 struct variable_field attributeData;
668 auto responsePtr =
669 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
670 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
671
672 rc = decode_get_bios_attribute_current_value_by_handle_resp(
673 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
674 &attributeData);
675 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
676 {
677 std::cerr << "Response Message Error: "
678 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
679 return;
680 }
681
682 auto tableEntry =
683 reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
684 attributeData.ptr);
685
686 displayAttributeValueEntry(tableEntry, attrTable, stringTable);
687 }
688
689 private:
690 std::string attrName;
691};
692
Adair Lice041e22020-05-09 17:27:43 +0800693class SetBIOSAttributeCurrentValue : public GetBIOSTableHandler
694{
695 public:
696 ~SetBIOSAttributeCurrentValue() = default;
697 SetBIOSAttributeCurrentValue() = delete;
698 SetBIOSAttributeCurrentValue(const SetBIOSAttributeCurrentValue&) = delete;
699 SetBIOSAttributeCurrentValue(SetBIOSAttributeCurrentValue&&) = default;
700 SetBIOSAttributeCurrentValue&
701 operator=(const SetBIOSAttributeCurrentValue&) = delete;
702 SetBIOSAttributeCurrentValue&
703 operator=(SetBIOSAttributeCurrentValue&&) = default;
704
705 explicit SetBIOSAttributeCurrentValue(const char* type, const char* name,
706 CLI::App* app) :
707 GetBIOSTableHandler(type, name, app)
708 {
709 app->add_option("-a, --attribute", attrName, "pldm attribute name")
710 ->required();
711 app->add_option("-d, --data", attrValue, "pldm attribute value")
712 ->required();
713 // -v is conflict with --verbose in class CommandInterface, so used -d
714 }
715
716 void exec()
717 {
718 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
719 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
720 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
721
722 if (!stringTable || !attrTable)
723 {
724 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
725 return;
726 }
727
728 auto attrEntry =
729 findAttrEntryByName(attrName, *attrTable, *stringTable);
730 if (attrEntry == nullptr)
731 {
732 std::cout << "Could not find attribute :" << attrName << std::endl;
733 return;
734 }
735
736 std::vector<uint8_t> requestMsg;
737
738 int rc = 0;
739 auto attrType = attrEntry->attr_type;
740 size_t entryLength = 1;
741 std::vector<uint8_t> attrValueEntry(entryLength, 0);
742
743 switch (attrType)
744 {
745 case PLDM_BIOS_ENUMERATION_READ_ONLY:
746 case PLDM_BIOS_STRING_READ_ONLY:
747 case PLDM_BIOS_INTEGER_READ_ONLY:
748 {
749 std::cerr << "Set attribute error: " << attrName
750 << "is read only." << std::endl;
751 return;
752 }
753 case PLDM_BIOS_ENUMERATION:
754 {
755 entryLength =
756 pldm_bios_table_attr_value_entry_encode_enum_length(1);
757 auto pvNum =
758 pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
759 std::vector<uint16_t> pvHdls(pvNum, 0);
760 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
761 attrEntry, pvHdls.data(), pvNum);
762 auto stringEntry = pldm_bios_table_string_find_by_string(
763 stringTable->data(), stringTable->size(),
764 attrValue.c_str());
765 if (stringEntry == nullptr)
766 {
767 std::cout
768 << "Set Attribute Error: It's not a possible value"
769 << std::endl;
770 return;
771 }
772 auto valueHandle =
773 pldm_bios_table_string_entry_decode_handle(stringEntry);
774
775 uint8_t i;
776 for (i = 0; i < pvNum; i++)
777 {
778 if (valueHandle == pvHdls[i])
779 break;
780 }
781 if (i == pvNum)
782 {
783 std::cout
784 << "Set Attribute Error: It's not a possible value"
785 << std::endl;
786 return;
787 }
788
789 attrValueEntry.resize(entryLength);
790 std::vector<uint8_t> handles = {i};
791 pldm_bios_table_attr_value_entry_encode_enum(
792 attrValueEntry.data(), attrValueEntry.size(),
793 attrEntry->attr_handle, attrType, 1, handles.data());
794 break;
795 }
796 case PLDM_BIOS_STRING:
797 {
798 entryLength =
799 pldm_bios_table_attr_value_entry_encode_string_length(
800 attrValue.size());
801
802 attrValueEntry.resize(entryLength);
803
804 pldm_bios_table_attr_value_entry_encode_string(
805 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
806 attrType, attrValue.size(), attrValue.c_str());
807 break;
808 }
809 case PLDM_BIOS_INTEGER:
810 {
811 uint64_t value = std::stoll(attrValue);
812 entryLength =
813 pldm_bios_table_attr_value_entry_encode_integer_length();
814 attrValueEntry.resize(entryLength);
815 pldm_bios_table_attr_value_entry_encode_integer(
816 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
817 attrType, value);
818 break;
819 }
820 }
821
822 requestMsg.resize(entryLength + sizeof(pldm_msg_hdr) +
823 PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES);
824
825 rc = encode_set_bios_attribute_current_value_req(
826 instanceId, 0, PLDM_START_AND_END, attrValueEntry.data(),
827 attrValueEntry.size(),
828 reinterpret_cast<pldm_msg*>(requestMsg.data()),
829 requestMsg.size() - sizeof(pldm_msg_hdr));
830
831 if (rc != PLDM_SUCCESS)
832 {
833 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
834 return;
835 }
836 std::vector<uint8_t> responseMsg;
837 rc = pldmSendRecv(requestMsg, responseMsg);
838 if (rc != PLDM_SUCCESS)
839 {
840 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
841 return;
842 }
843 uint8_t cc = 0;
844 uint32_t nextTransferHandle = 0;
845 auto responsePtr =
846 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
847 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
848
849 rc = decode_set_bios_attribute_current_value_resp(
850 responsePtr, payloadLength, &cc, &nextTransferHandle);
851 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
852 {
853 std::cerr << "Response Message Error: "
854 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
855 return;
856 }
857
858 std::cout << "SetBIOSAttributeCurrentValue: SUCCESS" << std::endl;
859 }
860
861 private:
862 std::string attrName;
863 std::string attrValue;
864};
865
Sridevi Ramesh98576432019-11-27 10:10:28 -0600866void registerCommand(CLI::App& app)
867{
868 auto bios = app.add_subcommand("bios", "bios type command");
869 bios->require_subcommand(1);
870 auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
871 commands.push_back(
872 std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
George Liud6649362019-11-27 19:06:51 +0800873
874 auto setDateTime =
875 bios->add_subcommand("SetDateTime", "set host date time");
876 commands.push_back(
877 std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600878
879 auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
880 commands.push_back(
881 std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));
Adair Li4dd11a72020-04-24 14:52:59 +0800882
883 auto getBIOSAttributeCurrentValueByHandle =
884 bios->add_subcommand("GetBIOSAttributeCurrentValueByHandle",
885 "get bios attribute current value by handle");
886 commands.push_back(std::make_unique<GetBIOSAttributeCurrentValueByHandle>(
887 "bios", "GetBIOSAttributeCurrentValueByHandle",
888 getBIOSAttributeCurrentValueByHandle));
Adair Lice041e22020-05-09 17:27:43 +0800889
890 auto setBIOSAttributeCurrentValue = bios->add_subcommand(
891 "SetBIOSAttributeCurrentValue", "set bios attribute current value");
892 commands.push_back(std::make_unique<SetBIOSAttributeCurrentValue>(
893 "bios", "SetBIOSAttributeCurrentValue", setBIOSAttributeCurrentValue));
Sridevi Ramesh98576432019-11-27 10:10:28 -0600894}
895
896} // namespace bios
897
898} // namespace pldmtool