blob: 1fb9853bfb2f79e3e8025ebc6bf9776424808a70 [file] [log] [blame]
Sridevi Ramesh98576432019-11-27 10:10:28 -06001#include "pldm_bios_cmd.hpp"
2
3#include "pldm_cmd_helper.hpp"
4
Sridevi Rameshcdfe1142020-01-31 05:42:50 -06005#include "libpldm/bios_table.h"
Sridevi Ramesh98576432019-11-27 10:10:28 -06006#include "libpldm/utils.h"
7
8namespace pldmtool
9{
10
11namespace bios
12{
13
14namespace
15{
16
17using namespace pldmtool::helper;
18
19std::vector<std::unique_ptr<CommandInterface>> commands;
20
Sridevi Rameshcdfe1142020-01-31 05:42:50 -060021const std::map<const char*, pldm_bios_table_types> pldmBIOSTableTypes{
22 {"StringTable", PLDM_BIOS_STRING_TABLE},
23 {"AttributeTable", PLDM_BIOS_ATTR_TABLE},
24 {"AttributeValueTable", PLDM_BIOS_ATTR_VAL_TABLE},
25};
26
Sridevi Ramesh98576432019-11-27 10:10:28 -060027} // namespace
28
29class GetDateTime : public CommandInterface
30{
31 public:
32 ~GetDateTime() = default;
33 GetDateTime() = delete;
34 GetDateTime(const GetDateTime&) = delete;
35 GetDateTime(GetDateTime&&) = default;
36 GetDateTime& operator=(const GetDateTime&) = delete;
37 GetDateTime& operator=(GetDateTime&&) = default;
38
39 using CommandInterface::CommandInterface;
40
41 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
42 {
43 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
44 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
45
46 auto rc = encode_get_date_time_req(PLDM_LOCAL_INSTANCE_ID, request);
47 return {rc, requestMsg};
48 }
49
50 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
51 {
52 uint8_t cc = 0;
53
54 uint8_t seconds, minutes, hours, day, month;
55 uint16_t year;
56 auto rc =
57 decode_get_date_time_resp(responsePtr, payloadLength, &cc, &seconds,
58 &minutes, &hours, &day, &month, &year);
59 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
60 {
61 std::cerr << "Response Message Error: "
62 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
63 return;
64 }
65 std::cout << "Date & Time : " << std::endl;
Sridevi Ramesh213a8552020-02-03 00:59:30 -060066 std::cout << "YYYY-MM-DD HH:MM:SS - ";
67 std::cout << bcd2dec16(year);
Sridevi Ramesh98576432019-11-27 10:10:28 -060068 std::cout << "-";
69 setWidth(month);
Sridevi Ramesh213a8552020-02-03 00:59:30 -060070 std::cout << "-";
71 setWidth(day);
72 std::cout << " ";
Sridevi Ramesh98576432019-11-27 10:10:28 -060073 setWidth(hours);
74 std::cout << ":";
75 setWidth(minutes);
76 std::cout << ":";
77 setWidth(seconds);
78 std::cout << std::endl;
79 }
80
81 private:
82 void setWidth(uint8_t data)
83 {
84 std::cout << std::setfill('0') << std::setw(2)
85 << static_cast<uint32_t>(bcd2dec8(data));
86 }
87};
88
George Liud6649362019-11-27 19:06:51 +080089class SetDateTime : public CommandInterface
90{
91 public:
92 ~SetDateTime() = default;
93 SetDateTime() = delete;
94 SetDateTime(const SetDateTime&) = delete;
95 SetDateTime(SetDateTime&&) = default;
96 SetDateTime& operator=(const SetDateTime&) = delete;
97 SetDateTime& operator=(SetDateTime&&) = default;
98
99 explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
100 CommandInterface(type, name, app)
101 {
102 app->add_option("-d,--data", tmData,
103 "set date time data\n"
104 "eg: YYYYMMDDHHMMSS")
105 ->required();
106 }
107
108 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
109 {
110 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
111 sizeof(struct pldm_set_date_time_req));
112 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
113 uint16_t year = 0;
114 uint8_t month = 0;
115 uint8_t day = 0;
116 uint8_t hours = 0;
117 uint8_t minutes = 0;
118 uint8_t seconds = 0;
119
120 if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
121 &seconds))
122 {
123 std::cerr << "decode date Error: "
124 << "tmData=" << tmData << std::endl;
125
126 return {PLDM_ERROR_INVALID_DATA, requestMsg};
127 }
128
129 auto rc = encode_set_date_time_req(
130 PLDM_LOCAL_INSTANCE_ID, seconds, minutes, hours, day, month, year,
131 request, sizeof(struct pldm_set_date_time_req));
132
133 return {rc, requestMsg};
134 }
135
136 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
137 {
138 uint8_t completionCode = 0;
139 auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
140 &completionCode);
141
142 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
143 {
144 std::cerr << "Response Message Error: "
145 << "rc=" << rc << ",cc=" << (int)completionCode
146 << std::endl;
147 return;
148 }
149
150 std::cout << "SetDateTime: SUCCESS" << std::endl;
151 }
152
153 private:
154 uint64_t tmData;
155};
156
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600157class GetBIOSTable : public CommandInterface
158{
159 public:
160 ~GetBIOSTable() = default;
161 GetBIOSTable() = delete;
162 GetBIOSTable(const GetBIOSTable&) = delete;
163 GetBIOSTable(GetBIOSTable&&) = default;
164 GetBIOSTable& operator=(const GetBIOSTable&) = delete;
165 GetBIOSTable& operator=(GetBIOSTable&&) = default;
166
167 using CommandInterface::CommandInterface;
168
169 explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
170 CommandInterface(type, name, app)
171 {
172 app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
173 ->required()
174 ->transform(
175 CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
176 }
177
178 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
179 {
180 uint32_t nextTransferHandle = 32;
181
182 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
183 PLDM_GET_BIOS_TABLE_REQ_BYTES);
184 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
185
186 auto rc = encode_get_bios_table_req(
187 PLDM_LOCAL_INSTANCE_ID, nextTransferHandle, PLDM_GET_FIRSTPART,
188 pldmBIOSTableType, request);
189 return {rc, requestMsg};
190 }
191
192 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
193 {
194 uint8_t cc = 0, transferFlag = 0;
195 uint32_t nextTransferHandle = 0;
196 size_t bios_table_offset;
197
198 auto rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc,
199 &nextTransferHandle, &transferFlag,
200 &bios_table_offset);
201
202 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
203 {
204 std::cerr << "Response Message Error: "
205 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
206 return;
207 }
208 auto tableData =
209 reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset);
210 auto tableSize =
211 payloadLength - sizeof(nextTransferHandle) - sizeof(transferFlag);
212 printBIOSTable(tableData, tableSize, pldmBIOSTableType);
213 }
214
215 private:
216 pldm_bios_table_types pldmBIOSTableType;
217
218 void decodeStringTable(const void* tableData, size_t tableSize)
219 {
220 std::cout << "Parsed Response Msg: " << std::endl;
221 std::cout << "BIOSStringHandle : BIOSString" << std::endl;
222 std::string strTableData;
223 std::unique_ptr<pldm_bios_table_iter,
224 decltype(&pldm_bios_table_iter_free)>
225 iter(pldm_bios_table_iter_create(tableData, tableSize,
226 PLDM_BIOS_STRING_TABLE),
227 pldm_bios_table_iter_free);
228 while (!pldm_bios_table_iter_is_end(iter.get()))
229 {
230 try
231 {
232 auto tableEntry =
233 pldm_bios_table_iter_string_entry_value(iter.get());
234 auto strLength =
235 pldm_bios_table_string_entry_decode_string_length(
236 tableEntry);
237 strTableData.resize(strLength + 1);
238 auto strHandle =
239 pldm_bios_table_string_entry_decode_handle(tableEntry);
240 pldm_bios_table_string_entry_decode_string(
241 tableEntry, strTableData.data(), strTableData.size());
242 std::cout << strHandle << " : " << strTableData << std::endl;
243 }
244 catch (const std::exception& e)
245 {
246 std::cerr
247 << "handler fails when traversing BIOSStringTable, ERROR="
248 << e.what() << "\n";
249 }
250 pldm_bios_table_iter_next(iter.get());
251 }
252 }
253 void printBIOSTable(const void* tableData, size_t tableSize,
254 enum pldm_bios_table_types type)
255 {
256 if (!tableSize)
257 {
258 std::cerr << "Found table size null." << std::endl;
259 return;
260 }
261 switch (type)
262 {
263 case PLDM_BIOS_STRING_TABLE:
264 decodeStringTable(tableData, tableSize);
265 break;
266 default:
267 break;
268 }
269 }
270};
271
Sridevi Ramesh98576432019-11-27 10:10:28 -0600272void registerCommand(CLI::App& app)
273{
274 auto bios = app.add_subcommand("bios", "bios type command");
275 bios->require_subcommand(1);
276 auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
277 commands.push_back(
278 std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
George Liud6649362019-11-27 19:06:51 +0800279
280 auto setDateTime =
281 bios->add_subcommand("SetDateTime", "set host date time");
282 commands.push_back(
283 std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600284
285 auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
286 commands.push_back(
287 std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));
Sridevi Ramesh98576432019-11-27 10:10:28 -0600288}
289
290} // namespace bios
291
292} // namespace pldmtool