blob: d54ec202e1a220a89d23b2bedaef42d59b594c0e [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
21class GetPDR : public CommandInterface
22{
23 public:
24 ~GetPDR() = default;
25 GetPDR() = delete;
26 GetPDR(const GetPDR&) = delete;
27 GetPDR(GetPDR&&) = default;
28 GetPDR& operator=(const GetPDR&) = delete;
29 GetPDR& operator=(GetPDR&&) = default;
30
31 using CommandInterface::CommandInterface;
32
George Liud6649362019-11-27 19:06:51 +080033 explicit GetPDR(const char* type, const char* name, CLI::App* app) :
34 CommandInterface(type, name, app)
35 {
36 app->add_option(
37 "-d,--data", recordHandle,
38 "retrieve individual PDRs from a PDR Repository\n"
39 "eg: The recordHandle value for the PDR to be retrieved and 0 "
40 "means get first PDR in the repository.")
41 ->required();
42 }
43
44 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
45 {
46 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
47 PLDM_GET_PDR_REQ_BYTES);
48 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
49
Deepak Kodihallia59cdc62020-07-14 05:11:33 -050050 auto rc =
51 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
52 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
George Liud6649362019-11-27 19:06:51 +080053 return {rc, requestMsg};
54 }
55
56 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
57 {
58 uint8_t completionCode = 0;
Deepak Kodihallia59cdc62020-07-14 05:11:33 -050059 uint8_t recordData[UINT16_MAX] = {0};
George Liud6649362019-11-27 19:06:51 +080060 uint32_t nextRecordHndl = 0;
61 uint32_t nextDataTransferHndl = 0;
62 uint8_t transferFlag = 0;
63 uint16_t respCnt = 0;
64 uint8_t transferCRC = 0;
65
66 auto rc = decode_get_pdr_resp(
67 responsePtr, payloadLength, &completionCode, &nextRecordHndl,
68 &nextDataTransferHndl, &transferFlag, &respCnt, recordData,
69 sizeof(recordData), &transferCRC);
70
71 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
72 {
73 std::cerr << "Response Message Error: "
74 << "rc=" << rc << ",cc=" << (int)completionCode
75 << std::endl;
76 return;
77 }
78
George Liu62d12ec2020-02-05 16:27:08 +080079 printPDRMsg(nextRecordHndl, respCnt, recordData);
George Liud6649362019-11-27 19:06:51 +080080 }
81
82 private:
Tom Josepha65c0412020-07-03 21:14:44 +053083 const std::map<pldm::pdr::EntityType, std::string> entityType = {
84 {PLDM_ENTITY_COMM_CHANNEL, "Communication Channel"},
85 {PLDM_ENTITY_SYS_FIRMWARE, "System Firmware"},
86 {PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER, "Virtual Machine Manager"},
87 {PLDM_ENTITY_SYSTEM_CHASSIS, "System chassis (main enclosure)"},
88 {PLDM_ENTITY_SYS_BOARD, "System Board"},
89 {PLDM_ENTITY_MEMORY_MODULE, "Memory Module"},
90 {PLDM_ENTITY_PROC_MODULE, "Processor Module"},
91 {PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD,
92 "Chassis front panel board (control panel)"},
93 {PLDM_ENTITY_POWER_CONVERTER, "Power converter"},
94 {PLDM_ENTITY_PROC, "Processor"},
95 {PLDM_ENTITY_MGMT_CONTROLLER, "Management Controller"},
96 {PLDM_ENTITY_CONNECTOR, "Connector"},
Deepak Kodihallie05dcc22020-07-14 05:13:58 -050097 {PLDM_ENTITY_POWER_SUPPLY, "Power Supply"},
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -050098 {11521, "System (logical)"},
99 };
100
Tom Josepha65c0412020-07-03 21:14:44 +0530101 const std::map<uint16_t, std::string> stateSet = {
102 {PLDM_STATE_SET_HEALTH_STATE, "Health State"},
103 {PLDM_STATE_SET_AVAILABILITY, "Availability"},
104 {PLDM_STATE_SET_OPERATIONAL_STATUS, "Operational Status"},
105 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
106 "Operational Running Status"},
107 {PLDM_STATE_SET_PRESENCE, "Presence"},
108 {PLDM_STATE_SET_CONFIGURATION_STATE, "Configuration State"},
109 {PLDM_STATE_SET_LINK_STATE, "Link State"},
110 {PLDM_STATE_SET_SW_TERMINATION_STATUS, "Software Termination Status"},
111 {PLDM_STATE_SET_BOOT_RESTART_CAUSE, "Boot/Restart Cause"},
112 {PLDM_STATE_SET_BOOT_PROGRESS, "Boot Progress"},
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500113 {PLDM_STATE_SET_SYSTEM_POWER_STATE, "System Power State"},
Tom Josepha65c0412020-07-03 21:14:44 +0530114 };
115
116 const std::array<std::string_view, 4> sensorInit = {
117 "noInit", "useInitPDR", "enableSensor", "disableSensor"};
118
Tom Joseph97a7a762020-07-06 10:37:18 +0530119 const std::array<std::string_view, 4> effecterInit = {
120 "noInit", "useInitPDR", "enableEffecter", "disableEffecter"};
121
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500122 const std::map<uint8_t, std::string> pdrType = {
123 {PLDM_TERMINUS_LOCATOR_PDR, "Terminus Locator PDR"},
124 {PLDM_NUMERIC_SENSOR_PDR, "Numeric Sensor PDR"},
125 {PLDM_NUMERIC_SENSOR_INITIALIZATION_PDR,
126 "Numeric Sensor Initialization PDR"},
127 {PLDM_STATE_SENSOR_PDR, "State Sensor PDR"},
128 {PLDM_STATE_SENSOR_INITIALIZATION_PDR,
129 "State Sensor Initialization PDR"},
130 {PLDM_SENSOR_AUXILIARY_NAMES_PDR, "Sensor Auxiliary Names PDR"},
131 {PLDM_OEM_UNIT_PDR, "OEM Unit PDR"},
132 {PLDM_OEM_STATE_SET_PDR, "OEM State Set PDR"},
133 {PLDM_NUMERIC_EFFECTER_PDR, "Numeric Effecter PDR"},
134 {PLDM_NUMERIC_EFFECTER_INITIALIZATION_PDR,
135 "Numeric Effecter Initialization PDR"},
136 {PLDM_STATE_EFFECTER_PDR, "State Effecter PDR"},
137 {PLDM_STATE_EFFECTER_INITIALIZATION_PDR,
138 "State Effecter Initialization PDR"},
139 {PLDM_EFFECTER_AUXILIARY_NAMES_PDR, "Effecter Auxiliary Names PDR"},
140 {PLDM_EFFECTER_OEM_SEMANTIC_PDR, "Effecter OEM Semantic PDR"},
141 {PLDM_PDR_ENTITY_ASSOCIATION, "Entity Association PDR"},
142 {PLDM_ENTITY_AUXILIARY_NAMES_PDR, "Entity Auxiliary Names PDR"},
143 {PLDM_OEM_ENTITY_ID_PDR, "OEM Entity ID PDR"},
144 {PLDM_INTERRUPT_ASSOCIATION_PDR, "Interrupt Association PDR"},
145 {PLDM_EVENT_LOG_PDR, "PLDM Event Log PDR"},
146 {PLDM_PDR_FRU_RECORD_SET, "FRU Record Set PDR"},
147 {PLDM_OEM_DEVICE_PDR, "OEM Device PDR"},
148 {PLDM_OEM_PDR, "OEM PDR"},
149 };
150
Tom Josepha65c0412020-07-03 21:14:44 +0530151 std::string getEntityName(pldm::pdr::EntityType type)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500152 {
153 try
154 {
155 return entityType.at(type);
156 }
157 catch (const std::out_of_range& e)
158 {
159 return std::to_string(static_cast<unsigned>(type)) + "(OEM)";
160 }
161 }
162
Tom Josepha65c0412020-07-03 21:14:44 +0530163 std::string getStateSetName(uint16_t id)
164 {
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500165 auto typeString = std::to_string(id);
Tom Josepha65c0412020-07-03 21:14:44 +0530166 try
167 {
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500168 return stateSet.at(id) + "(" + typeString + ")";
Tom Josepha65c0412020-07-03 21:14:44 +0530169 }
170 catch (const std::out_of_range& e)
171 {
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500172 return typeString;
173 }
174 }
175
176 std::string getPDRType(uint8_t type)
177 {
178 auto typeString = std::to_string(type);
179 try
180 {
181 return pdrType.at(type) + "(" + typeString + ")";
182 }
183 catch (const std::out_of_range& e)
184 {
185 return typeString;
Tom Josepha65c0412020-07-03 21:14:44 +0530186 }
187 }
188
Tom Joseph952abfa2020-07-03 12:25:15 +0530189 void printCommonPDRHeader(const pldm_pdr_hdr* hdr)
190 {
191 std::cout << "recordHandle: " << hdr->record_handle << std::endl;
192 std::cout << "PDRHeaderVersion: " << unsigned(hdr->version)
193 << std::endl;
Sridevi Ramesha1bfb782020-07-14 02:51:23 -0500194 std::cout << "PDRType: " << getPDRType(hdr->type) << std::endl;
Tom Joseph952abfa2020-07-03 12:25:15 +0530195 std::cout << "recordChangeNumber: " << hdr->record_change_num
196 << std::endl;
197 std::cout << "dataLength: " << hdr->length << std::endl << std::endl;
198 }
199
Tom Josepha65c0412020-07-03 21:14:44 +0530200 void printPossibleStates(uint8_t possibleStatesSize,
201 const bitfield8_t* states)
202 {
203 uint8_t possibleStatesPos{};
204 auto printStates = [&possibleStatesPos](const bitfield8_t& val) {
205 for (int i = 0; i < CHAR_BIT; i++)
206 {
207 if (val.byte & (1 << i))
208 {
209 std::cout << " " << (possibleStatesPos * CHAR_BIT + i);
210 }
211 }
212 possibleStatesPos++;
213 };
214 std::for_each(states, states + possibleStatesSize, printStates);
215 }
216
217 void printStateSensorPDR(const uint8_t* data)
218 {
219 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(data);
220
221 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
222 << std::endl;
223 std::cout << "sensorID: " << pdr->sensor_id << std::endl;
224 std::cout << "entityType: " << getEntityName(pdr->entity_type)
225 << std::endl;
226 std::cout << "entityInstanceNumber: " << pdr->entity_instance
227 << std::endl;
228 std::cout << "containerID: " << pdr->container_id << std::endl;
229 std::cout << "sensorInit: " << sensorInit[pdr->sensor_init]
230 << std::endl;
231 std::cout << "sensorAuxiliaryNamesPDR: "
232 << (pdr->sensor_auxiliary_names_pdr ? "true" : "false")
233 << std::endl;
234 std::cout << "compositeSensorCount: "
235 << unsigned(pdr->composite_sensor_count) << std::endl;
236
237 auto statesPtr = pdr->possible_states;
238 auto compositeSensorCount = pdr->composite_sensor_count;
239
240 while (compositeSensorCount--)
241 {
242 auto state = reinterpret_cast<const state_sensor_possible_states*>(
243 statesPtr);
244 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
245 << std::endl;
246 std::cout << "possibleStatesSize: "
247 << unsigned(state->possible_states_size) << std::endl;
248 std::cout << "possibleStates:";
249 printPossibleStates(state->possible_states_size, state->states);
250 std::cout << std::endl;
251
252 if (compositeSensorCount)
253 {
254 statesPtr += sizeof(state_sensor_possible_states) +
255 state->possible_states_size - 1;
256 }
257 }
258 }
259
George Liu62d12ec2020-02-05 16:27:08 +0800260 void printPDRFruRecordSet(uint8_t* data)
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
271 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
272 << std::endl;
273 std::cout << "FRURecordSetIdentifier: " << pdr->fru_rsi << std::endl;
274 std::cout << "entityType: " << getEntityName(pdr->entity_type)
275 << std::endl;
276 std::cout << "entityInstanceNumber: " << pdr->entity_instance_num
277 << std::endl;
278 std::cout << "containerID: " << pdr->container_id << std::endl;
279 }
280
George Liu62d12ec2020-02-05 16:27:08 +0800281 void printPDREntityAssociation(uint8_t* data)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500282 {
283 const std::map<uint8_t, const char*> assocationType = {
284 {PLDM_ENTITY_ASSOCIAION_PHYSICAL, "Physical"},
285 {PLDM_ENTITY_ASSOCIAION_LOGICAL, "Logical"},
286 };
287
George Liu62d12ec2020-02-05 16:27:08 +0800288 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500289 {
290 return;
291 }
292
293 data += sizeof(pldm_pdr_hdr);
294 pldm_pdr_entity_association* pdr =
295 reinterpret_cast<pldm_pdr_entity_association*>(data);
296
297 std::cout << "containerID: " << pdr->container_id << std::endl;
298 std::cout << "associationType: "
299 << assocationType.at(pdr->association_type) << std::endl
300 << std::endl;
301
302 std::cout << "containerEntityType: "
303 << getEntityName(pdr->container.entity_type) << std::endl;
304 std::cout << "containerEntityInstanceNumber: "
305 << pdr->container.entity_instance_num << std::endl;
306 std::cout << "containerEntityContainerID: "
307 << pdr->container.entity_container_id << std::endl;
308
309 std::cout << "containedEntityCount: "
310 << static_cast<unsigned>(pdr->num_children) << std::endl
311 << std::endl;
312
313 auto child = reinterpret_cast<pldm_entity*>(&pdr->children[0]);
314 for (int i = 0; i < pdr->num_children; ++i)
315 {
316 std::cout << "containedEntityType[" << i + 1
317 << "]: " << getEntityName(child->entity_type)
318 << std::endl;
319 std::cout << "containedEntityInstanceNumber[" << i + 1
320 << "]: " << child->entity_instance_num << std::endl;
321 std::cout << "containedEntityContainerID[" << i + 1
322 << "]: " << child->entity_container_id << std::endl
323 << std::endl;
324 ++child;
325 }
326 }
327
George Liu62d12ec2020-02-05 16:27:08 +0800328 void printNumericEffecterPDR(uint8_t* data)
329 {
330 struct pldm_numeric_effecter_value_pdr* pdr =
331 (struct pldm_numeric_effecter_value_pdr*)data;
George Liu62d12ec2020-02-05 16:27:08 +0800332 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
333 << std::endl;
334 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
335 std::cout << "entityType: " << pdr->entity_type << std::endl;
336 std::cout << "entityInstanceNumber: " << pdr->entity_instance
337 << std::endl;
338 std::cout << "containerID: " << pdr->container_id << std::endl;
339 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
340 << std::endl;
341 std::cout << "effecterInit: " << unsigned(pdr->effecter_init)
342 << std::endl;
343 std::cout << "effecterAuxiliaryNames: "
344 << (unsigned(pdr->effecter_auxiliary_names) ? "true"
345 : "false")
346 << std::endl;
347 std::cout << "baseUnit: " << unsigned(pdr->base_unit) << std::endl;
348 std::cout << "unitModifier: " << unsigned(pdr->unit_modifier)
349 << std::endl;
350 std::cout << "rateUnit: " << unsigned(pdr->rate_unit) << std::endl;
351 std::cout << "baseOEMUnitHandle: "
352 << unsigned(pdr->base_oem_unit_handle) << std::endl;
353 std::cout << "auxUnit: " << unsigned(pdr->aux_unit) << std::endl;
354 std::cout << "auxUnitModifier: " << unsigned(pdr->aux_unit_modifier)
355 << std::endl;
356 std::cout << "auxrateUnit: " << unsigned(pdr->aux_rate_unit)
357 << std::endl;
358 std::cout << "auxOEMUnitHandle: " << unsigned(pdr->aux_oem_unit_handle)
359 << std::endl;
360 std::cout << "isLinear: "
361 << (unsigned(pdr->is_linear) ? "true" : "false") << std::endl;
362 std::cout << "effecterDataSize: " << unsigned(pdr->effecter_data_size)
363 << std::endl;
364 std::cout << "resolution: " << pdr->resolution << std::endl;
365 std::cout << "offset: " << pdr->offset << std::endl;
366 std::cout << "accuracy: " << pdr->accuracy << std::endl;
367 std::cout << "plusTolerance: " << unsigned(pdr->plus_tolerance)
368 << std::endl;
369 std::cout << "minusTolerance: " << unsigned(pdr->minus_tolerance)
370 << std::endl;
371 std::cout << "stateTransitionInterval: "
372 << pdr->state_transition_interval << std::endl;
373 std::cout << "TransitionInterval: " << pdr->transition_interval
374 << std::endl;
375 switch (pdr->effecter_data_size)
376 {
377 case PLDM_EFFECTER_DATA_SIZE_UINT8:
378 std::cout << "maxSettable: "
379 << unsigned(pdr->max_set_table.value_u8) << std::endl;
380 std::cout << "minSettable: "
381 << unsigned(pdr->min_set_table.value_u8) << std::endl;
382 break;
383 case PLDM_EFFECTER_DATA_SIZE_SINT8:
384 std::cout << "maxSettable: "
385 << unsigned(pdr->max_set_table.value_s8) << std::endl;
386 std::cout << "minSettable: "
387 << unsigned(pdr->min_set_table.value_s8) << std::endl;
388 break;
389 case PLDM_EFFECTER_DATA_SIZE_UINT16:
390 std::cout << "maxSettable: " << pdr->max_set_table.value_u16
391 << std::endl;
392 std::cout << "minSettable: " << pdr->min_set_table.value_u16
393 << std::endl;
394 break;
395 case PLDM_EFFECTER_DATA_SIZE_SINT16:
396 std::cout << "maxSettable: " << pdr->max_set_table.value_s16
397 << std::endl;
398 std::cout << "minSettable: " << pdr->min_set_table.value_s16
399 << std::endl;
400 break;
401 case PLDM_EFFECTER_DATA_SIZE_UINT32:
402 std::cout << "maxSettable: " << pdr->max_set_table.value_u32
403 << std::endl;
404 std::cout << "minSettable: " << pdr->min_set_table.value_u32
405 << std::endl;
406 break;
407 case PLDM_EFFECTER_DATA_SIZE_SINT32:
408 std::cout << "maxSettable: " << pdr->max_set_table.value_s32
409 << std::endl;
410 std::cout << "minSettable: " << pdr->min_set_table.value_s32
411 << std::endl;
412 break;
413 default:
414 break;
415 }
416 std::cout << "rangeFieldFormat: " << unsigned(pdr->range_field_format)
417 << std::endl;
418 std::cout << "rangeFieldSupport: "
419 << unsigned(pdr->range_field_support.byte) << std::endl;
420 switch (pdr->range_field_format)
421 {
422 case PLDM_RANGE_FIELD_FORMAT_UINT8:
423 std::cout << "nominalValue: "
424 << unsigned(pdr->nominal_value.value_u8) << std::endl;
425 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_u8)
426 << std::endl;
427 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_u8)
428 << std::endl;
429 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_u8)
430 << std::endl;
431 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_u8)
432 << std::endl;
433 break;
434 case PLDM_RANGE_FIELD_FORMAT_SINT8:
435 std::cout << "nominalValue: "
436 << unsigned(pdr->nominal_value.value_s8) << std::endl;
437 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_s8)
438 << std::endl;
439 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_s8)
440 << std::endl;
441 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_s8)
442 << std::endl;
443 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_s8)
444 << std::endl;
445 break;
446 case PLDM_RANGE_FIELD_FORMAT_UINT16:
447 std::cout << "nominalValue: " << pdr->nominal_value.value_u16
448 << std::endl;
449 std::cout << "normalMax: " << pdr->normal_max.value_u16
450 << std::endl;
451 std::cout << "normalMin: " << pdr->normal_min.value_u16
452 << std::endl;
453 std::cout << "ratedMax: " << pdr->rated_max.value_u16
454 << std::endl;
455 std::cout << "ratedMin: " << pdr->rated_min.value_u16
456 << std::endl;
457 break;
458 case PLDM_RANGE_FIELD_FORMAT_SINT16:
459 std::cout << "nominalValue: " << pdr->nominal_value.value_s16
460 << std::endl;
461 std::cout << "normalMax: " << pdr->normal_max.value_s16
462 << std::endl;
463 std::cout << "normalMin: " << pdr->normal_min.value_s16
464 << std::endl;
465 std::cout << "ratedMax: " << pdr->rated_max.value_s16
466 << std::endl;
467 std::cout << "ratedMin: " << pdr->rated_min.value_s16
468 << std::endl;
469 break;
470 case PLDM_RANGE_FIELD_FORMAT_UINT32:
471 std::cout << "nominalValue: " << pdr->nominal_value.value_u32
472 << std::endl;
473 std::cout << "normalMax: " << pdr->normal_max.value_u32
474 << std::endl;
475 std::cout << "normalMin: " << pdr->normal_min.value_u32
476 << std::endl;
477 std::cout << "ratedMax: " << pdr->rated_max.value_u32
478 << std::endl;
479 std::cout << "ratedMin: " << pdr->rated_min.value_u32
480 << std::endl;
481 break;
482 case PLDM_RANGE_FIELD_FORMAT_SINT32:
483 std::cout << "nominalValue: " << pdr->nominal_value.value_s32
484 << std::endl;
485 std::cout << "normalMax: " << pdr->normal_max.value_s32
486 << std::endl;
487 std::cout << "normalMin: " << pdr->normal_min.value_s32
488 << std::endl;
489 std::cout << "ratedMax: " << pdr->rated_max.value_s32
490 << std::endl;
491 std::cout << "ratedMin: " << pdr->rated_min.value_s32
492 << std::endl;
493 break;
494 case PLDM_RANGE_FIELD_FORMAT_REAL32:
495 std::cout << "nominalValue: " << pdr->nominal_value.value_f32
496 << std::endl;
497 std::cout << "normalMax: " << pdr->normal_max.value_f32
498 << std::endl;
499 std::cout << "normalMin: " << pdr->normal_min.value_f32
500 << std::endl;
501 std::cout << "ratedMax: " << pdr->rated_max.value_f32
502 << std::endl;
503 std::cout << "ratedMin: " << pdr->rated_min.value_f32
504 << std::endl;
505 break;
506 default:
507 break;
508 }
509 }
510
Tom Joseph97a7a762020-07-06 10:37:18 +0530511 void printStateEffecterPDR(const uint8_t* data)
George Liu62d12ec2020-02-05 16:27:08 +0800512 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530513 auto pdr = reinterpret_cast<const pldm_state_effecter_pdr*>(data);
George Liu62d12ec2020-02-05 16:27:08 +0800514
George Liud6649362019-11-27 19:06:51 +0800515 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
516 << std::endl;
517 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530518 std::cout << "entityType: " << getEntityName(pdr->entity_type)
519 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800520 std::cout << "entityInstanceNumber: " << pdr->entity_instance
521 << std::endl;
522 std::cout << "containerID: " << pdr->container_id << std::endl;
523 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
524 << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530525 std::cout << "effecterInit: " << effecterInit[pdr->effecter_init]
George Liud6649362019-11-27 19:06:51 +0800526 << std::endl;
527 std::cout << "effecterDescriptionPDR: "
Tom Joseph97a7a762020-07-06 10:37:18 +0530528 << (pdr->has_description_pdr ? "true" : "false") << std::endl;
George Liud6649362019-11-27 19:06:51 +0800529 std::cout << "compositeEffecterCount: "
530 << unsigned(pdr->composite_effecter_count) << std::endl;
531
Tom Joseph97a7a762020-07-06 10:37:18 +0530532 auto statesPtr = pdr->possible_states;
533 auto compositeEffecterCount = pdr->composite_effecter_count;
534
535 while (compositeEffecterCount--)
George Liud6649362019-11-27 19:06:51 +0800536 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530537 auto state =
538 reinterpret_cast<const state_effecter_possible_states*>(
539 statesPtr);
540 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
541 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800542 std::cout << "possibleStatesSize: "
543 << unsigned(state->possible_states_size) << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530544 std::cout << "possibleStates:";
545 printPossibleStates(state->possible_states_size, state->states);
546 std::cout << std::endl;
547
548 if (compositeEffecterCount)
549 {
550 statesPtr += sizeof(state_effecter_possible_states) +
551 state->possible_states_size - 1;
552 }
George Liud6649362019-11-27 19:06:51 +0800553 }
554 }
555
Sampa Misra12afe112020-05-25 11:40:44 -0500556 void printTerminusLocatorPDR(const uint8_t* data)
557 {
558 const std::array<std::string_view, 4> terminusLocatorType = {
559 "UID", "MCTP_EID", "SMBusRelative", "systemSoftware"};
560
561 auto pdr = reinterpret_cast<const pldm_terminus_locator_pdr*>(data);
562
563 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
564 << std::endl;
565 std::cout << "validity: " << (pdr->validity ? "valid" : "notValid")
566 << std::endl;
567 std::cout << "TID: " << unsigned(pdr->tid) << std::endl;
568 std::cout << "containerID: " << pdr->container_id << std::endl;
569 std::cout << "terminusLocatorType: "
570 << terminusLocatorType[pdr->terminus_locator_type]
571 << std::endl;
572 std::cout << "terminusLocatorValueSize: "
573 << unsigned(pdr->terminus_locator_value_size) << std::endl;
574
575 if (pdr->terminus_locator_type == PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID)
576 {
577 auto locatorValue =
578 reinterpret_cast<const pldm_terminus_locator_type_mctp_eid*>(
579 pdr->terminus_locator_value);
580 std::cout << "EID: " << unsigned(locatorValue->eid) << std::endl;
581 }
582 }
583
George Liud6649362019-11-27 19:06:51 +0800584 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt,
George Liu62d12ec2020-02-05 16:27:08 +0800585 uint8_t* data)
George Liud6649362019-11-27 19:06:51 +0800586 {
George Liu62d12ec2020-02-05 16:27:08 +0800587 if (data == NULL)
George Liud6649362019-11-27 19:06:51 +0800588 {
589 return;
590 }
591
George Liud6649362019-11-27 19:06:51 +0800592 std::cout << "nextRecordHandle: " << nextRecordHndl << std::endl;
593 std::cout << "responseCount: " << respCnt << std::endl;
594
595 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
Tom Joseph952abfa2020-07-03 12:25:15 +0530596 printCommonPDRHeader(pdr);
George Liud6649362019-11-27 19:06:51 +0800597 switch (pdr->type)
598 {
Sampa Misra12afe112020-05-25 11:40:44 -0500599 case PLDM_TERMINUS_LOCATOR_PDR:
600 printTerminusLocatorPDR(data);
601 break;
Tom Josepha65c0412020-07-03 21:14:44 +0530602 case PLDM_STATE_SENSOR_PDR:
603 printStateSensorPDR(data);
604 break;
George Liu62d12ec2020-02-05 16:27:08 +0800605 case PLDM_NUMERIC_EFFECTER_PDR:
606 printNumericEffecterPDR(data);
607 break;
George Liud6649362019-11-27 19:06:51 +0800608 case PLDM_STATE_EFFECTER_PDR:
George Liu62d12ec2020-02-05 16:27:08 +0800609 printStateEffecterPDR(data);
George Liud6649362019-11-27 19:06:51 +0800610 break;
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500611 case PLDM_PDR_ENTITY_ASSOCIATION:
George Liu62d12ec2020-02-05 16:27:08 +0800612 printPDREntityAssociation(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500613 break;
614 case PLDM_PDR_FRU_RECORD_SET:
George Liu62d12ec2020-02-05 16:27:08 +0800615 printPDRFruRecordSet(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500616 break;
George Liud6649362019-11-27 19:06:51 +0800617 default:
618 break;
619 }
620 }
621
622 private:
623 uint32_t recordHandle;
624};
625
626class SetStateEffecter : public CommandInterface
627{
628 public:
629 ~SetStateEffecter() = default;
630 SetStateEffecter() = delete;
631 SetStateEffecter(const SetStateEffecter&) = delete;
632 SetStateEffecter(SetStateEffecter&&) = default;
633 SetStateEffecter& operator=(const SetStateEffecter&) = delete;
634 SetStateEffecter& operator=(SetStateEffecter&&) = default;
635
George Liuba4c1fb2020-02-05 14:13:30 +0800636 // compositeEffecterCount(value: 0x01 to 0x08) * stateField(2)
637 static constexpr auto maxEffecterDataSize = 16;
638
639 // compositeEffecterCount(value: 0x01 to 0x08)
640 static constexpr auto minEffecterCount = 1;
641 static constexpr auto maxEffecterCount = 8;
George Liud6649362019-11-27 19:06:51 +0800642 explicit SetStateEffecter(const char* type, const char* name,
643 CLI::App* app) :
644 CommandInterface(type, name, app)
645 {
646 app->add_option(
George Liuba4c1fb2020-02-05 14:13:30 +0800647 "-i, --id", effecterId,
648 "A handle that is used to identify and access the effecter")
649 ->required();
650 app->add_option("-c, --count", effecterCount,
651 "The number of individual sets of effecter information")
652 ->required();
653 app->add_option(
George Liud6649362019-11-27 19:06:51 +0800654 "-d,--data", effecterData,
George Liuba4c1fb2020-02-05 14:13:30 +0800655 "Set effecter state data\n"
656 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...")
657 ->required();
George Liud6649362019-11-27 19:06:51 +0800658 }
659
660 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
661 {
662 std::vector<uint8_t> requestMsg(
663 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES);
664 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
665
George Liuba4c1fb2020-02-05 14:13:30 +0800666 if (effecterCount > maxEffecterCount ||
667 effecterCount < minEffecterCount)
George Liud6649362019-11-27 19:06:51 +0800668 {
George Liuba4c1fb2020-02-05 14:13:30 +0800669 std::cerr << "Request Message Error: effecterCount size "
670 << effecterCount << "is invalid\n";
George Liud6649362019-11-27 19:06:51 +0800671 auto rc = PLDM_ERROR_INVALID_DATA;
672 return {rc, requestMsg};
673 }
674
George Liuba4c1fb2020-02-05 14:13:30 +0800675 if (effecterData.size() > maxEffecterDataSize)
George Liud6649362019-11-27 19:06:51 +0800676 {
George Liuba4c1fb2020-02-05 14:13:30 +0800677 std::cerr << "Request Message Error: effecterData size "
678 << effecterData.size() << "is invalid\n";
679 auto rc = PLDM_ERROR_INVALID_DATA;
680 return {rc, requestMsg};
681 }
682
683 auto stateField = parseEffecterData(effecterData, effecterCount);
684 if (!stateField)
685 {
686 std::cerr << "Failed to parse effecter data, effecterCount size "
687 << effecterCount << "\n";
George Liud6649362019-11-27 19:06:51 +0800688 auto rc = PLDM_ERROR_INVALID_DATA;
689 return {rc, requestMsg};
690 }
691
692 auto rc = encode_set_state_effecter_states_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600693 instanceId, effecterId, effecterCount, stateField->data(), request);
George Liud6649362019-11-27 19:06:51 +0800694 return {rc, requestMsg};
695 }
696
697 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
698 {
699 uint8_t completionCode = 0;
700 auto rc = decode_set_state_effecter_states_resp(
701 responsePtr, payloadLength, &completionCode);
702
703 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
704 {
705 std::cerr << "Response Message Error: "
George Liuba4c1fb2020-02-05 14:13:30 +0800706 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
George Liud6649362019-11-27 19:06:51 +0800707 return;
708 }
709
710 std::cout << "SetStateEffecterStates: SUCCESS" << std::endl;
711 }
712
713 private:
George Liuba4c1fb2020-02-05 14:13:30 +0800714 uint16_t effecterId;
715 uint8_t effecterCount;
George Liud6649362019-11-27 19:06:51 +0800716 std::vector<uint8_t> effecterData;
717};
718
George Liucc9c20d2020-02-05 10:24:11 +0800719class SetNumericEffecterValue : public CommandInterface
720{
721 public:
722 ~SetNumericEffecterValue() = default;
723 SetNumericEffecterValue() = delete;
724 SetNumericEffecterValue(const SetNumericEffecterValue&) = delete;
725 SetNumericEffecterValue(SetNumericEffecterValue&&) = default;
726 SetNumericEffecterValue& operator=(const SetNumericEffecterValue&) = delete;
727 SetNumericEffecterValue& operator=(SetNumericEffecterValue&&) = default;
728
729 explicit SetNumericEffecterValue(const char* type, const char* name,
730 CLI::App* app) :
731 CommandInterface(type, name, app)
732 {
733 app->add_option(
734 "-i, --id", effecterId,
735 "A handle that is used to identify and access the effecter")
736 ->required();
737 app->add_option("-s, --size", effecterDataSize,
738 "The bit width and format of the setting value for the "
739 "effecter. enum value: {uint8, sint8, uint16, sint16, "
740 "uint32, sint32}\n")
741 ->required();
742 app->add_option("-d,--data", maxEffecterValue,
743 "The setting value of numeric effecter being "
744 "requested\n")
745 ->required();
746 }
747
748 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
749 {
750 std::vector<uint8_t> requestMsg(
751 sizeof(pldm_msg_hdr) +
752 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3);
753
754 uint8_t* effecterValue = (uint8_t*)&maxEffecterValue;
755
756 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
757 size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES;
758
759 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
760 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
761 {
762 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1;
763 }
764 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
765 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
766 {
767 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3;
768 }
769 auto rc = encode_set_numeric_effecter_value_req(
770 0, effecterId, effecterDataSize, effecterValue, request,
771 payload_length);
772
773 return {rc, requestMsg};
774 }
775
776 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
777 {
778 uint8_t completionCode = 0;
779 auto rc = decode_set_numeric_effecter_value_resp(
780 responsePtr, payloadLength, &completionCode);
781
782 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
783 {
784 std::cerr << "Response Message Error: "
785 << "rc=" << rc << ",cc=" << (int)completionCode
786 << std::endl;
787 return;
788 }
789
790 std::cout << "SetNumericEffecterValue: SUCCESS" << std::endl;
791 }
792
793 private:
794 uint16_t effecterId;
795 uint8_t effecterDataSize;
796 uint64_t maxEffecterValue;
797};
798
George Liud6649362019-11-27 19:06:51 +0800799void registerCommand(CLI::App& app)
800{
801 auto platform = app.add_subcommand("platform", "platform type command");
802 platform->require_subcommand(1);
803
804 auto getPDR =
805 platform->add_subcommand("GetPDR", "get platform descriptor records");
806 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR));
807
808 auto setStateEffecterStates = platform->add_subcommand(
809 "SetStateEffecterStates", "set effecter states");
810 commands.push_back(std::make_unique<SetStateEffecter>(
811 "platform", "setStateEffecterStates", setStateEffecterStates));
George Liucc9c20d2020-02-05 10:24:11 +0800812
813 auto setNumericEffecterValue = platform->add_subcommand(
814 "SetNumericEffecterValue", "set the value for a PLDM Numeric Effecter");
815 commands.push_back(std::make_unique<SetNumericEffecterValue>(
816 "platform", "setNumericEffecterValue", setNumericEffecterValue));
George Liud6649362019-11-27 19:06:51 +0800817}
818
819} // namespace platform
820} // namespace pldmtool