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