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 #include <cstddef> 8 #include <map> 9 10 #ifdef OEM_IBM 11 #include "oem/ibm/oem_ibm_state_set.hpp" 12 #endif 13 14 using namespace pldm::utils; 15 16 namespace pldmtool 17 { 18 19 namespace platform 20 { 21 22 namespace 23 { 24 25 using namespace pldmtool::helper; 26 27 static const std::map<uint8_t, std::string> sensorPresState{ 28 {PLDM_SENSOR_UNKNOWN, "Sensor Unknown"}, 29 {PLDM_SENSOR_NORMAL, "Sensor Normal"}, 30 {PLDM_SENSOR_WARNING, "Sensor Warning"}, 31 {PLDM_SENSOR_CRITICAL, "Sensor Critical"}, 32 {PLDM_SENSOR_FATAL, "Sensor Fatal"}, 33 {PLDM_SENSOR_LOWERWARNING, "Sensor Lower Warning"}, 34 {PLDM_SENSOR_LOWERCRITICAL, "Sensor Lower Critical"}, 35 {PLDM_SENSOR_LOWERFATAL, "Sensor Lower Fatal"}, 36 {PLDM_SENSOR_UPPERWARNING, "Sensor Upper Warning"}, 37 {PLDM_SENSOR_UPPERCRITICAL, "Sensor Upper Critical"}, 38 {PLDM_SENSOR_UPPERFATAL, "Sensor Upper Fatal"}}; 39 40 static const std::map<uint8_t, std::string> sensorOpState{ 41 {PLDM_SENSOR_ENABLED, "Sensor Enabled"}, 42 {PLDM_SENSOR_DISABLED, "Sensor Disabled"}, 43 {PLDM_SENSOR_UNAVAILABLE, "Sensor Unavailable"}, 44 {PLDM_SENSOR_STATUSUNKOWN, "Sensor Status Unknown"}, 45 {PLDM_SENSOR_FAILED, "Sensor Failed"}, 46 {PLDM_SENSOR_INITIALIZING, "Sensor Sensor Intializing"}, 47 {PLDM_SENSOR_SHUTTINGDOWN, "Sensor Shutting down"}, 48 {PLDM_SENSOR_INTEST, "Sensor Intest"}}; 49 50 std::vector<std::unique_ptr<CommandInterface>> commands; 51 52 } // namespace 53 54 using ordered_json = nlohmann::ordered_json; 55 56 class GetPDR : public CommandInterface 57 { 58 public: 59 ~GetPDR() = default; 60 GetPDR() = delete; 61 GetPDR(const GetPDR&) = delete; 62 GetPDR(GetPDR&&) = default; 63 GetPDR& operator=(const GetPDR&) = delete; 64 GetPDR& operator=(GetPDR&&) = default; 65 66 using CommandInterface::CommandInterface; 67 68 explicit GetPDR(const char* type, const char* name, CLI::App* app) : 69 CommandInterface(type, name, app) 70 { 71 auto pdrOptionGroup = app->add_option_group( 72 "Required Option", 73 "Retrieve individual PDR, all PDRs, or PDRs of a requested type"); 74 pdrOptionGroup->add_option( 75 "-d,--data", recordHandle, 76 "retrieve individual PDRs from a PDR Repository\n" 77 "eg: The recordHandle value for the PDR to be retrieved and 0 " 78 "means get first PDR in the repository."); 79 pdrRecType = ""; 80 pdrOptionGroup->add_option("-t, --type", pdrRecType, 81 "retrieve all PDRs of the requested type\n" 82 "supported types:\n" 83 "[terminusLocator, stateSensor, " 84 "numericEffecter, stateEffecter, " 85 "EntityAssociation, fruRecord, ... ]"); 86 allPDRs = false; 87 pdrOptionGroup->add_flag("-a, --all", allPDRs, 88 "retrieve all PDRs from a PDR repository"); 89 pdrOptionGroup->require_option(1); 90 } 91 92 void exec() override 93 { 94 if (allPDRs || !pdrRecType.empty()) 95 { 96 if (!pdrRecType.empty()) 97 { 98 std::transform(pdrRecType.begin(), pdrRecType.end(), 99 pdrRecType.begin(), tolower); 100 } 101 102 // start the array 103 std::cout << "[\n"; 104 105 // Retrieve all PDR records starting from the first 106 recordHandle = 0; 107 uint32_t prevRecordHandle = 0; 108 std::map<uint32_t, uint32_t> recordsSeen; 109 do 110 { 111 CommandInterface::exec(); 112 // recordHandle is updated to nextRecord when 113 // CommandInterface::exec() is successful. 114 // In case of any error, return. 115 if (recordHandle == prevRecordHandle) 116 { 117 return; 118 } 119 120 // check for circular references. 121 auto result = 122 recordsSeen.emplace(recordHandle, prevRecordHandle); 123 if (!result.second) 124 { 125 std::cerr 126 << "Record handle " << recordHandle 127 << " has multiple references: " << result.first->second 128 << ", " << prevRecordHandle << "\n"; 129 return; 130 } 131 prevRecordHandle = recordHandle; 132 133 if (recordHandle != 0) 134 { 135 // close the array 136 std::cout << ","; 137 } 138 } while (recordHandle != 0); 139 140 // close the array 141 std::cout << "]\n"; 142 } 143 else 144 { 145 CommandInterface::exec(); 146 } 147 } 148 149 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 150 { 151 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 152 PLDM_GET_PDR_REQ_BYTES); 153 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 154 155 auto rc = 156 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART, 157 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES); 158 return {rc, requestMsg}; 159 } 160 161 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 162 { 163 uint8_t completionCode = 0; 164 uint8_t recordData[UINT16_MAX] = {0}; 165 uint32_t nextRecordHndl = 0; 166 uint32_t nextDataTransferHndl = 0; 167 uint8_t transferFlag = 0; 168 uint16_t respCnt = 0; 169 uint8_t transferCRC = 0; 170 171 auto rc = decode_get_pdr_resp( 172 responsePtr, payloadLength, &completionCode, &nextRecordHndl, 173 &nextDataTransferHndl, &transferFlag, &respCnt, recordData, 174 sizeof(recordData), &transferCRC); 175 176 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) 177 { 178 std::cerr << "Response Message Error: " 179 << "rc=" << rc << ",cc=" << (int)completionCode 180 << std::endl; 181 return; 182 } 183 184 printPDRMsg(nextRecordHndl, respCnt, recordData); 185 recordHandle = nextRecordHndl; 186 } 187 188 private: 189 const std::map<pldm::pdr::EntityType, std::string> entityType = { 190 {PLDM_ENTITY_UNSPECIFIED, "Unspecified"}, 191 {PLDM_ENTITY_OTHER, "Other"}, 192 {PLDM_ENTITY_NETWORK, "Network"}, 193 {PLDM_ENTITY_GROUP, "Group"}, 194 {PLDM_ENTITY_REMOTE_MGMT_COMM_DEVICE, 195 "Remote Management Communication Device"}, 196 {PLDM_ENTITY_EXTERNAL_ENVIRONMENT, "External Environment"}, 197 {PLDM_ENTITY_COMM_CHANNEL, " Communication Channel"}, 198 {PLDM_ENTITY_TERMINUS, "PLDM Terminus"}, 199 {PLDM_ENTITY_PLATFORM_EVENT_LOG, " Platform Event Log"}, 200 {PLDM_ENTITY_KEYPAD, "keypad"}, 201 {PLDM_ENTITY_SWITCH, "Switch"}, 202 {PLDM_ENTITY_PUSHBUTTON, "Pushbutton"}, 203 {PLDM_ENTITY_DISPLAY, "Display"}, 204 {PLDM_ENTITY_INDICATOR, "Indicator"}, 205 {PLDM_ENTITY_SYS_MGMT_SW, "System Management Software"}, 206 {PLDM_ENTITY_SYS_FIRMWARE, "System Firmware"}, 207 {PLDM_ENTITY_OPERATING_SYS, "Operating System"}, 208 {PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER, "Virtual Machine Manager"}, 209 {PLDM_ENTITY_OS_LOADER, "OS Loader"}, 210 {PLDM_ENTITY_DEVICE_DRIVER, "Device Driver"}, 211 {PLDM_ENTITY_MGMT_CONTROLLER_FW, "Management Controller Firmware"}, 212 {PLDM_ENTITY_SYSTEM_CHASSIS, "System chassis (main enclosure)"}, 213 {PLDM_ENTITY_SUB_CHASSIS, "Sub-chassis"}, 214 {PLDM_ENTITY_DISK_DRIVE_BAY, "Disk Drive Bay"}, 215 {PLDM_ENTITY_PERIPHERAL_BAY, "Peripheral Bay"}, 216 {PLDM_ENTITY_DEVICE_BAY, "Device bay"}, 217 {PLDM_ENTITY_DOOR, "Door"}, 218 {PLDM_ENTITY_ACCESS_PANEL, "Access Panel"}, 219 {PLDM_ENTITY_COVER, "Cover"}, 220 {PLDM_ENTITY_BOARD, "Board"}, 221 {PLDM_ENTITY_CARD, "Card"}, 222 {PLDM_ENTITY_MODULE, "Module"}, 223 {PLDM_ENTITY_SYS_MGMT_MODULE, "System management module"}, 224 {PLDM_ENTITY_SYS_BOARD, "System Board"}, 225 {PLDM_ENTITY_MEMORY_BOARD, "Memory Board"}, 226 {PLDM_ENTITY_MEMORY_MODULE, "Memory Module"}, 227 {PLDM_ENTITY_PROC_MODULE, "Processor Module"}, 228 {PLDM_ENTITY_ADD_IN_CARD, "Add-in Card"}, 229 {PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD, 230 "Chassis front panel board(control panel)"}, 231 {PLDM_ENTITY_BACK_PANEL_BOARD, "Back panel board"}, 232 {PLDM_ENTITY_POWER_MGMT, "Power management board"}, 233 {PLDM_ENTITY_POWER_SYS_BOARD, "Power system board"}, 234 {PLDM_ENTITY_DRIVE_BACKPLANE, "Drive backplane"}, 235 {PLDM_ENTITY_SYS_INTERNAL_EXPANSION_BOARD, 236 "System internal expansion board"}, 237 {PLDM_ENTITY_OTHER_SYS_BOARD, "Other system board"}, 238 {PLDM_ENTITY_CHASSIS_BACK_PANEL_BOARD, "Chassis back panel board"}, 239 {PLDM_ENTITY_PROCESSING_BLADE, "Processing blade"}, 240 {PLDM_ENTITY_CONNECTIVITY_SWITCH, "Connectivity switch"}, 241 {PLDM_ENTITY_PROC_MEMORY_MODULE, "Processor/Memory Module"}, 242 {PLDM_ENTITY_IO_MODULE, "I/O Module"}, 243 {PLDM_ENTITY_PROC_IO_MODULE, "Processor I/O Module"}, 244 {PLDM_ENTITY_COOLING_DEVICE, "Cooling device"}, 245 {PLDM_ENTITY_COOLING_SUBSYSTEM, "Cooling subsystem"}, 246 {PLDM_ENTITY_COOLING_UNIT, "Cooling Unit"}, 247 {PLDM_ENTITY_FAN, "Fan"}, 248 {PLDM_ENTITY_PELTIER_COOLING_DEVICE, "Peltier Cooling Device"}, 249 {PLDM_ENTITY_LIQUID_COOLING_DEVICE, "Liquid Cooling Device"}, 250 {PLDM_ENTITY_LIQUID_COOLING_SUBSYSTEM, "Liquid Colling Subsystem"}, 251 {PLDM_ENTITY_OTHER_STORAGE_DEVICE, "Other Storage Device"}, 252 {PLDM_ENTITY_FLOPPY_DRIVE, "Floppy Drive"}, 253 {PLDM_ENTITY_FIXED_DISK_HARD_DRIVE, "Hard Drive"}, 254 {PLDM_ENTITY_CD_DRIVE, "CD Drive"}, 255 {PLDM_ENTITY_CD_DVD_DRIVE, "CD/DVD Drive"}, 256 {PLDM_ENTITY_OTHER_SILICON_STORAGE_DEVICE, 257 "Other Silicon Storage Device"}, 258 {PLDM_ENTITY_SOLID_STATE_SRIVE, "Solid State Drive"}, 259 {PLDM_ENTITY_POWER_SUPPLY, "Power supply"}, 260 {PLDM_ENTITY_BATTERY, "Battery"}, 261 {PLDM_ENTITY_SUPER_CAPACITOR, "Super Capacitor"}, 262 {PLDM_ENTITY_POWER_CONVERTER, "Power Converter"}, 263 {PLDM_ENTITY_DC_DC_CONVERTER, "DC-DC Converter"}, 264 {PLDM_ENTITY_AC_MAINS_POWER_SUPPLY, "AC mains power supply"}, 265 {PLDM_ENTITY_DC_MAINS_POWER_SUPPLY, "DC mains power supply"}, 266 {PLDM_ENTITY_PROC, "Processor"}, 267 {PLDM_ENTITY_CHIPSET_COMPONENT, "Chipset Component"}, 268 {PLDM_ENTITY_MGMT_CONTROLLER, "Management Controller"}, 269 {PLDM_ENTITY_PERIPHERAL_CONTROLLER, "Peripheral Controller"}, 270 {PLDM_ENTITY_SEEPROM, "SEEPROM"}, 271 {PLDM_ENTITY_NVRAM_CHIP, "NVRAM Chip"}, 272 {PLDM_ENTITY_FLASH_MEMORY_CHIP, "FLASH Memory chip"}, 273 {PLDM_ENTITY_MEMORY_CHIP, "Memory Chip"}, 274 {PLDM_ENTITY_MEMORY_CONTROLLER, "Memory Controller"}, 275 {PLDM_ENTITY_NETWORK_CONTROLLER, "Network Controller"}, 276 {PLDM_ENTITY_IO_CONTROLLER, "I/O Controller"}, 277 {PLDM_ENTITY_SOUTH_BRIDGE, "South Bridge"}, 278 {PLDM_ENTITY_REAL_TIME_CLOCK, "Real Time Clock (RTC)"}, 279 {PLDM_ENTITY_FPGA_CPLD_DEVICE, "FPGA/CPLD Configurable Logic Device"}, 280 {PLDM_ENTITY_OTHER_BUS, "Other Bus"}, 281 {PLDM_ENTITY_SYS_BUS, "System Bus"}, 282 {PLDM_ENTITY_I2C_BUS, "I2C Bus"}, 283 {PLDM_ENTITY_SMBUS_BUS, "SMBus Bus"}, 284 {PLDM_ENTITY_SPI_BUS, "SPI Bus"}, 285 {PLDM_ENTITY_PCI_BUS, "PCI Bus"}, 286 {PLDM_ENTITY_PCI_EXPRESS_BUS, "PCI Express Bus"}, 287 {PLDM_ENTITY_PECI_BUS, "PECI Bus"}, 288 {PLDM_ENTITY_LPC_BUS, "LPC Bus"}, 289 {PLDM_ENTITY_USB_BUS, "USB Bus"}, 290 {PLDM_ENTITY_FIREWIRE_BUS, "FireWire Bus"}, 291 {PLDM_ENTITY_SCSI_BUS, "SCSI Bus"}, 292 {PLDM_ENTITY_SATA_SAS_BUS, "SATA/SAS Bus"}, 293 {PLDM_ENTITY_PROC_FRONT_SIDE_BUS, "Processor/Front-side Bus"}, 294 {PLDM_ENTITY_INTER_PROC_BUS, "Inter-processor Bus"}, 295 {PLDM_ENTITY_CONNECTOR, "Connector"}, 296 {PLDM_ENTITY_SLOT, "Slot"}, 297 {PLDM_ENTITY_CABLE, "Cable(electrical or optical)"}, 298 {PLDM_ENTITY_INTERCONNECT, "Interconnect"}, 299 {PLDM_ENTITY_PLUG, "Plug"}, 300 {PLDM_ENTITY_SOCKET, "Socket"}, 301 }; 302 303 const std::map<uint16_t, std::string> stateSet = { 304 {PLDM_STATE_SET_HEALTH_STATE, "Health State"}, 305 {PLDM_STATE_SET_AVAILABILITY, "Availability"}, 306 {PLDM_STATE_SET_PREDICTIVE_CONDITION, "Predictive Condition"}, 307 {PLDM_STATE_SET_REDUNDANCY_STATUS, "Redundancy Status"}, 308 {PLDM_STATE_SET_HEALTH_REDUNDANCY_TREND, "Health/Redundancy Trend"}, 309 {PLDM_STATE_SET_GROUP_RESOURCE_LEVEL, "Group Resource Level"}, 310 {PLDM_STATE_SET_REDUNDANCY_ENTITY_ROLE, "Redundancy Entity Role"}, 311 {PLDM_STATE_SET_OPERATIONAL_STATUS, "Operational Status"}, 312 {PLDM_STATE_SET_OPERATIONAL_STRESS_STATUS, "Operational Stress Status"}, 313 {PLDM_STATE_SET_OPERATIONAL_FAULT_STATUS, "Operational Fault Status"}, 314 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS, 315 "Operational Running Status"}, 316 {PLDM_STATE_SET_OPERATIONAL_CONNECTION_STATUS, 317 "Operational Connection Status"}, 318 {PLDM_STATE_SET_PRESENCE, "Presence"}, 319 {PLDM_STATE_SET_PERFORMANCE, "Performance"}, 320 {PLDM_STATE_SET_CONFIGURATION_STATE, "Configuration State"}, 321 {PLDM_STATE_SET_CHANGED_CONFIGURATION, "Changed Configuration"}, 322 {PLDM_STATE_SET_IDENTIFY_STATE, "Identify State"}, 323 {PLDM_STATE_SET_VERSION, "Version"}, 324 {PLDM_STATE_SET_ALARM_STATE, "Alarm State"}, 325 {PLDM_STATE_SET_DEVICE_INITIALIZATION, "Device Initialization"}, 326 {PLDM_STATE_SET_THERMAL_TRIP, "Thermal Trip"}, 327 {PLDM_STATE_SET_HEARTBEAT, "Heartbeat"}, 328 {PLDM_STATE_SET_LINK_STATE, "Link State"}, 329 {PLDM_STATE_SET_SMOKE_STATE, "Smoke State"}, 330 {PLDM_STATE_SET_HUMIDITY_STATE, "Humidity State"}, 331 {PLDM_STATE_SET_DOOR_STATE, "Door State"}, 332 {PLDM_STATE_SET_SWITCH_STATE, "Switch State"}, 333 {PLDM_STATE_SET_LOCK_STATE, "Lock State"}, 334 {PLDM_STATE_SET_PHYSICAL_SECURITY, "Physical Security"}, 335 {PLDM_STATE_SET_DOCK_AUTHORIZATION, "Dock Authorization"}, 336 {PLDM_STATE_SET_HW_SECURITY, "Hardware Security"}, 337 {PLDM_STATE_SET_PHYSICAL_COMM_CONNECTION, 338 "Physical Communication Connection"}, 339 {PLDM_STATE_SET_COMM_LEASH_STATUS, "Communication Leash Status"}, 340 {PLDM_STATE_SET_FOREIGN_NW_DETECTION_STATUS, 341 "Foreign Network Detection Status"}, 342 {PLDM_STATE_SET_PASSWORD_PROTECTED_ACCESS_SECURITY, 343 "Password-Protected Access Security"}, 344 {PLDM_STATE_SET_SECURITY_ACCESS_PRIVILEGE_LEVEL, 345 "Security Access –PrivilegeLevel"}, 346 {PLDM_STATE_SET_SESSION_AUDIT, "PLDM Session Audit"}, 347 {PLDM_STATE_SET_SW_TERMINATION_STATUS, "Software Termination Status"}, 348 {PLDM_STATE_SET_STORAGE_MEDIA_ACTIVITY, "Storage Media Activity"}, 349 {PLDM_STATE_SET_BOOT_RESTART_CAUSE, "Boot/Restart Cause"}, 350 {PLDM_STATE_SET_BOOT_RESTART_REQUEST, "Boot/Restart Request"}, 351 {PLDM_STATE_SET_ENTITY_BOOT_STATUS, "Entity Boot Status"}, 352 {PLDM_STATE_SET_BOOT_ERROR_STATUS, "Boot ErrorStatus"}, 353 {PLDM_STATE_SET_BOOT_PROGRESS, "Boot Progress"}, 354 {PLDM_STATE_SET_SYS_FIRMWARE_HANG, "System Firmware Hang"}, 355 {PLDM_STATE_SET_POST_ERRORS, "POST Errors"}, 356 {PLDM_STATE_SET_LOG_FILL_STATUS, "Log Fill Status"}, 357 {PLDM_STATE_SET_LOG_FILTER_STATUS, "Log Filter Status"}, 358 {PLDM_STATE_SET_LOG_TIMESTAMP_CHANGE, "Log Timestamp Change"}, 359 {PLDM_STATE_SET_INTERRUPT_REQUESTED, "Interrupt Requested"}, 360 {PLDM_STATE_SET_INTERRUPT_RECEIVED, "Interrupt Received"}, 361 {PLDM_STATE_SET_DIAGNOSTIC_INTERRUPT_REQUESTED, 362 "Diagnostic Interrupt Requested"}, 363 {PLDM_STATE_SET_DIAGNOSTIC_INTERRUPT_RECEIVED, 364 "Diagnostic Interrupt Received"}, 365 {PLDM_STATE_SET_IO_CHANNEL_CHECK_NMI_REQUESTED, 366 "I/O Channel Check NMI Requested"}, 367 {PLDM_STATE_SET_IO_CHANNEL_CHECK_NMI_RECEIVED, 368 "I/O Channel Check NMI Received"}, 369 {PLDM_STATE_SET_FATAL_NMI_REQUESTED, "Fatal NMI Requested"}, 370 {PLDM_STATE_SET_FATAL_NMI_RECEIVED, "Fatal NMI Received"}, 371 {PLDM_STATE_SET_SOFTWARE_NMI_REQUESTED, "Software NMI Requested"}, 372 {PLDM_STATE_SET_SOFTWARE_NMI_RECEIVED, "Software NMI Received"}, 373 {PLDM_STATE_SET_SMI_REQUESTED, "SMI Requested"}, 374 {PLDM_STATE_SET_SMI_RECEIVED, "SMI Received"}, 375 {PLDM_STATE_SET_PCI_PERR_REQUESTED, "PCI PERR Requested"}, 376 {PLDM_STATE_SET_PCI_PERR_RECEIVED, "PCI PERR Received"}, 377 {PLDM_STATE_SET_PCI_SERR_REQUESTED, "PCI SERR Requested "}, 378 {PLDM_STATE_SET_PCI_SERR_RECEIVED, "PCI SERR Received"}, 379 {PLDM_STATE_SET_BUS_ERROR_STATUS, "Bus Error Status"}, 380 {PLDM_STATE_SET_WATCHDOG_STATUS, "Watchdog Status"}, 381 {PLDM_STATE_SET_POWER_SUPPLY_STATE, "Power Supply State"}, 382 {PLDM_STATE_SET_DEVICE_POWER_STATE, "Device Power State"}, 383 {PLDM_STATE_SET_ACPI_POWER_STATE, "ACPI Power State"}, 384 {PLDM_STATE_SET_BACKUP_POWER_SOURCE, "Backup Power Source"}, 385 {PLDM_STATE_SET_SYSTEM_POWER_STATE, "System Power State "}, 386 {PLDM_STATE_SET_BATTERY_ACTIVITY, "Battery Activity"}, 387 {PLDM_STATE_SET_BATTERY_STATE, "Battery State"}, 388 {PLDM_STATE_SET_PROC_POWER_STATE, "Processor Power State"}, 389 {PLDM_STATE_SET_POWER_PERFORMANCE_STATE, "Power-Performance State"}, 390 {PLDM_STATE_SET_PROC_ERROR_STATUS, "Processor Error Status"}, 391 {PLDM_STATE_SET_BIST_FAILURE_STATUS, "BIST FailureStatus"}, 392 {PLDM_STATE_SET_IBIST_FAILURE_STATUS, "IBIST FailureStatus"}, 393 {PLDM_STATE_SET_PROC_HANG_IN_POST, "Processor Hang in POST"}, 394 {PLDM_STATE_SET_PROC_STARTUP_FAILURE, "Processor Startup Failure"}, 395 {PLDM_STATE_SET_UNCORRECTABLE_CPU_ERROR, "Uncorrectable CPU Error"}, 396 {PLDM_STATE_SET_MACHINE_CHECK_ERROR, "Machine Check Error"}, 397 {PLDM_STATE_SET_CORRECTED_MACHINE_CHECK, "Corrected Machine Check"}, 398 {PLDM_STATE_SET_CACHE_STATUS, "Cache Status"}, 399 {PLDM_STATE_SET_MEMORY_ERROR_STATUS, "Memory Error Status"}, 400 {PLDM_STATE_SET_REDUNDANT_MEMORY_ACTIVITY_STATUS, 401 "Redundant Memory Activity Status"}, 402 {PLDM_STATE_SET_ERROR_DETECTION_STATUS, "Error Detection Status"}, 403 {PLDM_STATE_SET_STUCK_BIT_STATUS, "Stuck Bit Status"}, 404 {PLDM_STATE_SET_SCRUB_STATUS, "Scrub Status"}, 405 {PLDM_STATE_SET_SLOT_OCCUPANCY, "Slot Occupancy"}, 406 {PLDM_STATE_SET_SLOT_STATE, "Slot State"}, 407 }; 408 409 const std::array<std::string_view, 4> sensorInit = { 410 "noInit", "useInitPDR", "enableSensor", "disableSensor"}; 411 412 const std::array<std::string_view, 4> effecterInit = { 413 "noInit", "useInitPDR", "enableEffecter", "disableEffecter"}; 414 415 const std::map<uint8_t, std::string> pdrType = { 416 {PLDM_TERMINUS_LOCATOR_PDR, "Terminus Locator PDR"}, 417 {PLDM_NUMERIC_SENSOR_PDR, "Numeric Sensor PDR"}, 418 {PLDM_NUMERIC_SENSOR_INITIALIZATION_PDR, 419 "Numeric Sensor Initialization PDR"}, 420 {PLDM_STATE_SENSOR_PDR, "State Sensor PDR"}, 421 {PLDM_STATE_SENSOR_INITIALIZATION_PDR, 422 "State Sensor Initialization PDR"}, 423 {PLDM_SENSOR_AUXILIARY_NAMES_PDR, "Sensor Auxiliary Names PDR"}, 424 {PLDM_OEM_UNIT_PDR, "OEM Unit PDR"}, 425 {PLDM_OEM_STATE_SET_PDR, "OEM State Set PDR"}, 426 {PLDM_NUMERIC_EFFECTER_PDR, "Numeric Effecter PDR"}, 427 {PLDM_NUMERIC_EFFECTER_INITIALIZATION_PDR, 428 "Numeric Effecter Initialization PDR"}, 429 {PLDM_STATE_EFFECTER_PDR, "State Effecter PDR"}, 430 {PLDM_STATE_EFFECTER_INITIALIZATION_PDR, 431 "State Effecter Initialization PDR"}, 432 {PLDM_EFFECTER_AUXILIARY_NAMES_PDR, "Effecter Auxiliary Names PDR"}, 433 {PLDM_EFFECTER_OEM_SEMANTIC_PDR, "Effecter OEM Semantic PDR"}, 434 {PLDM_PDR_ENTITY_ASSOCIATION, "Entity Association PDR"}, 435 {PLDM_ENTITY_AUXILIARY_NAMES_PDR, "Entity Auxiliary Names PDR"}, 436 {PLDM_OEM_ENTITY_ID_PDR, "OEM Entity ID PDR"}, 437 {PLDM_INTERRUPT_ASSOCIATION_PDR, "Interrupt Association PDR"}, 438 {PLDM_EVENT_LOG_PDR, "PLDM Event Log PDR"}, 439 {PLDM_PDR_FRU_RECORD_SET, "FRU Record Set PDR"}, 440 {PLDM_OEM_DEVICE_PDR, "OEM Device PDR"}, 441 {PLDM_OEM_PDR, "OEM PDR"}, 442 }; 443 444 static inline const std::map<uint8_t, std::string> setThermalTrip{ 445 {PLDM_STATE_SET_THERMAL_TRIP_STATUS_NORMAL, "Normal"}, 446 {PLDM_STATE_SET_THERMAL_TRIP_STATUS_THERMAL_TRIP, "Thermal Trip"}}; 447 448 static inline const std::map<uint8_t, std::string> setIdentifyState{ 449 {PLDM_STATE_SET_IDENTIFY_STATE_UNASSERTED, "Identify State Unasserted"}, 450 {PLDM_STATE_SET_IDENTIFY_STATE_ASSERTED, "Identify State Asserted"}}; 451 452 static inline const std::map<uint8_t, std::string> setBootProgressState{ 453 {PLDM_STATE_SET_BOOT_PROG_STATE_NOT_ACTIVE, "Boot Not Active"}, 454 {PLDM_STATE_SET_BOOT_PROG_STATE_COMPLETED, "Boot Completed"}, 455 {PLDM_STATE_SET_BOOT_PROG_STATE_MEM_INITIALIZATION, 456 "Memory Initialization"}, 457 {PLDM_STATE_SET_BOOT_PROG_STATE_SEC_PROC_INITIALIZATION, 458 "Secondary Processor(s) Initialization"}, 459 {PLDM_STATE_SET_BOOT_PROG_STATE_PCI_RESORUCE_CONFIG, 460 "PCI Resource Configuration"}, 461 {PLDM_STATE_SET_BOOT_PROG_STATE_STARTING_OP_SYS, 462 "Starting Operating System"}, 463 {PLDM_STATE_SET_BOOT_PROG_STATE_BASE_BOARD_INITIALIZATION, 464 "Baseboard Initialization"}, 465 {PLDM_STATE_SET_BOOT_PROG_STATE_PRIMARY_PROC_INITIALIZATION, 466 "Primary Processor Initialization"}}; 467 468 static inline const std::map<uint8_t, std::string> setOpFaultStatus{ 469 {PLDM_STATE_SET_OPERATIONAL_FAULT_STATUS_NORMAL, "Normal"}, 470 {PLDM_STATE_SET_OPERATIONAL_FAULT_STATUS_STRESSED, "Stressed"}}; 471 472 static inline const std::map<uint8_t, std::string> setSysPowerState{ 473 {PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL, 474 "Off-Soft Graceful"}}; 475 476 static inline const std::map<uint8_t, std::string> setSWTerminationStatus{ 477 {PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED, 478 "Graceful Restart Requested"}}; 479 480 static inline const std::map<uint8_t, std::string> setAvailability{ 481 {PLDM_STATE_SET_AVAILABILITY_REBOOTING, "Rebooting"}}; 482 483 static inline const std::map<uint8_t, std::string> setHealthState{ 484 {PLDM_STATE_SET_HEALTH_STATE_NORMAL, "Normal"}, 485 {PLDM_STATE_SET_HEALTH_STATE_NON_CRITICAL, "Non-Critical"}, 486 {PLDM_STATE_SET_HEALTH_STATE_CRITICAL, "Critical"}, 487 {PLDM_STATE_SET_HEALTH_STATE_FATAL, "Fatal"}, 488 {PLDM_STATE_SET_HEALTH_STATE_UPPER_NON_CRITICAL, "Upper Non-Critical"}, 489 {PLDM_STATE_SET_HEALTH_STATE_LOWER_NON_CRITICAL, "Lower Non-Critical"}, 490 {PLDM_STATE_SET_HEALTH_STATE_UPPER_CRITICAL, "Upper Critical"}, 491 {PLDM_STATE_SET_HEALTH_STATE_LOWER_CRITICAL, "Lower Critical"}, 492 {PLDM_STATE_SET_HEALTH_STATE_UPPER_FATAL, "Upper Fatal"}, 493 {PLDM_STATE_SET_HEALTH_STATE_LOWER_FATAL, "Lower Fatal"}}; 494 495 static inline const std::map<uint8_t, std::string> 496 setOperationalRunningState{ 497 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STARTING, "Starting"}, 498 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPING, "Stopping"}, 499 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED, "Stopped"}, 500 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE, 501 "In Service"}, 502 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_ABORTED, "Aborted"}, 503 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_DORMANT, "Dormant"}}; 504 505 static inline const std::map<uint16_t, const std::map<uint8_t, std::string>> 506 populatePStateMaps{ 507 {PLDM_STATE_SET_THERMAL_TRIP, setThermalTrip}, 508 {PLDM_STATE_SET_IDENTIFY_STATE, setIdentifyState}, 509 {PLDM_STATE_SET_BOOT_PROGRESS, setBootProgressState}, 510 {PLDM_STATE_SET_OPERATIONAL_FAULT_STATUS, setOpFaultStatus}, 511 {PLDM_STATE_SET_SYSTEM_POWER_STATE, setSysPowerState}, 512 {PLDM_STATE_SET_SW_TERMINATION_STATUS, setSWTerminationStatus}, 513 {PLDM_STATE_SET_AVAILABILITY, setAvailability}, 514 {PLDM_STATE_SET_HEALTH_STATE, setHealthState}, 515 {PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS, 516 setOperationalRunningState}, 517 }; 518 519 const std::map<std::string, uint8_t> strToPdrType = { 520 {"terminuslocator", PLDM_TERMINUS_LOCATOR_PDR}, 521 {"statesensor", PLDM_STATE_SENSOR_PDR}, 522 {"numericeffecter", PLDM_NUMERIC_EFFECTER_PDR}, 523 {"stateeffecter", PLDM_STATE_EFFECTER_PDR}, 524 {"entityassociation", PLDM_PDR_ENTITY_ASSOCIATION}, 525 {"frurecord", PLDM_PDR_FRU_RECORD_SET}, 526 // Add other types 527 }; 528 529 bool isLogicalBitSet(const uint16_t entity_type) 530 { 531 return entity_type & 0x8000; 532 } 533 534 uint16_t getEntityTypeForLogicalEntity(const uint16_t logical_entity_type) 535 { 536 return logical_entity_type & 0x7FFF; 537 } 538 539 std::string getEntityName(pldm::pdr::EntityType type) 540 { 541 uint16_t entityNumber = type; 542 std::string entityName = "[Physical] "; 543 544 if (isLogicalBitSet(type)) 545 { 546 entityName = "[Logical] "; 547 entityNumber = getEntityTypeForLogicalEntity(type); 548 } 549 550 try 551 { 552 return entityName + entityType.at(entityNumber); 553 } 554 catch (const std::out_of_range& e) 555 { 556 auto OemString = 557 std::to_string(static_cast<unsigned>(entityNumber)); 558 if (type >= PLDM_OEM_ENTITY_TYPE_START && 559 type <= PLDM_OEM_ENTITY_TYPE_END) 560 { 561 #ifdef OEM_IBM 562 if (OemIBMEntityType.contains(entityNumber)) 563 { 564 return entityName + OemIBMEntityType.at(entityNumber) + 565 "(OEM)"; 566 } 567 #endif 568 return entityName + OemString + "(OEM)"; 569 } 570 return OemString; 571 } 572 } 573 574 std::string getStateSetName(uint16_t id) 575 { 576 auto typeString = std::to_string(id); 577 try 578 { 579 return stateSet.at(id) + "(" + typeString + ")"; 580 } 581 catch (const std::out_of_range& e) 582 { 583 return typeString; 584 } 585 } 586 587 std::vector<std::string> 588 getStateSetPossibleStateNames(uint16_t stateId, 589 const std::vector<uint8_t>& value) 590 { 591 std::vector<std::string> data{}; 592 std::map<uint8_t, std::string> stateNameMaps; 593 594 for (auto& s : value) 595 { 596 std::map<uint8_t, std::string> stateNameMaps; 597 auto pstr = std::to_string(s); 598 599 #ifdef OEM_IBM 600 if (stateId >= PLDM_OEM_STATE_SET_ID_START && 601 stateId < PLDM_OEM_STATE_SET_ID_END) 602 { 603 if (populateOemIBMStateMaps.contains(stateId)) 604 { 605 const std::map<uint8_t, std::string> stateNames = 606 populateOemIBMStateMaps.at(stateId); 607 stateNameMaps.insert(stateNames.begin(), stateNames.end()); 608 } 609 } 610 #endif 611 if (populatePStateMaps.contains(stateId)) 612 { 613 const std::map<uint8_t, std::string> stateNames = 614 populatePStateMaps.at(stateId); 615 stateNameMaps.insert(stateNames.begin(), stateNames.end()); 616 } 617 if (stateNameMaps.contains(s)) 618 { 619 data.push_back(stateNameMaps.at(s) + "(" + pstr + ")"); 620 } 621 else 622 { 623 data.push_back(pstr); 624 } 625 } 626 return data; 627 } 628 629 std::string getPDRType(uint8_t type) 630 { 631 auto typeString = std::to_string(type); 632 try 633 { 634 return pdrType.at(type); 635 } 636 catch (const std::out_of_range& e) 637 { 638 return typeString; 639 } 640 } 641 642 void printCommonPDRHeader(const pldm_pdr_hdr* hdr, ordered_json& output) 643 { 644 output["recordHandle"] = hdr->record_handle; 645 output["PDRHeaderVersion"] = unsigned(hdr->version); 646 output["PDRType"] = getPDRType(hdr->type); 647 output["recordChangeNumber"] = hdr->record_change_num; 648 output["dataLength"] = hdr->length; 649 } 650 651 std::vector<uint8_t> printPossibleStates(uint8_t possibleStatesSize, 652 const bitfield8_t* states) 653 { 654 uint8_t possibleStatesPos{}; 655 std::vector<uint8_t> data{}; 656 auto printStates = [&possibleStatesPos, &data](const bitfield8_t& val) { 657 std::stringstream pstates; 658 for (int i = 0; i < CHAR_BIT; i++) 659 { 660 if (val.byte & (1 << i)) 661 { 662 pstates << (possibleStatesPos * CHAR_BIT + i); 663 data.push_back( 664 static_cast<uint8_t>(std::stoi(pstates.str()))); 665 pstates.str(""); 666 } 667 } 668 possibleStatesPos++; 669 }; 670 std::for_each(states, states + possibleStatesSize, printStates); 671 return data; 672 } 673 674 void printStateSensorPDR(const uint8_t* data, ordered_json& output) 675 { 676 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>(data); 677 output["PLDMTerminusHandle"] = pdr->terminus_handle; 678 output["sensorID"] = pdr->sensor_id; 679 output["entityType"] = getEntityName(pdr->entity_type); 680 output["entityInstanceNumber"] = pdr->entity_instance; 681 output["containerID"] = pdr->container_id; 682 output["sensorInit"] = sensorInit[pdr->sensor_init]; 683 output["sensorAuxiliaryNamesPDR"] = 684 (pdr->sensor_auxiliary_names_pdr ? true : false); 685 output["compositeSensorCount"] = unsigned(pdr->composite_sensor_count); 686 687 auto statesPtr = pdr->possible_states; 688 auto compCount = pdr->composite_sensor_count; 689 690 while (compCount--) 691 { 692 auto state = reinterpret_cast<const state_sensor_possible_states*>( 693 statesPtr); 694 output.emplace(("stateSetID[" + std::to_string(compCount) + "]"), 695 getStateSetName(state->state_set_id)); 696 output.emplace( 697 ("possibleStatesSize[" + std::to_string(compCount) + "]"), 698 state->possible_states_size); 699 output.emplace( 700 ("possibleStates[" + std::to_string(compCount) + "]"), 701 getStateSetPossibleStateNames( 702 state->state_set_id, 703 printPossibleStates(state->possible_states_size, 704 state->states))); 705 706 if (compCount) 707 { 708 statesPtr += sizeof(state_sensor_possible_states) + 709 state->possible_states_size - 1; 710 } 711 } 712 } 713 714 void printPDRFruRecordSet(uint8_t* data, ordered_json& output) 715 { 716 if (data == NULL) 717 { 718 return; 719 } 720 721 data += sizeof(pldm_pdr_hdr); 722 pldm_pdr_fru_record_set* pdr = 723 reinterpret_cast<pldm_pdr_fru_record_set*>(data); 724 if (!pdr) 725 { 726 std::cerr << "Failed to get the FRU record set PDR" << std::endl; 727 return; 728 } 729 730 output["PLDMTerminusHandle"] = unsigned(pdr->terminus_handle); 731 output["FRURecordSetIdentifier"] = unsigned(pdr->fru_rsi); 732 output["entityType"] = getEntityName(pdr->entity_type); 733 output["entityInstanceNumber"] = unsigned(pdr->entity_instance_num); 734 output["containerID"] = unsigned(pdr->container_id); 735 } 736 737 void printPDREntityAssociation(uint8_t* data, ordered_json& output) 738 { 739 const std::map<uint8_t, const char*> assocationType = { 740 {PLDM_ENTITY_ASSOCIAION_PHYSICAL, "Physical"}, 741 {PLDM_ENTITY_ASSOCIAION_LOGICAL, "Logical"}, 742 }; 743 744 if (data == NULL) 745 { 746 return; 747 } 748 749 data += sizeof(pldm_pdr_hdr); 750 pldm_pdr_entity_association* pdr = 751 reinterpret_cast<pldm_pdr_entity_association*>(data); 752 if (!pdr) 753 { 754 std::cerr << "Failed to get the PDR eneity association" 755 << std::endl; 756 return; 757 } 758 759 output["containerID"] = int(pdr->container_id); 760 if (assocationType.contains(pdr->association_type)) 761 { 762 output["associationType"] = 763 assocationType.at(pdr->association_type); 764 } 765 else 766 { 767 std::cout << "Get associationType failed.\n"; 768 } 769 output["containerEntityType"] = 770 getEntityName(pdr->container.entity_type); 771 output["containerEntityInstanceNumber"] = 772 int(pdr->container.entity_instance_num); 773 output["containerEntityContainerID"] = 774 int(pdr->container.entity_container_id); 775 output["containedEntityCount"] = 776 static_cast<unsigned>(pdr->num_children); 777 778 auto child = reinterpret_cast<pldm_entity*>(&pdr->children[0]); 779 for (int i = 0; i < pdr->num_children; ++i) 780 { 781 output.emplace("containedEntityType[" + std::to_string(i + 1) + "]", 782 getEntityName(child->entity_type)); 783 output.emplace("containedEntityInstanceNumber[" + 784 std::to_string(i + 1) + "]", 785 unsigned(child->entity_instance_num)); 786 output.emplace("containedEntityContainerID[" + 787 std::to_string(i + 1) + "]", 788 unsigned(child->entity_container_id)); 789 790 ++child; 791 } 792 } 793 794 void printNumericEffecterPDR(uint8_t* data, ordered_json& output) 795 { 796 struct pldm_numeric_effecter_value_pdr* pdr = 797 (struct pldm_numeric_effecter_value_pdr*)data; 798 if (!pdr) 799 { 800 std::cerr << "Failed to get numeric effecter PDR" << std::endl; 801 return; 802 } 803 804 output["PLDMTerminusHandle"] = int(pdr->terminus_handle); 805 output["effecterID"] = int(pdr->effecter_id); 806 output["entityType"] = int(pdr->entity_type); 807 output["entityInstanceNumber"] = int(pdr->entity_instance); 808 output["containerID"] = int(pdr->container_id); 809 output["effecterSemanticID"] = int(pdr->effecter_semantic_id); 810 output["effecterInit"] = unsigned(pdr->effecter_init); 811 output["effecterAuxiliaryNames"] = 812 (unsigned(pdr->effecter_auxiliary_names) ? true : false); 813 output["baseUnit"] = unsigned(pdr->base_unit); 814 output["unitModifier"] = unsigned(pdr->unit_modifier); 815 output["rateUnit"] = unsigned(pdr->rate_unit); 816 output["baseOEMUnitHandle"] = unsigned(pdr->base_oem_unit_handle); 817 output["auxUnit"] = unsigned(pdr->aux_unit); 818 output["auxUnitModifier"] = unsigned(pdr->aux_unit_modifier); 819 output["auxrateUnit"] = unsigned(pdr->aux_rate_unit); 820 output["auxOEMUnitHandle"] = unsigned(pdr->aux_oem_unit_handle); 821 output["isLinear"] = (unsigned(pdr->is_linear) ? true : false); 822 output["effecterDataSize"] = unsigned(pdr->effecter_data_size); 823 output["resolution"] = unsigned(pdr->resolution); 824 output["offset"] = unsigned(pdr->offset); 825 output["accuracy"] = unsigned(pdr->accuracy); 826 output["plusTolerance"] = unsigned(pdr->plus_tolerance); 827 output["minusTolerance"] = unsigned(pdr->minus_tolerance); 828 output["stateTransitionInterval"] = 829 unsigned(pdr->state_transition_interval); 830 output["TransitionInterval"] = unsigned(pdr->transition_interval); 831 832 switch (pdr->effecter_data_size) 833 { 834 case PLDM_EFFECTER_DATA_SIZE_UINT8: 835 output["maxSettable"] = unsigned(pdr->max_settable.value_u8); 836 output["minSettable"] = unsigned(pdr->min_settable.value_u8); 837 break; 838 case PLDM_EFFECTER_DATA_SIZE_SINT8: 839 output["maxSettable"] = unsigned(pdr->max_settable.value_s8); 840 output["minSettable"] = unsigned(pdr->min_settable.value_s8); 841 break; 842 case PLDM_EFFECTER_DATA_SIZE_UINT16: 843 output["maxSettable"] = unsigned(pdr->max_settable.value_u16); 844 output["minSettable"] = unsigned(pdr->min_settable.value_u16); 845 break; 846 case PLDM_EFFECTER_DATA_SIZE_SINT16: 847 output["maxSettable"] = unsigned(pdr->max_settable.value_s16); 848 output["minSettable"] = unsigned(pdr->min_settable.value_s16); 849 break; 850 case PLDM_EFFECTER_DATA_SIZE_UINT32: 851 output["maxSettable"] = unsigned(pdr->max_settable.value_u32); 852 output["minSettable"] = unsigned(pdr->min_settable.value_u32); 853 break; 854 case PLDM_EFFECTER_DATA_SIZE_SINT32: 855 output["maxSettable"] = unsigned(pdr->max_settable.value_s32); 856 output["minSettable"] = unsigned(pdr->min_settable.value_s32); 857 break; 858 default: 859 break; 860 } 861 862 output["rangeFieldFormat"] = unsigned(pdr->range_field_format); 863 output["rangeFieldSupport"] = unsigned(pdr->range_field_support.byte); 864 865 switch (pdr->range_field_format) 866 { 867 case PLDM_RANGE_FIELD_FORMAT_UINT8: 868 output["nominalValue"] = unsigned(pdr->nominal_value.value_u8); 869 output["normalMax"] = unsigned(pdr->normal_max.value_u8); 870 output["normalMin"] = unsigned(pdr->normal_min.value_u8); 871 output["ratedMax"] = unsigned(pdr->rated_max.value_u8); 872 output["ratedMin"] = unsigned(pdr->rated_min.value_u8); 873 break; 874 case PLDM_RANGE_FIELD_FORMAT_SINT8: 875 output["nominalValue"] = unsigned(pdr->nominal_value.value_s8); 876 output["normalMax"] = unsigned(pdr->normal_max.value_s8); 877 output["normalMin"] = unsigned(pdr->normal_min.value_s8); 878 output["ratedMax"] = unsigned(pdr->rated_max.value_s8); 879 output["ratedMin"] = unsigned(pdr->rated_min.value_s8); 880 break; 881 case PLDM_RANGE_FIELD_FORMAT_UINT16: 882 output["nominalValue"] = unsigned(pdr->nominal_value.value_u16); 883 output["normalMax"] = unsigned(pdr->normal_max.value_u16); 884 output["normalMin"] = unsigned(pdr->normal_min.value_u16); 885 output["ratedMax"] = unsigned(pdr->rated_max.value_u16); 886 output["ratedMin"] = unsigned(pdr->rated_min.value_u16); 887 break; 888 case PLDM_RANGE_FIELD_FORMAT_SINT16: 889 output["nominalValue"] = unsigned(pdr->nominal_value.value_s16); 890 output["normalMax"] = unsigned(pdr->normal_max.value_s16); 891 output["normalMin"] = unsigned(pdr->normal_min.value_s16); 892 output["ratedMax"] = unsigned(pdr->rated_max.value_s16); 893 output["ratedMin"] = unsigned(pdr->rated_min.value_s16); 894 break; 895 case PLDM_RANGE_FIELD_FORMAT_UINT32: 896 output["nominalValue"] = unsigned(pdr->nominal_value.value_u32); 897 output["normalMax"] = unsigned(pdr->normal_max.value_u32); 898 output["normalMin"] = unsigned(pdr->normal_min.value_u32); 899 output["ratedMax"] = unsigned(pdr->rated_max.value_u32); 900 output["ratedMin"] = unsigned(pdr->rated_min.value_u32); 901 break; 902 case PLDM_RANGE_FIELD_FORMAT_SINT32: 903 output["nominalValue"] = unsigned(pdr->nominal_value.value_s32); 904 output["normalMax"] = unsigned(pdr->normal_max.value_s32); 905 output["normalMin"] = unsigned(pdr->normal_min.value_s32); 906 output["ratedMax"] = unsigned(pdr->rated_max.value_s32); 907 output["ratedMin"] = unsigned(pdr->rated_min.value_s32); 908 break; 909 case PLDM_RANGE_FIELD_FORMAT_REAL32: 910 output["nominalValue"] = unsigned(pdr->nominal_value.value_f32); 911 output["normalMax"] = unsigned(pdr->normal_max.value_f32); 912 output["normalMin"] = unsigned(pdr->normal_min.value_f32); 913 output["ratedMax"] = unsigned(pdr->rated_max.value_f32); 914 output["ratedMin"] = unsigned(pdr->rated_min.value_f32); 915 break; 916 default: 917 break; 918 } 919 } 920 921 void printStateEffecterPDR(const uint8_t* data, ordered_json& output) 922 { 923 auto pdr = reinterpret_cast<const pldm_state_effecter_pdr*>(data); 924 925 output["PLDMTerminusHandle"] = pdr->terminus_handle; 926 output["effecterID"] = pdr->effecter_id; 927 output["entityType"] = getEntityName(pdr->entity_type); 928 output["entityInstanceNumber"] = pdr->entity_instance; 929 output["containerID"] = pdr->container_id; 930 output["effecterSemanticID"] = pdr->effecter_semantic_id; 931 output["effecterInit"] = effecterInit[pdr->effecter_init]; 932 output["effecterDescriptionPDR"] = 933 (pdr->has_description_pdr ? true : false); 934 output["compositeEffecterCount"] = 935 unsigned(pdr->composite_effecter_count); 936 937 auto statesPtr = pdr->possible_states; 938 auto compEffCount = pdr->composite_effecter_count; 939 940 while (compEffCount--) 941 { 942 auto state = 943 reinterpret_cast<const state_effecter_possible_states*>( 944 statesPtr); 945 output.emplace(("stateSetID[" + std::to_string(compEffCount) + "]"), 946 getStateSetName(state->state_set_id)); 947 output.emplace( 948 ("possibleStatesSize[" + std::to_string(compEffCount) + "]"), 949 state->possible_states_size); 950 output.emplace( 951 ("possibleStates[" + std::to_string(compEffCount) + "]"), 952 getStateSetPossibleStateNames( 953 state->state_set_id, 954 printPossibleStates(state->possible_states_size, 955 state->states))); 956 957 if (compEffCount) 958 { 959 statesPtr += sizeof(state_effecter_possible_states) + 960 state->possible_states_size - 1; 961 } 962 } 963 } 964 965 void printTerminusLocatorPDR(const uint8_t* data, ordered_json& output) 966 { 967 const std::array<std::string_view, 4> terminusLocatorType = { 968 "UID", "MCTP_EID", "SMBusRelative", "systemSoftware"}; 969 970 auto pdr = reinterpret_cast<const pldm_terminus_locator_pdr*>(data); 971 972 output["PLDMTerminusHandle"] = pdr->terminus_handle; 973 output["validity"] = (pdr->validity ? "valid" : "notValid"); 974 output["TID"] = unsigned(pdr->tid); 975 output["containerID"] = pdr->container_id; 976 output["terminusLocatorType"] = 977 terminusLocatorType[pdr->terminus_locator_type]; 978 output["terminusLocatorValueSize"] = 979 unsigned(pdr->terminus_locator_value_size); 980 981 if (pdr->terminus_locator_type == PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID) 982 { 983 auto locatorValue = 984 reinterpret_cast<const pldm_terminus_locator_type_mctp_eid*>( 985 pdr->terminus_locator_value); 986 output["EID"] = unsigned(locatorValue->eid); 987 } 988 } 989 990 void printPDRMsg(uint32_t& nextRecordHndl, const uint16_t respCnt, 991 uint8_t* data) 992 { 993 if (data == NULL) 994 { 995 std::cerr << "Failed to get PDR message" << std::endl; 996 return; 997 } 998 999 ordered_json output; 1000 output["nextRecordHandle"] = nextRecordHndl; 1001 output["responseCount"] = respCnt; 1002 1003 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data; 1004 if (!pdr) 1005 { 1006 return; 1007 } 1008 1009 if (!pdrRecType.empty()) 1010 { 1011 // Need to return if the requested PDR type 1012 // is not supported 1013 if (!strToPdrType.contains(pdrRecType)) 1014 { 1015 std::cerr << "PDR type '" << pdrRecType 1016 << "' is not supported or invalid\n"; 1017 // PDR type not supported, setting next record handle to 0 1018 // to avoid looping through all PDR records 1019 nextRecordHndl = 0; 1020 return; 1021 } 1022 1023 // Do not print PDR record if the current record 1024 // PDR type does not match with requested type 1025 if (pdr->type != strToPdrType.at(pdrRecType)) 1026 { 1027 return; 1028 } 1029 } 1030 1031 printCommonPDRHeader(pdr, output); 1032 1033 switch (pdr->type) 1034 { 1035 case PLDM_TERMINUS_LOCATOR_PDR: 1036 printTerminusLocatorPDR(data, output); 1037 break; 1038 case PLDM_STATE_SENSOR_PDR: 1039 printStateSensorPDR(data, output); 1040 break; 1041 case PLDM_NUMERIC_EFFECTER_PDR: 1042 printNumericEffecterPDR(data, output); 1043 break; 1044 case PLDM_STATE_EFFECTER_PDR: 1045 printStateEffecterPDR(data, output); 1046 break; 1047 case PLDM_PDR_ENTITY_ASSOCIATION: 1048 printPDREntityAssociation(data, output); 1049 break; 1050 case PLDM_PDR_FRU_RECORD_SET: 1051 printPDRFruRecordSet(data, output); 1052 break; 1053 default: 1054 break; 1055 } 1056 pldmtool::helper::DisplayInJson(output); 1057 } 1058 1059 private: 1060 uint32_t recordHandle; 1061 bool allPDRs; 1062 std::string pdrRecType; 1063 }; 1064 1065 class SetStateEffecter : public CommandInterface 1066 { 1067 public: 1068 ~SetStateEffecter() = default; 1069 SetStateEffecter() = delete; 1070 SetStateEffecter(const SetStateEffecter&) = delete; 1071 SetStateEffecter(SetStateEffecter&&) = default; 1072 SetStateEffecter& operator=(const SetStateEffecter&) = delete; 1073 SetStateEffecter& operator=(SetStateEffecter&&) = default; 1074 1075 // compositeEffecterCount(value: 0x01 to 0x08) * stateField(2) 1076 static constexpr auto maxEffecterDataSize = 16; 1077 1078 // compositeEffecterCount(value: 0x01 to 0x08) 1079 static constexpr auto minEffecterCount = 1; 1080 static constexpr auto maxEffecterCount = 8; 1081 explicit SetStateEffecter(const char* type, const char* name, 1082 CLI::App* app) : 1083 CommandInterface(type, name, app) 1084 { 1085 app->add_option( 1086 "-i, --id", effecterId, 1087 "A handle that is used to identify and access the effecter") 1088 ->required(); 1089 app->add_option("-c, --count", effecterCount, 1090 "The number of individual sets of effecter information") 1091 ->required(); 1092 app->add_option( 1093 "-d,--data", effecterData, 1094 "Set effecter state data\n" 1095 "eg: requestSet0 effecterState0 noChange1 dummyState1 ...") 1096 ->required(); 1097 } 1098 1099 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 1100 { 1101 std::vector<uint8_t> requestMsg( 1102 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES); 1103 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1104 1105 if (effecterCount > maxEffecterCount || 1106 effecterCount < minEffecterCount) 1107 { 1108 std::cerr << "Request Message Error: effecterCount size " 1109 << effecterCount << "is invalid\n"; 1110 auto rc = PLDM_ERROR_INVALID_DATA; 1111 return {rc, requestMsg}; 1112 } 1113 1114 if (effecterData.size() > maxEffecterDataSize) 1115 { 1116 std::cerr << "Request Message Error: effecterData size " 1117 << effecterData.size() << "is invalid\n"; 1118 auto rc = PLDM_ERROR_INVALID_DATA; 1119 return {rc, requestMsg}; 1120 } 1121 1122 auto stateField = parseEffecterData(effecterData, effecterCount); 1123 if (!stateField) 1124 { 1125 std::cerr << "Failed to parse effecter data, effecterCount size " 1126 << effecterCount << "\n"; 1127 auto rc = PLDM_ERROR_INVALID_DATA; 1128 return {rc, requestMsg}; 1129 } 1130 1131 auto rc = encode_set_state_effecter_states_req( 1132 instanceId, effecterId, effecterCount, stateField->data(), request); 1133 return {rc, requestMsg}; 1134 } 1135 1136 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 1137 { 1138 uint8_t completionCode = 0; 1139 auto rc = decode_set_state_effecter_states_resp( 1140 responsePtr, payloadLength, &completionCode); 1141 1142 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) 1143 { 1144 std::cerr << "Response Message Error: " 1145 << "rc=" << rc << ",cc=" << (int)completionCode << "\n"; 1146 return; 1147 } 1148 1149 ordered_json data; 1150 data["Response"] = "SUCCESS"; 1151 pldmtool::helper::DisplayInJson(data); 1152 } 1153 1154 private: 1155 uint16_t effecterId; 1156 uint8_t effecterCount; 1157 std::vector<uint8_t> effecterData; 1158 }; 1159 1160 class SetNumericEffecterValue : public CommandInterface 1161 { 1162 public: 1163 ~SetNumericEffecterValue() = default; 1164 SetNumericEffecterValue() = delete; 1165 SetNumericEffecterValue(const SetNumericEffecterValue&) = delete; 1166 SetNumericEffecterValue(SetNumericEffecterValue&&) = default; 1167 SetNumericEffecterValue& operator=(const SetNumericEffecterValue&) = delete; 1168 SetNumericEffecterValue& operator=(SetNumericEffecterValue&&) = default; 1169 1170 explicit SetNumericEffecterValue(const char* type, const char* name, 1171 CLI::App* app) : 1172 CommandInterface(type, name, app) 1173 { 1174 app->add_option( 1175 "-i, --id", effecterId, 1176 "A handle that is used to identify and access the effecter") 1177 ->required(); 1178 app->add_option("-s, --size", effecterDataSize, 1179 "The bit width and format of the setting value for the " 1180 "effecter. enum value: {uint8, sint8, uint16, sint16, " 1181 "uint32, sint32}\n") 1182 ->required(); 1183 app->add_option("-d,--data", maxEffecterValue, 1184 "The setting value of numeric effecter being " 1185 "requested\n") 1186 ->required(); 1187 } 1188 1189 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 1190 { 1191 std::vector<uint8_t> requestMsg( 1192 sizeof(pldm_msg_hdr) + 1193 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3); 1194 1195 uint8_t* effecterValue = (uint8_t*)&maxEffecterValue; 1196 1197 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1198 size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES; 1199 1200 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT16 || 1201 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT16) 1202 { 1203 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1; 1204 } 1205 if (effecterDataSize == PLDM_EFFECTER_DATA_SIZE_UINT32 || 1206 effecterDataSize == PLDM_EFFECTER_DATA_SIZE_SINT32) 1207 { 1208 payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3; 1209 } 1210 auto rc = encode_set_numeric_effecter_value_req( 1211 0, effecterId, effecterDataSize, effecterValue, request, 1212 payload_length); 1213 1214 return {rc, requestMsg}; 1215 } 1216 1217 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 1218 { 1219 uint8_t completionCode = 0; 1220 auto rc = decode_set_numeric_effecter_value_resp( 1221 responsePtr, payloadLength, &completionCode); 1222 1223 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) 1224 { 1225 std::cerr << "Response Message Error: " 1226 << "rc=" << rc << ",cc=" << (int)completionCode 1227 << std::endl; 1228 return; 1229 } 1230 1231 ordered_json data; 1232 data["Response"] = "SUCCESS"; 1233 pldmtool::helper::DisplayInJson(data); 1234 } 1235 1236 private: 1237 uint16_t effecterId; 1238 uint8_t effecterDataSize; 1239 uint64_t maxEffecterValue; 1240 }; 1241 1242 class GetStateSensorReadings : public CommandInterface 1243 { 1244 public: 1245 ~GetStateSensorReadings() = default; 1246 GetStateSensorReadings() = delete; 1247 GetStateSensorReadings(const GetStateSensorReadings&) = delete; 1248 GetStateSensorReadings(GetStateSensorReadings&&) = default; 1249 GetStateSensorReadings& operator=(const GetStateSensorReadings&) = delete; 1250 GetStateSensorReadings& operator=(GetStateSensorReadings&&) = default; 1251 1252 explicit GetStateSensorReadings(const char* type, const char* name, 1253 CLI::App* app) : 1254 CommandInterface(type, name, app) 1255 { 1256 app->add_option( 1257 "-i, --sensor_id", sensorId, 1258 "Sensor ID that is used to identify and access the sensor") 1259 ->required(); 1260 app->add_option("-r, --rearm", sensorRearm, 1261 "Each bit location in this field corresponds to a " 1262 "particular sensor") 1263 ->required(); 1264 } 1265 1266 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 1267 { 1268 std::vector<uint8_t> requestMsg( 1269 sizeof(pldm_msg_hdr) + PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES); 1270 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1271 1272 uint8_t reserved = 0; 1273 bitfield8_t bf; 1274 bf.byte = sensorRearm; 1275 auto rc = encode_get_state_sensor_readings_req(instanceId, sensorId, bf, 1276 reserved, request); 1277 1278 return {rc, requestMsg}; 1279 } 1280 1281 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 1282 { 1283 uint8_t completionCode = 0; 1284 uint8_t compSensorCount = 0; 1285 std::array<get_sensor_state_field, 8> stateField{}; 1286 auto rc = decode_get_state_sensor_readings_resp( 1287 responsePtr, payloadLength, &completionCode, &compSensorCount, 1288 stateField.data()); 1289 1290 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) 1291 { 1292 std::cerr << "Response Message Error: " 1293 << "rc=" << rc << ",cc=" << (int)completionCode 1294 << std::endl; 1295 return; 1296 } 1297 ordered_json output; 1298 output["compositeSensorCount"] = (int)compSensorCount; 1299 1300 for (size_t i = 0; i < compSensorCount; i++) 1301 { 1302 if (sensorOpState.contains(stateField[i].sensor_op_state)) 1303 { 1304 output.emplace(("sensorOpState[" + std::to_string(i) + "]"), 1305 sensorOpState.at(stateField[i].sensor_op_state)); 1306 } 1307 1308 if (sensorPresState.contains(stateField[i].present_state)) 1309 { 1310 output.emplace(("presentState[" + std::to_string(i) + "]"), 1311 sensorPresState.at(stateField[i].present_state)); 1312 } 1313 1314 if (sensorPresState.contains(stateField[i].previous_state)) 1315 { 1316 output.emplace( 1317 ("previousState[" + std::to_string(i) + "]"), 1318 sensorPresState.at(stateField[i].previous_state)); 1319 } 1320 1321 if (sensorPresState.contains(stateField[i].event_state)) 1322 { 1323 output.emplace(("eventState[" + std::to_string(i) + "]"), 1324 sensorPresState.at(stateField[i].event_state)); 1325 } 1326 } 1327 1328 pldmtool::helper::DisplayInJson(output); 1329 } 1330 1331 private: 1332 uint16_t sensorId; 1333 uint8_t sensorRearm; 1334 }; 1335 1336 void registerCommand(CLI::App& app) 1337 { 1338 auto platform = app.add_subcommand("platform", "platform type command"); 1339 platform->require_subcommand(1); 1340 1341 auto getPDR = 1342 platform->add_subcommand("GetPDR", "get platform descriptor records"); 1343 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR)); 1344 1345 auto setStateEffecterStates = platform->add_subcommand( 1346 "SetStateEffecterStates", "set effecter states"); 1347 commands.push_back(std::make_unique<SetStateEffecter>( 1348 "platform", "setStateEffecterStates", setStateEffecterStates)); 1349 1350 auto setNumericEffecterValue = platform->add_subcommand( 1351 "SetNumericEffecterValue", "set the value for a PLDM Numeric Effecter"); 1352 commands.push_back(std::make_unique<SetNumericEffecterValue>( 1353 "platform", "setNumericEffecterValue", setNumericEffecterValue)); 1354 1355 auto getStateSensorReadings = platform->add_subcommand( 1356 "GetStateSensorReadings", "get the state sensor readings"); 1357 commands.push_back(std::make_unique<GetStateSensorReadings>( 1358 "platform", "getStateSensorReadings", getStateSensorReadings)); 1359 } 1360 1361 } // namespace platform 1362 } // namespace pldmtool 1363