blob: 475932f98c420d0309ecbbce5222c2778acbf87f [file] [log] [blame]
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05001#include "pldm_base_cmd.hpp"
2
John Wang58a0e062019-11-08 15:38:15 +08003#include "libpldm/utils.h"
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05004
George Liu6492f522020-06-16 10:34:05 +08005#include "pldm_cmd_helper.hpp"
6
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
Sridevi Rameshca4a8152020-08-11 09:26:19 -050012#include <string>
13
John Wang58a0e062019-11-08 15:38:15 +080014namespace pldmtool
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050015{
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050016
John Wang58a0e062019-11-08 15:38:15 +080017namespace base
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050018{
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050019
John Wang58a0e062019-11-08 15:38:15 +080020namespace
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050021{
John Wang58a0e062019-11-08 15:38:15 +080022
23using namespace pldmtool::helper;
24
25std::vector<std::unique_ptr<CommandInterface>> commands;
26const std::map<const char*, pldm_supported_types> pldmTypes{
Sridevi Ramesh45e52542020-04-03 07:54:18 -050027 {"base", PLDM_BASE}, {"platform", PLDM_PLATFORM},
28 {"bios", PLDM_BIOS}, {"fru", PLDM_FRU},
29#ifdef OEM_IBM
30 {"oem-ibm", PLDM_OEM},
31#endif
John Wang58a0e062019-11-08 15:38:15 +080032};
33
Sridevi Ramesh66294d32020-02-21 03:52:07 -060034const std::map<const char*, pldm_supported_commands> pldmBaseCmds{
35 {"GetTID", PLDM_GET_TID},
36 {"GetPLDMVersion", PLDM_GET_PLDM_VERSION},
37 {"GetPLDMTypes", PLDM_GET_PLDM_TYPES},
38 {"GetPLDMCommands", PLDM_GET_PLDM_COMMANDS}};
39
40const std::map<const char*, pldm_bios_commands> pldmBiosCmds{
41 {"GetBIOSTable", PLDM_GET_BIOS_TABLE},
42 {"SetBIOSAttributeCurrentValue", PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE},
43 {"GetBIOSAttributeCurrentValueByHandle",
44 PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE},
45 {"GetDateTime", PLDM_GET_DATE_TIME},
46 {"SetDateTime", PLDM_SET_DATE_TIME}};
47
48const std::map<const char*, pldm_platform_commands> pldmPlatformCmds{
49 {"SetNumericEffecterValue", PLDM_SET_NUMERIC_EFFECTER_VALUE},
50 {"SetStateEffecterStates", PLDM_SET_STATE_EFFECTER_STATES},
51 {"GetPDR", PLDM_GET_PDR}};
52
53const std::map<const char*, pldm_fru_commands> pldmFruCmds{
54 {"GetFRURecordTableMetadata", PLDM_GET_FRU_RECORD_TABLE_METADATA},
John Wang5bdde3a2020-06-16 15:02:33 +080055 {"GetFRURecordTable", PLDM_GET_FRU_RECORD_TABLE},
56 {"GetFRURecordByOption", PLDM_GET_FRU_RECORD_BY_OPTION}};
Sridevi Ramesh66294d32020-02-21 03:52:07 -060057
Sridevi Ramesh45e52542020-04-03 07:54:18 -050058#ifdef OEM_IBM
59const std::map<const char*, pldm_host_commands> pldmIBMHostCmds{
60 {"GetAlertStatus", PLDM_HOST_GET_ALERT_STATUS}};
61
62const std::map<const char*, pldm_fileio_commands> pldmIBMFileIOCmds{
63 {"GetFileTable", PLDM_GET_FILE_TABLE},
64 {"ReadFile", PLDM_READ_FILE},
65 {"WriteFile", PLDM_WRITE_FILE},
66 {"ReadFileInToMemory", PLDM_READ_FILE_INTO_MEMORY},
67 {"WriteFileFromMemory", PLDM_WRITE_FILE_FROM_MEMORY},
68 {"ReadFileByTypeIntoMemory", PLDM_READ_FILE_BY_TYPE_INTO_MEMORY},
69 {"WriteFileByTypeFromMemory", PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY},
70 {"NewFileAvailable", PLDM_NEW_FILE_AVAILABLE},
71 {"ReadFileByType", PLDM_READ_FILE_BY_TYPE},
72 {"WriteFileByType", PLDM_WRITE_FILE_BY_TYPE},
73 {"FileAck", PLDM_FILE_ACK}};
74#endif
75
John Wang58a0e062019-11-08 15:38:15 +080076} // namespace
77
78class GetPLDMTypes : public CommandInterface
79{
80 public:
81 ~GetPLDMTypes() = default;
82 GetPLDMTypes() = delete;
83 GetPLDMTypes(const GetPLDMTypes&) = delete;
84 GetPLDMTypes(GetPLDMTypes&&) = default;
85 GetPLDMTypes& operator=(const GetPLDMTypes&) = delete;
86 GetPLDMTypes& operator=(GetPLDMTypes&&) = default;
87
88 using CommandInterface::CommandInterface;
89
90 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050091 {
John Wang58a0e062019-11-08 15:38:15 +080092 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
93 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060094 auto rc = encode_get_types_req(instanceId, request);
John Wang58a0e062019-11-08 15:38:15 +080095 return {rc, requestMsg};
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050096 }
97
John Wang58a0e062019-11-08 15:38:15 +080098 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050099 {
John Wang58a0e062019-11-08 15:38:15 +0800100 uint8_t cc = 0;
101 std::vector<bitfield8_t> types(8);
102 auto rc = decode_get_types_resp(responsePtr, payloadLength, &cc,
103 types.data());
104 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
105 {
106 std::cerr << "Response Message Error: "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600107 << "rc=" << rc << ",cc=" << (int)cc << "\n";
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500108 return;
John Wang58a0e062019-11-08 15:38:15 +0800109 }
110
111 printPldmTypes(types);
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500112 }
113
John Wang58a0e062019-11-08 15:38:15 +0800114 private:
115 void printPldmTypes(std::vector<bitfield8_t>& types)
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500116 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500117 ordered_json data;
118 ordered_json jarray;
John Wang58a0e062019-11-08 15:38:15 +0800119 for (int i = 0; i < PLDM_MAX_TYPES; i++)
120 {
121 bitfield8_t b = types[i / 8];
122 if (b.byte & (1 << i % 8))
123 {
John Wang58a0e062019-11-08 15:38:15 +0800124 auto it = std::find_if(
125 pldmTypes.begin(), pldmTypes.end(),
126 [i](const auto& typePair) { return typePair.second == i; });
127 if (it != pldmTypes.end())
128 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500129 jarray["PLDM Type"] = it->first;
130 jarray["PLDM Type Code"] = i;
131 data.emplace_back(jarray);
John Wang58a0e062019-11-08 15:38:15 +0800132 }
133 }
134 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500135 pldmtool::helper::DisplayInJson(data);
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500136 }
John Wang58a0e062019-11-08 15:38:15 +0800137};
138
139class GetPLDMVersion : public CommandInterface
140{
141 public:
142 ~GetPLDMVersion() = default;
143 GetPLDMVersion() = delete;
144 GetPLDMVersion(const GetPLDMVersion&) = delete;
145 GetPLDMVersion(GetPLDMVersion&&) = default;
146 GetPLDMVersion& operator=(const GetPLDMVersion&) = delete;
147 GetPLDMVersion& operator=(GetPLDMVersion&&) = default;
148
149 explicit GetPLDMVersion(const char* type, const char* name, CLI::App* app) :
150 CommandInterface(type, name, app)
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500151 {
John Wang58a0e062019-11-08 15:38:15 +0800152 app->add_option("-t,--type", pldmType, "pldm supported type")
153 ->required()
154 ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500155 }
John Wang58a0e062019-11-08 15:38:15 +0800156 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
157 {
158 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
159 PLDM_GET_VERSION_REQ_BYTES);
160 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
161
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600162 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
163 pldmType, request);
John Wang58a0e062019-11-08 15:38:15 +0800164 return {rc, requestMsg};
165 }
166
167 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
168 {
169 uint8_t cc = 0, transferFlag = 0;
170 uint32_t transferHandle = 0;
171 ver32_t version;
172 auto rc =
173 decode_get_version_resp(responsePtr, payloadLength, &cc,
174 &transferHandle, &transferFlag, &version);
175 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
176 {
177 std::cerr << "Response Message Error: "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600178 << "rc=" << rc << ",cc=" << (int)cc << "\n";
John Wang58a0e062019-11-08 15:38:15 +0800179 return;
180 }
181 char buffer[16] = {0};
182 ver2str(&version, buffer, sizeof(buffer));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500183 ordered_json data;
John Wang58a0e062019-11-08 15:38:15 +0800184 auto it = std::find_if(
185 pldmTypes.begin(), pldmTypes.end(),
186 [&](const auto& typePair) { return typePair.second == pldmType; });
187
188 if (it != pldmTypes.end())
189 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500190 data["Response"] = buffer;
John Wang58a0e062019-11-08 15:38:15 +0800191 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500192 pldmtool::helper::DisplayInJson(data);
John Wang58a0e062019-11-08 15:38:15 +0800193 }
194
195 private:
196 pldm_supported_types pldmType;
197};
198
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600199class GetTID : public CommandInterface
200{
201 public:
202 ~GetTID() = default;
203 GetTID() = delete;
204 GetTID(const GetTID&) = delete;
205 GetTID(GetTID&&) = default;
206 GetTID& operator=(const GetTID&) = delete;
207 GetTID& operator=(GetTID&&) = default;
208
209 using CommandInterface::CommandInterface;
210
211 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
212 {
213 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
214 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600215 auto rc = encode_get_tid_req(instanceId, request);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600216 return {rc, requestMsg};
217 }
218
219 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
220 {
221 uint8_t cc = 0;
222 uint8_t tid = 0;
223 std::vector<bitfield8_t> types(8);
224 auto rc = decode_get_tid_resp(responsePtr, payloadLength, &cc, &tid);
225 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
226 {
227 std::cerr << "Response Message Error: "
228 << "rc=" << rc << ",cc=" << (int)cc << "\n";
229 return;
230 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500231 ordered_json data;
232 data["Response"] = static_cast<uint32_t>(tid);
233 pldmtool::helper::DisplayInJson(data);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600234 }
235};
236
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600237class GetPLDMCommands : public CommandInterface
238{
239 public:
240 ~GetPLDMCommands() = default;
241 GetPLDMCommands() = delete;
242 GetPLDMCommands(const GetPLDMCommands&) = delete;
243 GetPLDMCommands(GetPLDMCommands&&) = default;
244 GetPLDMCommands& operator=(const GetPLDMCommands&) = delete;
245 GetPLDMCommands& operator=(GetPLDMCommands&&) = default;
246
247 explicit GetPLDMCommands(const char* type, const char* name,
248 CLI::App* app) :
249 CommandInterface(type, name, app)
250 {
251 app->add_option("-t,--type", pldmType, "pldm supported type")
252 ->required()
253 ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
254 }
255
256 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
257 {
258 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
259 PLDM_GET_COMMANDS_REQ_BYTES);
260 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
261 ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600262 auto rc =
263 encode_get_commands_req(instanceId, pldmType, version, request);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600264 return {rc, requestMsg};
265 }
266
267 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
268 {
269 uint8_t cc = 0;
270 std::vector<bitfield8_t> cmdTypes(32);
271 auto rc = decode_get_commands_resp(responsePtr, payloadLength, &cc,
272 cmdTypes.data());
273 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
274 {
275 std::cerr << "Response Message Error: "
276 << "rc=" << rc << ",cc=" << (int)cc << "\n";
277 return;
278 }
279 printPldmCommands(cmdTypes, pldmType);
280 }
281
282 private:
283 pldm_supported_types pldmType;
284
285 template <typename CommandMap>
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500286 void printCommand(CommandMap& commandMap, int i, ordered_json& jarray)
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600287 {
288 auto it = std::find_if(
289 commandMap.begin(), commandMap.end(),
290 [i](const auto& typePair) { return typePair.second == i; });
291 if (it != commandMap.end())
292 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500293 jarray["PLDM Command Code"] = i;
294 jarray["PLDM Command"] = it->first;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600295 }
296 }
297
298 void printPldmCommands(std::vector<bitfield8_t>& cmdTypes,
299 pldm_supported_types pldmType)
300 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500301 ordered_json output;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600302 for (int i = 0; i < PLDM_MAX_CMDS_PER_TYPE; i++)
303 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500304
305 ordered_json cmdinfo;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600306 bitfield8_t b = cmdTypes[i / 8];
307 if (b.byte & (1 << i % 8))
308 {
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600309 switch (pldmType)
310 {
311 case PLDM_BASE:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500312 printCommand(pldmBaseCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600313 break;
314 case PLDM_PLATFORM:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500315 printCommand(pldmPlatformCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600316 break;
317 case PLDM_BIOS:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500318 printCommand(pldmBiosCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600319 break;
320 case PLDM_FRU:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500321 printCommand(pldmFruCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600322 break;
Sridevi Ramesh45e52542020-04-03 07:54:18 -0500323 case PLDM_OEM:
Pavithra Barithaya6f4e9042020-04-20 23:33:46 -0500324#ifdef OEM_IBM
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500325 printCommand(pldmIBMHostCmds, i, cmdinfo);
326 printCommand(pldmIBMFileIOCmds, i, cmdinfo);
Pavithra Barithaya6f4e9042020-04-20 23:33:46 -0500327#endif
Sridevi Ramesh45e52542020-04-03 07:54:18 -0500328 break;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600329 default:
330 break;
331 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500332 output.emplace_back(cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600333 }
334 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500335 pldmtool::helper::DisplayInJson(output);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600336 }
337};
338
John Wang58a0e062019-11-08 15:38:15 +0800339void registerCommand(CLI::App& app)
340{
341 auto base = app.add_subcommand("base", "base type command");
342 base->require_subcommand(1);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600343
John Wang58a0e062019-11-08 15:38:15 +0800344 auto getPLDMTypes =
345 base->add_subcommand("GetPLDMTypes", "get pldm supported types");
346 commands.push_back(
347 std::make_unique<GetPLDMTypes>("base", "GetPLDMTypes", getPLDMTypes));
348
349 auto getPLDMVersion =
350 base->add_subcommand("GetPLDMVersion", "get version of a certain type");
351 commands.push_back(std::make_unique<GetPLDMVersion>(
352 "base", "GetPLDMVersion", getPLDMVersion));
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600353
354 auto getPLDMTID = base->add_subcommand("GetTID", "get Terminus ID (TID)");
355 commands.push_back(std::make_unique<GetTID>("base", "GetTID", getPLDMTID));
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600356
357 auto getPLDMCommands = base->add_subcommand(
358 "GetPLDMCommands", "get supported commands of pldm type");
359 commands.push_back(std::make_unique<GetPLDMCommands>(
360 "base", "GetPLDMCommands", getPLDMCommands));
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500361}
John Wang58a0e062019-11-08 15:38:15 +0800362
363} // namespace base
364} // namespace pldmtool