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