blob: a12243505b5b578e9850d5442d29da5058030f20 [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
Tom Joseph97a7a762020-07-06 10:37:18 +0530121 const std::array<std::string_view, 4> effecterInit = {
122 "noInit", "useInitPDR", "enableEffecter", "disableEffecter"};
123
Tom Josepha65c0412020-07-03 21:14:44 +0530124 std::string getEntityName(pldm::pdr::EntityType type)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500125 {
126 try
127 {
128 return entityType.at(type);
129 }
130 catch (const std::out_of_range& e)
131 {
132 return std::to_string(static_cast<unsigned>(type)) + "(OEM)";
133 }
134 }
135
Tom Josepha65c0412020-07-03 21:14:44 +0530136 std::string getStateSetName(uint16_t id)
137 {
138 try
139 {
140 return stateSet.at(id);
141 }
142 catch (const std::out_of_range& e)
143 {
144 return std::to_string(id);
145 }
146 }
147
Tom Joseph952abfa2020-07-03 12:25:15 +0530148 void printCommonPDRHeader(const pldm_pdr_hdr* hdr)
149 {
150 std::cout << "recordHandle: " << hdr->record_handle << std::endl;
151 std::cout << "PDRHeaderVersion: " << unsigned(hdr->version)
152 << std::endl;
153 std::cout << "PDRType: " << unsigned(hdr->type) << std::endl;
154 std::cout << "recordChangeNumber: " << hdr->record_change_num
155 << std::endl;
156 std::cout << "dataLength: " << hdr->length << std::endl << std::endl;
157 }
158
Tom Josepha65c0412020-07-03 21:14:44 +0530159 void printPossibleStates(uint8_t possibleStatesSize,
160 const bitfield8_t* states)
161 {
162 uint8_t possibleStatesPos{};
163 auto printStates = [&possibleStatesPos](const bitfield8_t& val) {
164 for (int i = 0; i < CHAR_BIT; i++)
165 {
166 if (val.byte & (1 << i))
167 {
168 std::cout << " " << (possibleStatesPos * CHAR_BIT + i);
169 }
170 }
171 possibleStatesPos++;
172 };
173 std::for_each(states, states + possibleStatesSize, printStates);
174 }
175
176 void printStateSensorPDR(const uint8_t* data)
177 {
178 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(data);
179
180 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
181 << std::endl;
182 std::cout << "sensorID: " << pdr->sensor_id << std::endl;
183 std::cout << "entityType: " << getEntityName(pdr->entity_type)
184 << std::endl;
185 std::cout << "entityInstanceNumber: " << pdr->entity_instance
186 << std::endl;
187 std::cout << "containerID: " << pdr->container_id << std::endl;
188 std::cout << "sensorInit: " << sensorInit[pdr->sensor_init]
189 << std::endl;
190 std::cout << "sensorAuxiliaryNamesPDR: "
191 << (pdr->sensor_auxiliary_names_pdr ? "true" : "false")
192 << std::endl;
193 std::cout << "compositeSensorCount: "
194 << unsigned(pdr->composite_sensor_count) << std::endl;
195
196 auto statesPtr = pdr->possible_states;
197 auto compositeSensorCount = pdr->composite_sensor_count;
198
199 while (compositeSensorCount--)
200 {
201 auto state = reinterpret_cast<const state_sensor_possible_states*>(
202 statesPtr);
203 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
204 << std::endl;
205 std::cout << "possibleStatesSize: "
206 << unsigned(state->possible_states_size) << std::endl;
207 std::cout << "possibleStates:";
208 printPossibleStates(state->possible_states_size, state->states);
209 std::cout << std::endl;
210
211 if (compositeSensorCount)
212 {
213 statesPtr += sizeof(state_sensor_possible_states) +
214 state->possible_states_size - 1;
215 }
216 }
217 }
218
George Liu62d12ec2020-02-05 16:27:08 +0800219 void printPDRFruRecordSet(uint8_t* data)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500220 {
George Liu62d12ec2020-02-05 16:27:08 +0800221 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500222 {
223 return;
224 }
225
226 data += sizeof(pldm_pdr_hdr);
227 pldm_pdr_fru_record_set* pdr =
228 reinterpret_cast<pldm_pdr_fru_record_set*>(data);
229
230 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
231 << std::endl;
232 std::cout << "FRURecordSetIdentifier: " << pdr->fru_rsi << std::endl;
233 std::cout << "entityType: " << getEntityName(pdr->entity_type)
234 << std::endl;
235 std::cout << "entityInstanceNumber: " << pdr->entity_instance_num
236 << std::endl;
237 std::cout << "containerID: " << pdr->container_id << std::endl;
238 }
239
George Liu62d12ec2020-02-05 16:27:08 +0800240 void printPDREntityAssociation(uint8_t* data)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500241 {
242 const std::map<uint8_t, const char*> assocationType = {
243 {PLDM_ENTITY_ASSOCIAION_PHYSICAL, "Physical"},
244 {PLDM_ENTITY_ASSOCIAION_LOGICAL, "Logical"},
245 };
246
George Liu62d12ec2020-02-05 16:27:08 +0800247 if (data == NULL)
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500248 {
249 return;
250 }
251
252 data += sizeof(pldm_pdr_hdr);
253 pldm_pdr_entity_association* pdr =
254 reinterpret_cast<pldm_pdr_entity_association*>(data);
255
256 std::cout << "containerID: " << pdr->container_id << std::endl;
257 std::cout << "associationType: "
258 << assocationType.at(pdr->association_type) << std::endl
259 << std::endl;
260
261 std::cout << "containerEntityType: "
262 << getEntityName(pdr->container.entity_type) << std::endl;
263 std::cout << "containerEntityInstanceNumber: "
264 << pdr->container.entity_instance_num << std::endl;
265 std::cout << "containerEntityContainerID: "
266 << pdr->container.entity_container_id << std::endl;
267
268 std::cout << "containedEntityCount: "
269 << static_cast<unsigned>(pdr->num_children) << std::endl
270 << std::endl;
271
272 auto child = reinterpret_cast<pldm_entity*>(&pdr->children[0]);
273 for (int i = 0; i < pdr->num_children; ++i)
274 {
275 std::cout << "containedEntityType[" << i + 1
276 << "]: " << getEntityName(child->entity_type)
277 << std::endl;
278 std::cout << "containedEntityInstanceNumber[" << i + 1
279 << "]: " << child->entity_instance_num << std::endl;
280 std::cout << "containedEntityContainerID[" << i + 1
281 << "]: " << child->entity_container_id << std::endl
282 << std::endl;
283 ++child;
284 }
285 }
286
George Liu62d12ec2020-02-05 16:27:08 +0800287 void printNumericEffecterPDR(uint8_t* data)
288 {
289 struct pldm_numeric_effecter_value_pdr* pdr =
290 (struct pldm_numeric_effecter_value_pdr*)data;
George Liu62d12ec2020-02-05 16:27:08 +0800291 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
292 << std::endl;
293 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
294 std::cout << "entityType: " << pdr->entity_type << std::endl;
295 std::cout << "entityInstanceNumber: " << pdr->entity_instance
296 << std::endl;
297 std::cout << "containerID: " << pdr->container_id << std::endl;
298 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
299 << std::endl;
300 std::cout << "effecterInit: " << unsigned(pdr->effecter_init)
301 << std::endl;
302 std::cout << "effecterAuxiliaryNames: "
303 << (unsigned(pdr->effecter_auxiliary_names) ? "true"
304 : "false")
305 << std::endl;
306 std::cout << "baseUnit: " << unsigned(pdr->base_unit) << std::endl;
307 std::cout << "unitModifier: " << unsigned(pdr->unit_modifier)
308 << std::endl;
309 std::cout << "rateUnit: " << unsigned(pdr->rate_unit) << std::endl;
310 std::cout << "baseOEMUnitHandle: "
311 << unsigned(pdr->base_oem_unit_handle) << std::endl;
312 std::cout << "auxUnit: " << unsigned(pdr->aux_unit) << std::endl;
313 std::cout << "auxUnitModifier: " << unsigned(pdr->aux_unit_modifier)
314 << std::endl;
315 std::cout << "auxrateUnit: " << unsigned(pdr->aux_rate_unit)
316 << std::endl;
317 std::cout << "auxOEMUnitHandle: " << unsigned(pdr->aux_oem_unit_handle)
318 << std::endl;
319 std::cout << "isLinear: "
320 << (unsigned(pdr->is_linear) ? "true" : "false") << std::endl;
321 std::cout << "effecterDataSize: " << unsigned(pdr->effecter_data_size)
322 << std::endl;
323 std::cout << "resolution: " << pdr->resolution << std::endl;
324 std::cout << "offset: " << pdr->offset << std::endl;
325 std::cout << "accuracy: " << pdr->accuracy << std::endl;
326 std::cout << "plusTolerance: " << unsigned(pdr->plus_tolerance)
327 << std::endl;
328 std::cout << "minusTolerance: " << unsigned(pdr->minus_tolerance)
329 << std::endl;
330 std::cout << "stateTransitionInterval: "
331 << pdr->state_transition_interval << std::endl;
332 std::cout << "TransitionInterval: " << pdr->transition_interval
333 << std::endl;
334 switch (pdr->effecter_data_size)
335 {
336 case PLDM_EFFECTER_DATA_SIZE_UINT8:
337 std::cout << "maxSettable: "
338 << unsigned(pdr->max_set_table.value_u8) << std::endl;
339 std::cout << "minSettable: "
340 << unsigned(pdr->min_set_table.value_u8) << std::endl;
341 break;
342 case PLDM_EFFECTER_DATA_SIZE_SINT8:
343 std::cout << "maxSettable: "
344 << unsigned(pdr->max_set_table.value_s8) << std::endl;
345 std::cout << "minSettable: "
346 << unsigned(pdr->min_set_table.value_s8) << std::endl;
347 break;
348 case PLDM_EFFECTER_DATA_SIZE_UINT16:
349 std::cout << "maxSettable: " << pdr->max_set_table.value_u16
350 << std::endl;
351 std::cout << "minSettable: " << pdr->min_set_table.value_u16
352 << std::endl;
353 break;
354 case PLDM_EFFECTER_DATA_SIZE_SINT16:
355 std::cout << "maxSettable: " << pdr->max_set_table.value_s16
356 << std::endl;
357 std::cout << "minSettable: " << pdr->min_set_table.value_s16
358 << std::endl;
359 break;
360 case PLDM_EFFECTER_DATA_SIZE_UINT32:
361 std::cout << "maxSettable: " << pdr->max_set_table.value_u32
362 << std::endl;
363 std::cout << "minSettable: " << pdr->min_set_table.value_u32
364 << std::endl;
365 break;
366 case PLDM_EFFECTER_DATA_SIZE_SINT32:
367 std::cout << "maxSettable: " << pdr->max_set_table.value_s32
368 << std::endl;
369 std::cout << "minSettable: " << pdr->min_set_table.value_s32
370 << std::endl;
371 break;
372 default:
373 break;
374 }
375 std::cout << "rangeFieldFormat: " << unsigned(pdr->range_field_format)
376 << std::endl;
377 std::cout << "rangeFieldSupport: "
378 << unsigned(pdr->range_field_support.byte) << std::endl;
379 switch (pdr->range_field_format)
380 {
381 case PLDM_RANGE_FIELD_FORMAT_UINT8:
382 std::cout << "nominalValue: "
383 << unsigned(pdr->nominal_value.value_u8) << std::endl;
384 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_u8)
385 << std::endl;
386 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_u8)
387 << std::endl;
388 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_u8)
389 << std::endl;
390 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_u8)
391 << std::endl;
392 break;
393 case PLDM_RANGE_FIELD_FORMAT_SINT8:
394 std::cout << "nominalValue: "
395 << unsigned(pdr->nominal_value.value_s8) << std::endl;
396 std::cout << "normalMax: " << unsigned(pdr->normal_max.value_s8)
397 << std::endl;
398 std::cout << "normalMin: " << unsigned(pdr->normal_min.value_s8)
399 << std::endl;
400 std::cout << "ratedMax: " << unsigned(pdr->rated_max.value_s8)
401 << std::endl;
402 std::cout << "ratedMin: " << unsigned(pdr->rated_min.value_s8)
403 << std::endl;
404 break;
405 case PLDM_RANGE_FIELD_FORMAT_UINT16:
406 std::cout << "nominalValue: " << pdr->nominal_value.value_u16
407 << std::endl;
408 std::cout << "normalMax: " << pdr->normal_max.value_u16
409 << std::endl;
410 std::cout << "normalMin: " << pdr->normal_min.value_u16
411 << std::endl;
412 std::cout << "ratedMax: " << pdr->rated_max.value_u16
413 << std::endl;
414 std::cout << "ratedMin: " << pdr->rated_min.value_u16
415 << std::endl;
416 break;
417 case PLDM_RANGE_FIELD_FORMAT_SINT16:
418 std::cout << "nominalValue: " << pdr->nominal_value.value_s16
419 << std::endl;
420 std::cout << "normalMax: " << pdr->normal_max.value_s16
421 << std::endl;
422 std::cout << "normalMin: " << pdr->normal_min.value_s16
423 << std::endl;
424 std::cout << "ratedMax: " << pdr->rated_max.value_s16
425 << std::endl;
426 std::cout << "ratedMin: " << pdr->rated_min.value_s16
427 << std::endl;
428 break;
429 case PLDM_RANGE_FIELD_FORMAT_UINT32:
430 std::cout << "nominalValue: " << pdr->nominal_value.value_u32
431 << std::endl;
432 std::cout << "normalMax: " << pdr->normal_max.value_u32
433 << std::endl;
434 std::cout << "normalMin: " << pdr->normal_min.value_u32
435 << std::endl;
436 std::cout << "ratedMax: " << pdr->rated_max.value_u32
437 << std::endl;
438 std::cout << "ratedMin: " << pdr->rated_min.value_u32
439 << std::endl;
440 break;
441 case PLDM_RANGE_FIELD_FORMAT_SINT32:
442 std::cout << "nominalValue: " << pdr->nominal_value.value_s32
443 << std::endl;
444 std::cout << "normalMax: " << pdr->normal_max.value_s32
445 << std::endl;
446 std::cout << "normalMin: " << pdr->normal_min.value_s32
447 << std::endl;
448 std::cout << "ratedMax: " << pdr->rated_max.value_s32
449 << std::endl;
450 std::cout << "ratedMin: " << pdr->rated_min.value_s32
451 << std::endl;
452 break;
453 case PLDM_RANGE_FIELD_FORMAT_REAL32:
454 std::cout << "nominalValue: " << pdr->nominal_value.value_f32
455 << std::endl;
456 std::cout << "normalMax: " << pdr->normal_max.value_f32
457 << std::endl;
458 std::cout << "normalMin: " << pdr->normal_min.value_f32
459 << std::endl;
460 std::cout << "ratedMax: " << pdr->rated_max.value_f32
461 << std::endl;
462 std::cout << "ratedMin: " << pdr->rated_min.value_f32
463 << std::endl;
464 break;
465 default:
466 break;
467 }
468 }
469
Tom Joseph97a7a762020-07-06 10:37:18 +0530470 void printStateEffecterPDR(const uint8_t* data)
George Liu62d12ec2020-02-05 16:27:08 +0800471 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530472 auto pdr = reinterpret_cast<const pldm_state_effecter_pdr*>(data);
George Liu62d12ec2020-02-05 16:27:08 +0800473
George Liud6649362019-11-27 19:06:51 +0800474 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
475 << std::endl;
476 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530477 std::cout << "entityType: " << getEntityName(pdr->entity_type)
478 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800479 std::cout << "entityInstanceNumber: " << pdr->entity_instance
480 << std::endl;
481 std::cout << "containerID: " << pdr->container_id << std::endl;
482 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
483 << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530484 std::cout << "effecterInit: " << effecterInit[pdr->effecter_init]
George Liud6649362019-11-27 19:06:51 +0800485 << std::endl;
486 std::cout << "effecterDescriptionPDR: "
Tom Joseph97a7a762020-07-06 10:37:18 +0530487 << (pdr->has_description_pdr ? "true" : "false") << std::endl;
George Liud6649362019-11-27 19:06:51 +0800488 std::cout << "compositeEffecterCount: "
489 << unsigned(pdr->composite_effecter_count) << std::endl;
490
Tom Joseph97a7a762020-07-06 10:37:18 +0530491 auto statesPtr = pdr->possible_states;
492 auto compositeEffecterCount = pdr->composite_effecter_count;
493
494 while (compositeEffecterCount--)
George Liud6649362019-11-27 19:06:51 +0800495 {
Tom Joseph97a7a762020-07-06 10:37:18 +0530496 auto state =
497 reinterpret_cast<const state_effecter_possible_states*>(
498 statesPtr);
499 std::cout << "stateSetID: " << getStateSetName(state->state_set_id)
500 << std::endl;
George Liud6649362019-11-27 19:06:51 +0800501 std::cout << "possibleStatesSize: "
502 << unsigned(state->possible_states_size) << std::endl;
Tom Joseph97a7a762020-07-06 10:37:18 +0530503 std::cout << "possibleStates:";
504 printPossibleStates(state->possible_states_size, state->states);
505 std::cout << std::endl;
506
507 if (compositeEffecterCount)
508 {
509 statesPtr += sizeof(state_effecter_possible_states) +
510 state->possible_states_size - 1;
511 }
George Liud6649362019-11-27 19:06:51 +0800512 }
513 }
514
515 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt,
George Liu62d12ec2020-02-05 16:27:08 +0800516 uint8_t* data)
George Liud6649362019-11-27 19:06:51 +0800517 {
George Liu62d12ec2020-02-05 16:27:08 +0800518 if (data == NULL)
George Liud6649362019-11-27 19:06:51 +0800519 {
520 return;
521 }
522
George Liud6649362019-11-27 19:06:51 +0800523 std::cout << "nextRecordHandle: " << nextRecordHndl << std::endl;
524 std::cout << "responseCount: " << respCnt << std::endl;
525
526 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
Tom Joseph952abfa2020-07-03 12:25:15 +0530527 printCommonPDRHeader(pdr);
George Liud6649362019-11-27 19:06:51 +0800528 switch (pdr->type)
529 {
Tom Josepha65c0412020-07-03 21:14:44 +0530530 case PLDM_STATE_SENSOR_PDR:
531 printStateSensorPDR(data);
532 break;
George Liu62d12ec2020-02-05 16:27:08 +0800533 case PLDM_NUMERIC_EFFECTER_PDR:
534 printNumericEffecterPDR(data);
535 break;
George Liud6649362019-11-27 19:06:51 +0800536 case PLDM_STATE_EFFECTER_PDR:
George Liu62d12ec2020-02-05 16:27:08 +0800537 printStateEffecterPDR(data);
George Liud6649362019-11-27 19:06:51 +0800538 break;
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500539 case PLDM_PDR_ENTITY_ASSOCIATION:
George Liu62d12ec2020-02-05 16:27:08 +0800540 printPDREntityAssociation(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500541 break;
542 case PLDM_PDR_FRU_RECORD_SET:
George Liu62d12ec2020-02-05 16:27:08 +0800543 printPDRFruRecordSet(data);
Deepak Kodihalli5544ccd2020-03-15 23:36:16 -0500544 break;
George Liud6649362019-11-27 19:06:51 +0800545 default:
546 break;
547 }
548 }
549
550 private:
551 uint32_t recordHandle;
552};
553
554class SetStateEffecter : public CommandInterface
555{
556 public:
557 ~SetStateEffecter() = default;
558 SetStateEffecter() = delete;
559 SetStateEffecter(const SetStateEffecter&) = delete;
560 SetStateEffecter(SetStateEffecter&&) = default;
561 SetStateEffecter& operator=(const SetStateEffecter&) = delete;
562 SetStateEffecter& operator=(SetStateEffecter&&) = default;
563
George Liuba4c1fb2020-02-05 14:13:30 +0800564 // compositeEffecterCount(value: 0x01 to 0x08) * stateField(2)
565 static constexpr auto maxEffecterDataSize = 16;
566
567 // compositeEffecterCount(value: 0x01 to 0x08)
568 static constexpr auto minEffecterCount = 1;
569 static constexpr auto maxEffecterCount = 8;
George Liud6649362019-11-27 19:06:51 +0800570 explicit SetStateEffecter(const char* type, const char* name,
571 CLI::App* app) :
572 CommandInterface(type, name, app)
573 {
574 app->add_option(
George Liuba4c1fb2020-02-05 14:13:30 +0800575 "-i, --id", effecterId,
576 "A handle that is used to identify and access the effecter")
577 ->required();
578 app->add_option("-c, --count", effecterCount,
579 "The number of individual sets of effecter information")
580 ->required();
581 app->add_option(
George Liud6649362019-11-27 19:06:51 +0800582 "-d,--data", effecterData,
George Liuba4c1fb2020-02-05 14:13:30 +0800583 "Set effecter state data\n"
584 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...")
585 ->required();
George Liud6649362019-11-27 19:06:51 +0800586 }
587
588 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
589 {
590 std::vector<uint8_t> requestMsg(
591 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES);
592 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
593
George Liuba4c1fb2020-02-05 14:13:30 +0800594 if (effecterCount > maxEffecterCount ||
595 effecterCount < minEffecterCount)
George Liud6649362019-11-27 19:06:51 +0800596 {
George Liuba4c1fb2020-02-05 14:13:30 +0800597 std::cerr << "Request Message Error: effecterCount size "
598 << effecterCount << "is invalid\n";
George Liud6649362019-11-27 19:06:51 +0800599 auto rc = PLDM_ERROR_INVALID_DATA;
600 return {rc, requestMsg};
601 }
602
George Liuba4c1fb2020-02-05 14:13:30 +0800603 if (effecterData.size() > maxEffecterDataSize)
George Liud6649362019-11-27 19:06:51 +0800604 {
George Liuba4c1fb2020-02-05 14:13:30 +0800605 std::cerr << "Request Message Error: effecterData size "
606 << effecterData.size() << "is invalid\n";
607 auto rc = PLDM_ERROR_INVALID_DATA;
608 return {rc, requestMsg};
609 }
610
611 auto stateField = parseEffecterData(effecterData, effecterCount);
612 if (!stateField)
613 {
614 std::cerr << "Failed to parse effecter data, effecterCount size "
615 << effecterCount << "\n";
George Liud6649362019-11-27 19:06:51 +0800616 auto rc = PLDM_ERROR_INVALID_DATA;
617 return {rc, requestMsg};
618 }
619
620 auto rc = encode_set_state_effecter_states_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600621 instanceId, effecterId, effecterCount, stateField->data(), request);
George Liud6649362019-11-27 19:06:51 +0800622 return {rc, requestMsg};
623 }
624
625 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
626 {
627 uint8_t completionCode = 0;
628 auto rc = decode_set_state_effecter_states_resp(
629 responsePtr, payloadLength, &completionCode);
630
631 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
632 {
633 std::cerr << "Response Message Error: "
George Liuba4c1fb2020-02-05 14:13:30 +0800634 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
George Liud6649362019-11-27 19:06:51 +0800635 return;
636 }
637
638 std::cout << "SetStateEffecterStates: SUCCESS" << std::endl;
639 }
640
641 private:
George Liuba4c1fb2020-02-05 14:13:30 +0800642 uint16_t effecterId;
643 uint8_t effecterCount;
George Liud6649362019-11-27 19:06:51 +0800644 std::vector<uint8_t> effecterData;
645};
646
George Liucc9c20d2020-02-05 10:24:11 +0800647class SetNumericEffecterValue : public CommandInterface
648{
649 public:
650 ~SetNumericEffecterValue() = default;
651 SetNumericEffecterValue() = delete;
652 SetNumericEffecterValue(const SetNumericEffecterValue&) = delete;
653 SetNumericEffecterValue(SetNumericEffecterValue&&) = default;
654 SetNumericEffecterValue& operator=(const SetNumericEffecterValue&) = delete;
655 SetNumericEffecterValue& operator=(SetNumericEffecterValue&&) = default;
656
657 explicit SetNumericEffecterValue(const char* type, const char* name,
658 CLI::App* app) :
659 CommandInterface(type, name, app)
660 {
661 app->add_option(
662 "-i, --id", effecterId,
663 "A handle that is used to identify and access the effecter")
664 ->required();
665 app->add_option("-s, --size", effecterDataSize,
666 "The bit width and format of the setting value for the "
667 "effecter. enum value: {uint8, sint8, uint16, sint16, "
668 "uint32, sint32}\n")
669 ->required();
670 app->add_option("-d,--data", maxEffecterValue,
671 "The setting value of numeric effecter being "
672 "requested\n")
673 ->required();
674 }
675
676 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
677 {
678 std::vector<uint8_t> requestMsg(
679 sizeof(pldm_msg_hdr) +
680 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3);
681
682 uint8_t* effecterValue = (uint8_t*)&maxEffecterValue;
683
684 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
685 size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES;
686
687 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
688 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16)
689 {
690 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1;
691 }
692 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
693 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32)
694 {
695 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3;
696 }
697 auto rc = encode_set_numeric_effecter_value_req(
698 0, effecterId, effecterDataSize, effecterValue, request,
699 payload_length);
700
701 return {rc, requestMsg};
702 }
703
704 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
705 {
706 uint8_t completionCode = 0;
707 auto rc = decode_set_numeric_effecter_value_resp(
708 responsePtr, payloadLength, &completionCode);
709
710 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
711 {
712 std::cerr << "Response Message Error: "
713 << "rc=" << rc << ",cc=" << (int)completionCode
714 << std::endl;
715 return;
716 }
717
718 std::cout << "SetNumericEffecterValue: SUCCESS" << std::endl;
719 }
720
721 private:
722 uint16_t effecterId;
723 uint8_t effecterDataSize;
724 uint64_t maxEffecterValue;
725};
726
George Liud6649362019-11-27 19:06:51 +0800727void registerCommand(CLI::App& app)
728{
729 auto platform = app.add_subcommand("platform", "platform type command");
730 platform->require_subcommand(1);
731
732 auto getPDR =
733 platform->add_subcommand("GetPDR", "get platform descriptor records");
734 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR));
735
736 auto setStateEffecterStates = platform->add_subcommand(
737 "SetStateEffecterStates", "set effecter states");
738 commands.push_back(std::make_unique<SetStateEffecter>(
739 "platform", "setStateEffecterStates", setStateEffecterStates));
George Liucc9c20d2020-02-05 10:24:11 +0800740
741 auto setNumericEffecterValue = platform->add_subcommand(
742 "SetNumericEffecterValue", "set the value for a PLDM Numeric Effecter");
743 commands.push_back(std::make_unique<SetNumericEffecterValue>(
744 "platform", "setNumericEffecterValue", setNumericEffecterValue));
George Liud6649362019-11-27 19:06:51 +0800745}
746
747} // namespace platform
748} // namespace pldmtool