blob: ba40dea9f151003d9ed515541fe8497183a46ec5 [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
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05006#include "common/bios_utils.hpp"
7#include "common/utils.hpp"
Sridevi Ramesh98576432019-11-27 10:10:28 -06008#include "pldm_cmd_helper.hpp"
John Wangb754eee2020-02-15 16:10:25 +08009
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 return nullptr;
Adair Li4dd11a72020-04-24 14:52:59 +0800253 }
John Wangb754eee2020-02-15 16:10:25 +0800254
Adair Li4dd11a72020-04-24 14:52:59 +0800255 auto nameHandle =
256 pldm_bios_table_string_entry_decode_handle(stringEntry);
John Wangb754eee2020-02-15 16:10:25 +0800257
Adair Li4dd11a72020-04-24 14:52:59 +0800258 for (auto attr : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable.data(),
259 attrTable.size()))
260 {
261 auto attrNameHandle =
262 pldm_bios_table_attr_entry_decode_string_handle(attr);
263 if (attrNameHandle == nameHandle)
264 {
Adair Lice041e22020-05-09 17:27:43 +0800265 return attr;
John Wangb754eee2020-02-15 16:10:25 +0800266 }
267 }
Adair Lice041e22020-05-09 17:27:43 +0800268 return nullptr;
269 }
270
271 std::optional<uint16_t> findAttrHandleByName(const std::string& name,
272 const Table& attrTable,
273 const Table& stringTable)
274 {
275 auto attribute = findAttrEntryByName(name, attrTable, stringTable);
276 if (attribute == nullptr)
277 {
278 return std::nullopt;
279 }
280
281 return pldm_bios_table_attr_entry_decode_attribute_handle(attribute);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600282 }
283
John Wangb754eee2020-02-15 16:10:25 +0800284 std::string decodeStringFromStringEntry(
285 const pldm_bios_string_table_entry* stringEntry)
286 {
287 auto strLength =
288 pldm_bios_table_string_entry_decode_string_length(stringEntry);
289 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
290 pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
291 buffer.size());
292
293 return std::string(buffer.data(), buffer.data() + strLength);
294 }
295
296 std::string displayStringHandle(uint16_t handle,
Adair Li4dd11a72020-04-24 14:52:59 +0800297 const std::optional<Table>& stringTable,
298 bool displayHandle = true)
John Wangb754eee2020-02-15 16:10:25 +0800299 {
300 std::string displayString = std::to_string(handle);
301 if (!stringTable)
302 {
303 return displayString;
304 }
305 auto stringEntry = pldm_bios_table_string_find_by_handle(
306 stringTable->data(), stringTable->size(), handle);
307 if (stringEntry == nullptr)
308 {
309 return displayString;
310 }
311
Adair Li4dd11a72020-04-24 14:52:59 +0800312 auto decodedStr = decodeStringFromStringEntry(stringEntry);
313 if (!displayHandle)
314 {
315 return decodedStr;
316 }
317
318 return displayString + "(" + decodedStr + ")";
John Wangb754eee2020-02-15 16:10:25 +0800319 }
320
321 std::string displayEnumValueByIndex(uint16_t attrHandle, uint8_t index,
322 const std::optional<Table>& attrTable,
323 const std::optional<Table>& stringTable)
324 {
325 std::string displayString;
326 if (!attrTable)
327 {
328 return displayString;
329 }
330
331 auto attrEntry = pldm_bios_table_attr_find_by_handle(
332 attrTable->data(), attrTable->size(), attrHandle);
333 if (attrEntry == nullptr)
334 {
335 return displayString;
336 }
337 auto pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
338 std::vector<uint16_t> pvHandls(pvNum);
339 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
340 attrEntry, pvHandls.data(), pvHandls.size());
Adair Li4dd11a72020-04-24 14:52:59 +0800341 return displayStringHandle(pvHandls[index], stringTable, false);
John Wangb754eee2020-02-15 16:10:25 +0800342 }
343
Adair Li4dd11a72020-04-24 14:52:59 +0800344 void displayAttributeValueEntry(
345 const pldm_bios_attr_val_table_entry* tableEntry,
346 const std::optional<Table>& attrTable,
John Wang2cd07da2020-06-19 15:45:39 +0800347 const std::optional<Table>& stringTable, bool verbose)
Adair Li4dd11a72020-04-24 14:52:59 +0800348 {
349 auto attrHandle =
350 pldm_bios_table_attr_value_entry_decode_attribute_handle(
351 tableEntry);
352 auto attrType = static_cast<pldm_bios_attribute_type>(
353 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
John Wang2cd07da2020-06-19 15:45:39 +0800354 if (verbose)
355 {
356 std::cout << "AttributeHandle: " << attrHandle << std::endl;
357 std::cout << "\tAttributeType: " << attrTypeMap.at(attrType)
358 << std::endl;
359 }
Adair Li4dd11a72020-04-24 14:52:59 +0800360 switch (attrType)
361 {
362 case PLDM_BIOS_ENUMERATION:
363 case PLDM_BIOS_ENUMERATION_READ_ONLY:
364 {
365 auto count =
366 pldm_bios_table_attr_value_entry_enum_decode_number(
367 tableEntry);
368 std::vector<uint8_t> handles(count);
369 pldm_bios_table_attr_value_entry_enum_decode_handles(
370 tableEntry, handles.data(), handles.size());
John Wang2cd07da2020-06-19 15:45:39 +0800371 if (verbose)
372 {
373 std::cout << "\tNumberOfCurrentValues: " << (int)count
374 << std::endl;
375 }
Adair Li4dd11a72020-04-24 14:52:59 +0800376 for (size_t i = 0; i < handles.size(); i++)
377 {
John Wang2cd07da2020-06-19 15:45:39 +0800378 if (verbose)
379 {
380 std::cout
381 << "\tCurrentValueStringHandleIndex[" << i
382 << "] = " << (int)handles[i] << ", StringHandle = "
383 << displayEnumValueByIndex(attrHandle, handles[i],
384 attrTable, stringTable)
385 << std::endl;
386 }
387 else
388 {
389 std::cout
390 << "CurrentValue: "
391 << displayEnumValueByIndex(attrHandle, handles[i],
392 attrTable, stringTable)
393 << std::endl;
394 }
Adair Li4dd11a72020-04-24 14:52:59 +0800395 }
396 break;
397 }
398 case PLDM_BIOS_INTEGER:
399 case PLDM_BIOS_INTEGER_READ_ONLY:
400 {
401 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(
402 tableEntry);
John Wang2cd07da2020-06-19 15:45:39 +0800403 if (verbose)
404 {
405 std::cout << "\tCurrentValue: " << cv << std::endl;
406 }
407 else
408 {
409 std::cout << "CurrentValue: " << cv << std::endl;
410 }
Adair Li4dd11a72020-04-24 14:52:59 +0800411 break;
412 }
413 case PLDM_BIOS_STRING:
414 case PLDM_BIOS_STRING_READ_ONLY:
415 {
416 variable_field currentString;
417 pldm_bios_table_attr_value_entry_string_decode_string(
418 tableEntry, &currentString);
John Wang2cd07da2020-06-19 15:45:39 +0800419 if (verbose)
420 {
421 std::cout
422 << "\tCurrentStringLength: " << currentString.length
423 << std::endl
424 << "\tCurrentString: "
425 << std::string(
426 reinterpret_cast<const char*>(currentString.ptr),
427 currentString.length)
428 << std::endl;
429 }
430 else
431 {
432 std::cout << "CurrentValue: "
433 << std::string(reinterpret_cast<const char*>(
434 currentString.ptr),
435 currentString.length)
436 << std::endl;
437 }
Adair Li4dd11a72020-04-24 14:52:59 +0800438
439 break;
440 }
441 case PLDM_BIOS_PASSWORD:
442 case PLDM_BIOS_PASSWORD_READ_ONLY:
443 {
444 std::cout << "Password attribute: Not Supported" << std::endl;
445 break;
446 }
447 }
448 }
449};
450
451class GetBIOSTable : public GetBIOSTableHandler
452{
453 public:
454 ~GetBIOSTable() = default;
455 GetBIOSTable() = delete;
456 GetBIOSTable(const GetBIOSTable&) = delete;
457 GetBIOSTable(GetBIOSTable&&) = default;
458 GetBIOSTable& operator=(const GetBIOSTable&) = delete;
459 GetBIOSTable& operator=(GetBIOSTable&&) = default;
460
461 using Table = std::vector<uint8_t>;
462
463 explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
464 GetBIOSTableHandler(type, name, app)
465 {
466 app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
467 ->required()
468 ->transform(
469 CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
470 }
471
472 void exec() override
473 {
474 switch (pldmBIOSTableType)
475 {
476 case PLDM_BIOS_STRING_TABLE:
477 {
478 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
479 decodeStringTable(stringTable);
480 break;
481 }
482 case PLDM_BIOS_ATTR_TABLE:
483 {
484 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
485 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
486
487 decodeAttributeTable(attrTable, stringTable);
488 break;
489 }
490 case PLDM_BIOS_ATTR_VAL_TABLE:
491 {
492 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
493 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
494 auto attrValTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
495
496 decodeAttributeValueTable(attrValTable, attrTable, stringTable);
497 break;
498 }
499 }
500 }
501
502 private:
503 pldm_bios_table_types pldmBIOSTableType;
504
John Wangb754eee2020-02-15 16:10:25 +0800505 void decodeStringTable(const std::optional<Table>& stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600506 {
John Wangb754eee2020-02-15 16:10:25 +0800507 if (!stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600508 {
John Wangb754eee2020-02-15 16:10:25 +0800509 std::cerr << "GetBIOSStringTable Error" << std::endl;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600510 return;
511 }
John Wangb754eee2020-02-15 16:10:25 +0800512 std::cout << "PLDM StringTable: " << std::endl;
513 std::cout << "BIOSStringHandle : BIOSString" << std::endl;
514
515 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
516 stringTable->data(), stringTable->size()))
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600517 {
John Wangb754eee2020-02-15 16:10:25 +0800518 auto strHandle =
519 pldm_bios_table_string_entry_decode_handle(tableEntry);
520 auto strTableData = decodeStringFromStringEntry(tableEntry);
521 std::cout << strHandle << " : " << strTableData << std::endl;
522 }
523 }
524 void decodeAttributeTable(const std::optional<Table>& attrTable,
525 const std::optional<Table>& stringTable)
526 {
John Wangb754eee2020-02-15 16:10:25 +0800527 if (!stringTable)
528 {
529 std::cerr << "GetBIOSAttributeTable Error" << std::endl;
530 return;
531 }
532 std::cout << "PLDM AttributeTable: " << std::endl;
533 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
534 attrTable->data(), attrTable->size()))
535 {
536 auto attrHandle =
537 pldm_bios_table_attr_entry_decode_attribute_handle(entry);
538 auto attrNameHandle =
539 pldm_bios_table_attr_entry_decode_string_handle(entry);
540 auto attrType = static_cast<pldm_bios_attribute_type>(
541 pldm_bios_table_attr_entry_decode_attribute_type(entry));
542 std::cout << "AttributeHandle: " << attrHandle
543 << ", AttributeNameHandle: "
544 << displayStringHandle(attrNameHandle, stringTable)
545 << std::endl;
546 std::cout << "\tAttributeType: " << attrTypeMap.at(attrType)
547 << std::endl;
548 switch (attrType)
549 {
550 case PLDM_BIOS_ENUMERATION:
551 case PLDM_BIOS_ENUMERATION_READ_ONLY:
552 {
553 auto pvNum =
554 pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
555 std::vector<uint16_t> pvHandls(pvNum);
556 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
557 entry, pvHandls.data(), pvHandls.size());
558 auto defNum =
559 pldm_bios_table_attr_entry_enum_decode_def_num(entry);
560 std::vector<uint8_t> defIndices(defNum);
561 pldm_bios_table_attr_entry_enum_decode_def_indices(
562 entry, defIndices.data(), defIndices.size());
563 std::cout << "\tNumberOfPossibleValues: " << (int)pvNum
564 << std::endl;
565
566 for (size_t i = 0; i < pvHandls.size(); i++)
567 {
568 std::cout
569 << "\t\tPossibleValueStringHandle"
570 << "[" << i << "] = "
571 << displayStringHandle(pvHandls[i], stringTable)
572 << std::endl;
573 }
574 std::cout << "\tNumberOfDefaultValues: " << (int)defNum
575 << std::endl;
576 for (size_t i = 0; i < defIndices.size(); i++)
577 {
578 std::cout << "\t\tDefaultValueStringHandleIndex"
579 << "[" << i << "] = " << (int)defIndices[i]
580 << ", StringHandle = "
581 << displayStringHandle(
582 pvHandls[defIndices[i]], stringTable)
583 << std::endl;
584 }
585 break;
586 }
587 case PLDM_BIOS_INTEGER:
588 case PLDM_BIOS_INTEGER_READ_ONLY:
589 {
590 uint64_t lower, upper, def;
591 uint32_t scalar;
592 pldm_bios_table_attr_entry_integer_decode(
593 entry, &lower, &upper, &scalar, &def);
594 std::cout << "\tLowerBound: " << lower << std::endl
595 << "\tUpperBound: " << upper << std::endl
596 << "\tScalarIncrement: " << scalar << std::endl
597 << "\tDefaultValue: " << def << std::endl;
598 break;
599 }
600 case PLDM_BIOS_STRING:
601 case PLDM_BIOS_STRING_READ_ONLY:
602 {
603 auto strType =
604 pldm_bios_table_attr_entry_string_decode_string_type(
605 entry);
606 auto min =
607 pldm_bios_table_attr_entry_string_decode_min_length(
608 entry);
609 auto max =
610 pldm_bios_table_attr_entry_string_decode_max_length(
611 entry);
612 auto def =
613 pldm_bios_table_attr_entry_string_decode_def_string_length(
614 entry);
615 std::vector<char> defString(def + 1);
616 pldm_bios_table_attr_entry_string_decode_def_string(
617 entry, defString.data(), defString.size());
618 std::cout
619 << "\tStringType: 0x" << std::hex << std::setw(2)
620 << std::setfill('0') << (int)strType << std::dec
621 << std::setw(0) << std::endl
622 << "\tMinimumStringLength: " << (int)min << std::endl
623 << "\tMaximumStringLength: " << (int)max << std::endl
624 << "\tDefaultStringLength: " << (int)def << std::endl
625 << "\tDefaultString: " << defString.data() << std::endl;
626 break;
627 }
628 case PLDM_BIOS_PASSWORD:
629 case PLDM_BIOS_PASSWORD_READ_ONLY:
630 std::cout << "Password attribute: Not Supported"
631 << std::endl;
632 }
633 }
634 }
635 void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
636 const std::optional<Table>& attrTable,
637 const std::optional<Table>& stringTable)
638 {
John Wangb754eee2020-02-15 16:10:25 +0800639 if (!attrValTable)
640 {
641 std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
642 return;
643 }
644 std::cout << "PLDM AttributeValueTable: " << std::endl;
645 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
646 attrValTable->data(), attrValTable->size()))
647 {
John Wang2cd07da2020-06-19 15:45:39 +0800648 displayAttributeValueEntry(tableEntry, attrTable, stringTable,
649 true);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600650 }
651 }
652};
653
Adair Li4dd11a72020-04-24 14:52:59 +0800654class GetBIOSAttributeCurrentValueByHandle : public GetBIOSTableHandler
655{
656 public:
657 ~GetBIOSAttributeCurrentValueByHandle() = default;
658 GetBIOSAttributeCurrentValueByHandle(
659 const GetBIOSAttributeCurrentValueByHandle&) = delete;
660 GetBIOSAttributeCurrentValueByHandle(
661 GetBIOSAttributeCurrentValueByHandle&&) = delete;
662 GetBIOSAttributeCurrentValueByHandle&
663 operator=(const GetBIOSAttributeCurrentValueByHandle&) = delete;
664 GetBIOSAttributeCurrentValueByHandle&
665 operator=(GetBIOSAttributeCurrentValueByHandle&&) = delete;
666
667 explicit GetBIOSAttributeCurrentValueByHandle(const char* type,
668 const char* name,
669 CLI::App* app) :
670 GetBIOSTableHandler(type, name, app)
671 {
672 app->add_option("-a, --attribute", attrName, "pldm bios attribute name")
673 ->required();
674 }
675
676 void exec()
677 {
678 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
679 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
680
681 if (!stringTable || !attrTable)
682 {
683 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
684 return;
685 }
686
687 auto handle = findAttrHandleByName(attrName, *attrTable, *stringTable);
John Wangcee24b62020-06-19 17:23:10 +0800688 if (!handle)
689 {
690
691 std::cerr << "Can not find the attribute " << attrName << std::endl;
692 return;
693 }
Adair Li4dd11a72020-04-24 14:52:59 +0800694
695 std::vector<uint8_t> requestMsg(
696 sizeof(pldm_msg_hdr) +
697 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES);
698 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
699
700 auto rc = encode_get_bios_attribute_current_value_by_handle_req(
701 instanceId, 0, PLDM_GET_FIRSTPART, *handle, request);
702 if (rc != PLDM_SUCCESS)
703 {
704 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
705 return;
706 }
707
708 std::vector<uint8_t> responseMsg;
709 rc = pldmSendRecv(requestMsg, responseMsg);
710 if (rc != PLDM_SUCCESS)
711 {
712 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
713 return;
714 }
715
716 uint8_t cc = 0, transferFlag = 0;
717 uint32_t nextTransferHandle = 0;
718 struct variable_field attributeData;
719 auto responsePtr =
720 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
721 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
722
723 rc = decode_get_bios_attribute_current_value_by_handle_resp(
724 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
725 &attributeData);
726 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
727 {
728 std::cerr << "Response Message Error: "
729 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
730 return;
731 }
732
733 auto tableEntry =
734 reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
735 attributeData.ptr);
736
John Wang2cd07da2020-06-19 15:45:39 +0800737 displayAttributeValueEntry(tableEntry, attrTable, stringTable, false);
Adair Li4dd11a72020-04-24 14:52:59 +0800738 }
739
740 private:
741 std::string attrName;
742};
743
Adair Lice041e22020-05-09 17:27:43 +0800744class SetBIOSAttributeCurrentValue : public GetBIOSTableHandler
745{
746 public:
747 ~SetBIOSAttributeCurrentValue() = default;
748 SetBIOSAttributeCurrentValue() = delete;
749 SetBIOSAttributeCurrentValue(const SetBIOSAttributeCurrentValue&) = delete;
750 SetBIOSAttributeCurrentValue(SetBIOSAttributeCurrentValue&&) = default;
751 SetBIOSAttributeCurrentValue&
752 operator=(const SetBIOSAttributeCurrentValue&) = delete;
753 SetBIOSAttributeCurrentValue&
754 operator=(SetBIOSAttributeCurrentValue&&) = default;
755
756 explicit SetBIOSAttributeCurrentValue(const char* type, const char* name,
757 CLI::App* app) :
758 GetBIOSTableHandler(type, name, app)
759 {
760 app->add_option("-a, --attribute", attrName, "pldm attribute name")
761 ->required();
762 app->add_option("-d, --data", attrValue, "pldm attribute value")
763 ->required();
764 // -v is conflict with --verbose in class CommandInterface, so used -d
765 }
766
767 void exec()
768 {
769 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
770 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
771 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
772
773 if (!stringTable || !attrTable)
774 {
775 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
776 return;
777 }
778
779 auto attrEntry =
780 findAttrEntryByName(attrName, *attrTable, *stringTable);
781 if (attrEntry == nullptr)
782 {
783 std::cout << "Could not find attribute :" << attrName << std::endl;
784 return;
785 }
786
787 std::vector<uint8_t> requestMsg;
788
789 int rc = 0;
790 auto attrType = attrEntry->attr_type;
791 size_t entryLength = 1;
792 std::vector<uint8_t> attrValueEntry(entryLength, 0);
793
794 switch (attrType)
795 {
796 case PLDM_BIOS_ENUMERATION_READ_ONLY:
797 case PLDM_BIOS_STRING_READ_ONLY:
798 case PLDM_BIOS_INTEGER_READ_ONLY:
799 {
800 std::cerr << "Set attribute error: " << attrName
801 << "is read only." << std::endl;
802 return;
803 }
804 case PLDM_BIOS_ENUMERATION:
805 {
806 entryLength =
807 pldm_bios_table_attr_value_entry_encode_enum_length(1);
808 auto pvNum =
809 pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
810 std::vector<uint16_t> pvHdls(pvNum, 0);
811 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
812 attrEntry, pvHdls.data(), pvNum);
813 auto stringEntry = pldm_bios_table_string_find_by_string(
814 stringTable->data(), stringTable->size(),
815 attrValue.c_str());
816 if (stringEntry == nullptr)
817 {
818 std::cout
819 << "Set Attribute Error: It's not a possible value"
820 << std::endl;
821 return;
822 }
823 auto valueHandle =
824 pldm_bios_table_string_entry_decode_handle(stringEntry);
825
826 uint8_t i;
827 for (i = 0; i < pvNum; i++)
828 {
829 if (valueHandle == pvHdls[i])
830 break;
831 }
832 if (i == pvNum)
833 {
834 std::cout
835 << "Set Attribute Error: It's not a possible value"
836 << std::endl;
837 return;
838 }
839
840 attrValueEntry.resize(entryLength);
841 std::vector<uint8_t> handles = {i};
842 pldm_bios_table_attr_value_entry_encode_enum(
843 attrValueEntry.data(), attrValueEntry.size(),
844 attrEntry->attr_handle, attrType, 1, handles.data());
845 break;
846 }
847 case PLDM_BIOS_STRING:
848 {
849 entryLength =
850 pldm_bios_table_attr_value_entry_encode_string_length(
851 attrValue.size());
852
853 attrValueEntry.resize(entryLength);
854
855 pldm_bios_table_attr_value_entry_encode_string(
856 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
857 attrType, attrValue.size(), attrValue.c_str());
858 break;
859 }
860 case PLDM_BIOS_INTEGER:
861 {
862 uint64_t value = std::stoll(attrValue);
863 entryLength =
864 pldm_bios_table_attr_value_entry_encode_integer_length();
865 attrValueEntry.resize(entryLength);
866 pldm_bios_table_attr_value_entry_encode_integer(
867 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
868 attrType, value);
869 break;
870 }
871 }
872
873 requestMsg.resize(entryLength + sizeof(pldm_msg_hdr) +
874 PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES);
875
876 rc = encode_set_bios_attribute_current_value_req(
877 instanceId, 0, PLDM_START_AND_END, attrValueEntry.data(),
878 attrValueEntry.size(),
879 reinterpret_cast<pldm_msg*>(requestMsg.data()),
880 requestMsg.size() - sizeof(pldm_msg_hdr));
881
882 if (rc != PLDM_SUCCESS)
883 {
884 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
885 return;
886 }
887 std::vector<uint8_t> responseMsg;
888 rc = pldmSendRecv(requestMsg, responseMsg);
889 if (rc != PLDM_SUCCESS)
890 {
891 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
892 return;
893 }
894 uint8_t cc = 0;
895 uint32_t nextTransferHandle = 0;
896 auto responsePtr =
897 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
898 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
899
900 rc = decode_set_bios_attribute_current_value_resp(
901 responsePtr, payloadLength, &cc, &nextTransferHandle);
902 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
903 {
904 std::cerr << "Response Message Error: "
905 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
906 return;
907 }
908
909 std::cout << "SetBIOSAttributeCurrentValue: SUCCESS" << std::endl;
910 }
911
912 private:
913 std::string attrName;
914 std::string attrValue;
915};
916
Sridevi Ramesh98576432019-11-27 10:10:28 -0600917void registerCommand(CLI::App& app)
918{
919 auto bios = app.add_subcommand("bios", "bios type command");
920 bios->require_subcommand(1);
921 auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
922 commands.push_back(
923 std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
George Liud6649362019-11-27 19:06:51 +0800924
925 auto setDateTime =
926 bios->add_subcommand("SetDateTime", "set host date time");
927 commands.push_back(
928 std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600929
930 auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
931 commands.push_back(
932 std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));
Adair Li4dd11a72020-04-24 14:52:59 +0800933
934 auto getBIOSAttributeCurrentValueByHandle =
935 bios->add_subcommand("GetBIOSAttributeCurrentValueByHandle",
936 "get bios attribute current value by handle");
937 commands.push_back(std::make_unique<GetBIOSAttributeCurrentValueByHandle>(
938 "bios", "GetBIOSAttributeCurrentValueByHandle",
939 getBIOSAttributeCurrentValueByHandle));
Adair Lice041e22020-05-09 17:27:43 +0800940
941 auto setBIOSAttributeCurrentValue = bios->add_subcommand(
942 "SetBIOSAttributeCurrentValue", "set bios attribute current value");
943 commands.push_back(std::make_unique<SetBIOSAttributeCurrentValue>(
944 "bios", "SetBIOSAttributeCurrentValue", setBIOSAttributeCurrentValue));
Sridevi Ramesh98576432019-11-27 10:10:28 -0600945}
946
947} // namespace bios
948
949} // namespace pldmtool