blob: fc3827ab6f0836706ac6bf2057f2054fcd3e67e6 [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
33 // The maximum number of record bytes requested to be returned in the
34 // response to this instance of the GetPDR command.
35 static constexpr uint16_t requestCount = 128;
36
37 explicit GetPDR(const char* type, const char* name, CLI::App* app) :
38 CommandInterface(type, name, app)
39 {
40 app->add_option(
41 "-d,--data", recordHandle,
42 "retrieve individual PDRs from a PDR Repository\n"
43 "eg: The recordHandle value for the PDR to be retrieved and 0 "
44 "means get first PDR in the repository.")
45 ->required();
46 }
47
48 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
49 {
50 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
51 PLDM_GET_PDR_REQ_BYTES);
52 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
53
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060054 auto rc = encode_get_pdr_req(instanceId, recordHandle, 0,
George Liud6649362019-11-27 19:06:51 +080055 PLDM_GET_FIRSTPART, requestCount, 0,
56 request, PLDM_GET_PDR_REQ_BYTES);
57 return {rc, requestMsg};
58 }
59
60 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
61 {
62 uint8_t completionCode = 0;
George Liu62d12ec2020-02-05 16:27:08 +080063 uint8_t recordData[65535] = {0};
George Liud6649362019-11-27 19:06:51 +080064 uint32_t nextRecordHndl = 0;
65 uint32_t nextDataTransferHndl = 0;
66 uint8_t transferFlag = 0;
67 uint16_t respCnt = 0;
68 uint8_t transferCRC = 0;
69
70 auto rc = decode_get_pdr_resp(
71 responsePtr, payloadLength, &completionCode, &nextRecordHndl,
72 &nextDataTransferHndl, &transferFlag, &respCnt, recordData,
73 sizeof(recordData), &transferCRC);
74
75 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
76 {
77 std::cerr << "Response Message Error: "
78 << "rc=" << rc << ",cc=" << (int)completionCode
79 << std::endl;
80 return;
81 }
82
George Liu62d12ec2020-02-05 16:27:08 +080083 printPDRMsg(nextRecordHndl, respCnt, recordData);
George Liud6649362019-11-27 19:06:51 +080084 }
85
86 private:
Tom Josepha65c0412020-07-03 21:14:44 +053087 const std::map<pldm::pdr::EntityType, std::string> entityType = {
88 {PLDM_ENTITY_COMM_CHANNEL, "Communication Channel"},
89 {PLDM_ENTITY_SYS_FIRMWARE, "System Firmware"},
90 {PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER, "Virtual Machine Manager"},
91 {PLDM_ENTITY_SYSTEM_CHASSIS, "System chassis (main enclosure)"},
92 {PLDM_ENTITY_SYS_BOARD, "System Board"},
93 {PLDM_ENTITY_MEMORY_MODULE, "Memory Module"},
94 {PLDM_ENTITY_PROC_MODULE, "Processor Module"},
95 {PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD,
96 "Chassis front panel board (control panel)"},
97 {PLDM_ENTITY_POWER_CONVERTER, "Power converter"},
98 {PLDM_ENTITY_PROC, "Processor"},
99 {PLDM_ENTITY_MGMT_CONTROLLER, "Management Controller"},
100 {PLDM_ENTITY_CONNECTOR, "Connector"},
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500101 {11521, "System (logical)"},
102 };
103
Tom Josepha65c0412020-07-03 21:14:44 +0530104 const std::map<uint16_t, std::string> stateSet = {
105 {PLDM_STATE_SET_HEALTH_STATE, "Health State"},
106 {PLDM_STATE_SET_AVAILABILITY, "Availability"},
107 {PLDM_STATE_SET_OPERATIONAL_STATUS, "Operational Status"},
108 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
109 "Operational Running Status"},
110 {PLDM_STATE_SET_PRESENCE, "Presence"},
111 {PLDM_STATE_SET_CONFIGURATION_STATE, "Configuration State"},
112 {PLDM_STATE_SET_LINK_STATE, "Link State"},
113 {PLDM_STATE_SET_SW_TERMINATION_STATUS, "Software Termination Status"},
114 {PLDM_STATE_SET_BOOT_RESTART_CAUSE, "Boot/Restart Cause"},
115 {PLDM_STATE_SET_BOOT_PROGRESS, "Boot Progress"},
116 };
117
118 const std::array<std::string_view, 4> sensorInit = {
119 "noInit", "useInitPDR", "enableSensor", "disableSensor"};
120
121 std::string getEntityName(pldm::pdr::EntityType type)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500122 {
123 try
124 {
125 return entityType.at(type);
126 }
127 catch (const std::out_of_range& e)
128 {
129 return std::to_string(static_cast<unsigned>(type)) + "(OEM)";
130 }
131 }
132
Tom Josepha65c0412020-07-03 21:14:44 +0530133 std::string getStateSetName(uint16_t id)
134 {
135 try
136 {
137 return stateSet.at(id);
138 }
139 catch (const std::out_of_range& e)
140 {
141 return std::to_string(id);
142 }
143 }
144
Tom Joseph952abfa2020-07-03 12:25:15 +0530145 void printCommonPDRHeader(const pldm_pdr_hdr* hdr)
146 {
147 std::cout << "recordHandle: " << hdr->record_handle << std::endl;
148 std::cout << "PDRHeaderVersion: " << unsigned(hdr->version)
149 << std::endl;
150 std::cout << "PDRType: " << unsigned(hdr->type) << std::endl;
151 std::cout << "recordChangeNumber: " << hdr->record_change_num
152 << std::endl;
153 std::cout << "dataLength: " << hdr->length << std::endl << std::endl;
154 }
155
Tom Josepha65c0412020-07-03 21:14:44 +0530156 void printPossibleStates(uint8_t possibleStatesSize,
157 const bitfield8_t* states)
158 {
159 uint8_t possibleStatesPos{};
160 auto printStates = [&possibleStatesPos](const bitfield8_t& val) {
161 for (int i = 0; i < CHAR_BIT; i++)
162 {
163 if (val.byte & (1 << i))
164 {
165 std::cout << " " << (possibleStatesPos * CHAR_BIT + i);
166 }
167 }
168 possibleStatesPos++;
169 };
170 std::for_each(states, states + possibleStatesSize, printStates);
171 }
172
173 void printStateSensorPDR(const uint8_t* data)
174 {
175 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(data);
176
177 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
178 << std::endl;
179 std::cout << "sensorID: " << pdr->sensor_id << std::endl;
180 std::cout << "entityType: " << getEntityName(pdr->entity_type)
181 << std::endl;
182 std::cout << "entityInstanceNumber: " << pdr->entity_instance
183 << std::endl;
184 std::cout << "containerID: " << pdr->container_id << std::endl;
185 std::cout << "sensorInit: " << sensorInit[pdr->sensor_init]
186 << std::endl;
187 std::cout << "sensorAuxiliaryNamesPDR: "
188 << (pdr->sensor_auxiliary_names_pdr ? "true" : "false")
189 << std::endl;
190 std::cout << "compositeSensorCount: "
191 << unsigned(pdr->composite_sensor_count) << std::endl;
192
193 auto statesPtr = pdr->possible_states;
194 auto compositeSensorCount = pdr->composite_sensor_count;
195
196 while (compositeSensorCount--)
197 {
198 auto state = reinterpret_cast<const state_sensor_possible_states*>(
199 statesPtr);
200 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
201 << std::endl;
202 std::cout << "possibleStatesSize: "
203 << unsigned(state->possible_states_size) << std::endl;
204 std::cout << "possibleStates:";
205 printPossibleStates(state->possible_states_size, state->states);
206 std::cout << std::endl;
207
208 if (compositeSensorCount)
209 {
210 statesPtr += sizeof(state_sensor_possible_states) +
211 state->possible_states_size - 1;
212 }
213 }
214 }
215
George Liu62d12ec2020-02-05 16:27:08 +0800216 void printPDRFruRecordSet(uint8_t* data)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500217 {
George Liu62d12ec2020-02-05 16:27:08 +0800218 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500219 {
220 return;
221 }
222
223 data += sizeof(pldm_pdr_hdr);
224 pldm_pdr_fru_record_set* pdr =
225 reinterpret_cast<pldm_pdr_fru_record_set*>(data);
226
227 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
228 << std::endl;
229 std::cout << "FRURecordSetIdentifier: " << pdr->fru_rsi << std::endl;
230 std::cout << "entityType: " << getEntityName(pdr->entity_type)
231 << std::endl;
232 std::cout << "entityInstanceNumber: " << pdr->entity_instance_num
233 << std::endl;
234 std::cout << "containerID: " << pdr->container_id << std::endl;
235 }
236
George Liu62d12ec2020-02-05 16:27:08 +0800237 void printPDREntityAssociation(uint8_t* data)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500238 {
239 const std::map<uint8_t, const char*> assocationType = {
240 {PLDM_ENTITY_ASSOCIAION_PHYSICAL, "Physical"},
241 {PLDM_ENTITY_ASSOCIAION_LOGICAL, "Logical"},
242 };
243
George Liu62d12ec2020-02-05 16:27:08 +0800244 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500245 {
246 return;
247 }
248
249 data += sizeof(pldm_pdr_hdr);
250 pldm_pdr_entity_association* pdr =
251 reinterpret_cast<pldm_pdr_entity_association*>(data);
252
253 std::cout << "containerID: " << pdr->container_id << std::endl;
254 std::cout << "associationType: "
255 << assocationType.at(pdr->association_type) << std::endl
256 << std::endl;
257
258 std::cout << "containerEntityType: "
259 << getEntityName(pdr->container.entity_type) << std::endl;
260 std::cout << "containerEntityInstanceNumber: "
261 << pdr->container.entity_instance_num << std::endl;
262 std::cout << "containerEntityContainerID: "
263 << pdr->container.entity_container_id << std::endl;
264
265 std::cout << "containedEntityCount: "
266 << static_cast<unsigned>(pdr->num_children) << std::endl
267 << std::endl;
268
269 auto child = reinterpret_cast<pldm_entity*>(&pdr->children[0]);
270 for (int i = 0; i < pdr->num_children; ++i)
271 {
272 std::cout << "containedEntityType[" << i + 1
273 << "]: " << getEntityName(child->entity_type)
274 << std::endl;
275 std::cout << "containedEntityInstanceNumber[" << i + 1
276 << "]: " << child->entity_instance_num << std::endl;
277 std::cout << "containedEntityContainerID[" << i + 1
278 << "]: " << child->entity_container_id << std::endl
279 << std::endl;
280 ++child;
281 }
282 }
283
George Liu62d12ec2020-02-05 16:27:08 +0800284 void printNumericEffecterPDR(uint8_t* data)
285 {
286 struct pldm_numeric_effecter_value_pdr* pdr =
287 (struct pldm_numeric_effecter_value_pdr*)data;
George Liu62d12ec2020-02-05 16:27:08 +0800288 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
289 << std::endl;
290 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
291 std::cout << "entityType: " << pdr->entity_type << std::endl;
292 std::cout << "entityInstanceNumber: " << pdr->entity_instance
293 << std::endl;
294 std::cout << "containerID: " << pdr->container_id << std::endl;
295 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
296 << std::endl;
297 std::cout << "effecterInit: " << unsigned(pdr->effecter_init)
298 << std::endl;
299 std::cout << "effecterAuxiliaryNames: "
300 << (unsigned(pdr->effecter_auxiliary_names) ? "true"
301 : "false")
302 << std::endl;
303 std::cout << "baseUnit: " << unsigned(pdr->base_unit) << std::endl;
304 std::cout << "unitModifier: " << unsigned(pdr->unit_modifier)
305 << std::endl;
306 std::cout << "rateUnit: " << unsigned(pdr->rate_unit) << std::endl;
307 std::cout << "baseOEMUnitHandle: "
308 << unsigned(pdr->base_oem_unit_handle) << std::endl;
309 std::cout << "auxUnit: " << unsigned(pdr->aux_unit) << std::endl;
310 std::cout << "auxUnitModifier: " << unsigned(pdr->aux_unit_modifier)
311 << std::endl;
312 std::cout << "auxrateUnit: " << unsigned(pdr->aux_rate_unit)
313 << std::endl;
314 std::cout << "auxOEMUnitHandle: " << unsigned(pdr->aux_oem_unit_handle)
315 << std::endl;
316 std::cout << "isLinear: "
317 << (unsigned(pdr->is_linear) ? "true" : "false") << std::endl;
318 std::cout << "effecterDataSize: " << unsigned(pdr->effecter_data_size)
319 << std::endl;
320 std::cout << "resolution: " << pdr->resolution << std::endl;
321 std::cout << "offset: " << pdr->offset << std::endl;
322 std::cout << "accuracy: " << pdr->accuracy << std::endl;
323 std::cout << "plusTolerance: " << unsigned(pdr->plus_tolerance)
324 << std::endl;
325 std::cout << "minusTolerance: " << unsigned(pdr->minus_tolerance)
326 << std::endl;
327 std::cout << "stateTransitionInterval: "
328 << pdr->state_transition_interval << std::endl;
329 std::cout << "TransitionInterval: " << pdr->transition_interval
330 << std::endl;
331 switch (pdr->effecter_data_size)
332 {
333 case PLDM_EFFECTER_DATA_SIZE_UINT8:
334 std::cout << "maxSettable: "
335 << unsigned(pdr->max_set_table.value_u8) << std::endl;
336 std::cout << "minSettable: "
337 << unsigned(pdr->min_set_table.value_u8) << std::endl;
338 break;
339 case PLDM_EFFECTER_DATA_SIZE_SINT8:
340 std::cout << "maxSettable: "
341 << unsigned(pdr->max_set_table.value_s8) << std::endl;
342 std::cout << "minSettable: "
343 << unsigned(pdr->min_set_table.value_s8) << std::endl;
344 break;
345 case PLDM_EFFECTER_DATA_SIZE_UINT16:
346 std::cout << "maxSettable: " << pdr->max_set_table.value_u16
347 << std::endl;
348 std::cout << "minSettable: " << pdr->min_set_table.value_u16
349 << std::endl;
350 break;
351 case PLDM_EFFECTER_DATA_SIZE_SINT16:
352 std::cout << "maxSettable: " << pdr->max_set_table.value_s16
353 << std::endl;
354 std::cout << "minSettable: " << pdr->min_set_table.value_s16
355 << std::endl;
356 break;
357 case PLDM_EFFECTER_DATA_SIZE_UINT32:
358 std::cout << "maxSettable: " << pdr->max_set_table.value_u32
359 << std::endl;
360 std::cout << "minSettable: " << pdr->min_set_table.value_u32
361 << std::endl;
362 break;
363 case PLDM_EFFECTER_DATA_SIZE_SINT32:
364 std::cout << "maxSettable: " << pdr->max_set_table.value_s32
365 << std::endl;
366 std::cout << "minSettable: " << pdr->min_set_table.value_s32
367 << std::endl;
368 break;
369 default:
370 break;
371 }
372 std::cout << "rangeFieldFormat: " << unsigned(pdr->range_field_format)
373 << std::endl;
374 std::cout << "rangeFieldSupport: "
375 << unsigned(pdr->range_field_support.byte) << std::endl;
376 switch (pdr->range_field_format)
377 {
378 case PLDM_RANGE_FIELD_FORMAT_UINT8:
379 std::cout << "nominalValue: "
380 << unsigned(pdr->nominal_value.value_u8) << std::endl;
381 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_u8)
382 << std::endl;
383 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_u8)
384 << std::endl;
385 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_u8)
386 << std::endl;
387 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_u8)
388 << std::endl;
389 break;
390 case PLDM_RANGE_FIELD_FORMAT_SINT8:
391 std::cout << "nominalValue: "
392 << unsigned(pdr->nominal_value.value_s8) << std::endl;
393 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_s8)
394 << std::endl;
395 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_s8)
396 << std::endl;
397 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_s8)
398 << std::endl;
399 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_s8)
400 << std::endl;
401 break;
402 case PLDM_RANGE_FIELD_FORMAT_UINT16:
403 std::cout << "nominalValue: " << pdr->nominal_value.value_u16
404 << std::endl;
405 std::cout << "normalMax: " << pdr->normal_max.value_u16
406 << std::endl;
407 std::cout << "normalMin: " << pdr->normal_min.value_u16
408 << std::endl;
409 std::cout << "ratedMax: " << pdr->rated_max.value_u16
410 << std::endl;
411 std::cout << "ratedMin: " << pdr->rated_min.value_u16
412 << std::endl;
413 break;
414 case PLDM_RANGE_FIELD_FORMAT_SINT16:
415 std::cout << "nominalValue: " << pdr->nominal_value.value_s16
416 << std::endl;
417 std::cout << "normalMax: " << pdr->normal_max.value_s16
418 << std::endl;
419 std::cout << "normalMin: " << pdr->normal_min.value_s16
420 << std::endl;
421 std::cout << "ratedMax: " << pdr->rated_max.value_s16
422 << std::endl;
423 std::cout << "ratedMin: " << pdr->rated_min.value_s16
424 << std::endl;
425 break;
426 case PLDM_RANGE_FIELD_FORMAT_UINT32:
427 std::cout << "nominalValue: " << pdr->nominal_value.value_u32
428 << std::endl;
429 std::cout << "normalMax: " << pdr->normal_max.value_u32
430 << std::endl;
431 std::cout << "normalMin: " << pdr->normal_min.value_u32
432 << std::endl;
433 std::cout << "ratedMax: " << pdr->rated_max.value_u32
434 << std::endl;
435 std::cout << "ratedMin: " << pdr->rated_min.value_u32
436 << std::endl;
437 break;
438 case PLDM_RANGE_FIELD_FORMAT_SINT32:
439 std::cout << "nominalValue: " << pdr->nominal_value.value_s32
440 << std::endl;
441 std::cout << "normalMax: " << pdr->normal_max.value_s32
442 << std::endl;
443 std::cout << "normalMin: " << pdr->normal_min.value_s32
444 << std::endl;
445 std::cout << "ratedMax: " << pdr->rated_max.value_s32
446 << std::endl;
447 std::cout << "ratedMin: " << pdr->rated_min.value_s32
448 << std::endl;
449 break;
450 case PLDM_RANGE_FIELD_FORMAT_REAL32:
451 std::cout << "nominalValue: " << pdr->nominal_value.value_f32
452 << std::endl;
453 std::cout << "normalMax: " << pdr->normal_max.value_f32
454 << std::endl;
455 std::cout << "normalMin: " << pdr->normal_min.value_f32
456 << std::endl;
457 std::cout << "ratedMax: " << pdr->rated_max.value_f32
458 << std::endl;
459 std::cout << "ratedMin: " << pdr->rated_min.value_f32
460 << std::endl;
461 break;
462 default:
463 break;
464 }
465 }
466
467 void printStateEffecterPDR(uint8_t* data)
468 {
469 if (data == NULL)
George Liud6649362019-11-27 19:06:51 +0800470 {
471 return;
472 }
473
474 struct pldm_state_effecter_pdr* pdr =
475 (struct pldm_state_effecter_pdr*)data;
George Liu62d12ec2020-02-05 16:27:08 +0800476
George Liud6649362019-11-27 19:06:51 +0800477 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
478 << std::endl;
479 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
480 std::cout << "entityType: " << pdr->entity_type << std::endl;
481 std::cout << "entityInstanceNumber: " << pdr->entity_instance
482 << std::endl;
483 std::cout << "containerID: " << pdr->container_id << std::endl;
484 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
485 << std::endl;
486 std::cout << "effecterInit: " << unsigned(pdr->effecter_init)
487 << std::endl;
488 std::cout << "effecterDescriptionPDR: "
489 << (unsigned(pdr->has_description_pdr) ? "true" : "false")
490 << std::endl;
491 std::cout << "compositeEffecterCount: "
492 << unsigned(pdr->composite_effecter_count) << std::endl;
493
494 for (size_t i = 0; i < pdr->composite_effecter_count; ++i)
495 {
496 struct state_effecter_possible_states* state =
497 (struct state_effecter_possible_states*)pdr->possible_states +
498 i * sizeof(state_effecter_possible_states);
499 std::cout << "stateSetID: " << state->state_set_id << std::endl;
500 std::cout << "possibleStatesSize: "
501 << unsigned(state->possible_states_size) << std::endl;
502 bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(state->states);
503 std::cout << "possibleStates: " << unsigned(bf->byte) << std::endl;
504 }
505 }
506
507 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt,
George Liu62d12ec2020-02-05 16:27:08 +0800508 uint8_t* data)
George Liud6649362019-11-27 19:06:51 +0800509 {
George Liu62d12ec2020-02-05 16:27:08 +0800510 if (data == NULL)
George Liud6649362019-11-27 19:06:51 +0800511 {
512 return;
513 }
514
George Liud6649362019-11-27 19:06:51 +0800515 std::cout << "nextRecordHandle: " << nextRecordHndl << std::endl;
516 std::cout << "responseCount: " << respCnt << std::endl;
517
518 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
Tom Joseph952abfa2020-07-03 12:25:15 +0530519 printCommonPDRHeader(pdr);
George Liud6649362019-11-27 19:06:51 +0800520 switch (pdr->type)
521 {
Tom Josepha65c0412020-07-03 21:14:44 +0530522 case PLDM_STATE_SENSOR_PDR:
523 printStateSensorPDR(data);
524 break;
George Liu62d12ec2020-02-05 16:27:08 +0800525 case PLDM_NUMERIC_EFFECTER_PDR:
526 printNumericEffecterPDR(data);
527 break;
George Liud6649362019-11-27 19:06:51 +0800528 case PLDM_STATE_EFFECTER_PDR:
George Liu62d12ec2020-02-05 16:27:08 +0800529 printStateEffecterPDR(data);
George Liud6649362019-11-27 19:06:51 +0800530 break;
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500531 case PLDM_PDR_ENTITY_ASSOCIATION:
George Liu62d12ec2020-02-05 16:27:08 +0800532 printPDREntityAssociation(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500533 break;
534 case PLDM_PDR_FRU_RECORD_SET:
George Liu62d12ec2020-02-05 16:27:08 +0800535 printPDRFruRecordSet(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500536 break;
George Liud6649362019-11-27 19:06:51 +0800537 default:
538 break;
539 }
540 }
541
542 private:
543 uint32_t recordHandle;
544};
545
546class SetStateEffecter : public CommandInterface
547{
548 public:
549 ~SetStateEffecter() = default;
550 SetStateEffecter() = delete;
551 SetStateEffecter(const SetStateEffecter&) = delete;
552 SetStateEffecter(SetStateEffecter&&) = default;
553 SetStateEffecter& operator=(const SetStateEffecter&) = delete;
554 SetStateEffecter& operator=(SetStateEffecter&&) = default;
555
George Liuba4c1fb2020-02-05 14:13:30 +0800556 // compositeEffecterCount(value: 0x01 to 0x08) * stateField(2)
557 static constexpr auto maxEffecterDataSize = 16;
558
559 // compositeEffecterCount(value: 0x01 to 0x08)
560 static constexpr auto minEffecterCount = 1;
561 static constexpr auto maxEffecterCount = 8;
George Liud6649362019-11-27 19:06:51 +0800562 explicit SetStateEffecter(const char* type, const char* name,
563 CLI::App* app) :
564 CommandInterface(type, name, app)
565 {
566 app->add_option(
George Liuba4c1fb2020-02-05 14:13:30 +0800567 "-i, --id", effecterId,
568 "A handle that is used to identify and access the effecter")
569 ->required();
570 app->add_option("-c, --count", effecterCount,
571 "The number of individual sets of effecter information")
572 ->required();
573 app->add_option(
George Liud6649362019-11-27 19:06:51 +0800574 "-d,--data", effecterData,
George Liuba4c1fb2020-02-05 14:13:30 +0800575 "Set effecter state data\n"
576 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...")
577 ->required();
George Liud6649362019-11-27 19:06:51 +0800578 }
579
580 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
581 {
582 std::vector<uint8_t> requestMsg(
583 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES);
584 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
585
George Liuba4c1fb2020-02-05 14:13:30 +0800586 if (effecterCount > maxEffecterCount ||
587 effecterCount < minEffecterCount)
George Liud6649362019-11-27 19:06:51 +0800588 {
George Liuba4c1fb2020-02-05 14:13:30 +0800589 std::cerr << "Request Message Error: effecterCount size "
590 << effecterCount << "is invalid\n";
George Liud6649362019-11-27 19:06:51 +0800591 auto rc = PLDM_ERROR_INVALID_DATA;
592 return {rc, requestMsg};
593 }
594
George Liuba4c1fb2020-02-05 14:13:30 +0800595 if (effecterData.size() > maxEffecterDataSize)
George Liud6649362019-11-27 19:06:51 +0800596 {
George Liuba4c1fb2020-02-05 14:13:30 +0800597 std::cerr << "Request Message Error: effecterData size "
598 << effecterData.size() << "is invalid\n";
599 auto rc = PLDM_ERROR_INVALID_DATA;
600 return {rc, requestMsg};
601 }
602
603 auto stateField = parseEffecterData(effecterData, effecterCount);
604 if (!stateField)
605 {
606 std::cerr << "Failed to parse effecter data, effecterCount size "
607 << effecterCount << "\n";
George Liud6649362019-11-27 19:06:51 +0800608 auto rc = PLDM_ERROR_INVALID_DATA;
609 return {rc, requestMsg};
610 }
611
612 auto rc = encode_set_state_effecter_states_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600613 instanceId, effecterId, effecterCount, stateField->data(), request);
George Liud6649362019-11-27 19:06:51 +0800614 return {rc, requestMsg};
615 }
616
617 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
618 {
619 uint8_t completionCode = 0;
620 auto rc = decode_set_state_effecter_states_resp(
621 responsePtr, payloadLength, &completionCode);
622
623 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
624 {
625 std::cerr << "Response Message Error: "
George Liuba4c1fb2020-02-05 14:13:30 +0800626 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
George Liud6649362019-11-27 19:06:51 +0800627 return;
628 }
629
630 std::cout << "SetStateEffecterStates: SUCCESS" << std::endl;
631 }
632
633 private:
George Liuba4c1fb2020-02-05 14:13:30 +0800634 uint16_t effecterId;
635 uint8_t effecterCount;
George Liud6649362019-11-27 19:06:51 +0800636 std::vector<uint8_t> effecterData;
637};
638
George Liucc9c20d2020-02-05 10:24:11 +0800639class SetNumericEffecterValue : public CommandInterface
640{
641 public:
642 ~SetNumericEffecterValue() = default;
643 SetNumericEffecterValue() = delete;
644 SetNumericEffecterValue(const SetNumericEffecterValue&) = delete;
645 SetNumericEffecterValue(SetNumericEffecterValue&&) = default;
646 SetNumericEffecterValue& operator=(const SetNumericEffecterValue&) = delete;
647 SetNumericEffecterValue& operator=(SetNumericEffecterValue&&) = default;
648
649 explicit SetNumericEffecterValue(const char* type, const char* name,
650 CLI::App* app) :
651 CommandInterface(type, name, app)
652 {
653 app->add_option(
654 "-i, --id", effecterId,
655 "A handle that is used to identify and access the effecter")
656 ->required();
657 app->add_option("-s, --size", effecterDataSize,
658 "The bit width and format of the setting value for the "
659 "effecter. enum value: {uint8, sint8, uint16, sint16, "
660 "uint32, sint32}\n")
661 ->required();
662 app->add_option("-d,--data", maxEffecterValue,
663 "The setting value of numeric effecter being "
664 "requested\n")
665 ->required();
666 }
667
668 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
669 {
670 std::vector<uint8_t> requestMsg(
671 sizeof(pldm_msg_hdr) +
672 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3);
673
674 uint8_t* effecterValue = (uint8_t*)&maxEffecterValue;
675
676 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
677 size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES;
678
679 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
680 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
681 {
682 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1;
683 }
684 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
685 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
686 {
687 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3;
688 }
689 auto rc = encode_set_numeric_effecter_value_req(
690 0, effecterId, effecterDataSize, effecterValue, request,
691 payload_length);
692
693 return {rc, requestMsg};
694 }
695
696 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
697 {
698 uint8_t completionCode = 0;
699 auto rc = decode_set_numeric_effecter_value_resp(
700 responsePtr, payloadLength, &completionCode);
701
702 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
703 {
704 std::cerr << "Response Message Error: "
705 << "rc=" << rc << ",cc=" << (int)completionCode
706 << std::endl;
707 return;
708 }
709
710 std::cout << "SetNumericEffecterValue: SUCCESS" << std::endl;
711 }
712
713 private:
714 uint16_t effecterId;
715 uint8_t effecterDataSize;
716 uint64_t maxEffecterValue;
717};
718
George Liud6649362019-11-27 19:06:51 +0800719void registerCommand(CLI::App& app)
720{
721 auto platform = app.add_subcommand("platform", "platform type command");
722 platform->require_subcommand(1);
723
724 auto getPDR =
725 platform->add_subcommand("GetPDR", "get platform descriptor records");
726 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR));
727
728 auto setStateEffecterStates = platform->add_subcommand(
729 "SetStateEffecterStates", "set effecter states");
730 commands.push_back(std::make_unique<SetStateEffecter>(
731 "platform", "setStateEffecterStates", setStateEffecterStates));
George Liucc9c20d2020-02-05 10:24:11 +0800732
733 auto setNumericEffecterValue = platform->add_subcommand(
734 "SetNumericEffecterValue", "set the value for a PLDM Numeric Effecter");
735 commands.push_back(std::make_unique<SetNumericEffecterValue>(
736 "platform", "setNumericEffecterValue", setNumericEffecterValue));
George Liud6649362019-11-27 19:06:51 +0800737}
738
739} // namespace platform
740} // namespace pldmtool