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