blob: 9d6449a758974cafdd61e0404f4ab9704d9a06f0 [file] [log] [blame]
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05001#include "pldm_base_cmd.hpp"
2
George Liu6492f522020-06-16 10:34:05 +08003#include "pldm_cmd_helper.hpp"
4
George Liuc453e162022-12-21 17:16:23 +08005#include <libpldm/utils.h>
6
Sridevi Ramesh45e52542020-04-03 07:54:18 -05007#ifdef OEM_IBM
Andrew Jeffery21f128d2024-01-15 15:34:26 +10308#include <libpldm/oem/ibm/file_io.h>
9#include <libpldm/oem/ibm/host.h>
Sridevi Ramesh45e52542020-04-03 07:54:18 -050010#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},
Sridevi Ramesh8fb11c92021-06-08 08:45:01 -050042 {"SetBIOSTable", PLDM_SET_BIOS_TABLE},
Sridevi Ramesh66294d32020-02-21 03:52:07 -060043 {"SetBIOSAttributeCurrentValue", PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE},
44 {"GetBIOSAttributeCurrentValueByHandle",
45 PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE},
46 {"GetDateTime", PLDM_GET_DATE_TIME},
47 {"SetDateTime", PLDM_SET_DATE_TIME}};
48
49const std::map<const char*, pldm_platform_commands> pldmPlatformCmds{
50 {"SetNumericEffecterValue", PLDM_SET_NUMERIC_EFFECTER_VALUE},
51 {"SetStateEffecterStates", PLDM_SET_STATE_EFFECTER_STATES},
Tal Yacobi8570fcc2024-05-28 11:11:23 +030052 {"GetStateEffecterStates", PLDM_GET_STATE_EFFECTER_STATES},
Sridevi Ramesh8fb11c92021-06-08 08:45:01 -050053 {"GetPDR", PLDM_GET_PDR},
54 {"GetNumericEffecterValue", PLDM_GET_NUMERIC_EFFECTER_VALUE},
55 {"SetEventReceiver", PLDM_SET_EVENT_RECEIVER},
56 {"GetSensorReading", PLDM_GET_SENSOR_READING},
57 {"GetStateSensorReadings", PLDM_GET_STATE_SENSOR_READINGS},
58 {"PlatformEventMessage", PLDM_PLATFORM_EVENT_MESSAGE}};
Sridevi Ramesh66294d32020-02-21 03:52:07 -060059
60const std::map<const char*, pldm_fru_commands> pldmFruCmds{
61 {"GetFRURecordTableMetadata", PLDM_GET_FRU_RECORD_TABLE_METADATA},
John Wang5bdde3a2020-06-16 15:02:33 +080062 {"GetFRURecordTable", PLDM_GET_FRU_RECORD_TABLE},
63 {"GetFRURecordByOption", PLDM_GET_FRU_RECORD_BY_OPTION}};
Sridevi Ramesh66294d32020-02-21 03:52:07 -060064
Sridevi Ramesh45e52542020-04-03 07:54:18 -050065#ifdef OEM_IBM
66const std::map<const char*, pldm_host_commands> pldmIBMHostCmds{
67 {"GetAlertStatus", PLDM_HOST_GET_ALERT_STATUS}};
68
69const std::map<const char*, pldm_fileio_commands> pldmIBMFileIOCmds{
70 {"GetFileTable", PLDM_GET_FILE_TABLE},
71 {"ReadFile", PLDM_READ_FILE},
72 {"WriteFile", PLDM_WRITE_FILE},
73 {"ReadFileInToMemory", PLDM_READ_FILE_INTO_MEMORY},
74 {"WriteFileFromMemory", PLDM_WRITE_FILE_FROM_MEMORY},
75 {"ReadFileByTypeIntoMemory", PLDM_READ_FILE_BY_TYPE_INTO_MEMORY},
76 {"WriteFileByTypeFromMemory", PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY},
77 {"NewFileAvailable", PLDM_NEW_FILE_AVAILABLE},
78 {"ReadFileByType", PLDM_READ_FILE_BY_TYPE},
79 {"WriteFileByType", PLDM_WRITE_FILE_BY_TYPE},
80 {"FileAck", PLDM_FILE_ACK}};
81#endif
82
John Wang58a0e062019-11-08 15:38:15 +080083} // namespace
84
85class GetPLDMTypes : public CommandInterface
86{
87 public:
88 ~GetPLDMTypes() = default;
89 GetPLDMTypes() = delete;
90 GetPLDMTypes(const GetPLDMTypes&) = delete;
91 GetPLDMTypes(GetPLDMTypes&&) = default;
92 GetPLDMTypes& operator=(const GetPLDMTypes&) = delete;
Pavithra Barithayaa7dbca52023-07-07 04:19:37 -050093 GetPLDMTypes& operator=(GetPLDMTypes&&) = delete;
John Wang58a0e062019-11-08 15:38:15 +080094
95 using CommandInterface::CommandInterface;
96
97 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -050098 {
John Wang58a0e062019-11-08 15:38:15 +080099 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
100 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600101 auto rc = encode_get_types_req(instanceId, request);
John Wang58a0e062019-11-08 15:38:15 +0800102 return {rc, requestMsg};
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500103 }
104
John Wang58a0e062019-11-08 15:38:15 +0800105 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500106 {
John Wang58a0e062019-11-08 15:38:15 +0800107 uint8_t cc = 0;
108 std::vector<bitfield8_t> types(8);
109 auto rc = decode_get_types_resp(responsePtr, payloadLength, &cc,
110 types.data());
111 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
112 {
113 std::cerr << "Response Message Error: "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600114 << "rc=" << rc << ",cc=" << (int)cc << "\n";
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500115 return;
John Wang58a0e062019-11-08 15:38:15 +0800116 }
117
118 printPldmTypes(types);
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500119 }
120
John Wang58a0e062019-11-08 15:38:15 +0800121 private:
122 void printPldmTypes(std::vector<bitfield8_t>& types)
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500123 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500124 ordered_json data;
125 ordered_json jarray;
John Wang58a0e062019-11-08 15:38:15 +0800126 for (int i = 0; i < PLDM_MAX_TYPES; i++)
127 {
128 bitfield8_t b = types[i / 8];
129 if (b.byte & (1 << i % 8))
130 {
Patrick Williamsa6756622023-10-20 11:19:15 -0500131 auto it = std::find_if(
132 pldmTypes.begin(), pldmTypes.end(),
133 [i](const auto& typePair) { return typePair.second == i; });
John Wang58a0e062019-11-08 15:38:15 +0800134 if (it != pldmTypes.end())
135 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500136 jarray["PLDM Type"] = it->first;
137 jarray["PLDM Type Code"] = i;
138 data.emplace_back(jarray);
John Wang58a0e062019-11-08 15:38:15 +0800139 }
140 }
141 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500142 pldmtool::helper::DisplayInJson(data);
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500143 }
John Wang58a0e062019-11-08 15:38:15 +0800144};
145
146class GetPLDMVersion : public CommandInterface
147{
148 public:
149 ~GetPLDMVersion() = default;
150 GetPLDMVersion() = delete;
151 GetPLDMVersion(const GetPLDMVersion&) = delete;
152 GetPLDMVersion(GetPLDMVersion&&) = default;
153 GetPLDMVersion& operator=(const GetPLDMVersion&) = delete;
Pavithra Barithayaa7dbca52023-07-07 04:19:37 -0500154 GetPLDMVersion& operator=(GetPLDMVersion&&) = delete;
John Wang58a0e062019-11-08 15:38:15 +0800155
156 explicit GetPLDMVersion(const char* type, const char* name, CLI::App* app) :
157 CommandInterface(type, name, app)
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500158 {
John Wang58a0e062019-11-08 15:38:15 +0800159 app->add_option("-t,--type", pldmType, "pldm supported type")
160 ->required()
161 ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500162 }
John Wang58a0e062019-11-08 15:38:15 +0800163 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
164 {
165 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
166 PLDM_GET_VERSION_REQ_BYTES);
167 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
168
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600169 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART,
170 pldmType, request);
John Wang58a0e062019-11-08 15:38:15 +0800171 return {rc, requestMsg};
172 }
173
174 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
175 {
176 uint8_t cc = 0, transferFlag = 0;
177 uint32_t transferHandle = 0;
178 ver32_t version;
Patrick Williams6da4f912023-05-10 07:50:53 -0500179 auto rc = decode_get_version_resp(responsePtr, payloadLength, &cc,
180 &transferHandle, &transferFlag,
181 &version);
John Wang58a0e062019-11-08 15:38:15 +0800182 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
183 {
184 std::cerr << "Response Message Error: "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600185 << "rc=" << rc << ",cc=" << (int)cc << "\n";
John Wang58a0e062019-11-08 15:38:15 +0800186 return;
187 }
188 char buffer[16] = {0};
189 ver2str(&version, buffer, sizeof(buffer));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500190 ordered_json data;
Patrick Williamsa6756622023-10-20 11:19:15 -0500191 auto it = std::find_if(
192 pldmTypes.begin(), pldmTypes.end(),
193 [&](const auto& typePair) { return typePair.second == pldmType; });
John Wang58a0e062019-11-08 15:38:15 +0800194
195 if (it != pldmTypes.end())
196 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500197 data["Response"] = buffer;
John Wang58a0e062019-11-08 15:38:15 +0800198 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500199 pldmtool::helper::DisplayInJson(data);
John Wang58a0e062019-11-08 15:38:15 +0800200 }
201
202 private:
203 pldm_supported_types pldmType;
204};
205
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600206class GetTID : public CommandInterface
207{
208 public:
209 ~GetTID() = default;
210 GetTID() = delete;
211 GetTID(const GetTID&) = delete;
212 GetTID(GetTID&&) = default;
213 GetTID& operator=(const GetTID&) = delete;
Pavithra Barithayaa7dbca52023-07-07 04:19:37 -0500214 GetTID& operator=(GetTID&&) = delete;
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600215
216 using CommandInterface::CommandInterface;
217
218 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
219 {
220 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
221 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600222 auto rc = encode_get_tid_req(instanceId, request);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600223 return {rc, requestMsg};
224 }
225
226 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
227 {
228 uint8_t cc = 0;
229 uint8_t tid = 0;
230 std::vector<bitfield8_t> types(8);
231 auto rc = decode_get_tid_resp(responsePtr, payloadLength, &cc, &tid);
232 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
233 {
234 std::cerr << "Response Message Error: "
235 << "rc=" << rc << ",cc=" << (int)cc << "\n";
236 return;
237 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500238 ordered_json data;
239 data["Response"] = static_cast<uint32_t>(tid);
240 pldmtool::helper::DisplayInJson(data);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600241 }
242};
243
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600244class GetPLDMCommands : public CommandInterface
245{
246 public:
247 ~GetPLDMCommands() = default;
248 GetPLDMCommands() = delete;
249 GetPLDMCommands(const GetPLDMCommands&) = delete;
250 GetPLDMCommands(GetPLDMCommands&&) = default;
251 GetPLDMCommands& operator=(const GetPLDMCommands&) = delete;
Pavithra Barithayaa7dbca52023-07-07 04:19:37 -0500252 GetPLDMCommands& operator=(GetPLDMCommands&&) = delete;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600253
254 explicit GetPLDMCommands(const char* type, const char* name,
255 CLI::App* app) :
256 CommandInterface(type, name, app)
257 {
258 app->add_option("-t,--type", pldmType, "pldm supported type")
259 ->required()
260 ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
Thu Nguyen6c83d3b2024-06-22 13:06:12 +0000261 app->add_option(
262 "-d,--data", inputVersion,
263 "Set PLDM type version. Which is got from GetPLDMVersion\n"
264 "eg: version 1.1.0 then data will be `0xf1 0xf1 0xf0 0x00`");
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600265 }
266
267 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
268 {
269 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
270 PLDM_GET_COMMANDS_REQ_BYTES);
271 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
272 ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
Thu Nguyen6c83d3b2024-06-22 13:06:12 +0000273 if (inputVersion.size() != 0)
274 {
275 if (inputVersion.size() != 4)
276 {
277 std::cerr << "Invalid version format. "
278 << "\n";
279 }
280 else
281 {
282 version.major = inputVersion[3];
283 version.minor = inputVersion[2];
284 version.update = inputVersion[1];
285 version.alpha = inputVersion[0];
286 }
287 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500288 auto rc = encode_get_commands_req(instanceId, pldmType, version,
289 request);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600290 return {rc, requestMsg};
291 }
292
293 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
294 {
295 uint8_t cc = 0;
296 std::vector<bitfield8_t> cmdTypes(32);
297 auto rc = decode_get_commands_resp(responsePtr, payloadLength, &cc,
298 cmdTypes.data());
299 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
300 {
301 std::cerr << "Response Message Error: "
302 << "rc=" << rc << ",cc=" << (int)cc << "\n";
303 return;
304 }
305 printPldmCommands(cmdTypes, pldmType);
306 }
307
308 private:
309 pldm_supported_types pldmType;
Thu Nguyen6c83d3b2024-06-22 13:06:12 +0000310 std::vector<uint8_t> inputVersion;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600311
312 template <typename CommandMap>
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500313 void printCommand(CommandMap& commandMap, int i, ordered_json& jarray)
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600314 {
Patrick Williamsa6756622023-10-20 11:19:15 -0500315 auto it = std::find_if(
316 commandMap.begin(), commandMap.end(),
317 [i](const auto& typePair) { return typePair.second == i; });
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600318 if (it != commandMap.end())
319 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500320 jarray["PLDM Command Code"] = i;
321 jarray["PLDM Command"] = it->first;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600322 }
323 }
324
325 void printPldmCommands(std::vector<bitfield8_t>& cmdTypes,
326 pldm_supported_types pldmType)
327 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500328 ordered_json output;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600329 for (int i = 0; i < PLDM_MAX_CMDS_PER_TYPE; i++)
330 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500331 ordered_json cmdinfo;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600332 bitfield8_t b = cmdTypes[i / 8];
333 if (b.byte & (1 << i % 8))
334 {
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600335 switch (pldmType)
336 {
337 case PLDM_BASE:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500338 printCommand(pldmBaseCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600339 break;
340 case PLDM_PLATFORM:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500341 printCommand(pldmPlatformCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600342 break;
343 case PLDM_BIOS:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500344 printCommand(pldmBiosCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600345 break;
346 case PLDM_FRU:
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500347 printCommand(pldmFruCmds, i, cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600348 break;
Sridevi Ramesh45e52542020-04-03 07:54:18 -0500349 case PLDM_OEM:
Pavithra Barithaya6f4e9042020-04-20 23:33:46 -0500350#ifdef OEM_IBM
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500351 printCommand(pldmIBMHostCmds, i, cmdinfo);
352 printCommand(pldmIBMFileIOCmds, i, cmdinfo);
Pavithra Barithaya6f4e9042020-04-20 23:33:46 -0500353#endif
Sridevi Ramesh45e52542020-04-03 07:54:18 -0500354 break;
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600355 default:
356 break;
357 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500358 output.emplace_back(cmdinfo);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600359 }
360 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500361 pldmtool::helper::DisplayInJson(output);
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600362 }
363};
364
John Wang58a0e062019-11-08 15:38:15 +0800365void registerCommand(CLI::App& app)
366{
367 auto base = app.add_subcommand("base", "base type command");
368 base->require_subcommand(1);
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600369
Patrick Williams6da4f912023-05-10 07:50:53 -0500370 auto getPLDMTypes = base->add_subcommand("GetPLDMTypes",
371 "get pldm supported types");
John Wang58a0e062019-11-08 15:38:15 +0800372 commands.push_back(
373 std::make_unique<GetPLDMTypes>("base", "GetPLDMTypes", getPLDMTypes));
374
Patrick Williams6da4f912023-05-10 07:50:53 -0500375 auto getPLDMVersion = base->add_subcommand("GetPLDMVersion",
376 "get version of a certain type");
John Wang58a0e062019-11-08 15:38:15 +0800377 commands.push_back(std::make_unique<GetPLDMVersion>(
378 "base", "GetPLDMVersion", getPLDMVersion));
Sridevi Rameshadd56f02020-01-20 23:44:22 -0600379
380 auto getPLDMTID = base->add_subcommand("GetTID", "get Terminus ID (TID)");
381 commands.push_back(std::make_unique<GetTID>("base", "GetTID", getPLDMTID));
Sridevi Ramesh66294d32020-02-21 03:52:07 -0600382
383 auto getPLDMCommands = base->add_subcommand(
384 "GetPLDMCommands", "get supported commands of pldm type");
385 commands.push_back(std::make_unique<GetPLDMCommands>(
386 "base", "GetPLDMCommands", getPLDMCommands));
Lakshminarayana R. Kammath58229b22019-08-09 06:30:04 -0500387}
John Wang58a0e062019-11-08 15:38:15 +0800388
389} // namespace base
390} // namespace pldmtool