blob: da60d4dfa4a526f26c24fb59e5c910feea135dd7 [file] [log] [blame]
Tom Josepha65c0412020-07-03 21:14:44 +05301#include "libpldm/entity.h"
2#include "libpldm/state_set.h"
3
4#include "common/types.hpp"
George Liud6649362019-11-27 19:06:51 +08005#include "pldm_cmd_helper.hpp"
6
George Liud6649362019-11-27 19:06:51 +08007namespace pldmtool
8{
9
10namespace platform
11{
12
13namespace
14{
15
16using namespace pldmtool::helper;
17std::vector<std::unique_ptr<CommandInterface>> commands;
18
19} // namespace
20
Sridevi Ramesh27c512a2020-08-12 03:29:42 -050021using ordered_json = nlohmann::ordered_json;
22
George Liud6649362019-11-27 19:06:51 +080023class GetPDR : public CommandInterface
24{
25 public:
26 ~GetPDR() = default;
27 GetPDR() = delete;
28 GetPDR(const GetPDR&) = delete;
29 GetPDR(GetPDR&&) = default;
30 GetPDR& operator=(const GetPDR&) = delete;
31 GetPDR& operator=(GetPDR&&) = default;
32
33 using CommandInterface::CommandInterface;
34
George Liud6649362019-11-27 19:06:51 +080035 explicit GetPDR(const char* type, const char* name, CLI::App* app) :
36 CommandInterface(type, name, app)
37 {
38 app->add_option(
39 "-d,--data", recordHandle,
40 "retrieve individual PDRs from a PDR Repository\n"
41 "eg: The recordHandle value for the PDR to be retrieved and 0 "
42 "means get first PDR in the repository.")
43 ->required();
44 }
45
46 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
47 {
48 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
49 PLDM_GET_PDR_REQ_BYTES);
50 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
51
Deepak Kodihallia59cdc62020-07-14 05:11:33 -050052 auto rc =
53 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
54 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
George Liud6649362019-11-27 19:06:51 +080055 return {rc, requestMsg};
56 }
57
58 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
59 {
60 uint8_t completionCode = 0;
Deepak Kodihallia59cdc62020-07-14 05:11:33 -050061 uint8_t recordData[UINT16_MAX] = {0};
George Liud6649362019-11-27 19:06:51 +080062 uint32_t nextRecordHndl = 0;
63 uint32_t nextDataTransferHndl = 0;
64 uint8_t transferFlag = 0;
65 uint16_t respCnt = 0;
66 uint8_t transferCRC = 0;
67
68 auto rc = decode_get_pdr_resp(
69 responsePtr, payloadLength, &completionCode, &nextRecordHndl,
70 &nextDataTransferHndl, &transferFlag, &respCnt, recordData,
71 sizeof(recordData), &transferCRC);
72
73 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
74 {
75 std::cerr << "Response Message Error: "
76 << "rc=" << rc << ",cc=" << (int)completionCode
77 << std::endl;
78 return;
79 }
80
George Liu62d12ec2020-02-05 16:27:08 +080081 printPDRMsg(nextRecordHndl, respCnt, recordData);
George Liud6649362019-11-27 19:06:51 +080082 }
83
84 private:
Tom Josepha65c0412020-07-03 21:14:44 +053085 const std::map<pldm::pdr::EntityType, std::string> entityType = {
86 {PLDM_ENTITY_COMM_CHANNEL, "Communication Channel"},
87 {PLDM_ENTITY_SYS_FIRMWARE, "System Firmware"},
88 {PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER, "Virtual Machine Manager"},
89 {PLDM_ENTITY_SYSTEM_CHASSIS, "System chassis (main enclosure)"},
90 {PLDM_ENTITY_SYS_BOARD, "System Board"},
91 {PLDM_ENTITY_MEMORY_MODULE, "Memory Module"},
92 {PLDM_ENTITY_PROC_MODULE, "Processor Module"},
93 {PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD,
94 "Chassis front panel board (control panel)"},
95 {PLDM_ENTITY_POWER_CONVERTER, "Power converter"},
96 {PLDM_ENTITY_PROC, "Processor"},
97 {PLDM_ENTITY_MGMT_CONTROLLER, "Management Controller"},
98 {PLDM_ENTITY_CONNECTOR, "Connector"},
Deepak Kodihallie05dcc22020-07-14 05:13:58 -050099 {PLDM_ENTITY_POWER_SUPPLY, "Power Supply"},
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500100 {11521, "System (logical)"},
101 };
102
Tom Josepha65c0412020-07-03 21:14:44 +0530103 const std::map<uint16_t, std::string> stateSet = {
104 {PLDM_STATE_SET_HEALTH_STATE, "Health State"},
105 {PLDM_STATE_SET_AVAILABILITY, "Availability"},
106 {PLDM_STATE_SET_OPERATIONAL_STATUS, "Operational Status"},
107 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
108 "Operational Running Status"},
109 {PLDM_STATE_SET_PRESENCE, "Presence"},
110 {PLDM_STATE_SET_CONFIGURATION_STATE, "Configuration State"},
111 {PLDM_STATE_SET_LINK_STATE, "Link State"},
112 {PLDM_STATE_SET_SW_TERMINATION_STATUS, "Software Termination Status"},
113 {PLDM_STATE_SET_BOOT_RESTART_CAUSE, "Boot/Restart Cause"},
114 {PLDM_STATE_SET_BOOT_PROGRESS, "Boot Progress"},
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500115 {PLDM_STATE_SET_SYSTEM_POWER_STATE, "System Power State"},
Tom Josepha65c0412020-07-03 21:14:44 +0530116 };
117
118 const std::array<std::string_view, 4> sensorInit = {
119 "noInit", "useInitPDR", "enableSensor", "disableSensor"};
120
Tom Joseph97a7a762020-07-06 10:37:18 +0530121 const std::array<std::string_view, 4> effecterInit = {
122 "noInit", "useInitPDR", "enableEffecter", "disableEffecter"};
123
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500124 const std::map<uint8_t, std::string> pdrType = {
125 {PLDM_TERMINUS_LOCATOR_PDR, "Terminus Locator PDR"},
126 {PLDM_NUMERIC_SENSOR_PDR, "Numeric Sensor PDR"},
127 {PLDM_NUMERIC_SENSOR_INITIALIZATION_PDR,
128 "Numeric Sensor Initialization PDR"},
129 {PLDM_STATE_SENSOR_PDR, "State Sensor PDR"},
130 {PLDM_STATE_SENSOR_INITIALIZATION_PDR,
131 "State Sensor Initialization PDR"},
132 {PLDM_SENSOR_AUXILIARY_NAMES_PDR, "Sensor Auxiliary Names PDR"},
133 {PLDM_OEM_UNIT_PDR, "OEM Unit PDR"},
134 {PLDM_OEM_STATE_SET_PDR, "OEM State Set PDR"},
135 {PLDM_NUMERIC_EFFECTER_PDR, "Numeric Effecter PDR"},
136 {PLDM_NUMERIC_EFFECTER_INITIALIZATION_PDR,
137 "Numeric Effecter Initialization PDR"},
138 {PLDM_STATE_EFFECTER_PDR, "State Effecter PDR"},
139 {PLDM_STATE_EFFECTER_INITIALIZATION_PDR,
140 "State Effecter Initialization PDR"},
141 {PLDM_EFFECTER_AUXILIARY_NAMES_PDR, "Effecter Auxiliary Names PDR"},
142 {PLDM_EFFECTER_OEM_SEMANTIC_PDR, "Effecter OEM Semantic PDR"},
143 {PLDM_PDR_ENTITY_ASSOCIATION, "Entity Association PDR"},
144 {PLDM_ENTITY_AUXILIARY_NAMES_PDR, "Entity Auxiliary Names PDR"},
145 {PLDM_OEM_ENTITY_ID_PDR, "OEM Entity ID PDR"},
146 {PLDM_INTERRUPT_ASSOCIATION_PDR, "Interrupt Association PDR"},
147 {PLDM_EVENT_LOG_PDR, "PLDM Event Log PDR"},
148 {PLDM_PDR_FRU_RECORD_SET, "FRU Record Set PDR"},
149 {PLDM_OEM_DEVICE_PDR, "OEM Device PDR"},
150 {PLDM_OEM_PDR, "OEM PDR"},
151 };
152
Tom Josepha65c0412020-07-03 21:14:44 +0530153 std::string getEntityName(pldm::pdr::EntityType type)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500154 {
155 try
156 {
157 return entityType.at(type);
158 }
159 catch (const std::out_of_range& e)
160 {
161 return std::to_string(static_cast<unsigned>(type)) + "(OEM)";
162 }
163 }
164
Tom Josepha65c0412020-07-03 21:14:44 +0530165 std::string getStateSetName(uint16_t id)
166 {
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500167 auto typeString = std::to_string(id);
Tom Josepha65c0412020-07-03 21:14:44 +0530168 try
169 {
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500170 return stateSet.at(id) + "(" + typeString + ")";
Tom Josepha65c0412020-07-03 21:14:44 +0530171 }
172 catch (const std::out_of_range& e)
173 {
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500174 return typeString;
175 }
176 }
177
178 std::string getPDRType(uint8_t type)
179 {
180 auto typeString = std::to_string(type);
181 try
182 {
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500183 return pdrType.at(type);
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500184 }
185 catch (const std::out_of_range& e)
186 {
187 return typeString;
Tom Josepha65c0412020-07-03 21:14:44 +0530188 }
189 }
190
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500191 void printCommonPDRHeader(const pldm_pdr_hdr* hdr, ordered_json& output)
Tom Joseph952abfa2020-07-03 12:25:15 +0530192 {
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500193 output["recordHandle"] = hdr->record_handle;
194 output["PDRHeaderVersion"] = unsigned(hdr->version);
195 output["PDRType"] = getPDRType(hdr->type);
196 output["recordChangeNumber"] = hdr->record_change_num;
197 output["dataLength"] = hdr->length;
Tom Joseph952abfa2020-07-03 12:25:15 +0530198 }
199
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500200 std::string printPossibleStates(uint8_t possibleStatesSize,
201 const bitfield8_t* states)
Tom Josepha65c0412020-07-03 21:14:44 +0530202 {
203 uint8_t possibleStatesPos{};
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500204 std::string data;
205 auto printStates = [&possibleStatesPos, &data](const bitfield8_t& val) {
206 std::stringstream pstates;
Tom Josepha65c0412020-07-03 21:14:44 +0530207 for (int i = 0; i < CHAR_BIT; i++)
208 {
209 if (val.byte & (1 << i))
210 {
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500211 pstates << " " << (possibleStatesPos * CHAR_BIT + i);
212 data.append(pstates.str());
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600213 pstates.str("");
Tom Josepha65c0412020-07-03 21:14:44 +0530214 }
215 }
216 possibleStatesPos++;
217 };
218 std::for_each(states, states + possibleStatesSize, printStates);
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500219 return data;
Tom Josepha65c0412020-07-03 21:14:44 +0530220 }
221
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500222 void printStateSensorPDR(const uint8_t* data, ordered_json& output)
Tom Josepha65c0412020-07-03 21:14:44 +0530223 {
224 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(data);
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500225 output["PLDMTerminusHandle"] = pdr->terminus_handle;
226 output["sensorID"] = pdr->sensor_id;
227 output["entityType"] = getEntityName(pdr->entity_type);
228 output["entityInstanceNumber"] = pdr->entity_instance;
229 output["containerID"] = pdr->container_id;
230 output["sensorInit"] = sensorInit[pdr->sensor_init];
231 output["sensorAuxiliaryNamesPDR"] =
232 (pdr->sensor_auxiliary_names_pdr ? true : false);
233 output["compositeSensorCount"] = unsigned(pdr->composite_sensor_count);
Tom Josepha65c0412020-07-03 21:14:44 +0530234
235 auto statesPtr = pdr->possible_states;
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600236 auto compCount = pdr->composite_sensor_count;
Tom Josepha65c0412020-07-03 21:14:44 +0530237
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600238 while (compCount--)
Tom Josepha65c0412020-07-03 21:14:44 +0530239 {
240 auto state = reinterpret_cast<const state_sensor_possible_states*>(
241 statesPtr);
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600242 output.emplace(("stateSetID[" + std::to_string(compCount) + "]"),
243 getStateSetName(state->state_set_id));
244 output.emplace(
245 ("possibleStatesSize[" + std::to_string(compCount) + "]"),
246 state->possible_states_size);
247 output.emplace(
248 ("possibleStates[" + std::to_string(compCount) + "]"),
249 printPossibleStates(state->possible_states_size,
250 state->states));
Tom Josepha65c0412020-07-03 21:14:44 +0530251
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600252 if (compCount)
Tom Josepha65c0412020-07-03 21:14:44 +0530253 {
254 statesPtr += sizeof(state_sensor_possible_states) +
255 state->possible_states_size - 1;
256 }
257 }
258 }
259
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500260 void printPDRFruRecordSet(uint8_t* data, ordered_json& output)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500261 {
George Liu62d12ec2020-02-05 16:27:08 +0800262 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500263 {
264 return;
265 }
266
267 data += sizeof(pldm_pdr_hdr);
268 pldm_pdr_fru_record_set* pdr =
269 reinterpret_cast<pldm_pdr_fru_record_set*>(data);
270
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500271 output["PLDMTerminusHandle"] = unsigned(pdr->terminus_handle);
272 output["FRURecordSetIdentifier"] = unsigned(pdr->fru_rsi);
273 output["entityType"] = getEntityName(pdr->entity_type);
274 output["entityInstanceNumber"] = unsigned(pdr->entity_instance_num);
275 output["containerID"] = unsigned(pdr->container_id);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500276 }
277
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500278 void printPDREntityAssociation(uint8_t* data, ordered_json& output)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500279 {
280 const std::map<uint8_t, const char*> assocationType = {
281 {PLDM_ENTITY_ASSOCIAION_PHYSICAL, "Physical"},
282 {PLDM_ENTITY_ASSOCIAION_LOGICAL, "Logical"},
283 };
284
George Liu62d12ec2020-02-05 16:27:08 +0800285 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500286 {
287 return;
288 }
289
290 data += sizeof(pldm_pdr_hdr);
291 pldm_pdr_entity_association* pdr =
292 reinterpret_cast<pldm_pdr_entity_association*>(data);
293
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500294 output["containerID"] = int(pdr->container_id);
295 output["associationType"] = assocationType.at(pdr->association_type);
296 output["containerEntityType"] =
297 getEntityName(pdr->container.entity_type);
298 output["containerEntityInstanceNumber"] =
299 int(pdr->container.entity_instance_num);
300 output["containerEntityContainerID"] =
301 int(pdr->container.entity_container_id);
302 output["containedEntityCount"] =
303 static_cast<unsigned>(pdr->num_children);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500304
305 auto child = reinterpret_cast<pldm_entity*>(&pdr->children[0]);
306 for (int i = 0; i < pdr->num_children; ++i)
307 {
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500308 output.emplace("containedEntityType[" + std::to_string(i + 1) + "]",
309 getEntityName(child->entity_type));
310 output.emplace("containedEntityInstanceNumber[" +
311 std::to_string(i + 1) + "]",
312 unsigned(child->entity_instance_num));
313 output.emplace("containedEntityContainerID[" +
314 std::to_string(i + 1) + "]",
315 unsigned(child->entity_container_id));
316
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500317 ++child;
318 }
319 }
320
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500321 void printNumericEffecterPDR(uint8_t* data, ordered_json& output)
George Liu62d12ec2020-02-05 16:27:08 +0800322 {
323 struct pldm_numeric_effecter_value_pdr* pdr =
324 (struct pldm_numeric_effecter_value_pdr*)data;
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500325
326 output["PLDMTerminusHandle"] = int(pdr->terminus_handle);
327 output["effecterID"] = int(pdr->effecter_id);
328 output["entityType"] = int(pdr->entity_type);
329 output["entityInstanceNumber"] = int(pdr->entity_instance);
330 output["containerID"] = int(pdr->container_id);
331 output["effecterSemanticID"] = int(pdr->effecter_semantic_id);
332 output["effecterInit"] = unsigned(pdr->effecter_init);
333 output["effecterAuxiliaryNames"] =
334 (unsigned(pdr->effecter_auxiliary_names) ? true : false);
335 output["baseUnit"] = unsigned(pdr->base_unit);
336 output["unitModifier"] = unsigned(pdr->unit_modifier);
337 output["rateUnit"] = unsigned(pdr->rate_unit);
338 output["baseOEMUnitHandle"] = unsigned(pdr->base_oem_unit_handle);
339 output["auxUnit"] = unsigned(pdr->aux_unit);
340 output["auxUnitModifier"] = unsigned(pdr->aux_unit_modifier);
341 output["auxrateUnit"] = unsigned(pdr->aux_rate_unit);
342 output["auxOEMUnitHandle"] = unsigned(pdr->aux_oem_unit_handle);
343 output["isLinear"] = (unsigned(pdr->is_linear) ? true : false);
344 output["effecterDataSize"] = unsigned(pdr->effecter_data_size);
345 output["resolution"] = unsigned(pdr->resolution);
346 output["offset"] = unsigned(pdr->offset);
347 output["accuracy"] = unsigned(pdr->accuracy);
348 output["plusTolerance"] = unsigned(pdr->plus_tolerance);
349 output["minusTolerance"] = unsigned(pdr->minus_tolerance);
350 output["stateTransitionInterval"] =
351 unsigned(pdr->state_transition_interval);
352 output["TransitionInterval"] = unsigned(pdr->transition_interval);
353
George Liu62d12ec2020-02-05 16:27:08 +0800354 switch (pdr->effecter_data_size)
355 {
356 case PLDM_EFFECTER_DATA_SIZE_UINT8:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500357 output["maxSettable"] = unsigned(pdr->max_set_table.value_u8);
358 output["minSettable"] = unsigned(pdr->min_set_table.value_u8);
George Liu62d12ec2020-02-05 16:27:08 +0800359 break;
360 case PLDM_EFFECTER_DATA_SIZE_SINT8:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500361 output["maxSettable"] = unsigned(pdr->max_set_table.value_s8);
362 output["minSettable"] = unsigned(pdr->min_set_table.value_s8);
George Liu62d12ec2020-02-05 16:27:08 +0800363 break;
364 case PLDM_EFFECTER_DATA_SIZE_UINT16:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500365 output["maxSettable"] = unsigned(pdr->max_set_table.value_u16);
366 output["minSettable"] = unsigned(pdr->min_set_table.value_u16);
George Liu62d12ec2020-02-05 16:27:08 +0800367 break;
368 case PLDM_EFFECTER_DATA_SIZE_SINT16:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500369 output["maxSettable"] = unsigned(pdr->max_set_table.value_s16);
370 output["minSettable"] = unsigned(pdr->min_set_table.value_s16);
George Liu62d12ec2020-02-05 16:27:08 +0800371 break;
372 case PLDM_EFFECTER_DATA_SIZE_UINT32:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500373 output["maxSettable"] = unsigned(pdr->max_set_table.value_u32);
374 output["minSettable"] = unsigned(pdr->min_set_table.value_u32);
George Liu62d12ec2020-02-05 16:27:08 +0800375 break;
376 case PLDM_EFFECTER_DATA_SIZE_SINT32:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500377 output["maxSettable"] = unsigned(pdr->max_set_table.value_s32);
378 output["minSettable"] = unsigned(pdr->min_set_table.value_s32);
George Liu62d12ec2020-02-05 16:27:08 +0800379 break;
380 default:
381 break;
382 }
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500383
384 output["rangeFieldFormat"] = unsigned(pdr->range_field_format);
385 output["rangeFieldSupport"] = unsigned(pdr->range_field_support.byte);
386
George Liu62d12ec2020-02-05 16:27:08 +0800387 switch (pdr->range_field_format)
388 {
389 case PLDM_RANGE_FIELD_FORMAT_UINT8:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500390 output["nominalValue"] = unsigned(pdr->nominal_value.value_u8);
391 output["normalMax"] = unsigned(pdr->normal_max.value_u8);
392 output["normalMin"] = unsigned(pdr->normal_min.value_u8);
393 output["ratedMax"] = unsigned(pdr->rated_max.value_u8);
394 output["ratedMin"] = unsigned(pdr->rated_min.value_u8);
George Liu62d12ec2020-02-05 16:27:08 +0800395 break;
396 case PLDM_RANGE_FIELD_FORMAT_SINT8:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500397 output["nominalValue"] = unsigned(pdr->nominal_value.value_s8);
398 output["normalMax"] = unsigned(pdr->normal_max.value_s8);
399 output["normalMin"] = unsigned(pdr->normal_min.value_s8);
400 output["ratedMax"] = unsigned(pdr->rated_max.value_s8);
401 output["ratedMin"] = unsigned(pdr->rated_min.value_s8);
George Liu62d12ec2020-02-05 16:27:08 +0800402 break;
403 case PLDM_RANGE_FIELD_FORMAT_UINT16:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500404 output["nominalValue"] = unsigned(pdr->nominal_value.value_u16);
405 output["normalMax"] = unsigned(pdr->normal_max.value_u16);
406 output["normalMin"] = unsigned(pdr->normal_min.value_u16);
407 output["ratedMax"] = unsigned(pdr->rated_max.value_u16);
408 output["ratedMin"] = unsigned(pdr->rated_min.value_u16);
George Liu62d12ec2020-02-05 16:27:08 +0800409 break;
410 case PLDM_RANGE_FIELD_FORMAT_SINT16:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500411 output["nominalValue"] = unsigned(pdr->nominal_value.value_s16);
412 output["normalMax"] = unsigned(pdr->normal_max.value_s16);
413 output["normalMin"] = unsigned(pdr->normal_min.value_s16);
414 output["ratedMax"] = unsigned(pdr->rated_max.value_s16);
415 output["ratedMin"] = unsigned(pdr->rated_min.value_s16);
George Liu62d12ec2020-02-05 16:27:08 +0800416 break;
417 case PLDM_RANGE_FIELD_FORMAT_UINT32:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500418 output["nominalValue"] = unsigned(pdr->nominal_value.value_u32);
419 output["normalMax"] = unsigned(pdr->normal_max.value_u32);
420 output["normalMin"] = unsigned(pdr->normal_min.value_u32);
421 output["ratedMax"] = unsigned(pdr->rated_max.value_u32);
422 output["ratedMin"] = unsigned(pdr->rated_min.value_u32);
George Liu62d12ec2020-02-05 16:27:08 +0800423 break;
424 case PLDM_RANGE_FIELD_FORMAT_SINT32:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500425 output["nominalValue"] = unsigned(pdr->nominal_value.value_s32);
426 output["normalMax"] = unsigned(pdr->normal_max.value_s32);
427 output["normalMin"] = unsigned(pdr->normal_min.value_s32);
428 output["ratedMax"] = unsigned(pdr->rated_max.value_s32);
429 output["ratedMin"] = unsigned(pdr->rated_min.value_s32);
George Liu62d12ec2020-02-05 16:27:08 +0800430 break;
431 case PLDM_RANGE_FIELD_FORMAT_REAL32:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500432 output["nominalValue"] = unsigned(pdr->nominal_value.value_f32);
433 output["normalMax"] = unsigned(pdr->normal_max.value_f32);
434 output["normalMin"] = unsigned(pdr->normal_min.value_f32);
435 output["ratedMax"] = unsigned(pdr->rated_max.value_f32);
436 output["ratedMin"] = unsigned(pdr->rated_min.value_f32);
George Liu62d12ec2020-02-05 16:27:08 +0800437 break;
438 default:
439 break;
440 }
441 }
442
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500443 void printStateEffecterPDR(const uint8_t* data, ordered_json& output)
George Liu62d12ec2020-02-05 16:27:08 +0800444 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530445 auto pdr = reinterpret_cast<const pldm_state_effecter_pdr*>(data);
George Liu62d12ec2020-02-05 16:27:08 +0800446
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500447 output["PLDMTerminusHandle"] = pdr->terminus_handle;
448 output["effecterID"] = pdr->effecter_id;
449 output["entityType"] = getEntityName(pdr->entity_type);
450 output["entityInstanceNumber"] = pdr->entity_instance;
451 output["containerID"] = pdr->container_id;
452 output["effecterSemanticID"] = pdr->effecter_semantic_id;
453 output["effecterInit"] = effecterInit[pdr->effecter_init];
454 output["effecterDescriptionPDR"] =
455 (pdr->has_description_pdr ? true : false);
456 output["compositeEffecterCount"] =
457 unsigned(pdr->composite_effecter_count);
George Liud6649362019-11-27 19:06:51 +0800458
Tom Joseph97a7a762020-07-06 10:37:18 +0530459 auto statesPtr = pdr->possible_states;
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600460 auto compEffCount = pdr->composite_effecter_count;
Tom Joseph97a7a762020-07-06 10:37:18 +0530461
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600462 while (compEffCount--)
George Liud6649362019-11-27 19:06:51 +0800463 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530464 auto state =
465 reinterpret_cast<const state_effecter_possible_states*>(
466 statesPtr);
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600467 output.emplace(("stateSetID[" + std::to_string(compEffCount) + "]"),
468 getStateSetName(state->state_set_id));
469 output.emplace(
470 ("possibleStatesSize[" + std::to_string(compEffCount) + "]"),
471 state->possible_states_size);
472 output.emplace(
473 ("possibleStates[" + std::to_string(compEffCount) + "]"),
474 printPossibleStates(state->possible_states_size,
475 state->states));
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500476
Sridevi Ramesh148ccab2020-11-23 08:23:09 -0600477 if (compEffCount)
Tom Joseph97a7a762020-07-06 10:37:18 +0530478 {
479 statesPtr += sizeof(state_effecter_possible_states) +
480 state->possible_states_size - 1;
481 }
George Liud6649362019-11-27 19:06:51 +0800482 }
483 }
484
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500485 void printTerminusLocatorPDR(const uint8_t* data, ordered_json& output)
Sampa Misra12afe112020-05-25 11:40:44 -0500486 {
487 const std::array<std::string_view, 4> terminusLocatorType = {
488 "UID", "MCTP_EID", "SMBusRelative", "systemSoftware"};
489
490 auto pdr = reinterpret_cast<const pldm_terminus_locator_pdr*>(data);
491
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500492 output["PLDMTerminusHandle"] = pdr->terminus_handle;
493 output["validity"] = (pdr->validity ? "valid" : "notValid");
494 output["TID"] = unsigned(pdr->tid);
495 output["containerID"] = pdr->container_id;
496 output["terminusLocatorType"] =
497 terminusLocatorType[pdr->terminus_locator_type];
498 output["terminusLocatorValueSize"] =
499 unsigned(pdr->terminus_locator_value_size);
Sampa Misra12afe112020-05-25 11:40:44 -0500500
501 if (pdr->terminus_locator_type == PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
502 {
503 auto locatorValue =
504 reinterpret_cast<const pldm_terminus_locator_type_mctp_eid*>(
505 pdr->terminus_locator_value);
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500506 output["EID"] = unsigned(locatorValue->eid);
Sampa Misra12afe112020-05-25 11:40:44 -0500507 }
508 }
509
George Liud6649362019-11-27 19:06:51 +0800510 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt,
George Liu62d12ec2020-02-05 16:27:08 +0800511 uint8_t* data)
George Liud6649362019-11-27 19:06:51 +0800512 {
George Liu62d12ec2020-02-05 16:27:08 +0800513 if (data == NULL)
George Liud6649362019-11-27 19:06:51 +0800514 {
515 return;
516 }
517
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500518 ordered_json output;
519 output["nextRecordHandle"] = nextRecordHndl;
520 output["responseCount"] = respCnt;
George Liud6649362019-11-27 19:06:51 +0800521
522 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500523 printCommonPDRHeader(pdr, output);
524
George Liud6649362019-11-27 19:06:51 +0800525 switch (pdr->type)
526 {
Sampa Misra12afe112020-05-25 11:40:44 -0500527 case PLDM_TERMINUS_LOCATOR_PDR:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500528 printTerminusLocatorPDR(data, output);
Sampa Misra12afe112020-05-25 11:40:44 -0500529 break;
Tom Josepha65c0412020-07-03 21:14:44 +0530530 case PLDM_STATE_SENSOR_PDR:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500531 printStateSensorPDR(data, output);
Tom Josepha65c0412020-07-03 21:14:44 +0530532 break;
George Liu62d12ec2020-02-05 16:27:08 +0800533 case PLDM_NUMERIC_EFFECTER_PDR:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500534 printNumericEffecterPDR(data, output);
George Liu62d12ec2020-02-05 16:27:08 +0800535 break;
George Liud6649362019-11-27 19:06:51 +0800536 case PLDM_STATE_EFFECTER_PDR:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500537 printStateEffecterPDR(data, output);
George Liud6649362019-11-27 19:06:51 +0800538 break;
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500539 case PLDM_PDR_ENTITY_ASSOCIATION:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500540 printPDREntityAssociation(data, output);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500541 break;
542 case PLDM_PDR_FRU_RECORD_SET:
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500543 printPDRFruRecordSet(data, output);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500544 break;
George Liud6649362019-11-27 19:06:51 +0800545 default:
546 break;
547 }
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500548 pldmtool::helper::DisplayInJson(output);
George Liud6649362019-11-27 19:06:51 +0800549 }
550
551 private:
552 uint32_t recordHandle;
553};
554
555class SetStateEffecter : public CommandInterface
556{
557 public:
558 ~SetStateEffecter() = default;
559 SetStateEffecter() = delete;
560 SetStateEffecter(const SetStateEffecter&) = delete;
561 SetStateEffecter(SetStateEffecter&&) = default;
562 SetStateEffecter& operator=(const SetStateEffecter&) = delete;
563 SetStateEffecter& operator=(SetStateEffecter&&) = default;
564
George Liuba4c1fb2020-02-05 14:13:30 +0800565 // compositeEffecterCount(value: 0x01 to 0x08) * stateField(2)
566 static constexpr auto maxEffecterDataSize = 16;
567
568 // compositeEffecterCount(value: 0x01 to 0x08)
569 static constexpr auto minEffecterCount = 1;
570 static constexpr auto maxEffecterCount = 8;
George Liud6649362019-11-27 19:06:51 +0800571 explicit SetStateEffecter(const char* type, const char* name,
572 CLI::App* app) :
573 CommandInterface(type, name, app)
574 {
575 app->add_option(
George Liuba4c1fb2020-02-05 14:13:30 +0800576 "-i, --id", effecterId,
577 "A handle that is used to identify and access the effecter")
578 ->required();
579 app->add_option("-c, --count", effecterCount,
580 "The number of individual sets of effecter information")
581 ->required();
582 app->add_option(
George Liud6649362019-11-27 19:06:51 +0800583 "-d,--data", effecterData,
George Liuba4c1fb2020-02-05 14:13:30 +0800584 "Set effecter state data\n"
585 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...")
586 ->required();
George Liud6649362019-11-27 19:06:51 +0800587 }
588
589 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
590 {
591 std::vector<uint8_t> requestMsg(
592 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES);
593 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
594
George Liuba4c1fb2020-02-05 14:13:30 +0800595 if (effecterCount > maxEffecterCount ||
596 effecterCount < minEffecterCount)
George Liud6649362019-11-27 19:06:51 +0800597 {
George Liuba4c1fb2020-02-05 14:13:30 +0800598 std::cerr << "Request Message Error: effecterCount size "
599 << effecterCount << "is invalid\n";
George Liud6649362019-11-27 19:06:51 +0800600 auto rc = PLDM_ERROR_INVALID_DATA;
601 return {rc, requestMsg};
602 }
603
George Liuba4c1fb2020-02-05 14:13:30 +0800604 if (effecterData.size() > maxEffecterDataSize)
George Liud6649362019-11-27 19:06:51 +0800605 {
George Liuba4c1fb2020-02-05 14:13:30 +0800606 std::cerr << "Request Message Error: effecterData size "
607 << effecterData.size() << "is invalid\n";
608 auto rc = PLDM_ERROR_INVALID_DATA;
609 return {rc, requestMsg};
610 }
611
612 auto stateField = parseEffecterData(effecterData, effecterCount);
613 if (!stateField)
614 {
615 std::cerr << "Failed to parse effecter data, effecterCount size "
616 << effecterCount << "\n";
George Liud6649362019-11-27 19:06:51 +0800617 auto rc = PLDM_ERROR_INVALID_DATA;
618 return {rc, requestMsg};
619 }
620
621 auto rc = encode_set_state_effecter_states_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600622 instanceId, effecterId, effecterCount, stateField->data(), request);
George Liud6649362019-11-27 19:06:51 +0800623 return {rc, requestMsg};
624 }
625
626 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
627 {
628 uint8_t completionCode = 0;
629 auto rc = decode_set_state_effecter_states_resp(
630 responsePtr, payloadLength, &completionCode);
631
632 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
633 {
634 std::cerr << "Response Message Error: "
George Liuba4c1fb2020-02-05 14:13:30 +0800635 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
George Liud6649362019-11-27 19:06:51 +0800636 return;
637 }
638
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500639 ordered_json data;
640 data["Response"] = "SUCCESS";
641 pldmtool::helper::DisplayInJson(data);
George Liud6649362019-11-27 19:06:51 +0800642 }
643
644 private:
George Liuba4c1fb2020-02-05 14:13:30 +0800645 uint16_t effecterId;
646 uint8_t effecterCount;
George Liud6649362019-11-27 19:06:51 +0800647 std::vector<uint8_t> effecterData;
648};
649
George Liucc9c20d2020-02-05 10:24:11 +0800650class SetNumericEffecterValue : public CommandInterface
651{
652 public:
653 ~SetNumericEffecterValue() = default;
654 SetNumericEffecterValue() = delete;
655 SetNumericEffecterValue(const SetNumericEffecterValue&) = delete;
656 SetNumericEffecterValue(SetNumericEffecterValue&&) = default;
657 SetNumericEffecterValue& operator=(const SetNumericEffecterValue&) = delete;
658 SetNumericEffecterValue& operator=(SetNumericEffecterValue&&) = default;
659
660 explicit SetNumericEffecterValue(const char* type, const char* name,
661 CLI::App* app) :
662 CommandInterface(type, name, app)
663 {
664 app->add_option(
665 "-i, --id", effecterId,
666 "A handle that is used to identify and access the effecter")
667 ->required();
668 app->add_option("-s, --size", effecterDataSize,
669 "The bit width and format of the setting value for the "
670 "effecter. enum value: {uint8, sint8, uint16, sint16, "
671 "uint32, sint32}\n")
672 ->required();
673 app->add_option("-d,--data", maxEffecterValue,
674 "The setting value of numeric effecter being "
675 "requested\n")
676 ->required();
677 }
678
679 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
680 {
681 std::vector<uint8_t> requestMsg(
682 sizeof(pldm_msg_hdr) +
683 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3);
684
685 uint8_t* effecterValue = (uint8_t*)&maxEffecterValue;
686
687 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
688 size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES;
689
690 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
691 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
692 {
693 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1;
694 }
695 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
696 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
697 {
698 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3;
699 }
700 auto rc = encode_set_numeric_effecter_value_req(
701 0, effecterId, effecterDataSize, effecterValue, request,
702 payload_length);
703
704 return {rc, requestMsg};
705 }
706
707 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
708 {
709 uint8_t completionCode = 0;
710 auto rc = decode_set_numeric_effecter_value_resp(
711 responsePtr, payloadLength, &completionCode);
712
713 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
714 {
715 std::cerr << "Response Message Error: "
716 << "rc=" << rc << ",cc=" << (int)completionCode
717 << std::endl;
718 return;
719 }
720
Sridevi Ramesh27c512a2020-08-12 03:29:42 -0500721 ordered_json data;
722 data["Response"] = "SUCCESS";
723 pldmtool::helper::DisplayInJson(data);
George Liucc9c20d2020-02-05 10:24:11 +0800724 }
725
726 private:
727 uint16_t effecterId;
728 uint8_t effecterDataSize;
729 uint64_t maxEffecterValue;
730};
731
George Liud6649362019-11-27 19:06:51 +0800732void registerCommand(CLI::App& app)
733{
734 auto platform = app.add_subcommand("platform", "platform type command");
735 platform->require_subcommand(1);
736
737 auto getPDR =
738 platform->add_subcommand("GetPDR", "get platform descriptor records");
739 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR));
740
741 auto setStateEffecterStates = platform->add_subcommand(
742 "SetStateEffecterStates", "set effecter states");
743 commands.push_back(std::make_unique<SetStateEffecter>(
744 "platform", "setStateEffecterStates", setStateEffecterStates));
George Liucc9c20d2020-02-05 10:24:11 +0800745
746 auto setNumericEffecterValue = platform->add_subcommand(
747 "SetNumericEffecterValue", "set the value for a PLDM Numeric Effecter");
748 commands.push_back(std::make_unique<SetNumericEffecterValue>(
749 "platform", "setNumericEffecterValue", setNumericEffecterValue));
George Liud6649362019-11-27 19:06:51 +0800750}
751
752} // namespace platform
753} // namespace pldmtool