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