1 #include "libpldm/entity.h" 2 #include "libpldm/state_set.h" 3 4 #include "common/types.hpp" 5 #include "pldm_cmd_helper.hpp" 6 7 namespace pldmtool 8 { 9 10 namespace platform 11 { 12 13 namespace 14 { 15 16 using namespace pldmtool::helper; 17 std::vector<std::unique_ptr<CommandInterface>> commands; 18 19 } // namespace 20 21 class 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 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 50 auto rc = 51 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART, 52 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES); 53 return {rc, requestMsg}; 54 } 55 56 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 57 { 58 uint8_t completionCode = 0; 59 uint8_t recordData[UINT16_MAX] = {0}; 60 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 79 printPDRMsg(nextRecordHndl, respCnt, recordData); 80 } 81 82 private: 83 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"}, 97 {PLDM_ENTITY_POWER_SUPPLY, "Power Supply"}, 98 {11521, "System (logical)"}, 99 }; 100 101 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 118 const std::array<std::string_view, 4> effecterInit = { 119 "noInit", "useInitPDR", "enableEffecter", "disableEffecter"}; 120 121 std::string getEntityName(pldm::pdr::EntityType type) 122 { 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 133 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 145 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 156 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 216 void printPDRFruRecordSet(uint8_t* data) 217 { 218 if (data == NULL) 219 { 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 237 void printPDREntityAssociation(uint8_t* data) 238 { 239 const std::map<uint8_t, const char*> assocationType = { 240 {PLDM_ENTITY_ASSOCIAION_PHYSICAL, "Physical"}, 241 {PLDM_ENTITY_ASSOCIAION_LOGICAL, "Logical"}, 242 }; 243 244 if (data == NULL) 245 { 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 284 void printNumericEffecterPDR(uint8_t* data) 285 { 286 struct pldm_numeric_effecter_value_pdr* pdr = 287 (struct pldm_numeric_effecter_value_pdr*)data; 288 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(const uint8_t* data) 468 { 469 auto pdr = reinterpret_cast<const pldm_state_effecter_pdr*>(data); 470 471 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle 472 << std::endl; 473 std::cout << "effecterID: " << pdr->effecter_id << std::endl; 474 std::cout << "entityType: " << getEntityName(pdr->entity_type) 475 << std::endl; 476 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; 481 std::cout << "effecterInit: " << effecterInit[pdr->effecter_init] 482 << std::endl; 483 std::cout << "effecterDescriptionPDR: " 484 << (pdr->has_description_pdr ? "true" : "false") << std::endl; 485 std::cout << "compositeEffecterCount: " 486 << unsigned(pdr->composite_effecter_count) << std::endl; 487 488 auto statesPtr = pdr->possible_states; 489 auto compositeEffecterCount = pdr->composite_effecter_count; 490 491 while (compositeEffecterCount--) 492 { 493 auto state = 494 reinterpret_cast<const state_effecter_possible_states*>( 495 statesPtr); 496 std::cout << "stateSetID: " << getStateSetName(state->state_set_id) 497 << std::endl; 498 std::cout << "possibleStatesSize: " 499 << unsigned(state->possible_states_size) << std::endl; 500 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 } 509 } 510 } 511 512 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt, 513 uint8_t* data) 514 { 515 if (data == NULL) 516 { 517 return; 518 } 519 520 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; 524 printCommonPDRHeader(pdr); 525 switch (pdr->type) 526 { 527 case PLDM_STATE_SENSOR_PDR: 528 printStateSensorPDR(data); 529 break; 530 case PLDM_NUMERIC_EFFECTER_PDR: 531 printNumericEffecterPDR(data); 532 break; 533 case PLDM_STATE_EFFECTER_PDR: 534 printStateEffecterPDR(data); 535 break; 536 case PLDM_PDR_ENTITY_ASSOCIATION: 537 printPDREntityAssociation(data); 538 break; 539 case PLDM_PDR_FRU_RECORD_SET: 540 printPDRFruRecordSet(data); 541 break; 542 default: 543 break; 544 } 545 } 546 547 private: 548 uint32_t recordHandle; 549 }; 550 551 class 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 561 // 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; 567 explicit SetStateEffecter(const char* type, const char* name, 568 CLI::App* app) : 569 CommandInterface(type, name, app) 570 { 571 app->add_option( 572 "-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( 579 "-d,--data", effecterData, 580 "Set effecter state data\n" 581 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...") 582 ->required(); 583 } 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 591 if (effecterCount > maxEffecterCount || 592 effecterCount < minEffecterCount) 593 { 594 std::cerr << "Request Message Error: effecterCount size " 595 << effecterCount << "is invalid\n"; 596 auto rc = PLDM_ERROR_INVALID_DATA; 597 return {rc, requestMsg}; 598 } 599 600 if (effecterData.size() > maxEffecterDataSize) 601 { 602 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"; 613 auto rc = PLDM_ERROR_INVALID_DATA; 614 return {rc, requestMsg}; 615 } 616 617 auto rc = encode_set_state_effecter_states_req( 618 instanceId, effecterId, effecterCount, stateField->data(), request); 619 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: " 631 << "rc=" << rc << ",cc=" << (int)completionCode << "\n"; 632 return; 633 } 634 635 std::cout << "SetStateEffecterStates: SUCCESS" << std::endl; 636 } 637 638 private: 639 uint16_t effecterId; 640 uint8_t effecterCount; 641 std::vector<uint8_t> effecterData; 642 }; 643 644 class 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 724 void 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)); 737 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)); 742 } 743 744 } // namespace platform 745 } // namespace pldmtool 746