blob: 4f18a919fd3b6e6dd5e200d0c892c42713f4e780 [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"},
113 };
114
115 const std::array<std::string_view, 4> sensorInit = {
116 "noInit", "useInitPDR", "enableSensor", "disableSensor"};
117
Tom Joseph97a7a762020-07-06 10:37:18 +0530118 const std::array<std::string_view, 4> effecterInit = {
119 "noInit", "useInitPDR", "enableEffecter", "disableEffecter"};
120
Tom Josepha65c0412020-07-03 21:14:44 +0530121 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
Tom Joseph97a7a762020-07-06 10:37:18 +0530467 void printStateEffecterPDR(const uint8_t* data)
George Liu62d12ec2020-02-05 16:27:08 +0800468 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530469 auto pdr = reinterpret_cast<const pldm_state_effecter_pdr*>(data);
George Liu62d12ec2020-02-05 16:27:08 +0800470
George Liud6649362019-11-27 19:06:51 +0800471 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
472 << std::endl;
473 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530474 std::cout << "entityType: " << getEntityName(pdr->entity_type)
475 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800476 std::cout << "entityInstanceNumber: " << pdr->entity_instance
477 << std::endl;
478 std::cout << "containerID: " << pdr->container_id << std::endl;
479 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
480 << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530481 std::cout << "effecterInit: " << effecterInit[pdr->effecter_init]
George Liud6649362019-11-27 19:06:51 +0800482 << std::endl;
483 std::cout << "effecterDescriptionPDR: "
Tom Joseph97a7a762020-07-06 10:37:18 +0530484 << (pdr->has_description_pdr ? "true" : "false") << std::endl;
George Liud6649362019-11-27 19:06:51 +0800485 std::cout << "compositeEffecterCount: "
486 << unsigned(pdr->composite_effecter_count) << std::endl;
487
Tom Joseph97a7a762020-07-06 10:37:18 +0530488 auto statesPtr = pdr->possible_states;
489 auto compositeEffecterCount = pdr->composite_effecter_count;
490
491 while (compositeEffecterCount--)
George Liud6649362019-11-27 19:06:51 +0800492 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530493 auto state =
494 reinterpret_cast<const state_effecter_possible_states*>(
495 statesPtr);
496 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
497 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800498 std::cout << "possibleStatesSize: "
499 << unsigned(state->possible_states_size) << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530500 std::cout << "possibleStates:";
501 printPossibleStates(state->possible_states_size, state->states);
502 std::cout << std::endl;
503
504 if (compositeEffecterCount)
505 {
506 statesPtr += sizeof(state_effecter_possible_states) +
507 state->possible_states_size - 1;
508 }
George Liud6649362019-11-27 19:06:51 +0800509 }
510 }
511
512 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt,
George Liu62d12ec2020-02-05 16:27:08 +0800513 uint8_t* data)
George Liud6649362019-11-27 19:06:51 +0800514 {
George Liu62d12ec2020-02-05 16:27:08 +0800515 if (data == NULL)
George Liud6649362019-11-27 19:06:51 +0800516 {
517 return;
518 }
519
George Liud6649362019-11-27 19:06:51 +0800520 std::cout << "nextRecordHandle: " << nextRecordHndl << std::endl;
521 std::cout << "responseCount: " << respCnt << std::endl;
522
523 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
Tom Joseph952abfa2020-07-03 12:25:15 +0530524 printCommonPDRHeader(pdr);
George Liud6649362019-11-27 19:06:51 +0800525 switch (pdr->type)
526 {
Tom Josepha65c0412020-07-03 21:14:44 +0530527 case PLDM_STATE_SENSOR_PDR:
528 printStateSensorPDR(data);
529 break;
George Liu62d12ec2020-02-05 16:27:08 +0800530 case PLDM_NUMERIC_EFFECTER_PDR:
531 printNumericEffecterPDR(data);
532 break;
George Liud6649362019-11-27 19:06:51 +0800533 case PLDM_STATE_EFFECTER_PDR:
George Liu62d12ec2020-02-05 16:27:08 +0800534 printStateEffecterPDR(data);
George Liud6649362019-11-27 19:06:51 +0800535 break;
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500536 case PLDM_PDR_ENTITY_ASSOCIATION:
George Liu62d12ec2020-02-05 16:27:08 +0800537 printPDREntityAssociation(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500538 break;
539 case PLDM_PDR_FRU_RECORD_SET:
George Liu62d12ec2020-02-05 16:27:08 +0800540 printPDRFruRecordSet(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500541 break;
George Liud6649362019-11-27 19:06:51 +0800542 default:
543 break;
544 }
545 }
546
547 private:
548 uint32_t recordHandle;
549};
550
551class SetStateEffecter : public CommandInterface
552{
553 public:
554 ~SetStateEffecter() = default;
555 SetStateEffecter() = delete;
556 SetStateEffecter(const SetStateEffecter&) = delete;
557 SetStateEffecter(SetStateEffecter&&) = default;
558 SetStateEffecter& operator=(const SetStateEffecter&) = delete;
559 SetStateEffecter& operator=(SetStateEffecter&&) = default;
560
George Liuba4c1fb2020-02-05 14:13:30 +0800561 // compositeEffecterCount(value: 0x01 to 0x08) * stateField(2)
562 static constexpr auto maxEffecterDataSize = 16;
563
564 // compositeEffecterCount(value: 0x01 to 0x08)
565 static constexpr auto minEffecterCount = 1;
566 static constexpr auto maxEffecterCount = 8;
George Liud6649362019-11-27 19:06:51 +0800567 explicit SetStateEffecter(const char* type, const char* name,
568 CLI::App* app) :
569 CommandInterface(type, name, app)
570 {
571 app->add_option(
George Liuba4c1fb2020-02-05 14:13:30 +0800572 "-i, --id", effecterId,
573 "A handle that is used to identify and access the effecter")
574 ->required();
575 app->add_option("-c, --count", effecterCount,
576 "The number of individual sets of effecter information")
577 ->required();
578 app->add_option(
George Liud6649362019-11-27 19:06:51 +0800579 "-d,--data", effecterData,
George Liuba4c1fb2020-02-05 14:13:30 +0800580 "Set effecter state data\n"
581 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...")
582 ->required();
George Liud6649362019-11-27 19:06:51 +0800583 }
584
585 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
586 {
587 std::vector<uint8_t> requestMsg(
588 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES);
589 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
590
George Liuba4c1fb2020-02-05 14:13:30 +0800591 if (effecterCount > maxEffecterCount ||
592 effecterCount < minEffecterCount)
George Liud6649362019-11-27 19:06:51 +0800593 {
George Liuba4c1fb2020-02-05 14:13:30 +0800594 std::cerr << "Request Message Error: effecterCount size "
595 << effecterCount << "is invalid\n";
George Liud6649362019-11-27 19:06:51 +0800596 auto rc = PLDM_ERROR_INVALID_DATA;
597 return {rc, requestMsg};
598 }
599
George Liuba4c1fb2020-02-05 14:13:30 +0800600 if (effecterData.size() > maxEffecterDataSize)
George Liud6649362019-11-27 19:06:51 +0800601 {
George Liuba4c1fb2020-02-05 14:13:30 +0800602 std::cerr << "Request Message Error: effecterData size "
603 << effecterData.size() << "is invalid\n";
604 auto rc = PLDM_ERROR_INVALID_DATA;
605 return {rc, requestMsg};
606 }
607
608 auto stateField = parseEffecterData(effecterData, effecterCount);
609 if (!stateField)
610 {
611 std::cerr << "Failed to parse effecter data, effecterCount size "
612 << effecterCount << "\n";
George Liud6649362019-11-27 19:06:51 +0800613 auto rc = PLDM_ERROR_INVALID_DATA;
614 return {rc, requestMsg};
615 }
616
617 auto rc = encode_set_state_effecter_states_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600618 instanceId, effecterId, effecterCount, stateField->data(), request);
George Liud6649362019-11-27 19:06:51 +0800619 return {rc, requestMsg};
620 }
621
622 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
623 {
624 uint8_t completionCode = 0;
625 auto rc = decode_set_state_effecter_states_resp(
626 responsePtr, payloadLength, &completionCode);
627
628 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
629 {
630 std::cerr << "Response Message Error: "
George Liuba4c1fb2020-02-05 14:13:30 +0800631 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
George Liud6649362019-11-27 19:06:51 +0800632 return;
633 }
634
635 std::cout << "SetStateEffecterStates: SUCCESS" << std::endl;
636 }
637
638 private:
George Liuba4c1fb2020-02-05 14:13:30 +0800639 uint16_t effecterId;
640 uint8_t effecterCount;
George Liud6649362019-11-27 19:06:51 +0800641 std::vector<uint8_t> effecterData;
642};
643
George Liucc9c20d2020-02-05 10:24:11 +0800644class SetNumericEffecterValue : public CommandInterface
645{
646 public:
647 ~SetNumericEffecterValue() = default;
648 SetNumericEffecterValue() = delete;
649 SetNumericEffecterValue(const SetNumericEffecterValue&) = delete;
650 SetNumericEffecterValue(SetNumericEffecterValue&&) = default;
651 SetNumericEffecterValue& operator=(const SetNumericEffecterValue&) = delete;
652 SetNumericEffecterValue& operator=(SetNumericEffecterValue&&) = default;
653
654 explicit SetNumericEffecterValue(const char* type, const char* name,
655 CLI::App* app) :
656 CommandInterface(type, name, app)
657 {
658 app->add_option(
659 "-i, --id", effecterId,
660 "A handle that is used to identify and access the effecter")
661 ->required();
662 app->add_option("-s, --size", effecterDataSize,
663 "The bit width and format of the setting value for the "
664 "effecter. enum value: {uint8, sint8, uint16, sint16, "
665 "uint32, sint32}\n")
666 ->required();
667 app->add_option("-d,--data", maxEffecterValue,
668 "The setting value of numeric effecter being "
669 "requested\n")
670 ->required();
671 }
672
673 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
674 {
675 std::vector<uint8_t> requestMsg(
676 sizeof(pldm_msg_hdr) +
677 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3);
678
679 uint8_t* effecterValue = (uint8_t*)&maxEffecterValue;
680
681 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
682 size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES;
683
684 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
685 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
686 {
687 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1;
688 }
689 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
690 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
691 {
692 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3;
693 }
694 auto rc = encode_set_numeric_effecter_value_req(
695 0, effecterId, effecterDataSize, effecterValue, request,
696 payload_length);
697
698 return {rc, requestMsg};
699 }
700
701 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
702 {
703 uint8_t completionCode = 0;
704 auto rc = decode_set_numeric_effecter_value_resp(
705 responsePtr, payloadLength, &completionCode);
706
707 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
708 {
709 std::cerr << "Response Message Error: "
710 << "rc=" << rc << ",cc=" << (int)completionCode
711 << std::endl;
712 return;
713 }
714
715 std::cout << "SetNumericEffecterValue: SUCCESS" << std::endl;
716 }
717
718 private:
719 uint16_t effecterId;
720 uint8_t effecterDataSize;
721 uint64_t maxEffecterValue;
722};
723
George Liud6649362019-11-27 19:06:51 +0800724void registerCommand(CLI::App& app)
725{
726 auto platform = app.add_subcommand("platform", "platform type command");
727 platform->require_subcommand(1);
728
729 auto getPDR =
730 platform->add_subcommand("GetPDR", "get platform descriptor records");
731 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR));
732
733 auto setStateEffecterStates = platform->add_subcommand(
734 "SetStateEffecterStates", "set effecter states");
735 commands.push_back(std::make_unique<SetStateEffecter>(
736 "platform", "setStateEffecterStates", setStateEffecterStates));
George Liucc9c20d2020-02-05 10:24:11 +0800737
738 auto setNumericEffecterValue = platform->add_subcommand(
739 "SetNumericEffecterValue", "set the value for a PLDM Numeric Effecter");
740 commands.push_back(std::make_unique<SetNumericEffecterValue>(
741 "platform", "setNumericEffecterValue", setNumericEffecterValue));
George Liud6649362019-11-27 19:06:51 +0800742}
743
744} // namespace platform
745} // namespace pldmtool