blob: 68fc2d8b91c2172db09785d601e6426e4b0a0b26 [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 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -050071
72 std::stringstream dt;
73 ordered_json data;
74 dt << bcd2dec16(year) << "-" << setWidth(month) << "-" << setWidth(day)
75 << " " << setWidth(hours) << ":" << setWidth(minutes) << ":"
76 << setWidth(seconds);
77 data["Response"] = dt.str();
78 pldmtool::helper::DisplayInJson(data);
Sridevi Ramesh98576432019-11-27 10:10:28 -060079 }
80
81 private:
Sridevi Rameshca4a8152020-08-11 09:26:19 -050082 static std::string setWidth(uint8_t data)
Sridevi Ramesh98576432019-11-27 10:10:28 -060083 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -050084 std::stringstream s;
85 s << std::setfill('0') << std::setw(2)
86 << static_cast<uint32_t>(bcd2dec8(data));
87 return s.str();
Sridevi Ramesh98576432019-11-27 10:10:28 -060088 }
89};
90
George Liud6649362019-11-27 19:06:51 +080091class SetDateTime : public CommandInterface
92{
93 public:
94 ~SetDateTime() = default;
95 SetDateTime() = delete;
96 SetDateTime(const SetDateTime&) = delete;
97 SetDateTime(SetDateTime&&) = default;
98 SetDateTime& operator=(const SetDateTime&) = delete;
99 SetDateTime& operator=(SetDateTime&&) = default;
100
101 explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
102 CommandInterface(type, name, app)
103 {
104 app->add_option("-d,--data", tmData,
105 "set date time data\n"
106 "eg: YYYYMMDDHHMMSS")
107 ->required();
108 }
109
110 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
111 {
112 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
113 sizeof(struct pldm_set_date_time_req));
114 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
115 uint16_t year = 0;
116 uint8_t month = 0;
117 uint8_t day = 0;
118 uint8_t hours = 0;
119 uint8_t minutes = 0;
120 uint8_t seconds = 0;
121
122 if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
123 &seconds))
124 {
125 std::cerr << "decode date Error: "
126 << "tmData=" << tmData << std::endl;
127
128 return {PLDM_ERROR_INVALID_DATA, requestMsg};
129 }
130
131 auto rc = encode_set_date_time_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600132 instanceId, seconds, minutes, hours, day, month, year, request,
133 sizeof(struct pldm_set_date_time_req));
George Liud6649362019-11-27 19:06:51 +0800134
135 return {rc, requestMsg};
136 }
137
138 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
139 {
140 uint8_t completionCode = 0;
141 auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
142 &completionCode);
143
144 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
145 {
146 std::cerr << "Response Message Error: "
147 << "rc=" << rc << ",cc=" << (int)completionCode
148 << std::endl;
149 return;
150 }
151
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500152 ordered_json data;
153 data["Response"] = "SUCCESS";
154 pldmtool::helper::DisplayInJson(data);
George Liud6649362019-11-27 19:06:51 +0800155 }
156
157 private:
158 uint64_t tmData;
159};
160
Adair Li4dd11a72020-04-24 14:52:59 +0800161class GetBIOSTableHandler : public CommandInterface
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600162{
163 public:
Adair Li4dd11a72020-04-24 14:52:59 +0800164 ~GetBIOSTableHandler() = default;
165 GetBIOSTableHandler() = delete;
166 GetBIOSTableHandler(const GetBIOSTableHandler&) = delete;
167 GetBIOSTableHandler(GetBIOSTableHandler&&) = delete;
168 GetBIOSTableHandler& operator=(const GetBIOSTableHandler&) = delete;
169 GetBIOSTableHandler& operator=(GetBIOSTableHandler&&) = delete;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600170
John Wangb754eee2020-02-15 16:10:25 +0800171 using Table = std::vector<uint8_t>;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600172
Adair Li4dd11a72020-04-24 14:52:59 +0800173 using CommandInterface::CommandInterface;
174
175 static inline const std::map<pldm_bios_attribute_type, const char*>
176 attrTypeMap = {
177 {PLDM_BIOS_ENUMERATION, "BIOSEnumeration"},
178 {PLDM_BIOS_ENUMERATION_READ_ONLY, "BIOSEnumerationReadOnly"},
179 {PLDM_BIOS_STRING, "BIOSString"},
180 {PLDM_BIOS_STRING_READ_ONLY, "BIOSStringReadOnly"},
181 {PLDM_BIOS_PASSWORD, "BIOSPassword"},
182 {PLDM_BIOS_PASSWORD_READ_ONLY, "BIOSPasswordReadOnly"},
183 {PLDM_BIOS_INTEGER, "BIOSInteger"},
184 {PLDM_BIOS_INTEGER_READ_ONLY, "BIOSIntegerReadOnly"},
185
186 };
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600187
188 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
189 {
John Wangb754eee2020-02-15 16:10:25 +0800190 return {PLDM_ERROR, {}};
191 }
Adair Li4dd11a72020-04-24 14:52:59 +0800192
John Wangb754eee2020-02-15 16:10:25 +0800193 void parseResponseMsg(pldm_msg*, size_t) override
George Liu6492f522020-06-16 10:34:05 +0800194 {}
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600195
John Wangb754eee2020-02-15 16:10:25 +0800196 std::optional<Table> getBIOSTable(pldm_bios_table_types tableType)
197 {
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600198 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
199 PLDM_GET_BIOS_TABLE_REQ_BYTES);
200 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
201
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600202 auto rc = encode_get_bios_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
203 tableType, request);
John Wangb754eee2020-02-15 16:10:25 +0800204 if (rc != PLDM_SUCCESS)
205 {
206 std::cerr << "Encode GetBIOSTable Error, tableType=," << tableType
207 << " ,rc=" << rc << std::endl;
208 return std::nullopt;
209 }
210 std::vector<uint8_t> responseMsg;
211 rc = pldmSendRecv(requestMsg, responseMsg);
212 if (rc != PLDM_SUCCESS)
213 {
214 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
215 return std::nullopt;
216 }
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600217
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600218 uint8_t cc = 0, transferFlag = 0;
219 uint32_t nextTransferHandle = 0;
220 size_t bios_table_offset;
John Wangb754eee2020-02-15 16:10:25 +0800221 auto responsePtr =
222 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
223 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600224
John Wangb754eee2020-02-15 16:10:25 +0800225 rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc,
226 &nextTransferHandle, &transferFlag,
227 &bios_table_offset);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600228
229 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
230 {
John Wangb754eee2020-02-15 16:10:25 +0800231 std::cerr << "GetBIOSTable Response Error: tableType=" << tableType
232 << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
233 return std::nullopt;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600234 }
235 auto tableData =
236 reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset);
John Wangb754eee2020-02-15 16:10:25 +0800237 auto tableSize = payloadLength - sizeof(nextTransferHandle) -
238 sizeof(transferFlag) - sizeof(cc);
239 return std::make_optional<Table>(tableData, tableData + tableSize);
240 }
241
Adair Lice041e22020-05-09 17:27:43 +0800242 const pldm_bios_attr_table_entry*
243 findAttrEntryByName(const std::string& name, const Table& attrTable,
244 const Table& stringTable)
John Wangb754eee2020-02-15 16:10:25 +0800245 {
Adair Li4dd11a72020-04-24 14:52:59 +0800246 auto stringEntry = pldm_bios_table_string_find_by_string(
247 stringTable.data(), stringTable.size(), name.c_str());
248 if (stringEntry == nullptr)
John Wangb754eee2020-02-15 16:10:25 +0800249 {
Adair Lice041e22020-05-09 17:27:43 +0800250 return nullptr;
Adair Li4dd11a72020-04-24 14:52:59 +0800251 }
John Wangb754eee2020-02-15 16:10:25 +0800252
Adair Li4dd11a72020-04-24 14:52:59 +0800253 auto nameHandle =
254 pldm_bios_table_string_entry_decode_handle(stringEntry);
John Wangb754eee2020-02-15 16:10:25 +0800255
Adair Li4dd11a72020-04-24 14:52:59 +0800256 for (auto attr : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable.data(),
257 attrTable.size()))
258 {
259 auto attrNameHandle =
260 pldm_bios_table_attr_entry_decode_string_handle(attr);
261 if (attrNameHandle == nameHandle)
262 {
Adair Lice041e22020-05-09 17:27:43 +0800263 return attr;
John Wangb754eee2020-02-15 16:10:25 +0800264 }
265 }
Adair Lice041e22020-05-09 17:27:43 +0800266 return nullptr;
267 }
268
269 std::optional<uint16_t> findAttrHandleByName(const std::string& name,
270 const Table& attrTable,
271 const Table& stringTable)
272 {
273 auto attribute = findAttrEntryByName(name, attrTable, stringTable);
274 if (attribute == nullptr)
275 {
276 return std::nullopt;
277 }
278
279 return pldm_bios_table_attr_entry_decode_attribute_handle(attribute);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600280 }
281
John Wangb754eee2020-02-15 16:10:25 +0800282 std::string decodeStringFromStringEntry(
283 const pldm_bios_string_table_entry* stringEntry)
284 {
285 auto strLength =
286 pldm_bios_table_string_entry_decode_string_length(stringEntry);
287 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
288 pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
289 buffer.size());
290
291 return std::string(buffer.data(), buffer.data() + strLength);
292 }
293
294 std::string displayStringHandle(uint16_t handle,
Adair Li4dd11a72020-04-24 14:52:59 +0800295 const std::optional<Table>& stringTable,
296 bool displayHandle = true)
John Wangb754eee2020-02-15 16:10:25 +0800297 {
298 std::string displayString = std::to_string(handle);
299 if (!stringTable)
300 {
301 return displayString;
302 }
303 auto stringEntry = pldm_bios_table_string_find_by_handle(
304 stringTable->data(), stringTable->size(), handle);
305 if (stringEntry == nullptr)
306 {
307 return displayString;
308 }
309
Adair Li4dd11a72020-04-24 14:52:59 +0800310 auto decodedStr = decodeStringFromStringEntry(stringEntry);
311 if (!displayHandle)
312 {
313 return decodedStr;
314 }
315
316 return displayString + "(" + decodedStr + ")";
John Wangb754eee2020-02-15 16:10:25 +0800317 }
318
319 std::string displayEnumValueByIndex(uint16_t attrHandle, uint8_t index,
320 const std::optional<Table>& attrTable,
321 const std::optional<Table>& stringTable)
322 {
323 std::string displayString;
324 if (!attrTable)
325 {
326 return displayString;
327 }
328
329 auto attrEntry = pldm_bios_table_attr_find_by_handle(
330 attrTable->data(), attrTable->size(), attrHandle);
331 if (attrEntry == nullptr)
332 {
333 return displayString;
334 }
335 auto pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
336 std::vector<uint16_t> pvHandls(pvNum);
337 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
338 attrEntry, pvHandls.data(), pvHandls.size());
Adair Li4dd11a72020-04-24 14:52:59 +0800339 return displayStringHandle(pvHandls[index], stringTable, false);
John Wangb754eee2020-02-15 16:10:25 +0800340 }
341
Adair Li4dd11a72020-04-24 14:52:59 +0800342 void displayAttributeValueEntry(
343 const pldm_bios_attr_val_table_entry* tableEntry,
344 const std::optional<Table>& attrTable,
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500345 const std::optional<Table>& stringTable, bool verbose,
346 ordered_json& output)
Adair Li4dd11a72020-04-24 14:52:59 +0800347 {
348 auto attrHandle =
349 pldm_bios_table_attr_value_entry_decode_attribute_handle(
350 tableEntry);
351 auto attrType = static_cast<pldm_bios_attribute_type>(
352 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500353
John Wang2cd07da2020-06-19 15:45:39 +0800354 if (verbose)
355 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500356 output["AttributeHandle"] = attrHandle;
357 output["AttributeType"] = attrTypeMap.at(attrType);
John Wang2cd07da2020-06-19 15:45:39 +0800358 }
Adair Li4dd11a72020-04-24 14:52:59 +0800359 switch (attrType)
360 {
361 case PLDM_BIOS_ENUMERATION:
362 case PLDM_BIOS_ENUMERATION_READ_ONLY:
363 {
364 auto count =
365 pldm_bios_table_attr_value_entry_enum_decode_number(
366 tableEntry);
367 std::vector<uint8_t> handles(count);
368 pldm_bios_table_attr_value_entry_enum_decode_handles(
369 tableEntry, handles.data(), handles.size());
John Wang2cd07da2020-06-19 15:45:39 +0800370 if (verbose)
371 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500372 output["NumberOfCurrentValues"] = (int)count;
John Wang2cd07da2020-06-19 15:45:39 +0800373 }
Adair Li4dd11a72020-04-24 14:52:59 +0800374 for (size_t i = 0; i < handles.size(); i++)
375 {
John Wang2cd07da2020-06-19 15:45:39 +0800376 if (verbose)
377 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500378 output["CurrentValueStringHandleIndex[" +
379 std::to_string(i) + "]"] =
380 displayEnumValueByIndex(attrHandle, handles[i],
381 attrTable, stringTable);
John Wang2cd07da2020-06-19 15:45:39 +0800382 }
383 else
384 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500385 output["CurrentValue"] = displayEnumValueByIndex(
386 attrHandle, handles[i], attrTable, stringTable);
John Wang2cd07da2020-06-19 15:45:39 +0800387 }
Adair Li4dd11a72020-04-24 14:52:59 +0800388 }
389 break;
390 }
391 case PLDM_BIOS_INTEGER:
392 case PLDM_BIOS_INTEGER_READ_ONLY:
393 {
394 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(
395 tableEntry);
John Wang2cd07da2020-06-19 15:45:39 +0800396 if (verbose)
397 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500398 output["CurrentValue"] = cv;
John Wang2cd07da2020-06-19 15:45:39 +0800399 }
400 else
401 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500402 output["CurrentValue"] = cv;
John Wang2cd07da2020-06-19 15:45:39 +0800403 }
Adair Li4dd11a72020-04-24 14:52:59 +0800404 break;
405 }
406 case PLDM_BIOS_STRING:
407 case PLDM_BIOS_STRING_READ_ONLY:
408 {
409 variable_field currentString;
410 pldm_bios_table_attr_value_entry_string_decode_string(
411 tableEntry, &currentString);
John Wang2cd07da2020-06-19 15:45:39 +0800412 if (verbose)
413 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500414 output["CurrentStringLength"] = currentString.length;
415 output["CurrentString"] = std::string(
416 reinterpret_cast<const char*>(currentString.ptr),
417 currentString.length);
John Wang2cd07da2020-06-19 15:45:39 +0800418 }
419 else
420 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500421 output["CurrentValue"] = std::string(
422 reinterpret_cast<const char*>(currentString.ptr),
423 currentString.length);
John Wang2cd07da2020-06-19 15:45:39 +0800424 }
Adair Li4dd11a72020-04-24 14:52:59 +0800425
426 break;
427 }
428 case PLDM_BIOS_PASSWORD:
429 case PLDM_BIOS_PASSWORD_READ_ONLY:
430 {
431 std::cout << "Password attribute: Not Supported" << std::endl;
432 break;
433 }
434 }
435 }
436};
437
438class GetBIOSTable : public GetBIOSTableHandler
439{
440 public:
441 ~GetBIOSTable() = default;
442 GetBIOSTable() = delete;
443 GetBIOSTable(const GetBIOSTable&) = delete;
444 GetBIOSTable(GetBIOSTable&&) = default;
445 GetBIOSTable& operator=(const GetBIOSTable&) = delete;
446 GetBIOSTable& operator=(GetBIOSTable&&) = default;
447
448 using Table = std::vector<uint8_t>;
449
450 explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
451 GetBIOSTableHandler(type, name, app)
452 {
453 app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
454 ->required()
455 ->transform(
456 CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
457 }
458
459 void exec() override
460 {
461 switch (pldmBIOSTableType)
462 {
463 case PLDM_BIOS_STRING_TABLE:
464 {
465 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
466 decodeStringTable(stringTable);
467 break;
468 }
469 case PLDM_BIOS_ATTR_TABLE:
470 {
471 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
472 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
473
474 decodeAttributeTable(attrTable, stringTable);
475 break;
476 }
477 case PLDM_BIOS_ATTR_VAL_TABLE:
478 {
479 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
480 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
481 auto attrValTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
482
483 decodeAttributeValueTable(attrValTable, attrTable, stringTable);
484 break;
485 }
486 }
487 }
488
489 private:
490 pldm_bios_table_types pldmBIOSTableType;
491
John Wangb754eee2020-02-15 16:10:25 +0800492 void decodeStringTable(const std::optional<Table>& stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600493 {
John Wangb754eee2020-02-15 16:10:25 +0800494 if (!stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600495 {
John Wangb754eee2020-02-15 16:10:25 +0800496 std::cerr << "GetBIOSStringTable Error" << std::endl;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600497 return;
498 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500499 ordered_json stringdata;
John Wangb754eee2020-02-15 16:10:25 +0800500
501 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
502 stringTable->data(), stringTable->size()))
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600503 {
John Wangb754eee2020-02-15 16:10:25 +0800504 auto strHandle =
505 pldm_bios_table_string_entry_decode_handle(tableEntry);
506 auto strTableData = decodeStringFromStringEntry(tableEntry);
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500507 stringdata[std::to_string(strHandle)] = strTableData;
John Wangb754eee2020-02-15 16:10:25 +0800508 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500509 pldmtool::helper::DisplayInJson(stringdata);
John Wangb754eee2020-02-15 16:10:25 +0800510 }
511 void decodeAttributeTable(const std::optional<Table>& attrTable,
512 const std::optional<Table>& stringTable)
513 {
John Wangb754eee2020-02-15 16:10:25 +0800514 if (!stringTable)
515 {
516 std::cerr << "GetBIOSAttributeTable Error" << std::endl;
517 return;
518 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500519 ordered_json output;
520
John Wangb754eee2020-02-15 16:10:25 +0800521 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
522 attrTable->data(), attrTable->size()))
523 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500524 ordered_json attrdata;
525
John Wangb754eee2020-02-15 16:10:25 +0800526 auto attrHandle =
527 pldm_bios_table_attr_entry_decode_attribute_handle(entry);
528 auto attrNameHandle =
529 pldm_bios_table_attr_entry_decode_string_handle(entry);
530 auto attrType = static_cast<pldm_bios_attribute_type>(
531 pldm_bios_table_attr_entry_decode_attribute_type(entry));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500532
533 attrdata["AttributeHandle"] = attrHandle;
534 attrdata["AttributeNameHandle"] =
535 displayStringHandle(attrNameHandle, stringTable);
536 attrdata["AttributeType"] = attrTypeMap.at(attrType);
537
John Wangb754eee2020-02-15 16:10:25 +0800538 switch (attrType)
539 {
540 case PLDM_BIOS_ENUMERATION:
541 case PLDM_BIOS_ENUMERATION_READ_ONLY:
542 {
543 auto pvNum =
544 pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
545 std::vector<uint16_t> pvHandls(pvNum);
546 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
547 entry, pvHandls.data(), pvHandls.size());
548 auto defNum =
549 pldm_bios_table_attr_entry_enum_decode_def_num(entry);
550 std::vector<uint8_t> defIndices(defNum);
551 pldm_bios_table_attr_entry_enum_decode_def_indices(
552 entry, defIndices.data(), defIndices.size());
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500553
554 attrdata["NumberOfPossibleValues"] = (int)pvNum;
John Wangb754eee2020-02-15 16:10:25 +0800555
556 for (size_t i = 0; i < pvHandls.size(); i++)
557 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500558 attrdata["PossibleValueStringHandle[" +
559 std::to_string(i) + "]"] =
560 displayStringHandle(pvHandls[i], stringTable);
John Wangb754eee2020-02-15 16:10:25 +0800561 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500562 attrdata["NumberOfDefaultValues"] = (int)defNum;
John Wangb754eee2020-02-15 16:10:25 +0800563 for (size_t i = 0; i < defIndices.size(); i++)
564 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500565 attrdata["DefaultValueStringHandleIndex[" +
566 std::to_string(i) + "]"] = (int)defIndices[i];
George Liua6daacb2021-03-23 11:18:41 +0800567 attrdata["DefaultValueStringHandle"] =
568 displayStringHandle(pvHandls[defIndices[i]],
569 stringTable);
John Wangb754eee2020-02-15 16:10:25 +0800570 }
571 break;
572 }
573 case PLDM_BIOS_INTEGER:
574 case PLDM_BIOS_INTEGER_READ_ONLY:
575 {
576 uint64_t lower, upper, def;
577 uint32_t scalar;
578 pldm_bios_table_attr_entry_integer_decode(
579 entry, &lower, &upper, &scalar, &def);
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500580 attrdata["LowerBound"] = lower;
581 attrdata["UpperBound"] = upper;
582 attrdata["ScalarIncrement"] = scalar;
583 attrdata["DefaultValue"] = def;
John Wangb754eee2020-02-15 16:10:25 +0800584 break;
585 }
586 case PLDM_BIOS_STRING:
587 case PLDM_BIOS_STRING_READ_ONLY:
588 {
589 auto strType =
590 pldm_bios_table_attr_entry_string_decode_string_type(
591 entry);
592 auto min =
593 pldm_bios_table_attr_entry_string_decode_min_length(
594 entry);
595 auto max =
596 pldm_bios_table_attr_entry_string_decode_max_length(
597 entry);
598 auto def =
599 pldm_bios_table_attr_entry_string_decode_def_string_length(
600 entry);
601 std::vector<char> defString(def + 1);
602 pldm_bios_table_attr_entry_string_decode_def_string(
603 entry, defString.data(), defString.size());
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500604
605 std::stringstream stringtype;
606 stringtype << "0x" << std::hex << std::setw(2)
607 << std::setfill('0') << (int)strType << std::dec
608 << std::setw(0);
609 attrdata["StringType"] = stringtype.str();
610 attrdata["MinimumStringLength"] = (int)min;
611 attrdata["MaximumStringLength"] = (int)max;
612 attrdata["DefaultStringLength"] = (int)def;
613 attrdata["DefaultString"] = defString.data();
John Wangb754eee2020-02-15 16:10:25 +0800614 break;
615 }
616 case PLDM_BIOS_PASSWORD:
617 case PLDM_BIOS_PASSWORD_READ_ONLY:
618 std::cout << "Password attribute: Not Supported"
619 << std::endl;
620 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500621 output.emplace_back(std::move(attrdata));
John Wangb754eee2020-02-15 16:10:25 +0800622 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500623 pldmtool::helper::DisplayInJson(output);
John Wangb754eee2020-02-15 16:10:25 +0800624 }
625 void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
626 const std::optional<Table>& attrTable,
627 const std::optional<Table>& stringTable)
628 {
John Wangb754eee2020-02-15 16:10:25 +0800629 if (!attrValTable)
630 {
631 std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
632 return;
633 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500634 ordered_json output;
John Wangb754eee2020-02-15 16:10:25 +0800635 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
636 attrValTable->data(), attrValTable->size()))
637 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500638 ordered_json attrValueData;
639 displayAttributeValueEntry(tableEntry, attrTable, stringTable, true,
640 attrValueData);
641 output.emplace_back(attrValueData);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600642 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500643 pldmtool::helper::DisplayInJson(output);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600644 }
645};
646
Adair Li4dd11a72020-04-24 14:52:59 +0800647class GetBIOSAttributeCurrentValueByHandle : public GetBIOSTableHandler
648{
649 public:
650 ~GetBIOSAttributeCurrentValueByHandle() = default;
651 GetBIOSAttributeCurrentValueByHandle(
652 const GetBIOSAttributeCurrentValueByHandle&) = delete;
653 GetBIOSAttributeCurrentValueByHandle(
654 GetBIOSAttributeCurrentValueByHandle&&) = delete;
655 GetBIOSAttributeCurrentValueByHandle&
656 operator=(const GetBIOSAttributeCurrentValueByHandle&) = delete;
657 GetBIOSAttributeCurrentValueByHandle&
658 operator=(GetBIOSAttributeCurrentValueByHandle&&) = delete;
659
660 explicit GetBIOSAttributeCurrentValueByHandle(const char* type,
661 const char* name,
662 CLI::App* app) :
663 GetBIOSTableHandler(type, name, app)
664 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500665 app->add_option("-a, --attribute", attrName, "pldm BIOS attribute name")
Adair Li4dd11a72020-04-24 14:52:59 +0800666 ->required();
667 }
668
669 void exec()
670 {
671 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
672 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
673
674 if (!stringTable || !attrTable)
675 {
676 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
677 return;
678 }
679
680 auto handle = findAttrHandleByName(attrName, *attrTable, *stringTable);
John Wangcee24b62020-06-19 17:23:10 +0800681 if (!handle)
682 {
683
684 std::cerr << "Can not find the attribute " << attrName << std::endl;
685 return;
686 }
Adair Li4dd11a72020-04-24 14:52:59 +0800687
688 std::vector<uint8_t> requestMsg(
689 sizeof(pldm_msg_hdr) +
690 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES);
691 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
692
693 auto rc = encode_get_bios_attribute_current_value_by_handle_req(
694 instanceId, 0, PLDM_GET_FIRSTPART, *handle, request);
695 if (rc != PLDM_SUCCESS)
696 {
697 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
698 return;
699 }
700
701 std::vector<uint8_t> responseMsg;
702 rc = pldmSendRecv(requestMsg, responseMsg);
703 if (rc != PLDM_SUCCESS)
704 {
705 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
706 return;
707 }
708
709 uint8_t cc = 0, transferFlag = 0;
710 uint32_t nextTransferHandle = 0;
711 struct variable_field attributeData;
712 auto responsePtr =
713 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
714 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
715
716 rc = decode_get_bios_attribute_current_value_by_handle_resp(
717 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
718 &attributeData);
719 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
720 {
721 std::cerr << "Response Message Error: "
722 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
723 return;
724 }
725
726 auto tableEntry =
727 reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
728 attributeData.ptr);
729
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500730 ordered_json avdata;
731 displayAttributeValueEntry(tableEntry, attrTable, stringTable, false,
732 avdata);
733 pldmtool::helper::DisplayInJson(avdata);
Adair Li4dd11a72020-04-24 14:52:59 +0800734 }
735
736 private:
737 std::string attrName;
738};
739
Adair Lice041e22020-05-09 17:27:43 +0800740class SetBIOSAttributeCurrentValue : public GetBIOSTableHandler
741{
742 public:
743 ~SetBIOSAttributeCurrentValue() = default;
744 SetBIOSAttributeCurrentValue() = delete;
745 SetBIOSAttributeCurrentValue(const SetBIOSAttributeCurrentValue&) = delete;
746 SetBIOSAttributeCurrentValue(SetBIOSAttributeCurrentValue&&) = default;
747 SetBIOSAttributeCurrentValue&
748 operator=(const SetBIOSAttributeCurrentValue&) = delete;
749 SetBIOSAttributeCurrentValue&
750 operator=(SetBIOSAttributeCurrentValue&&) = default;
751
752 explicit SetBIOSAttributeCurrentValue(const char* type, const char* name,
753 CLI::App* app) :
754 GetBIOSTableHandler(type, name, app)
755 {
756 app->add_option("-a, --attribute", attrName, "pldm attribute name")
757 ->required();
758 app->add_option("-d, --data", attrValue, "pldm attribute value")
759 ->required();
760 // -v is conflict with --verbose in class CommandInterface, so used -d
761 }
762
763 void exec()
764 {
765 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
766 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
767 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
768
769 if (!stringTable || !attrTable)
770 {
771 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
772 return;
773 }
774
775 auto attrEntry =
776 findAttrEntryByName(attrName, *attrTable, *stringTable);
777 if (attrEntry == nullptr)
778 {
779 std::cout << "Could not find attribute :" << attrName << std::endl;
780 return;
781 }
782
783 std::vector<uint8_t> requestMsg;
784
785 int rc = 0;
786 auto attrType = attrEntry->attr_type;
787 size_t entryLength = 1;
788 std::vector<uint8_t> attrValueEntry(entryLength, 0);
789
790 switch (attrType)
791 {
792 case PLDM_BIOS_ENUMERATION_READ_ONLY:
793 case PLDM_BIOS_STRING_READ_ONLY:
794 case PLDM_BIOS_INTEGER_READ_ONLY:
795 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500796 std::cerr << "Set attribute error: " << attrName
Adair Lice041e22020-05-09 17:27:43 +0800797 << "is read only." << std::endl;
798 return;
799 }
800 case PLDM_BIOS_ENUMERATION:
801 {
802 entryLength =
803 pldm_bios_table_attr_value_entry_encode_enum_length(1);
804 auto pvNum =
805 pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
806 std::vector<uint16_t> pvHdls(pvNum, 0);
807 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
808 attrEntry, pvHdls.data(), pvNum);
809 auto stringEntry = pldm_bios_table_string_find_by_string(
810 stringTable->data(), stringTable->size(),
811 attrValue.c_str());
812 if (stringEntry == nullptr)
813 {
814 std::cout
815 << "Set Attribute Error: It's not a possible value"
816 << std::endl;
817 return;
818 }
819 auto valueHandle =
820 pldm_bios_table_string_entry_decode_handle(stringEntry);
821
822 uint8_t i;
823 for (i = 0; i < pvNum; i++)
824 {
825 if (valueHandle == pvHdls[i])
826 break;
827 }
828 if (i == pvNum)
829 {
830 std::cout
831 << "Set Attribute Error: It's not a possible value"
832 << std::endl;
833 return;
834 }
835
836 attrValueEntry.resize(entryLength);
837 std::vector<uint8_t> handles = {i};
838 pldm_bios_table_attr_value_entry_encode_enum(
839 attrValueEntry.data(), attrValueEntry.size(),
840 attrEntry->attr_handle, attrType, 1, handles.data());
841 break;
842 }
843 case PLDM_BIOS_STRING:
844 {
845 entryLength =
846 pldm_bios_table_attr_value_entry_encode_string_length(
847 attrValue.size());
848
849 attrValueEntry.resize(entryLength);
850
851 pldm_bios_table_attr_value_entry_encode_string(
852 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
853 attrType, attrValue.size(), attrValue.c_str());
854 break;
855 }
856 case PLDM_BIOS_INTEGER:
857 {
858 uint64_t value = std::stoll(attrValue);
859 entryLength =
860 pldm_bios_table_attr_value_entry_encode_integer_length();
861 attrValueEntry.resize(entryLength);
862 pldm_bios_table_attr_value_entry_encode_integer(
863 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
864 attrType, value);
865 break;
866 }
867 }
868
869 requestMsg.resize(entryLength + sizeof(pldm_msg_hdr) +
870 PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES);
871
872 rc = encode_set_bios_attribute_current_value_req(
873 instanceId, 0, PLDM_START_AND_END, attrValueEntry.data(),
874 attrValueEntry.size(),
875 reinterpret_cast<pldm_msg*>(requestMsg.data()),
876 requestMsg.size() - sizeof(pldm_msg_hdr));
877
878 if (rc != PLDM_SUCCESS)
879 {
880 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
881 return;
882 }
883 std::vector<uint8_t> responseMsg;
884 rc = pldmSendRecv(requestMsg, responseMsg);
885 if (rc != PLDM_SUCCESS)
886 {
887 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
888 return;
889 }
890 uint8_t cc = 0;
891 uint32_t nextTransferHandle = 0;
892 auto responsePtr =
893 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
894 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
895
896 rc = decode_set_bios_attribute_current_value_resp(
897 responsePtr, payloadLength, &cc, &nextTransferHandle);
898 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
899 {
900 std::cerr << "Response Message Error: "
901 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
902 return;
903 }
904
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500905 ordered_json data;
906 data["Response"] = "SUCCESS";
907 pldmtool::helper::DisplayInJson(data);
Adair Lice041e22020-05-09 17:27:43 +0800908 }
909
910 private:
911 std::string attrName;
912 std::string attrValue;
913};
914
Sridevi Ramesh98576432019-11-27 10:10:28 -0600915void registerCommand(CLI::App& app)
916{
917 auto bios = app.add_subcommand("bios", "bios type command");
918 bios->require_subcommand(1);
919 auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
920 commands.push_back(
921 std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
George Liud6649362019-11-27 19:06:51 +0800922
923 auto setDateTime =
924 bios->add_subcommand("SetDateTime", "set host date time");
925 commands.push_back(
926 std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600927
928 auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
929 commands.push_back(
930 std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));
Adair Li4dd11a72020-04-24 14:52:59 +0800931
932 auto getBIOSAttributeCurrentValueByHandle =
933 bios->add_subcommand("GetBIOSAttributeCurrentValueByHandle",
934 "get bios attribute current value by handle");
935 commands.push_back(std::make_unique<GetBIOSAttributeCurrentValueByHandle>(
936 "bios", "GetBIOSAttributeCurrentValueByHandle",
937 getBIOSAttributeCurrentValueByHandle));
Adair Lice041e22020-05-09 17:27:43 +0800938
939 auto setBIOSAttributeCurrentValue = bios->add_subcommand(
940 "SetBIOSAttributeCurrentValue", "set bios attribute current value");
941 commands.push_back(std::make_unique<SetBIOSAttributeCurrentValue>(
942 "bios", "SetBIOSAttributeCurrentValue", setBIOSAttributeCurrentValue));
Sridevi Ramesh98576432019-11-27 10:10:28 -0600943}
944
945} // namespace bios
946
947} // namespace pldmtool