blob: c0801a0d438a295087cd3b166ea493036172c43c [file] [log] [blame]
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05001#include "pldm_base_cmd.hpp"
2
3#include "pldm_cmd_helper.hpp"
4
John Wang58a0e062019-11-08 15:38:15 +08005#include "libpldm/utils.h"
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05006
Sridevi Ramesh45e52542020-04-03 07:54:18 -05007#ifdef OEM_IBM
8#include "libpldm/file_io.h"
9#include "libpldm/host.h"
10#endif
11
John Wang58a0e062019-11-08 15:38:15 +080012namespace pldmtool
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050013{
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050014
John Wang58a0e062019-11-08 15:38:15 +080015namespace base
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050016{
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050017
John Wang58a0e062019-11-08 15:38:15 +080018namespace
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050019{
John Wang58a0e062019-11-08 15:38:15 +080020
21using namespace pldmtool::helper;
22
23std::vector<std::unique_ptr<CommandInterface>> commands;
24const std::map<const char*, pldm_supported_types> pldmTypes{
Sridevi Ramesh45e52542020-04-03 07:54:18 -050025 {"base", PLDM_BASE}, {"platform", PLDM_PLATFORM},
26 {"bios", PLDM_BIOS}, {"fru", PLDM_FRU},
27#ifdef OEM_IBM
28 {"oem-ibm", PLDM_OEM},
29#endif
John Wang58a0e062019-11-08 15:38:15 +080030};
31
Sridevi Ramesh66294d32020-02-21 03:52:07 -060032const std::map<const char*, pldm_supported_commands> pldmBaseCmds{
33 {"GetTID", PLDM_GET_TID},
34 {"GetPLDMVersion", PLDM_GET_PLDM_VERSION},
35 {"GetPLDMTypes", PLDM_GET_PLDM_TYPES},
36 {"GetPLDMCommands", PLDM_GET_PLDM_COMMANDS}};
37
38const std::map<const char*, pldm_bios_commands> pldmBiosCmds{
39 {"GetBIOSTable", PLDM_GET_BIOS_TABLE},
40 {"SetBIOSAttributeCurrentValue", PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE},
41 {"GetBIOSAttributeCurrentValueByHandle",
42 PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE},
43 {"GetDateTime", PLDM_GET_DATE_TIME},
44 {"SetDateTime", PLDM_SET_DATE_TIME}};
45
46const std::map<const char*, pldm_platform_commands> pldmPlatformCmds{
47 {"SetNumericEffecterValue", PLDM_SET_NUMERIC_EFFECTER_VALUE},
48 {"SetStateEffecterStates", PLDM_SET_STATE_EFFECTER_STATES},
49 {"GetPDR", PLDM_GET_PDR}};
50
51const std::map<const char*, pldm_fru_commands> pldmFruCmds{
52 {"GetFRURecordTableMetadata", PLDM_GET_FRU_RECORD_TABLE_METADATA},
53 {"GetFRURecordTable", PLDM_GET_FRU_RECORD_TABLE}};
54
Sridevi Ramesh45e52542020-04-03 07:54:18 -050055#ifdef OEM_IBM
56const std::map<const char*, pldm_host_commands> pldmIBMHostCmds{
57 {"GetAlertStatus", PLDM_HOST_GET_ALERT_STATUS}};
58
59const std::map<const char*, pldm_fileio_commands> pldmIBMFileIOCmds{
60 {"GetFileTable", PLDM_GET_FILE_TABLE},
61 {"ReadFile", PLDM_READ_FILE},
62 {"WriteFile", PLDM_WRITE_FILE},
63 {"ReadFileInToMemory", PLDM_READ_FILE_INTO_MEMORY},
64 {"WriteFileFromMemory", PLDM_WRITE_FILE_FROM_MEMORY},
65 {"ReadFileByTypeIntoMemory", PLDM_READ_FILE_BY_TYPE_INTO_MEMORY},
66 {"WriteFileByTypeFromMemory", PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY},
67 {"NewFileAvailable", PLDM_NEW_FILE_AVAILABLE},
68 {"ReadFileByType", PLDM_READ_FILE_BY_TYPE},
69 {"WriteFileByType", PLDM_WRITE_FILE_BY_TYPE},
70 {"FileAck", PLDM_FILE_ACK}};
71#endif
72
John Wang58a0e062019-11-08 15:38:15 +080073} // namespace
74
75class GetPLDMTypes : public CommandInterface
76{
77 public:
78 ~GetPLDMTypes() = default;
79 GetPLDMTypes() = delete;
80 GetPLDMTypes(const GetPLDMTypes&) = delete;
81 GetPLDMTypes(GetPLDMTypes&&) = default;
82 GetPLDMTypes& operator=(const GetPLDMTypes&) = delete;
83 GetPLDMTypes& operator=(GetPLDMTypes&&) = default;
84
85 using CommandInterface::CommandInterface;
86
87 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050088 {
John Wang58a0e062019-11-08 15:38:15 +080089 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
90 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060091 auto rc = encode_get_types_req(instanceId, request);
John Wang58a0e062019-11-08 15:38:15 +080092 return {rc, requestMsg};
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050093 }
94
John Wang58a0e062019-11-08 15:38:15 +080095 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050096 {
John Wang58a0e062019-11-08 15:38:15 +080097 uint8_t cc = 0;
98 std::vector<bitfield8_t> types(8);
99 auto rc = decode_get_types_resp(responsePtr, payloadLength, &cc,
100 types.data());
101 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
102 {
103 std::cerr << "Response Message Error: "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600104 << "rc=" << rc << ",cc=" << (int)cc << "\n";
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500105 return;
John Wang58a0e062019-11-08 15:38:15 +0800106 }
107
108 printPldmTypes(types);
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500109 }
110
John Wang58a0e062019-11-08 15:38:15 +0800111 private:
112 void printPldmTypes(std::vector<bitfield8_t>& types)
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500113 {
John Wang58a0e062019-11-08 15:38:15 +0800114 std::cout << "Supported types:";
115 for (int i = 0; i < PLDM_MAX_TYPES; i++)
116 {
117 bitfield8_t b = types[i / 8];
118 if (b.byte & (1 << i % 8))
119 {
120 std::cout << " " << i;
121 auto it = std::find_if(
122 pldmTypes.begin(), pldmTypes.end(),
123 [i](const auto& typePair) { return typePair.second == i; });
124 if (it != pldmTypes.end())
125 {
126
127 std::cout << "(" << it->first << ")";
128 }
129 }
130 }
131
132 std::cout << std::endl;
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500133 }
John Wang58a0e062019-11-08 15:38:15 +0800134};
135
136class GetPLDMVersion : public CommandInterface
137{
138 public:
139 ~GetPLDMVersion() = default;
140 GetPLDMVersion() = delete;
141 GetPLDMVersion(const GetPLDMVersion&) = delete;
142 GetPLDMVersion(GetPLDMVersion&&) = default;
143 GetPLDMVersion& operator=(const GetPLDMVersion&) = delete;
144 GetPLDMVersion& operator=(GetPLDMVersion&&) = default;
145
146 explicit GetPLDMVersion(const char* type, const char* name, CLI::App* app) :
147 CommandInterface(type, name, app)
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500148 {
John Wang58a0e062019-11-08 15:38:15 +0800149 app->add_option("-t,--type", pldmType, "pldm supported type")
150 ->required()
151 ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500152 }
John Wang58a0e062019-11-08 15:38:15 +0800153 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
154 {
155 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
156 PLDM_GET_VERSION_REQ_BYTES);
157 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
158
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600159 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
160 pldmType, request);
John Wang58a0e062019-11-08 15:38:15 +0800161 return {rc, requestMsg};
162 }
163
164 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
165 {
166 uint8_t cc = 0, transferFlag = 0;
167 uint32_t transferHandle = 0;
168 ver32_t version;
169 auto rc =
170 decode_get_version_resp(responsePtr, payloadLength, &cc,
171 &transferHandle, &transferFlag, &version);
172 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
173 {
174 std::cerr << "Response Message Error: "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600175 << "rc=" << rc << ",cc=" << (int)cc << "\n";
John Wang58a0e062019-11-08 15:38:15 +0800176 return;
177 }
178 char buffer[16] = {0};
179 ver2str(&version, buffer, sizeof(buffer));
180 std::cout << "Type " << pldmType;
181 auto it = std::find_if(
182 pldmTypes.begin(), pldmTypes.end(),
183 [&](const auto& typePair) { return typePair.second == pldmType; });
184
185 if (it != pldmTypes.end())
186 {
187 std::cout << "(" << it->first << ")";
188 }
189 std::cout << ": " << buffer << std::endl;
190 }
191
192 private:
193 pldm_supported_types pldmType;
194};
195
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600196class GetTID : public CommandInterface
197{
198 public:
199 ~GetTID() = default;
200 GetTID() = delete;
201 GetTID(const GetTID&) = delete;
202 GetTID(GetTID&&) = default;
203 GetTID& operator=(const GetTID&) = delete;
204 GetTID& operator=(GetTID&&) = default;
205
206 using CommandInterface::CommandInterface;
207
208 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
209 {
210 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
211 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600212 auto rc = encode_get_tid_req(instanceId, request);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600213 return {rc, requestMsg};
214 }
215
216 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
217 {
218 uint8_t cc = 0;
219 uint8_t tid = 0;
220 std::vector<bitfield8_t> types(8);
221 auto rc = decode_get_tid_resp(responsePtr, payloadLength, &cc, &tid);
222 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
223 {
224 std::cerr << "Response Message Error: "
225 << "rc=" << rc << ",cc=" << (int)cc << "\n";
226 return;
227 }
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600228 std::cout << "TID : " << static_cast<uint32_t>(tid) << std::endl;
229 }
230};
231
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600232class GetPLDMCommands : public CommandInterface
233{
234 public:
235 ~GetPLDMCommands() = default;
236 GetPLDMCommands() = delete;
237 GetPLDMCommands(const GetPLDMCommands&) = delete;
238 GetPLDMCommands(GetPLDMCommands&&) = default;
239 GetPLDMCommands& operator=(const GetPLDMCommands&) = delete;
240 GetPLDMCommands& operator=(GetPLDMCommands&&) = default;
241
242 explicit GetPLDMCommands(const char* type, const char* name,
243 CLI::App* app) :
244 CommandInterface(type, name, app)
245 {
246 app->add_option("-t,--type", pldmType, "pldm supported type")
247 ->required()
248 ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
249 }
250
251 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
252 {
253 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
254 PLDM_GET_COMMANDS_REQ_BYTES);
255 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
256 ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600257 auto rc =
258 encode_get_commands_req(instanceId, pldmType, version, request);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600259 return {rc, requestMsg};
260 }
261
262 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
263 {
264 uint8_t cc = 0;
265 std::vector<bitfield8_t> cmdTypes(32);
266 auto rc = decode_get_commands_resp(responsePtr, payloadLength, &cc,
267 cmdTypes.data());
268 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
269 {
270 std::cerr << "Response Message Error: "
271 << "rc=" << rc << ",cc=" << (int)cc << "\n";
272 return;
273 }
274 printPldmCommands(cmdTypes, pldmType);
275 }
276
277 private:
278 pldm_supported_types pldmType;
279
280 template <typename CommandMap>
281 void printCommand(CommandMap& commandMap, int i)
282 {
283 auto it = std::find_if(
284 commandMap.begin(), commandMap.end(),
285 [i](const auto& typePair) { return typePair.second == i; });
286 if (it != commandMap.end())
287 {
288 std::cout << "(" << it->first << ")";
289 }
290 }
291
292 void printPldmCommands(std::vector<bitfield8_t>& cmdTypes,
293 pldm_supported_types pldmType)
294 {
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600295 std::cout << "Supported Commands :";
296 for (int i = 0; i < PLDM_MAX_CMDS_PER_TYPE; i++)
297 {
298 bitfield8_t b = cmdTypes[i / 8];
299 if (b.byte & (1 << i % 8))
300 {
301 std::cout << " " << i;
302 switch (pldmType)
303 {
304 case PLDM_BASE:
305 printCommand(pldmBaseCmds, i);
306 break;
307 case PLDM_PLATFORM:
308 printCommand(pldmPlatformCmds, i);
309 break;
310 case PLDM_BIOS:
311 printCommand(pldmBiosCmds, i);
312 break;
313 case PLDM_FRU:
314 printCommand(pldmFruCmds, i);
315 break;
Sridevi Ramesh45e52542020-04-03 07:54:18 -0500316 case PLDM_OEM:
317 printCommand(pldmIBMHostCmds, i);
318 printCommand(pldmIBMFileIOCmds, i);
319 break;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600320 default:
321 break;
322 }
323 }
324 }
325 std::cout << std::endl;
326 }
327};
328
John Wang58a0e062019-11-08 15:38:15 +0800329void registerCommand(CLI::App& app)
330{
331 auto base = app.add_subcommand("base", "base type command");
332 base->require_subcommand(1);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600333
John Wang58a0e062019-11-08 15:38:15 +0800334 auto getPLDMTypes =
335 base->add_subcommand("GetPLDMTypes", "get pldm supported types");
336 commands.push_back(
337 std::make_unique<GetPLDMTypes>("base", "GetPLDMTypes", getPLDMTypes));
338
339 auto getPLDMVersion =
340 base->add_subcommand("GetPLDMVersion", "get version of a certain type");
341 commands.push_back(std::make_unique<GetPLDMVersion>(
342 "base", "GetPLDMVersion", getPLDMVersion));
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600343
344 auto getPLDMTID = base->add_subcommand("GetTID", "get Terminus ID (TID)");
345 commands.push_back(std::make_unique<GetTID>("base", "GetTID", getPLDMTID));
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600346
347 auto getPLDMCommands = base->add_subcommand(
348 "GetPLDMCommands", "get supported commands of pldm type");
349 commands.push_back(std::make_unique<GetPLDMCommands>(
350 "base", "GetPLDMCommands", getPLDMCommands));
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500351}
John Wang58a0e062019-11-08 15:38:15 +0800352
353} // namespace base
354} // namespace pldmtool