blob: 0774b686b310ce0ea3ed65568054198dfb41a0d6 [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 Kodihalli5544ccd2020-03-15 23:36:16 -050097 {11521, "System (logical)"},
98 };
99
Tom Josepha65c0412020-07-03 21:14:44 +0530100 const std::map<uint16_t, std::string> stateSet = {
101 {PLDM_STATE_SET_HEALTH_STATE, "Health State"},
102 {PLDM_STATE_SET_AVAILABILITY, "Availability"},
103 {PLDM_STATE_SET_OPERATIONAL_STATUS, "Operational Status"},
104 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS,
105 "Operational Running Status"},
106 {PLDM_STATE_SET_PRESENCE, "Presence"},
107 {PLDM_STATE_SET_CONFIGURATION_STATE, "Configuration State"},
108 {PLDM_STATE_SET_LINK_STATE, "Link State"},
109 {PLDM_STATE_SET_SW_TERMINATION_STATUS, "Software Termination Status"},
110 {PLDM_STATE_SET_BOOT_RESTART_CAUSE, "Boot/Restart Cause"},
111 {PLDM_STATE_SET_BOOT_PROGRESS, "Boot Progress"},
112 };
113
114 const std::array<std::string_view, 4> sensorInit = {
115 "noInit", "useInitPDR", "enableSensor", "disableSensor"};
116
Tom Joseph97a7a762020-07-06 10:37:18 +0530117 const std::array<std::string_view, 4> effecterInit = {
118 "noInit", "useInitPDR", "enableEffecter", "disableEffecter"};
119
Tom Josepha65c0412020-07-03 21:14:44 +0530120 std::string getEntityName(pldm::pdr::EntityType type)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500121 {
122 try
123 {
124 return entityType.at(type);
125 }
126 catch (const std::out_of_range& e)
127 {
128 return std::to_string(static_cast<unsigned>(type)) + "(OEM)";
129 }
130 }
131
Tom Josepha65c0412020-07-03 21:14:44 +0530132 std::string getStateSetName(uint16_t id)
133 {
134 try
135 {
136 return stateSet.at(id);
137 }
138 catch (const std::out_of_range& e)
139 {
140 return std::to_string(id);
141 }
142 }
143
Tom Joseph952abfa2020-07-03 12:25:15 +0530144 void printCommonPDRHeader(const pldm_pdr_hdr* hdr)
145 {
146 std::cout << "recordHandle: " << hdr->record_handle << std::endl;
147 std::cout << "PDRHeaderVersion: " << unsigned(hdr->version)
148 << std::endl;
149 std::cout << "PDRType: " << unsigned(hdr->type) << std::endl;
150 std::cout << "recordChangeNumber: " << hdr->record_change_num
151 << std::endl;
152 std::cout << "dataLength: " << hdr->length << std::endl << std::endl;
153 }
154
Tom Josepha65c0412020-07-03 21:14:44 +0530155 void printPossibleStates(uint8_t possibleStatesSize,
156 const bitfield8_t* states)
157 {
158 uint8_t possibleStatesPos{};
159 auto printStates = [&possibleStatesPos](const bitfield8_t& val) {
160 for (int i = 0; i < CHAR_BIT; i++)
161 {
162 if (val.byte & (1 << i))
163 {
164 std::cout << " " << (possibleStatesPos * CHAR_BIT + i);
165 }
166 }
167 possibleStatesPos++;
168 };
169 std::for_each(states, states + possibleStatesSize, printStates);
170 }
171
172 void printStateSensorPDR(const uint8_t* data)
173 {
174 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(data);
175
176 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
177 << std::endl;
178 std::cout << "sensorID: " << pdr->sensor_id << std::endl;
179 std::cout << "entityType: " << getEntityName(pdr->entity_type)
180 << std::endl;
181 std::cout << "entityInstanceNumber: " << pdr->entity_instance
182 << std::endl;
183 std::cout << "containerID: " << pdr->container_id << std::endl;
184 std::cout << "sensorInit: " << sensorInit[pdr->sensor_init]
185 << std::endl;
186 std::cout << "sensorAuxiliaryNamesPDR: "
187 << (pdr->sensor_auxiliary_names_pdr ? "true" : "false")
188 << std::endl;
189 std::cout << "compositeSensorCount: "
190 << unsigned(pdr->composite_sensor_count) << std::endl;
191
192 auto statesPtr = pdr->possible_states;
193 auto compositeSensorCount = pdr->composite_sensor_count;
194
195 while (compositeSensorCount--)
196 {
197 auto state = reinterpret_cast<const state_sensor_possible_states*>(
198 statesPtr);
199 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
200 << std::endl;
201 std::cout << "possibleStatesSize: "
202 << unsigned(state->possible_states_size) << std::endl;
203 std::cout << "possibleStates:";
204 printPossibleStates(state->possible_states_size, state->states);
205 std::cout << std::endl;
206
207 if (compositeSensorCount)
208 {
209 statesPtr += sizeof(state_sensor_possible_states) +
210 state->possible_states_size - 1;
211 }
212 }
213 }
214
George Liu62d12ec2020-02-05 16:27:08 +0800215 void printPDRFruRecordSet(uint8_t* data)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500216 {
George Liu62d12ec2020-02-05 16:27:08 +0800217 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500218 {
219 return;
220 }
221
222 data += sizeof(pldm_pdr_hdr);
223 pldm_pdr_fru_record_set* pdr =
224 reinterpret_cast<pldm_pdr_fru_record_set*>(data);
225
226 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
227 << std::endl;
228 std::cout << "FRURecordSetIdentifier: " << pdr->fru_rsi << std::endl;
229 std::cout << "entityType: " << getEntityName(pdr->entity_type)
230 << std::endl;
231 std::cout << "entityInstanceNumber: " << pdr->entity_instance_num
232 << std::endl;
233 std::cout << "containerID: " << pdr->container_id << std::endl;
234 }
235
George Liu62d12ec2020-02-05 16:27:08 +0800236 void printPDREntityAssociation(uint8_t* data)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500237 {
238 const std::map<uint8_t, const char*> assocationType = {
239 {PLDM_ENTITY_ASSOCIAION_PHYSICAL, "Physical"},
240 {PLDM_ENTITY_ASSOCIAION_LOGICAL, "Logical"},
241 };
242
George Liu62d12ec2020-02-05 16:27:08 +0800243 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500244 {
245 return;
246 }
247
248 data += sizeof(pldm_pdr_hdr);
249 pldm_pdr_entity_association* pdr =
250 reinterpret_cast<pldm_pdr_entity_association*>(data);
251
252 std::cout << "containerID: " << pdr->container_id << std::endl;
253 std::cout << "associationType: "
254 << assocationType.at(pdr->association_type) << std::endl
255 << std::endl;
256
257 std::cout << "containerEntityType: "
258 << getEntityName(pdr->container.entity_type) << std::endl;
259 std::cout << "containerEntityInstanceNumber: "
260 << pdr->container.entity_instance_num << std::endl;
261 std::cout << "containerEntityContainerID: "
262 << pdr->container.entity_container_id << std::endl;
263
264 std::cout << "containedEntityCount: "
265 << static_cast<unsigned>(pdr->num_children) << std::endl
266 << std::endl;
267
268 auto child = reinterpret_cast<pldm_entity*>(&pdr->children[0]);
269 for (int i = 0; i < pdr->num_children; ++i)
270 {
271 std::cout << "containedEntityType[" << i + 1
272 << "]: " << getEntityName(child->entity_type)
273 << std::endl;
274 std::cout << "containedEntityInstanceNumber[" << i + 1
275 << "]: " << child->entity_instance_num << std::endl;
276 std::cout << "containedEntityContainerID[" << i + 1
277 << "]: " << child->entity_container_id << std::endl
278 << std::endl;
279 ++child;
280 }
281 }
282
George Liu62d12ec2020-02-05 16:27:08 +0800283 void printNumericEffecterPDR(uint8_t* data)
284 {
285 struct pldm_numeric_effecter_value_pdr* pdr =
286 (struct pldm_numeric_effecter_value_pdr*)data;
George Liu62d12ec2020-02-05 16:27:08 +0800287 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
288 << std::endl;
289 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
290 std::cout << "entityType: " << pdr->entity_type << std::endl;
291 std::cout << "entityInstanceNumber: " << pdr->entity_instance
292 << std::endl;
293 std::cout << "containerID: " << pdr->container_id << std::endl;
294 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
295 << std::endl;
296 std::cout << "effecterInit: " << unsigned(pdr->effecter_init)
297 << std::endl;
298 std::cout << "effecterAuxiliaryNames: "
299 << (unsigned(pdr->effecter_auxiliary_names) ? "true"
300 : "false")
301 << std::endl;
302 std::cout << "baseUnit: " << unsigned(pdr->base_unit) << std::endl;
303 std::cout << "unitModifier: " << unsigned(pdr->unit_modifier)
304 << std::endl;
305 std::cout << "rateUnit: " << unsigned(pdr->rate_unit) << std::endl;
306 std::cout << "baseOEMUnitHandle: "
307 << unsigned(pdr->base_oem_unit_handle) << std::endl;
308 std::cout << "auxUnit: " << unsigned(pdr->aux_unit) << std::endl;
309 std::cout << "auxUnitModifier: " << unsigned(pdr->aux_unit_modifier)
310 << std::endl;
311 std::cout << "auxrateUnit: " << unsigned(pdr->aux_rate_unit)
312 << std::endl;
313 std::cout << "auxOEMUnitHandle: " << unsigned(pdr->aux_oem_unit_handle)
314 << std::endl;
315 std::cout << "isLinear: "
316 << (unsigned(pdr->is_linear) ? "true" : "false") << std::endl;
317 std::cout << "effecterDataSize: " << unsigned(pdr->effecter_data_size)
318 << std::endl;
319 std::cout << "resolution: " << pdr->resolution << std::endl;
320 std::cout << "offset: " << pdr->offset << std::endl;
321 std::cout << "accuracy: " << pdr->accuracy << std::endl;
322 std::cout << "plusTolerance: " << unsigned(pdr->plus_tolerance)
323 << std::endl;
324 std::cout << "minusTolerance: " << unsigned(pdr->minus_tolerance)
325 << std::endl;
326 std::cout << "stateTransitionInterval: "
327 << pdr->state_transition_interval << std::endl;
328 std::cout << "TransitionInterval: " << pdr->transition_interval
329 << std::endl;
330 switch (pdr->effecter_data_size)
331 {
332 case PLDM_EFFECTER_DATA_SIZE_UINT8:
333 std::cout << "maxSettable: "
334 << unsigned(pdr->max_set_table.value_u8) << std::endl;
335 std::cout << "minSettable: "
336 << unsigned(pdr->min_set_table.value_u8) << std::endl;
337 break;
338 case PLDM_EFFECTER_DATA_SIZE_SINT8:
339 std::cout << "maxSettable: "
340 << unsigned(pdr->max_set_table.value_s8) << std::endl;
341 std::cout << "minSettable: "
342 << unsigned(pdr->min_set_table.value_s8) << std::endl;
343 break;
344 case PLDM_EFFECTER_DATA_SIZE_UINT16:
345 std::cout << "maxSettable: " << pdr->max_set_table.value_u16
346 << std::endl;
347 std::cout << "minSettable: " << pdr->min_set_table.value_u16
348 << std::endl;
349 break;
350 case PLDM_EFFECTER_DATA_SIZE_SINT16:
351 std::cout << "maxSettable: " << pdr->max_set_table.value_s16
352 << std::endl;
353 std::cout << "minSettable: " << pdr->min_set_table.value_s16
354 << std::endl;
355 break;
356 case PLDM_EFFECTER_DATA_SIZE_UINT32:
357 std::cout << "maxSettable: " << pdr->max_set_table.value_u32
358 << std::endl;
359 std::cout << "minSettable: " << pdr->min_set_table.value_u32
360 << std::endl;
361 break;
362 case PLDM_EFFECTER_DATA_SIZE_SINT32:
363 std::cout << "maxSettable: " << pdr->max_set_table.value_s32
364 << std::endl;
365 std::cout << "minSettable: " << pdr->min_set_table.value_s32
366 << std::endl;
367 break;
368 default:
369 break;
370 }
371 std::cout << "rangeFieldFormat: " << unsigned(pdr->range_field_format)
372 << std::endl;
373 std::cout << "rangeFieldSupport: "
374 << unsigned(pdr->range_field_support.byte) << std::endl;
375 switch (pdr->range_field_format)
376 {
377 case PLDM_RANGE_FIELD_FORMAT_UINT8:
378 std::cout << "nominalValue: "
379 << unsigned(pdr->nominal_value.value_u8) << std::endl;
380 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_u8)
381 << std::endl;
382 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_u8)
383 << std::endl;
384 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_u8)
385 << std::endl;
386 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_u8)
387 << std::endl;
388 break;
389 case PLDM_RANGE_FIELD_FORMAT_SINT8:
390 std::cout << "nominalValue: "
391 << unsigned(pdr->nominal_value.value_s8) << std::endl;
392 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_s8)
393 << std::endl;
394 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_s8)
395 << std::endl;
396 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_s8)
397 << std::endl;
398 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_s8)
399 << std::endl;
400 break;
401 case PLDM_RANGE_FIELD_FORMAT_UINT16:
402 std::cout << "nominalValue: " << pdr->nominal_value.value_u16
403 << std::endl;
404 std::cout << "normalMax: " << pdr->normal_max.value_u16
405 << std::endl;
406 std::cout << "normalMin: " << pdr->normal_min.value_u16
407 << std::endl;
408 std::cout << "ratedMax: " << pdr->rated_max.value_u16
409 << std::endl;
410 std::cout << "ratedMin: " << pdr->rated_min.value_u16
411 << std::endl;
412 break;
413 case PLDM_RANGE_FIELD_FORMAT_SINT16:
414 std::cout << "nominalValue: " << pdr->nominal_value.value_s16
415 << std::endl;
416 std::cout << "normalMax: " << pdr->normal_max.value_s16
417 << std::endl;
418 std::cout << "normalMin: " << pdr->normal_min.value_s16
419 << std::endl;
420 std::cout << "ratedMax: " << pdr->rated_max.value_s16
421 << std::endl;
422 std::cout << "ratedMin: " << pdr->rated_min.value_s16
423 << std::endl;
424 break;
425 case PLDM_RANGE_FIELD_FORMAT_UINT32:
426 std::cout << "nominalValue: " << pdr->nominal_value.value_u32
427 << std::endl;
428 std::cout << "normalMax: " << pdr->normal_max.value_u32
429 << std::endl;
430 std::cout << "normalMin: " << pdr->normal_min.value_u32
431 << std::endl;
432 std::cout << "ratedMax: " << pdr->rated_max.value_u32
433 << std::endl;
434 std::cout << "ratedMin: " << pdr->rated_min.value_u32
435 << std::endl;
436 break;
437 case PLDM_RANGE_FIELD_FORMAT_SINT32:
438 std::cout << "nominalValue: " << pdr->nominal_value.value_s32
439 << std::endl;
440 std::cout << "normalMax: " << pdr->normal_max.value_s32
441 << std::endl;
442 std::cout << "normalMin: " << pdr->normal_min.value_s32
443 << std::endl;
444 std::cout << "ratedMax: " << pdr->rated_max.value_s32
445 << std::endl;
446 std::cout << "ratedMin: " << pdr->rated_min.value_s32
447 << std::endl;
448 break;
449 case PLDM_RANGE_FIELD_FORMAT_REAL32:
450 std::cout << "nominalValue: " << pdr->nominal_value.value_f32
451 << std::endl;
452 std::cout << "normalMax: " << pdr->normal_max.value_f32
453 << std::endl;
454 std::cout << "normalMin: " << pdr->normal_min.value_f32
455 << std::endl;
456 std::cout << "ratedMax: " << pdr->rated_max.value_f32
457 << std::endl;
458 std::cout << "ratedMin: " << pdr->rated_min.value_f32
459 << std::endl;
460 break;
461 default:
462 break;
463 }
464 }
465
Tom Joseph97a7a762020-07-06 10:37:18 +0530466 void printStateEffecterPDR(const uint8_t* data)
George Liu62d12ec2020-02-05 16:27:08 +0800467 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530468 auto pdr = reinterpret_cast<const pldm_state_effecter_pdr*>(data);
George Liu62d12ec2020-02-05 16:27:08 +0800469
George Liud6649362019-11-27 19:06:51 +0800470 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
471 << std::endl;
472 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530473 std::cout << "entityType: " << getEntityName(pdr->entity_type)
474 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800475 std::cout << "entityInstanceNumber: " << pdr->entity_instance
476 << std::endl;
477 std::cout << "containerID: " << pdr->container_id << std::endl;
478 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
479 << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530480 std::cout << "effecterInit: " << effecterInit[pdr->effecter_init]
George Liud6649362019-11-27 19:06:51 +0800481 << std::endl;
482 std::cout << "effecterDescriptionPDR: "
Tom Joseph97a7a762020-07-06 10:37:18 +0530483 << (pdr->has_description_pdr ? "true" : "false") << std::endl;
George Liud6649362019-11-27 19:06:51 +0800484 std::cout << "compositeEffecterCount: "
485 << unsigned(pdr->composite_effecter_count) << std::endl;
486
Tom Joseph97a7a762020-07-06 10:37:18 +0530487 auto statesPtr = pdr->possible_states;
488 auto compositeEffecterCount = pdr->composite_effecter_count;
489
490 while (compositeEffecterCount--)
George Liud6649362019-11-27 19:06:51 +0800491 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530492 auto state =
493 reinterpret_cast<const state_effecter_possible_states*>(
494 statesPtr);
495 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
496 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800497 std::cout << "possibleStatesSize: "
498 << unsigned(state->possible_states_size) << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530499 std::cout << "possibleStates:";
500 printPossibleStates(state->possible_states_size, state->states);
501 std::cout << std::endl;
502
503 if (compositeEffecterCount)
504 {
505 statesPtr += sizeof(state_effecter_possible_states) +
506 state->possible_states_size - 1;
507 }
George Liud6649362019-11-27 19:06:51 +0800508 }
509 }
510
511 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt,
George Liu62d12ec2020-02-05 16:27:08 +0800512 uint8_t* data)
George Liud6649362019-11-27 19:06:51 +0800513 {
George Liu62d12ec2020-02-05 16:27:08 +0800514 if (data == NULL)
George Liud6649362019-11-27 19:06:51 +0800515 {
516 return;
517 }
518
George Liud6649362019-11-27 19:06:51 +0800519 std::cout << "nextRecordHandle: " << nextRecordHndl << std::endl;
520 std::cout << "responseCount: " << respCnt << std::endl;
521
522 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
Tom Joseph952abfa2020-07-03 12:25:15 +0530523 printCommonPDRHeader(pdr);
George Liud6649362019-11-27 19:06:51 +0800524 switch (pdr->type)
525 {
Tom Josepha65c0412020-07-03 21:14:44 +0530526 case PLDM_STATE_SENSOR_PDR:
527 printStateSensorPDR(data);
528 break;
George Liu62d12ec2020-02-05 16:27:08 +0800529 case PLDM_NUMERIC_EFFECTER_PDR:
530 printNumericEffecterPDR(data);
531 break;
George Liud6649362019-11-27 19:06:51 +0800532 case PLDM_STATE_EFFECTER_PDR:
George Liu62d12ec2020-02-05 16:27:08 +0800533 printStateEffecterPDR(data);
George Liud6649362019-11-27 19:06:51 +0800534 break;
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500535 case PLDM_PDR_ENTITY_ASSOCIATION:
George Liu62d12ec2020-02-05 16:27:08 +0800536 printPDREntityAssociation(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500537 break;
538 case PLDM_PDR_FRU_RECORD_SET:
George Liu62d12ec2020-02-05 16:27:08 +0800539 printPDRFruRecordSet(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500540 break;
George Liud6649362019-11-27 19:06:51 +0800541 default:
542 break;
543 }
544 }
545
546 private:
547 uint32_t recordHandle;
548};
549
550class SetStateEffecter : public CommandInterface
551{
552 public:
553 ~SetStateEffecter() = default;
554 SetStateEffecter() = delete;
555 SetStateEffecter(const SetStateEffecter&) = delete;
556 SetStateEffecter(SetStateEffecter&&) = default;
557 SetStateEffecter& operator=(const SetStateEffecter&) = delete;
558 SetStateEffecter& operator=(SetStateEffecter&&) = default;
559
George Liuba4c1fb2020-02-05 14:13:30 +0800560 // compositeEffecterCount(value: 0x01 to 0x08) * stateField(2)
561 static constexpr auto maxEffecterDataSize = 16;
562
563 // compositeEffecterCount(value: 0x01 to 0x08)
564 static constexpr auto minEffecterCount = 1;
565 static constexpr auto maxEffecterCount = 8;
George Liud6649362019-11-27 19:06:51 +0800566 explicit SetStateEffecter(const char* type, const char* name,
567 CLI::App* app) :
568 CommandInterface(type, name, app)
569 {
570 app->add_option(
George Liuba4c1fb2020-02-05 14:13:30 +0800571 "-i, --id", effecterId,
572 "A handle that is used to identify and access the effecter")
573 ->required();
574 app->add_option("-c, --count", effecterCount,
575 "The number of individual sets of effecter information")
576 ->required();
577 app->add_option(
George Liud6649362019-11-27 19:06:51 +0800578 "-d,--data", effecterData,
George Liuba4c1fb2020-02-05 14:13:30 +0800579 "Set effecter state data\n"
580 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...")
581 ->required();
George Liud6649362019-11-27 19:06:51 +0800582 }
583
584 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
585 {
586 std::vector<uint8_t> requestMsg(
587 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES);
588 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
589
George Liuba4c1fb2020-02-05 14:13:30 +0800590 if (effecterCount > maxEffecterCount ||
591 effecterCount < minEffecterCount)
George Liud6649362019-11-27 19:06:51 +0800592 {
George Liuba4c1fb2020-02-05 14:13:30 +0800593 std::cerr << "Request Message Error: effecterCount size "
594 << effecterCount << "is invalid\n";
George Liud6649362019-11-27 19:06:51 +0800595 auto rc = PLDM_ERROR_INVALID_DATA;
596 return {rc, requestMsg};
597 }
598
George Liuba4c1fb2020-02-05 14:13:30 +0800599 if (effecterData.size() > maxEffecterDataSize)
George Liud6649362019-11-27 19:06:51 +0800600 {
George Liuba4c1fb2020-02-05 14:13:30 +0800601 std::cerr << "Request Message Error: effecterData size "
602 << effecterData.size() << "is invalid\n";
603 auto rc = PLDM_ERROR_INVALID_DATA;
604 return {rc, requestMsg};
605 }
606
607 auto stateField = parseEffecterData(effecterData, effecterCount);
608 if (!stateField)
609 {
610 std::cerr << "Failed to parse effecter data, effecterCount size "
611 << effecterCount << "\n";
George Liud6649362019-11-27 19:06:51 +0800612 auto rc = PLDM_ERROR_INVALID_DATA;
613 return {rc, requestMsg};
614 }
615
616 auto rc = encode_set_state_effecter_states_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600617 instanceId, effecterId, effecterCount, stateField->data(), request);
George Liud6649362019-11-27 19:06:51 +0800618 return {rc, requestMsg};
619 }
620
621 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
622 {
623 uint8_t completionCode = 0;
624 auto rc = decode_set_state_effecter_states_resp(
625 responsePtr, payloadLength, &completionCode);
626
627 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
628 {
629 std::cerr << "Response Message Error: "
George Liuba4c1fb2020-02-05 14:13:30 +0800630 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
George Liud6649362019-11-27 19:06:51 +0800631 return;
632 }
633
634 std::cout << "SetStateEffecterStates: SUCCESS" << std::endl;
635 }
636
637 private:
George Liuba4c1fb2020-02-05 14:13:30 +0800638 uint16_t effecterId;
639 uint8_t effecterCount;
George Liud6649362019-11-27 19:06:51 +0800640 std::vector<uint8_t> effecterData;
641};
642
George Liucc9c20d2020-02-05 10:24:11 +0800643class SetNumericEffecterValue : public CommandInterface
644{
645 public:
646 ~SetNumericEffecterValue() = default;
647 SetNumericEffecterValue() = delete;
648 SetNumericEffecterValue(const SetNumericEffecterValue&) = delete;
649 SetNumericEffecterValue(SetNumericEffecterValue&&) = default;
650 SetNumericEffecterValue& operator=(const SetNumericEffecterValue&) = delete;
651 SetNumericEffecterValue& operator=(SetNumericEffecterValue&&) = default;
652
653 explicit SetNumericEffecterValue(const char* type, const char* name,
654 CLI::App* app) :
655 CommandInterface(type, name, app)
656 {
657 app->add_option(
658 "-i, --id", effecterId,
659 "A handle that is used to identify and access the effecter")
660 ->required();
661 app->add_option("-s, --size", effecterDataSize,
662 "The bit width and format of the setting value for the "
663 "effecter. enum value: {uint8, sint8, uint16, sint16, "
664 "uint32, sint32}\n")
665 ->required();
666 app->add_option("-d,--data", maxEffecterValue,
667 "The setting value of numeric effecter being "
668 "requested\n")
669 ->required();
670 }
671
672 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
673 {
674 std::vector<uint8_t> requestMsg(
675 sizeof(pldm_msg_hdr) +
676 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3);
677
678 uint8_t* effecterValue = (uint8_t*)&maxEffecterValue;
679
680 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
681 size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES;
682
683 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
684 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
685 {
686 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1;
687 }
688 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
689 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
690 {
691 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3;
692 }
693 auto rc = encode_set_numeric_effecter_value_req(
694 0, effecterId, effecterDataSize, effecterValue, request,
695 payload_length);
696
697 return {rc, requestMsg};
698 }
699
700 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
701 {
702 uint8_t completionCode = 0;
703 auto rc = decode_set_numeric_effecter_value_resp(
704 responsePtr, payloadLength, &completionCode);
705
706 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
707 {
708 std::cerr << "Response Message Error: "
709 << "rc=" << rc << ",cc=" << (int)completionCode
710 << std::endl;
711 return;
712 }
713
714 std::cout << "SetNumericEffecterValue: SUCCESS" << std::endl;
715 }
716
717 private:
718 uint16_t effecterId;
719 uint8_t effecterDataSize;
720 uint64_t maxEffecterValue;
721};
722
George Liud6649362019-11-27 19:06:51 +0800723void registerCommand(CLI::App& app)
724{
725 auto platform = app.add_subcommand("platform", "platform type command");
726 platform->require_subcommand(1);
727
728 auto getPDR =
729 platform->add_subcommand("GetPDR", "get platform descriptor records");
730 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR));
731
732 auto setStateEffecterStates = platform->add_subcommand(
733 "SetStateEffecterStates", "set effecter states");
734 commands.push_back(std::make_unique<SetStateEffecter>(
735 "platform", "setStateEffecterStates", setStateEffecterStates));
George Liucc9c20d2020-02-05 10:24:11 +0800736
737 auto setNumericEffecterValue = platform->add_subcommand(
738 "SetNumericEffecterValue", "set the value for a PLDM Numeric Effecter");
739 commands.push_back(std::make_unique<SetNumericEffecterValue>(
740 "platform", "setNumericEffecterValue", setNumericEffecterValue));
George Liud6649362019-11-27 19:06:51 +0800741}
742
743} // namespace platform
744} // namespace pldmtool