pldmtool: Add GetStateEffecterStates command
Add GetStateEffecterStates command in pldmtool.
Used to get state effecter current and pending states
by supplying an effecter ID.
Tested:
```
root@bmc:~# pldmtool platform GetStateEffecterStates -h
get the state effecter states
Usage: pldmtool platform GetStateEffecterStates [OPTIONS]
Options:
-h,--help Print this help message and exit
-m,--mctp_eid UINT MCTP endpoint ID
-v,--verbose
-n,--retry-count UINT Number of retry when PLDM request message is failed
-i,--effecter_id UINT REQUIRED
Effecter ID that is used to identify and access the effecter
root@bmc:~# pldmtool platform GetStateEffecterStates -m 9 -i 348
{
"compositeEffecterCount": 1,
"effecterOpState[0])": "Effecter Enabled No Update Pending",
"pendingState[0]": 1,
"presentState[0]": 1
}
```
Change-Id: Ib72d2181dec955367310d6218628bb26952346b2
Signed-off-by: Tal Yacobi <talycb8@gmail.com>
diff --git a/pldmtool/pldm_base_cmd.cpp b/pldmtool/pldm_base_cmd.cpp
index 87152cd..3d94481 100644
--- a/pldmtool/pldm_base_cmd.cpp
+++ b/pldmtool/pldm_base_cmd.cpp
@@ -49,6 +49,7 @@
const std::map<const char*, pldm_platform_commands> pldmPlatformCmds{
{"SetNumericEffecterValue", PLDM_SET_NUMERIC_EFFECTER_VALUE},
{"SetStateEffecterStates", PLDM_SET_STATE_EFFECTER_STATES},
+ {"GetStateEffecterStates", PLDM_GET_STATE_EFFECTER_STATES},
{"GetPDR", PLDM_GET_PDR},
{"GetNumericEffecterValue", PLDM_GET_NUMERIC_EFFECTER_VALUE},
{"SetEventReceiver", PLDM_SET_EVENT_RECEIVER},
diff --git a/pldmtool/pldm_platform_cmd.cpp b/pldmtool/pldm_platform_cmd.cpp
index 21d0c8a..0f3ca25 100644
--- a/pldmtool/pldm_platform_cmd.cpp
+++ b/pldmtool/pldm_platform_cmd.cpp
@@ -7,7 +7,9 @@
#include <algorithm>
#include <cstddef>
+#include <format>
#include <map>
+#include <memory>
#include <ranges>
#ifdef OEM_IBM
@@ -47,6 +49,25 @@
{PLDM_SENSOR_SHUTTINGDOWN, "Sensor Shutting down"},
{PLDM_SENSOR_INTEST, "Sensor Intest"}};
+const std::map<uint8_t, std::string> effecterOpState{
+ {EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING,
+ "Effecter Enabled Update Pending"},
+ {EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
+ "Effecter Enabled No Update Pending"},
+ {EFFECTER_OPER_STATE_DISABLED, "Effecter Disabled"},
+ {EFFECTER_OPER_STATE_UNAVAILABLE, "Effecter Unavailable"},
+ {EFFECTER_OPER_STATE_STATUSUNKNOWN, "Effecter Status Unknown"},
+ {EFFECTER_OPER_STATE_FAILED, "Effecter Failed"},
+ {EFFECTER_OPER_STATE_INITIALIZING, "Effecter Initializing"},
+ {EFFECTER_OPER_STATE_SHUTTINGDOWN, "Effecter Shutting Down"},
+ {EFFECTER_OPER_STATE_INTEST, "Effecter In Test"}};
+
+std::string getEffecterOpState(uint8_t state)
+{
+ return effecterOpState.contains(state) ? effecterOpState.at(state)
+ : std::to_string(state);
+}
+
std::vector<std::unique_ptr<CommandInterface>> commands;
} // namespace
@@ -2007,6 +2028,76 @@
}
};
+class GetStateEffecterStates : public CommandInterface
+{
+ public:
+ ~GetStateEffecterStates() = default;
+ GetStateEffecterStates() = delete;
+ GetStateEffecterStates(const GetStateEffecterStates&) = delete;
+ GetStateEffecterStates(GetStateEffecterStates&&) = default;
+ GetStateEffecterStates& operator=(const GetStateEffecterStates&) = delete;
+ GetStateEffecterStates& operator=(GetStateEffecterStates&&) = delete;
+
+ explicit GetStateEffecterStates(const char* type, const char* name,
+ CLI::App* app) :
+ CommandInterface(type, name, app)
+ {
+ app->add_option(
+ "-i, --effecter_id", effecter_id,
+ "Effecter ID that is used to identify and access the effecter")
+ ->required();
+ }
+
+ std::pair<int, std::vector<uint8_t>> createRequestMsg() override
+ {
+ std::vector<uint8_t> requestMsg(
+ sizeof(pldm_msg_hdr) + PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ auto rc = encode_get_state_effecter_states_req(
+ instanceId, effecter_id, request,
+ PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES);
+
+ return {rc, requestMsg};
+ }
+
+ void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
+ {
+ struct pldm_get_state_effecter_states_resp resp;
+ auto rc = decode_get_state_effecter_states_resp(responsePtr,
+ payloadLength, &resp);
+
+ if (rc || resp.completion_code != PLDM_SUCCESS)
+ {
+ std::cerr << "Response Message Error: "
+ << "rc=" << rc
+ << ",cc=" << static_cast<int>(resp.completion_code)
+ << std::endl;
+ return;
+ }
+ ordered_json output;
+ auto comp_effecter_count = static_cast<int>(resp.comp_effecter_count);
+ output["compositeEffecterCount"] = comp_effecter_count;
+
+ for (auto i : std::views::iota(comp_effecter_count))
+ {
+ output[std::format("effecterOpState[{}])", i)] =
+ getEffecterOpState(resp.field[i].effecter_op_state);
+
+ output[std::format("pendingState[{}]", i)] =
+ resp.field[i].pending_state;
+
+ output[std::format("presentState[{}]", i)] =
+ resp.field[i].present_state;
+ }
+
+ pldmtool::helper::DisplayInJson(output);
+ }
+
+ private:
+ uint16_t effecter_id;
+};
+
class GetNumericEffecterValue : public CommandInterface
{
public:
@@ -2068,7 +2159,7 @@
ordered_json output;
output["effecterDataSize"] = static_cast<int>(effecterDataSize);
output["effecterOperationalState"] =
- getOpState(effecterOperationalState);
+ getEffecterOpState(effecterOperationalState);
switch (effecterDataSize)
{
@@ -2133,32 +2224,6 @@
private:
uint16_t effecterId;
-
- static inline const std::map<uint8_t, std::string> numericEffecterOpState{
- {EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING,
- "Effecter Enabled Update Pending"},
- {EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
- "Effecter Enabled No Update Pending"},
- {EFFECTER_OPER_STATE_DISABLED, "Effecter Disabled"},
- {EFFECTER_OPER_STATE_UNAVAILABLE, "Effecter Unavailable"},
- {EFFECTER_OPER_STATE_STATUSUNKNOWN, "Effecter Status Unknown"},
- {EFFECTER_OPER_STATE_FAILED, "Effecter Failed"},
- {EFFECTER_OPER_STATE_INITIALIZING, "Effecter Initializing"},
- {EFFECTER_OPER_STATE_SHUTTINGDOWN, "Effecter Shutting Down"},
- {EFFECTER_OPER_STATE_INTEST, "Effecter In Test"}};
-
- std::string getOpState(uint8_t state)
- {
- auto typeString = std::to_string(state);
- try
- {
- return numericEffecterOpState.at(state);
- }
- catch (const std::out_of_range& e)
- {
- return typeString;
- }
- }
};
void registerCommand(CLI::App& app)
@@ -2194,6 +2259,11 @@
"GetSensorReading", "get the numeric sensor reading");
commands.push_back(std::make_unique<GetSensorReading>(
"platform", "getSensorReading", getSensorReading));
+
+ auto getStateEffecterStates = platform->add_subcommand(
+ "GetStateEffecterStates", "get the state effecter states");
+ commands.push_back(std::make_unique<GetStateEffecterStates>(
+ "platform", "getStateEffecterStates", getStateEffecterStates));
}
void parseGetPDROption()