blob: 03e5d9cb692d1aa932c9f313c2b78d5e685aaebe [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;
Brad Bishop5079ac42021-08-19 18:35:06 -040024using namespace pldm::utils;
Sridevi Ramesh98576432019-11-27 10:10:28 -060025
26std::vector<std::unique_ptr<CommandInterface>> commands;
27
Sridevi Rameshcdfe1142020-01-31 05:42:50 -060028const std::map<const char*, pldm_bios_table_types> pldmBIOSTableTypes{
29 {"StringTable", PLDM_BIOS_STRING_TABLE},
30 {"AttributeTable", PLDM_BIOS_ATTR_TABLE},
31 {"AttributeValueTable", PLDM_BIOS_ATTR_VAL_TABLE},
32};
33
Sridevi Ramesh98576432019-11-27 10:10:28 -060034} // namespace
35
36class GetDateTime : public CommandInterface
37{
38 public:
39 ~GetDateTime() = default;
40 GetDateTime() = delete;
41 GetDateTime(const GetDateTime&) = delete;
42 GetDateTime(GetDateTime&&) = default;
43 GetDateTime& operator=(const GetDateTime&) = delete;
44 GetDateTime& operator=(GetDateTime&&) = default;
45
46 using CommandInterface::CommandInterface;
47
48 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
49 {
50 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
51 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
52
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060053 auto rc = encode_get_date_time_req(instanceId, request);
Sridevi Ramesh98576432019-11-27 10:10:28 -060054 return {rc, requestMsg};
55 }
56
57 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
58 {
59 uint8_t cc = 0;
60
61 uint8_t seconds, minutes, hours, day, month;
62 uint16_t year;
63 auto rc =
64 decode_get_date_time_resp(responsePtr, payloadLength, &cc, &seconds,
65 &minutes, &hours, &day, &month, &year);
66 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
67 {
68 std::cerr << "Response Message Error: "
69 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
70 return;
71 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -050072
73 std::stringstream dt;
74 ordered_json data;
75 dt << bcd2dec16(year) << "-" << setWidth(month) << "-" << setWidth(day)
76 << " " << setWidth(hours) << ":" << setWidth(minutes) << ":"
77 << setWidth(seconds);
78 data["Response"] = dt.str();
79 pldmtool::helper::DisplayInJson(data);
Sridevi Ramesh98576432019-11-27 10:10:28 -060080 }
81
82 private:
Sridevi Rameshca4a8152020-08-11 09:26:19 -050083 static std::string setWidth(uint8_t data)
Sridevi Ramesh98576432019-11-27 10:10:28 -060084 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -050085 std::stringstream s;
86 s << std::setfill('0') << std::setw(2)
87 << static_cast<uint32_t>(bcd2dec8(data));
88 return s.str();
Sridevi Ramesh98576432019-11-27 10:10:28 -060089 }
90};
91
George Liud6649362019-11-27 19:06:51 +080092class SetDateTime : public CommandInterface
93{
94 public:
95 ~SetDateTime() = default;
96 SetDateTime() = delete;
97 SetDateTime(const SetDateTime&) = delete;
98 SetDateTime(SetDateTime&&) = default;
99 SetDateTime& operator=(const SetDateTime&) = delete;
100 SetDateTime& operator=(SetDateTime&&) = default;
101
102 explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
103 CommandInterface(type, name, app)
104 {
105 app->add_option("-d,--data", tmData,
106 "set date time data\n"
107 "eg: YYYYMMDDHHMMSS")
108 ->required();
109 }
110
111 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
112 {
113 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
114 sizeof(struct pldm_set_date_time_req));
115 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
116 uint16_t year = 0;
117 uint8_t month = 0;
118 uint8_t day = 0;
119 uint8_t hours = 0;
120 uint8_t minutes = 0;
121 uint8_t seconds = 0;
122
123 if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
124 &seconds))
125 {
126 std::cerr << "decode date Error: "
127 << "tmData=" << tmData << std::endl;
128
129 return {PLDM_ERROR_INVALID_DATA, requestMsg};
130 }
131
132 auto rc = encode_set_date_time_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600133 instanceId, seconds, minutes, hours, day, month, year, request,
134 sizeof(struct pldm_set_date_time_req));
George Liud6649362019-11-27 19:06:51 +0800135
136 return {rc, requestMsg};
137 }
138
139 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
140 {
141 uint8_t completionCode = 0;
142 auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
143 &completionCode);
144
145 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
146 {
147 std::cerr << "Response Message Error: "
148 << "rc=" << rc << ",cc=" << (int)completionCode
149 << std::endl;
150 return;
151 }
152
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500153 ordered_json data;
154 data["Response"] = "SUCCESS";
155 pldmtool::helper::DisplayInJson(data);
George Liud6649362019-11-27 19:06:51 +0800156 }
157
158 private:
159 uint64_t tmData;
160};
161
Adair Li4dd11a72020-04-24 14:52:59 +0800162class GetBIOSTableHandler : public CommandInterface
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600163{
164 public:
Adair Li4dd11a72020-04-24 14:52:59 +0800165 ~GetBIOSTableHandler() = default;
166 GetBIOSTableHandler() = delete;
167 GetBIOSTableHandler(const GetBIOSTableHandler&) = delete;
168 GetBIOSTableHandler(GetBIOSTableHandler&&) = delete;
169 GetBIOSTableHandler& operator=(const GetBIOSTableHandler&) = delete;
170 GetBIOSTableHandler& operator=(GetBIOSTableHandler&&) = delete;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600171
John Wangb754eee2020-02-15 16:10:25 +0800172 using Table = std::vector<uint8_t>;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600173
Adair Li4dd11a72020-04-24 14:52:59 +0800174 using CommandInterface::CommandInterface;
175
176 static inline const std::map<pldm_bios_attribute_type, const char*>
177 attrTypeMap = {
178 {PLDM_BIOS_ENUMERATION, "BIOSEnumeration"},
179 {PLDM_BIOS_ENUMERATION_READ_ONLY, "BIOSEnumerationReadOnly"},
180 {PLDM_BIOS_STRING, "BIOSString"},
181 {PLDM_BIOS_STRING_READ_ONLY, "BIOSStringReadOnly"},
182 {PLDM_BIOS_PASSWORD, "BIOSPassword"},
183 {PLDM_BIOS_PASSWORD_READ_ONLY, "BIOSPasswordReadOnly"},
184 {PLDM_BIOS_INTEGER, "BIOSInteger"},
185 {PLDM_BIOS_INTEGER_READ_ONLY, "BIOSIntegerReadOnly"},
186
187 };
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600188
189 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
190 {
John Wangb754eee2020-02-15 16:10:25 +0800191 return {PLDM_ERROR, {}};
192 }
Adair Li4dd11a72020-04-24 14:52:59 +0800193
John Wangb754eee2020-02-15 16:10:25 +0800194 void parseResponseMsg(pldm_msg*, size_t) override
George Liu6492f522020-06-16 10:34:05 +0800195 {}
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600196
John Wangb754eee2020-02-15 16:10:25 +0800197 std::optional<Table> getBIOSTable(pldm_bios_table_types tableType)
198 {
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600199 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
200 PLDM_GET_BIOS_TABLE_REQ_BYTES);
201 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
202
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600203 auto rc = encode_get_bios_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
204 tableType, request);
John Wangb754eee2020-02-15 16:10:25 +0800205 if (rc != PLDM_SUCCESS)
206 {
207 std::cerr << "Encode GetBIOSTable Error, tableType=," << tableType
208 << " ,rc=" << rc << std::endl;
209 return std::nullopt;
210 }
211 std::vector<uint8_t> responseMsg;
212 rc = pldmSendRecv(requestMsg, responseMsg);
213 if (rc != PLDM_SUCCESS)
214 {
215 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
216 return std::nullopt;
217 }
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600218
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600219 uint8_t cc = 0, transferFlag = 0;
220 uint32_t nextTransferHandle = 0;
221 size_t bios_table_offset;
John Wangb754eee2020-02-15 16:10:25 +0800222 auto responsePtr =
223 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
224 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600225
John Wangb754eee2020-02-15 16:10:25 +0800226 rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc,
227 &nextTransferHandle, &transferFlag,
228 &bios_table_offset);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600229
230 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
231 {
John Wangb754eee2020-02-15 16:10:25 +0800232 std::cerr << "GetBIOSTable Response Error: tableType=" << tableType
233 << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
234 return std::nullopt;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600235 }
236 auto tableData =
237 reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset);
John Wangb754eee2020-02-15 16:10:25 +0800238 auto tableSize = payloadLength - sizeof(nextTransferHandle) -
239 sizeof(transferFlag) - sizeof(cc);
240 return std::make_optional<Table>(tableData, tableData + tableSize);
241 }
242
Adair Lice041e22020-05-09 17:27:43 +0800243 const pldm_bios_attr_table_entry*
244 findAttrEntryByName(const std::string& name, const Table& attrTable,
245 const Table& stringTable)
John Wangb754eee2020-02-15 16:10:25 +0800246 {
Adair Li4dd11a72020-04-24 14:52:59 +0800247 auto stringEntry = pldm_bios_table_string_find_by_string(
248 stringTable.data(), stringTable.size(), name.c_str());
249 if (stringEntry == nullptr)
John Wangb754eee2020-02-15 16:10:25 +0800250 {
Adair Lice041e22020-05-09 17:27:43 +0800251 return nullptr;
Adair Li4dd11a72020-04-24 14:52:59 +0800252 }
John Wangb754eee2020-02-15 16:10:25 +0800253
Adair Li4dd11a72020-04-24 14:52:59 +0800254 auto nameHandle =
255 pldm_bios_table_string_entry_decode_handle(stringEntry);
John Wangb754eee2020-02-15 16:10:25 +0800256
Adair Li4dd11a72020-04-24 14:52:59 +0800257 for (auto attr : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable.data(),
258 attrTable.size()))
259 {
260 auto attrNameHandle =
261 pldm_bios_table_attr_entry_decode_string_handle(attr);
262 if (attrNameHandle == nameHandle)
263 {
Adair Lice041e22020-05-09 17:27:43 +0800264 return attr;
John Wangb754eee2020-02-15 16:10:25 +0800265 }
266 }
Adair Lice041e22020-05-09 17:27:43 +0800267 return nullptr;
268 }
269
270 std::optional<uint16_t> findAttrHandleByName(const std::string& name,
271 const Table& attrTable,
272 const Table& stringTable)
273 {
274 auto attribute = findAttrEntryByName(name, attrTable, stringTable);
275 if (attribute == nullptr)
276 {
277 return std::nullopt;
278 }
279
280 return pldm_bios_table_attr_entry_decode_attribute_handle(attribute);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600281 }
282
John Wangb754eee2020-02-15 16:10:25 +0800283 std::string decodeStringFromStringEntry(
284 const pldm_bios_string_table_entry* stringEntry)
285 {
286 auto strLength =
287 pldm_bios_table_string_entry_decode_string_length(stringEntry);
288 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
289 pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
290 buffer.size());
291
292 return std::string(buffer.data(), buffer.data() + strLength);
293 }
294
295 std::string displayStringHandle(uint16_t handle,
Adair Li4dd11a72020-04-24 14:52:59 +0800296 const std::optional<Table>& stringTable,
297 bool displayHandle = true)
John Wangb754eee2020-02-15 16:10:25 +0800298 {
299 std::string displayString = std::to_string(handle);
300 if (!stringTable)
301 {
302 return displayString;
303 }
304 auto stringEntry = pldm_bios_table_string_find_by_handle(
305 stringTable->data(), stringTable->size(), handle);
306 if (stringEntry == nullptr)
307 {
308 return displayString;
309 }
310
Adair Li4dd11a72020-04-24 14:52:59 +0800311 auto decodedStr = decodeStringFromStringEntry(stringEntry);
312 if (!displayHandle)
313 {
314 return decodedStr;
315 }
316
317 return displayString + "(" + decodedStr + ")";
John Wangb754eee2020-02-15 16:10:25 +0800318 }
319
320 std::string displayEnumValueByIndex(uint16_t attrHandle, uint8_t index,
321 const std::optional<Table>& attrTable,
322 const std::optional<Table>& stringTable)
323 {
324 std::string displayString;
325 if (!attrTable)
326 {
327 return displayString;
328 }
329
330 auto attrEntry = pldm_bios_table_attr_find_by_handle(
331 attrTable->data(), attrTable->size(), attrHandle);
332 if (attrEntry == nullptr)
333 {
334 return displayString;
335 }
336 auto pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
337 std::vector<uint16_t> pvHandls(pvNum);
338 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
339 attrEntry, pvHandls.data(), pvHandls.size());
Adair Li4dd11a72020-04-24 14:52:59 +0800340 return displayStringHandle(pvHandls[index], stringTable, false);
John Wangb754eee2020-02-15 16:10:25 +0800341 }
342
Adair Li4dd11a72020-04-24 14:52:59 +0800343 void displayAttributeValueEntry(
344 const pldm_bios_attr_val_table_entry* tableEntry,
345 const std::optional<Table>& attrTable,
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500346 const std::optional<Table>& stringTable, bool verbose,
347 ordered_json& output)
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));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500354
John Wang2cd07da2020-06-19 15:45:39 +0800355 if (verbose)
356 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500357 output["AttributeHandle"] = attrHandle;
George Liubd5e2ea2021-04-22 20:33:06 +0800358 if (attrTypeMap.contains(attrType))
359 {
360 output["AttributeType"] = attrTypeMap.at(attrType);
361 }
362 else
363 {
364 std::cout << "Get AttributeType failed.\n";
365 }
John Wang2cd07da2020-06-19 15:45:39 +0800366 }
Adair Li4dd11a72020-04-24 14:52:59 +0800367 switch (attrType)
368 {
369 case PLDM_BIOS_ENUMERATION:
370 case PLDM_BIOS_ENUMERATION_READ_ONLY:
371 {
372 auto count =
373 pldm_bios_table_attr_value_entry_enum_decode_number(
374 tableEntry);
375 std::vector<uint8_t> handles(count);
376 pldm_bios_table_attr_value_entry_enum_decode_handles(
377 tableEntry, handles.data(), handles.size());
John Wang2cd07da2020-06-19 15:45:39 +0800378 if (verbose)
379 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500380 output["NumberOfCurrentValues"] = (int)count;
John Wang2cd07da2020-06-19 15:45:39 +0800381 }
Adair Li4dd11a72020-04-24 14:52:59 +0800382 for (size_t i = 0; i < handles.size(); i++)
383 {
John Wang2cd07da2020-06-19 15:45:39 +0800384 if (verbose)
385 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500386 output["CurrentValueStringHandleIndex[" +
387 std::to_string(i) + "]"] =
388 displayEnumValueByIndex(attrHandle, handles[i],
389 attrTable, stringTable);
John Wang2cd07da2020-06-19 15:45:39 +0800390 }
391 else
392 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500393 output["CurrentValue"] = displayEnumValueByIndex(
394 attrHandle, handles[i], attrTable, stringTable);
John Wang2cd07da2020-06-19 15:45:39 +0800395 }
Adair Li4dd11a72020-04-24 14:52:59 +0800396 }
397 break;
398 }
399 case PLDM_BIOS_INTEGER:
400 case PLDM_BIOS_INTEGER_READ_ONLY:
401 {
402 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(
403 tableEntry);
John Wang2cd07da2020-06-19 15:45:39 +0800404 if (verbose)
405 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500406 output["CurrentValue"] = cv;
John Wang2cd07da2020-06-19 15:45:39 +0800407 }
408 else
409 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500410 output["CurrentValue"] = cv;
John Wang2cd07da2020-06-19 15:45:39 +0800411 }
Adair Li4dd11a72020-04-24 14:52:59 +0800412 break;
413 }
414 case PLDM_BIOS_STRING:
415 case PLDM_BIOS_STRING_READ_ONLY:
416 {
417 variable_field currentString;
418 pldm_bios_table_attr_value_entry_string_decode_string(
419 tableEntry, &currentString);
John Wang2cd07da2020-06-19 15:45:39 +0800420 if (verbose)
421 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500422 output["CurrentStringLength"] = currentString.length;
423 output["CurrentString"] = std::string(
424 reinterpret_cast<const char*>(currentString.ptr),
425 currentString.length);
John Wang2cd07da2020-06-19 15:45:39 +0800426 }
427 else
428 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500429 output["CurrentValue"] = std::string(
430 reinterpret_cast<const char*>(currentString.ptr),
431 currentString.length);
John Wang2cd07da2020-06-19 15:45:39 +0800432 }
Adair Li4dd11a72020-04-24 14:52:59 +0800433
434 break;
435 }
436 case PLDM_BIOS_PASSWORD:
437 case PLDM_BIOS_PASSWORD_READ_ONLY:
438 {
439 std::cout << "Password attribute: Not Supported" << std::endl;
440 break;
441 }
442 }
443 }
444};
445
446class GetBIOSTable : public GetBIOSTableHandler
447{
448 public:
449 ~GetBIOSTable() = default;
450 GetBIOSTable() = delete;
451 GetBIOSTable(const GetBIOSTable&) = delete;
452 GetBIOSTable(GetBIOSTable&&) = default;
453 GetBIOSTable& operator=(const GetBIOSTable&) = delete;
454 GetBIOSTable& operator=(GetBIOSTable&&) = default;
455
456 using Table = std::vector<uint8_t>;
457
458 explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
459 GetBIOSTableHandler(type, name, app)
460 {
461 app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
462 ->required()
463 ->transform(
464 CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
465 }
466
467 void exec() override
468 {
469 switch (pldmBIOSTableType)
470 {
471 case PLDM_BIOS_STRING_TABLE:
472 {
473 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
474 decodeStringTable(stringTable);
475 break;
476 }
477 case PLDM_BIOS_ATTR_TABLE:
478 {
479 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
480 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
481
482 decodeAttributeTable(attrTable, stringTable);
483 break;
484 }
485 case PLDM_BIOS_ATTR_VAL_TABLE:
486 {
487 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
488 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
489 auto attrValTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
490
491 decodeAttributeValueTable(attrValTable, attrTable, stringTable);
492 break;
493 }
494 }
495 }
496
497 private:
498 pldm_bios_table_types pldmBIOSTableType;
499
John Wangb754eee2020-02-15 16:10:25 +0800500 void decodeStringTable(const std::optional<Table>& stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600501 {
John Wangb754eee2020-02-15 16:10:25 +0800502 if (!stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600503 {
John Wangb754eee2020-02-15 16:10:25 +0800504 std::cerr << "GetBIOSStringTable Error" << std::endl;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600505 return;
506 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500507 ordered_json stringdata;
John Wangb754eee2020-02-15 16:10:25 +0800508
509 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
510 stringTable->data(), stringTable->size()))
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600511 {
John Wangb754eee2020-02-15 16:10:25 +0800512 auto strHandle =
513 pldm_bios_table_string_entry_decode_handle(tableEntry);
514 auto strTableData = decodeStringFromStringEntry(tableEntry);
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500515 stringdata[std::to_string(strHandle)] = strTableData;
John Wangb754eee2020-02-15 16:10:25 +0800516 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500517 pldmtool::helper::DisplayInJson(stringdata);
John Wangb754eee2020-02-15 16:10:25 +0800518 }
519 void decodeAttributeTable(const std::optional<Table>& attrTable,
520 const std::optional<Table>& stringTable)
521 {
John Wangb754eee2020-02-15 16:10:25 +0800522 if (!stringTable)
523 {
524 std::cerr << "GetBIOSAttributeTable Error" << std::endl;
525 return;
526 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500527 ordered_json output;
528
John Wangb754eee2020-02-15 16:10:25 +0800529 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
530 attrTable->data(), attrTable->size()))
531 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500532 ordered_json attrdata;
533
John Wangb754eee2020-02-15 16:10:25 +0800534 auto attrHandle =
535 pldm_bios_table_attr_entry_decode_attribute_handle(entry);
536 auto attrNameHandle =
537 pldm_bios_table_attr_entry_decode_string_handle(entry);
538 auto attrType = static_cast<pldm_bios_attribute_type>(
539 pldm_bios_table_attr_entry_decode_attribute_type(entry));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500540
541 attrdata["AttributeHandle"] = attrHandle;
542 attrdata["AttributeNameHandle"] =
543 displayStringHandle(attrNameHandle, stringTable);
George Liubd5e2ea2021-04-22 20:33:06 +0800544 if (attrTypeMap.contains(attrType))
545 {
546 attrdata["AttributeType"] = attrTypeMap.at(attrType);
547 }
548 else
549 {
550 std::cout << "Get AttributeType failed.\n";
551 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500552
John Wangb754eee2020-02-15 16:10:25 +0800553 switch (attrType)
554 {
555 case PLDM_BIOS_ENUMERATION:
556 case PLDM_BIOS_ENUMERATION_READ_ONLY:
557 {
558 auto pvNum =
559 pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
560 std::vector<uint16_t> pvHandls(pvNum);
561 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
562 entry, pvHandls.data(), pvHandls.size());
563 auto defNum =
564 pldm_bios_table_attr_entry_enum_decode_def_num(entry);
565 std::vector<uint8_t> defIndices(defNum);
566 pldm_bios_table_attr_entry_enum_decode_def_indices(
567 entry, defIndices.data(), defIndices.size());
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500568
569 attrdata["NumberOfPossibleValues"] = (int)pvNum;
John Wangb754eee2020-02-15 16:10:25 +0800570
571 for (size_t i = 0; i < pvHandls.size(); i++)
572 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500573 attrdata["PossibleValueStringHandle[" +
574 std::to_string(i) + "]"] =
575 displayStringHandle(pvHandls[i], stringTable);
John Wangb754eee2020-02-15 16:10:25 +0800576 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500577 attrdata["NumberOfDefaultValues"] = (int)defNum;
John Wangb754eee2020-02-15 16:10:25 +0800578 for (size_t i = 0; i < defIndices.size(); i++)
579 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500580 attrdata["DefaultValueStringHandleIndex[" +
581 std::to_string(i) + "]"] = (int)defIndices[i];
George Liua6daacb2021-03-23 11:18:41 +0800582 attrdata["DefaultValueStringHandle"] =
583 displayStringHandle(pvHandls[defIndices[i]],
584 stringTable);
John Wangb754eee2020-02-15 16:10:25 +0800585 }
586 break;
587 }
588 case PLDM_BIOS_INTEGER:
589 case PLDM_BIOS_INTEGER_READ_ONLY:
590 {
591 uint64_t lower, upper, def;
592 uint32_t scalar;
593 pldm_bios_table_attr_entry_integer_decode(
594 entry, &lower, &upper, &scalar, &def);
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500595 attrdata["LowerBound"] = lower;
596 attrdata["UpperBound"] = upper;
597 attrdata["ScalarIncrement"] = scalar;
598 attrdata["DefaultValue"] = def;
John Wangb754eee2020-02-15 16:10:25 +0800599 break;
600 }
601 case PLDM_BIOS_STRING:
602 case PLDM_BIOS_STRING_READ_ONLY:
603 {
604 auto strType =
605 pldm_bios_table_attr_entry_string_decode_string_type(
606 entry);
607 auto min =
608 pldm_bios_table_attr_entry_string_decode_min_length(
609 entry);
610 auto max =
611 pldm_bios_table_attr_entry_string_decode_max_length(
612 entry);
613 auto def =
614 pldm_bios_table_attr_entry_string_decode_def_string_length(
615 entry);
616 std::vector<char> defString(def + 1);
617 pldm_bios_table_attr_entry_string_decode_def_string(
618 entry, defString.data(), defString.size());
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500619
620 std::stringstream stringtype;
621 stringtype << "0x" << std::hex << std::setw(2)
622 << std::setfill('0') << (int)strType << std::dec
623 << std::setw(0);
624 attrdata["StringType"] = stringtype.str();
625 attrdata["MinimumStringLength"] = (int)min;
626 attrdata["MaximumStringLength"] = (int)max;
627 attrdata["DefaultStringLength"] = (int)def;
628 attrdata["DefaultString"] = defString.data();
John Wangb754eee2020-02-15 16:10:25 +0800629 break;
630 }
631 case PLDM_BIOS_PASSWORD:
632 case PLDM_BIOS_PASSWORD_READ_ONLY:
633 std::cout << "Password attribute: Not Supported"
634 << std::endl;
635 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500636 output.emplace_back(std::move(attrdata));
John Wangb754eee2020-02-15 16:10:25 +0800637 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500638 pldmtool::helper::DisplayInJson(output);
John Wangb754eee2020-02-15 16:10:25 +0800639 }
640 void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
641 const std::optional<Table>& attrTable,
642 const std::optional<Table>& stringTable)
643 {
John Wangb754eee2020-02-15 16:10:25 +0800644 if (!attrValTable)
645 {
646 std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
647 return;
648 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500649 ordered_json output;
John Wangb754eee2020-02-15 16:10:25 +0800650 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
651 attrValTable->data(), attrValTable->size()))
652 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500653 ordered_json attrValueData;
654 displayAttributeValueEntry(tableEntry, attrTable, stringTable, true,
655 attrValueData);
656 output.emplace_back(attrValueData);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600657 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500658 pldmtool::helper::DisplayInJson(output);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600659 }
660};
661
Adair Li4dd11a72020-04-24 14:52:59 +0800662class GetBIOSAttributeCurrentValueByHandle : public GetBIOSTableHandler
663{
664 public:
665 ~GetBIOSAttributeCurrentValueByHandle() = default;
666 GetBIOSAttributeCurrentValueByHandle(
667 const GetBIOSAttributeCurrentValueByHandle&) = delete;
668 GetBIOSAttributeCurrentValueByHandle(
669 GetBIOSAttributeCurrentValueByHandle&&) = delete;
670 GetBIOSAttributeCurrentValueByHandle&
671 operator=(const GetBIOSAttributeCurrentValueByHandle&) = delete;
672 GetBIOSAttributeCurrentValueByHandle&
673 operator=(GetBIOSAttributeCurrentValueByHandle&&) = delete;
674
675 explicit GetBIOSAttributeCurrentValueByHandle(const char* type,
676 const char* name,
677 CLI::App* app) :
678 GetBIOSTableHandler(type, name, app)
679 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500680 app->add_option("-a, --attribute", attrName, "pldm BIOS attribute name")
Adair Li4dd11a72020-04-24 14:52:59 +0800681 ->required();
682 }
683
684 void exec()
685 {
686 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
687 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
688
689 if (!stringTable || !attrTable)
690 {
691 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
692 return;
693 }
694
695 auto handle = findAttrHandleByName(attrName, *attrTable, *stringTable);
John Wangcee24b62020-06-19 17:23:10 +0800696 if (!handle)
697 {
698
699 std::cerr << "Can not find the attribute " << attrName << std::endl;
700 return;
701 }
Adair Li4dd11a72020-04-24 14:52:59 +0800702
703 std::vector<uint8_t> requestMsg(
704 sizeof(pldm_msg_hdr) +
705 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES);
706 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
707
708 auto rc = encode_get_bios_attribute_current_value_by_handle_req(
709 instanceId, 0, PLDM_GET_FIRSTPART, *handle, request);
710 if (rc != PLDM_SUCCESS)
711 {
712 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
713 return;
714 }
715
716 std::vector<uint8_t> responseMsg;
717 rc = pldmSendRecv(requestMsg, responseMsg);
718 if (rc != PLDM_SUCCESS)
719 {
720 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
721 return;
722 }
723
724 uint8_t cc = 0, transferFlag = 0;
725 uint32_t nextTransferHandle = 0;
726 struct variable_field attributeData;
727 auto responsePtr =
728 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
729 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
730
731 rc = decode_get_bios_attribute_current_value_by_handle_resp(
732 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
733 &attributeData);
734 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
735 {
736 std::cerr << "Response Message Error: "
737 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
738 return;
739 }
740
741 auto tableEntry =
742 reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
743 attributeData.ptr);
744
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500745 ordered_json avdata;
746 displayAttributeValueEntry(tableEntry, attrTable, stringTable, false,
747 avdata);
748 pldmtool::helper::DisplayInJson(avdata);
Adair Li4dd11a72020-04-24 14:52:59 +0800749 }
750
751 private:
752 std::string attrName;
753};
754
Adair Lice041e22020-05-09 17:27:43 +0800755class SetBIOSAttributeCurrentValue : public GetBIOSTableHandler
756{
757 public:
758 ~SetBIOSAttributeCurrentValue() = default;
759 SetBIOSAttributeCurrentValue() = delete;
760 SetBIOSAttributeCurrentValue(const SetBIOSAttributeCurrentValue&) = delete;
761 SetBIOSAttributeCurrentValue(SetBIOSAttributeCurrentValue&&) = default;
762 SetBIOSAttributeCurrentValue&
763 operator=(const SetBIOSAttributeCurrentValue&) = delete;
764 SetBIOSAttributeCurrentValue&
765 operator=(SetBIOSAttributeCurrentValue&&) = default;
766
767 explicit SetBIOSAttributeCurrentValue(const char* type, const char* name,
768 CLI::App* app) :
769 GetBIOSTableHandler(type, name, app)
770 {
771 app->add_option("-a, --attribute", attrName, "pldm attribute name")
772 ->required();
773 app->add_option("-d, --data", attrValue, "pldm attribute value")
774 ->required();
775 // -v is conflict with --verbose in class CommandInterface, so used -d
776 }
777
778 void exec()
779 {
780 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
781 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
782 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
783
784 if (!stringTable || !attrTable)
785 {
786 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
787 return;
788 }
789
790 auto attrEntry =
791 findAttrEntryByName(attrName, *attrTable, *stringTable);
792 if (attrEntry == nullptr)
793 {
794 std::cout << "Could not find attribute :" << attrName << std::endl;
795 return;
796 }
797
798 std::vector<uint8_t> requestMsg;
799
800 int rc = 0;
801 auto attrType = attrEntry->attr_type;
802 size_t entryLength = 1;
803 std::vector<uint8_t> attrValueEntry(entryLength, 0);
804
805 switch (attrType)
806 {
Adair Lice041e22020-05-09 17:27:43 +0800807 case PLDM_BIOS_ENUMERATION:
George Liu5bb9edb2021-08-05 20:10:32 +0800808 case PLDM_BIOS_ENUMERATION_READ_ONLY:
Adair Lice041e22020-05-09 17:27:43 +0800809 {
810 entryLength =
811 pldm_bios_table_attr_value_entry_encode_enum_length(1);
812 auto pvNum =
813 pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
814 std::vector<uint16_t> pvHdls(pvNum, 0);
815 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
816 attrEntry, pvHdls.data(), pvNum);
817 auto stringEntry = pldm_bios_table_string_find_by_string(
818 stringTable->data(), stringTable->size(),
819 attrValue.c_str());
820 if (stringEntry == nullptr)
821 {
822 std::cout
823 << "Set Attribute Error: It's not a possible value"
824 << std::endl;
825 return;
826 }
827 auto valueHandle =
828 pldm_bios_table_string_entry_decode_handle(stringEntry);
829
830 uint8_t i;
831 for (i = 0; i < pvNum; i++)
832 {
833 if (valueHandle == pvHdls[i])
834 break;
835 }
836 if (i == pvNum)
837 {
838 std::cout
839 << "Set Attribute Error: It's not a possible value"
840 << std::endl;
841 return;
842 }
843
844 attrValueEntry.resize(entryLength);
845 std::vector<uint8_t> handles = {i};
846 pldm_bios_table_attr_value_entry_encode_enum(
847 attrValueEntry.data(), attrValueEntry.size(),
848 attrEntry->attr_handle, attrType, 1, handles.data());
849 break;
850 }
851 case PLDM_BIOS_STRING:
George Liu5bb9edb2021-08-05 20:10:32 +0800852 case PLDM_BIOS_STRING_READ_ONLY:
Adair Lice041e22020-05-09 17:27:43 +0800853 {
854 entryLength =
855 pldm_bios_table_attr_value_entry_encode_string_length(
856 attrValue.size());
857
858 attrValueEntry.resize(entryLength);
859
860 pldm_bios_table_attr_value_entry_encode_string(
861 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
862 attrType, attrValue.size(), attrValue.c_str());
863 break;
864 }
865 case PLDM_BIOS_INTEGER:
George Liu5bb9edb2021-08-05 20:10:32 +0800866 case PLDM_BIOS_INTEGER_READ_ONLY:
Adair Lice041e22020-05-09 17:27:43 +0800867 {
868 uint64_t value = std::stoll(attrValue);
869 entryLength =
870 pldm_bios_table_attr_value_entry_encode_integer_length();
871 attrValueEntry.resize(entryLength);
872 pldm_bios_table_attr_value_entry_encode_integer(
873 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
874 attrType, value);
875 break;
876 }
877 }
878
879 requestMsg.resize(entryLength + sizeof(pldm_msg_hdr) +
880 PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES);
881
882 rc = encode_set_bios_attribute_current_value_req(
883 instanceId, 0, PLDM_START_AND_END, attrValueEntry.data(),
884 attrValueEntry.size(),
885 reinterpret_cast<pldm_msg*>(requestMsg.data()),
886 requestMsg.size() - sizeof(pldm_msg_hdr));
887
888 if (rc != PLDM_SUCCESS)
889 {
890 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
891 return;
892 }
893 std::vector<uint8_t> responseMsg;
894 rc = pldmSendRecv(requestMsg, responseMsg);
895 if (rc != PLDM_SUCCESS)
896 {
897 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
898 return;
899 }
900 uint8_t cc = 0;
901 uint32_t nextTransferHandle = 0;
902 auto responsePtr =
903 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
904 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
905
906 rc = decode_set_bios_attribute_current_value_resp(
907 responsePtr, payloadLength, &cc, &nextTransferHandle);
908 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
909 {
910 std::cerr << "Response Message Error: "
911 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
912 return;
913 }
914
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500915 ordered_json data;
916 data["Response"] = "SUCCESS";
917 pldmtool::helper::DisplayInJson(data);
Adair Lice041e22020-05-09 17:27:43 +0800918 }
919
920 private:
921 std::string attrName;
922 std::string attrValue;
923};
924
Sridevi Ramesh98576432019-11-27 10:10:28 -0600925void registerCommand(CLI::App& app)
926{
927 auto bios = app.add_subcommand("bios", "bios type command");
928 bios->require_subcommand(1);
929 auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
930 commands.push_back(
931 std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
George Liud6649362019-11-27 19:06:51 +0800932
933 auto setDateTime =
934 bios->add_subcommand("SetDateTime", "set host date time");
935 commands.push_back(
936 std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600937
938 auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
939 commands.push_back(
940 std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));
Adair Li4dd11a72020-04-24 14:52:59 +0800941
942 auto getBIOSAttributeCurrentValueByHandle =
943 bios->add_subcommand("GetBIOSAttributeCurrentValueByHandle",
944 "get bios attribute current value by handle");
945 commands.push_back(std::make_unique<GetBIOSAttributeCurrentValueByHandle>(
946 "bios", "GetBIOSAttributeCurrentValueByHandle",
947 getBIOSAttributeCurrentValueByHandle));
Adair Lice041e22020-05-09 17:27:43 +0800948
949 auto setBIOSAttributeCurrentValue = bios->add_subcommand(
950 "SetBIOSAttributeCurrentValue", "set bios attribute current value");
951 commands.push_back(std::make_unique<SetBIOSAttributeCurrentValue>(
952 "bios", "SetBIOSAttributeCurrentValue", setBIOSAttributeCurrentValue));
Sridevi Ramesh98576432019-11-27 10:10:28 -0600953}
954
955} // namespace bios
956
957} // namespace pldmtool