summaryrefslogtreecommitdiff
path: root/redfish-core
diff options
context:
space:
mode:
Diffstat (limited to 'redfish-core')
-rw-r--r--redfish-core/include/aggregation_utils.hpp3
-rw-r--r--redfish-core/include/error_messages.hpp99
-rw-r--r--redfish-core/include/event_service_manager.hpp641
-rw-r--r--redfish-core/include/filter_expr_executor.hpp9
-rw-r--r--redfish-core/include/filter_expr_parser_ast.hpp1
-rw-r--r--redfish-core/include/filter_expr_parser_grammar.hpp4
-rw-r--r--redfish-core/include/generated/enums/account_service.hpp2
-rw-r--r--redfish-core/include/generated/enums/certificate.hpp2
-rw-r--r--redfish-core/include/generated/enums/component_integrity.hpp4
-rw-r--r--redfish-core/include/generated/enums/computer_system.hpp28
-rw-r--r--redfish-core/include/generated/enums/drive.hpp26
-rw-r--r--redfish-core/include/generated/enums/open_bmc_computer_system.hpp (renamed from redfish-core/include/generated/enums/oem_computer_system.hpp)2
-rw-r--r--redfish-core/include/generated/enums/pcie_device.hpp2
-rw-r--r--redfish-core/include/generated/enums/physical_context.hpp14
-rw-r--r--redfish-core/include/generated/enums/storage.hpp32
-rw-r--r--redfish-core/include/gzfile.hpp4
-rw-r--r--redfish-core/include/privileges.hpp28
-rw-r--r--redfish-core/include/query.hpp11
-rw-r--r--redfish-core/include/redfish_aggregator.hpp147
-rw-r--r--redfish-core/include/registries.hpp40
-rw-r--r--redfish-core/include/registries/base_message_registry.hpp198
-rw-r--r--redfish-core/include/registries/openbmc.json12
-rw-r--r--redfish-core/include/registries/openbmc_message_registry.hpp129
-rw-r--r--redfish-core/include/registries/openbmc_message_registry.readmefirst.md9
-rw-r--r--redfish-core/include/schemas.hpp132
-rw-r--r--redfish-core/include/snmp_trap_event_clients.hpp106
-rw-r--r--redfish-core/include/task_messages.hpp26
-rw-r--r--redfish-core/include/utils/chassis_utils.hpp46
-rw-r--r--redfish-core/include/utils/collection.hpp28
-rw-r--r--redfish-core/include/utils/dbus_event_log_entry.hpp52
-rw-r--r--redfish-core/include/utils/dbus_utils.hpp47
-rw-r--r--redfish-core/include/utils/json_utils.hpp105
-rw-r--r--redfish-core/include/utils/query_param.hpp33
-rw-r--r--redfish-core/include/utils/sensor_utils.hpp625
-rw-r--r--redfish-core/include/utils/sw_utils.hpp489
-rw-r--r--redfish-core/include/utils/systemd_utils.hpp26
-rw-r--r--redfish-core/include/utils/time_utils.hpp3
-rw-r--r--redfish-core/lib/account_service.hpp1130
-rw-r--r--redfish-core/lib/bios.hpp14
-rw-r--r--redfish-core/lib/cable.hpp165
-rw-r--r--redfish-core/lib/certificate_service.hpp493
-rw-r--r--redfish-core/lib/chassis.hpp483
-rw-r--r--redfish-core/lib/ethernet.hpp1027
-rw-r--r--redfish-core/lib/event_service.hpp1160
-rw-r--r--redfish-core/lib/eventservice_sse.hpp26
-rw-r--r--redfish-core/lib/fabric_adapters.hpp198
-rw-r--r--redfish-core/lib/fan.hpp258
-rw-r--r--redfish-core/lib/hypervisor_system.hpp605
-rw-r--r--redfish-core/lib/led.hpp215
-rw-r--r--redfish-core/lib/log_services.hpp4178
-rw-r--r--redfish-core/lib/manager_diagnostic_data.hpp4
-rw-r--r--redfish-core/lib/manager_logservices_journal.hpp655
-rw-r--r--redfish-core/lib/managers.hpp2198
-rw-r--r--redfish-core/lib/memory.hpp310
-rw-r--r--redfish-core/lib/message_registries.hpp34
-rw-r--r--redfish-core/lib/metric_report.hpp111
-rw-r--r--redfish-core/lib/metric_report_definition.hpp809
-rw-r--r--redfish-core/lib/network_protocol.hpp199
-rw-r--r--redfish-core/lib/odata.hpp56
-rw-r--r--redfish-core/lib/pcie.hpp409
-rw-r--r--redfish-core/lib/pcie_slots.hpp23
-rw-r--r--redfish-core/lib/power.hpp58
-rw-r--r--redfish-core/lib/power_subsystem.hpp5
-rw-r--r--redfish-core/lib/power_supply.hpp472
-rw-r--r--redfish-core/lib/processor.hpp1230
-rw-r--r--redfish-core/lib/redfish_sessions.hpp67
-rw-r--r--redfish-core/lib/redfish_util.hpp298
-rw-r--r--redfish-core/lib/redfish_v1.hpp148
-rw-r--r--redfish-core/lib/roles.hpp157
-rw-r--r--redfish-core/lib/sensors.hpp2299
-rw-r--r--redfish-core/lib/service_root.hpp26
-rw-r--r--redfish-core/lib/storage.hpp642
-rw-r--r--redfish-core/lib/systems.hpp1689
-rw-r--r--redfish-core/lib/systems_logservices_hostlogger.hpp241
-rw-r--r--redfish-core/lib/systems_logservices_postcodes.hpp615
-rw-r--r--redfish-core/lib/task.hpp454
-rw-r--r--redfish-core/lib/telemetry_service.hpp83
-rw-r--r--redfish-core/lib/thermal.hpp122
-rw-r--r--redfish-core/lib/thermal_metrics.hpp19
-rw-r--r--redfish-core/lib/thermal_subsystem.hpp5
-rw-r--r--redfish-core/lib/trigger.hpp175
-rw-r--r--redfish-core/lib/update_service.hpp527
-rw-r--r--redfish-core/lib/virtual_media.hpp364
-rw-r--r--redfish-core/meson.build1
-rw-r--r--redfish-core/schema/dmtf/csdl/AccountService_v1.xml74
-rw-r--r--redfish-core/schema/dmtf/csdl/AggregationSource_v1.xml68
-rw-r--r--redfish-core/schema/dmtf/csdl/CXLLogicalDevice_v1.xml24
-rw-r--r--redfish-core/schema/dmtf/csdl/Certificate_v1.xml79
-rw-r--r--redfish-core/schema/dmtf/csdl/Chassis_v1.xml70
-rw-r--r--redfish-core/schema/dmtf/csdl/Circuit_v1.xml98
-rw-r--r--redfish-core/schema/dmtf/csdl/ComponentIntegrity_v1.xml34
-rw-r--r--redfish-core/schema/dmtf/csdl/ComputerSystem_v1.xml337
-rw-r--r--redfish-core/schema/dmtf/csdl/Control_v1.xml42
-rw-r--r--redfish-core/schema/dmtf/csdl/Drive_v1.xml226
-rw-r--r--redfish-core/schema/dmtf/csdl/EthernetInterface_v1.xml82
-rw-r--r--redfish-core/schema/dmtf/csdl/EventDestination_v1.xml72
-rw-r--r--redfish-core/schema/dmtf/csdl/Event_v1.xml22
-rw-r--r--redfish-core/schema/dmtf/csdl/ExternalAccountProvider_v1.xml25
-rw-r--r--redfish-core/schema/dmtf/csdl/LeakDetection_v1.xml17
-rw-r--r--redfish-core/schema/dmtf/csdl/LeakDetector_v1.xml31
-rw-r--r--redfish-core/schema/dmtf/csdl/LogEntry_v1.xml52
-rw-r--r--redfish-core/schema/dmtf/csdl/ManagerAccount_v1.xml136
-rw-r--r--redfish-core/schema/dmtf/csdl/Manager_v1.xml130
-rw-r--r--redfish-core/schema/dmtf/csdl/MemoryRegion_v1.xml10
-rw-r--r--redfish-core/schema/dmtf/csdl/Message_v1.xml20
-rw-r--r--redfish-core/schema/dmtf/csdl/MetricReport_v1.xml40
-rw-r--r--redfish-core/schema/dmtf/csdl/Outlet_v1.xml44
-rw-r--r--redfish-core/schema/dmtf/csdl/PCIeDevice_v1.xml40
-rw-r--r--redfish-core/schema/dmtf/csdl/PhysicalContext_v1.xml108
-rw-r--r--redfish-core/schema/dmtf/csdl/PortMetrics_v1.xml18
-rw-r--r--redfish-core/schema/dmtf/csdl/Port_v1.xml39
-rw-r--r--redfish-core/schema/dmtf/csdl/Processor_v1.xml142
-rw-r--r--redfish-core/schema/dmtf/csdl/RedfishExtensions_v1.xml4
-rw-r--r--redfish-core/schema/dmtf/csdl/Resource_v1.xml136
-rw-r--r--redfish-core/schema/dmtf/csdl/Sensor_v1.xml87
-rw-r--r--redfish-core/schema/dmtf/csdl/StorageController_v1.xml24
-rw-r--r--redfish-core/schema/dmtf/csdl/Storage_v1.xml279
-rw-r--r--redfish-core/schema/dmtf/csdl/UpdateService_v1.xml92
-rw-r--r--redfish-core/schema/dmtf/csdl/VolumeCollection_v1.xml2
-rw-r--r--redfish-core/schema/dmtf/csdl/Volume_v1.xml56
l---------redfish-core/schema/dmtf/installed/AccountService_v1.xml1
l---------redfish-core/schema/dmtf/installed/ActionInfo_v1.xml1
l---------redfish-core/schema/dmtf/installed/AggregationService_v1.xml1
l---------redfish-core/schema/dmtf/installed/AggregationSourceCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/AggregationSource_v1.xml1
l---------redfish-core/schema/dmtf/installed/Assembly_v1.xml1
l---------redfish-core/schema/dmtf/installed/AttributeRegistry_v1.xml1
l---------redfish-core/schema/dmtf/installed/Bios_v1.xml1
l---------redfish-core/schema/dmtf/installed/CableCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Cable_v1.xml1
l---------redfish-core/schema/dmtf/installed/CertificateCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/CertificateLocations_v1.xml1
l---------redfish-core/schema/dmtf/installed/CertificateService_v1.xml1
l---------redfish-core/schema/dmtf/installed/Certificate_v1.xml1
l---------redfish-core/schema/dmtf/installed/ChassisCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Chassis_v1.xml1
l---------redfish-core/schema/dmtf/installed/ComponentIntegrityCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/ComponentIntegrity_v1.xml1
l---------redfish-core/schema/dmtf/installed/ComputerSystemCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/ComputerSystem_v1.xml1
l---------redfish-core/schema/dmtf/installed/DriveCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Drive_v1.xml1
l---------redfish-core/schema/dmtf/installed/EnvironmentMetrics_v1.xml1
l---------redfish-core/schema/dmtf/installed/EthernetInterfaceCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/EthernetInterface_v1.xml1
l---------redfish-core/schema/dmtf/installed/EventDestinationCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/EventDestination_v1.xml1
l---------redfish-core/schema/dmtf/installed/EventService_v1.xml1
l---------redfish-core/schema/dmtf/installed/Event_v1.xml1
l---------redfish-core/schema/dmtf/installed/FabricAdapterCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/FabricAdapter_v1.xml1
l---------redfish-core/schema/dmtf/installed/FanCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Fan_v1.xml1
l---------redfish-core/schema/dmtf/installed/IPAddresses_v1.xml1
l---------redfish-core/schema/dmtf/installed/JsonSchemaFileCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/JsonSchemaFile_v1.xml1
l---------redfish-core/schema/dmtf/installed/LogEntryCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/LogEntry_v1.xml1
l---------redfish-core/schema/dmtf/installed/LogServiceCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/LogService_v1.xml1
l---------redfish-core/schema/dmtf/installed/ManagerAccountCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/ManagerAccount_v1.xml1
l---------redfish-core/schema/dmtf/installed/ManagerCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/ManagerDiagnosticData_v1.xml1
l---------redfish-core/schema/dmtf/installed/ManagerNetworkProtocol_v1.xml1
l---------redfish-core/schema/dmtf/installed/Manager_v1.xml1
l---------redfish-core/schema/dmtf/installed/MemoryCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Memory_v1.xml1
l---------redfish-core/schema/dmtf/installed/MessageRegistryCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/MessageRegistryFileCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/MessageRegistryFile_v1.xml1
l---------redfish-core/schema/dmtf/installed/MessageRegistry_v1.xml1
l---------redfish-core/schema/dmtf/installed/Message_v1.xml1
l---------redfish-core/schema/dmtf/installed/MetricDefinitionCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/MetricDefinition_v1.xml1
l---------redfish-core/schema/dmtf/installed/MetricReportCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/MetricReportDefinitionCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/MetricReportDefinition_v1.xml1
l---------redfish-core/schema/dmtf/installed/MetricReport_v1.xml1
l---------redfish-core/schema/dmtf/installed/OperatingConfigCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/OperatingConfig_v1.xml1
l---------redfish-core/schema/dmtf/installed/PCIeDeviceCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/PCIeDevice_v1.xml1
l---------redfish-core/schema/dmtf/installed/PCIeFunctionCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/PCIeFunction_v1.xml1
l---------redfish-core/schema/dmtf/installed/PCIeSlots_v1.xml1
l---------redfish-core/schema/dmtf/installed/PhysicalContext_v1.xml1
l---------redfish-core/schema/dmtf/installed/PortCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Port_v1.xml1
l---------redfish-core/schema/dmtf/installed/PowerSubsystem_v1.xml1
l---------redfish-core/schema/dmtf/installed/PowerSupplyCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/PowerSupply_v1.xml1
l---------redfish-core/schema/dmtf/installed/Power_v1.xml1
l---------redfish-core/schema/dmtf/installed/Privileges_v1.xml1
l---------redfish-core/schema/dmtf/installed/ProcessorCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Processor_v1.xml1
l---------redfish-core/schema/dmtf/installed/Protocol_v1.xml1
l---------redfish-core/schema/dmtf/installed/RedfishError_v1.xml1
l---------redfish-core/schema/dmtf/installed/RedfishExtensions_v1.xml1
l---------redfish-core/schema/dmtf/installed/Redundancy_v1.xml1
l---------redfish-core/schema/dmtf/installed/Resource_v1.xml1
l---------redfish-core/schema/dmtf/installed/RoleCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Role_v1.xml1
l---------redfish-core/schema/dmtf/installed/SensorCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Sensor_v1.xml1
l---------redfish-core/schema/dmtf/installed/ServiceRoot_v1.xml1
l---------redfish-core/schema/dmtf/installed/SessionCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/SessionService_v1.xml1
l---------redfish-core/schema/dmtf/installed/Session_v1.xml1
l---------redfish-core/schema/dmtf/installed/Settings_v1.xml1
l---------redfish-core/schema/dmtf/installed/SoftwareInventoryCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/SoftwareInventory_v1.xml1
l---------redfish-core/schema/dmtf/installed/StorageCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/StorageControllerCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/StorageController_v1.xml1
l---------redfish-core/schema/dmtf/installed/Storage_v1.xml1
l---------redfish-core/schema/dmtf/installed/TaskCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/TaskService_v1.xml1
l---------redfish-core/schema/dmtf/installed/Task_v1.xml1
l---------redfish-core/schema/dmtf/installed/TelemetryService_v1.xml1
l---------redfish-core/schema/dmtf/installed/ThermalMetrics_v1.xml1
l---------redfish-core/schema/dmtf/installed/ThermalSubsystem_v1.xml1
l---------redfish-core/schema/dmtf/installed/Thermal_v1.xml1
l---------redfish-core/schema/dmtf/installed/TriggersCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/Triggers_v1.xml1
l---------redfish-core/schema/dmtf/installed/UpdateService_v1.xml1
l---------redfish-core/schema/dmtf/installed/VirtualMediaCollection_v1.xml1
l---------redfish-core/schema/dmtf/installed/VirtualMedia_v1.xml1
l---------redfish-core/schema/dmtf/json-schema-installed/AccountService.v1_16_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ActionInfo.v1_4_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/AggregationService.v1_0_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/AggregationSource.v1_4_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/AggregationSourceCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Assembly.v1_5_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/AttributeRegistry.v1_3_9.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Bios.v1_2_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Cable.v1_2_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/CableCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Certificate.v1_9_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/CertificateCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/CertificateLocations.v1_0_4.json1
l---------redfish-core/schema/dmtf/json-schema-installed/CertificateService.v1_0_5.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Chassis.v1_25_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ChassisCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrity.v1_3_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrityCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ComputerSystem.v1_23_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ComputerSystemCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Drive.v1_20_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/DriveCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/EnvironmentMetrics.v1_3_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/EthernetInterface.v1_12_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/EthernetInterfaceCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Event.v1_11_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/EventDestination.v1_15_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/EventDestinationCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/EventService.v1_10_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/FabricAdapter.v1_5_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/FabricAdapterCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Fan.v1_5_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/FanCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/IPAddresses.v1_1_5.json1
l---------redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFile.v1_1_5.json1
l---------redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFileCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/LogEntry.v1_17_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/LogEntryCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/LogService.v1_7_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/LogServiceCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Manager.v1_19_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ManagerAccount.v1_13_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ManagerAccountCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ManagerCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ManagerDiagnosticData.v1_2_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ManagerNetworkProtocol.v1_10_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Memory.v1_20_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MemoryCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Message.v1_3_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MessageRegistry.v1_6_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MessageRegistryCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFile.v1_1_5.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFileCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MetricDefinition.v1_3_4.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MetricDefinitionCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MetricReport.v1_5_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MetricReportCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinition.v1_4_6.json1
l---------redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinitionCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/OperatingConfig.v1_0_4.json1
l---------redfish-core/schema/dmtf/json-schema-installed/OperatingConfigCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PCIeDevice.v1_16_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PCIeDeviceCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PCIeFunction.v1_6_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PCIeFunctionCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PCIeSlots.v1_6_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PhysicalContext.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Port.v1_14_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PortCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Power.v1_7_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PowerSubsystem.v1_1_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PowerSupply.v1_6_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/PowerSupplyCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Privileges.v1_0_6.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Processor.v1_20_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ProcessorCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Protocol.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Redundancy.v1_4_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Resource.v1_20_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Role.v1_3_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/RoleCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Sensor.v1_10_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/SensorCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ServiceRoot.v1_17_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Session.v1_7_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/SessionCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/SessionService.v1_1_9.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Settings.v1_4_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/SoftwareInventory.v1_10_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/SoftwareInventoryCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Storage.v1_17_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/StorageCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/StorageController.v1_8_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/StorageControllerCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Task.v1_7_4.json1
l---------redfish-core/schema/dmtf/json-schema-installed/TaskCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/TaskService.v1_2_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/TelemetryService.v1_3_4.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Thermal.v1_7_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ThermalMetrics.v1_3_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/ThermalSubsystem.v1_3_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/Triggers.v1_4_0.json1
l---------redfish-core/schema/dmtf/json-schema-installed/TriggersCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/UpdateService.v1_14_1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/VirtualMedia.v1_6_4.json1
l---------redfish-core/schema/dmtf/json-schema-installed/VirtualMediaCollection.json1
l---------redfish-core/schema/dmtf/json-schema-installed/odata-v4.json1
l---------redfish-core/schema/dmtf/json-schema-installed/odata.v4_0_5.json1
l---------redfish-core/schema/dmtf/json-schema-installed/redfish-error.v1_0_2.json1
l---------redfish-core/schema/dmtf/json-schema-installed/redfish-payload-annotations.v1_2_3.json1
l---------redfish-core/schema/dmtf/json-schema-installed/redfish-schema-v1.json1
l---------redfish-core/schema/dmtf/json-schema-installed/redfish-schema.v1_10_0.json1
-rw-r--r--redfish-core/schema/dmtf/json-schema/AccountService.v1_16_0.json (renamed from redfish-core/schema/dmtf/json-schema/AccountService.v1_15_1.json)96
-rw-r--r--redfish-core/schema/dmtf/json-schema/AggregationSource.v1_4_3.json (renamed from redfish-core/schema/dmtf/json-schema/AggregationSource.v1_4_1.json)16
-rw-r--r--redfish-core/schema/dmtf/json-schema/CXLLogicalDevice.v1_2_1.json (renamed from redfish-core/schema/dmtf/json-schema/CXLLogicalDevice.v1_2_0.json)8
-rw-r--r--redfish-core/schema/dmtf/json-schema/Certificate.v1_9_0.json (renamed from redfish-core/schema/dmtf/json-schema/Certificate.v1_8_2.json)15
-rw-r--r--redfish-core/schema/dmtf/json-schema/Chassis.v1_25_2.json (renamed from redfish-core/schema/dmtf/json-schema/Chassis.v1_25_1.json)6
-rw-r--r--redfish-core/schema/dmtf/json-schema/Circuit.v1_8_1.json (renamed from redfish-core/schema/dmtf/json-schema/Circuit.v1_8_0.json)20
-rw-r--r--redfish-core/schema/dmtf/json-schema/ComponentIntegrity.v1_3_0.json (renamed from redfish-core/schema/dmtf/json-schema/ComponentIntegrity.v1_2_3.json)16
-rw-r--r--redfish-core/schema/dmtf/json-schema/ComputerSystem.v1_23_0.json (renamed from redfish-core/schema/dmtf/json-schema/ComputerSystem.v1_22_1.json)54
-rw-r--r--redfish-core/schema/dmtf/json-schema/Control.v1_5_2.json (renamed from redfish-core/schema/dmtf/json-schema/Control.v1_5_1.json)8
-rw-r--r--redfish-core/schema/dmtf/json-schema/Drive.v1_20_1.json (renamed from redfish-core/schema/dmtf/json-schema/Drive.v1_19_0.json)200
-rw-r--r--redfish-core/schema/dmtf/json-schema/EthernetInterface.v1_12_2.json (renamed from redfish-core/schema/dmtf/json-schema/EthernetInterface.v1_12_1.json)6
-rw-r--r--redfish-core/schema/dmtf/json-schema/Event.v1_11_0.json (renamed from redfish-core/schema/dmtf/json-schema/Event.v1_10_1.json)26
-rw-r--r--redfish-core/schema/dmtf/json-schema/EventDestination.v1_15_0.json (renamed from redfish-core/schema/dmtf/json-schema/EventDestination.v1_14_1.json)28
-rw-r--r--redfish-core/schema/dmtf/json-schema/ExternalAccountProvider.v1_8_0.json (renamed from redfish-core/schema/dmtf/json-schema/ExternalAccountProvider.v1_7_2.json)36
-rw-r--r--redfish-core/schema/dmtf/json-schema/LeakDetection.v1_1_0.json (renamed from redfish-core/schema/dmtf/json-schema/LeakDetection.v1_0_1.json)15
-rw-r--r--redfish-core/schema/dmtf/json-schema/LeakDetector.v1_2_0.json (renamed from redfish-core/schema/dmtf/json-schema/LeakDetector.v1_1_0.json)24
-rw-r--r--redfish-core/schema/dmtf/json-schema/LogEntry.v1_17_0.json (renamed from redfish-core/schema/dmtf/json-schema/LogEntry.v1_16_1.json)28
-rw-r--r--redfish-core/schema/dmtf/json-schema/Manager.v1_19_2.json (renamed from redfish-core/schema/dmtf/json-schema/Manager.v1_19_1.json)12
-rw-r--r--redfish-core/schema/dmtf/json-schema/ManagerAccount.v1_13_0.json (renamed from redfish-core/schema/dmtf/json-schema/ManagerAccount.v1_12_1.json)168
-rw-r--r--redfish-core/schema/dmtf/json-schema/MemoryRegion.v1_0_3.json (renamed from redfish-core/schema/dmtf/json-schema/MemoryRegion.v1_0_2.json)6
-rw-r--r--redfish-core/schema/dmtf/json-schema/Message.v1_3_0.json (renamed from redfish-core/schema/dmtf/json-schema/Message.v1_2_1.json)26
-rw-r--r--redfish-core/schema/dmtf/json-schema/MetricReport.v1_5_2.json (renamed from redfish-core/schema/dmtf/json-schema/MetricReport.v1_5_1.json)6
-rw-r--r--redfish-core/schema/dmtf/json-schema/Outlet.v1_4_4.json (renamed from redfish-core/schema/dmtf/json-schema/Outlet.v1_4_3.json)16
-rw-r--r--redfish-core/schema/dmtf/json-schema/PCIeDevice.v1_16_0.json (renamed from redfish-core/schema/dmtf/json-schema/PCIeDevice.v1_14_0.json)26
-rw-r--r--redfish-core/schema/dmtf/json-schema/PhysicalContext.json54
-rw-r--r--redfish-core/schema/dmtf/json-schema/Port.v1_14_0.json (renamed from redfish-core/schema/dmtf/json-schema/Port.v1_12_0.json)37
-rw-r--r--redfish-core/schema/dmtf/json-schema/PortMetrics.v1_7_0.json (renamed from redfish-core/schema/dmtf/json-schema/PortMetrics.v1_6_1.json)17
-rw-r--r--redfish-core/schema/dmtf/json-schema/Processor.v1_20_1.json (renamed from redfish-core/schema/dmtf/json-schema/Processor.v1_20_0.json)18
-rw-r--r--redfish-core/schema/dmtf/json-schema/Resource.v1_20_0.json (renamed from redfish-core/schema/dmtf/json-schema/Resource.v1_19_0.json)6
-rw-r--r--redfish-core/schema/dmtf/json-schema/Sensor.v1_10_1.json (renamed from redfish-core/schema/dmtf/json-schema/Sensor.v1_9_0.json)42
-rw-r--r--redfish-core/schema/dmtf/json-schema/Storage.v1_17_1.json (renamed from redfish-core/schema/dmtf/json-schema/Storage.v1_16_0.json)225
-rw-r--r--redfish-core/schema/dmtf/json-schema/StorageController.v1_8_0.json (renamed from redfish-core/schema/dmtf/json-schema/StorageController.v1_7_3.json)17
-rw-r--r--redfish-core/schema/dmtf/json-schema/UpdateService.v1_14_1.json (renamed from redfish-core/schema/dmtf/json-schema/UpdateService.v1_14_0.json)4
-rw-r--r--redfish-core/schema/dmtf/json-schema/Volume.v1_10_0.json82
-rw-r--r--redfish-core/schema/dmtf/json-schema/VolumeCollection.json2
-rw-r--r--redfish-core/schema/dmtf/json-schema/info.json4
-rw-r--r--redfish-core/schema/dmtf/json-schema/redfish-payload-annotations-v1.json8
-rw-r--r--redfish-core/schema/dmtf/json-schema/redfish-payload-annotations.v1_2_3.json (renamed from redfish-core/schema/dmtf/json-schema/redfish-payload-annotations.v1_2_2.json)8
-rw-r--r--redfish-core/schema/dmtf/meson.build13
-rw-r--r--redfish-core/schema/meson.build2
-rw-r--r--redfish-core/schema/oem/meson.build1
-rw-r--r--redfish-core/schema/oem/openbmc/csdl/OemComputerSystem_v1.xml68
-rw-r--r--redfish-core/schema/oem/openbmc/csdl/OpenBMCAccountService_v1.xml15
-rw-r--r--redfish-core/schema/oem/openbmc/csdl/OpenBMCComputerSystem_v1.xml73
-rw-r--r--redfish-core/schema/oem/openbmc/csdl/OpenBMCManager_v1.xml (renamed from redfish-core/schema/oem/openbmc/csdl/OemManager_v1.xml)370
-rw-r--r--redfish-core/schema/oem/openbmc/csdl/OpenBMCVirtualMedia_v1.xml (renamed from redfish-core/schema/oem/openbmc/csdl/OemVirtualMedia_v1.xml)11
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.json8
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.v1_0_0.json (renamed from redfish-core/schema/oem/openbmc/json-schema/OemAccountService.json)11
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.json8
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.v1_0_0.json (renamed from redfish-core/schema/oem/openbmc/json-schema/OemComputerSystem.json)13
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.json8
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.v1_0_0.json (renamed from redfish-core/schema/oem/openbmc/json-schema/OemManager.json)167
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.json8
-rw-r--r--redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.v1_0_0.json (renamed from redfish-core/schema/oem/openbmc/json-schema/OemVirtualMedia.json)6
-rw-r--r--redfish-core/schema/oem/openbmc/meson.build23
-rw-r--r--redfish-core/src/error_messages.cpp154
-rw-r--r--redfish-core/src/filter_expr_executor.cpp109
-rw-r--r--redfish-core/src/filter_expr_printer.cpp9
-rw-r--r--redfish-core/src/redfish.cpp36
-rw-r--r--redfish-core/src/registries.cpp4
-rw-r--r--redfish-core/src/utils/dbus_utils.cpp13
-rw-r--r--redfish-core/src/utils/json_utils.cpp26
-rw-r--r--redfish-core/src/utils/time_utils.cpp3
403 files changed, 19219 insertions, 13928 deletions
diff --git a/redfish-core/include/aggregation_utils.hpp b/redfish-core/include/aggregation_utils.hpp
index f0b259eb9e..78ff3c227f 100644
--- a/redfish-core/include/aggregation_utils.hpp
+++ b/redfish-core/include/aggregation_utils.hpp
@@ -17,7 +17,7 @@ namespace redfish
{
// Note that each URI actually begins with "/redfish/v1"
// They've been omitted to save space and reduce search time
-constexpr std::array<std::string_view, 49> topCollections{
+constexpr std::array<std::string_view, 50> topCollections{
"/AggregationService/Aggregates",
"/AggregationService/AggregationSources",
"/AggregationService/ConnectionMethods",
@@ -52,6 +52,7 @@ constexpr std::array<std::string_view, 49> topCollections{
"/StorageServices",
"/StorageSystems",
"/Systems",
+ "/TaskService/TaskMonitors",
"/TaskService/Tasks",
"/TelemetryService/LogService/Entries",
"/TelemetryService/MetricDefinitions",
diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp
index 64ce9cbe96..020c33e07a 100644
--- a/redfish-core/include/error_messages.hpp
+++ b/redfish-core/include/error_messages.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -25,7 +25,6 @@
#include <string>
#include <string_view>
-// IWYU pragma: no_include <cstdint.h>
// IWYU pragma: no_forward_declare crow::Response
namespace redfish
@@ -86,14 +85,12 @@ void resourceMissingAtURI(crow::Response& res,
* @param[in] arg3 Parameter of message that will replace %3 in its body.
*
* @returns Message ActionParameterValueFormatError formatted to JSON */
-nlohmann::json actionParameterValueFormatError(const nlohmann::json& arg1,
- std::string_view arg2,
- std::string_view arg3);
+nlohmann::json actionParameterValueFormatError(
+ const nlohmann::json& arg1, std::string_view arg2, std::string_view arg3);
-void actionParameterValueFormatError(crow::Response& res,
- const nlohmann::json& arg1,
- std::string_view arg2,
- std::string_view arg3);
+void actionParameterValueFormatError(
+ crow::Response& res, const nlohmann::json& arg1, std::string_view arg2,
+ std::string_view arg3);
/**
* @brief Formats ActionParameterValueNotInList message into JSON
@@ -105,9 +102,8 @@ void actionParameterValueFormatError(crow::Response& res,
* @param[in] arg3 Parameter of message that will replace %3 in its body.
*
* @returns Message ActionParameterValueFormatError formatted to JSON */
-nlohmann::json actionParameterValueNotInList(std::string_view arg1,
- std::string_view arg2,
- std::string_view arg3);
+nlohmann::json actionParameterValueNotInList(
+ std::string_view arg1, std::string_view arg2, std::string_view arg3);
void actionParameterValueNotInList(crow::Response& res, std::string_view arg1,
std::string_view arg2,
@@ -211,9 +207,8 @@ void serviceTemporarilyUnavailable(crow::Response& res, std::string_view arg1);
* @param[in] arg3 Parameter of message that will replace %3 in its body.
*
* @returns Message ResourceAlreadyExists formatted to JSON */
-nlohmann::json resourceAlreadyExists(std::string_view arg1,
- std::string_view arg2,
- std::string_view arg3);
+nlohmann::json resourceAlreadyExists(
+ std::string_view arg1, std::string_view arg2, std::string_view arg3);
void resourceAlreadyExists(crow::Response& res, std::string_view arg1,
std::string_view arg2, std::string_view arg3);
@@ -461,10 +456,9 @@ void propertyValueConflict(crow::Response& res, std::string_view arg1,
* @param[in] arg3 Parameter of message that will replace %3 in its body.
*
* @returns Message PropertyValueResourceConflict to JSON */
-nlohmann::json
- propertyValueResourceConflict(std::string_view arg1,
- const nlohmann::json& arg2,
- const boost::urls::url_view_base& arg3);
+nlohmann::json propertyValueResourceConflict(
+ std::string_view arg1, const nlohmann::json& arg2,
+ const boost::urls::url_view_base& arg3);
void propertyValueResourceConflict(crow::Response& res, std::string_view arg1,
const nlohmann::json& arg2,
@@ -585,6 +579,17 @@ void propertyValueTypeError(crow::Response& res, const nlohmann::json& arg1,
std::string_view arg2);
/**
+ * @brief Formats PropertyValueError message into JSON
+ * Message body: "The value provided for the property <arg1> is not valid."
+ *
+ * @param[in] arg1 Parameter of message that will replace %1 in its body.
+ *
+ * @returns Message PropertyValueTypeError formatted to JSON */
+nlohmann::json propertyValueError(std::string_view arg1);
+
+void propertyValueError(crow::Response& res, std::string_view arg1);
+
+/**
* @brief Formats ResourceNotFound message into JSON
* Message body: "The requested resource of type <arg1> named <arg2> was not
* found."
@@ -636,9 +641,8 @@ void propertyNotWritable(crow::Response& res, std::string_view arg1);
nlohmann::json queryParameterValueTypeError(const nlohmann::json& arg1,
std::string_view arg2);
-void queryParameterValueTypeError(crow::Response& res,
- const nlohmann::json& arg1,
- std::string_view arg2);
+void queryParameterValueTypeError(
+ crow::Response& res, const nlohmann::json& arg1, std::string_view arg2);
/**
* @brief Formats ServiceShuttingDown message into JSON
@@ -690,9 +694,8 @@ void actionParameterNotSupported(crow::Response& res, std::string_view arg1,
* @param[in] arg2 Parameter of message that will replace %2 in its body.
*
* @returns Message SourceDoesNotSupportProtocol formatted to JSON */
-nlohmann::json
- sourceDoesNotSupportProtocol(const boost::urls::url_view_base& arg1,
- std::string_view arg2);
+nlohmann::json sourceDoesNotSupportProtocol(
+ const boost::urls::url_view_base& arg1, std::string_view arg2);
void sourceDoesNotSupportProtocol(crow::Response& res,
const boost::urls::url_view_base& arg1,
@@ -849,14 +852,12 @@ void resourceInStandby(crow::Response& res);
* @param[in] arg3 Parameter of message that will replace %3 in its body.
*
* @returns Message ActionParameterValueTypeError formatted to JSON */
-nlohmann::json actionParameterValueTypeError(const nlohmann::json& arg1,
- std::string_view arg2,
- std::string_view arg3);
+nlohmann::json actionParameterValueTypeError(
+ const nlohmann::json& arg1, std::string_view arg2, std::string_view arg3);
-void actionParameterValueTypeError(crow::Response& res,
- const nlohmann::json& arg1,
- std::string_view arg2,
- std::string_view arg3);
+void actionParameterValueTypeError(
+ crow::Response& res, const nlohmann::json& arg1, std::string_view arg2,
+ std::string_view arg3);
/**
* @brief Formats ActionParameterValueError message into JSON
@@ -1009,9 +1010,8 @@ void accountNotModified(crow::Response& res);
nlohmann::json queryParameterValueFormatError(const nlohmann::json& arg1,
std::string_view arg2);
-void queryParameterValueFormatError(crow::Response& res,
- const nlohmann::json& arg1,
- std::string_view arg2);
+void queryParameterValueFormatError(
+ crow::Response& res, const nlohmann::json& arg1, std::string_view arg2);
/**
* @brief Formats PropertyMissing message into JSON
@@ -1057,9 +1057,8 @@ void accountModified(crow::Response& res);
* @param[in] arg3 Parameter of message that will replace %3 in its body.
*
* @returns Message QueryParameterOutOfRange formatted to JSON */
-nlohmann::json queryParameterOutOfRange(std::string_view arg1,
- std::string_view arg2,
- std::string_view arg3);
+nlohmann::json queryParameterOutOfRange(
+ std::string_view arg1, std::string_view arg2, std::string_view arg3);
void queryParameterOutOfRange(crow::Response& res, std::string_view arg1,
std::string_view arg2, std::string_view arg3);
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 4c2d0eebbd..8fd0157f9d 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -1,22 +1,25 @@
/*
-// Copyright (c) 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "event_service_store.hpp"
+#include "filter_expr_executor.hpp"
+#include "generated/enums/event.hpp"
+#include "generated/enums/log_entry.hpp"
#include "http_client.hpp"
#include "metric_report.hpp"
#include "ossl_random.hpp"
@@ -31,6 +34,7 @@
#include <sys/inotify.h>
#include <boost/asio/io_context.hpp>
+#include <boost/circular_buffer.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/url/format.hpp>
#include <boost/url/url_view_base.hpp>
@@ -39,17 +43,16 @@
#include <algorithm>
#include <cstdlib>
#include <ctime>
+#include <format>
#include <fstream>
#include <memory>
#include <ranges>
#include <span>
+#include <string>
namespace redfish
{
-using ReadingsObjType =
- std::vector<std::tuple<std::string, std::string, double, int32_t>>;
-
static constexpr const char* eventFormatType = "Event";
static constexpr const char* metricReportFormatType = "MetricReport";
@@ -72,11 +75,13 @@ static int inotifyFd = -1;
static int dirWatchDesc = -1;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static int fileWatchDesc = -1;
-
-// <ID, timestamp, RedfishLogId, registryPrefix, MessageId, MessageArgs>
-using EventLogObjectsType =
- std::tuple<std::string, std::string, std::string, std::string, std::string,
- std::vector<std::string>>;
+struct EventLogObjectsType
+{
+ std::string id;
+ std::string timestamp;
+ std::string messageId;
+ std::vector<std::string> messageArgs;
+};
namespace registries
{
@@ -86,8 +91,8 @@ static const Message*
{
std::span<const MessageEntry>::iterator messageIt = std::ranges::find_if(
registry, [&messageKey](const MessageEntry& messageEntry) {
- return messageKey == messageEntry.first;
- });
+ return messageKey == messageEntry.first;
+ });
if (messageIt != registry.end())
{
return &messageIt->second;
@@ -159,6 +164,8 @@ inline int getEventLogParams(const std::string& logEntry,
size_t space = logEntry.find_first_of(' ');
if (space == std::string::npos)
{
+ BMCWEB_LOG_ERROR("EventLog Params: could not find first space: {}",
+ logEntry);
return -EINVAL;
}
timestamp = logEntry.substr(0, space);
@@ -166,6 +173,8 @@ inline int getEventLogParams(const std::string& logEntry,
size_t entryStart = logEntry.find_first_not_of(' ', space);
if (entryStart == std::string::npos)
{
+ BMCWEB_LOG_ERROR("EventLog Params: could not find log contents: {}",
+ logEntry);
return -EINVAL;
}
std::string_view entry(logEntry);
@@ -176,6 +185,8 @@ inline int getEventLogParams(const std::string& logEntry,
// We need at least a MessageId to be valid
if (logEntryFields.empty())
{
+ BMCWEB_LOG_ERROR("EventLog Params: could not find entry fields: {}",
+ logEntry);
return -EINVAL;
}
messageID = logEntryFields[0];
@@ -212,12 +223,10 @@ inline void getRegistryAndMessageKey(const std::string& messageID,
}
}
-inline int formatEventLogEntry(const std::string& logEntryID,
- const std::string& messageID,
- const std::span<std::string_view> messageArgs,
- std::string timestamp,
- const std::string& customText,
- nlohmann::json& logEntryJson)
+inline int formatEventLogEntry(
+ const std::string& logEntryID, const std::string& messageID,
+ const std::span<std::string_view> messageArgs, std::string timestamp,
+ const std::string& customText, nlohmann::json::object_t& logEntryJson)
{
// Get the Message from the MessageRegistry
const registries::Message* message = registries::formatMessage(messageID);
@@ -227,8 +236,8 @@ inline int formatEventLogEntry(const std::string& logEntryID,
return -1;
}
- std::string msg = redfish::registries::fillMessageArgs(messageArgs,
- message->message);
+ std::string msg =
+ redfish::registries::fillMessageArgs(messageArgs, message->message);
if (msg.empty())
{
return -1;
@@ -246,7 +255,7 @@ inline int formatEventLogEntry(const std::string& logEntryID,
// Fill in the log entry with the gathered data
logEntryJson["EventId"] = logEntryID;
- logEntryJson["EventType"] = "Event";
+
logEntryJson["Severity"] = message->messageSeverity;
logEntryJson["Message"] = std::move(msg);
logEntryJson["MessageId"] = messageID;
@@ -282,7 +291,7 @@ class Subscription : public persistent_data::UserSubscription
~Subscription() = default;
- bool sendEvent(std::string&& msg)
+ bool sendEventToSubscriber(std::string&& msg)
{
persistent_data::EventServiceConfig eventServiceConfig =
persistent_data::EventServiceStore::getInstance()
@@ -292,33 +301,158 @@ class Subscription : public persistent_data::UserSubscription
return false;
}
- // A connection pool will be created if one does not already exist
if (client)
{
- client->sendData(std::move(msg), destinationUrl, httpHeaders,
- boost::beast::http::verb::post);
+ client->sendData(
+ std::move(msg), destinationUrl,
+ static_cast<ensuressl::VerifyCertificate>(verifyCertificate),
+ httpHeaders, boost::beast::http::verb::post);
return true;
}
if (sseConn != nullptr)
{
eventSeqNum++;
- sseConn->sendEvent(std::to_string(eventSeqNum), msg);
+ sseConn->sendSseEvent(std::to_string(eventSeqNum), msg);
}
return true;
}
+ bool eventMatchesFilter(const nlohmann::json::object_t& eventMessage,
+ std::string_view resType)
+ {
+ // If resourceTypes list is empty, assume all
+ if (!resourceTypes.empty())
+ {
+ // Search the resourceTypes list for the subscription.
+ auto resourceTypeIndex = std::ranges::find_if(
+ resourceTypes, [resType](const std::string& rtEntry) {
+ return rtEntry == resType;
+ });
+ if (resourceTypeIndex == resourceTypes.end())
+ {
+ BMCWEB_LOG_DEBUG("Not subscribed to this resource");
+ return false;
+ }
+ BMCWEB_LOG_DEBUG("ResourceType {} found in the subscribed list",
+ resType);
+ }
+
+ // If registryPrefixes list is empty, don't filter events
+ // send everything.
+ if (!registryPrefixes.empty())
+ {
+ auto eventJson = eventMessage.find("MessageId");
+ if (eventJson == eventMessage.end())
+ {
+ return false;
+ }
+
+ const std::string* messageId =
+ eventJson->second.get_ptr<const std::string*>();
+ if (messageId == nullptr)
+ {
+ BMCWEB_LOG_ERROR("MessageId wasn't a string???");
+ return false;
+ }
+
+ std::string registry;
+ std::string messageKey;
+ event_log::getRegistryAndMessageKey(*messageId, registry,
+ messageKey);
+
+ auto obj = std::ranges::find(registryPrefixes, registry);
+ if (obj == registryPrefixes.end())
+ {
+ return false;
+ }
+ }
+
+ if (!originResources.empty())
+ {
+ auto eventJson = eventMessage.find("OriginOfCondition");
+ if (eventJson == eventMessage.end())
+ {
+ return false;
+ }
+
+ const std::string* originOfCondition =
+ eventJson->second.get_ptr<const std::string*>();
+ if (originOfCondition == nullptr)
+ {
+ BMCWEB_LOG_ERROR("OriginOfCondition wasn't a string???");
+ return false;
+ }
+
+ auto obj = std::ranges::find(originResources, *originOfCondition);
+
+ if (obj == originResources.end())
+ {
+ return false;
+ }
+ }
+
+ // If registryMsgIds list is empty, assume all
+ if (!registryMsgIds.empty())
+ {
+ auto eventJson = eventMessage.find("MessageId");
+ if (eventJson == eventMessage.end())
+ {
+ BMCWEB_LOG_DEBUG("'MessageId' not present");
+ return false;
+ }
+
+ const std::string* messageId =
+ eventJson->second.get_ptr<const std::string*>();
+ if (messageId == nullptr)
+ {
+ BMCWEB_LOG_ERROR("EventType wasn't a string???");
+ return false;
+ }
+
+ std::string registry;
+ std::string messageKey;
+ event_log::getRegistryAndMessageKey(*messageId, registry,
+ messageKey);
+
+ BMCWEB_LOG_DEBUG("extracted registry {}", registry);
+ BMCWEB_LOG_DEBUG("extracted message key {}", messageKey);
+
+ auto obj = std::ranges::find(
+ registryMsgIds, std::format("{}.{}", registry, messageKey));
+ if (obj == registryMsgIds.end())
+ {
+ BMCWEB_LOG_DEBUG("did not find registry {} in registryMsgIds",
+ registry);
+ BMCWEB_LOG_DEBUG("registryMsgIds has {} entries",
+ registryMsgIds.size());
+ return false;
+ }
+ }
+
+ if (filter)
+ {
+ if (!memberMatches(eventMessage, *filter))
+ {
+ BMCWEB_LOG_DEBUG("Filter didn't match");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
bool sendTestEventLog()
{
- nlohmann::json logEntryArray;
- logEntryArray.push_back({});
- nlohmann::json& logEntryJson = logEntryArray.back();
+ nlohmann::json::array_t logEntryArray;
+ nlohmann::json& logEntryJson = logEntryArray.emplace_back();
logEntryJson["EventId"] = "TestID";
- logEntryJson["EventType"] = "Event";
- logEntryJson["Severity"] = "OK";
+ logEntryJson["Severity"] = log_entry::EventSeverity::OK;
logEntryJson["Message"] = "Generated test event";
logEntryJson["MessageId"] = "OpenBMC.0.2.TestEventLog";
+ // MemberId is 0 : since we are sending one event record.
+ logEntryJson["MemberId"] = 0;
logEntryJson["MessageArgs"] = nlohmann::json::array();
logEntryJson["EventTimestamp"] =
redfish::time_utils::getDateTimeOffsetNow().first;
@@ -330,58 +464,37 @@ class Subscription : public persistent_data::UserSubscription
msg["Name"] = "Event Log";
msg["Events"] = logEntryArray;
- std::string strMsg = msg.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
- return sendEvent(std::move(strMsg));
+ std::string strMsg =
+ msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+ return sendEventToSubscriber(std::move(strMsg));
}
void filterAndSendEventLogs(
const std::vector<EventLogObjectsType>& eventRecords)
{
- nlohmann::json logEntryArray;
+ nlohmann::json::array_t logEntryArray;
for (const EventLogObjectsType& logEntry : eventRecords)
{
- const std::string& idStr = std::get<0>(logEntry);
- const std::string& timestamp = std::get<1>(logEntry);
- const std::string& messageID = std::get<2>(logEntry);
- const std::string& registryName = std::get<3>(logEntry);
- const std::string& messageKey = std::get<4>(logEntry);
- const std::vector<std::string>& messageArgs = std::get<5>(logEntry);
-
- // If registryPrefixes list is empty, don't filter events
- // send everything.
- if (!registryPrefixes.empty())
- {
- auto obj = std::ranges::find(registryPrefixes, registryName);
- if (obj == registryPrefixes.end())
- {
- continue;
- }
- }
+ std::vector<std::string_view> messageArgsView(
+ logEntry.messageArgs.begin(), logEntry.messageArgs.end());
- // If registryMsgIds list is empty, don't filter events
- // send everything.
- if (!registryMsgIds.empty())
+ nlohmann::json::object_t bmcLogEntry;
+ if (event_log::formatEventLogEntry(
+ logEntry.id, logEntry.messageId, messageArgsView,
+ logEntry.timestamp, customText, bmcLogEntry) != 0)
{
- auto obj = std::ranges::find(registryMsgIds, messageKey);
- if (obj == registryMsgIds.end())
- {
- continue;
- }
+ BMCWEB_LOG_DEBUG("Read eventLog entry failed");
+ continue;
}
- std::vector<std::string_view> messageArgsView(messageArgs.begin(),
- messageArgs.end());
-
- logEntryArray.push_back({});
- nlohmann::json& bmcLogEntry = logEntryArray.back();
- if (event_log::formatEventLogEntry(idStr, messageID,
- messageArgsView, timestamp,
- customText, bmcLogEntry) != 0)
+ if (!eventMatchesFilter(bmcLogEntry, ""))
{
- BMCWEB_LOG_DEBUG("Read eventLog entry failed");
+ BMCWEB_LOG_DEBUG("Event {} did not match the filter",
+ nlohmann::json(bmcLogEntry).dump());
continue;
}
+
+ logEntryArray.emplace_back(std::move(bmcLogEntry));
}
if (logEntryArray.empty())
@@ -394,10 +507,10 @@ class Subscription : public persistent_data::UserSubscription
msg["@odata.type"] = "#Event.v1_4_0.Event";
msg["Id"] = std::to_string(eventSeqNum);
msg["Name"] = "Event Log";
- msg["Events"] = logEntryArray;
- std::string strMsg = msg.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
- sendEvent(std::move(strMsg));
+ msg["Events"] = std::move(logEntryArray);
+ std::string strMsg =
+ msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+ sendEventToSubscriber(std::move(strMsg));
eventSeqNum++;
}
@@ -434,9 +547,9 @@ class Subscription : public persistent_data::UserSubscription
msg["Context"] = customText;
}
- std::string strMsg = msg.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
- sendEvent(std::move(strMsg));
+ std::string strMsg =
+ msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+ sendEventToSubscriber(std::move(strMsg));
}
void updateRetryConfig(uint32_t retryAttempts,
@@ -472,16 +585,6 @@ class Subscription : public persistent_data::UserSubscription
return &thisConn == sseConn;
}
- private:
- std::string subId;
- uint64_t eventSeqNum = 1;
- boost::urls::url host;
- std::shared_ptr<crow::ConnectionPolicy> policy;
- crow::sse_socket::Connection* sseConn = nullptr;
- std::optional<crow::HttpClient> client;
- std::string path;
- std::string uriProto;
-
// Check used to indicate what response codes are valid as part of our retry
// policy. 2XX is considered acceptable
static boost::system::error_code retryRespHandler(unsigned int respCode)
@@ -498,6 +601,18 @@ class Subscription : public persistent_data::UserSubscription
return boost::system::errc::make_error_code(
boost::system::errc::success);
}
+
+ private:
+ std::string subId;
+ uint64_t eventSeqNum = 1;
+ boost::urls::url host;
+ std::shared_ptr<crow::ConnectionPolicy> policy;
+ crow::sse_socket::Connection* sseConn = nullptr;
+
+ std::optional<crow::HttpClient> client;
+
+ public:
+ std::optional<filter_ast::LogicalAnd> filter;
};
class EventServiceManager
@@ -516,6 +631,15 @@ class EventServiceManager
uint64_t eventId{1};
+ struct Event
+ {
+ std::string id;
+ nlohmann::json message;
+ };
+
+ constexpr static size_t maxMessages = 200;
+ boost::circular_buffer<Event> messages{maxMessages};
+
boost::asio::io_context& ioc;
public:
@@ -571,6 +695,7 @@ class EventServiceManager
subValue->id = newSub->id;
subValue->destinationUrl = newSub->destinationUrl;
subValue->protocol = newSub->protocol;
+ subValue->verifyCertificate = newSub->verifyCertificate;
subValue->retryPolicy = newSub->retryPolicy;
subValue->customText = newSub->customText;
subValue->eventFormatType = newSub->eventFormatType;
@@ -580,6 +705,7 @@ class EventServiceManager
subValue->resourceTypes = newSub->resourceTypes;
subValue->httpHeaders = newSub->httpHeaders;
subValue->metricReportDefinitions = newSub->metricReportDefinitions;
+ subValue->originResources = newSub->originResources;
if (subValue->id.empty())
{
@@ -796,8 +922,8 @@ class EventServiceManager
return subValue;
}
- std::string addSubscription(const std::shared_ptr<Subscription>& subValue,
- const bool updateFile = true)
+ std::string
+ addSubscriptionInternal(const std::shared_ptr<Subscription>& subValue)
{
std::uniform_int_distribution<uint32_t> dist(0);
bmcweb::OpenSSLGenerator gen;
@@ -841,16 +967,13 @@ class EventServiceManager
newSub->resourceTypes = subValue->resourceTypes;
newSub->httpHeaders = subValue->httpHeaders;
newSub->metricReportDefinitions = subValue->metricReportDefinitions;
+ newSub->originResources = subValue->originResources;
+
persistent_data::EventServiceStore::getInstance()
.subscriptionsConfigMap.emplace(newSub->id, newSub);
updateNoOfSubscribersCount();
- if (updateFile)
- {
- updateSubscriptionData();
- }
-
if constexpr (!BMCWEB_REDFISH_DBUS_LOG)
{
if (redfishLogFilePosition != 0)
@@ -863,6 +986,55 @@ class EventServiceManager
// Set Subscription ID for back trace
subValue->setSubscriptionId(id);
+
+ return id;
+ }
+
+ std::string
+ addSSESubscription(const std::shared_ptr<Subscription>& subValue,
+ std::string_view lastEventId)
+ {
+ std::string id = addSubscriptionInternal(subValue);
+
+ if (!lastEventId.empty())
+ {
+ BMCWEB_LOG_INFO("Attempting to find message for last id {}",
+ lastEventId);
+ boost::circular_buffer<Event>::iterator lastEvent =
+ std::find_if(messages.begin(), messages.end(),
+ [&lastEventId](const Event& event) {
+ return event.id == lastEventId;
+ });
+ // Can't find a matching ID
+ if (lastEvent == messages.end())
+ {
+ nlohmann::json msg = messages::eventBufferExceeded();
+ // If the buffer overloaded, send all messages.
+ subValue->sendEventToSubscriber(msg);
+ lastEvent = messages.begin();
+ }
+ else
+ {
+ // Skip the last event the user already has
+ lastEvent++;
+ }
+
+ for (boost::circular_buffer<Event>::const_iterator event =
+ lastEvent;
+ lastEvent != messages.end(); lastEvent++)
+ {
+ subValue->sendEventToSubscriber(event->message);
+ }
+ }
+ return id;
+ }
+
+ std::string
+ addPushSubscription(const std::shared_ptr<Subscription>& subValue)
+ {
+ std::string id = addSubscriptionInternal(subValue);
+
+ updateSubscriptionData();
return id;
}
@@ -916,8 +1088,8 @@ class EventServiceManager
subscriptionsMap,
[](const std::pair<std::string, std::shared_ptr<Subscription>>&
entry) {
- return (entry.second->subscriptionType == subscriptionTypeSSE);
- });
+ return (entry.second->subscriptionType == subscriptionTypeSSE);
+ });
return static_cast<size_t>(size);
}
@@ -944,68 +1116,43 @@ class EventServiceManager
return true;
}
- void sendEvent(nlohmann::json eventMessage, const std::string& origin,
- const std::string& resType)
+ void sendEvent(nlohmann::json::object_t eventMessage,
+ std::string_view origin, std::string_view resourceType)
{
- if (!serviceEnabled || (noOfEventLogSubscribers == 0U))
- {
- BMCWEB_LOG_DEBUG("EventService disabled or no Subscriptions.");
- return;
- }
- nlohmann::json eventRecord = nlohmann::json::array();
-
eventMessage["EventId"] = eventId;
- // MemberId is 0 : since we are sending one event record.
- eventMessage["MemberId"] = 0;
+
eventMessage["EventTimestamp"] =
redfish::time_utils::getDateTimeOffsetNow().first;
eventMessage["OriginOfCondition"] = origin;
- eventRecord.emplace_back(std::move(eventMessage));
+ // MemberId is 0 : since we are sending one event record.
+ eventMessage["MemberId"] = 0;
- for (const auto& it : subscriptionsMap)
+ messages.push_back(Event(std::to_string(eventId), eventMessage));
+
+ for (auto& it : subscriptionsMap)
{
- std::shared_ptr<Subscription> entry = it.second;
- bool isSubscribed = false;
- // Search the resourceTypes list for the subscription.
- // If resourceTypes list is empty, don't filter events
- // send everything.
- if (!entry->resourceTypes.empty())
+ std::shared_ptr<Subscription>& entry = it.second;
+ if (!entry->eventMatchesFilter(eventMessage, resourceType))
{
- for (const auto& resource : entry->resourceTypes)
- {
- if (resType == resource)
- {
- BMCWEB_LOG_INFO(
- "ResourceType {} found in the subscribed list",
- resource);
- isSubscribed = true;
- break;
- }
- }
- }
- else // resourceTypes list is empty.
- {
- isSubscribed = true;
+ BMCWEB_LOG_DEBUG("Filter didn't match");
+ continue;
}
- if (isSubscribed)
- {
- nlohmann::json msgJson;
- msgJson["@odata.type"] = "#Event.v1_4_0.Event";
- msgJson["Name"] = "Event Log";
- msgJson["Id"] = eventId;
- msgJson["Events"] = eventRecord;
+ nlohmann::json::array_t eventRecord;
+ eventRecord.emplace_back(eventMessage);
- std::string strMsg = msgJson.dump(
- 2, ' ', true, nlohmann::json::error_handler_t::replace);
- entry->sendEvent(std::move(strMsg));
- eventId++; // increment the eventId
- }
- else
- {
- BMCWEB_LOG_INFO("Not subscribed to this resource");
- }
+ nlohmann::json msgJson;
+
+ msgJson["@odata.type"] = "#Event.v1_4_0.Event";
+ msgJson["Name"] = "Event Log";
+ msgJson["Id"] = eventId;
+ msgJson["Events"] = std::move(eventRecord);
+
+ std::string strMsg = msgJson.dump(
+ 2, ' ', true, nlohmann::json::error_handler_t::replace);
+ entry->sendEventToSubscriber(std::move(strMsg));
+ eventId++; // increment the eventId
}
}
@@ -1046,17 +1193,24 @@ class EventServiceManager
std::string logEntry;
+ BMCWEB_LOG_DEBUG("Redfish log file: seek to {}",
+ static_cast<int>(redfishLogFilePosition));
+
// Get the read pointer to the next log to be read.
logStream.seekg(redfishLogFilePosition);
while (std::getline(logStream, logEntry))
{
+ BMCWEB_LOG_DEBUG("Redfish log file: found new event log entry");
// Update Pointer position
redfishLogFilePosition = logStream.tellg();
std::string idStr;
if (!event_log::getUniqueEntryID(logEntry, idStr))
{
+ BMCWEB_LOG_DEBUG(
+ "Redfish log file: could not get unique entry id for {}",
+ logEntry);
continue;
}
@@ -1065,6 +1219,8 @@ class EventServiceManager
// If Service is not enabled, no need to compute
// the remaining items below.
// But, Loop must continue to keep track of Timestamp
+ BMCWEB_LOG_DEBUG(
+ "Redfish log file: no subscribers / event service not enabled");
continue;
}
@@ -1074,21 +1230,12 @@ class EventServiceManager
if (event_log::getEventLogParams(logEntry, timestamp, messageID,
messageArgs) != 0)
{
- BMCWEB_LOG_DEBUG("Read eventLog entry params failed");
+ BMCWEB_LOG_DEBUG("Read eventLog entry params failed for {}",
+ logEntry);
continue;
}
- std::string registryName;
- std::string messageKey;
- event_log::getRegistryAndMessageKey(messageID, registryName,
- messageKey);
- if (registryName.empty() || messageKey.empty())
- {
- continue;
- }
-
- eventRecords.emplace_back(idStr, timestamp, messageID, registryName,
- messageKey, messageArgs);
+ eventRecords.emplace_back(idStr, timestamp, messageID, messageArgs);
}
if (!serviceEnabled || noOfEventLogSubscribers == 0)
@@ -1118,98 +1265,110 @@ class EventServiceManager
{
if (!inotifyConn)
{
+ BMCWEB_LOG_ERROR("inotify Connection is not present");
return;
}
static std::array<char, 1024> readBuffer;
- inotifyConn->async_read_some(boost::asio::buffer(readBuffer),
- [&](const boost::system::error_code& ec,
- const std::size_t& bytesTransferred) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Callback Error: {}", ec.message());
- return;
- }
- std::size_t index = 0;
- while ((index + iEventSize) <= bytesTransferred)
- {
- struct inotify_event event
- {};
- std::memcpy(&event, &readBuffer[index], iEventSize);
- if (event.wd == dirWatchDesc)
+ inotifyConn->async_read_some(
+ boost::asio::buffer(readBuffer),
+ [&](const boost::system::error_code& ec,
+ const std::size_t& bytesTransferred) {
+ if (ec == boost::asio::error::operation_aborted)
{
- if ((event.len == 0) ||
- (index + iEventSize + event.len > bytesTransferred))
- {
- index += (iEventSize + event.len);
- continue;
- }
+ BMCWEB_LOG_DEBUG("Inotify was canceled (shutdown?)");
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Callback Error: {}", ec.message());
+ return;
+ }
- std::string fileName(&readBuffer[index + iEventSize]);
- if (fileName != "redfish")
- {
- index += (iEventSize + event.len);
- continue;
- }
+ BMCWEB_LOG_DEBUG("reading {} via inotify", bytesTransferred);
- BMCWEB_LOG_DEBUG(
- "Redfish log file created/deleted. event.name: {}",
- fileName);
- if (event.mask == IN_CREATE)
+ std::size_t index = 0;
+ while ((index + iEventSize) <= bytesTransferred)
+ {
+ struct inotify_event event
+ {};
+ std::memcpy(&event, &readBuffer[index], iEventSize);
+ if (event.wd == dirWatchDesc)
{
- if (fileWatchDesc != -1)
+ if ((event.len == 0) ||
+ (index + iEventSize + event.len > bytesTransferred))
{
- BMCWEB_LOG_DEBUG(
- "Remove and Add inotify watcher on "
- "redfish event log file");
- // Remove existing inotify watcher and add
- // with new redfish event log file.
- inotify_rm_watch(inotifyFd, fileWatchDesc);
- fileWatchDesc = -1;
+ index += (iEventSize + event.len);
+ continue;
}
- fileWatchDesc = inotify_add_watch(
- inotifyFd, redfishEventLogFile, IN_MODIFY);
- if (fileWatchDesc == -1)
+ std::string fileName(&readBuffer[index + iEventSize]);
+ if (fileName != "redfish")
{
- BMCWEB_LOG_ERROR("inotify_add_watch failed for "
- "redfish log file.");
- return;
+ index += (iEventSize + event.len);
+ continue;
}
- EventServiceManager::getInstance()
- .resetRedfishFilePosition();
- EventServiceManager::getInstance()
- .readEventLogsFromFile();
- }
- else if ((event.mask == IN_DELETE) ||
- (event.mask == IN_MOVED_TO))
- {
- if (fileWatchDesc != -1)
+ BMCWEB_LOG_DEBUG(
+ "Redfish log file created/deleted. event.name: {}",
+ fileName);
+ if (event.mask == IN_CREATE)
{
- inotify_rm_watch(inotifyFd, fileWatchDesc);
- fileWatchDesc = -1;
+ if (fileWatchDesc != -1)
+ {
+ BMCWEB_LOG_DEBUG(
+ "Remove and Add inotify watcher on "
+ "redfish event log file");
+ // Remove existing inotify watcher and add
+ // with new redfish event log file.
+ inotify_rm_watch(inotifyFd, fileWatchDesc);
+ fileWatchDesc = -1;
+ }
+
+ fileWatchDesc = inotify_add_watch(
+ inotifyFd, redfishEventLogFile, IN_MODIFY);
+ if (fileWatchDesc == -1)
+ {
+ BMCWEB_LOG_ERROR("inotify_add_watch failed for "
+ "redfish log file.");
+ return;
+ }
+
+ EventServiceManager::getInstance()
+ .resetRedfishFilePosition();
+ EventServiceManager::getInstance()
+ .readEventLogsFromFile();
+ }
+ else if ((event.mask == IN_DELETE) ||
+ (event.mask == IN_MOVED_TO))
+ {
+ if (fileWatchDesc != -1)
+ {
+ inotify_rm_watch(inotifyFd, fileWatchDesc);
+ fileWatchDesc = -1;
+ }
}
}
- }
- else if (event.wd == fileWatchDesc)
- {
- if (event.mask == IN_MODIFY)
+ else if (event.wd == fileWatchDesc)
{
- EventServiceManager::getInstance()
- .readEventLogsFromFile();
+ if (event.mask == IN_MODIFY)
+ {
+ EventServiceManager::getInstance()
+ .readEventLogsFromFile();
+ }
}
+ index += (iEventSize + event.len);
}
- index += (iEventSize + event.len);
- }
- watchRedfishEventLogFile();
- });
+ watchRedfishEventLogFile();
+ });
}
static int startEventLogMonitor(boost::asio::io_context& ioc)
{
+ BMCWEB_LOG_DEBUG("starting Event Log Monitor");
+
inotifyConn.emplace(ioc);
inotifyFd = inotify_init1(IN_NONBLOCK);
if (inotifyFd == -1)
@@ -1230,8 +1389,8 @@ class EventServiceManager
}
// Watch redfish event log file for modifications.
- fileWatchDesc = inotify_add_watch(inotifyFd, redfishEventLogFile,
- IN_MODIFY);
+ fileWatchDesc =
+ inotify_add_watch(inotifyFd, redfishEventLogFile, IN_MODIFY);
if (fileWatchDesc == -1)
{
BMCWEB_LOG_ERROR("inotify_add_watch failed for redfish log file.");
@@ -1246,6 +1405,11 @@ class EventServiceManager
return 0;
}
+ static void stopEventLogMonitor()
+ {
+ inotifyConn.reset();
+ }
+
static void getReadingsForReport(sdbusplus::message_t& msg)
{
if (msg.is_method_error())
@@ -1267,8 +1431,9 @@ class EventServiceManager
std::vector<std::string> invalidProps;
msg.read(interface, props, invalidProps);
- auto found = std::ranges::find_if(
- props, [](const auto& x) { return x.first == "Readings"; });
+ auto found = std::ranges::find_if(props, [](const auto& x) {
+ return x.first == "Readings";
+ });
if (found == props.end())
{
BMCWEB_LOG_INFO("Failed to get Readings from Report properties");
diff --git a/redfish-core/include/filter_expr_executor.hpp b/redfish-core/include/filter_expr_executor.hpp
index a5aef04c54..66217a5da1 100644
--- a/redfish-core/include/filter_expr_executor.hpp
+++ b/redfish-core/include/filter_expr_executor.hpp
@@ -7,7 +7,10 @@
namespace redfish
{
-bool applyFilter(nlohmann::json& body,
- const filter_ast::LogicalAnd& filterParam);
+bool memberMatches(const nlohmann::json& member,
+ const filter_ast::LogicalAnd& filterParam);
-}
+bool applyFilterToCollection(nlohmann::json& body,
+ const filter_ast::LogicalAnd& filterParam);
+
+} // namespace redfish
diff --git a/redfish-core/include/filter_expr_parser_ast.hpp b/redfish-core/include/filter_expr_parser_ast.hpp
index b27dbb4f72..a9303fe320 100644
--- a/redfish-core/include/filter_expr_parser_ast.hpp
+++ b/redfish-core/include/filter_expr_parser_ast.hpp
@@ -1,6 +1,5 @@
#pragma once
#include <boost/fusion/include/adapt_struct.hpp>
-#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <iostream>
diff --git a/redfish-core/include/filter_expr_parser_grammar.hpp b/redfish-core/include/filter_expr_parser_grammar.hpp
index 1b422ff147..939a683f1b 100644
--- a/redfish-core/include/filter_expr_parser_grammar.hpp
+++ b/redfish-core/include/filter_expr_parser_grammar.hpp
@@ -50,8 +50,8 @@ const rule<class LogicalNotId, LogicalNot> logicalNot("LogicalNot");
///// BEGIN GRAMMAR
// Two types of strings.
-const auto quotedString_def = '\'' >> lexeme[*('\\' >> char_ | ~char_('\''))] >>
- '\'';
+const auto quotedString_def =
+ '\'' >> lexeme[*('\\' >> char_ | ~char_('\''))] >> '\'';
const auto unquotedString_def = char_("a-zA-Z") >> *(char_("a-zA-Z0-9[]/"));
// Make sure we only parse true floating points as doubles
diff --git a/redfish-core/include/generated/enums/account_service.hpp b/redfish-core/include/generated/enums/account_service.hpp
index e06b5f288d..761e681ed9 100644
--- a/redfish-core/include/generated/enums/account_service.hpp
+++ b/redfish-core/include/generated/enums/account_service.hpp
@@ -13,6 +13,7 @@ enum class MFABypassType{
MicrosoftAuthenticator,
ClientCertificate,
OneTimePasscode,
+ TimeBasedOneTimePassword,
OEM,
};
@@ -79,6 +80,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(MFABypassType, {
{MFABypassType::MicrosoftAuthenticator, "MicrosoftAuthenticator"},
{MFABypassType::ClientCertificate, "ClientCertificate"},
{MFABypassType::OneTimePasscode, "OneTimePasscode"},
+ {MFABypassType::TimeBasedOneTimePassword, "TimeBasedOneTimePassword"},
{MFABypassType::OEM, "OEM"},
});
diff --git a/redfish-core/include/generated/enums/certificate.hpp b/redfish-core/include/generated/enums/certificate.hpp
index d647bc5d40..45094b445f 100644
--- a/redfish-core/include/generated/enums/certificate.hpp
+++ b/redfish-core/include/generated/enums/certificate.hpp
@@ -43,6 +43,7 @@ enum class CertificateUsageType{
LDevID,
IAK,
LAK,
+ EK,
};
NLOHMANN_JSON_SERIALIZE_ENUM(CertificateType, {
@@ -83,6 +84,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(CertificateUsageType, {
{CertificateUsageType::LDevID, "LDevID"},
{CertificateUsageType::IAK, "IAK"},
{CertificateUsageType::LAK, "LAK"},
+ {CertificateUsageType::EK, "EK"},
});
}
diff --git a/redfish-core/include/generated/enums/component_integrity.hpp b/redfish-core/include/generated/enums/component_integrity.hpp
index 433b195e46..26ed422615 100644
--- a/redfish-core/include/generated/enums/component_integrity.hpp
+++ b/redfish-core/include/generated/enums/component_integrity.hpp
@@ -9,6 +9,8 @@ enum class ComponentIntegrityType{
Invalid,
SPDM,
TPM,
+ TCM,
+ TPCM,
OEM,
};
@@ -51,6 +53,8 @@ NLOHMANN_JSON_SERIALIZE_ENUM(ComponentIntegrityType, {
{ComponentIntegrityType::Invalid, "Invalid"},
{ComponentIntegrityType::SPDM, "SPDM"},
{ComponentIntegrityType::TPM, "TPM"},
+ {ComponentIntegrityType::TCM, "TCM"},
+ {ComponentIntegrityType::TPCM, "TPCM"},
{ComponentIntegrityType::OEM, "OEM"},
});
diff --git a/redfish-core/include/generated/enums/computer_system.hpp b/redfish-core/include/generated/enums/computer_system.hpp
index cb053af979..9c04c3acd7 100644
--- a/redfish-core/include/generated/enums/computer_system.hpp
+++ b/redfish-core/include/generated/enums/computer_system.hpp
@@ -198,6 +198,20 @@ enum class DecommissionType{
Logs,
};
+enum class LastResetCauses{
+ Invalid,
+ PowerButtonPress,
+ ManagementCommand,
+ PowerRestorePolicy,
+ RTCWakeup,
+ WatchdogExpiration,
+ OSSoftRestart,
+ SystemCrash,
+ ThermalEvent,
+ PowerEvent,
+ Unknown,
+};
+
NLOHMANN_JSON_SERIALIZE_ENUM(BootSource, {
{BootSource::Invalid, "Invalid"},
{BootSource::None, "None"},
@@ -391,5 +405,19 @@ NLOHMANN_JSON_SERIALIZE_ENUM(DecommissionType, {
{DecommissionType::Logs, "Logs"},
});
+NLOHMANN_JSON_SERIALIZE_ENUM(LastResetCauses, {
+ {LastResetCauses::Invalid, "Invalid"},
+ {LastResetCauses::PowerButtonPress, "PowerButtonPress"},
+ {LastResetCauses::ManagementCommand, "ManagementCommand"},
+ {LastResetCauses::PowerRestorePolicy, "PowerRestorePolicy"},
+ {LastResetCauses::RTCWakeup, "RTCWakeup"},
+ {LastResetCauses::WatchdogExpiration, "WatchdogExpiration"},
+ {LastResetCauses::OSSoftRestart, "OSSoftRestart"},
+ {LastResetCauses::SystemCrash, "SystemCrash"},
+ {LastResetCauses::ThermalEvent, "ThermalEvent"},
+ {LastResetCauses::PowerEvent, "PowerEvent"},
+ {LastResetCauses::Unknown, "Unknown"},
+});
+
}
// clang-format on
diff --git a/redfish-core/include/generated/enums/drive.hpp b/redfish-core/include/generated/enums/drive.hpp
index 6bf5094a25..abf3205fad 100644
--- a/redfish-core/include/generated/enums/drive.hpp
+++ b/redfish-core/include/generated/enums/drive.hpp
@@ -89,6 +89,19 @@ enum class ConfigurationLock{
Partial,
};
+enum class TargetConfigurationLockLevel{
+ Invalid,
+ Baseline,
+};
+
+enum class ConfigLockOptions{
+ Invalid,
+ Unlocked,
+ Locked,
+ LockdownUnsupported,
+ CommandUnsupported,
+};
+
NLOHMANN_JSON_SERIALIZE_ENUM(MediaType, {
{MediaType::Invalid, "Invalid"},
{MediaType::HDD, "HDD"},
@@ -173,5 +186,18 @@ NLOHMANN_JSON_SERIALIZE_ENUM(ConfigurationLock, {
{ConfigurationLock::Partial, "Partial"},
});
+NLOHMANN_JSON_SERIALIZE_ENUM(TargetConfigurationLockLevel, {
+ {TargetConfigurationLockLevel::Invalid, "Invalid"},
+ {TargetConfigurationLockLevel::Baseline, "Baseline"},
+});
+
+NLOHMANN_JSON_SERIALIZE_ENUM(ConfigLockOptions, {
+ {ConfigLockOptions::Invalid, "Invalid"},
+ {ConfigLockOptions::Unlocked, "Unlocked"},
+ {ConfigLockOptions::Locked, "Locked"},
+ {ConfigLockOptions::LockdownUnsupported, "LockdownUnsupported"},
+ {ConfigLockOptions::CommandUnsupported, "CommandUnsupported"},
+});
+
}
// clang-format on
diff --git a/redfish-core/include/generated/enums/oem_computer_system.hpp b/redfish-core/include/generated/enums/open_bmc_computer_system.hpp
index a1a4a6e170..aa4539eeac 100644
--- a/redfish-core/include/generated/enums/oem_computer_system.hpp
+++ b/redfish-core/include/generated/enums/open_bmc_computer_system.hpp
@@ -1,7 +1,7 @@
#pragma once
#include <nlohmann/json.hpp>
-namespace oem_computer_system
+namespace open_bmc_computer_system
{
// clang-format off
diff --git a/redfish-core/include/generated/enums/pcie_device.hpp b/redfish-core/include/generated/enums/pcie_device.hpp
index 209d0030fe..cd2016faf1 100644
--- a/redfish-core/include/generated/enums/pcie_device.hpp
+++ b/redfish-core/include/generated/enums/pcie_device.hpp
@@ -12,6 +12,7 @@ enum class PCIeTypes{
Gen3,
Gen4,
Gen5,
+ Gen6,
};
enum class DeviceType{
@@ -64,6 +65,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(PCIeTypes, {
{PCIeTypes::Gen3, "Gen3"},
{PCIeTypes::Gen4, "Gen4"},
{PCIeTypes::Gen5, "Gen5"},
+ {PCIeTypes::Gen6, "Gen6"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(DeviceType, {
diff --git a/redfish-core/include/generated/enums/physical_context.hpp b/redfish-core/include/generated/enums/physical_context.hpp
index aead54eece..876e62c639 100644
--- a/redfish-core/include/generated/enums/physical_context.hpp
+++ b/redfish-core/include/generated/enums/physical_context.hpp
@@ -30,7 +30,9 @@ enum class PhysicalContext{
VoltageRegulator,
Rectifier,
StorageDevice,
+ StorageSubsystem,
NetworkingDevice,
+ ExpansionSubsystem,
ComputeBay,
StorageBay,
NetworkBay,
@@ -49,11 +51,16 @@ enum class PhysicalContext{
DCBus,
ACOutput,
ACInput,
+ PowerOutlet,
TrustedModule,
Board,
Transceiver,
Battery,
Pump,
+ Filter,
+ Reservoir,
+ Switch,
+ Manager,
};
enum class PhysicalSubContext{
@@ -97,7 +104,9 @@ NLOHMANN_JSON_SERIALIZE_ENUM(PhysicalContext, {
{PhysicalContext::VoltageRegulator, "VoltageRegulator"},
{PhysicalContext::Rectifier, "Rectifier"},
{PhysicalContext::StorageDevice, "StorageDevice"},
+ {PhysicalContext::StorageSubsystem, "StorageSubsystem"},
{PhysicalContext::NetworkingDevice, "NetworkingDevice"},
+ {PhysicalContext::ExpansionSubsystem, "ExpansionSubsystem"},
{PhysicalContext::ComputeBay, "ComputeBay"},
{PhysicalContext::StorageBay, "StorageBay"},
{PhysicalContext::NetworkBay, "NetworkBay"},
@@ -116,11 +125,16 @@ NLOHMANN_JSON_SERIALIZE_ENUM(PhysicalContext, {
{PhysicalContext::DCBus, "DCBus"},
{PhysicalContext::ACOutput, "ACOutput"},
{PhysicalContext::ACInput, "ACInput"},
+ {PhysicalContext::PowerOutlet, "PowerOutlet"},
{PhysicalContext::TrustedModule, "TrustedModule"},
{PhysicalContext::Board, "Board"},
{PhysicalContext::Transceiver, "Transceiver"},
{PhysicalContext::Battery, "Battery"},
{PhysicalContext::Pump, "Pump"},
+ {PhysicalContext::Filter, "Filter"},
+ {PhysicalContext::Reservoir, "Reservoir"},
+ {PhysicalContext::Switch, "Switch"},
+ {PhysicalContext::Manager, "Manager"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(PhysicalSubContext, {
diff --git a/redfish-core/include/generated/enums/storage.hpp b/redfish-core/include/generated/enums/storage.hpp
index 4e845c40b3..989f1ee049 100644
--- a/redfish-core/include/generated/enums/storage.hpp
+++ b/redfish-core/include/generated/enums/storage.hpp
@@ -23,6 +23,9 @@ enum class EncryptionMode{
Disabled,
UseExternalKey,
UseLocalKey,
+ PasswordOnly,
+ PasswordWithExternalKey,
+ PasswordWithLocalKey,
};
enum class AutoVolumeCreate{
@@ -40,6 +43,19 @@ enum class ConfigurationLock{
Partial,
};
+enum class TargetConfigurationLockLevel{
+ Invalid,
+ Baseline,
+};
+
+enum class ConfigLockOptions{
+ Invalid,
+ Unlocked,
+ Locked,
+ LockdownUnsupported,
+ CommandUnsupported,
+};
+
NLOHMANN_JSON_SERIALIZE_ENUM(ResetToDefaultsType, {
{ResetToDefaultsType::Invalid, "Invalid"},
{ResetToDefaultsType::ResetAll, "ResetAll"},
@@ -58,6 +74,9 @@ NLOHMANN_JSON_SERIALIZE_ENUM(EncryptionMode, {
{EncryptionMode::Disabled, "Disabled"},
{EncryptionMode::UseExternalKey, "UseExternalKey"},
{EncryptionMode::UseLocalKey, "UseLocalKey"},
+ {EncryptionMode::PasswordOnly, "PasswordOnly"},
+ {EncryptionMode::PasswordWithExternalKey, "PasswordWithExternalKey"},
+ {EncryptionMode::PasswordWithLocalKey, "PasswordWithLocalKey"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(AutoVolumeCreate, {
@@ -75,5 +94,18 @@ NLOHMANN_JSON_SERIALIZE_ENUM(ConfigurationLock, {
{ConfigurationLock::Partial, "Partial"},
});
+NLOHMANN_JSON_SERIALIZE_ENUM(TargetConfigurationLockLevel, {
+ {TargetConfigurationLockLevel::Invalid, "Invalid"},
+ {TargetConfigurationLockLevel::Baseline, "Baseline"},
+});
+
+NLOHMANN_JSON_SERIALIZE_ENUM(ConfigLockOptions, {
+ {ConfigLockOptions::Invalid, "Invalid"},
+ {ConfigLockOptions::Unlocked, "Unlocked"},
+ {ConfigLockOptions::Locked, "Locked"},
+ {ConfigLockOptions::LockdownUnsupported, "LockdownUnsupported"},
+ {ConfigLockOptions::CommandUnsupported, "CommandUnsupported"},
+});
+
}
// clang-format on
diff --git a/redfish-core/include/gzfile.hpp b/redfish-core/include/gzfile.hpp
index 3fa1e49e34..fd8ddd001a 100644
--- a/redfish-core/include/gzfile.hpp
+++ b/redfish-core/include/gzfile.hpp
@@ -97,8 +97,8 @@ class GzFileReader
while (pos != std::string::npos)
{
- std::string logEntry = bufferStr.substr(initialPos,
- pos - initialPos);
+ std::string logEntry =
+ bufferStr.substr(initialPos, pos - initialPos);
// Since there might be consecutive delimiters like "\r\n", we need
// to filter empty strings.
if (!logEntry.empty())
diff --git a/redfish-core/include/privileges.hpp b/redfish-core/include/privileges.hpp
index 87780ee84f..da1bf4be00 100644
--- a/redfish-core/include/privileges.hpp
+++ b/redfish-core/include/privileges.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -32,8 +32,6 @@
#include <utility>
#include <vector>
-// IWYU pragma: no_include <stddef.h>
-
namespace redfish
{
diff --git a/redfish-core/include/query.hpp b/redfish-core/include/query.hpp
index 2d280cb787..89f862d8b8 100644
--- a/redfish-core/include/query.hpp
+++ b/redfish-core/include/query.hpp
@@ -23,8 +23,6 @@
#include <utility>
// IWYU pragma: no_forward_declare crow::App
-// IWYU pragma: no_include <boost/url/impl/params_view.hpp>
-// IWYU pragma: no_include <boost/url/impl/url_view.hpp>
#include "redfish_aggregator.hpp"
@@ -153,8 +151,9 @@ inline bool handleIfMatch(crow::App& app, const crow::Request& req,
if constexpr (BMCWEB_REDFISH_AGGREGATION)
{
- needToCallHandlers = RedfishAggregator::beginAggregation(
- req, asyncResp) == Result::LocalHandle;
+ needToCallHandlers =
+ RedfishAggregator::beginAggregation(req, asyncResp) ==
+ Result::LocalHandle;
// If the request should be forwarded to a satellite BMC then we don't
// want to write anything to the asyncResp since it will get overwritten
@@ -174,8 +173,8 @@ inline bool handleIfMatch(crow::App& app, const crow::Request& req,
asyncResp->res.setCompleteRequestHandler(
[&app, handler(std::move(handler)), query{std::move(*queryOpt)},
delegated{delegated}](crow::Response& resIn) mutable {
- processAllParams(app, query, delegated, handler, resIn);
- });
+ processAllParams(app, query, delegated, handler, resIn);
+ });
return needToCallHandlers;
}
diff --git a/redfish-core/include/redfish_aggregator.hpp b/redfish-core/include/redfish_aggregator.hpp
index bc0300a1a9..0a4ea4a73e 100644
--- a/redfish-core/include/redfish_aggregator.hpp
+++ b/redfish-core/include/redfish_aggregator.hpp
@@ -57,51 +57,52 @@ constexpr std::array nonUriProperties{
inline bool searchCollectionsArray(std::string_view uri,
const SearchType searchType)
{
- constexpr std::string_view serviceRootUri = "/redfish/v1";
-
- // The passed URI must begin with "/redfish/v1", but we have to strip it
- // from the URI since topCollections does not include it in its URIs
- if (!uri.starts_with(serviceRootUri))
+ boost::system::result<boost::urls::url> parsedUrl =
+ boost::urls::parse_relative_ref(uri);
+ if (!parsedUrl)
{
+ BMCWEB_LOG_ERROR("Failed to get target URI from {}", uri);
return false;
}
- // Catch empty final segments such as "/redfish/v1/Chassis//"
- if (uri.ends_with("//"))
+ parsedUrl->normalize();
+ boost::urls::segments_ref segments = parsedUrl->segments();
+ if (!segments.is_absolute())
{
return false;
}
- std::size_t parseCount = uri.size() - serviceRootUri.size();
- // Don't include the trailing "/" if it exists such as in "/redfish/v1/"
- if (uri.ends_with("/"))
+ // The passed URI must begin with "/redfish/v1", but we have to strip it
+ // from the URI since topCollections does not include it in its URIs.
+ if (segments.size() < 2)
{
- parseCount--;
+ return false;
}
-
- boost::system::result<boost::urls::url_view> parsedUrl =
- boost::urls::parse_relative_ref(
- uri.substr(serviceRootUri.size(), parseCount));
- if (!parsedUrl)
+ if (segments.front() != "redfish")
{
- BMCWEB_LOG_ERROR("Failed to get target URI from {}",
- uri.substr(serviceRootUri.size()));
return false;
}
-
- if (!parsedUrl->segments().is_absolute() && !parsedUrl->segments().empty())
+ segments.erase(segments.begin());
+ if (segments.front() != "v1")
{
return false;
}
+ segments.erase(segments.begin());
- // If no segments() then the passed URI was either "/redfish/v1" or
+ // Exclude the trailing "/" if it exists such as in "/redfish/v1/".
+ if (!segments.empty() && segments.back().empty())
+ {
+ segments.pop_back();
+ }
+
+ // If no segments then the passed URI was either "/redfish/v1" or
// "/redfish/v1/".
- if (parsedUrl->segments().empty())
+ if (segments.empty())
{
return (searchType == SearchType::ContainsSubordinate) ||
(searchType == SearchType::CollOrCon);
}
- std::string_view url = parsedUrl->buffer();
+ std::string_view url = segments.buffer();
const auto* it = std::ranges::lower_bound(topCollections, url);
if (it == topCollections.end())
{
@@ -118,7 +119,7 @@ inline bool searchCollectionsArray(std::string_view uri,
collectionSegments.end();
// Each segment in the passed URI should match the found collection
- for (const auto& segment : parsedUrl->segments())
+ for (const auto& segment : segments)
{
if (itCollection == endCollection)
{
@@ -162,8 +163,8 @@ inline bool isPropertyUri(std::string_view propertyName)
propertyName);
}
-static inline void addPrefixToStringItem(std::string& strValue,
- std::string_view prefix)
+inline void addPrefixToStringItem(std::string& strValue,
+ std::string_view prefix)
{
// Make sure the value is a properly formatted URI
auto parsed = boost::urls::parse_relative_ref(strValue);
@@ -245,8 +246,7 @@ static inline void addPrefixToStringItem(std::string& strValue,
}
}
-static inline void addPrefixToItem(nlohmann::json& item,
- std::string_view prefix)
+inline void addPrefixToItem(nlohmann::json& item, std::string_view prefix)
{
std::string* strValue = item.get_ptr<std::string*>();
if (strValue == nullptr)
@@ -261,9 +261,9 @@ static inline void addPrefixToItem(nlohmann::json& item,
item = *strValue;
}
-static inline void addAggregatedHeaders(crow::Response& asyncResp,
- const crow::Response& resp,
- std::string_view prefix)
+inline void addAggregatedHeaders(crow::Response& asyncResp,
+ const crow::Response& resp,
+ std::string_view prefix)
{
if (!resp.getHeaderValue("Content-Type").empty())
{
@@ -291,8 +291,8 @@ static inline void addAggregatedHeaders(crow::Response& asyncResp,
}
// Fix HTTP headers which appear in responses from Task resources among others
-static inline void addPrefixToHeadersInResp(nlohmann::json& json,
- std::string_view prefix)
+inline void addPrefixToHeadersInResp(nlohmann::json& json,
+ std::string_view prefix)
{
// The passed in "HttpHeaders" should be an array of headers
nlohmann::json::array_t* array = json.get_ptr<nlohmann::json::array_t*>();
@@ -324,7 +324,7 @@ static inline void addPrefixToHeadersInResp(nlohmann::json& json,
// Search the json for all URIs and add the supplied prefix if the URI is for
// an aggregated resource.
-static inline void addPrefixes(nlohmann::json& json, std::string_view prefix)
+inline void addPrefixes(nlohmann::json& json, std::string_view prefix)
{
nlohmann::json::object_t* object =
json.get_ptr<nlohmann::json::object_t*>();
@@ -371,7 +371,7 @@ inline boost::system::error_code aggregationRetryHandler(unsigned int respCode)
inline crow::ConnectionPolicy getAggregationPolicy()
{
- return {.maxRetryAttempts = 1,
+ return {.maxRetryAttempts = 0,
.requestByteLimit = aggregatorReadBodyLimit,
.maxConnections = 20,
.retryPolicyAction = "TerminateAfterRetries",
@@ -737,8 +737,9 @@ class RedfishAggregator
{
url.set_query(targetURI.query());
}
- client.sendDataWithCallback(std::move(data), url, thisReq.fields(),
- thisReq.method(), cb);
+ client.sendDataWithCallback(std::move(data), url,
+ ensuressl::VerifyCertificate::Verify,
+ thisReq.fields(), thisReq.method(), cb);
}
// Forward a request for a collection URI to each known satellite BMC
@@ -759,8 +760,9 @@ class RedfishAggregator
url.set_query(thisReq.url().query());
}
std::string data = thisReq.body();
- client.sendDataWithCallback(std::move(data), url, thisReq.fields(),
- thisReq.method(), cb);
+ client.sendDataWithCallback(std::move(data), url,
+ ensuressl::VerifyCertificate::Verify,
+ thisReq.fields(), thisReq.method(), cb);
}
}
@@ -785,8 +787,9 @@ class RedfishAggregator
std::string data = thisReq.body();
- client.sendDataWithCallback(std::move(data), url, thisReq.fields(),
- thisReq.method(), cb);
+ client.sendDataWithCallback(std::move(data), url,
+ ensuressl::VerifyCertificate::Verify,
+ thisReq.fields(), thisReq.method(), cb);
}
}
@@ -824,33 +827,33 @@ class RedfishAggregator
[handler{std::move(handler)}](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& objects) {
- std::unordered_map<std::string, boost::urls::url> satelliteInfo;
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error {}, {}", ec.value(),
- ec.message());
- handler(ec, satelliteInfo);
- return;
- }
+ std::unordered_map<std::string, boost::urls::url> satelliteInfo;
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}, {}", ec.value(),
+ ec.message());
+ handler(ec, satelliteInfo);
+ return;
+ }
- // Maps a chosen alias representing a satellite BMC to a url
- // containing the information required to create a http
- // connection to the satellite
- findSatelliteConfigs(objects, satelliteInfo);
+ // Maps a chosen alias representing a satellite BMC to a url
+ // containing the information required to create a http
+ // connection to the satellite
+ findSatelliteConfigs(objects, satelliteInfo);
- if (!satelliteInfo.empty())
- {
- BMCWEB_LOG_DEBUG(
- "Redfish Aggregation enabled with {} satellite BMCs",
- std::to_string(satelliteInfo.size()));
- }
- else
- {
- BMCWEB_LOG_DEBUG(
- "No satellite BMCs detected. Redfish Aggregation not enabled");
- }
- handler(ec, satelliteInfo);
- });
+ if (!satelliteInfo.empty())
+ {
+ BMCWEB_LOG_DEBUG(
+ "Redfish Aggregation enabled with {} satellite BMCs",
+ std::to_string(satelliteInfo.size()));
+ }
+ else
+ {
+ BMCWEB_LOG_DEBUG(
+ "No satellite BMCs detected. Redfish Aggregation not enabled");
+ }
+ handler(ec, satelliteInfo);
+ });
}
// Processes the response returned by a satellite BMC and loads its
@@ -874,8 +877,8 @@ class RedfishAggregator
// We need to create a json from resp's stringResponse
if (isJsonContentType(resp.getHeaderValue("Content-Type")))
{
- nlohmann::json jsonVal = nlohmann::json::parse(*resp.body(),
- nullptr, false);
+ nlohmann::json jsonVal =
+ nlohmann::json::parse(*resp.body(), nullptr, false);
if (jsonVal.is_discarded())
{
BMCWEB_LOG_ERROR("Error parsing satellite response as JSON");
@@ -936,8 +939,8 @@ class RedfishAggregator
// We need to create a json from resp's stringResponse
if (isJsonContentType(resp.getHeaderValue("Content-Type")))
{
- nlohmann::json jsonVal = nlohmann::json::parse(*resp.body(),
- nullptr, false);
+ nlohmann::json jsonVal =
+ nlohmann::json::parse(*resp.body(), nullptr, false);
if (jsonVal.is_discarded())
{
BMCWEB_LOG_ERROR("Error parsing satellite response as JSON");
@@ -1069,8 +1072,8 @@ class RedfishAggregator
if (isJsonContentType(resp.getHeaderValue("Content-Type")))
{
bool addedLinks = false;
- nlohmann::json jsonVal = nlohmann::json::parse(*resp.body(),
- nullptr, false);
+ nlohmann::json jsonVal =
+ nlohmann::json::parse(*resp.body(), nullptr, false);
if (jsonVal.is_discarded())
{
BMCWEB_LOG_ERROR("Error parsing satellite response as JSON");
diff --git a/redfish-core/include/registries.hpp b/redfish-core/include/registries.hpp
index b0ddb68fdd..f7aa32bf1e 100644
--- a/redfish-core/include/registries.hpp
+++ b/redfish-core/include/registries.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2019 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2019 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -26,8 +26,6 @@
#include <string_view>
#include <utility>
-// IWYU pragma: no_include <stddef.h>
-
namespace redfish::registries
{
struct Header
@@ -54,9 +52,8 @@ struct Message
};
using MessageEntry = std::pair<const char*, const Message>;
-inline std::string
- fillMessageArgs(const std::span<const std::string_view> messageArgs,
- std::string_view msg)
+inline std::string fillMessageArgs(
+ const std::span<const std::string_view> messageArgs, std::string_view msg)
{
std::string ret;
size_t reserve = msg.size();
@@ -90,10 +87,9 @@ inline std::string
return ret;
}
-inline nlohmann::json::object_t
- getLogFromRegistry(const Header& header,
- std::span<const MessageEntry> registry, size_t index,
- std::span<const std::string_view> args)
+inline nlohmann::json::object_t getLogFromRegistry(
+ const Header& header, std::span<const MessageEntry> registry, size_t index,
+ std::span<const std::string_view> args)
{
const redfish::registries::MessageEntry& entry = registry[index];
// Intentionally make a copy of the string, so we can append in the
diff --git a/redfish-core/include/registries/base_message_registry.hpp b/redfish-core/include/registries/base_message_registry.hpp
index 5f3b027b16..8f89a6f3d6 100644
--- a/redfish-core/include/registries/base_message_registry.hpp
+++ b/redfish-core/include/registries/base_message_registry.hpp
@@ -20,16 +20,16 @@ namespace redfish::registries::base
const Header header = {
"Copyright 2014-2024 DMTF. All rights reserved.",
"#MessageRegistry.v1_6_2.MessageRegistry",
- "Base.1.18.1",
+ "Base.1.19.0",
"Base Message Registry",
"en",
"This registry defines the base messages for Redfish.",
"Base",
- "1.18.1",
+ "1.19.0",
"DMTF",
};
constexpr const char* url =
- "https://redfish.dmtf.org/registries/Base.1.18.1.json";
+ "https://redfish.dmtf.org/registries/Base.1.19.0.json";
constexpr std::array registry =
{
@@ -398,6 +398,18 @@ constexpr std::array registry =
"None.",
}},
MessageEntry{
+ "GenerateSecretKeyRequired",
+ {
+ "Indicates that the Time-based One-Time Password (TOTP) secret key needs to be generated for the account before accessing the service. The secret key can be generated with a `POST` to the `GenerateSecretKey` action for the `ManagerAccount` resource instance.",
+ "The Time-based One-Time Password (TOTP) secret key for this account must be generated before access is granted. Perform the GenerateSecretKey action at URI '%1' and retain the secret key from the response.",
+ "Critical",
+ 1,
+ {
+ "string",
+ },
+ "Generate secret key for this account by performing the `GenerateSecretKey` action on the referenced URI and retaining the secret key from the action response to produce a Time-based One-Time Password (TOTP) for the `Token` property in future session creation requests.",
+ }},
+ MessageEntry{
"HeaderInvalid",
{
"Indicates that a request header is invalid.",
@@ -584,14 +596,14 @@ constexpr std::array registry =
MessageEntry{
"OneTimePasscodeSent",
{
- "Indicates that a required one-time passcode was sent to the user. The code should be provided as the `Token` property in the request to create a session.",
- "A one-time passcode was sent to: %1. Supply the passcode as the Token property in the request to create a session.",
+ "Indicates that a required one-time passcode was sent to the user. The code should be provided as the Token property in the request to create a session.",
+ "A one-time passcode was sent to: %1. Supply the passcode as the `Token` property in the request to create a session.",
"OK",
1,
{
"string",
},
- "Obtain the one-time passcode sent to the delivery address and resubmit the request using the passcode as the Token property.",
+ "Obtain the one-time passcode sent to the delivery address and resubmit the request using the passcode as the `Token` property.",
}},
MessageEntry{
"OperationFailed",
@@ -702,6 +714,16 @@ constexpr std::array registry =
"Ensure that the property is in the request body and has a valid value and resubmit the request if the operation failed.",
}},
MessageEntry{
+ "PropertyModified",
+ {
+ "Indicates that all properties listed in `RelatedProperties` in the message were successfully modified.",
+ "One or more properties were successfully modified.",
+ "OK",
+ 0,
+ {},
+ "None.",
+ }},
+ MessageEntry{
"PropertyNotUpdated",
{
"Indicates that a property was not updated due to an internal service error, but the service is still functional.",
@@ -1370,86 +1392,88 @@ enum class Index
eventBufferExceeded = 28,
eventSubscriptionLimitExceeded = 29,
generalError = 30,
- headerInvalid = 31,
- headerMissing = 32,
- insufficientPrivilege = 33,
- insufficientStorage = 34,
- internalError = 35,
- invalidIndex = 36,
- invalidJSON = 37,
- invalidObject = 38,
- invalidURI = 39,
- licenseRequired = 40,
- malformedJSON = 41,
- maximumErrorsExceeded = 42,
- missingOrMalformedPart = 43,
- networkNameResolutionNotConfigured = 44,
- networkNameResolutionNotSupported = 45,
- noOperation = 46,
- noValidSession = 47,
- oneTimePasscodeSent = 48,
- operationFailed = 49,
- operationNotAllowed = 50,
- operationTimeout = 51,
- passwordChangeRequired = 52,
- payloadTooLarge = 53,
- preconditionFailed = 54,
- preconditionRequired = 55,
- propertyDeprecated = 56,
- propertyDuplicate = 57,
- propertyMissing = 58,
- propertyNotUpdated = 59,
- propertyNotWritable = 60,
- propertyUnknown = 61,
- propertyValueConflict = 62,
- propertyValueDeprecated = 63,
- propertyValueError = 64,
- propertyValueExternalConflict = 65,
- propertyValueFormatError = 66,
- propertyValueIncorrect = 67,
- propertyValueModified = 68,
- propertyValueNotInList = 69,
- propertyValueOutOfRange = 70,
- propertyValueResourceConflict = 71,
- propertyValueTypeError = 72,
- queryCombinationInvalid = 73,
- queryNotSupported = 74,
- queryNotSupportedOnOperation = 75,
- queryNotSupportedOnResource = 76,
- queryParameterOutOfRange = 77,
- queryParameterUnsupported = 78,
- queryParameterValueError = 79,
- queryParameterValueFormatError = 80,
- queryParameterValueTypeError = 81,
- resetRecommended = 82,
- resetRequired = 83,
- resourceAlreadyExists = 84,
- resourceAtUriInUnknownFormat = 85,
- resourceAtUriUnauthorized = 86,
- resourceCannotBeDeleted = 87,
- resourceCreationConflict = 88,
- resourceDeprecated = 89,
- resourceExhaustion = 90,
- resourceInStandby = 91,
- resourceInUse = 92,
- resourceMissingAtURI = 93,
- resourceNotFound = 94,
- resourceTypeIncompatible = 95,
- restrictedPrivilege = 96,
- restrictedRole = 97,
- serviceDisabled = 98,
- serviceInUnknownState = 99,
- serviceShuttingDown = 100,
- serviceTemporarilyUnavailable = 101,
- sessionLimitExceeded = 102,
- sessionTerminated = 103,
- sourceDoesNotSupportProtocol = 104,
- strictAccountTypes = 105,
- stringValueTooLong = 106,
- stringValueTooShort = 107,
- subscriptionTerminated = 108,
- success = 109,
- undeterminedFault = 110,
- unrecognizedRequestBody = 111,
+ generateSecretKeyRequired = 31,
+ headerInvalid = 32,
+ headerMissing = 33,
+ insufficientPrivilege = 34,
+ insufficientStorage = 35,
+ internalError = 36,
+ invalidIndex = 37,
+ invalidJSON = 38,
+ invalidObject = 39,
+ invalidURI = 40,
+ licenseRequired = 41,
+ malformedJSON = 42,
+ maximumErrorsExceeded = 43,
+ missingOrMalformedPart = 44,
+ networkNameResolutionNotConfigured = 45,
+ networkNameResolutionNotSupported = 46,
+ noOperation = 47,
+ noValidSession = 48,
+ oneTimePasscodeSent = 49,
+ operationFailed = 50,
+ operationNotAllowed = 51,
+ operationTimeout = 52,
+ passwordChangeRequired = 53,
+ payloadTooLarge = 54,
+ preconditionFailed = 55,
+ preconditionRequired = 56,
+ propertyDeprecated = 57,
+ propertyDuplicate = 58,
+ propertyMissing = 59,
+ propertyModified = 60,
+ propertyNotUpdated = 61,
+ propertyNotWritable = 62,
+ propertyUnknown = 63,
+ propertyValueConflict = 64,
+ propertyValueDeprecated = 65,
+ propertyValueError = 66,
+ propertyValueExternalConflict = 67,
+ propertyValueFormatError = 68,
+ propertyValueIncorrect = 69,
+ propertyValueModified = 70,
+ propertyValueNotInList = 71,
+ propertyValueOutOfRange = 72,
+ propertyValueResourceConflict = 73,
+ propertyValueTypeError = 74,
+ queryCombinationInvalid = 75,
+ queryNotSupported = 76,
+ queryNotSupportedOnOperation = 77,
+ queryNotSupportedOnResource = 78,
+ queryParameterOutOfRange = 79,
+ queryParameterUnsupported = 80,
+ queryParameterValueError = 81,
+ queryParameterValueFormatError = 82,
+ queryParameterValueTypeError = 83,
+ resetRecommended = 84,
+ resetRequired = 85,
+ resourceAlreadyExists = 86,
+ resourceAtUriInUnknownFormat = 87,
+ resourceAtUriUnauthorized = 88,
+ resourceCannotBeDeleted = 89,
+ resourceCreationConflict = 90,
+ resourceDeprecated = 91,
+ resourceExhaustion = 92,
+ resourceInStandby = 93,
+ resourceInUse = 94,
+ resourceMissingAtURI = 95,
+ resourceNotFound = 96,
+ resourceTypeIncompatible = 97,
+ restrictedPrivilege = 98,
+ restrictedRole = 99,
+ serviceDisabled = 100,
+ serviceInUnknownState = 101,
+ serviceShuttingDown = 102,
+ serviceTemporarilyUnavailable = 103,
+ sessionLimitExceeded = 104,
+ sessionTerminated = 105,
+ sourceDoesNotSupportProtocol = 106,
+ strictAccountTypes = 107,
+ stringValueTooLong = 108,
+ stringValueTooShort = 109,
+ subscriptionTerminated = 110,
+ success = 111,
+ undeterminedFault = 112,
+ unrecognizedRequestBody = 113,
};
} // namespace redfish::registries::base
diff --git a/redfish-core/include/registries/openbmc.json b/redfish-core/include/registries/openbmc.json
index 885fef46e2..f3ec1e8965 100644
--- a/redfish-core/include/registries/openbmc.json
+++ b/redfish-core/include/registries/openbmc.json
@@ -2,7 +2,7 @@
"@Redfish.Copyright": "Copyright 2022 OpenBMC. All rights reserved.",
"@odata.type": "#MessageRegistry.v1_4_0.MessageRegistry",
"Description": "This registry defines the base messages for OpenBMC.",
- "Id": "OpenBMC.0.4.0",
+ "Id": "OpenBMC.0.5.0",
"Language": "en",
"Messages": {
"ADDDCCorrectable": {
@@ -1187,6 +1187,14 @@
"Resolution": "None.",
"Severity": "OK"
},
+ "PowerButtonLongPressed": {
+ "Description": "Indicates that the power button was long pressed.",
+ "Message": "Power Button Long Pressed.",
+ "MessageSeverity": "OK",
+ "NumberOfArgs": 0,
+ "Resolution": "None.",
+ "Severity": "OK"
+ },
"PowerRestorePolicyApplied": {
"Description": "Indicates that power was restored and the BMC has applied the restore policy.",
"Message": "Power restore policy applied.",
@@ -1667,5 +1675,5 @@
"Name": "OpenBMC Message Registry",
"OwningEntity": "OpenBMC",
"RegistryPrefix": "OpenBMC",
- "RegistryVersion": "0.4.0"
+ "RegistryVersion": "0.5.0"
}
diff --git a/redfish-core/include/registries/openbmc_message_registry.hpp b/redfish-core/include/registries/openbmc_message_registry.hpp
index 35625042bb..2bd4d1dabf 100644
--- a/redfish-core/include/registries/openbmc_message_registry.hpp
+++ b/redfish-core/include/registries/openbmc_message_registry.hpp
@@ -20,12 +20,12 @@ namespace redfish::registries::openbmc
const Header header = {
"Copyright 2022 OpenBMC. All rights reserved.",
"#MessageRegistry.v1_4_0.MessageRegistry",
- "OpenBMC.0.4.0",
+ "OpenBMC.0.5.0",
"OpenBMC Message Registry",
"en",
"This registry defines the base messages for OpenBMC.",
"OpenBMC",
- "0.4.0",
+ "0.5.0",
"OpenBMC",
};
constexpr const char* url =
@@ -1687,6 +1687,16 @@ constexpr std::array registry =
"None.",
}},
MessageEntry{
+ "PowerButtonLongPressed",
+ {
+ "Indicates that the power button was long pressed.",
+ "Power Button Long Pressed.",
+ "OK",
+ 0,
+ {},
+ "None.",
+ }},
+ MessageEntry{
"PowerButtonPressed",
{
"Indicates that the power button was pressed.",
@@ -2477,62 +2487,63 @@ enum class Index
pCIeFatalUnexpectedCompletion = 131,
pCIeFatalUnspecifiedNonAERFatalError = 132,
pCIeFatalUnsupportedRequest = 133,
- powerButtonPressed = 134,
- powerRestorePolicyApplied = 135,
- powerSupplyConfigurationError = 136,
- powerSupplyConfigurationErrorRecovered = 137,
- powerSupplyFailed = 138,
- powerSupplyFailurePredicted = 139,
- powerSupplyFanFailed = 140,
- powerSupplyFanRecovered = 141,
- powerSupplyInserted = 142,
- powerSupplyPowerGoodFailed = 143,
- powerSupplyPowerLost = 144,
- powerSupplyPowerRestored = 145,
- powerSupplyPredictedFailureRecovered = 146,
- powerSupplyRecovered = 147,
- powerSupplyRemoved = 148,
- powerUnitDegradedFromNonRedundant = 149,
- powerUnitDegradedFromRedundant = 150,
- powerUnitNonRedundantFromInsufficient = 151,
- powerUnitNonRedundantInsufficient = 152,
- powerUnitNonRedundantSufficient = 153,
- powerUnitRedundancyDegraded = 154,
- powerUnitRedundancyLost = 155,
- powerUnitRedundancyRegained = 156,
- resetButtonPressed = 157,
- sELEntryAdded = 158,
- securityBoot2ndFlashEnabled = 159,
- securityP2aBridgeEnabled = 160,
- securityUartPortDebugEnabled = 161,
- securityUserNonRootUidZeroAssigned = 162,
- securityUserNonRootUidZeroRemoved = 163,
- securityUserRootDisabled = 164,
- securityUserRootEnabled = 165,
- securityUserStrongHashAlgoRestored = 166,
- securityUserUnsupportedShellEnabled = 167,
- securityUserUnsupportedShellRemoved = 168,
- securityUserWeakHashAlgoEnabled = 169,
- sensorThresholdCriticalHighGoingHigh = 170,
- sensorThresholdCriticalHighGoingLow = 171,
- sensorThresholdCriticalLowGoingHigh = 172,
- sensorThresholdCriticalLowGoingLow = 173,
- sensorThresholdWarningHighGoingHigh = 174,
- sensorThresholdWarningHighGoingLow = 175,
- sensorThresholdWarningLowGoingHigh = 176,
- sensorThresholdWarningLowGoingLow = 177,
- serviceFailure = 178,
- serviceStarted = 179,
- sparingRedundancyDegraded = 180,
- sparingRedundancyFull = 181,
- ssbThermalTrip = 182,
- systemInterfaceDisabledProvisioned = 183,
- systemInterfaceUnprovisioned = 184,
- systemInterfaceWhitelistProvisioned = 185,
- systemPowerGoodFailed = 186,
- systemPowerLost = 187,
- systemPowerOffFailed = 188,
- systemPowerOnFailed = 189,
- voltageRegulatorOverheated = 190,
+ powerButtonLongPressed = 134,
+ powerButtonPressed = 135,
+ powerRestorePolicyApplied = 136,
+ powerSupplyConfigurationError = 137,
+ powerSupplyConfigurationErrorRecovered = 138,
+ powerSupplyFailed = 139,
+ powerSupplyFailurePredicted = 140,
+ powerSupplyFanFailed = 141,
+ powerSupplyFanRecovered = 142,
+ powerSupplyInserted = 143,
+ powerSupplyPowerGoodFailed = 144,
+ powerSupplyPowerLost = 145,
+ powerSupplyPowerRestored = 146,
+ powerSupplyPredictedFailureRecovered = 147,
+ powerSupplyRecovered = 148,
+ powerSupplyRemoved = 149,
+ powerUnitDegradedFromNonRedundant = 150,
+ powerUnitDegradedFromRedundant = 151,
+ powerUnitNonRedundantFromInsufficient = 152,
+ powerUnitNonRedundantInsufficient = 153,
+ powerUnitNonRedundantSufficient = 154,
+ powerUnitRedundancyDegraded = 155,
+ powerUnitRedundancyLost = 156,
+ powerUnitRedundancyRegained = 157,
+ resetButtonPressed = 158,
+ sELEntryAdded = 159,
+ securityBoot2ndFlashEnabled = 160,
+ securityP2aBridgeEnabled = 161,
+ securityUartPortDebugEnabled = 162,
+ securityUserNonRootUidZeroAssigned = 163,
+ securityUserNonRootUidZeroRemoved = 164,
+ securityUserRootDisabled = 165,
+ securityUserRootEnabled = 166,
+ securityUserStrongHashAlgoRestored = 167,
+ securityUserUnsupportedShellEnabled = 168,
+ securityUserUnsupportedShellRemoved = 169,
+ securityUserWeakHashAlgoEnabled = 170,
+ sensorThresholdCriticalHighGoingHigh = 171,
+ sensorThresholdCriticalHighGoingLow = 172,
+ sensorThresholdCriticalLowGoingHigh = 173,
+ sensorThresholdCriticalLowGoingLow = 174,
+ sensorThresholdWarningHighGoingHigh = 175,
+ sensorThresholdWarningHighGoingLow = 176,
+ sensorThresholdWarningLowGoingHigh = 177,
+ sensorThresholdWarningLowGoingLow = 178,
+ serviceFailure = 179,
+ serviceStarted = 180,
+ sparingRedundancyDegraded = 181,
+ sparingRedundancyFull = 182,
+ ssbThermalTrip = 183,
+ systemInterfaceDisabledProvisioned = 184,
+ systemInterfaceUnprovisioned = 185,
+ systemInterfaceWhitelistProvisioned = 186,
+ systemPowerGoodFailed = 187,
+ systemPowerLost = 188,
+ systemPowerOffFailed = 189,
+ systemPowerOnFailed = 190,
+ voltageRegulatorOverheated = 191,
};
} // namespace redfish::registries::openbmc
diff --git a/redfish-core/include/registries/openbmc_message_registry.readmefirst.md b/redfish-core/include/registries/openbmc_message_registry.readmefirst.md
index c521ff4d4c..012bb5be4f 100644
--- a/redfish-core/include/registries/openbmc_message_registry.readmefirst.md
+++ b/redfish-core/include/registries/openbmc_message_registry.readmefirst.md
@@ -1,3 +1,5 @@
+# Registry Edits: Read me first
+
Please read this before making edits to the openbmc base registry.
Messages in this registry are intended to be generally useful across OpenBMC
@@ -16,11 +18,8 @@ this file to remain useful across systems.
3. Message strings should be human readable, and read like a normal sentence.
This generally involves placing the substitution parameters in the
- appropriate place in the string.
-
-Incorrect: "An error occurred. Device: %1"
-
-Correct: "An error occurred on device %1".
+ appropriate place in the string. Incorrect: "An error occurred. Device: %1"
+ Correct: "An error occurred on device %1".
4. Message registry versioning semantics shall be obeyed. Adding new messages
require an increment to the subminor revision. Changes to existing messages
diff --git a/redfish-core/include/schemas.hpp b/redfish-core/include/schemas.hpp
deleted file mode 100644
index cf553cbc8b..0000000000
--- a/redfish-core/include/schemas.hpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#pragma once
-/****************************************************************
- * READ THIS WARNING FIRST
- * This is an auto-generated header which contains definitions
- * for Redfish DMTF defined schemas.
- * DO NOT modify this registry outside of running the
- * update_schemas.py script. The definitions contained within
- * this file are owned by DMTF. Any modifications to these files
- * should be first pushed to the relevant registry in the DMTF
- * github organization.
- ***************************************************************/
-// clang-format off
-#include <array>
-#include <string_view>
-
-namespace redfish
-{
- constexpr std::array<std::string_view,112> schemas {
- "AccountService",
- "ActionInfo",
- "AggregationService",
- "AggregationSource",
- "AggregationSourceCollection",
- "Assembly",
- "AttributeRegistry",
- "Bios",
- "Cable",
- "CableCollection",
- "Certificate",
- "CertificateCollection",
- "CertificateLocations",
- "CertificateService",
- "Chassis",
- "ChassisCollection",
- "ComponentIntegrity",
- "ComponentIntegrityCollection",
- "ComputerSystem",
- "ComputerSystemCollection",
- "Drive",
- "DriveCollection",
- "EnvironmentMetrics",
- "EthernetInterface",
- "EthernetInterfaceCollection",
- "Event",
- "EventDestination",
- "EventDestinationCollection",
- "EventService",
- "FabricAdapter",
- "FabricAdapterCollection",
- "Fan",
- "FanCollection",
- "IPAddresses",
- "JsonSchemaFile",
- "JsonSchemaFileCollection",
- "LogEntry",
- "LogEntryCollection",
- "LogService",
- "LogServiceCollection",
- "Manager",
- "ManagerAccount",
- "ManagerAccountCollection",
- "ManagerCollection",
- "ManagerDiagnosticData",
- "ManagerNetworkProtocol",
- "Memory",
- "MemoryCollection",
- "Message",
- "MessageRegistry",
- "MessageRegistryCollection",
- "MessageRegistryFile",
- "MessageRegistryFileCollection",
- "MetricDefinition",
- "MetricDefinitionCollection",
- "MetricReport",
- "MetricReportCollection",
- "MetricReportDefinition",
- "MetricReportDefinitionCollection",
- "OemComputerSystem",
- "OemManager",
- "OemVirtualMedia",
- "OpenBMCAccountService",
- "OperatingConfig",
- "OperatingConfigCollection",
- "PCIeDevice",
- "PCIeDeviceCollection",
- "PCIeFunction",
- "PCIeFunctionCollection",
- "PCIeSlots",
- "PhysicalContext",
- "Port",
- "PortCollection",
- "Power",
- "PowerSubsystem",
- "PowerSupply",
- "PowerSupplyCollection",
- "Privileges",
- "Processor",
- "ProcessorCollection",
- "Protocol",
- "RedfishError",
- "RedfishExtensions",
- "Redundancy",
- "Resource",
- "Role",
- "RoleCollection",
- "Sensor",
- "SensorCollection",
- "ServiceRoot",
- "Session",
- "SessionCollection",
- "SessionService",
- "Settings",
- "SoftwareInventory",
- "SoftwareInventoryCollection",
- "Storage",
- "StorageCollection",
- "StorageController",
- "StorageControllerCollection",
- "Task",
- "TaskCollection",
- "TaskService",
- "TelemetryService",
- "Thermal",
- "ThermalMetrics",
- "ThermalSubsystem",
- "Triggers",
- "TriggersCollection",
- "UpdateService",
- "VirtualMedia",
- "VirtualMediaCollection",
- };
-}
diff --git a/redfish-core/include/snmp_trap_event_clients.hpp b/redfish-core/include/snmp_trap_event_clients.hpp
index 6cc96a62b5..d71d59f846 100644
--- a/redfish-core/include/snmp_trap_event_clients.hpp
+++ b/redfish-core/include/snmp_trap_event_clients.hpp
@@ -5,6 +5,7 @@
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "event_service_manager.hpp"
+#include "generated/enums/event_destination.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"
@@ -56,15 +57,18 @@ inline void
{
asyncResp->res.jsonValue["@odata.type"] =
"#EventDestination.v1_8_0.EventDestination";
- asyncResp->res.jsonValue["Protocol"] = "SNMPv2c";
+ asyncResp->res.jsonValue["Protocol"] =
+ event_destination::EventDestinationProtocol::SNMPv2c;
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/EventService/Subscriptions/{}", id);
asyncResp->res.jsonValue["Id"] = id;
asyncResp->res.jsonValue["Name"] = "Event Destination";
- asyncResp->res.jsonValue["SubscriptionType"] = "SNMPTrap";
- asyncResp->res.jsonValue["EventFormatType"] = "Event";
+ asyncResp->res.jsonValue["SubscriptionType"] =
+ event_destination::SubscriptionType::SNMPTrap;
+ asyncResp->res.jsonValue["EventFormatType"] =
+ event_destination::EventFormatType::Event;
std::shared_ptr<Subscription> subValue =
EventServiceManager::getInstance().getSubscription(id);
@@ -82,48 +86,47 @@ inline void
objectPath, "xyz.openbmc_project.Network.Client",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- afterGetSnmpTrapClientdata(asyncResp, ec, properties);
- });
+ afterGetSnmpTrapClientdata(asyncResp, ec, properties);
+ });
}
-inline void
- getSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& id)
+inline void getSnmpTrapClient(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
{
crow::connections::systemBus->async_method_call(
[asyncResp, id](const boost::system::error_code& ec,
dbus::utility::ManagedObjectType& resp) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}",
- ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- for (const auto& objpath : resp)
- {
- sdbusplus::message::object_path path(objpath.first);
- const std::string snmpId = path.filename();
- if (snmpId.empty())
+ if (ec)
{
- BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
+ BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}",
+ ec);
messages::internalError(asyncResp->res);
return;
}
- const std::string subscriptionId = "snmp" + snmpId;
- if (id != subscriptionId)
+
+ for (const auto& objpath : resp)
{
- continue;
+ sdbusplus::message::object_path path(objpath.first);
+ const std::string snmpId = path.filename();
+ if (snmpId.empty())
+ {
+ BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const std::string subscriptionId = "snmp" + snmpId;
+ if (id != subscriptionId)
+ {
+ continue;
+ }
+
+ getSnmpTrapClientdata(asyncResp, id, objpath.first);
+ return;
}
- getSnmpTrapClientdata(asyncResp, id, objpath.first);
- return;
- }
-
- messages::resourceNotFound(asyncResp->res, "Subscriptions", id);
- EventServiceManager::getInstance().deleteSubscription(id);
- },
+ messages::resourceNotFound(asyncResp->res, "Subscriptions", id);
+ EventServiceManager::getInstance().deleteSubscription(id);
+ },
"xyz.openbmc_project.Network.SNMP",
"/xyz/openbmc_project/network/snmp/manager",
"org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
@@ -179,21 +182,20 @@ inline void
const std::string& host, uint16_t snmpTrapPort)
{
crow::connections::systemBus->async_method_call(
- [asyncResp, host](const boost::system::error_code& ec,
- const sdbusplus::message_t& msg,
- const std::string& dbusSNMPid) {
- afterSnmpClientCreate(asyncResp, ec, msg, host, dbusSNMPid);
- },
+ [asyncResp,
+ host](const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg, const std::string& dbusSNMPid) {
+ afterSnmpClientCreate(asyncResp, ec, msg, host, dbusSNMPid);
+ },
"xyz.openbmc_project.Network.SNMP",
"/xyz/openbmc_project/network/snmp/manager",
"xyz.openbmc_project.Network.Client.Create", "Client", host,
snmpTrapPort);
}
-inline void
- getSnmpSubscriptionList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& snmpId,
- nlohmann::json& memberArray)
+inline void getSnmpSubscriptionList(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& snmpId, nlohmann::json& memberArray)
{
const std::string subscriptionId = "snmp" + snmpId;
@@ -223,20 +225,20 @@ inline void
crow::connections::systemBus->async_method_call(
[asyncResp, param](const boost::system::error_code& ec) {
- if (ec)
- {
- // The snmp trap id is incorrect
- if (ec.value() == EBADR)
+ if (ec)
{
- messages::resourceNotFound(asyncResp->res, "Subscription",
- param);
+ // The snmp trap id is incorrect
+ if (ec.value() == EBADR)
+ {
+ messages::resourceNotFound(asyncResp->res, "Subscription",
+ param);
+ return;
+ }
+ messages::internalError(asyncResp->res);
return;
}
- messages::internalError(asyncResp->res);
- return;
- }
- messages::success(asyncResp->res);
- },
+ messages::success(asyncResp->res);
+ },
"xyz.openbmc_project.Network.SNMP", static_cast<std::string>(snmpPath),
"xyz.openbmc_project.Object.Delete", "Delete");
}
diff --git a/redfish-core/include/task_messages.hpp b/redfish-core/include/task_messages.hpp
index cb7b355912..ed16e09a81 100644
--- a/redfish-core/include/task_messages.hpp
+++ b/redfish-core/include/task_messages.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "registries/task_event_message_registry.hpp"
diff --git a/redfish-core/include/utils/chassis_utils.hpp b/redfish-core/include/utils/chassis_utils.hpp
index 410a28990d..889b6f72be 100644
--- a/redfish-core/include/utils/chassis_utils.hpp
+++ b/redfish-core/include/utils/chassis_utils.hpp
@@ -33,33 +33,33 @@ void getValidChassisPath(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
chassisId](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse&
chassisPaths) mutable {
- BMCWEB_LOG_DEBUG("getValidChassisPath respHandler enter");
- if (ec)
- {
- BMCWEB_LOG_ERROR("getValidChassisPath respHandler DBUS error: {}",
- ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- std::optional<std::string> chassisPath;
- for (const std::string& chassis : chassisPaths)
- {
- sdbusplus::message::object_path path(chassis);
- std::string chassisName = path.filename();
- if (chassisName.empty())
+ BMCWEB_LOG_DEBUG("getValidChassisPath respHandler enter");
+ if (ec)
{
- BMCWEB_LOG_ERROR("Failed to find '/' in {}", chassis);
- continue;
+ BMCWEB_LOG_ERROR(
+ "getValidChassisPath respHandler DBUS error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
}
- if (chassisName == chassisId)
+
+ std::optional<std::string> chassisPath;
+ for (const std::string& chassis : chassisPaths)
{
- chassisPath = chassis;
- break;
+ sdbusplus::message::object_path path(chassis);
+ std::string chassisName = path.filename();
+ if (chassisName.empty())
+ {
+ BMCWEB_LOG_ERROR("Failed to find '/' in {}", chassis);
+ continue;
+ }
+ if (chassisName == chassisId)
+ {
+ chassisPath = chassis;
+ break;
+ }
}
- }
- callback(chassisPath);
- });
+ callback(chassisPath);
+ });
BMCWEB_LOG_DEBUG("checkChassisId exit");
}
diff --git a/redfish-core/include/utils/collection.hpp b/redfish-core/include/utils/collection.hpp
index 9efa7d3ef3..6528a98adb 100644
--- a/redfish-core/include/utils/collection.hpp
+++ b/redfish-core/include/utils/collection.hpp
@@ -92,24 +92,22 @@ inline void handleCollectionMembers(
*
* @return void
*/
-inline void
- getCollectionToKey(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const boost::urls::url& collectionPath,
- std::span<const std::string_view> interfaces,
- const std::string& subtree,
- const nlohmann::json::json_pointer& jsonKeyName)
+inline void getCollectionToKey(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::urls::url& collectionPath,
+ std::span<const std::string_view> interfaces, const std::string& subtree,
+ const nlohmann::json::json_pointer& jsonKeyName)
{
BMCWEB_LOG_DEBUG("Get collection members for: {}", collectionPath.buffer());
- dbus::utility::getSubTreePaths(subtree, 0, interfaces,
- std::bind_front(handleCollectionMembers,
- asyncResp, collectionPath,
- jsonKeyName));
+ dbus::utility::getSubTreePaths(
+ subtree, 0, interfaces,
+ std::bind_front(handleCollectionMembers, asyncResp, collectionPath,
+ jsonKeyName));
}
-inline void
- getCollectionMembers(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const boost::urls::url& collectionPath,
- std::span<const std::string_view> interfaces,
- const std::string& subtree)
+inline void getCollectionMembers(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::urls::url& collectionPath,
+ std::span<const std::string_view> interfaces, const std::string& subtree)
{
getCollectionToKey(asyncResp, collectionPath, interfaces, subtree,
nlohmann::json::json_pointer("/Members"));
diff --git a/redfish-core/include/utils/dbus_event_log_entry.hpp b/redfish-core/include/utils/dbus_event_log_entry.hpp
new file mode 100644
index 0000000000..f5eb5f61e4
--- /dev/null
+++ b/redfish-core/include/utils/dbus_event_log_entry.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "dbus_utility.hpp"
+#include "utils/dbus_utils.hpp"
+
+#include <optional>
+#include <string>
+
+namespace redfish
+{
+struct DbusEventLogEntry
+{
+ // represents a subset of an instance of dbus interface
+ // xyz.openbmc_project.Logging.Entry
+
+ uint32_t Id = 0;
+ std::string Message;
+ const std::string* Path = nullptr;
+ const std::string* Resolution = nullptr;
+ bool Resolved = false;
+ std::string ServiceProviderNotify;
+ std::string Severity;
+ uint64_t Timestamp = 0;
+ uint64_t UpdateTimestamp = 0;
+};
+
+inline std::optional<DbusEventLogEntry> fillDbusEventLogEntryFromPropertyMap(
+ const dbus::utility::DBusPropertiesMap& resp)
+{
+ DbusEventLogEntry entry;
+
+ // clang-format off
+ bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), resp,
+ "Id", entry.Id,
+ "Message", entry.Message,
+ "Path", entry.Path,
+ "Resolution", entry.Resolution,
+ "Resolved", entry.Resolved,
+ "ServiceProviderNotify", entry.ServiceProviderNotify,
+ "Severity", entry.Severity,
+ "Timestamp", entry.Timestamp,
+ "UpdateTimestamp", entry.UpdateTimestamp
+ );
+ // clang-format on
+ if (!success)
+ {
+ return std::nullopt;
+ }
+ return entry;
+}
+} // namespace redfish
diff --git a/redfish-core/include/utils/dbus_utils.hpp b/redfish-core/include/utils/dbus_utils.hpp
index dbb6fd1b11..3fcd2c7c72 100644
--- a/redfish-core/include/utils/dbus_utils.hpp
+++ b/redfish-core/include/utils/dbus_utils.hpp
@@ -34,11 +34,10 @@ struct UnpackErrorPrinter
namespace details
{
-void afterSetProperty(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& redfishPropertyName,
- const nlohmann::json& propertyValue,
- const boost::system::error_code& ec,
- const sdbusplus::message_t& msg);
+void afterSetProperty(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& redfishPropertyName, const nlohmann::json& propertyValue,
+ const boost::system::error_code& ec, const sdbusplus::message_t& msg);
void afterSetPropertyAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& redfishActionName,
@@ -48,12 +47,11 @@ void afterSetPropertyAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
} // namespace details
template <typename PropertyType>
-void setDbusProperty(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string_view redfishPropertyName,
- std::string_view processName,
- const sdbusplus::message::object_path& path,
- std::string_view interface, std::string_view dbusProperty,
- const PropertyType& prop)
+void setDbusProperty(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ std::string_view redfishPropertyName, std::string_view processName,
+ const sdbusplus::message::object_path& path, std::string_view interface,
+ std::string_view dbusProperty, const PropertyType& prop)
{
std::string processNameStr(processName);
std::string interfaceStr(interface);
@@ -65,20 +63,18 @@ void setDbusProperty(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
[asyncResp, redfishPropertyNameStr = std::string{redfishPropertyName},
jsonProp = nlohmann::json(prop)](const boost::system::error_code& ec,
const sdbusplus::message_t& msg) {
- details::afterSetProperty(asyncResp, redfishPropertyNameStr, jsonProp,
- ec, msg);
- });
+ details::afterSetProperty(asyncResp, redfishPropertyNameStr,
+ jsonProp, ec, msg);
+ });
}
template <typename DbusPropertyType>
-void setDbusPropertyAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string_view processName,
- const sdbusplus::message::object_path& path,
- std::string_view interface,
- std::string_view dbusProperty,
- std::string_view redfishActionParameterName,
- std::string_view redfishActionName,
- const DbusPropertyType& prop)
+void setDbusPropertyAction(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ std::string_view processName, const sdbusplus::message::object_path& path,
+ std::string_view interface, std::string_view dbusProperty,
+ std::string_view redfishActionParameterName,
+ std::string_view redfishActionName, const DbusPropertyType& prop)
{
std::string processNameStr(processName);
std::string interfaceStr(interface);
@@ -93,9 +89,10 @@ void setDbusPropertyAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
redfishActionNameStr = std::string{redfishActionName}](
const boost::system::error_code& ec,
const sdbusplus::message_t& msg) {
- details::afterSetPropertyAction(asyncResp, redfishActionNameStr,
- redfishActionParameterName, ec, msg);
- });
+ details::afterSetPropertyAction(asyncResp, redfishActionNameStr,
+ redfishActionParameterName, ec,
+ msg);
+ });
}
} // namespace redfish
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp
index f6ac70b19a..4339e90ff4 100644
--- a/redfish-core/include/utils/json_utils.hpp
+++ b/redfish-core/include/utils/json_utils.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -41,7 +41,6 @@
#include <variant>
#include <vector>
-// IWYU pragma: no_include <stdint.h>
// IWYU pragma: no_forward_declare crow::Request
namespace redfish
@@ -209,8 +208,8 @@ UnpackErrorCode unpackValueWithErrorCode(nlohmann::json& jsonValue,
value = static_cast<Type>(*jsonPtr);
}
- else if constexpr ((std::is_unsigned_v<Type>)&&(
- !std::is_same_v<bool, Type>))
+ else if constexpr ((std::is_unsigned_v<Type>) &&
+ (!std::is_same_v<bool, Type>))
{
uint64_t* jsonPtr = jsonValue.get_ptr<uint64_t*>();
if (jsonPtr == nullptr)
@@ -560,15 +559,16 @@ inline bool readJsonHelperObject(nlohmann::json::object_t& obj,
break;
}
- result = std::visit(
- [&item, &unpackSpec, &res](auto&& val) {
- using ContainedT =
- std::remove_pointer_t<std::decay_t<decltype(val)>>;
- return details::unpackValue<ContainedT>(
- item.second, unpackSpec.key, res, *val);
- },
- unpackSpec.value) &&
- result;
+ result =
+ std::visit(
+ [&item, &unpackSpec, &res](auto& val) {
+ using ContainedT =
+ std::remove_pointer_t<std::decay_t<decltype(val)>>;
+ return details::unpackValue<ContainedT>(
+ item.second, unpackSpec.key, res, *val);
+ },
+ unpackSpec.value) &&
+ result;
unpackSpec.complete = true;
break;
@@ -586,11 +586,11 @@ inline bool readJsonHelperObject(nlohmann::json::object_t& obj,
if (!perUnpack.complete)
{
bool isOptional = std::visit(
- [](auto&& val) {
- using ContainedType =
- std::remove_pointer_t<std::decay_t<decltype(val)>>;
- return details::IsOptional<ContainedType>::value;
- },
+ [](auto& val) {
+ using ContainedType =
+ std::remove_pointer_t<std::decay_t<decltype(val)>>;
+ return details::IsOptional<ContainedType>::value;
+ },
perUnpack.value);
if (isOptional)
{
@@ -621,7 +621,7 @@ inline void packVariant(std::span<PerUnpack> /*toPack*/) {}
template <typename FirstType, typename... UnpackTypes>
void packVariant(std::span<PerUnpack> toPack, std::string_view key,
- FirstType& first, UnpackTypes&&... in)
+ FirstType&& first, UnpackTypes&&... in)
{
if (toPack.empty())
{
@@ -640,7 +640,8 @@ bool readJsonObject(nlohmann::json::object_t& jsonRequest, crow::Response& res,
{
const std::size_t n = sizeof...(UnpackTypes) + 2;
std::array<PerUnpack, n / 2> toUnpack2;
- packVariant(toUnpack2, key, first, std::forward<UnpackTypes&&>(in)...);
+ packVariant(toUnpack2, key, std::forward<FirstType>(first),
+ std::forward<UnpackTypes&&>(in)...);
return readJsonHelperObject(jsonRequest, res, toUnpack2);
}
@@ -679,8 +680,8 @@ inline std::optional<nlohmann::json::object_t>
}
std::erase_if(*object,
[](const std::pair<std::string, nlohmann::json>& item) {
- return item.first.starts_with("@odata.");
- });
+ return item.first.starts_with("@odata.");
+ });
if (object->empty())
{
// If the update request only contains OData annotations, the service
@@ -737,7 +738,8 @@ bool readJsonAction(const crow::Request& req, crow::Response& res,
// Determines if two json objects are less, based on the presence of the
// @odata.id key
-inline int odataObjectCmp(const nlohmann::json& a, const nlohmann::json& b)
+inline int objectKeyCmp(std::string_view key, const nlohmann::json& a,
+ const nlohmann::json& b)
{
using object_t = nlohmann::json::object_t;
const object_t* aObj = a.get_ptr<const object_t*>();
@@ -755,9 +757,10 @@ inline int odataObjectCmp(const nlohmann::json& a, const nlohmann::json& b)
{
return 1;
}
- object_t::const_iterator aIt = aObj->find("@odata.id");
- object_t::const_iterator bIt = bObj->find("@odata.id");
- // If either object doesn't have the key, they get "sorted" to the end.
+ object_t::const_iterator aIt = aObj->find(key);
+ object_t::const_iterator bIt = bObj->find(key);
+ // If either object doesn't have the key, they get "sorted" to the
+ // beginning.
if (aIt == aObj->end())
{
if (bIt == bObj->end())
@@ -775,7 +778,7 @@ inline int odataObjectCmp(const nlohmann::json& a, const nlohmann::json& b)
const nlohmann::json::string_t* nameB =
bIt->second.get_ptr<const std::string*>();
// If either object doesn't have a string as the key, they get "sorted" to
- // the end.
+ // the beginning.
if (nameA == nullptr)
{
if (nameB == nullptr)
@@ -818,21 +821,41 @@ inline int odataObjectCmp(const nlohmann::json& a, const nlohmann::json& b)
}
};
+// kept for backward compatibility
+inline int odataObjectCmp(const nlohmann::json& left,
+ const nlohmann::json& right)
+{
+ return objectKeyCmp("@odata.id", left, right);
+}
+
struct ODataObjectLess
{
+ std::string_view key;
+
+ explicit ODataObjectLess(std::string_view keyIn) : key(keyIn) {}
+
bool operator()(const nlohmann::json& left,
const nlohmann::json& right) const
{
- return odataObjectCmp(left, right) < 0;
+ return objectKeyCmp(key, left, right) < 0;
}
};
// Sort the JSON array by |element[key]|.
// Elements without |key| or type of |element[key]| is not string are smaller
// those whose |element[key]| is string.
+inline void sortJsonArrayByKey(nlohmann::json::array_t& array,
+ std::string_view key)
+{
+ std::ranges::sort(array, ODataObjectLess(key));
+}
+
+// Sort the JSON array by |element[key]|.
+// Elements without |key| or type of |element[key]| is not string are smaller
+// those whose |element[key]| is string.
inline void sortJsonArrayByOData(nlohmann::json::array_t& array)
{
- std::ranges::sort(array, ODataObjectLess());
+ std::ranges::sort(array, ODataObjectLess("@odata.id"));
}
// Returns the estimated size of the JSON value
diff --git a/redfish-core/include/utils/query_param.hpp b/redfish-core/include/utils/query_param.hpp
index e5f619535b..34ba5b3814 100644
--- a/redfish-core/include/utils/query_param.hpp
+++ b/redfish-core/include/utils/query_param.hpp
@@ -14,7 +14,7 @@
#include <sys/types.h>
-#include <boost/beast/http/message.hpp> // IWYU pragma: keep
+#include <boost/beast/http/message.hpp>
#include <boost/beast/http/status.hpp>
#include <boost/beast/http/verb.hpp>
#include <boost/url/params_view.hpp>
@@ -39,14 +39,6 @@
#include <utility>
#include <vector>
-// IWYU pragma: no_include <boost/url/impl/params_view.hpp>
-// IWYU pragma: no_include <boost/beast/http/impl/message.hpp>
-// IWYU pragma: no_include <boost/intrusive/detail/list_iterator.hpp>
-// IWYU pragma: no_include <boost/algorithm/string/detail/classification.hpp>
-// IWYU pragma: no_include <boost/iterator/iterator_facade.hpp>
-// IWYU pragma: no_include <boost/type_index/type_index_facade.hpp>
-// IWYU pragma: no_include <stdint.h>
-
namespace redfish
{
namespace query_param
@@ -310,8 +302,8 @@ enum class QueryError
inline QueryError getNumericParam(std::string_view value, size_t& param)
{
- std::from_chars_result r = std::from_chars(value.begin(), value.end(),
- param);
+ std::from_chars_result r =
+ std::from_chars(value.begin(), value.end(), param);
// If the number wasn't representable in the type, it's out of range
if (r.ec == std::errc::result_out_of_range)
@@ -387,8 +379,8 @@ inline bool getFilterParam(std::string_view value, Query& query)
return query.filter.has_value();
}
-inline std::optional<Query> parseParameters(boost::urls::params_view urlParams,
- crow::Response& res)
+inline std::optional<Query>
+ parseParameters(boost::urls::params_view urlParams, crow::Response& res)
{
Query ret{};
for (const boost::urls::params_view::value_type& it : urlParams)
@@ -698,9 +690,8 @@ inline void findNavigationReferencesInObjectRecursive(
// Isn't a concern until https://gerrit.openbmc.org/c/openbmc/bmcweb/+/60556
// lands. May want to avoid forwarding query params when request is uptree from
// a top level collection.
-inline std::vector<ExpandNode>
- findNavigationReferences(ExpandType eType, int depth, int skipDepth,
- nlohmann::json& jsonResponse)
+inline std::vector<ExpandNode> findNavigationReferences(
+ ExpandType eType, int depth, int skipDepth, nlohmann::json& jsonResponse)
{
std::vector<ExpandNode> ret;
const nlohmann::json::json_pointer root = nlohmann::json::json_pointer("");
@@ -790,8 +781,9 @@ inline unsigned propogateErrorCode(unsigned finalCode, unsigned subResponseCode)
if (finalCodeIndex != std::numeric_limits<size_t>::max() &&
subResponseCodeIndex != std::numeric_limits<size_t>::max())
{
- return finalCodeIndex <= subResponseCodeIndex ? finalCode
- : subResponseCode;
+ return finalCodeIndex <= subResponseCodeIndex
+ ? finalCode
+ : subResponseCode;
}
if (subResponseCode == 500 || finalCode == 500)
{
@@ -832,8 +824,7 @@ class MultiAsyncResp : public std::enable_shared_from_this<MultiAsyncResp>
// class manages the final "merge" of the json resources.
MultiAsyncResp(crow::App& appIn,
std::shared_ptr<bmcweb::AsyncResp> finalResIn) :
- app(appIn),
- finalRes(std::move(finalResIn))
+ app(appIn), finalRes(std::move(finalResIn))
{}
void addAwaitingResponse(
@@ -1070,7 +1061,7 @@ inline void
if (query.filter)
{
- applyFilter(intermediateResponse.jsonValue, *query.filter);
+ applyFilterToCollection(intermediateResponse.jsonValue, *query.filter);
}
// According to Redfish Spec Section 7.3.1, $select is the last parameter to
diff --git a/redfish-core/include/utils/sensor_utils.hpp b/redfish-core/include/utils/sensor_utils.hpp
new file mode 100644
index 0000000000..f3d1e5693e
--- /dev/null
+++ b/redfish-core/include/utils/sensor_utils.hpp
@@ -0,0 +1,625 @@
+#pragma once
+
+#include "dbus_utility.hpp"
+#include "generated/enums/resource.hpp"
+#include "generated/enums/sensor.hpp"
+#include "generated/enums/thermal.hpp"
+#include "str_utility.hpp"
+#include "utils/dbus_utils.hpp"
+#include "utils/json_utils.hpp"
+
+#include <sdbusplus/unpack_properties.hpp>
+
+#include <algorithm>
+#include <format>
+#include <ranges>
+#include <string>
+#include <string_view>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace redfish
+{
+namespace sensor_utils
+{
+
+enum class ChassisSubNode
+{
+ powerNode,
+ sensorsNode,
+ thermalNode,
+ unknownNode,
+};
+
+constexpr std::string_view chassisSubNodeToString(ChassisSubNode subNode)
+{
+ switch (subNode)
+ {
+ case ChassisSubNode::powerNode:
+ return "Power";
+ case ChassisSubNode::sensorsNode:
+ return "Sensors";
+ case ChassisSubNode::thermalNode:
+ return "Thermal";
+ case ChassisSubNode::unknownNode:
+ default:
+ return "";
+ }
+}
+
+inline ChassisSubNode chassisSubNodeFromString(const std::string& subNodeStr)
+{
+ // If none match unknownNode is returned
+ ChassisSubNode subNode = ChassisSubNode::unknownNode;
+
+ if (subNodeStr == "Power")
+ {
+ subNode = ChassisSubNode::powerNode;
+ }
+ else if (subNodeStr == "Sensors")
+ {
+ subNode = ChassisSubNode::sensorsNode;
+ }
+ else if (subNodeStr == "Thermal")
+ {
+ subNode = ChassisSubNode::thermalNode;
+ }
+
+ return subNode;
+}
+
+/**
+ * Possible states for physical inventory leds
+ */
+enum class LedState
+{
+ OFF,
+ ON,
+ BLINK,
+ UNKNOWN
+};
+
+/**
+ * D-Bus inventory item associated with one or more sensors.
+ */
+class InventoryItem
+{
+ public:
+ explicit InventoryItem(const std::string& objPath) : objectPath(objPath)
+ {
+ // Set inventory item name to last node of object path
+ sdbusplus::message::object_path path(objectPath);
+ name = path.filename();
+ if (name.empty())
+ {
+ BMCWEB_LOG_ERROR("Failed to find '/' in {}", objectPath);
+ }
+ }
+
+ std::string objectPath;
+ std::string name;
+ bool isPresent = true;
+ bool isFunctional = true;
+ bool isPowerSupply = false;
+ int powerSupplyEfficiencyPercent = -1;
+ std::string manufacturer;
+ std::string model;
+ std::string partNumber;
+ std::string serialNumber;
+ std::set<std::string> sensors;
+ std::string ledObjectPath;
+ LedState ledState = LedState::UNKNOWN;
+};
+
+inline std::string getSensorId(std::string_view sensorName,
+ std::string_view sensorType)
+{
+ std::string normalizedType(sensorType);
+ auto remove = std::ranges::remove(normalizedType, '_');
+ normalizedType.erase(std::ranges::begin(remove), normalizedType.end());
+
+ return std::format("{}_{}", normalizedType, sensorName);
+}
+
+inline std::pair<std::string, std::string>
+ splitSensorNameAndType(std::string_view sensorId)
+{
+ size_t index = sensorId.find('_');
+ if (index == std::string::npos)
+ {
+ return std::make_pair<std::string, std::string>("", "");
+ }
+ std::string sensorType{sensorId.substr(0, index)};
+ std::string sensorName{sensorId.substr(index + 1)};
+ // fan_pwm and fan_tach need special handling
+ if (sensorType == "fantach" || sensorType == "fanpwm")
+ {
+ sensorType.insert(3, 1, '_');
+ }
+ return std::make_pair(sensorType, sensorName);
+}
+
+namespace sensors
+{
+inline std::string_view toReadingUnits(std::string_view sensorType)
+{
+ if (sensorType == "voltage")
+ {
+ return "V";
+ }
+ if (sensorType == "power")
+ {
+ return "W";
+ }
+ if (sensorType == "current")
+ {
+ return "A";
+ }
+ if (sensorType == "fan_tach")
+ {
+ return "RPM";
+ }
+ if (sensorType == "temperature")
+ {
+ return "Cel";
+ }
+ if (sensorType == "fan_pwm" || sensorType == "utilization" ||
+ sensorType == "humidity")
+ {
+ return "%";
+ }
+ if (sensorType == "altitude")
+ {
+ return "m";
+ }
+ if (sensorType == "airflow")
+ {
+ return "cft_i/min";
+ }
+ if (sensorType == "energy")
+ {
+ return "J";
+ }
+ return "";
+}
+
+inline sensor::ReadingType toReadingType(std::string_view sensorType)
+{
+ if (sensorType == "voltage")
+ {
+ return sensor::ReadingType::Voltage;
+ }
+ if (sensorType == "power")
+ {
+ return sensor::ReadingType::Power;
+ }
+ if (sensorType == "current")
+ {
+ return sensor::ReadingType::Current;
+ }
+ if (sensorType == "fan_tach")
+ {
+ return sensor::ReadingType::Rotational;
+ }
+ if (sensorType == "temperature")
+ {
+ return sensor::ReadingType::Temperature;
+ }
+ if (sensorType == "fan_pwm" || sensorType == "utilization")
+ {
+ return sensor::ReadingType::Percent;
+ }
+ if (sensorType == "humidity")
+ {
+ return sensor::ReadingType::Humidity;
+ }
+ if (sensorType == "altitude")
+ {
+ return sensor::ReadingType::Altitude;
+ }
+ if (sensorType == "airflow")
+ {
+ return sensor::ReadingType::AirFlow;
+ }
+ if (sensorType == "energy")
+ {
+ return sensor::ReadingType::EnergyJoules;
+ }
+ return sensor::ReadingType::Invalid;
+}
+
+} // namespace sensors
+
+/**
+ * @brief Returns the Redfish State value for the specified inventory item.
+ * @param inventoryItem D-Bus inventory item associated with a sensor.
+ * @param sensorAvailable Boolean representing if D-Bus sensor is marked as
+ * available.
+ * @return State value for inventory item.
+ */
+inline resource::State getState(const InventoryItem* inventoryItem,
+ const bool sensorAvailable)
+{
+ if ((inventoryItem != nullptr) && !(inventoryItem->isPresent))
+ {
+ return resource::State::Absent;
+ }
+
+ if (!sensorAvailable)
+ {
+ return resource::State::UnavailableOffline;
+ }
+
+ return resource::State::Enabled;
+}
+
+/**
+ * @brief Returns the Redfish Health value for the specified sensor.
+ * @param sensorJson Sensor JSON object.
+ * @param valuesDict Map of all sensor DBus values.
+ * @param inventoryItem D-Bus inventory item associated with the sensor. Will
+ * be nullptr if no associated inventory item was found.
+ * @return Health value for sensor.
+ */
+inline std::string getHealth(nlohmann::json& sensorJson,
+ const dbus::utility::DBusPropertiesMap& valuesDict,
+ const InventoryItem* inventoryItem)
+{
+ // Get current health value (if any) in the sensor JSON object. Some JSON
+ // objects contain multiple sensors (such as PowerSupplies). We want to set
+ // the overall health to be the most severe of any of the sensors.
+ std::string currentHealth;
+ auto statusIt = sensorJson.find("Status");
+ if (statusIt != sensorJson.end())
+ {
+ auto healthIt = statusIt->find("Health");
+ if (healthIt != statusIt->end())
+ {
+ std::string* health = healthIt->get_ptr<std::string*>();
+ if (health != nullptr)
+ {
+ currentHealth = *health;
+ }
+ }
+ }
+
+ // If current health in JSON object is already Critical, return that. This
+ // should override the sensor health, which might be less severe.
+ if (currentHealth == "Critical")
+ {
+ return "Critical";
+ }
+
+ const bool* criticalAlarmHigh = nullptr;
+ const bool* criticalAlarmLow = nullptr;
+ const bool* warningAlarmHigh = nullptr;
+ const bool* warningAlarmLow = nullptr;
+
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), valuesDict, "CriticalAlarmHigh",
+ criticalAlarmHigh, "CriticalAlarmLow", criticalAlarmLow,
+ "WarningAlarmHigh", warningAlarmHigh, "WarningAlarmLow",
+ warningAlarmLow);
+
+ if (success)
+ {
+ // Check if sensor has critical threshold alarm
+ if ((criticalAlarmHigh != nullptr && *criticalAlarmHigh) ||
+ (criticalAlarmLow != nullptr && *criticalAlarmLow))
+ {
+ return "Critical";
+ }
+ }
+
+ // Check if associated inventory item is not functional
+ if ((inventoryItem != nullptr) && !(inventoryItem->isFunctional))
+ {
+ return "Critical";
+ }
+
+ // If current health in JSON object is already Warning, return that. This
+ // should override the sensor status, which might be less severe.
+ if (currentHealth == "Warning")
+ {
+ return "Warning";
+ }
+
+ if (success)
+ {
+ // Check if sensor has warning threshold alarm
+ if ((warningAlarmHigh != nullptr && *warningAlarmHigh) ||
+ (warningAlarmLow != nullptr && *warningAlarmLow))
+ {
+ return "Warning";
+ }
+ }
+
+ return "OK";
+}
+
+inline void setLedState(nlohmann::json& sensorJson,
+ const InventoryItem* inventoryItem)
+{
+ if (inventoryItem != nullptr && !inventoryItem->ledObjectPath.empty())
+ {
+ switch (inventoryItem->ledState)
+ {
+ case LedState::OFF:
+ sensorJson["IndicatorLED"] = resource::IndicatorLED::Off;
+ break;
+ case LedState::ON:
+ sensorJson["IndicatorLED"] = resource::IndicatorLED::Lit;
+ break;
+ case LedState::BLINK:
+ sensorJson["IndicatorLED"] = resource::IndicatorLED::Blinking;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Builds a json sensor representation of a sensor.
+ * @param sensorName The name of the sensor to be built
+ * @param sensorType The type (temperature, fan_tach, etc) of the sensor to
+ * build
+ * @param chassisSubNode The subnode (thermal, sensor, etc) of the sensor
+ * @param propertiesDict A dictionary of the properties to build the sensor
+ * from.
+ * @param sensorJson The json object to fill
+ * @param inventoryItem D-Bus inventory item associated with the sensor. Will
+ * be nullptr if no associated inventory item was found.
+ */
+inline void objectPropertiesToJson(
+ std::string_view sensorName, std::string_view sensorType,
+ ChassisSubNode chassisSubNode,
+ const dbus::utility::DBusPropertiesMap& propertiesDict,
+ nlohmann::json& sensorJson, InventoryItem* inventoryItem)
+{
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
+ {
+ std::string subNodeEscaped = getSensorId(sensorName, sensorType);
+ // For sensors in SensorCollection we set Id instead of MemberId,
+ // including power sensors.
+ sensorJson["Id"] = std::move(subNodeEscaped);
+
+ std::string sensorNameEs(sensorName);
+ std::replace(sensorNameEs.begin(), sensorNameEs.end(), '_', ' ');
+ sensorJson["Name"] = std::move(sensorNameEs);
+ }
+ else if (sensorType != "power")
+ {
+ // Set MemberId and Name for non-power sensors. For PowerSupplies and
+ // PowerControl, those properties have more general values because
+ // multiple sensors can be stored in the same JSON object.
+ std::string sensorNameEs(sensorName);
+ std::replace(sensorNameEs.begin(), sensorNameEs.end(), '_', ' ');
+ sensorJson["Name"] = std::move(sensorNameEs);
+ }
+
+ const bool* checkAvailable = nullptr;
+ bool available = true;
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesDict, "Available",
+ checkAvailable);
+ if (!success)
+ {
+ messages::internalError();
+ }
+ if (checkAvailable != nullptr)
+ {
+ available = *checkAvailable;
+ }
+
+ sensorJson["Status"]["State"] = getState(inventoryItem, available);
+ sensorJson["Status"]["Health"] =
+ getHealth(sensorJson, propertiesDict, inventoryItem);
+
+ // Parameter to set to override the type we get from dbus, and force it to
+ // int, regardless of what is available. This is used for schemas like fan,
+ // that require integers, not floats.
+ bool forceToInt = false;
+
+ nlohmann::json::json_pointer unit("/Reading");
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
+ {
+ sensorJson["@odata.type"] = "#Sensor.v1_2_0.Sensor";
+
+ sensor::ReadingType readingType = sensors::toReadingType(sensorType);
+ if (readingType == sensor::ReadingType::Invalid)
+ {
+ BMCWEB_LOG_ERROR("Redfish cannot map reading type for {}",
+ sensorType);
+ }
+ else
+ {
+ sensorJson["ReadingType"] = readingType;
+ }
+
+ std::string_view readingUnits = sensors::toReadingUnits(sensorType);
+ if (readingUnits.empty())
+ {
+ BMCWEB_LOG_ERROR("Redfish cannot map reading unit for {}",
+ sensorType);
+ }
+ else
+ {
+ sensorJson["ReadingUnits"] = readingUnits;
+ }
+ }
+ else if (sensorType == "temperature")
+ {
+ unit = "/ReadingCelsius"_json_pointer;
+ sensorJson["@odata.type"] = "#Thermal.v1_3_0.Temperature";
+ // TODO(ed) Documentation says that path should be type fan_tach,
+ // implementation seems to implement fan
+ }
+ else if (sensorType == "fan" || sensorType == "fan_tach")
+ {
+ unit = "/Reading"_json_pointer;
+ sensorJson["ReadingUnits"] = thermal::ReadingUnits::RPM;
+ sensorJson["@odata.type"] = "#Thermal.v1_3_0.Fan";
+ setLedState(sensorJson, inventoryItem);
+ forceToInt = true;
+ }
+ else if (sensorType == "fan_pwm")
+ {
+ unit = "/Reading"_json_pointer;
+ sensorJson["ReadingUnits"] = thermal::ReadingUnits::Percent;
+ sensorJson["@odata.type"] = "#Thermal.v1_3_0.Fan";
+ setLedState(sensorJson, inventoryItem);
+ forceToInt = true;
+ }
+ else if (sensorType == "voltage")
+ {
+ unit = "/ReadingVolts"_json_pointer;
+ sensorJson["@odata.type"] = "#Power.v1_0_0.Voltage";
+ }
+ else if (sensorType == "power")
+ {
+ std::string lower;
+ std::ranges::transform(sensorName, std::back_inserter(lower),
+ bmcweb::asciiToLower);
+ if (lower == "total_power")
+ {
+ sensorJson["@odata.type"] = "#Power.v1_0_0.PowerControl";
+ // Put multiple "sensors" into a single PowerControl, so have
+ // generic names for MemberId and Name. Follows Redfish mockup.
+ sensorJson["MemberId"] = "0";
+ sensorJson["Name"] = "Chassis Power Control";
+ unit = "/PowerConsumedWatts"_json_pointer;
+ }
+ else if (lower.find("input") != std::string::npos)
+ {
+ unit = "/PowerInputWatts"_json_pointer;
+ }
+ else
+ {
+ unit = "/PowerOutputWatts"_json_pointer;
+ }
+ }
+ else
+ {
+ BMCWEB_LOG_ERROR("Redfish cannot map object type for {}", sensorName);
+ return;
+ }
+ // Map of dbus interface name, dbus property name and redfish property_name
+ std::vector<
+ std::tuple<const char*, const char*, nlohmann::json::json_pointer>>
+ properties;
+
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
+
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
+ {
+ properties.emplace_back(
+ "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningHigh",
+ "/Thresholds/UpperCaution/Reading"_json_pointer);
+ properties.emplace_back(
+ "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningLow",
+ "/Thresholds/LowerCaution/Reading"_json_pointer);
+ properties.emplace_back(
+ "xyz.openbmc_project.Sensor.Threshold.Critical", "CriticalHigh",
+ "/Thresholds/UpperCritical/Reading"_json_pointer);
+ properties.emplace_back(
+ "xyz.openbmc_project.Sensor.Threshold.Critical", "CriticalLow",
+ "/Thresholds/LowerCritical/Reading"_json_pointer);
+
+ /* Add additional properties specific to sensorType */
+ if (sensorType == "fan_tach")
+ {
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value",
+ "/SpeedRPM"_json_pointer);
+ }
+ }
+ else if (sensorType != "power")
+ {
+ properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+ "WarningHigh",
+ "/UpperThresholdNonCritical"_json_pointer);
+ properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+ "WarningLow",
+ "/LowerThresholdNonCritical"_json_pointer);
+ properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+ "CriticalHigh",
+ "/UpperThresholdCritical"_json_pointer);
+ properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+ "CriticalLow",
+ "/LowerThresholdCritical"_json_pointer);
+ }
+
+ // TODO Need to get UpperThresholdFatal and LowerThresholdFatal
+
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
+ {
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+ "/ReadingRangeMin"_json_pointer);
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+ "/ReadingRangeMax"_json_pointer);
+ properties.emplace_back("xyz.openbmc_project.Sensor.Accuracy",
+ "Accuracy", "/Accuracy"_json_pointer);
+ }
+ else if (sensorType == "temperature")
+ {
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+ "/MinReadingRangeTemp"_json_pointer);
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+ "/MaxReadingRangeTemp"_json_pointer);
+ }
+ else if (sensorType != "power")
+ {
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+ "/MinReadingRange"_json_pointer);
+ properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+ "/MaxReadingRange"_json_pointer);
+ }
+
+ for (const std::tuple<const char*, const char*,
+ nlohmann::json::json_pointer>& p : properties)
+ {
+ for (const auto& [valueName, valueVariant] : propertiesDict)
+ {
+ if (valueName != std::get<1>(p))
+ {
+ continue;
+ }
+
+ // The property we want to set may be nested json, so use
+ // a json_pointer for easy indexing into the json structure.
+ const nlohmann::json::json_pointer& key = std::get<2>(p);
+
+ const double* doubleValue = std::get_if<double>(&valueVariant);
+ if (doubleValue == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Got value interface that wasn't double");
+ continue;
+ }
+ if (!std::isfinite(*doubleValue))
+ {
+ if (valueName == "Value")
+ {
+ // Readings are allowed to be NAN for unavailable; coerce
+ // them to null in the json response.
+ sensorJson[key] = nullptr;
+ continue;
+ }
+ BMCWEB_LOG_WARNING("Sensor value for {} was unexpectedly {}",
+ valueName, *doubleValue);
+ continue;
+ }
+ if (forceToInt)
+ {
+ sensorJson[key] = static_cast<int64_t>(*doubleValue);
+ }
+ else
+ {
+ sensorJson[key] = *doubleValue;
+ }
+ }
+ }
+}
+
+} // namespace sensor_utils
+} // namespace redfish
diff --git a/redfish-core/include/utils/sw_utils.hpp b/redfish-core/include/utils/sw_utils.hpp
index 8a715e673f..fc15783158 100644
--- a/redfish-core/include/utils/sw_utils.hpp
+++ b/redfish-core/include/utils/sw_utils.hpp
@@ -13,6 +13,7 @@
#include <algorithm>
#include <array>
+#include <optional>
#include <ranges>
#include <string>
#include <string_view>
@@ -30,6 +31,42 @@ constexpr const char* biosPurpose =
constexpr const char* bmcPurpose =
"xyz.openbmc_project.Software.Version.VersionPurpose.BMC";
+inline std::optional<sdbusplus::message::object_path>
+ getFunctionalSoftwarePath(const std::string& swType)
+{
+ if (swType == bmcPurpose)
+ {
+ if constexpr (BMCWEB_REDFISH_UPDATESERVICE_USE_DBUS)
+ {
+ return sdbusplus::message::object_path(
+ "/xyz/openbmc_project/software/bmc/functional");
+ }
+ else
+ {
+ return sdbusplus::message::object_path(
+ "/xyz/openbmc_project/software/functional");
+ }
+ }
+ else if (swType == biosPurpose)
+ {
+ if constexpr (BMCWEB_REDFISH_UPDATESERVICE_USE_DBUS)
+ {
+ return sdbusplus::message::object_path(
+ "/xyz/openbmc_project/software/bios/functional");
+ }
+ else
+ {
+ return sdbusplus::message::object_path(
+ "/xyz/openbmc_project/software/functional");
+ }
+ }
+ else
+ {
+ BMCWEB_LOG_ERROR("No valid software path");
+ return std::nullopt;
+ }
+}
+
/**
* @brief Populate the running software version and image links
*
@@ -48,185 +85,207 @@ inline void populateSoftwareInformation(
const std::string& swVersionPurpose,
const std::string& activeVersionPropName, const bool populateLinkToImages)
{
+ auto swPath = getFunctionalSoftwarePath(swVersionPurpose);
+ if (!swPath)
+ {
+ BMCWEB_LOG_ERROR("Invalid software type");
+ messages::internalError(asyncResp->res);
+ return;
+ }
// Used later to determine running (known on Redfish as active) Sw images
dbus::utility::getAssociationEndPoints(
- "/xyz/openbmc_project/software/functional",
+ swPath.value().str,
[asyncResp, swVersionPurpose, activeVersionPropName,
populateLinkToImages](
const boost::system::error_code& ec,
const dbus::utility::MapperEndPoints& functionalSw) {
- BMCWEB_LOG_DEBUG("populateSoftwareInformation enter");
- if (ec)
- {
- BMCWEB_LOG_ERROR("error_code = {}", ec);
- BMCWEB_LOG_ERROR("error msg = {}", ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
-
- if (functionalSw.empty())
- {
- // Could keep going and try to populate SoftwareImages but
- // something is seriously wrong, so just fail
- BMCWEB_LOG_ERROR("Zero functional software in system");
- messages::internalError(asyncResp->res);
- return;
- }
-
- std::vector<std::string> functionalSwIds;
- // example functionalSw:
- // v as 2 "/xyz/openbmc_project/software/ace821ef"
- // "/xyz/openbmc_project/software/230fb078"
- for (const auto& sw : functionalSw)
- {
- sdbusplus::message::object_path path(sw);
- std::string leaf = path.filename();
- if (leaf.empty())
+ BMCWEB_LOG_DEBUG("populateSoftwareInformation enter");
+ if (ec)
{
- continue;
+ BMCWEB_LOG_ERROR("error_code = {}", ec);
+ BMCWEB_LOG_ERROR("error msg = {}", ec.message());
+ messages::internalError(asyncResp->res);
+ return;
}
- functionalSwIds.push_back(leaf);
- }
-
- constexpr std::array<std::string_view, 1> interfaces = {
- "xyz.openbmc_project.Software.Version"};
- dbus::utility::getSubTree(
- "/xyz/openbmc_project/software", 0, interfaces,
- [asyncResp, swVersionPurpose, activeVersionPropName,
- populateLinkToImages, functionalSwIds](
- const boost::system::error_code& ec2,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec2)
+ if (functionalSw.empty())
{
- BMCWEB_LOG_ERROR("error_code = {}", ec2);
- BMCWEB_LOG_ERROR("error msg = {}", ec2.message());
+ // Could keep going and try to populate SoftwareImages but
+ // something is seriously wrong, so just fail
+ BMCWEB_LOG_ERROR("Zero functional software in system");
messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_DEBUG("Found {} images", subtree.size());
-
- for (const std::pair<std::string,
- std::vector<std::pair<
- std::string, std::vector<std::string>>>>&
- obj : subtree)
+ std::vector<std::string> functionalSwIds;
+ // example functionalSw:
+ // v as 2 "/xyz/openbmc_project/software/ace821ef"
+ // "/xyz/openbmc_project/software/230fb078"
+ for (const auto& sw : functionalSw)
{
- sdbusplus::message::object_path path(obj.first);
- std::string swId = path.filename();
- if (swId.empty())
+ sdbusplus::message::object_path path(sw);
+ std::string leaf = path.filename();
+ if (leaf.empty())
{
- messages::internalError(asyncResp->res);
- BMCWEB_LOG_ERROR("Invalid software ID");
-
- return;
+ continue;
}
- bool runningImage = false;
- // Look at Ids from
- // /xyz/openbmc_project/software/functional
- // to determine if this is a running image
- if (std::ranges::find(functionalSwIds, swId) !=
- functionalSwIds.end())
- {
- runningImage = true;
- }
+ functionalSwIds.push_back(leaf);
+ }
- // Now grab its version info
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, obj.second[0].first,
- obj.first, "xyz.openbmc_project.Software.Version",
- [asyncResp, swId, runningImage, swVersionPurpose,
- activeVersionPropName, populateLinkToImages](
- const boost::system::error_code& ec3,
- const dbus::utility::DBusPropertiesMap&
- propertiesList) {
- if (ec3)
- {
- BMCWEB_LOG_ERROR("error_code = {}", ec3);
- BMCWEB_LOG_ERROR("error msg = {}", ec3.message());
- // Have seen the code update app delete the D-Bus
- // object, during code update, between the call to
- // mapper and here. Just leave these properties off if
- // resource not found.
- if (ec3.value() == EBADR)
- {
- return;
- }
- messages::internalError(asyncResp->res);
- return;
- }
- // example propertiesList
- // a{sv} 2 "Version" s
- // "IBM-witherspoon-OP9-v2.0.10-2.22" "Purpose"
- // s
- // "xyz.openbmc_project.Software.Version.VersionPurpose.Host"
- const std::string* version = nullptr;
- const std::string* swInvPurpose = nullptr;
-
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList,
- "Purpose", swInvPurpose, "Version", version);
-
- if (!success)
+ constexpr std::array<std::string_view, 1> interfaces = {
+ "xyz.openbmc_project.Software.Version"};
+ dbus::utility::getSubTree(
+ "/xyz/openbmc_project/software", 0, interfaces,
+ [asyncResp, swVersionPurpose, activeVersionPropName,
+ populateLinkToImages, functionalSwIds](
+ const boost::system::error_code& ec2,
+ const dbus::utility::MapperGetSubTreeResponse& subtree) {
+ if (ec2)
{
+ BMCWEB_LOG_ERROR("error_code = {}", ec2);
+ BMCWEB_LOG_ERROR("error msg = {}", ec2.message());
messages::internalError(asyncResp->res);
return;
}
- if (version == nullptr || version->empty())
- {
- messages::internalError(asyncResp->res);
- return;
- }
- if (swInvPurpose == nullptr ||
- *swInvPurpose != swVersionPurpose)
+ BMCWEB_LOG_DEBUG("Found {} images", subtree.size());
+
+ for (const std::pair<
+ std::string,
+ std::vector<std::pair<
+ std::string, std::vector<std::string>>>>& obj :
+ subtree)
{
- // Not purpose we're looking for
- return;
- }
+ sdbusplus::message::object_path path(obj.first);
+ std::string swId = path.filename();
+ if (swId.empty())
+ {
+ messages::internalError(asyncResp->res);
+ BMCWEB_LOG_ERROR("Invalid software ID");
- BMCWEB_LOG_DEBUG("Image ID: {}", swId);
- BMCWEB_LOG_DEBUG("Running image: {}", runningImage);
- BMCWEB_LOG_DEBUG("Image purpose: {}", *swInvPurpose);
+ return;
+ }
- if (populateLinkToImages)
- {
- nlohmann::json& softwareImageMembers =
- asyncResp->res.jsonValue["Links"]["SoftwareImages"];
- // Firmware images are at
- // /redfish/v1/UpdateService/FirmwareInventory/<Id>
- // e.g. .../FirmwareInventory/82d3ec86
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/UpdateService/FirmwareInventory/{}",
- swId);
- softwareImageMembers.emplace_back(std::move(member));
- asyncResp->res
- .jsonValue["Links"]["SoftwareImages@odata.count"] =
- softwareImageMembers.size();
-
- if (runningImage)
+ bool runningImage = false;
+ // Look at Ids from
+ // /xyz/openbmc_project/software/functional
+ // to determine if this is a running image
+ if (std::ranges::find(functionalSwIds, swId) !=
+ functionalSwIds.end())
{
- nlohmann::json::object_t runningMember;
- runningMember["@odata.id"] = boost::urls::format(
- "/redfish/v1/UpdateService/FirmwareInventory/{}",
- swId);
- // Create the link to the running image
- asyncResp->res
- .jsonValue["Links"]["ActiveSoftwareImage"] =
- std::move(runningMember);
+ runningImage = true;
}
- }
- if (!activeVersionPropName.empty() && runningImage)
- {
- asyncResp->res.jsonValue[activeVersionPropName] =
- *version;
+
+ // Now grab its version info
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, obj.second[0].first,
+ obj.first, "xyz.openbmc_project.Software.Version",
+ [asyncResp, swId, runningImage, swVersionPurpose,
+ activeVersionPropName, populateLinkToImages](
+ const boost::system::error_code& ec3,
+ const dbus::utility::DBusPropertiesMap&
+ propertiesList) {
+ if (ec3)
+ {
+ BMCWEB_LOG_ERROR("error_code = {}", ec3);
+ BMCWEB_LOG_ERROR("error msg = {}",
+ ec3.message());
+ // Have seen the code update app delete the
+ // D-Bus object, during code update, between
+ // the call to mapper and here. Just leave
+ // these properties off if resource not
+ // found.
+ if (ec3.value() == EBADR)
+ {
+ return;
+ }
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // example propertiesList
+ // a{sv} 2 "Version" s
+ // "IBM-witherspoon-OP9-v2.0.10-2.22" "Purpose"
+ // s
+ // "xyz.openbmc_project.Software.Version.VersionPurpose.Host"
+ const std::string* version = nullptr;
+ const std::string* swInvPurpose = nullptr;
+
+ const bool success =
+ sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(),
+ propertiesList, "Purpose", swInvPurpose,
+ "Version", version);
+
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (version == nullptr || version->empty())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (swInvPurpose == nullptr ||
+ *swInvPurpose != swVersionPurpose)
+ {
+ // Not purpose we're looking for
+ return;
+ }
+
+ BMCWEB_LOG_DEBUG("Image ID: {}", swId);
+ BMCWEB_LOG_DEBUG("Running image: {}",
+ runningImage);
+ BMCWEB_LOG_DEBUG("Image purpose: {}",
+ *swInvPurpose);
+
+ if (populateLinkToImages)
+ {
+ nlohmann::json& softwareImageMembers =
+ asyncResp->res
+ .jsonValue["Links"]
+ ["SoftwareImages"];
+ // Firmware images are at
+ // /redfish/v1/UpdateService/FirmwareInventory/<Id>
+ // e.g. .../FirmwareInventory/82d3ec86
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/UpdateService/FirmwareInventory/{}",
+ swId);
+ softwareImageMembers.emplace_back(
+ std::move(member));
+ asyncResp->res.jsonValue
+ ["Links"]
+ ["SoftwareImages@odata.count"] =
+ softwareImageMembers.size();
+
+ if (runningImage)
+ {
+ nlohmann::json::object_t runningMember;
+ runningMember["@odata.id"] =
+ boost::urls::format(
+ "/redfish/v1/UpdateService/FirmwareInventory/{}",
+ swId);
+ // Create the link to the running image
+ asyncResp->res
+ .jsonValue["Links"]
+ ["ActiveSoftwareImage"] =
+ std::move(runningMember);
+ }
+ }
+ if (!activeVersionPropName.empty() &&
+ runningImage)
+ {
+ asyncResp->res
+ .jsonValue[activeVersionPropName] =
+ *version;
+ }
+ });
}
});
- }
});
- });
}
/**
@@ -307,37 +366,84 @@ inline void getSwStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
[asyncResp,
swId](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- if (ec)
- {
- // not all swtypes are updateable, this is ok
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- return;
- }
+ if (ec)
+ {
+ // not all swtypes are updateable, this is ok
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+ return;
+ }
- const std::string* swInvActivation = nullptr;
+ const std::string* swInvActivation = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList, "Activation",
- swInvActivation);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList, "Activation",
+ swInvActivation);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (swInvActivation == nullptr)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (swInvActivation == nullptr)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ BMCWEB_LOG_DEBUG("getSwStatus: Activation {}", *swInvActivation);
+ asyncResp->res.jsonValue["Status"]["State"] =
+ getRedfishSwState(*swInvActivation);
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ getRedfishSwHealth(*swInvActivation);
+ });
+}
- BMCWEB_LOG_DEBUG("getSwStatus: Activation {}", *swInvActivation);
- asyncResp->res.jsonValue["Status"]["State"] =
- getRedfishSwState(*swInvActivation);
- asyncResp->res.jsonValue["Status"]["Health"] =
- getRedfishSwHealth(*swInvActivation);
- });
+inline void handleUpdateableEndpoints(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::shared_ptr<std::string>& swId,
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperEndPoints& objPaths)
+{
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG(" error_code = {} error msg = {}", ec, ec.message());
+ // System can exist with no updateable software,
+ // so don't throw error here.
+ return;
+ }
+ sdbusplus::message::object_path reqSwObjPath(
+ "/xyz/openbmc_project/software");
+ reqSwObjPath = reqSwObjPath / *swId;
+
+ if (std::ranges::find(objPaths, reqSwObjPath.str) != objPaths.end())
+ {
+ asyncResp->res.jsonValue["Updateable"] = true;
+ return;
+ }
+}
+
+inline void
+ handleUpdateableObject(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperGetObject& objectInfo)
+{
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG(" error_code = {} error msg = {}", ec, ec.message());
+ // System can exist with no updateable software,
+ // so don't throw error here.
+ return;
+ }
+ if (objectInfo.empty())
+ {
+ BMCWEB_LOG_DEBUG("No updateable software found");
+ // System can exist with no updateable software,
+ // so don't throw error here.
+ return;
+ }
+ asyncResp->res.jsonValue["Updateable"] = true;
}
/**
@@ -354,26 +460,23 @@ inline void
getSwUpdatableStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::shared_ptr<std::string>& swId)
{
- dbus::utility::getAssociationEndPoints(
- "/xyz/openbmc_project/software/updateable",
- [asyncResp, swId](const boost::system::error_code& ec,
- const dbus::utility::MapperEndPoints& objPaths) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG(" error_code = {} error msg = {}", ec,
- ec.message());
- // System can exist with no updateable software,
- // so don't throw error here.
- return;
- }
- std::string reqSwObjPath = "/xyz/openbmc_project/software/" + *swId;
-
- if (std::ranges::find(objPaths, reqSwObjPath) != objPaths.end())
- {
- asyncResp->res.jsonValue["Updateable"] = true;
- return;
- }
- });
+ if constexpr (BMCWEB_REDFISH_UPDATESERVICE_USE_DBUS)
+ {
+ sdbusplus::message::object_path swObjectPath(
+ "/xyz/openbmc_project/software");
+ swObjectPath = swObjectPath / *swId;
+ constexpr std::array<std::string_view, 1> interfaces = {
+ "xyz.openbmc_project.Software.Update"};
+ dbus::utility::getDbusObject(
+ swObjectPath.str, interfaces,
+ std::bind_front(handleUpdateableObject, asyncResp));
+ }
+ else
+ {
+ dbus::utility::getAssociationEndPoints(
+ "/xyz/openbmc_project/software/updateable",
+ std::bind_front(handleUpdateableEndpoints, asyncResp, swId));
+ }
}
} // namespace sw_util
diff --git a/redfish-core/include/utils/systemd_utils.hpp b/redfish-core/include/utils/systemd_utils.hpp
index 4757283006..66a89ae1de 100644
--- a/redfish-core/include/utils/systemd_utils.hpp
+++ b/redfish-core/include/utils/systemd_utils.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2019 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2019 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
diff --git a/redfish-core/include/utils/time_utils.hpp b/redfish-core/include/utils/time_utils.hpp
index 17509b0e3c..fbcd39e926 100644
--- a/redfish-core/include/utils/time_utils.hpp
+++ b/redfish-core/include/utils/time_utils.hpp
@@ -13,9 +13,6 @@
#include <string>
#include <string_view>
-// IWYU pragma: no_include <stddef.h>
-// IWYU pragma: no_include <stdint.h>
-
namespace redfish
{
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 05cfbe762d..8bb746eda8 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -1,21 +1,22 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
+#include "boost_formatters.hpp"
#include "certificate_service.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
@@ -23,6 +24,7 @@
#include "persistent_data.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
+#include "sessions.hpp"
#include "utils/collection.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
@@ -175,10 +177,9 @@ inline bool translateUserGroup(const std::vector<std::string>& userGroups,
*
* @return true if Account Types mapped to User Groups, false otherwise.
*/
-inline bool
- getUserGroupFromAccountType(crow::Response& res,
- const std::vector<std::string>& accountTypes,
- std::vector<std::string>& userGroups)
+inline bool getUserGroupFromAccountType(
+ crow::Response& res, const std::vector<std::string>& accountTypes,
+ std::vector<std::string>& userGroups)
{
// Need both Redfish and WebUI Account Types to map to 'redfish' User Group
bool redfishType = false;
@@ -383,24 +384,25 @@ inline void handleRoleMapPatch(
crow::connections::systemBus->async_method_call(
[asyncResp, roleMapObjData, serverType,
index](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue[serverType]["RemoteRoleMapping"]
- [index] = nullptr;
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res
+ .jsonValue[serverType]["RemoteRoleMapping"][index] =
+ nullptr;
+ },
ldapDbusService, roleMapObjData[index].first,
"xyz.openbmc_project.Object.Delete", "Delete");
}
else
{
BMCWEB_LOG_ERROR("Can't delete the object");
- messages::propertyValueTypeError(asyncResp->res, "null",
- "RemoteRoleMapping/" +
- std::to_string(index));
+ messages::propertyValueTypeError(
+ asyncResp->res, "null",
+ "RemoteRoleMapping/" + std::to_string(index));
return;
}
}
@@ -439,12 +441,21 @@ inline void handleRoleMapPatch(
// If "LocalRole" info is provided
if (localRole)
{
+ std::string priv = getPrivilegeFromRoleId(*localRole);
+ if (priv.empty())
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, *localRole,
+ std::format("RemoteRoleMapping/{}/LocalRole",
+ index));
+ return;
+ }
setDbusProperty(
asyncResp,
std::format("RemoteRoleMapping/{}/LocalRole", index),
ldapDbusService, roleMapObjData[index].first,
"xyz.openbmc_project.User.PrivilegeMapperEntry",
- "Privilege", *localRole);
+ "Privilege", priv);
}
}
// Create a new RoleMapping Object.
@@ -452,8 +463,8 @@ inline void handleRoleMapPatch(
{
BMCWEB_LOG_DEBUG(
"setRoleMappingProperties: Creating new Object");
- std::string pathString = "RemoteRoleMapping/" +
- std::to_string(index);
+ std::string pathString =
+ "RemoteRoleMapping/" + std::to_string(index);
if (!localRole)
{
@@ -484,20 +495,20 @@ inline void handleRoleMapPatch(
crow::connections::systemBus->async_method_call(
[asyncResp, serverType, localRole,
remoteGroup](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- nlohmann::json& remoteRoleJson =
- asyncResp->res
- .jsonValue[serverType]["RemoteRoleMapping"];
- nlohmann::json::object_t roleMapEntry;
- roleMapEntry["LocalRole"] = *localRole;
- roleMapEntry["RemoteGroup"] = *remoteGroup;
- remoteRoleJson.emplace_back(std::move(roleMapEntry));
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ nlohmann::json& remoteRoleJson =
+ asyncResp->res
+ .jsonValue[serverType]["RemoteRoleMapping"];
+ nlohmann::json::object_t roleMapEntry;
+ roleMapEntry["LocalRole"] = *localRole;
+ roleMapEntry["RemoteGroup"] = *remoteGroup;
+ remoteRoleJson.emplace_back(std::move(roleMapEntry));
+ },
ldapDbusService, dbusObjectPath, ldapPrivMapperInterface,
"Create", *remoteGroup,
getPrivilegeFromRoleId(std::move(*localRole)));
@@ -511,8 +522,8 @@ inline void handleRoleMapPatch(
* into JSON
*/
template <typename CallbackFunc>
-inline void getLDAPConfigData(const std::string& ldapType,
- CallbackFunc&& callback)
+inline void
+ getLDAPConfigData(const std::string& ldapType, CallbackFunc&& callback)
{
constexpr std::array<std::string_view, 2> interfaces = {
ldapEnableInterface, ldapConfigInterface};
@@ -522,156 +533,165 @@ inline void getLDAPConfigData(const std::string& ldapType,
[callback = std::forward<CallbackFunc>(callback),
ldapType](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& resp) mutable {
- if (ec || resp.empty())
- {
- BMCWEB_LOG_WARNING(
- "DBUS response error during getting of service name: {}", ec);
- LDAPConfigData empty{};
- callback(false, empty, ldapType);
- return;
- }
- std::string service = resp.begin()->first;
- sdbusplus::message::object_path path(ldapRootObject);
- dbus::utility::getManagedObjects(
- service, path,
- [callback, ldapType](
- const boost::system::error_code& ec2,
- const dbus::utility::ManagedObjectType& ldapObjects) mutable {
- LDAPConfigData confData{};
- if (ec2)
+ if (ec || resp.empty())
{
- callback(false, confData, ldapType);
- BMCWEB_LOG_WARNING("D-Bus responses error: {}", ec2);
+ BMCWEB_LOG_WARNING(
+ "DBUS response error during getting of service name: {}",
+ ec);
+ LDAPConfigData empty{};
+ callback(false, empty, ldapType);
return;
}
+ std::string service = resp.begin()->first;
+ sdbusplus::message::object_path path(ldapRootObject);
+ dbus::utility::getManagedObjects(
+ service, path,
+ [callback, ldapType](const boost::system::error_code& ec2,
+ const dbus::utility::ManagedObjectType&
+ ldapObjects) mutable {
+ LDAPConfigData confData{};
+ if (ec2)
+ {
+ callback(false, confData, ldapType);
+ BMCWEB_LOG_WARNING("D-Bus responses error: {}", ec2);
+ return;
+ }
- std::string ldapDbusType;
- std::string searchString;
-
- if (ldapType == "LDAP")
- {
- ldapDbusType =
- "xyz.openbmc_project.User.Ldap.Config.Type.OpenLdap";
- searchString = "openldap";
- }
- else if (ldapType == "ActiveDirectory")
- {
- ldapDbusType =
- "xyz.openbmc_project.User.Ldap.Config.Type.ActiveDirectory";
- searchString = "active_directory";
- }
- else
- {
- BMCWEB_LOG_ERROR("Can't get the DbusType for the given type={}",
- ldapType);
- callback(false, confData, ldapType);
- return;
- }
-
- std::string ldapEnableInterfaceStr = ldapEnableInterface;
- std::string ldapConfigInterfaceStr = ldapConfigInterface;
+ std::string ldapDbusType;
+ std::string searchString;
- for (const auto& object : ldapObjects)
- {
- // let's find the object whose ldap type is equal to the
- // given type
- if (object.first.str.find(searchString) == std::string::npos)
- {
- continue;
- }
-
- for (const auto& interface : object.second)
- {
- if (interface.first == ldapEnableInterfaceStr)
+ if (ldapType == "LDAP")
{
- // rest of the properties are string.
- for (const auto& property : interface.second)
- {
- if (property.first == "Enabled")
- {
- const bool* value =
- std::get_if<bool>(&property.second);
- if (value == nullptr)
- {
- continue;
- }
- confData.serviceEnabled = *value;
- break;
- }
- }
+ ldapDbusType =
+ "xyz.openbmc_project.User.Ldap.Config.Type.OpenLdap";
+ searchString = "openldap";
}
- else if (interface.first == ldapConfigInterfaceStr)
+ else if (ldapType == "ActiveDirectory")
{
- for (const auto& property : interface.second)
- {
- const std::string* strValue =
- std::get_if<std::string>(&property.second);
- if (strValue == nullptr)
- {
- continue;
- }
- if (property.first == "LDAPServerURI")
- {
- confData.uri = *strValue;
- }
- else if (property.first == "LDAPBindDN")
- {
- confData.bindDN = *strValue;
- }
- else if (property.first == "LDAPBaseDN")
- {
- confData.baseDN = *strValue;
- }
- else if (property.first == "LDAPSearchScope")
- {
- confData.searchScope = *strValue;
- }
- else if (property.first == "GroupNameAttribute")
- {
- confData.groupAttribute = *strValue;
- }
- else if (property.first == "UserNameAttribute")
- {
- confData.userNameAttribute = *strValue;
- }
- else if (property.first == "LDAPType")
- {
- confData.serverType = *strValue;
- }
- }
+ ldapDbusType =
+ "xyz.openbmc_project.User.Ldap.Config.Type.ActiveDirectory";
+ searchString = "active_directory";
+ }
+ else
+ {
+ BMCWEB_LOG_ERROR(
+ "Can't get the DbusType for the given type={}",
+ ldapType);
+ callback(false, confData, ldapType);
+ return;
}
- else if (interface.first ==
- "xyz.openbmc_project.User.PrivilegeMapperEntry")
+
+ std::string ldapEnableInterfaceStr = ldapEnableInterface;
+ std::string ldapConfigInterfaceStr = ldapConfigInterface;
+
+ for (const auto& object : ldapObjects)
{
- LDAPRoleMapData roleMapData{};
- for (const auto& property : interface.second)
+ // let's find the object whose ldap type is equal to the
+ // given type
+ if (object.first.str.find(searchString) ==
+ std::string::npos)
{
- const std::string* strValue =
- std::get_if<std::string>(&property.second);
+ continue;
+ }
- if (strValue == nullptr)
+ for (const auto& interface : object.second)
+ {
+ if (interface.first == ldapEnableInterfaceStr)
{
- continue;
+ // rest of the properties are string.
+ for (const auto& property : interface.second)
+ {
+ if (property.first == "Enabled")
+ {
+ const bool* value =
+ std::get_if<bool>(&property.second);
+ if (value == nullptr)
+ {
+ continue;
+ }
+ confData.serviceEnabled = *value;
+ break;
+ }
+ }
}
-
- if (property.first == "GroupName")
+ else if (interface.first == ldapConfigInterfaceStr)
{
- roleMapData.groupName = *strValue;
+ for (const auto& property : interface.second)
+ {
+ const std::string* strValue =
+ std::get_if<std::string>(
+ &property.second);
+ if (strValue == nullptr)
+ {
+ continue;
+ }
+ if (property.first == "LDAPServerURI")
+ {
+ confData.uri = *strValue;
+ }
+ else if (property.first == "LDAPBindDN")
+ {
+ confData.bindDN = *strValue;
+ }
+ else if (property.first == "LDAPBaseDN")
+ {
+ confData.baseDN = *strValue;
+ }
+ else if (property.first ==
+ "LDAPSearchScope")
+ {
+ confData.searchScope = *strValue;
+ }
+ else if (property.first ==
+ "GroupNameAttribute")
+ {
+ confData.groupAttribute = *strValue;
+ }
+ else if (property.first ==
+ "UserNameAttribute")
+ {
+ confData.userNameAttribute = *strValue;
+ }
+ else if (property.first == "LDAPType")
+ {
+ confData.serverType = *strValue;
+ }
+ }
}
- else if (property.first == "Privilege")
+ else if (
+ interface.first ==
+ "xyz.openbmc_project.User.PrivilegeMapperEntry")
{
- roleMapData.privilege = *strValue;
+ LDAPRoleMapData roleMapData{};
+ for (const auto& property : interface.second)
+ {
+ const std::string* strValue =
+ std::get_if<std::string>(
+ &property.second);
+
+ if (strValue == nullptr)
+ {
+ continue;
+ }
+
+ if (property.first == "GroupName")
+ {
+ roleMapData.groupName = *strValue;
+ }
+ else if (property.first == "Privilege")
+ {
+ roleMapData.privilege = *strValue;
+ }
+ }
+
+ confData.groupRoleList.emplace_back(
+ object.first.str, roleMapData);
}
}
-
- confData.groupRoleList.emplace_back(object.first.str,
- roleMapData);
}
- }
- }
- callback(true, confData, ldapType);
+ callback(true, confData, ldapType);
+ });
});
- });
}
/**
@@ -764,17 +784,17 @@ inline void
server(openLDAP/ActiveDirectory)
*/
-inline void
- handleUserNameAttrPatch(const std::string& userNameAttribute,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& ldapServerElementName,
- const std::string& ldapConfigObject)
+inline void handleUserNameAttrPatch(
+ const std::string& userNameAttribute,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& ldapServerElementName,
+ const std::string& ldapConfigObject)
{
- setDbusProperty(asyncResp,
- ldapServerElementName +
- "LDAPService/SearchSettings/UsernameAttribute",
- ldapDbusService, ldapConfigObject, ldapConfigInterface,
- "UserNameAttribute", userNameAttribute);
+ setDbusProperty(
+ asyncResp,
+ ldapServerElementName + "LDAPService/SearchSettings/UsernameAttribute",
+ ldapDbusService, ldapConfigObject, ldapConfigInterface,
+ "UserNameAttribute", userNameAttribute);
}
/**
* @brief updates the LDAP group attribute and updates the
@@ -791,11 +811,11 @@ inline void handleGroupNameAttrPatch(
const std::string& ldapServerElementName,
const std::string& ldapConfigObject)
{
- setDbusProperty(asyncResp,
- ldapServerElementName +
- "/LDAPService/SearchSettings/GroupsAttribute",
- ldapDbusService, ldapConfigObject, ldapConfigInterface,
- "GroupNameAttribute", groupsAttribute);
+ setDbusProperty(
+ asyncResp,
+ ldapServerElementName + "/LDAPService/SearchSettings/GroupsAttribute",
+ ldapDbusService, ldapConfigObject, ldapConfigInterface,
+ "GroupNameAttribute", groupsAttribute);
}
/**
* @brief updates the LDAP service enable and updates the
@@ -991,11 +1011,11 @@ inline void handleLDAPPatch(LdapPatchParams&& input,
// Get the existing resource first then keep modifying
// whenever any property gets updated.
- getLDAPConfigData(serverType,
- [asyncResp, input = std::move(input),
- dbusObjectPath = std::move(dbusObjectPath)](
- bool success, const LDAPConfigData& confData,
- const std::string& serverT) mutable {
+ getLDAPConfigData(serverType, [asyncResp, input = std::move(input),
+ dbusObjectPath = std::move(dbusObjectPath)](
+ bool success,
+ const LDAPConfigData& confData,
+ const std::string& serverT) mutable {
if (!success)
{
messages::internalError(asyncResp->res);
@@ -1085,89 +1105,91 @@ inline void updateUserProperties(
[dbusObjectPath, username, password, roleId, enabled, locked,
accountTypes(std::move(accountTypes)), userSelf, session,
asyncResp{std::move(asyncResp)}](int rc) {
- if (rc <= 0)
- {
- messages::resourceNotFound(asyncResp->res, "ManagerAccount",
- username);
- return;
- }
-
- if (password)
- {
- int retval = pamUpdatePassword(username, *password);
-
- if (retval == PAM_USER_UNKNOWN)
+ if (rc <= 0)
{
messages::resourceNotFound(asyncResp->res, "ManagerAccount",
username);
+ return;
}
- else if (retval == PAM_AUTHTOK_ERR)
+
+ if (password)
{
- // If password is invalid
- messages::propertyValueFormatError(asyncResp->res, nullptr,
- "Password");
- BMCWEB_LOG_ERROR("pamUpdatePassword Failed");
+ int retval = pamUpdatePassword(username, *password);
+
+ if (retval == PAM_USER_UNKNOWN)
+ {
+ messages::resourceNotFound(asyncResp->res, "ManagerAccount",
+ username);
+ }
+ else if (retval == PAM_AUTHTOK_ERR)
+ {
+ // If password is invalid
+ messages::propertyValueFormatError(asyncResp->res, nullptr,
+ "Password");
+ BMCWEB_LOG_ERROR("pamUpdatePassword Failed");
+ }
+ else if (retval != PAM_SUCCESS)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ else
+ {
+ // Remove existing sessions of the user when password
+ // changed
+ persistent_data::SessionStore::getInstance()
+ .removeSessionsByUsernameExceptSession(username,
+ session);
+ messages::success(asyncResp->res);
+ }
}
- else if (retval != PAM_SUCCESS)
+
+ if (enabled)
{
- messages::internalError(asyncResp->res);
- return;
+ setDbusProperty(
+ asyncResp, "Enabled", "xyz.openbmc_project.User.Manager",
+ dbusObjectPath, "xyz.openbmc_project.User.Attributes",
+ "UserEnabled", *enabled);
}
- else
+
+ if (roleId)
{
- // Remove existing sessions of the user when password changed
- persistent_data::SessionStore::getInstance()
- .removeSessionsByUsernameExceptSession(username, session);
- messages::success(asyncResp->res);
+ std::string priv = getPrivilegeFromRoleId(*roleId);
+ if (priv.empty())
+ {
+ messages::propertyValueNotInList(asyncResp->res, true,
+ "Locked");
+ return;
+ }
+ setDbusProperty(
+ asyncResp, "RoleId", "xyz.openbmc_project.User.Manager",
+ dbusObjectPath, "xyz.openbmc_project.User.Attributes",
+ "UserPrivilege", priv);
}
- }
- if (enabled)
- {
- setDbusProperty(asyncResp, "Enabled",
- "xyz.openbmc_project.User.Manager", dbusObjectPath,
- "xyz.openbmc_project.User.Attributes",
- "UserEnabled", *enabled);
- }
-
- if (roleId)
- {
- std::string priv = getPrivilegeFromRoleId(*roleId);
- if (priv.empty())
+ if (locked)
{
- messages::propertyValueNotInList(asyncResp->res, true,
- "Locked");
- return;
+ // admin can unlock the account which is locked by
+ // successive authentication failures but admin should
+ // not be allowed to lock an account.
+ if (*locked)
+ {
+ messages::propertyValueNotInList(asyncResp->res, "true",
+ "Locked");
+ return;
+ }
+ setDbusProperty(
+ asyncResp, "Locked", "xyz.openbmc_project.User.Manager",
+ dbusObjectPath, "xyz.openbmc_project.User.Attributes",
+ "UserLockedForFailedAttempt", *locked);
}
- setDbusProperty(asyncResp, "RoleId",
- "xyz.openbmc_project.User.Manager", dbusObjectPath,
- "xyz.openbmc_project.User.Attributes",
- "UserPrivilege", priv);
- }
- if (locked)
- {
- // admin can unlock the account which is locked by
- // successive authentication failures but admin should
- // not be allowed to lock an account.
- if (*locked)
+ if (accountTypes)
{
- messages::propertyValueNotInList(asyncResp->res, "true",
- "Locked");
- return;
+ patchAccountTypes(*accountTypes, asyncResp, dbusObjectPath,
+ userSelf);
}
- setDbusProperty(asyncResp, "Locked",
- "xyz.openbmc_project.User.Manager", dbusObjectPath,
- "xyz.openbmc_project.User.Attributes",
- "UserLockedForFailedAttempt", *locked);
- }
-
- if (accountTypes)
- {
- patchAccountTypes(*accountTypes, asyncResp, dbusObjectPath,
- userSelf);
- }
- });
+ });
}
inline void handleAccountServiceHead(
@@ -1257,6 +1279,45 @@ inline void handleAccountServiceClientCertificatesGet(
getClientCertificates(asyncResp, "/Members"_json_pointer);
}
+using account_service::CertificateMappingAttribute;
+using persistent_data::MTLSCommonNameParseMode;
+inline CertificateMappingAttribute
+ getCertificateMapping(MTLSCommonNameParseMode parse)
+{
+ switch (parse)
+ {
+ case MTLSCommonNameParseMode::CommonName:
+ {
+ return CertificateMappingAttribute::CommonName;
+ }
+ break;
+ case MTLSCommonNameParseMode::Whole:
+ {
+ return CertificateMappingAttribute::Whole;
+ }
+ break;
+ case MTLSCommonNameParseMode::UserPrincipalName:
+ {
+ return CertificateMappingAttribute::UserPrincipalName;
+ }
+ break;
+
+ case MTLSCommonNameParseMode::Meta:
+ {
+ if constexpr (BMCWEB_META_TLS_COMMON_NAME_PARSING)
+ {
+ return CertificateMappingAttribute::CommonName;
+ }
+ }
+ break;
+ default:
+ {
+ return CertificateMappingAttribute::Invalid;
+ }
+ break;
+ }
+}
+
inline void
handleAccountServiceGet(App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
@@ -1300,9 +1361,21 @@ inline void
nlohmann::json::object_t clientCertificate;
clientCertificate["Enabled"] = authMethodsConfig.tls;
- clientCertificate["RespondToUnauthenticatedClients"] = true;
- clientCertificate["CertificateMappingAttribute"] =
- account_service::CertificateMappingAttribute::CommonName;
+ clientCertificate["RespondToUnauthenticatedClients"] =
+ !authMethodsConfig.tlsStrict;
+
+ using account_service::CertificateMappingAttribute;
+
+ CertificateMappingAttribute mapping =
+ getCertificateMapping(authMethodsConfig.mTLSCommonNameParsingMode);
+ if (mapping == CertificateMappingAttribute::Invalid)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ else
+ {
+ clientCertificate["CertificateMappingAttribute"] = mapping;
+ }
nlohmann::json::object_t certificates;
certificates["@odata.id"] =
"/redfish/v1/AccountService/MultiFactorAuth/ClientCertificate/Certificates";
@@ -1344,48 +1417,49 @@ inline void
"/xyz/openbmc_project/user", "xyz.openbmc_project.User.AccountPolicy",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- BMCWEB_LOG_DEBUG("Got {} properties for AccountService",
- propertiesList.size());
+ BMCWEB_LOG_DEBUG("Got {} properties for AccountService",
+ propertiesList.size());
- const uint8_t* minPasswordLength = nullptr;
- const uint32_t* accountUnlockTimeout = nullptr;
- const uint16_t* maxLoginAttemptBeforeLockout = nullptr;
+ const uint8_t* minPasswordLength = nullptr;
+ const uint32_t* accountUnlockTimeout = nullptr;
+ const uint16_t* maxLoginAttemptBeforeLockout = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList,
- "MinPasswordLength", minPasswordLength, "AccountUnlockTimeout",
- accountUnlockTimeout, "MaxLoginAttemptBeforeLockout",
- maxLoginAttemptBeforeLockout);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList,
+ "MinPasswordLength", minPasswordLength, "AccountUnlockTimeout",
+ accountUnlockTimeout, "MaxLoginAttemptBeforeLockout",
+ maxLoginAttemptBeforeLockout);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (minPasswordLength != nullptr)
- {
- asyncResp->res.jsonValue["MinPasswordLength"] = *minPasswordLength;
- }
+ if (minPasswordLength != nullptr)
+ {
+ asyncResp->res.jsonValue["MinPasswordLength"] =
+ *minPasswordLength;
+ }
- if (accountUnlockTimeout != nullptr)
- {
- asyncResp->res.jsonValue["AccountLockoutDuration"] =
- *accountUnlockTimeout;
- }
+ if (accountUnlockTimeout != nullptr)
+ {
+ asyncResp->res.jsonValue["AccountLockoutDuration"] =
+ *accountUnlockTimeout;
+ }
- if (maxLoginAttemptBeforeLockout != nullptr)
- {
- asyncResp->res.jsonValue["AccountLockoutThreshold"] =
- *maxLoginAttemptBeforeLockout;
- }
- });
+ if (maxLoginAttemptBeforeLockout != nullptr)
+ {
+ asyncResp->res.jsonValue["AccountLockoutThreshold"] =
+ *maxLoginAttemptBeforeLockout;
+ }
+ });
auto callback = [asyncResp](bool success, const LDAPConfigData& confData,
const std::string& ldapType) {
@@ -1400,6 +1474,55 @@ inline void
getLDAPConfigData("ActiveDirectory", callback);
}
+inline void handleCertificateMappingAttributePatch(
+ crow::Response& res, const std::string& certMapAttribute)
+{
+ MTLSCommonNameParseMode parseMode =
+ persistent_data::getMTLSCommonNameParseMode(certMapAttribute);
+ if (parseMode == MTLSCommonNameParseMode::Invalid)
+ {
+ messages::propertyValueNotInList(res, "CertificateMappingAttribute",
+ certMapAttribute);
+ return;
+ }
+
+ persistent_data::AuthConfigMethods& authMethodsConfig =
+ persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
+ authMethodsConfig.mTLSCommonNameParsingMode = parseMode;
+}
+
+inline void handleRespondToUnauthenticatedClientsPatch(
+ App& app, const crow::Request& req, crow::Response& res,
+ bool respondToUnauthenticatedClients)
+{
+ if (req.session != nullptr)
+ {
+ // Sanity check. If the user isn't currently authenticated with mutual
+ // TLS, they very likely are about to permanently lock themselves out.
+ // Make sure they're using mutual TLS before allowing locking.
+ if (req.session->sessionType != persistent_data::SessionType::MutualTLS)
+ {
+ messages::propertyValueExternalConflict(
+ res,
+ "MultiFactorAuth/ClientCertificate/RespondToUnauthenticatedClients",
+ respondToUnauthenticatedClients);
+ return;
+ }
+ }
+
+ persistent_data::AuthConfigMethods& authMethodsConfig =
+ persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
+
+ // Change the settings
+ authMethodsConfig.tlsStrict = !respondToUnauthenticatedClients;
+
+ // Write settings to disk
+ persistent_data::getConfig().writeData();
+
+ // Trigger a reload, to apply the new settings to new connections
+ app.loadCertificate();
+}
+
inline void handleAccountServicePatch(
App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
@@ -1413,9 +1536,12 @@ inline void handleAccountServicePatch(
std::optional<uint8_t> minPasswordLength;
std::optional<uint16_t> maxPasswordLength;
LdapPatchParams ldapObject;
+ std::optional<std::string> certificateMappingAttribute;
+ std::optional<bool> respondToUnauthenticatedClients;
LdapPatchParams activeDirectoryObject;
AuthMethods auth;
std::optional<std::string> httpBasicAuth;
+
// clang-format off
if (!json_util::readJsonPatch(
req, asyncResp->res,
@@ -1430,6 +1556,8 @@ inline void handleAccountServicePatch(
"ActiveDirectory/RemoteRoleMapping", activeDirectoryObject.remoteRoleMapData,
"ActiveDirectory/ServiceAddresses", activeDirectoryObject.serviceAddressList,
"ActiveDirectory/ServiceEnabled", activeDirectoryObject.serviceEnabled,
+ "MultiFactorAuth/ClientCertificate/CertificateMappingAttribute", certificateMappingAttribute,
+ "MultiFactorAuth/ClientCertificate/RespondToUnauthenticatedClients", respondToUnauthenticatedClients,
"LDAP/Authentication/AuthenticationType", ldapObject.authType,
"LDAP/Authentication/Password", ldapObject.password,
"LDAP/Authentication/Username", ldapObject.userName,
@@ -1469,6 +1597,18 @@ inline void handleAccountServicePatch(
}
}
+ if (respondToUnauthenticatedClients)
+ {
+ handleRespondToUnauthenticatedClientsPatch(
+ app, req, asyncResp->res, *respondToUnauthenticatedClients);
+ }
+
+ if (certificateMappingAttribute)
+ {
+ handleCertificateMappingAttributePatch(asyncResp->res,
+ *certificateMappingAttribute);
+ }
+
if (minPasswordLength)
{
setDbusProperty(
@@ -1562,47 +1702,49 @@ inline void handleAccountCollectionGet(
[asyncResp, thisUser, effectiveUserPrivileges](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& users) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- bool userCanSeeAllAccounts =
- effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"});
+ bool userCanSeeAllAccounts =
+ effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"});
- bool userCanSeeSelf =
- effectiveUserPrivileges.isSupersetOf({"ConfigureSelf"});
+ bool userCanSeeSelf =
+ effectiveUserPrivileges.isSupersetOf({"ConfigureSelf"});
- nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
- memberArray = nlohmann::json::array();
+ nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
+ memberArray = nlohmann::json::array();
- for (const auto& userpath : users)
- {
- std::string user = userpath.first.filename();
- if (user.empty())
+ for (const auto& userpath : users)
{
- messages::internalError(asyncResp->res);
- BMCWEB_LOG_ERROR("Invalid firmware ID");
+ std::string user = userpath.first.filename();
+ if (user.empty())
+ {
+ messages::internalError(asyncResp->res);
+ BMCWEB_LOG_ERROR("Invalid firmware ID");
- return;
- }
+ return;
+ }
- // As clarified by Redfish here:
- // https://redfishforum.com/thread/281/manageraccountcollection-change-allows-account-enumeration
- // Users without ConfigureUsers, only see their own
- // account. Users with ConfigureUsers, see all
- // accounts.
- if (userCanSeeAllAccounts || (thisUser == user && userCanSeeSelf))
- {
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/AccountService/Accounts/{}", user);
- memberArray.emplace_back(std::move(member));
+ // As clarified by Redfish here:
+ // https://redfishforum.com/thread/281/manageraccountcollection-change-allows-account-enumeration
+ // Users without ConfigureUsers, only see their own
+ // account. Users with ConfigureUsers, see all
+ // accounts.
+ if (userCanSeeAllAccounts ||
+ (thisUser == user && userCanSeeSelf))
+ {
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/AccountService/Accounts/{}", user);
+ memberArray.emplace_back(std::move(member));
+ }
}
- }
- asyncResp->res.jsonValue["Members@odata.count"] = memberArray.size();
- });
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ memberArray.size();
+ });
}
inline void processAfterCreateUser(
@@ -1628,16 +1770,16 @@ inline void processAfterCreateUser(
crow::connections::systemBus->async_method_call(
[asyncResp, password](const boost::system::error_code& ec3) {
- if (ec3)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec3)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // If password is invalid
- messages::propertyValueFormatError(asyncResp->res, nullptr,
- "Password");
- },
+ // If password is invalid
+ messages::propertyValueFormatError(asyncResp->res, nullptr,
+ "Password");
+ },
"xyz.openbmc_project.User.Manager", userPath,
"xyz.openbmc_project.Object.Delete", "Delete");
@@ -1721,8 +1863,8 @@ inline void processAfterGetAllGroups(
crow::connections::systemBus->async_method_call(
[asyncResp, username, password](const boost::system::error_code& ec2,
sdbusplus::message_t& m) {
- processAfterCreateUser(asyncResp, username, password, ec2, m);
- },
+ processAfterCreateUser(asyncResp, username, password, ec2, m);
+ },
"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
"xyz.openbmc_project.User.Manager", "CreateUser", username, userGroups,
roleId, enabled);
@@ -1741,10 +1883,10 @@ inline void handleAccountCollectionPost(
std::optional<std::string> roleIdJson;
std::optional<bool> enabledJson;
std::optional<std::vector<std::string>> accountTypes;
- if (!json_util::readJsonPatch(req, asyncResp->res, "UserName", username,
- "Password", password, "RoleId", roleIdJson,
- "Enabled", enabledJson, "AccountTypes",
- accountTypes))
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "UserName", username, "Password", password,
+ "RoleId", roleIdJson, "Enabled", enabledJson, "AccountTypes",
+ accountTypes))
{
return;
}
@@ -1768,22 +1910,22 @@ inline void handleAccountCollectionPost(
[asyncResp, username, password{std::move(password)}, roleId, enabled,
accountTypes](const boost::system::error_code& ec,
const std::vector<std::string>& allGroupsList) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("ERROR with async_method_call");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("D-Bus response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (allGroupsList.empty())
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (allGroupsList.empty())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- processAfterGetAllGroups(asyncResp, username, password, roleId, enabled,
- accountTypes, allGroupsList);
- });
+ processAfterGetAllGroups(asyncResp, username, password, roleId,
+ enabled, accountTypes, allGroupsList);
+ });
}
inline void
@@ -1851,138 +1993,140 @@ inline void
[asyncResp,
accountName](const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& users) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- const auto userIt = std::ranges::find_if(
- users,
- [accountName](
- const std::pair<sdbusplus::message::object_path,
- dbus::utility::DBusInterfacesMap>& user) {
- return accountName == user.first.filename();
- });
-
- if (userIt == users.end())
- {
- messages::resourceNotFound(asyncResp->res, "ManagerAccount",
- accountName);
- return;
- }
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const auto userIt = std::ranges::find_if(
+ users,
+ [accountName](
+ const std::pair<sdbusplus::message::object_path,
+ dbus::utility::DBusInterfacesMap>& user) {
+ return accountName == user.first.filename();
+ });
+
+ if (userIt == users.end())
+ {
+ messages::resourceNotFound(asyncResp->res, "ManagerAccount",
+ accountName);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.type"] =
- "#ManagerAccount.v1_7_0.ManagerAccount";
- asyncResp->res.jsonValue["Name"] = "User Account";
- asyncResp->res.jsonValue["Description"] = "User Account";
- asyncResp->res.jsonValue["Password"] = nullptr;
- asyncResp->res.jsonValue["StrictAccountTypes"] = true;
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ManagerAccount.v1_7_0.ManagerAccount";
+ asyncResp->res.jsonValue["Name"] = "User Account";
+ asyncResp->res.jsonValue["Description"] = "User Account";
+ asyncResp->res.jsonValue["Password"] = nullptr;
+ asyncResp->res.jsonValue["StrictAccountTypes"] = true;
- for (const auto& interface : userIt->second)
- {
- if (interface.first == "xyz.openbmc_project.User.Attributes")
+ for (const auto& interface : userIt->second)
{
- for (const auto& property : interface.second)
+ if (interface.first == "xyz.openbmc_project.User.Attributes")
{
- if (property.first == "UserEnabled")
- {
- const bool* userEnabled =
- std::get_if<bool>(&property.second);
- if (userEnabled == nullptr)
- {
- BMCWEB_LOG_ERROR("UserEnabled wasn't a bool");
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["Enabled"] = *userEnabled;
- }
- else if (property.first == "UserLockedForFailedAttempt")
+ for (const auto& property : interface.second)
{
- const bool* userLocked =
- std::get_if<bool>(&property.second);
- if (userLocked == nullptr)
+ if (property.first == "UserEnabled")
{
- BMCWEB_LOG_ERROR("UserLockedForF"
- "ailedAttempt "
- "wasn't a bool");
- messages::internalError(asyncResp->res);
- return;
+ const bool* userEnabled =
+ std::get_if<bool>(&property.second);
+ if (userEnabled == nullptr)
+ {
+ BMCWEB_LOG_ERROR("UserEnabled wasn't a bool");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["Enabled"] = *userEnabled;
}
- asyncResp->res.jsonValue["Locked"] = *userLocked;
- nlohmann::json::array_t allowed;
- // can only unlock accounts
- allowed.emplace_back("false");
- asyncResp->res
- .jsonValue["Locked@Redfish.AllowableValues"] =
- std::move(allowed);
- }
- else if (property.first == "UserPrivilege")
- {
- const std::string* userPrivPtr =
- std::get_if<std::string>(&property.second);
- if (userPrivPtr == nullptr)
+ else if (property.first == "UserLockedForFailedAttempt")
{
- BMCWEB_LOG_ERROR("UserPrivilege wasn't a "
- "string");
- messages::internalError(asyncResp->res);
- return;
+ const bool* userLocked =
+ std::get_if<bool>(&property.second);
+ if (userLocked == nullptr)
+ {
+ BMCWEB_LOG_ERROR("UserLockedForF"
+ "ailedAttempt "
+ "wasn't a bool");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["Locked"] = *userLocked;
+ nlohmann::json::array_t allowed;
+ // can only unlock accounts
+ allowed.emplace_back("false");
+ asyncResp->res
+ .jsonValue["Locked@Redfish.AllowableValues"] =
+ std::move(allowed);
}
- std::string role = getRoleIdFromPrivilege(*userPrivPtr);
- if (role.empty())
+ else if (property.first == "UserPrivilege")
{
- BMCWEB_LOG_ERROR("Invalid user role");
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["RoleId"] = role;
+ const std::string* userPrivPtr =
+ std::get_if<std::string>(&property.second);
+ if (userPrivPtr == nullptr)
+ {
+ BMCWEB_LOG_ERROR("UserPrivilege wasn't a "
+ "string");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ std::string role =
+ getRoleIdFromPrivilege(*userPrivPtr);
+ if (role.empty())
+ {
+ BMCWEB_LOG_ERROR("Invalid user role");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["RoleId"] = role;
- nlohmann::json& roleEntry =
- asyncResp->res.jsonValue["Links"]["Role"];
- roleEntry["@odata.id"] = boost::urls::format(
- "/redfish/v1/AccountService/Roles/{}", role);
- }
- else if (property.first == "UserPasswordExpired")
- {
- const bool* userPasswordExpired =
- std::get_if<bool>(&property.second);
- if (userPasswordExpired == nullptr)
- {
- BMCWEB_LOG_ERROR(
- "UserPasswordExpired wasn't a bool");
- messages::internalError(asyncResp->res);
- return;
+ nlohmann::json& roleEntry =
+ asyncResp->res.jsonValue["Links"]["Role"];
+ roleEntry["@odata.id"] = boost::urls::format(
+ "/redfish/v1/AccountService/Roles/{}", role);
}
- asyncResp->res.jsonValue["PasswordChangeRequired"] =
- *userPasswordExpired;
- }
- else if (property.first == "UserGroups")
- {
- const std::vector<std::string>* userGroups =
- std::get_if<std::vector<std::string>>(
- &property.second);
- if (userGroups == nullptr)
+ else if (property.first == "UserPasswordExpired")
{
- BMCWEB_LOG_ERROR(
- "userGroups wasn't a string vector");
- messages::internalError(asyncResp->res);
- return;
+ const bool* userPasswordExpired =
+ std::get_if<bool>(&property.second);
+ if (userPasswordExpired == nullptr)
+ {
+ BMCWEB_LOG_ERROR(
+ "UserPasswordExpired wasn't a bool");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["PasswordChangeRequired"] =
+ *userPasswordExpired;
}
- if (!translateUserGroup(*userGroups, asyncResp->res))
+ else if (property.first == "UserGroups")
{
- BMCWEB_LOG_ERROR("userGroups mapping failed");
- messages::internalError(asyncResp->res);
- return;
+ const std::vector<std::string>* userGroups =
+ std::get_if<std::vector<std::string>>(
+ &property.second);
+ if (userGroups == nullptr)
+ {
+ BMCWEB_LOG_ERROR(
+ "userGroups wasn't a string vector");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (!translateUserGroup(*userGroups,
+ asyncResp->res))
+ {
+ BMCWEB_LOG_ERROR("userGroups mapping failed");
+ messages::internalError(asyncResp->res);
+ return;
+ }
}
}
}
}
- }
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/AccountService/Accounts/{}", accountName);
- asyncResp->res.jsonValue["Id"] = accountName;
- asyncResp->res.jsonValue["UserName"] = accountName;
- });
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/AccountService/Accounts/{}", accountName);
+ asyncResp->res.jsonValue["Id"] = accountName;
+ asyncResp->res.jsonValue["UserName"] = accountName;
+ });
}
inline void
@@ -2007,15 +2151,15 @@ inline void
crow::connections::systemBus->async_method_call(
[asyncResp, username](const boost::system::error_code& ec) {
- if (ec)
- {
- messages::resourceNotFound(asyncResp->res, "ManagerAccount",
- username);
- return;
- }
+ if (ec)
+ {
+ messages::resourceNotFound(asyncResp->res, "ManagerAccount",
+ username);
+ return;
+ }
- messages::accountRemoved(asyncResp->res);
- },
+ messages::accountRemoved(asyncResp->res);
+ },
"xyz.openbmc_project.User.Manager", userPath,
"xyz.openbmc_project.Object.Delete", "Delete");
}
@@ -2099,16 +2243,16 @@ inline void
roleId(std::move(roleId)), enabled, newUser{std::string(*newUserName)},
locked, userSelf, req, accountTypes(std::move(accountTypes))](
const boost::system::error_code& ec, sdbusplus::message_t& m) {
- if (ec)
- {
- userErrorMessageHandler(m.get_error(), asyncResp, newUser,
- username);
- return;
- }
+ if (ec)
+ {
+ userErrorMessageHandler(m.get_error(), asyncResp, newUser,
+ username);
+ return;
+ }
- updateUserProperties(asyncResp, newUser, password, enabled, roleId,
- locked, accountTypes, userSelf, req.session);
- },
+ updateUserProperties(asyncResp, newUser, password, enabled, roleId,
+ locked, accountTypes, userSelf, req.session);
+ },
"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
"xyz.openbmc_project.User.Manager", "RenameUser", username,
*newUserName);
diff --git a/redfish-core/lib/bios.hpp b/redfish-core/lib/bios.hpp
index 1ec967b6eb..ee922af854 100644
--- a/redfish-core/lib/bios.hpp
+++ b/redfish-core/lib/bios.hpp
@@ -91,13 +91,13 @@ inline void
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Failed to reset bios: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Failed to reset bios: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ },
"org.open_power.Software.Host.Updater", "/xyz/openbmc_project/software",
"xyz.openbmc_project.Common.FactoryReset", "Reset");
}
diff --git a/redfish-core/lib/cable.hpp b/redfish-core/lib/cable.hpp
index bc73267101..27ee276a55 100644
--- a/redfish-core/lib/cable.hpp
+++ b/redfish-core/lib/cable.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "dbus_utility.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
@@ -23,10 +24,9 @@ namespace redfish
* @param[in] ec Error code corresponding to Async method call.
* @param[in] properties List of Cable Properties key/value pairs.
*/
-inline void
- fillCableProperties(crow::Response& resp,
- const boost::system::error_code& ec,
- const dbus::utility::DBusPropertiesMap& properties)
+inline void fillCableProperties(
+ crow::Response& resp, const boost::system::error_code& ec,
+ const dbus::utility::DBusPropertiesMap& properties)
{
if (ec)
{
@@ -97,8 +97,8 @@ inline void
[asyncResp](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- fillCableProperties(asyncResp->res, ec, properties);
- });
+ fillCableProperties(asyncResp->res, ec, properties);
+ });
}
else if (interface == "xyz.openbmc_project.Inventory.Item")
{
@@ -107,23 +107,24 @@ inline void
interface, "Present",
[asyncResp, cableObjectPath](
const boost::system::error_code& ec, bool present) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG(
- "get presence failed for Cable {} with error {}",
- cableObjectPath, ec);
- if (ec.value() != EBADR)
+ if (ec)
{
- messages::internalError(asyncResp->res);
+ BMCWEB_LOG_DEBUG(
+ "get presence failed for Cable {} with error {}",
+ cableObjectPath, ec);
+ if (ec.value() != EBADR)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ return;
+ }
+
+ if (!present)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
}
- return;
- }
-
- if (!present)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- }
- });
+ });
}
}
}
@@ -140,52 +141,59 @@ inline void requestRoutesCable(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& cableId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- BMCWEB_LOG_DEBUG("Cable Id: {}", cableId);
- constexpr std::array<std::string_view, 1> interfaces = {
- "xyz.openbmc_project.Inventory.Item.Cable"};
- dbus::utility::getSubTree(
- "/xyz/openbmc_project/inventory", 0, interfaces,
- [asyncResp,
- cableId](const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec.value() == EBADR)
- {
- messages::resourceNotFound(asyncResp->res, "Cable", cableId);
- return;
- }
-
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- for (const auto& [objectPath, serviceMap] : subtree)
- {
- sdbusplus::message::object_path path(objectPath);
- if (path.filename() != cableId)
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- continue;
+ return;
}
+ BMCWEB_LOG_DEBUG("Cable Id: {}", cableId);
+ constexpr std::array<std::string_view, 1> interfaces = {
+ "xyz.openbmc_project.Inventory.Item.Cable"};
+ dbus::utility::getSubTree(
+ "/xyz/openbmc_project/inventory", 0, interfaces,
+ [asyncResp,
+ cableId](const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreeResponse&
+ subtree) {
+ if (ec.value() == EBADR)
+ {
+ messages::resourceNotFound(asyncResp->res, "Cable",
+ cableId);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/Cables/{}", cableId);
- asyncResp->res.jsonValue["Id"] = cableId;
- asyncResp->res.jsonValue["Name"] = "Cable";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- getCableProperties(asyncResp, objectPath, serviceMap);
- return;
- }
- messages::resourceNotFound(asyncResp->res, "Cable", cableId);
- });
- });
+ for (const auto& [objectPath, serviceMap] : subtree)
+ {
+ sdbusplus::message::object_path path(objectPath);
+ if (path.filename() != cableId)
+ {
+ continue;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Cable.v1_0_0.Cable";
+ asyncResp->res.jsonValue["@odata.id"] =
+ boost::urls::format("/redfish/v1/Cables/{}",
+ cableId);
+ asyncResp->res.jsonValue["Id"] = cableId;
+ asyncResp->res.jsonValue["Name"] = "Cable";
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+
+ getCableProperties(asyncResp, objectPath,
+ serviceMap);
+ return;
+ }
+ messages::resourceNotFound(asyncResp->res, "Cable",
+ cableId);
+ });
+ });
}
/**
@@ -198,21 +206,22 @@ inline void requestRoutesCableCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#CableCollection.CableCollection";
- asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
- asyncResp->res.jsonValue["Name"] = "Cable Collection";
- asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
- constexpr std::array<std::string_view, 1> interfaces{
- "xyz.openbmc_project.Inventory.Item.Cable"};
- collection_util::getCollectionMembers(
- asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces,
- "/xyz/openbmc_project/inventory");
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#CableCollection.CableCollection";
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
+ asyncResp->res.jsonValue["Name"] = "Cable Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of Cable Entries";
+ constexpr std::array<std::string_view, 1> interfaces{
+ "xyz.openbmc_project.Inventory.Item.Cable"};
+ collection_util::getCollectionMembers(
+ asyncResp, boost::urls::url("/redfish/v1/Cables"),
+ interfaces, "/xyz/openbmc_project/inventory");
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/certificate_service.hpp b/redfish-core/lib/certificate_service.hpp
index af35450ab7..7ae194cdf2 100644
--- a/redfish-core/lib/certificate_service.hpp
+++ b/redfish-core/lib/certificate_service.hpp
@@ -106,9 +106,9 @@ class CertificateFile
{
certDirectory = tempDirectory;
certificateFile = certDirectory / "cert.pem";
- std::ofstream out(certificateFile, std::ofstream::out |
- std::ofstream::binary |
- std::ofstream::trunc);
+ std::ofstream out(certificateFile,
+ std::ofstream::out | std::ofstream::binary |
+ std::ofstream::trunc);
out << certString;
out.close();
BMCWEB_LOG_DEBUG("Creating certificate file{}",
@@ -148,7 +148,7 @@ class CertificateFile
* @param[in] type Issuer/Subject
* @return None
*/
-static void updateCertIssuerOrSubject(nlohmann::json& out,
+inline void updateCertIssuerOrSubject(nlohmann::json& out,
std::string_view value)
{
// example: O=openbmc-project.xyz,CN=localhost
@@ -213,11 +213,10 @@ static void updateCertIssuerOrSubject(nlohmann::json& out,
* @param[in] countPtr Json pointer to the count in asyncResp
* @return None
*/
-static void
- getCertificateList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& basePath,
- const nlohmann::json::json_pointer& listPtr,
- const nlohmann::json::json_pointer& countPtr)
+inline void getCertificateList(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& basePath, const nlohmann::json::json_pointer& listPtr,
+ const nlohmann::json::json_pointer& countPtr)
{
constexpr std::array<std::string_view, 1> interfaces = {
certs::certPropIntf};
@@ -226,55 +225,57 @@ static void
[asyncResp, listPtr, countPtr](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& certPaths) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Certificate collection query failed: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- nlohmann::json& links = asyncResp->res.jsonValue[listPtr];
- links = nlohmann::json::array();
- for (const auto& certPath : certPaths)
- {
- sdbusplus::message::object_path objPath(certPath);
- std::string certId = objPath.filename();
- if (certId.empty())
+ if (ec)
{
- BMCWEB_LOG_ERROR("Invalid certificate objPath {}", certPath);
- continue;
+ BMCWEB_LOG_ERROR("Certificate collection query failed: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
}
- boost::urls::url certURL;
- if (objPath.parent_path() == certs::httpsObjectPath)
+ nlohmann::json& links = asyncResp->res.jsonValue[listPtr];
+ links = nlohmann::json::array();
+ for (const auto& certPath : certPaths)
{
- certURL = boost::urls::format(
- "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
+ sdbusplus::message::object_path objPath(certPath);
+ std::string certId = objPath.filename();
+ if (certId.empty())
+ {
+ BMCWEB_LOG_ERROR("Invalid certificate objPath {}",
+ certPath);
+ continue;
+ }
+
+ boost::urls::url certURL;
+ if (objPath.parent_path() == certs::httpsObjectPath)
+ {
+ certURL = boost::urls::format(
+ "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
+ }
+ else if (objPath.parent_path() == certs::ldapObjectPath)
+ {
+ certURL = boost::urls::format(
+ "/redfish/v1/AccountService/LDAP/Certificates/{}",
+ certId);
+ }
+ else if (objPath.parent_path() == certs::authorityObjectPath)
+ {
+ certURL = boost::urls::format(
+ "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
+ }
+ else
+ {
+ continue;
+ }
+
+ nlohmann::json::object_t link;
+ link["@odata.id"] = certURL;
+ links.emplace_back(std::move(link));
}
- else if (objPath.parent_path() == certs::ldapObjectPath)
- {
- certURL = boost::urls::format(
- "/redfish/v1/AccountService/LDAP/Certificates/{}", certId);
- }
- else if (objPath.parent_path() == certs::authorityObjectPath)
- {
- certURL = boost::urls::format(
- "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
- }
- else
- {
- continue;
- }
-
- nlohmann::json::object_t link;
- link["@odata.id"] = certURL;
- links.emplace_back(std::move(link));
- }
- asyncResp->res.jsonValue[countPtr] = links.size();
- });
+ asyncResp->res.jsonValue[countPtr] = links.size();
+ });
}
/**
@@ -288,7 +289,7 @@ static void
* @param[in] name name of the certificate
* @return None
*/
-static void getCertificateProperties(
+inline void getCertificateProperties(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& objectPath, const std::string& service,
const std::string& certId, const boost::urls::url& certURL,
@@ -301,82 +302,84 @@ static void getCertificateProperties(
[asyncResp, certURL, certId,
name](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- messages::resourceNotFound(asyncResp->res, "Certificate", certId);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ messages::resourceNotFound(asyncResp->res, "Certificate",
+ certId);
+ return;
+ }
- const std::string* certificateString = nullptr;
- const std::vector<std::string>* keyUsage = nullptr;
- const std::string* issuer = nullptr;
- const std::string* subject = nullptr;
- const uint64_t* validNotAfter = nullptr;
- const uint64_t* validNotBefore = nullptr;
+ const std::string* certificateString = nullptr;
+ const std::vector<std::string>* keyUsage = nullptr;
+ const std::string* issuer = nullptr;
+ const std::string* subject = nullptr;
+ const uint64_t* validNotAfter = nullptr;
+ const uint64_t* validNotBefore = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "CertificateString",
- certificateString, "KeyUsage", keyUsage, "Issuer", issuer,
- "Subject", subject, "ValidNotAfter", validNotAfter,
- "ValidNotBefore", validNotBefore);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties,
+ "CertificateString", certificateString, "KeyUsage", keyUsage,
+ "Issuer", issuer, "Subject", subject, "ValidNotAfter",
+ validNotAfter, "ValidNotBefore", validNotBefore);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.id"] = certURL;
- asyncResp->res.jsonValue["@odata.type"] =
- "#Certificate.v1_0_0.Certificate";
- asyncResp->res.jsonValue["Id"] = certId;
- asyncResp->res.jsonValue["Name"] = name;
- asyncResp->res.jsonValue["Description"] = name;
- asyncResp->res.jsonValue["CertificateString"] = "";
- asyncResp->res.jsonValue["KeyUsage"] = nlohmann::json::array();
+ asyncResp->res.jsonValue["@odata.id"] = certURL;
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Certificate.v1_0_0.Certificate";
+ asyncResp->res.jsonValue["Id"] = certId;
+ asyncResp->res.jsonValue["Name"] = name;
+ asyncResp->res.jsonValue["Description"] = name;
+ asyncResp->res.jsonValue["CertificateString"] = "";
+ asyncResp->res.jsonValue["KeyUsage"] = nlohmann::json::array();
- if (certificateString != nullptr)
- {
- asyncResp->res.jsonValue["CertificateString"] = *certificateString;
- }
+ if (certificateString != nullptr)
+ {
+ asyncResp->res.jsonValue["CertificateString"] =
+ *certificateString;
+ }
- if (keyUsage != nullptr)
- {
- asyncResp->res.jsonValue["KeyUsage"] = *keyUsage;
- }
+ if (keyUsage != nullptr)
+ {
+ asyncResp->res.jsonValue["KeyUsage"] = *keyUsage;
+ }
- if (issuer != nullptr)
- {
- updateCertIssuerOrSubject(asyncResp->res.jsonValue["Issuer"],
- *issuer);
- }
+ if (issuer != nullptr)
+ {
+ updateCertIssuerOrSubject(asyncResp->res.jsonValue["Issuer"],
+ *issuer);
+ }
- if (subject != nullptr)
- {
- updateCertIssuerOrSubject(asyncResp->res.jsonValue["Subject"],
- *subject);
- }
+ if (subject != nullptr)
+ {
+ updateCertIssuerOrSubject(asyncResp->res.jsonValue["Subject"],
+ *subject);
+ }
- if (validNotAfter != nullptr)
- {
- asyncResp->res.jsonValue["ValidNotAfter"] =
- redfish::time_utils::getDateTimeUint(*validNotAfter);
- }
+ if (validNotAfter != nullptr)
+ {
+ asyncResp->res.jsonValue["ValidNotAfter"] =
+ redfish::time_utils::getDateTimeUint(*validNotAfter);
+ }
- if (validNotBefore != nullptr)
- {
- asyncResp->res.jsonValue["ValidNotBefore"] =
- redfish::time_utils::getDateTimeUint(*validNotBefore);
- }
+ if (validNotBefore != nullptr)
+ {
+ asyncResp->res.jsonValue["ValidNotBefore"] =
+ redfish::time_utils::getDateTimeUint(*validNotBefore);
+ }
- asyncResp->res.addHeader(
- boost::beast::http::field::location,
- std::string_view(certURL.data(), certURL.size()));
- });
+ asyncResp->res.addHeader(
+ boost::beast::http::field::location,
+ std::string_view(certURL.data(), certURL.size()));
+ });
}
-static void
+inline void
deleteCertificate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& service,
const sdbusplus::message::object_path& objectPath)
@@ -384,14 +387,14 @@ static void
crow::connections::systemBus->async_method_call(
[asyncResp,
id{objectPath.filename()}](const boost::system::error_code& ec) {
- if (ec)
- {
- messages::resourceNotFound(asyncResp->res, "Certificate", id);
- return;
- }
- BMCWEB_LOG_INFO("Certificate deleted");
- asyncResp->res.result(boost::beast::http::status::no_content);
- },
+ if (ec)
+ {
+ messages::resourceNotFound(asyncResp->res, "Certificate", id);
+ return;
+ }
+ BMCWEB_LOG_INFO("Certificate deleted");
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ },
service, objectPath, certs::objDeleteIntf, "Delete");
}
@@ -462,6 +465,26 @@ inline void handleCertificateLocationsGet(
"/Links/Certificates@odata.count"_json_pointer);
}
+inline void handleError(const std::string_view dbusErrorName,
+ const std::string& id, const std::string& certificate,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (dbusErrorName == "org.freedesktop.DBus.Error.UnknownObject")
+ {
+ messages::resourceNotFound(asyncResp->res, "Certificate", id);
+ }
+ else if (dbusErrorName ==
+ "xyz.openbmc_project.Certs.Error.InvalidCertificate")
+ {
+ messages::propertyValueIncorrect(asyncResp->res, "Certificate",
+ certificate);
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ }
+}
+
inline void handleReplaceCertificateAction(
App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
@@ -546,24 +569,28 @@ inline void handleReplaceCertificateAction(
std::shared_ptr<CertificateFile> certFile =
std::make_shared<CertificateFile>(certificate);
crow::connections::systemBus->async_method_call(
- [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id,
- name](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- if (ec.value() ==
- boost::system::linux_error::bad_request_descriptor)
+ [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id, name,
+ certificate](const boost::system::error_code& ec,
+ sdbusplus::message_t& m) {
+ if (ec)
{
- messages::resourceNotFound(asyncResp->res, "Certificate", id);
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ const sd_bus_error* dbusError = m.get_error();
+ if ((dbusError != nullptr) && (dbusError->name != nullptr))
+ {
+ handleError(dbusError->name, id, certificate, asyncResp);
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ }
return;
}
- messages::internalError(asyncResp->res);
- return;
- }
- getCertificateProperties(asyncResp, objectPath, service, id, url, name);
- BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
- certFile->getCertFilePath());
- },
+ getCertificateProperties(asyncResp, objectPath, service, id, url,
+ name);
+ BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
+ certFile->getCertFilePath());
+ },
service, objectPath, certs::certReplaceIntf, "Replace",
certFile->getCertFilePath());
}
@@ -580,7 +607,7 @@ static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
* @param[in] csrObjPath CSR D-Bus object path
* @return None
*/
-static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+inline void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& certURI, const std::string& service,
const std::string& certObjPath,
const std::string& csrObjPath)
@@ -588,24 +615,24 @@ static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
BMCWEB_LOG_DEBUG("getCSR CertObjectPath{} CSRObjectPath={} service={}",
certObjPath, csrObjPath, service);
crow::connections::systemBus->async_method_call(
- [asyncResp, certURI](const boost::system::error_code& ec,
- const std::string& csr) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- if (csr.empty())
- {
- BMCWEB_LOG_ERROR("CSR read is empty");
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["CSRString"] = csr;
- asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
- certURI;
- },
+ [asyncResp,
+ certURI](const boost::system::error_code& ec, const std::string& csr) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (csr.empty())
+ {
+ BMCWEB_LOG_ERROR("CSR read is empty");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["CSRString"] = csr;
+ asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
+ certURI;
+ },
service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
}
@@ -804,38 +831,38 @@ inline void
csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
*crow::connections::systemBus, match,
[asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
- timeout.cancel();
- if (m.is_method_error())
- {
- BMCWEB_LOG_ERROR("Dbus method error!!!");
- messages::internalError(asyncResp->res);
- return;
- }
+ timeout.cancel();
+ if (m.is_method_error())
+ {
+ BMCWEB_LOG_ERROR("Dbus method error!!!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- dbus::utility::DBusInterfacesMap interfacesProperties;
+ dbus::utility::DBusInterfacesMap interfacesProperties;
- sdbusplus::message::object_path csrObjectPath;
- m.read(csrObjectPath, interfacesProperties);
- BMCWEB_LOG_DEBUG("CSR object added{}", csrObjectPath.str);
- for (const auto& interface : interfacesProperties)
- {
- if (interface.first == "xyz.openbmc_project.Certs.CSR")
+ sdbusplus::message::object_path csrObjectPath;
+ m.read(csrObjectPath, interfacesProperties);
+ BMCWEB_LOG_DEBUG("CSR object added{}", csrObjectPath.str);
+ for (const auto& interface : interfacesProperties)
{
- getCSR(asyncResp, certURI, service, objectPath,
- csrObjectPath.str);
- break;
+ if (interface.first == "xyz.openbmc_project.Certs.CSR")
+ {
+ getCSR(asyncResp, certURI, service, objectPath,
+ csrObjectPath.str);
+ break;
+ }
}
- }
- });
+ });
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec, const std::string&) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ },
service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
"GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
commonName, *optContactPerson, country, *optEmail, *optGivenName,
@@ -937,23 +964,24 @@ inline void handleHTTPSCertificateCollectionPost(
crow::connections::systemBus->async_method_call(
[asyncResp, certFile](const boost::system::error_code& ec,
const std::string& objectPath) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- sdbusplus::message::object_path path(objectPath);
- std::string certId = path.filename();
- const boost::urls::url certURL = boost::urls::format(
- "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
- getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName,
- certId, certURL, "HTTPS Certificate");
- BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
- certFile->getCertFilePath());
- },
+ sdbusplus::message::object_path path(objectPath);
+ std::string certId = path.filename();
+ const boost::urls::url certURL = boost::urls::format(
+ "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
+ getCertificateProperties(asyncResp, objectPath,
+ certs::httpsServiceName, certId, certURL,
+ "HTTPS Certificate");
+ BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
+ certFile->getCertFilePath());
+ },
certs::httpsServiceName, certs::httpsObjectPath, certs::certInstallIntf,
"Install", certFile->getCertFilePath());
}
@@ -1051,22 +1079,23 @@ inline void handleLDAPCertificateCollectionPost(
crow::connections::systemBus->async_method_call(
[asyncResp, certFile](const boost::system::error_code& ec,
const std::string& objectPath) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- sdbusplus::message::object_path path(objectPath);
- std::string certId = path.filename();
- const boost::urls::url certURL = boost::urls::format(
- "/redfish/v1/AccountService/LDAP/Certificates/{}", certId);
- getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName,
- certId, certURL, "LDAP Certificate");
- BMCWEB_LOG_DEBUG("LDAP certificate install file={}",
- certFile->getCertFilePath());
- },
+ sdbusplus::message::object_path path(objectPath);
+ std::string certId = path.filename();
+ const boost::urls::url certURL = boost::urls::format(
+ "/redfish/v1/AccountService/LDAP/Certificates/{}", certId);
+ getCertificateProperties(asyncResp, objectPath,
+ certs::ldapServiceName, certId, certURL,
+ "LDAP Certificate");
+ BMCWEB_LOG_DEBUG("LDAP certificate install file={}",
+ certFile->getCertFilePath());
+ },
certs::ldapServiceName, certs::ldapObjectPath, certs::certInstallIntf,
"Install", certFile->getCertFilePath());
}
@@ -1188,24 +1217,24 @@ inline void handleTrustStoreCertificateCollectionPost(
crow::connections::systemBus->async_method_call(
[asyncResp, certFile](const boost::system::error_code& ec,
const std::string& objectPath) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- sdbusplus::message::object_path path(objectPath);
- std::string certId = path.filename();
- const boost::urls::url certURL = boost::urls::format(
- "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
- getCertificateProperties(asyncResp, objectPath,
- certs::authorityServiceName, certId, certURL,
- "TrustStore Certificate");
- BMCWEB_LOG_DEBUG("TrustStore certificate install file={}",
- certFile->getCertFilePath());
- },
+ sdbusplus::message::object_path path(objectPath);
+ std::string certId = path.filename();
+ const boost::urls::url certURL = boost::urls::format(
+ "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
+ getCertificateProperties(asyncResp, objectPath,
+ certs::authorityServiceName, certId,
+ certURL, "TrustStore Certificate");
+ BMCWEB_LOG_DEBUG("TrustStore certificate install file={}",
+ certFile->getCertFilePath());
+ },
certs::authorityServiceName, certs::authorityObjectPath,
certs::certInstallIntf, "Install", certFile->getCertFilePath());
}
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index 723cc1e411..a993b016bc 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -1,22 +1,25 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/action_info.hpp"
+#include "generated/enums/chassis.hpp"
+#include "generated/enums/resource.hpp"
#include "led.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
@@ -59,32 +62,32 @@ inline void getStorageLink(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
(path / "storage").str, "xyz.openbmc_project.Association", "endpoints",
[asyncResp](const boost::system::error_code& ec,
const std::vector<std::string>& storageList) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("getStorageLink got DBUS response error");
- return;
- }
-
- nlohmann::json::array_t storages;
- for (const std::string& storagePath : storageList)
- {
- std::string id =
- sdbusplus::message::object_path(storagePath).filename();
- if (id.empty())
+ if (ec)
{
- continue;
+ BMCWEB_LOG_DEBUG("getStorageLink got DBUS response error");
+ return;
}
- nlohmann::json::object_t storage;
- storage["@odata.id"] =
- boost::urls::format("/redfish/v1/Systems/{}/Storage/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, id);
- storages.emplace_back(std::move(storage));
- }
- asyncResp->res.jsonValue["Links"]["Storage@odata.count"] =
- storages.size();
- asyncResp->res.jsonValue["Links"]["Storage"] = std::move(storages);
- });
+ nlohmann::json::array_t storages;
+ for (const std::string& storagePath : storageList)
+ {
+ std::string id =
+ sdbusplus::message::object_path(storagePath).filename();
+ if (id.empty())
+ {
+ continue;
+ }
+
+ nlohmann::json::object_t storage;
+ storage["@odata.id"] =
+ boost::urls::format("/redfish/v1/Systems/{}/Storage/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, id);
+ storages.emplace_back(std::move(storage));
+ }
+ asyncResp->res.jsonValue["Links"]["Storage@odata.count"] =
+ storages.size();
+ asyncResp->res.jsonValue["Links"]["Storage"] = std::move(storages);
+ });
}
/**
@@ -103,34 +106,39 @@ inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
"xyz.openbmc_project.State.Chassis", "CurrentPowerState",
[asyncResp{std::move(asyncResp)}](const boost::system::error_code& ec,
const std::string& chassisState) {
- if (ec)
- {
- if (ec == boost::system::errc::host_unreachable)
+ if (ec)
{
- // Service not available, no error, just don't return
- // chassis state info
- BMCWEB_LOG_DEBUG("Service not available {}", ec);
+ if (ec == boost::system::errc::host_unreachable)
+ {
+ // Service not available, no error, just don't return
+ // chassis state info
+ BMCWEB_LOG_DEBUG("Service not available {}", ec);
+ return;
+ }
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG("Chassis state: {}", chassisState);
- // Verify Chassis State
- if (chassisState == "xyz.openbmc_project.State.Chassis.PowerState.On")
- {
- asyncResp->res.jsonValue["PowerState"] = "On";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- }
- else if (chassisState ==
- "xyz.openbmc_project.State.Chassis.PowerState.Off")
- {
- asyncResp->res.jsonValue["PowerState"] = "Off";
- asyncResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
- }
- });
+ BMCWEB_LOG_DEBUG("Chassis state: {}", chassisState);
+ // Verify Chassis State
+ if (chassisState ==
+ "xyz.openbmc_project.State.Chassis.PowerState.On")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::On;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+ }
+ else if (chassisState ==
+ "xyz.openbmc_project.State.Chassis.PowerState.Off")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::Off;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::StandbyOffline;
+ }
+ });
}
/**
@@ -162,19 +170,20 @@ inline void handlePhysicalSecurityGetSubTree(
"xyz.openbmc_project.Chassis.Intrusion", "Status",
[asyncResp](const boost::system::error_code& ec1,
const std::string& value) {
- if (ec1)
- {
- // do not add err msg in redfish response, because this is
- // not
- // mandatory property
- BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
- return;
- }
- asyncResp->res
- .jsonValue["PhysicalSecurity"]["IntrusionSensorNumber"] = 1;
- asyncResp->res
- .jsonValue["PhysicalSecurity"]["IntrusionSensor"] = value;
- });
+ if (ec1)
+ {
+ // do not add err msg in redfish response, because this
+ // is not
+ // mandatory property
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
+ return;
+ }
+ asyncResp->res.jsonValue["PhysicalSecurity"]
+ ["IntrusionSensorNumber"] = 1;
+ asyncResp->res
+ .jsonValue["PhysicalSecurity"]["IntrusionSensor"] =
+ value;
+ });
return;
}
@@ -205,7 +214,7 @@ inline void handleChassisCollectionGet(
inline void getChassisContainedBy(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& chassisId, const boost::system::error_code& ec,
- const dbus::utility::MapperEndPoints& upstreamChassisPaths)
+ const dbus::utility::MapperGetSubTreePathsResponse& upstreamChassisPaths)
{
if (ec)
{
@@ -244,7 +253,7 @@ inline void getChassisContainedBy(
inline void getChassisContains(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& chassisId, const boost::system::error_code& ec,
- const dbus::utility::MapperEndPoints& downstreamChassisPaths)
+ const dbus::utility::MapperGetSubTreePathsResponse& downstreamChassisPaths)
{
if (ec)
{
@@ -276,27 +285,33 @@ inline void getChassisContains(
continue;
}
nlohmann::json link;
- link["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
- downstreamChassis);
+ link["@odata.id"] =
+ boost::urls::format("/redfish/v1/Chassis/{}", downstreamChassis);
jValue.push_back(std::move(link));
}
asyncResp->res.jsonValue["Links"]["Contains@odata.count"] = jValue.size();
}
-inline void
- getChassisConnectivity(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId,
- const std::string& chassisPath)
+inline void getChassisConnectivity(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const std::string& chassisPath)
{
BMCWEB_LOG_DEBUG("Get chassis connectivity");
- dbus::utility::getAssociationEndPoints(
+ constexpr std::array<std::string_view, 2> interfaces{
+ "xyz.openbmc_project.Inventory.Item.Board",
+ "xyz.openbmc_project.Inventory.Item.Chassis"};
+
+ dbus::utility::getAssociatedSubTreePaths(
chassisPath + "/contained_by",
+ sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
+ interfaces,
std::bind_front(getChassisContainedBy, asyncResp, chassisId));
- dbus::utility::getAssociationEndPoints(
+ dbus::utility::getAssociatedSubTreePaths(
chassisPath + "/containing",
- std::bind_front(getChassisContains, asyncResp, chassisId));
+ sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
+ interfaces, std::bind_front(getChassisContains, asyncResp, chassisId));
}
/**
@@ -311,26 +326,26 @@ inline void requestRoutesChassisCollection(App& app)
std::bind_front(handleChassisCollectionGet, std::ref(app)));
}
-inline void
- getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& connectionName,
- const std::string& path)
+inline void getChassisLocationCode(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& connectionName, const std::string& path)
{
sdbusplus::asio::getProperty<std::string>(
*crow::connections::systemBus, connectionName, path,
"xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
[asyncResp](const boost::system::error_code& ec,
const std::string& property) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error for Location");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Location");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
- property;
- });
+ asyncResp->res
+ .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+ property;
+ });
}
inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -342,14 +357,14 @@ inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
"xyz.openbmc_project.Common.UUID", "UUID",
[asyncResp](const boost::system::error_code& ec,
const std::string& chassisUUID) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error for UUID");
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["UUID"] = chassisUUID;
- });
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for UUID");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["UUID"] = chassisUUID;
+ });
}
inline void handleDecoratorAssetProperties(
@@ -428,12 +443,12 @@ inline void handleDecoratorAssetProperties(
// SensorCollection
asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
boost::urls::format("/redfish/v1/Chassis/{}/Sensors", chassisId);
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
nlohmann::json::array_t computerSystems;
nlohmann::json::object_t system;
- system["@odata.id"] = std::format("/redfish/v1/Systems/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ system["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
computerSystems.emplace_back(std::move(system));
asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
std::move(computerSystems);
@@ -487,7 +502,8 @@ inline void handleChassisGetSubTree(
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
asyncResp->res.jsonValue["Name"] = "Chassis Collection";
- asyncResp->res.jsonValue["ChassisType"] = "RackMount";
+ asyncResp->res.jsonValue["ChassisType"] =
+ chassis::ChassisType::RackMount;
asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] =
boost::urls::format("/redfish/v1/Chassis/{}/Actions/Chassis.Reset",
chassisId);
@@ -499,16 +515,16 @@ inline void handleChassisGetSubTree(
path + "/drive",
[asyncResp, chassisId](const boost::system::error_code& ec3,
const dbus::utility::MapperEndPoints& resp) {
- if (ec3 || resp.empty())
- {
- return; // no drives = no failures
- }
+ if (ec3 || resp.empty())
+ {
+ return; // no drives = no failures
+ }
- nlohmann::json reference;
- reference["@odata.id"] =
- boost::urls::format("/redfish/v1/Chassis/{}/Drives", chassisId);
- asyncResp->res.jsonValue["Drives"] = std::move(reference);
- });
+ nlohmann::json reference;
+ reference["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}/Drives", chassisId);
+ asyncResp->res.jsonValue["Drives"] = std::move(reference);
+ });
const std::string& connectionName = connectionNames[0].first;
@@ -533,15 +549,15 @@ inline void handleChassisGetSubTree(
assetTagInterface, "AssetTag",
[asyncResp, chassisId](const boost::system::error_code& ec2,
const std::string& property) {
- if (ec2)
- {
- BMCWEB_LOG_ERROR("DBus response error for AssetTag: {}",
- ec2);
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["AssetTag"] = property;
- });
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBus response error for AssetTag: {}", ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["AssetTag"] = property;
+ });
}
else if (interface == replaceableInterface)
{
@@ -550,15 +566,16 @@ inline void handleChassisGetSubTree(
replaceableInterface, "HotPluggable",
[asyncResp, chassisId](const boost::system::error_code& ec2,
const bool property) {
- if (ec2)
- {
- BMCWEB_LOG_ERROR(
- "DBus response error for HotPluggable: {}", ec2);
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["HotPluggable"] = property;
- });
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBus response error for HotPluggable: {}",
+ ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["HotPluggable"] = property;
+ });
}
else if (interface == revisionInterface)
{
@@ -567,15 +584,15 @@ inline void handleChassisGetSubTree(
revisionInterface, "Version",
[asyncResp, chassisId](const boost::system::error_code& ec2,
const std::string& property) {
- if (ec2)
- {
- BMCWEB_LOG_ERROR("DBus response error for Version: {}",
- ec2);
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["Version"] = property;
- });
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBus response error for Version: {}", ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["Version"] = property;
+ });
}
}
@@ -595,9 +612,9 @@ inline void handleChassisGetSubTree(
[asyncResp, chassisId,
path](const boost::system::error_code&,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- handleDecoratorAssetProperties(asyncResp, chassisId, path,
- propertiesList);
- });
+ handleDecoratorAssetProperties(asyncResp, chassisId, path,
+ propertiesList);
+ });
for (const auto& interface : interfaces2)
{
@@ -691,81 +708,83 @@ inline void
[asyncResp, chassisId, locationIndicatorActive,
indicatorLed](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Iterate over all retrieved ObjectPaths.
- for (const std::pair<
- std::string,
- std::vector<std::pair<std::string, std::vector<std::string>>>>&
- object : subtree)
- {
- const std::string& path = object.first;
- const std::vector<std::pair<std::string, std::vector<std::string>>>&
- connectionNames = object.second;
-
- sdbusplus::message::object_path objPath(path);
- if (objPath.filename() != chassisId)
+ if (ec)
{
- continue;
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
}
- if (connectionNames.empty())
+ // Iterate over all retrieved ObjectPaths.
+ for (const std::pair<std::string,
+ std::vector<std::pair<
+ std::string, std::vector<std::string>>>>&
+ object : subtree)
{
- BMCWEB_LOG_ERROR("Got 0 Connection names");
- continue;
- }
-
- const std::vector<std::string>& interfaces3 =
- connectionNames[0].second;
+ const std::string& path = object.first;
+ const std::vector<
+ std::pair<std::string, std::vector<std::string>>>&
+ connectionNames = object.second;
- const std::array<const char*, 3> hasIndicatorLed = {
- "xyz.openbmc_project.Inventory.Item.Chassis",
- "xyz.openbmc_project.Inventory.Item.Panel",
- "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
- bool indicatorChassis = false;
- for (const char* interface : hasIndicatorLed)
- {
- if (std::ranges::find(interfaces3, interface) !=
- interfaces3.end())
+ sdbusplus::message::object_path objPath(path);
+ if (objPath.filename() != chassisId)
{
- indicatorChassis = true;
- break;
+ continue;
}
- }
- if (locationIndicatorActive)
- {
- if (indicatorChassis)
+
+ if (connectionNames.empty())
{
- setSystemLocationIndicatorActive(asyncResp,
- *locationIndicatorActive);
+ BMCWEB_LOG_ERROR("Got 0 Connection names");
+ continue;
}
- else
+
+ const std::vector<std::string>& interfaces3 =
+ connectionNames[0].second;
+
+ const std::array<const char*, 3> hasIndicatorLed = {
+ "xyz.openbmc_project.Inventory.Item.Chassis",
+ "xyz.openbmc_project.Inventory.Item.Panel",
+ "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
+ bool indicatorChassis = false;
+ for (const char* interface : hasIndicatorLed)
{
- messages::propertyUnknown(asyncResp->res,
- "LocationIndicatorActive");
+ if (std::ranges::find(interfaces3, interface) !=
+ interfaces3.end())
+ {
+ indicatorChassis = true;
+ break;
+ }
}
- }
- if (indicatorLed)
- {
- if (indicatorChassis)
+ if (locationIndicatorActive)
{
- setIndicatorLedState(asyncResp, *indicatorLed);
+ if (indicatorChassis)
+ {
+ setSystemLocationIndicatorActive(
+ asyncResp, *locationIndicatorActive);
+ }
+ else
+ {
+ messages::propertyUnknown(asyncResp->res,
+ "LocationIndicatorActive");
+ }
}
- else
+ if (indicatorLed)
{
- messages::propertyUnknown(asyncResp->res, "IndicatorLED");
+ if (indicatorChassis)
+ {
+ setIndicatorLedState(asyncResp, *indicatorLed);
+ }
+ else
+ {
+ messages::propertyUnknown(asyncResp->res,
+ "IndicatorLED");
+ }
}
+ return;
}
- return;
- }
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
- });
+ messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+ });
}
/**
@@ -797,32 +816,34 @@ inline void
[asyncResp](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("[mapper] Bad D-Bus request error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- const char* processName = "xyz.openbmc_project.State.Chassis";
- const char* interfaceName = "xyz.openbmc_project.State.Chassis";
- const char* destProperty = "RequestedPowerTransition";
- const std::string propertyValue =
- "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
- std::string objectPath = "/xyz/openbmc_project/state/chassis_system0";
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("[mapper] Bad D-Bus request error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- /* Look for system reset chassis path */
- if ((std::ranges::find(chassisList, objectPath)) == chassisList.end())
- {
- /* We prefer to reset the full chassis_system, but if it doesn't
- * exist on some platforms, fall back to a host-only power reset
- */
- objectPath = "/xyz/openbmc_project/state/chassis0";
- }
+ const char* processName = "xyz.openbmc_project.State.Chassis";
+ const char* interfaceName = "xyz.openbmc_project.State.Chassis";
+ const char* destProperty = "RequestedPowerTransition";
+ const std::string propertyValue =
+ "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
+ std::string objectPath =
+ "/xyz/openbmc_project/state/chassis_system0";
+
+ /* Look for system reset chassis path */
+ if ((std::ranges::find(chassisList, objectPath)) ==
+ chassisList.end())
+ {
+ /* We prefer to reset the full chassis_system, but if it doesn't
+ * exist on some platforms, fall back to a host-only power reset
+ */
+ objectPath = "/xyz/openbmc_project/state/chassis0";
+ }
- setDbusProperty(asyncResp, "ResetType", processName, objectPath,
- interfaceName, destProperty, propertyValue);
- });
+ setDbusProperty(asyncResp, "ResetType", processName, objectPath,
+ interfaceName, destProperty, propertyValue);
+ });
}
inline void handleChassisResetActionInfoPost(
@@ -888,7 +909,7 @@ inline void handleChassisResetActionInfoGet(
nlohmann::json::object_t parameter;
parameter["Name"] = "ResetType";
parameter["Required"] = true;
- parameter["DataType"] = "String";
+ parameter["DataType"] = action_info::ParameterTypes::String;
nlohmann::json::array_t allowed;
allowed.emplace_back("PowerCycle");
parameter["AllowableValues"] = std::move(allowed);
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index a3cda9ca38..d8c5ae358e 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -19,6 +19,8 @@
#include "dbus_singleton.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
+#include "generated/enums/ethernet_interface.hpp"
+#include "generated/enums/resource.hpp"
#include "human_sort.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
@@ -116,7 +118,7 @@ struct EthernetInterfaceData
std::string defaultGateway;
std::string ipv6DefaultGateway;
std::string ipv6StaticDefaultGateway;
- std::string macAddress;
+ std::optional<std::string> macAddress;
std::optional<uint32_t> vlanId;
std::vector<std::string> nameServers;
std::vector<std::string> staticNameServers;
@@ -178,9 +180,8 @@ inline std::string getDhcpEnabledEnumeration(bool isIPv4, bool isIPv6)
return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none";
}
-inline std::string
- translateAddressOriginDbusToRedfish(const std::string& inputOrigin,
- bool isIPv4)
+inline std::string translateAddressOriginDbusToRedfish(
+ const std::string& inputOrigin, bool isIPv4)
{
if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
{
@@ -393,8 +394,8 @@ inline bool extractEthernetInterfaceData(
sdbusplus::message::object_path path(
"/xyz/openbmc_project/network");
- sdbusplus::message::object_path dhcp4Path = path / ethifaceId /
- "dhcp4";
+ sdbusplus::message::object_path dhcp4Path =
+ path / ethifaceId / "dhcp4";
if (sdbusplus::message::object_path(objpath.first) == dhcp4Path)
{
@@ -443,8 +444,8 @@ inline bool extractEthernetInterfaceData(
}
}
- sdbusplus::message::object_path dhcp6Path = path / ethifaceId /
- "dhcp6";
+ sdbusplus::message::object_path dhcp6Path =
+ path / ethifaceId / "dhcp6";
if (sdbusplus::message::object_path(objpath.first) == dhcp6Path)
{
@@ -520,8 +521,8 @@ inline void extractIPV6Data(const std::string& ethifaceId,
const dbus::utility::ManagedObjectType& dbusData,
std::vector<IPv6AddressData>& ipv6Config)
{
- const std::string ipPathStart = "/xyz/openbmc_project/network/" +
- ethifaceId;
+ const std::string ipPathStart =
+ "/xyz/openbmc_project/network/" + ethifaceId;
// Since there might be several IPv6 configurations aligned with
// single ethernet interface, loop over all of them
@@ -534,10 +535,10 @@ inline void extractIPV6Data(const std::string& ethifaceId,
{
if (interface.first == "xyz.openbmc_project.Network.IP")
{
- auto type = std::ranges::find_if(interface.second,
- [](const auto& property) {
- return property.first == "Type";
- });
+ auto type = std::ranges::find_if(
+ interface.second, [](const auto& property) {
+ return property.first == "Type";
+ });
if (type == interface.second.end())
{
continue;
@@ -612,8 +613,8 @@ inline void extractIPData(const std::string& ethifaceId,
const dbus::utility::ManagedObjectType& dbusData,
std::vector<IPv4AddressData>& ipv4Config)
{
- const std::string ipPathStart = "/xyz/openbmc_project/network/" +
- ethifaceId;
+ const std::string ipPathStart =
+ "/xyz/openbmc_project/network/" + ethifaceId;
// Since there might be several IPv4 configurations aligned with
// single ethernet interface, loop over all of them
@@ -626,10 +627,10 @@ inline void extractIPData(const std::string& ethifaceId,
{
if (interface.first == "xyz.openbmc_project.Network.IP")
{
- auto type = std::ranges::find_if(interface.second,
- [](const auto& property) {
- return property.first == "Type";
- });
+ auto type = std::ranges::find_if(
+ interface.second, [](const auto& property) {
+ return property.first == "Type";
+ });
if (type == interface.second.end())
{
continue;
@@ -743,11 +744,11 @@ inline void deleteIPAddress(const std::string& ifaceId,
{
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- }
- },
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ },
"xyz.openbmc_project.Network",
"/xyz/openbmc_project/network/" + ifaceId + ipHash,
"xyz.openbmc_project.Object.Delete", "Delete");
@@ -768,14 +769,14 @@ inline void createIPv4(const std::string& ifaceId, uint8_t prefixLength,
const std::string& gateway, const std::string& address,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- auto createIpHandler = [asyncResp, ifaceId,
- gateway](const boost::system::error_code& ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- };
+ auto createIpHandler =
+ [asyncResp, ifaceId, gateway](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ };
crow::connections::systemBus->async_method_call(
std::move(createIpHandler), "xyz.openbmc_project.Network",
@@ -808,24 +809,24 @@ inline void deleteAndCreateIPAddress(
crow::connections::systemBus->async_method_call(
[asyncResp, version, ifaceId, address, prefixLength,
gateway](const boost::system::error_code& ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- }
- std::string protocol = "xyz.openbmc_project.Network.IP.Protocol.";
- protocol += version == IpVersion::IpV4 ? "IPv4" : "IPv6";
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code& ec2) {
- if (ec2)
+ if (ec)
{
messages::internalError(asyncResp->res);
}
+ std::string protocol = "xyz.openbmc_project.Network.IP.Protocol.";
+ protocol += version == IpVersion::IpV4 ? "IPv4" : "IPv6";
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code& ec2) {
+ if (ec2)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId,
+ "xyz.openbmc_project.Network.IP.Create", "IP", protocol,
+ address, prefixLength, gateway);
},
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId,
- "xyz.openbmc_project.Network.IP.Create", "IP", protocol, address,
- prefixLength, gateway);
- },
"xyz.openbmc_project.Network",
"/xyz/openbmc_project/network/" + ifaceId + id,
"xyz.openbmc_project.Object.Delete", "Delete");
@@ -858,8 +859,7 @@ inline bool extractIPv6DefaultGatewayData(
bool success = sdbusplus::unpackPropertiesNoThrow(
redfish::dbus_utils::UnpackErrorPrinter(), interface.second,
- "Gateway", staticGateway.gateway, "PrefixLength",
- staticGateway.prefixLength, "ProtocolType",
+ "Gateway", staticGateway.gateway, "ProtocolType",
staticGateway.protocol);
if (!success)
{
@@ -887,21 +887,21 @@ inline void createIPv6(const std::string& ifaceId, uint8_t prefixLength,
sdbusplus::message::object_path path("/xyz/openbmc_project/network");
path /= ifaceId;
- auto createIpHandler = [asyncResp,
- address](const boost::system::error_code& ec) {
- if (ec)
- {
- if (ec == boost::system::errc::io_error)
+ auto createIpHandler =
+ [asyncResp, address](const boost::system::error_code& ec) {
+ if (ec)
{
- messages::propertyValueFormatError(asyncResp->res, address,
- "Address");
- }
- else
- {
- messages::internalError(asyncResp->res);
+ if (ec == boost::system::errc::io_error)
+ {
+ messages::propertyValueFormatError(asyncResp->res, address,
+ "Address");
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ }
}
- }
- };
+ };
// Passing null for gateway, as per redfish spec IPv6StaticAddresses
// object does not have associated gateway property
crow::connections::systemBus->async_method_call(
@@ -921,18 +921,19 @@ inline void createIPv6(const std::string& ifaceId, uint8_t prefixLength,
* @return None
*/
inline void
- deleteIPv6Gateway(std::string_view gatewayId,
+ deleteIPv6Gateway(std::string_view ifaceId, std::string_view gatewayId,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
sdbusplus::message::object_path path("/xyz/openbmc_project/network");
+ path /= ifaceId;
path /= gatewayId;
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- }
- },
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ },
"xyz.openbmc_project.Network", path,
"xyz.openbmc_project.Object.Delete", "Delete");
}
@@ -941,14 +942,13 @@ inline void
* @brief Creates IPv6 static default gateway with given data
*
* @param[in] ifaceId Id of interface whose IP should be added
- * @param[in] prefixLength Prefix length that needs to be added
* @param[in] gateway Gateway address that needs to be added
* @param[io] asyncResp Response object that will be returned to client
*
* @return None
*/
inline void createIPv6DefaultGateway(
- std::string_view ifaceId, size_t prefixLength, std::string_view gateway,
+ std::string_view ifaceId, std::string_view gateway,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
sdbusplus::message::object_path path("/xyz/openbmc_project/network");
@@ -962,7 +962,7 @@ inline void createIPv6DefaultGateway(
crow::connections::systemBus->async_method_call(
std::move(createIpHandler), "xyz.openbmc_project.Network", path,
"xyz.openbmc_project.Network.StaticGateway.Create", "StaticGateway",
- gateway, prefixLength, "xyz.openbmc_project.Network.IP.Protocol.IPv6");
+ gateway, "xyz.openbmc_project.Network.IP.Protocol.IPv6");
}
/**
@@ -972,28 +972,27 @@ inline void createIPv6DefaultGateway(
* @param[in] ifaceId Id of interface upon which to create the IPv6
* entry
* @param[in] gateway IPv6 gateway to assign to this interface
- * @param[in] prefixLength IPv6 prefix syntax for the subnet mask
* @param[io] asyncResp Response object that will be returned to client
*
* @return None
*/
inline void deleteAndCreateIPv6DefaultGateway(
std::string_view ifaceId, std::string_view gatewayId,
- std::string_view gateway, size_t prefixLength,
+ std::string_view gateway,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
sdbusplus::message::object_path path("/xyz/openbmc_project/network");
+ path /= ifaceId;
path /= gatewayId;
crow::connections::systemBus->async_method_call(
- [asyncResp, ifaceId, gateway,
- prefixLength](const boost::system::error_code& ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- createIPv6DefaultGateway(ifaceId, prefixLength, gateway, asyncResp);
- },
+ [asyncResp, ifaceId, gateway](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ createIPv6DefaultGateway(ifaceId, gateway, asyncResp);
+ },
"xyz.openbmc_project.Network", path,
"xyz.openbmc_project.Object.Delete", "Delete");
}
@@ -1032,8 +1031,8 @@ inline void handleIPv6DefaultGateway(
}
staticGatewayEntry++;
}
- std::string pathString = "IPv6StaticDefaultGateways/" +
- std::to_string(entryIdx);
+ std::string pathString =
+ "IPv6StaticDefaultGateways/" + std::to_string(entryIdx);
nlohmann::json::object_t* obj =
std::get_if<nlohmann::json::object_t>(&thisJson);
if (obj == nullptr)
@@ -1043,7 +1042,7 @@ inline void handleIPv6DefaultGateway(
messages::resourceCannotBeDeleted(asyncResp->res);
return;
}
- deleteIPv6Gateway(staticGatewayEntry->id, asyncResp);
+ deleteIPv6Gateway(ifaceId, staticGatewayEntry->id, asyncResp);
return;
}
if (obj->empty())
@@ -1057,15 +1056,13 @@ inline void handleIPv6DefaultGateway(
}
}
std::optional<std::string> address;
- std::optional<size_t> prefixLength;
- if (!json_util::readJsonObject(*obj, asyncResp->res, "Address", address,
- "PrefixLength", prefixLength))
+ if (!json_util::readJsonObject(*obj, asyncResp->res, "Address",
+ address))
{
return;
}
const std::string* addr = nullptr;
- size_t prefix = 0;
if (address)
{
addr = &(*address);
@@ -1079,29 +1076,15 @@ inline void handleIPv6DefaultGateway(
messages::propertyMissing(asyncResp->res, pathString + "/Address");
return;
}
- if (prefixLength)
- {
- prefix = *prefixLength;
- }
- else if (staticGatewayEntry != staticGatewayData.end())
- {
- prefix = staticGatewayEntry->prefixLength;
- }
- else
- {
- messages::propertyMissing(asyncResp->res,
- pathString + "/PrefixLength");
- return;
- }
if (staticGatewayEntry != staticGatewayData.end())
{
deleteAndCreateIPv6DefaultGateway(ifaceId, staticGatewayEntry->id,
- *addr, prefix, asyncResp);
+ *addr, asyncResp);
staticGatewayEntry++;
}
else
{
- createIPv6DefaultGateway(ifaceId, prefix, *addr, asyncResp);
+ createIPv6DefaultGateway(ifaceId, *addr, asyncResp);
}
entryIdx++;
}
@@ -1126,44 +1109,46 @@ void getEthernetIfaceData(const std::string& ethifaceId,
callback = std::forward<CallbackFunc>(callback)](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& resp) mutable {
- EthernetInterfaceData ethData{};
- std::vector<IPv4AddressData> ipv4Data;
- std::vector<IPv6AddressData> ipv6Data;
- std::vector<StaticGatewayData> ipv6GatewayData;
+ EthernetInterfaceData ethData{};
+ std::vector<IPv4AddressData> ipv4Data;
+ std::vector<IPv6AddressData> ipv6Data;
+ std::vector<StaticGatewayData> ipv6GatewayData;
- if (ec)
- {
- callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
- return;
- }
+ if (ec)
+ {
+ callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
+ return;
+ }
- bool found = extractEthernetInterfaceData(ethifaceId, resp, ethData);
- if (!found)
- {
- callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
- return;
- }
+ bool found =
+ extractEthernetInterfaceData(ethifaceId, resp, ethData);
+ if (!found)
+ {
+ callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
+ return;
+ }
- extractIPData(ethifaceId, resp, ipv4Data);
- // Fix global GW
- for (IPv4AddressData& ipv4 : ipv4Data)
- {
- if (((ipv4.linktype == LinkType::Global) &&
- (ipv4.gateway == "0.0.0.0")) ||
- (ipv4.origin == "DHCP") || (ipv4.origin == "Static"))
+ extractIPData(ethifaceId, resp, ipv4Data);
+ // Fix global GW
+ for (IPv4AddressData& ipv4 : ipv4Data)
{
- ipv4.gateway = ethData.defaultGateway;
+ if (((ipv4.linktype == LinkType::Global) &&
+ (ipv4.gateway == "0.0.0.0")) ||
+ (ipv4.origin == "DHCP") || (ipv4.origin == "Static"))
+ {
+ ipv4.gateway = ethData.defaultGateway;
+ }
}
- }
- extractIPV6Data(ethifaceId, resp, ipv6Data);
- if (!extractIPv6DefaultGatewayData(ethifaceId, resp, ipv6GatewayData))
- {
- callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
- }
- // Finally make a callback with useful data
- callback(true, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
- });
+ extractIPV6Data(ethifaceId, resp, ipv6Data);
+ if (!extractIPv6DefaultGatewayData(ethifaceId, resp,
+ ipv6GatewayData))
+ {
+ callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
+ }
+ // Finally make a callback with useful data
+ callback(true, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
+ });
}
/**
@@ -1181,44 +1166,44 @@ void getEthernetIfaceList(CallbackFunc&& callback)
[callback = std::forward<CallbackFunc>(callback)](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& resp) {
- // Callback requires vector<string> to retrieve all available
- // ethernet interfaces
- std::vector<std::string> ifaceList;
- ifaceList.reserve(resp.size());
- if (ec)
- {
- callback(false, ifaceList);
- return;
- }
+ // Callback requires vector<string> to retrieve all available
+ // ethernet interfaces
+ std::vector<std::string> ifaceList;
+ ifaceList.reserve(resp.size());
+ if (ec)
+ {
+ callback(false, ifaceList);
+ return;
+ }
- // Iterate over all retrieved ObjectPaths.
- for (const auto& objpath : resp)
- {
- // And all interfaces available for certain ObjectPath.
- for (const auto& interface : objpath.second)
+ // Iterate over all retrieved ObjectPaths.
+ for (const auto& objpath : resp)
{
- // If interface is
- // xyz.openbmc_project.Network.EthernetInterface, this is
- // what we're looking for.
- if (interface.first ==
- "xyz.openbmc_project.Network.EthernetInterface")
+ // And all interfaces available for certain ObjectPath.
+ for (const auto& interface : objpath.second)
{
- std::string ifaceId = objpath.first.filename();
- if (ifaceId.empty())
+ // If interface is
+ // xyz.openbmc_project.Network.EthernetInterface, this is
+ // what we're looking for.
+ if (interface.first ==
+ "xyz.openbmc_project.Network.EthernetInterface")
{
- continue;
+ std::string ifaceId = objpath.first.filename();
+ if (ifaceId.empty())
+ {
+ continue;
+ }
+ // and put it into output vector.
+ ifaceList.emplace_back(ifaceId);
}
- // and put it into output vector.
- ifaceList.emplace_back(ifaceId);
}
}
- }
- std::ranges::sort(ifaceList, AlphanumLess<std::string>());
+ std::ranges::sort(ifaceList, AlphanumLess<std::string>());
- // Finally make a callback with useful data
- callback(true, ifaceList);
- });
+ // Finally make a callback with useful data
+ callback(true, ifaceList);
+ });
}
inline void
@@ -1250,10 +1235,9 @@ inline void
"MTU", mtuSize);
}
-inline void
- handleDomainnamePatch(const std::string& ifaceId,
- const std::string& domainname,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+inline void handleDomainnamePatch(
+ const std::string& ifaceId, const std::string& domainname,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
std::vector<std::string> vectorDomainname = {domainname};
setDbusProperty(
@@ -1323,10 +1307,9 @@ inline void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn,
handleDomainnamePatch(ifaceId, domainname, asyncResp);
}
-inline void
- handleMACAddressPatch(const std::string& ifaceId,
- const std::string& macAddress,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+inline void handleMACAddressPatch(
+ const std::string& ifaceId, const std::string& macAddress,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
setDbusProperty(
asyncResp, "MACAddress", "xyz.openbmc_project.Network",
@@ -1392,11 +1375,10 @@ inline void handleSLAACAutoConfigPatch(
"IPv6AcceptRA", ipv6AutoConfigEnabled);
}
-inline void handleDHCPPatch(const std::string& ifaceId,
- const EthernetInterfaceData& ethData,
- const DHCPParameters& v4dhcpParms,
- const DHCPParameters& v6dhcpParms,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+inline void handleDHCPPatch(
+ const std::string& ifaceId, const EthernetInterfaceData& ethData,
+ const DHCPParameters& v4dhcpParms, const DHCPParameters& v6dhcpParms,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
bool ipv4Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
bool ipv6Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, false);
@@ -1532,8 +1514,8 @@ inline void handleIPv4StaticPatch(
for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
input)
{
- std::string pathString = "IPv4StaticAddresses/" +
- std::to_string(entryIdx);
+ std::string pathString =
+ "IPv4StaticAddresses/" + std::to_string(entryIdx);
nlohmann::json::object_t* obj =
std::get_if<nlohmann::json::object_t>(&thisJson);
if (obj == nullptr)
@@ -1541,8 +1523,8 @@ inline void handleIPv4StaticPatch(
if (nicIpEntry != ipv4Data.cend())
{
deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp);
- nicIpEntry = getNextStaticIpEntry(++nicIpEntry,
- ipv4Data.cend());
+ nicIpEntry =
+ getNextStaticIpEntry(++nicIpEntry, ipv4Data.cend());
if (!preserveGateway && (nicIpEntry == ipv4Data.cend()))
{
// All entries have been processed, and this last has
@@ -1678,8 +1660,8 @@ inline void handleIPv4StaticPatch(
deleteAndCreateIPAddress(IpVersion::IpV4, ifaceId,
nicIpEntry->id, prefixLength, *address,
*gateway, asyncResp);
- nicIpEntry = getNextStaticIpEntry(++nicIpEntry,
- ipv4Data.cend());
+ nicIpEntry =
+ getNextStaticIpEntry(++nicIpEntry, ipv4Data.cend());
preserveGateway = true;
}
else
@@ -1695,8 +1677,8 @@ inline void handleIPv4StaticPatch(
// Received {}, do not modify this address
if (nicIpEntry != ipv4Data.cend())
{
- nicIpEntry = getNextStaticIpEntry(++nicIpEntry,
- ipv4Data.cend());
+ nicIpEntry =
+ getNextStaticIpEntry(++nicIpEntry, ipv4Data.cend());
preserveGateway = true;
entryIdx++;
}
@@ -1737,8 +1719,8 @@ inline void handleIPv6StaticAddressesPatch(
for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
input)
{
- std::string pathString = "IPv6StaticAddresses/" +
- std::to_string(entryIdx);
+ std::string pathString =
+ "IPv6StaticAddresses/" + std::to_string(entryIdx);
nlohmann::json::object_t* obj =
std::get_if<nlohmann::json::object_t>(&thisJson);
if (obj != nullptr && !obj->empty())
@@ -1786,8 +1768,8 @@ inline void handleIPv6StaticAddressesPatch(
deleteAndCreateIPAddress(IpVersion::IpV6, ifaceId,
nicIpEntry->id, *prefixLength,
*address, "", asyncResp);
- nicIpEntry = getNextStaticIpEntry(++nicIpEntry,
- ipv6Data.cend());
+ nicIpEntry =
+ getNextStaticIpEntry(++nicIpEntry, ipv6Data.cend());
}
else
{
@@ -1818,8 +1800,8 @@ inline void handleIPv6StaticAddressesPatch(
}
if (nicIpEntry != ipv6Data.cend())
{
- nicIpEntry = getNextStaticIpEntry(++nicIpEntry,
- ipv6Data.cend());
+ nicIpEntry =
+ getNextStaticIpEntry(++nicIpEntry, ipv6Data.cend());
}
entryIdx++;
}
@@ -1832,13 +1814,12 @@ inline std::string extractParentInterfaceName(const std::string& ifaceId)
return ifaceId.substr(0, pos);
}
-inline void
- parseInterfaceData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& ifaceId,
- const EthernetInterfaceData& ethData,
- const std::vector<IPv4AddressData>& ipv4Data,
- const std::vector<IPv6AddressData>& ipv6Data,
- const std::vector<StaticGatewayData>& ipv6GatewayData)
+inline void parseInterfaceData(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& ifaceId, const EthernetInterfaceData& ethData,
+ const std::vector<IPv4AddressData>& ipv4Data,
+ const std::vector<IPv6AddressData>& ipv6Data,
+ const std::vector<StaticGatewayData>& ipv6GatewayData)
{
nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
jsonResponse["Id"] = ifaceId;
@@ -1849,26 +1830,32 @@ inline void
if (ethData.nicEnabled)
{
- jsonResponse["LinkStatus"] = ethData.linkUp ? "LinkUp" : "LinkDown";
- jsonResponse["Status"]["State"] = "Enabled";
+ jsonResponse["LinkStatus"] =
+ ethData.linkUp ? ethernet_interface::LinkStatus::LinkUp
+ : ethernet_interface::LinkStatus::LinkDown;
+ jsonResponse["Status"]["State"] = resource::State::Enabled;
}
else
{
- jsonResponse["LinkStatus"] = "NoLink";
- jsonResponse["Status"]["State"] = "Disabled";
+ jsonResponse["LinkStatus"] = ethernet_interface::LinkStatus::NoLink;
+ jsonResponse["Status"]["State"] = resource::State::Disabled;
}
jsonResponse["SpeedMbps"] = ethData.speed;
jsonResponse["MTUSize"] = ethData.mtuSize;
- jsonResponse["MACAddress"] = ethData.macAddress;
+ if (ethData.macAddress)
+ {
+ jsonResponse["MACAddress"] = *ethData.macAddress;
+ }
jsonResponse["DHCPv4"]["DHCPEnabled"] =
translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.ntpv4Enabled;
jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.dnsv4Enabled;
jsonResponse["DHCPv4"]["UseDomainName"] = ethData.domainv4Enabled;
jsonResponse["DHCPv6"]["OperatingMode"] =
- translateDhcpEnabledToBool(ethData.dhcpEnabled, false) ? "Enabled"
- : "Disabled";
+ translateDhcpEnabledToBool(ethData.dhcpEnabled, false)
+ ? "Enabled"
+ : "Disabled";
jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.ntpv6Enabled;
jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.dnsv6Enabled;
jsonResponse["DHCPv6"]["UseDomainName"] = ethData.domainv6Enabled;
@@ -1892,7 +1879,8 @@ inline void
if (ethData.vlanId)
{
- jsonResponse["EthernetInterfaceType"] = "Virtual";
+ jsonResponse["EthernetInterfaceType"] =
+ ethernet_interface::EthernetDeviceType::Virtual;
jsonResponse["VLAN"]["VLANEnable"] = true;
jsonResponse["VLAN"]["VLANId"] = *ethData.vlanId;
jsonResponse["VLAN"]["Tagged"] = true;
@@ -1908,7 +1896,8 @@ inline void
}
else
{
- jsonResponse["EthernetInterfaceType"] = "Physical";
+ jsonResponse["EthernetInterfaceType"] =
+ ethernet_interface::EthernetDeviceType::Physical;
}
jsonResponse["NameServers"] = ethData.nameServers;
@@ -1952,7 +1941,6 @@ inline void
{
nlohmann::json::object_t ipv6Gateway;
ipv6Gateway["Address"] = ipv6GatewayConfig.gateway;
- ipv6Gateway["PrefixLength"] = ipv6GatewayConfig.prefixLength;
ipv6StaticGatewayArray.emplace_back(std::move(ipv6Gateway));
}
jsonResponse["IPv6StaticDefaultGateways"] =
@@ -2016,11 +2004,10 @@ inline void afterDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
messages::internalError(asyncResp->res);
}
-inline void afterVlanCreate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& parentInterfaceUri,
- const std::string& vlanInterface,
- const boost::system::error_code& ec,
- const sdbusplus::message_t& m
+inline void afterVlanCreate(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& parentInterfaceUri, const std::string& vlanInterface,
+ const boost::system::error_code& ec, const sdbusplus::message_t& m
)
{
@@ -2069,55 +2056,59 @@ inline void requestEthernetInterfacesRoutes(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.type"] =
- "#EthernetInterfaceCollection.EthernetInterfaceCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["Name"] =
- "Ethernet Network Interface Collection";
- asyncResp->res.jsonValue["Description"] =
- "Collection of EthernetInterfaces for this Manager";
-
- // Get eth interface list, and call the below callback for JSON
- // preparation
- getEthernetIfaceList(
- [asyncResp](const bool& success,
- const std::vector<std::string>& ifaceList) {
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EthernetInterfaceCollection.EthernetInterfaceCollection";
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/EthernetInterfaces",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["Name"] =
+ "Ethernet Network Interface Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of EthernetInterfaces for this Manager";
+
+ // Get eth interface list, and call the below callback for JSON
+ // preparation
+ getEthernetIfaceList(
+ [asyncResp](const bool& success,
+ const std::vector<std::string>& ifaceList) {
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
- ifaceArray = nlohmann::json::array();
- for (const std::string& ifaceItem : ifaceList)
- {
- nlohmann::json::object_t iface;
- iface["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/EthernetInterfaces/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceItem);
- ifaceArray.push_back(std::move(iface));
- }
+ nlohmann::json& ifaceArray =
+ asyncResp->res.jsonValue["Members"];
+ ifaceArray = nlohmann::json::array();
+ for (const std::string& ifaceItem : ifaceList)
+ {
+ nlohmann::json::object_t iface;
+ iface["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/EthernetInterfaces/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceItem);
+ ifaceArray.push_back(std::move(iface));
+ }
- asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size();
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/EthernetInterfaces",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- });
- });
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ ifaceArray.size();
+ asyncResp->res.jsonValue["@odata.id"] =
+ boost::urls::format(
+ "/redfish/v1/Managers/{}/EthernetInterfaces",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ });
+ });
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
.privileges(redfish::privileges::postEthernetInterfaceCollection)
@@ -2125,90 +2116,93 @@ inline void requestEthernetInterfacesRoutes(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- bool vlanEnable = false;
- uint32_t vlanId = 0;
- std::vector<nlohmann::json::object_t> relatedInterfaces;
+ bool vlanEnable = false;
+ uint32_t vlanId = 0;
+ std::vector<nlohmann::json::object_t> relatedInterfaces;
- if (!json_util::readJsonPatch(req, asyncResp->res, "VLAN/VLANEnable",
- vlanEnable, "VLAN/VLANId", vlanId,
- "Links/RelatedInterfaces",
- relatedInterfaces))
- {
- return;
- }
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "VLAN/VLANEnable", vlanEnable,
+ "VLAN/VLANId", vlanId, "Links/RelatedInterfaces",
+ relatedInterfaces))
+ {
+ return;
+ }
- if (relatedInterfaces.size() != 1)
- {
- messages::arraySizeTooLong(asyncResp->res,
- "Links/RelatedInterfaces",
- relatedInterfaces.size());
- return;
- }
+ if (relatedInterfaces.size() != 1)
+ {
+ messages::arraySizeTooLong(asyncResp->res,
+ "Links/RelatedInterfaces",
+ relatedInterfaces.size());
+ return;
+ }
- std::string parentInterfaceUri;
- if (!json_util::readJsonObject(relatedInterfaces[0], asyncResp->res,
- "@odata.id", parentInterfaceUri))
- {
- messages::propertyMissing(asyncResp->res,
- "Links/RelatedInterfaces/0/@odata.id");
- return;
- }
- BMCWEB_LOG_INFO("Parent Interface URI: {}", parentInterfaceUri);
+ std::string parentInterfaceUri;
+ if (!json_util::readJsonObject(relatedInterfaces[0],
+ asyncResp->res, "@odata.id",
+ parentInterfaceUri))
+ {
+ messages::propertyMissing(
+ asyncResp->res, "Links/RelatedInterfaces/0/@odata.id");
+ return;
+ }
+ BMCWEB_LOG_INFO("Parent Interface URI: {}", parentInterfaceUri);
- boost::system::result<boost::urls::url_view> parsedUri =
- boost::urls::parse_relative_ref(parentInterfaceUri);
- if (!parsedUri)
- {
- messages::propertyValueFormatError(
- asyncResp->res, parentInterfaceUri,
- "Links/RelatedInterfaces/0/@odata.id");
- return;
- }
+ boost::system::result<boost::urls::url_view> parsedUri =
+ boost::urls::parse_relative_ref(parentInterfaceUri);
+ if (!parsedUri)
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, parentInterfaceUri,
+ "Links/RelatedInterfaces/0/@odata.id");
+ return;
+ }
- std::string parentInterface;
- if (!crow::utility::readUrlSegments(
- *parsedUri, "redfish", "v1", "Managers", "bmc",
- "EthernetInterfaces", std::ref(parentInterface)))
- {
- messages::propertyValueNotInList(
- asyncResp->res, parentInterfaceUri,
- "Links/RelatedInterfaces/0/@odata.id");
- return;
- }
+ std::string parentInterface;
+ if (!crow::utility::readUrlSegments(
+ *parsedUri, "redfish", "v1", "Managers", "bmc",
+ "EthernetInterfaces", std::ref(parentInterface)))
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, parentInterfaceUri,
+ "Links/RelatedInterfaces/0/@odata.id");
+ return;
+ }
- if (!vlanEnable)
- {
- // In OpenBMC implementation, VLANEnable cannot be false on
- // create
- messages::propertyValueIncorrect(asyncResp->res, "VLAN/VLANEnable",
- "false");
- return;
- }
+ if (!vlanEnable)
+ {
+ // In OpenBMC implementation, VLANEnable cannot be false on
+ // create
+ messages::propertyValueIncorrect(
+ asyncResp->res, "VLAN/VLANEnable", "false");
+ return;
+ }
- std::string vlanInterface = parentInterface + "_" +
- std::to_string(vlanId);
- crow::connections::systemBus->async_method_call(
- [asyncResp, parentInterfaceUri,
- vlanInterface](const boost::system::error_code& ec,
- const sdbusplus::message_t& m) {
- afterVlanCreate(asyncResp, parentInterfaceUri, vlanInterface, ec,
- m);
- },
- "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
- "xyz.openbmc_project.Network.VLAN.Create", "VLAN", parentInterface,
- vlanId);
- });
+ std::string vlanInterface =
+ parentInterface + "_" + std::to_string(vlanId);
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, parentInterfaceUri,
+ vlanInterface](const boost::system::error_code& ec,
+ const sdbusplus::message_t& m) {
+ afterVlanCreate(asyncResp, parentInterfaceUri,
+ vlanInterface, ec, m);
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network",
+ "xyz.openbmc_project.Network.VLAN.Create", "VLAN",
+ parentInterface, vlanId);
+ });
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
.privileges(redfish::privileges::getEthernetInterface)
@@ -2216,43 +2210,46 @@ inline void requestEthernetInterfacesRoutes(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId, const std::string& ifaceId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- getEthernetIfaceData(
- ifaceId,
- [asyncResp,
- ifaceId](const bool& success, const EthernetInterfaceData& ethData,
- const std::vector<IPv4AddressData>& ipv4Data,
- const std::vector<IPv6AddressData>& ipv6Data,
- const std::vector<StaticGatewayData>& ipv6GatewayData) {
- if (!success)
- {
- // TODO(Pawel)consider distinguish between non
- // existing object, and other errors
- messages::resourceNotFound(asyncResp->res, "EthernetInterface",
- ifaceId);
- return;
- }
+ getEthernetIfaceData(
+ ifaceId,
+ [asyncResp, ifaceId](
+ const bool& success,
+ const EthernetInterfaceData& ethData,
+ const std::vector<IPv4AddressData>& ipv4Data,
+ const std::vector<IPv6AddressData>& ipv6Data,
+ const std::vector<StaticGatewayData>& ipv6GatewayData) {
+ if (!success)
+ {
+ // TODO(Pawel)consider distinguish between non
+ // existing object, and other errors
+ messages::resourceNotFound(
+ asyncResp->res, "EthernetInterface", ifaceId);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.type"] =
- "#EthernetInterface.v1_9_0.EthernetInterface";
- asyncResp->res.jsonValue["Name"] = "Manager Ethernet Interface";
- asyncResp->res.jsonValue["Description"] =
- "Management Network Interface";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EthernetInterface.v1_9_0.EthernetInterface";
+ asyncResp->res.jsonValue["Name"] =
+ "Manager Ethernet Interface";
+ asyncResp->res.jsonValue["Description"] =
+ "Management Network Interface";
- parseInterfaceData(asyncResp, ifaceId, ethData, ipv4Data, ipv6Data,
- ipv6GatewayData);
- });
- });
+ parseInterfaceData(asyncResp, ifaceId, ethData,
+ ipv4Data, ipv6Data, ipv6GatewayData);
+ });
+ });
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
.privileges(redfish::privileges::patchEthernetInterface)
@@ -2260,37 +2257,38 @@ inline void requestEthernetInterfacesRoutes(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId, const std::string& ifaceId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- std::optional<std::string> hostname;
- std::optional<std::string> fqdn;
- std::optional<std::string> macAddress;
- std::optional<std::string> ipv6DefaultGateway;
- std::optional<
- std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>>
- ipv4StaticAddresses;
- std::optional<
- std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>>
- ipv6StaticAddresses;
- std::optional<
- std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>>
- ipv6StaticDefaultGateways;
- std::optional<std::vector<std::string>> staticNameServers;
- std::optional<bool> ipv6AutoConfigEnabled;
- std::optional<bool> interfaceEnabled;
- std::optional<size_t> mtuSize;
- DHCPParameters v4dhcpParms;
- DHCPParameters v6dhcpParms;
- // clang-format off
+ std::optional<std::string> hostname;
+ std::optional<std::string> fqdn;
+ std::optional<std::string> macAddress;
+ std::optional<std::string> ipv6DefaultGateway;
+ std::optional<std::vector<
+ std::variant<nlohmann::json::object_t, std::nullptr_t>>>
+ ipv4StaticAddresses;
+ std::optional<std::vector<
+ std::variant<nlohmann::json::object_t, std::nullptr_t>>>
+ ipv6StaticAddresses;
+ std::optional<std::vector<
+ std::variant<nlohmann::json::object_t, std::nullptr_t>>>
+ ipv6StaticDefaultGateways;
+ std::optional<std::vector<std::string>> staticNameServers;
+ std::optional<bool> ipv6AutoConfigEnabled;
+ std::optional<bool> interfaceEnabled;
+ std::optional<size_t> mtuSize;
+ DHCPParameters v4dhcpParms;
+ DHCPParameters v6dhcpParms;
+ // clang-format off
if (!json_util::readJsonPatch(req, asyncResp->res,
"DHCPv4/DHCPEnabled", v4dhcpParms.dhcpv4Enabled,
"DHCPv4/UseDNSServers", v4dhcpParms.useDnsServers,
@@ -2316,106 +2314,114 @@ inline void requestEthernetInterfacesRoutes(App& app)
{
return;
}
- // clang-format on
-
- // Get single eth interface data, and call the below callback
- // for JSON preparation
- getEthernetIfaceData(
- ifaceId,
- [asyncResp, ifaceId, hostname = std::move(hostname),
- fqdn = std::move(fqdn), macAddress = std::move(macAddress),
- ipv4StaticAddresses = std::move(ipv4StaticAddresses),
- ipv6DefaultGateway = std::move(ipv6DefaultGateway),
- ipv6StaticAddresses = std::move(ipv6StaticAddresses),
- ipv6StaticDefaultGateway = std::move(ipv6StaticDefaultGateways),
- staticNameServers = std::move(staticNameServers), mtuSize,
- ipv6AutoConfigEnabled, v4dhcpParms = std::move(v4dhcpParms),
- v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
- const bool success, const EthernetInterfaceData& ethData,
- const std::vector<IPv4AddressData>& ipv4Data,
- const std::vector<IPv6AddressData>& ipv6Data,
- const std::vector<StaticGatewayData>& ipv6GatewayData) mutable {
- if (!success)
- {
- // ... otherwise return error
- // TODO(Pawel)consider distinguish between non
- // existing object, and other errors
- messages::resourceNotFound(asyncResp->res, "EthernetInterface",
- ifaceId);
- return;
- }
+ // clang-format on
+
+ // Get single eth interface data, and call the below callback
+ // for JSON preparation
+ getEthernetIfaceData(
+ ifaceId,
+ [asyncResp, ifaceId, hostname = std::move(hostname),
+ fqdn = std::move(fqdn), macAddress = std::move(macAddress),
+ ipv4StaticAddresses = std::move(ipv4StaticAddresses),
+ ipv6DefaultGateway = std::move(ipv6DefaultGateway),
+ ipv6StaticAddresses = std::move(ipv6StaticAddresses),
+ ipv6StaticDefaultGateway =
+ std::move(ipv6StaticDefaultGateways),
+ staticNameServers = std::move(staticNameServers), mtuSize,
+ ipv6AutoConfigEnabled,
+ v4dhcpParms = std::move(v4dhcpParms),
+ v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
+ const bool success,
+ const EthernetInterfaceData& ethData,
+ const std::vector<IPv4AddressData>& ipv4Data,
+ const std::vector<IPv6AddressData>& ipv6Data,
+ const std::vector<StaticGatewayData>&
+ ipv6GatewayData) mutable {
+ if (!success)
+ {
+ // ... otherwise return error
+ // TODO(Pawel)consider distinguish between non
+ // existing object, and other errors
+ messages::resourceNotFound(
+ asyncResp->res, "EthernetInterface", ifaceId);
+ return;
+ }
- handleDHCPPatch(ifaceId, ethData, v4dhcpParms, v6dhcpParms,
- asyncResp);
+ handleDHCPPatch(ifaceId, ethData, v4dhcpParms,
+ v6dhcpParms, asyncResp);
- if (hostname)
- {
- handleHostnamePatch(*hostname, asyncResp);
- }
+ if (hostname)
+ {
+ handleHostnamePatch(*hostname, asyncResp);
+ }
- if (ipv6AutoConfigEnabled)
- {
- handleSLAACAutoConfigPatch(ifaceId, *ipv6AutoConfigEnabled,
- asyncResp);
- }
+ if (ipv6AutoConfigEnabled)
+ {
+ handleSLAACAutoConfigPatch(
+ ifaceId, *ipv6AutoConfigEnabled, asyncResp);
+ }
- if (fqdn)
- {
- handleFqdnPatch(ifaceId, *fqdn, asyncResp);
- }
+ if (fqdn)
+ {
+ handleFqdnPatch(ifaceId, *fqdn, asyncResp);
+ }
- if (macAddress)
- {
- handleMACAddressPatch(ifaceId, *macAddress, asyncResp);
- }
+ if (macAddress)
+ {
+ handleMACAddressPatch(ifaceId, *macAddress,
+ asyncResp);
+ }
- if (ipv4StaticAddresses)
- {
- handleIPv4StaticPatch(ifaceId, *ipv4StaticAddresses, ethData,
- ipv4Data, asyncResp);
- }
+ if (ipv4StaticAddresses)
+ {
+ handleIPv4StaticPatch(ifaceId, *ipv4StaticAddresses,
+ ethData, ipv4Data, asyncResp);
+ }
- if (staticNameServers)
- {
- handleStaticNameServersPatch(ifaceId, *staticNameServers,
- asyncResp);
- }
+ if (staticNameServers)
+ {
+ handleStaticNameServersPatch(
+ ifaceId, *staticNameServers, asyncResp);
+ }
- if (ipv6DefaultGateway)
- {
- messages::propertyNotWritable(asyncResp->res,
- "IPv6DefaultGateway");
- }
+ if (ipv6DefaultGateway)
+ {
+ messages::propertyNotWritable(asyncResp->res,
+ "IPv6DefaultGateway");
+ }
- if (ipv6StaticAddresses)
- {
- handleIPv6StaticAddressesPatch(ifaceId, *ipv6StaticAddresses,
- ipv6Data, asyncResp);
- }
+ if (ipv6StaticAddresses)
+ {
+ handleIPv6StaticAddressesPatch(ifaceId,
+ *ipv6StaticAddresses,
+ ipv6Data, asyncResp);
+ }
- if (ipv6StaticDefaultGateway)
- {
- handleIPv6DefaultGateway(ifaceId, *ipv6StaticDefaultGateway,
- ipv6GatewayData, asyncResp);
- }
+ if (ipv6StaticDefaultGateway)
+ {
+ handleIPv6DefaultGateway(
+ ifaceId, *ipv6StaticDefaultGateway,
+ ipv6GatewayData, asyncResp);
+ }
- if (interfaceEnabled)
- {
- setDbusProperty(asyncResp, "InterfaceEnabled",
+ if (interfaceEnabled)
+ {
+ setDbusProperty(
+ asyncResp, "InterfaceEnabled",
"xyz.openbmc_project.Network",
sdbusplus::message::object_path(
"/xyz/openbmc_project/network") /
ifaceId,
"xyz.openbmc_project.Network.EthernetInterface",
"NICEnabled", *interfaceEnabled);
- }
+ }
- if (mtuSize)
- {
- handleMTUSizePatch(ifaceId, *mtuSize, asyncResp);
- }
- });
- });
+ if (mtuSize)
+ {
+ handleMTUSizePatch(ifaceId, *mtuSize, asyncResp);
+ }
+ });
+ });
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
.privileges(redfish::privileges::deleteEthernetInterface)
@@ -2423,26 +2429,27 @@ inline void requestEthernetInterfacesRoutes(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId, const std::string& ifaceId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- crow::connections::systemBus->async_method_call(
- [asyncResp, ifaceId](const boost::system::error_code& ec,
- const sdbusplus::message_t& m) {
- afterDelete(asyncResp, ifaceId, ec, m);
- },
- "xyz.openbmc_project.Network",
- std::string("/xyz/openbmc_project/network/") + ifaceId,
- "xyz.openbmc_project.Object.Delete", "Delete");
- });
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, ifaceId](const boost::system::error_code& ec,
+ const sdbusplus::message_t& m) {
+ afterDelete(asyncResp, ifaceId, ec, m);
+ },
+ "xyz.openbmc_project.Network",
+ std::string("/xyz/openbmc_project/network/") + ifaceId,
+ "xyz.openbmc_project.Object.Delete", "Delete");
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index aebc2824b0..76f3c5a9ed 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -1,21 +1,22 @@
/*
-// Copyright (c) 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "event_service_manager.hpp"
+#include "generated/enums/event_service.hpp"
#include "http/utility.hpp"
#include "logging.hpp"
#include "query.hpp"
@@ -33,6 +34,7 @@
#include <ranges>
#include <span>
#include <string>
+#include <vector>
namespace redfish
{
@@ -51,118 +53,123 @@ inline void requestRoutesEventService(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
.privileges(redfish::privileges::getEventService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](
+ const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
- asyncResp->res.jsonValue["@odata.type"] =
- "#EventService.v1_5_0.EventService";
- asyncResp->res.jsonValue["Id"] = "EventService";
- asyncResp->res.jsonValue["Name"] = "Event Service";
- asyncResp->res.jsonValue["ServerSentEventUri"] =
- "/redfish/v1/EventService/SSE";
-
- asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
- "/redfish/v1/EventService/Subscriptions";
- asyncResp->res
- .jsonValue["Actions"]["#EventService.SubmitTestEvent"]["target"] =
- "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
-
- const persistent_data::EventServiceConfig eventServiceConfig =
- persistent_data::EventServiceStore::getInstance()
- .getEventServiceConfig();
-
- asyncResp->res.jsonValue["Status"]["State"] =
- (eventServiceConfig.enabled ? "Enabled" : "Disabled");
- asyncResp->res.jsonValue["ServiceEnabled"] = eventServiceConfig.enabled;
- asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
- eventServiceConfig.retryAttempts;
- asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
- eventServiceConfig.retryTimeoutInterval;
- asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes;
- asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
- asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
-
- nlohmann::json::object_t supportedSSEFilters;
- supportedSSEFilters["EventFormatType"] = true;
- supportedSSEFilters["MessageId"] = true;
- supportedSSEFilters["MetricReportDefinition"] = true;
- supportedSSEFilters["RegistryPrefix"] = true;
- supportedSSEFilters["OriginResource"] = false;
- supportedSSEFilters["ResourceType"] = false;
-
- asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
- std::move(supportedSSEFilters);
- });
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EventService.v1_5_0.EventService";
+ asyncResp->res.jsonValue["Id"] = "EventService";
+ asyncResp->res.jsonValue["Name"] = "Event Service";
+ asyncResp->res.jsonValue["ServerSentEventUri"] =
+ "/redfish/v1/EventService/SSE";
+
+ asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
+ "/redfish/v1/EventService/Subscriptions";
+ asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
+ ["target"] =
+ "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
+
+ const persistent_data::EventServiceConfig eventServiceConfig =
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig();
+
+ asyncResp->res.jsonValue["Status"]["State"] =
+ (eventServiceConfig.enabled ? "Enabled" : "Disabled");
+ asyncResp->res.jsonValue["ServiceEnabled"] =
+ eventServiceConfig.enabled;
+ asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
+ eventServiceConfig.retryAttempts;
+ asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
+ eventServiceConfig.retryTimeoutInterval;
+ asyncResp->res.jsonValue["EventFormatTypes"] =
+ supportedEvtFormatTypes;
+ asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
+ asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
+
+ nlohmann::json::object_t supportedSSEFilters;
+ supportedSSEFilters["EventFormatType"] = true;
+ supportedSSEFilters["MessageId"] = true;
+ supportedSSEFilters["MetricReportDefinition"] = true;
+ supportedSSEFilters["RegistryPrefix"] = true;
+ supportedSSEFilters["OriginResource"] = false;
+ supportedSSEFilters["ResourceType"] = false;
+
+ asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
+ std::move(supportedSSEFilters);
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
.privileges(redfish::privileges::patchEventService)
.methods(boost::beast::http::verb::patch)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- std::optional<bool> serviceEnabled;
- std::optional<uint32_t> retryAttemps;
- std::optional<uint32_t> retryInterval;
-
- if (!json_util::readJsonPatch(
- req, asyncResp->res, "ServiceEnabled", serviceEnabled,
- "DeliveryRetryAttempts", retryAttemps,
- "DeliveryRetryIntervalSeconds", retryInterval))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::optional<bool> serviceEnabled;
+ std::optional<uint32_t> retryAttemps;
+ std::optional<uint32_t> retryInterval;
+
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "ServiceEnabled", serviceEnabled,
+ "DeliveryRetryAttempts", retryAttemps,
+ "DeliveryRetryIntervalSeconds", retryInterval))
+ {
+ return;
+ }
- persistent_data::EventServiceConfig eventServiceConfig =
- persistent_data::EventServiceStore::getInstance()
- .getEventServiceConfig();
+ persistent_data::EventServiceConfig eventServiceConfig =
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig();
- if (serviceEnabled)
- {
- eventServiceConfig.enabled = *serviceEnabled;
- }
+ if (serviceEnabled)
+ {
+ eventServiceConfig.enabled = *serviceEnabled;
+ }
- if (retryAttemps)
- {
- // Supported range [1-3]
- if ((*retryAttemps < 1) || (*retryAttemps > 3))
- {
- messages::queryParameterOutOfRange(
- asyncResp->res, std::to_string(*retryAttemps),
- "DeliveryRetryAttempts", "[1-3]");
- }
- else
- {
- eventServiceConfig.retryAttempts = *retryAttemps;
- }
- }
+ if (retryAttemps)
+ {
+ // Supported range [1-3]
+ if ((*retryAttemps < 1) || (*retryAttemps > 3))
+ {
+ messages::queryParameterOutOfRange(
+ asyncResp->res, std::to_string(*retryAttemps),
+ "DeliveryRetryAttempts", "[1-3]");
+ }
+ else
+ {
+ eventServiceConfig.retryAttempts = *retryAttemps;
+ }
+ }
- if (retryInterval)
- {
- // Supported range [5 - 180]
- if ((*retryInterval < 5) || (*retryInterval > 180))
- {
- messages::queryParameterOutOfRange(
- asyncResp->res, std::to_string(*retryInterval),
- "DeliveryRetryIntervalSeconds", "[5-180]");
- }
- else
- {
- eventServiceConfig.retryTimeoutInterval = *retryInterval;
- }
- }
+ if (retryInterval)
+ {
+ // Supported range [5 - 180]
+ if ((*retryInterval < 5) || (*retryInterval > 180))
+ {
+ messages::queryParameterOutOfRange(
+ asyncResp->res, std::to_string(*retryInterval),
+ "DeliveryRetryIntervalSeconds", "[5-180]");
+ }
+ else
+ {
+ eventServiceConfig.retryTimeoutInterval =
+ *retryInterval;
+ }
+ }
- EventServiceManager::getInstance().setEventServiceConfig(
- eventServiceConfig);
- });
+ EventServiceManager::getInstance().setEventServiceConfig(
+ eventServiceConfig);
+ });
}
inline void requestRoutesSubmitTestEvent(App& app)
@@ -173,18 +180,18 @@ inline void requestRoutesSubmitTestEvent(App& app)
.methods(boost::beast::http::verb::post)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (!EventServiceManager::getInstance().sendTestEventLog())
- {
- messages::serviceDisabled(asyncResp->res,
- "/redfish/v1/EventService/");
- return;
- }
- asyncResp->res.result(boost::beast::http::status::no_content);
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if (!EventServiceManager::getInstance().sendTestEventLog())
+ {
+ messages::serviceDisabled(asyncResp->res,
+ "/redfish/v1/EventService/");
+ return;
+ }
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ });
}
inline void doSubscriptionCollection(
@@ -227,402 +234,424 @@ inline void requestRoutesEventDestinationCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#EventDestinationCollection.EventDestinationCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/EventService/Subscriptions";
- asyncResp->res.jsonValue["Name"] = "Event Destination Collections";
-
- nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
-
- std::vector<std::string> subscripIds =
- EventServiceManager::getInstance().getAllIDs();
- memberArray = nlohmann::json::array();
- asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size();
-
- for (const std::string& id : subscripIds)
- {
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/EventService/Subscriptions/{}" + id);
- memberArray.emplace_back(std::move(member));
- }
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code& ec,
- const dbus::utility::ManagedObjectType& resp) {
- doSubscriptionCollection(ec, asyncResp, resp);
- },
- "xyz.openbmc_project.Network.SNMP",
- "/xyz/openbmc_project/network/snmp/manager",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EventDestinationCollection.EventDestinationCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/EventService/Subscriptions";
+ asyncResp->res.jsonValue["Name"] =
+ "Event Destination Collections";
+
+ nlohmann::json& memberArray =
+ asyncResp->res.jsonValue["Members"];
+
+ std::vector<std::string> subscripIds =
+ EventServiceManager::getInstance().getAllIDs();
+ memberArray = nlohmann::json::array();
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ subscripIds.size();
+
+ for (const std::string& id : subscripIds)
+ {
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/EventService/Subscriptions/{}" + id);
+ memberArray.emplace_back(std::move(member));
+ }
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code& ec,
+ const dbus::utility::ManagedObjectType& resp) {
+ doSubscriptionCollection(ec, asyncResp, resp);
+ },
+ "xyz.openbmc_project.Network.SNMP",
+ "/xyz/openbmc_project/network/snmp/manager",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
.privileges(redfish::privileges::postEventDestinationCollection)
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
- maxNoOfSubscriptions)
- {
- messages::eventSubscriptionLimitExceeded(asyncResp->res);
- return;
- }
- std::string destUrl;
- std::string protocol;
- std::optional<std::string> context;
- std::optional<std::string> subscriptionType;
- std::optional<std::string> eventFormatType2;
- std::optional<std::string> retryPolicy;
- std::optional<std::vector<std::string>> msgIds;
- std::optional<std::vector<std::string>> regPrefixes;
- std::optional<std::vector<std::string>> resTypes;
- std::optional<std::vector<nlohmann::json::object_t>> headers;
- std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
-
- if (!json_util::readJsonPatch(
- req, asyncResp->res, "Destination", destUrl, "Context", context,
- "Protocol", protocol, "SubscriptionType", subscriptionType,
- "EventFormatType", eventFormatType2, "HttpHeaders", headers,
- "RegistryPrefixes", regPrefixes, "MessageIds", msgIds,
- "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions",
- mrdJsonArray, "ResourceTypes", resTypes))
- {
- return;
- }
-
- // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
- static constexpr const uint16_t maxDestinationSize = 2000;
- if (destUrl.size() > maxDestinationSize)
- {
- messages::stringValueTooLong(asyncResp->res, "Destination",
- maxDestinationSize);
- return;
- }
-
- if (regPrefixes && msgIds)
- {
- if (!regPrefixes->empty() && !msgIds->empty())
+ .methods(
+ boost::beast::http::verb::
+ post)([&app](
+ const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- messages::propertyValueConflict(asyncResp->res, "MessageIds",
- "RegistryPrefixes");
return;
}
- }
-
- boost::system::result<boost::urls::url> url =
- boost::urls::parse_absolute_uri(destUrl);
- if (!url)
- {
- BMCWEB_LOG_WARNING("Failed to validate and split destination url");
- messages::propertyValueFormatError(asyncResp->res, destUrl,
- "Destination");
- return;
- }
- url->normalize();
- crow::utility::setProtocolDefaults(*url, protocol);
- crow::utility::setPortDefaults(*url);
-
- if (url->path().empty())
- {
- url->set_path("/");
- }
-
- if (url->has_userinfo())
- {
- messages::propertyValueFormatError(asyncResp->res, destUrl,
- "Destination");
- return;
- }
-
- if (protocol == "SNMPv2c")
- {
- if (context)
+ if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
+ maxNoOfSubscriptions)
{
- messages::propertyValueConflict(asyncResp->res, "Context",
- "Protocol");
+ messages::eventSubscriptionLimitExceeded(asyncResp->res);
return;
}
- if (eventFormatType2)
+ std::string destUrl;
+ std::string protocol;
+ std::optional<bool> verifyCertificate;
+ std::optional<std::string> context;
+ std::optional<std::string> subscriptionType;
+ std::optional<std::string> eventFormatType2;
+ std::optional<std::string> retryPolicy;
+ std::optional<std::vector<std::string>> msgIds;
+ std::optional<std::vector<std::string>> regPrefixes;
+ std::optional<std::vector<std::string>> originResources;
+ std::optional<std::vector<std::string>> resTypes;
+ std::optional<std::vector<nlohmann::json::object_t>> headers;
+ std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
+
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "Destination", destUrl, "Context",
+ context, "Protocol", protocol, "SubscriptionType",
+ subscriptionType, "EventFormatType", eventFormatType2,
+ "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
+ "OriginResources", originResources, "MessageIds", msgIds,
+ "DeliveryRetryPolicy", retryPolicy,
+ "MetricReportDefinitions", mrdJsonArray, "ResourceTypes",
+ resTypes, "VerifyCertificate", verifyCertificate))
{
- messages::propertyValueConflict(asyncResp->res,
- "EventFormatType", "Protocol");
return;
}
- if (retryPolicy)
- {
- messages::propertyValueConflict(asyncResp->res, "RetryPolicy",
- "Protocol");
- return;
- }
- if (msgIds)
+
+ // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
+ static constexpr const uint16_t maxDestinationSize = 2000;
+ if (destUrl.size() > maxDestinationSize)
{
- messages::propertyValueConflict(asyncResp->res, "MessageIds",
- "Protocol");
+ messages::stringValueTooLong(asyncResp->res, "Destination",
+ maxDestinationSize);
return;
}
- if (regPrefixes)
+
+ if (regPrefixes && msgIds)
{
- messages::propertyValueConflict(asyncResp->res,
- "RegistryPrefixes", "Protocol");
- return;
+ if (!regPrefixes->empty() && !msgIds->empty())
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "MessageIds", "RegistryPrefixes");
+ return;
+ }
}
- if (resTypes)
+
+ boost::system::result<boost::urls::url> url =
+ boost::urls::parse_absolute_uri(destUrl);
+ if (!url)
{
- messages::propertyValueConflict(asyncResp->res, "ResourceTypes",
- "Protocol");
+ BMCWEB_LOG_WARNING(
+ "Failed to validate and split destination url");
+ messages::propertyValueFormatError(asyncResp->res, destUrl,
+ "Destination");
return;
}
- if (headers)
+ url->normalize();
+ crow::utility::setProtocolDefaults(*url, protocol);
+ crow::utility::setPortDefaults(*url);
+
+ if (url->path().empty())
{
- messages::propertyValueConflict(asyncResp->res, "HttpHeaders",
- "Protocol");
- return;
+ url->set_path("/");
}
- if (mrdJsonArray)
+
+ if (url->has_userinfo())
{
- messages::propertyValueConflict(
- asyncResp->res, "MetricReportDefinitions", "Protocol");
+ messages::propertyValueFormatError(asyncResp->res, destUrl,
+ "Destination");
return;
}
- if (url->scheme() != "snmp")
+
+ if (protocol == "SNMPv2c")
{
- messages::propertyValueConflict(asyncResp->res, "Destination",
- "Protocol");
+ if (context)
+ {
+ messages::propertyValueConflict(asyncResp->res, "Context",
+ "Protocol");
+ return;
+ }
+ if (eventFormatType2)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "EventFormatType", "Protocol");
+ return;
+ }
+ if (retryPolicy)
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "RetryPolicy", "Protocol");
+ return;
+ }
+ if (msgIds)
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "MessageIds", "Protocol");
+ return;
+ }
+ if (regPrefixes)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "RegistryPrefixes", "Protocol");
+ return;
+ }
+ if (resTypes)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "ResourceTypes", "Protocol");
+ return;
+ }
+ if (headers)
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "HttpHeaders", "Protocol");
+ return;
+ }
+ if (mrdJsonArray)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "MetricReportDefinitions", "Protocol");
+ return;
+ }
+ if (url->scheme() != "snmp")
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "Destination", "Protocol");
+ return;
+ }
+
+ addSnmpTrapClient(asyncResp, url->host_address(),
+ url->port_number());
return;
}
- addSnmpTrapClient(asyncResp, url->host_address(),
- url->port_number());
- return;
- }
-
- std::shared_ptr<Subscription> subValue =
- std::make_shared<Subscription>(*url, app.ioContext());
+ std::shared_ptr<Subscription> subValue =
+ std::make_shared<Subscription>(*url, app.ioContext());
- subValue->destinationUrl = std::move(*url);
+ subValue->destinationUrl = std::move(*url);
- if (subscriptionType)
- {
- if (*subscriptionType != "RedfishEvent")
+ if (subscriptionType)
{
- messages::propertyValueNotInList(
- asyncResp->res, *subscriptionType, "SubscriptionType");
- return;
+ if (*subscriptionType != "RedfishEvent")
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, *subscriptionType, "SubscriptionType");
+ return;
+ }
+ subValue->subscriptionType = *subscriptionType;
}
- subValue->subscriptionType = *subscriptionType;
- }
- else
- {
- subValue->subscriptionType = "RedfishEvent"; // Default
- }
-
- if (protocol != "Redfish")
- {
- messages::propertyValueNotInList(asyncResp->res, protocol,
- "Protocol");
- return;
- }
- subValue->protocol = protocol;
-
- if (eventFormatType2)
- {
- if (std::ranges::find(supportedEvtFormatTypes, *eventFormatType2) ==
- supportedEvtFormatTypes.end())
+ else
{
- messages::propertyValueNotInList(
- asyncResp->res, *eventFormatType2, "EventFormatType");
- return;
+ subValue->subscriptionType = "RedfishEvent"; // Default
}
- subValue->eventFormatType = *eventFormatType2;
- }
- else
- {
- // If not specified, use default "Event"
- subValue->eventFormatType = "Event";
- }
- if (context)
- {
- // This value is selected arbitrarily.
- constexpr const size_t maxContextSize = 256;
- if (context->size() > maxContextSize)
+ if (protocol != "Redfish")
{
- messages::stringValueTooLong(asyncResp->res, "Context",
- maxContextSize);
+ messages::propertyValueNotInList(asyncResp->res, protocol,
+ "Protocol");
return;
}
- subValue->customText = *context;
- }
+ subValue->protocol = protocol;
- if (headers)
- {
- size_t cumulativeLen = 0;
+ if (verifyCertificate)
+ {
+ subValue->verifyCertificate = *verifyCertificate;
+ }
- for (const nlohmann::json::object_t& headerChunk : *headers)
+ if (eventFormatType2)
{
- for (const auto& item : headerChunk)
+ if (std::ranges::find(supportedEvtFormatTypes,
+ *eventFormatType2) ==
+ supportedEvtFormatTypes.end())
{
- const std::string* value =
- item.second.get_ptr<const std::string*>();
- if (value == nullptr)
- {
- messages::propertyValueFormatError(
- asyncResp->res, item.second,
- "HttpHeaders/" + item.first);
- return;
- }
- // Adding a new json value is the size of the key, +
- // the size of the value + 2 * 2 quotes for each, +
- // the colon and space between. example:
- // "key": "value"
- cumulativeLen += item.first.size() + value->size() + 6;
- // This value is selected to mirror http_connection.hpp
- constexpr const uint16_t maxHeaderSizeED = 8096;
- if (cumulativeLen > maxHeaderSizeED)
- {
- messages::arraySizeTooLong(
- asyncResp->res, "HttpHeaders", maxHeaderSizeED);
- return;
- }
- subValue->httpHeaders.set(item.first, *value);
+ messages::propertyValueNotInList(
+ asyncResp->res, *eventFormatType2, "EventFormatType");
+ return;
}
+ subValue->eventFormatType = *eventFormatType2;
+ }
+ else
+ {
+ // If not specified, use default "Event"
+ subValue->eventFormatType = "Event";
}
- }
- if (regPrefixes)
- {
- for (const std::string& it : *regPrefixes)
+ if (context)
{
- if (std::ranges::find(supportedRegPrefixes, it) ==
- supportedRegPrefixes.end())
+ // This value is selected arbitrarily.
+ constexpr const size_t maxContextSize = 256;
+ if (context->size() > maxContextSize)
{
- messages::propertyValueNotInList(asyncResp->res, it,
- "RegistryPrefixes");
+ messages::stringValueTooLong(asyncResp->res, "Context",
+ maxContextSize);
return;
}
+ subValue->customText = *context;
}
- subValue->registryPrefixes = *regPrefixes;
- }
- if (resTypes)
- {
- for (const std::string& it : *resTypes)
+ if (headers)
{
- if (std::ranges::find(supportedResourceTypes, it) ==
- supportedResourceTypes.end())
+ size_t cumulativeLen = 0;
+
+ for (const nlohmann::json::object_t& headerChunk : *headers)
{
- messages::propertyValueNotInList(asyncResp->res, it,
- "ResourceTypes");
- return;
+ for (const auto& item : headerChunk)
+ {
+ const std::string* value =
+ item.second.get_ptr<const std::string*>();
+ if (value == nullptr)
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, item.second,
+ "HttpHeaders/" + item.first);
+ return;
+ }
+ // Adding a new json value is the size of the key, +
+ // the size of the value + 2 * 2 quotes for each, +
+ // the colon and space between. example:
+ // "key": "value"
+ cumulativeLen += item.first.size() + value->size() + 6;
+ // This value is selected to mirror http_connection.hpp
+ constexpr const uint16_t maxHeaderSizeED = 8096;
+ if (cumulativeLen > maxHeaderSizeED)
+ {
+ messages::arraySizeTooLong(
+ asyncResp->res, "HttpHeaders", maxHeaderSizeED);
+ return;
+ }
+ subValue->httpHeaders.set(item.first, *value);
+ }
}
}
- subValue->resourceTypes = *resTypes;
- }
- if (msgIds)
- {
- std::vector<std::string> registryPrefix;
+ if (regPrefixes)
+ {
+ for (const std::string& it : *regPrefixes)
+ {
+ if (std::ranges::find(supportedRegPrefixes, it) ==
+ supportedRegPrefixes.end())
+ {
+ messages::propertyValueNotInList(asyncResp->res, it,
+ "RegistryPrefixes");
+ return;
+ }
+ }
+ subValue->registryPrefixes = *regPrefixes;
+ }
- // If no registry prefixes are mentioned, consider all
- // supported prefixes
- if (subValue->registryPrefixes.empty())
+ if (originResources)
{
- registryPrefix.assign(supportedRegPrefixes.begin(),
- supportedRegPrefixes.end());
+ subValue->originResources = *originResources;
}
- else
+
+ if (resTypes)
{
- registryPrefix = subValue->registryPrefixes;
+ for (const std::string& it : *resTypes)
+ {
+ if (std::ranges::find(supportedResourceTypes, it) ==
+ supportedResourceTypes.end())
+ {
+ messages::propertyValueNotInList(asyncResp->res, it,
+ "ResourceTypes");
+ return;
+ }
+ }
+ subValue->resourceTypes = *resTypes;
}
- for (const std::string& id : *msgIds)
+ if (msgIds)
{
- bool validId = false;
+ std::vector<std::string> registryPrefix;
- // Check for Message ID in each of the selected Registry
- for (const std::string& it : registryPrefix)
+ // If no registry prefixes are mentioned, consider all
+ // supported prefixes
+ if (subValue->registryPrefixes.empty())
+ {
+ registryPrefix.assign(supportedRegPrefixes.begin(),
+ supportedRegPrefixes.end());
+ }
+ else
{
- const std::span<const redfish::registries::MessageEntry>
- registry =
- redfish::registries::getRegistryFromPrefix(it);
+ registryPrefix = subValue->registryPrefixes;
+ }
- if (std::ranges::any_of(
- registry,
- [&id](const redfish::registries::MessageEntry&
- messageEntry) {
- return id == messageEntry.first;
- }))
+ for (const std::string& id : *msgIds)
+ {
+ bool validId = false;
+
+ // Check for Message ID in each of the selected Registry
+ for (const std::string& it : registryPrefix)
{
- validId = true;
- break;
+ const std::span<const redfish::registries::MessageEntry>
+ registry =
+ redfish::registries::getRegistryFromPrefix(it);
+
+ if (std::ranges::any_of(
+ registry,
+ [&id](const redfish::registries::MessageEntry&
+ messageEntry) {
+ return id == messageEntry.first;
+ }))
+ {
+ validId = true;
+ break;
+ }
+ }
+
+ if (!validId)
+ {
+ messages::propertyValueNotInList(asyncResp->res, id,
+ "MessageIds");
+ return;
}
}
- if (!validId)
+ subValue->registryMsgIds = *msgIds;
+ }
+
+ if (retryPolicy)
+ {
+ if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
+ supportedRetryPolicies.end())
{
- messages::propertyValueNotInList(asyncResp->res, id,
- "MessageIds");
+ messages::propertyValueNotInList(
+ asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
return;
}
+ subValue->retryPolicy = *retryPolicy;
}
-
- subValue->registryMsgIds = *msgIds;
- }
-
- if (retryPolicy)
- {
- if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
- supportedRetryPolicies.end())
+ else
{
- messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
- "DeliveryRetryPolicy");
- return;
+ // Default "TerminateAfterRetries"
+ subValue->retryPolicy = "TerminateAfterRetries";
}
- subValue->retryPolicy = *retryPolicy;
- }
- else
- {
- // Default "TerminateAfterRetries"
- subValue->retryPolicy = "TerminateAfterRetries";
- }
- if (mrdJsonArray)
- {
- for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
+ if (mrdJsonArray)
{
- std::string mrdUri;
+ for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
+ {
+ std::string mrdUri;
- if (!json_util::readJsonObject(mrdObj, asyncResp->res,
- "@odata.id", mrdUri))
+ if (!json_util::readJsonObject(mrdObj, asyncResp->res,
+ "@odata.id", mrdUri))
- {
- return;
+ {
+ return;
+ }
+ subValue->metricReportDefinitions.emplace_back(mrdUri);
}
- subValue->metricReportDefinitions.emplace_back(mrdUri);
}
- }
- std::string id =
- EventServiceManager::getInstance().addSubscription(subValue);
- if (id.empty())
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ std::string id =
+ EventServiceManager::getInstance().addPushSubscription(
+ subValue);
+ if (id.empty())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- messages::created(asyncResp->res);
- asyncResp->res.addHeader(
- "Location", "/redfish/v1/EventService/Subscriptions/" + id);
- });
+ messages::created(asyncResp->res);
+ asyncResp->res.addHeader(
+ "Location", "/redfish/v1/EventService/Subscriptions/" + id);
+ });
}
inline void requestRoutesEventDestination(App& app)
@@ -633,55 +662,66 @@ inline void requestRoutesEventDestination(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (param.starts_with("snmp"))
- {
- getSnmpTrapClient(asyncResp, param);
- return;
- }
+ if (param.starts_with("snmp"))
+ {
+ getSnmpTrapClient(asyncResp, param);
+ return;
+ }
- std::shared_ptr<Subscription> subValue =
- EventServiceManager::getInstance().getSubscription(param);
- if (subValue == nullptr)
- {
- asyncResp->res.result(boost::beast::http::status::not_found);
- return;
- }
- const std::string& id = param;
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#EventDestination.v1_8_0.EventDestination";
- asyncResp->res.jsonValue["Protocol"] = "Redfish";
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/EventService/Subscriptions/{}", id);
- asyncResp->res.jsonValue["Id"] = id;
- asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
- asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl;
- asyncResp->res.jsonValue["Context"] = subValue->customText;
- asyncResp->res.jsonValue["SubscriptionType"] =
- subValue->subscriptionType;
- asyncResp->res.jsonValue["HttpHeaders"] = nlohmann::json::array();
- asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType;
- asyncResp->res.jsonValue["RegistryPrefixes"] =
- subValue->registryPrefixes;
- asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes;
-
- asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds;
- asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy;
-
- nlohmann::json::array_t mrdJsonArray;
- for (const auto& mdrUri : subValue->metricReportDefinitions)
- {
- nlohmann::json::object_t mdr;
- mdr["@odata.id"] = mdrUri;
- mrdJsonArray.emplace_back(std::move(mdr));
- }
- asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray;
- });
+ std::shared_ptr<Subscription> subValue =
+ EventServiceManager::getInstance().getSubscription(param);
+ if (subValue == nullptr)
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::not_found);
+ return;
+ }
+ const std::string& id = param;
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EventDestination.v1_14_1.EventDestination";
+ asyncResp->res.jsonValue["Protocol"] =
+ event_destination::EventDestinationProtocol::Redfish;
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/EventService/Subscriptions/{}", id);
+ asyncResp->res.jsonValue["Id"] = id;
+ asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
+ asyncResp->res.jsonValue["Destination"] =
+ subValue->destinationUrl;
+ asyncResp->res.jsonValue["Context"] = subValue->customText;
+ asyncResp->res.jsonValue["SubscriptionType"] =
+ subValue->subscriptionType;
+ asyncResp->res.jsonValue["HttpHeaders"] =
+ nlohmann::json::array();
+ asyncResp->res.jsonValue["EventFormatType"] =
+ subValue->eventFormatType;
+ asyncResp->res.jsonValue["RegistryPrefixes"] =
+ subValue->registryPrefixes;
+ asyncResp->res.jsonValue["ResourceTypes"] =
+ subValue->resourceTypes;
+
+ asyncResp->res.jsonValue["MessageIds"] =
+ subValue->registryMsgIds;
+ asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
+ subValue->retryPolicy;
+ asyncResp->res.jsonValue["VerifyCertificate"] =
+ subValue->verifyCertificate;
+
+ nlohmann::json::array_t mrdJsonArray;
+ for (const auto& mdrUri : subValue->metricReportDefinitions)
+ {
+ nlohmann::json::object_t mdr;
+ mdr["@odata.id"] = mdrUri;
+ mrdJsonArray.emplace_back(std::move(mdr));
+ }
+ asyncResp->res.jsonValue["MetricReportDefinitions"] =
+ mrdJsonArray;
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
// The below privilege is wrong, it should be ConfigureManager OR
// ConfigureSelf
@@ -692,70 +732,81 @@ inline void requestRoutesEventDestination(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- std::shared_ptr<Subscription> subValue =
- EventServiceManager::getInstance().getSubscription(param);
- if (subValue == nullptr)
- {
- asyncResp->res.result(boost::beast::http::status::not_found);
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::shared_ptr<Subscription> subValue =
+ EventServiceManager::getInstance().getSubscription(param);
+ if (subValue == nullptr)
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::not_found);
+ return;
+ }
- std::optional<std::string> context;
- std::optional<std::string> retryPolicy;
- std::optional<std::vector<nlohmann::json::object_t>> headers;
+ std::optional<std::string> context;
+ std::optional<std::string> retryPolicy;
+ std::optional<bool> verifyCertificate;
+ std::optional<std::vector<nlohmann::json::object_t>> headers;
- if (!json_util::readJsonPatch(req, asyncResp->res, "Context", context,
- "DeliveryRetryPolicy", retryPolicy,
- "HttpHeaders", headers))
- {
- return;
- }
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "Context", context,
+ "VerifyCertificate", verifyCertificate,
+ "DeliveryRetryPolicy", retryPolicy, "HttpHeaders",
+ headers))
+ {
+ return;
+ }
- if (context)
- {
- subValue->customText = *context;
- }
+ if (context)
+ {
+ subValue->customText = *context;
+ }
- if (headers)
- {
- boost::beast::http::fields fields;
- for (const nlohmann::json::object_t& headerChunk : *headers)
- {
- for (const auto& it : headerChunk)
+ if (headers)
{
- const std::string* value =
- it.second.get_ptr<const std::string*>();
- if (value == nullptr)
+ boost::beast::http::fields fields;
+ for (const nlohmann::json::object_t& headerChunk : *headers)
{
- messages::propertyValueFormatError(
- asyncResp->res, it.second,
- "HttpHeaders/" + it.first);
+ for (const auto& it : headerChunk)
+ {
+ const std::string* value =
+ it.second.get_ptr<const std::string*>();
+ if (value == nullptr)
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, it.second,
+ "HttpHeaders/" + it.first);
+ return;
+ }
+ fields.set(it.first, *value);
+ }
+ }
+ subValue->httpHeaders = std::move(fields);
+ }
+
+ if (retryPolicy)
+ {
+ if (std::ranges::find(supportedRetryPolicies,
+ *retryPolicy) ==
+ supportedRetryPolicies.end())
+ {
+ messages::propertyValueNotInList(asyncResp->res,
+ *retryPolicy,
+ "DeliveryRetryPolicy");
return;
}
- fields.set(it.first, *value);
+ subValue->retryPolicy = *retryPolicy;
}
- }
- subValue->httpHeaders = std::move(fields);
- }
- if (retryPolicy)
- {
- if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
- supportedRetryPolicies.end())
- {
- messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
- "DeliveryRetryPolicy");
- return;
- }
- subValue->retryPolicy = *retryPolicy;
- }
+ if (verifyCertificate)
+ {
+ subValue->verifyCertificate = *verifyCertificate;
+ }
- EventServiceManager::getInstance().updateSubscriptionData();
- });
+ EventServiceManager::getInstance().updateSubscriptionData();
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
// The below privilege is wrong, it should be ConfigureManager OR
// ConfigureSelf
@@ -766,25 +817,28 @@ inline void requestRoutesEventDestination(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (param.starts_with("snmp"))
- {
- deleteSnmpTrapClient(asyncResp, param);
- EventServiceManager::getInstance().deleteSubscription(param);
- return;
- }
+ if (param.starts_with("snmp"))
+ {
+ deleteSnmpTrapClient(asyncResp, param);
+ EventServiceManager::getInstance().deleteSubscription(
+ param);
+ return;
+ }
- if (!EventServiceManager::getInstance().isSubscriptionExist(param))
- {
- asyncResp->res.result(boost::beast::http::status::not_found);
- return;
- }
- EventServiceManager::getInstance().deleteSubscription(param);
- });
+ if (!EventServiceManager::getInstance().isSubscriptionExist(
+ param))
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::not_found);
+ return;
+ }
+ EventServiceManager::getInstance().deleteSubscription(param);
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/eventservice_sse.hpp b/redfish-core/lib/eventservice_sse.hpp
index 3cbca3bc8b..c0a9527e94 100644
--- a/redfish-core/lib/eventservice_sse.hpp
+++ b/redfish-core/lib/eventservice_sse.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "filter_expr_executor.hpp"
#include "privileges.hpp"
#include "registries/privilege_registry.hpp"
@@ -12,7 +13,8 @@
namespace redfish
{
-inline void createSubscription(crow::sse_socket::Connection& conn)
+inline void createSubscription(crow::sse_socket::Connection& conn,
+ const crow::Request& req)
{
EventServiceManager& manager =
EventServiceManager::getInstance(&conn.getIoContext());
@@ -23,6 +25,25 @@ inline void createSubscription(crow::sse_socket::Connection& conn)
conn.close("Max SSE subscriptions reached");
return;
}
+
+ std::optional<filter_ast::LogicalAnd> filter;
+
+ boost::urls::params_base::iterator filterIt =
+ req.url().params().find("$filter");
+
+ if (filterIt != req.url().params().end())
+ {
+ std::string_view filterValue = (*filterIt).value;
+ filter = parseFilter(filterValue);
+ if (!filter)
+ {
+ conn.close(std::format("Bad $filter param: {}", filterValue));
+ return;
+ }
+ }
+
+ std::string lastEventId(req.getHeaderValue("Last-Event-Id"));
+
std::shared_ptr<redfish::Subscription> subValue =
std::make_shared<redfish::Subscription>(conn);
@@ -32,8 +53,9 @@ inline void createSubscription(crow::sse_socket::Connection& conn)
subValue->protocol = "Redfish";
subValue->retryPolicy = "TerminateAfterRetries";
subValue->eventFormatType = "Event";
+ subValue->filter = filter;
- std::string id = manager.addSubscription(subValue, false);
+ std::string id = manager.addSSESubscription(subValue, lastEventId);
if (id.empty())
{
conn.close("Internal Error");
diff --git a/redfish-core/lib/fabric_adapters.hpp b/redfish-core/lib/fabric_adapters.hpp
index 11dc7c6973..20e6726c07 100644
--- a/redfish-core/lib/fabric_adapters.hpp
+++ b/redfish-core/lib/fabric_adapters.hpp
@@ -2,6 +2,7 @@
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
@@ -32,25 +33,25 @@ inline void getFabricAdapterLocation(
"xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
[asyncResp](const boost::system::error_code& ec,
const std::string& property) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Location");
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Location");
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
- property;
- });
+ asyncResp->res
+ .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+ property;
+ });
}
-inline void
- getFabricAdapterAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& serviceName,
- const std::string& fabricAdapterPath)
+inline void getFabricAdapterAsset(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& serviceName, const std::string& fabricAdapterPath)
{
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, serviceName, fabricAdapterPath,
@@ -58,112 +59,111 @@ inline void
[fabricAdapterPath, asyncResp{asyncResp}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Properties");
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Properties");
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- const std::string* serialNumber = nullptr;
- const std::string* model = nullptr;
- const std::string* partNumber = nullptr;
- const std::string* sparePartNumber = nullptr;
+ const std::string* serialNumber = nullptr;
+ const std::string* model = nullptr;
+ const std::string* partNumber = nullptr;
+ const std::string* sparePartNumber = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList, "SerialNumber",
- serialNumber, "Model", model, "PartNumber", partNumber,
- "SparePartNumber", sparePartNumber);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList,
+ "SerialNumber", serialNumber, "Model", model, "PartNumber",
+ partNumber, "SparePartNumber", sparePartNumber);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (serialNumber != nullptr)
- {
- asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
- }
+ if (serialNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
+ }
- if (model != nullptr)
- {
- asyncResp->res.jsonValue["Model"] = *model;
- }
+ if (model != nullptr)
+ {
+ asyncResp->res.jsonValue["Model"] = *model;
+ }
- if (partNumber != nullptr)
- {
- asyncResp->res.jsonValue["PartNumber"] = *partNumber;
- }
+ if (partNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["PartNumber"] = *partNumber;
+ }
- if (sparePartNumber != nullptr && !sparePartNumber->empty())
- {
- asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
- }
- });
+ if (sparePartNumber != nullptr && !sparePartNumber->empty())
+ {
+ asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
+ }
+ });
}
-inline void
- getFabricAdapterState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& serviceName,
- const std::string& fabricAdapterPath)
+inline void getFabricAdapterState(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& serviceName, const std::string& fabricAdapterPath)
{
sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, serviceName, fabricAdapterPath,
"xyz.openbmc_project.Inventory.Item", "Present",
[asyncResp](const boost::system::error_code& ec, const bool present) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for State");
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for State");
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!present)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- }
- });
+ if (!present)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
+ }
+ });
}
-inline void
- getFabricAdapterHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& serviceName,
- const std::string& fabricAdapterPath)
+inline void getFabricAdapterHealth(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& serviceName, const std::string& fabricAdapterPath)
{
sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, serviceName, fabricAdapterPath,
"xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
[asyncResp](const boost::system::error_code& ec,
const bool functional) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Health");
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Health");
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!functional)
- {
- asyncResp->res.jsonValue["Status"]["Health"] = "Critical";
- }
- });
+ if (!functional)
+ {
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ resource::Health::Critical;
+ }
+ });
}
-inline void doAdapterGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& adapterId,
- const std::string& fabricAdapterPath,
- const std::string& serviceName)
+inline void doAdapterGet(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& adapterId,
+ const std::string& fabricAdapterPath, const std::string& serviceName)
{
asyncResp->res.addHeader(
boost::beast::http::field::link,
@@ -175,8 +175,8 @@ inline void doAdapterGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
"/redfish/v1/Systems/{}/FabricAdapters/{}", systemName, adapterId);
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath);
getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath);
@@ -256,11 +256,10 @@ inline void afterHandleFabricAdapterGet(
serviceName);
}
-inline void
- handleFabricAdapterGet(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& adapterId)
+inline void handleFabricAdapterGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& adapterId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -381,11 +380,10 @@ inline void afterHandleFabricAdapterHead(
"</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
}
-inline void
- handleFabricAdapterHead(crow::App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& adapterId)
+inline void handleFabricAdapterHead(
+ crow::App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& adapterId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
diff --git a/redfish-core/lib/fan.hpp b/redfish-core/lib/fan.hpp
index 39b9e2abd7..28b995e794 100644
--- a/redfish-core/lib/fan.hpp
+++ b/redfish-core/lib/fan.hpp
@@ -3,6 +3,7 @@
#include "app.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/chassis_utils.hpp"
@@ -64,19 +65,19 @@ inline void getFanPaths(
[asyncResp, callback](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR(
- "DBUS response error for getAssociatedSubTreePaths {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBUS response error for getAssociatedSubTreePaths {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- callback(subtreePaths);
- });
+ callback(subtreePaths);
+ });
}
inline void doFanCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -119,15 +120,16 @@ inline void
asyncResp, chassisId,
[asyncResp,
chassisId](const std::optional<std::string>& validChassisPath) {
- if (!validChassisPath)
- {
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
- return;
- }
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/FanCollection/FanCollection.json>; rel=describedby");
- });
+ if (!validChassisPath)
+ {
+ messages::resourceNotFound(asyncResp->res, "Chassis",
+ chassisId);
+ return;
+ }
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/FanCollection/FanCollection.json>; rel=describedby");
+ });
}
inline void
@@ -165,7 +167,7 @@ inline bool checkFanId(const std::string& fanPath, const std::string& fanId)
return !(fanName.empty() || fanName != fanId);
}
-static inline void handleFanPath(
+inline void handleFanPath(
const std::string& fanId,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const dbus::utility::MapperGetSubTreePathsResponse& fanPaths,
@@ -183,15 +185,15 @@ static inline void handleFanPath(
[fanPath, asyncResp,
callback](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& object) {
- if (ec || object.empty())
- {
- BMCWEB_LOG_ERROR("DBUS response error on getDbusObject {}",
- ec.value());
- messages::internalError(asyncResp->res);
- return;
- }
- callback(fanPath, object.begin()->first);
- });
+ if (ec || object.empty())
+ {
+ BMCWEB_LOG_ERROR("DBUS response error on getDbusObject {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ callback(fanPath, object.begin()->first);
+ });
return;
}
@@ -209,8 +211,8 @@ inline void getValidFanPath(
asyncResp, validChassisPath,
[fanId, asyncResp, callback](
const dbus::utility::MapperGetSubTreePathsResponse& fanPaths) {
- handleFanPath(fanId, asyncResp, fanPaths, callback);
- });
+ handleFanPath(fanId, asyncResp, fanPaths, callback);
+ });
}
inline void addFanCommonProperties(crow::Response& resp,
@@ -224,8 +226,8 @@ inline void addFanCommonProperties(crow::Response& resp,
resp.jsonValue["Id"] = fanId;
resp.jsonValue["@odata.id"] = boost::urls::format(
"/redfish/v1/Chassis/{}/ThermalSubsystem/Fans/{}", chassisId, fanId);
- resp.jsonValue["Status"]["State"] = "Enabled";
- resp.jsonValue["Status"]["Health"] = "OK";
+ resp.jsonValue["Status"]["State"] = resource::State::Enabled;
+ resp.jsonValue["Status"]["Health"] = resource::Health::OK;
}
inline void getFanHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -235,22 +237,23 @@ inline void getFanHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
*crow::connections::systemBus, service, fanPath,
"xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
[asyncResp](const boost::system::error_code& ec, const bool value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Health {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Health {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!value)
- {
- asyncResp->res.jsonValue["Status"]["Health"] = "Critical";
- }
- });
+ if (!value)
+ {
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ resource::Health::Critical;
+ }
+ });
}
inline void getFanState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -260,22 +263,23 @@ inline void getFanState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
*crow::connections::systemBus, service, fanPath,
"xyz.openbmc_project.Inventory.Item", "Present",
[asyncResp](const boost::system::error_code& ec, const bool value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for State {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for State {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!value)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- }
- });
+ if (!value)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
+ }
+ });
}
inline void getFanAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -287,52 +291,53 @@ inline void getFanAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
[fanPath, asyncResp{asyncResp}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& assetList) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
+ {
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
+ }
+ const std::string* manufacturer = nullptr;
+ const std::string* model = nullptr;
+ const std::string* partNumber = nullptr;
+ const std::string* serialNumber = nullptr;
+ const std::string* sparePartNumber = nullptr;
+
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
+ manufacturer, "Model", model, "PartNumber", partNumber,
+ "SerialNumber", serialNumber, "SparePartNumber",
+ sparePartNumber);
+ if (!success)
{
- BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
- ec.value());
messages::internalError(asyncResp->res);
+ return;
}
- return;
- }
- const std::string* manufacturer = nullptr;
- const std::string* model = nullptr;
- const std::string* partNumber = nullptr;
- const std::string* serialNumber = nullptr;
- const std::string* sparePartNumber = nullptr;
-
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
- manufacturer, "Model", model, "PartNumber", partNumber,
- "SerialNumber", serialNumber, "SparePartNumber", sparePartNumber);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- if (manufacturer != nullptr)
- {
- asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
- }
- if (model != nullptr)
- {
- asyncResp->res.jsonValue["Model"] = *model;
- }
- if (partNumber != nullptr)
- {
- asyncResp->res.jsonValue["PartNumber"] = *partNumber;
- }
- if (serialNumber != nullptr)
- {
- asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
- }
- if (sparePartNumber != nullptr && !sparePartNumber->empty())
- {
- asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
- }
- });
+ if (manufacturer != nullptr)
+ {
+ asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
+ }
+ if (model != nullptr)
+ {
+ asyncResp->res.jsonValue["Model"] = *model;
+ }
+ if (partNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["PartNumber"] = *partNumber;
+ }
+ if (serialNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
+ }
+ if (sparePartNumber != nullptr && !sparePartNumber->empty())
+ {
+ asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
+ }
+ });
}
inline void getFanLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -344,19 +349,20 @@ inline void getFanLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
"xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
[asyncResp](const boost::system::error_code& ec,
const std::string& property) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Location{}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Location{}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
- property;
- });
+ asyncResp->res
+ .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+ property;
+ });
}
inline void
@@ -400,18 +406,20 @@ inline void handleFanHead(App& app, const crow::Request& req,
asyncResp, chassisId,
[asyncResp, chassisId,
fanId](const std::optional<std::string>& validChassisPath) {
- if (!validChassisPath)
- {
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
- return;
- }
- getValidFanPath(asyncResp, *validChassisPath, fanId,
- [asyncResp](const std::string&, const std::string&) {
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/Fan/Fan.json>; rel=describedby");
+ if (!validChassisPath)
+ {
+ messages::resourceNotFound(asyncResp->res, "Chassis",
+ chassisId);
+ return;
+ }
+ getValidFanPath(
+ asyncResp, *validChassisPath, fanId,
+ [asyncResp](const std::string&, const std::string&) {
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/Fan/Fan.json>; rel=describedby");
+ });
});
- });
}
inline void handleFanGet(App& app, const crow::Request& req,
diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp
index 963fbfb84b..cc9d4c0313 100644
--- a/redfish-core/lib/hypervisor_system.hpp
+++ b/redfish-core/lib/hypervisor_system.hpp
@@ -5,6 +5,9 @@
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "ethernet.hpp"
+#include "generated/enums/action_info.hpp"
+#include "generated/enums/computer_system.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/ip_utils.hpp"
@@ -41,56 +44,69 @@ inline void
"xyz.openbmc_project.State.Host", "CurrentHostState",
[asyncResp](const boost::system::error_code& ec,
const std::string& hostState) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- // This is an optional D-Bus object so just return if
- // error occurs
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ // This is an optional D-Bus object so just return if
+ // error occurs
+ return;
+ }
- BMCWEB_LOG_DEBUG("Hypervisor state: {}", hostState);
- // Verify Host State
- if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
- {
- asyncResp->res.jsonValue["PowerState"] = "On";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- }
- else if (hostState == "xyz.openbmc_project.State.Host.HostState."
- "Quiesced")
- {
- asyncResp->res.jsonValue["PowerState"] = "On";
- asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
- }
- else if (hostState == "xyz.openbmc_project.State.Host.HostState."
- "Standby")
- {
- asyncResp->res.jsonValue["PowerState"] = "On";
- asyncResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
- }
- else if (hostState == "xyz.openbmc_project.State.Host.HostState."
- "TransitioningToRunning")
- {
- asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
- asyncResp->res.jsonValue["Status"]["State"] = "Starting";
- }
- else if (hostState == "xyz.openbmc_project.State.Host.HostState."
- "TransitioningToOff")
- {
- asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- }
- else if (hostState == "xyz.openbmc_project.State.Host.HostState.Off")
- {
- asyncResp->res.jsonValue["PowerState"] = "Off";
- asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
- }
- else
- {
- messages::internalError(asyncResp->res);
- return;
- }
- });
+ BMCWEB_LOG_DEBUG("Hypervisor state: {}", hostState);
+ // Verify Host State
+ if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::On;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+ }
+ else if (hostState == "xyz.openbmc_project.State.Host.HostState."
+ "Quiesced")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::On;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Quiesced;
+ }
+ else if (hostState == "xyz.openbmc_project.State.Host.HostState."
+ "Standby")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::On;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::StandbyOffline;
+ }
+ else if (hostState == "xyz.openbmc_project.State.Host.HostState."
+ "TransitioningToRunning")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::PoweringOn;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Starting;
+ }
+ else if (hostState == "xyz.openbmc_project.State.Host.HostState."
+ "TransitioningToOff")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::PoweringOff;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+ }
+ else if (hostState ==
+ "xyz.openbmc_project.State.Host.HostState.Off")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::Off;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Disabled;
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ });
}
/**
@@ -115,37 +131,37 @@ inline void
const boost::system::error_code& ec,
const std::vector<std::pair<std::string, std::vector<std::string>>>&
objInfo) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- // This is an optional D-Bus object so just return if
- // error occurs
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ // This is an optional D-Bus object so just return if
+ // error occurs
+ return;
+ }
- if (objInfo.empty())
- {
- // As noted above, this is an optional interface so just return
- // if there is no instance found
- return;
- }
+ if (objInfo.empty())
+ {
+ // As noted above, this is an optional interface so just return
+ // if there is no instance found
+ return;
+ }
- if (objInfo.size() > 1)
- {
- // More then one hypervisor object is not supported and is an
- // error
- messages::internalError(asyncResp->res);
- return;
- }
+ if (objInfo.size() > 1)
+ {
+ // More then one hypervisor object is not supported and is an
+ // error
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // Object present so system support limited ComputerSystem Action
- nlohmann::json& reset =
- asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"];
- reset["target"] =
- "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset";
- reset["@Redfish.ActionInfo"] =
- "/redfish/v1/Systems/hypervisor/ResetActionInfo";
- });
+ // Object present so system support limited ComputerSystem Action
+ nlohmann::json& reset =
+ asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"];
+ reset["target"] =
+ "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset";
+ reset["@Redfish.ActionInfo"] =
+ "/redfish/v1/Systems/hypervisor/ResetActionInfo";
+ });
}
inline bool extractHypervisorInterfaceData(
@@ -162,23 +178,8 @@ inline bool extractHypervisorInterfaceData(
"/xyz/openbmc_project/network/hypervisor/" + ethIfaceId)
{
idFound = true;
- if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress")
- {
- for (const auto& propertyPair : ifacePair.second)
- {
- if (propertyPair.first == "MACAddress")
- {
- const std::string* mac =
- std::get_if<std::string>(&propertyPair.second);
- if (mac != nullptr)
- {
- ethData.macAddress = *mac;
- }
- }
- }
- }
- else if (ifacePair.first ==
- "xyz.openbmc_project.Network.EthernetInterface")
+ if (ifacePair.first ==
+ "xyz.openbmc_project.Network.EthernetInterface")
{
for (const auto& propertyPair : ifacePair.second)
{
@@ -318,22 +319,22 @@ void getHypervisorIfaceData(const std::string& ethIfaceId,
callback = std::forward<CallbackFunc>(callback)](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& resp) mutable {
- EthernetInterfaceData ethData{};
- std::vector<IPv4AddressData> ipv4Data;
- if (ec)
- {
- callback(false, ethData, ipv4Data);
- return;
- }
+ EthernetInterfaceData ethData{};
+ std::vector<IPv4AddressData> ipv4Data;
+ if (ec)
+ {
+ callback(false, ethData, ipv4Data);
+ return;
+ }
- bool found = extractHypervisorInterfaceData(ethIfaceId, resp, ethData,
- ipv4Data);
- if (!found)
- {
- BMCWEB_LOG_INFO("Hypervisor Interface not found");
- }
- callback(found, ethData, ipv4Data);
- });
+ bool found = extractHypervisorInterfaceData(ethIfaceId, resp,
+ ethData, ipv4Data);
+ if (!found)
+ {
+ BMCWEB_LOG_INFO("Hypervisor Interface not found");
+ }
+ callback(found, ethData, ipv4Data);
+ });
}
/**
@@ -352,11 +353,11 @@ inline void setHypervisorIPv4Address(
BMCWEB_LOG_DEBUG("Setting the Hypervisor IPaddress : {} on Iface: {}",
ipv4Address, ethIfaceId);
- setDbusProperty(asyncResp, "IPv4StaticAddresses/1/Address",
- "xyz.openbmc_project.Settings",
- "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId +
- "/ipv4/addr0",
- "xyz.openbmc_project.Network.IP", "Address", ipv4Address);
+ setDbusProperty(
+ asyncResp, "IPv4StaticAddresses/1/Address",
+ "xyz.openbmc_project.Settings",
+ "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId + "/ipv4/addr0",
+ "xyz.openbmc_project.Network.IP", "Address", ipv4Address);
}
/**
@@ -375,11 +376,11 @@ inline void
BMCWEB_LOG_DEBUG("Setting the Hypervisor subnet : {} on Iface: {}", subnet,
ethIfaceId);
- setDbusProperty(asyncResp, "IPv4StaticAddresses/1/SubnetMask",
- "xyz.openbmc_project.Settings",
- "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId +
- "/ipv4/addr0",
- "xyz.openbmc_project.Network.IP", "PrefixLength", subnet);
+ setDbusProperty(
+ asyncResp, "IPv4StaticAddresses/1/SubnetMask",
+ "xyz.openbmc_project.Settings",
+ "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId + "/ipv4/addr0",
+ "xyz.openbmc_project.Network.IP", "PrefixLength", subnet);
}
/**
@@ -456,8 +457,6 @@ inline void parseInterfaceData(nlohmann::json& jsonResponse,
jsonResponse["@odata.id"] = boost::urls::format(
"/redfish/v1/Systems/hypervisor/EthernetInterfaces/{}", ifaceId);
jsonResponse["InterfaceEnabled"] = true;
- jsonResponse["MACAddress"] = ethData.macAddress;
-
jsonResponse["HostName"] = ethData.hostName;
jsonResponse["DHCPv4"]["DHCPEnabled"] =
translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
@@ -512,11 +511,11 @@ inline void setDHCPEnabled(const std::string& ifaceId, bool ipv4DHCPEnabled,
origin = "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
}
- setDbusProperty(asyncResp, "IPv4StaticAddresses/1/AddressOrigin",
- "xyz.openbmc_project.Settings",
- "/xyz/openbmc_project/network/hypervisor/" + ifaceId +
- "/ipv4/addr0",
- "xyz.openbmc_project.Network.IP", "Origin", origin);
+ setDbusProperty(
+ asyncResp, "IPv4StaticAddresses/1/AddressOrigin",
+ "xyz.openbmc_project.Settings",
+ "/xyz/openbmc_project/network/hypervisor/" + ifaceId + "/ipv4/addr0",
+ "xyz.openbmc_project.Network.IP", "Origin", origin);
}
inline void handleHypervisorIPv4StaticPatch(
@@ -625,39 +624,41 @@ inline void handleHypervisorEthernetInterfaceCollectionGet(
[asyncResp](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& ifaceList) {
- if (ec)
- {
- messages::resourceNotFound(asyncResp->res, "System", "hypervisor");
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#EthernetInterfaceCollection."
- "EthernetInterfaceCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
- asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet "
- "Interface Collection";
- asyncResp->res.jsonValue["Description"] =
- "Collection of Virtual Management "
- "Interfaces for the hypervisor";
-
- nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
- ifaceArray = nlohmann::json::array();
- for (const std::string& iface : ifaceList)
- {
- sdbusplus::message::object_path path(iface);
- std::string name = path.filename();
- if (name.empty())
+ if (ec)
{
- continue;
+ messages::resourceNotFound(asyncResp->res, "System",
+ "hypervisor");
+ return;
}
- nlohmann::json::object_t ethIface;
- ethIface["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/hypervisor/EthernetInterfaces/{}", name);
- ifaceArray.emplace_back(std::move(ethIface));
- }
- asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size();
- });
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EthernetInterfaceCollection."
+ "EthernetInterfaceCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
+ asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet "
+ "Interface Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of Virtual Management "
+ "Interfaces for the hypervisor";
+
+ nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
+ ifaceArray = nlohmann::json::array();
+ for (const std::string& iface : ifaceList)
+ {
+ sdbusplus::message::object_path path(iface);
+ std::string name = path.filename();
+ if (name.empty())
+ {
+ continue;
+ }
+ nlohmann::json::object_t ethIface;
+ ethIface["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/hypervisor/EthernetInterfaces/{}",
+ name);
+ ifaceArray.emplace_back(std::move(ethIface));
+ }
+ asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size();
+ });
}
inline void handleHypervisorEthernetInterfaceGet(
@@ -672,58 +673,43 @@ inline void handleHypervisorEthernetInterfaceGet(
id, [asyncResp, ifaceId{std::string(id)}](
bool success, const EthernetInterfaceData& ethData,
const std::vector<IPv4AddressData>& ipv4Data) {
- if (!success)
- {
- messages::resourceNotFound(asyncResp->res, "EthernetInterface",
- ifaceId);
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#EthernetInterface.v1_9_0.EthernetInterface";
- asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet Interface";
- asyncResp->res.jsonValue["Description"] =
- "Hypervisor's Virtual Management Ethernet Interface";
- parseInterfaceData(asyncResp->res.jsonValue, ifaceId, ethData,
- ipv4Data);
- });
+ if (!success)
+ {
+ messages::resourceNotFound(asyncResp->res, "EthernetInterface",
+ ifaceId);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EthernetInterface.v1_9_0.EthernetInterface";
+ asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet Interface";
+ asyncResp->res.jsonValue["Description"] =
+ "Hypervisor's Virtual Management Ethernet Interface";
+ parseInterfaceData(asyncResp->res.jsonValue, ifaceId, ethData,
+ ipv4Data);
+ });
}
inline void handleHypervisorSystemGet(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- sdbusplus::asio::getProperty<std::string>(
- *crow::connections::systemBus, "xyz.openbmc_project.Settings",
- "/xyz/openbmc_project/network/hypervisor",
- "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
- [asyncResp](const boost::system::error_code& ec,
- const std::string& /*hostName*/) {
- if (ec)
- {
- messages::resourceNotFound(asyncResp->res, "System", "hypervisor");
- return;
- }
- BMCWEB_LOG_DEBUG("Hypervisor is available");
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#ComputerSystem.v1_6_0.ComputerSystem";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/hypervisor";
- asyncResp->res.jsonValue["Description"] = "Hypervisor";
- asyncResp->res.jsonValue["Name"] = "Hypervisor";
- asyncResp->res.jsonValue["Id"] = "hypervisor";
- asyncResp->res.jsonValue["SystemType"] = "OS";
- nlohmann::json::array_t managedBy;
- nlohmann::json::object_t manager;
- manager["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}", BMCWEB_REDFISH_MANAGER_URI_NAME);
- managedBy.emplace_back(std::move(manager));
- asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
- asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
- "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
- getHypervisorState(asyncResp);
- getHypervisorActions(asyncResp);
- // TODO: Add "SystemType" : "hypervisor"
- });
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ComputerSystem.v1_6_0.ComputerSystem";
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/hypervisor";
+ asyncResp->res.jsonValue["Description"] = "Hypervisor";
+ asyncResp->res.jsonValue["Name"] = "Hypervisor";
+ asyncResp->res.jsonValue["Id"] = "hypervisor";
+ asyncResp->res.jsonValue["SystemType"] = computer_system::SystemType::OS;
+ nlohmann::json::array_t managedBy;
+ nlohmann::json::object_t manager;
+ manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ managedBy.emplace_back(std::move(manager));
+ asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
+ asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
+ "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
+ getHypervisorState(asyncResp);
+ getHypervisorActions(asyncResp);
+ // TODO: Add "SystemType" : "hypervisor"
}
inline void handleHypervisorEthernetInterfacePatch(
@@ -742,10 +728,10 @@ inline void handleHypervisorEthernetInterfacePatch(
std::optional<std::vector<nlohmann::json::object_t>> ipv4Addresses;
std::optional<bool> ipv4DHCPEnabled;
- if (!json_util::readJsonPatch(req, asyncResp->res, "HostName", hostName,
- "IPv4StaticAddresses", ipv4StaticAddresses,
- "IPv4Addresses", ipv4Addresses,
- "DHCPv4/DHCPEnabled", ipv4DHCPEnabled))
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "HostName", hostName, "IPv4StaticAddresses",
+ ipv4StaticAddresses, "IPv4Addresses", ipv4Addresses,
+ "DHCPv4/DHCPEnabled", ipv4DHCPEnabled))
{
return;
}
@@ -762,67 +748,70 @@ inline void handleHypervisorEthernetInterfacePatch(
ipv4StaticAddresses = std::move(ipv4StaticAddresses),
ipv4DHCPEnabled](bool success, const EthernetInterfaceData& ethData,
const std::vector<IPv4AddressData>&) mutable {
- if (!success)
- {
- messages::resourceNotFound(asyncResp->res, "EthernetInterface",
- ifaceId);
- return;
- }
-
- if (ipv4StaticAddresses)
- {
- std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>&
- ipv4Static = *ipv4StaticAddresses;
- if (ipv4Static.begin() == ipv4Static.end())
+ if (!success)
{
- messages::propertyValueTypeError(asyncResp->res,
- std::vector<std::string>(),
- "IPv4StaticAddresses");
+ messages::resourceNotFound(asyncResp->res, "EthernetInterface",
+ ifaceId);
return;
}
- // One and only one hypervisor instance supported
- if (ipv4Static.size() != 1)
+ if (ipv4StaticAddresses)
{
- messages::propertyValueFormatError(asyncResp->res, "[]",
- "IPv4StaticAddresses");
- return;
+ std::vector<std::variant<nlohmann::json::object_t,
+ std::nullptr_t>>& ipv4Static =
+ *ipv4StaticAddresses;
+ if (ipv4Static.begin() == ipv4Static.end())
+ {
+ messages::propertyValueTypeError(asyncResp->res,
+ std::vector<std::string>(),
+ "IPv4StaticAddresses");
+ return;
+ }
+
+ // One and only one hypervisor instance supported
+ if (ipv4Static.size() != 1)
+ {
+ messages::propertyValueFormatError(asyncResp->res, "[]",
+ "IPv4StaticAddresses");
+ return;
+ }
+
+ std::variant<nlohmann::json::object_t, std::nullptr_t>&
+ ipv4Json = ipv4Static[0];
+ // Check if the param is 'null'. If its null, it means
+ // that user wants to delete the IP address. Deleting
+ // the IP address is allowed only if its statically
+ // configured. Deleting the address originated from DHCP
+ // is not allowed.
+ if (std::holds_alternative<std::nullptr_t>(ipv4Json) &&
+ translateDhcpEnabledToBool(ethData.dhcpEnabled, true))
+ {
+ BMCWEB_LOG_INFO(
+ "Ignoring the delete on ipv4StaticAddresses "
+ "as the interface is DHCP enabled");
+ }
+ else
+ {
+ handleHypervisorIPv4StaticPatch(ifaceId, ipv4Static,
+ asyncResp);
+ }
}
- std::variant<nlohmann::json::object_t, std::nullptr_t>& ipv4Json =
- ipv4Static[0];
- // Check if the param is 'null'. If its null, it means
- // that user wants to delete the IP address. Deleting
- // the IP address is allowed only if its statically
- // configured. Deleting the address originated from DHCP
- // is not allowed.
- if (std::holds_alternative<std::nullptr_t>(ipv4Json) &&
- translateDhcpEnabledToBool(ethData.dhcpEnabled, true))
+ if (hostName)
{
- BMCWEB_LOG_INFO("Ignoring the delete on ipv4StaticAddresses "
- "as the interface is DHCP enabled");
+ handleHypervisorHostnamePatch(*hostName, asyncResp);
}
- else
+
+ if (ipv4DHCPEnabled)
{
- handleHypervisorIPv4StaticPatch(ifaceId, ipv4Static, asyncResp);
+ setDHCPEnabled(ifaceId, *ipv4DHCPEnabled, asyncResp);
}
- }
-
- if (hostName)
- {
- handleHypervisorHostnamePatch(*hostName, asyncResp);
- }
- if (ipv4DHCPEnabled)
- {
- setDHCPEnabled(ifaceId, *ipv4DHCPEnabled, asyncResp);
- }
-
- // Set this interface to disabled/inactive. This will be set
- // to enabled/active by the pldm once the hypervisor
- // consumes the updated settings from the user.
- setIPv4InterfaceEnabled(ifaceId, false, asyncResp);
- });
+ // Set this interface to disabled/inactive. This will be set
+ // to enabled/active by the pldm once the hypervisor
+ // consumes the updated settings from the user.
+ setIPv4InterfaceEnabled(ifaceId, false, asyncResp);
+ });
asyncResp->res.result(boost::beast::http::status::accepted);
}
@@ -838,60 +827,56 @@ inline void handleHypervisorResetActionGet(
const boost::system::error_code& ec,
const std::vector<std::pair<std::string, std::vector<std::string>>>&
objInfo) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
-
- // No hypervisor objects found by mapper
- if (ec.value() == boost::system::errc::io_error)
+ if (ec)
{
- messages::resourceNotFound(asyncResp->res, "hypervisor",
- "ResetActionInfo");
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+
+ // No hypervisor objects found by mapper
+ if (ec.value() == boost::system::errc::io_error)
+ {
+ messages::resourceNotFound(asyncResp->res, "hypervisor",
+ "ResetActionInfo");
+ return;
+ }
+
+ messages::internalError(asyncResp->res);
return;
}
- messages::internalError(asyncResp->res);
- return;
- }
-
- // One and only one hypervisor instance supported
- if (objInfo.size() != 1)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ // One and only one hypervisor instance supported
+ if (objInfo.size() != 1)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // The hypervisor object only support the ability to
- // turn On The system object Action should be utilized
- // for other operations
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#ActionInfo.v1_1_2.ActionInfo";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/hypervisor/ResetActionInfo";
- asyncResp->res.jsonValue["Name"] = "Reset Action Info";
- asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
- nlohmann::json::array_t parameters;
- nlohmann::json::object_t parameter;
- parameter["Name"] = "ResetType";
- parameter["Required"] = true;
- parameter["DataType"] = "String";
- nlohmann::json::array_t allowed;
- allowed.emplace_back("On");
- parameter["AllowableValues"] = std::move(allowed);
- parameters.emplace_back(std::move(parameter));
- asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
- });
+ // The hypervisor object only support the ability to
+ // turn On The system object Action should be utilized
+ // for other operations
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ActionInfo.v1_1_2.ActionInfo";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Systems/hypervisor/ResetActionInfo";
+ asyncResp->res.jsonValue["Name"] = "Reset Action Info";
+ asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
+ nlohmann::json::array_t parameters;
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = action_info::ParameterTypes::String;
+ nlohmann::json::array_t allowed;
+ allowed.emplace_back("On");
+ parameter["AllowableValues"] = std::move(allowed);
+ parameters.emplace_back(std::move(parameter));
+ asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
+ });
}
inline void handleHypervisorSystemResetPost(
- App& app, const crow::Request& req,
+ const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
std::optional<std::string> resetType;
if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
{
@@ -916,12 +901,12 @@ inline void handleHypervisorSystemResetPost(
std::string command = "xyz.openbmc_project.State.Host.Transition.On";
- setDbusPropertyAction(asyncResp, "xyz.openbmc_project.State.Hypervisor",
- sdbusplus::message::object_path(
- "/xyz/openbmc_project/state/hypervisor0"),
- "xyz.openbmc_project.State.Host",
- "RequestedHostTransition", "ResetType",
- "ComputerSystem.Reset", command);
+ setDbusPropertyAction(
+ asyncResp, "xyz.openbmc_project.State.Hypervisor",
+ sdbusplus::message::object_path(
+ "/xyz/openbmc_project/state/hypervisor0"),
+ "xyz.openbmc_project.State.Host", "RequestedHostTransition",
+ "ResetType", "ComputerSystem.Reset", command);
}
inline void requestRoutesHypervisorSystems(App& app)
@@ -947,11 +932,5 @@ inline void requestRoutesHypervisorSystems(App& app)
.privileges(redfish::privileges::patchEthernetInterface)
.methods(boost::beast::http::verb::patch)(std::bind_front(
handleHypervisorEthernetInterfacePatch, std::ref(app)));
-
- BMCWEB_ROUTE(app,
- "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset/")
- .privileges(redfish::privileges::postComputerSystem)
- .methods(boost::beast::http::verb::post)(
- std::bind_front(handleHypervisorSystemResetPost, std::ref(app)));
}
} // namespace redfish
diff --git a/redfish-core/lib/led.hpp b/redfish-core/lib/led.hpp
index 8cbe86ac94..1acde11dc8 100644
--- a/redfish-core/lib/led.hpp
+++ b/redfish-core/lib/led.hpp
@@ -1,23 +1,24 @@
/*
-// Copyright (c) 2019 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2019 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/chassis.hpp"
#include "redfish_util.hpp"
#include <sdbusplus/asio/property.hpp>
@@ -41,53 +42,56 @@ inline void
"/xyz/openbmc_project/led/groups/enclosure_identify_blink",
"xyz.openbmc_project.Led.Group", "Asserted",
[asyncResp](const boost::system::error_code& ec, const bool blinking) {
- // Some systems may not have enclosure_identify_blink object so
- // proceed to get enclosure_identify state.
- if (ec == boost::system::errc::invalid_argument)
- {
- BMCWEB_LOG_DEBUG(
- "Get identity blinking LED failed, mismatch in property type");
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Blinking ON, no need to check enclosure_identify assert.
- if (!ec && blinking)
- {
- asyncResp->res.jsonValue["IndicatorLED"] = "Blinking";
- return;
- }
-
- sdbusplus::asio::getProperty<bool>(
- *crow::connections::systemBus,
- "xyz.openbmc_project.LED.GroupManager",
- "/xyz/openbmc_project/led/groups/enclosure_identify",
- "xyz.openbmc_project.Led.Group", "Asserted",
- [asyncResp](const boost::system::error_code& ec2,
- const bool ledOn) {
- if (ec2 == boost::system::errc::invalid_argument)
+ // Some systems may not have enclosure_identify_blink object so
+ // proceed to get enclosure_identify state.
+ if (ec == boost::system::errc::invalid_argument)
{
BMCWEB_LOG_DEBUG(
- "Get enclosure identity led failed, mismatch in property type");
+ "Get identity blinking LED failed, mismatch in property type");
messages::internalError(asyncResp->res);
return;
}
- if (ec2)
+ // Blinking ON, no need to check enclosure_identify assert.
+ if (!ec && blinking)
{
+ asyncResp->res.jsonValue["IndicatorLED"] =
+ chassis::IndicatorLED::Blinking;
return;
}
- if (ledOn)
- {
- asyncResp->res.jsonValue["IndicatorLED"] = "Lit";
- }
- else
- {
- asyncResp->res.jsonValue["IndicatorLED"] = "Off";
- }
+ sdbusplus::asio::getProperty<bool>(
+ *crow::connections::systemBus,
+ "xyz.openbmc_project.LED.GroupManager",
+ "/xyz/openbmc_project/led/groups/enclosure_identify",
+ "xyz.openbmc_project.Led.Group", "Asserted",
+ [asyncResp](const boost::system::error_code& ec2,
+ const bool ledOn) {
+ if (ec2 == boost::system::errc::invalid_argument)
+ {
+ BMCWEB_LOG_DEBUG(
+ "Get enclosure identity led failed, mismatch in property type");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (ec2)
+ {
+ return;
+ }
+
+ if (ledOn)
+ {
+ asyncResp->res.jsonValue["IndicatorLED"] =
+ chassis::IndicatorLED::Lit;
+ }
+ else
+ {
+ asyncResp->res.jsonValue["IndicatorLED"] =
+ chassis::IndicatorLED::Off;
+ }
+ });
});
- });
}
/**
@@ -128,22 +132,23 @@ inline void
"xyz.openbmc_project.Led.Group", "Asserted", ledBlinkng,
[asyncResp, ledOn,
ledBlinkng](const boost::system::error_code& ec) mutable {
- if (ec)
- {
- // Some systems may not have enclosure_identify_blink object so
- // Lets set enclosure_identify state to true if Blinking is
- // true.
- if (ledBlinkng)
+ if (ec)
{
- ledOn = true;
+ // Some systems may not have enclosure_identify_blink object so
+ // Lets set enclosure_identify state to true if Blinking is
+ // true.
+ if (ledBlinkng)
+ {
+ ledOn = true;
+ }
}
- }
- setDbusProperty(
- asyncResp, "IndicatorLED", "xyz.openbmc_project.LED.GroupManager",
- sdbusplus::message::object_path(
- "/xyz/openbmc_project/led/groups/enclosure_identify"),
- "xyz.openbmc_project.Led.Group", "Asserted", ledBlinkng);
- });
+ setDbusProperty(
+ asyncResp, "IndicatorLED",
+ "xyz.openbmc_project.LED.GroupManager",
+ sdbusplus::message::object_path(
+ "/xyz/openbmc_project/led/groups/enclosure_identify"),
+ "xyz.openbmc_project.Led.Group", "Asserted", ledBlinkng);
+ });
}
/**
@@ -162,46 +167,46 @@ inline void getSystemLocationIndicatorActive(
"/xyz/openbmc_project/led/groups/enclosure_identify_blink",
"xyz.openbmc_project.Led.Group", "Asserted",
[asyncResp](const boost::system::error_code& ec, const bool blinking) {
- // Some systems may not have enclosure_identify_blink object so
- // proceed to get enclosure_identify state.
- if (ec == boost::system::errc::invalid_argument)
- {
- BMCWEB_LOG_DEBUG(
- "Get identity blinking LED failed, mismatch in property type");
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Blinking ON, no need to check enclosure_identify assert.
- if (!ec && blinking)
- {
- asyncResp->res.jsonValue["LocationIndicatorActive"] = true;
- return;
- }
-
- sdbusplus::asio::getProperty<bool>(
- *crow::connections::systemBus,
- "xyz.openbmc_project.LED.GroupManager",
- "/xyz/openbmc_project/led/groups/enclosure_identify",
- "xyz.openbmc_project.Led.Group", "Asserted",
- [asyncResp](const boost::system::error_code& ec2,
- const bool ledOn) {
- if (ec2 == boost::system::errc::invalid_argument)
+ // Some systems may not have enclosure_identify_blink object so
+ // proceed to get enclosure_identify state.
+ if (ec == boost::system::errc::invalid_argument)
{
BMCWEB_LOG_DEBUG(
- "Get enclosure identity led failed, mismatch in property type");
+ "Get identity blinking LED failed, mismatch in property type");
messages::internalError(asyncResp->res);
return;
}
- if (ec2)
+ // Blinking ON, no need to check enclosure_identify assert.
+ if (!ec && blinking)
{
+ asyncResp->res.jsonValue["LocationIndicatorActive"] = true;
return;
}
- asyncResp->res.jsonValue["LocationIndicatorActive"] = ledOn;
+ sdbusplus::asio::getProperty<bool>(
+ *crow::connections::systemBus,
+ "xyz.openbmc_project.LED.GroupManager",
+ "/xyz/openbmc_project/led/groups/enclosure_identify",
+ "xyz.openbmc_project.Led.Group", "Asserted",
+ [asyncResp](const boost::system::error_code& ec2,
+ const bool ledOn) {
+ if (ec2 == boost::system::errc::invalid_argument)
+ {
+ BMCWEB_LOG_DEBUG(
+ "Get enclosure identity led failed, mismatch in property type");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (ec2)
+ {
+ return;
+ }
+
+ asyncResp->res.jsonValue["LocationIndicatorActive"] = ledOn;
+ });
});
- });
}
/**
@@ -222,18 +227,18 @@ inline void setSystemLocationIndicatorActive(
"/xyz/openbmc_project/led/groups/enclosure_identify_blink",
"xyz.openbmc_project.Led.Group", "Asserted", ledState,
[asyncResp, ledState](const boost::system::error_code& ec) {
- if (ec)
- {
- // Some systems may not have enclosure_identify_blink object so
- // lets set enclosure_identify state also if
- // enclosure_identify_blink failed
- setDbusProperty(
- asyncResp, "LocationIndicatorActive",
- "xyz.openbmc_project.LED.GroupManager",
- sdbusplus::message::object_path(
- "/xyz/openbmc_project/led/groups/enclosure_identify"),
- "xyz.openbmc_project.Led.Group", "Asserted", ledState);
- }
- });
+ if (ec)
+ {
+ // Some systems may not have enclosure_identify_blink object so
+ // lets set enclosure_identify state also if
+ // enclosure_identify_blink failed
+ setDbusProperty(
+ asyncResp, "LocationIndicatorActive",
+ "xyz.openbmc_project.LED.GroupManager",
+ sdbusplus::message::object_path(
+ "/xyz/openbmc_project/led/groups/enclosure_identify"),
+ "xyz.openbmc_project.Led.Group", "Asserted", ledState);
+ }
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index da2d1b55ad..639a31488c 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -19,6 +19,7 @@
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "generated/enums/log_entry.hpp"
+#include "generated/enums/log_service.hpp"
#include "gzfile.hpp"
#include "http_utility.hpp"
#include "human_sort.hpp"
@@ -29,12 +30,12 @@
#include "registries/privilege_registry.hpp"
#include "task.hpp"
#include "task_messages.hpp"
+#include "utils/dbus_event_log_entry.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/time_utils.hpp"
#include <systemd/sd-id128.h>
-#include <systemd/sd-journal.h>
#include <tinyxml2.h>
#include <unistd.h>
@@ -125,110 +126,7 @@ inline std::string getDumpPath(std::string_view dumpType)
return dbusDumpPath;
}
-inline int getJournalMetadata(sd_journal* journal, std::string_view field,
- std::string_view& contents)
-{
- const char* data = nullptr;
- size_t length = 0;
- int ret = 0;
- // Get the metadata from the requested field of the journal entry
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const void** dataVoid = reinterpret_cast<const void**>(&data);
-
- ret = sd_journal_get_data(journal, field.data(), dataVoid, &length);
- if (ret < 0)
- {
- return ret;
- }
- contents = std::string_view(data, length);
- // Only use the content after the "=" character.
- contents.remove_prefix(std::min(contents.find('=') + 1, contents.size()));
- return ret;
-}
-
-inline int getJournalMetadata(sd_journal* journal, std::string_view field,
- const int& base, long int& contents)
-{
- int ret = 0;
- std::string_view metadata;
- // Get the metadata from the requested field of the journal entry
- ret = getJournalMetadata(journal, field, metadata);
- if (ret < 0)
- {
- return ret;
- }
- contents = strtol(metadata.data(), nullptr, base);
- return ret;
-}
-
-inline bool getEntryTimestamp(sd_journal* journal, std::string& entryTimestamp)
-{
- int ret = 0;
- uint64_t timestamp = 0;
- ret = sd_journal_get_realtime_usec(journal, &timestamp);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}", strerror(-ret));
- return false;
- }
- entryTimestamp = redfish::time_utils::getDateTimeUintUs(timestamp);
- return true;
-}
-
-inline bool getUniqueEntryID(sd_journal* journal, std::string& entryID,
- const bool firstEntry = true)
-{
- int ret = 0;
- static sd_id128_t prevBootID{};
- static uint64_t prevTs = 0;
- static int index = 0;
- if (firstEntry)
- {
- prevBootID = {};
- prevTs = 0;
- }
-
- // Get the entry timestamp
- uint64_t curTs = 0;
- sd_id128_t curBootID{};
- ret = sd_journal_get_monotonic_usec(journal, &curTs, &curBootID);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}", strerror(-ret));
- return false;
- }
- // If the timestamp isn't unique on the same boot, increment the index
- bool sameBootIDs = sd_id128_equal(curBootID, prevBootID) != 0;
- if (sameBootIDs && (curTs == prevTs))
- {
- index++;
- }
- else
- {
- // Otherwise, reset it
- index = 0;
- }
-
- if (!sameBootIDs)
- {
- // Save the bootID
- prevBootID = curBootID;
- }
- // Save the timestamp
- prevTs = curTs;
-
- // make entryID as <bootID>_<timestamp>[_<index>]
- std::array<char, SD_ID128_STRING_MAX> bootIDStr{};
- sd_id128_to_string(curBootID, bootIDStr.data());
- entryID = std::format("{}_{}", bootIDStr.data(), curTs);
- if (index > 0)
- {
- entryID += "_" + std::to_string(index);
- }
- return true;
-}
-
-static bool getUniqueEntryID(const std::string& logEntry, std::string& entryID,
+inline bool getUniqueEntryID(const std::string& logEntry, std::string& entryID,
const bool firstEntry = true)
{
static time_t prevTs = 0;
@@ -267,70 +165,7 @@ static bool getUniqueEntryID(const std::string& logEntry, std::string& entryID,
return true;
}
-// Entry is formed like "BootID_timestamp" or "BootID_timestamp_index"
inline bool
- getTimestampFromID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string_view entryIDStrView, sd_id128_t& bootID,
- uint64_t& timestamp, uint64_t& index)
-{
- // Convert the unique ID back to a bootID + timestamp to find the entry
- auto underscore1Pos = entryIDStrView.find('_');
- if (underscore1Pos == std::string_view::npos)
- {
- // EntryID has no bootID or timestamp
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
- return false;
- }
-
- // EntryID has bootID + timestamp
-
- // Convert entryIDViewString to BootID
- // NOTE: bootID string which needs to be null-terminated for
- // sd_id128_from_string()
- std::string bootIDStr(entryIDStrView.substr(0, underscore1Pos));
- if (sd_id128_from_string(bootIDStr.c_str(), &bootID) < 0)
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
- return false;
- }
-
- // Get the timestamp from entryID
- entryIDStrView.remove_prefix(underscore1Pos + 1);
-
- auto [timestampEnd, tstampEc] = std::from_chars(
- entryIDStrView.begin(), entryIDStrView.end(), timestamp);
- if (tstampEc != std::errc())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
- return false;
- }
- entryIDStrView = std::string_view(
- timestampEnd,
- static_cast<size_t>(std::distance(timestampEnd, entryIDStrView.end())));
- if (entryIDStrView.empty())
- {
- index = 0U;
- return true;
- }
- // Timestamp might include optional index, if two events happened at the
- // same "time".
- if (entryIDStrView[0] != '_')
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
- return false;
- }
- entryIDStrView.remove_prefix(1);
- auto [ptr, indexEc] = std::from_chars(entryIDStrView.begin(),
- entryIDStrView.end(), index);
- if (indexEc != std::errc() || ptr != entryIDStrView.end())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
- return false;
- }
- return true;
-}
-
-static bool
getRedfishLogFiles(std::vector<std::filesystem::path>& redfishLogFiles)
{
static const std::filesystem::path redfishLogDir = "/var/log";
@@ -525,102 +360,103 @@ inline void
[asyncResp, entriesPath,
dumpType](const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& objects) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // Remove ending slash
- std::string odataIdStr = entriesPath;
- if (!odataIdStr.empty())
- {
- odataIdStr.pop_back();
- }
+ // Remove ending slash
+ std::string odataIdStr = entriesPath;
+ if (!odataIdStr.empty())
+ {
+ odataIdStr.pop_back();
+ }
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
- asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
- asyncResp->res.jsonValue["Description"] = "Collection of " + dumpType +
- " Dump Entries";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
+ asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of " + dumpType + " Dump Entries";
- nlohmann::json::array_t entriesArray;
- std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
+ nlohmann::json::array_t entriesArray;
+ std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
- dbus::utility::ManagedObjectType resp(objects);
- std::ranges::sort(resp, [](const auto& l, const auto& r) {
- return AlphanumLess<std::string>()(l.first.filename(),
- r.first.filename());
- });
+ dbus::utility::ManagedObjectType resp(objects);
+ std::ranges::sort(resp, [](const auto& l, const auto& r) {
+ return AlphanumLess<std::string>()(l.first.filename(),
+ r.first.filename());
+ });
- for (auto& object : resp)
- {
- if (object.first.str.find(dumpEntryPath) == std::string::npos)
+ for (auto& object : resp)
{
- continue;
- }
- uint64_t timestampUs = 0;
- uint64_t size = 0;
- std::string dumpStatus;
- std::string originatorId;
- log_entry::OriginatorTypes originatorType =
- log_entry::OriginatorTypes::Internal;
- nlohmann::json::object_t thisEntry;
-
- std::string entryID = object.first.filename();
- if (entryID.empty())
- {
- continue;
- }
+ if (object.first.str.find(dumpEntryPath) == std::string::npos)
+ {
+ continue;
+ }
+ uint64_t timestampUs = 0;
+ uint64_t size = 0;
+ std::string dumpStatus;
+ std::string originatorId;
+ log_entry::OriginatorTypes originatorType =
+ log_entry::OriginatorTypes::Internal;
+ nlohmann::json::object_t thisEntry;
+
+ std::string entryID = object.first.filename();
+ if (entryID.empty())
+ {
+ continue;
+ }
- parseDumpEntryFromDbusObject(object, dumpStatus, size, timestampUs,
- originatorId, originatorType,
- asyncResp);
+ parseDumpEntryFromDbusObject(object, dumpStatus, size,
+ timestampUs, originatorId,
+ originatorType, asyncResp);
- if (dumpStatus !=
- "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
- !dumpStatus.empty())
- {
- // Dump status is not Complete, no need to enumerate
- continue;
- }
+ if (dumpStatus !=
+ "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
+ !dumpStatus.empty())
+ {
+ // Dump status is not Complete, no need to enumerate
+ continue;
+ }
- thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
- thisEntry["@odata.id"] = entriesPath + entryID;
- thisEntry["Id"] = entryID;
- thisEntry["EntryType"] = "Event";
- thisEntry["Name"] = dumpType + " Dump Entry";
- thisEntry["Created"] =
- redfish::time_utils::getDateTimeUintUs(timestampUs);
+ thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
+ thisEntry["@odata.id"] = entriesPath + entryID;
+ thisEntry["Id"] = entryID;
+ thisEntry["EntryType"] = "Event";
+ thisEntry["Name"] = dumpType + " Dump Entry";
+ thisEntry["Created"] =
+ redfish::time_utils::getDateTimeUintUs(timestampUs);
- if (!originatorId.empty())
- {
- thisEntry["Originator"] = originatorId;
- thisEntry["OriginatorType"] = originatorType;
- }
+ if (!originatorId.empty())
+ {
+ thisEntry["Originator"] = originatorId;
+ thisEntry["OriginatorType"] = originatorType;
+ }
- if (dumpType == "BMC")
- {
- thisEntry["DiagnosticDataType"] = "Manager";
- thisEntry["AdditionalDataURI"] = entriesPath + entryID +
- "/attachment";
- thisEntry["AdditionalDataSizeBytes"] = size;
- }
- else if (dumpType == "System")
- {
- thisEntry["DiagnosticDataType"] = "OEM";
- thisEntry["OEMDiagnosticDataType"] = "System";
- thisEntry["AdditionalDataURI"] = entriesPath + entryID +
- "/attachment";
- thisEntry["AdditionalDataSizeBytes"] = size;
+ if (dumpType == "BMC")
+ {
+ thisEntry["DiagnosticDataType"] = "Manager";
+ thisEntry["AdditionalDataURI"] =
+ entriesPath + entryID + "/attachment";
+ thisEntry["AdditionalDataSizeBytes"] = size;
+ }
+ else if (dumpType == "System")
+ {
+ thisEntry["DiagnosticDataType"] = "OEM";
+ thisEntry["OEMDiagnosticDataType"] = "System";
+ thisEntry["AdditionalDataURI"] =
+ entriesPath + entryID + "/attachment";
+ thisEntry["AdditionalDataSizeBytes"] = size;
+ }
+ entriesArray.emplace_back(std::move(thisEntry));
}
- entriesArray.emplace_back(std::move(thisEntry));
- }
- asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
- asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
- });
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ entriesArray.size();
+ asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
+ });
}
inline void
@@ -640,85 +476,86 @@ inline void
[asyncResp, entryID, dumpType,
entriesPath](const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& resp) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- bool foundDumpEntry = false;
- std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
-
- for (const auto& objectPath : resp)
- {
- if (objectPath.first.str != dumpEntryPath + entryID)
- {
- continue;
- }
-
- foundDumpEntry = true;
- uint64_t timestampUs = 0;
- uint64_t size = 0;
- std::string dumpStatus;
- std::string originatorId;
- log_entry::OriginatorTypes originatorType =
- log_entry::OriginatorTypes::Internal;
-
- parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
- timestampUs, originatorId,
- originatorType, asyncResp);
-
- if (dumpStatus !=
- "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
- !dumpStatus.empty())
+ if (ec)
{
- // Dump status is not Complete
- // return not found until status is changed to Completed
- messages::resourceNotFound(asyncResp->res, dumpType + " dump",
- entryID);
+ BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
+ messages::internalError(asyncResp->res);
return;
}
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntry.v1_11_0.LogEntry";
- asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
- asyncResp->res.jsonValue["Id"] = entryID;
- asyncResp->res.jsonValue["EntryType"] = "Event";
- asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
- asyncResp->res.jsonValue["Created"] =
- redfish::time_utils::getDateTimeUintUs(timestampUs);
-
- if (!originatorId.empty())
- {
- asyncResp->res.jsonValue["Originator"] = originatorId;
- asyncResp->res.jsonValue["OriginatorType"] = originatorType;
- }
+ bool foundDumpEntry = false;
+ std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
- if (dumpType == "BMC")
+ for (const auto& objectPath : resp)
{
- asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
- asyncResp->res.jsonValue["AdditionalDataURI"] =
- entriesPath + entryID + "/attachment";
- asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
+ if (objectPath.first.str != dumpEntryPath + entryID)
+ {
+ continue;
+ }
+
+ foundDumpEntry = true;
+ uint64_t timestampUs = 0;
+ uint64_t size = 0;
+ std::string dumpStatus;
+ std::string originatorId;
+ log_entry::OriginatorTypes originatorType =
+ log_entry::OriginatorTypes::Internal;
+
+ parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
+ timestampUs, originatorId,
+ originatorType, asyncResp);
+
+ if (dumpStatus !=
+ "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
+ !dumpStatus.empty())
+ {
+ // Dump status is not Complete
+ // return not found until status is changed to Completed
+ messages::resourceNotFound(asyncResp->res,
+ dumpType + " dump", entryID);
+ return;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntry.v1_11_0.LogEntry";
+ asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
+ asyncResp->res.jsonValue["Id"] = entryID;
+ asyncResp->res.jsonValue["EntryType"] = "Event";
+ asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
+ asyncResp->res.jsonValue["Created"] =
+ redfish::time_utils::getDateTimeUintUs(timestampUs);
+
+ if (!originatorId.empty())
+ {
+ asyncResp->res.jsonValue["Originator"] = originatorId;
+ asyncResp->res.jsonValue["OriginatorType"] = originatorType;
+ }
+
+ if (dumpType == "BMC")
+ {
+ asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
+ asyncResp->res.jsonValue["AdditionalDataURI"] =
+ entriesPath + entryID + "/attachment";
+ asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
+ }
+ else if (dumpType == "System")
+ {
+ asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
+ asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
+ "System";
+ asyncResp->res.jsonValue["AdditionalDataURI"] =
+ entriesPath + entryID + "/attachment";
+ asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
+ }
}
- else if (dumpType == "System")
+ if (!foundDumpEntry)
{
- asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
- asyncResp->res.jsonValue["OEMDiagnosticDataType"] = "System";
- asyncResp->res.jsonValue["AdditionalDataURI"] =
- entriesPath + entryID + "/attachment";
- asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
+ BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
+ messages::resourceNotFound(asyncResp->res, dumpType + " dump",
+ entryID);
+ return;
}
- }
- if (!foundDumpEntry)
- {
- BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
- messages::resourceNotFound(asyncResp->res, dumpType + " dump",
- entryID);
- return;
- }
- });
+ });
}
inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -777,12 +614,11 @@ inline bool checkSizeLimit(int fd, crow::Response& res)
}
return true;
}
-inline void
- downloadEntryCallback(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& entryID,
- const std::string& downloadEntryType,
- const boost::system::error_code& ec,
- const sdbusplus::message::unix_fd& unixfd)
+inline void downloadEntryCallback(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& entryID, const std::string& downloadEntryType,
+ const boost::system::error_code& ec,
+ const sdbusplus::message::unix_fd& unixfd)
{
if (ec.value() == EBADR)
{
@@ -850,26 +686,25 @@ inline void
return;
}
- std::string dumpEntryPath = std::format("{}/entry/{}",
- getDumpPath(dumpType), entryID);
+ std::string dumpEntryPath =
+ std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
auto downloadDumpEntryHandler =
[asyncResp, entryID,
dumpType](const boost::system::error_code& ec,
const sdbusplus::message::unix_fd& unixfd) {
- downloadEntryCallback(asyncResp, entryID, dumpType, ec, unixfd);
- };
+ downloadEntryCallback(asyncResp, entryID, dumpType, ec, unixfd);
+ };
crow::connections::systemBus->async_method_call(
std::move(downloadDumpEntryHandler), "xyz.openbmc_project.Dump.Manager",
dumpEntryPath, "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
}
-inline void
- downloadEventLogEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& entryID,
- const std::string& dumpType)
+inline void downloadEventLogEntry(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& entryID,
+ const std::string& dumpType)
{
if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
@@ -893,8 +728,8 @@ inline void
[asyncResp, entryID,
dumpType](const boost::system::error_code& ec,
const sdbusplus::message::unix_fd& unixfd) {
- downloadEntryCallback(asyncResp, entryID, dumpType, ec, unixfd);
- };
+ downloadEntryCallback(asyncResp, entryID, dumpType, ec, unixfd);
+ };
crow::connections::systemBus->async_method_call(
std::move(downloadEventLogEntryHandler), "xyz.openbmc_project.Logging",
@@ -942,7 +777,7 @@ inline std::string getDumpEntryPath(const std::string& dumpPath)
if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
{
return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
}
if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
{
@@ -974,114 +809,121 @@ inline void createDumpTaskCallback(
dumpEntryPath{std::move(dumpEntryPath)},
dumpId](const boost::system::error_code& ec,
const std::string& introspectXml) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
- ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Check if the created dump object has implemented Progress
- // interface to track dump completion. If yes, fetch the "Status"
- // property of the interface, modify the task state accordingly.
- // Else, return task completed.
- tinyxml2::XMLDocument doc;
-
- doc.Parse(introspectXml.data(), introspectXml.size());
- tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
- if (pRoot == nullptr)
- {
- BMCWEB_LOG_ERROR("XML document failed to parse");
- messages::internalError(asyncResp->res);
- return;
- }
- tinyxml2::XMLElement* interfaceNode =
- pRoot->FirstChildElement("interface");
-
- bool isProgressIntfPresent = false;
- while (interfaceNode != nullptr)
- {
- const char* thisInterfaceName = interfaceNode->Attribute("name");
- if (thisInterfaceName != nullptr)
+ if (ec)
{
- if (thisInterfaceName ==
- std::string_view("xyz.openbmc_project.Common.Progress"))
- {
- interfaceNode =
- interfaceNode->NextSiblingElement("interface");
- continue;
- }
- isProgressIntfPresent = true;
- break;
+ BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
+ ec.message());
+ messages::internalError(asyncResp->res);
+ return;
}
- interfaceNode = interfaceNode->NextSiblingElement("interface");
- }
- std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
- [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
- const boost::system::error_code& ec2, sdbusplus::message_t& msg,
- const std::shared_ptr<task::TaskData>& taskData) {
- if (ec2)
+ // Check if the created dump object has implemented Progress
+ // interface to track dump completion. If yes, fetch the "Status"
+ // property of the interface, modify the task state accordingly.
+ // Else, return task completed.
+ tinyxml2::XMLDocument doc;
+
+ doc.Parse(introspectXml.data(), introspectXml.size());
+ tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
+ if (pRoot == nullptr)
{
- BMCWEB_LOG_ERROR("{}: Error in creating dump",
- createdObjPath.str);
- taskData->messages.emplace_back(messages::internalError());
- taskData->state = "Cancelled";
- return task::completed;
+ BMCWEB_LOG_ERROR("XML document failed to parse");
+ messages::internalError(asyncResp->res);
+ return;
}
+ tinyxml2::XMLElement* interfaceNode =
+ pRoot->FirstChildElement("interface");
- if (isProgressIntfPresent)
+ bool isProgressIntfPresent = false;
+ while (interfaceNode != nullptr)
{
- dbus::utility::DBusPropertiesMap values;
- std::string prop;
- msg.read(prop, values);
-
- DumpCreationProgress dumpStatus =
- getDumpCompletionStatus(values);
- if (dumpStatus == DumpCreationProgress::DUMP_CREATE_FAILED)
- {
- BMCWEB_LOG_ERROR("{}: Error in creating dump",
- createdObjPath.str);
- taskData->state = "Cancelled";
- return task::completed;
- }
-
- if (dumpStatus == DumpCreationProgress::DUMP_CREATE_INPROGRESS)
+ const char* thisInterfaceName =
+ interfaceNode->Attribute("name");
+ if (thisInterfaceName != nullptr)
{
- BMCWEB_LOG_DEBUG("{}: Dump creation task is in progress",
- createdObjPath.str);
- return !task::completed;
+ if (thisInterfaceName ==
+ std::string_view("xyz.openbmc_project.Common.Progress"))
+ {
+ interfaceNode =
+ interfaceNode->NextSiblingElement("interface");
+ continue;
+ }
+ isProgressIntfPresent = true;
+ break;
}
+ interfaceNode = interfaceNode->NextSiblingElement("interface");
}
- nlohmann::json retMessage = messages::success();
- taskData->messages.emplace_back(retMessage);
+ std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
+ [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
+ const boost::system::error_code& ec2,
+ sdbusplus::message_t& msg,
+ const std::shared_ptr<task::TaskData>& taskData) {
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR("{}: Error in creating dump",
+ createdObjPath.str);
+ taskData->messages.emplace_back(
+ messages::internalError());
+ taskData->state = "Cancelled";
+ return task::completed;
+ }
- boost::urls::url url = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
+ if (isProgressIntfPresent)
+ {
+ dbus::utility::DBusPropertiesMap values;
+ std::string prop;
+ msg.read(prop, values);
+
+ DumpCreationProgress dumpStatus =
+ getDumpCompletionStatus(values);
+ if (dumpStatus ==
+ DumpCreationProgress::DUMP_CREATE_FAILED)
+ {
+ BMCWEB_LOG_ERROR("{}: Error in creating dump",
+ createdObjPath.str);
+ taskData->state = "Cancelled";
+ return task::completed;
+ }
- std::string headerLoc = "Location: ";
- headerLoc += url.buffer();
+ if (dumpStatus ==
+ DumpCreationProgress::DUMP_CREATE_INPROGRESS)
+ {
+ BMCWEB_LOG_DEBUG(
+ "{}: Dump creation task is in progress",
+ createdObjPath.str);
+ return !task::completed;
+ }
+ }
+
+ nlohmann::json retMessage = messages::success();
+ taskData->messages.emplace_back(retMessage);
- taskData->payload->httpHeaders.emplace_back(std::move(headerLoc));
+ boost::urls::url url = boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
- BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
- createdObjPath.str);
- taskData->state = "Completed";
- return task::completed;
+ std::string headerLoc = "Location: ";
+ headerLoc += url.buffer();
+
+ taskData->payload->httpHeaders.emplace_back(
+ std::move(headerLoc));
+
+ BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
+ createdObjPath.str);
+ taskData->state = "Completed";
+ return task::completed;
+ },
+ "type='signal',interface='org.freedesktop.DBus.Properties',"
+ "member='PropertiesChanged',path='" +
+ createdObjPath.str + "'");
+
+ // The task timer is set to max time limit within which the
+ // requested dump will be collected.
+ task->startTimer(std::chrono::minutes(6));
+ task->populateResp(asyncResp->res);
+ task->payload.emplace(payload);
},
- "type='signal',interface='org.freedesktop.DBus.Properties',"
- "member='PropertiesChanged',path='" +
- createdObjPath.str + "'");
-
- // The task timer is set to max time limit within which the
- // requested dump will be collected.
- task->startTimer(std::chrono::minutes(6));
- task->populateResp(asyncResp->res);
- task->payload.emplace(payload);
- },
"xyz.openbmc_project.Dump.Manager", createdObjPath,
"org.freedesktop.DBus.Introspectable", "Introspect");
}
@@ -1172,52 +1014,52 @@ inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
dumpPath](const boost::system::error_code& ec,
const sdbusplus::message_t& msg,
const sdbusplus::message::object_path& objPath) mutable {
- if (ec)
- {
- BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
- const sd_bus_error* dbusError = msg.get_error();
- if (dbusError == nullptr)
+ if (ec)
{
- messages::internalError(asyncResp->res);
- return;
- }
+ BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
+ const sd_bus_error* dbusError = msg.get_error();
+ if (dbusError == nullptr)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
- dbusError->name, dbusError->message);
- if (std::string_view(
- "xyz.openbmc_project.Common.Error.NotAllowed") ==
- dbusError->name)
- {
- messages::resourceInStandby(asyncResp->res);
- return;
- }
- if (std::string_view(
- "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
- dbusError->name)
- {
- messages::serviceDisabled(asyncResp->res, dumpPath);
- return;
- }
- if (std::string_view(
- "xyz.openbmc_project.Common.Error.Unavailable") ==
- dbusError->name)
- {
- messages::resourceInUse(asyncResp->res);
+ BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
+ dbusError->name, dbusError->message);
+ if (std::string_view(
+ "xyz.openbmc_project.Common.Error.NotAllowed") ==
+ dbusError->name)
+ {
+ messages::resourceInStandby(asyncResp->res);
+ return;
+ }
+ if (std::string_view(
+ "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
+ dbusError->name)
+ {
+ messages::serviceDisabled(asyncResp->res, dumpPath);
+ return;
+ }
+ if (std::string_view(
+ "xyz.openbmc_project.Common.Error.Unavailable") ==
+ dbusError->name)
+ {
+ messages::resourceInUse(asyncResp->res);
+ return;
+ }
+ // Other Dbus errors such as:
+ // xyz.openbmc_project.Common.Error.InvalidArgument &
+ // org.freedesktop.DBus.Error.InvalidArgs are all related to
+ // the dbus call that is made here in the bmcweb
+ // implementation and has nothing to do with the client's
+ // input in the request. Hence, returning internal error
+ // back to the client.
+ messages::internalError(asyncResp->res);
return;
}
- // Other Dbus errors such as:
- // xyz.openbmc_project.Common.Error.InvalidArgument &
- // org.freedesktop.DBus.Error.InvalidArgs are all related to
- // the dbus call that is made here in the bmcweb
- // implementation and has nothing to do with the client's
- // input in the request. Hence, returning internal error
- // back to the client.
- messages::internalError(asyncResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
- createDumpTaskCallback(std::move(payload), asyncResp, objPath);
- },
+ BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
+ createDumpTaskCallback(std::move(payload), asyncResp, objPath);
+ },
"xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
"xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
}
@@ -1227,21 +1069,20 @@ inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
{
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ },
"xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
"xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
}
-inline void
- parseCrashdumpParameters(const dbus::utility::DBusPropertiesMap& params,
- std::string& filename, std::string& timestamp,
- std::string& logfile)
+inline void parseCrashdumpParameters(
+ const dbus::utility::DBusPropertiesMap& params, std::string& filename,
+ std::string& timestamp, std::string& logfile)
{
const std::string* filenamePtr = nullptr;
const std::string* timestampPtr = nullptr;
@@ -1279,189 +1120,192 @@ inline void requestRoutesSystemLogServiceCollection(App& app)
*/
BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
.privileges(redfish::privileges::getLogServiceCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- // Collections don't include the static data added by SubRoute
- // because it has a duplicate entry for members
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogServiceCollection.LogServiceCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
- asyncResp->res.jsonValue["Description"] =
- "Collection of LogServices for this Computer System";
- nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
- logServiceArray = nlohmann::json::array();
- nlohmann::json::object_t eventLog;
- eventLog["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- logServiceArray.emplace_back(std::move(eventLog));
- if constexpr (BMCWEB_REDFISH_DUMP_LOG)
- {
- nlohmann::json::object_t dumpLog;
- dumpLog["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/Dump",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- logServiceArray.emplace_back(std::move(dumpLog));
- }
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- if constexpr (BMCWEB_REDFISH_CPU_LOG)
- {
- nlohmann::json::object_t crashdump;
- crashdump["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
+ // Collections don't include the static data added by SubRoute
+ // because it has a duplicate entry for members
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogServiceCollection.LogServiceCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices",
BMCWEB_REDFISH_SYSTEM_URI_NAME);
- logServiceArray.emplace_back(std::move(crashdump));
- }
-
- if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
- {
- nlohmann::json::object_t hostlogger;
- hostlogger["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
+ asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of LogServices for this Computer System";
+ nlohmann::json& logServiceArray =
+ asyncResp->res.jsonValue["Members"];
+ logServiceArray = nlohmann::json::array();
+ nlohmann::json::object_t eventLog;
+ eventLog["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
BMCWEB_REDFISH_SYSTEM_URI_NAME);
- logServiceArray.emplace_back(std::move(hostlogger));
- }
- asyncResp->res.jsonValue["Members@odata.count"] =
- logServiceArray.size();
-
- constexpr std::array<std::string_view, 1> interfaces = {
- "xyz.openbmc_project.State.Boot.PostCode"};
- dbus::utility::getSubTreePaths(
- "/", 0, interfaces,
- [asyncResp](const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse&
- subtreePath) {
- if (ec)
+ logServiceArray.emplace_back(std::move(eventLog));
+ if constexpr (BMCWEB_REDFISH_DUMP_LOG)
{
- BMCWEB_LOG_ERROR("{}", ec);
- return;
+ nlohmann::json::object_t dumpLog;
+ dumpLog["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/Dump",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ logServiceArray.emplace_back(std::move(dumpLog));
}
- for (const auto& pathStr : subtreePath)
+ if constexpr (BMCWEB_REDFISH_CPU_LOG)
{
- if (pathStr.find("PostCode") != std::string::npos)
- {
- nlohmann::json& logServiceArrayLocal =
- asyncResp->res.jsonValue["Members"];
- nlohmann::json::object_t member;
- member["@odata.id"] = std::format(
- "/redfish/v1/Systems/{}/LogServices/PostCodes",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
-
- logServiceArrayLocal.emplace_back(std::move(member));
+ nlohmann::json::object_t crashdump;
+ crashdump["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ logServiceArray.emplace_back(std::move(crashdump));
+ }
- asyncResp->res.jsonValue["Members@odata.count"] =
- logServiceArrayLocal.size();
- return;
- }
+ if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
+ {
+ nlohmann::json::object_t hostlogger;
+ hostlogger["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ logServiceArray.emplace_back(std::move(hostlogger));
}
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ logServiceArray.size();
+
+ constexpr std::array<std::string_view, 1> interfaces = {
+ "xyz.openbmc_project.State.Boot.PostCode"};
+ dbus::utility::getSubTreePaths(
+ "/", 0, interfaces,
+ [asyncResp](const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreePathsResponse&
+ subtreePath) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("{}", ec);
+ return;
+ }
+
+ for (const auto& pathStr : subtreePath)
+ {
+ if (pathStr.find("PostCode") != std::string::npos)
+ {
+ nlohmann::json& logServiceArrayLocal =
+ asyncResp->res.jsonValue["Members"];
+ nlohmann::json::object_t member;
+ member["@odata.id"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/PostCodes",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+
+ logServiceArrayLocal.emplace_back(
+ std::move(member));
+
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ logServiceArrayLocal.size();
+ return;
+ }
+ }
+ });
});
- });
}
inline void requestRoutesEventLogService(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
.privileges(redfish::privileges::getLogService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogService.v1_2_0.LogService";
- asyncResp->res.jsonValue["Name"] = "Event Log Service";
- asyncResp->res.jsonValue["Description"] = "System Event Log Service";
- asyncResp->res.jsonValue["Id"] = "EventLog";
- asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
-
- std::pair<std::string, std::string> redfishDateTimeOffset =
- redfish::time_utils::getDateTimeOffsetNow();
-
- asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
- asyncResp->res.jsonValue["DateTimeLocalOffset"] =
- redfishDateTimeOffset.second;
-
- asyncResp->res.jsonValue["Entries"]["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]["target"]
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogService.v1_2_0.LogService";
+ asyncResp->res.jsonValue["Name"] = "Event Log Service";
+ asyncResp->res.jsonValue["Description"] =
+ "System Event Log Service";
+ asyncResp->res.jsonValue["Id"] = "EventLog";
+ asyncResp->res.jsonValue["OverWritePolicy"] =
+ log_service::OverWritePolicy::WrapsWhenFull;
+
+ std::pair<std::string, std::string> redfishDateTimeOffset =
+ redfish::time_utils::getDateTimeOffsetNow();
- = std::format(
- "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
+ asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
+ asyncResp->res.jsonValue["DateTimeLocalOffset"] =
+ redfishDateTimeOffset.second;
+
+ asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
BMCWEB_REDFISH_SYSTEM_URI_NAME);
- });
+ asyncResp->res
+ .jsonValue["Actions"]["#LogService.ClearLog"]["target"]
+
+ = std::format(
+ "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ });
}
-inline void requestRoutesJournalEventLogClear(App& app)
+inline void handleSystemsLogServicesEventLogActionsClearPost(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName)
{
- BMCWEB_ROUTE(
- app,
- "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
- .privileges({{"ConfigureComponents"}})
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- // Clear the EventLog by deleting the log files
- std::vector<std::filesystem::path> redfishLogFiles;
- if (getRedfishLogFiles(redfishLogFiles))
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ // Clear the EventLog by deleting the log files
+ std::vector<std::filesystem::path> redfishLogFiles;
+ if (getRedfishLogFiles(redfishLogFiles))
+ {
+ for (const std::filesystem::path& file : redfishLogFiles)
{
- for (const std::filesystem::path& file : redfishLogFiles)
- {
- std::error_code ec;
- std::filesystem::remove(file, ec);
- }
+ std::error_code ec;
+ std::filesystem::remove(file, ec);
}
+ }
- // Reload rsyslog so it knows to start new log files
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code& ec) {
+ // Reload rsyslog so it knows to start new log files
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code& ec) {
if (ec)
{
BMCWEB_LOG_ERROR("Failed to reload rsyslog: {}", ec);
@@ -1471,10 +1315,19 @@ inline void requestRoutesJournalEventLogClear(App& app)
messages::success(asyncResp->res);
},
- "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service",
- "replace");
- });
+ "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service",
+ "replace");
+}
+
+inline void requestRoutesJournalEventLogClear(App& app)
+{
+ BMCWEB_ROUTE(
+ app,
+ "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
+ .privileges({{"ConfigureComponents"}})
+ .methods(boost::beast::http::verb::post)(std::bind_front(
+ handleSystemsLogServicesEventLogActionsClearPost, std::ref(app)));
}
enum class LogParseError
@@ -1484,10 +1337,9 @@ enum class LogParseError
messageIdNotInRegistry,
};
-static LogParseError
- fillEventLogEntryJson(const std::string& logEntryID,
- const std::string& logEntry,
- nlohmann::json::object_t& logEntryJson)
+static LogParseError fillEventLogEntryJson(
+ const std::string& logEntryID, const std::string& logEntry,
+ nlohmann::json::object_t& logEntryJson)
{
// The redfish log format is "<Timestamp> <MessageId>,<MessageArgs>"
// First get the Timestamp
@@ -1529,8 +1381,8 @@ static LogParseError
logEntryFields.end());
messageArgs.resize(message->numberOfArgs);
- std::string msg = redfish::registries::fillMessageArgs(messageArgs,
- message->message);
+ std::string msg =
+ redfish::registries::fillMessageArgs(messageArgs, message->message);
if (msg.empty())
{
return LogParseError::parseFailed;
@@ -1562,194 +1414,318 @@ static LogParseError
return LogParseError::success;
}
-inline void requestRoutesJournalEventLogEntryCollection(App& app)
+inline void fillEventLogLogEntryFromPropertyMap(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const dbus::utility::DBusPropertiesMap& resp,
+ nlohmann::json& objectToFillOut)
{
- BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
- .privileges(redfish::privileges::getLogEntryCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- query_param::QueryCapabilities capabilities = {
- .canDelegateTop = true,
- .canDelegateSkip = true,
- };
- query_param::Query delegatedQuery;
- if (!redfish::setUpRedfishRouteWithDelegation(
- app, req, asyncResp, delegatedQuery, capabilities))
+ std::optional<DbusEventLogEntry> optEntry =
+ fillDbusEventLogEntryFromPropertyMap(resp);
+
+ if (!optEntry.has_value())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ DbusEventLogEntry entry = optEntry.value();
+
+ objectToFillOut["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+ objectToFillOut["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
+ objectToFillOut["Name"] = "System Event Log Entry";
+ objectToFillOut["Id"] = std::to_string(entry.Id);
+ objectToFillOut["Message"] = entry.Message;
+ objectToFillOut["Resolved"] = entry.Resolved;
+ std::optional<bool> notifyAction =
+ getProviderNotifyAction(entry.ServiceProviderNotify);
+ if (notifyAction)
+ {
+ objectToFillOut["ServiceProviderNotified"] = *notifyAction;
+ }
+ if ((entry.Resolution != nullptr) && !entry.Resolution->empty())
+ {
+ objectToFillOut["Resolution"] = *entry.Resolution;
+ }
+ objectToFillOut["EntryType"] = "Event";
+ objectToFillOut["Severity"] =
+ translateSeverityDbusToRedfish(entry.Severity);
+ objectToFillOut["Created"] =
+ redfish::time_utils::getDateTimeUintMs(entry.Timestamp);
+ objectToFillOut["Modified"] =
+ redfish::time_utils::getDateTimeUintMs(entry.UpdateTimestamp);
+ if (entry.Path != nullptr)
+ {
+ objectToFillOut["AdditionalDataURI"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}/attachment",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
+ }
+}
+
+inline void afterLogEntriesGetManagedObjects(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::system::error_code& ec,
+ const dbus::utility::ManagedObjectType& resp)
+{
+ if (ec)
+ {
+ // TODO Handle for specific error code
+ BMCWEB_LOG_ERROR("getLogEntriesIfaceData resp_handler got error {}",
+ ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ nlohmann::json::array_t entriesArray;
+ for (const auto& objectPath : resp)
+ {
+ dbus::utility::DBusPropertiesMap propsFlattened;
+ auto isEntry =
+ std::ranges::find_if(objectPath.second, [](const auto& object) {
+ return object.first == "xyz.openbmc_project.Logging.Entry";
+ });
+ if (isEntry == objectPath.second.end())
{
- return;
+ continue;
}
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ for (const auto& interfaceMap : objectPath.second)
{
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
+ for (const auto& propertyMap : interfaceMap.second)
+ {
+ propsFlattened.emplace_back(propertyMap.first,
+ propertyMap.second);
+ }
}
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ fillEventLogLogEntryFromPropertyMap(asyncResp, propsFlattened,
+ entriesArray.emplace_back());
+ }
+
+ std::ranges::sort(entriesArray, [](const nlohmann::json& left,
+ const nlohmann::json& right) {
+ return (left["Id"] <= right["Id"]);
+ });
+ asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
+ asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
+}
+
+inline void handleSystemsLogServiceEventLogLogEntryCollection(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName)
+{
+ query_param::QueryCapabilities capabilities = {
+ .canDelegateTop = true,
+ .canDelegateSkip = true,
+ };
+ query_param::Query delegatedQuery;
+ if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
+ delegatedQuery, capabilities))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
+ size_t skip = delegatedQuery.skip.value_or(0);
+
+ // Collections don't include the static data added by SubRoute
+ // because it has a duplicate entry for members
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of System Event Log Entries";
+
+ nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
+ logEntryArray = nlohmann::json::array();
+ // Go through the log files and create a unique ID for each
+ // entry
+ std::vector<std::filesystem::path> redfishLogFiles;
+ getRedfishLogFiles(redfishLogFiles);
+ uint64_t entryCount = 0;
+ std::string logEntry;
+
+ // Oldest logs are in the last file, so start there and loop
+ // backwards
+ for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); it++)
+ {
+ std::ifstream logStream(*it);
+ if (!logStream.is_open())
{
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
+ continue;
}
- size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
- size_t skip = delegatedQuery.skip.value_or(0);
-
- // Collections don't include the static data added by SubRoute
- // because it has a duplicate entry for members
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
- asyncResp->res.jsonValue["Description"] =
- "Collection of System Event Log Entries";
-
- nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
- logEntryArray = nlohmann::json::array();
- // Go through the log files and create a unique ID for each
- // entry
- std::vector<std::filesystem::path> redfishLogFiles;
- getRedfishLogFiles(redfishLogFiles);
- uint64_t entryCount = 0;
- std::string logEntry;
-
- // Oldest logs are in the last file, so start there and loop
- // backwards
- for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
- it++)
+ // Reset the unique ID on the first entry
+ bool firstEntry = true;
+ while (std::getline(logStream, logEntry))
{
- std::ifstream logStream(*it);
- if (!logStream.is_open())
+ std::string idStr;
+ if (!getUniqueEntryID(logEntry, idStr, firstEntry))
{
continue;
}
+ firstEntry = false;
- // Reset the unique ID on the first entry
- bool firstEntry = true;
- while (std::getline(logStream, logEntry))
+ nlohmann::json::object_t bmcLogEntry;
+ LogParseError status =
+ fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
+ if (status == LogParseError::messageIdNotInRegistry)
{
- std::string idStr;
- if (!getUniqueEntryID(logEntry, idStr, firstEntry))
- {
- continue;
- }
- firstEntry = false;
-
- nlohmann::json::object_t bmcLogEntry;
- LogParseError status = fillEventLogEntryJson(idStr, logEntry,
- bmcLogEntry);
- if (status == LogParseError::messageIdNotInRegistry)
- {
- continue;
- }
- if (status != LogParseError::success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- entryCount++;
- // Handle paging using skip (number of entries to skip from the
- // start) and top (number of entries to display)
- if (entryCount <= skip || entryCount > skip + top)
- {
- continue;
- }
+ continue;
+ }
+ if (status != LogParseError::success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- logEntryArray.emplace_back(std::move(bmcLogEntry));
+ entryCount++;
+ // Handle paging using skip (number of entries to skip from the
+ // start) and top (number of entries to display)
+ if (entryCount <= skip || entryCount > skip + top)
+ {
+ continue;
}
+
+ logEntryArray.emplace_back(std::move(bmcLogEntry));
}
- asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
- if (skip + top < entryCount)
- {
- asyncResp->res
- .jsonValue["Members@odata.nextLink"] = boost::urls::format(
+ }
+ asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
+ if (skip + top < entryCount)
+ {
+ asyncResp->res.jsonValue["Members@odata.nextLink"] =
+ boost::urls::format(
"/redfish/v1/Systems/{}/LogServices/EventLog/Entries?$skip={}",
BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(skip + top));
- }
- });
+ }
}
-inline void requestRoutesJournalEventLogEntry(App& app)
+inline void requestRoutesJournalEventLogEntryCollection(App& app)
{
- BMCWEB_ROUTE(
- app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName, const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
+ .privileges(redfish::privileges::getLogEntryCollection)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServiceEventLogLogEntryCollection, std::ref(app)));
+}
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+inline void handleSystemsLogServiceEventLogEntriesGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& param)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- const std::string& targetID = param;
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ const std::string& targetID = param;
- // Go through the log files and check the unique ID for each
- // entry to find the target entry
- std::vector<std::filesystem::path> redfishLogFiles;
- getRedfishLogFiles(redfishLogFiles);
- std::string logEntry;
+ // Go through the log files and check the unique ID for each
+ // entry to find the target entry
+ std::vector<std::filesystem::path> redfishLogFiles;
+ getRedfishLogFiles(redfishLogFiles);
+ std::string logEntry;
- // Oldest logs are in the last file, so start there and loop
- // backwards
- for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
- it++)
+ // Oldest logs are in the last file, so start there and loop
+ // backwards
+ for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); it++)
+ {
+ std::ifstream logStream(*it);
+ if (!logStream.is_open())
{
- std::ifstream logStream(*it);
- if (!logStream.is_open())
+ continue;
+ }
+
+ // Reset the unique ID on the first entry
+ bool firstEntry = true;
+ while (std::getline(logStream, logEntry))
+ {
+ std::string idStr;
+ if (!getUniqueEntryID(logEntry, idStr, firstEntry))
{
continue;
}
+ firstEntry = false;
- // Reset the unique ID on the first entry
- bool firstEntry = true;
- while (std::getline(logStream, logEntry))
+ if (idStr == targetID)
{
- std::string idStr;
- if (!getUniqueEntryID(logEntry, idStr, firstEntry))
- {
- continue;
- }
- firstEntry = false;
-
- if (idStr == targetID)
+ nlohmann::json::object_t bmcLogEntry;
+ LogParseError status =
+ fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
+ if (status != LogParseError::success)
{
- nlohmann::json::object_t bmcLogEntry;
- LogParseError status =
- fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
- if (status != LogParseError::success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue.update(bmcLogEntry);
+ messages::internalError(asyncResp->res);
return;
}
+ asyncResp->res.jsonValue.update(bmcLogEntry);
+ return;
}
}
- // Requested ID was not found
- messages::resourceNotFound(asyncResp->res, "LogEntry", targetID);
- });
+ }
+ // Requested ID was not found
+ messages::resourceNotFound(asyncResp->res, "LogEntry", targetID);
+}
+
+inline void requestRoutesJournalEventLogEntry(App& app)
+{
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServiceEventLogEntriesGet, std::ref(app)));
+}
+
+inline void dBusEventLogEntryCollection(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ // Collections don't include the static data added by SubRoute
+ // because it has a duplicate entry for members
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of System Event Log Entries";
+
+ // DBus implementation of EventLog/Entries
+ // Make call to Logging Service to find all log entry objects
+ sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
+ dbus::utility::getManagedObjects(
+ "xyz.openbmc_project.Logging", path,
+ [asyncResp](const boost::system::error_code& ec,
+ const dbus::utility::ManagedObjectType& resp) {
+ afterLogEntriesGetManagedObjects(asyncResp, ec, resp);
+ });
}
inline void requestRoutesDBusEventLogEntryCollection(App& app)
@@ -1760,234 +1736,39 @@ inline void requestRoutesDBusEventLogEntryCollection(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- // Collections don't include the static data added by SubRoute
- // because it has a duplicate entry for members
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
- asyncResp->res.jsonValue["Description"] =
- "Collection of System Event Log Entries";
-
- // DBus implementation of EventLog/Entries
- // Make call to Logging Service to find all log entry objects
- sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
- dbus::utility::getManagedObjects(
- "xyz.openbmc_project.Logging", path,
- [asyncResp](const boost::system::error_code& ec,
- const dbus::utility::ManagedObjectType& resp) {
- if (ec)
- {
- // TODO Handle for specific error code
- BMCWEB_LOG_ERROR(
- "getLogEntriesIfaceData resp_handler got error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- nlohmann::json::array_t entriesArray;
- for (const auto& objectPath : resp)
- {
- const uint32_t* id = nullptr;
- const uint64_t* timestamp = nullptr;
- const uint64_t* updateTimestamp = nullptr;
- const std::string* severity = nullptr;
- const std::string* message = nullptr;
- const std::string* filePath = nullptr;
- const std::string* resolution = nullptr;
- bool resolved = false;
- const std::string* notify = nullptr;
-
- for (const auto& interfaceMap : objectPath.second)
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- if (interfaceMap.first ==
- "xyz.openbmc_project.Logging.Entry")
- {
- for (const auto& propertyMap : interfaceMap.second)
- {
- if (propertyMap.first == "Id")
- {
- id = std::get_if<uint32_t>(&propertyMap.second);
- }
- else if (propertyMap.first == "Timestamp")
- {
- timestamp =
- std::get_if<uint64_t>(&propertyMap.second);
- }
- else if (propertyMap.first == "UpdateTimestamp")
- {
- updateTimestamp =
- std::get_if<uint64_t>(&propertyMap.second);
- }
- else if (propertyMap.first == "Severity")
- {
- severity = std::get_if<std::string>(
- &propertyMap.second);
- }
- else if (propertyMap.first == "Resolution")
- {
- resolution = std::get_if<std::string>(
- &propertyMap.second);
- }
- else if (propertyMap.first == "Message")
- {
- message = std::get_if<std::string>(
- &propertyMap.second);
- }
- else if (propertyMap.first == "Resolved")
- {
- const bool* resolveptr =
- std::get_if<bool>(&propertyMap.second);
- if (resolveptr == nullptr)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- resolved = *resolveptr;
- }
- else if (propertyMap.first ==
- "ServiceProviderNotify")
- {
- notify = std::get_if<std::string>(
- &propertyMap.second);
- if (notify == nullptr)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- }
- }
- if (id == nullptr || message == nullptr ||
- severity == nullptr)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- }
- else if (interfaceMap.first ==
- "xyz.openbmc_project.Common.FilePath")
- {
- for (const auto& propertyMap : interfaceMap.second)
- {
- if (propertyMap.first == "Path")
- {
- filePath = std::get_if<std::string>(
- &propertyMap.second);
- }
- }
- }
- }
- // Object path without the
- // xyz.openbmc_project.Logging.Entry interface, ignore
- // and continue.
- if (id == nullptr || message == nullptr ||
- severity == nullptr || timestamp == nullptr ||
- updateTimestamp == nullptr)
- {
- continue;
- }
- nlohmann::json& thisEntry = entriesArray.emplace_back();
- thisEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
- thisEntry["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(*id));
- thisEntry["Name"] = "System Event Log Entry";
- thisEntry["Id"] = std::to_string(*id);
- thisEntry["Message"] = *message;
- thisEntry["Resolved"] = resolved;
- if ((resolution != nullptr) && (!(*resolution).empty()))
- {
- thisEntry["Resolution"] = *resolution;
+ return;
}
- std::optional<bool> notifyAction =
- getProviderNotifyAction(*notify);
- if (notifyAction)
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
- thisEntry["ServiceProviderNotified"] = *notifyAction;
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
}
- thisEntry["EntryType"] = "Event";
- thisEntry["Severity"] =
- translateSeverityDbusToRedfish(*severity);
- thisEntry["Created"] =
- redfish::time_utils::getDateTimeUintMs(*timestamp);
- thisEntry["Modified"] =
- redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
- if (filePath != nullptr)
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
{
- thisEntry["AdditionalDataURI"] =
- std::format(
- "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/",
- BMCWEB_REDFISH_SYSTEM_URI_NAME) +
- std::to_string(*id) + "/attachment";
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
}
- }
- std::ranges::sort(entriesArray, [](const nlohmann::json& left,
- const nlohmann::json& right) {
- return (left["Id"] <= right["Id"]);
+ dBusEventLogEntryCollection(asyncResp);
});
- asyncResp->res.jsonValue["Members@odata.count"] =
- entriesArray.size();
- asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
- });
- });
}
-inline void requestRoutesDBusEventLogEntry(App& app)
+inline void dBusEventLogEntryGet(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
{
- BMCWEB_ROUTE(
- app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName, const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- std::string entryID = param;
- dbus::utility::escapePathForDbus(entryID);
+ dbus::utility::escapePathForDbus(entryID);
- // DBus implementation of EventLog/Entries
- // Make call to Logging Service to find all log entry objects
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, "xyz.openbmc_project.Logging",
- "/xyz/openbmc_project/logging/entry/" + entryID, "",
- [asyncResp, entryID](const boost::system::error_code& ec,
- const dbus::utility::DBusPropertiesMap& resp) {
+ // DBus implementation of EventLog/Entries
+ // Make call to Logging Service to find all log entry objects
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, "xyz.openbmc_project.Logging",
+ "/xyz/openbmc_project/logging/entry/" + entryID, "",
+ [asyncResp, entryID](const boost::system::error_code& ec,
+ const dbus::utility::DBusPropertiesMap& resp) {
if (ec.value() == EBADR)
{
messages::resourceNotFound(asyncResp->res, "EventLogEntry",
@@ -2001,73 +1782,96 @@ inline void requestRoutesDBusEventLogEntry(App& app)
messages::internalError(asyncResp->res);
return;
}
- const uint32_t* id = nullptr;
- const uint64_t* timestamp = nullptr;
- const uint64_t* updateTimestamp = nullptr;
- const std::string* severity = nullptr;
- const std::string* message = nullptr;
- const std::string* filePath = nullptr;
- const std::string* resolution = nullptr;
- bool resolved = false;
- const std::string* notify = nullptr;
-
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), resp, "Id", id, "Timestamp",
- timestamp, "UpdateTimestamp", updateTimestamp, "Severity",
- severity, "Message", message, "Resolved", resolved,
- "Resolution", resolution, "Path", filePath,
- "ServiceProviderNotify", notify);
-
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- if (id == nullptr || message == nullptr || severity == nullptr ||
- timestamp == nullptr || updateTimestamp == nullptr ||
- notify == nullptr)
+ fillEventLogLogEntryFromPropertyMap(asyncResp, resp,
+ asyncResp->res.jsonValue);
+ });
+}
+
+inline void
+ dBusEventLogEntryPatch(const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& entryId)
+{
+ std::optional<bool> resolved;
+
+ if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", resolved))
+ {
+ return;
+ }
+ BMCWEB_LOG_DEBUG("Set Resolved");
+
+ setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
+ "/xyz/openbmc_project/logging/entry/" + entryId,
+ "xyz.openbmc_project.Logging.Entry", "Resolved",
+ resolved.value_or(false));
+}
+
+inline void dBusEventLogEntryDelete(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
+{
+ BMCWEB_LOG_DEBUG("Do delete single event entries.");
+
+ dbus::utility::escapePathForDbus(entryID);
+
+ // Process response from Logging service.
+ auto respHandler = [asyncResp,
+ entryID](const boost::system::error_code& ec) {
+ BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
+ if (ec)
+ {
+ if (ec.value() == EBADR)
{
- messages::internalError(asyncResp->res);
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
return;
}
+ // TODO Handle for specific error code
+ BMCWEB_LOG_ERROR(
+ "EventLogEntry (DBus) doDelete respHandler got error {}", ec);
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntry.v1_9_0.LogEntry";
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(*id));
- asyncResp->res.jsonValue["Name"] = "System Event Log Entry";
- asyncResp->res.jsonValue["Id"] = std::to_string(*id);
- asyncResp->res.jsonValue["Message"] = *message;
- asyncResp->res.jsonValue["Resolved"] = resolved;
- std::optional<bool> notifyAction = getProviderNotifyAction(*notify);
- if (notifyAction)
- {
- asyncResp->res.jsonValue["ServiceProviderNotified"] =
- *notifyAction;
- }
- if ((resolution != nullptr) && (!(*resolution).empty()))
- {
- asyncResp->res.jsonValue["Resolution"] = *resolution;
- }
- asyncResp->res.jsonValue["EntryType"] = "Event";
- asyncResp->res.jsonValue["Severity"] =
- translateSeverityDbusToRedfish(*severity);
- asyncResp->res.jsonValue["Created"] =
- redfish::time_utils::getDateTimeUintMs(*timestamp);
- asyncResp->res.jsonValue["Modified"] =
- redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
- if (filePath != nullptr)
- {
- asyncResp->res.jsonValue["AdditionalDataURI"] =
- std::format(
- "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/",
- BMCWEB_REDFISH_SYSTEM_URI_NAME) +
- std::to_string(*id) + "/attachment";
- }
- });
- });
+ asyncResp->res.result(boost::beast::http::status::ok);
+ };
+
+ // Make call to Logging service to request Delete Log
+ crow::connections::systemBus->async_method_call(
+ respHandler, "xyz.openbmc_project.Logging",
+ "/xyz/openbmc_project/logging/entry/" + entryID,
+ "xyz.openbmc_project.Object.Delete", "Delete");
+}
+
+inline void requestRoutesDBusEventLogEntry(App& app)
+{
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(boost::beast::http::verb::get)(
+ [&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& entryId) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ dBusEventLogEntryGet(asyncResp, entryId);
+ });
BMCWEB_ROUTE(
app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
@@ -2076,37 +1880,26 @@ inline void requestRoutesDBusEventLogEntry(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName, const std::string& entryId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- std::optional<bool> resolved;
-
- if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved",
- resolved))
- {
- return;
- }
- BMCWEB_LOG_DEBUG("Set Resolved");
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
- "/xyz/openbmc_project/logging/entry/" + entryId,
- "xyz.openbmc_project.Logging.Entry", "Resolved",
- *resolved);
- });
+ dBusEventLogEntryPatch(req, asyncResp, entryId);
+ });
BMCWEB_ROUTE(
app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
@@ -2116,59 +1909,25 @@ inline void requestRoutesDBusEventLogEntry(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName, const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- BMCWEB_LOG_DEBUG("Do delete single event entries.");
-
- std::string entryID = param;
-
- dbus::utility::escapePathForDbus(entryID);
-
- // Process response from Logging service.
- auto respHandler = [asyncResp,
- entryID](const boost::system::error_code& ec) {
- BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
- if (ec)
- {
- if (ec.value() == EBADR)
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- messages::resourceNotFound(asyncResp->res, "LogEntry",
- entryID);
return;
}
- // TODO Handle for specific error code
- BMCWEB_LOG_ERROR(
- "EventLogEntry (DBus) doDelete respHandler got error {}",
- ec);
- asyncResp->res.result(
- boost::beast::http::status::internal_server_error);
- return;
- }
-
- asyncResp->res.result(boost::beast::http::status::ok);
- };
-
- // Make call to Logging service to request Delete Log
- crow::connections::systemBus->async_method_call(
- respHandler, "xyz.openbmc_project.Logging",
- "/xyz/openbmc_project/logging/entry/" + entryID,
- "xyz.openbmc_project.Object.Delete", "Delete");
- });
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ dBusEventLogEntryDelete(asyncResp, param);
+ });
}
constexpr const char* hostLoggerFolderPath = "/var/log/console";
@@ -2231,226 +1990,6 @@ inline bool getHostLoggerEntries(
return true;
}
-inline void fillHostLoggerEntryJson(std::string_view logEntryID,
- std::string_view msg,
- nlohmann::json::object_t& logEntryJson)
-{
- // Fill in the log entry with the gathered data.
- logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
- logEntryJson["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, logEntryID);
- logEntryJson["Name"] = "Host Logger Entry";
- logEntryJson["Id"] = logEntryID;
- logEntryJson["Message"] = msg;
- logEntryJson["EntryType"] = "Oem";
- logEntryJson["Severity"] = "OK";
- logEntryJson["OemRecordFormat"] = "Host Logger Entry";
-}
-
-inline void requestRoutesSystemHostLogger(App& app)
-{
- BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/")
- .privileges(redfish::privileges::getLogService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogService.v1_2_0.LogService";
- asyncResp->res.jsonValue["Name"] = "Host Logger Service";
- asyncResp->res.jsonValue["Description"] = "Host Logger Service";
- asyncResp->res.jsonValue["Id"] = "HostLogger";
- asyncResp->res.jsonValue["Entries"]["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- });
-}
-
-inline void requestRoutesSystemHostLoggerCollection(App& app)
-{
- BMCWEB_ROUTE(app,
- "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- query_param::QueryCapabilities capabilities = {
- .canDelegateTop = true,
- .canDelegateSkip = true,
- };
- query_param::Query delegatedQuery;
- if (!redfish::setUpRedfishRouteWithDelegation(
- app, req, asyncResp, delegatedQuery, capabilities))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["Name"] = "HostLogger Entries";
- asyncResp->res.jsonValue["Description"] =
- "Collection of HostLogger Entries";
- nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
- logEntryArray = nlohmann::json::array();
- asyncResp->res.jsonValue["Members@odata.count"] = 0;
-
- std::vector<std::filesystem::path> hostLoggerFiles;
- if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
- {
- BMCWEB_LOG_DEBUG("Failed to get host log file path");
- return;
- }
- // If we weren't provided top and skip limits, use the defaults.
- size_t skip = delegatedQuery.skip.value_or(0);
- size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
- size_t logCount = 0;
- // This vector only store the entries we want to expose that
- // control by skip and top.
- std::vector<std::string> logEntries;
- if (!getHostLoggerEntries(hostLoggerFiles, skip, top, logEntries,
- logCount))
- {
- messages::internalError(asyncResp->res);
- return;
- }
- // If vector is empty, that means skip value larger than total
- // log count
- if (logEntries.empty())
- {
- asyncResp->res.jsonValue["Members@odata.count"] = logCount;
- return;
- }
- if (!logEntries.empty())
- {
- for (size_t i = 0; i < logEntries.size(); i++)
- {
- nlohmann::json::object_t hostLogEntry;
- fillHostLoggerEntryJson(std::to_string(skip + i), logEntries[i],
- hostLogEntry);
- logEntryArray.emplace_back(std::move(hostLogEntry));
- }
-
- asyncResp->res.jsonValue["Members@odata.count"] = logCount;
- if (skip + top < logCount)
- {
- asyncResp->res.jsonValue["Members@odata.nextLink"] =
- std::format(
- "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries?$skip=",
- BMCWEB_REDFISH_SYSTEM_URI_NAME) +
- std::to_string(skip + top);
- }
- }
- });
-}
-
-inline void requestRoutesSystemHostLoggerLogEntry(App& app)
-{
- BMCWEB_ROUTE(
- app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/<str>/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName, const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- std::string_view targetID = param;
-
- uint64_t idInt = 0;
-
- auto [ptr, ec] = std::from_chars(targetID.begin(), targetID.end(),
- idInt);
- if (ec != std::errc{} || ptr != targetID.end())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", param);
- return;
- }
-
- std::vector<std::filesystem::path> hostLoggerFiles;
- if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
- {
- BMCWEB_LOG_DEBUG("Failed to get host log file path");
- return;
- }
-
- size_t logCount = 0;
- size_t top = 1;
- std::vector<std::string> logEntries;
- // We can get specific entry by skip and top. For example, if we
- // want to get nth entry, we can set skip = n-1 and top = 1 to
- // get that entry
- if (!getHostLoggerEntries(hostLoggerFiles, idInt, top, logEntries,
- logCount))
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- if (!logEntries.empty())
- {
- nlohmann::json::object_t hostLogEntry;
- fillHostLoggerEntryJson(targetID, logEntries[0], hostLogEntry);
- asyncResp->res.jsonValue.update(hostLogEntry);
- return;
- }
-
- // Requested ID was not found
- messages::resourceNotFound(asyncResp->res, "LogEntry", param);
- });
-}
-
inline void handleBMCLogServicesCollectionGet(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -2499,42 +2038,43 @@ inline void handleBMCLogServicesCollectionGet(
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse&
subTreePaths) {
- if (ec)
- {
- BMCWEB_LOG_ERROR(
- "handleBMCLogServicesCollectionGet respHandler got error {}",
- ec);
- // Assume that getting an error simply means there are no dump
- // LogServices. Return without adding any error response.
- return;
- }
-
- nlohmann::json& logServiceArrayLocal =
- asyncResp->res.jsonValue["Members"];
-
- for (const std::string& path : subTreePaths)
- {
- if (path == "/xyz/openbmc_project/dump/bmc")
+ if (ec)
{
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/Dump",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- logServiceArrayLocal.emplace_back(std::move(member));
+ BMCWEB_LOG_ERROR(
+ "handleBMCLogServicesCollectionGet respHandler got error {}",
+ ec);
+ // Assume that getting an error simply means there are no
+ // dump LogServices. Return without adding any error
+ // response.
+ return;
}
- else if (path == "/xyz/openbmc_project/dump/faultlog")
+
+ nlohmann::json& logServiceArrayLocal =
+ asyncResp->res.jsonValue["Members"];
+
+ for (const std::string& path : subTreePaths)
{
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/FaultLog",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- logServiceArrayLocal.emplace_back(std::move(member));
+ if (path == "/xyz/openbmc_project/dump/bmc")
+ {
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/Dump",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ logServiceArrayLocal.emplace_back(std::move(member));
+ }
+ else if (path == "/xyz/openbmc_project/dump/faultlog")
+ {
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/FaultLog",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ logServiceArrayLocal.emplace_back(std::move(member));
+ }
}
- }
- asyncResp->res.jsonValue["Members@odata.count"] =
- logServiceArrayLocal.size();
- });
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ logServiceArrayLocal.size();
+ });
}
}
@@ -2546,318 +2086,34 @@ inline void requestRoutesBMCLogServiceCollection(App& app)
std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
}
-inline void requestRoutesBMCJournalLogService(App& app)
-{
- BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Journal/")
- .privileges(redfish::privileges::getLogService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogService.v1_2_0.LogService";
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "Open BMC Journal Log Service";
- asyncResp->res.jsonValue["Description"] = "BMC Journal Log Service";
- asyncResp->res.jsonValue["Id"] = "Journal";
- asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
-
- std::pair<std::string, std::string> redfishDateTimeOffset =
- redfish::time_utils::getDateTimeOffsetNow();
- asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
- asyncResp->res.jsonValue["DateTimeLocalOffset"] =
- redfishDateTimeOffset.second;
-
- asyncResp->res.jsonValue["Entries"]["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/Journal/Entries",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- });
-}
-
-static int
- fillBMCJournalLogEntryJson(const std::string& bmcJournalLogEntryID,
- sd_journal* journal,
- nlohmann::json::object_t& bmcJournalLogEntryJson)
-{
- // Get the Log Entry contents
- int ret = 0;
-
- std::string message;
- std::string_view syslogID;
- ret = getJournalMetadata(journal, "SYSLOG_IDENTIFIER", syslogID);
- if (ret < 0)
- {
- BMCWEB_LOG_DEBUG("Failed to read SYSLOG_IDENTIFIER field: {}",
- strerror(-ret));
- }
- if (!syslogID.empty())
- {
- message += std::string(syslogID) + ": ";
- }
-
- std::string_view msg;
- ret = getJournalMetadata(journal, "MESSAGE", msg);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("Failed to read MESSAGE field: {}", strerror(-ret));
- return 1;
- }
- message += std::string(msg);
-
- // Get the severity from the PRIORITY field
- long int severity = 8; // Default to an invalid priority
- ret = getJournalMetadata(journal, "PRIORITY", 10, severity);
- if (ret < 0)
- {
- BMCWEB_LOG_DEBUG("Failed to read PRIORITY field: {}", strerror(-ret));
- }
-
- // Get the Created time from the timestamp
- std::string entryTimeStr;
- if (!getEntryTimestamp(journal, entryTimeStr))
- {
- return 1;
- }
-
- // Fill in the log entry with the gathered data
- bmcJournalLogEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
- bmcJournalLogEntryJson["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/Journal/Entries/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, bmcJournalLogEntryID);
- bmcJournalLogEntryJson["Name"] = "BMC Journal Entry";
- bmcJournalLogEntryJson["Id"] = bmcJournalLogEntryID;
- bmcJournalLogEntryJson["Message"] = std::move(message);
- bmcJournalLogEntryJson["EntryType"] = "Oem";
- log_entry::EventSeverity severityEnum = log_entry::EventSeverity::OK;
- if (severity <= 2)
- {
- severityEnum = log_entry::EventSeverity::Critical;
- }
- else if (severity <= 4)
- {
- severityEnum = log_entry::EventSeverity::Warning;
- }
-
- bmcJournalLogEntryJson["Severity"] = severityEnum;
- bmcJournalLogEntryJson["OemRecordFormat"] = "BMC Journal Entry";
- bmcJournalLogEntryJson["Created"] = std::move(entryTimeStr);
- return 0;
-}
-
-inline void requestRoutesBMCJournalLogEntryCollection(App& app)
-{
- BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Journal/Entries/")
- .privileges(redfish::privileges::getLogEntryCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& managerId) {
- query_param::QueryCapabilities capabilities = {
- .canDelegateTop = true,
- .canDelegateSkip = true,
- };
- query_param::Query delegatedQuery;
- if (!redfish::setUpRedfishRouteWithDelegation(
- app, req, asyncResp, delegatedQuery, capabilities))
- {
- return;
- }
-
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
-
- size_t skip = delegatedQuery.skip.value_or(0);
- size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
-
- // Collections don't include the static data added by SubRoute
- // because it has a duplicate entry for members
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/Journal/Entries",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "Open BMC Journal Entries";
- asyncResp->res.jsonValue["Description"] =
- "Collection of BMC Journal Entries";
- nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
- logEntryArray = nlohmann::json::array();
-
- // Go through the journal and use the timestamp to create a
- // unique ID for each entry
- sd_journal* journalTmp = nullptr;
- int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("failed to open journal: {}", strerror(-ret));
- messages::internalError(asyncResp->res);
- return;
- }
- std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
- journalTmp, sd_journal_close);
- journalTmp = nullptr;
- uint64_t entryCount = 0;
- // Reset the unique ID on the first entry
- bool firstEntry = true;
- SD_JOURNAL_FOREACH(journal.get())
- {
- entryCount++;
- // Handle paging using skip (number of entries to skip from
- // the start) and top (number of entries to display)
- if (entryCount <= skip || entryCount > skip + top)
- {
- continue;
- }
-
- std::string idStr;
- if (!getUniqueEntryID(journal.get(), idStr, firstEntry))
- {
- continue;
- }
- firstEntry = false;
-
- nlohmann::json::object_t bmcJournalLogEntry;
- if (fillBMCJournalLogEntryJson(idStr, journal.get(),
- bmcJournalLogEntry) != 0)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- logEntryArray.emplace_back(std::move(bmcJournalLogEntry));
- }
- asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
- if (skip + top < entryCount)
- {
- asyncResp->res
- .jsonValue["Members@odata.nextLink"] = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/Journal/Entries?$skip={}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, std::to_string(skip + top));
- }
- });
-}
-
-inline void requestRoutesBMCJournalLogEntry(App& app)
-{
- BMCWEB_ROUTE(
- app, "/redfish/v1/Managers/<str>/LogServices/Journal/Entries/<str>/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& managerId, const std::string& entryID) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
-
- // Convert the unique ID back to a timestamp to find the entry
- sd_id128_t bootID{};
- uint64_t ts = 0;
- uint64_t index = 0;
- if (!getTimestampFromID(asyncResp, entryID, bootID, ts, index))
- {
- return;
- }
-
- sd_journal* journalTmp = nullptr;
- int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("failed to open journal: {}", strerror(-ret));
- messages::internalError(asyncResp->res);
- return;
- }
- std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
- journalTmp, sd_journal_close);
- journalTmp = nullptr;
- // Go to the timestamp in the log and move to the entry at the
- // index tracking the unique ID
- std::string idStr;
- bool firstEntry = true;
- ret = sd_journal_seek_monotonic_usec(journal.get(), bootID, ts);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("failed to seek to an entry in journal{}",
- strerror(-ret));
- messages::internalError(asyncResp->res);
- return;
- }
- for (uint64_t i = 0; i <= index; i++)
- {
- sd_journal_next(journal.get());
- if (!getUniqueEntryID(journal.get(), idStr, firstEntry))
- {
- messages::internalError(asyncResp->res);
- return;
- }
- firstEntry = false;
- }
- // Confirm that the entry ID matches what was requested
- if (idStr != entryID)
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
- return;
- }
-
- nlohmann::json::object_t bmcJournalLogEntry;
- if (fillBMCJournalLogEntryJson(entryID, journal.get(),
- bmcJournalLogEntry) != 0)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue.update(bmcJournalLogEntry);
- });
-}
-
inline void
getDumpServiceInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& dumpType)
{
std::string dumpPath;
- std::string overWritePolicy;
+ log_service::OverWritePolicy overWritePolicy =
+ log_service::OverWritePolicy::Invalid;
bool collectDiagnosticDataSupported = false;
if (dumpType == "BMC")
{
dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
BMCWEB_REDFISH_MANAGER_URI_NAME);
- overWritePolicy = "WrapsWhenFull";
+ overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
collectDiagnosticDataSupported = true;
}
else if (dumpType == "FaultLog")
{
dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
BMCWEB_REDFISH_MANAGER_URI_NAME);
- overWritePolicy = "Unknown";
+ overWritePolicy = log_service::OverWritePolicy::Unknown;
collectDiagnosticDataSupported = false;
}
else if (dumpType == "System")
{
dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
BMCWEB_REDFISH_SYSTEM_URI_NAME);
- overWritePolicy = "WrapsWhenFull";
+ overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
collectDiagnosticDataSupported = true;
}
else
@@ -2873,7 +2129,7 @@ inline void
asyncResp->res.jsonValue["Name"] = "Dump LogService";
asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
- asyncResp->res.jsonValue["OverWritePolicy"] = std::move(overWritePolicy);
+ asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
std::pair<std::string, std::string> redfishDateTimeOffset =
redfish::time_utils::getDateTimeOffsetNow();
@@ -2896,25 +2152,26 @@ inline void
[asyncResp, dumpType, dumpPath](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}", ec);
- // Assume that getting an error simply means there are no dump
- // LogServices. Return without adding any error response.
- return;
- }
- std::string dbusDumpPath = getDumpPath(dumpType);
- for (const std::string& path : subTreePaths)
- {
- if (path == dbusDumpPath)
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
+ ec);
+ // Assume that getting an error simply means there are no dump
+ // LogServices. Return without adding any error response.
+ return;
+ }
+ std::string dbusDumpPath = getDumpPath(dumpType);
+ for (const std::string& path : subTreePaths)
{
- asyncResp->res
- .jsonValue["Actions"]["#LogService.ClearLog"]["target"] =
- dumpPath + "/Actions/LogService.ClearLog";
- break;
+ if (path == dbusDumpPath)
+ {
+ asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
+ ["target"] =
+ dumpPath + "/Actions/LogService.ClearLog";
+ break;
+ }
}
- }
- });
+ });
}
inline void handleLogServicesDumpServiceGet(
@@ -3360,59 +2617,62 @@ inline void requestRoutesCrashdumpService(App& app)
// This is incorrect, should be:
//.privileges(redfish::privileges::getLogService)
.privileges({{"ConfigureManager"}})
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- // Copy over the static data to include the entries added by
- // SubRoute
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogService.v1_2_0.LogService";
- asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
- asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
- asyncResp->res.jsonValue["Id"] = "Crashdump";
- asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
- asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
-
- std::pair<std::string, std::string> redfishDateTimeOffset =
- redfish::time_utils::getDateTimeOffsetNow();
- asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
- asyncResp->res.jsonValue["DateTimeLocalOffset"] =
- redfishDateTimeOffset.second;
-
- asyncResp->res.jsonValue["Entries"]["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
- ["target"] = std::format(
- "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
- ["target"] = std::format(
- "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- });
+ // Copy over the static data to include the entries added by
+ // SubRoute
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogService.v1_2_0.LogService";
+ asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
+ asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
+ asyncResp->res.jsonValue["Id"] = "Crashdump";
+ asyncResp->res.jsonValue["OverWritePolicy"] =
+ log_service::OverWritePolicy::WrapsWhenFull;
+ asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
+
+ std::pair<std::string, std::string> redfishDateTimeOffset =
+ redfish::time_utils::getDateTimeOffsetNow();
+ asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
+ asyncResp->res.jsonValue["DateTimeLocalOffset"] =
+ redfishDateTimeOffset.second;
+
+ asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
+ ["target"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res
+ .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
+ ["target"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ });
}
void inline requestRoutesCrashdumpClear(App& app)
@@ -3427,38 +2687,39 @@ void inline requestRoutesCrashdumpClear(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code& ec,
- const std::string&) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- messages::success(asyncResp->res);
- },
- crashdumpObject, crashdumpPath, deleteAllInterface, "DeleteAll");
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code& ec,
+ const std::string&) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ messages::success(asyncResp->res);
+ },
+ crashdumpObject, crashdumpPath, deleteAllInterface,
+ "DeleteAll");
+ });
}
-static void
+inline void
logCrashdumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& logID, nlohmann::json& logEntryJson)
{
@@ -3466,63 +2727,65 @@ static void
[asyncResp, logID,
&logEntryJson](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& params) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
- if (ec.value() ==
- boost::system::linux_error::bad_request_descriptor)
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
+ if (ec.value() ==
+ boost::system::linux_error::bad_request_descriptor)
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry",
+ logID);
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ }
+ return;
+ }
+
+ std::string timestamp{};
+ std::string filename{};
+ std::string logfile{};
+ parseCrashdumpParameters(params, filename, timestamp, logfile);
+
+ if (filename.empty() || timestamp.empty())
{
messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
+ return;
+ }
+
+ std::string crashdumpURI =
+ std::format(
+ "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME) +
+ logID + "/" + filename;
+ nlohmann::json::object_t logEntry;
+ logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+ logEntry["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
+ logEntry["Name"] = "CPU Crashdump";
+ logEntry["Id"] = logID;
+ logEntry["EntryType"] = log_entry::LogEntryType::Oem;
+ logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
+ logEntry["DiagnosticDataType"] = "OEM";
+ logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
+ logEntry["Created"] = std::move(timestamp);
+
+ // If logEntryJson references an array of LogEntry resources
+ // ('Members' list), then push this as a new entry, otherwise set it
+ // directly
+ if (logEntryJson.is_array())
+ {
+ logEntryJson.push_back(logEntry);
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ logEntryJson.size();
}
else
{
- messages::internalError(asyncResp->res);
+ logEntryJson.update(logEntry);
}
- return;
- }
-
- std::string timestamp{};
- std::string filename{};
- std::string logfile{};
- parseCrashdumpParameters(params, filename, timestamp, logfile);
-
- if (filename.empty() || timestamp.empty())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
- return;
- }
-
- std::string crashdumpURI =
- std::format("/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
- BMCWEB_REDFISH_SYSTEM_URI_NAME) +
- logID + "/" + filename;
- nlohmann::json::object_t logEntry;
- logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
- logEntry["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
- logEntry["Name"] = "CPU Crashdump";
- logEntry["Id"] = logID;
- logEntry["EntryType"] = "Oem";
- logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
- logEntry["DiagnosticDataType"] = "OEM";
- logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
- logEntry["Created"] = std::move(timestamp);
-
- // If logEntryJson references an array of LogEntry resources
- // ('Members' list), then push this as a new entry, otherwise set it
- // directly
- if (logEntryJson.is_array())
- {
- logEntryJson.push_back(logEntry);
- asyncResp->res.jsonValue["Members@odata.count"] =
- logEntryJson.size();
- }
- else
- {
- logEntryJson.update(logEntry);
- }
- };
+ };
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, crashdumpObject,
crashdumpPath + std::string("/") + logID, crashdumpInterface,
@@ -3541,71 +2804,74 @@ inline void requestRoutesCrashdumpEntryCollection(App& app)
// This is incorrect, should be.
//.privileges(redfish::privileges::postLogEntryCollection)
.privileges({{"ConfigureComponents"}})
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- constexpr std::array<std::string_view, 1> interfaces = {
- crashdumpInterface};
- dbus::utility::getSubTreePaths(
- "/", 0, interfaces,
- [asyncResp](const boost::system::error_code& ec,
- const std::vector<std::string>& resp) {
- if (ec)
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- if (ec.value() !=
- boost::system::errc::no_such_file_or_directory)
- {
- BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
- ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
+ return;
}
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["@odata.id"] = std::format(
- "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "Open BMC Crashdump Entries";
- asyncResp->res.jsonValue["Description"] =
- "Collection of Crashdump Entries";
- asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
- asyncResp->res.jsonValue["Members@odata.count"] = 0;
-
- for (const std::string& path : resp)
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
- const sdbusplus::message::object_path objPath(path);
- // Get the log ID
- std::string logID = objPath.filename();
- if (logID.empty())
- {
- continue;
- }
- // Add the log entry to the array
- logCrashdumpEntry(asyncResp, logID,
- asyncResp->res.jsonValue["Members"]);
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
}
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ constexpr std::array<std::string_view, 1> interfaces = {
+ crashdumpInterface};
+ dbus::utility::getSubTreePaths(
+ "/", 0, interfaces,
+ [asyncResp](const boost::system::error_code& ec,
+ const std::vector<std::string>& resp) {
+ if (ec)
+ {
+ if (ec.value() !=
+ boost::system::errc::no_such_file_or_directory)
+ {
+ BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
+ ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["@odata.id"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["Name"] =
+ "Open BMC Crashdump Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of Crashdump Entries";
+ asyncResp->res.jsonValue["Members"] =
+ nlohmann::json::array();
+ asyncResp->res.jsonValue["Members@odata.count"] = 0;
+
+ for (const std::string& path : resp)
+ {
+ const sdbusplus::message::object_path objPath(path);
+ // Get the log ID
+ std::string logID = objPath.filename();
+ if (logID.empty())
+ {
+ continue;
+ }
+ // Add the log entry to the array
+ logCrashdumpEntry(asyncResp, logID,
+ asyncResp->res.jsonValue["Members"]);
+ }
+ });
});
- });
}
inline void requestRoutesCrashdumpEntry(App& app)
@@ -3622,26 +2888,26 @@ inline void requestRoutesCrashdumpEntry(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName, const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- const std::string& logID = param;
- logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ const std::string& logID = param;
+ logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
+ });
}
inline void requestRoutesCrashdumpFile(App& app)
@@ -3657,73 +2923,80 @@ inline void requestRoutesCrashdumpFile(App& app)
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName, const std::string& logID,
const std::string& fileName) {
- // Do not call getRedfishRoute here since the crashdump file is not a
- // Redfish resource.
+ // Do not call getRedfishRoute here since the crashdump file is
+ // not a Redfish resource.
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- auto getStoredLogCallback =
- [asyncResp, logID, fileName, url(boost::urls::url(req.url()))](
- const boost::system::error_code& ec,
- const std::vector<
- std::pair<std::string, dbus::utility::DbusVariantType>>&
- resp) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
+ auto getStoredLogCallback =
+ [asyncResp, logID, fileName,
+ url(boost::urls::url(req.url()))](
+ const boost::system::error_code& ec,
+ const std::vector<std::pair<
+ std::string, dbus::utility::DbusVariantType>>&
+ resp) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("failed to get log ec: {}",
+ ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
- std::string dbusFilename{};
- std::string dbusTimestamp{};
- std::string dbusFilepath{};
+ std::string dbusFilename{};
+ std::string dbusTimestamp{};
+ std::string dbusFilepath{};
- parseCrashdumpParameters(resp, dbusFilename, dbusTimestamp,
- dbusFilepath);
+ parseCrashdumpParameters(resp, dbusFilename,
+ dbusTimestamp, dbusFilepath);
- if (dbusFilename.empty() || dbusTimestamp.empty() ||
- dbusFilepath.empty())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
- return;
- }
+ if (dbusFilename.empty() || dbusTimestamp.empty() ||
+ dbusFilepath.empty())
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "LogEntry", logID);
+ return;
+ }
- // Verify the file name parameter is correct
- if (fileName != dbusFilename)
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
- return;
- }
+ // Verify the file name parameter is correct
+ if (fileName != dbusFilename)
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "LogEntry", logID);
+ return;
+ }
- if (!asyncResp->res.openFile(dbusFilepath))
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
- return;
- }
+ if (asyncResp->res.openFile(dbusFilepath) !=
+ crow::OpenCode::Success)
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "LogEntry", logID);
+ return;
+ }
- // Configure this to be a file download when accessed
- // from a browser
- asyncResp->res.addHeader(
- boost::beast::http::field::content_disposition, "attachment");
- };
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, crashdumpObject,
- crashdumpPath + std::string("/") + logID, crashdumpInterface,
- std::move(getStoredLogCallback));
- });
+ // Configure this to be a file download when accessed
+ // from a browser
+ asyncResp->res.addHeader(
+ boost::beast::http::field::content_disposition,
+ "attachment");
+ };
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, crashdumpObject,
+ crashdumpPath + std::string("/") + logID,
+ crashdumpInterface, std::move(getStoredLogCallback));
+ });
}
enum class OEMDiagnosticType
@@ -3761,122 +3034,158 @@ inline void requestRoutesCrashdumpCollect(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- std::string diagnosticDataType;
- std::string oemDiagnosticDataType;
- if (!redfish::json_util::readJsonAction(
- req, asyncResp->res, "DiagnosticDataType", diagnosticDataType,
- "OEMDiagnosticDataType", oemDiagnosticDataType))
- {
- return;
- }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- if (diagnosticDataType != "OEM")
- {
- BMCWEB_LOG_ERROR(
- "Only OEM DiagnosticDataType supported for Crashdump");
- messages::actionParameterValueFormatError(
- asyncResp->res, diagnosticDataType, "DiagnosticDataType",
- "CollectDiagnosticData");
- return;
- }
+ std::string diagnosticDataType;
+ std::string oemDiagnosticDataType;
+ if (!redfish::json_util::readJsonAction(
+ req, asyncResp->res, "DiagnosticDataType",
+ diagnosticDataType, "OEMDiagnosticDataType",
+ oemDiagnosticDataType))
+ {
+ return;
+ }
- OEMDiagnosticType oemDiagType =
- getOEMDiagnosticType(oemDiagnosticDataType);
+ if (diagnosticDataType != "OEM")
+ {
+ BMCWEB_LOG_ERROR(
+ "Only OEM DiagnosticDataType supported for Crashdump");
+ messages::actionParameterValueFormatError(
+ asyncResp->res, diagnosticDataType,
+ "DiagnosticDataType", "CollectDiagnosticData");
+ return;
+ }
- std::string iface;
- std::string method;
- std::string taskMatchStr;
- if (oemDiagType == OEMDiagnosticType::onDemand)
- {
- iface = crashdumpOnDemandInterface;
- method = "GenerateOnDemandLog";
- taskMatchStr = "type='signal',"
- "interface='org.freedesktop.DBus.Properties',"
- "member='PropertiesChanged',"
- "arg0namespace='com.intel.crashdump'";
- }
- else if (oemDiagType == OEMDiagnosticType::telemetry)
- {
- iface = crashdumpTelemetryInterface;
- method = "GenerateTelemetryLog";
- taskMatchStr = "type='signal',"
- "interface='org.freedesktop.DBus.Properties',"
- "member='PropertiesChanged',"
- "arg0namespace='com.intel.crashdump'";
- }
- else
- {
- BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
- oemDiagnosticDataType);
- messages::actionParameterValueFormatError(
- asyncResp->res, oemDiagnosticDataType, "OEMDiagnosticDataType",
- "CollectDiagnosticData");
- return;
- }
+ OEMDiagnosticType oemDiagType =
+ getOEMDiagnosticType(oemDiagnosticDataType);
- auto collectCrashdumpCallback =
- [asyncResp, payload(task::Payload(req)),
- taskMatchStr](const boost::system::error_code& ec,
- const std::string&) mutable {
- if (ec)
- {
- if (ec.value() == boost::system::errc::operation_not_supported)
+ std::string iface;
+ std::string method;
+ std::string taskMatchStr;
+ if (oemDiagType == OEMDiagnosticType::onDemand)
{
- messages::resourceInStandby(asyncResp->res);
+ iface = crashdumpOnDemandInterface;
+ method = "GenerateOnDemandLog";
+ taskMatchStr =
+ "type='signal',"
+ "interface='org.freedesktop.DBus.Properties',"
+ "member='PropertiesChanged',"
+ "arg0namespace='com.intel.crashdump'";
}
- else if (ec.value() ==
- boost::system::errc::device_or_resource_busy)
+ else if (oemDiagType == OEMDiagnosticType::telemetry)
{
- messages::serviceTemporarilyUnavailable(asyncResp->res,
- "60");
+ iface = crashdumpTelemetryInterface;
+ method = "GenerateTelemetryLog";
+ taskMatchStr =
+ "type='signal',"
+ "interface='org.freedesktop.DBus.Properties',"
+ "member='PropertiesChanged',"
+ "arg0namespace='com.intel.crashdump'";
}
else
{
- messages::internalError(asyncResp->res);
- }
- return;
- }
- std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
- [](const boost::system::error_code& ec2, sdbusplus::message_t&,
- const std::shared_ptr<task::TaskData>& taskData) {
- if (!ec2)
- {
- taskData->messages.emplace_back(messages::taskCompletedOK(
- std::to_string(taskData->index)));
- taskData->state = "Completed";
+ BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
+ oemDiagnosticDataType);
+ messages::actionParameterValueFormatError(
+ asyncResp->res, oemDiagnosticDataType,
+ "OEMDiagnosticDataType", "CollectDiagnosticData");
+ return;
}
- return task::completed;
- },
- taskMatchStr);
- task->startTimer(std::chrono::minutes(5));
- task->populateResp(asyncResp->res);
- task->payload.emplace(std::move(payload));
- };
+ auto collectCrashdumpCallback =
+ [asyncResp, payload(task::Payload(req)),
+ taskMatchStr](const boost::system::error_code& ec,
+ const std::string&) mutable {
+ if (ec)
+ {
+ if (ec.value() ==
+ boost::system::errc::operation_not_supported)
+ {
+ messages::resourceInStandby(asyncResp->res);
+ }
+ else if (ec.value() == boost::system::errc::
+ device_or_resource_busy)
+ {
+ messages::serviceTemporarilyUnavailable(
+ asyncResp->res, "60");
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ }
+ return;
+ }
+ std::shared_ptr<task::TaskData> task =
+ task::TaskData::createTask(
+ [](const boost::system::error_code& ec2,
+ sdbusplus::message_t&,
+ const std::shared_ptr<task::TaskData>&
+ taskData) {
+ if (!ec2)
+ {
+ taskData->messages.emplace_back(
+ messages::taskCompletedOK(
+ std::to_string(
+ taskData->index)));
+ taskData->state = "Completed";
+ }
+ return task::completed;
+ },
+ taskMatchStr);
+
+ task->startTimer(std::chrono::minutes(5));
+ task->populateResp(asyncResp->res);
+ task->payload.emplace(std::move(payload));
+ };
+
+ crow::connections::systemBus->async_method_call(
+ std::move(collectCrashdumpCallback), crashdumpObject,
+ crashdumpPath, iface, method);
+ });
+}
- crow::connections::systemBus->async_method_call(
- std::move(collectCrashdumpCallback), crashdumpObject, crashdumpPath,
- iface, method);
- });
+inline void dBusLogServiceActionsClear(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ BMCWEB_LOG_DEBUG("Do delete all entries.");
+
+ // Process response from Logging service.
+ auto respHandler = [asyncResp](const boost::system::error_code& ec) {
+ BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
+ if (ec)
+ {
+ // TODO Handle for specific error code
+ BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
+ return;
+ }
+
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ };
+
+ // Make call to Logging service to request Clear Log
+ crow::connections::systemBus->async_method_call(
+ respHandler, "xyz.openbmc_project.Logging",
+ "/xyz/openbmc_project/logging",
+ "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
}
/**
@@ -3898,638 +3207,25 @@ inline void requestRoutesDBusLogServiceActionsClear(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- BMCWEB_LOG_DEBUG("Do delete all entries.");
-
- // Process response from Logging service.
- auto respHandler = [asyncResp](const boost::system::error_code& ec) {
- BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
- if (ec)
- {
- // TODO Handle for specific error code
- BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
- asyncResp->res.result(
- boost::beast::http::status::internal_server_error);
- return;
- }
-
- asyncResp->res.result(boost::beast::http::status::no_content);
- };
-
- // Make call to Logging service to request Clear Log
- crow::connections::systemBus->async_method_call(
- respHandler, "xyz.openbmc_project.Logging",
- "/xyz/openbmc_project/logging",
- "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
- });
-}
-
-/****************************************************
- * Redfish PostCode interfaces
- * using DBUS interface: getPostCodesTS
- ******************************************************/
-inline void requestRoutesPostCodesLogService(App& app)
-{
- BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/")
- .privileges(redfish::privileges::getLogService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/PostCodes",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogService.v1_2_0.LogService";
- asyncResp->res.jsonValue["Name"] = "POST Code Log Service";
- asyncResp->res.jsonValue["Description"] = "POST Code Log Service";
- asyncResp->res.jsonValue["Id"] = "PostCodes";
- asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
- asyncResp->res.jsonValue["Entries"]["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/PostCodes/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
-
- std::pair<std::string, std::string> redfishDateTimeOffset =
- redfish::time_utils::getDateTimeOffsetNow();
- asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
- asyncResp->res.jsonValue["DateTimeLocalOffset"] =
- redfishDateTimeOffset.second;
-
- asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
- ["target"] = std::format(
- "/redfish/v1/Systems/{}/LogServices/PostCodes/Actions/LogService.ClearLog",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- });
-}
-
-inline void requestRoutesPostCodesClear(App& app)
-{
- BMCWEB_ROUTE(
- app,
- "/redfish/v1/Systems/<str>/LogServices/PostCodes/Actions/LogService.ClearLog/")
- // The following privilege is incorrect; It should be ConfigureManager
- //.privileges(redfish::privileges::postLogService)
- .privileges({{"ConfigureComponents"}})
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- BMCWEB_LOG_DEBUG("Do delete all postcodes entries.");
-
- // Make call to post-code service to request clear all
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- // TODO Handle for specific error code
- BMCWEB_LOG_ERROR("doClearPostCodes resp_handler got error {}",
- ec);
- asyncResp->res.result(
- boost::beast::http::status::internal_server_error);
- messages::internalError(asyncResp->res);
- return;
- }
- messages::success(asyncResp->res);
- },
- "xyz.openbmc_project.State.Boot.PostCode0",
- "/xyz/openbmc_project/State/Boot/PostCode0",
- "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
- });
-}
-
-/**
- * @brief Parse post code ID and get the current value and index value
- * eg: postCodeID=B1-2, currentValue=1, index=2
- *
- * @param[in] postCodeID Post Code ID
- * @param[out] currentValue Current value
- * @param[out] index Index value
- *
- * @return bool true if the parsing is successful, false the parsing fails
- */
-inline bool parsePostCode(std::string_view postCodeID, uint64_t& currentValue,
- uint16_t& index)
-{
- std::vector<std::string> split;
- bmcweb::split(split, postCodeID, '-');
- if (split.size() != 2)
- {
- return false;
- }
- std::string_view postCodeNumber = split[0];
- if (postCodeNumber.size() < 2)
- {
- return false;
- }
- if (postCodeNumber[0] != 'B')
- {
- return false;
- }
- postCodeNumber.remove_prefix(1);
- auto [ptrIndex, ecIndex] = std::from_chars(postCodeNumber.begin(),
- postCodeNumber.end(), index);
- if (ptrIndex != postCodeNumber.end() || ecIndex != std::errc())
- {
- return false;
- }
-
- std::string_view postCodeIndex = split[1];
-
- auto [ptrValue, ecValue] = std::from_chars(
- postCodeIndex.begin(), postCodeIndex.end(), currentValue);
-
- return ptrValue == postCodeIndex.end() && ecValue == std::errc();
-}
-
-static bool fillPostCodeEntry(
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const boost::container::flat_map<
- uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& postcode,
- const uint16_t bootIndex, const uint64_t codeIndex = 0,
- const uint64_t skip = 0, const uint64_t top = 0)
-{
- // Get the Message from the MessageRegistry
- const registries::Message* message =
- registries::getMessage("OpenBMC.0.2.BIOSPOSTCode");
- if (message == nullptr)
- {
- BMCWEB_LOG_ERROR("Couldn't find known message?");
- return false;
- }
- uint64_t currentCodeIndex = 0;
- uint64_t firstCodeTimeUs = 0;
- for (const std::pair<uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>&
- code : postcode)
- {
- currentCodeIndex++;
- std::string postcodeEntryID =
- "B" + std::to_string(bootIndex) + "-" +
- std::to_string(currentCodeIndex); // 1 based index in EntryID string
-
- uint64_t usecSinceEpoch = code.first;
- uint64_t usTimeOffset = 0;
-
- if (1 == currentCodeIndex)
- { // already incremented
- firstCodeTimeUs = code.first;
- }
- else
- {
- usTimeOffset = code.first - firstCodeTimeUs;
- }
-
- // skip if no specific codeIndex is specified and currentCodeIndex does
- // not fall between top and skip
- if ((codeIndex == 0) &&
- (currentCodeIndex <= skip || currentCodeIndex > top))
- {
- continue;
- }
-
- // skip if a specific codeIndex is specified and does not match the
- // currentIndex
- if ((codeIndex > 0) && (currentCodeIndex != codeIndex))
- {
- // This is done for simplicity. 1st entry is needed to calculate
- // time offset. To improve efficiency, one can get to the entry
- // directly (possibly with flatmap's nth method)
- continue;
- }
-
- // currentCodeIndex is within top and skip or equal to specified code
- // index
-
- // Get the Created time from the timestamp
- std::string entryTimeStr;
- entryTimeStr = redfish::time_utils::getDateTimeUintUs(usecSinceEpoch);
-
- // assemble messageArgs: BootIndex, TimeOffset(100us), PostCode(hex)
- std::ostringstream hexCode;
- hexCode << "0x" << std::setfill('0') << std::setw(2) << std::hex
- << std::get<0>(code.second);
- std::ostringstream timeOffsetStr;
- // Set Fixed -Point Notation
- timeOffsetStr << std::fixed;
- // Set precision to 4 digits
- timeOffsetStr << std::setprecision(4);
- // Add double to stream
- timeOffsetStr << static_cast<double>(usTimeOffset) / 1000 / 1000;
-
- std::string bootIndexStr = std::to_string(bootIndex);
- std::string timeOffsetString = timeOffsetStr.str();
- std::string hexCodeStr = hexCode.str();
-
- std::array<std::string_view, 3> messageArgs = {
- bootIndexStr, timeOffsetString, hexCodeStr};
-
- std::string msg =
- redfish::registries::fillMessageArgs(messageArgs, message->message);
- if (msg.empty())
- {
- messages::internalError(asyncResp->res);
- return false;
- }
-
- // Get Severity template from message registry
- std::string severity;
- if (message != nullptr)
- {
- severity = message->messageSeverity;
- }
-
- // Format entry
- nlohmann::json::object_t bmcLogEntry;
- bmcLogEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
- bmcLogEntry["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/LogServices/PostCodes/Entries/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, postcodeEntryID);
- bmcLogEntry["Name"] = "POST Code Log Entry";
- bmcLogEntry["Id"] = postcodeEntryID;
- bmcLogEntry["Message"] = std::move(msg);
- bmcLogEntry["MessageId"] = "OpenBMC.0.2.BIOSPOSTCode";
- bmcLogEntry["MessageArgs"] = messageArgs;
- bmcLogEntry["EntryType"] = "Event";
- bmcLogEntry["Severity"] = std::move(severity);
- bmcLogEntry["Created"] = entryTimeStr;
- if (!std::get<std::vector<uint8_t>>(code.second).empty())
- {
- bmcLogEntry["AdditionalDataURI"] =
- std::format(
- "/redfish/v1/Systems/{}/LogServices/PostCodes/Entries/",
- BMCWEB_REDFISH_SYSTEM_URI_NAME) +
- postcodeEntryID + "/attachment";
- }
-
- // codeIndex is only specified when querying single entry, return only
- // that entry in this case
- if (codeIndex != 0)
- {
- asyncResp->res.jsonValue.update(bmcLogEntry);
- return true;
- }
-
- nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
- logEntryArray.emplace_back(std::move(bmcLogEntry));
- }
-
- // Return value is always false when querying multiple entries
- return false;
-}
-
-static void
- getPostCodeForEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& entryId)
-{
- uint16_t bootIndex = 0;
- uint64_t codeIndex = 0;
- if (!parsePostCode(entryId, codeIndex, bootIndex))
- {
- // Requested ID was not found
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
- return;
- }
-
- if (bootIndex == 0 || codeIndex == 0)
- {
- // 0 is an invalid index
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
- return;
- }
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, entryId, bootIndex,
- codeIndex](const boost::system::error_code& ec,
- const boost::container::flat_map<
- uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>&
- postcode) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS POST CODE PostCode response error");
- messages::internalError(asyncResp->res);
- return;
- }
-
- if (postcode.empty())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
- return;
- }
-
- if (!fillPostCodeEntry(asyncResp, postcode, bootIndex, codeIndex))
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
- return;
- }
- },
- "xyz.openbmc_project.State.Boot.PostCode0",
- "/xyz/openbmc_project/State/Boot/PostCode0",
- "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp",
- bootIndex);
-}
-
-static void
- getPostCodeForBoot(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const uint16_t bootIndex, const uint16_t bootCount,
- const uint64_t entryCount, size_t skip, size_t top)
-{
- crow::connections::systemBus->async_method_call(
- [asyncResp, bootIndex, bootCount, entryCount, skip,
- top](const boost::system::error_code& ec,
- const boost::container::flat_map<
- uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>&
- postcode) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS POST CODE PostCode response error");
- messages::internalError(asyncResp->res);
- return;
- }
-
- uint64_t endCount = entryCount;
- if (!postcode.empty())
- {
- endCount = entryCount + postcode.size();
- if (skip < endCount && (top + skip) > entryCount)
- {
- uint64_t thisBootSkip = std::max(static_cast<uint64_t>(skip),
- entryCount) -
- entryCount;
- uint64_t thisBootTop =
- std::min(static_cast<uint64_t>(top + skip), endCount) -
- entryCount;
-
- fillPostCodeEntry(asyncResp, postcode, bootIndex, 0,
- thisBootSkip, thisBootTop);
- }
- asyncResp->res.jsonValue["Members@odata.count"] = endCount;
- }
-
- // continue to previous bootIndex
- if (bootIndex < bootCount)
- {
- getPostCodeForBoot(asyncResp, static_cast<uint16_t>(bootIndex + 1),
- bootCount, endCount, skip, top);
- }
- else if (skip + top < endCount)
- {
- asyncResp->res.jsonValue["Members@odata.nextLink"] =
- std::format(
- "/redfish/v1/Systems/{}/LogServices/PostCodes/Entries?$skip=",
- BMCWEB_REDFISH_SYSTEM_URI_NAME) +
- std::to_string(skip + top);
- }
- },
- "xyz.openbmc_project.State.Boot.PostCode0",
- "/xyz/openbmc_project/State/Boot/PostCode0",
- "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp",
- bootIndex);
-}
-
-static void
- getCurrentBootNumber(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- size_t skip, size_t top)
-{
- uint64_t entryCount = 0;
- sdbusplus::asio::getProperty<uint16_t>(
- *crow::connections::systemBus,
- "xyz.openbmc_project.State.Boot.PostCode0",
- "/xyz/openbmc_project/State/Boot/PostCode0",
- "xyz.openbmc_project.State.Boot.PostCode", "CurrentBootCycleCount",
- [asyncResp, entryCount, skip, top](const boost::system::error_code& ec,
- const uint16_t bootCount) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- getPostCodeForBoot(asyncResp, 1, bootCount, entryCount, skip, top);
- });
-}
-
-inline void requestRoutesPostCodesEntryCollection(App& app)
-{
- BMCWEB_ROUTE(app,
- "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/")
- .privileges(redfish::privileges::getLogEntryCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- query_param::QueryCapabilities capabilities = {
- .canDelegateTop = true,
- .canDelegateSkip = true,
- };
- query_param::Query delegatedQuery;
- if (!redfish::setUpRedfishRouteWithDelegation(
- app, req, asyncResp, delegatedQuery, capabilities))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/PostCodes/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries";
- asyncResp->res.jsonValue["Description"] =
- "Collection of POST Code Log Entries";
- asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
- asyncResp->res.jsonValue["Members@odata.count"] = 0;
- size_t skip = delegatedQuery.skip.value_or(0);
- size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
- getCurrentBootNumber(asyncResp, skip, top);
- });
-}
-
-inline void requestRoutesPostCodesEntryAdditionalData(App& app)
-{
- BMCWEB_ROUTE(
- app,
- "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/attachment/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& postCodeID) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (!http_helpers::isContentTypeAllowed(
- req.getHeaderValue("Accept"),
- http_helpers::ContentType::OctetStream, true))
- {
- asyncResp->res.result(boost::beast::http::status::bad_request);
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- uint64_t currentValue = 0;
- uint16_t index = 0;
- if (!parsePostCode(postCodeID, currentValue, index))
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", postCodeID);
- return;
- }
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, postCodeID, currentValue](
- const boost::system::error_code& ec,
- const std::vector<std::tuple<uint64_t, std::vector<uint8_t>>>&
- postcodes) {
- if (ec.value() == EBADR)
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry",
- postCodeID);
- return;
- }
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- size_t value = static_cast<size_t>(currentValue) - 1;
- if (value == std::string::npos || postcodes.size() < currentValue)
- {
- BMCWEB_LOG_WARNING("Wrong currentValue value");
- messages::resourceNotFound(asyncResp->res, "LogEntry",
- postCodeID);
- return;
- }
-
- const auto& [tID, c] = postcodes[value];
- if (c.empty())
- {
- BMCWEB_LOG_WARNING("No found post code data");
- messages::resourceNotFound(asyncResp->res, "LogEntry",
- postCodeID);
- return;
- }
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const char* d = reinterpret_cast<const char*>(c.data());
- std::string_view strData(d, c.size());
-
- asyncResp->res.addHeader(boost::beast::http::field::content_type,
- "application/octet-stream");
- asyncResp->res.addHeader(
- boost::beast::http::field::content_transfer_encoding, "Base64");
- asyncResp->res.write(crow::utility::base64encode(strData));
- },
- "xyz.openbmc_project.State.Boot.PostCode0",
- "/xyz/openbmc_project/State/Boot/PostCode0",
- "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodes", index);
- });
-}
-
-inline void requestRoutesPostCodesEntry(App& app)
-{
- BMCWEB_ROUTE(
- app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName, const std::string& targetID) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- getPostCodeForEntry(asyncResp, targetID);
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ dBusLogServiceActionsClear(asyncResp);
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/manager_diagnostic_data.hpp b/redfish-core/lib/manager_diagnostic_data.hpp
index 1856e1f9e6..1ca80fdd54 100644
--- a/redfish-core/lib/manager_diagnostic_data.hpp
+++ b/redfish-core/lib/manager_diagnostic_data.hpp
@@ -106,8 +106,8 @@ inline void
}
static constexpr double roundFactor = 10000; // 4 decimal places
- asyncResp->res.jsonValue[jPtr] = std::round(userCPU * roundFactor) /
- roundFactor;
+ asyncResp->res.jsonValue[jPtr] =
+ std::round(userCPU * roundFactor) / roundFactor;
}
inline void managerGetProcessorStatistics(
diff --git a/redfish-core/lib/manager_logservices_journal.hpp b/redfish-core/lib/manager_logservices_journal.hpp
new file mode 100644
index 0000000000..17fb95bfc5
--- /dev/null
+++ b/redfish-core/lib/manager_logservices_journal.hpp
@@ -0,0 +1,655 @@
+#pragma once
+
+#include "app.hpp"
+#include "error_messages.hpp"
+#include "generated/enums/log_entry.hpp"
+#include "query.hpp"
+#include "registries/base_message_registry.hpp"
+#include "registries/privilege_registry.hpp"
+#include "utils/time_utils.hpp"
+
+#include <systemd/sd-journal.h>
+
+#include <boost/beast/http/verb.hpp>
+
+#include <array>
+#include <memory>
+#include <string>
+#include <string_view>
+
+namespace redfish
+{
+// Entry is formed like "BootID_timestamp" or "BootID_timestamp_index"
+inline bool
+ getTimestampFromID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ std::string_view entryIDStrView, sd_id128_t& bootID,
+ uint64_t& timestamp, uint64_t& index)
+{
+ // Convert the unique ID back to a bootID + timestamp to find the entry
+ auto underscore1Pos = entryIDStrView.find('_');
+ if (underscore1Pos == std::string_view::npos)
+ {
+ // EntryID has no bootID or timestamp
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
+ }
+
+ // EntryID has bootID + timestamp
+
+ // Convert entryIDViewString to BootID
+ // NOTE: bootID string which needs to be null-terminated for
+ // sd_id128_from_string()
+ std::string bootIDStr(entryIDStrView.substr(0, underscore1Pos));
+ if (sd_id128_from_string(bootIDStr.c_str(), &bootID) < 0)
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
+ }
+
+ // Get the timestamp from entryID
+ entryIDStrView.remove_prefix(underscore1Pos + 1);
+
+ auto [timestampEnd, tstampEc] = std::from_chars(
+ entryIDStrView.begin(), entryIDStrView.end(), timestamp);
+ if (tstampEc != std::errc())
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
+ }
+ entryIDStrView = std::string_view(
+ timestampEnd,
+ static_cast<size_t>(std::distance(timestampEnd, entryIDStrView.end())));
+ if (entryIDStrView.empty())
+ {
+ index = 0U;
+ return true;
+ }
+ // Timestamp might include optional index, if two events happened at the
+ // same "time".
+ if (entryIDStrView[0] != '_')
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
+ }
+ entryIDStrView.remove_prefix(1);
+ auto [ptr, indexEc] =
+ std::from_chars(entryIDStrView.begin(), entryIDStrView.end(), index);
+ if (indexEc != std::errc() || ptr != entryIDStrView.end())
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
+ }
+ if (index <= 1)
+ {
+ // Indexes go directly from no postfix (handled above) to _2
+ // so if we ever see _0 or _1, it's incorrect
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
+ }
+
+ // URI indexes are one based, journald is zero based
+ index -= 1;
+ return true;
+}
+
+inline std::string getUniqueEntryID(uint64_t index, uint64_t curTs,
+ sd_id128_t& curBootID)
+{
+ // make entryID as <bootID>_<timestamp>[_<index>]
+ std::array<char, SD_ID128_STRING_MAX> bootIDStr{};
+ sd_id128_to_string(curBootID, bootIDStr.data());
+ std::string postfix;
+ if (index > 0)
+ {
+ postfix = std::format("_{}", index + 1);
+ }
+ return std::format("{}_{}{}", bootIDStr.data(), curTs, postfix);
+}
+
+inline int getJournalMetadata(sd_journal* journal, std::string_view field,
+ std::string_view& contents)
+{
+ const char* data = nullptr;
+ size_t length = 0;
+ int ret = 0;
+ // Get the metadata from the requested field of the journal entry
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ const void** dataVoid = reinterpret_cast<const void**>(&data);
+
+ ret = sd_journal_get_data(journal, field.data(), dataVoid, &length);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ contents = std::string_view(data, length);
+ // Only use the content after the "=" character.
+ contents.remove_prefix(std::min(contents.find('=') + 1, contents.size()));
+ return ret;
+}
+
+inline int getJournalMetadataInt(sd_journal* journal, std::string_view field,
+ const int& base, long int& contents)
+{
+ int ret = 0;
+ std::string_view metadata;
+ // Get the metadata from the requested field of the journal entry
+ ret = getJournalMetadata(journal, field, metadata);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ contents = strtol(metadata.data(), nullptr, base);
+ return ret;
+}
+
+inline bool getEntryTimestamp(sd_journal* journal, std::string& entryTimestamp)
+{
+ int ret = 0;
+ uint64_t timestamp = 0;
+ ret = sd_journal_get_realtime_usec(journal, &timestamp);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}", strerror(-ret));
+ return false;
+ }
+ entryTimestamp = redfish::time_utils::getDateTimeUintUs(timestamp);
+ return true;
+}
+
+inline bool fillBMCJournalLogEntryJson(
+ const std::string& bmcJournalLogEntryID, sd_journal* journal,
+ nlohmann::json::object_t& bmcJournalLogEntryJson)
+{
+ // Get the Log Entry contents
+ std::string message;
+ std::string_view syslogID;
+ int ret = getJournalMetadata(journal, "SYSLOG_IDENTIFIER", syslogID);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_DEBUG("Failed to read SYSLOG_IDENTIFIER field: {}",
+ strerror(-ret));
+ }
+ if (!syslogID.empty())
+ {
+ message += std::string(syslogID) + ": ";
+ }
+
+ std::string_view msg;
+ ret = getJournalMetadata(journal, "MESSAGE", msg);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to read MESSAGE field: {}", strerror(-ret));
+ return false;
+ }
+ message += std::string(msg);
+
+ // Get the severity from the PRIORITY field
+ long int severity = 8; // Default to an invalid priority
+ ret = getJournalMetadataInt(journal, "PRIORITY", 10, severity);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_DEBUG("Failed to read PRIORITY field: {}", strerror(-ret));
+ }
+
+ // Get the Created time from the timestamp
+ std::string entryTimeStr;
+ if (!getEntryTimestamp(journal, entryTimeStr))
+ {
+ return false;
+ }
+
+ // Fill in the log entry with the gathered data
+ bmcJournalLogEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+ bmcJournalLogEntryJson["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/Journal/Entries/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, bmcJournalLogEntryID);
+ bmcJournalLogEntryJson["Name"] = "BMC Journal Entry";
+ bmcJournalLogEntryJson["Id"] = bmcJournalLogEntryID;
+ bmcJournalLogEntryJson["Message"] = std::move(message);
+ bmcJournalLogEntryJson["EntryType"] = log_entry::LogEntryType::Oem;
+ log_entry::EventSeverity severityEnum = log_entry::EventSeverity::OK;
+ if (severity <= 2)
+ {
+ severityEnum = log_entry::EventSeverity::Critical;
+ }
+ else if (severity <= 4)
+ {
+ severityEnum = log_entry::EventSeverity::Warning;
+ }
+
+ bmcJournalLogEntryJson["Severity"] = severityEnum;
+ bmcJournalLogEntryJson["OemRecordFormat"] = "BMC Journal Entry";
+ bmcJournalLogEntryJson["Created"] = std::move(entryTimeStr);
+ return true;
+}
+
+inline void handleManagersLogServiceJournalGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& managerId)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager", managerId);
+ return;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
+ asyncResp->res.jsonValue["@odata.id"] =
+ boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["Name"] = "Open BMC Journal Log Service";
+ asyncResp->res.jsonValue["Description"] = "BMC Journal Log Service";
+ asyncResp->res.jsonValue["Id"] = "Journal";
+ asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
+
+ std::pair<std::string, std::string> redfishDateTimeOffset =
+ redfish::time_utils::getDateTimeOffsetNow();
+ asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
+ asyncResp->res.jsonValue["DateTimeLocalOffset"] =
+ redfishDateTimeOffset.second;
+
+ asyncResp->res.jsonValue["Entries"]["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/Journal/Entries",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+}
+
+struct JournalReadState
+{
+ std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal;
+ uint64_t index = 0;
+ sd_id128_t prevBootID{};
+ uint64_t prevTs = 0;
+};
+
+inline void readJournalEntries(
+ uint64_t topEntryCount, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ JournalReadState&& readState)
+{
+ nlohmann::json& logEntry = asyncResp->res.jsonValue["Members"];
+ nlohmann::json::array_t* logEntryArray =
+ logEntry.get_ptr<nlohmann::json::array_t*>();
+ if (logEntryArray == nullptr)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // The Journal APIs unfortunately do blocking calls to the filesystem, and
+ // can be somewhat expensive. Short of creating our own io_uring based
+ // implementation of sd-journal, which would be difficult, the best thing we
+ // can do is to only parse a certain number of entries at a time. The
+ // current chunk size is selected arbitrarily to ensure that we're not
+ // trying to process thousands of entries at the same time.
+ // The implementation will process the number of entries, then return
+ // control to the io_context to let other operations continue.
+ size_t segmentCountRemaining = 10;
+
+ // Reset the unique ID on the first entry
+ for (uint64_t entryCount = logEntryArray->size();
+ entryCount < topEntryCount; entryCount++)
+ {
+ if (segmentCountRemaining == 0)
+ {
+ boost::asio::post(crow::connections::systemBus->get_io_context(),
+ [asyncResp, topEntryCount,
+ readState = std::move(readState)]() mutable {
+ readJournalEntries(topEntryCount, asyncResp,
+ std::move(readState));
+ });
+ return;
+ }
+
+ // Get the entry timestamp
+ sd_id128_t curBootID{};
+ uint64_t curTs = 0;
+ int ret = sd_journal_get_monotonic_usec(readState.journal.get(), &curTs,
+ &curBootID);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}",
+ strerror(-ret));
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // If the timestamp isn't unique on the same boot, increment the index
+ bool sameBootIDs = sd_id128_equal(curBootID, readState.prevBootID) != 0;
+ if (sameBootIDs && (curTs == readState.prevTs))
+ {
+ readState.index++;
+ }
+ else
+ {
+ // Otherwise, reset it
+ readState.index = 0;
+ }
+
+ // Save the bootID
+ readState.prevBootID = curBootID;
+
+ // Save the timestamp
+ readState.prevTs = curTs;
+
+ std::string idStr = getUniqueEntryID(readState.index, curTs, curBootID);
+
+ nlohmann::json::object_t bmcJournalLogEntry;
+ if (!fillBMCJournalLogEntryJson(idStr, readState.journal.get(),
+ bmcJournalLogEntry))
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ logEntryArray->emplace_back(std::move(bmcJournalLogEntry));
+
+ ret = sd_journal_next(readState.journal.get());
+ if (ret < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (ret == 0)
+ {
+ break;
+ }
+ segmentCountRemaining--;
+ }
+}
+
+inline void handleManagersJournalLogEntryCollectionGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& managerId)
+{
+ query_param::QueryCapabilities capabilities = {
+ .canDelegateTop = true,
+ .canDelegateSkip = true,
+ };
+ query_param::Query delegatedQuery;
+ if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
+ delegatedQuery, capabilities))
+ {
+ return;
+ }
+
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager", managerId);
+ return;
+ }
+
+ size_t skip = delegatedQuery.skip.value_or(0);
+ size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
+
+ // Collections don't include the static data added by SubRoute
+ // because it has a duplicate entry for members
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/Journal/Entries",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["Name"] = "Open BMC Journal Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of BMC Journal Entries";
+ asyncResp->res.jsonValue["Members"] = nlohmann::json::array_t();
+
+ // Go through the journal and use the timestamp to create a
+ // unique ID for each entry
+ sd_journal* journalTmp = nullptr;
+ int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("failed to open journal: {}", strerror(-ret));
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
+ journalTmp, sd_journal_close);
+ journalTmp = nullptr;
+
+ // Seek to the end
+ if (sd_journal_seek_tail(journal.get()) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // Get the last entry
+ if (sd_journal_previous(journal.get()) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // Get the last sequence number
+ uint64_t endSeqNum = 0;
+#if LIBSYSTEMD_VERSION >= 254
+ {
+ if (sd_journal_get_seqnum(journal.get(), &endSeqNum, nullptr) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+#endif
+
+ // Seek to the beginning
+ if (sd_journal_seek_head(journal.get()) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // Get the first entry
+ if (sd_journal_next(journal.get()) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // Get the first sequence number
+ uint64_t startSeqNum = 0;
+#if LIBSYSTEMD_VERSION >= 254
+ {
+ if (sd_journal_get_seqnum(journal.get(), &startSeqNum, nullptr) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+#endif
+
+ BMCWEB_LOG_DEBUG("journal Sequence IDs start:{} end:{}", startSeqNum,
+ endSeqNum);
+
+ // Add 1 to account for the last entry
+ uint64_t totalEntries = endSeqNum - startSeqNum + 1;
+ asyncResp->res.jsonValue["Members@odata.count"] = totalEntries;
+ if (skip + top < totalEntries)
+ {
+ asyncResp->res.jsonValue["Members@odata.nextLink"] =
+ boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/Journal/Entries?$skip={}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, std::to_string(skip + top));
+ }
+ uint64_t index = 0;
+ sd_id128_t curBootID{};
+ uint64_t curTs = 0;
+ if (skip > 0)
+ {
+ if (sd_journal_next_skip(journal.get(), skip) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // Get the entry timestamp
+ ret = sd_journal_get_monotonic_usec(journal.get(), &curTs, &curBootID);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}",
+ strerror(-ret));
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ uint64_t endChunkSeqNum = 0;
+#if LIBSYSTEMD_VERSION >= 254
+ {
+ if (sd_journal_get_seqnum(journal.get(), &endChunkSeqNum, nullptr) <
+ 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+#endif
+
+ // Seek to the first entry with the same timestamp and boot
+ ret = sd_journal_seek_monotonic_usec(journal.get(), curBootID, curTs);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to seek: {}", strerror(-ret));
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (sd_journal_next(journal.get()) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ uint64_t startChunkSeqNum = 0;
+#if LIBSYSTEMD_VERSION >= 254
+ {
+ if (sd_journal_get_seqnum(journal.get(), &startChunkSeqNum,
+ nullptr) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+#endif
+
+ // Get the difference between the start and end. Most of the time this
+ // will be 0
+ BMCWEB_LOG_DEBUG("start={} end={}", startChunkSeqNum, endChunkSeqNum);
+ index = endChunkSeqNum - startChunkSeqNum;
+ if (index > endChunkSeqNum)
+ {
+ // Detect underflows. Should never happen.
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (index > 0)
+ {
+ BMCWEB_LOG_DEBUG("index = {}", index);
+ if (sd_journal_next_skip(journal.get(), index) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+ }
+ // If this is the first entry of this series, reset the timestamps so the
+ // Index doesn't increment
+ if (index == 0)
+ {
+ curBootID = {};
+ curTs = 0;
+ }
+ else
+ {
+ index -= 1;
+ }
+ BMCWEB_LOG_DEBUG("Index was {}", index);
+ readJournalEntries(top, asyncResp,
+ {std::move(journal), index, curBootID, curTs});
+}
+
+inline void handleManagersJournalEntriesLogEntryGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& managerId, const std::string& entryID)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager", managerId);
+ return;
+ }
+
+ // Convert the unique ID back to a timestamp to find the entry
+ sd_id128_t bootID{};
+ uint64_t ts = 0;
+ uint64_t index = 0;
+ if (!getTimestampFromID(asyncResp, entryID, bootID, ts, index))
+ {
+ return;
+ }
+
+ sd_journal* journalTmp = nullptr;
+ int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("failed to open journal: {}", strerror(-ret));
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
+ journalTmp, sd_journal_close);
+ journalTmp = nullptr;
+ // Go to the timestamp in the log and move to the entry at the
+ // index tracking the unique ID
+ ret = sd_journal_seek_monotonic_usec(journal.get(), bootID, ts);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("failed to seek to an entry in journal{}",
+ strerror(-ret));
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (sd_journal_next_skip(journal.get(), index + 1) < 0)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ nlohmann::json::object_t bmcJournalLogEntry;
+ if (!fillBMCJournalLogEntryJson(entryID, journal.get(), bmcJournalLogEntry))
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue.update(bmcJournalLogEntry);
+}
+
+inline void requestRoutesBMCJournalLogService(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Journal/")
+ .privileges(redfish::privileges::getLogService)
+ .methods(boost::beast::http::verb::get)(
+ std::bind_front(handleManagersLogServiceJournalGet, std::ref(app)));
+
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Journal/Entries/")
+ .privileges(redfish::privileges::getLogEntryCollection)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleManagersJournalLogEntryCollectionGet, std::ref(app)));
+
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Managers/<str>/LogServices/Journal/Entries/<str>/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleManagersJournalEntriesLogEntryGet, std::ref(app)));
+}
+} // namespace redfish
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index f0a4e0ab21..c4f9956cf5 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -19,6 +19,9 @@
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/action_info.hpp"
+#include "generated/enums/manager.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries/privilege_registry.hpp"
@@ -67,16 +70,16 @@ inline void
*crow::connections::systemBus, processName, objectPath, interfaceName,
destProperty, propertyValue,
[asyncResp](const boost::system::error_code& ec) {
- // Use "Set" method to set the property value.
- if (ec)
- {
- BMCWEB_LOG_DEBUG("[Set] Bad D-Bus request error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ // Use "Set" method to set the property value.
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("[Set] Bad D-Bus request error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- messages::success(asyncResp->res);
- });
+ messages::success(asyncResp->res);
+ });
}
inline void
@@ -94,16 +97,16 @@ inline void
*crow::connections::systemBus, processName, objectPath, interfaceName,
destProperty, propertyValue,
[asyncResp](const boost::system::error_code& ec) {
- // Use "Set" method to set the property value.
- if (ec)
- {
- BMCWEB_LOG_DEBUG("[Set] Bad D-Bus request error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ // Use "Set" method to set the property value.
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("[Set] Bad D-Bus request error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- messages::success(asyncResp->res);
- });
+ messages::success(asyncResp->res);
+ });
}
/**
@@ -124,44 +127,46 @@ inline void requestRoutesManagerResetAction(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- BMCWEB_LOG_DEBUG("Post Manager Reset.");
+ BMCWEB_LOG_DEBUG("Post Manager Reset.");
- std::string resetType;
+ std::string resetType;
- if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
- resetType))
- {
- return;
- }
+ if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
+ resetType))
+ {
+ return;
+ }
- if (resetType == "GracefulRestart")
- {
- BMCWEB_LOG_DEBUG("Proceeding with {}", resetType);
- doBMCGracefulRestart(asyncResp);
- return;
- }
- if (resetType == "ForceRestart")
- {
- BMCWEB_LOG_DEBUG("Proceeding with {}", resetType);
- doBMCForceRestart(asyncResp);
- return;
- }
- BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}", resetType);
- messages::actionParameterNotSupported(asyncResp->res, resetType,
- "ResetType");
+ if (resetType == "GracefulRestart")
+ {
+ BMCWEB_LOG_DEBUG("Proceeding with {}", resetType);
+ doBMCGracefulRestart(asyncResp);
+ return;
+ }
+ if (resetType == "ForceRestart")
+ {
+ BMCWEB_LOG_DEBUG("Proceeding with {}", resetType);
+ doBMCForceRestart(asyncResp);
+ return;
+ }
+ BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}",
+ resetType);
+ messages::actionParameterNotSupported(asyncResp->res, resetType,
+ "ResetType");
- return;
- });
+ return;
+ });
}
/**
@@ -185,70 +190,73 @@ inline void requestRoutesManagerResetToDefaultsAction(App& app)
BMCWEB_ROUTE(app,
"/redfish/v1/Managers/<str>/Actions/Manager.ResetToDefaults/")
.privileges(redfish::privileges::postManager)
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ .methods(
+ boost::beast::http::verb::
+ post)([&app](
+ const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& managerId) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- BMCWEB_LOG_DEBUG("Post ResetToDefaults.");
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- std::optional<std::string> resetType;
- std::optional<std::string> resetToDefaultsType;
+ BMCWEB_LOG_DEBUG("Post ResetToDefaults.");
- if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
- resetType, "ResetToDefaultsType",
- resetToDefaultsType))
- {
- BMCWEB_LOG_DEBUG("Missing property ResetType.");
+ std::optional<std::string> resetType;
+ std::optional<std::string> resetToDefaultsType;
- messages::actionParameterMissing(asyncResp->res, "ResetToDefaults",
- "ResetType");
- return;
- }
+ if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
+ resetType, "ResetToDefaultsType",
+ resetToDefaultsType))
+ {
+ BMCWEB_LOG_DEBUG("Missing property ResetType.");
- if (resetToDefaultsType && !resetType)
- {
- BMCWEB_LOG_WARNING(
- "Using deprecated ResetToDefaultsType, should be ResetType."
- "Support for the ResetToDefaultsType will be dropped in 2Q24");
- resetType = resetToDefaultsType;
- }
+ messages::actionParameterMissing(
+ asyncResp->res, "ResetToDefaults", "ResetType");
+ return;
+ }
- if (resetType != "ResetAll")
- {
- BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}",
- *resetType);
- messages::actionParameterNotSupported(asyncResp->res, *resetType,
- "ResetType");
- return;
- }
+ if (resetToDefaultsType && !resetType)
+ {
+ BMCWEB_LOG_WARNING(
+ "Using deprecated ResetToDefaultsType, should be ResetType."
+ "Support for the ResetToDefaultsType will be dropped in 2Q24");
+ resetType = resetToDefaultsType;
+ }
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code& ec) {
- if (ec)
+ if (resetType != "ResetAll")
{
- BMCWEB_LOG_DEBUG("Failed to ResetToDefaults: {}", ec);
- messages::internalError(asyncResp->res);
+ BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}",
+ *resetType);
+ messages::actionParameterNotSupported(asyncResp->res,
+ *resetType, "ResetType");
return;
}
- // Factory Reset doesn't actually happen until a reboot
- // Can't erase what the BMC is running on
- doBMCGracefulRestart(asyncResp);
- },
- "xyz.openbmc_project.Software.BMC.Updater",
- "/xyz/openbmc_project/software",
- "xyz.openbmc_project.Common.FactoryReset", "Reset");
- });
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("Failed to ResetToDefaults: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // Factory Reset doesn't actually happen until a reboot
+ // Can't erase what the BMC is running on
+ doBMCGracefulRestart(asyncResp);
+ },
+ "xyz.openbmc_project.Software.BMC.Updater",
+ "/xyz/openbmc_project/software",
+ "xyz.openbmc_project.Common.FactoryReset", "Reset");
+ });
}
/**
@@ -267,39 +275,40 @@ inline void requestRoutesManagerResetActionInfo(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.type"] =
- "#ActionInfo.v1_1_2.ActionInfo";
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/ResetActionInfo",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["Name"] = "Reset Action Info";
- asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
- nlohmann::json::object_t parameter;
- parameter["Name"] = "ResetType";
- parameter["Required"] = true;
- parameter["DataType"] = "String";
-
- nlohmann::json::array_t allowableValues;
- allowableValues.emplace_back("GracefulRestart");
- allowableValues.emplace_back("ForceRestart");
- parameter["AllowableValues"] = std::move(allowableValues);
-
- nlohmann::json::array_t parameters;
- parameters.emplace_back(std::move(parameter));
-
- asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
- });
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ActionInfo.v1_1_2.ActionInfo";
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/ResetActionInfo",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["Name"] = "Reset Action Info";
+ asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = action_info::ParameterTypes::String;
+
+ nlohmann::json::array_t allowableValues;
+ allowableValues.emplace_back("GracefulRestart");
+ allowableValues.emplace_back("ForceRestart");
+ parameter["AllowableValues"] = std::move(allowableValues);
+
+ nlohmann::json::array_t parameters;
+ parameters.emplace_back(std::move(parameter));
+
+ asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
+ });
}
static constexpr const char* objectManagerIface =
@@ -325,231 +334,221 @@ inline void
[asyncResp, currentProfile, supportedProfiles](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& managedObj) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("{}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- nlohmann::json& configRoot =
- asyncResp->res.jsonValue["Oem"]["OpenBmc"]["Fan"];
- nlohmann::json& fans = configRoot["FanControllers"];
- fans["@odata.type"] = "#OemManager.FanControllers";
- fans["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/FanControllers",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
-
- nlohmann::json& pids = configRoot["PidControllers"];
- pids["@odata.type"] = "#OemManager.PidControllers";
- pids["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/PidControllers",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
-
- nlohmann::json& stepwise = configRoot["StepwiseControllers"];
- stepwise["@odata.type"] = "#OemManager.StepwiseControllers";
- stepwise["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/StepwiseControllers",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
-
- nlohmann::json& zones = configRoot["FanZones"];
- zones["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/FanZones",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- zones["@odata.type"] = "#OemManager.FanZones";
- configRoot["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- configRoot["@odata.type"] = "#OemManager.Fan";
- configRoot["Profile@Redfish.AllowableValues"] = supportedProfiles;
-
- if (!currentProfile.empty())
- {
- configRoot["Profile"] = currentProfile;
- }
- BMCWEB_LOG_DEBUG("profile = {} !", currentProfile);
-
- for (const auto& pathPair : managedObj)
- {
- for (const auto& intfPair : pathPair.second)
+ if (ec)
{
- if (intfPair.first != pidConfigurationIface &&
- intfPair.first != pidZoneConfigurationIface &&
- intfPair.first != stepwiseConfigurationIface)
- {
- continue;
- }
+ BMCWEB_LOG_ERROR("{}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ nlohmann::json& configRoot =
+ asyncResp->res.jsonValue["Oem"]["OpenBmc"]["Fan"];
+ nlohmann::json& fans = configRoot["FanControllers"];
+ fans["@odata.type"] =
+ "#OpenBMCManager.v1_0_0.Manager.FanControllers";
+ fans["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/FanControllers",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+
+ nlohmann::json& pids = configRoot["PidControllers"];
+ pids["@odata.type"] =
+ "#OpenBMCManager.v1_0_0.Manager.PidControllers";
+ pids["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/PidControllers",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+
+ nlohmann::json& stepwise = configRoot["StepwiseControllers"];
+ stepwise["@odata.type"] =
+ "#OpenBMCManager.v1_0_0.Manager.StepwiseControllers";
+ stepwise["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/StepwiseControllers",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+
+ nlohmann::json& zones = configRoot["FanZones"];
+ zones["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan/FanZones",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ zones["@odata.type"] = "#OpenBMCManager.v1_0_0.Manager.FanZones";
+ configRoot["@odata.id"] =
+ boost::urls::format("/redfish/v1/Managers/{}#/Oem/OpenBmc/Fan",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ configRoot["@odata.type"] = "#OpenBMCManager.v1_0_0.Manager.Fan";
+ configRoot["Profile@Redfish.AllowableValues"] = supportedProfiles;
- std::string name;
+ if (!currentProfile.empty())
+ {
+ configRoot["Profile"] = currentProfile;
+ }
+ BMCWEB_LOG_DEBUG("profile = {} !", currentProfile);
- for (const std::pair<std::string,
- dbus::utility::DbusVariantType>& propPair :
- intfPair.second)
+ for (const auto& pathPair : managedObj)
+ {
+ for (const auto& intfPair : pathPair.second)
{
- if (propPair.first == "Name")
+ if (intfPair.first != pidConfigurationIface &&
+ intfPair.first != pidZoneConfigurationIface &&
+ intfPair.first != stepwiseConfigurationIface)
{
- const std::string* namePtr =
- std::get_if<std::string>(&propPair.second);
- if (namePtr == nullptr)
- {
- BMCWEB_LOG_ERROR("Pid Name Field illegal");
- messages::internalError(asyncResp->res);
- return;
- }
- name = *namePtr;
- dbus::utility::escapePathForDbus(name);
+ continue;
}
- else if (propPair.first == "Profiles")
+
+ std::string name;
+
+ for (const std::pair<std::string,
+ dbus::utility::DbusVariantType>&
+ propPair : intfPair.second)
{
- const std::vector<std::string>* profiles =
- std::get_if<std::vector<std::string>>(
- &propPair.second);
- if (profiles == nullptr)
+ if (propPair.first == "Name")
{
- BMCWEB_LOG_ERROR("Pid Profiles Field illegal");
- messages::internalError(asyncResp->res);
- return;
+ const std::string* namePtr =
+ std::get_if<std::string>(&propPair.second);
+ if (namePtr == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Pid Name Field illegal");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ name = *namePtr;
+ dbus::utility::escapePathForDbus(name);
}
- if (std::find(profiles->begin(), profiles->end(),
- currentProfile) == profiles->end())
+ else if (propPair.first == "Profiles")
{
- BMCWEB_LOG_INFO(
- "{} not supported in current profile", name);
- continue;
+ const std::vector<std::string>* profiles =
+ std::get_if<std::vector<std::string>>(
+ &propPair.second);
+ if (profiles == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Pid Profiles Field illegal");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (std::find(profiles->begin(), profiles->end(),
+ currentProfile) == profiles->end())
+ {
+ BMCWEB_LOG_INFO(
+ "{} not supported in current profile",
+ name);
+ continue;
+ }
}
}
- }
- nlohmann::json* config = nullptr;
- const std::string* classPtr = nullptr;
-
- for (const std::pair<std::string,
- dbus::utility::DbusVariantType>& propPair :
- intfPair.second)
- {
- if (propPair.first == "Class")
- {
- classPtr = std::get_if<std::string>(&propPair.second);
- }
- }
+ nlohmann::json* config = nullptr;
+ const std::string* classPtr = nullptr;
- boost::urls::url url(
- boost::urls::format("/redfish/v1/Managers/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME));
- if (intfPair.first == pidZoneConfigurationIface)
- {
- std::string chassis;
- if (!dbus::utility::getNthStringFromPath(pathPair.first.str,
- 5, chassis))
+ for (const std::pair<std::string,
+ dbus::utility::DbusVariantType>&
+ propPair : intfPair.second)
{
- chassis = "#IllegalValue";
- }
- nlohmann::json& zone = zones[name];
- zone["Chassis"]["@odata.id"] =
- boost::urls::format("/redfish/v1/Chassis/{}", chassis);
- url.set_fragment(
- ("/Oem/OpenBmc/Fan/FanZones"_json_pointer / name)
- .to_string());
- zone["@odata.id"] = std::move(url);
- zone["@odata.type"] = "#OemManager.FanZone";
- config = &zone;
- }
-
- else if (intfPair.first == stepwiseConfigurationIface)
- {
- if (classPtr == nullptr)
- {
- BMCWEB_LOG_ERROR("Pid Class Field illegal");
- messages::internalError(asyncResp->res);
- return;
+ if (propPair.first == "Class")
+ {
+ classPtr =
+ std::get_if<std::string>(&propPair.second);
+ }
}
- nlohmann::json& controller = stepwise[name];
- config = &controller;
- url.set_fragment(
- ("/Oem/OpenBmc/Fan/StepwiseControllers"_json_pointer /
- name)
- .to_string());
- controller["@odata.id"] = std::move(url);
- controller["@odata.type"] =
- "#OemManager.StepwiseController";
-
- controller["Direction"] = *classPtr;
- }
-
- // pid and fans are off the same configuration
- else if (intfPair.first == pidConfigurationIface)
- {
- if (classPtr == nullptr)
- {
- BMCWEB_LOG_ERROR("Pid Class Field illegal");
- messages::internalError(asyncResp->res);
- return;
- }
- bool isFan = *classPtr == "fan";
- nlohmann::json& element = isFan ? fans[name] : pids[name];
- config = &element;
- if (isFan)
+ boost::urls::url url(
+ boost::urls::format("/redfish/v1/Managers/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME));
+ if (intfPair.first == pidZoneConfigurationIface)
{
+ std::string chassis;
+ if (!dbus::utility::getNthStringFromPath(
+ pathPair.first.str, 5, chassis))
+ {
+ chassis = "#IllegalValue";
+ }
+ nlohmann::json& zone = zones[name];
+ zone["Chassis"]["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}", chassis);
url.set_fragment(
- ("/Oem/OpenBmc/Fan/FanControllers"_json_pointer /
- name)
+ ("/Oem/OpenBmc/Fan/FanZones"_json_pointer / name)
.to_string());
- element["@odata.id"] = std::move(url);
- element["@odata.type"] = "#OemManager.FanController";
+ zone["@odata.id"] = std::move(url);
+ zone["@odata.type"] =
+ "#OpenBMCManager.v1_0_0.Manager.FanZone";
+ config = &zone;
}
- else
+
+ else if (intfPair.first == stepwiseConfigurationIface)
{
+ if (classPtr == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Pid Class Field illegal");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ nlohmann::json& controller = stepwise[name];
+ config = &controller;
url.set_fragment(
- ("/Oem/OpenBmc/Fan/PidControllers"_json_pointer /
+ ("/Oem/OpenBmc/Fan/StepwiseControllers"_json_pointer /
name)
.to_string());
- element["@odata.id"] = std::move(url);
- element["@odata.type"] = "#OemManager.PidController";
- }
- }
- else
- {
- BMCWEB_LOG_ERROR("Unexpected configuration");
- messages::internalError(asyncResp->res);
- return;
- }
-
- // used for making maps out of 2 vectors
- const std::vector<double>* keys = nullptr;
- const std::vector<double>* values = nullptr;
+ controller["@odata.id"] = std::move(url);
+ controller["@odata.type"] =
+ "#OpenBMCManager.v1_0_0.Manager.StepwiseController";
- for (const auto& propertyPair : intfPair.second)
- {
- if (propertyPair.first == "Type" ||
- propertyPair.first == "Class" ||
- propertyPair.first == "Name")
- {
- continue;
+ controller["Direction"] = *classPtr;
}
- // zones
- if (intfPair.first == pidZoneConfigurationIface)
+ // pid and fans are off the same configuration
+ else if (intfPair.first == pidConfigurationIface)
{
- const double* ptr =
- std::get_if<double>(&propertyPair.second);
- if (ptr == nullptr)
+ if (classPtr == nullptr)
{
- BMCWEB_LOG_ERROR("Field Illegal {}",
- propertyPair.first);
+ BMCWEB_LOG_ERROR("Pid Class Field illegal");
messages::internalError(asyncResp->res);
return;
}
- (*config)[propertyPair.first] = *ptr;
+ bool isFan = *classPtr == "fan";
+ nlohmann::json& element =
+ isFan ? fans[name] : pids[name];
+ config = &element;
+ if (isFan)
+ {
+ url.set_fragment(
+ ("/Oem/OpenBmc/Fan/FanControllers"_json_pointer /
+ name)
+ .to_string());
+ element["@odata.id"] = std::move(url);
+ element["@odata.type"] =
+ "#OpenBMCManager.v1_0_0.Manager.FanController";
+ }
+ else
+ {
+ url.set_fragment(
+ ("/Oem/OpenBmc/Fan/PidControllers"_json_pointer /
+ name)
+ .to_string());
+ element["@odata.id"] = std::move(url);
+ element["@odata.type"] =
+ "#OpenBMCManager.v1_0_0.Manager.PidController";
+ }
}
+ else
+ {
+ BMCWEB_LOG_ERROR("Unexpected configuration");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ // used for making maps out of 2 vectors
+ const std::vector<double>* keys = nullptr;
+ const std::vector<double>* values = nullptr;
- if (intfPair.first == stepwiseConfigurationIface)
+ for (const auto& propertyPair : intfPair.second)
{
- if (propertyPair.first == "Reading" ||
- propertyPair.first == "Output")
+ if (propertyPair.first == "Type" ||
+ propertyPair.first == "Class" ||
+ propertyPair.first == "Name")
{
- const std::vector<double>* ptr =
- std::get_if<std::vector<double>>(
- &propertyPair.second);
+ continue;
+ }
+ // zones
+ if (intfPair.first == pidZoneConfigurationIface)
+ {
+ const double* ptr =
+ std::get_if<double>(&propertyPair.second);
if (ptr == nullptr)
{
BMCWEB_LOG_ERROR("Field Illegal {}",
@@ -557,178 +556,202 @@ inline void
messages::internalError(asyncResp->res);
return;
}
+ (*config)[propertyPair.first] = *ptr;
+ }
- if (propertyPair.first == "Reading")
- {
- keys = ptr;
- }
- else
- {
- values = ptr;
- }
- if (keys != nullptr && values != nullptr)
+ if (intfPair.first == stepwiseConfigurationIface)
+ {
+ if (propertyPair.first == "Reading" ||
+ propertyPair.first == "Output")
{
- if (keys->size() != values->size())
+ const std::vector<double>* ptr =
+ std::get_if<std::vector<double>>(
+ &propertyPair.second);
+
+ if (ptr == nullptr)
{
- BMCWEB_LOG_ERROR(
- "Reading and Output size don't match ");
+ BMCWEB_LOG_ERROR("Field Illegal {}",
+ propertyPair.first);
messages::internalError(asyncResp->res);
return;
}
- nlohmann::json& steps = (*config)["Steps"];
- steps = nlohmann::json::array();
- for (size_t ii = 0; ii < keys->size(); ii++)
+
+ if (propertyPair.first == "Reading")
+ {
+ keys = ptr;
+ }
+ else
{
- nlohmann::json::object_t step;
- step["Target"] = (*keys)[ii];
- step["Output"] = (*values)[ii];
- steps.emplace_back(std::move(step));
+ values = ptr;
+ }
+ if (keys != nullptr && values != nullptr)
+ {
+ if (keys->size() != values->size())
+ {
+ BMCWEB_LOG_ERROR(
+ "Reading and Output size don't match ");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ nlohmann::json& steps = (*config)["Steps"];
+ steps = nlohmann::json::array();
+ for (size_t ii = 0; ii < keys->size(); ii++)
+ {
+ nlohmann::json::object_t step;
+ step["Target"] = (*keys)[ii];
+ step["Output"] = (*values)[ii];
+ steps.emplace_back(std::move(step));
+ }
}
}
- }
- if (propertyPair.first == "NegativeHysteresis" ||
- propertyPair.first == "PositiveHysteresis")
- {
- const double* ptr =
- std::get_if<double>(&propertyPair.second);
- if (ptr == nullptr)
+ if (propertyPair.first == "NegativeHysteresis" ||
+ propertyPair.first == "PositiveHysteresis")
{
- BMCWEB_LOG_ERROR("Field Illegal {}",
- propertyPair.first);
- messages::internalError(asyncResp->res);
- return;
+ const double* ptr =
+ std::get_if<double>(&propertyPair.second);
+ if (ptr == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Field Illegal {}",
+ propertyPair.first);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ (*config)[propertyPair.first] = *ptr;
}
- (*config)[propertyPair.first] = *ptr;
}
- }
-
- // pid and fans are off the same configuration
- if (intfPair.first == pidConfigurationIface ||
- intfPair.first == stepwiseConfigurationIface)
- {
- if (propertyPair.first == "Zones")
- {
- const std::vector<std::string>* inputs =
- std::get_if<std::vector<std::string>>(
- &propertyPair.second);
- if (inputs == nullptr)
- {
- BMCWEB_LOG_ERROR("Zones Pid Field Illegal");
- messages::internalError(asyncResp->res);
- return;
- }
- auto& data = (*config)[propertyPair.first];
- data = nlohmann::json::array();
- for (std::string itemCopy : *inputs)
- {
- dbus::utility::escapePathForDbus(itemCopy);
- nlohmann::json::object_t input;
- boost::urls::url managerUrl = boost::urls::format(
- "/redfish/v1/Managers/{}#{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME,
- ("/Oem/OpenBmc/Fan/FanZones"_json_pointer /
- itemCopy)
- .to_string());
- input["@odata.id"] = std::move(managerUrl);
- data.emplace_back(std::move(input));
- }
- }
- // todo(james): may never happen, but this
- // assumes configuration data referenced in the
- // PID config is provided by the same daemon, we
- // could add another loop to cover all cases,
- // but I'm okay kicking this can down the road a
- // bit
-
- else if (propertyPair.first == "Inputs" ||
- propertyPair.first == "Outputs")
+ // pid and fans are off the same configuration
+ if (intfPair.first == pidConfigurationIface ||
+ intfPair.first == stepwiseConfigurationIface)
{
- auto& data = (*config)[propertyPair.first];
- const std::vector<std::string>* inputs =
- std::get_if<std::vector<std::string>>(
- &propertyPair.second);
-
- if (inputs == nullptr)
+ if (propertyPair.first == "Zones")
{
- BMCWEB_LOG_ERROR("Field Illegal {}",
- propertyPair.first);
- messages::internalError(asyncResp->res);
- return;
- }
- data = *inputs;
- }
- else if (propertyPair.first == "SetPointOffset")
- {
- const std::string* ptr =
- std::get_if<std::string>(&propertyPair.second);
+ const std::vector<std::string>* inputs =
+ std::get_if<std::vector<std::string>>(
+ &propertyPair.second);
- if (ptr == nullptr)
- {
- BMCWEB_LOG_ERROR("Field Illegal {}",
- propertyPair.first);
- messages::internalError(asyncResp->res);
- return;
- }
- // translate from dbus to redfish
- if (*ptr == "WarningHigh")
- {
- (*config)["SetPointOffset"] =
- "UpperThresholdNonCritical";
- }
- else if (*ptr == "WarningLow")
- {
- (*config)["SetPointOffset"] =
- "LowerThresholdNonCritical";
- }
- else if (*ptr == "CriticalHigh")
- {
- (*config)["SetPointOffset"] =
- "UpperThresholdCritical";
+ if (inputs == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Zones Pid Field Illegal");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ auto& data = (*config)[propertyPair.first];
+ data = nlohmann::json::array();
+ for (std::string itemCopy : *inputs)
+ {
+ dbus::utility::escapePathForDbus(itemCopy);
+ nlohmann::json::object_t input;
+ boost::urls::url managerUrl =
+ boost::urls::format(
+ "/redfish/v1/Managers/{}#{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME,
+ ("/Oem/OpenBmc/Fan/FanZones"_json_pointer /
+ itemCopy)
+ .to_string());
+ input["@odata.id"] = std::move(managerUrl);
+ data.emplace_back(std::move(input));
+ }
}
- else if (*ptr == "CriticalLow")
+ // todo(james): may never happen, but this
+ // assumes configuration data referenced in the
+ // PID config is provided by the same daemon, we
+ // could add another loop to cover all cases,
+ // but I'm okay kicking this can down the road a
+ // bit
+
+ else if (propertyPair.first == "Inputs" ||
+ propertyPair.first == "Outputs")
{
- (*config)["SetPointOffset"] =
- "LowerThresholdCritical";
+ auto& data = (*config)[propertyPair.first];
+ const std::vector<std::string>* inputs =
+ std::get_if<std::vector<std::string>>(
+ &propertyPair.second);
+
+ if (inputs == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Field Illegal {}",
+ propertyPair.first);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ data = *inputs;
}
- else
+ else if (propertyPair.first == "SetPointOffset")
{
- BMCWEB_LOG_ERROR("Value Illegal {}", *ptr);
- messages::internalError(asyncResp->res);
- return;
+ const std::string* ptr =
+ std::get_if<std::string>(
+ &propertyPair.second);
+
+ if (ptr == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Field Illegal {}",
+ propertyPair.first);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // translate from dbus to redfish
+ if (*ptr == "WarningHigh")
+ {
+ (*config)["SetPointOffset"] =
+ "UpperThresholdNonCritical";
+ }
+ else if (*ptr == "WarningLow")
+ {
+ (*config)["SetPointOffset"] =
+ "LowerThresholdNonCritical";
+ }
+ else if (*ptr == "CriticalHigh")
+ {
+ (*config)["SetPointOffset"] =
+ "UpperThresholdCritical";
+ }
+ else if (*ptr == "CriticalLow")
+ {
+ (*config)["SetPointOffset"] =
+ "LowerThresholdCritical";
+ }
+ else
+ {
+ BMCWEB_LOG_ERROR("Value Illegal {}", *ptr);
+ messages::internalError(asyncResp->res);
+ return;
+ }
}
- }
- // doubles
- else if (propertyPair.first == "FFGainCoefficient" ||
- propertyPair.first == "FFOffCoefficient" ||
- propertyPair.first == "ICoefficient" ||
- propertyPair.first == "ILimitMax" ||
- propertyPair.first == "ILimitMin" ||
- propertyPair.first == "PositiveHysteresis" ||
- propertyPair.first == "NegativeHysteresis" ||
- propertyPair.first == "OutLimitMax" ||
- propertyPair.first == "OutLimitMin" ||
- propertyPair.first == "PCoefficient" ||
- propertyPair.first == "SetPoint" ||
- propertyPair.first == "SlewNeg" ||
- propertyPair.first == "SlewPos")
- {
- const double* ptr =
- std::get_if<double>(&propertyPair.second);
- if (ptr == nullptr)
+ // doubles
+ else if (propertyPair.first ==
+ "FFGainCoefficient" ||
+ propertyPair.first == "FFOffCoefficient" ||
+ propertyPair.first == "ICoefficient" ||
+ propertyPair.first == "ILimitMax" ||
+ propertyPair.first == "ILimitMin" ||
+ propertyPair.first ==
+ "PositiveHysteresis" ||
+ propertyPair.first ==
+ "NegativeHysteresis" ||
+ propertyPair.first == "OutLimitMax" ||
+ propertyPair.first == "OutLimitMin" ||
+ propertyPair.first == "PCoefficient" ||
+ propertyPair.first == "SetPoint" ||
+ propertyPair.first == "SlewNeg" ||
+ propertyPair.first == "SlewPos")
{
- BMCWEB_LOG_ERROR("Field Illegal {}",
- propertyPair.first);
- messages::internalError(asyncResp->res);
- return;
+ const double* ptr =
+ std::get_if<double>(&propertyPair.second);
+ if (ptr == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Field Illegal {}",
+ propertyPair.first);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ (*config)[propertyPair.first] = *ptr;
}
- (*config)[propertyPair.first] = *ptr;
}
}
}
}
- }
- });
+ });
}
enum class CreatePIDRet
@@ -841,14 +864,14 @@ inline CreatePIDRet createPidInterface(
// delete interface
crow::connections::systemBus->async_method_call(
[response, path](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Error patching {}: {}", path, ec);
- messages::internalError(response->res);
- return;
- }
- messages::success(response->res);
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Error patching {}: {}", path, ec);
+ messages::internalError(response->res);
+ return;
+ }
+ messages::success(response->res);
+ },
"xyz.openbmc_project.EntityManager", path, iface, "Delete");
return CreatePIDRet::del;
}
@@ -909,8 +932,8 @@ inline CreatePIDRet createPidInterface(
return CreatePIDRet::fail;
}
if (std::find(curProfiles->begin(),
- curProfiles->end(),
- profile) == curProfiles->end())
+ curProfiles->end(), profile) ==
+ curProfiles->end())
{
std::vector<std::string> newProfiles =
*curProfiles;
@@ -1046,10 +1069,10 @@ inline CreatePIDRet createPidInterface(
std::optional<std::string> chassisId;
std::optional<double> failSafePercent;
std::optional<double> minThermalOutput;
- if (!redfish::json_util::readJson(jsonValue, response->res,
- "Chassis/@odata.id", chassisId,
- "FailSafePercent", failSafePercent,
- "MinThermalOutput", minThermalOutput))
+ if (!redfish::json_util::readJson(
+ jsonValue, response->res, "Chassis/@odata.id", chassisId,
+ "FailSafePercent", failSafePercent, "MinThermalOutput",
+ minThermalOutput))
{
return CreatePIDRet::fail;
}
@@ -1199,14 +1222,14 @@ struct GetPIDValues : std::enable_shared_from_this<GetPIDValues>
[self](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtreeLocal) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("{}", ec);
- messages::internalError(self->asyncResp->res);
- return;
- }
- self->complete.subtree = subtreeLocal;
- });
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("{}", ec);
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+ self->complete.subtree = subtreeLocal;
+ });
// at the same time get the selected profile
constexpr std::array<std::string_view, 1> thermalModeIfaces = {
@@ -1216,58 +1239,61 @@ struct GetPIDValues : std::enable_shared_from_this<GetPIDValues>
[self](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtreeLocal) {
- if (ec || subtreeLocal.empty())
- {
- return;
- }
- if (subtreeLocal[0].second.size() != 1)
- {
- // invalid mapper response, should never happen
- BMCWEB_LOG_ERROR("GetPIDValues: Mapper Error");
- messages::internalError(self->asyncResp->res);
- return;
- }
-
- const std::string& path = subtreeLocal[0].first;
- const std::string& owner = subtreeLocal[0].second[0].first;
-
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, owner, path, thermalModeIface,
- [path, owner,
- self](const boost::system::error_code& ec2,
- const dbus::utility::DBusPropertiesMap& resp) {
- if (ec2)
+ if (ec || subtreeLocal.empty())
{
- BMCWEB_LOG_ERROR(
- "GetPIDValues: Can't get thermalModeIface {}", path);
- messages::internalError(self->asyncResp->res);
return;
}
-
- const std::string* current = nullptr;
- const std::vector<std::string>* supported = nullptr;
-
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), resp, "Current", current,
- "Supported", supported);
-
- if (!success)
+ if (subtreeLocal[0].second.size() != 1)
{
+ // invalid mapper response, should never happen
+ BMCWEB_LOG_ERROR("GetPIDValues: Mapper Error");
messages::internalError(self->asyncResp->res);
return;
}
- if (current == nullptr || supported == nullptr)
- {
- BMCWEB_LOG_ERROR(
- "GetPIDValues: thermal mode iface invalid {}", path);
- messages::internalError(self->asyncResp->res);
- return;
- }
- self->complete.currentProfile = *current;
- self->complete.supportedProfiles = *supported;
+ const std::string& path = subtreeLocal[0].first;
+ const std::string& owner = subtreeLocal[0].second[0].first;
+
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, owner, path,
+ thermalModeIface,
+ [path, owner,
+ self](const boost::system::error_code& ec2,
+ const dbus::utility::DBusPropertiesMap& resp) {
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "GetPIDValues: Can't get thermalModeIface {}",
+ path);
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+
+ const std::string* current = nullptr;
+ const std::vector<std::string>* supported = nullptr;
+
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), resp, "Current",
+ current, "Supported", supported);
+
+ if (!success)
+ {
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+
+ if (current == nullptr || supported == nullptr)
+ {
+ BMCWEB_LOG_ERROR(
+ "GetPIDValues: thermal mode iface invalid {}",
+ path);
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+ self->complete.currentProfile = *current;
+ self->complete.supportedProfiles = *supported;
+ });
});
- });
}
static void
@@ -1354,8 +1380,7 @@ struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
std::pair<std::string, std::optional<nlohmann::json::object_t>>>&&
configurationsIn,
std::optional<std::string>& profileIn) :
- asyncResp(asyncRespIn),
- configuration(std::move(configurationsIn)),
+ asyncResp(asyncRespIn), configuration(std::move(configurationsIn)),
profile(std::move(profileIn))
{}
@@ -1381,30 +1406,30 @@ struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
"xyz.openbmc_project.EntityManager", objPath,
[self](const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& mObj) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Error communicating to Entity Manager");
- messages::internalError(self->asyncResp->res);
- return;
- }
- const std::array<const char*, 3> configurations = {
- pidConfigurationIface, pidZoneConfigurationIface,
- stepwiseConfigurationIface};
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Error communicating to Entity Manager");
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+ const std::array<const char*, 3> configurations = {
+ pidConfigurationIface, pidZoneConfigurationIface,
+ stepwiseConfigurationIface};
- for (const auto& [path, object] : mObj)
- {
- for (const auto& [interface, _] : object)
+ for (const auto& [path, object] : mObj)
{
- if (std::ranges::find(configurations, interface) !=
- configurations.end())
+ for (const auto& [interface, _] : object)
{
- self->objectCount++;
- break;
+ if (std::ranges::find(configurations, interface) !=
+ configurations.end())
+ {
+ self->objectCount++;
+ break;
+ }
}
}
- }
- self->managedObj = mObj;
- });
+ self->managedObj = mObj;
+ });
// at the same time get the profile information
constexpr std::array<std::string_view, 1> thermalModeIfaces = {
@@ -1413,57 +1438,61 @@ struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
"/", 0, thermalModeIfaces,
[self](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec || subtree.empty())
- {
- return;
- }
- if (subtree[0].second.empty())
- {
- // invalid mapper response, should never happen
- BMCWEB_LOG_ERROR("SetPIDValues: Mapper Error");
- messages::internalError(self->asyncResp->res);
- return;
- }
-
- const std::string& path = subtree[0].first;
- const std::string& owner = subtree[0].second[0].first;
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, owner, path, thermalModeIface,
- [self, path, owner](const boost::system::error_code& ec2,
- const dbus::utility::DBusPropertiesMap& r) {
- if (ec2)
+ if (ec || subtree.empty())
{
- BMCWEB_LOG_ERROR(
- "SetPIDValues: Can't get thermalModeIface {}", path);
- messages::internalError(self->asyncResp->res);
return;
}
- const std::string* current = nullptr;
- const std::vector<std::string>* supported = nullptr;
-
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), r, "Current", current,
- "Supported", supported);
-
- if (!success)
+ if (subtree[0].second.empty())
{
+ // invalid mapper response, should never happen
+ BMCWEB_LOG_ERROR("SetPIDValues: Mapper Error");
messages::internalError(self->asyncResp->res);
return;
}
- if (current == nullptr || supported == nullptr)
- {
- BMCWEB_LOG_ERROR(
- "SetPIDValues: thermal mode iface invalid {}", path);
- messages::internalError(self->asyncResp->res);
- return;
- }
- self->currentProfile = *current;
- self->supportedProfiles = *supported;
- self->profileConnection = owner;
- self->profilePath = path;
+ const std::string& path = subtree[0].first;
+ const std::string& owner = subtree[0].second[0].first;
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, owner, path,
+ thermalModeIface,
+ [self, path,
+ owner](const boost::system::error_code& ec2,
+ const dbus::utility::DBusPropertiesMap& r) {
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "SetPIDValues: Can't get thermalModeIface {}",
+ path);
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+ const std::string* current = nullptr;
+ const std::vector<std::string>* supported = nullptr;
+
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), r, "Current",
+ current, "Supported", supported);
+
+ if (!success)
+ {
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+
+ if (current == nullptr || supported == nullptr)
+ {
+ BMCWEB_LOG_ERROR(
+ "SetPIDValues: thermal mode iface invalid {}",
+ path);
+ messages::internalError(self->asyncResp->res);
+ return;
+ }
+ self->currentProfile = *current;
+ self->supportedProfiles = *supported;
+ self->profileConnection = owner;
+ self->profilePath = path;
+ });
});
- });
}
void pidSetDone()
{
@@ -1486,12 +1515,12 @@ struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
*crow::connections::systemBus, profileConnection, profilePath,
thermalModeIface, "Current", *profile,
[response](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Error patching profile{}", ec);
- messages::internalError(response->res);
- }
- });
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Error patching profile{}", ec);
+ messages::internalError(response->res);
+ }
+ });
}
for (auto& containerPair : configuration)
@@ -1512,8 +1541,8 @@ struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
auto pathItr = std::ranges::find_if(
managedObj, [&dbusObjName](const auto& obj) {
- return obj.first.filename() == dbusObjName;
- });
+ return obj.first.filename() == dbusObjName;
+ });
dbus::utility::DBusPropertiesMap output;
output.reserve(16); // The pid interface length
@@ -1614,15 +1643,15 @@ struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
[response,
propertyName{std::string(property.first)}](
const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Error patching {}: {}",
- propertyName, ec);
- messages::internalError(response->res);
- return;
- }
- messages::success(response->res);
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Error patching {}: {}",
+ propertyName, ec);
+ messages::internalError(response->res);
+ return;
+ }
+ messages::success(response->res);
+ },
"xyz.openbmc_project.EntityManager", path,
"org.freedesktop.DBus.Properties", "Set", iface,
property.first, property.second);
@@ -1659,14 +1688,15 @@ struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
crow::connections::systemBus->async_method_call(
[response](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Error Adding Pid Object {}", ec);
- messages::internalError(response->res);
- return;
- }
- messages::success(response->res);
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Error Adding Pid Object {}",
+ ec);
+ messages::internalError(response->res);
+ return;
+ }
+ messages::success(response->res);
+ },
"xyz.openbmc_project.EntityManager", chassis,
"xyz.openbmc_project.AddObject", "AddObject", output);
}
@@ -1717,17 +1747,18 @@ inline void getLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
"xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
[asyncResp](const boost::system::error_code& ec,
const std::string& property) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error for "
- "Location");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error for "
+ "Location");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
- property;
- });
+ asyncResp->res
+ .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+ property;
+ });
}
// avoid name collision systems.hpp
inline void
@@ -1741,20 +1772,20 @@ inline void
"LastRebootTime",
[asyncResp](const boost::system::error_code& ec,
const uint64_t lastResetTime) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
+ return;
+ }
- // LastRebootTime is epoch time, in milliseconds
- // https://github.com/openbmc/phosphor-dbus-interfaces/blob/7f9a128eb9296e926422ddc312c148b625890bb6/xyz/openbmc_project/State/BMC.interface.yaml#L19
- uint64_t lastResetTimeStamp = lastResetTime / 1000;
+ // LastRebootTime is epoch time, in milliseconds
+ // https://github.com/openbmc/phosphor-dbus-interfaces/blob/7f9a128eb9296e926422ddc312c148b625890bb6/xyz/openbmc_project/State/BMC.interface.yaml#L19
+ uint64_t lastResetTimeStamp = lastResetTime / 1000;
- // Convert to ISO 8601 standard
- asyncResp->res.jsonValue["LastResetTime"] =
- redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
- });
+ // Convert to ISO 8601 standard
+ asyncResp->res.jsonValue["LastResetTime"] =
+ redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
+ });
}
/**
@@ -1795,81 +1826,80 @@ inline void
[asyncResp, firmwareId, runningFirmwareTarget](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("D-Bus response error getting objects.");
- messages::internalError(asyncResp->res);
- return;
- }
-
- if (subtree.empty())
- {
- BMCWEB_LOG_DEBUG("Can't find image!");
- messages::internalError(asyncResp->res);
- return;
- }
-
- bool foundImage = false;
- for (const auto& object : subtree)
- {
- const std::string& path =
- static_cast<const std::string&>(object.first);
- std::size_t idPos2 = path.rfind('/');
-
- if (idPos2 == std::string::npos)
+ if (ec)
{
- continue;
+ BMCWEB_LOG_DEBUG("D-Bus response error getting objects.");
+ messages::internalError(asyncResp->res);
+ return;
}
- idPos2++;
- if (idPos2 >= path.size())
+ if (subtree.empty())
{
- continue;
+ BMCWEB_LOG_DEBUG("Can't find image!");
+ messages::internalError(asyncResp->res);
+ return;
}
- if (path.substr(idPos2) == firmwareId)
+ bool foundImage = false;
+ for (const auto& object : subtree)
{
- foundImage = true;
- break;
- }
- }
+ const std::string& path =
+ static_cast<const std::string&>(object.first);
+ std::size_t idPos2 = path.rfind('/');
- if (!foundImage)
- {
- messages::propertyValueNotInList(
- asyncResp->res, runningFirmwareTarget, "@odata.id");
- BMCWEB_LOG_DEBUG("Invalid firmware ID.");
- return;
- }
+ if (idPos2 == std::string::npos)
+ {
+ continue;
+ }
+
+ idPos2++;
+ if (idPos2 >= path.size())
+ {
+ continue;
+ }
+
+ if (path.substr(idPos2) == firmwareId)
+ {
+ foundImage = true;
+ break;
+ }
+ }
- BMCWEB_LOG_DEBUG("Setting firmware version {} to priority 0.",
- firmwareId);
-
- // Only support Immediate
- // An addition could be a Redfish Setting like
- // ActiveSoftwareImageApplyTime and support OnReset
- sdbusplus::asio::setProperty(
- *crow::connections::systemBus,
- "xyz.openbmc_project.Software.BMC.Updater",
- "/xyz/openbmc_project/software/" + firmwareId,
- "xyz.openbmc_project.Software.RedundancyPriority", "Priority",
- static_cast<uint8_t>(0),
- [asyncResp](const boost::system::error_code& ec2) {
- if (ec2)
+ if (!foundImage)
{
- BMCWEB_LOG_DEBUG("D-Bus response error setting.");
- messages::internalError(asyncResp->res);
+ messages::propertyValueNotInList(
+ asyncResp->res, runningFirmwareTarget, "@odata.id");
+ BMCWEB_LOG_DEBUG("Invalid firmware ID.");
return;
}
- doBMCGracefulRestart(asyncResp);
+
+ BMCWEB_LOG_DEBUG("Setting firmware version {} to priority 0.",
+ firmwareId);
+
+ // Only support Immediate
+ // An addition could be a Redfish Setting like
+ // ActiveSoftwareImageApplyTime and support OnReset
+ sdbusplus::asio::setProperty(
+ *crow::connections::systemBus,
+ "xyz.openbmc_project.Software.BMC.Updater",
+ "/xyz/openbmc_project/software/" + firmwareId,
+ "xyz.openbmc_project.Software.RedundancyPriority", "Priority",
+ static_cast<uint8_t>(0),
+ [asyncResp](const boost::system::error_code& ec2) {
+ if (ec2)
+ {
+ BMCWEB_LOG_DEBUG("D-Bus response error setting.");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ doBMCGracefulRestart(asyncResp);
+ });
});
- });
}
-inline void
- afterSetDateTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const boost::system::error_code& ec,
- const sdbusplus::message_t& msg)
+inline void afterSetDateTime(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::system::error_code& ec, const sdbusplus::message_t& msg)
{
if (ec)
{
@@ -1914,8 +1944,8 @@ inline void setDateTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec,
const sdbusplus::message_t& msg) {
- afterSetDateTime(asyncResp, ec, msg);
- },
+ afterSetDateTime(asyncResp, ec, msg);
+ },
"org.freedesktop.timedate1", "/org/freedesktop/timedate1",
"org.freedesktop.timedate1", "SetTime", us->count(), relative,
interactive);
@@ -1930,18 +1960,21 @@ inline void
"org.freedesktop.systemd1.Unit", "ActiveState",
[asyncResp](const boost::system::error_code& ec,
const std::string& val) {
- if (!ec)
- {
- if (val == "active")
+ if (!ec)
{
- asyncResp->res.jsonValue["Status"]["Health"] = "Critical";
- asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
- return;
+ if (val == "active")
+ {
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ resource::Health::Critical;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Quiesced;
+ return;
+ }
}
- }
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- });
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+ });
}
inline void requestRoutesManager(App& app)
@@ -1950,295 +1983,321 @@ inline void requestRoutesManager(App& app)
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/")
.privileges(redfish::privileges::getManager)
- .methods(boost::beast::http::verb::get)(
- [&app, uuid](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
-
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}", BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] = "#Manager.v1_14_0.Manager";
- asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_MANAGER_URI_NAME;
- asyncResp->res.jsonValue["Name"] = "OpenBmc Manager";
- asyncResp->res.jsonValue["Description"] =
- "Baseboard Management Controller";
- asyncResp->res.jsonValue["PowerState"] = "On";
-
- asyncResp->res.jsonValue["ManagerType"] = "BMC";
- asyncResp->res.jsonValue["UUID"] = systemd_utils::getUuid();
- asyncResp->res.jsonValue["ServiceEntryPointUUID"] = uuid;
- asyncResp->res.jsonValue["Model"] = "OpenBmc"; // TODO(ed), get model
-
- asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/LogServices",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["NetworkProtocol"]["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/NetworkProtocol",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
-
- if constexpr (BMCWEB_VM_NBDPROXY)
- {
- asyncResp->res.jsonValue["VirtualMedia"]["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- }
-
- // default oem data
- nlohmann::json& oem = asyncResp->res.jsonValue["Oem"];
- nlohmann::json& oemOpenbmc = oem["OpenBmc"];
- oem["@odata.type"] = "#OemManager.Oem";
- oem["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}#/Oem",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- oemOpenbmc["@odata.type"] = "#OemManager.OpenBmc";
- oemOpenbmc["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}#/Oem/OpenBmc",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
-
- nlohmann::json::object_t certificates;
- certificates["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/Truststore/Certificates",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- oemOpenbmc["Certificates"] = std::move(certificates);
-
- // Manager.Reset (an action) can be many values, OpenBMC only
- // supports BMC reboot.
- nlohmann::json& managerReset =
- asyncResp->res.jsonValue["Actions"]["#Manager.Reset"];
- managerReset["target"] =
- boost::urls::format("/redfish/v1/Managers/{}/Actions/Manager.Reset",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- managerReset["@Redfish.ActionInfo"] =
- boost::urls::format("/redfish/v1/Managers/{}/ResetActionInfo",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
-
- // ResetToDefaults (Factory Reset) has values like
- // PreserveNetworkAndUsers and PreserveNetwork that aren't supported
- // on OpenBMC
- nlohmann::json& resetToDefaults =
- asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
- resetToDefaults["target"] = boost::urls::format(
- "/redfish/v1/Managers/{}/Actions/Manager.ResetToDefaults",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- resetToDefaults["ResetType@Redfish.AllowableValues"] =
- nlohmann::json::array_t({"ResetAll"});
-
- std::pair<std::string, std::string> redfishDateTimeOffset =
- redfish::time_utils::getDateTimeOffsetNow();
-
- asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
- asyncResp->res.jsonValue["DateTimeLocalOffset"] =
- redfishDateTimeOffset.second;
-
- // TODO (Gunnar): Remove these one day since moved to ComputerSystem
- // Still used by OCP profiles
- // https://github.com/opencomputeproject/OCP-Profiles/issues/23
- // Fill in SerialConsole info
- asyncResp->res.jsonValue["SerialConsole"]["ServiceEnabled"] = true;
- asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
- asyncResp->res.jsonValue["SerialConsole"]["ConnectTypesSupported"] =
- nlohmann::json::array_t({"IPMI", "SSH"});
- if constexpr (BMCWEB_KVM)
- {
- // Fill in GraphicalConsole info
- asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] =
- true;
- asyncResp->res
- .jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
- asyncResp->res
- .jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
- nlohmann::json::array_t({"KVMIP"});
- }
- if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- asyncResp->res.jsonValue["Links"]["ManagerForServers@odata.count"] =
- 1;
-
- nlohmann::json::array_t managerForServers;
- nlohmann::json::object_t manager;
- manager["@odata.id"] = std::format("/redfish/v1/Systems/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- managerForServers.emplace_back(std::move(manager));
-
- asyncResp->res.jsonValue["Links"]["ManagerForServers"] =
- std::move(managerForServers);
- }
-
- sw_util::populateSoftwareInformation(asyncResp, sw_util::bmcPurpose,
- "FirmwareVersion", true);
-
- managerGetLastResetTime(asyncResp);
-
- // ManagerDiagnosticData is added for all BMCs.
- nlohmann::json& managerDiagnosticData =
- asyncResp->res.jsonValue["ManagerDiagnosticData"];
- managerDiagnosticData["@odata.id"] =
- boost::urls::format("/redfish/v1/Managers/{}/ManagerDiagnosticData",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
-
- if constexpr (BMCWEB_REDFISH_OEM_MANAGER_FAN_DATA)
- {
- auto pids = std::make_shared<GetPIDValues>(asyncResp);
- pids->run();
- }
-
- getMainChassisId(asyncResp,
- [](const std::string& chassisId,
- const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
- aRsp->res.jsonValue["Links"]["ManagerForChassis@odata.count"] = 1;
- nlohmann::json::array_t managerForChassis;
- nlohmann::json::object_t managerObj;
- boost::urls::url chassiUrl =
- boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
- managerObj["@odata.id"] = chassiUrl;
- managerForChassis.emplace_back(std::move(managerObj));
- aRsp->res.jsonValue["Links"]["ManagerForChassis"] =
- std::move(managerForChassis);
- aRsp->res.jsonValue["Links"]["ManagerInChassis"]["@odata.id"] =
- chassiUrl;
- });
-
- sdbusplus::asio::getProperty<double>(
- *crow::connections::systemBus, "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager",
- "Progress",
- [asyncResp](const boost::system::error_code& ec, double val) {
- if (ec)
+ .methods(
+ boost::beast::http::verb::
+ get)([&app,
+ uuid](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& managerId) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- BMCWEB_LOG_ERROR("Error while getting progress");
- messages::internalError(asyncResp->res);
return;
}
- if (val < 1.0)
+
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
{
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
- asyncResp->res.jsonValue["Status"]["State"] = "Starting";
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
return;
}
- checkForQuiesced(asyncResp);
- });
- constexpr std::array<std::string_view, 1> interfaces = {
- "xyz.openbmc_project.Inventory.Item.Bmc"};
- dbus::utility::getSubTree(
- "/xyz/openbmc_project/inventory", 0, interfaces,
- [asyncResp](
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}", BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Manager.v1_14_0.Manager";
+ asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_MANAGER_URI_NAME;
+ asyncResp->res.jsonValue["Name"] = "OpenBmc Manager";
+ asyncResp->res.jsonValue["Description"] =
+ "Baseboard Management Controller";
+ asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On;
+
+ asyncResp->res.jsonValue["ManagerType"] = manager::ManagerType::BMC;
+ asyncResp->res.jsonValue["UUID"] = systemd_utils::getUuid();
+ asyncResp->res.jsonValue["ServiceEntryPointUUID"] = uuid;
+ asyncResp->res.jsonValue["Model"] =
+ "OpenBmc"; // TODO(ed), get model
+
+ asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
+ boost::urls::format("/redfish/v1/Managers/{}/LogServices",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["NetworkProtocol"]["@odata.id"] =
+ boost::urls::format("/redfish/v1/Managers/{}/NetworkProtocol",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
+ boost::urls::format(
+ "/redfish/v1/Managers/{}/EthernetInterfaces",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+
+ if constexpr (BMCWEB_VM_NBDPROXY)
{
- BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
- return;
+ asyncResp->res.jsonValue["VirtualMedia"]["@odata.id"] =
+ boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
}
- if (subtree.empty())
+
+ // default oem data
+ nlohmann::json& oem = asyncResp->res.jsonValue["Oem"];
+ nlohmann::json& oemOpenbmc = oem["OpenBmc"];
+ oem["@odata.id"] =
+ boost::urls::format("/redfish/v1/Managers/{}#/Oem",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ oemOpenbmc["@odata.type"] = "#OpenBMCManager.v1_0_0.Manager";
+ oemOpenbmc["@odata.id"] =
+ boost::urls::format("/redfish/v1/Managers/{}#/Oem/OpenBmc",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+
+ nlohmann::json::object_t certificates;
+ certificates["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/Truststore/Certificates",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ oemOpenbmc["Certificates"] = std::move(certificates);
+
+ // Manager.Reset (an action) can be many values, OpenBMC only
+ // supports BMC reboot.
+ nlohmann::json& managerReset =
+ asyncResp->res.jsonValue["Actions"]["#Manager.Reset"];
+ managerReset["target"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/Actions/Manager.Reset",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ managerReset["@Redfish.ActionInfo"] =
+ boost::urls::format("/redfish/v1/Managers/{}/ResetActionInfo",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+
+ // ResetToDefaults (Factory Reset) has values like
+ // PreserveNetworkAndUsers and PreserveNetwork that aren't supported
+ // on OpenBMC
+ nlohmann::json& resetToDefaults =
+ asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
+ resetToDefaults["target"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/Actions/Manager.ResetToDefaults",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
+ resetToDefaults["ResetType@Redfish.AllowableValues"] =
+ nlohmann::json::array_t({"ResetAll"});
+
+ std::pair<std::string, std::string> redfishDateTimeOffset =
+ redfish::time_utils::getDateTimeOffsetNow();
+
+ asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
+ asyncResp->res.jsonValue["DateTimeLocalOffset"] =
+ redfishDateTimeOffset.second;
+
+ // TODO (Gunnar): Remove these one day since moved to ComputerSystem
+ // Still used by OCP profiles
+ // https://github.com/opencomputeproject/OCP-Profiles/issues/23
+ // Fill in SerialConsole info
+ asyncResp->res.jsonValue["SerialConsole"]["ServiceEnabled"] = true;
+ asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
+ 15;
+ asyncResp->res.jsonValue["SerialConsole"]["ConnectTypesSupported"] =
+ nlohmann::json::array_t({"IPMI", "SSH"});
+ if constexpr (BMCWEB_KVM)
{
- BMCWEB_LOG_DEBUG("Can't find bmc D-Bus object!");
- return;
+ // Fill in GraphicalConsole info
+ asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] =
+ true;
+ asyncResp->res
+ .jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
+ asyncResp->res
+ .jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
+ nlohmann::json::array_t({"KVMIP"});
}
- // Assume only 1 bmc D-Bus object
- // Throw an error if there is more than 1
- if (subtree.size() > 1)
+ if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
- BMCWEB_LOG_DEBUG("Found more than 1 bmc D-Bus object!");
- messages::internalError(asyncResp->res);
- return;
- }
+ asyncResp->res
+ .jsonValue["Links"]["ManagerForServers@odata.count"] = 1;
- if (subtree[0].first.empty() || subtree[0].second.size() != 1)
- {
- BMCWEB_LOG_DEBUG("Error getting bmc D-Bus object!");
- messages::internalError(asyncResp->res);
- return;
+ nlohmann::json::array_t managerForServers;
+ nlohmann::json::object_t manager;
+ manager["@odata.id"] = std::format(
+ "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ managerForServers.emplace_back(std::move(manager));
+
+ asyncResp->res.jsonValue["Links"]["ManagerForServers"] =
+ std::move(managerForServers);
}
- const std::string& path = subtree[0].first;
- const std::string& connectionName = subtree[0].second[0].first;
+ sw_util::populateSoftwareInformation(asyncResp, sw_util::bmcPurpose,
+ "FirmwareVersion", true);
- for (const auto& interfaceName : subtree[0].second[0].second)
- {
- if (interfaceName ==
- "xyz.openbmc_project.Inventory.Decorator.Asset")
- {
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, connectionName, path,
- "xyz.openbmc_project.Inventory.Decorator.Asset",
- [asyncResp](const boost::system::error_code& ec2,
- const dbus::utility::DBusPropertiesMap&
- propertiesList) {
- if (ec2)
- {
- BMCWEB_LOG_DEBUG("Can't get bmc asset!");
- return;
- }
+ managerGetLastResetTime(asyncResp);
- const std::string* partNumber = nullptr;
- const std::string* serialNumber = nullptr;
- const std::string* manufacturer = nullptr;
- const std::string* model = nullptr;
- const std::string* sparePartNumber = nullptr;
+ // ManagerDiagnosticData is added for all BMCs.
+ nlohmann::json& managerDiagnosticData =
+ asyncResp->res.jsonValue["ManagerDiagnosticData"];
+ managerDiagnosticData["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/ManagerDiagnosticData",
+ BMCWEB_REDFISH_MANAGER_URI_NAME);
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList,
- "PartNumber", partNumber, "SerialNumber",
- serialNumber, "Manufacturer", manufacturer, "Model",
- model, "SparePartNumber", sparePartNumber);
+ if constexpr (BMCWEB_REDFISH_OEM_MANAGER_FAN_DATA)
+ {
+ auto pids = std::make_shared<GetPIDValues>(asyncResp);
+ pids->run();
+ }
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ getMainChassisId(asyncResp, [](const std::string& chassisId,
+ const std::shared_ptr<
+ bmcweb::AsyncResp>& aRsp) {
+ aRsp->res.jsonValue["Links"]["ManagerForChassis@odata.count"] =
+ 1;
+ nlohmann::json::array_t managerForChassis;
+ nlohmann::json::object_t managerObj;
+ boost::urls::url chassiUrl =
+ boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
+ managerObj["@odata.id"] = chassiUrl;
+ managerForChassis.emplace_back(std::move(managerObj));
+ aRsp->res.jsonValue["Links"]["ManagerForChassis"] =
+ std::move(managerForChassis);
+ aRsp->res.jsonValue["Links"]["ManagerInChassis"]["@odata.id"] =
+ chassiUrl;
+ });
- if (partNumber != nullptr)
- {
- asyncResp->res.jsonValue["PartNumber"] =
- *partNumber;
- }
+ sdbusplus::asio::getProperty<double>(
+ *crow::connections::systemBus, "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager",
+ "Progress",
+ [asyncResp](const boost::system::error_code& ec, double val) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Error while getting progress");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (val < 1.0)
+ {
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ resource::Health::OK;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Starting;
+ return;
+ }
+ checkForQuiesced(asyncResp);
+ });
- if (serialNumber != nullptr)
- {
- asyncResp->res.jsonValue["SerialNumber"] =
- *serialNumber;
- }
+ constexpr std::array<std::string_view, 1> interfaces = {
+ "xyz.openbmc_project.Inventory.Item.Bmc"};
+ dbus::utility::getSubTree(
+ "/xyz/openbmc_project/inventory", 0, interfaces,
+ [asyncResp](
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreeResponse& subtree) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG(
+ "D-Bus response error on GetSubTree {}", ec);
+ return;
+ }
+ if (subtree.empty())
+ {
+ BMCWEB_LOG_DEBUG("Can't find bmc D-Bus object!");
+ return;
+ }
+ // Assume only 1 bmc D-Bus object
+ // Throw an error if there is more than 1
+ if (subtree.size() > 1)
+ {
+ BMCWEB_LOG_DEBUG("Found more than 1 bmc D-Bus object!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (manufacturer != nullptr)
- {
- asyncResp->res.jsonValue["Manufacturer"] =
- *manufacturer;
- }
+ if (subtree[0].first.empty() ||
+ subtree[0].second.size() != 1)
+ {
+ BMCWEB_LOG_DEBUG("Error getting bmc D-Bus object!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ const std::string& path = subtree[0].first;
+ const std::string& connectionName =
+ subtree[0].second[0].first;
- if (model != nullptr)
+ for (const auto& interfaceName :
+ subtree[0].second[0].second)
+ {
+ if (interfaceName ==
+ "xyz.openbmc_project.Inventory.Decorator.Asset")
{
- asyncResp->res.jsonValue["Model"] = *model;
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, connectionName,
+ path,
+ "xyz.openbmc_project.Inventory.Decorator.Asset",
+ [asyncResp](
+ const boost::system::error_code& ec2,
+ const dbus::utility::DBusPropertiesMap&
+ propertiesList) {
+ if (ec2)
+ {
+ BMCWEB_LOG_DEBUG(
+ "Can't get bmc asset!");
+ return;
+ }
+
+ const std::string* partNumber = nullptr;
+ const std::string* serialNumber = nullptr;
+ const std::string* manufacturer = nullptr;
+ const std::string* model = nullptr;
+ const std::string* sparePartNumber =
+ nullptr;
+
+ const bool success =
+ sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(),
+ propertiesList, "PartNumber",
+ partNumber, "SerialNumber",
+ serialNumber, "Manufacturer",
+ manufacturer, "Model", model,
+ "SparePartNumber", sparePartNumber);
+
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (partNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["PartNumber"] =
+ *partNumber;
+ }
+
+ if (serialNumber != nullptr)
+ {
+ asyncResp->res
+ .jsonValue["SerialNumber"] =
+ *serialNumber;
+ }
+
+ if (manufacturer != nullptr)
+ {
+ asyncResp->res
+ .jsonValue["Manufacturer"] =
+ *manufacturer;
+ }
+
+ if (model != nullptr)
+ {
+ asyncResp->res.jsonValue["Model"] =
+ *model;
+ }
+
+ if (sparePartNumber != nullptr)
+ {
+ asyncResp->res
+ .jsonValue["SparePartNumber"] =
+ *sparePartNumber;
+ }
+ });
}
-
- if (sparePartNumber != nullptr)
+ else if (
+ interfaceName ==
+ "xyz.openbmc_project.Inventory.Decorator.LocationCode")
{
- asyncResp->res.jsonValue["SparePartNumber"] =
- *sparePartNumber;
+ getLocation(asyncResp, connectionName, path);
}
- });
- }
- else if (interfaceName ==
- "xyz.openbmc_project.Inventory.Decorator.LocationCode")
- {
- getLocation(asyncResp, connectionName, path);
- }
- }
+ }
+ });
});
- });
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/")
.privileges(redfish::privileges::patchManager)
@@ -2246,26 +2305,27 @@ inline void requestRoutesManager(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "Manager", managerId);
- return;
- }
+ if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "Manager",
+ managerId);
+ return;
+ }
- std::optional<std::string> activeSoftwareImageOdataId;
- std::optional<std::string> datetime;
- std::optional<nlohmann::json::object_t> pidControllers;
- std::optional<nlohmann::json::object_t> fanControllers;
- std::optional<nlohmann::json::object_t> fanZones;
- std::optional<nlohmann::json::object_t> stepwiseControllers;
- std::optional<std::string> profile;
+ std::optional<std::string> activeSoftwareImageOdataId;
+ std::optional<std::string> datetime;
+ std::optional<nlohmann::json::object_t> pidControllers;
+ std::optional<nlohmann::json::object_t> fanControllers;
+ std::optional<nlohmann::json::object_t> fanZones;
+ std::optional<nlohmann::json::object_t> stepwiseControllers;
+ std::optional<std::string> profile;
- // clang-format off
+ // clang-format off
if (!json_util::readJsonPatch(req, asyncResp->res,
"DateTime", datetime,
"Links/ActiveSoftwareImage/@odata.id", activeSoftwareImageOdataId,
@@ -2278,56 +2338,60 @@ inline void requestRoutesManager(App& app)
{
return;
}
- // clang-format on
+ // clang-format on
- if (pidControllers || fanControllers || fanZones ||
- stepwiseControllers || profile)
- {
- if constexpr (BMCWEB_REDFISH_OEM_MANAGER_FAN_DATA)
- {
- std::vector<std::pair<std::string,
- std::optional<nlohmann::json::object_t>>>
- configuration;
- if (pidControllers)
+ if (pidControllers || fanControllers || fanZones ||
+ stepwiseControllers || profile)
{
- configuration.emplace_back("PidControllers",
- std::move(pidControllers));
- }
- if (fanControllers)
- {
- configuration.emplace_back("FanControllers",
- std::move(fanControllers));
+ if constexpr (BMCWEB_REDFISH_OEM_MANAGER_FAN_DATA)
+ {
+ std::vector<
+ std::pair<std::string,
+ std::optional<nlohmann::json::object_t>>>
+ configuration;
+ if (pidControllers)
+ {
+ configuration.emplace_back(
+ "PidControllers", std::move(pidControllers));
+ }
+ if (fanControllers)
+ {
+ configuration.emplace_back(
+ "FanControllers", std::move(fanControllers));
+ }
+ if (fanZones)
+ {
+ configuration.emplace_back("FanZones",
+ std::move(fanZones));
+ }
+ if (stepwiseControllers)
+ {
+ configuration.emplace_back(
+ "StepwiseControllers",
+ std::move(stepwiseControllers));
+ }
+ auto pid = std::make_shared<SetPIDValues>(
+ asyncResp, std::move(configuration), profile);
+ pid->run();
+ }
+ else
+ {
+ messages::propertyUnknown(asyncResp->res, "Oem");
+ return;
+ }
}
- if (fanZones)
+
+ if (activeSoftwareImageOdataId)
{
- configuration.emplace_back("FanZones", std::move(fanZones));
+ setActiveFirmwareImage(asyncResp,
+ *activeSoftwareImageOdataId);
}
- if (stepwiseControllers)
+
+ if (datetime)
{
- configuration.emplace_back("StepwiseControllers",
- std::move(stepwiseControllers));
+ setDateTime(asyncResp, *datetime);
}
- auto pid = std::make_shared<SetPIDValues>(
- asyncResp, std::move(configuration), profile);
- pid->run();
- }
- else
- {
- messages::propertyUnknown(asyncResp->res, "Oem");
- return;
- }
- }
-
- if (activeSoftwareImageOdataId)
- {
- setActiveFirmwareImage(asyncResp, *activeSoftwareImageOdataId);
- }
-
- if (datetime)
- {
- setDateTime(asyncResp, *datetime);
- }
- });
+ });
}
inline void requestRoutesManagerCollection(App& app)
@@ -2337,22 +2401,22 @@ inline void requestRoutesManagerCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- // Collections don't include the static data added by SubRoute
- // because it has a duplicate entry for members
- asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
- asyncResp->res.jsonValue["@odata.type"] =
- "#ManagerCollection.ManagerCollection";
- asyncResp->res.jsonValue["Name"] = "Manager Collection";
- asyncResp->res.jsonValue["Members@odata.count"] = 1;
- nlohmann::json::array_t members;
- nlohmann::json& bmc = members.emplace_back();
- bmc["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME);
- asyncResp->res.jsonValue["Members"] = std::move(members);
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ // Collections don't include the static data added by SubRoute
+ // because it has a duplicate entry for members
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ManagerCollection.ManagerCollection";
+ asyncResp->res.jsonValue["Name"] = "Manager Collection";
+ asyncResp->res.jsonValue["Members@odata.count"] = 1;
+ nlohmann::json::array_t members;
+ nlohmann::json& bmc = members.emplace_back();
+ bmc["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}", BMCWEB_REDFISH_MANAGER_URI_NAME);
+ asyncResp->res.jsonValue["Members"] = std::move(members);
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/memory.hpp b/redfish-core/lib/memory.hpp
index c77a5346a6..eb5fb2312c 100644
--- a/redfish-core/lib/memory.hpp
+++ b/redfish-core/lib/memory.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -19,6 +19,8 @@
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/memory.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
@@ -368,39 +370,45 @@ inline void getPersistentMemoryProperties(
if (dataLockCapable != nullptr)
{
- asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
- ["DataLockCapable"] = *dataLockCapable;
+ asyncResp->res
+ .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] =
+ *dataLockCapable;
}
if (passphraseCapable != nullptr)
{
- asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
- ["PassphraseCapable"] = *passphraseCapable;
+ asyncResp->res
+ .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] =
+ *passphraseCapable;
}
if (maxPassphraseCount != nullptr)
{
- asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
- ["MaxPassphraseCount"] = *maxPassphraseCount;
+ asyncResp->res
+ .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] =
+ *maxPassphraseCount;
}
if (passphraseLockLimit != nullptr)
{
- asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
- ["PassphraseLockLimit"] = *passphraseLockLimit;
+ asyncResp->res
+ .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] =
+ *passphraseLockLimit;
}
}
-inline void
- assembleDimmProperties(std::string_view dimmId,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const dbus::utility::DBusPropertiesMap& properties,
- const nlohmann::json::json_pointer& jsonPtr)
+inline void assembleDimmProperties(
+ std::string_view dimmId,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const dbus::utility::DBusPropertiesMap& properties,
+ const nlohmann::json::json_pointer& jsonPtr)
{
asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
- asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
+ asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
+ resource::State::Enabled;
+ asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] =
+ resource::Health::OK;
const uint16_t* memoryDataWidth = nullptr;
const size_t* memorySizeInKB = nullptr;
@@ -477,7 +485,8 @@ inline void
if (present != nullptr && !*present)
{
- asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
+ asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
+ resource::State::Absent;
}
if (memoryTotalWidth != nullptr)
@@ -552,11 +561,13 @@ inline void
}
if (memoryType->find("DDR") != std::string::npos)
{
- asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
+ asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
+ memory::MemoryType::DRAM;
}
else if (memoryType->ends_with("Logical"))
{
- asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
+ asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
+ memory::MemoryType::IntelOptane;
}
}
@@ -568,8 +579,9 @@ inline void
if (memoryController != nullptr)
{
- asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]
- ["MemoryController"] = *memoryController;
+ asyncResp->res
+ .jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
+ *memoryController;
}
if (slot != nullptr)
@@ -594,17 +606,17 @@ inline void
if (locationCode != nullptr)
{
- asyncResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
- ["ServiceLabel"] = *locationCode;
+ asyncResp->res
+ .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
+ *locationCode;
}
getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
}
-inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
- const std::string& dimmId,
- const std::string& service,
- const std::string& objPath)
+inline void getDimmDataByService(
+ std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& dimmId,
+ const std::string& service, const std::string& objPath)
{
BMCWEB_LOG_DEBUG("Get available system components.");
sdbusplus::asio::getAllProperties(
@@ -612,14 +624,15 @@ inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[dimmId, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
- return;
- }
- assembleDimmProperties(dimmId, asyncResp, properties, ""_json_pointer);
- });
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ assembleDimmProperties(dimmId, asyncResp, properties,
+ ""_json_pointer);
+ });
}
inline void assembleDimmPartitionData(
@@ -685,16 +698,16 @@ inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
- return;
+ return;
+ }
+ nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
+ assembleDimmPartitionData(asyncResp, properties, regionPtr);
}
- nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
- assembleDimmPartitionData(asyncResp, properties, regionPtr);
- }
);
}
@@ -711,57 +724,57 @@ inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[dimmId, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
- return;
- }
- bool found = false;
- for (const auto& [rawPath, object] : subtree)
- {
- sdbusplus::message::object_path path(rawPath);
- for (const auto& [service, interfaces] : object)
+ return;
+ }
+ bool found = false;
+ for (const auto& [rawPath, object] : subtree)
{
- for (const auto& interface : interfaces)
+ sdbusplus::message::object_path path(rawPath);
+ for (const auto& [service, interfaces] : object)
{
- if (interface ==
- "xyz.openbmc_project.Inventory.Item.Dimm" &&
- path.filename() == dimmId)
- {
- getDimmDataByService(asyncResp, dimmId, service,
- rawPath);
- found = true;
- }
-
- // partitions are separate as there can be multiple
- // per
- // device, i.e.
- // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
- // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
- if (interface ==
- "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
- path.parent_path().filename() == dimmId)
+ for (const auto& interface : interfaces)
{
- getDimmPartitionData(asyncResp, service, rawPath);
+ if (interface ==
+ "xyz.openbmc_project.Inventory.Item.Dimm" &&
+ path.filename() == dimmId)
+ {
+ getDimmDataByService(asyncResp, dimmId, service,
+ rawPath);
+ found = true;
+ }
+
+ // partitions are separate as there can be multiple
+ // per
+ // device, i.e.
+ // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
+ // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
+ if (interface ==
+ "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
+ path.parent_path().filename() == dimmId)
+ {
+ getDimmPartitionData(asyncResp, service, rawPath);
+ }
}
}
}
- }
- // Object not found
- if (!found)
- {
- messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
+ // Object not found
+ if (!found)
+ {
+ messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
+ return;
+ }
+ // Set @odata only if object is found
+ asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
+ asyncResp->res.jsonValue["@odata.id"] =
+ boost::urls::format("/redfish/v1/Systems/{}/Memory/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, dimmId);
return;
- }
- // Set @odata only if object is found
- asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/Systems/{}/Memory/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, dimmId);
- return;
- });
+ });
}
inline void requestRoutesMemoryCollection(App& app)
@@ -775,38 +788,39 @@ inline void requestRoutesMemoryCollection(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- asyncResp->res.jsonValue["@odata.type"] =
- "#MemoryCollection.MemoryCollection";
- asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
-
- constexpr std::array<std::string_view, 1> interfaces{
- "xyz.openbmc_project.Inventory.Item.Dimm"};
- collection_util::getCollectionMembers(
- asyncResp,
- boost::urls::format("/redfish/v1/Systems/{}/Memory",
- BMCWEB_REDFISH_SYSTEM_URI_NAME),
- interfaces, "/xyz/openbmc_project/inventory");
- });
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#MemoryCollection.MemoryCollection";
+ asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ boost::urls::format("/redfish/v1/Systems/{}/Memory",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+
+ constexpr std::array<std::string_view, 1> interfaces{
+ "xyz.openbmc_project.Inventory.Item.Dimm"};
+ collection_util::getCollectionMembers(
+ asyncResp,
+ boost::urls::format("/redfish/v1/Systems/{}/Memory",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME),
+ interfaces, "/xyz/openbmc_project/inventory");
+ });
}
inline void requestRoutesMemory(App& app)
@@ -820,28 +834,28 @@ inline void requestRoutesMemory(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName, const std::string& dimmId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- getDimmData(asyncResp, dimmId);
- });
+ getDimmData(asyncResp, dimmId);
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/message_registries.hpp b/redfish-core/lib/message_registries.hpp
index 94588ac1ca..c41b144023 100644
--- a/redfish-core/lib/message_registries.hpp
+++ b/redfish-core/lib/message_registries.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2019 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2019 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -56,8 +56,8 @@ inline void handleMessageRegistryFileCollectionGet(
{"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry"}))
{
nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format("/redfish/v1/Registries/{}",
- memberName);
+ member["@odata.id"] =
+ boost::urls::format("/redfish/v1/Registries/{}", memberName);
members.emplace_back(std::move(member));
}
}
@@ -123,8 +123,8 @@ inline void handleMessageRoutesMessageRegistryFileGet(
asyncResp->res.jsonValue["@odata.type"] =
"#MessageRegistryFile.v1_1_0.MessageRegistryFile";
asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
- asyncResp->res.jsonValue["Description"] = dmtf + registry +
- " Message Registry File Location";
+ asyncResp->res.jsonValue["Description"] =
+ dmtf + registry + " Message Registry File Location";
asyncResp->res.jsonValue["Id"] = header->registryPrefix;
asyncResp->res.jsonValue["Registry"] = header->id;
nlohmann::json::array_t languages;
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
index 3eb692776c..c47ba13181 100644
--- a/redfish-core/lib/metric_report.hpp
+++ b/redfish-core/lib/metric_report.hpp
@@ -65,24 +65,25 @@ inline void requestRoutesMetricReportCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#MetricReportCollection.MetricReportCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/TelemetryService/MetricReports";
- asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
- constexpr std::array<std::string_view, 1> interfaces{
- telemetry::reportInterface};
- collection_util::getCollectionMembers(
- asyncResp,
- boost::urls::url("/redfish/v1/TelemetryService/MetricReports"),
- interfaces,
- "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#MetricReportCollection.MetricReportCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/TelemetryService/MetricReports";
+ asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
+ constexpr std::array<std::string_view, 1> interfaces{
+ telemetry::reportInterface};
+ collection_util::getCollectionMembers(
+ asyncResp,
+ boost::urls::url(
+ "/redfish/v1/TelemetryService/MetricReports"),
+ interfaces,
+ "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
+ });
}
inline void requestRoutesMetricReport(App& app)
@@ -93,43 +94,49 @@ inline void requestRoutesMetricReport(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& id) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- const std::string reportPath = telemetry::getDbusReportPath(id);
- crow::connections::systemBus->async_method_call(
- [asyncResp, id, reportPath](const boost::system::error_code& ec) {
- if (ec.value() == EBADR ||
- ec == boost::system::errc::host_unreachable)
- {
- messages::resourceNotFound(asyncResp->res, "MetricReport", id);
- return;
- }
- if (ec)
- {
- BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- sdbusplus::asio::getProperty<telemetry::TimestampReadings>(
- *crow::connections::systemBus, telemetry::service, reportPath,
- telemetry::reportInterface, "Readings",
- [asyncResp, id](const boost::system::error_code& ec2,
- const telemetry::TimestampReadings& ret) {
- if (ec2)
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- BMCWEB_LOG_ERROR("respHandler DBus error {}", ec2);
- messages::internalError(asyncResp->res);
return;
}
-
- telemetry::fillReport(asyncResp->res.jsonValue, id, ret);
+ const std::string reportPath = telemetry::getDbusReportPath(id);
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, id,
+ reportPath](const boost::system::error_code& ec) {
+ if (ec.value() == EBADR ||
+ ec == boost::system::errc::host_unreachable)
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "MetricReport", id);
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ sdbusplus::asio::getProperty<
+ telemetry::TimestampReadings>(
+ *crow::connections::systemBus, telemetry::service,
+ reportPath, telemetry::reportInterface, "Readings",
+ [asyncResp,
+ id](const boost::system::error_code& ec2,
+ const telemetry::TimestampReadings& ret) {
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "respHandler DBus error {}", ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ telemetry::fillReport(asyncResp->res.jsonValue,
+ id, ret);
+ });
+ },
+ telemetry::service, reportPath, telemetry::reportInterface,
+ "Update");
});
- },
- telemetry::service, reportPath, telemetry::reportInterface,
- "Update");
- });
}
} // namespace redfish
diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp
index 36f2334638..d92343d0fe 100644
--- a/redfish-core/lib/metric_report_definition.hpp
+++ b/redfish-core/lib/metric_report_definition.hpp
@@ -3,6 +3,7 @@
#include "app.hpp"
#include "dbus_utility.hpp"
#include "generated/enums/metric_report_definition.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "sensors.hpp"
@@ -245,10 +246,9 @@ inline std::optional<nlohmann::json::array_t> getLinkedTriggers(
return triggers;
}
-inline void
- fillReportDefinition(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& id,
- const dbus::utility::DBusPropertiesMap& properties)
+inline void fillReportDefinition(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id,
+ const dbus::utility::DBusPropertiesMap& properties)
{
std::vector<std::string> reportActions;
ReadingParameters readingParams;
@@ -356,11 +356,11 @@ inline void
if (enabled)
{
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
}
else
{
- asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Disabled;
}
metric_report_definition::ReportUpdatesEnum redfishReportUpdates =
@@ -641,22 +641,120 @@ inline bool getChassisSensorNodeFromMetrics(
getChassisSensorNode(metric.uris, matched);
if (error)
{
- messages::propertyValueIncorrect(asyncResp->res, error->uri,
- "MetricProperties/" +
- std::to_string(error->index));
+ messages::propertyValueIncorrect(
+ asyncResp->res, error->uri,
+ "MetricProperties/" + std::to_string(error->index));
+ return false;
+ }
+ }
+ return true;
+}
+
+inline std::string toRedfishProperty(std::string_view dbusMessage)
+{
+ if (dbusMessage == "Id")
+ {
+ return "Id";
+ }
+ if (dbusMessage == "Name")
+ {
+ return "Name";
+ }
+ if (dbusMessage == "ReportingType")
+ {
+ return "MetricReportDefinitionType";
+ }
+ if (dbusMessage == "AppendLimit")
+ {
+ return "AppendLimit";
+ }
+ if (dbusMessage == "ReportActions")
+ {
+ return "ReportActions";
+ }
+ if (dbusMessage == "Interval")
+ {
+ return "RecurrenceInterval";
+ }
+ if (dbusMessage == "ReportUpdates")
+ {
+ return "ReportUpdates";
+ }
+ if (dbusMessage == "ReadingParameters")
+ {
+ return "Metrics";
+ }
+ return "";
+}
+
+inline bool handleParamError(crow::Response& res, const char* errorMessage,
+ std::string_view key)
+{
+ if (errorMessage == nullptr)
+ {
+ BMCWEB_LOG_ERROR("errorMessage was null");
+ return true;
+ }
+ std::string_view errorMessageSv(errorMessage);
+ if (errorMessageSv.starts_with(key))
+ {
+ std::string redfishProperty = toRedfishProperty(key);
+ if (redfishProperty.empty())
+ {
+ // Getting here means most possibly that toRedfishProperty has
+ // incomplete implementation. Return internal error for now.
+ BMCWEB_LOG_ERROR("{} has no corresponding Redfish property", key);
+ messages::internalError(res);
return false;
}
+ messages::propertyValueError(res, redfishProperty);
+ return false;
}
+
return true;
}
+inline void afterAddReport(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const AddReportArgs& args,
+ const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg)
+{
+ if (!ec)
+ {
+ messages::created(asyncResp->res);
+ return;
+ }
+
+ if (ec == boost::system::errc::invalid_argument)
+ {
+ const sd_bus_error* errorMessage = msg.get_error();
+ if (errorMessage != nullptr)
+ {
+ for (const auto& arg :
+ {"Id", "Name", "ReportingType", "AppendLimit", "ReportActions",
+ "Interval", "ReportUpdates", "ReadingParameters"})
+ {
+ if (!handleParamError(asyncResp->res, errorMessage->message,
+ arg))
+ {
+ return;
+ }
+ }
+ }
+ }
+ if (!verifyCommonErrors(asyncResp->res, args.id, ec))
+ {
+ return;
+ }
+ messages::internalError(asyncResp->res);
+}
+
class AddReport
{
public:
AddReport(AddReportArgs&& argsIn,
const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
- asyncResp(asyncRespIn),
- args(std::move(argsIn))
+ asyncResp(asyncRespIn), args(std::move(argsIn))
{}
~AddReport()
@@ -695,9 +793,9 @@ class AddReport
BMCWEB_LOG_ERROR(
"Failed to find DBus sensor corresponding to URI {}",
uri);
- messages::propertyValueNotInList(asyncResp->res, uri,
- "MetricProperties/" +
- std::to_string(i));
+ messages::propertyValueNotInList(
+ asyncResp->res, uri,
+ "MetricProperties/" + std::to_string(i));
return;
}
@@ -709,41 +807,12 @@ class AddReport
std::move(sensorParams), metric.collectionFunction,
metric.collectionTimeScope, metric.collectionDuration);
}
-
crow::connections::systemBus->async_method_call(
- [asyncResp, id = args.id, uriToDbus](
- const boost::system::error_code& ec, const std::string&) {
- if (ec == boost::system::errc::file_exists)
- {
- messages::resourceAlreadyExists(
- asyncResp->res, "MetricReportDefinition", "Id", id);
- return;
- }
- if (ec == boost::system::errc::too_many_files_open)
- {
- messages::createLimitReachedForResource(asyncResp->res);
- return;
- }
- if (ec == boost::system::errc::argument_list_too_long)
- {
- nlohmann::json metricProperties = nlohmann::json::array();
- for (const auto& [uri, _] : uriToDbus)
- {
- metricProperties.emplace_back(uri);
- }
- messages::propertyValueIncorrect(
- asyncResp->res, "MetricProperties", metricProperties);
- return;
- }
- if (ec)
- {
- messages::internalError(asyncResp->res);
- BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
- return;
- }
-
- messages::created(asyncResp->res);
- },
+ [asyncResp, args](const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg,
+ const std::string& /*arg1*/) {
+ afterAddReport(asyncResp, args, ec, msg);
+ },
telemetry::service, "/xyz/openbmc_project/Telemetry/Reports",
"xyz.openbmc_project.Telemetry.ReportManager", "AddReport",
"TelemetryService/" + args.id, args.name, args.reportingType,
@@ -762,36 +831,128 @@ class AddReport
}
private:
- std::shared_ptr<bmcweb::AsyncResp> asyncResp;
+ const std::shared_ptr<bmcweb::AsyncResp> asyncResp;
AddReportArgs args;
boost::container::flat_map<std::string, std::string> uriToDbus;
};
-class UpdateMetrics
+inline std::optional<
+ std::vector<std::tuple<sdbusplus::message::object_path, std::string>>>
+ sensorPathToUri(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ std::span<const std::string> uris,
+ const std::map<std::string, std::string>& metricPropertyToDbusPaths)
{
- public:
- UpdateMetrics(std::string_view idIn,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
- id(idIn),
- asyncResp(asyncRespIn)
- {}
+ std::vector<std::tuple<sdbusplus::message::object_path, std::string>>
+ result;
- ~UpdateMetrics()
+ for (const std::string& uri : uris)
{
- try
+ auto it = metricPropertyToDbusPaths.find(uri);
+ if (it == metricPropertyToDbusPaths.end())
{
- setReadingParams();
+ messages::propertyValueNotInList(asyncResp->res, uri,
+ "MetricProperties");
+ return {};
}
- catch (const std::exception& e)
+ result.emplace_back(it->second, uri);
+ }
+
+ return result;
+}
+
+inline void afterSetReadingParams(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& reportId, const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg)
+{
+ if (!ec)
+ {
+ messages::success(asyncResp->res);
+ return;
+ }
+ if (ec == boost::system::errc::invalid_argument)
+ {
+ const sd_bus_error* errorMessage = msg.get_error();
+ if (errorMessage != nullptr)
{
- BMCWEB_LOG_ERROR("{}", e.what());
+ for (const auto& arg : {"Id", "ReadingParameters"})
+ {
+ if (!handleParamError(asyncResp->res, errorMessage->message,
+ arg))
+ {
+ return;
+ }
+ }
}
- catch (...)
+ }
+ if (!verifyCommonErrors(asyncResp->res, reportId, ec))
+ {
+ return;
+ }
+ messages::internalError(asyncResp->res);
+}
+
+inline void setReadingParams(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& reportId, ReadingParameters readingParams,
+ const std::vector<std::vector<std::string>>& readingParamsUris,
+ const std::map<std::string, std::string>& metricPropertyToDbusPaths)
+{
+ if (asyncResp->res.result() != boost::beast::http::status::ok)
+ {
+ return;
+ }
+
+ for (size_t index = 0; index < readingParamsUris.size(); ++index)
+ {
+ std::span<const std::string> newUris = readingParamsUris[index];
+
+ const std::optional<std::vector<
+ std::tuple<sdbusplus::message::object_path, std::string>>>
+ readingParam =
+ sensorPathToUri(asyncResp, newUris, metricPropertyToDbusPaths);
+
+ if (!readingParam)
+ {
+ return;
+ }
+
+ for (const std::tuple<sdbusplus::message::object_path, std::string>&
+ value : *readingParam)
{
- BMCWEB_LOG_ERROR("Unknown error");
+ std::get<0>(readingParams[index]).emplace_back(value);
}
}
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, reportId](const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg) {
+ afterSetReadingParams(asyncResp, reportId, ec, msg);
+ },
+ "xyz.openbmc_project.Telemetry", getDbusReportPath(reportId),
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Telemetry.Report", "ReadingParameters",
+ dbus::utility::DbusVariantType{readingParams});
+}
+
+class UpdateMetrics
+{
+ public:
+ UpdateMetrics(std::string_view idIn,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
+ id(idIn), asyncResp(asyncRespIn)
+ {}
+
+ ~UpdateMetrics()
+ {
+ boost::asio::post(
+ crow::connections::systemBus->get_io_context(),
+ std::bind_front(&setReadingParams, asyncResp, id,
+ std::move(readingParams), readingParamsUris,
+ metricPropertyToDbusPaths));
+ }
+
UpdateMetrics(const UpdateMetrics&) = delete;
UpdateMetrics(UpdateMetrics&&) = delete;
UpdateMetrics& operator=(const UpdateMetrics&) = delete;
@@ -808,10 +969,11 @@ class UpdateMetrics
additionalMetricPropertyToDbusPaths.end());
}
- void emplace(std::span<const std::tuple<sdbusplus::message::object_path,
- std::string>>
- pathAndUri,
- const AddReportArgs::MetricArgs& metricArgs)
+ void emplace(
+ std::span<
+ const std::tuple<sdbusplus::message::object_path, std::string>>
+ pathAndUri,
+ const AddReportArgs::MetricArgs& metricArgs)
{
readingParamsUris.emplace_back(metricArgs.uris);
readingParams.emplace_back(
@@ -820,66 +982,7 @@ class UpdateMetrics
metricArgs.collectionDuration);
}
- void setReadingParams()
- {
- if (asyncResp->res.result() != boost::beast::http::status::ok)
- {
- return;
- }
-
- for (size_t index = 0; index < readingParamsUris.size(); ++index)
- {
- std::span<const std::string> newUris = readingParamsUris[index];
-
- const std::optional<std::vector<
- std::tuple<sdbusplus::message::object_path, std::string>>>
- readingParam = sensorPathToUri(newUris);
-
- if (!readingParam)
- {
- return;
- }
-
- std::get<0>(readingParams[index]) = *readingParam;
- }
-
- crow::connections::systemBus->async_method_call(
- [asyncResp(this->asyncResp),
- reportId = id](const boost::system::error_code& ec) {
- if (!verifyCommonErrors(asyncResp->res, reportId, ec))
- {
- return;
- }
- },
- "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Telemetry.Report", "ReadingParameters",
- dbus::utility::DbusVariantType{readingParams});
- }
-
private:
- std::optional<
- std::vector<std::tuple<sdbusplus::message::object_path, std::string>>>
- sensorPathToUri(std::span<const std::string> uris) const
- {
- std::vector<std::tuple<sdbusplus::message::object_path, std::string>>
- result;
-
- for (const std::string& uri : uris)
- {
- auto it = metricPropertyToDbusPaths.find(uri);
- if (it == metricPropertyToDbusPaths.end())
- {
- messages::propertyValueNotInList(asyncResp->res, uri,
- "MetricProperties");
- return {};
- }
- result.emplace_back(it->second, uri);
- }
-
- return result;
- }
-
const std::shared_ptr<bmcweb::AsyncResp> asyncResp;
std::vector<std::vector<std::string>> readingParamsUris;
ReadingParameters readingParams;
@@ -891,160 +994,282 @@ inline void
{
crow::connections::systemBus->async_method_call(
[asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
- if (!verifyCommonErrors(asyncResp->res, id, ec))
- {
- return;
- }
- },
+ if (!verifyCommonErrors(asyncResp->res, id, ec))
+ {
+ return;
+ }
+ },
"xyz.openbmc_project.Telemetry", getDbusReportPath(id),
"org.freedesktop.DBus.Properties", "Set",
"xyz.openbmc_project.Telemetry.Report", "Enabled",
dbus::utility::DbusVariantType{enabled});
}
+inline void afterSetReportingProperties(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id,
+ const boost::system::error_code& ec, const sdbusplus::message_t& msg)
+{
+ if (!ec)
+ {
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ return;
+ }
+
+ if (ec == boost::system::errc::invalid_argument)
+ {
+ const sd_bus_error* errorMessage = msg.get_error();
+ if (errorMessage != nullptr)
+ {
+ for (const auto& arg : {"Id", "ReportingType", "Interval"})
+ {
+ if (!handleParamError(asyncResp->res, errorMessage->message,
+ arg))
+ {
+ return;
+ }
+ }
+ }
+ }
+ if (!verifyCommonErrors(asyncResp->res, id, ec))
+ {
+ return;
+ }
+ messages::internalError(asyncResp->res);
+}
+
inline void setReportTypeAndInterval(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string_view id,
- const std::string& reportingType, uint64_t recurrenceInterval)
+ const std::optional<std::string>& reportingType,
+ const std::optional<std::string>& recurrenceIntervalStr)
{
- crow::connections::systemBus->async_method_call(
- [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
- if (!verifyCommonErrors(asyncResp->res, id, ec))
+ std::string dbusReportingType;
+ if (reportingType)
+ {
+ dbusReportingType = toDbusReportingType(*reportingType);
+ if (dbusReportingType.empty())
{
+ messages::propertyValueNotInList(asyncResp->res, *reportingType,
+ "MetricReportDefinitionType");
return;
}
- },
+ }
+
+ uint64_t recurrenceInterval = std::numeric_limits<uint64_t>::max();
+ if (recurrenceIntervalStr)
+ {
+ std::optional<std::chrono::milliseconds> durationNum =
+ time_utils::fromDurationString(*recurrenceIntervalStr);
+ if (!durationNum || durationNum->count() < 0)
+ {
+ messages::propertyValueIncorrect(
+ asyncResp->res, "RecurrenceInterval", *recurrenceIntervalStr);
+ return;
+ }
+
+ recurrenceInterval = static_cast<uint64_t>(durationNum->count());
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, id = std::string(id)](const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg) {
+ afterSetReportingProperties(asyncResp, id, ec, msg);
+ },
"xyz.openbmc_project.Telemetry", getDbusReportPath(id),
"xyz.openbmc_project.Telemetry.Report", "SetReportingProperties",
- reportingType, recurrenceInterval);
+ dbusReportingType, recurrenceInterval);
+}
+
+inline void afterSetReportUpdates(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id,
+ const boost::system::error_code& ec, const sdbusplus::message_t& msg)
+{
+ if (!ec)
+ {
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ return;
+ }
+ if (ec == boost::system::errc::invalid_argument)
+ {
+ const sd_bus_error* errorMessage = msg.get_error();
+ if (errorMessage != nullptr)
+ {
+ for (const auto& arg : {"Id", "ReportUpdates"})
+ {
+ if (!handleParamError(asyncResp->res, errorMessage->message,
+ arg))
+ {
+ return;
+ }
+ }
+ }
+ }
+ if (!verifyCommonErrors(asyncResp->res, id, ec))
+ {
+ return;
+ }
}
inline void
setReportUpdates(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
std::string_view id, const std::string& reportUpdates)
{
+ std::string dbusReportUpdates = toDbusReportUpdates(reportUpdates);
+ if (dbusReportUpdates.empty())
+ {
+ messages::propertyValueNotInList(asyncResp->res, reportUpdates,
+ "ReportUpdates");
+ return;
+ }
crow::connections::systemBus->async_method_call(
- [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
- if (!verifyCommonErrors(asyncResp->res, id, ec))
- {
- return;
- }
- },
+ [asyncResp, id = std::string(id)](const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg) {
+ afterSetReportUpdates(asyncResp, id, ec, msg);
+ },
"xyz.openbmc_project.Telemetry", getDbusReportPath(id),
"org.freedesktop.DBus.Properties", "Set",
"xyz.openbmc_project.Telemetry.Report", "ReportUpdates",
- dbus::utility::DbusVariantType{reportUpdates});
+ dbus::utility::DbusVariantType{dbusReportUpdates});
}
-inline void
- setReportActions(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string_view id,
- const std::vector<std::string>& dbusReportActions)
+inline void afterSetReportActions(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id,
+ const boost::system::error_code& ec, const sdbusplus::message_t& msg)
{
- crow::connections::systemBus->async_method_call(
- [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
- if (!verifyCommonErrors(asyncResp->res, id, ec))
+ if (ec == boost::system::errc::invalid_argument)
+ {
+ const sd_bus_error* errorMessage = msg.get_error();
+ if (errorMessage != nullptr)
{
- return;
+ for (const auto& arg : {"Id", "ReportActions"})
+ {
+ if (!handleParamError(asyncResp->res, errorMessage->message,
+ arg))
+ {
+ return;
+ }
+ }
}
- },
+ }
+
+ if (!verifyCommonErrors(asyncResp->res, id, ec))
+ {
+ return;
+ }
+
+ messages::internalError(asyncResp->res);
+}
+
+inline void setReportActions(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string_view id,
+ const std::vector<std::string>& reportActions)
+{
+ std::vector<std::string> dbusReportActions;
+ if (!toDbusReportActions(asyncResp->res, reportActions, dbusReportActions))
+ {
+ return;
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, id = std::string(id)](const boost::system::error_code& ec,
+ const sdbusplus::message_t& msg) {
+ afterSetReportActions(asyncResp, id, ec, msg);
+ },
"xyz.openbmc_project.Telemetry", getDbusReportPath(id),
"org.freedesktop.DBus.Properties", "Set",
"xyz.openbmc_project.Telemetry.Report", "ReportActions",
dbus::utility::DbusVariantType{dbusReportActions});
}
-inline void
- setReportMetrics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string_view id,
- std::span<nlohmann::json::object_t> metrics)
+inline void setReportMetrics(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string_view id,
+ std::vector<nlohmann::json::object_t>&& metrics)
{
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, telemetry::service,
telemetry::getDbusReportPath(id), telemetry::reportInterface,
- [asyncResp, id = std::string(id),
- redfishMetrics = std::vector<nlohmann::json::object_t>(metrics.begin(),
- metrics.end())](
+ [asyncResp, id = std::string(id), redfishMetrics = std::move(metrics)](
boost::system::error_code ec,
const dbus::utility::DBusPropertiesMap& properties) mutable {
- if (!redfish::telemetry::verifyCommonErrors(asyncResp->res, id, ec))
- {
- return;
- }
-
- ReadingParameters readingParams;
+ if (!verifyCommonErrors(asyncResp->res, id, ec))
+ {
+ return;
+ }
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "ReadingParameters",
- readingParams);
+ ReadingParameters readingParams;
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties,
+ "ReadingParameters", readingParams);
- auto updateMetricsReq = std::make_shared<UpdateMetrics>(id, asyncResp);
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- boost::container::flat_set<std::pair<std::string, std::string>>
- chassisSensors;
+ auto updateMetricsReq =
+ std::make_shared<UpdateMetrics>(id, asyncResp);
- size_t index = 0;
- for (nlohmann::json::object_t& metric : redfishMetrics)
- {
- AddReportArgs::MetricArgs metricArgs;
- std::vector<
- std::tuple<sdbusplus::message::object_path, std::string>>
- pathAndUri;
+ boost::container::flat_set<std::pair<std::string, std::string>>
+ chassisSensors;
- if (index < readingParams.size())
+ size_t index = 0;
+ for (nlohmann::json::object_t& metric : redfishMetrics)
{
- const ReadingParameters::value_type& existing =
- readingParams[index];
-
- pathAndUri = std::get<0>(existing);
- metricArgs.collectionFunction = std::get<1>(existing);
- metricArgs.collectionTimeScope = std::get<2>(existing);
- metricArgs.collectionDuration = std::get<3>(existing);
- }
+ AddReportArgs::MetricArgs metricArgs;
+ std::vector<
+ std::tuple<sdbusplus::message::object_path, std::string>>
+ pathAndUri;
- if (!getUserMetric(asyncResp->res, metric, metricArgs))
- {
- return;
- }
+ if (index < readingParams.size())
+ {
+ const ReadingParameters::value_type& existing =
+ readingParams[index];
- std::optional<IncorrectMetricUri> error =
- getChassisSensorNode(metricArgs.uris, chassisSensors);
+ pathAndUri = std::get<0>(existing);
+ metricArgs.collectionFunction = std::get<1>(existing);
+ metricArgs.collectionTimeScope = std::get<2>(existing);
+ metricArgs.collectionDuration = std::get<3>(existing);
+ }
- if (error)
- {
- messages::propertyValueIncorrect(
- asyncResp->res, error->uri,
- "MetricProperties/" + std::to_string(error->index));
- return;
- }
+ if (!getUserMetric(asyncResp->res, metric, metricArgs))
+ {
+ return;
+ }
- updateMetricsReq->emplace(pathAndUri, metricArgs);
- index++;
- }
+ std::optional<IncorrectMetricUri> error =
+ getChassisSensorNode(metricArgs.uris, chassisSensors);
- for (const auto& [chassis, sensorType] : chassisSensors)
- {
- retrieveUriToDbusMap(
- chassis, sensorType,
- [asyncResp, updateMetricsReq](
- const boost::beast::http::status status,
- const std::map<std::string, std::string>& uriToDbus) {
- if (status != boost::beast::http::status::ok)
+ if (error)
{
- BMCWEB_LOG_ERROR(
- "Failed to retrieve URI to dbus sensors map with err {}",
- static_cast<unsigned>(status));
+ messages::propertyValueIncorrect(
+ asyncResp->res, error->uri,
+ "MetricProperties/" + std::to_string(error->index));
return;
}
- updateMetricsReq->insert(uriToDbus);
- });
- }
- });
+
+ updateMetricsReq->emplace(pathAndUri, metricArgs);
+ index++;
+ }
+
+ for (const auto& [chassis, sensorType] : chassisSensors)
+ {
+ retrieveUriToDbusMap(
+ chassis, sensorType,
+ [asyncResp, updateMetricsReq](
+ const boost::beast::http::status status,
+ const std::map<std::string, std::string>& uriToDbus) {
+ if (status != boost::beast::http::status::ok)
+ {
+ BMCWEB_LOG_ERROR(
+ "Failed to retrieve URI to dbus sensors map with err {}",
+ static_cast<unsigned>(status));
+ return;
+ }
+ updateMetricsReq->insert(uriToDbus);
+ });
+ }
+ });
}
inline void handleMetricReportDefinitionCollectionHead(
@@ -1087,10 +1312,9 @@ inline void handleMetricReportDefinitionCollectionGet(
interfaces, "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
}
-inline void
- handleReportPatch(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string_view id)
+inline void handleReportPatch(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string_view id)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -1121,71 +1345,29 @@ inline void
if (reportUpdatesStr)
{
- std::string dbusReportUpdates = toDbusReportUpdates(*reportUpdatesStr);
- if (dbusReportUpdates.empty())
- {
- messages::propertyValueNotInList(asyncResp->res, *reportUpdatesStr,
- "ReportUpdates");
- return;
- }
- setReportUpdates(asyncResp, id, dbusReportUpdates);
+ setReportUpdates(asyncResp, id, *reportUpdatesStr);
}
if (reportActionsStr)
{
- std::vector<std::string> dbusReportActions;
- if (!toDbusReportActions(asyncResp->res, *reportActionsStr,
- dbusReportActions))
- {
- return;
- }
- setReportActions(asyncResp, id, dbusReportActions);
+ setReportActions(asyncResp, id, *reportActionsStr);
}
if (reportingTypeStr || scheduleDurationStr)
{
- std::string dbusReportingType;
- if (reportingTypeStr)
- {
- dbusReportingType = toDbusReportingType(*reportingTypeStr);
- if (dbusReportingType.empty())
- {
- messages::propertyValueNotInList(asyncResp->res,
- *reportingTypeStr,
- "MetricReportDefinitionType");
- return;
- }
- }
-
- uint64_t recurrenceInterval = std::numeric_limits<uint64_t>::max();
- if (scheduleDurationStr)
- {
- std::optional<std::chrono::milliseconds> durationNum =
- time_utils::fromDurationString(*scheduleDurationStr);
- if (!durationNum || durationNum->count() < 0)
- {
- messages::propertyValueIncorrect(
- asyncResp->res, "RecurrenceInterval", *scheduleDurationStr);
- return;
- }
-
- recurrenceInterval = static_cast<uint64_t>(durationNum->count());
- }
-
- setReportTypeAndInterval(asyncResp, id, dbusReportingType,
- recurrenceInterval);
+ setReportTypeAndInterval(asyncResp, id, reportingTypeStr,
+ scheduleDurationStr);
}
if (metrics)
{
- setReportMetrics(asyncResp, id, *metrics);
+ setReportMetrics(asyncResp, id, std::move(*metrics));
}
}
-inline void
- handleReportDelete(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string_view id)
+inline void handleReportDelete(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string_view id)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -1197,12 +1379,12 @@ inline void
crow::connections::systemBus->async_method_call(
[asyncResp,
reportId = std::string(id)](const boost::system::error_code& ec) {
- if (!verifyCommonErrors(asyncResp->res, reportId, ec))
- {
- return;
- }
- asyncResp->res.result(boost::beast::http::status::no_content);
- },
+ if (!verifyCommonErrors(asyncResp->res, reportId, ec))
+ {
+ return;
+ }
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ },
service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete");
}
} // namespace telemetry
@@ -1246,8 +1428,8 @@ inline void handleMetricReportDefinitionsPost(
return;
}
- auto addReportReq = std::make_shared<telemetry::AddReport>(std::move(args),
- asyncResp);
+ auto addReportReq =
+ std::make_shared<telemetry::AddReport>(std::move(args), asyncResp);
for (const auto& [chassis, sensorType] : chassisSensors)
{
retrieveUriToDbusMap(chassis, sensorType,
@@ -1270,10 +1452,9 @@ inline void
"</redfish/v1/JsonSchemas/MetricReport/MetricReport.json>; rel=describedby");
}
-inline void
- handleMetricReportGet(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& id)
+inline void handleMetricReportGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -1288,13 +1469,13 @@ inline void
telemetry::getDbusReportPath(id), telemetry::reportInterface,
[asyncResp, id](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (!redfish::telemetry::verifyCommonErrors(asyncResp->res, id, ec))
- {
- return;
- }
+ if (!redfish::telemetry::verifyCommonErrors(asyncResp->res, id, ec))
+ {
+ return;
+ }
- telemetry::fillReportDefinition(asyncResp, id, properties);
- });
+ telemetry::fillReportDefinition(asyncResp, id, properties);
+ });
}
inline void handleMetricReportDelete(
@@ -1311,26 +1492,26 @@ inline void handleMetricReportDelete(
crow::connections::systemBus->async_method_call(
[asyncResp, id](const boost::system::error_code& ec) {
- /*
- * boost::system::errc and std::errc are missing value
- * for EBADR error that is defined in Linux.
- */
- if (ec.value() == EBADR)
- {
- messages::resourceNotFound(asyncResp->res, "MetricReportDefinition",
- id);
- return;
- }
+ /*
+ * boost::system::errc and std::errc are missing value
+ * for EBADR error that is defined in Linux.
+ */
+ if (ec.value() == EBADR)
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "MetricReportDefinition", id);
+ return;
+ }
- if (ec)
- {
- BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.result(boost::beast::http::status::no_content);
- },
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ },
telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete",
"Delete");
}
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index 410c32cc4c..f5b64f8aa7 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -1,23 +1,24 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries/privilege_registry.hpp"
@@ -32,6 +33,7 @@
#include <optional>
#include <string_view>
#include <variant>
+#include <vector>
namespace redfish
{
@@ -52,7 +54,8 @@ static constexpr std::array<std::pair<std::string_view, std::string_view>, 3>
inline void extractNTPServersAndDomainNamesData(
const dbus::utility::ManagedObjectType& dbusData,
- std::vector<std::string>& ntpData, std::vector<std::string>& dnData)
+ std::vector<std::string>& ntpData, std::vector<std::string>& dynamicNtpData,
+ std::vector<std::string>& dnData)
{
for (const auto& obj : dbusData)
{
@@ -77,6 +80,16 @@ inline void extractNTPServersAndDomainNamesData(
ntpServers->end());
}
}
+ else if (propertyPair.first == "NTPServers")
+ {
+ const std::vector<std::string>* dynamicNtpServers =
+ std::get_if<std::vector<std::string>>(
+ &propertyPair.second);
+ if (dynamicNtpServers != nullptr)
+ {
+ dynamicNtpData = *dynamicNtpServers;
+ }
+ }
else if (propertyPair.first == "DomainName")
{
const std::vector<std::string>* domainNames =
@@ -104,19 +117,21 @@ void getEthernetIfaceData(CallbackFunc&& callback)
[callback = std::forward<CallbackFunc>(callback)](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& dbusData) {
- std::vector<std::string> ntpServers;
- std::vector<std::string> domainNames;
+ std::vector<std::string> ntpServers;
+ std::vector<std::string> dynamicNtpServers;
+ std::vector<std::string> domainNames;
- if (ec)
- {
- callback(false, ntpServers, domainNames);
- return;
- }
+ if (ec)
+ {
+ callback(false, ntpServers, dynamicNtpServers, domainNames);
+ return;
+ }
- extractNTPServersAndDomainNamesData(dbusData, ntpServers, domainNames);
+ extractNTPServersAndDomainNamesData(dbusData, ntpServers,
+ dynamicNtpServers, domainNames);
- callback(true, ntpServers, domainNames);
- });
+ callback(true, ntpServers, dynamicNtpServers, domainNames);
+ });
}
inline void afterNetworkPortRequest(
@@ -164,16 +179,16 @@ inline void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
boost::beast::http::field::link,
"</redfish/v1/JsonSchemas/ManagerNetworkProtocol/NetworkProtocol.json>; rel=describedby");
asyncResp->res.jsonValue["@odata.type"] =
- "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
+ "#ManagerNetworkProtocol.v1_9_0.ManagerNetworkProtocol";
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/Managers/{}/NetworkProtocol",
BMCWEB_REDFISH_MANAGER_URI_NAME);
asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
asyncResp->res.jsonValue["Description"] = "Manager Network Service";
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
- asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
+ asyncResp->res.jsonValue["Status"]["HealthRollup"] = resource::Health::OK;
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
// HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
// but from security perspective it is not recommended to use.
@@ -199,10 +214,11 @@ inline void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
getNTPProtocolEnabled(asyncResp);
- getEthernetIfaceData(
- [hostName, asyncResp](const bool& success,
- const std::vector<std::string>& ntpServers,
- const std::vector<std::string>& domainNames) {
+ getEthernetIfaceData([hostName, asyncResp](
+ const bool& success,
+ const std::vector<std::string>& ntpServers,
+ const std::vector<std::string>& dynamicNtpServers,
+ const std::vector<std::string>& domainNames) {
if (!success)
{
messages::resourceNotFound(asyncResp->res, "ManagerNetworkProtocol",
@@ -210,6 +226,8 @@ inline void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
return;
}
asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
+ asyncResp->res.jsonValue["NTP"]["NetworkSuppliedServers"] =
+ dynamicNtpServers;
if (!hostName.empty())
{
std::string fqdn = hostName;
@@ -289,9 +307,9 @@ inline void
// Can't delete an item that doesn't exist
if (currentNtpServer == currentNtpServers.end())
{
- messages::propertyValueNotInList(asyncResp->res, "null",
- "NTP/NTPServers/" +
- std::to_string(index));
+ messages::propertyValueNotInList(
+ asyncResp->res, "null",
+ "NTP/NTPServers/" + std::to_string(index));
return;
}
@@ -350,32 +368,32 @@ inline void
[asyncResp, currentNtpServers](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
- for (const auto& [objectPath, serviceMap] : subtree)
- {
- for (const auto& [service, interfaces] : serviceMap)
+ for (const auto& [objectPath, serviceMap] : subtree)
{
- for (const auto& interface : interfaces)
+ for (const auto& [service, interfaces] : serviceMap)
{
- if (interface !=
- "xyz.openbmc_project.Network.EthernetInterface")
+ for (const auto& interface : interfaces)
{
- continue;
+ if (interface !=
+ "xyz.openbmc_project.Network.EthernetInterface")
+ {
+ continue;
+ }
+
+ setDbusProperty(asyncResp, "NTP/NTPServers/", service,
+ objectPath, interface,
+ "StaticNTPServers", currentNtpServers);
}
-
- setDbusProperty(asyncResp, "NTP/NTPServers/", service,
- objectPath, interface, "StaticNTPServers",
- currentNtpServers);
}
}
- }
- });
+ });
}
inline void
@@ -390,29 +408,29 @@ inline void
[protocolEnabled, asyncResp,
netBasePath](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- for (const auto& entry : subtree)
- {
- if (entry.first.starts_with(netBasePath))
+ for (const auto& entry : subtree)
{
- setDbusProperty(
- asyncResp, "IPMI/ProtocolEnabled",
- entry.second.begin()->first, entry.first,
- "xyz.openbmc_project.Control.Service.Attributes", "Running",
- protocolEnabled);
- setDbusProperty(
- asyncResp, "IPMI/ProtocolEnabled",
- entry.second.begin()->first, entry.first,
- "xyz.openbmc_project.Control.Service.Attributes", "Enabled",
- protocolEnabled);
+ if (entry.first.starts_with(netBasePath))
+ {
+ setDbusProperty(
+ asyncResp, "IPMI/ProtocolEnabled",
+ entry.second.begin()->first, entry.first,
+ "xyz.openbmc_project.Control.Service.Attributes",
+ "Running", protocolEnabled);
+ setDbusProperty(
+ asyncResp, "IPMI/ProtocolEnabled",
+ entry.second.begin()->first, entry.first,
+ "xyz.openbmc_project.Control.Service.Attributes",
+ "Enabled", protocolEnabled);
+ }
}
- }
- });
+ });
}
inline std::string getHostName()
@@ -434,15 +452,15 @@ inline void
*crow::connections::systemBus, "org.freedesktop.timedate1",
"/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP",
[asyncResp](const boost::system::error_code& ec, bool enabled) {
- if (ec)
- {
- BMCWEB_LOG_WARNING(
- "Failed to get NTP status, assuming not supported");
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_WARNING(
+ "Failed to get NTP status, assuming not supported");
+ return;
+ }
- asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = enabled;
- });
+ asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = enabled;
+ });
}
inline std::string encodeServiceObjectPath(std::string_view serviceName)
@@ -518,15 +536,16 @@ inline void handleManagersNetworkProtocolPatch(
getEthernetIfaceData(
[asyncResp, ntpServerObjects](
const bool success, std::vector<std::string>& currentNtpServers,
+ const std::vector<std::string>& /*dynamicNtpServers*/,
const std::vector<std::string>& /*domainNames*/) {
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- handleNTPServersPatch(asyncResp, *ntpServerObjects,
- std::move(currentNtpServers));
- });
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ handleNTPServersPatch(asyncResp, *ntpServerObjects,
+ std::move(currentNtpServers));
+ });
}
if (ipmiEnabled)
diff --git a/redfish-core/lib/odata.hpp b/redfish-core/lib/odata.hpp
new file mode 100644
index 0000000000..beb26477a5
--- /dev/null
+++ b/redfish-core/lib/odata.hpp
@@ -0,0 +1,56 @@
+#pragma once
+
+#include "app.hpp"
+#include "error_messages.hpp"
+#include "http_request.hpp"
+#include "http_response.hpp"
+#include "query.hpp"
+#include "registries/privilege_registry.hpp"
+#include "utility.hpp"
+
+#include <boost/url/format.hpp>
+#include <nlohmann/json.hpp>
+
+#include <memory>
+#include <ranges>
+#include <string>
+#include <string_view>
+
+namespace redfish
+{
+
+inline void redfishOdataGet(const crow::Request& /*req*/,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ nlohmann::json::object_t obj;
+ obj["@odata.context"] = "/redfish/v1/$metadata";
+ nlohmann::json::array_t value;
+ for (std::string_view service :
+ {"$metadata", "odata", "JsonSchemas", "Service", "ServiceRoot",
+ "Systems", "Chassis", "Managers", "SessionService", "AccountService",
+ "UpdateService"})
+ {
+ nlohmann::json::object_t serviceObj;
+ serviceObj["kind"] = "Singleton";
+ serviceObj["name"] = "$metadata";
+ boost::urls::url url = boost::urls::format("/redfish/v1/{}", service);
+ if (service == "Service")
+ {
+ url = boost::urls::url("/redfish/v1");
+ }
+ serviceObj["url"] = url;
+ value.emplace_back(std::move(serviceObj));
+ }
+
+ obj["value"] = std::move(value);
+
+ asyncResp->res.jsonValue = std::move(obj);
+}
+
+inline void requestRoutesOdata(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/odata/")
+ .methods(boost::beast::http::verb::get)(redfishOdataGet);
+}
+
+} // namespace redfish
diff --git a/redfish-core/lib/pcie.hpp b/redfish-core/lib/pcie.hpp
index 3cfed3a3ca..7ddbaa0177 100644
--- a/redfish-core/lib/pcie.hpp
+++ b/redfish-core/lib/pcie.hpp
@@ -1,23 +1,24 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
@@ -40,7 +41,7 @@ static constexpr std::array<std::string_view, 1> pcieDeviceInterface = {
static constexpr std::array<std::string_view, 1> pcieSlotInterface = {
"xyz.openbmc_project.Inventory.Item.PCIeSlot"};
-static inline void handlePCIeDevicePath(
+inline void handlePCIeDevicePath(
const std::string& pcieDeviceId,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const dbus::utility::MapperGetSubTreePathsResponse& pcieDevicePaths,
@@ -58,18 +59,18 @@ static inline void handlePCIeDevicePath(
}
dbus::utility::getDbusObject(
- pcieDevicePath, {},
+ pcieDevicePath, pcieDeviceInterface,
[pcieDevicePath, asyncResp,
callback](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& object) {
- if (ec || object.empty())
- {
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- callback(pcieDevicePath, object.begin()->first);
- });
+ if (ec || object.empty())
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ callback(pcieDevicePath, object.begin()->first);
+ });
return;
}
@@ -77,7 +78,7 @@ static inline void handlePCIeDevicePath(
messages::resourceNotFound(asyncResp->res, "PCIeDevice", pcieDeviceId);
}
-static inline void getValidPCIeDevicePath(
+inline void getValidPCIeDevicePath(
const std::string& pcieDeviceId,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::function<void(const std::string& pcieDevicePath,
@@ -89,19 +90,19 @@ static inline void getValidPCIeDevicePath(
callback](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse&
pcieDevicePaths) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("D-Bus response error on GetSubTree {}", ec);
- messages::internalError(asyncResp->res);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("D-Bus response error on GetSubTree {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ handlePCIeDevicePath(pcieDeviceId, asyncResp, pcieDevicePaths,
+ callback);
return;
- }
- handlePCIeDevicePath(pcieDeviceId, asyncResp, pcieDevicePaths,
- callback);
- return;
- });
+ });
}
-static inline void handlePCIeDeviceCollectionGet(
+inline void handlePCIeDeviceCollectionGet(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName)
@@ -226,43 +227,42 @@ inline void getPCIeDeviceSlotPath(
[callback = std::move(callback), asyncResp, pcieDevicePath](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& endpoints) {
- if (ec)
- {
- if (ec.value() == EBADR)
+ if (ec)
{
- // Missing association is not an error
+ if (ec.value() == EBADR)
+ {
+ // Missing association is not an error
+ return;
+ }
+ BMCWEB_LOG_ERROR(
+ "DBUS response error for getAssociatedSubTreePaths {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_ERROR(
- "DBUS response error for getAssociatedSubTreePaths {}",
- ec.value());
- messages::internalError(asyncResp->res);
- return;
- }
- if (endpoints.size() > 1)
- {
- BMCWEB_LOG_ERROR(
- "PCIeDevice is associated with more than one PCIeSlot: {}",
- endpoints.size());
- messages::internalError(asyncResp->res);
- return;
- }
- if (endpoints.empty())
- {
- // If the device doesn't have an association, return without PCIe
- // Slot properties
- BMCWEB_LOG_DEBUG("PCIeDevice is not associated with PCIeSlot");
- return;
- }
- callback(endpoints[0]);
- });
+ if (endpoints.size() > 1)
+ {
+ BMCWEB_LOG_ERROR(
+ "PCIeDevice is associated with more than one PCIeSlot: {}",
+ endpoints.size());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (endpoints.empty())
+ {
+ // If the device doesn't have an association, return without
+ // PCIe Slot properties
+ BMCWEB_LOG_DEBUG("PCIeDevice is not associated with PCIeSlot");
+ return;
+ }
+ callback(endpoints[0]);
+ });
}
-inline void
- afterGetDbusObject(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& pcieDeviceSlot,
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetObject& object)
+inline void afterGetDbusObject(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDeviceSlot, const boost::system::error_code& ec,
+ const dbus::utility::MapperGetObject& object)
{
if (ec || object.empty())
{
@@ -277,8 +277,8 @@ inline void
[asyncResp](
const boost::system::error_code& ec2,
const dbus::utility::DBusPropertiesMap& pcieSlotProperties) {
- addPCIeSlotProperties(asyncResp->res, ec2, pcieSlotProperties);
- });
+ addPCIeSlotProperties(asyncResp->res, ec2, pcieSlotProperties);
+ });
}
inline void afterGetPCIeDeviceSlotPath(
@@ -290,67 +290,66 @@ inline void afterGetPCIeDeviceSlotPath(
[asyncResp,
pcieDeviceSlot](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& object) {
- afterGetDbusObject(asyncResp, pcieDeviceSlot, ec, object);
- });
+ afterGetDbusObject(asyncResp, pcieDeviceSlot, ec, object);
+ });
}
-inline void
- getPCIeDeviceHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& pcieDevicePath,
- const std::string& service)
+inline void getPCIeDeviceHealth(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDevicePath, const std::string& service)
{
sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, service, pcieDevicePath,
"xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
[asyncResp](const boost::system::error_code& ec, const bool value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Health {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Health {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!value)
- {
- asyncResp->res.jsonValue["Status"]["Health"] = "Critical";
- }
- });
+ if (!value)
+ {
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ resource::Health::Critical;
+ }
+ });
}
-inline void
- getPCIeDeviceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& pcieDevicePath,
- const std::string& service)
+inline void getPCIeDeviceState(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDevicePath, const std::string& service)
{
sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, service, pcieDevicePath,
"xyz.openbmc_project.Inventory.Item", "Present",
[asyncResp](const boost::system::error_code& ec, bool value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for State");
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for State");
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!value)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- }
- });
+ if (!value)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
+ }
+ });
}
-inline void
- getPCIeDeviceAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& pcieDevicePath,
- const std::string& service)
+inline void getPCIeDeviceAsset(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDevicePath, const std::string& service)
{
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, service, pcieDevicePath,
@@ -358,58 +357,59 @@ inline void
[pcieDevicePath, asyncResp{asyncResp}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& assetList) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- const std::string* manufacturer = nullptr;
- const std::string* model = nullptr;
- const std::string* partNumber = nullptr;
- const std::string* serialNumber = nullptr;
- const std::string* sparePartNumber = nullptr;
+ const std::string* manufacturer = nullptr;
+ const std::string* model = nullptr;
+ const std::string* partNumber = nullptr;
+ const std::string* serialNumber = nullptr;
+ const std::string* sparePartNumber = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
- manufacturer, "Model", model, "PartNumber", partNumber,
- "SerialNumber", serialNumber, "SparePartNumber", sparePartNumber);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
+ manufacturer, "Model", model, "PartNumber", partNumber,
+ "SerialNumber", serialNumber, "SparePartNumber",
+ sparePartNumber);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (manufacturer != nullptr)
- {
- asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
- }
- if (model != nullptr)
- {
- asyncResp->res.jsonValue["Model"] = *model;
- }
+ if (manufacturer != nullptr)
+ {
+ asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
+ }
+ if (model != nullptr)
+ {
+ asyncResp->res.jsonValue["Model"] = *model;
+ }
- if (partNumber != nullptr)
- {
- asyncResp->res.jsonValue["PartNumber"] = *partNumber;
- }
+ if (partNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["PartNumber"] = *partNumber;
+ }
- if (serialNumber != nullptr)
- {
- asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
- }
+ if (serialNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
+ }
- if (sparePartNumber != nullptr && !sparePartNumber->empty())
- {
- asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
- }
- });
+ if (sparePartNumber != nullptr && !sparePartNumber->empty())
+ {
+ asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
+ }
+ });
}
inline void addPCIeDeviceProperties(
@@ -520,17 +520,17 @@ inline void getPCIeDeviceProperties(
[asyncResp,
callback](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Properties");
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Properties");
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- callback(pcieDevProperties);
- });
+ callback(pcieDevProperties);
+ });
}
inline void addPCIeDeviceCommonProperties(
@@ -546,8 +546,8 @@ inline void addPCIeDeviceCommonProperties(
BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
asyncResp->res.jsonValue["Name"] = "PCIe Device";
asyncResp->res.jsonValue["Id"] = pcieDeviceId;
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
}
inline void afterGetValidPcieDevicePath(
@@ -567,11 +567,10 @@ inline void afterGetValidPcieDevicePath(
std::bind_front(afterGetPCIeDeviceSlotPath, asyncResp));
}
-inline void
- handlePCIeDeviceGet(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& pcieDeviceId)
+inline void handlePCIeDeviceGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& pcieDeviceId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -616,8 +615,8 @@ inline void addPCIeFunctionList(
{
// Check if this function exists by
// looking for a device ID
- std::string devIDProperty = "Function" + std::to_string(functionNum) +
- "DeviceId";
+ std::string devIDProperty =
+ "Function" + std::to_string(functionNum) + "DeviceId";
const std::string* property = nullptr;
for (const auto& propEntry : pcieDevProperties)
{
@@ -663,25 +662,25 @@ inline void handlePCIeFunctionCollectionGet(
pcieDeviceId, asyncResp,
[asyncResp, pcieDeviceId](const std::string& pcieDevicePath,
const std::string& service) {
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/PCIeFunctionCollection/PCIeFunctionCollection.json>; rel=describedby");
- asyncResp->res.jsonValue["@odata.type"] =
- "#PCIeFunctionCollection.PCIeFunctionCollection";
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
- asyncResp->res.jsonValue["Name"] = "PCIe Function Collection";
- asyncResp->res.jsonValue["Description"] =
- "Collection of PCIe Functions for PCIe Device " + pcieDeviceId;
- getPCIeDeviceProperties(
- asyncResp, pcieDevicePath, service,
- [asyncResp, pcieDeviceId](
- const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
- addPCIeFunctionList(asyncResp->res, pcieDeviceId,
- pcieDevProperties);
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/PCIeFunctionCollection/PCIeFunctionCollection.json>; rel=describedby");
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#PCIeFunctionCollection.PCIeFunctionCollection";
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
+ asyncResp->res.jsonValue["Name"] = "PCIe Function Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of PCIe Functions for PCIe Device " + pcieDeviceId;
+ getPCIeDeviceProperties(
+ asyncResp, pcieDevicePath, service,
+ [asyncResp, pcieDeviceId](
+ const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
+ addPCIeFunctionList(asyncResp->res, pcieDeviceId,
+ pcieDevProperties);
+ });
});
- });
}
inline void requestRoutesSystemPCIeFunctionCollection(App& app)
@@ -726,7 +725,6 @@ inline void addPCIeFunctionProperties(
std::get_if<std::string>(&property.second);
if (strProperty == nullptr)
{
- BMCWEB_LOG_ERROR("Function wasn't a string?");
continue;
}
if (property.first == functionName + "DeviceId")
@@ -793,12 +791,11 @@ inline void addPCIeFunctionCommonProperties(crow::Response& resp,
BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
}
-inline void
- handlePCIeFunctionGet(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& pcieDeviceId,
- const std::string& pcieFunctionIdStr)
+inline void handlePCIeFunctionGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& pcieDeviceId,
+ const std::string& pcieFunctionIdStr)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -829,20 +826,20 @@ inline void
return;
}
- getValidPCIeDevicePath(pcieDeviceId, asyncResp,
- [asyncResp, pcieDeviceId,
- pcieFunctionId](const std::string& pcieDevicePath,
- const std::string& service) {
- getPCIeDeviceProperties(
- asyncResp, pcieDevicePath, service,
- [asyncResp, pcieDeviceId, pcieFunctionId](
- const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
- addPCIeFunctionCommonProperties(asyncResp->res, pcieDeviceId,
- pcieFunctionId);
- addPCIeFunctionProperties(asyncResp->res, pcieFunctionId,
- pcieDevProperties);
+ getValidPCIeDevicePath(
+ pcieDeviceId, asyncResp,
+ [asyncResp, pcieDeviceId, pcieFunctionId](
+ const std::string& pcieDevicePath, const std::string& service) {
+ getPCIeDeviceProperties(
+ asyncResp, pcieDevicePath, service,
+ [asyncResp, pcieDeviceId, pcieFunctionId](
+ const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
+ addPCIeFunctionCommonProperties(
+ asyncResp->res, pcieDeviceId, pcieFunctionId);
+ addPCIeFunctionProperties(asyncResp->res, pcieFunctionId,
+ pcieDevProperties);
+ });
});
- });
}
inline void requestRoutesSystemPCIeFunction(App& app)
diff --git a/redfish-core/lib/pcie_slots.hpp b/redfish-core/lib/pcie_slots.hpp
index b8e6389275..a6796b9913 100644
--- a/redfish-core/lib/pcie_slots.hpp
+++ b/redfish-core/lib/pcie_slots.hpp
@@ -153,15 +153,14 @@ inline void onMapperAssociationDone(
"xyz.openbmc_project.Inventory.Item.PCIeSlot",
[asyncResp](const boost::system::error_code& ec2,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- onPcieSlotGetAllDone(asyncResp, ec2, propertiesList);
- });
+ onPcieSlotGetAllDone(asyncResp, ec2, propertiesList);
+ });
}
-inline void
- onMapperSubtreeDone(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisID,
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree)
+inline void onMapperSubtreeDone(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisID, const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreeResponse& subtree)
{
if (ec)
{
@@ -202,9 +201,9 @@ inline void
[asyncResp, chassisID, pcieSlotPath, connectionName](
const boost::system::error_code& ec2,
const dbus::utility::MapperEndPoints& endpoints) {
- onMapperAssociationDone(asyncResp, chassisID, pcieSlotPath,
- connectionName, ec2, endpoints);
- });
+ onMapperAssociationDone(asyncResp, chassisID, pcieSlotPath,
+ connectionName, ec2, endpoints);
+ });
}
}
}
@@ -226,8 +225,8 @@ inline void handlePCIeSlotCollectionGet(
[asyncResp,
chassisID](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- onMapperSubtreeDone(asyncResp, chassisID, ec, subtree);
- });
+ onMapperSubtreeDone(asyncResp, chassisID, ec, subtree);
+ });
}
inline void requestRoutesPCIeSlots(App& app)
diff --git a/redfish-core/lib/power.hpp b/redfish-core/lib/power.hpp
index cd7fa0f08a..d2843615e0 100644
--- a/redfish-core/lib/power.hpp
+++ b/redfish-core/lib/power.hpp
@@ -1,28 +1,30 @@
/*
-// Copyright (c) 2018 Intel Corporation
-// Copyright (c) 2018 Ampere Computing LLC
-/
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+Copyright (c) 2018 Ampere Computing LLC
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/power.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "sensors.hpp"
#include "utils/chassis_utils.hpp"
#include "utils/json_utils.hpp"
+#include "utils/sensor_utils.hpp"
#include <sdbusplus/asio/property.hpp>
@@ -125,9 +127,9 @@ inline void afterPowerCapSettingGet(
// A warning without a odata.type
nlohmann::json::object_t powerControl;
powerControl["@odata.type"] = "#Power.v1_0_0.PowerControl";
- powerControl["@odata.id"] = "/redfish/v1/Chassis/" +
- sensorAsyncResp->chassisId +
- "/Power#/PowerControl/0";
+ powerControl["@odata.id"] =
+ "/redfish/v1/Chassis/" + sensorAsyncResp->chassisId +
+ "/Power#/PowerControl/0";
powerControl["Name"] = "Chassis Power Control";
powerControl["MemberId"] = "0";
tempArray.emplace_back(std::move(powerControl));
@@ -181,24 +183,24 @@ inline void afterPowerCapSettingGet(
}
// LimitException is Mandatory attribute as per OCP
- // Baseline Profile – v1.0.0, so currently making it
+ // Baseline Profile - v1.0.0, so currently making it
// "NoAction" as default value to make it OCP Compliant.
- sensorJson["PowerLimit"]["LimitException"] = "NoAction";
+ sensorJson["PowerLimit"]["LimitException"] =
+ power::PowerLimitException::NoAction;
if (enabled)
{
// Redfish specification indicates PowerLimit should
// be null if the limit is not enabled.
- sensorJson["PowerLimit"]["LimitInWatts"] = powerCap *
- std::pow(10, scale);
+ sensorJson["PowerLimit"]["LimitInWatts"] =
+ powerCap * std::pow(10, scale);
}
}
using Mapper = dbus::utility::MapperGetSubTreePathsResponse;
-inline void
- afterGetChassis(const std::shared_ptr<SensorsAsyncResp>& sensorAsyncResp,
- const boost::system::error_code& ec2,
- const Mapper& chassisPaths)
+inline void afterGetChassis(
+ const std::shared_ptr<SensorsAsyncResp>& sensorAsyncResp,
+ const boost::system::error_code& ec2, const Mapper& chassisPaths)
{
if (ec2)
{
@@ -267,7 +269,8 @@ inline void
auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisName, sensors::dbus::powerPaths,
- sensors::node::power);
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::powerNode));
getChassisData(sensorAsyncResp);
@@ -296,7 +299,8 @@ inline void
}
auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisName, sensors::dbus::powerPaths,
- sensors::node::power);
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::powerNode));
std::optional<std::vector<nlohmann::json::object_t>> voltageCollections;
std::optional<std::vector<nlohmann::json::object_t>> powerCtlCollections;
diff --git a/redfish-core/lib/power_subsystem.hpp b/redfish-core/lib/power_subsystem.hpp
index d54fd18389..ff7d52cd22 100644
--- a/redfish-core/lib/power_subsystem.hpp
+++ b/redfish-core/lib/power_subsystem.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "app.hpp"
+#include "generated/enums/resource.hpp"
#include "logging.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
@@ -35,8 +36,8 @@ inline void doPowerSubsystemCollection(
asyncResp->res.jsonValue["Id"] = "PowerSubsystem";
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/Chassis/{}/PowerSubsystem", chassisId);
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
asyncResp->res.jsonValue["PowerSupplies"]["@odata.id"] =
boost::urls::format(
"/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies", chassisId);
diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp
index f59ed57d5f..26ea26c93c 100644
--- a/redfish-core/lib/power_supply.hpp
+++ b/redfish-core/lib/power_supply.hpp
@@ -2,6 +2,7 @@
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/chassis_utils.hpp"
@@ -46,17 +47,20 @@ inline void updatePowerSupplyList(
asyncResp->res.jsonValue["Members@odata.count"] = powerSupplyList.size();
}
-inline void
- doPowerSupplyCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId,
- const std::optional<std::string>& validChassisPath)
+inline void doPowerSupplyCollection(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths)
{
- if (!validChassisPath)
+ if (ec)
{
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
+ messages::internalError(asyncResp->res);
+ }
return;
}
-
asyncResp->res.addHeader(
boost::beast::http::field::link,
"</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
@@ -70,26 +74,7 @@ inline void
asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
asyncResp->res.jsonValue["Members@odata.count"] = 0;
- std::string powerPath = *validChassisPath + "/powered_by";
- dbus::utility::getAssociatedSubTreePaths(
- powerPath,
- sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
- powerSupplyInterface,
- [asyncResp, chassisId](
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
- if (ec)
- {
- if (ec.value() != EBADR)
- {
- BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
- messages::internalError(asyncResp->res);
- }
- return;
- }
-
- updatePowerSupplyList(asyncResp, chassisId, subtreePaths);
- });
+ updatePowerSupplyList(asyncResp, chassisId, subtreePaths);
}
inline void handlePowerSupplyCollectionHead(
@@ -106,15 +91,16 @@ inline void handlePowerSupplyCollectionHead(
asyncResp, chassisId,
[asyncResp,
chassisId](const std::optional<std::string>& validChassisPath) {
- if (!validChassisPath)
- {
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
- return;
- }
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
- });
+ if (!validChassisPath)
+ {
+ messages::resourceNotFound(asyncResp->res, "Chassis",
+ chassisId);
+ return;
+ }
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
+ });
}
inline void handlePowerSupplyCollectionGet(
@@ -127,9 +113,19 @@ inline void handlePowerSupplyCollectionGet(
return;
}
- redfish::chassis_utils::getValidChassisPath(
- asyncResp, chassisId,
- std::bind_front(doPowerSupplyCollection, asyncResp, chassisId));
+ constexpr std::array<std::string_view, 2> chasisInterfaces = {
+ "xyz.openbmc_project.Inventory.Item.Board",
+ "xyz.openbmc_project.Inventory.Item.Chassis"};
+ const std::string reqpath = "/xyz/openbmc_project/inventory";
+
+ dbus::utility::getAssociatedSubTreePathsById(
+ chassisId, reqpath, chasisInterfaces, "powered_by",
+ powerSupplyInterface,
+ [asyncResp, chassisId](
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
+ doPowerSupplyCollection(asyncResp, chassisId, ec, subtreePaths);
+ });
}
inline void requestRoutesPowerSupplyCollection(App& app)
@@ -145,60 +141,56 @@ inline void requestRoutesPowerSupplyCollection(App& app)
std::bind_front(handlePowerSupplyCollectionGet, std::ref(app)));
}
-inline bool checkPowerSupplyId(const std::string& powerSupplyPath,
- const std::string& powerSupplyId)
+inline void afterGetValidPowerSupplyPath(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& powerSupplyId, const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreeResponse& subtree,
+ const std::function<void(const std::string& powerSupplyPath,
+ const std::string& service)>& callback)
{
- std::string powerSupplyName =
- sdbusplus::message::object_path(powerSupplyPath).filename();
+ if (ec)
+ {
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
+ }
+ for (const auto& [objectPath, service] : subtree)
+ {
+ sdbusplus::message::object_path path(objectPath);
+ if (path == powerSupplyId)
+ {
+ callback(path, service.begin()->first);
+ return;
+ }
+ }
- return !(powerSupplyName.empty() || powerSupplyName != powerSupplyId);
+ BMCWEB_LOG_WARNING("Power supply not found: {}", powerSupplyId);
+ messages::resourceNotFound(asyncResp->res, "PowerSupplies", powerSupplyId);
}
inline void getValidPowerSupplyPath(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& validChassisPath, const std::string& powerSupplyId,
- std::function<void(const std::string& powerSupplyPath)>&& callback)
+ const std::string& chassisId, const std::string& powerSupplyId,
+ std::function<void(const std::string& powerSupplyPath,
+ const std::string& service)>&& callback)
{
- std::string powerPath = validChassisPath + "/powered_by";
- dbus::utility::getAssociatedSubTreePaths(
- powerPath,
- sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
+ constexpr std::array<std::string_view, 2> chasisInterfaces = {
+ "xyz.openbmc_project.Inventory.Item.Board",
+ "xyz.openbmc_project.Inventory.Item.Chassis"};
+ const std::string reqpath = "/xyz/openbmc_project/inventory";
+
+ dbus::utility::getAssociatedSubTreeById(
+ chassisId, reqpath, chasisInterfaces, "powered_by",
powerSupplyInterface,
- [asyncResp, powerSupplyId, callback{std::move(callback)}](
+ [asyncResp, chassisId, powerSupplyId, callback{std::move(callback)}](
const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
- if (ec)
- {
- if (ec.value() != EBADR)
- {
- BMCWEB_LOG_ERROR(
- "DBUS response error for getAssociatedSubTreePaths{}",
- ec.value());
- messages::internalError(asyncResp->res);
- return;
- }
- messages::resourceNotFound(asyncResp->res, "PowerSupplies",
- powerSupplyId);
- return;
- }
-
- for (const std::string& path : subtreePaths)
- {
- if (checkPowerSupplyId(path, powerSupplyId))
- {
- callback(path);
- return;
- }
- }
-
- if (!subtreePaths.empty())
- {
- BMCWEB_LOG_WARNING("Power supply not found: {}", powerSupplyId);
- messages::resourceNotFound(asyncResp->res, "PowerSupplies",
- powerSupplyId);
- return;
- }
- });
+ const dbus::utility::MapperGetSubTreeResponse& subtree) {
+ afterGetValidPowerSupplyPath(asyncResp, powerSupplyId, ec, subtree,
+ callback);
+ });
}
inline void
@@ -209,22 +201,23 @@ inline void
*crow::connections::systemBus, service, path,
"xyz.openbmc_project.Inventory.Item", "Present",
[asyncResp](const boost::system::error_code& ec, const bool value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for State {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for State {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!value)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- }
- });
+ if (!value)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
+ }
+ });
}
inline void
@@ -235,22 +228,23 @@ inline void
*crow::connections::systemBus, service, path,
"xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
[asyncResp](const boost::system::error_code& ec, const bool value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Health {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Health {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (!value)
- {
- asyncResp->res.jsonValue["Status"]["Health"] = "Critical";
- }
- });
+ if (!value)
+ {
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ resource::Health::Critical;
+ }
+ });
}
inline void
@@ -262,60 +256,61 @@ inline void
"xyz.openbmc_project.Inventory.Decorator.Asset",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Asset {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Asset {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- const std::string* partNumber = nullptr;
- const std::string* serialNumber = nullptr;
- const std::string* manufacturer = nullptr;
- const std::string* model = nullptr;
- const std::string* sparePartNumber = nullptr;
+ const std::string* partNumber = nullptr;
+ const std::string* serialNumber = nullptr;
+ const std::string* manufacturer = nullptr;
+ const std::string* model = nullptr;
+ const std::string* sparePartNumber = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
- partNumber, "SerialNumber", serialNumber, "Manufacturer",
- manufacturer, "Model", model, "SparePartNumber", sparePartNumber);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
+ partNumber, "SerialNumber", serialNumber, "Manufacturer",
+ manufacturer, "Model", model, "SparePartNumber",
+ sparePartNumber);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (partNumber != nullptr)
- {
- asyncResp->res.jsonValue["PartNumber"] = *partNumber;
- }
+ if (partNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["PartNumber"] = *partNumber;
+ }
- if (serialNumber != nullptr)
- {
- asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
- }
+ if (serialNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
+ }
- if (manufacturer != nullptr)
- {
- asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
- }
+ if (manufacturer != nullptr)
+ {
+ asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
+ }
- if (model != nullptr)
- {
- asyncResp->res.jsonValue["Model"] = *model;
- }
+ if (model != nullptr)
+ {
+ asyncResp->res.jsonValue["Model"] = *model;
+ }
- // SparePartNumber is optional on D-Bus so skip if it is empty
- if (sparePartNumber != nullptr && !sparePartNumber->empty())
- {
- asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
- }
- });
+ // SparePartNumber is optional on D-Bus so skip if it is empty
+ if (sparePartNumber != nullptr && !sparePartNumber->empty())
+ {
+ asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
+ }
+ });
}
inline void getPowerSupplyFirmwareVersion(
@@ -327,18 +322,19 @@ inline void getPowerSupplyFirmwareVersion(
"xyz.openbmc_project.Software.Version", "Version",
[asyncResp](const boost::system::error_code& ec,
const std::string& value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for FirmwareVersion {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBUS response error for FirmwareVersion {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- asyncResp->res.jsonValue["FirmwareVersion"] = value;
- });
+ asyncResp->res.jsonValue["FirmwareVersion"] = value;
+ });
}
inline void
@@ -350,19 +346,19 @@ inline void
"xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
[asyncResp](const boost::system::error_code& ec,
const std::string& value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error for Location {}",
- ec.value());
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error for Location {}",
+ ec.value());
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
- value;
- });
+ asyncResp->res
+ .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = value;
+ });
}
inline void handleGetEfficiencyResponse(
@@ -430,8 +426,8 @@ inline void handlePowerSupplyAttributesSubTreeResponse(
*crow::connections::systemBus, service, path,
"xyz.openbmc_project.Control.PowerSupplyAttributes", "DeratingFactor",
[asyncResp](const boost::system::error_code& ec1, uint32_t value) {
- handleGetEfficiencyResponse(asyncResp, ec1, value);
- });
+ handleGetEfficiencyResponse(asyncResp, ec1, value);
+ });
}
inline void
@@ -444,111 +440,67 @@ inline void
"/xyz/openbmc_project", 0, efficiencyIntf,
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- handlePowerSupplyAttributesSubTreeResponse(asyncResp, ec, subtree);
- });
+ handlePowerSupplyAttributesSubTreeResponse(asyncResp, ec, subtree);
+ });
}
-inline void
- doPowerSupplyGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId,
- const std::string& powerSupplyId,
- const std::optional<std::string>& validChassisPath)
+inline void doPowerSupplyGet(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const std::string& powerSupplyId,
+ const std::string& powerSupplyPath, const std::string& service)
{
- if (!validChassisPath)
- {
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
- return;
- }
-
- // Get the correct Path and Service that match the input parameters
- getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
- [asyncResp, chassisId, powerSupplyId](
- const std::string& powerSupplyPath) {
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
- asyncResp->res.jsonValue["@odata.type"] =
- "#PowerSupply.v1_5_0.PowerSupply";
- asyncResp->res.jsonValue["Name"] = "Power Supply";
- asyncResp->res.jsonValue["Id"] = powerSupplyId;
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
- powerSupplyId);
-
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
-
- dbus::utility::getDbusObject(
- powerSupplyPath, powerSupplyInterface,
- [asyncResp,
- powerSupplyPath](const boost::system::error_code& ec,
- const dbus::utility::MapperGetObject& object) {
- if (ec || object.empty())
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- getPowerSupplyState(asyncResp, object.begin()->first,
- powerSupplyPath);
- getPowerSupplyHealth(asyncResp, object.begin()->first,
- powerSupplyPath);
- getPowerSupplyAsset(asyncResp, object.begin()->first,
- powerSupplyPath);
- getPowerSupplyFirmwareVersion(asyncResp, object.begin()->first,
- powerSupplyPath);
- getPowerSupplyLocation(asyncResp, object.begin()->first,
- powerSupplyPath);
- });
-
- getEfficiencyPercent(asyncResp);
- });
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
+ asyncResp->res.jsonValue["@odata.type"] = "#PowerSupply.v1_5_0.PowerSupply";
+ asyncResp->res.jsonValue["Name"] = "Power Supply";
+ asyncResp->res.jsonValue["Id"] = powerSupplyId;
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
+ powerSupplyId);
+
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
+
+ getPowerSupplyState(asyncResp, service, powerSupplyPath);
+ getPowerSupplyHealth(asyncResp, service, powerSupplyPath);
+ getPowerSupplyAsset(asyncResp, service, powerSupplyPath);
+ getPowerSupplyFirmwareVersion(asyncResp, service, powerSupplyPath);
+ getPowerSupplyLocation(asyncResp, service, powerSupplyPath);
+ getEfficiencyPercent(asyncResp);
}
-inline void
- handlePowerSupplyHead(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId,
- const std::string& powerSupplyId)
+inline void handlePowerSupplyHead(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const std::string& powerSupplyId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
- redfish::chassis_utils::getValidChassisPath(
- asyncResp, chassisId,
- [asyncResp, chassisId,
- powerSupplyId](const std::optional<std::string>& validChassisPath) {
- if (!validChassisPath)
- {
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
- return;
- }
-
- // Get the correct Path and Service that match the input parameters
- getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
- [asyncResp](const std::string&) {
+ // Get the correct Path and Service that match the input parameters
+ getValidPowerSupplyPath(
+ asyncResp, chassisId, powerSupplyId,
+ [asyncResp](const std::string&, const std::string&) {
asyncResp->res.addHeader(
boost::beast::http::field::link,
"</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
});
- });
}
-inline void
- handlePowerSupplyGet(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId,
- const std::string& powerSupplyId)
+inline void handlePowerSupplyGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const std::string& powerSupplyId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
-
- redfish::chassis_utils::getValidChassisPath(
- asyncResp, chassisId,
+ getValidPowerSupplyPath(
+ asyncResp, chassisId, powerSupplyId,
std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId));
}
diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp
index 8015369dbf..82781d3bd9 100644
--- a/redfish-core/lib/processor.hpp
+++ b/redfish-core/lib/processor.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -20,6 +20,7 @@
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "generated/enums/processor.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
@@ -66,14 +67,14 @@ inline void getProcessorUUID(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
"xyz.openbmc_project.Common.UUID", "UUID",
[objPath, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec, const std::string& property) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["UUID"] = property;
- });
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["UUID"] = property;
+ });
}
inline void getCpuDataByInterface(
@@ -83,8 +84,8 @@ inline void getCpuDataByInterface(
BMCWEB_LOG_DEBUG("Get CPU resources by interface.");
// Set the default value of state
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
for (const auto& interface : cpuInterfacesProperties)
{
@@ -102,7 +103,8 @@ inline void getCpuDataByInterface(
if (!*cpuPresent)
{
// Slot is not populated
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
}
}
else if (property.first == "Functional")
@@ -115,7 +117,8 @@ inline void getCpuDataByInterface(
}
if (!*cpuFunctional)
{
- asyncResp->res.jsonValue["Status"]["Health"] = "Critical";
+ asyncResp->res.jsonValue["Status"]["Health"] =
+ resource::Health::Critical;
}
}
else if (property.first == "CoreCount")
@@ -219,10 +222,9 @@ inline void getCpuDataByInterface(
}
}
-inline void getCpuDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
- const std::string& cpuId,
- const std::string& service,
- const std::string& objPath)
+inline void getCpuDataByService(
+ std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& cpuId,
+ const std::string& service, const std::string& objPath)
{
BMCWEB_LOG_DEBUG("Get available system cpu resources by service.");
@@ -232,43 +234,46 @@ inline void getCpuDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[cpuId, service, objPath, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& dbusData) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["Id"] = cpuId;
- asyncResp->res.jsonValue["Name"] = "Processor";
- asyncResp->res.jsonValue["ProcessorType"] = "CPU";
-
- bool slotPresent = false;
- std::string corePath = objPath + "/core";
- size_t totalCores = 0;
- for (const auto& object : dbusData)
- {
- if (object.first.str == objPath)
+ if (ec)
{
- getCpuDataByInterface(asyncResp, object.second);
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
+ return;
}
- else if (object.first.str.starts_with(corePath))
+ asyncResp->res.jsonValue["Id"] = cpuId;
+ asyncResp->res.jsonValue["Name"] = "Processor";
+ asyncResp->res.jsonValue["ProcessorType"] =
+ processor::ProcessorType::CPU;
+
+ bool slotPresent = false;
+ std::string corePath = objPath + "/core";
+ size_t totalCores = 0;
+ for (const auto& object : dbusData)
{
- for (const auto& interface : object.second)
+ if (object.first.str == objPath)
{
- if (interface.first == "xyz.openbmc_project.Inventory.Item")
+ getCpuDataByInterface(asyncResp, object.second);
+ }
+ else if (object.first.str.starts_with(corePath))
+ {
+ for (const auto& interface : object.second)
{
- for (const auto& property : interface.second)
+ if (interface.first ==
+ "xyz.openbmc_project.Inventory.Item")
{
- if (property.first == "Present")
+ for (const auto& property : interface.second)
{
- const bool* present =
- std::get_if<bool>(&property.second);
- if (present != nullptr)
+ if (property.first == "Present")
{
- if (*present)
+ const bool* present =
+ std::get_if<bool>(&property.second);
+ if (present != nullptr)
{
- slotPresent = true;
- totalCores++;
+ if (*present)
+ {
+ slotPresent = true;
+ totalCores++;
+ }
}
}
}
@@ -276,16 +281,15 @@ inline void getCpuDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
}
}
}
- }
- // In getCpuDataByInterface(), state and health are set
- // based on the present and functional status. If core
- // count is zero, then it has a higher precedence.
- if (slotPresent)
- {
- asyncResp->res.jsonValue["TotalCores"] = totalCores;
- }
- return;
- });
+ // In getCpuDataByInterface(), state and health are set
+ // based on the present and functional status. If core
+ // count is zero, then it has a higher precedence.
+ if (slotPresent)
+ {
+ asyncResp->res.jsonValue["TotalCores"] = totalCores;
+ }
+ return;
+ });
}
/**
@@ -366,10 +370,9 @@ inline void
asyncResp->res.jsonValue["ThrottleCauses"] = std::move(rCauses);
}
-inline void
- getThrottleProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& service,
- const std::string& objectPath)
+inline void getThrottleProperties(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& service, const std::string& objectPath)
{
BMCWEB_LOG_DEBUG("Get processor throttle resources");
@@ -378,8 +381,8 @@ inline void
"xyz.openbmc_project.Control.Power.Throttle",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- readThrottleProperties(asyncResp, ec, properties);
- });
+ readThrottleProperties(asyncResp, ec, properties);
+ });
}
inline void getCpuAssetData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
@@ -393,67 +396,67 @@ inline void getCpuAssetData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[objPath, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
- return;
- }
-
- const std::string* serialNumber = nullptr;
- const std::string* model = nullptr;
- const std::string* manufacturer = nullptr;
- const std::string* partNumber = nullptr;
- const std::string* sparePartNumber = nullptr;
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "SerialNumber",
- serialNumber, "Model", model, "Manufacturer", manufacturer,
- "PartNumber", partNumber, "SparePartNumber", sparePartNumber);
+ const std::string* serialNumber = nullptr;
+ const std::string* model = nullptr;
+ const std::string* manufacturer = nullptr;
+ const std::string* partNumber = nullptr;
+ const std::string* sparePartNumber = nullptr;
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties, "SerialNumber",
+ serialNumber, "Model", model, "Manufacturer", manufacturer,
+ "PartNumber", partNumber, "SparePartNumber", sparePartNumber);
- if (serialNumber != nullptr && !serialNumber->empty())
- {
- asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
- }
-
- if ((model != nullptr) && !model->empty())
- {
- asyncResp->res.jsonValue["Model"] = *model;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (manufacturer != nullptr)
- {
- asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
+ if (serialNumber != nullptr && !serialNumber->empty())
+ {
+ asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
+ }
- // Otherwise would be unexpected.
- if (manufacturer->find("Intel") != std::string::npos)
+ if ((model != nullptr) && !model->empty())
{
- asyncResp->res.jsonValue["ProcessorArchitecture"] = "x86";
- asyncResp->res.jsonValue["InstructionSet"] = "x86-64";
+ asyncResp->res.jsonValue["Model"] = *model;
}
- else if (manufacturer->find("IBM") != std::string::npos)
+
+ if (manufacturer != nullptr)
{
- asyncResp->res.jsonValue["ProcessorArchitecture"] = "Power";
- asyncResp->res.jsonValue["InstructionSet"] = "PowerISA";
+ asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
+
+ // Otherwise would be unexpected.
+ if (manufacturer->find("Intel") != std::string::npos)
+ {
+ asyncResp->res.jsonValue["ProcessorArchitecture"] = "x86";
+ asyncResp->res.jsonValue["InstructionSet"] = "x86-64";
+ }
+ else if (manufacturer->find("IBM") != std::string::npos)
+ {
+ asyncResp->res.jsonValue["ProcessorArchitecture"] = "Power";
+ asyncResp->res.jsonValue["InstructionSet"] = "PowerISA";
+ }
}
- }
- if (partNumber != nullptr)
- {
- asyncResp->res.jsonValue["PartNumber"] = *partNumber;
- }
+ if (partNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["PartNumber"] = *partNumber;
+ }
- if (sparePartNumber != nullptr && !sparePartNumber->empty())
- {
- asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
- }
- });
+ if (sparePartNumber != nullptr && !sparePartNumber->empty())
+ {
+ asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
+ }
+ });
}
inline void getCpuRevisionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
@@ -467,29 +470,30 @@ inline void getCpuRevisionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[objPath, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const std::string* version = nullptr;
+ const std::string* version = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "Version", version);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties, "Version",
+ version);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (version != nullptr)
- {
- asyncResp->res.jsonValue["Version"] = *version;
- }
- });
+ if (version != nullptr)
+ {
+ asyncResp->res.jsonValue["Version"] = *version;
+ }
+ });
}
inline void getAcceleratorDataByService(
@@ -502,48 +506,49 @@ inline void getAcceleratorDataByService(
[acclrtrId, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const bool* functional = nullptr;
- const bool* present = nullptr;
+ const bool* functional = nullptr;
+ const bool* present = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "Functional",
- functional, "Present", present);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties, "Functional",
+ functional, "Present", present);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- std::string state = "Enabled";
- std::string health = "OK";
+ std::string state = "Enabled";
+ std::string health = "OK";
- if (present != nullptr && !*present)
- {
- state = "Absent";
- }
+ if (present != nullptr && !*present)
+ {
+ state = "Absent";
+ }
- if (functional != nullptr && !*functional)
- {
- if (state == "Enabled")
+ if (functional != nullptr && !*functional)
{
- health = "Critical";
+ if (state == "Enabled")
+ {
+ health = "Critical";
+ }
}
- }
- asyncResp->res.jsonValue["Id"] = acclrtrId;
- asyncResp->res.jsonValue["Name"] = "Processor";
- asyncResp->res.jsonValue["Status"]["State"] = state;
- asyncResp->res.jsonValue["Status"]["Health"] = health;
- asyncResp->res.jsonValue["ProcessorType"] = "Accelerator";
- });
+ asyncResp->res.jsonValue["Id"] = acclrtrId;
+ asyncResp->res.jsonValue["Name"] = "Processor";
+ asyncResp->res.jsonValue["Status"]["State"] = state;
+ asyncResp->res.jsonValue["Status"]["Health"] = health;
+ asyncResp->res.jsonValue["ProcessorType"] =
+ processor::ProcessorType::Accelerator;
+ });
}
// OperatingConfig D-Bus Types
@@ -616,85 +621,87 @@ inline void
[asyncResp, cpuId,
service](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
-
- nlohmann::json& json = asyncResp->res.jsonValue;
+ if (ec)
+ {
+ BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const sdbusplus::message::object_path* appliedConfig = nullptr;
- const bool* baseSpeedPriorityEnabled = nullptr;
+ nlohmann::json& json = asyncResp->res.jsonValue;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "AppliedConfig",
- appliedConfig, "BaseSpeedPriorityEnabled",
- baseSpeedPriorityEnabled);
+ const sdbusplus::message::object_path* appliedConfig = nullptr;
+ const bool* baseSpeedPriorityEnabled = nullptr;
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties, "AppliedConfig",
+ appliedConfig, "BaseSpeedPriorityEnabled",
+ baseSpeedPriorityEnabled);
- if (appliedConfig != nullptr)
- {
- const std::string& dbusPath = appliedConfig->str;
- nlohmann::json::object_t operatingConfig;
- operatingConfig["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId);
- json["OperatingConfigs"] = std::move(operatingConfig);
-
- // Reuse the D-Bus config object name for the Redfish
- // URI
- size_t baseNamePos = dbusPath.rfind('/');
- if (baseNamePos == std::string::npos ||
- baseNamePos == (dbusPath.size() - 1))
- {
- // If the AppliedConfig was somehow not a valid path,
- // skip adding any more properties, since everything
- // else is tied to this applied config.
+ if (!success)
+ {
messages::internalError(asyncResp->res);
return;
}
- nlohmann::json::object_t appliedOperatingConfig;
- appliedOperatingConfig["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId,
- dbusPath.substr(baseNamePos + 1));
- json["AppliedOperatingConfig"] = std::move(appliedOperatingConfig);
-
- // Once we found the current applied config, queue another
- // request to read the base freq core ids out of that
- // config.
- sdbusplus::asio::getProperty<BaseSpeedPrioritySettingsProperty>(
- *crow::connections::systemBus, service, dbusPath,
- "xyz.openbmc_project.Inventory.Item.Cpu."
- "OperatingConfig",
- "BaseSpeedPrioritySettings",
- [asyncResp](
- const boost::system::error_code& ec2,
- const BaseSpeedPrioritySettingsProperty& baseSpeedList) {
- if (ec2)
+
+ if (appliedConfig != nullptr)
+ {
+ const std::string& dbusPath = appliedConfig->str;
+ nlohmann::json::object_t operatingConfig;
+ operatingConfig["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId);
+ json["OperatingConfigs"] = std::move(operatingConfig);
+
+ // Reuse the D-Bus config object name for the Redfish
+ // URI
+ size_t baseNamePos = dbusPath.rfind('/');
+ if (baseNamePos == std::string::npos ||
+ baseNamePos == (dbusPath.size() - 1))
{
- BMCWEB_LOG_WARNING("D-Bus Property Get error: {}", ec2);
+ // If the AppliedConfig was somehow not a valid path,
+ // skip adding any more properties, since everything
+ // else is tied to this applied config.
messages::internalError(asyncResp->res);
return;
}
+ nlohmann::json::object_t appliedOperatingConfig;
+ appliedOperatingConfig["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId,
+ dbusPath.substr(baseNamePos + 1));
+ json["AppliedOperatingConfig"] =
+ std::move(appliedOperatingConfig);
+
+ // Once we found the current applied config, queue another
+ // request to read the base freq core ids out of that
+ // config.
+ sdbusplus::asio::getProperty<BaseSpeedPrioritySettingsProperty>(
+ *crow::connections::systemBus, service, dbusPath,
+ "xyz.openbmc_project.Inventory.Item.Cpu."
+ "OperatingConfig",
+ "BaseSpeedPrioritySettings",
+ [asyncResp](const boost::system::error_code& ec2,
+ const BaseSpeedPrioritySettingsProperty&
+ baseSpeedList) {
+ if (ec2)
+ {
+ BMCWEB_LOG_WARNING("D-Bus Property Get error: {}",
+ ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- highSpeedCoreIdsHandler(asyncResp, baseSpeedList);
- });
- }
+ highSpeedCoreIdsHandler(asyncResp, baseSpeedList);
+ });
+ }
- if (baseSpeedPriorityEnabled != nullptr)
- {
- json["BaseSpeedPriorityState"] =
- *baseSpeedPriorityEnabled ? "Enabled" : "Disabled";
- }
- });
+ if (baseSpeedPriorityEnabled != nullptr)
+ {
+ json["BaseSpeedPriorityState"] =
+ *baseSpeedPriorityEnabled ? "Enabled" : "Disabled";
+ }
+ });
}
/**
@@ -715,16 +722,17 @@ inline void getCpuLocationCode(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
"xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
[objPath, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec, const std::string& property) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
- property;
- });
+ asyncResp->res
+ .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+ property;
+ });
}
/**
@@ -746,15 +754,15 @@ inline void getCpuUniqueId(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
"UniqueIdentifier",
[asyncResp](const boost::system::error_code& ec,
const std::string& id) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Failed to read cpu unique id: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res
- .jsonValue["ProcessorId"]["ProtectedIdentificationNumber"] = id;
- });
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Failed to read cpu unique id: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res
+ .jsonValue["ProcessorId"]["ProtectedIdentificationNumber"] = id;
+ });
}
/**
@@ -790,57 +798,56 @@ inline void getProcessorObject(const std::shared_ptr<bmcweb::AsyncResp>& resp,
[resp, processorId, handler = std::forward<Handler>(handler)](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error: {}", ec);
- messages::internalError(resp->res);
- return;
- }
- for (const auto& [objectPath, serviceMap] : subtree)
- {
- // Ignore any objects which don't end with our desired cpu name
- if (!objectPath.ends_with(processorId))
+ if (ec)
{
- continue;
+ BMCWEB_LOG_DEBUG("DBUS response error: {}", ec);
+ messages::internalError(resp->res);
+ return;
}
-
- bool found = false;
- // Filter out objects that don't have the CPU-specific
- // interfaces to make sure we can return 404 on non-CPUs
- // (e.g. /redfish/../Processors/dimm0)
- for (const auto& [serviceName, interfaceList] : serviceMap)
+ for (const auto& [objectPath, serviceMap] : subtree)
{
- if (std::ranges::find_first_of(interfaceList,
- processorInterfaces) !=
- std::end(interfaceList))
+ // Ignore any objects which don't end with our desired cpu name
+ if (!objectPath.ends_with(processorId))
{
- found = true;
- break;
+ continue;
}
- }
- if (!found)
- {
- continue;
- }
+ bool found = false;
+ // Filter out objects that don't have the CPU-specific
+ // interfaces to make sure we can return 404 on non-CPUs
+ // (e.g. /redfish/../Processors/dimm0)
+ for (const auto& [serviceName, interfaceList] : serviceMap)
+ {
+ if (std::ranges::find_first_of(interfaceList,
+ processorInterfaces) !=
+ std::end(interfaceList))
+ {
+ found = true;
+ break;
+ }
+ }
- // Process the first object which does match our cpu name and
- // required interfaces, and potentially ignore any other
- // matching objects. Assume all interfaces we want to process
- // must be on the same object path.
+ if (!found)
+ {
+ continue;
+ }
- handler(objectPath, serviceMap);
- return;
- }
- messages::resourceNotFound(resp->res, "Processor", processorId);
- });
+ // Process the first object which does match our cpu name and
+ // required interfaces, and potentially ignore any other
+ // matching objects. Assume all interfaces we want to process
+ // must be on the same object path.
+
+ handler(objectPath, serviceMap);
+ return;
+ }
+ messages::resourceNotFound(resp->res, "Processor", processorId);
+ });
}
-inline void
- getProcessorData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& processorId,
- const std::string& objectPath,
- const dbus::utility::MapperServiceMap& serviceMap)
+inline void getProcessorData(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& processorId, const std::string& objectPath,
+ const dbus::utility::MapperServiceMap& serviceMap)
{
for (const auto& [serviceName, interfaceList] : serviceMap)
{
@@ -903,100 +910,101 @@ inline void
* @param[in] service D-Bus service name to query.
* @param[in] objPath D-Bus object to query.
*/
-inline void
- getOperatingConfigData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& service,
- const std::string& objPath)
+inline void getOperatingConfigData(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& service, const std::string& objPath)
{
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, service, objPath,
"xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const size_t* availableCoreCount = nullptr;
- const uint32_t* baseSpeed = nullptr;
- const uint32_t* maxJunctionTemperature = nullptr;
- const uint32_t* maxSpeed = nullptr;
- const uint32_t* powerLimit = nullptr;
- const TurboProfileProperty* turboProfile = nullptr;
- const BaseSpeedPrioritySettingsProperty* baseSpeedPrioritySettings =
- nullptr;
-
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "AvailableCoreCount",
- availableCoreCount, "BaseSpeed", baseSpeed,
- "MaxJunctionTemperature", maxJunctionTemperature, "MaxSpeed",
- maxSpeed, "PowerLimit", powerLimit, "TurboProfile", turboProfile,
- "BaseSpeedPrioritySettings", baseSpeedPrioritySettings);
-
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ const size_t* availableCoreCount = nullptr;
+ const uint32_t* baseSpeed = nullptr;
+ const uint32_t* maxJunctionTemperature = nullptr;
+ const uint32_t* maxSpeed = nullptr;
+ const uint32_t* powerLimit = nullptr;
+ const TurboProfileProperty* turboProfile = nullptr;
+ const BaseSpeedPrioritySettingsProperty* baseSpeedPrioritySettings =
+ nullptr;
+
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties,
+ "AvailableCoreCount", availableCoreCount, "BaseSpeed",
+ baseSpeed, "MaxJunctionTemperature", maxJunctionTemperature,
+ "MaxSpeed", maxSpeed, "PowerLimit", powerLimit, "TurboProfile",
+ turboProfile, "BaseSpeedPrioritySettings",
+ baseSpeedPrioritySettings);
+
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- nlohmann::json& json = asyncResp->res.jsonValue;
+ nlohmann::json& json = asyncResp->res.jsonValue;
- if (availableCoreCount != nullptr)
- {
- json["TotalAvailableCoreCount"] = *availableCoreCount;
- }
+ if (availableCoreCount != nullptr)
+ {
+ json["TotalAvailableCoreCount"] = *availableCoreCount;
+ }
- if (baseSpeed != nullptr)
- {
- json["BaseSpeedMHz"] = *baseSpeed;
- }
+ if (baseSpeed != nullptr)
+ {
+ json["BaseSpeedMHz"] = *baseSpeed;
+ }
- if (maxJunctionTemperature != nullptr)
- {
- json["MaxJunctionTemperatureCelsius"] = *maxJunctionTemperature;
- }
+ if (maxJunctionTemperature != nullptr)
+ {
+ json["MaxJunctionTemperatureCelsius"] = *maxJunctionTemperature;
+ }
- if (maxSpeed != nullptr)
- {
- json["MaxSpeedMHz"] = *maxSpeed;
- }
+ if (maxSpeed != nullptr)
+ {
+ json["MaxSpeedMHz"] = *maxSpeed;
+ }
- if (powerLimit != nullptr)
- {
- json["TDPWatts"] = *powerLimit;
- }
+ if (powerLimit != nullptr)
+ {
+ json["TDPWatts"] = *powerLimit;
+ }
- if (turboProfile != nullptr)
- {
- nlohmann::json& turboArray = json["TurboProfile"];
- turboArray = nlohmann::json::array();
- for (const auto& [turboSpeed, coreCount] : *turboProfile)
+ if (turboProfile != nullptr)
{
- nlohmann::json::object_t turbo;
- turbo["ActiveCoreCount"] = coreCount;
- turbo["MaxSpeedMHz"] = turboSpeed;
- turboArray.emplace_back(std::move(turbo));
+ nlohmann::json& turboArray = json["TurboProfile"];
+ turboArray = nlohmann::json::array();
+ for (const auto& [turboSpeed, coreCount] : *turboProfile)
+ {
+ nlohmann::json::object_t turbo;
+ turbo["ActiveCoreCount"] = coreCount;
+ turbo["MaxSpeedMHz"] = turboSpeed;
+ turboArray.emplace_back(std::move(turbo));
+ }
}
- }
- if (baseSpeedPrioritySettings != nullptr)
- {
- nlohmann::json& baseSpeedArray = json["BaseSpeedPrioritySettings"];
- baseSpeedArray = nlohmann::json::array();
- for (const auto& [baseSpeedMhz, coreList] :
- *baseSpeedPrioritySettings)
+ if (baseSpeedPrioritySettings != nullptr)
{
- nlohmann::json::object_t speed;
- speed["CoreCount"] = coreList.size();
- speed["CoreIDs"] = coreList;
- speed["BaseSpeedMHz"] = baseSpeedMhz;
- baseSpeedArray.emplace_back(std::move(speed));
+ nlohmann::json& baseSpeedArray =
+ json["BaseSpeedPrioritySettings"];
+ baseSpeedArray = nlohmann::json::array();
+ for (const auto& [baseSpeedMhz, coreList] :
+ *baseSpeedPrioritySettings)
+ {
+ nlohmann::json::object_t speed;
+ speed["CoreCount"] = coreList.size();
+ speed["CoreIDs"] = coreList;
+ speed["BaseSpeedMHz"] = baseSpeedMhz;
+ baseSpeedArray.emplace_back(std::move(speed));
+ }
}
- }
- });
+ });
}
/**
@@ -1064,11 +1072,10 @@ inline void patchAppliedOperatingConfig(
"AppliedConfig", configPath);
}
-inline void
- handleProcessorHead(crow::App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& /* systemName */,
- const std::string& /* processorId */)
+inline void handleProcessorHead(
+ crow::App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& /* systemName */, const std::string& /* processorId */)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -1098,77 +1105,81 @@ inline void requestRoutesOperatingConfigCollection(App& app)
BMCWEB_ROUTE(app,
"/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/")
.privileges(redfish::privileges::getOperatingConfigCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName, const std::string& cpuName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#OperatingConfigCollection.OperatingConfigCollection";
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName);
- asyncResp->res.jsonValue["Name"] = "Operating Config Collection";
-
- // First find the matching CPU object so we know how to
- // constrain our search for related Config objects.
- const std::array<std::string_view, 1> interfaces = {
- "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig"};
- dbus::utility::getSubTreePaths(
- "/xyz/openbmc_project/inventory", 0, interfaces,
- [asyncResp, cpuName](
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse& objects) {
- if (ec)
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName,
+ const std::string& cpuName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
- messages::internalError(asyncResp->res);
return;
}
- for (const std::string& object : objects)
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
- if (!object.ends_with(cpuName))
- {
- continue;
- }
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- // Not expected that there will be multiple matching
- // CPU objects, but if there are just use the first
- // one.
-
- // Use the common search routine to construct the
- // Collection of all Config objects under this CPU.
- constexpr std::array<std::string_view, 1> interface{
- "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
- collection_util::getCollectionMembers(
- asyncResp,
- boost::urls::format(
- "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName),
- interface, object);
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
return;
}
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#OperatingConfigCollection.OperatingConfigCollection";
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName);
+ asyncResp->res.jsonValue["Name"] = "Operating Config Collection";
+
+ // First find the matching CPU object so we know how to
+ // constrain our search for related Config objects.
+ const std::array<std::string_view, 1> interfaces = {
+ "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig"};
+ dbus::utility::getSubTreePaths(
+ "/xyz/openbmc_project/inventory", 0, interfaces,
+ [asyncResp,
+ cpuName](const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreePathsResponse&
+ objects) {
+ if (ec)
+ {
+ BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
+ ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ for (const std::string& object : objects)
+ {
+ if (!object.ends_with(cpuName))
+ {
+ continue;
+ }
+
+ // Not expected that there will be multiple matching
+ // CPU objects, but if there are just use the first
+ // one.
+
+ // Use the common search routine to construct the
+ // Collection of all Config objects under this CPU.
+ constexpr std::array<std::string_view, 1> interface{
+ "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
+ collection_util::getCollectionMembers(
+ asyncResp,
+ boost::urls::format(
+ "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName),
+ interface, object);
+ return;
+ }
+ });
});
- });
}
inline void requestRoutesOperatingConfig(App& app)
@@ -1177,72 +1188,79 @@ inline void requestRoutesOperatingConfig(App& app)
app,
"/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/<str>/")
.privileges(redfish::privileges::getOperatingConfig)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName, const std::string& cpuName,
- const std::string& configName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- // Ask for all objects implementing OperatingConfig so we can search
- // for one with a matching name
- constexpr std::array<std::string_view, 1> interfaces = {
- "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
- dbus::utility::getSubTree(
- "/xyz/openbmc_project/inventory", 0, interfaces,
- [asyncResp, cpuName, configName](
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName,
+ const std::string& cpuName,
+ const std::string& configName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
- messages::internalError(asyncResp->res);
return;
}
- const std::string expectedEnding = cpuName + '/' + configName;
- for (const auto& [objectPath, serviceMap] : subtree)
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
- // Ignore any configs without matching cpuX/configY
- if (!objectPath.ends_with(expectedEnding) || serviceMap.empty())
- {
- continue;
- }
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- nlohmann::json& json = asyncResp->res.jsonValue;
- json["@odata.type"] = "#OperatingConfig.v1_0_0.OperatingConfig";
- json["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName, configName);
- json["Name"] = "Processor Profile";
- json["Id"] = configName;
-
- // Just use the first implementation of the object - not
- // expected that there would be multiple matching
- // services
- getOperatingConfigData(asyncResp, serviceMap.begin()->first,
- objectPath);
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
return;
}
- messages::resourceNotFound(asyncResp->res, "OperatingConfig",
- configName);
+ // Ask for all objects implementing OperatingConfig so we can search
+ // for one with a matching name
+ constexpr std::array<std::string_view, 1> interfaces = {
+ "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
+ dbus::utility::getSubTree(
+ "/xyz/openbmc_project/inventory", 0, interfaces,
+ [asyncResp, cpuName, configName](
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreeResponse& subtree) {
+ if (ec)
+ {
+ BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
+ ec.message());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const std::string expectedEnding =
+ cpuName + '/' + configName;
+ for (const auto& [objectPath, serviceMap] : subtree)
+ {
+ // Ignore any configs without matching cpuX/configY
+ if (!objectPath.ends_with(expectedEnding) ||
+ serviceMap.empty())
+ {
+ continue;
+ }
+
+ nlohmann::json& json = asyncResp->res.jsonValue;
+ json["@odata.type"] =
+ "#OperatingConfig.v1_0_0.OperatingConfig";
+ json["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName,
+ configName);
+ json["Name"] = "Processor Profile";
+ json["Id"] = configName;
+
+ // Just use the first implementation of the object - not
+ // expected that there would be multiple matching
+ // services
+ getOperatingConfigData(
+ asyncResp, serviceMap.begin()->first, objectPath);
+ return;
+ }
+ messages::resourceNotFound(asyncResp->res,
+ "OperatingConfig", configName);
+ });
});
- });
}
inline void requestRoutesProcessorCollection(App& app)
@@ -1257,47 +1275,48 @@ inline void requestRoutesProcessorCollection(App& app)
BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
.privileges(redfish::privileges::getProcessorCollection)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
- asyncResp->res.jsonValue["@odata.type"] =
- "#ProcessorCollection.ProcessorCollection";
- asyncResp->res.jsonValue["Name"] = "Processor Collection";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ProcessorCollection.ProcessorCollection";
+ asyncResp->res.jsonValue["Name"] = "Processor Collection";
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/Processors",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/Processors",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
- collection_util::getCollectionMembers(
- asyncResp,
- boost::urls::format("/redfish/v1/Systems/{}/Processors",
- BMCWEB_REDFISH_SYSTEM_URI_NAME),
- processorInterfaces, "/xyz/openbmc_project/inventory");
- });
+ collection_util::getCollectionMembers(
+ asyncResp,
+ boost::urls::format("/redfish/v1/Systems/{}/Processors",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME),
+ processorInterfaces, "/xyz/openbmc_project/inventory");
+ });
}
inline void requestRoutesProcessor(App& app)
@@ -1313,42 +1332,43 @@ inline void requestRoutesProcessor(App& app)
BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
.privileges(redfish::privileges::getProcessor)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& processorId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
-
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
- asyncResp->res.jsonValue["@odata.type"] =
- "#Processor.v1_18_0.Processor";
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/Systems/{}/Processors/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId);
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName,
+ const std::string& processorId) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- getProcessorObject(
- asyncResp, processorId,
- std::bind_front(getProcessorData, asyncResp, processorId));
- });
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Processor.v1_18_0.Processor";
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/Processors/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId);
+
+ getProcessorObject(
+ asyncResp, processorId,
+ std::bind_front(getProcessorData, asyncResp, processorId));
+ });
BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
.privileges(redfish::privileges::patchProcessor)
@@ -1357,42 +1377,42 @@ inline void requestRoutesProcessor(App& app)
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName,
const std::string& processorId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
- std::optional<std::string> appliedConfigUri;
- if (!json_util::readJsonPatch(req, asyncResp->res,
- "AppliedOperatingConfig/@odata.id",
- appliedConfigUri))
- {
- return;
- }
+ std::optional<std::string> appliedConfigUri;
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "AppliedOperatingConfig/@odata.id",
+ appliedConfigUri))
+ {
+ return;
+ }
- if (appliedConfigUri)
- {
- // Check for 404 and find matching D-Bus object, then run
- // property patch handlers if that all succeeds.
- getProcessorObject(asyncResp, processorId,
- std::bind_front(patchAppliedOperatingConfig,
- asyncResp, processorId,
- *appliedConfigUri));
- }
- });
+ if (appliedConfigUri)
+ {
+ // Check for 404 and find matching D-Bus object, then run
+ // property patch handlers if that all succeeds.
+ getProcessorObject(
+ asyncResp, processorId,
+ std::bind_front(patchAppliedOperatingConfig, asyncResp,
+ processorId, *appliedConfigUri));
+ }
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 555e7f32ac..48d53bfd94 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -1,22 +1,23 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "account_service.hpp"
#include "app.hpp"
+#include "cookies.hpp"
#include "error_messages.hpp"
#include "http/utility.hpp"
#include "persistent_data.hpp"
@@ -26,6 +27,9 @@
#include <boost/url/format.hpp>
+#include <string>
+#include <vector>
+
namespace redfish
{
@@ -125,21 +129,26 @@ inline void
}
}
+ if (req.session != nullptr && req.session->uniqueId == sessionId &&
+ session->cookieAuth)
+ {
+ bmcweb::clearSessionCookies(asyncResp->res);
+ }
+
persistent_data::SessionStore::getInstance().removeSession(session);
messages::success(asyncResp->res);
}
inline nlohmann::json getSessionCollectionMembers()
{
- std::vector<const std::string*> sessionIds =
- persistent_data::SessionStore::getInstance().getUniqueIds(
- false, persistent_data::PersistenceType::TIMEOUT);
+ std::vector<std::string> sessionIds =
+ persistent_data::SessionStore::getInstance().getAllUniqueIds();
nlohmann::json ret = nlohmann::json::array();
- for (const std::string* uid : sessionIds)
+ for (const std::string& uid : sessionIds)
{
nlohmann::json::object_t session;
session["@odata.id"] =
- boost::urls::format("/redfish/v1/SessionService/Sessions/{}", *uid);
+ boost::urls::format("/redfish/v1/SessionService/Sessions/{}", uid);
ret.emplace_back(std::move(session));
}
return ret;
@@ -203,12 +212,13 @@ inline void handleSessionCollectionPost(
std::string username;
std::string password;
std::optional<std::string> clientId;
+ std::optional<std::string> token;
if (!json_util::readJsonPatch(req, asyncResp->res, "UserName", username,
- "Password", password, "Context", clientId))
+ "Password", password, "Token", token,
+ "Context", clientId))
{
return;
}
-
if (password.empty() || username.empty() ||
asyncResp->res.result() != boost::beast::http::status::ok)
{
@@ -225,7 +235,7 @@ inline void handleSessionCollectionPost(
return;
}
- int pamrc = pamAuthenticateUser(username, password);
+ int pamrc = pamAuthenticateUser(username, password, token);
bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
{
@@ -238,14 +248,25 @@ inline void handleSessionCollectionPost(
std::shared_ptr<persistent_data::UserSession> session =
persistent_data::SessionStore::getInstance().generateUserSession(
username, req.ipAddress, clientId,
- persistent_data::PersistenceType::TIMEOUT, isConfigureSelfOnly);
+ persistent_data::SessionType::Session, isConfigureSelfOnly);
if (session == nullptr)
{
messages::internalError(asyncResp->res);
return;
}
- asyncResp->res.addHeader("X-Auth-Token", session->sessionToken);
+ // When session is created by webui-vue give it session cookies as a
+ // non-standard Redfish extension. This is needed for authentication for
+ // WebSockets-based functionality.
+ if (!req.getHeaderValue("X-Requested-With").empty())
+ {
+ bmcweb::setSessionCookies(asyncResp->res, *session);
+ }
+ else
+ {
+ asyncResp->res.addHeader("X-Auth-Token", session->sessionToken);
+ }
+
asyncResp->res.addHeader(
"Location", "/redfish/v1/SessionService/Sessions/" + session->uniqueId);
asyncResp->res.result(boost::beast::http::status::created);
diff --git a/redfish-core/lib/redfish_util.hpp b/redfish-core/lib/redfish_util.hpp
index 8fe2bbc400..4164e10775 100644
--- a/redfish-core/lib/redfish_util.hpp
+++ b/redfish-core/lib/redfish_util.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2019 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2019 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -71,29 +71,29 @@ void getMainChassisId(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[callback = std::forward<CallbackFunc>(callback),
asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("{}", ec);
- return;
- }
- if (subtree.empty())
- {
- BMCWEB_LOG_DEBUG("Can't find chassis!");
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("{}", ec);
+ return;
+ }
+ if (subtree.empty())
+ {
+ BMCWEB_LOG_DEBUG("Can't find chassis!");
+ return;
+ }
- std::size_t idPos = subtree[0].first.rfind('/');
- if (idPos == std::string::npos ||
- (idPos + 1) >= subtree[0].first.size())
- {
- messages::internalError(asyncResp->res);
- BMCWEB_LOG_DEBUG("Can't parse chassis ID!");
- return;
- }
- std::string chassisId = subtree[0].first.substr(idPos + 1);
- BMCWEB_LOG_DEBUG("chassisId = {}", chassisId);
- callback(chassisId, asyncResp);
- });
+ std::size_t idPos = subtree[0].first.rfind('/');
+ if (idPos == std::string::npos ||
+ (idPos + 1) >= subtree[0].first.size())
+ {
+ messages::internalError(asyncResp->res);
+ BMCWEB_LOG_DEBUG("Can't parse chassis ID!");
+ return;
+ }
+ std::string chassisId = subtree[0].first.substr(idPos + 1);
+ BMCWEB_LOG_DEBUG("chassisId = {}", chassisId);
+ callback(chassisId, asyncResp);
+ });
}
template <typename CallbackFunc>
@@ -106,99 +106,101 @@ void getPortStatusAndPath(
[protocolToDBus, callback = std::forward<CallbackFunc>(callback)](
const boost::system::error_code& ec,
const std::vector<UnitStruct>& r) {
- std::vector<std::tuple<std::string, std::string, bool>> socketData;
- if (ec)
- {
- BMCWEB_LOG_ERROR("{}", ec);
- // return error code
- callback(ec, socketData);
- return;
- }
-
- // save all service output into vector
- for (const UnitStruct& unit : r)
- {
- // Only traverse through <xyz>.socket units
- const std::string& unitName = std::get<NET_PROTO_UNIT_NAME>(unit);
-
- // find "." into unitsName
- size_t lastCharPos = unitName.rfind('.');
- if (lastCharPos == std::string::npos)
+ std::vector<std::tuple<std::string, std::string, bool>> socketData;
+ if (ec)
{
- continue;
+ BMCWEB_LOG_ERROR("{}", ec);
+ // return error code
+ callback(ec, socketData);
+ return;
}
- // is unitsName end with ".socket"
- std::string unitNameEnd = unitName.substr(lastCharPos);
- if (unitNameEnd != ".socket")
+ // save all service output into vector
+ for (const UnitStruct& unit : r)
{
- continue;
- }
+ // Only traverse through <xyz>.socket units
+ const std::string& unitName =
+ std::get<NET_PROTO_UNIT_NAME>(unit);
- // find "@" into unitsName
- if (size_t atCharPos = unitName.rfind('@');
- atCharPos != std::string::npos)
- {
- lastCharPos = atCharPos;
- }
-
- // unitsName without "@eth(x).socket", only <xyz>
- // unitsName without ".socket", only <xyz>
- std::string unitNameStr = unitName.substr(0, lastCharPos);
+ // find "." into unitsName
+ size_t lastCharPos = unitName.rfind('.');
+ if (lastCharPos == std::string::npos)
+ {
+ continue;
+ }
- for (const auto& kv : protocolToDBus)
- {
- // We are interested in services, which starts with
- // mapped service name
- if (unitNameStr != kv.second)
+ // is unitsName end with ".socket"
+ std::string unitNameEnd = unitName.substr(lastCharPos);
+ if (unitNameEnd != ".socket")
{
continue;
}
- const std::string& socketPath =
- std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
- const std::string& unitState =
- std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
+ // find "@" into unitsName
+ if (size_t atCharPos = unitName.rfind('@');
+ atCharPos != std::string::npos)
+ {
+ lastCharPos = atCharPos;
+ }
- bool isProtocolEnabled = ((unitState == "running") ||
- (unitState == "listening"));
+ // unitsName without "@eth(x).socket", only <xyz>
+ // unitsName without ".socket", only <xyz>
+ std::string unitNameStr = unitName.substr(0, lastCharPos);
- // Some protocols may have multiple services associated with
- // them (for example IPMI). Look to see if we've already added
- // an entry for the current protocol.
- auto find = std::ranges::find_if(
- socketData,
- [&kv](const std::tuple<std::string, std::string, bool>& i) {
- return std::get<1>(i) == kv.first;
- });
- if (find != socketData.end())
+ for (const auto& kv : protocolToDBus)
{
- // It only takes one enabled systemd service to consider a
- // protocol enabled so if the current entry already has it
- // enabled (or the new one is disabled) then just continue,
- // otherwise remove the current one and add this new one.
- if (std::get<2>(*find) || !isProtocolEnabled)
+ // We are interested in services, which starts with
+ // mapped service name
+ if (unitNameStr != kv.second)
{
- // Already registered as enabled or current one is not
- // enabled, nothing to do
- BMCWEB_LOG_DEBUG(
- "protocolName: {}, already true or current one is false: {}",
- kv.first, isProtocolEnabled);
- break;
+ continue;
+ }
+
+ const std::string& socketPath =
+ std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
+ const std::string& unitState =
+ std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
+
+ bool isProtocolEnabled = ((unitState == "running") ||
+ (unitState == "listening"));
+
+ // Some protocols may have multiple services associated with
+ // them (for example IPMI). Look to see if we've already
+ // added an entry for the current protocol.
+ auto find = std::ranges::find_if(
+ socketData,
+ [&kv](const std::tuple<std::string, std::string, bool>&
+ i) { return std::get<1>(i) == kv.first; });
+ if (find != socketData.end())
+ {
+ // It only takes one enabled systemd service to consider
+ // a protocol enabled so if the current entry already
+ // has it enabled (or the new one is disabled) then just
+ // continue, otherwise remove the current one and add
+ // this new one.
+ if (std::get<2>(*find) || !isProtocolEnabled)
+ {
+ // Already registered as enabled or current one is
+ // not enabled, nothing to do
+ BMCWEB_LOG_DEBUG(
+ "protocolName: {}, already true or current one is false: {}",
+ kv.first, isProtocolEnabled);
+ break;
+ }
+ // Remove existing entry and replace with new one
+ // (below)
+ socketData.erase(find);
}
- // Remove existing entry and replace with new one (below)
- socketData.erase(find);
- }
- socketData.emplace_back(socketPath, std::string(kv.first),
- isProtocolEnabled);
- // We found service, return from inner loop.
- break;
+ socketData.emplace_back(socketPath, std::string(kv.first),
+ isProtocolEnabled);
+ // We found service, return from inner loop.
+ break;
+ }
}
- }
- callback(ec, socketData);
- },
+ callback(ec, socketData);
+ },
"org.freedesktop.systemd1", "/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager", "ListUnits");
}
@@ -213,46 +215,46 @@ void getPortNumber(const std::string& socketPath, CallbackFunc&& callback)
[callback = std::forward<CallbackFunc>(callback)](
const boost::system::error_code& ec,
const std::vector<std::tuple<std::string, std::string>>& resp) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("{}", ec);
- callback(ec, 0);
- return;
- }
- if (resp.empty())
- {
- // Network Protocol Listen Response Elements is empty
- boost::system::error_code ec1 =
- boost::system::errc::make_error_code(
- boost::system::errc::bad_message);
- // return error code
- callback(ec1, 0);
- BMCWEB_LOG_ERROR("{}", ec1);
- return;
- }
- const std::string& listenStream =
- std::get<NET_PROTO_LISTEN_STREAM>(resp[0]);
- const char* pa = &listenStream[listenStream.rfind(':') + 1];
- int port{0};
- if (auto [p, ec2] = std::from_chars(pa, nullptr, port);
- ec2 != std::errc())
- {
- // there is only two possibility invalid_argument and
- // result_out_of_range
- boost::system::error_code ec3 =
- boost::system::errc::make_error_code(
- boost::system::errc::invalid_argument);
- if (ec2 == std::errc::result_out_of_range)
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("{}", ec);
+ callback(ec, 0);
+ return;
+ }
+ if (resp.empty())
{
- ec3 = boost::system::errc::make_error_code(
- boost::system::errc::result_out_of_range);
+ // Network Protocol Listen Response Elements is empty
+ boost::system::error_code ec1 =
+ boost::system::errc::make_error_code(
+ boost::system::errc::bad_message);
+ // return error code
+ callback(ec1, 0);
+ BMCWEB_LOG_ERROR("{}", ec1);
+ return;
+ }
+ const std::string& listenStream =
+ std::get<NET_PROTO_LISTEN_STREAM>(resp[0]);
+ const char* pa = &listenStream[listenStream.rfind(':') + 1];
+ int port{0};
+ if (auto [p, ec2] = std::from_chars(pa, nullptr, port);
+ ec2 != std::errc())
+ {
+ // there is only two possibility invalid_argument and
+ // result_out_of_range
+ boost::system::error_code ec3 =
+ boost::system::errc::make_error_code(
+ boost::system::errc::invalid_argument);
+ if (ec2 == std::errc::result_out_of_range)
+ {
+ ec3 = boost::system::errc::make_error_code(
+ boost::system::errc::result_out_of_range);
+ }
+ // return error code
+ callback(ec3, 0);
+ BMCWEB_LOG_ERROR("{}", ec3);
}
- // return error code
- callback(ec3, 0);
- BMCWEB_LOG_ERROR("{}", ec3);
- }
- callback(ec, port);
- });
+ callback(ec, port);
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/redfish_v1.hpp b/redfish-core/lib/redfish_v1.hpp
index bbda45bcdd..418f66c431 100644
--- a/redfish-core/lib/redfish_v1.hpp
+++ b/redfish-core/lib/redfish_v1.hpp
@@ -6,7 +6,6 @@
#include "http_response.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
-#include "schemas.hpp"
#include "utility.hpp"
#include <boost/url/format.hpp>
@@ -86,15 +85,32 @@ inline void
json["Name"] = "JsonSchemaFile Collection";
json["Description"] = "Collection of JsonSchemaFiles";
nlohmann::json::array_t members;
- for (std::string_view schema : schemas)
+
+ std::error_code ec;
+ std::filesystem::directory_iterator dirList(
+ "/usr/share/www/redfish/v1/JsonSchemas", ec);
+ if (ec)
{
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ for (const std::filesystem::path& file : dirList)
+ {
+ std::string filename = file.filename();
+ std::vector<std::string> split;
+ bmcweb::split(split, filename, '.');
+ if (split.empty())
+ {
+ continue;
+ }
nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format("/redfish/v1/JsonSchemas/{}",
- schema);
+ member["@odata.id"] =
+ boost::urls::format("/redfish/v1/JsonSchemas/{}", split[0]);
members.emplace_back(std::move(member));
}
+
+ json["Members@odata.count"] = members.size();
json["Members"] = std::move(members);
- json["Members@odata.count"] = schemas.size();
}
inline void jsonSchemaGet(App& app, const crow::Request& req,
@@ -106,40 +122,100 @@ inline void jsonSchemaGet(App& app, const crow::Request& req,
return;
}
- if (std::ranges::find(schemas, schema) == schemas.end())
+ std::error_code ec;
+ std::filesystem::directory_iterator dirList(
+ "/usr/share/www/redfish/v1/JsonSchemas", ec);
+ if (ec)
{
messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema);
return;
}
+ for (const std::filesystem::path& file : dirList)
+ {
+ std::string filename = file.filename();
+ std::vector<std::string> split;
+ bmcweb::split(split, filename, '.');
+ if (split.empty())
+ {
+ continue;
+ }
+ BMCWEB_LOG_DEBUG("Checking {}", split[0]);
+ if (split[0] != schema)
+ {
+ continue;
+ }
+
+ nlohmann::json& json = asyncResp->res.jsonValue;
+ json["@odata.id"] =
+ boost::urls::format("/redfish/v1/JsonSchemas/{}", schema);
+ json["@odata.type"] = "#JsonSchemaFile.v1_0_2.JsonSchemaFile";
+ json["Name"] = schema + " Schema File";
+ json["Description"] = schema + " Schema File Location";
+ json["Id"] = schema;
+ std::string schemaName = std::format("#{}.{}", schema, schema);
+ json["Schema"] = std::move(schemaName);
+ constexpr std::array<std::string_view, 1> languages{"en"};
+ json["Languages"] = languages;
+ json["Languages@odata.count"] = languages.size();
+
+ nlohmann::json::array_t locationArray;
+ nlohmann::json::object_t locationEntry;
+ locationEntry["Language"] = "en";
+
+ locationEntry["PublicationUri"] = boost::urls::format(
+ "http://redfish.dmtf.org/schemas/v1/{}", filename);
+ locationEntry["Uri"] = boost::urls::format(
+ "/redfish/v1/JsonSchemas/{}/{}", schema, filename);
+
+ locationArray.emplace_back(locationEntry);
+
+ json["Location"] = std::move(locationArray);
+ json["Location@odata.count"] = 1;
+ return;
+ }
+ messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema);
+}
- nlohmann::json& json = asyncResp->res.jsonValue;
- json["@odata.id"] = boost::urls::format("/redfish/v1/JsonSchemas/{}",
- schema);
- json["@odata.type"] = "#JsonSchemaFile.v1_0_2.JsonSchemaFile";
- json["Name"] = schema + " Schema File";
- json["Description"] = schema + " Schema File Location";
- json["Id"] = schema;
- std::string schemaName = "#";
- schemaName += schema;
- schemaName += ".";
- schemaName += schema;
- json["Schema"] = std::move(schemaName);
- constexpr std::array<std::string_view, 1> languages{"en"};
- json["Languages"] = languages;
- json["Languages@odata.count"] = languages.size();
-
- nlohmann::json::array_t locationArray;
- nlohmann::json::object_t locationEntry;
- locationEntry["Language"] = "en";
- locationEntry["PublicationUri"] = "http://redfish.dmtf.org/schemas/v1/" +
- schema + ".json";
- locationEntry["Uri"] = boost::urls::format(
- "/redfish/v1/JsonSchemas/{}/{}", schema, std::string(schema) + ".json");
-
- locationArray.emplace_back(locationEntry);
-
- json["Location"] = std::move(locationArray);
- json["Location@odata.count"] = 1;
+inline void
+ jsonSchemaGetFile(const crow::Request& /*req*/,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& schema, const std::string& schemaFile)
+{
+ // Sanity check the filename
+ if (schemaFile.find_first_not_of(
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.") !=
+ std::string::npos)
+ {
+ messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema);
+ return;
+ }
+ // Schema path should look like /redfish/v1/JsonSchemas/Foo/Foo.x.json
+ // Make sure the two paths match.
+ if (!schemaFile.starts_with(schema))
+ {
+ messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema);
+ return;
+ }
+ std::filesystem::path filepath("/usr/share/www/redfish/v1/JsonSchemas");
+ filepath /= schemaFile;
+ if (filepath.is_relative())
+ {
+ messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema);
+ return;
+ }
+
+ crow::OpenCode ec = asyncResp->res.openFile(filepath);
+ if (ec == crow::OpenCode::FileDoesNotExist)
+ {
+ messages::resourceNotFound(asyncResp->res, "JsonSchemaFile", schema);
+ return;
+ }
+ if (ec == crow::OpenCode::InternalError)
+ {
+ BMCWEB_LOG_DEBUG("failed to read file");
+ messages::internalError(asyncResp->res);
+ return;
+ }
}
inline void requestRoutesRedfish(App& app)
@@ -148,6 +224,10 @@ inline void requestRoutesRedfish(App& app)
.methods(boost::beast::http::verb::get)(
std::bind_front(redfishGet, std::ref(app)));
+ BMCWEB_ROUTE(app, "/redfish/v1/JsonSchemas/<str>/<str>")
+ .privileges(redfish::privileges::getJsonSchemaFile)
+ .methods(boost::beast::http::verb::get)(jsonSchemaGetFile);
+
BMCWEB_ROUTE(app, "/redfish/v1/JsonSchemas/<str>/")
.privileges(redfish::privileges::getJsonSchemaFileCollection)
.methods(boost::beast::http::verb::get)(
diff --git a/redfish-core/lib/roles.hpp b/redfish-core/lib/roles.hpp
index a0f4f34754..c17a2256be 100644
--- a/redfish-core/lib/roles.hpp
+++ b/redfish-core/lib/roles.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -85,31 +85,33 @@ inline void requestRoutesRoles(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& roleId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- std::optional<nlohmann::json::array_t> privArray =
- getAssignedPrivFromRole(roleId);
- if (!privArray)
- {
- messages::resourceNotFound(asyncResp->res, "Role", roleId);
-
- return;
- }
-
- asyncResp->res.jsonValue["@odata.type"] = "#Role.v1_2_2.Role";
- asyncResp->res.jsonValue["Name"] = "User Role";
- asyncResp->res.jsonValue["Description"] = roleId + " User Role";
- asyncResp->res.jsonValue["OemPrivileges"] = nlohmann::json::array();
- asyncResp->res.jsonValue["IsPredefined"] = true;
- asyncResp->res.jsonValue["Id"] = roleId;
- asyncResp->res.jsonValue["RoleId"] = roleId;
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/AccountService/Roles/{}", roleId);
- asyncResp->res.jsonValue["AssignedPrivileges"] = std::move(*privArray);
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ std::optional<nlohmann::json::array_t> privArray =
+ getAssignedPrivFromRole(roleId);
+ if (!privArray)
+ {
+ messages::resourceNotFound(asyncResp->res, "Role", roleId);
+
+ return;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] = "#Role.v1_2_2.Role";
+ asyncResp->res.jsonValue["Name"] = "User Role";
+ asyncResp->res.jsonValue["Description"] = roleId + " User Role";
+ asyncResp->res.jsonValue["OemPrivileges"] =
+ nlohmann::json::array();
+ asyncResp->res.jsonValue["IsPredefined"] = true;
+ asyncResp->res.jsonValue["Id"] = roleId;
+ asyncResp->res.jsonValue["RoleId"] = roleId;
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/AccountService/Roles/{}", roleId);
+ asyncResp->res.jsonValue["AssignedPrivileges"] =
+ std::move(*privArray);
+ });
}
inline void requestRoutesRoleCollection(App& app)
@@ -119,46 +121,49 @@ inline void requestRoutesRoleCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
-
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/AccountService/Roles";
- asyncResp->res.jsonValue["@odata.type"] =
- "#RoleCollection.RoleCollection";
- asyncResp->res.jsonValue["Name"] = "Roles Collection";
- asyncResp->res.jsonValue["Description"] = "BMC User Roles";
-
- sdbusplus::asio::getProperty<std::vector<std::string>>(
- *crow::connections::systemBus, "xyz.openbmc_project.User.Manager",
- "/xyz/openbmc_project/user", "xyz.openbmc_project.User.Manager",
- "AllPrivileges",
- [asyncResp](const boost::system::error_code& ec,
- const std::vector<std::string>& privList) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
- memberArray = nlohmann::json::array();
- for (const std::string& priv : privList)
- {
- std::string role = getRoleFromPrivileges(priv);
- if (!role.empty())
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/AccountService/Roles/{}", role);
- memberArray.emplace_back(std::move(member));
+ return;
}
- }
- asyncResp->res.jsonValue["Members@odata.count"] =
- memberArray.size();
- });
- });
+
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/AccountService/Roles";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#RoleCollection.RoleCollection";
+ asyncResp->res.jsonValue["Name"] = "Roles Collection";
+ asyncResp->res.jsonValue["Description"] = "BMC User Roles";
+
+ sdbusplus::asio::getProperty<std::vector<std::string>>(
+ *crow::connections::systemBus,
+ "xyz.openbmc_project.User.Manager",
+ "/xyz/openbmc_project/user",
+ "xyz.openbmc_project.User.Manager", "AllPrivileges",
+ [asyncResp](const boost::system::error_code& ec,
+ const std::vector<std::string>& privList) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ nlohmann::json& memberArray =
+ asyncResp->res.jsonValue["Members"];
+ memberArray = nlohmann::json::array();
+ for (const std::string& priv : privList)
+ {
+ std::string role = getRoleFromPrivileges(priv);
+ if (!role.empty())
+ {
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/AccountService/Roles/{}",
+ role);
+ memberArray.emplace_back(std::move(member));
+ }
+ }
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ memberArray.size();
+ });
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index 8be861ba65..f344220b01 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -1,31 +1,32 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "dbus_singleton.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/redundancy.hpp"
#include "generated/enums/resource.hpp"
-#include "generated/enums/sensor.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "str_utility.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/query_param.hpp"
+#include "utils/sensor_utils.hpp"
#include <boost/system/error_code.hpp>
#include <boost/url/format.hpp>
@@ -49,12 +50,6 @@ namespace redfish
namespace sensors
{
-namespace node
-{
-static constexpr std::string_view power = "Power";
-static constexpr std::string_view sensors = "Sensors";
-static constexpr std::string_view thermal = "Thermal";
-} // namespace node
// clang-format off
namespace dbus
@@ -98,99 +93,22 @@ constexpr auto thermalPaths = std::to_array<std::string_view>({
} // namespace dbus
// clang-format on
+constexpr std::string_view powerNodeStr = sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::powerNode);
+constexpr std::string_view sensorsNodeStr =
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::sensorsNode);
+constexpr std::string_view thermalNodeStr =
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::thermalNode);
+
using sensorPair =
std::pair<std::string_view, std::span<const std::string_view>>;
static constexpr std::array<sensorPair, 3> paths = {
- {{node::power, dbus::powerPaths},
- {node::sensors, dbus::sensorPaths},
- {node::thermal, dbus::thermalPaths}}};
-
-inline sensor::ReadingType toReadingType(std::string_view sensorType)
-{
- if (sensorType == "voltage")
- {
- return sensor::ReadingType::Voltage;
- }
- if (sensorType == "power")
- {
- return sensor::ReadingType::Power;
- }
- if (sensorType == "current")
- {
- return sensor::ReadingType::Current;
- }
- if (sensorType == "fan_tach")
- {
- return sensor::ReadingType::Rotational;
- }
- if (sensorType == "temperature")
- {
- return sensor::ReadingType::Temperature;
- }
- if (sensorType == "fan_pwm" || sensorType == "utilization")
- {
- return sensor::ReadingType::Percent;
- }
- if (sensorType == "humidity")
- {
- return sensor::ReadingType::Humidity;
- }
- if (sensorType == "altitude")
- {
- return sensor::ReadingType::Altitude;
- }
- if (sensorType == "airflow")
- {
- return sensor::ReadingType::AirFlow;
- }
- if (sensorType == "energy")
- {
- return sensor::ReadingType::EnergyJoules;
- }
- return sensor::ReadingType::Invalid;
-}
+ {{sensors::powerNodeStr, dbus::powerPaths},
+ {sensors::sensorsNodeStr, dbus::sensorPaths},
+ {sensors::thermalNodeStr, dbus::thermalPaths}}};
-inline std::string_view toReadingUnits(std::string_view sensorType)
-{
- if (sensorType == "voltage")
- {
- return "V";
- }
- if (sensorType == "power")
- {
- return "W";
- }
- if (sensorType == "current")
- {
- return "A";
- }
- if (sensorType == "fan_tach")
- {
- return "RPM";
- }
- if (sensorType == "temperature")
- {
- return "Cel";
- }
- if (sensorType == "fan_pwm" || sensorType == "utilization" ||
- sensorType == "humidity")
- {
- return "%";
- }
- if (sensorType == "altitude")
- {
- return "m";
- }
- if (sensorType == "airflow")
- {
- return "cft_i/min";
- }
- if (sensorType == "energy")
- {
- return "J";
- }
- return "";
-}
} // namespace sensors
/**
@@ -206,18 +124,17 @@ class SensorsAsyncResp
struct SensorData
{
- const std::string name;
+ std::string name;
std::string uri;
- const std::string dbusPath;
+ std::string dbusPath;
};
SensorsAsyncResp(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn,
const std::string& chassisIdIn,
std::span<const std::string_view> typesIn,
std::string_view subNode) :
- asyncResp(asyncRespIn),
- chassisId(chassisIdIn), types(typesIn), chassisSubNode(subNode),
- efficientExpand(false)
+ asyncResp(asyncRespIn), chassisId(chassisIdIn), types(typesIn),
+ chassisSubNode(subNode), efficientExpand(false)
{}
// Store extra data about sensor mapping and return it in callback
@@ -226,9 +143,9 @@ class SensorsAsyncResp
std::span<const std::string_view> typesIn,
std::string_view subNode,
DataCompleteCb&& creationComplete) :
- asyncResp(asyncRespIn),
- chassisId(chassisIdIn), types(typesIn), chassisSubNode(subNode),
- efficientExpand(false), metadata{std::vector<SensorData>()},
+ asyncResp(asyncRespIn), chassisId(chassisIdIn), types(typesIn),
+ chassisSubNode(subNode), efficientExpand(false),
+ metadata{std::vector<SensorData>()},
dataComplete{std::move(creationComplete)}
{}
@@ -237,9 +154,8 @@ class SensorsAsyncResp
const std::string& chassisIdIn,
std::span<const std::string_view> typesIn,
const std::string_view& subNode, bool efficientExpandIn) :
- asyncResp(asyncRespIn),
- chassisId(chassisIdIn), types(typesIn), chassisSubNode(subNode),
- efficientExpand(efficientExpandIn)
+ asyncResp(asyncRespIn), chassisId(chassisIdIn), types(typesIn),
+ chassisSubNode(subNode), efficientExpand(efficientExpandIn)
{}
~SensorsAsyncResp()
@@ -307,48 +223,7 @@ class SensorsAsyncResp
DataCompleteCb dataComplete;
};
-/**
- * Possible states for physical inventory leds
- */
-enum class LedState
-{
- OFF,
- ON,
- BLINK,
- UNKNOWN
-};
-
-/**
- * D-Bus inventory item associated with one or more sensors.
- */
-class InventoryItem
-{
- public:
- explicit InventoryItem(const std::string& objPath) : objectPath(objPath)
- {
- // Set inventory item name to last node of object path
- sdbusplus::message::object_path path(objectPath);
- name = path.filename();
- if (name.empty())
- {
- BMCWEB_LOG_ERROR("Failed to find '/' in {}", objectPath);
- }
- }
-
- std::string objectPath;
- std::string name;
- bool isPresent = true;
- bool isFunctional = true;
- bool isPowerSupply = false;
- int powerSupplyEfficiencyPercent = -1;
- std::string manufacturer;
- std::string model;
- std::string partNumber;
- std::string serialNumber;
- std::set<std::string> sensors;
- std::string ledObjectPath;
- LedState ledState = LedState::UNKNOWN;
-};
+using InventoryItem = sensor_utils::InventoryItem;
/**
* @brief Get objects with connection necessary for sensors
@@ -373,50 +248,51 @@ void getObjectsWithConnection(
[callback = std::forward<Callback>(callback), sensorsAsyncResp,
sensorNames](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- // Response handler for parsing objects subtree
- BMCWEB_LOG_DEBUG("getObjectsWithConnection resp_handler enter");
- if (ec)
- {
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- BMCWEB_LOG_ERROR(
- "getObjectsWithConnection resp_handler: Dbus error {}", ec);
- return;
- }
+ // Response handler for parsing objects subtree
+ BMCWEB_LOG_DEBUG("getObjectsWithConnection resp_handler enter");
+ if (ec)
+ {
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ BMCWEB_LOG_ERROR(
+ "getObjectsWithConnection resp_handler: Dbus error {}", ec);
+ return;
+ }
- BMCWEB_LOG_DEBUG("Found {} subtrees", subtree.size());
+ BMCWEB_LOG_DEBUG("Found {} subtrees", subtree.size());
- // Make unique list of connections only for requested sensor types and
- // found in the chassis
- std::set<std::string> connections;
- std::set<std::pair<std::string, std::string>> objectsWithConnection;
+ // Make unique list of connections only for requested sensor types
+ // and found in the chassis
+ std::set<std::string> connections;
+ std::set<std::pair<std::string, std::string>> objectsWithConnection;
- BMCWEB_LOG_DEBUG("sensorNames list count: {}", sensorNames->size());
- for (const std::string& tsensor : *sensorNames)
- {
- BMCWEB_LOG_DEBUG("Sensor to find: {}", tsensor);
- }
+ BMCWEB_LOG_DEBUG("sensorNames list count: {}", sensorNames->size());
+ for (const std::string& tsensor : *sensorNames)
+ {
+ BMCWEB_LOG_DEBUG("Sensor to find: {}", tsensor);
+ }
- for (const std::pair<
- std::string,
- std::vector<std::pair<std::string, std::vector<std::string>>>>&
- object : subtree)
- {
- if (sensorNames->find(object.first) != sensorNames->end())
+ for (const std::pair<std::string,
+ std::vector<std::pair<
+ std::string, std::vector<std::string>>>>&
+ object : subtree)
{
- for (const std::pair<std::string, std::vector<std::string>>&
- objData : object.second)
+ if (sensorNames->find(object.first) != sensorNames->end())
{
- BMCWEB_LOG_DEBUG("Adding connection: {}", objData.first);
- connections.insert(objData.first);
- objectsWithConnection.insert(
- std::make_pair(object.first, objData.first));
+ for (const std::pair<std::string, std::vector<std::string>>&
+ objData : object.second)
+ {
+ BMCWEB_LOG_DEBUG("Adding connection: {}",
+ objData.first);
+ connections.insert(objData.first);
+ objectsWithConnection.insert(
+ std::make_pair(object.first, objData.first));
+ }
}
}
- }
- BMCWEB_LOG_DEBUG("Found {} connections", connections.size());
- callback(std::move(connections), std::move(objectsWithConnection));
- BMCWEB_LOG_DEBUG("getObjectsWithConnection resp_handler exit");
- });
+ BMCWEB_LOG_DEBUG("Found {} connections", connections.size());
+ callback(std::move(connections), std::move(objectsWithConnection));
+ BMCWEB_LOG_DEBUG("getObjectsWithConnection resp_handler exit");
+ });
BMCWEB_LOG_DEBUG("getObjectsWithConnection exit");
}
@@ -458,7 +334,7 @@ inline void reduceSensorList(
if ((allSensors == nullptr) || (activeSensors == nullptr))
{
messages::resourceNotFound(res, chassisSubNode,
- chassisSubNode == sensors::node::thermal
+ chassisSubNode == sensors::thermalNodeStr
? "Temperatures"
: "Voltages");
@@ -490,17 +366,17 @@ inline void reduceSensorList(
inline void populateChassisNode(nlohmann::json& jsonValue,
std::string_view chassisSubNode)
{
- if (chassisSubNode == sensors::node::power)
+ if (chassisSubNode == sensors::powerNodeStr)
{
jsonValue["@odata.type"] = "#Power.v1_5_2.Power";
}
- else if (chassisSubNode == sensors::node::thermal)
+ else if (chassisSubNode == sensors::thermalNodeStr)
{
jsonValue["@odata.type"] = "#Thermal.v1_4_0.Thermal";
jsonValue["Fans"] = nlohmann::json::array();
jsonValue["Temperatures"] = nlohmann::json::array();
}
- else if (chassisSubNode == sensors::node::sensors)
+ else if (chassisSubNode == sensors::sensorsNodeStr)
{
jsonValue["@odata.type"] = "#SensorCollection.SensorCollection";
jsonValue["Description"] = "Collection of Sensors for this Chassis";
@@ -508,7 +384,7 @@ inline void populateChassisNode(nlohmann::json& jsonValue,
jsonValue["Members@odata.count"] = 0;
}
- if (chassisSubNode != sensors::node::sensors)
+ if (chassisSubNode != sensors::sensorsNodeStr)
{
jsonValue["Id"] = chassisSubNode;
}
@@ -536,456 +412,72 @@ void getChassis(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
"/xyz/openbmc_project/inventory", 0, interfaces,
[callback = std::forward<Callback>(callback), asyncResp,
chassisIdStr{std::string(chassisId)},
- chassisSubNode{std::string(chassisSubNode)}, sensorTypes](
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse& chassisPaths) {
- BMCWEB_LOG_DEBUG("getChassis respHandler enter");
- if (ec)
- {
- BMCWEB_LOG_ERROR("getChassis respHandler DBUS error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string* chassisPath = nullptr;
- for (const std::string& chassis : chassisPaths)
- {
- sdbusplus::message::object_path path(chassis);
- std::string chassisName = path.filename();
- if (chassisName.empty())
- {
- BMCWEB_LOG_ERROR("Failed to find '/' in {}", chassis);
- continue;
- }
- if (chassisName == chassisIdStr)
+ chassisSubNode{std::string(chassisSubNode)},
+ sensorTypes](const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreePathsResponse&
+ chassisPaths) mutable {
+ BMCWEB_LOG_DEBUG("getChassis respHandler enter");
+ if (ec)
{
- chassisPath = &chassis;
- break;
+ BMCWEB_LOG_ERROR("getChassis respHandler DBUS error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
}
- }
- if (chassisPath == nullptr)
- {
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisIdStr);
- return;
- }
- populateChassisNode(asyncResp->res.jsonValue, chassisSubNode);
-
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/Chassis/{}/{}", chassisIdStr, chassisSubNode);
-
- // Get the list of all sensors for this Chassis element
- std::string sensorPath = *chassisPath + "/all_sensors";
- dbus::utility::getAssociationEndPoints(
- sensorPath,
- [asyncResp, chassisSubNode, sensorTypes,
- callback = std::forward<const Callback>(callback)](
- const boost::system::error_code& ec2,
- const dbus::utility::MapperEndPoints& nodeSensorList) {
- if (ec2)
+ const std::string* chassisPath = nullptr;
+ for (const std::string& chassis : chassisPaths)
{
- if (ec2.value() != EBADR)
+ sdbusplus::message::object_path path(chassis);
+ std::string chassisName = path.filename();
+ if (chassisName.empty())
{
- messages::internalError(asyncResp->res);
- return;
+ BMCWEB_LOG_ERROR("Failed to find '/' in {}", chassis);
+ continue;
}
- }
- const std::shared_ptr<std::set<std::string>> culledSensorList =
- std::make_shared<std::set<std::string>>();
- reduceSensorList(asyncResp->res, chassisSubNode, sensorTypes,
- &nodeSensorList, culledSensorList);
- BMCWEB_LOG_DEBUG("Finishing with {}", culledSensorList->size());
- callback(culledSensorList);
- });
- });
- BMCWEB_LOG_DEBUG("getChassis exit");
-}
-
-/**
- * @brief Returns the Redfish State value for the specified inventory item.
- * @param inventoryItem D-Bus inventory item associated with a sensor.
- * @param sensorAvailable Boolean representing if D-Bus sensor is marked as
- * available.
- * @return State value for inventory item.
- */
-inline resource::State getState(const InventoryItem* inventoryItem,
- const bool sensorAvailable)
-{
- if ((inventoryItem != nullptr) && !(inventoryItem->isPresent))
- {
- return resource::State::Absent;
- }
-
- if (!sensorAvailable)
- {
- return resource::State::UnavailableOffline;
- }
-
- return resource::State::Enabled;
-}
-
-/**
- * @brief Returns the Redfish Health value for the specified sensor.
- * @param sensorJson Sensor JSON object.
- * @param valuesDict Map of all sensor DBus values.
- * @param inventoryItem D-Bus inventory item associated with the sensor. Will
- * be nullptr if no associated inventory item was found.
- * @return Health value for sensor.
- */
-inline std::string getHealth(nlohmann::json& sensorJson,
- const dbus::utility::DBusPropertiesMap& valuesDict,
- const InventoryItem* inventoryItem)
-{
- // Get current health value (if any) in the sensor JSON object. Some JSON
- // objects contain multiple sensors (such as PowerSupplies). We want to set
- // the overall health to be the most severe of any of the sensors.
- std::string currentHealth;
- auto statusIt = sensorJson.find("Status");
- if (statusIt != sensorJson.end())
- {
- auto healthIt = statusIt->find("Health");
- if (healthIt != statusIt->end())
- {
- std::string* health = healthIt->get_ptr<std::string*>();
- if (health != nullptr)
- {
- currentHealth = *health;
- }
- }
- }
-
- // If current health in JSON object is already Critical, return that. This
- // should override the sensor health, which might be less severe.
- if (currentHealth == "Critical")
- {
- return "Critical";
- }
-
- const bool* criticalAlarmHigh = nullptr;
- const bool* criticalAlarmLow = nullptr;
- const bool* warningAlarmHigh = nullptr;
- const bool* warningAlarmLow = nullptr;
-
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), valuesDict, "CriticalAlarmHigh",
- criticalAlarmHigh, "CriticalAlarmLow", criticalAlarmLow,
- "WarningAlarmHigh", warningAlarmHigh, "WarningAlarmLow",
- warningAlarmLow);
-
- if (success)
- {
- // Check if sensor has critical threshold alarm
- if ((criticalAlarmHigh != nullptr && *criticalAlarmHigh) ||
- (criticalAlarmLow != nullptr && *criticalAlarmLow))
- {
- return "Critical";
- }
- }
-
- // Check if associated inventory item is not functional
- if ((inventoryItem != nullptr) && !(inventoryItem->isFunctional))
- {
- return "Critical";
- }
-
- // If current health in JSON object is already Warning, return that. This
- // should override the sensor status, which might be less severe.
- if (currentHealth == "Warning")
- {
- return "Warning";
- }
-
- if (success)
- {
- // Check if sensor has warning threshold alarm
- if ((warningAlarmHigh != nullptr && *warningAlarmHigh) ||
- (warningAlarmLow != nullptr && *warningAlarmLow))
- {
- return "Warning";
- }
- }
-
- return "OK";
-}
-
-inline void setLedState(nlohmann::json& sensorJson,
- const InventoryItem* inventoryItem)
-{
- if (inventoryItem != nullptr && !inventoryItem->ledObjectPath.empty())
- {
- switch (inventoryItem->ledState)
- {
- case LedState::OFF:
- sensorJson["IndicatorLED"] = "Off";
- break;
- case LedState::ON:
- sensorJson["IndicatorLED"] = "Lit";
- break;
- case LedState::BLINK:
- sensorJson["IndicatorLED"] = "Blinking";
- break;
- default:
- break;
- }
- }
-}
-
-/**
- * @brief Builds a json sensor representation of a sensor.
- * @param sensorName The name of the sensor to be built
- * @param sensorType The type (temperature, fan_tach, etc) of the sensor to
- * build
- * @param chassisSubNode The subnode (thermal, sensor, etc) of the sensor
- * @param propertiesDict A dictionary of the properties to build the sensor
- * from.
- * @param sensorJson The json object to fill
- * @param inventoryItem D-Bus inventory item associated with the sensor. Will
- * be nullptr if no associated inventory item was found.
- */
-inline void objectPropertiesToJson(
- std::string_view sensorName, std::string_view sensorType,
- std::string_view chassisSubNode,
- const dbus::utility::DBusPropertiesMap& propertiesDict,
- nlohmann::json& sensorJson, InventoryItem* inventoryItem)
-{
- if (chassisSubNode == sensors::node::sensors)
- {
- std::string subNodeEscaped(sensorType);
- auto remove = std::ranges::remove(subNodeEscaped, '_');
- subNodeEscaped.erase(std::ranges::begin(remove), subNodeEscaped.end());
-
- // For sensors in SensorCollection we set Id instead of MemberId,
- // including power sensors.
- subNodeEscaped += '_';
- subNodeEscaped += sensorName;
- sensorJson["Id"] = std::move(subNodeEscaped);
-
- std::string sensorNameEs(sensorName);
- std::replace(sensorNameEs.begin(), sensorNameEs.end(), '_', ' ');
- sensorJson["Name"] = std::move(sensorNameEs);
- }
- else if (sensorType != "power")
- {
- // Set MemberId and Name for non-power sensors. For PowerSupplies and
- // PowerControl, those properties have more general values because
- // multiple sensors can be stored in the same JSON object.
- std::string sensorNameEs(sensorName);
- std::replace(sensorNameEs.begin(), sensorNameEs.end(), '_', ' ');
- sensorJson["Name"] = std::move(sensorNameEs);
- }
-
- const bool* checkAvailable = nullptr;
- bool available = true;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesDict, "Available",
- checkAvailable);
- if (!success)
- {
- messages::internalError();
- }
- if (checkAvailable != nullptr)
- {
- available = *checkAvailable;
- }
-
- sensorJson["Status"]["State"] = getState(inventoryItem, available);
- sensorJson["Status"]["Health"] = getHealth(sensorJson, propertiesDict,
- inventoryItem);
-
- // Parameter to set to override the type we get from dbus, and force it to
- // int, regardless of what is available. This is used for schemas like fan,
- // that require integers, not floats.
- bool forceToInt = false;
-
- nlohmann::json::json_pointer unit("/Reading");
- if (chassisSubNode == sensors::node::sensors)
- {
- sensorJson["@odata.type"] = "#Sensor.v1_2_0.Sensor";
-
- sensor::ReadingType readingType = sensors::toReadingType(sensorType);
- if (readingType == sensor::ReadingType::Invalid)
- {
- BMCWEB_LOG_ERROR("Redfish cannot map reading type for {}",
- sensorType);
- }
- else
- {
- sensorJson["ReadingType"] = readingType;
- }
-
- std::string_view readingUnits = sensors::toReadingUnits(sensorType);
- if (readingUnits.empty())
- {
- BMCWEB_LOG_ERROR("Redfish cannot map reading unit for {}",
- sensorType);
- }
- else
- {
- sensorJson["ReadingUnits"] = readingUnits;
- }
- }
- else if (sensorType == "temperature")
- {
- unit = "/ReadingCelsius"_json_pointer;
- sensorJson["@odata.type"] = "#Thermal.v1_3_0.Temperature";
- // TODO(ed) Documentation says that path should be type fan_tach,
- // implementation seems to implement fan
- }
- else if (sensorType == "fan" || sensorType == "fan_tach")
- {
- unit = "/Reading"_json_pointer;
- sensorJson["ReadingUnits"] = "RPM";
- sensorJson["@odata.type"] = "#Thermal.v1_3_0.Fan";
- setLedState(sensorJson, inventoryItem);
- forceToInt = true;
- }
- else if (sensorType == "fan_pwm")
- {
- unit = "/Reading"_json_pointer;
- sensorJson["ReadingUnits"] = "Percent";
- sensorJson["@odata.type"] = "#Thermal.v1_3_0.Fan";
- setLedState(sensorJson, inventoryItem);
- forceToInt = true;
- }
- else if (sensorType == "voltage")
- {
- unit = "/ReadingVolts"_json_pointer;
- sensorJson["@odata.type"] = "#Power.v1_0_0.Voltage";
- }
- else if (sensorType == "power")
- {
- std::string lower;
- std::ranges::transform(sensorName, std::back_inserter(lower),
- bmcweb::asciiToLower);
- if (lower == "total_power")
- {
- sensorJson["@odata.type"] = "#Power.v1_0_0.PowerControl";
- // Put multiple "sensors" into a single PowerControl, so have
- // generic names for MemberId and Name. Follows Redfish mockup.
- sensorJson["MemberId"] = "0";
- sensorJson["Name"] = "Chassis Power Control";
- unit = "/PowerConsumedWatts"_json_pointer;
- }
- else if (lower.find("input") != std::string::npos)
- {
- unit = "/PowerInputWatts"_json_pointer;
- }
- else
- {
- unit = "/PowerOutputWatts"_json_pointer;
- }
- }
- else
- {
- BMCWEB_LOG_ERROR("Redfish cannot map object type for {}", sensorName);
- return;
- }
- // Map of dbus interface name, dbus property name and redfish property_name
- std::vector<
- std::tuple<const char*, const char*, nlohmann::json::json_pointer>>
- properties;
- properties.reserve(7);
-
- properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
-
- if (chassisSubNode == sensors::node::sensors)
- {
- properties.emplace_back(
- "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningHigh",
- "/Thresholds/UpperCaution/Reading"_json_pointer);
- properties.emplace_back(
- "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningLow",
- "/Thresholds/LowerCaution/Reading"_json_pointer);
- properties.emplace_back(
- "xyz.openbmc_project.Sensor.Threshold.Critical", "CriticalHigh",
- "/Thresholds/UpperCritical/Reading"_json_pointer);
- properties.emplace_back(
- "xyz.openbmc_project.Sensor.Threshold.Critical", "CriticalLow",
- "/Thresholds/LowerCritical/Reading"_json_pointer);
- }
- else if (sensorType != "power")
- {
- properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
- "WarningHigh",
- "/UpperThresholdNonCritical"_json_pointer);
- properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
- "WarningLow",
- "/LowerThresholdNonCritical"_json_pointer);
- properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
- "CriticalHigh",
- "/UpperThresholdCritical"_json_pointer);
- properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
- "CriticalLow",
- "/LowerThresholdCritical"_json_pointer);
- }
-
- // TODO Need to get UpperThresholdFatal and LowerThresholdFatal
-
- if (chassisSubNode == sensors::node::sensors)
- {
- properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
- "/ReadingRangeMin"_json_pointer);
- properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
- "/ReadingRangeMax"_json_pointer);
- properties.emplace_back("xyz.openbmc_project.Sensor.Accuracy",
- "Accuracy", "/Accuracy"_json_pointer);
- }
- else if (sensorType == "temperature")
- {
- properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
- "/MinReadingRangeTemp"_json_pointer);
- properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
- "/MaxReadingRangeTemp"_json_pointer);
- }
- else if (sensorType != "power")
- {
- properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
- "/MinReadingRange"_json_pointer);
- properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
- "/MaxReadingRange"_json_pointer);
- }
-
- for (const std::tuple<const char*, const char*,
- nlohmann::json::json_pointer>& p : properties)
- {
- for (const auto& [valueName, valueVariant] : propertiesDict)
- {
- if (valueName != std::get<1>(p))
- {
- continue;
- }
-
- // The property we want to set may be nested json, so use
- // a json_pointer for easy indexing into the json structure.
- const nlohmann::json::json_pointer& key = std::get<2>(p);
-
- const double* doubleValue = std::get_if<double>(&valueVariant);
- if (doubleValue == nullptr)
- {
- BMCWEB_LOG_ERROR("Got value interface that wasn't double");
- continue;
- }
- if (!std::isfinite(*doubleValue))
- {
- if (valueName == "Value")
+ if (chassisName == chassisIdStr)
{
- // Readings are allowed to be NAN for unavailable; coerce
- // them to null in the json response.
- sensorJson[key] = nullptr;
- continue;
+ chassisPath = &chassis;
+ break;
}
- BMCWEB_LOG_WARNING("Sensor value for {} was unexpectedly {}",
- valueName, *doubleValue);
- continue;
- }
- if (forceToInt)
- {
- sensorJson[key] = static_cast<int64_t>(*doubleValue);
}
- else
+ if (chassisPath == nullptr)
{
- sensorJson[key] = *doubleValue;
+ messages::resourceNotFound(asyncResp->res, "Chassis",
+ chassisIdStr);
+ return;
}
- }
- }
+ populateChassisNode(asyncResp->res.jsonValue, chassisSubNode);
+
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}/{}", chassisIdStr, chassisSubNode);
+
+ // Get the list of all sensors for this Chassis element
+ std::string sensorPath = *chassisPath + "/all_sensors";
+ dbus::utility::getAssociationEndPoints(
+ sensorPath, [asyncResp, chassisSubNode, sensorTypes,
+ callback = std::forward<Callback>(callback)](
+ const boost::system::error_code& ec2,
+ const dbus::utility::MapperEndPoints&
+ nodeSensorList) mutable {
+ if (ec2)
+ {
+ if (ec2.value() != EBADR)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+ const std::shared_ptr<std::set<std::string>>
+ culledSensorList =
+ std::make_shared<std::set<std::string>>();
+ reduceSensorList(asyncResp->res, chassisSubNode,
+ sensorTypes, &nodeSensorList,
+ culledSensorList);
+ BMCWEB_LOG_DEBUG("Finishing with {}",
+ culledSensorList->size());
+ callback(culledSensorList);
+ });
+ });
+ BMCWEB_LOG_DEBUG("getChassis exit");
}
/**
@@ -1002,14 +494,15 @@ inline void objectPropertiesToJson(
*/
inline void objectInterfacesToJson(
const std::string& sensorName, const std::string& sensorType,
- const std::string& chassisSubNode,
+ const sensor_utils::ChassisSubNode chassisSubNode,
const dbus::utility::DBusInterfacesMap& interfacesDict,
nlohmann::json& sensorJson, InventoryItem* inventoryItem)
{
for (const auto& [interface, valuesDict] : interfacesDict)
{
- objectPropertiesToJson(sensorName, sensorType, chassisSubNode,
- valuesDict, sensorJson, inventoryItem);
+ sensor_utils::objectPropertiesToJson(
+ sensorName, sensorType, chassisSubNode, valuesDict, sensorJson,
+ inventoryItem);
}
BMCWEB_LOG_DEBUG("Added sensor {}", sensorName);
}
@@ -1024,167 +517,184 @@ inline void populateFanRedundancy(
[sensorsAsyncResp](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& resp) {
- if (ec)
- {
- return; // don't have to have this interface
- }
- for (const std::pair<std::string, dbus::utility::MapperServiceMap>&
- pathPair : resp)
- {
- const std::string& path = pathPair.first;
- const dbus::utility::MapperServiceMap& objDict = pathPair.second;
- if (objDict.empty())
+ if (ec)
{
- continue; // this should be impossible
+ return; // don't have to have this interface
}
-
- const std::string& owner = objDict.begin()->first;
- dbus::utility::getAssociationEndPoints(
- path + "/chassis",
- [path, owner, sensorsAsyncResp](
- const boost::system::error_code& ec2,
- const dbus::utility::MapperEndPoints& endpoints) {
- if (ec2)
+ for (const std::pair<std::string, dbus::utility::MapperServiceMap>&
+ pathPair : resp)
+ {
+ const std::string& path = pathPair.first;
+ const dbus::utility::MapperServiceMap& objDict =
+ pathPair.second;
+ if (objDict.empty())
{
- return; // if they don't have an association we
- // can't tell what chassis is
+ continue; // this should be impossible
}
- auto found = std::ranges::find_if(
- endpoints, [sensorsAsyncResp](const std::string& entry) {
- return entry.find(sensorsAsyncResp->chassisId) !=
- std::string::npos;
- });
- if (found == endpoints.end())
- {
- return;
- }
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, owner, path,
- "xyz.openbmc_project.Control.FanRedundancy",
- [path, sensorsAsyncResp](
- const boost::system::error_code& ec3,
- const dbus::utility::DBusPropertiesMap& ret) {
- if (ec3)
- {
- return; // don't have to have this
- // interface
- }
+ const std::string& owner = objDict.begin()->first;
+ dbus::utility::getAssociationEndPoints(
+ path + "/chassis",
+ [path, owner, sensorsAsyncResp](
+ const boost::system::error_code& ec2,
+ const dbus::utility::MapperEndPoints& endpoints) {
+ if (ec2)
+ {
+ return; // if they don't have an association we
+ // can't tell what chassis is
+ }
+ auto found = std::ranges::find_if(
+ endpoints,
+ [sensorsAsyncResp](const std::string& entry) {
+ return entry.find(
+ sensorsAsyncResp->chassisId) !=
+ std::string::npos;
+ });
+
+ if (found == endpoints.end())
+ {
+ return;
+ }
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, owner, path,
+ "xyz.openbmc_project.Control.FanRedundancy",
+ [path, sensorsAsyncResp](
+ const boost::system::error_code& ec3,
+ const dbus::utility::DBusPropertiesMap& ret) {
+ if (ec3)
+ {
+ return; // don't have to have this
+ // interface
+ }
- const uint8_t* allowedFailures = nullptr;
- const std::vector<std::string>* collection = nullptr;
- const std::string* status = nullptr;
+ const uint8_t* allowedFailures = nullptr;
+ const std::vector<std::string>* collection =
+ nullptr;
+ const std::string* status = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), ret,
- "AllowedFailures", allowedFailures, "Collection",
- collection, "Status", status);
+ const bool success =
+ sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), ret,
+ "AllowedFailures", allowedFailures,
+ "Collection", collection, "Status",
+ status);
- if (!success)
- {
- messages::internalError(
- sensorsAsyncResp->asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(
+ sensorsAsyncResp->asyncResp->res);
+ return;
+ }
- if (allowedFailures == nullptr || collection == nullptr ||
- status == nullptr)
- {
- BMCWEB_LOG_ERROR("Invalid redundancy interface");
- messages::internalError(
- sensorsAsyncResp->asyncResp->res);
- return;
- }
+ if (allowedFailures == nullptr ||
+ collection == nullptr || status == nullptr)
+ {
+ BMCWEB_LOG_ERROR(
+ "Invalid redundancy interface");
+ messages::internalError(
+ sensorsAsyncResp->asyncResp->res);
+ return;
+ }
- sdbusplus::message::object_path objectPath(path);
- std::string name = objectPath.filename();
- if (name.empty())
- {
- // this should be impossible
- messages::internalError(
- sensorsAsyncResp->asyncResp->res);
- return;
- }
- std::ranges::replace(name, '_', ' ');
+ sdbusplus::message::object_path objectPath(
+ path);
+ std::string name = objectPath.filename();
+ if (name.empty())
+ {
+ // this should be impossible
+ messages::internalError(
+ sensorsAsyncResp->asyncResp->res);
+ return;
+ }
+ std::ranges::replace(name, '_', ' ');
- std::string health;
+ std::string health;
- if (status->ends_with("Full"))
- {
- health = "OK";
- }
- else if (status->ends_with("Degraded"))
- {
- health = "Warning";
- }
- else
- {
- health = "Critical";
- }
- nlohmann::json::array_t redfishCollection;
- const auto& fanRedfish =
- sensorsAsyncResp->asyncResp->res.jsonValue["Fans"];
- for (const std::string& item : *collection)
- {
- sdbusplus::message::object_path itemPath(item);
- std::string itemName = itemPath.filename();
- if (itemName.empty())
- {
- continue;
- }
- /*
- todo(ed): merge patch that fixes the names
- std::replace(itemName.begin(),
- itemName.end(), '_', ' ');*/
- auto schemaItem = std::ranges::find_if(
- fanRedfish, [itemName](const nlohmann::json& fan) {
- return fan["Name"] == itemName;
- });
- if (schemaItem != fanRedfish.end())
- {
- nlohmann::json::object_t collectionId;
- collectionId["@odata.id"] =
- (*schemaItem)["@odata.id"];
- redfishCollection.emplace_back(
- std::move(collectionId));
- }
- else
- {
- BMCWEB_LOG_ERROR("failed to find fan in schema");
- messages::internalError(
- sensorsAsyncResp->asyncResp->res);
- return;
- }
- }
+ if (status->ends_with("Full"))
+ {
+ health = "OK";
+ }
+ else if (status->ends_with("Degraded"))
+ {
+ health = "Warning";
+ }
+ else
+ {
+ health = "Critical";
+ }
+ nlohmann::json::array_t redfishCollection;
+ const auto& fanRedfish =
+ sensorsAsyncResp->asyncResp->res
+ .jsonValue["Fans"];
+ for (const std::string& item : *collection)
+ {
+ sdbusplus::message::object_path itemPath(
+ item);
+ std::string itemName = itemPath.filename();
+ if (itemName.empty())
+ {
+ continue;
+ }
+ /*
+ todo(ed): merge patch that fixes the names
+ std::replace(itemName.begin(),
+ itemName.end(), '_', ' ');*/
+ auto schemaItem = std::ranges::find_if(
+ fanRedfish,
+ [itemName](const nlohmann::json& fan) {
+ return fan["Name"] == itemName;
+ });
+ if (schemaItem != fanRedfish.end())
+ {
+ nlohmann::json::object_t collectionId;
+ collectionId["@odata.id"] =
+ (*schemaItem)["@odata.id"];
+ redfishCollection.emplace_back(
+ std::move(collectionId));
+ }
+ else
+ {
+ BMCWEB_LOG_ERROR(
+ "failed to find fan in schema");
+ messages::internalError(
+ sensorsAsyncResp->asyncResp->res);
+ return;
+ }
+ }
- size_t minNumNeeded = collection->empty()
- ? 0
- : collection->size() -
- *allowedFailures;
- nlohmann::json& jResp = sensorsAsyncResp->asyncResp->res
- .jsonValue["Redundancy"];
-
- nlohmann::json::object_t redundancy;
- boost::urls::url url =
- boost::urls::format("/redfish/v1/Chassis/{}/{}",
- sensorsAsyncResp->chassisId,
- sensorsAsyncResp->chassisSubNode);
- url.set_fragment(("/Redundancy"_json_pointer / jResp.size())
- .to_string());
- redundancy["@odata.id"] = std::move(url);
- redundancy["@odata.type"] = "#Redundancy.v1_3_2.Redundancy";
- redundancy["MinNumNeeded"] = minNumNeeded;
- redundancy["Mode"] = "N+m";
- redundancy["Name"] = name;
- redundancy["RedundancySet"] = redfishCollection;
- redundancy["Status"]["Health"] = health;
- redundancy["Status"]["State"] = "Enabled";
-
- jResp.emplace_back(std::move(redundancy));
- });
- });
- }
- });
+ size_t minNumNeeded =
+ collection->empty()
+ ? 0
+ : collection->size() - *allowedFailures;
+ nlohmann::json& jResp =
+ sensorsAsyncResp->asyncResp->res
+ .jsonValue["Redundancy"];
+
+ nlohmann::json::object_t redundancy;
+ boost::urls::url url = boost::urls::format(
+ "/redfish/v1/Chassis/{}/{}",
+ sensorsAsyncResp->chassisId,
+ sensorsAsyncResp->chassisSubNode);
+ url.set_fragment(
+ ("/Redundancy"_json_pointer / jResp.size())
+ .to_string());
+ redundancy["@odata.id"] = std::move(url);
+ redundancy["@odata.type"] =
+ "#Redundancy.v1_3_2.Redundancy";
+ redundancy["MinNumNeeded"] = minNumNeeded;
+ redundancy["Mode"] =
+ redundancy::RedundancyType::NPlusM;
+ redundancy["Name"] = name;
+ redundancy["RedundancySet"] = redfishCollection;
+ redundancy["Status"]["Health"] = health;
+ redundancy["Status"]["State"] =
+ resource::State::Enabled;
+
+ jResp.emplace_back(std::move(redundancy));
+ });
+ });
+ }
+ });
}
inline void
@@ -1192,37 +702,41 @@ inline void
{
nlohmann::json& response = sensorsAsyncResp->asyncResp->res.jsonValue;
std::array<std::string, 2> sensorHeaders{"Temperatures", "Fans"};
- if (sensorsAsyncResp->chassisSubNode == sensors::node::power)
+ if (sensorsAsyncResp->chassisSubNode == sensors::powerNodeStr)
{
sensorHeaders = {"Voltages", "PowerSupplies"};
}
for (const std::string& sensorGroup : sensorHeaders)
{
nlohmann::json::iterator entry = response.find(sensorGroup);
- if (entry != response.end())
+ if (entry == response.end())
{
- std::sort(entry->begin(), entry->end(),
- [](const nlohmann::json& c1, const nlohmann::json& c2) {
- return c1["Name"] < c2["Name"];
- });
+ continue;
+ }
+ nlohmann::json::array_t* arr =
+ entry->get_ptr<nlohmann::json::array_t*>();
+ if (arr == nullptr)
+ {
+ continue;
+ }
+ json_util::sortJsonArrayByKey(*arr, "Name");
- // add the index counts to the end of each entry
- size_t count = 0;
- for (nlohmann::json& sensorJson : *entry)
+ // add the index counts to the end of each entry
+ size_t count = 0;
+ for (nlohmann::json& sensorJson : *entry)
+ {
+ nlohmann::json::iterator odata = sensorJson.find("@odata.id");
+ if (odata == sensorJson.end())
{
- nlohmann::json::iterator odata = sensorJson.find("@odata.id");
- if (odata == sensorJson.end())
- {
- continue;
- }
- std::string* value = odata->get_ptr<std::string*>();
- if (value != nullptr)
- {
- *value += "/" + std::to_string(count);
- sensorJson["MemberId"] = std::to_string(count);
- count++;
- sensorsAsyncResp->updateUri(sensorJson["Name"], *value);
- }
+ continue;
+ }
+ std::string* value = odata->get_ptr<std::string*>();
+ if (value != nullptr)
+ {
+ *value += "/" + std::to_string(count);
+ sensorJson["MemberId"] = std::to_string(count);
+ count++;
+ sensorsAsyncResp->updateUri(sensorJson["Name"], *value);
}
}
}
@@ -1274,9 +788,8 @@ inline InventoryItem* findInventoryItemForSensor(
* @param ledObjPath D-Bus object path of led.
* @return Inventory item within vector, or nullptr if no match found.
*/
-inline InventoryItem*
- findInventoryItemForLed(std::vector<InventoryItem>& inventoryItems,
- const std::string& ledObjPath)
+inline InventoryItem* findInventoryItemForLed(
+ std::vector<InventoryItem>& inventoryItems, const std::string& ledObjPath)
{
for (InventoryItem& inventoryItem : inventoryItems)
{
@@ -1307,8 +820,8 @@ inline void addInventoryItem(
const std::string& invItemObjPath, const std::string& sensorObjPath)
{
// Look for inventory item in vector
- InventoryItem* inventoryItem = findInventoryItem(inventoryItems,
- invItemObjPath);
+ InventoryItem* inventoryItem =
+ findInventoryItem(inventoryItems, invItemObjPath);
// If inventory item doesn't exist in vector, add it
if (inventoryItem == nullptr)
@@ -1456,7 +969,7 @@ inline void storeInventoryItemData(
* in recursive calls to this function.
*/
template <typename Callback>
-static void getInventoryItemsData(
+void getInventoryItemsData(
std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp,
std::shared_ptr<std::vector<InventoryItem>> inventoryItems,
std::shared_ptr<std::set<std::string>> invConnections, Callback&& callback,
@@ -1486,39 +999,41 @@ static void getInventoryItemsData(
[sensorsAsyncResp, inventoryItems, invConnections,
callback = std::forward<Callback>(callback), invConnectionsIndex](
const boost::system::error_code& ec,
- const dbus::utility::ManagedObjectType& resp) {
- BMCWEB_LOG_DEBUG("getInventoryItemsData respHandler enter");
- if (ec)
- {
- BMCWEB_LOG_ERROR(
- "getInventoryItemsData respHandler DBus error {}", ec);
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- return;
- }
-
- // Loop through returned object paths
- for (const auto& objDictEntry : resp)
- {
- const std::string& objPath =
- static_cast<const std::string&>(objDictEntry.first);
+ const dbus::utility::ManagedObjectType& resp) mutable {
+ BMCWEB_LOG_DEBUG("getInventoryItemsData respHandler enter");
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR(
+ "getInventoryItemsData respHandler DBus error {}", ec);
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ return;
+ }
- // If this object path is one of the specified inventory items
- InventoryItem* inventoryItem = findInventoryItem(inventoryItems,
- objPath);
- if (inventoryItem != nullptr)
+ // Loop through returned object paths
+ for (const auto& objDictEntry : resp)
{
- // Store inventory data in InventoryItem
- storeInventoryItemData(*inventoryItem, objDictEntry.second);
+ const std::string& objPath =
+ static_cast<const std::string&>(objDictEntry.first);
+
+ // If this object path is one of the specified inventory
+ // items
+ InventoryItem* inventoryItem =
+ findInventoryItem(inventoryItems, objPath);
+ if (inventoryItem != nullptr)
+ {
+ // Store inventory data in InventoryItem
+ storeInventoryItemData(*inventoryItem,
+ objDictEntry.second);
+ }
}
- }
- // Recurse to get inventory item data from next connection
- getInventoryItemsData(sensorsAsyncResp, inventoryItems,
- invConnections, std::move(callback),
- invConnectionsIndex + 1);
+ // Recurse to get inventory item data from next connection
+ getInventoryItemsData(sensorsAsyncResp, inventoryItems,
+ invConnections, std::move(callback),
+ invConnectionsIndex + 1);
- BMCWEB_LOG_DEBUG("getInventoryItemsData respHandler exit");
- });
+ BMCWEB_LOG_DEBUG("getInventoryItemsData respHandler exit");
+ });
}
BMCWEB_LOG_DEBUG("getInventoryItemsData exit");
@@ -1543,7 +1058,7 @@ static void getInventoryItemsData(
* @param callback Callback to invoke when connections have been obtained.
*/
template <typename Callback>
-static void getInventoryItemsConnections(
+void getInventoryItemsConnections(
const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
const std::shared_ptr<std::vector<InventoryItem>>& inventoryItems,
Callback&& callback)
@@ -1563,44 +1078,45 @@ static void getInventoryItemsConnections(
[callback = std::forward<Callback>(callback), sensorsAsyncResp,
inventoryItems](
const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- // Response handler for parsing output from GetSubTree
- BMCWEB_LOG_DEBUG("getInventoryItemsConnections respHandler enter");
- if (ec)
- {
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- BMCWEB_LOG_ERROR(
- "getInventoryItemsConnections respHandler DBus error {}", ec);
- return;
- }
+ const dbus::utility::MapperGetSubTreeResponse& subtree) mutable {
+ // Response handler for parsing output from GetSubTree
+ BMCWEB_LOG_DEBUG("getInventoryItemsConnections respHandler enter");
+ if (ec)
+ {
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ BMCWEB_LOG_ERROR(
+ "getInventoryItemsConnections respHandler DBus error {}",
+ ec);
+ return;
+ }
- // Make unique list of connections for desired inventory items
- std::shared_ptr<std::set<std::string>> invConnections =
- std::make_shared<std::set<std::string>>();
+ // Make unique list of connections for desired inventory items
+ std::shared_ptr<std::set<std::string>> invConnections =
+ std::make_shared<std::set<std::string>>();
- // Loop through objects from GetSubTree
- for (const std::pair<
- std::string,
- std::vector<std::pair<std::string, std::vector<std::string>>>>&
- object : subtree)
- {
- // Check if object path is one of the specified inventory items
- const std::string& objPath = object.first;
- if (findInventoryItem(inventoryItems, objPath) != nullptr)
+ // Loop through objects from GetSubTree
+ for (const std::pair<std::string,
+ std::vector<std::pair<
+ std::string, std::vector<std::string>>>>&
+ object : subtree)
{
- // Store all connections to inventory item
- for (const std::pair<std::string, std::vector<std::string>>&
- objData : object.second)
+ // Check if object path is one of the specified inventory items
+ const std::string& objPath = object.first;
+ if (findInventoryItem(inventoryItems, objPath) != nullptr)
{
- const std::string& invConnection = objData.first;
- invConnections->insert(invConnection);
+ // Store all connections to inventory item
+ for (const std::pair<std::string, std::vector<std::string>>&
+ objData : object.second)
+ {
+ const std::string& invConnection = objData.first;
+ invConnections->insert(invConnection);
+ }
}
}
- }
- callback(invConnections);
- BMCWEB_LOG_DEBUG("getInventoryItemsConnections respHandler exit");
- });
+ callback(invConnections);
+ BMCWEB_LOG_DEBUG("getInventoryItemsConnections respHandler exit");
+ });
BMCWEB_LOG_DEBUG("getInventoryItemsConnections exit");
}
@@ -1625,7 +1141,7 @@ static void getInventoryItemsConnections(
* @param callback Callback to invoke when inventory items have been obtained.
*/
template <typename Callback>
-static void getInventoryItemAssociations(
+void getInventoryItemAssociations(
const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
const std::shared_ptr<std::set<std::string>>& sensorNames,
Callback&& callback)
@@ -1638,113 +1154,120 @@ static void getInventoryItemAssociations(
"xyz.openbmc_project.ObjectMapper", path,
[callback = std::forward<Callback>(callback), sensorsAsyncResp,
sensorNames](const boost::system::error_code& ec,
- const dbus::utility::ManagedObjectType& resp) {
- BMCWEB_LOG_DEBUG("getInventoryItemAssociations respHandler enter");
- if (ec)
- {
- BMCWEB_LOG_ERROR(
- "getInventoryItemAssociations respHandler DBus error {}", ec);
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- return;
- }
-
- // Create vector to hold list of inventory items
- std::shared_ptr<std::vector<InventoryItem>> inventoryItems =
- std::make_shared<std::vector<InventoryItem>>();
+ const dbus::utility::ManagedObjectType& resp) mutable {
+ BMCWEB_LOG_DEBUG("getInventoryItemAssociations respHandler enter");
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR(
+ "getInventoryItemAssociations respHandler DBus error {}",
+ ec);
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ return;
+ }
- // Loop through returned object paths
- std::string sensorAssocPath;
- sensorAssocPath.reserve(128); // avoid memory allocations
- for (const auto& objDictEntry : resp)
- {
- const std::string& objPath =
- static_cast<const std::string&>(objDictEntry.first);
+ // Create vector to hold list of inventory items
+ std::shared_ptr<std::vector<InventoryItem>> inventoryItems =
+ std::make_shared<std::vector<InventoryItem>>();
- // If path is inventory association for one of the specified sensors
- for (const std::string& sensorName : *sensorNames)
+ // Loop through returned object paths
+ std::string sensorAssocPath;
+ sensorAssocPath.reserve(128); // avoid memory allocations
+ for (const auto& objDictEntry : resp)
{
- sensorAssocPath = sensorName;
- sensorAssocPath += "/inventory";
- if (objPath == sensorAssocPath)
+ const std::string& objPath =
+ static_cast<const std::string&>(objDictEntry.first);
+
+ // If path is inventory association for one of the specified
+ // sensors
+ for (const std::string& sensorName : *sensorNames)
{
- // Get Association interface for object path
- for (const auto& [interface, values] : objDictEntry.second)
+ sensorAssocPath = sensorName;
+ sensorAssocPath += "/inventory";
+ if (objPath == sensorAssocPath)
{
- if (interface == "xyz.openbmc_project.Association")
+ // Get Association interface for object path
+ for (const auto& [interface, values] :
+ objDictEntry.second)
{
- for (const auto& [valueName, value] : values)
+ if (interface == "xyz.openbmc_project.Association")
{
- if (valueName == "endpoints")
+ for (const auto& [valueName, value] : values)
{
- const std::vector<std::string>* endpoints =
- std::get_if<std::vector<std::string>>(
- &value);
- if ((endpoints != nullptr) &&
- !endpoints->empty())
+ if (valueName == "endpoints")
{
- // Add inventory item to vector
- const std::string& invItemPath =
- endpoints->front();
- addInventoryItem(inventoryItems,
- invItemPath,
- sensorName);
+ const std::vector<std::string>*
+ endpoints = std::get_if<
+ std::vector<std::string>>(
+ &value);
+ if ((endpoints != nullptr) &&
+ !endpoints->empty())
+ {
+ // Add inventory item to vector
+ const std::string& invItemPath =
+ endpoints->front();
+ addInventoryItem(inventoryItems,
+ invItemPath,
+ sensorName);
+ }
}
}
}
}
+ break;
}
- break;
}
}
- }
-
- // Now loop through the returned object paths again, this time to
- // find the leds associated with the inventory items we just found
- std::string inventoryAssocPath;
- inventoryAssocPath.reserve(128); // avoid memory allocations
- for (const auto& objDictEntry : resp)
- {
- const std::string& objPath =
- static_cast<const std::string&>(objDictEntry.first);
- for (InventoryItem& inventoryItem : *inventoryItems)
+ // Now loop through the returned object paths again, this time to
+ // find the leds associated with the inventory items we just found
+ std::string inventoryAssocPath;
+ inventoryAssocPath.reserve(128); // avoid memory allocations
+ for (const auto& objDictEntry : resp)
{
- inventoryAssocPath = inventoryItem.objectPath;
- inventoryAssocPath += "/leds";
- if (objPath == inventoryAssocPath)
+ const std::string& objPath =
+ static_cast<const std::string&>(objDictEntry.first);
+
+ for (InventoryItem& inventoryItem : *inventoryItems)
{
- for (const auto& [interface, values] : objDictEntry.second)
+ inventoryAssocPath = inventoryItem.objectPath;
+ inventoryAssocPath += "/leds";
+ if (objPath == inventoryAssocPath)
{
- if (interface == "xyz.openbmc_project.Association")
+ for (const auto& [interface, values] :
+ objDictEntry.second)
{
- for (const auto& [valueName, value] : values)
+ if (interface == "xyz.openbmc_project.Association")
{
- if (valueName == "endpoints")
+ for (const auto& [valueName, value] : values)
{
- const std::vector<std::string>* endpoints =
- std::get_if<std::vector<std::string>>(
- &value);
- if ((endpoints != nullptr) &&
- !endpoints->empty())
+ if (valueName == "endpoints")
{
- // Add inventory item to vector
- // Store LED path in inventory item
- const std::string& ledPath =
- endpoints->front();
- inventoryItem.ledObjectPath = ledPath;
+ const std::vector<std::string>*
+ endpoints = std::get_if<
+ std::vector<std::string>>(
+ &value);
+ if ((endpoints != nullptr) &&
+ !endpoints->empty())
+ {
+ // Add inventory item to vector
+ // Store LED path in inventory item
+ const std::string& ledPath =
+ endpoints->front();
+ inventoryItem.ledObjectPath =
+ ledPath;
+ }
}
}
}
}
- }
- break;
+ break;
+ }
}
}
- }
- callback(inventoryItems);
- BMCWEB_LOG_DEBUG("getInventoryItemAssociations respHandler exit");
- });
+ callback(inventoryItems);
+ BMCWEB_LOG_DEBUG("getInventoryItemAssociations respHandler exit");
+ });
BMCWEB_LOG_DEBUG("getInventoryItemAssociations exit");
}
@@ -1805,49 +1328,51 @@ void getInventoryLedData(
// Response handler for Get State property
auto respHandler =
[sensorsAsyncResp, inventoryItems, ledConnections, ledPath,
- callback = std::forward<Callback>(callback), ledConnectionsIndex](
- const boost::system::error_code& ec, const std::string& state) {
- BMCWEB_LOG_DEBUG("getInventoryLedData respHandler enter");
- if (ec)
- {
- BMCWEB_LOG_ERROR(
- "getInventoryLedData respHandler DBus error {}", ec);
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- return;
- }
-
- BMCWEB_LOG_DEBUG("Led state: {}", state);
- // Find inventory item with this LED object path
- InventoryItem* inventoryItem =
- findInventoryItemForLed(*inventoryItems, ledPath);
- if (inventoryItem != nullptr)
- {
- // Store LED state in InventoryItem
- if (state.ends_with("On"))
- {
- inventoryItem->ledState = LedState::ON;
- }
- else if (state.ends_with("Blink"))
- {
- inventoryItem->ledState = LedState::BLINK;
- }
- else if (state.ends_with("Off"))
+ callback = std::forward<Callback>(callback),
+ ledConnectionsIndex](const boost::system::error_code& ec,
+ const std::string& state) mutable {
+ BMCWEB_LOG_DEBUG("getInventoryLedData respHandler enter");
+ if (ec)
{
- inventoryItem->ledState = LedState::OFF;
+ BMCWEB_LOG_ERROR(
+ "getInventoryLedData respHandler DBus error {}", ec);
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ return;
}
- else
+
+ BMCWEB_LOG_DEBUG("Led state: {}", state);
+ // Find inventory item with this LED object path
+ InventoryItem* inventoryItem =
+ findInventoryItemForLed(*inventoryItems, ledPath);
+ if (inventoryItem != nullptr)
{
- inventoryItem->ledState = LedState::UNKNOWN;
+ // Store LED state in InventoryItem
+ if (state.ends_with("On"))
+ {
+ inventoryItem->ledState = sensor_utils::LedState::ON;
+ }
+ else if (state.ends_with("Blink"))
+ {
+ inventoryItem->ledState = sensor_utils::LedState::BLINK;
+ }
+ else if (state.ends_with("Off"))
+ {
+ inventoryItem->ledState = sensor_utils::LedState::OFF;
+ }
+ else
+ {
+ inventoryItem->ledState =
+ sensor_utils::LedState::UNKNOWN;
+ }
}
- }
- // Recurse to get LED data from next connection
- getInventoryLedData(sensorsAsyncResp, inventoryItems,
- ledConnections, std::move(callback),
- ledConnectionsIndex + 1);
+ // Recurse to get LED data from next connection
+ getInventoryLedData(sensorsAsyncResp, inventoryItems,
+ ledConnections, std::move(callback),
+ ledConnectionsIndex + 1);
- BMCWEB_LOG_DEBUG("getInventoryLedData respHandler exit");
- };
+ BMCWEB_LOG_DEBUG("getInventoryLedData respHandler exit");
+ };
// Get the State property for the current LED
sdbusplus::asio::getProperty<std::string>(
@@ -1899,42 +1424,46 @@ void getInventoryLeds(
[callback = std::forward<Callback>(callback), sensorsAsyncResp,
inventoryItems](
const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- // Response handler for parsing output from GetSubTree
- BMCWEB_LOG_DEBUG("getInventoryLeds respHandler enter");
- if (ec)
- {
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- BMCWEB_LOG_ERROR("getInventoryLeds respHandler DBus error {}", ec);
- return;
- }
+ const dbus::utility::MapperGetSubTreeResponse& subtree) mutable {
+ // Response handler for parsing output from GetSubTree
+ BMCWEB_LOG_DEBUG("getInventoryLeds respHandler enter");
+ if (ec)
+ {
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ BMCWEB_LOG_ERROR("getInventoryLeds respHandler DBus error {}",
+ ec);
+ return;
+ }
- // Build map of LED object paths to connections
- std::shared_ptr<std::map<std::string, std::string>> ledConnections =
- std::make_shared<std::map<std::string, std::string>>();
+ // Build map of LED object paths to connections
+ std::shared_ptr<std::map<std::string, std::string>> ledConnections =
+ std::make_shared<std::map<std::string, std::string>>();
- // Loop through objects from GetSubTree
- for (const std::pair<
- std::string,
- std::vector<std::pair<std::string, std::vector<std::string>>>>&
- object : subtree)
- {
- // Check if object path is LED for one of the specified inventory
- // items
- const std::string& ledPath = object.first;
- if (findInventoryItemForLed(*inventoryItems, ledPath) != nullptr)
+ // Loop through objects from GetSubTree
+ for (const std::pair<std::string,
+ std::vector<std::pair<
+ std::string, std::vector<std::string>>>>&
+ object : subtree)
{
- // Add mapping from ledPath to connection
- const std::string& connection = object.second.begin()->first;
- (*ledConnections)[ledPath] = connection;
- BMCWEB_LOG_DEBUG("Added mapping {} -> {}", ledPath, connection);
+ // Check if object path is LED for one of the specified
+ // inventory items
+ const std::string& ledPath = object.first;
+ if (findInventoryItemForLed(*inventoryItems, ledPath) !=
+ nullptr)
+ {
+ // Add mapping from ledPath to connection
+ const std::string& connection =
+ object.second.begin()->first;
+ (*ledConnections)[ledPath] = connection;
+ BMCWEB_LOG_DEBUG("Added mapping {} -> {}", ledPath,
+ connection);
+ }
}
- }
- getInventoryLedData(sensorsAsyncResp, inventoryItems, ledConnections,
- std::move(callback));
- BMCWEB_LOG_DEBUG("getInventoryLeds respHandler exit");
- });
+ getInventoryLedData(sensorsAsyncResp, inventoryItems,
+ ledConnections, std::move(callback));
+ BMCWEB_LOG_DEBUG("getInventoryLeds respHandler exit");
+ });
BMCWEB_LOG_DEBUG("getInventoryLeds exit");
}
@@ -1988,7 +1517,7 @@ void getPowerSupplyAttributesData(
auto respHandler = [sensorsAsyncResp, inventoryItems,
callback = std::forward<Callback>(callback)](
const boost::system::error_code& ec,
- const uint32_t value) {
+ uint32_t value) mutable {
BMCWEB_LOG_DEBUG("getPowerSupplyAttributesData respHandler enter");
if (ec)
{
@@ -2055,7 +1584,7 @@ void getPowerSupplyAttributes(
BMCWEB_LOG_DEBUG("getPowerSupplyAttributes enter");
// Only need the power supply attributes when the Power Schema
- if (sensorsAsyncResp->chassisSubNode != sensors::node::power)
+ if (sensorsAsyncResp->chassisSubNode != sensors::powerNodeStr)
{
BMCWEB_LOG_DEBUG("getPowerSupplyAttributes exit since not Power");
callback(inventoryItems);
@@ -2071,54 +1600,54 @@ void getPowerSupplyAttributes(
[callback = std::forward<Callback>(callback), sensorsAsyncResp,
inventoryItems](
const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- // Response handler for parsing output from GetSubTree
- BMCWEB_LOG_DEBUG("getPowerSupplyAttributes respHandler enter");
- if (ec)
- {
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- BMCWEB_LOG_ERROR(
- "getPowerSupplyAttributes respHandler DBus error {}", ec);
- return;
- }
- if (subtree.empty())
- {
- BMCWEB_LOG_DEBUG("Can't find Power Supply Attributes!");
- callback(inventoryItems);
- return;
- }
+ const dbus::utility::MapperGetSubTreeResponse& subtree) mutable {
+ // Response handler for parsing output from GetSubTree
+ BMCWEB_LOG_DEBUG("getPowerSupplyAttributes respHandler enter");
+ if (ec)
+ {
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ BMCWEB_LOG_ERROR(
+ "getPowerSupplyAttributes respHandler DBus error {}", ec);
+ return;
+ }
+ if (subtree.empty())
+ {
+ BMCWEB_LOG_DEBUG("Can't find Power Supply Attributes!");
+ callback(inventoryItems);
+ return;
+ }
- // Currently we only support 1 power supply attribute, use this for
- // all the power supplies. Build map of object path to connection.
- // Assume just 1 connection and 1 path for now.
- std::map<std::string, std::string> psAttributesConnections;
+ // Currently we only support 1 power supply attribute, use this for
+ // all the power supplies. Build map of object path to connection.
+ // Assume just 1 connection and 1 path for now.
+ std::map<std::string, std::string> psAttributesConnections;
- if (subtree[0].first.empty() || subtree[0].second.empty())
- {
- BMCWEB_LOG_DEBUG("Power Supply Attributes mapper error!");
- callback(inventoryItems);
- return;
- }
+ if (subtree[0].first.empty() || subtree[0].second.empty())
+ {
+ BMCWEB_LOG_DEBUG("Power Supply Attributes mapper error!");
+ callback(inventoryItems);
+ return;
+ }
- const std::string& psAttributesPath = subtree[0].first;
- const std::string& connection = subtree[0].second.begin()->first;
+ const std::string& psAttributesPath = subtree[0].first;
+ const std::string& connection = subtree[0].second.begin()->first;
- if (connection.empty())
- {
- BMCWEB_LOG_DEBUG("Power Supply Attributes mapper error!");
- callback(inventoryItems);
- return;
- }
+ if (connection.empty())
+ {
+ BMCWEB_LOG_DEBUG("Power Supply Attributes mapper error!");
+ callback(inventoryItems);
+ return;
+ }
- psAttributesConnections[psAttributesPath] = connection;
- BMCWEB_LOG_DEBUG("Added mapping {} -> {}", psAttributesPath,
- connection);
+ psAttributesConnections[psAttributesPath] = connection;
+ BMCWEB_LOG_DEBUG("Added mapping {} -> {}", psAttributesPath,
+ connection);
- getPowerSupplyAttributesData(sensorsAsyncResp, inventoryItems,
- psAttributesConnections,
- std::move(callback));
- BMCWEB_LOG_DEBUG("getPowerSupplyAttributes respHandler exit");
- });
+ getPowerSupplyAttributesData(sensorsAsyncResp, inventoryItems,
+ psAttributesConnections,
+ std::move(callback));
+ BMCWEB_LOG_DEBUG("getPowerSupplyAttributes respHandler exit");
+ });
BMCWEB_LOG_DEBUG("getPowerSupplyAttributes exit");
}
@@ -2145,7 +1674,7 @@ void getPowerSupplyAttributes(
* @param callback Callback to invoke when inventory items have been obtained.
*/
template <typename Callback>
-static void
+inline void
getInventoryItems(std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp,
const std::shared_ptr<std::set<std::string>> sensorNames,
Callback&& callback)
@@ -2153,45 +1682,55 @@ static void
BMCWEB_LOG_DEBUG("getInventoryItems enter");
auto getInventoryItemAssociationsCb =
[sensorsAsyncResp, callback = std::forward<Callback>(callback)](
- std::shared_ptr<std::vector<InventoryItem>> inventoryItems) {
- BMCWEB_LOG_DEBUG("getInventoryItemAssociationsCb enter");
- auto getInventoryItemsConnectionsCb =
- [sensorsAsyncResp, inventoryItems,
- callback = std::forward<const Callback>(callback)](
- std::shared_ptr<std::set<std::string>> invConnections) {
- BMCWEB_LOG_DEBUG("getInventoryItemsConnectionsCb enter");
- auto getInventoryItemsDataCb = [sensorsAsyncResp, inventoryItems,
- callback{std::move(callback)}]() {
- BMCWEB_LOG_DEBUG("getInventoryItemsDataCb enter");
-
- auto getInventoryLedsCb = [sensorsAsyncResp, inventoryItems,
- callback{std::move(callback)}]() {
- BMCWEB_LOG_DEBUG("getInventoryLedsCb enter");
- // Find Power Supply Attributes and get the data
- getPowerSupplyAttributes(sensorsAsyncResp, inventoryItems,
- std::move(callback));
- BMCWEB_LOG_DEBUG("getInventoryLedsCb exit");
+ std::shared_ptr<std::vector<InventoryItem>>
+ inventoryItems) mutable {
+ BMCWEB_LOG_DEBUG("getInventoryItemAssociationsCb enter");
+ auto getInventoryItemsConnectionsCb =
+ [sensorsAsyncResp, inventoryItems,
+ callback = std::forward<Callback>(callback)](
+ std::shared_ptr<std::set<std::string>>
+ invConnections) mutable {
+ BMCWEB_LOG_DEBUG("getInventoryItemsConnectionsCb enter");
+ auto getInventoryItemsDataCb =
+ [sensorsAsyncResp, inventoryItems,
+ callback =
+ std::forward<Callback>(callback)]() mutable {
+ BMCWEB_LOG_DEBUG("getInventoryItemsDataCb enter");
+
+ auto getInventoryLedsCb =
+ [sensorsAsyncResp, inventoryItems,
+ callback = std::forward<Callback>(
+ callback)]() mutable {
+ BMCWEB_LOG_DEBUG(
+ "getInventoryLedsCb enter");
+ // Find Power Supply Attributes and get the
+ // data
+ getPowerSupplyAttributes(
+ sensorsAsyncResp, inventoryItems,
+ std::move(callback));
+ BMCWEB_LOG_DEBUG("getInventoryLedsCb exit");
+ };
+
+ // Find led connections and get the data
+ getInventoryLeds(sensorsAsyncResp, inventoryItems,
+ std::move(getInventoryLedsCb));
+ BMCWEB_LOG_DEBUG("getInventoryItemsDataCb exit");
+ };
+
+ // Get inventory item data from connections
+ getInventoryItemsData(sensorsAsyncResp, inventoryItems,
+ invConnections,
+ std::move(getInventoryItemsDataCb));
+ BMCWEB_LOG_DEBUG("getInventoryItemsConnectionsCb exit");
};
- // Find led connections and get the data
- getInventoryLeds(sensorsAsyncResp, inventoryItems,
- std::move(getInventoryLedsCb));
- BMCWEB_LOG_DEBUG("getInventoryItemsDataCb exit");
- };
-
- // Get inventory item data from connections
- getInventoryItemsData(sensorsAsyncResp, inventoryItems,
- invConnections,
- std::move(getInventoryItemsDataCb));
- BMCWEB_LOG_DEBUG("getInventoryItemsConnectionsCb exit");
+ // Get connections that provide inventory item data
+ getInventoryItemsConnections(
+ sensorsAsyncResp, inventoryItems,
+ std::move(getInventoryItemsConnectionsCb));
+ BMCWEB_LOG_DEBUG("getInventoryItemAssociationsCb exit");
};
- // Get connections that provide inventory item data
- getInventoryItemsConnections(sensorsAsyncResp, inventoryItems,
- std::move(getInventoryItemsConnectionsCb));
- BMCWEB_LOG_DEBUG("getInventoryItemAssociationsCb exit");
- };
-
// Get associations from sensors to inventory items
getInventoryItemAssociations(sensorsAsyncResp, sensorNames,
std::move(getInventoryItemAssociationsCb));
@@ -2243,8 +1782,8 @@ inline nlohmann::json& getPowerSupply(nlohmann::json& powerSupplyArray,
// Add new PowerSupply object to JSON array
powerSupplyArray.push_back({});
nlohmann::json& powerSupply = powerSupplyArray.back();
- boost::urls::url url = boost::urls::format("/redfish/v1/Chassis/{}/Power",
- chassisId);
+ boost::urls::url url =
+ boost::urls::format("/redfish/v1/Chassis/{}/Power", chassisId);
url.set_fragment(("/PowerSupplies"_json_pointer).to_string());
powerSupply["@odata.id"] = std::move(url);
std::string escaped;
@@ -2255,7 +1794,7 @@ inline nlohmann::json& getPowerSupply(nlohmann::json& powerSupplyArray,
powerSupply["Model"] = inventoryItem.model;
powerSupply["PartNumber"] = inventoryItem.partNumber;
powerSupply["SerialNumber"] = inventoryItem.serialNumber;
- setLedState(powerSupply, &inventoryItem);
+ sensor_utils::setLedState(powerSupply, &inventoryItem);
if (inventoryItem.powerSupplyEfficiencyPercent >= 0)
{
@@ -2263,7 +1802,8 @@ inline nlohmann::json& getPowerSupply(nlohmann::json& powerSupplyArray,
inventoryItem.powerSupplyEfficiencyPercent;
}
- powerSupply["Status"]["State"] = getState(&inventoryItem, true);
+ powerSupply["Status"]["State"] =
+ sensor_utils::getState(&inventoryItem, true);
const char* health = inventoryItem.isFunctional ? "OK" : "Critical";
powerSupply["Status"]["Health"] = health;
@@ -2312,215 +1852,212 @@ inline void getSensorData(
[sensorsAsyncResp, sensorNames,
inventoryItems](const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& resp) {
- BMCWEB_LOG_DEBUG("getManagedObjectsCb enter");
- if (ec)
- {
- BMCWEB_LOG_ERROR("getManagedObjectsCb DBUS error: {}", ec);
- messages::internalError(sensorsAsyncResp->asyncResp->res);
- return;
- }
- // Go through all objects and update response with sensor data
- for (const auto& objDictEntry : resp)
- {
- const std::string& objPath =
- static_cast<const std::string&>(objDictEntry.first);
- BMCWEB_LOG_DEBUG("getManagedObjectsCb parsing object {}",
- objPath);
-
- std::vector<std::string> split;
- // Reserve space for
- // /xyz/openbmc_project/sensors/<name>/<subname>
- split.reserve(6);
- // NOLINTNEXTLINE
- bmcweb::split(split, objPath, '/');
- if (split.size() < 6)
+ BMCWEB_LOG_DEBUG("getManagedObjectsCb enter");
+ if (ec)
{
- BMCWEB_LOG_ERROR("Got path that isn't long enough {}",
- objPath);
- continue;
+ BMCWEB_LOG_ERROR("getManagedObjectsCb DBUS error: {}", ec);
+ messages::internalError(sensorsAsyncResp->asyncResp->res);
+ return;
}
- // These indexes aren't intuitive, as split puts an empty
- // string at the beginning
- const std::string& sensorType = split[4];
- const std::string& sensorName = split[5];
- BMCWEB_LOG_DEBUG("sensorName {} sensorType {}", sensorName,
- sensorType);
- if (sensorNames->find(objPath) == sensorNames->end())
+ auto chassisSubNode = sensor_utils::chassisSubNodeFromString(
+ sensorsAsyncResp->chassisSubNode);
+ // Go through all objects and update response with sensor data
+ for (const auto& objDictEntry : resp)
{
- BMCWEB_LOG_DEBUG("{} not in sensor list ", sensorName);
- continue;
- }
-
- // Find inventory item (if any) associated with sensor
- InventoryItem* inventoryItem =
- findInventoryItemForSensor(inventoryItems, objPath);
-
- const std::string& sensorSchema =
- sensorsAsyncResp->chassisSubNode;
-
- nlohmann::json* sensorJson = nullptr;
+ const std::string& objPath =
+ static_cast<const std::string&>(objDictEntry.first);
+ BMCWEB_LOG_DEBUG("getManagedObjectsCb parsing object {}",
+ objPath);
- if (sensorSchema == sensors::node::sensors &&
- !sensorsAsyncResp->efficientExpand)
- {
- std::string sensorTypeEscaped(sensorType);
- auto remove = std::ranges::remove(sensorTypeEscaped, '_');
-
- sensorTypeEscaped.erase(std::ranges::begin(remove),
- sensorTypeEscaped.end());
- std::string sensorId(sensorTypeEscaped);
- sensorId += "_";
- sensorId += sensorName;
-
- sensorsAsyncResp->asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/Chassis/{}/{}/{}",
- sensorsAsyncResp->chassisId,
- sensorsAsyncResp->chassisSubNode,
- sensorId);
- sensorJson = &(sensorsAsyncResp->asyncResp->res.jsonValue);
- }
- else
- {
- std::string fieldName;
- if (sensorsAsyncResp->efficientExpand)
+ std::vector<std::string> split;
+ // Reserve space for
+ // /xyz/openbmc_project/sensors/<name>/<subname>
+ split.reserve(6);
+ // NOLINTNEXTLINE
+ bmcweb::split(split, objPath, '/');
+ if (split.size() < 6)
{
- fieldName = "Members";
- }
- else if (sensorType == "temperature")
- {
- fieldName = "Temperatures";
+ BMCWEB_LOG_ERROR("Got path that isn't long enough {}",
+ objPath);
+ continue;
}
- else if (sensorType == "fan" || sensorType == "fan_tach" ||
- sensorType == "fan_pwm")
+ // These indexes aren't intuitive, as split puts an empty
+ // string at the beginning
+ const std::string& sensorType = split[4];
+ const std::string& sensorName = split[5];
+ BMCWEB_LOG_DEBUG("sensorName {} sensorType {}", sensorName,
+ sensorType);
+ if (sensorNames->find(objPath) == sensorNames->end())
{
- fieldName = "Fans";
+ BMCWEB_LOG_DEBUG("{} not in sensor list ", sensorName);
+ continue;
}
- else if (sensorType == "voltage")
+
+ // Find inventory item (if any) associated with sensor
+ InventoryItem* inventoryItem =
+ findInventoryItemForSensor(inventoryItems, objPath);
+
+ const std::string& sensorSchema =
+ sensorsAsyncResp->chassisSubNode;
+
+ nlohmann::json* sensorJson = nullptr;
+
+ if (sensorSchema == sensors::sensorsNodeStr &&
+ !sensorsAsyncResp->efficientExpand)
{
- fieldName = "Voltages";
+ std::string sensorId =
+ redfish::sensor_utils::getSensorId(sensorName,
+ sensorType);
+
+ sensorsAsyncResp->asyncResp->res
+ .jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}/{}/{}",
+ sensorsAsyncResp->chassisId,
+ sensorsAsyncResp->chassisSubNode, sensorId);
+ sensorJson =
+ &(sensorsAsyncResp->asyncResp->res.jsonValue);
}
- else if (sensorType == "power")
+ else
{
- if (sensorName == "total_power")
+ std::string fieldName;
+ if (sensorsAsyncResp->efficientExpand)
+ {
+ fieldName = "Members";
+ }
+ else if (sensorType == "temperature")
{
- fieldName = "PowerControl";
+ fieldName = "Temperatures";
}
- else if ((inventoryItem != nullptr) &&
- (inventoryItem->isPowerSupply))
+ else if (sensorType == "fan" ||
+ sensorType == "fan_tach" ||
+ sensorType == "fan_pwm")
{
- fieldName = "PowerSupplies";
+ fieldName = "Fans";
+ }
+ else if (sensorType == "voltage")
+ {
+ fieldName = "Voltages";
+ }
+ else if (sensorType == "power")
+ {
+ if (sensorName == "total_power")
+ {
+ fieldName = "PowerControl";
+ }
+ else if ((inventoryItem != nullptr) &&
+ (inventoryItem->isPowerSupply))
+ {
+ fieldName = "PowerSupplies";
+ }
+ else
+ {
+ // Other power sensors are in SensorCollection
+ continue;
+ }
}
else
{
- // Other power sensors are in SensorCollection
+ BMCWEB_LOG_ERROR(
+ "Unsure how to handle sensorType {}",
+ sensorType);
continue;
}
- }
- else
- {
- BMCWEB_LOG_ERROR("Unsure how to handle sensorType {}",
- sensorType);
- continue;
- }
- nlohmann::json& tempArray =
- sensorsAsyncResp->asyncResp->res.jsonValue[fieldName];
- if (fieldName == "PowerControl")
- {
- if (tempArray.empty())
+ nlohmann::json& tempArray =
+ sensorsAsyncResp->asyncResp->res
+ .jsonValue[fieldName];
+ if (fieldName == "PowerControl")
+ {
+ if (tempArray.empty())
+ {
+ // Put multiple "sensors" into a single
+ // PowerControl. Follows MemberId naming and
+ // naming in power.hpp.
+ nlohmann::json::object_t power;
+ boost::urls::url url = boost::urls::format(
+ "/redfish/v1/Chassis/{}/{}",
+ sensorsAsyncResp->chassisId,
+ sensorsAsyncResp->chassisSubNode);
+ url.set_fragment(
+ (""_json_pointer / fieldName / "0")
+ .to_string());
+ power["@odata.id"] = std::move(url);
+ tempArray.emplace_back(std::move(power));
+ }
+ sensorJson = &(tempArray.back());
+ }
+ else if (fieldName == "PowerSupplies")
+ {
+ if (inventoryItem != nullptr)
+ {
+ sensorJson = &(getPowerSupply(
+ tempArray, *inventoryItem,
+ sensorsAsyncResp->chassisId));
+ }
+ }
+ else if (fieldName == "Members")
+ {
+ std::string sensorId =
+ redfish::sensor_utils::getSensorId(sensorName,
+ sensorType);
+
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}/{}/{}",
+ sensorsAsyncResp->chassisId,
+ sensorsAsyncResp->chassisSubNode, sensorId);
+ tempArray.emplace_back(std::move(member));
+ sensorJson = &(tempArray.back());
+ }
+ else
{
- // Put multiple "sensors" into a single
- // PowerControl. Follows MemberId naming and
- // naming in power.hpp.
- nlohmann::json::object_t power;
+ nlohmann::json::object_t member;
boost::urls::url url = boost::urls::format(
"/redfish/v1/Chassis/{}/{}",
sensorsAsyncResp->chassisId,
sensorsAsyncResp->chassisSubNode);
- url.set_fragment((""_json_pointer / fieldName / "0")
- .to_string());
- power["@odata.id"] = std::move(url);
- tempArray.emplace_back(std::move(power));
+ url.set_fragment(
+ (""_json_pointer / fieldName).to_string());
+ member["@odata.id"] = std::move(url);
+ tempArray.emplace_back(std::move(member));
+ sensorJson = &(tempArray.back());
}
- sensorJson = &(tempArray.back());
}
- else if (fieldName == "PowerSupplies")
+
+ if (sensorJson != nullptr)
{
- if (inventoryItem != nullptr)
- {
- sensorJson =
- &(getPowerSupply(tempArray, *inventoryItem,
- sensorsAsyncResp->chassisId));
- }
+ objectInterfacesToJson(
+ sensorName, sensorType, chassisSubNode,
+ objDictEntry.second, *sensorJson, inventoryItem);
+
+ std::string path = "/xyz/openbmc_project/sensors/";
+ path += sensorType;
+ path += "/";
+ path += sensorName;
+ sensorsAsyncResp->addMetadata(*sensorJson, path);
}
- else if (fieldName == "Members")
+ }
+ if (sensorsAsyncResp.use_count() == 1)
+ {
+ sortJSONResponse(sensorsAsyncResp);
+ if (chassisSubNode ==
+ sensor_utils::ChassisSubNode::sensorsNode &&
+ sensorsAsyncResp->efficientExpand)
{
- std::string sensorTypeEscaped(sensorType);
- auto remove = std::ranges::remove(sensorTypeEscaped,
- '_');
- sensorTypeEscaped.erase(std::ranges::begin(remove),
- sensorTypeEscaped.end());
- std::string sensorId(sensorTypeEscaped);
- sensorId += "_";
- sensorId += sensorName;
-
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/Chassis/{}/{}/{}",
- sensorsAsyncResp->chassisId,
- sensorsAsyncResp->chassisSubNode, sensorId);
- tempArray.emplace_back(std::move(member));
- sensorJson = &(tempArray.back());
+ sensorsAsyncResp->asyncResp->res
+ .jsonValue["Members@odata.count"] =
+ sensorsAsyncResp->asyncResp->res
+ .jsonValue["Members"]
+ .size();
}
- else
+ else if (chassisSubNode ==
+ sensor_utils::ChassisSubNode::thermalNode)
{
- nlohmann::json::object_t member;
- boost::urls::url url = boost::urls::format(
- "/redfish/v1/Chassis/{}/{}",
- sensorsAsyncResp->chassisId,
- sensorsAsyncResp->chassisSubNode);
- url.set_fragment(
- (""_json_pointer / fieldName).to_string());
- member["@odata.id"] = std::move(url);
- tempArray.emplace_back(std::move(member));
- sensorJson = &(tempArray.back());
+ populateFanRedundancy(sensorsAsyncResp);
}
}
-
- if (sensorJson != nullptr)
- {
- objectInterfacesToJson(sensorName, sensorType,
- sensorsAsyncResp->chassisSubNode,
- objDictEntry.second, *sensorJson,
- inventoryItem);
-
- std::string path = "/xyz/openbmc_project/sensors/";
- path += sensorType;
- path += "/";
- path += sensorName;
- sensorsAsyncResp->addMetadata(*sensorJson, path);
- }
- }
- if (sensorsAsyncResp.use_count() == 1)
- {
- sortJSONResponse(sensorsAsyncResp);
- if (sensorsAsyncResp->chassisSubNode ==
- sensors::node::sensors &&
- sensorsAsyncResp->efficientExpand)
- {
- sensorsAsyncResp->asyncResp->res
- .jsonValue["Members@odata.count"] =
- sensorsAsyncResp->asyncResp->res.jsonValue["Members"]
- .size();
- }
- else if (sensorsAsyncResp->chassisSubNode ==
- sensors::node::thermal)
- {
- populateFanRedundancy(sensorsAsyncResp);
- }
- }
- BMCWEB_LOG_DEBUG("getManagedObjectsCb exit");
- });
+ BMCWEB_LOG_DEBUG("getManagedObjectsCb exit");
+ });
}
BMCWEB_LOG_DEBUG("getSensorData exit");
}
@@ -2533,15 +2070,15 @@ inline void
const std::set<std::string>& connections) {
BMCWEB_LOG_DEBUG("getConnectionCb enter");
auto getInventoryItemsCb =
- [sensorsAsyncResp, sensorNames,
- connections](const std::shared_ptr<std::vector<InventoryItem>>&
- inventoryItems) {
- BMCWEB_LOG_DEBUG("getInventoryItemsCb enter");
- // Get sensor data and store results in JSON
- getSensorData(sensorsAsyncResp, sensorNames, connections,
- inventoryItems);
- BMCWEB_LOG_DEBUG("getInventoryItemsCb exit");
- };
+ [sensorsAsyncResp, sensorNames, connections](
+ const std::shared_ptr<std::vector<InventoryItem>>&
+ inventoryItems) mutable {
+ BMCWEB_LOG_DEBUG("getInventoryItemsCb enter");
+ // Get sensor data and store results in JSON
+ getSensorData(sensorsAsyncResp, sensorNames, connections,
+ inventoryItems);
+ BMCWEB_LOG_DEBUG("getInventoryItemsCb exit");
+ };
// Get inventory items associated with sensors
getInventoryItems(sensorsAsyncResp, sensorNames,
@@ -2566,12 +2103,12 @@ inline void
auto getChassisCb =
[sensorsAsyncResp](
const std::shared_ptr<std::set<std::string>>& sensorNames) {
- BMCWEB_LOG_DEBUG("getChassisCb enter");
- processSensorList(sensorsAsyncResp, sensorNames);
- BMCWEB_LOG_DEBUG("getChassisCb exit");
- };
+ BMCWEB_LOG_DEBUG("getChassisCb enter");
+ processSensorList(sensorsAsyncResp, sensorNames);
+ BMCWEB_LOG_DEBUG("getChassisCb exit");
+ };
// SensorCollection doesn't contain the Redundancy property
- if (sensorsAsyncResp->chassisSubNode != sensors::node::sensors)
+ if (sensorsAsyncResp->chassisSubNode != sensors::sensorsNodeStr)
{
sensorsAsyncResp->asyncResp->res.jsonValue["Redundancy"] =
nlohmann::json::array();
@@ -2592,10 +2129,9 @@ inline void
* @param sensorsModified The list of sensors that were found as a result of
* repeated calls to this function
*/
-inline bool
- findSensorNameUsingSensorPath(std::string_view sensorName,
- const std::set<std::string>& sensorsList,
- std::set<std::string>& sensorsModified)
+inline bool findSensorNameUsingSensorPath(
+ std::string_view sensorName, const std::set<std::string>& sensorsList,
+ std::set<std::string>& sensorsModified)
{
for (const auto& chassisSensor : sensorsList)
{
@@ -2614,24 +2150,6 @@ inline bool
return false;
}
-inline std::pair<std::string, std::string>
- splitSensorNameAndType(std::string_view sensorId)
-{
- size_t index = sensorId.find('_');
- if (index == std::string::npos)
- {
- return std::make_pair<std::string, std::string>("", "");
- }
- std::string sensorType{sensorId.substr(0, index)};
- std::string sensorName{sensorId.substr(index + 1)};
- // fan_pwm and fan_tach need special handling
- if (sensorType == "fantach" || sensorType == "fanpwm")
- {
- sensorType.insert(3, 1, '_');
- }
- return std::make_pair(sensorType, sensorName);
-}
-
/**
* @brief Entry point for overriding sensor values of given sensor
*
@@ -2678,10 +2196,11 @@ inline void setSensorsOverride(
}
}
- auto getChassisSensorListCb =
- [sensorAsyncResp, overrideMap,
- propertyValueNameStr = std::string(propertyValueName)](
- const std::shared_ptr<std::set<std::string>>& sensorsList) {
+ auto getChassisSensorListCb = [sensorAsyncResp, overrideMap,
+ propertyValueNameStr =
+ std::string(propertyValueName)](
+ const std::shared_ptr<
+ std::set<std::string>>& sensorsList) {
// Match sensor names in the PATCH request to those managed by the
// chassis node
const std::shared_ptr<std::set<std::string>> sensorNames =
@@ -2690,7 +2209,7 @@ inline void setSensorsOverride(
{
const auto& sensor = item.first;
std::pair<std::string, std::string> sensorNameType =
- splitSensorNameAndType(sensor);
+ redfish::sensor_utils::splitSensorNameAndType(sensor);
if (!findSensorNameUsingSensorPath(sensorNameType.second,
*sensorsList, *sensorNames))
{
@@ -2701,22 +2220,24 @@ inline void setSensorsOverride(
}
}
// Get the connection to which the memberId belongs
- auto getObjectsWithConnectionCb =
- [sensorAsyncResp, overrideMap, propertyValueNameStr](
- const std::set<std::string>& /*connections*/,
- const std::set<std::pair<std::string, std::string>>&
- objectsWithConnection) {
+ auto getObjectsWithConnectionCb = [sensorAsyncResp, overrideMap,
+ propertyValueNameStr](
+ const std::set<
+ std::string>& /*connections*/,
+ const std::set<std::pair<
+ std::string, std::string>>&
+ objectsWithConnection) {
if (objectsWithConnection.size() != overrideMap.size())
{
BMCWEB_LOG_INFO(
"Unable to find all objects with proper connection {} requested {}",
objectsWithConnection.size(), overrideMap.size());
- messages::resourceNotFound(sensorAsyncResp->asyncResp->res,
- sensorAsyncResp->chassisSubNode ==
- sensors::node::thermal
- ? "Temperatures"
- : "Voltages",
- "Count");
+ messages::resourceNotFound(
+ sensorAsyncResp->asyncResp->res,
+ sensorAsyncResp->chassisSubNode == sensors::thermalNodeStr
+ ? "Temperatures"
+ : "Voltages",
+ "Count");
return;
}
for (const auto& item : objectsWithConnection)
@@ -2728,11 +2249,8 @@ inline void setSensorsOverride(
messages::internalError(sensorAsyncResp->asyncResp->res);
return;
}
- std::string id = path.parent_path().filename();
- auto remove = std::ranges::remove(id, '_');
- id.erase(std::ranges::begin(remove), id.end());
- id += "_";
- id += sensorName;
+ std::string id = redfish::sensor_utils::getSensorId(
+ sensorName, path.parent_path().filename());
const auto& iterator = overrideMap.find(id);
if (iterator == overrideMap.end())
@@ -2767,13 +2285,13 @@ inline void setSensorsOverride(
* it to caller in a callback.
*
* @param chassis Chassis for which retrieval should be performed
- * @param node Node (group) of sensors. See sensors::node for supported values
+ * @param node Node (group) of sensors. See sensor_utils::node for supported
+ * values
* @param mapComplete Callback to be called with retrieval result
*/
template <typename Callback>
-inline void retrieveUriToDbusMap(const std::string& chassis,
- const std::string& node,
- Callback&& mapComplete)
+inline void retrieveUriToDbusMap(
+ const std::string& chassis, const std::string& node, Callback&& mapComplete)
{
decltype(sensors::paths)::const_iterator pathIt =
std::find_if(sensors::paths.cbegin(), sensors::paths.cend(),
@@ -2787,12 +2305,12 @@ inline void retrieveUriToDbusMap(const std::string& chassis,
}
auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
- auto callback = [asyncResp,
- mapCompleteCb = std::forward<Callback>(mapComplete)](
- const boost::beast::http::status status,
- const std::map<std::string, std::string>& uriToDbus) {
- mapCompleteCb(status, uriToDbus);
- };
+ auto callback =
+ [asyncResp, mapCompleteCb = std::forward<Callback>(mapComplete)](
+ const boost::beast::http::status status,
+ const std::map<std::string, std::string>& uriToDbus) {
+ mapCompleteCb(status, uriToDbus);
+ };
auto resp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassis, pathIt->second, node, std::move(callback));
@@ -2823,15 +2341,9 @@ inline void getChassisCallback(
return;
}
std::string type = path.parent_path().filename();
- // fan_tach has an underscore in it, so remove it to "normalize" the
- // type in the URI
- auto remove = std::ranges::remove(type, '_');
- type.erase(std::ranges::begin(remove), type.end());
+ std::string id = redfish::sensor_utils::getSensorId(sensorName, type);
nlohmann::json::object_t member;
- std::string id = type;
- id += "_";
- id += sensorName;
member["@odata.id"] = boost::urls::format(
"/redfish/v1/Chassis/{}/{}/{}", chassisId, chassisSubNode, id);
@@ -2862,7 +2374,7 @@ inline void handleSensorCollectionGet(
// we perform efficient expand.
auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisId, sensors::dbus::sensorPaths,
- sensors::node::sensors,
+ sensors::sensorsNodeStr,
/*efficientExpand=*/true);
getChassisData(sensorsAsyncResp);
@@ -2873,9 +2385,9 @@ inline void handleSensorCollectionGet(
// We get all sensors as hyperlinkes in the chassis (this
// implies we reply on the default query parameters handler)
- getChassis(asyncResp, chassisId, sensors::node::sensors, dbus::sensorPaths,
+ getChassis(asyncResp, chassisId, sensors::sensorsNodeStr, dbus::sensorPaths,
std::bind_front(sensors::getChassisCallback, asyncResp,
- chassisId, sensors::node::sensors));
+ chassisId, sensors::sensorsNodeStr));
}
inline void
@@ -2898,18 +2410,19 @@ inline void
[asyncResp,
sensorPath](const boost::system::error_code& ec,
const ::dbus::utility::DBusPropertiesMap& valuesDict) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- sdbusplus::message::object_path path(sensorPath);
- std::string name = path.filename();
- path = path.parent_path();
- std::string type = path.filename();
- objectPropertiesToJson(name, type, sensors::node::sensors, valuesDict,
- asyncResp->res.jsonValue, nullptr);
- });
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ sdbusplus::message::object_path path(sensorPath);
+ std::string name = path.filename();
+ path = path.parent_path();
+ std::string type = path.filename();
+ sensor_utils::objectPropertiesToJson(
+ name, type, sensor_utils::ChassisSubNode::sensorsNode,
+ valuesDict, asyncResp->res.jsonValue, nullptr);
+ });
}
inline void handleSensorGet(App& app, const crow::Request& req,
@@ -2922,7 +2435,7 @@ inline void handleSensorGet(App& app, const crow::Request& req,
return;
}
std::pair<std::string, std::string> nameType =
- splitSensorNameAndType(sensorId);
+ redfish::sensor_utils::splitSensorNameAndType(sensorId);
if (nameType.first.empty() || nameType.second.empty())
{
messages::resourceNotFound(asyncResp->res, sensorId, "Sensor");
@@ -2945,23 +2458,23 @@ inline void handleSensorGet(App& app, const crow::Request& req,
[asyncResp, sensorId,
sensorPath](const boost::system::error_code& ec,
const ::dbus::utility::MapperGetObject& subtree) {
- BMCWEB_LOG_DEBUG("respHandler1 enter");
- if (ec == boost::system::errc::io_error)
- {
- BMCWEB_LOG_WARNING("Sensor not found from getSensorPaths");
- messages::resourceNotFound(asyncResp->res, sensorId, "Sensor");
- return;
- }
- if (ec)
- {
- messages::internalError(asyncResp->res);
- BMCWEB_LOG_ERROR(
- "Sensor getSensorPaths resp_handler: Dbus error {}", ec);
- return;
- }
- getSensorFromDbus(asyncResp, sensorPath, subtree);
- BMCWEB_LOG_DEBUG("respHandler1 exit");
- });
+ BMCWEB_LOG_DEBUG("respHandler1 enter");
+ if (ec == boost::system::errc::io_error)
+ {
+ BMCWEB_LOG_WARNING("Sensor not found from getSensorPaths");
+ messages::resourceNotFound(asyncResp->res, sensorId, "Sensor");
+ return;
+ }
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ BMCWEB_LOG_ERROR(
+ "Sensor getSensorPaths resp_handler: Dbus error {}", ec);
+ return;
+ }
+ getSensorFromDbus(asyncResp, sensorPath, subtree);
+ BMCWEB_LOG_DEBUG("respHandler1 exit");
+ });
}
} // namespace sensors
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 57b967c427..ca640749ed 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index e0ad737752..e670de72e3 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2019 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2019 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -21,6 +21,7 @@
#include "dbus_utility.hpp"
#include "generated/enums/drive.hpp"
#include "generated/enums/protocol.hpp"
+#include "generated/enums/resource.hpp"
#include "human_sort.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
@@ -162,9 +163,9 @@ inline void afterSystemsStorageGetSubtree(
subtree,
[&storageId](const std::pair<std::string,
dbus::utility::MapperServiceMap>& object) {
- return sdbusplus::message::object_path(object.first).filename() ==
- storageId;
- });
+ return sdbusplus::message::object_path(object.first).filename() ==
+ storageId;
+ });
if (storage == subtree.end())
{
messages::resourceNotFound(asyncResp->res, "#Storage.v1_13_0.Storage",
@@ -178,7 +179,7 @@ inline void afterSystemsStorageGetSubtree(
BMCWEB_REDFISH_SYSTEM_URI_NAME, storageId);
asyncResp->res.jsonValue["Name"] = "Storage";
asyncResp->res.jsonValue["Id"] = storageId;
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
getDrives(asyncResp);
asyncResp->res.jsonValue["Controllers"]["@odata.id"] =
@@ -186,11 +187,10 @@ inline void afterSystemsStorageGetSubtree(
BMCWEB_REDFISH_SYSTEM_URI_NAME, storageId);
}
-inline void
- handleSystemsStorageGet(App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName,
- const std::string& storageId)
+inline void handleSystemsStorageGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& storageId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -227,9 +227,9 @@ inline void afterSubtree(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
subtree,
[&storageId](const std::pair<std::string,
dbus::utility::MapperServiceMap>& object) {
- return sdbusplus::message::object_path(object.first).filename() ==
- storageId;
- });
+ return sdbusplus::message::object_path(object.first).filename() ==
+ storageId;
+ });
if (storage == subtree.end())
{
messages::resourceNotFound(asyncResp->res, "#Storage.v1_13_0.Storage",
@@ -242,7 +242,7 @@ inline void afterSubtree(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
boost::urls::format("/redfish/v1/Storage/{}", storageId);
asyncResp->res.jsonValue["Name"] = "Storage";
asyncResp->res.jsonValue["Id"] = storageId;
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
// Storage subsystem to Storage link.
nlohmann::json::array_t storageServices;
@@ -298,48 +298,48 @@ inline void getDriveAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::vector<
std::pair<std::string, dbus::utility::DbusVariantType>>&
propertiesList) {
- if (ec)
- {
- // this interface isn't necessary
- return;
- }
+ if (ec)
+ {
+ // this interface isn't necessary
+ return;
+ }
- const std::string* partNumber = nullptr;
- const std::string* serialNumber = nullptr;
- const std::string* manufacturer = nullptr;
- const std::string* model = nullptr;
+ const std::string* partNumber = nullptr;
+ const std::string* serialNumber = nullptr;
+ const std::string* manufacturer = nullptr;
+ const std::string* model = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
- partNumber, "SerialNumber", serialNumber, "Manufacturer",
- manufacturer, "Model", model);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
+ partNumber, "SerialNumber", serialNumber, "Manufacturer",
+ manufacturer, "Model", model);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (partNumber != nullptr)
- {
- asyncResp->res.jsonValue["PartNumber"] = *partNumber;
- }
+ if (partNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["PartNumber"] = *partNumber;
+ }
- if (serialNumber != nullptr)
- {
- asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
- }
+ if (serialNumber != nullptr)
+ {
+ asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
+ }
- if (manufacturer != nullptr)
- {
- asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
- }
+ if (manufacturer != nullptr)
+ {
+ asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
+ }
- if (model != nullptr)
- {
- asyncResp->res.jsonValue["Model"] = *model;
- }
- });
+ if (model != nullptr)
+ {
+ asyncResp->res.jsonValue["Model"] = *model;
+ }
+ });
}
inline void getDrivePresent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -349,20 +349,21 @@ inline void getDrivePresent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, connectionName, path,
"xyz.openbmc_project.Inventory.Item", "Present",
- [asyncResp, path](const boost::system::error_code& ec,
- const bool isPresent) {
- // this interface isn't necessary, only check it if
- // we get a good return
- if (ec)
- {
- return;
- }
+ [asyncResp,
+ path](const boost::system::error_code& ec, const bool isPresent) {
+ // this interface isn't necessary, only check it if
+ // we get a good return
+ if (ec)
+ {
+ return;
+ }
- if (!isPresent)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- }
- });
+ if (!isPresent)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
+ }
+ });
}
inline void getDriveState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -373,22 +374,23 @@ inline void getDriveState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
*crow::connections::systemBus, connectionName, path,
"xyz.openbmc_project.State.Drive", "Rebuilding",
[asyncResp](const boost::system::error_code& ec, const bool updating) {
- // this interface isn't necessary, only check it
- // if we get a good return
- if (ec)
- {
- return;
- }
+ // this interface isn't necessary, only check it
+ // if we get a good return
+ if (ec)
+ {
+ return;
+ }
- // updating and disabled in the backend shouldn't be
- // able to be set at the same time, so we don't need
- // to check for the race condition of these two
- // calls
- if (updating)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Updating";
- }
- });
+ // updating and disabled in the backend shouldn't be
+ // able to be set at the same time, so we don't need
+ // to check for the race condition of these two
+ // calls
+ if (updating)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Updating;
+ }
+ });
}
inline std::optional<drive::MediaType> convertDriveType(std::string_view type)
@@ -437,10 +439,9 @@ inline std::optional<protocol::Protocol>
return protocol::Protocol::Invalid;
}
-inline void
- getDriveItemProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& connectionName,
- const std::string& path)
+inline void getDriveItemProperties(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& connectionName, const std::string& path)
{
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, connectionName, path,
@@ -449,160 +450,162 @@ inline void
const std::vector<
std::pair<std::string, dbus::utility::DbusVariantType>>&
propertiesList) {
- if (ec)
- {
- // this interface isn't required
- return;
- }
- const std::string* encryptionStatus = nullptr;
- const bool* isLocked = nullptr;
- for (const std::pair<std::string, dbus::utility::DbusVariantType>&
- property : propertiesList)
- {
- const std::string& propertyName = property.first;
- if (propertyName == "Type")
+ if (ec)
{
- const std::string* value =
- std::get_if<std::string>(&property.second);
- if (value == nullptr)
- {
- // illegal property
- BMCWEB_LOG_ERROR("Illegal property: Type");
- messages::internalError(asyncResp->res);
- return;
- }
-
- std::optional<drive::MediaType> mediaType =
- convertDriveType(*value);
- if (!mediaType)
- {
- BMCWEB_LOG_WARNING("UnknownDriveType Interface: {}",
- *value);
- continue;
- }
- if (*mediaType == drive::MediaType::Invalid)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- asyncResp->res.jsonValue["MediaType"] = *mediaType;
+ // this interface isn't required
+ return;
}
- else if (propertyName == "Capacity")
+ const std::string* encryptionStatus = nullptr;
+ const bool* isLocked = nullptr;
+ for (const std::pair<std::string, dbus::utility::DbusVariantType>&
+ property : propertiesList)
{
- const uint64_t* capacity =
- std::get_if<uint64_t>(&property.second);
- if (capacity == nullptr)
+ const std::string& propertyName = property.first;
+ if (propertyName == "Type")
{
- BMCWEB_LOG_ERROR("Illegal property: Capacity");
- messages::internalError(asyncResp->res);
- return;
+ const std::string* value =
+ std::get_if<std::string>(&property.second);
+ if (value == nullptr)
+ {
+ // illegal property
+ BMCWEB_LOG_ERROR("Illegal property: Type");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ std::optional<drive::MediaType> mediaType =
+ convertDriveType(*value);
+ if (!mediaType)
+ {
+ BMCWEB_LOG_WARNING("UnknownDriveType Interface: {}",
+ *value);
+ continue;
+ }
+ if (*mediaType == drive::MediaType::Invalid)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ asyncResp->res.jsonValue["MediaType"] = *mediaType;
}
- if (*capacity == 0)
+ else if (propertyName == "Capacity")
{
- // drive capacity not known
- continue;
+ const uint64_t* capacity =
+ std::get_if<uint64_t>(&property.second);
+ if (capacity == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Illegal property: Capacity");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (*capacity == 0)
+ {
+ // drive capacity not known
+ continue;
+ }
+
+ asyncResp->res.jsonValue["CapacityBytes"] = *capacity;
}
-
- asyncResp->res.jsonValue["CapacityBytes"] = *capacity;
- }
- else if (propertyName == "Protocol")
- {
- const std::string* value =
- std::get_if<std::string>(&property.second);
- if (value == nullptr)
+ else if (propertyName == "Protocol")
{
- BMCWEB_LOG_ERROR("Illegal property: Protocol");
- messages::internalError(asyncResp->res);
- return;
+ const std::string* value =
+ std::get_if<std::string>(&property.second);
+ if (value == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Illegal property: Protocol");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ std::optional<protocol::Protocol> proto =
+ convertDriveProtocol(*value);
+ if (!proto)
+ {
+ BMCWEB_LOG_WARNING(
+ "Unknown DrivePrototype Interface: {}", *value);
+ continue;
+ }
+ if (*proto == protocol::Protocol::Invalid)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["Protocol"] = *proto;
}
-
- std::optional<protocol::Protocol> proto =
- convertDriveProtocol(*value);
- if (!proto)
+ else if (propertyName == "PredictedMediaLifeLeftPercent")
{
- BMCWEB_LOG_WARNING("Unknown DrivePrototype Interface: {}",
- *value);
- continue;
- }
- if (*proto == protocol::Protocol::Invalid)
- {
- messages::internalError(asyncResp->res);
- return;
+ const uint8_t* lifeLeft =
+ std::get_if<uint8_t>(&property.second);
+ if (lifeLeft == nullptr)
+ {
+ BMCWEB_LOG_ERROR(
+ "Illegal property: PredictedMediaLifeLeftPercent");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // 255 means reading the value is not supported
+ if (*lifeLeft != 255)
+ {
+ asyncResp->res
+ .jsonValue["PredictedMediaLifeLeftPercent"] =
+ *lifeLeft;
+ }
}
- asyncResp->res.jsonValue["Protocol"] = *proto;
- }
- else if (propertyName == "PredictedMediaLifeLeftPercent")
- {
- const uint8_t* lifeLeft =
- std::get_if<uint8_t>(&property.second);
- if (lifeLeft == nullptr)
+ else if (propertyName == "EncryptionStatus")
{
- BMCWEB_LOG_ERROR(
- "Illegal property: PredictedMediaLifeLeftPercent");
- messages::internalError(asyncResp->res);
- return;
+ encryptionStatus =
+ std::get_if<std::string>(&property.second);
+ if (encryptionStatus == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Illegal property: EncryptionStatus");
+ messages::internalError(asyncResp->res);
+ return;
+ }
}
- // 255 means reading the value is not supported
- if (*lifeLeft != 255)
+ else if (propertyName == "Locked")
{
- asyncResp->res.jsonValue["PredictedMediaLifeLeftPercent"] =
- *lifeLeft;
+ isLocked = std::get_if<bool>(&property.second);
+ if (isLocked == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Illegal property: Locked");
+ messages::internalError(asyncResp->res);
+ return;
+ }
}
}
- else if (propertyName == "EncryptionStatus")
+
+ if (encryptionStatus == nullptr || isLocked == nullptr ||
+ *encryptionStatus ==
+ "xyz.openbmc_project.Inventory.Item.Drive.DriveEncryptionState.Unknown")
{
- encryptionStatus = std::get_if<std::string>(&property.second);
- if (encryptionStatus == nullptr)
- {
- BMCWEB_LOG_ERROR("Illegal property: EncryptionStatus");
- messages::internalError(asyncResp->res);
- return;
- }
+ return;
}
- else if (propertyName == "Locked")
+ if (*encryptionStatus !=
+ "xyz.openbmc_project.Inventory.Item.Drive.DriveEncryptionState.Encrypted")
{
- isLocked = std::get_if<bool>(&property.second);
- if (isLocked == nullptr)
- {
- BMCWEB_LOG_ERROR("Illegal property: Locked");
- messages::internalError(asyncResp->res);
- return;
- }
+ //"The drive is not currently encrypted."
+ asyncResp->res.jsonValue["EncryptionStatus"] =
+ drive::EncryptionStatus::Unencrypted;
+ return;
}
- }
-
- if (encryptionStatus == nullptr || isLocked == nullptr ||
- *encryptionStatus ==
- "xyz.openbmc_project.Inventory.Item.Drive.DriveEncryptionState.Unknown")
- {
- return;
- }
- if (*encryptionStatus !=
- "xyz.openbmc_project.Inventory.Item.Drive.DriveEncryptionState.Encrypted")
- {
- //"The drive is not currently encrypted."
- asyncResp->res.jsonValue["EncryptionStatus"] =
- drive::EncryptionStatus::Unencrypted;
- return;
- }
- if (*isLocked)
- {
- //"The drive is currently encrypted and the data is not
- // accessible to the user."
+ if (*isLocked)
+ {
+ //"The drive is currently encrypted and the data is not
+ // accessible to the user."
+ asyncResp->res.jsonValue["EncryptionStatus"] =
+ drive::EncryptionStatus::Locked;
+ return;
+ }
+ // if not locked
+ // "The drive is currently encrypted but the data is accessible
+ // to the user in unencrypted form."
asyncResp->res.jsonValue["EncryptionStatus"] =
- drive::EncryptionStatus::Locked;
- return;
- }
- // if not locked
- // "The drive is currently encrypted but the data is accessible
- // to the user in unencrypted form."
- asyncResp->res.jsonValue["EncryptionStatus"] =
- drive::EncryptionStatus::Unlocked;
- });
+ drive::EncryptionStatus::Unlocked;
+ });
}
-static void addAllDriveInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+inline void addAllDriveInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& connectionName,
const std::string& path,
const std::vector<std::string>& interfaces)
@@ -644,9 +647,9 @@ inline void afterGetSubtreeSystemsStorageDrive(
subtree,
[&driveId](const std::pair<std::string,
dbus::utility::MapperServiceMap>& object) {
- return sdbusplus::message::object_path(object.first).filename() ==
- driveId;
- });
+ return sdbusplus::message::object_path(object.first).filename() ==
+ driveId;
+ });
if (drive == subtree.end())
{
@@ -672,15 +675,15 @@ inline void afterGetSubtreeSystemsStorageDrive(
return;
}
- getMainChassisId(asyncResp,
- [](const std::string& chassisId,
- const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
- aRsp->res.jsonValue["Links"]["Chassis"]["@odata.id"] =
- boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
- });
+ getMainChassisId(
+ asyncResp, [](const std::string& chassisId,
+ const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
+ aRsp->res.jsonValue["Links"]["Chassis"]["@odata.id"] =
+ boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
+ });
// default it to Enabled
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
addAllDriveInfo(asyncResp, connectionNames[0].first, path,
connectionNames[0].second);
@@ -768,35 +771,36 @@ inline void afterChassisDriveCollectionSubtreeGet(
path + "/drive",
[asyncResp, chassisId](const boost::system::error_code& ec3,
const dbus::utility::MapperEndPoints& resp) {
- if (ec3)
- {
- BMCWEB_LOG_ERROR("Error in chassis Drive association ");
- }
- nlohmann::json& members = asyncResp->res.jsonValue["Members"];
- // important if array is empty
- members = nlohmann::json::array();
+ if (ec3)
+ {
+ BMCWEB_LOG_ERROR("Error in chassis Drive association ");
+ }
+ nlohmann::json& members = asyncResp->res.jsonValue["Members"];
+ // important if array is empty
+ members = nlohmann::json::array();
- std::vector<std::string> leafNames;
- for (const auto& drive : resp)
- {
- sdbusplus::message::object_path drivePath(drive);
- leafNames.push_back(drivePath.filename());
- }
+ std::vector<std::string> leafNames;
+ for (const auto& drive : resp)
+ {
+ sdbusplus::message::object_path drivePath(drive);
+ leafNames.push_back(drivePath.filename());
+ }
- std::ranges::sort(leafNames, AlphanumLess<std::string>());
+ std::ranges::sort(leafNames, AlphanumLess<std::string>());
- for (const auto& leafName : leafNames)
- {
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/Chassis/{}/Drives/{}", chassisId, leafName);
- members.emplace_back(std::move(member));
- // navigation links will be registered in next patch set
- }
- asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
- }); // end association lambda
+ for (const auto& leafName : leafNames)
+ {
+ nlohmann::json::object_t member;
+ member["@odata.id"] =
+ boost::urls::format("/redfish/v1/Chassis/{}/Drives/{}",
+ chassisId, leafName);
+ members.emplace_back(std::move(member));
+ // navigation links will be registered in next patch set
+ }
+ asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
+ }); // end association lambda
- } // end Iterate over all retrieved ObjectPaths
+ } // end Iterate over all retrieved ObjectPaths
}
/**
* Chassis drives, this URL will show all the DriveCollection
@@ -865,7 +869,7 @@ inline void buildDrive(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
asyncResp->res.jsonValue["Name"] = driveName;
asyncResp->res.jsonValue["Id"] = driveName;
// default it to Enabled
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
nlohmann::json::object_t linkChassisNav;
linkChassisNav["@odata.id"] =
@@ -877,11 +881,10 @@ inline void buildDrive(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
}
}
-inline void
- matchAndFillDrive(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId,
- const std::string& driveName,
- const std::vector<std::string>& resp)
+inline void matchAndFillDrive(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const std::string& driveName,
+ const std::vector<std::string>& resp)
{
for (const std::string& drivePath : resp)
{
@@ -899,16 +902,15 @@ inline void
[asyncResp, chassisId, driveName](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- buildDrive(asyncResp, chassisId, driveName, ec, subtree);
- });
+ buildDrive(asyncResp, chassisId, driveName, ec, subtree);
+ });
}
}
-inline void
- handleChassisDriveGet(crow::App& app, const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId,
- const std::string& driveName)
+inline void handleChassisDriveGet(
+ crow::App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const std::string& driveName)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
@@ -924,41 +926,42 @@ inline void
[asyncResp, chassisId,
driveName](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Iterate over all retrieved ObjectPaths.
- for (const auto& [path, connectionNames] : subtree)
- {
- sdbusplus::message::object_path objPath(path);
- if (objPath.filename() != chassisId)
+ if (ec)
{
- continue;
+ messages::internalError(asyncResp->res);
+ return;
}
- if (connectionNames.empty())
+ // Iterate over all retrieved ObjectPaths.
+ for (const auto& [path, connectionNames] : subtree)
{
- BMCWEB_LOG_ERROR("Got 0 Connection names");
- continue;
- }
+ sdbusplus::message::object_path objPath(path);
+ if (objPath.filename() != chassisId)
+ {
+ continue;
+ }
- dbus::utility::getAssociationEndPoints(
- path + "/drive",
- [asyncResp, chassisId,
- driveName](const boost::system::error_code& ec3,
- const dbus::utility::MapperEndPoints& resp) {
- if (ec3)
+ if (connectionNames.empty())
{
- return; // no drives = no failures
+ BMCWEB_LOG_ERROR("Got 0 Connection names");
+ continue;
}
- matchAndFillDrive(asyncResp, chassisId, driveName, resp);
- });
- break;
- }
- });
+
+ dbus::utility::getAssociationEndPoints(
+ path + "/drive",
+ [asyncResp, chassisId,
+ driveName](const boost::system::error_code& ec3,
+ const dbus::utility::MapperEndPoints& resp) {
+ if (ec3)
+ {
+ return; // no drives = no failures
+ }
+ matchAndFillDrive(asyncResp, chassisId, driveName,
+ resp);
+ });
+ break;
+ }
+ });
}
/**
@@ -1031,24 +1034,25 @@ inline void populateStorageController(
BMCWEB_REDFISH_SYSTEM_URI_NAME, controllerId);
asyncResp->res.jsonValue["Name"] = controllerId;
asyncResp->res.jsonValue["Id"] = controllerId;
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, connectionName, path,
"xyz.openbmc_project.Inventory.Item", "Present",
[asyncResp](const boost::system::error_code& ec, bool isPresent) {
- // this interface isn't necessary, only check it
- // if we get a good return
- if (ec)
- {
- BMCWEB_LOG_DEBUG("Failed to get Present property");
- return;
- }
- if (!isPresent)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- }
- });
+ // this interface isn't necessary, only check it
+ // if we get a good return
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("Failed to get Present property");
+ return;
+ }
+ if (!isPresent)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
+ }
+ });
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, connectionName, path,
@@ -1057,8 +1061,8 @@ inline void populateStorageController(
const std::vector<
std::pair<std::string, dbus::utility::DbusVariantType>>&
propertiesList) {
- getStorageControllerAsset(asyncResp, ec, propertiesList);
- });
+ getStorageControllerAsset(asyncResp, ec, propertiesList);
+ });
}
inline void getStorageControllerHandler(
@@ -1166,8 +1170,8 @@ inline void handleSystemsStorageControllerCollectionGet(
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse&
controllerList) {
- populateStorageControllerCollection(asyncResp, ec, controllerList);
- });
+ populateStorageControllerCollection(asyncResp, ec, controllerList);
+ });
}
inline void handleSystemsStorageControllerGet(
@@ -1194,8 +1198,8 @@ inline void handleSystemsStorageControllerGet(
[asyncResp,
controllerId](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- getStorageControllerHandler(asyncResp, controllerId, ec, subtree);
- });
+ getStorageControllerHandler(asyncResp, controllerId, ec, subtree);
+ });
}
inline void requestRoutesStorageControllerCollection(App& app)
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 5d7dba1c36..d9a8d17455 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -20,7 +20,9 @@
#include "app.hpp"
#include "dbus_singleton.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/action_info.hpp"
#include "generated/enums/computer_system.hpp"
+#include "generated/enums/open_bmc_computer_system.hpp"
#include "generated/enums/resource.hpp"
#include "hypervisor_system.hpp"
#include "led.hpp"
@@ -65,9 +67,8 @@ const static std::array<std::pair<std::string_view, std::string_view>, 2>
*
* @return None.
*/
-inline void
- updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- bool isDimmFunctional)
+inline void updateDimmProperties(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
{
BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
@@ -124,9 +125,8 @@ inline void modifyCpuFunctionalState(
*
* @return None.
*/
-inline void
- modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- bool isCpuPresent)
+inline void modifyCpuPresenceState(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
{
BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
@@ -216,14 +216,14 @@ inline void
[asyncResp, service,
path](const boost::system::error_code& ec2,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec2)
- {
- BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
- messages::internalError(asyncResp->res);
- return;
- }
- getProcessorProperties(asyncResp, properties);
- });
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ getProcessorProperties(asyncResp, properties);
+ });
}
/*
@@ -295,14 +295,14 @@ inline void
[asyncResp, service,
path](const boost::system::error_code& ec2,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec2)
- {
- BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
- messages::internalError(asyncResp->res);
- return;
- }
- processMemoryProperties(asyncResp, properties);
- });
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ processMemoryProperties(asyncResp, properties);
+ });
}
inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -403,10 +403,9 @@ inline void
"BiosVersion", false);
}
-inline void
- afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const boost::system::error_code& ec,
- const std::string& value)
+inline void afterGetAssetTag(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::system::error_code& ec, const std::string& value)
{
if (ec)
{
@@ -473,8 +472,8 @@ inline void afterSystemGetSubTree(
[asyncResp](const boost::system::error_code& ec3,
const dbus::utility::DBusPropertiesMap&
properties) {
- afterGetUUID(asyncResp, ec3, properties);
- });
+ afterGetUUID(asyncResp, ec3, properties);
+ });
}
else if (interfaceName ==
"xyz.openbmc_project.Inventory.Item.System")
@@ -485,8 +484,8 @@ inline void afterSystemGetSubTree(
[asyncResp](const boost::system::error_code& ec3,
const dbus::utility::DBusPropertiesMap&
properties) {
- afterGetInventory(asyncResp, ec3, properties);
- });
+ afterGetInventory(asyncResp, ec3, properties);
+ });
sdbusplus::asio::getProperty<std::string>(
*crow::connections::systemBus, connection.first, path,
@@ -539,58 +538,71 @@ inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
"CurrentHostState",
[asyncResp](const boost::system::error_code& ec,
const std::string& hostState) {
- if (ec)
- {
- if (ec == boost::system::errc::host_unreachable)
+ if (ec)
{
- // Service not available, no error, just don't return
- // host state info
- BMCWEB_LOG_DEBUG("Service not available {}", ec);
+ if (ec == boost::system::errc::host_unreachable)
+ {
+ // Service not available, no error, just don't return
+ // host state info
+ BMCWEB_LOG_DEBUG("Service not available {}", ec);
+ return;
+ }
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG("Host state: {}", hostState);
- // Verify Host State
- if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
- {
- asyncResp->res.jsonValue["PowerState"] = "On";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- }
- else if (hostState ==
- "xyz.openbmc_project.State.Host.HostState.Quiesced")
- {
- asyncResp->res.jsonValue["PowerState"] = "On";
- asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
- }
- else if (hostState ==
- "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
- {
- asyncResp->res.jsonValue["PowerState"] = "On";
- asyncResp->res.jsonValue["Status"]["State"] = "InTest";
- }
- else if (
- hostState ==
- "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
- {
- asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
- asyncResp->res.jsonValue["Status"]["State"] = "Starting";
- }
- else if (hostState ==
- "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
- {
- asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
- asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
- }
- else
- {
- asyncResp->res.jsonValue["PowerState"] = "Off";
- asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
- }
- });
+ BMCWEB_LOG_DEBUG("Host state: {}", hostState);
+ // Verify Host State
+ if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::On;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+ }
+ else if (hostState ==
+ "xyz.openbmc_project.State.Host.HostState.Quiesced")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::On;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Quiesced;
+ }
+ else if (hostState ==
+ "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::On;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::InTest;
+ }
+ else if (
+ hostState ==
+ "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::PoweringOn;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Starting;
+ }
+ else if (
+ hostState ==
+ "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::PoweringOff;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Disabled;
+ }
+ else
+ {
+ asyncResp->res.jsonValue["PowerState"] =
+ resource::PowerState::Off;
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Disabled;
+ }
+ });
}
/**
@@ -763,10 +775,9 @@ inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
*
* @return Integer error code.
*/
-inline int
- assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& rfSource, std::string& bootSource,
- std::string& bootMode)
+inline int assignBootParameters(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& rfSource, std::string& bootSource, std::string& bootMode)
{
bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
@@ -828,18 +839,18 @@ inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
"xyz.openbmc_project.State.Boot.Progress", "BootProgress",
[asyncResp](const boost::system::error_code& ec,
const std::string& bootProgressStr) {
- if (ec)
- {
- // BootProgress is an optional object so just do nothing if
- // not found
- return;
- }
+ if (ec)
+ {
+ // BootProgress is an optional object so just do nothing if
+ // not found
+ return;
+ }
- BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
+ BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
- asyncResp->res.jsonValue["BootProgress"]["LastState"] =
- dbusToRfBootProgress(bootProgressStr);
- });
+ asyncResp->res.jsonValue["BootProgress"]["LastState"] =
+ dbusToRfBootProgress(bootProgressStr);
+ });
}
/**
@@ -858,22 +869,22 @@ inline void getBootProgressLastStateTime(
"xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
[asyncResp](const boost::system::error_code& ec,
const uint64_t lastStateTime) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
+ return;
+ }
- // BootProgressLastUpdate is the last time the BootProgress property
- // was updated. The time is the Epoch time, number of microseconds
- // since 1 Jan 1970 00::00::00 UTC."
- // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
- // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
+ // BootProgressLastUpdate is the last time the BootProgress property
+ // was updated. The time is the Epoch time, number of microseconds
+ // since 1 Jan 1970 00::00::00 UTC."
+ // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
+ // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
- // Convert to ISO 8601 standard
- asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
- redfish::time_utils::getDateTimeUintUs(lastStateTime);
- });
+ // Convert to ISO 8601 standard
+ asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
+ redfish::time_utils::getDateTimeUintUs(lastStateTime);
+ });
}
/**
@@ -893,28 +904,28 @@ inline void
"xyz.openbmc_project.Control.Boot.Type", "BootType",
[asyncResp](const boost::system::error_code& ec,
const std::string& bootType) {
- if (ec)
- {
- // not an error, don't have to have the interface
- return;
- }
+ if (ec)
+ {
+ // not an error, don't have to have the interface
+ return;
+ }
- BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
+ BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
- asyncResp->res
- .jsonValue["Boot"]
- ["BootSourceOverrideMode@Redfish.AllowableValues"] =
- nlohmann::json::array_t({"Legacy", "UEFI"});
+ asyncResp->res
+ .jsonValue["Boot"]
+ ["BootSourceOverrideMode@Redfish.AllowableValues"] =
+ nlohmann::json::array_t({"Legacy", "UEFI"});
- auto rfType = dbusToRfBootType(bootType);
- if (rfType.empty())
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ auto rfType = dbusToRfBootType(bootType);
+ if (rfType.empty())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
- });
+ asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
+ });
}
/**
@@ -934,39 +945,39 @@ inline void
"xyz.openbmc_project.Control.Boot.Mode", "BootMode",
[asyncResp](const boost::system::error_code& ec,
const std::string& bootModeStr) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
-
- nlohmann::json::array_t allowed;
- allowed.emplace_back("None");
- allowed.emplace_back("Pxe");
- allowed.emplace_back("Hdd");
- allowed.emplace_back("Cd");
- allowed.emplace_back("Diags");
- allowed.emplace_back("BiosSetup");
- allowed.emplace_back("Usb");
-
- asyncResp->res
- .jsonValue["Boot"]
- ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
- std::move(allowed);
- if (bootModeStr !=
- "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
- {
- auto rfMode = dbusToRfBootMode(bootModeStr);
- if (!rfMode.empty())
+ BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
+
+ nlohmann::json::array_t allowed;
+ allowed.emplace_back("None");
+ allowed.emplace_back("Pxe");
+ allowed.emplace_back("Hdd");
+ allowed.emplace_back("Cd");
+ allowed.emplace_back("Diags");
+ allowed.emplace_back("BiosSetup");
+ allowed.emplace_back("Usb");
+
+ asyncResp->res
+ .jsonValue["Boot"]
+ ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
+ std::move(allowed);
+ if (bootModeStr !=
+ "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
{
- asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
- rfMode;
+ auto rfMode = dbusToRfBootMode(bootModeStr);
+ if (!rfMode.empty())
+ {
+ asyncResp->res
+ .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
+ }
}
- }
- });
+ });
}
/**
@@ -986,30 +997,30 @@ inline void
"xyz.openbmc_project.Control.Boot.Source", "BootSource",
[asyncResp](const boost::system::error_code& ec,
const std::string& bootSourceStr) {
- if (ec)
- {
- if (ec.value() == boost::asio::error::host_unreachable)
+ if (ec)
{
+ if (ec.value() == boost::asio::error::host_unreachable)
+ {
+ return;
+ }
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
+ BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
- auto rfSource = dbusToRfBootSource(bootSourceStr);
- if (!rfSource.empty())
- {
- asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
- rfSource;
- }
+ auto rfSource = dbusToRfBootSource(bootSourceStr);
+ if (!rfSource.empty())
+ {
+ asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
+ rfSource;
+ }
- // Get BootMode as BootSourceOverrideTarget is constructed
- // from both BootSource and BootMode
- getBootOverrideMode(asyncResp);
- });
+ // Get BootMode as BootSourceOverrideTarget is constructed
+ // from both BootSource and BootMode
+ getBootOverrideMode(asyncResp);
+ });
}
/**
@@ -1040,24 +1051,24 @@ inline void processBootOverrideEnable(
"/xyz/openbmc_project/control/host0/boot/one_time",
"xyz.openbmc_project.Object.Enable", "Enabled",
[asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (oneTimeSetting)
- {
- asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
- "Once";
- }
- else
- {
- asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
- "Continuous";
- }
- });
+ if (oneTimeSetting)
+ {
+ asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
+ "Once";
+ }
+ else
+ {
+ asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
+ "Continuous";
+ }
+ });
}
/**
@@ -1077,19 +1088,19 @@ inline void
"xyz.openbmc_project.Object.Enable", "Enabled",
[asyncResp](const boost::system::error_code& ec,
const bool bootOverrideEnable) {
- if (ec)
- {
- if (ec.value() == boost::asio::error::host_unreachable)
+ if (ec)
{
+ if (ec.value() == boost::asio::error::host_unreachable)
+ {
+ return;
+ }
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- processBootOverrideEnable(asyncResp, bootOverrideEnable);
- });
+ processBootOverrideEnable(asyncResp, bootOverrideEnable);
+ });
}
/**
@@ -1132,20 +1143,20 @@ inline void
"xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
[asyncResp](const boost::system::error_code& ec,
uint64_t lastResetTime) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
+ return;
+ }
- // LastStateChangeTime is epoch time, in milliseconds
- // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
- uint64_t lastResetTimeStamp = lastResetTime / 1000;
+ // LastStateChangeTime is epoch time, in milliseconds
+ // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
+ uint64_t lastResetTimeStamp = lastResetTime / 1000;
- // Convert to ISO 8601 standard
- asyncResp->res.jsonValue["LastResetTime"] =
- redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
- });
+ // Convert to ISO 8601 standard
+ asyncResp->res.jsonValue["LastResetTime"] =
+ redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
+ });
}
/**
@@ -1172,42 +1183,42 @@ inline void getAutomaticRebootAttempts(
[asyncResp{asyncResp}](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- const uint32_t* attemptsLeft = nullptr;
- const uint32_t* retryAttempts = nullptr;
+ const uint32_t* attemptsLeft = nullptr;
+ const uint32_t* retryAttempts = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
- attemptsLeft, "RetryAttempts", retryAttempts);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList,
+ "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (attemptsLeft != nullptr)
- {
- asyncResp->res
- .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
- *attemptsLeft;
- }
+ if (attemptsLeft != nullptr)
+ {
+ asyncResp->res
+ .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
+ *attemptsLeft;
+ }
- if (retryAttempts != nullptr)
- {
- asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
- *retryAttempts;
- }
- });
+ if (retryAttempts != nullptr)
+ {
+ asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
+ *retryAttempts;
+ }
+ });
}
/**
@@ -1228,39 +1239,40 @@ inline void
"xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
[asyncResp](const boost::system::error_code& ec,
bool autoRebootEnabled) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
-
- BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
- if (autoRebootEnabled)
- {
- asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
- "RetryAttempts";
- }
- else
- {
- asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
- "Disabled";
- }
- getAutomaticRebootAttempts(asyncResp);
- // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
- // and RetryAttempts. OpenBMC only supports Disabled and
- // RetryAttempts.
- nlohmann::json::array_t allowed;
- allowed.emplace_back("Disabled");
- allowed.emplace_back("RetryAttempts");
- asyncResp->res
- .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
- std::move(allowed);
- });
+ BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
+ if (autoRebootEnabled)
+ {
+ asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
+ "RetryAttempts";
+ }
+ else
+ {
+ asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
+ "Disabled";
+ }
+ getAutomaticRebootAttempts(asyncResp);
+
+ // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
+ // and RetryAttempts. OpenBMC only supports Disabled and
+ // RetryAttempts.
+ nlohmann::json::array_t allowed;
+ allowed.emplace_back("Disabled");
+ allowed.emplace_back("RetryAttempts");
+ asyncResp->res
+ .jsonValue["Boot"]
+ ["AutomaticRetryConfig@Redfish.AllowableValues"] =
+ std::move(allowed);
+ });
}
/**
@@ -1327,21 +1339,21 @@ inline void
"xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
[asyncResp](const boost::system::error_code& ec,
const std::string& policy) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- return;
- }
- computer_system::PowerRestorePolicyTypes restore =
- redfishPowerRestorePolicyFromDbus(policy);
- if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ return;
+ }
+ computer_system::PowerRestorePolicyTypes restore =
+ redfishPowerRestorePolicyFromDbus(policy);
+ if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
- });
+ asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
+ });
}
/**
@@ -1361,25 +1373,27 @@ inline void
"/xyz/openbmc_project/logging/settings",
"xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
[asyncResp](const boost::system::error_code& ec, bool value) {
- if (ec)
- {
- if (ec.value() != EBADR)
+ if (ec)
{
- BMCWEB_LOG_ERROR("DBUS response error {}", ec);
- messages::internalError(asyncResp->res);
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ }
+ return;
}
- return;
- }
- if (value)
- {
- asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
- }
- else
- {
- asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
- }
- });
+ if (value)
+ {
+ asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
+ computer_system::StopBootOnFault::AnyFault;
+ }
+ else
+ {
+ asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
+ computer_system::StopBootOnFault::Never;
+ }
+ });
}
/**
@@ -1400,72 +1414,72 @@ inline void getTrustedModuleRequiredToBoot(
"/", 0, interfaces,
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
- ec);
- // This is an optional D-Bus object so just return if
- // error occurs
- return;
- }
- if (subtree.empty())
- {
- // As noted above, this is an optional interface so just return
- // if there is no instance found
- return;
- }
-
- /* When there is more than one TPMEnable object... */
- if (subtree.size() > 1)
- {
- BMCWEB_LOG_DEBUG(
- "DBUS response has more than 1 TPM Enable object:{}",
- subtree.size());
- // Throw an internal Error and return
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Make sure the Dbus response map has a service and objectPath
- // field
- if (subtree[0].first.empty() || subtree[0].second.size() != 1)
- {
- BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
-
- const std::string& path = subtree[0].first;
- const std::string& serv = subtree[0].second.begin()->first;
-
- // Valid TPM Enable object found, now reading the current value
- sdbusplus::asio::getProperty<bool>(
- *crow::connections::systemBus, serv, path,
- "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
- [asyncResp](const boost::system::error_code& ec2,
- bool tpmRequired) {
- if (ec2)
+ if (ec)
{
- BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
- ec2);
- messages::internalError(asyncResp->res);
+ BMCWEB_LOG_DEBUG(
+ "DBUS response error on TPM.Policy GetSubTree{}", ec);
+ // This is an optional D-Bus object so just return if
+ // error occurs
+ return;
+ }
+ if (subtree.empty())
+ {
+ // As noted above, this is an optional interface so just return
+ // if there is no instance found
return;
}
- if (tpmRequired)
+ /* When there is more than one TPMEnable object... */
+ if (subtree.size() > 1)
{
- asyncResp->res
- .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
- "Required";
+ BMCWEB_LOG_DEBUG(
+ "DBUS response has more than 1 TPM Enable object:{}",
+ subtree.size());
+ // Throw an internal Error and return
+ messages::internalError(asyncResp->res);
+ return;
}
- else
+
+ // Make sure the Dbus response map has a service and objectPath
+ // field
+ if (subtree[0].first.empty() || subtree[0].second.size() != 1)
{
- asyncResp->res
- .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
- "Disabled";
+ BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
}
+
+ const std::string& path = subtree[0].first;
+ const std::string& serv = subtree[0].second.begin()->first;
+
+ // Valid TPM Enable object found, now reading the current value
+ sdbusplus::asio::getProperty<bool>(
+ *crow::connections::systemBus, serv, path,
+ "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
+ [asyncResp](const boost::system::error_code& ec2,
+ bool tpmRequired) {
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "D-BUS response error on TPM.Policy Get{}", ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (tpmRequired)
+ {
+ asyncResp->res
+ .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
+ "Required";
+ }
+ else
+ {
+ asyncResp->res
+ .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
+ "Disabled";
+ }
+ });
});
- });
}
/**
@@ -1488,55 +1502,56 @@ inline void setTrustedModuleRequiredToBoot(
[asyncResp,
tpmRequired](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
- ec);
- messages::internalError(asyncResp->res);
- return;
- }
- if (subtree.empty())
- {
- messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
- "TrustedModuleRequiredToBoot");
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBUS response error on TPM.Policy GetSubTree{}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (subtree.empty())
+ {
+ messages::propertyValueNotInList(asyncResp->res,
+ "ComputerSystem",
+ "TrustedModuleRequiredToBoot");
+ return;
+ }
- /* When there is more than one TPMEnable object... */
- if (subtree.size() > 1)
- {
- BMCWEB_LOG_DEBUG(
- "DBUS response has more than 1 TPM Enable object:{}",
- subtree.size());
- // Throw an internal Error and return
- messages::internalError(asyncResp->res);
- return;
- }
+ /* When there is more than one TPMEnable object... */
+ if (subtree.size() > 1)
+ {
+ BMCWEB_LOG_DEBUG(
+ "DBUS response has more than 1 TPM Enable object:{}",
+ subtree.size());
+ // Throw an internal Error and return
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // Make sure the Dbus response map has a service and objectPath
- // field
- if (subtree[0].first.empty() || subtree[0].second.size() != 1)
- {
- BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
+ // Make sure the Dbus response map has a service and objectPath
+ // field
+ if (subtree[0].first.empty() || subtree[0].second.size() != 1)
+ {
+ BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const std::string& path = subtree[0].first;
- const std::string& serv = subtree[0].second.begin()->first;
+ const std::string& path = subtree[0].first;
+ const std::string& serv = subtree[0].second.begin()->first;
- if (serv.empty())
- {
- BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (serv.empty())
+ {
+ BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // Valid TPM Enable object found, now setting the value
- setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
- path, "xyz.openbmc_project.Control.TPM.Policy",
- "TPMEnable", tpmRequired);
- });
+ // Valid TPM Enable object found, now setting the value
+ setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
+ path, "xyz.openbmc_project.Control.TPM.Policy",
+ "TPMEnable", tpmRequired);
+ });
}
/**
@@ -1755,47 +1770,47 @@ inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
[asyncResp,
assetTag](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- if (subtree.empty())
- {
- BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
- messages::internalError(asyncResp->res);
- return;
- }
- // Assume only 1 system D-Bus object
- // Throw an error if there is more than 1
- if (subtree.size() > 1)
- {
- BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
- messages::internalError(asyncResp->res);
- return;
- }
- if (subtree[0].first.empty() || subtree[0].second.size() != 1)
- {
- BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (subtree.empty())
+ {
+ BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // Assume only 1 system D-Bus object
+ // Throw an error if there is more than 1
+ if (subtree.size() > 1)
+ {
+ BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (subtree[0].first.empty() || subtree[0].second.size() != 1)
+ {
+ BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const std::string& path = subtree[0].first;
- const std::string& service = subtree[0].second.begin()->first;
+ const std::string& path = subtree[0].first;
+ const std::string& service = subtree[0].second.begin()->first;
- if (service.empty())
- {
- BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (service.empty())
+ {
+ BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- setDbusProperty(asyncResp, "AssetTag", service, path,
- "xyz.openbmc_project.Inventory.Decorator.AssetTag",
- "AssetTag", assetTag);
- });
+ setDbusProperty(asyncResp, "AssetTag", service, path,
+ "xyz.openbmc_project.Inventory.Decorator.AssetTag",
+ "AssetTag", assetTag);
+ });
}
/**
@@ -1962,56 +1977,62 @@ inline void
"/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- nlohmann::json& oemPFR =
- asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
- asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
- "#OemComputerSystem.OpenBmc";
- oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
+ nlohmann::json& oemPFR =
+ asyncResp->res
+ .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
+ asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
+ "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
+ oemPFR["@odata.type"] =
+ "#OpenBMCComputerSystem.FirmwareProvisioning";
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- // not an error, don't have to have the interface
- oemPFR["ProvisioningStatus"] = "NotProvisioned";
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ // not an error, don't have to have the interface
+ oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
+ FirmwareProvisioningStatus::NotProvisioned;
+ return;
+ }
- const bool* provState = nullptr;
- const bool* lockState = nullptr;
+ const bool* provState = nullptr;
+ const bool* lockState = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
- provState, "UfmLocked", lockState);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList,
+ "UfmProvisioned", provState, "UfmLocked", lockState);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if ((provState == nullptr) || (lockState == nullptr))
- {
- BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
- messages::internalError(asyncResp->res);
- return;
- }
+ if ((provState == nullptr) || (lockState == nullptr))
+ {
+ BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (*provState)
- {
- if (*lockState)
+ if (*provState)
{
- oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
+ if (*lockState)
+ {
+ oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
+ FirmwareProvisioningStatus::ProvisionedAndLocked;
+ }
+ else
+ {
+ oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
+ FirmwareProvisioningStatus::ProvisionedButNotLocked;
+ }
}
else
{
- oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
+ oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
+ FirmwareProvisioningStatus::NotProvisioned;
}
- }
- else
- {
- oemPFR["ProvisioningStatus"] = "NotProvisioned";
- }
- });
+ });
}
/**
@@ -2139,54 +2160,55 @@ inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
"/", 0, interfaces,
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
- ec);
- // This is an optional D-Bus object so just return if
- // error occurs
- return;
- }
- if (subtree.empty())
- {
- // As noted above, this is an optional interface so just return
- // if there is no instance found
- return;
- }
- if (subtree.size() > 1)
- {
- // More then one PowerMode object is not supported and is an
- // error
- BMCWEB_LOG_DEBUG(
- "Found more than 1 system D-Bus Power.Mode objects: {}",
- subtree.size());
- messages::internalError(asyncResp->res);
- return;
- }
- if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
- {
- BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& path = subtree[0].first;
- const std::string& service = subtree[0].second.begin()->first;
- if (service.empty())
- {
- BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG(
+ "DBUS response error on Power.Mode GetSubTree {}", ec);
+ // This is an optional D-Bus object so just return if
+ // error occurs
+ return;
+ }
+ if (subtree.empty())
+ {
+ // As noted above, this is an optional interface so just return
+ // if there is no instance found
+ return;
+ }
+ if (subtree.size() > 1)
+ {
+ // More then one PowerMode object is not supported and is an
+ // error
+ BMCWEB_LOG_DEBUG(
+ "Found more than 1 system D-Bus Power.Mode objects: {}",
+ subtree.size());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
+ {
+ BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const std::string& path = subtree[0].first;
+ const std::string& service = subtree[0].second.begin()->first;
+ if (service.empty())
+ {
+ BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // Valid Power Mode object found, now read the mode properties
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, service, path,
- "xyz.openbmc_project.Control.Power.Mode",
- [asyncResp](const boost::system::error_code& ec2,
- const dbus::utility::DBusPropertiesMap& properties) {
- afterGetPowerMode(asyncResp, ec2, properties);
+ // Valid Power Mode object found, now read the mode properties
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, service, path,
+ "xyz.openbmc_project.Control.Power.Mode",
+ [asyncResp](
+ const boost::system::error_code& ec2,
+ const dbus::utility::DBusPropertiesMap& properties) {
+ afterGetPowerMode(asyncResp, ec2, properties);
+ });
});
- });
}
/**
@@ -2268,53 +2290,53 @@ inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
[asyncResp,
powerMode](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
- ec);
- // This is an optional D-Bus object, but user attempted to patch
- messages::internalError(asyncResp->res);
- return;
- }
- if (subtree.empty())
- {
- // This is an optional D-Bus object, but user attempted to patch
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- "PowerMode");
- return;
- }
- if (subtree.size() > 1)
- {
- // More then one PowerMode object is not supported and is an
- // error
- BMCWEB_LOG_DEBUG(
- "Found more than 1 system D-Bus Power.Mode objects: {}",
- subtree.size());
- messages::internalError(asyncResp->res);
- return;
- }
- if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
- {
- BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& path = subtree[0].first;
- const std::string& service = subtree[0].second.begin()->first;
- if (service.empty())
- {
- BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBUS response error on Power.Mode GetSubTree {}", ec);
+ // This is an optional D-Bus object, but user attempted to patch
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (subtree.empty())
+ {
+ // This is an optional D-Bus object, but user attempted to patch
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ "PowerMode");
+ return;
+ }
+ if (subtree.size() > 1)
+ {
+ // More then one PowerMode object is not supported and is an
+ // error
+ BMCWEB_LOG_DEBUG(
+ "Found more than 1 system D-Bus Power.Mode objects: {}",
+ subtree.size());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
+ {
+ BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const std::string& path = subtree[0].first;
+ const std::string& service = subtree[0].second.begin()->first;
+ if (service.empty())
+ {
+ BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
+ BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
- // Set the Power Mode property
- setDbusProperty(asyncResp, "PowerMode", service, path,
- "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
- powerMode);
- });
+ // Set the Power Mode property
+ setDbusProperty(asyncResp, "PowerMode", service, path,
+ "xyz.openbmc_project.Control.Power.Mode",
+ "PowerMode", powerMode);
+ });
}
/**
@@ -2395,50 +2417,50 @@ inline void
"xyz.openbmc_project.State.Watchdog",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& properties) {
- if (ec)
- {
- // watchdog service is stopped
- BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
- return;
- }
+ if (ec)
+ {
+ // watchdog service is stopped
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ return;
+ }
- BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
+ BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
- nlohmann::json& hostWatchdogTimer =
- asyncResp->res.jsonValue["HostWatchdogTimer"];
+ nlohmann::json& hostWatchdogTimer =
+ asyncResp->res.jsonValue["HostWatchdogTimer"];
- // watchdog service is running/enabled
- hostWatchdogTimer["Status"]["State"] = "Enabled";
+ // watchdog service is running/enabled
+ hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
- const bool* enabled = nullptr;
- const std::string* expireAction = nullptr;
+ const bool* enabled = nullptr;
+ const std::string* expireAction = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
- "ExpireAction", expireAction);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
+ enabled, "ExpireAction", expireAction);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- if (enabled != nullptr)
- {
- hostWatchdogTimer["FunctionEnabled"] = *enabled;
- }
-
- if (expireAction != nullptr)
- {
- std::string action = dbusToRfWatchdogAction(*expireAction);
- if (action.empty())
+ if (!success)
{
messages::internalError(asyncResp->res);
return;
}
- hostWatchdogTimer["TimeoutAction"] = action;
- }
- });
+
+ if (enabled != nullptr)
+ {
+ hostWatchdogTimer["FunctionEnabled"] = *enabled;
+ }
+
+ if (expireAction != nullptr)
+ {
+ std::string action = dbusToRfWatchdogAction(*expireAction);
+ if (action.empty())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ hostWatchdogTimer["TimeoutAction"] = action;
+ }
+ });
}
/**
@@ -2574,67 +2596,69 @@ inline void
"/", 0, interfaces,
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_ERROR(
- "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
- ec);
- messages::internalError(asyncResp->res);
- return;
- }
- if (subtree.empty())
- {
- // This is an optional interface so just return
- // if there is no instance found
- BMCWEB_LOG_DEBUG("No instances found");
- return;
- }
- if (subtree.size() > 1)
- {
- // More then one PowerIdlePowerSaver object is not supported and
- // is an error
- BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
- "Power.IdlePowerSaver objects: {}",
- subtree.size());
- messages::internalError(asyncResp->res);
- return;
- }
- if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
- {
- BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& path = subtree[0].first;
- const std::string& service = subtree[0].second.begin()->first;
- if (service.empty())
- {
- BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Valid IdlePowerSaver object found, now read the current values
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, service, path,
- "xyz.openbmc_project.Control.Power.IdlePowerSaver",
- [asyncResp](const boost::system::error_code& ec2,
- const dbus::utility::DBusPropertiesMap& properties) {
- if (ec2)
+ if (ec)
{
BMCWEB_LOG_ERROR(
- "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
+ "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
+ ec);
messages::internalError(asyncResp->res);
return;
}
-
- if (!parseIpsProperties(asyncResp, properties))
+ if (subtree.empty())
{
+ // This is an optional interface so just return
+ // if there is no instance found
+ BMCWEB_LOG_DEBUG("No instances found");
+ return;
+ }
+ if (subtree.size() > 1)
+ {
+ // More then one PowerIdlePowerSaver object is not supported and
+ // is an error
+ BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
+ "Power.IdlePowerSaver objects: {}",
+ subtree.size());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
+ {
+ BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const std::string& path = subtree[0].first;
+ const std::string& service = subtree[0].second.begin()->first;
+ if (service.empty())
+ {
+ BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
messages::internalError(asyncResp->res);
return;
}
+
+ // Valid IdlePowerSaver object found, now read the current values
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, service, path,
+ "xyz.openbmc_project.Control.Power.IdlePowerSaver",
+ [asyncResp](
+ const boost::system::error_code& ec2,
+ const dbus::utility::DBusPropertiesMap& properties) {
+ if (ec2)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBUS response error on IdlePowerSaver GetAll: {}",
+ ec2);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (!parseIpsProperties(asyncResp, properties))
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ });
});
- });
BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
}
@@ -2654,13 +2678,13 @@ inline void
*
* @return None.
*/
-inline void
- setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::optional<bool> ipsEnable,
- const std::optional<uint8_t> ipsEnterUtil,
- const std::optional<uint64_t> ipsEnterTime,
- const std::optional<uint8_t> ipsExitUtil,
- const std::optional<uint64_t> ipsExitTime)
+inline void setIdlePowerSaver(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::optional<bool> ipsEnable,
+ const std::optional<uint8_t> ipsEnterUtil,
+ const std::optional<uint64_t> ipsEnterTime,
+ const std::optional<uint8_t> ipsExitUtil,
+ const std::optional<uint64_t> ipsExitTime)
{
BMCWEB_LOG_DEBUG("Set idle power saver properties");
@@ -2672,88 +2696,90 @@ inline void
[asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
ipsExitTime](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_ERROR(
- "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
- ec);
- messages::internalError(asyncResp->res);
- return;
- }
- if (subtree.empty())
- {
- // This is an optional D-Bus object, but user attempted to patch
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- "IdlePowerSaver");
- return;
- }
- if (subtree.size() > 1)
- {
- // More then one PowerIdlePowerSaver object is not supported and
- // is an error
- BMCWEB_LOG_DEBUG(
- "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
- subtree.size());
- messages::internalError(asyncResp->res);
- return;
- }
- if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
- {
- BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& path = subtree[0].first;
- const std::string& service = subtree[0].second.begin()->first;
- if (service.empty())
- {
- BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR(
+ "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
+ ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (subtree.empty())
+ {
+ // This is an optional D-Bus object, but user attempted to patch
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ "IdlePowerSaver");
+ return;
+ }
+ if (subtree.size() > 1)
+ {
+ // More then one PowerIdlePowerSaver object is not supported and
+ // is an error
+ BMCWEB_LOG_DEBUG(
+ "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
+ subtree.size());
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
+ {
+ BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ const std::string& path = subtree[0].first;
+ const std::string& service = subtree[0].second.begin()->first;
+ if (service.empty())
+ {
+ BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- // Valid Power IdlePowerSaver object found, now set any values that
- // need to be updated
+ // Valid Power IdlePowerSaver object found, now set any values that
+ // need to be updated
- if (ipsEnable)
- {
- setDbusProperty(asyncResp, "IdlePowerSaver/Enabled", service, path,
- "xyz.openbmc_project.Control.Power.IdlePowerSaver",
- "Enabled", *ipsEnable);
- }
- if (ipsEnterUtil)
- {
- setDbusProperty(asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
- service, path,
- "xyz.openbmc_project.Control.Power.IdlePowerSaver",
- "EnterUtilizationPercent", *ipsEnterUtil);
- }
- if (ipsEnterTime)
- {
- // Convert from seconds into milliseconds for DBus
- const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
- setDbusProperty(asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds",
- service, path,
- "xyz.openbmc_project.Control.Power.IdlePowerSaver",
- "EnterDwellTime", timeMilliseconds);
- }
- if (ipsExitUtil)
- {
- setDbusProperty(asyncResp, "IdlePowerSaver/ExitUtilizationPercent",
- service, path,
- "xyz.openbmc_project.Control.Power.IdlePowerSaver",
- "ExitUtilizationPercent", *ipsExitUtil);
- }
- if (ipsExitTime)
- {
- // Convert from seconds into milliseconds for DBus
- const uint64_t timeMilliseconds = *ipsExitTime * 1000;
- setDbusProperty(asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds",
- service, path,
- "xyz.openbmc_project.Control.Power.IdlePowerSaver",
- "ExitDwellTime", timeMilliseconds);
- }
- });
+ if (ipsEnable)
+ {
+ setDbusProperty(
+ asyncResp, "IdlePowerSaver/Enabled", service, path,
+ "xyz.openbmc_project.Control.Power.IdlePowerSaver",
+ "Enabled", *ipsEnable);
+ }
+ if (ipsEnterUtil)
+ {
+ setDbusProperty(
+ asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
+ service, path,
+ "xyz.openbmc_project.Control.Power.IdlePowerSaver",
+ "EnterUtilizationPercent", *ipsEnterUtil);
+ }
+ if (ipsEnterTime)
+ {
+ // Convert from seconds into milliseconds for DBus
+ const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
+ setDbusProperty(
+ asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
+ path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
+ "EnterDwellTime", timeMilliseconds);
+ }
+ if (ipsExitUtil)
+ {
+ setDbusProperty(
+ asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
+ path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
+ "ExitUtilizationPercent", *ipsExitUtil);
+ }
+ if (ipsExitTime)
+ {
+ // Convert from seconds into milliseconds for DBus
+ const uint64_t timeMilliseconds = *ipsExitTime * 1000;
+ setDbusProperty(
+ asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
+ path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
+ "ExitDwellTime", timeMilliseconds);
+ }
+ });
BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
}
@@ -2801,35 +2827,16 @@ inline void handleComputerSystemCollectionGet(
system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
BMCWEB_REDFISH_SYSTEM_URI_NAME);
ifaceArray.emplace_back(std::move(system));
- sdbusplus::asio::getProperty<std::string>(
- *crow::connections::systemBus, "xyz.openbmc_project.Settings",
- "/xyz/openbmc_project/network/hypervisor",
- "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
- [asyncResp](const boost::system::error_code& ec2,
- const std::string& /*hostName*/) {
- if (ec2)
- {
- return;
- }
- auto val = asyncResp->res.jsonValue.find("Members@odata.count");
- if (val == asyncResp->res.jsonValue.end())
- {
- BMCWEB_LOG_CRITICAL("Count wasn't found??");
- return;
- }
- uint64_t* count = val->get_ptr<uint64_t*>();
- if (count == nullptr)
- {
- BMCWEB_LOG_CRITICAL("Count wasn't found??");
- return;
- }
- *count = *count + 1;
+
+ if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
+ {
BMCWEB_LOG_DEBUG("Hypervisor is available");
- nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
+ asyncResp->res.jsonValue["Members@odata.count"] = 2;
+
nlohmann::json::object_t hypervisor;
hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
- ifaceArray2.emplace_back(std::move(hypervisor));
- });
+ ifaceArray.emplace_back(std::move(hypervisor));
+ }
}
/**
@@ -2845,14 +2852,14 @@ inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- messages::success(asyncResp->res);
- },
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ messages::success(asyncResp->res);
+ },
serviceName, objectPath, interfaceName, method);
}
@@ -2865,6 +2872,16 @@ inline void handleComputerSystemResetActionPost(
{
return;
}
+
+ if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
+ {
+ if (systemName == "hypervisor")
+ {
+ handleHypervisorSystemResetPost(req, asyncResp);
+ return;
+ }
+ }
+
if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
{
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
@@ -3017,10 +3034,13 @@ inline void
return;
}
- if (systemName == "hypervisor")
+ if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
{
- handleHypervisorSystemGet(asyncResp);
- return;
+ if (systemName == "hypervisor")
+ {
+ handleHypervisorSystemGet(asyncResp);
+ return;
+ }
}
if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
@@ -3036,7 +3056,8 @@ inline void
"#ComputerSystem.v1_22_0.ComputerSystem";
asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
- asyncResp->res.jsonValue["SystemType"] = "Physical";
+ asyncResp->res.jsonValue["SystemType"] =
+ computer_system::SystemType::Physical;
asyncResp->res.jsonValue["Description"] = "Computer System";
asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
@@ -3073,8 +3094,8 @@ inline void
manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
BMCWEB_REDFISH_MANAGER_URI_NAME);
asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
// Fill in SerialConsole info
asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
@@ -3097,15 +3118,15 @@ inline void
nlohmann::json::array_t({"KVMIP"});
}
- getMainChassisId(asyncResp,
- [](const std::string& chassisId,
- const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
- nlohmann::json::array_t chassisArray;
- nlohmann::json& chassis = chassisArray.emplace_back();
- chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
- chassisId);
- aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
- });
+ getMainChassisId(
+ asyncResp, [](const std::string& chassisId,
+ const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
+ nlohmann::json::array_t chassisArray;
+ nlohmann::json& chassis = chassisArray.emplace_back();
+ chassis["@odata.id"] =
+ boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
+ aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
+ });
getSystemLocationIndicatorActive(asyncResp);
// TODO (Gunnar): Remove IndicatorLED after enough time has passed
@@ -3179,30 +3200,30 @@ inline void handleComputerSystemPatch(
std::optional<uint64_t> ipsExitTime;
// clang-format off
- if (!json_util::readJsonPatch(
- req, asyncResp->res,
- "IndicatorLED", indicatorLed,
- "LocationIndicatorActive", locationIndicatorActive,
- "AssetTag", assetTag,
- "PowerRestorePolicy", powerRestorePolicy,
- "PowerMode", powerMode,
- "HostWatchdogTimer/FunctionEnabled", wdtEnable,
- "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
- "Boot/BootSourceOverrideTarget", bootSource,
- "Boot/BootSourceOverrideMode", bootType,
- "Boot/BootSourceOverrideEnabled", bootEnable,
- "Boot/AutomaticRetryConfig", bootAutomaticRetry,
- "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
- "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
- "Boot/StopBootOnFault", stopBootOnFault,
- "IdlePowerSaver/Enabled", ipsEnable,
- "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
- "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
- "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
- "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
- {
- return;
- }
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res,
+ "IndicatorLED", indicatorLed,
+ "LocationIndicatorActive", locationIndicatorActive,
+ "AssetTag", assetTag,
+ "PowerRestorePolicy", powerRestorePolicy,
+ "PowerMode", powerMode,
+ "HostWatchdogTimer/FunctionEnabled", wdtEnable,
+ "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
+ "Boot/BootSourceOverrideTarget", bootSource,
+ "Boot/BootSourceOverrideMode", bootType,
+ "Boot/BootSourceOverrideEnabled", bootEnable,
+ "Boot/AutomaticRetryConfig", bootAutomaticRetry,
+ "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
+ "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
+ "Boot/StopBootOnFault", stopBootOnFault,
+ "IdlePowerSaver/Enabled", ipsEnable,
+ "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
+ "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
+ "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
+ "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
+ {
+ return;
+ }
// clang-format on
asyncResp->res.result(boost::beast::http::status::no_content);
@@ -3373,7 +3394,7 @@ inline void afterGetAllowedHostTransitions(
nlohmann::json::object_t parameter;
parameter["Name"] = "ResetType";
parameter["Required"] = true;
- parameter["DataType"] = "String";
+ parameter["DataType"] = action_info::ParameterTypes::String;
parameter["AllowableValues"] = std::move(allowableValues);
nlohmann::json::array_t parameters;
parameters.emplace_back(std::move(parameter));
@@ -3397,10 +3418,13 @@ inline void handleSystemCollectionResetActionGet(
return;
}
- if (systemName == "hypervisor")
+ if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
{
- handleHypervisorResetActionGet(asyncResp);
- return;
+ if (systemName == "hypervisor")
+ {
+ handleHypervisorResetActionGet(asyncResp);
+ return;
+ }
}
if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
@@ -3428,8 +3452,9 @@ inline void handleSystemCollectionResetActionGet(
"AllowedHostTransitions",
[asyncResp](const boost::system::error_code& ec,
const std::vector<std::string>& allowedHostTransitions) {
- afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
- });
+ afterGetAllowedHostTransitions(asyncResp, ec,
+ allowedHostTransitions);
+ });
}
/**
* SystemResetActionInfo derived class for delivering Computer Systems
diff --git a/redfish-core/lib/systems_logservices_hostlogger.hpp b/redfish-core/lib/systems_logservices_hostlogger.hpp
new file mode 100644
index 0000000000..98be6f3ac2
--- /dev/null
+++ b/redfish-core/lib/systems_logservices_hostlogger.hpp
@@ -0,0 +1,241 @@
+#pragma once
+
+#include "app.hpp"
+#include "generated/enums/log_entry.hpp"
+#include "query.hpp"
+#include "registries/openbmc_message_registry.hpp"
+#include "registries/privilege_registry.hpp"
+#include "utils/time_utils.hpp"
+
+#include <cstdint>
+#include <memory>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace redfish
+{
+
+inline void fillHostLoggerEntryJson(std::string_view logEntryID,
+ std::string_view msg,
+ nlohmann::json::object_t& logEntryJson)
+{
+ // Fill in the log entry with the gathered data.
+ logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+ logEntryJson["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, logEntryID);
+ logEntryJson["Name"] = "Host Logger Entry";
+ logEntryJson["Id"] = logEntryID;
+ logEntryJson["Message"] = msg;
+ logEntryJson["EntryType"] = log_entry::LogEntryType::Oem;
+ logEntryJson["Severity"] = log_entry::EventSeverity::OK;
+ logEntryJson["OemRecordFormat"] = "Host Logger Entry";
+}
+
+inline void handleSystemsLogServicesHostloggerGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
+ asyncResp->res.jsonValue["Name"] = "Host Logger Service";
+ asyncResp->res.jsonValue["Description"] = "Host Logger Service";
+ asyncResp->res.jsonValue["Id"] = "HostLogger";
+ asyncResp->res.jsonValue["Entries"]["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+}
+
+inline void handleSystemsLogServicesHostloggerEntriesGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName)
+{
+ query_param::QueryCapabilities capabilities = {
+ .canDelegateTop = true,
+ .canDelegateSkip = true,
+ };
+ query_param::Query delegatedQuery;
+ if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
+ delegatedQuery, capabilities))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["Name"] = "HostLogger Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of HostLogger Entries";
+ nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
+ logEntryArray = nlohmann::json::array();
+ asyncResp->res.jsonValue["Members@odata.count"] = 0;
+
+ std::vector<std::filesystem::path> hostLoggerFiles;
+ if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
+ {
+ BMCWEB_LOG_DEBUG("Failed to get host log file path");
+ return;
+ }
+ // If we weren't provided top and skip limits, use the defaults.
+ size_t skip = delegatedQuery.skip.value_or(0);
+ size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
+ size_t logCount = 0;
+ // This vector only store the entries we want to expose that
+ // control by skip and top.
+ std::vector<std::string> logEntries;
+ if (!getHostLoggerEntries(hostLoggerFiles, skip, top, logEntries, logCount))
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // If vector is empty, that means skip value larger than total
+ // log count
+ if (logEntries.empty())
+ {
+ asyncResp->res.jsonValue["Members@odata.count"] = logCount;
+ return;
+ }
+ if (!logEntries.empty())
+ {
+ for (size_t i = 0; i < logEntries.size(); i++)
+ {
+ nlohmann::json::object_t hostLogEntry;
+ fillHostLoggerEntryJson(std::to_string(skip + i), logEntries[i],
+ hostLogEntry);
+ logEntryArray.emplace_back(std::move(hostLogEntry));
+ }
+
+ asyncResp->res.jsonValue["Members@odata.count"] = logCount;
+ if (skip + top < logCount)
+ {
+ asyncResp->res.jsonValue["Members@odata.nextLink"] =
+ std::format(
+ "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries?$skip=",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME) +
+ std::to_string(skip + top);
+ }
+ }
+}
+
+inline void handleSystemsLogServicesHostloggerEntriesEntryGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& param)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ std::string_view targetID = param;
+
+ uint64_t idInt = 0;
+
+ auto [ptr, ec] = std::from_chars(targetID.begin(), targetID.end(), idInt);
+ if (ec != std::errc{} || ptr != targetID.end())
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", param);
+ return;
+ }
+
+ std::vector<std::filesystem::path> hostLoggerFiles;
+ if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
+ {
+ BMCWEB_LOG_DEBUG("Failed to get host log file path");
+ return;
+ }
+
+ size_t logCount = 0;
+ size_t top = 1;
+ std::vector<std::string> logEntries;
+ // We can get specific entry by skip and top. For example, if we
+ // want to get nth entry, we can set skip = n-1 and top = 1 to
+ // get that entry
+ if (!getHostLoggerEntries(hostLoggerFiles, idInt, top, logEntries,
+ logCount))
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (!logEntries.empty())
+ {
+ nlohmann::json::object_t hostLogEntry;
+ fillHostLoggerEntryJson(targetID, logEntries[0], hostLogEntry);
+ asyncResp->res.jsonValue.update(hostLogEntry);
+ return;
+ }
+
+ // Requested ID was not found
+ messages::resourceNotFound(asyncResp->res, "LogEntry", param);
+}
+
+inline void requestRoutesSystemsLogServiceHostlogger(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/")
+ .privileges(redfish::privileges::getLogService)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServicesHostloggerGet, std::ref(app)));
+ BMCWEB_ROUTE(app,
+ "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/")
+ .privileges(redfish::privileges::getLogEntryCollection)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServicesHostloggerEntriesGet, std::ref(app)));
+
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/<str>/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServicesHostloggerEntriesEntryGet, std::ref(app)));
+}
+
+} // namespace redfish
diff --git a/redfish-core/lib/systems_logservices_postcodes.hpp b/redfish-core/lib/systems_logservices_postcodes.hpp
new file mode 100644
index 0000000000..90782bde51
--- /dev/null
+++ b/redfish-core/lib/systems_logservices_postcodes.hpp
@@ -0,0 +1,615 @@
+#pragma once
+
+#include "app.hpp"
+#include "generated/enums/log_service.hpp"
+#include "query.hpp"
+#include "registries/openbmc_message_registry.hpp"
+#include "registries/privilege_registry.hpp"
+#include "utils/time_utils.hpp"
+
+#include <cstdint>
+#include <memory>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace redfish
+{
+
+inline void handleSystemsLogServicesPostCodesGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/PostCodes",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
+ asyncResp->res.jsonValue["Name"] = "POST Code Log Service";
+ asyncResp->res.jsonValue["Description"] = "POST Code Log Service";
+ asyncResp->res.jsonValue["Id"] = "PostCodes";
+ asyncResp->res.jsonValue["OverWritePolicy"] =
+ log_service::OverWritePolicy::WrapsWhenFull;
+ asyncResp->res.jsonValue["Entries"]["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/PostCodes/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+
+ std::pair<std::string, std::string> redfishDateTimeOffset =
+ redfish::time_utils::getDateTimeOffsetNow();
+ asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
+ asyncResp->res.jsonValue["DateTimeLocalOffset"] =
+ redfishDateTimeOffset.second;
+
+ asyncResp->res
+ .jsonValue["Actions"]["#LogService.ClearLog"]["target"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/PostCodes/Actions/LogService.ClearLog",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+}
+
+inline void handleSystemsLogServicesPostCodesPost(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ BMCWEB_LOG_DEBUG("Do delete all postcodes entries.");
+
+ // Make call to post-code service to request clear all
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ // TODO Handle for specific error code
+ BMCWEB_LOG_ERROR("doClearPostCodes resp_handler got error {}",
+ ec);
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ messages::success(asyncResp->res);
+ },
+ "xyz.openbmc_project.State.Boot.PostCode0",
+ "/xyz/openbmc_project/State/Boot/PostCode0",
+ "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
+}
+
+/**
+ * @brief Parse post code ID and get the current value and index value
+ * eg: postCodeID=B1-2, currentValue=1, index=2
+ *
+ * @param[in] postCodeID Post Code ID
+ * @param[out] currentValue Current value
+ * @param[out] index Index value
+ *
+ * @return bool true if the parsing is successful, false the parsing fails
+ */
+inline bool parsePostCode(std::string_view postCodeID, uint64_t& currentValue,
+ uint16_t& index)
+{
+ std::vector<std::string> split;
+ bmcweb::split(split, postCodeID, '-');
+ if (split.size() != 2)
+ {
+ return false;
+ }
+ std::string_view postCodeNumber = split[0];
+ if (postCodeNumber.size() < 2)
+ {
+ return false;
+ }
+ if (postCodeNumber[0] != 'B')
+ {
+ return false;
+ }
+ postCodeNumber.remove_prefix(1);
+ auto [ptrIndex, ecIndex] =
+ std::from_chars(postCodeNumber.begin(), postCodeNumber.end(), index);
+ if (ptrIndex != postCodeNumber.end() || ecIndex != std::errc())
+ {
+ return false;
+ }
+
+ std::string_view postCodeIndex = split[1];
+
+ auto [ptrValue, ecValue] = std::from_chars(
+ postCodeIndex.begin(), postCodeIndex.end(), currentValue);
+
+ return ptrValue == postCodeIndex.end() && ecValue == std::errc();
+}
+
+static bool fillPostCodeEntry(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::container::flat_map<
+ uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& postcode,
+ const uint16_t bootIndex, const uint64_t codeIndex = 0,
+ const uint64_t skip = 0, const uint64_t top = 0)
+{
+ // Get the Message from the MessageRegistry
+ const registries::Message* message =
+ registries::getMessage("OpenBMC.0.2.BIOSPOSTCode");
+ if (message == nullptr)
+ {
+ BMCWEB_LOG_ERROR("Couldn't find known message?");
+ return false;
+ }
+ uint64_t currentCodeIndex = 0;
+ uint64_t firstCodeTimeUs = 0;
+ for (const std::pair<uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>&
+ code : postcode)
+ {
+ currentCodeIndex++;
+ std::string postcodeEntryID =
+ "B" + std::to_string(bootIndex) + "-" +
+ std::to_string(currentCodeIndex); // 1 based index in EntryID string
+
+ uint64_t usecSinceEpoch = code.first;
+ uint64_t usTimeOffset = 0;
+
+ if (1 == currentCodeIndex)
+ { // already incremented
+ firstCodeTimeUs = code.first;
+ }
+ else
+ {
+ usTimeOffset = code.first - firstCodeTimeUs;
+ }
+
+ // skip if no specific codeIndex is specified and currentCodeIndex does
+ // not fall between top and skip
+ if ((codeIndex == 0) &&
+ (currentCodeIndex <= skip || currentCodeIndex > top))
+ {
+ continue;
+ }
+
+ // skip if a specific codeIndex is specified and does not match the
+ // currentIndex
+ if ((codeIndex > 0) && (currentCodeIndex != codeIndex))
+ {
+ // This is done for simplicity. 1st entry is needed to calculate
+ // time offset. To improve efficiency, one can get to the entry
+ // directly (possibly with flatmap's nth method)
+ continue;
+ }
+
+ // currentCodeIndex is within top and skip or equal to specified code
+ // index
+
+ // Get the Created time from the timestamp
+ std::string entryTimeStr;
+ entryTimeStr = redfish::time_utils::getDateTimeUintUs(usecSinceEpoch);
+
+ // assemble messageArgs: BootIndex, TimeOffset(100us), PostCode(hex)
+ std::ostringstream hexCode;
+ hexCode << "0x" << std::setfill('0') << std::setw(2) << std::hex
+ << std::get<0>(code.second);
+ std::ostringstream timeOffsetStr;
+ // Set Fixed -Point Notation
+ timeOffsetStr << std::fixed;
+ // Set precision to 4 digits
+ timeOffsetStr << std::setprecision(4);
+ // Add double to stream
+ timeOffsetStr << static_cast<double>(usTimeOffset) / 1000 / 1000;
+
+ std::string bootIndexStr = std::to_string(bootIndex);
+ std::string timeOffsetString = timeOffsetStr.str();
+ std::string hexCodeStr = hexCode.str();
+
+ std::array<std::string_view, 3> messageArgs = {
+ bootIndexStr, timeOffsetString, hexCodeStr};
+
+ std::string msg =
+ redfish::registries::fillMessageArgs(messageArgs, message->message);
+ if (msg.empty())
+ {
+ messages::internalError(asyncResp->res);
+ return false;
+ }
+
+ // Get Severity template from message registry
+ std::string severity;
+ if (message != nullptr)
+ {
+ severity = message->messageSeverity;
+ }
+
+ // Format entry
+ nlohmann::json::object_t bmcLogEntry;
+ bmcLogEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+ bmcLogEntry["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/LogServices/PostCodes/Entries/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, postcodeEntryID);
+ bmcLogEntry["Name"] = "POST Code Log Entry";
+ bmcLogEntry["Id"] = postcodeEntryID;
+ bmcLogEntry["Message"] = std::move(msg);
+ bmcLogEntry["MessageId"] = "OpenBMC.0.2.BIOSPOSTCode";
+ bmcLogEntry["MessageArgs"] = messageArgs;
+ bmcLogEntry["EntryType"] = "Event";
+ bmcLogEntry["Severity"] = std::move(severity);
+ bmcLogEntry["Created"] = entryTimeStr;
+ if (!std::get<std::vector<uint8_t>>(code.second).empty())
+ {
+ bmcLogEntry["AdditionalDataURI"] =
+ std::format(
+ "/redfish/v1/Systems/{}/LogServices/PostCodes/Entries/",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME) +
+ postcodeEntryID + "/attachment";
+ }
+
+ // codeIndex is only specified when querying single entry, return only
+ // that entry in this case
+ if (codeIndex != 0)
+ {
+ asyncResp->res.jsonValue.update(bmcLogEntry);
+ return true;
+ }
+
+ nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
+ logEntryArray.emplace_back(std::move(bmcLogEntry));
+ }
+
+ // Return value is always false when querying multiple entries
+ return false;
+}
+
+inline void
+ getPostCodeForEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& entryId)
+{
+ uint16_t bootIndex = 0;
+ uint64_t codeIndex = 0;
+ if (!parsePostCode(entryId, codeIndex, bootIndex))
+ {
+ // Requested ID was not found
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
+ return;
+ }
+
+ if (bootIndex == 0 || codeIndex == 0)
+ {
+ // 0 is an invalid index
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
+ return;
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, entryId, bootIndex,
+ codeIndex](const boost::system::error_code& ec,
+ const boost::container::flat_map<
+ uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>&
+ postcode) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS POST CODE PostCode response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (postcode.empty())
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
+ return;
+ }
+
+ if (!fillPostCodeEntry(asyncResp, postcode, bootIndex, codeIndex))
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
+ return;
+ }
+ },
+ "xyz.openbmc_project.State.Boot.PostCode0",
+ "/xyz/openbmc_project/State/Boot/PostCode0",
+ "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp",
+ bootIndex);
+}
+
+inline void
+ getPostCodeForBoot(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const uint16_t bootIndex, const uint16_t bootCount,
+ const uint64_t entryCount, size_t skip, size_t top)
+{
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, bootIndex, bootCount, entryCount, skip,
+ top](const boost::system::error_code& ec,
+ const boost::container::flat_map<
+ uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>&
+ postcode) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS POST CODE PostCode response error");
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ uint64_t endCount = entryCount;
+ if (!postcode.empty())
+ {
+ endCount = entryCount + postcode.size();
+ if (skip < endCount && (top + skip) > entryCount)
+ {
+ uint64_t thisBootSkip =
+ std::max(static_cast<uint64_t>(skip), entryCount) -
+ entryCount;
+ uint64_t thisBootTop =
+ std::min(static_cast<uint64_t>(top + skip), endCount) -
+ entryCount;
+
+ fillPostCodeEntry(asyncResp, postcode, bootIndex, 0,
+ thisBootSkip, thisBootTop);
+ }
+ asyncResp->res.jsonValue["Members@odata.count"] = endCount;
+ }
+
+ // continue to previous bootIndex
+ if (bootIndex < bootCount)
+ {
+ getPostCodeForBoot(asyncResp,
+ static_cast<uint16_t>(bootIndex + 1),
+ bootCount, endCount, skip, top);
+ }
+ else if (skip + top < endCount)
+ {
+ asyncResp->res.jsonValue["Members@odata.nextLink"] =
+ std::format(
+ "/redfish/v1/Systems/{}/LogServices/PostCodes/Entries?$skip=",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME) +
+ std::to_string(skip + top);
+ }
+ },
+ "xyz.openbmc_project.State.Boot.PostCode0",
+ "/xyz/openbmc_project/State/Boot/PostCode0",
+ "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp",
+ bootIndex);
+}
+
+inline void
+ getCurrentBootNumber(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ size_t skip, size_t top)
+{
+ uint64_t entryCount = 0;
+ sdbusplus::asio::getProperty<uint16_t>(
+ *crow::connections::systemBus,
+ "xyz.openbmc_project.State.Boot.PostCode0",
+ "/xyz/openbmc_project/State/Boot/PostCode0",
+ "xyz.openbmc_project.State.Boot.PostCode", "CurrentBootCycleCount",
+ [asyncResp, entryCount, skip,
+ top](const boost::system::error_code& ec, const uint16_t bootCount) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ getPostCodeForBoot(asyncResp, 1, bootCount, entryCount, skip, top);
+ });
+}
+
+inline void handleSystemsLogServicesPostCodesEntriesGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName)
+{
+ query_param::QueryCapabilities capabilities = {
+ .canDelegateTop = true,
+ .canDelegateSkip = true,
+ };
+ query_param::Query delegatedQuery;
+ if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
+ delegatedQuery, capabilities))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/PostCodes/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of POST Code Log Entries";
+ asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
+ asyncResp->res.jsonValue["Members@odata.count"] = 0;
+ size_t skip = delegatedQuery.skip.value_or(0);
+ size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
+ getCurrentBootNumber(asyncResp, skip, top);
+}
+
+inline void handleSystemsLogServicesPostCodesEntriesEntryAdditionalDataGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& postCodeID)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if (!http_helpers::isContentTypeAllowed(
+ req.getHeaderValue("Accept"),
+ http_helpers::ContentType::OctetStream, true))
+ {
+ asyncResp->res.result(boost::beast::http::status::bad_request);
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ uint64_t currentValue = 0;
+ uint16_t index = 0;
+ if (!parsePostCode(postCodeID, currentValue, index))
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", postCodeID);
+ return;
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, postCodeID, currentValue](
+ const boost::system::error_code& ec,
+ const std::vector<std::tuple<uint64_t, std::vector<uint8_t>>>&
+ postcodes) {
+ if (ec.value() == EBADR)
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry",
+ postCodeID);
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ size_t value = static_cast<size_t>(currentValue) - 1;
+ if (value == std::string::npos || postcodes.size() < currentValue)
+ {
+ BMCWEB_LOG_WARNING("Wrong currentValue value");
+ messages::resourceNotFound(asyncResp->res, "LogEntry",
+ postCodeID);
+ return;
+ }
+
+ const auto& [tID, c] = postcodes[value];
+ if (c.empty())
+ {
+ BMCWEB_LOG_WARNING("No found post code data");
+ messages::resourceNotFound(asyncResp->res, "LogEntry",
+ postCodeID);
+ return;
+ }
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ const char* d = reinterpret_cast<const char*>(c.data());
+ std::string_view strData(d, c.size());
+
+ asyncResp->res.addHeader(boost::beast::http::field::content_type,
+ "application/octet-stream");
+ asyncResp->res.addHeader(
+ boost::beast::http::field::content_transfer_encoding, "Base64");
+ asyncResp->res.write(crow::utility::base64encode(strData));
+ },
+ "xyz.openbmc_project.State.Boot.PostCode0",
+ "/xyz/openbmc_project/State/Boot/PostCode0",
+ "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodes", index);
+}
+
+inline void handleSystemsLogServicesPostCodesEntriesEntryGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& targetID)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+
+ getPostCodeForEntry(asyncResp, targetID);
+}
+
+inline void requestRoutesSystemsLogServicesPostCode(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/")
+ .privileges(redfish::privileges::getLogService)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServicesPostCodesGet, std::ref(app)));
+
+ BMCWEB_ROUTE(
+ app,
+ "/redfish/v1/Systems/<str>/LogServices/PostCodes/Actions/LogService.ClearLog/")
+ // The following privilege is correct; we need "SubordinateOverrides"
+ // before we can automate it.
+ .privileges({{"ConfigureComponents"}})
+ .methods(boost::beast::http::verb::post)(std::bind_front(
+ handleSystemsLogServicesPostCodesPost, std::ref(app)));
+
+ BMCWEB_ROUTE(app,
+ "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/")
+ .privileges(redfish::privileges::getLogEntryCollection)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServicesPostCodesEntriesGet, std::ref(app)));
+
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServicesPostCodesEntriesEntryGet, std::ref(app)));
+
+ BMCWEB_ROUTE(
+ app,
+ "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/attachment/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(boost::beast::http::verb::get)(std::bind_front(
+ handleSystemsLogServicesPostCodesEntriesEntryAdditionalDataGet,
+ std::ref(app)));
+}
+} // namespace redfish
diff --git a/redfish-core/lib/task.hpp b/redfish-core/lib/task.hpp
index a2959b8455..5f67cf0448 100644
--- a/redfish-core/lib/task.hpp
+++ b/redfish-core/lib/task.hpp
@@ -1,23 +1,25 @@
/*
-// Copyright (c) 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "app.hpp"
#include "dbus_utility.hpp"
#include "event_service_manager.hpp"
+#include "generated/enums/resource.hpp"
+#include "generated/enums/task_service.hpp"
#include "http/parsing.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
@@ -72,8 +74,8 @@ struct Payload
continue;
}
std::string header;
- header.reserve(field.name_string().size() + 2 +
- field.value().size());
+ header.reserve(
+ field.name_string().size() + 2 + field.value().size());
header += field.name_string();
header += ": ";
header += field.value();
@@ -95,8 +97,7 @@ struct TaskData : std::enable_shared_from_this<TaskData>
std::function<bool(boost::system::error_code, sdbusplus::message_t&,
const std::shared_ptr<TaskData>&)>&& handler,
const std::string& matchIn, size_t idx) :
- callback(std::move(handler)),
- matchStr(matchIn), index(idx),
+ callback(std::move(handler)), matchStr(matchIn), index(idx),
startTime(std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now())),
status("OK"), state("Running"), messages(nlohmann::json::array()),
@@ -144,7 +145,8 @@ struct TaskData : std::enable_shared_from_this<TaskData>
{
res.result(boost::beast::http::status::accepted);
std::string strIdx = std::to_string(index);
- std::string uri = "/redfish/v1/TaskService/Tasks/" + strIdx;
+ boost::urls::url uri =
+ boost::urls::format("/redfish/v1/TaskService/Tasks/{}", strIdx);
res.jsonValue["@odata.id"] = uri;
res.jsonValue["@odata.type"] = "#Task.v1_4_3.Task";
@@ -152,8 +154,11 @@ struct TaskData : std::enable_shared_from_this<TaskData>
res.jsonValue["TaskState"] = state;
res.jsonValue["TaskStatus"] = status;
+ boost::urls::url taskMonitor = boost::urls::format(
+ "/redfish/v1/TaskService/TaskMonitors/{}", strIdx);
+
res.addHeader(boost::beast::http::field::location,
- uri + "/Monitor");
+ taskMonitor.buffer());
res.addHeader(boost::beast::http::field::retry_after,
std::to_string(retryAfterSeconds));
}
@@ -175,33 +180,30 @@ struct TaskData : std::enable_shared_from_this<TaskData>
timer.expires_after(timeout);
timer.async_wait(
[self = shared_from_this()](boost::system::error_code ec) {
- if (ec == boost::asio::error::operation_aborted)
- {
- return; // completed successfully
- }
- if (!ec)
- {
- // change ec to error as timer expired
- ec = boost::asio::error::operation_aborted;
- }
- self->match.reset();
- sdbusplus::message_t msg;
- self->finishTask();
- self->state = "Cancelled";
- self->status = "Warning";
- self->messages.emplace_back(
- messages::taskAborted(std::to_string(self->index)));
- // Send event :TaskAborted
- self->sendTaskEvent(self->state, self->index);
- self->callback(ec, msg, self);
- });
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ return; // completed successfully
+ }
+ if (!ec)
+ {
+ // change ec to error as timer expired
+ ec = boost::asio::error::operation_aborted;
+ }
+ self->match.reset();
+ sdbusplus::message_t msg;
+ self->finishTask();
+ self->state = "Cancelled";
+ self->status = "Warning";
+ self->messages.emplace_back(
+ messages::taskAborted(std::to_string(self->index)));
+ // Send event :TaskAborted
+ self->sendTaskEvent(self->state, self->index);
+ self->callback(ec, msg, self);
+ });
}
static void sendTaskEvent(std::string_view state, size_t index)
{
- std::string origin = "/redfish/v1/TaskService/Tasks/" +
- std::to_string(index);
- std::string resType = "Task";
// TaskState enums which should send out an event are:
// "Starting" = taskResumed
// "Running" = taskStarted
@@ -213,59 +215,50 @@ struct TaskData : std::enable_shared_from_this<TaskData>
// "Killed" = taskRemoved
// "Exception" = taskCompletedWarning
// "Cancelled" = taskCancelled
+ nlohmann::json event;
+ std::string indexStr = std::to_string(index);
if (state == "Starting")
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskResumed(std::to_string(index)), origin,
- resType);
+ event = redfish::messages::taskResumed(indexStr);
}
else if (state == "Running")
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskStarted(std::to_string(index)), origin,
- resType);
+ event = redfish::messages::taskStarted(indexStr);
}
else if ((state == "Suspended") || (state == "Interrupted") ||
(state == "Pending"))
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskPaused(std::to_string(index)), origin,
- resType);
+ event = redfish::messages::taskPaused(indexStr);
}
else if (state == "Stopping")
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskAborted(std::to_string(index)), origin,
- resType);
+ event = redfish::messages::taskAborted(indexStr);
}
else if (state == "Completed")
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskCompletedOK(std::to_string(index)),
- origin, resType);
+ event = redfish::messages::taskCompletedOK(indexStr);
}
else if (state == "Killed")
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskRemoved(std::to_string(index)), origin,
- resType);
+ event = redfish::messages::taskRemoved(indexStr);
}
else if (state == "Exception")
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskCompletedWarning(std::to_string(index)),
- origin, resType);
+ event = redfish::messages::taskCompletedWarning(indexStr);
}
else if (state == "Cancelled")
{
- redfish::EventServiceManager::getInstance().sendEvent(
- redfish::messages::taskCancelled(std::to_string(index)), origin,
- resType);
+ event = redfish::messages::taskCancelled(indexStr);
}
else
{
BMCWEB_LOG_INFO("sendTaskEvent: No events to send");
+ return;
}
+ boost::urls::url origin =
+ boost::urls::format("/redfish/v1/TaskService/Tasks/{}", index);
+ EventServiceManager::getInstance().sendEvent(event, origin.buffer(),
+ "Task");
}
void startTimer(const std::chrono::seconds& timeout)
@@ -278,25 +271,25 @@ struct TaskData : std::enable_shared_from_this<TaskData>
static_cast<sdbusplus::bus_t&>(*crow::connections::systemBus),
matchStr,
[self = shared_from_this()](sdbusplus::message_t& message) {
- boost::system::error_code ec;
-
- // callback to return True if callback is done, callback needs
- // to update status itself if needed
- if (self->callback(ec, message, self) == task::completed)
- {
- self->timer.cancel();
- self->finishTask();
-
- // Send event
- self->sendTaskEvent(self->state, self->index);
-
- // reset the match after the callback was successful
- boost::asio::post(
- crow::connections::systemBus->get_io_context(),
- [self] { self->match.reset(); });
- return;
- }
- });
+ boost::system::error_code ec;
+
+ // callback to return True if callback is done, callback needs
+ // to update status itself if needed
+ if (self->callback(ec, message, self) == task::completed)
+ {
+ self->timer.cancel();
+ self->finishTask();
+
+ // Send event
+ self->sendTaskEvent(self->state, self->index);
+
+ // reset the match after the callback was successful
+ boost::asio::post(
+ crow::connections::systemBus->get_io_context(),
+ [self] { self->match.reset(); });
+ return;
+ }
+ });
extendTimer(timeout);
messages.emplace_back(messages::taskStarted(std::to_string(index)));
@@ -325,43 +318,45 @@ struct TaskData : std::enable_shared_from_this<TaskData>
inline void requestRoutesTaskMonitor(App& app)
{
- BMCWEB_ROUTE(app, "/redfish/v1/TaskService/Tasks/<str>/Monitor/")
+ BMCWEB_ROUTE(app, "/redfish/v1/TaskService/TaskMonitors/<str>/")
.privileges(redfish::privileges::getTask)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& strParam) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- auto find = std::ranges::find_if(
- task::tasks,
- [&strParam](const std::shared_ptr<task::TaskData>& task) {
- if (!task)
- {
- return false;
- }
-
- // we compare against the string version as on failure
- // strtoul returns 0
- return std::to_string(task->index) == strParam;
- });
-
- if (find == task::tasks.end())
- {
- messages::resourceNotFound(asyncResp->res, "Task", strParam);
- return;
- }
- std::shared_ptr<task::TaskData>& ptr = *find;
- // monitor expires after 204
- if (ptr->gave204)
- {
- messages::resourceNotFound(asyncResp->res, "Task", strParam);
- return;
- }
- ptr->populateResp(asyncResp->res);
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ auto find = std::ranges::find_if(
+ task::tasks,
+ [&strParam](const std::shared_ptr<task::TaskData>& task) {
+ if (!task)
+ {
+ return false;
+ }
+
+ // we compare against the string version as on failure
+ // strtoul returns 0
+ return std::to_string(task->index) == strParam;
+ });
+
+ if (find == task::tasks.end())
+ {
+ messages::resourceNotFound(asyncResp->res, "Task",
+ strParam);
+ return;
+ }
+ std::shared_ptr<task::TaskData>& ptr = *find;
+ // monitor expires after 204
+ if (ptr->gave204)
+ {
+ messages::resourceNotFound(asyncResp->res, "Task",
+ strParam);
+ return;
+ }
+ ptr->populateResp(asyncResp->res);
+ });
}
inline void requestRoutesTask(App& app)
@@ -372,66 +367,75 @@ inline void requestRoutesTask(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& strParam) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- auto find = std::ranges::find_if(
- task::tasks,
- [&strParam](const std::shared_ptr<task::TaskData>& task) {
- if (!task)
- {
- return false;
- }
-
- // we compare against the string version as on failure
- // strtoul returns 0
- return std::to_string(task->index) == strParam;
- });
-
- if (find == task::tasks.end())
- {
- messages::resourceNotFound(asyncResp->res, "Task", strParam);
- return;
- }
-
- const std::shared_ptr<task::TaskData>& ptr = *find;
-
- asyncResp->res.jsonValue["@odata.type"] = "#Task.v1_4_3.Task";
- asyncResp->res.jsonValue["Id"] = strParam;
- asyncResp->res.jsonValue["Name"] = "Task " + strParam;
- asyncResp->res.jsonValue["TaskState"] = ptr->state;
- asyncResp->res.jsonValue["StartTime"] =
- redfish::time_utils::getDateTimeStdtime(ptr->startTime);
- if (ptr->endTime)
- {
- asyncResp->res.jsonValue["EndTime"] =
- redfish::time_utils::getDateTimeStdtime(*(ptr->endTime));
- }
- asyncResp->res.jsonValue["TaskStatus"] = ptr->status;
- asyncResp->res.jsonValue["Messages"] = ptr->messages;
- asyncResp->res.jsonValue["@odata.id"] =
- boost::urls::format("/redfish/v1/TaskService/Tasks/{}", strParam);
- if (!ptr->gave204)
- {
- asyncResp->res.jsonValue["TaskMonitor"] =
- "/redfish/v1/TaskService/Tasks/" + strParam + "/Monitor";
- }
-
- asyncResp->res.jsonValue["HidePayload"] = !ptr->payload;
-
- if (ptr->payload)
- {
- const task::Payload& p = *(ptr->payload);
- asyncResp->res.jsonValue["Payload"]["TargetUri"] = p.targetUri;
- asyncResp->res.jsonValue["Payload"]["HttpOperation"] =
- p.httpOperation;
- asyncResp->res.jsonValue["Payload"]["HttpHeaders"] = p.httpHeaders;
- asyncResp->res.jsonValue["Payload"]["JsonBody"] = p.jsonBody.dump(
- 2, ' ', true, nlohmann::json::error_handler_t::replace);
- }
- asyncResp->res.jsonValue["PercentComplete"] = ptr->percentComplete;
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ auto find = std::ranges::find_if(
+ task::tasks,
+ [&strParam](const std::shared_ptr<task::TaskData>& task) {
+ if (!task)
+ {
+ return false;
+ }
+
+ // we compare against the string version as on failure
+ // strtoul returns 0
+ return std::to_string(task->index) == strParam;
+ });
+
+ if (find == task::tasks.end())
+ {
+ messages::resourceNotFound(asyncResp->res, "Task",
+ strParam);
+ return;
+ }
+
+ const std::shared_ptr<task::TaskData>& ptr = *find;
+
+ asyncResp->res.jsonValue["@odata.type"] = "#Task.v1_4_3.Task";
+ asyncResp->res.jsonValue["Id"] = strParam;
+ asyncResp->res.jsonValue["Name"] = "Task " + strParam;
+ asyncResp->res.jsonValue["TaskState"] = ptr->state;
+ asyncResp->res.jsonValue["StartTime"] =
+ redfish::time_utils::getDateTimeStdtime(ptr->startTime);
+ if (ptr->endTime)
+ {
+ asyncResp->res.jsonValue["EndTime"] =
+ redfish::time_utils::getDateTimeStdtime(
+ *(ptr->endTime));
+ }
+ asyncResp->res.jsonValue["TaskStatus"] = ptr->status;
+ asyncResp->res.jsonValue["Messages"] = ptr->messages;
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/TaskService/Tasks/{}", strParam);
+ if (!ptr->gave204)
+ {
+ asyncResp->res.jsonValue["TaskMonitor"] =
+ boost::urls::format(
+ "/redfish/v1/TaskService/TaskMonitors/{}",
+ strParam);
+ }
+
+ asyncResp->res.jsonValue["HidePayload"] = !ptr->payload;
+
+ if (ptr->payload)
+ {
+ const task::Payload& p = *(ptr->payload);
+ asyncResp->res.jsonValue["Payload"]["TargetUri"] =
+ p.targetUri;
+ asyncResp->res.jsonValue["Payload"]["HttpOperation"] =
+ p.httpOperation;
+ asyncResp->res.jsonValue["Payload"]["HttpHeaders"] =
+ p.httpHeaders;
+ asyncResp->res.jsonValue["Payload"]["JsonBody"] =
+ p.jsonBody.dump(
+ -1, ' ', true,
+ nlohmann::json::error_handler_t::replace);
+ }
+ asyncResp->res.jsonValue["PercentComplete"] =
+ ptr->percentComplete;
+ });
}
inline void requestRoutesTaskCollection(App& app)
@@ -441,31 +445,33 @@ inline void requestRoutesTaskCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#TaskCollection.TaskCollection";
- asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/TaskService/Tasks";
- asyncResp->res.jsonValue["Name"] = "Task Collection";
- asyncResp->res.jsonValue["Members@odata.count"] = task::tasks.size();
- nlohmann::json& members = asyncResp->res.jsonValue["Members"];
- members = nlohmann::json::array();
-
- for (const std::shared_ptr<task::TaskData>& task : task::tasks)
- {
- if (task == nullptr)
- {
- continue; // shouldn't be possible
- }
- nlohmann::json::object_t member;
- member["@odata.id"] =
- boost::urls::format("/redfish/v1/TaskService/Tasks/{}",
- std::to_string(task->index));
- members.emplace_back(std::move(member));
- }
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#TaskCollection.TaskCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/TaskService/Tasks";
+ asyncResp->res.jsonValue["Name"] = "Task Collection";
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ task::tasks.size();
+ nlohmann::json& members = asyncResp->res.jsonValue["Members"];
+ members = nlohmann::json::array();
+
+ for (const std::shared_ptr<task::TaskData>& task : task::tasks)
+ {
+ if (task == nullptr)
+ {
+ continue; // shouldn't be possible
+ }
+ nlohmann::json::object_t member;
+ member["@odata.id"] =
+ boost::urls::format("/redfish/v1/TaskService/Tasks/{}",
+ std::to_string(task->index));
+ members.emplace_back(std::move(member));
+ }
+ });
}
inline void requestRoutesTaskService(App& app)
@@ -475,26 +481,30 @@ inline void requestRoutesTaskService(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#TaskService.v1_1_4.TaskService";
- asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/TaskService";
- asyncResp->res.jsonValue["Name"] = "Task Service";
- asyncResp->res.jsonValue["Id"] = "TaskService";
- asyncResp->res.jsonValue["DateTime"] =
- redfish::time_utils::getDateTimeOffsetNow().first;
- asyncResp->res.jsonValue["CompletedTaskOverWritePolicy"] = "Oldest";
-
- asyncResp->res.jsonValue["LifeCycleEventOnTaskStateChange"] = true;
-
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue["ServiceEnabled"] = true;
- asyncResp->res.jsonValue["Tasks"]["@odata.id"] =
- "/redfish/v1/TaskService/Tasks";
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#TaskService.v1_1_4.TaskService";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/TaskService";
+ asyncResp->res.jsonValue["Name"] = "Task Service";
+ asyncResp->res.jsonValue["Id"] = "TaskService";
+ asyncResp->res.jsonValue["DateTime"] =
+ redfish::time_utils::getDateTimeOffsetNow().first;
+ asyncResp->res.jsonValue["CompletedTaskOverWritePolicy"] =
+ task_service::OverWritePolicy::Oldest;
+
+ asyncResp->res.jsonValue["LifeCycleEventOnTaskStateChange"] =
+ true;
+
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
+ asyncResp->res.jsonValue["ServiceEnabled"] = true;
+ asyncResp->res.jsonValue["Tasks"]["@odata.id"] =
+ "/redfish/v1/TaskService/Tasks";
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp
index 724e8aad27..cd051dcc0c 100644
--- a/redfish-core/lib/telemetry_service.hpp
+++ b/redfish-core/lib/telemetry_service.hpp
@@ -2,6 +2,7 @@
#include "app.hpp"
#include "dbus_utility.hpp"
+#include "generated/enums/resource.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/dbus_utils.hpp"
@@ -41,53 +42,55 @@ inline void handleTelemetryServiceGet(
"xyz.openbmc_project.Telemetry.ReportManager",
[asyncResp](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& ret) {
- if (ec == boost::system::errc::host_unreachable)
- {
- asyncResp->res.jsonValue["Status"]["State"] = "Absent";
- return;
- }
- if (ec)
- {
- BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec == boost::system::errc::host_unreachable)
+ {
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Absent;
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+ asyncResp->res.jsonValue["Status"]["State"] =
+ resource::State::Enabled;
- const size_t* maxReports = nullptr;
- const uint64_t* minInterval = nullptr;
+ const size_t* maxReports = nullptr;
+ const uint64_t* minInterval = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), ret, "MaxReports", maxReports,
- "MinInterval", minInterval);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), ret, "MaxReports", maxReports,
+ "MinInterval", minInterval);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (maxReports != nullptr)
- {
- asyncResp->res.jsonValue["MaxReports"] = *maxReports;
- }
+ if (maxReports != nullptr)
+ {
+ asyncResp->res.jsonValue["MaxReports"] = *maxReports;
+ }
- if (minInterval != nullptr)
- {
- asyncResp->res.jsonValue["MinCollectionInterval"] =
- time_utils::toDurationString(std::chrono::milliseconds(
- static_cast<time_t>(*minInterval)));
- }
- nlohmann::json::array_t supportedCollectionFunctions;
- supportedCollectionFunctions.emplace_back("Maximum");
- supportedCollectionFunctions.emplace_back("Minimum");
- supportedCollectionFunctions.emplace_back("Average");
- supportedCollectionFunctions.emplace_back("Summation");
+ if (minInterval != nullptr)
+ {
+ asyncResp->res.jsonValue["MinCollectionInterval"] =
+ time_utils::toDurationString(std::chrono::milliseconds(
+ static_cast<time_t>(*minInterval)));
+ }
+ nlohmann::json::array_t supportedCollectionFunctions;
+ supportedCollectionFunctions.emplace_back("Maximum");
+ supportedCollectionFunctions.emplace_back("Minimum");
+ supportedCollectionFunctions.emplace_back("Average");
+ supportedCollectionFunctions.emplace_back("Summation");
- asyncResp->res.jsonValue["SupportedCollectionFunctions"] =
- std::move(supportedCollectionFunctions);
- });
+ asyncResp->res.jsonValue["SupportedCollectionFunctions"] =
+ std::move(supportedCollectionFunctions);
+ });
}
inline void requestRoutesTelemetryService(App& app)
diff --git a/redfish-core/lib/thermal.hpp b/redfish-core/lib/thermal.hpp
index 84bf37a04e..adcd4b995d 100644
--- a/redfish-core/lib/thermal.hpp
+++ b/redfish-core/lib/thermal.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -20,6 +20,7 @@
#include "registries/privilege_registry.hpp"
#include "sensors.hpp"
#include "utils/json_utils.hpp"
+#include "utils/sensor_utils.hpp"
namespace redfish
{
@@ -32,18 +33,19 @@ inline void requestRoutesThermal(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& chassisName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
- asyncResp, chassisName, sensors::dbus::thermalPaths,
- sensors::node::thermal);
+ auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
+ asyncResp, chassisName, sensors::dbus::thermalPaths,
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::thermalNode));
- // TODO Need to get Chassis Redundancy information.
- getChassisData(sensorAsyncResp);
- });
+ // TODO Need to get Chassis Redundancy information.
+ getChassisData(sensorAsyncResp);
+ });
BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Thermal/")
.privileges(redfish::privileges::patchThermal)
@@ -51,44 +53,48 @@ inline void requestRoutesThermal(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& chassisName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- std::optional<std::vector<nlohmann::json::object_t>>
- temperatureCollections;
- std::optional<std::vector<nlohmann::json::object_t>> fanCollections;
- std::unordered_map<std::string, std::vector<nlohmann::json::object_t>>
- allCollections;
+ std::optional<std::vector<nlohmann::json::object_t>>
+ temperatureCollections;
+ std::optional<std::vector<nlohmann::json::object_t>>
+ fanCollections;
+ std::unordered_map<std::string,
+ std::vector<nlohmann::json::object_t>>
+ allCollections;
- auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>(
- asyncResp, chassisName, sensors::dbus::thermalPaths,
- sensors::node::thermal);
+ auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>(
+ asyncResp, chassisName, sensors::dbus::thermalPaths,
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::thermalNode));
- if (!json_util::readJsonPatch(req, sensorsAsyncResp->asyncResp->res,
- "Temperatures", temperatureCollections,
- "Fans", fanCollections))
- {
- return;
- }
- if (!temperatureCollections && !fanCollections)
- {
- messages::resourceNotFound(sensorsAsyncResp->asyncResp->res,
- "Thermal", "Temperatures / Voltages");
- return;
- }
- if (temperatureCollections)
- {
- allCollections.emplace("Temperatures",
- *std::move(temperatureCollections));
- }
- if (fanCollections)
- {
- allCollections.emplace("Fans", *std::move(fanCollections));
- }
- setSensorsOverride(sensorsAsyncResp, allCollections);
- });
+ if (!json_util::readJsonPatch(
+ req, sensorsAsyncResp->asyncResp->res, "Temperatures",
+ temperatureCollections, "Fans", fanCollections))
+ {
+ return;
+ }
+ if (!temperatureCollections && !fanCollections)
+ {
+ messages::resourceNotFound(sensorsAsyncResp->asyncResp->res,
+ "Thermal",
+ "Temperatures / Voltages");
+ return;
+ }
+ if (temperatureCollections)
+ {
+ allCollections.emplace("Temperatures",
+ *std::move(temperatureCollections));
+ }
+ if (fanCollections)
+ {
+ allCollections.emplace("Fans", *std::move(fanCollections));
+ }
+ setSensorsOverride(sensorsAsyncResp, allCollections);
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/thermal_metrics.hpp b/redfish-core/lib/thermal_metrics.hpp
index f2541182f7..da4da01858 100644
--- a/redfish-core/lib/thermal_metrics.hpp
+++ b/redfish-core/lib/thermal_metrics.hpp
@@ -48,15 +48,16 @@ inline void handleThermalMetricsHead(
asyncResp, chassisId,
[asyncResp,
chassisId](const std::optional<std::string>& validChassisPath) {
- if (!validChassisPath)
- {
- messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
- return;
- }
- asyncResp->res.addHeader(
- boost::beast::http::field::link,
- "</redfish/v1/JsonSchemas/ThermalMetrics/ThermalMetrics.json>; rel=describedby");
- });
+ if (!validChassisPath)
+ {
+ messages::resourceNotFound(asyncResp->res, "Chassis",
+ chassisId);
+ return;
+ }
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/ThermalMetrics/ThermalMetrics.json>; rel=describedby");
+ });
}
inline void
diff --git a/redfish-core/lib/thermal_subsystem.hpp b/redfish-core/lib/thermal_subsystem.hpp
index c52f395686..5365cb5a15 100644
--- a/redfish-core/lib/thermal_subsystem.hpp
+++ b/redfish-core/lib/thermal_subsystem.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "app.hpp"
+#include "generated/enums/resource.hpp"
#include "logging.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
@@ -46,8 +47,8 @@ inline void doThermalSubsystemCollection(
"/redfish/v1/Chassis/{}/ThermalSubsystem/ThermalMetrics",
chassisId);
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- asyncResp->res.jsonValue["Status"]["Health"] = "OK";
+ asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
+ asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
}
inline void handleThermalSubsystemCollectionHead(
diff --git a/redfish-core/lib/trigger.hpp b/redfish-core/lib/trigger.hpp
index a6101a2a1d..d405d26d60 100644
--- a/redfish-core/lib/trigger.hpp
+++ b/redfish-core/lib/trigger.hpp
@@ -1,15 +1,16 @@
#pragma once
#include "app.hpp"
+#include "generated/enums/metric_definition.hpp"
#include "generated/enums/resource.hpp"
#include "generated/enums/triggers.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
-#include "sensors.hpp"
#include "utility.hpp"
#include "utils/collection.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
+#include "utils/sensor_utils.hpp"
#include "utils/telemetry_utils.hpp"
#include "utils/time_utils.hpp"
@@ -321,9 +322,8 @@ struct NumericThresholds
}
};
-inline bool parseNumericThresholds(crow::Response& res,
- NumericThresholds& numericThresholds,
- Context& ctx)
+inline bool parseNumericThresholds(
+ crow::Response& res, NumericThresholds& numericThresholds, Context& ctx)
{
std::vector<NumericThresholdParams> parsedParams;
if (numericThresholds.upperCritical)
@@ -567,7 +567,7 @@ inline bool parseMetricProperties(crow::Response& res, Context& ctx)
}
std::pair<std::string, std::string> split =
- splitSensorNameAndType(sensorName);
+ redfish::sensor_utils::splitSensorNameAndType(sensorName);
if (split.first.empty() || split.second.empty())
{
messages::propertyValueIncorrect(
@@ -575,8 +575,8 @@ inline bool parseMetricProperties(crow::Response& res, Context& ctx)
return false;
}
- std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first +
- '/' + split.second;
+ std::string sensorPath =
+ "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second;
ctx.sensors.emplace_back(sensorPath, uriStr);
uriIdx++;
@@ -900,7 +900,7 @@ inline bool fillTrigger(
json["DiscreteTriggers"] = *discreteTriggers;
json["DiscreteTriggerCondition"] =
discreteTriggers->empty() ? "Changed" : "Specified";
- json["MetricType"] = "Discrete";
+ json["MetricType"] = metric_definition::MetricType::Discrete;
}
else
{
@@ -916,7 +916,7 @@ inline bool fillTrigger(
}
json["NumericThresholds"] = *numericThresholds;
- json["MetricType"] = "Numeric";
+ json["MetricType"] = metric_definition::MetricType::Numeric;
}
}
@@ -956,8 +956,8 @@ inline void handleTriggerCollectionPost(
crow::connections::systemBus->async_method_call(
[asyncResp, id = ctx.id](const boost::system::error_code& ec,
const std::string& dbusPath) {
- afterCreateTrigger(ec, dbusPath, asyncResp, id);
- },
+ afterCreateTrigger(ec, dbusPath, asyncResp, id);
+ },
service, "/xyz/openbmc_project/Telemetry/Triggers",
"xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
"TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
@@ -973,23 +973,23 @@ inline void requestRoutesTriggerCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#TriggersCollection.TriggersCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/TelemetryService/Triggers";
- asyncResp->res.jsonValue["Name"] = "Triggers Collection";
- constexpr std::array<std::string_view, 1> interfaces{
- telemetry::triggerInterface};
- collection_util::getCollectionMembers(
- asyncResp,
- boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
- interfaces,
- "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#TriggersCollection.TriggersCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/TelemetryService/Triggers";
+ asyncResp->res.jsonValue["Name"] = "Triggers Collection";
+ constexpr std::array<std::string_view, 1> interfaces{
+ telemetry::triggerInterface};
+ collection_util::getCollectionMembers(
+ asyncResp,
+ boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
+ interfaces,
+ "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
+ });
BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
.privileges(redfish::privileges::postTriggersCollection)
@@ -1005,36 +1005,40 @@ inline void requestRoutesTrigger(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& id) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- sdbusplus::asio::getAllProperties(
- *crow::connections::systemBus, telemetry::service,
- telemetry::getDbusTriggerPath(id), telemetry::triggerInterface,
- [asyncResp,
- id](const boost::system::error_code& ec,
- const std::vector<std::pair<
- std::string, telemetry::TriggerGetParamsVariant>>& ret) {
- if (ec.value() == EBADR ||
- ec == boost::system::errc::host_unreachable)
- {
- messages::resourceNotFound(asyncResp->res, "Triggers", id);
- return;
- }
- if (ec)
- {
- BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- if (!telemetry::fillTrigger(asyncResp->res.jsonValue, id, ret))
- {
- messages::internalError(asyncResp->res);
- }
- });
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, telemetry::service,
+ telemetry::getDbusTriggerPath(id),
+ telemetry::triggerInterface,
+ [asyncResp,
+ id](const boost::system::error_code& ec,
+ const std::vector<std::pair<
+ std::string, telemetry::TriggerGetParamsVariant>>&
+ ret) {
+ if (ec.value() == EBADR ||
+ ec == boost::system::errc::host_unreachable)
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "Triggers", id);
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (!telemetry::fillTrigger(asyncResp->res.jsonValue,
+ id, ret))
+ {
+ messages::internalError(asyncResp->res);
+ }
+ });
+ });
BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
.privileges(redfish::privileges::deleteTriggers)
@@ -1042,32 +1046,35 @@ inline void requestRoutesTrigger(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& id) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- const std::string triggerPath = telemetry::getDbusTriggerPath(id);
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, id](const boost::system::error_code& ec) {
- if (ec.value() == EBADR)
- {
- messages::resourceNotFound(asyncResp->res, "Triggers", id);
- return;
- }
-
- if (ec)
- {
- BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
-
- asyncResp->res.result(boost::beast::http::status::no_content);
- },
- telemetry::service, triggerPath,
- "xyz.openbmc_project.Object.Delete", "Delete");
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ const std::string triggerPath =
+ telemetry::getDbusTriggerPath(id);
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, id](const boost::system::error_code& ec) {
+ if (ec.value() == EBADR)
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "Triggers", id);
+ return;
+ }
+
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ asyncResp->res.result(
+ boost::beast::http::status::no_content);
+ },
+ telemetry::service, triggerPath,
+ "xyz.openbmc_project.Object.Delete", "Delete");
+ });
}
} // namespace redfish
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 9a399affa4..eb25d1f8f6 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -118,12 +118,12 @@ inline void activateImage(const std::string& objPath,
"xyz.openbmc_project.Software.Activation", "RequestedActivation",
"xyz.openbmc_project.Software.Activation.RequestedActivations.Active",
[](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("error_code = {}", ec);
- BMCWEB_LOG_DEBUG("error msg = {}", ec.message());
- }
- });
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("error_code = {}", ec);
+ BMCWEB_LOG_DEBUG("error msg = {}", ec.message());
+ }
+ });
}
inline bool handleCreateTask(const boost::system::error_code& ec2,
@@ -243,7 +243,7 @@ inline void createTask(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
// Note that asyncResp can be either a valid pointer or nullptr. If nullptr
// then no asyncResp updates will occur
-static void
+inline void
softwareInterfaceAdded(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
sdbusplus::message_t& m, task::Payload&& payload)
{
@@ -270,40 +270,41 @@ static void
const std::vector<
std::pair<std::string, std::vector<std::string>>>&
objInfo) mutable {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("error_code = {}", ec);
- BMCWEB_LOG_DEBUG("error msg = {}", ec.message());
- if (asyncResp)
+ if (ec)
{
- messages::internalError(asyncResp->res);
+ BMCWEB_LOG_DEBUG("error_code = {}", ec);
+ BMCWEB_LOG_DEBUG("error msg = {}", ec.message());
+ if (asyncResp)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ cleanUp();
+ return;
}
- cleanUp();
- return;
- }
- // Ensure we only got one service back
- if (objInfo.size() != 1)
- {
- BMCWEB_LOG_ERROR("Invalid Object Size {}", objInfo.size());
- if (asyncResp)
+ // Ensure we only got one service back
+ if (objInfo.size() != 1)
{
- messages::internalError(asyncResp->res);
+ BMCWEB_LOG_ERROR("Invalid Object Size {}",
+ objInfo.size());
+ if (asyncResp)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ cleanUp();
+ return;
}
- cleanUp();
- return;
- }
- // cancel timer only when
- // xyz.openbmc_project.Software.Activation interface
- // is added
- fwAvailableTimer = nullptr;
+ // cancel timer only when
+ // xyz.openbmc_project.Software.Activation interface
+ // is added
+ fwAvailableTimer = nullptr;
- activateImage(objPath.str, objInfo[0].first);
- if (asyncResp)
- {
- createTask(asyncResp, std::move(payload), objPath);
- }
- fwUpdateInProgress = false;
- });
+ activateImage(objPath.str, objInfo[0].first);
+ if (asyncResp)
+ {
+ createTask(asyncResp, std::move(payload), objPath);
+ }
+ fwUpdateInProgress = false;
+ });
break;
}
@@ -485,10 +486,9 @@ inline void monitorForSoftwareAvailable(
std::bind_front(afterUpdateErrorMatcher, asyncResp, url));
}
-inline std::optional<boost::urls::url>
- parseSimpleUpdateUrl(std::string imageURI,
- std::optional<std::string> transferProtocol,
- crow::Response& res)
+inline std::optional<boost::urls::url> parseSimpleUpdateUrl(
+ std::string imageURI, std::optional<std::string> transferProtocol,
+ crow::Response& res)
{
if (imageURI.find("://") == std::string::npos)
{
@@ -574,61 +574,6 @@ inline void doHttpsUpdate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
url.buffer());
}
-inline void doTftpUpdate(const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const boost::urls::url_view_base& url)
-{
- if (!BMCWEB_INSECURE_TFTP_UPDATE)
- {
- messages::actionParameterNotSupported(asyncResp->res, "ImageURI",
- url.buffer());
- return;
- }
-
- std::string path(url.encoded_path());
- if (path.size() < 2)
- {
- messages::actionParameterNotSupported(asyncResp->res, "ImageURI",
- url.buffer());
- return;
- }
- // TFTP expects a path without a /
- path.erase(0, 1);
- std::string host(url.encoded_host_and_port());
- BMCWEB_LOG_DEBUG("Server: {} File: {}", host, path);
-
- // Setup callback for when new software detected
- // Give TFTP 10 minutes to complete
- monitorForSoftwareAvailable(
- asyncResp, req,
- "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate", 600);
-
- // TFTP can take up to 10 minutes depending on image size and
- // connection speed. Return to caller as soon as the TFTP operation
- // has been started. The callback above will ensure the activate
- // is started once the download has completed
- redfish::messages::success(asyncResp->res);
-
- // Call TFTP service
- crow::connections::systemBus->async_method_call(
- [](const boost::system::error_code& ec) {
- if (ec)
- {
- // messages::internalError(asyncResp->res);
- cleanUp();
- BMCWEB_LOG_DEBUG("error_code = {}", ec);
- BMCWEB_LOG_DEBUG("error msg = {}", ec.message());
- }
- else
- {
- BMCWEB_LOG_DEBUG("Call to DownloaViaTFTP Success");
- }
- },
- "xyz.openbmc_project.Software.Download",
- "/xyz/openbmc_project/software", "xyz.openbmc_project.Common.TFTP",
- "DownloadViaTFTP", path, host);
-}
-
inline void handleUpdateServiceSimpleUpdateAction(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
@@ -662,11 +607,7 @@ inline void handleUpdateServiceSimpleUpdateAction(
{
return;
}
- if (url->scheme() == "tftp")
- {
- doTftpUpdate(req, asyncResp, *url);
- }
- else if (url->scheme() == "https")
+ if (url->scheme() == "https")
{
doHttpsUpdate(asyncResp, *url);
}
@@ -688,8 +629,8 @@ inline void uploadImageFile(crow::Response& res, std::string_view body)
std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
std::ofstream::trunc);
// set the permission of the file to 640
- std::filesystem::perms permission = std::filesystem::perms::owner_read |
- std::filesystem::perms::group_read;
+ std::filesystem::perms permission =
+ std::filesystem::perms::owner_read | std::filesystem::perms::group_read;
std::filesystem::permissions(filepath, permission);
out << body;
@@ -811,7 +752,11 @@ inline std::optional<MultiPartUpdateParameters>
{
std::vector<std::string> tempTargets;
nlohmann::json content =
- nlohmann::json::parse(formpart.content);
+ nlohmann::json::parse(formpart.content, nullptr, false);
+ if (content.is_discarded())
+ {
+ return std::nullopt;
+ }
nlohmann::json::object_t* obj =
content.get_ptr<nlohmann::json::object_t*>();
if (obj == nullptr)
@@ -872,11 +817,10 @@ inline std::optional<MultiPartUpdateParameters>
return multiRet;
}
-inline void
- handleStartUpdate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- task::Payload payload, const std::string& objectPath,
- const boost::system::error_code& ec,
- const sdbusplus::message::object_path& retPath)
+inline void handleStartUpdate(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, task::Payload payload,
+ const std::string& objectPath, const boost::system::error_code& ec,
+ const sdbusplus::message::object_path& retPath)
{
if (ec)
{
@@ -886,34 +830,37 @@ inline void
return;
}
- BMCWEB_LOG_INFO("Call to StartUpdate Success, retPath = {}", retPath.str);
- createTask(asyncResp, std::move(payload), objectPath);
+ BMCWEB_LOG_INFO("Call to StartUpdate on {} Success, retPath = {}",
+ objectPath, retPath.str);
+ createTask(asyncResp, std::move(payload), retPath);
}
-inline void startUpdate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- task::Payload payload,
- const MemoryFileDescriptor& memfd,
- const std::string& applyTime,
- const std::string& objectPath,
- const std::string& serviceName)
+inline void startUpdate(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, task::Payload payload,
+ const MemoryFileDescriptor& memfd, const std::string& applyTime,
+ const std::string& objectPath, const std::string& serviceName)
{
crow::connections::systemBus->async_method_call(
[asyncResp, payload = std::move(payload),
objectPath](const boost::system::error_code& ec1,
const sdbusplus::message::object_path& retPath) mutable {
- handleStartUpdate(asyncResp, std::move(payload), objectPath, ec1,
- retPath);
- },
+ handleStartUpdate(asyncResp, std::move(payload), objectPath, ec1,
+ retPath);
+ },
serviceName, objectPath, "xyz.openbmc_project.Software.Update",
"StartUpdate", sdbusplus::message::unix_fd(memfd.fd), applyTime);
}
-inline void getAssociatedUpdateInterface(
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, task::Payload payload,
- const MemoryFileDescriptor& memfd, const std::string& applyTime,
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree)
+inline void getSwInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ task::Payload payload, const MemoryFileDescriptor& memfd,
+ const std::string& applyTime, const std::string& target,
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreeResponse& subtree)
{
+ using SwInfoMap = std::unordered_map<
+ std::string, std::pair<sdbusplus::message::object_path, std::string>>;
+ SwInfoMap swInfoMap;
+
if (ec)
{
BMCWEB_LOG_ERROR("error_code = {}", ec);
@@ -921,35 +868,36 @@ inline void getAssociatedUpdateInterface(
messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_DEBUG("Found {} startUpdate subtree paths", subtree.size());
+ BMCWEB_LOG_DEBUG("Found {} software version paths", subtree.size());
- if (subtree.size() > 1)
+ for (const auto& entry : subtree)
{
- BMCWEB_LOG_ERROR("Found more than one startUpdate subtree paths");
- messages::internalError(asyncResp->res);
+ sdbusplus::message::object_path path(entry.first);
+ std::string swId = path.filename();
+ swInfoMap.emplace(swId, make_pair(path, entry.second[0].first));
+ }
+
+ auto swEntry = swInfoMap.find(target);
+ if (swEntry == swInfoMap.end())
+ {
+ BMCWEB_LOG_WARNING("No valid DBus path for Target URI {}", target);
+ messages::propertyValueFormatError(asyncResp->res, target, "Targets");
return;
}
- auto objectPath = subtree[0].first;
- auto serviceName = subtree[0].second[0].first;
+ BMCWEB_LOG_DEBUG("Found software version path {} serviceName {}",
+ swEntry->second.first.str, swEntry->second.second);
- BMCWEB_LOG_DEBUG("Found objectPath {} serviceName {}", objectPath,
- serviceName);
- startUpdate(asyncResp, std::move(payload), memfd, applyTime, objectPath,
- serviceName);
+ startUpdate(asyncResp, std::move(payload), memfd, applyTime,
+ swEntry->second.first.str, swEntry->second.second);
}
-inline void
- getSwInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- task::Payload payload, MemoryFileDescriptor memfd,
- const std::string& applyTime, const std::string& target,
- const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse& subtree)
+inline void handleBMCUpdate(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, task::Payload payload,
+ const MemoryFileDescriptor& memfd, const std::string& applyTime,
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperEndPoints& functionalSoftware)
{
- using SwInfoMap =
- std::unordered_map<std::string, sdbusplus::message::object_path>;
- SwInfoMap swInfoMap;
-
if (ec)
{
BMCWEB_LOG_ERROR("error_code = {}", ec);
@@ -957,47 +905,22 @@ inline void
messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_DEBUG("Found {} software version paths", subtree.size());
-
- for (const auto& objectPath : subtree)
- {
- sdbusplus::message::object_path path(objectPath);
- std::string swId = path.filename();
- swInfoMap.emplace(swId, path);
- }
-
- auto swEntry = swInfoMap.find(target);
- if (swEntry == swInfoMap.end())
+ if (functionalSoftware.size() != 1)
{
- BMCWEB_LOG_WARNING("No valid DBus path for Target URI {}", target);
- messages::propertyValueFormatError(asyncResp->res, target, "Targets");
+ BMCWEB_LOG_ERROR("Found {} functional software endpoints",
+ functionalSoftware.size());
+ messages::internalError(asyncResp->res);
return;
}
- BMCWEB_LOG_DEBUG("Found software version path {}", swEntry->second.str);
-
- sdbusplus::message::object_path swObjectPath = swEntry->second /
- "software_version";
- constexpr std::array<std::string_view, 1> interfaces = {
- "xyz.openbmc_project.Software.Update"};
- dbus::utility::getAssociatedSubTree(
- swObjectPath,
- sdbusplus::message::object_path("/xyz/openbmc_project/software"), 0,
- interfaces,
- [asyncResp, payload = std::move(payload), memfd = std::move(memfd),
- applyTime](
- const boost::system::error_code& ec1,
- const dbus::utility::MapperGetSubTreeResponse& subtree1) mutable {
- getAssociatedUpdateInterface(asyncResp, std::move(payload), memfd,
- applyTime, ec1, subtree1);
- });
+ startUpdate(asyncResp, std::move(payload), memfd, applyTime,
+ functionalSoftware[0], "xyz.openbmc_project.Software.Manager");
}
-inline void
- processUpdateRequest(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- task::Payload&& payload, std::string_view body,
- const std::string& applyTime,
- std::vector<std::string>& targets)
+inline void processUpdateRequest(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ task::Payload&& payload, std::string_view body,
+ const std::string& applyTime, std::vector<std::string>& targets)
{
MemoryFileDescriptor memfd("update-image");
if (memfd.fd == -1)
@@ -1021,24 +944,29 @@ inline void
if (!targets.empty() && targets[0] == BMCWEB_REDFISH_MANAGER_URI_NAME)
{
- startUpdate(asyncResp, std::move(payload), memfd, applyTime,
- "/xyz/openbmc_project/software/bmc",
- "xyz.openbmc_project.Software.Manager");
+ dbus::utility::getAssociationEndPoints(
+ "/xyz/openbmc_project/software/bmc/functional",
+ [asyncResp, payload = std::move(payload), memfd = std::move(memfd),
+ applyTime](
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperEndPoints& objectPaths) mutable {
+ handleBMCUpdate(asyncResp, std::move(payload), memfd, applyTime,
+ ec, objectPaths);
+ });
}
else
{
constexpr std::array<std::string_view, 1> interfaces = {
"xyz.openbmc_project.Software.Version"};
- dbus::utility::getSubTreePaths(
+ dbus::utility::getSubTree(
"/xyz/openbmc_project/software", 1, interfaces,
[asyncResp, payload = std::move(payload), memfd = std::move(memfd),
- applyTime,
- targets](const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse&
- subtree) mutable {
- getSwInfo(asyncResp, std::move(payload), std::move(memfd),
- applyTime, targets[0], ec, subtree);
- });
+ applyTime, targets](const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreeResponse&
+ subtree) mutable {
+ getSwInfo(asyncResp, std::move(payload), memfd, applyTime,
+ targets[0], ec, subtree);
+ });
}
}
@@ -1176,8 +1104,8 @@ inline void
asyncResp->res.jsonValue["FirmwareInventory"]["@odata.id"] =
"/redfish/v1/UpdateService/FirmwareInventory";
// Get the MaxImageSizeBytes
- asyncResp->res.jsonValue["MaxImageSizeBytes"] = BMCWEB_HTTP_BODY_LIMIT *
- 1024 * 1024;
+ asyncResp->res.jsonValue["MaxImageSizeBytes"] =
+ BMCWEB_HTTP_BODY_LIMIT * 1024 * 1024;
// Update Actions object.
nlohmann::json& updateSvcSimpleUpdate =
@@ -1196,8 +1124,9 @@ inline void
updateSvcSimpleUpdate["TransferProtocol@Redfish.AllowableValues"] =
std::move(allowed);
- asyncResp->res.jsonValue["HttpPushUriOptions"]["HttpPushUriApplyTime"]
- ["ApplyTime"] = "Immediate";
+ asyncResp->res
+ .jsonValue["HttpPushUriOptions"]["HttpPushUriApplyTime"]["ApplyTime"] =
+ update_service::ApplyTime::Immediate;
}
inline void handleUpdateServiceFirmwareInventoryCollectionGet(
@@ -1263,65 +1192,65 @@ inline void
[asyncResp,
swId](const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap& propertiesList) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- const std::string* swInvPurpose = nullptr;
- const std::string* version = nullptr;
+ const std::string* swInvPurpose = nullptr;
+ const std::string* version = nullptr;
- const bool success = sdbusplus::unpackPropertiesNoThrow(
- dbus_utils::UnpackErrorPrinter(), propertiesList, "Purpose",
- swInvPurpose, "Version", version);
+ const bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), propertiesList, "Purpose",
+ swInvPurpose, "Version", version);
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (!success)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- if (swInvPurpose == nullptr)
- {
- BMCWEB_LOG_DEBUG("Can't find property \"Purpose\"!");
- messages::internalError(asyncResp->res);
- return;
- }
+ if (swInvPurpose == nullptr)
+ {
+ BMCWEB_LOG_DEBUG("Can't find property \"Purpose\"!");
+ messages::internalError(asyncResp->res);
+ return;
+ }
- BMCWEB_LOG_DEBUG("swInvPurpose = {}", *swInvPurpose);
+ BMCWEB_LOG_DEBUG("swInvPurpose = {}", *swInvPurpose);
- if (version == nullptr)
- {
- BMCWEB_LOG_DEBUG("Can't find property \"Version\"!");
+ if (version == nullptr)
+ {
+ BMCWEB_LOG_DEBUG("Can't find property \"Version\"!");
- messages::internalError(asyncResp->res);
+ messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["Version"] = *version;
- asyncResp->res.jsonValue["Id"] = swId;
-
- // swInvPurpose is of format:
- // xyz.openbmc_project.Software.Version.VersionPurpose.ABC
- // Translate this to "ABC image"
- size_t endDesc = swInvPurpose->rfind('.');
- if (endDesc == std::string::npos)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- endDesc++;
- if (endDesc >= swInvPurpose->size())
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ return;
+ }
+ asyncResp->res.jsonValue["Version"] = *version;
+ asyncResp->res.jsonValue["Id"] = swId;
+
+ // swInvPurpose is of format:
+ // xyz.openbmc_project.Software.Version.VersionPurpose.ABC
+ // Translate this to "ABC image"
+ size_t endDesc = swInvPurpose->rfind('.');
+ if (endDesc == std::string::npos)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ endDesc++;
+ if (endDesc >= swInvPurpose->size())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- std::string formatDesc = swInvPurpose->substr(endDesc);
- asyncResp->res.jsonValue["Description"] = formatDesc + " image";
- getRelatedItems(asyncResp, *swInvPurpose);
- });
+ std::string formatDesc = swInvPurpose->substr(endDesc);
+ asyncResp->res.jsonValue["Description"] = formatDesc + " image";
+ getRelatedItems(asyncResp, *swInvPurpose);
+ });
}
inline void handleUpdateServiceFirmwareInventoryGet(
@@ -1345,52 +1274,54 @@ inline void handleUpdateServiceFirmwareInventoryGet(
[asyncResp,
swId](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
- BMCWEB_LOG_DEBUG("doGet callback...");
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- // Ensure we find our input swId, otherwise return an error
- bool found = false;
- for (const std::pair<
- std::string,
- std::vector<std::pair<std::string, std::vector<std::string>>>>&
- obj : subtree)
- {
- if (!obj.first.ends_with(*swId))
+ BMCWEB_LOG_DEBUG("doGet callback...");
+ if (ec)
{
- continue;
+ messages::internalError(asyncResp->res);
+ return;
}
- if (obj.second.empty())
+ // Ensure we find our input swId, otherwise return an error
+ bool found = false;
+ for (const std::pair<std::string,
+ std::vector<std::pair<
+ std::string, std::vector<std::string>>>>&
+ obj : subtree)
{
- continue;
- }
+ if (!obj.first.ends_with(*swId))
+ {
+ continue;
+ }
- found = true;
- sw_util::getSwStatus(asyncResp, swId, obj.second[0].first);
- getSoftwareVersion(asyncResp, obj.second[0].first, obj.first,
- *swId);
- }
- if (!found)
- {
- BMCWEB_LOG_WARNING("Input swID {} not found!", *swId);
- messages::resourceMissingAtURI(
- asyncResp->res,
- boost::urls::format(
- "/redfish/v1/UpdateService/FirmwareInventory/{}", *swId));
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#SoftwareInventory.v1_1_0.SoftwareInventory";
- asyncResp->res.jsonValue["Name"] = "Software Inventory";
- asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
-
- asyncResp->res.jsonValue["Updateable"] = false;
- sw_util::getSwUpdatableStatus(asyncResp, swId);
- });
+ if (obj.second.empty())
+ {
+ continue;
+ }
+
+ found = true;
+ sw_util::getSwStatus(asyncResp, swId, obj.second[0].first);
+ getSoftwareVersion(asyncResp, obj.second[0].first, obj.first,
+ *swId);
+ }
+ if (!found)
+ {
+ BMCWEB_LOG_WARNING("Input swID {} not found!", *swId);
+ messages::resourceMissingAtURI(
+ asyncResp->res,
+ boost::urls::format(
+ "/redfish/v1/UpdateService/FirmwareInventory/{}",
+ *swId));
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#SoftwareInventory.v1_1_0.SoftwareInventory";
+ asyncResp->res.jsonValue["Name"] = "Software Inventory";
+ asyncResp->res.jsonValue["Status"]["HealthRollup"] =
+ resource::Health::OK;
+
+ asyncResp->res.jsonValue["Updateable"] = false;
+ sw_util::getSwUpdatableStatus(asyncResp, swId);
+ });
}
inline void requestRoutesUpdateService(App& app)
diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp
index 37fb2045c9..a18f1d03ca 100644
--- a/redfish-core/lib/virtual_media.hpp
+++ b/redfish-core/lib/virtual_media.hpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
@@ -43,9 +43,8 @@ enum class VmMode
Proxy
};
-inline VmMode
- parseObjectPathAndGetMode(const sdbusplus::message::object_path& itemPath,
- const std::string& resName)
+inline VmMode parseObjectPathAndGetMode(
+ const sdbusplus::message::object_path& itemPath, const std::string& resName)
{
std::string thisPath = itemPath.filename();
BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
@@ -101,26 +100,26 @@ inline void
[service, resName, asyncResp, handler = std::move(handler)](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG("DBUS response error");
- return;
- }
+ return;
+ }
- for (const auto& item : subtree)
- {
- VmMode mode = parseObjectPathAndGetMode(item.first, resName);
- if (mode != VmMode::Invalid)
+ for (const auto& item : subtree)
{
- handler(service, resName, asyncResp, item);
- return;
+ VmMode mode = parseObjectPathAndGetMode(item.first, resName);
+ if (mode != VmMode::Invalid)
+ {
+ handler(service, resName, asyncResp, item);
+ return;
+ }
}
- }
- BMCWEB_LOG_DEBUG("Parent item not found");
- asyncResp->res.result(boost::beast::http::status::not_found);
- });
+ BMCWEB_LOG_DEBUG("Parent item not found");
+ asyncResp->res.result(boost::beast::http::status::not_found);
+ });
}
/**
@@ -257,9 +256,9 @@ inline nlohmann::json vmItemTemplate(const std::string& name,
item["WriteProtected"] = true;
item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
- item["TransferMethod"] = "Stream";
+ item["TransferMethod"] = virtual_media::TransferMethod::Stream;
item["Oem"]["OpenBMC"]["@odata.type"] =
- "#OemVirtualMedia.v1_0_0.VirtualMedia";
+ "#OpenBMCVirtualMedia.v1_0_0.VirtualMedia";
item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
@@ -281,29 +280,29 @@ inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
[name, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG("DBUS response error");
- return;
- }
- nlohmann::json& members = asyncResp->res.jsonValue["Members"];
- members = nlohmann::json::array();
-
- for (const auto& object : subtree)
- {
- nlohmann::json item;
- std::string path = object.first.filename();
- if (path.empty())
+ if (ec)
{
- continue;
+ BMCWEB_LOG_DEBUG("DBUS response error");
+ return;
}
+ nlohmann::json& members = asyncResp->res.jsonValue["Members"];
+ members = nlohmann::json::array();
- item["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
- members.emplace_back(std::move(item));
- }
- asyncResp->res.jsonValue["Members@odata.count"] = members.size();
- });
+ for (const auto& object : subtree)
+ {
+ nlohmann::json item;
+ std::string path = object.first.filename();
+ if (path.empty())
+ {
+ continue;
+ }
+
+ item["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
+ members.emplace_back(std::move(item));
+ }
+ asyncResp->res.jsonValue["Members@odata.count"] = members.size();
+ });
}
inline void
@@ -415,9 +414,8 @@ inline std::optional<TransferProtocol> getTransferProtocolFromParam(
* @brief Function extends URI with transfer protocol type.
*
*/
-inline std::string
- getUriWithTransferProtocol(const std::string& imageUri,
- const TransferProtocol& transferProtocol)
+inline std::string getUriWithTransferProtocol(
+ const std::string& imageUri, const TransferProtocol& transferProtocol)
{
if (transferProtocol == TransferProtocol::smb)
{
@@ -474,14 +472,14 @@ inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
// Pass secret over pipe
secretPipe->asyncWrite(
std::move(userName), std::move(password),
- [asyncResp, secretPipe](const boost::system::error_code& ec,
- std::size_t) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
- messages::internalError(asyncResp->res);
- }
- });
+ [asyncResp,
+ secretPipe](const boost::system::error_code& ec, std::size_t) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
+ messages::internalError(asyncResp->res);
+ }
+ });
}
dbus::utility::DbusVariantType unixFd(
@@ -491,20 +489,20 @@ inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
"/xyz/openbmc_project/VirtualMedia/Legacy");
path /= name;
crow::connections::systemBus->async_method_call(
- [asyncResp, secretPipe](const boost::system::error_code& ec,
- bool success) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- if (!success)
- {
- BMCWEB_LOG_ERROR("Service responded with error");
- messages::internalError(asyncResp->res);
- }
- },
+ [asyncResp,
+ secretPipe](const boost::system::error_code& ec, bool success) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (!success)
+ {
+ BMCWEB_LOG_ERROR("Service responded with error");
+ messages::internalError(asyncResp->res);
+ }
+ },
service, path.str, "xyz.openbmc_project.VirtualMedia.Legacy", "Mount",
imageUrl, rw, unixFd);
}
@@ -662,14 +660,14 @@ inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
{
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- },
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ },
service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
"xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
}
@@ -677,14 +675,14 @@ inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
{
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
- messages::internalError(asyncResp->res);
- return;
- }
- },
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ },
service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
"xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
}
@@ -726,47 +724,51 @@ inline void handleManagersVirtualMediaActionInsertPost(
[asyncResp, action, actionParams,
resName](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& getObjectType) mutable {
- if (ec)
- {
- BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
- messages::resourceNotFound(asyncResp->res, action, resName);
-
- return;
- }
-
- std::string service = getObjectType.begin()->first;
- BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
-
- sdbusplus::message::object_path path(
- "/xyz/openbmc_project/VirtualMedia");
- dbus::utility::getManagedObjects(
- service, path,
- [service, resName, action, actionParams, asyncResp](
- const boost::system::error_code& ec2,
- const dbus::utility::ManagedObjectType& subtree) mutable {
- if (ec2)
+ if (ec)
{
- // Not possible in proxy mode
- BMCWEB_LOG_DEBUG("InsertMedia not "
- "allowed in proxy mode");
+ BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
messages::resourceNotFound(asyncResp->res, action, resName);
return;
}
- for (const auto& object : subtree)
- {
- VmMode mode = parseObjectPathAndGetMode(object.first, resName);
- if (mode == VmMode::Legacy)
- {
- validateParams(asyncResp, service, resName, actionParams);
- return;
- }
- }
- BMCWEB_LOG_DEBUG("Parent item not found");
- messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
+ std::string service = getObjectType.begin()->first;
+ BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
+
+ sdbusplus::message::object_path path(
+ "/xyz/openbmc_project/VirtualMedia");
+ dbus::utility::getManagedObjects(
+ service, path,
+ [service, resName, action, actionParams, asyncResp](
+ const boost::system::error_code& ec2,
+ const dbus::utility::ManagedObjectType& subtree) mutable {
+ if (ec2)
+ {
+ // Not possible in proxy mode
+ BMCWEB_LOG_DEBUG("InsertMedia not "
+ "allowed in proxy mode");
+ messages::resourceNotFound(asyncResp->res, action,
+ resName);
+
+ return;
+ }
+ for (const auto& object : subtree)
+ {
+ VmMode mode =
+ parseObjectPathAndGetMode(object.first, resName);
+ if (mode == VmMode::Legacy)
+ {
+ validateParams(asyncResp, service, resName,
+ actionParams);
+
+ return;
+ }
+ }
+ BMCWEB_LOG_DEBUG("Parent item not found");
+ messages::resourceNotFound(asyncResp->res, "VirtualMedia",
+ resName);
+ });
});
- });
}
inline void handleManagersVirtualMediaActionEject(
@@ -792,44 +794,48 @@ inline void handleManagersVirtualMediaActionEject(
[asyncResp, action,
resName](const boost::system::error_code& ec2,
const dbus::utility::MapperGetObject& getObjectType) {
- if (ec2)
- {
- BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec2);
- messages::internalError(asyncResp->res);
-
- return;
- }
- std::string service = getObjectType.begin()->first;
- BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
-
- sdbusplus::message::object_path path(
- "/xyz/openbmc_project/VirtualMedia");
- dbus::utility::getManagedObjects(
- service, path,
- [resName, service, action,
- asyncResp](const boost::system::error_code& ec,
- const dbus::utility::ManagedObjectType& subtree) {
- if (ec)
+ if (ec2)
{
- BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
- messages::resourceNotFound(asyncResp->res, action, resName);
+ BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}",
+ ec2);
+ messages::internalError(asyncResp->res);
+
return;
}
+ std::string service = getObjectType.begin()->first;
+ BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
+
+ sdbusplus::message::object_path path(
+ "/xyz/openbmc_project/VirtualMedia");
+ dbus::utility::getManagedObjects(
+ service, path,
+ [resName, service, action,
+ asyncResp](const boost::system::error_code& ec,
+ const dbus::utility::ManagedObjectType& subtree) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
+ messages::resourceNotFound(asyncResp->res, action,
+ resName);
+ return;
+ }
- for (const auto& object : subtree)
- {
- VmMode mode = parseObjectPathAndGetMode(object.first, resName);
- if (mode != VmMode::Invalid)
- {
- doEjectAction(asyncResp, service, resName,
- mode == VmMode::Legacy);
- return;
- }
- }
- BMCWEB_LOG_DEBUG("Parent item not found");
- messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
+ for (const auto& object : subtree)
+ {
+ VmMode mode =
+ parseObjectPathAndGetMode(object.first, resName);
+ if (mode != VmMode::Invalid)
+ {
+ doEjectAction(asyncResp, service, resName,
+ mode == VmMode::Legacy);
+ return;
+ }
+ }
+ BMCWEB_LOG_DEBUG("Parent item not found");
+ messages::resourceNotFound(asyncResp->res, "VirtualMedia",
+ resName);
+ });
});
- });
}
inline void handleManagersVirtualMediaCollectionGet(
@@ -858,18 +864,18 @@ inline void handleManagersVirtualMediaCollectionGet(
"/xyz/openbmc_project/VirtualMedia", {},
[asyncResp, name](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& getObjectType) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
- messages::internalError(asyncResp->res);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
+ messages::internalError(asyncResp->res);
- return;
- }
- std::string service = getObjectType.begin()->first;
- BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
+ return;
+ }
+ std::string service = getObjectType.begin()->first;
+ BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
- getVmResourceList(asyncResp, service, name);
- });
+ getVmResourceList(asyncResp, service, name);
+ });
}
inline void
@@ -893,18 +899,18 @@ inline void
[asyncResp, name,
resName](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& getObjectType) {
- if (ec)
- {
- BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
- messages::internalError(asyncResp->res);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
+ messages::internalError(asyncResp->res);
- return;
- }
- std::string service = getObjectType.begin()->first;
- BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
+ return;
+ }
+ std::string service = getObjectType.begin()->first;
+ BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
- getVmData(asyncResp, service, name, resName);
- });
+ getVmData(asyncResp, service, name, resName);
+ });
}
inline void requestNBDVirtualMediaRoutes(App& app)
diff --git a/redfish-core/meson.build b/redfish-core/meson.build
new file mode 100644
index 0000000000..8bec0e659e
--- /dev/null
+++ b/redfish-core/meson.build
@@ -0,0 +1 @@
+subdir('schema')
diff --git a/redfish-core/schema/dmtf/csdl/AccountService_v1.xml b/redfish-core/schema/dmtf/csdl/AccountService_v1.xml
index 14a56cec03..ab0450cea7 100644
--- a/redfish-core/schema/dmtf/csdl/AccountService_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/AccountService_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: AccountService v1.15.1 -->
+<!--# Redfish Schema: AccountService v1.16.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -107,23 +107,23 @@
</Member>
<Member Name="SecurID">
<Annotation Term="OData.Description" String="Bypass RSA SecurID."/>
- <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass RSA SecurID."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass RSA SecurID. Authentication with RSA SecurID is configured with the `SecurID` property."/>
</Member>
<Member Name="GoogleAuthenticator">
<Annotation Term="OData.Description" String="Bypass Google Authenticator."/>
- <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass Google Authenticator."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass Google Authenticator. Authentication with Google Authenticator is configured with the `GoogleAuthenticator` property."/>
</Member>
<Member Name="MicrosoftAuthenticator">
<Annotation Term="OData.Description" String="Bypass Microsoft Authenticator."/>
- <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass Microsoft Authenticator."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass Microsoft Authenticator. Authentication with Microsoft Authenticator is configured with the `MicrosoftAuthenticator` property."/>
</Member>
<Member Name="ClientCertificate">
<Annotation Term="OData.Description" String="Bypass client certificate authentication."/>
- <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass client certificate authentication."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass client certificate authentication. Authentication with client certificates is configured with the `ClientCertificate` property."/>
</Member>
<Member Name="OneTimePasscode">
<Annotation Term="OData.Description" String="Bypass one-time passcode authentication."/>
- <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass one-time passcode authentication."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass one-time passcode authentication. Authentication with a one-time passcode is configured with the `OneTimePasscode` property."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -133,6 +133,18 @@
</Collection>
</Annotation>
</Member>
+ <Member Name="TimeBasedOneTimePassword">
+ <Annotation Term="OData.Description" String="Bypass Time-based One-Time Password (TOTP) authentication."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass RFC6238-defined Time-based One-Time Password (TOTP) authentication. Authentication with a Time-based One-Time Password is configured with the `TimeBasedOneTimePassword` property."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_16_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
<Member Name="OEM">
<Annotation Term="OData.Description" String="Bypass OEM-defined multi-factor authentication."/>
<Annotation Term="OData.LongDescription" String="This value shall indicate an account or role mapping can bypass OEM-defined multi-factor authentication."/>
@@ -1508,11 +1520,11 @@
<Annotation Term="OData.LongDescription" String="This property shall contain the settings related to RSA SecurID multi-factor authentication."/>
</Property>
<Property Name="GoogleAuthenticator" Type="AccountService.v1_12_0.GoogleAuthenticator">
- <Annotation Term="OData.Description" String="The settings related to Google Authenticator multi-factor authentication."/>
+ <Annotation Term="OData.Description" String="The settings related to Google Authenticator multi-factor authentication. For generic Time-Based One-Time Password (TOTP) multi-factor authentication, use the `TimeBasedOneTimePassword` property."/>
<Annotation Term="OData.LongDescription" String="This property shall contain the settings related to Google Authenticator multi-factor authentication."/>
</Property>
<Property Name="MicrosoftAuthenticator" Type="AccountService.v1_12_0.MicrosoftAuthenticator">
- <Annotation Term="OData.Description" String="The settings related to Microsoft Authenticator multi-factor authentication."/>
+ <Annotation Term="OData.Description" String="The settings related to Microsoft Authenticator multi-factor authentication. For generic Time-Based One-Time Password (TOTP) multi-factor authentication, use the `TimeBasedOneTimePassword` property."/>
<Annotation Term="OData.LongDescription" String="This property shall contain the settings related to Microsoft Authenticator multi-factor authentication."/>
</Property>
<Property Name="ClientCertificate" Type="AccountService.v1_12_0.ClientCertificate">
@@ -1755,6 +1767,7 @@
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AccountService.v1_14_0">
<Annotation Term="Redfish.Release" String="2023.2"/>
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add `OneTimePasscode` to `BypassTypes` for multi-factor authentication configurations."/>
<EntityType Name="AccountService" BaseType="AccountService.v1_13_1.AccountService">
<Property Name="RequireChangePasswordAction" Type="Edm.Boolean">
@@ -1841,5 +1854,50 @@
<EntityType Name="AccountService" BaseType="AccountService.v1_15_0.AccountService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AccountService.v1_16_0">
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add `TimeBasedOneTimePassword` to `BypassTypes` for multi-factor authentication configurations."/>
+
+ <EntityType Name="AccountService" BaseType="AccountService.v1_15_1.AccountService"/>
+
+ <ComplexType Name="RoleMapping" BaseType="AccountService.v1_12_0.RoleMapping">
+ <Property Name="LocalAccountTypes" Type="Collection(ManagerAccount.AccountTypes)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="The list of local services in the manager that the remote user or group is allowed to access."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain an array of the various local manager services that the remote user or group is allowed to access. This shall not include functionality for receiving events or other notifications. If this property is not supported, the value shall be assumed to be an array that contains the value `Redfish`."/>
+ </Property>
+ <Property Name="LocalOEMAccountTypes" Type="Collection(Edm.String)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="The OEM account types for the remote user or group."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain an array of the OEM account types for the remote user or group when `LocalAccountTypes` contains `OEM`."/>
+ </Property>
+ </ComplexType>
+
+ <ComplexType Name="MultiFactorAuth" BaseType="AccountService.v1_14_0.MultiFactorAuth">
+ <Property Name="TimeBasedOneTimePassword" Type="AccountService.v1_16_0.TimeBasedOneTimePassword">
+ <Annotation Term="OData.Description" String="The settings related to Time-based One-Time Password (TOTP) multi-factor authentication."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the settings related to RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication."/>
+ </Property>
+ </ComplexType>
+
+ <ComplexType Name="TimeBasedOneTimePassword">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="Various settings for Time-based One-Time Password (TOTP) multi-factor authentication."/>
+ <Annotation Term="OData.LongDescription" String="This type shall contain settings for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication."/>
+ <Property Name="Enabled" Type="Edm.Boolean">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="An indication of whether multi-factor authentication with a Time-based One-Time Password (TOTP) is enabled."/>
+ <Annotation Term="OData.LongDescription" String="This property shall indicate whether multi-factor authentication with an RFC6238-defined Time-based One-Time Password (TOTP) is enabled."/>
+ </Property>
+ <Property Name="TimeStepSeconds" Type="Edm.Int64">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="The time step, in seconds, for calculating the one-time password."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the RFC6238-defined time step, in seconds, for calculating the one-time password. If this property is not supported by the service, it shall be assumed to be `30`."/>
+ <Annotation Term="Validation.Minimum" Int="1"/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/AggregationSource_v1.xml b/redfish-core/schema/dmtf/csdl/AggregationSource_v1.xml
index 423f5ab1ce..4a58396702 100644
--- a/redfish-core/schema/dmtf/csdl/AggregationSource_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/AggregationSource_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: AggregationSource v1.4.1 -->
+<!--# Redfish Schema: AggregationSource v1.4.3 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -143,8 +143,8 @@
<Annotation Term="OData.LongDescription" String="This Redfish Specification-described type shall contain links to resources that are related to but are not contained by, or subordinate to, this resource."/>
<NavigationProperty Name="ConnectionMethod" Type="ConnectionMethod.ConnectionMethod" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
- <Annotation Term="OData.Description" String="An array of links to the connection methods used to contact this aggregation source."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain an array of links to resources of type `ConnectionMethod` that are used to connect to the aggregation source."/>
+ <Annotation Term="OData.Description" String="A link to the connection method used to contact this aggregation source."/>
+ <Annotation Term="OData.LongDescription" String="This property shall a link to a resource of type `ConnectionMethod` that represents the method used to connect to the aggregation source."/>
<Annotation Term="OData.AutoExpandReferences"/>
</NavigationProperty>
<NavigationProperty Name="ResourcesAccessed" Type="Collection(Resource.Resource)">
@@ -190,6 +190,12 @@
<EntityType Name="AggregationSource" BaseType="AggregationSource.v1_0_2.AggregationSource"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_0_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the description for `ConnectionMethod` to show it's singular."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_0_3.AggregationSource"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -208,8 +214,8 @@
<Property Name="AuthenticationKey" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Write"/>
<Annotation Term="OData.Description" String="The secret authentication key for SNMPv3."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark."/>
- <Annotation Term="Validation.Pattern" String="(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\*+$)"/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414."/>
+ <Annotation Term="Validation.Pattern" String="(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{24,96}$)|(^\*+$)"/>
</Property>
<Property Name="AuthenticationProtocol" Type="AggregationSource.v1_1_0.SNMPAuthenticationProtocols">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -219,8 +225,8 @@
<Property Name="EncryptionKey" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Write"/>
<Annotation Term="OData.Description" String="The secret authentication key for SNMPv3."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark."/>
- <Annotation Term="Validation.Pattern" String="(^[A-Za-z0-9]+$)|(^\*+$)"/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414."/>
+ <Annotation Term="Validation.Pattern" String="(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{16,64}$)|(^\*+$)"/>
</Property>
<Property Name="EncryptionProtocol" Type="AggregationSource.v1_1_0.SNMPEncryptionProtocols">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -332,6 +338,18 @@
<EntityType Name="AggregationSource" BaseType="AggregationSource.v1_1_2.AggregationSource"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_1_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the description for `ConnectionMethod` to show it's singular."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_1_3.AggregationSource"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_1_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_1_4.AggregationSource"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.3"/>
@@ -382,6 +400,18 @@
<EntityType Name="AggregationSource" BaseType="AggregationSource.v1_2_2.AggregationSource"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_2_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the description for `ConnectionMethod` to show it's singular."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_2_3.AggregationSource"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_2_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_2_4.AggregationSource"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -458,6 +488,18 @@
<EntityType Name="AggregationSource" BaseType="AggregationSource.v1_3_2.AggregationSource"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_3_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the description for `ConnectionMethod` to show it's singular."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_3_3.AggregationSource"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_3_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_3_4.AggregationSource"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -472,5 +514,17 @@
<EntityType Name="AggregationSource" BaseType="AggregationSource.v1_4_0.AggregationSource"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_4_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the description for `ConnectionMethod` to show it's singular."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_4_1.AggregationSource"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="AggregationSource.v1_4_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="AggregationSource" BaseType="AggregationSource.v1_4_2.AggregationSource"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/CXLLogicalDevice_v1.xml b/redfish-core/schema/dmtf/csdl/CXLLogicalDevice_v1.xml
index 4686e7a6de..f1a13d152d 100644
--- a/redfish-core/schema/dmtf/csdl/CXLLogicalDevice_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/CXLLogicalDevice_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: CXLLogicalDevice v1.2.0 -->
+<!--# Redfish Schema: CXLLogicalDevice v1.2.1 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -108,8 +108,8 @@
</Property>
<Property Name="MemorySizeMiB" Type="Edm.Int64" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
- <Annotation Term="OData.Description" String="The memory region size defined in this CXL logical device."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the memory region size defined in this CXL logical device in mebibytes (MiB)."/>
+ <Annotation Term="OData.Description" String="The total memory capacity currently available in this CXL logical device."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the total memory capacity currently available in this CXL logical device in mebibytes (MiB). This value shall equate to the sum of the dynamic capacity extents and the static capacity assigned to this logical device."/>
<Annotation Term="Measures.Unit" String="MiBy"/>
</Property>
<Property Name="QoSTelemetryCapabilities" Type="CXLLogicalDevice.v1_0_0.QoSTelemetryCapabilities" Nullable="false">
@@ -254,6 +254,12 @@
<EntityType Name="CXLLogicalDevice" BaseType="CXLLogicalDevice.v1_0_2.CXLLogicalDevice"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="CXLLogicalDevice.v1_0_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of `MemorySizeMiB`."/>
+ <EntityType Name="CXLLogicalDevice" BaseType="CXLLogicalDevice.v1_0_3.CXLLogicalDevice"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="CXLLogicalDevice.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -280,6 +286,12 @@
<EntityType Name="CXLLogicalDevice" BaseType="CXLLogicalDevice.v1_1_1.CXLLogicalDevice"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="CXLLogicalDevice.v1_1_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of `MemorySizeMiB`."/>
+ <EntityType Name="CXLLogicalDevice" BaseType="CXLLogicalDevice.v1_1_2.CXLLogicalDevice"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="CXLLogicalDevice.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -288,5 +300,11 @@
<EntityType Name="CXLLogicalDevice" BaseType="CXLLogicalDevice.v1_1_2.CXLLogicalDevice"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="CXLLogicalDevice.v1_2_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of `MemorySizeMiB`."/>
+ <EntityType Name="CXLLogicalDevice" BaseType="CXLLogicalDevice.v1_2_0.CXLLogicalDevice"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Certificate_v1.xml b/redfish-core/schema/dmtf/csdl/Certificate_v1.xml
index 8f60d34c2e..7058585a4b 100644
--- a/redfish-core/schema/dmtf/csdl/Certificate_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Certificate_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Certificate v1.8.2 -->
+<!--# Redfish Schema: Certificate v1.9.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -269,13 +269,13 @@
<Property Name="CertificateString" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The string for the certificate."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the certificate, and the format shall follow the requirements specified by the `CertificateType` property value. If the certificate contains any private keys, they shall be removed from the string in responses. If the service does not know the private key for the certificate and is needed to use the certificate, the client shall provide the private key as part of the string in the `POST` request."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the certificate, and the format shall follow the requirements specified by the `CertificateType` property value. If the certificate contains any private keys, they shall be removed from the string in responses. If the service does not know the private key for the certificate and is needed to use the certificate, the client shall provide the private key as part of the string in the `POST` request. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
<Annotation Term="Redfish.RequiredOnCreate"/>
</Property>
<Property Name="CertificateType" Type="Certificate.CertificateType">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The format of the certificate."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the format type for the certificate."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the format type for the certificate. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
<Annotation Term="Redfish.RequiredOnCreate"/>
</Property>
<Property Name="Issuer" Type="Certificate.v1_0_0.Identifier" Nullable="false">
@@ -408,6 +408,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_0_6.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_0_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_0_7.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.1"/>
@@ -488,6 +494,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_1_5.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_1_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_1_6.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.1"/>
@@ -537,6 +549,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_2_5.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_2_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_2_6.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -585,6 +603,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_3_2.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_3_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_3_3.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -681,6 +705,17 @@
</Collection>
</Annotation>
</Member>
+ <Member Name="EK">
+ <Annotation Term="OData.Description" String="This certificate is an EK certificate like those associated with TCG TPMs."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_9_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
</EnumType>
</Schema>
@@ -702,6 +737,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_4_2.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_4_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_4_3.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.3"/>
@@ -743,6 +784,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_5_2.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_5_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_5_3.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -785,6 +832,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_6_1.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_6_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_6_2.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -812,6 +865,12 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_7_1.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_7_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_7_2.Certificate"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -832,5 +891,19 @@
<EntityType Name="Certificate" BaseType="Certificate.v1_8_1.Certificate"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_8_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Certificate" BaseType="Certificate.v1_8_2.Certificate"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Certificate.v1_9_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+ <Annotation Term="OData.Description" String="This version was created to add the value `EK` to `CertificateUsageType` to support TCG TPM certificates."/>
+
+ <EntityType Name="Certificate" BaseType="Certificate.v1_8_3.Certificate"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Chassis_v1.xml b/redfish-core/schema/dmtf/csdl/Chassis_v1.xml
index a31935422b..a8a64efc8c 100644
--- a/redfish-core/schema/dmtf/csdl/Chassis_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Chassis_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Chassis v1.25.1 -->
+<!--# Redfish Schema: Chassis v1.25.2 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -2012,7 +2012,7 @@
<NavigationProperty Name="EnvironmentMetrics" Type="EnvironmentMetrics.EnvironmentMetrics" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The link to the environment metrics for this chassis."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain a link to a resource of type `EnvironmentMetrics` that specifies the environment metrics for this chassis."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain a link to a resource of type `EnvironmentMetrics` that specifies the environment metrics for this chassis, all containing chassis, and devices contained by any of these chassis instances. When determining power and energy readings, care should be taken to ensure any reported values do not overlap or result in double-counting."/>
<Annotation Term="OData.AutoExpandReferences"/>
</NavigationProperty>
<NavigationProperty Name="Certificates" Type="CertificateCollection.CertificateCollection" ContainsTarget="true" Nullable="false">
@@ -2073,6 +2073,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_15_5.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_15_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_15_6.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -2117,6 +2123,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_16_4.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_16_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_16_5.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_17_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -2170,6 +2182,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_17_4.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_17_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_17_5.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_18_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.3"/>
@@ -2228,6 +2246,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_18_4.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_18_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_18_5.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_19_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -2266,6 +2290,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_19_4.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_19_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_19_5.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_20_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -2360,6 +2390,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_20_3.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_20_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_20_4.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_21_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -2413,6 +2449,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_21_3.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_21_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_21_4.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_22_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -2446,6 +2488,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_22_2.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_22_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_22_3.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_23_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -2481,6 +2529,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_23_1.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_23_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_23_2.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_24_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -2560,6 +2614,12 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_24_1.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_24_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_24_2.Chassis"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_25_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -2586,5 +2646,11 @@
<EntityType Name="Chassis" BaseType="Chassis.v1_25_0.Chassis"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Chassis.v1_25_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the scope of the metrics in the subordinate `EnvironmentMetrics` resource."/>
+ <EntityType Name="Chassis" BaseType="Chassis.v1_25_1.Chassis"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Circuit_v1.xml b/redfish-core/schema/dmtf/csdl/Circuit_v1.xml
index ad0a23fbf6..953b2097cd 100644
--- a/redfish-core/schema/dmtf/csdl/Circuit_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Circuit_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Circuit v1.8.0 -->
+<!--# Redfish Schema: Circuit v1.8.1 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -156,28 +156,28 @@
<EnumType Name="PhaseWiringType">
<Member Name="OnePhase3Wire">
- <Annotation Term="OData.Description" String="Single-phase / 3-Wire (Line1, Neutral, Protective Earth)."/>
- <Annotation Term="OData.LongDescription" String="This value shall represent a Single-phase / 3-Wire (Line1, Neutral, Protective Earth) wiring."/>
+ <Annotation Term="OData.Description" String="Single-phase / 3-wire (Line1, Neutral, Protective Earth)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall represent a single-phase / 3-wire (Line1, Neutral, Protective Earth) wiring."/>
</Member>
<Member Name="TwoPhase3Wire">
- <Annotation Term="OData.Description" String="Two-phase / 3-Wire (Line1, Line2, Protective Earth)."/>
- <Annotation Term="OData.LongDescription" String="This value shall represent a Two-phase / 3-Wire (Line1, Line2, Protective Earth) wiring."/>
+ <Annotation Term="OData.Description" String="Two-phase / 3-wire (Line1, Line2, Protective Earth)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall represent a two-phase / 3-wire (Line1, Line2, Protective Earth) wiring."/>
</Member>
<Member Name="OneOrTwoPhase3Wire">
- <Annotation Term="OData.Description" String="Single or Two-Phase / 3-Wire (Line1, Line2 or Neutral, Protective Earth)."/>
- <Annotation Term="OData.LongDescription" String="This value shall represent a Single or Two-Phase / 3-Wire (Line1, Line2 or Neutral, Protective Earth) wiring. This value shall be used when both phase configurations are supported. This is most common where detachable cordsets are used."/>
+ <Annotation Term="OData.Description" String="Single or two-phase / 3-wire (Line1, Line2 or Neutral, Protective Earth)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall represent a single or two-phase / 3-wire (Line1, Line2 or Neutral, Protective Earth) wiring. This value shall be used when both phase configurations are supported. This is most common where detachable cordsets are used. If poly-phase properties such as `PolyPhaseVoltage` are supported, the service should populate the measurements as if the circuit is wired as Line1, Neutral, and Protective Earth."/>
</Member>
<Member Name="TwoPhase4Wire">
- <Annotation Term="OData.Description" String="Two-phase / 4-Wire (Line1, Line2, Neutral, Protective Earth)."/>
- <Annotation Term="OData.LongDescription" String="This value shall represent a Two-phase / 4-Wire (Line1, Line2, Neutral, Protective Earth) wiring."/>
+ <Annotation Term="OData.Description" String="Two-phase / 4-wire (Line1, Line2, Neutral, Protective Earth)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall represent a two-phase / 4-wire (Line1, Line2, Neutral, Protective Earth) wiring."/>
</Member>
<Member Name="ThreePhase4Wire">
- <Annotation Term="OData.Description" String="Three-phase / 4-Wire (Line1, Line2, Line3, Protective Earth)."/>
- <Annotation Term="OData.LongDescription" String="This value shall represent a Three-phase / 4-Wire (Line1, Line2, Line3, Protective Earth) wiring."/>
+ <Annotation Term="OData.Description" String="Three-phase / 4-wire (Line1, Line2, Line3, Protective Earth)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall represent a three-phase / 4-wire (Line1, Line2, Line3, Protective Earth) wiring."/>
</Member>
<Member Name="ThreePhase5Wire">
- <Annotation Term="OData.Description" String="Three-phase / 5-Wire (Line1, Line2, Line3, Neutral, Protective Earth)."/>
- <Annotation Term="OData.LongDescription" String="This value shall represent a Three-phase / 5-Wire (Line1, Line2, Line3, Neutral, Protective Earth) wiring."/>
+ <Annotation Term="OData.Description" String="Three-phase / 5-wire (Line1, Line2, Line3, Neutral, Protective Earth)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall represent a three-phase / 5-wire (Line1, Line2, Line3, Neutral, Protective Earth) wiring."/>
</Member>
</EnumType>
@@ -419,7 +419,7 @@
</Member>
<Member Name="California_CS8265">
<Annotation Term="OData.Description" String="California Standard CS8265 (Single-phase 250V; 50A; 2P3W)."/>
- <Annotation Term="OData.LongDescription" String="This value shall represent a plug that matches the 'California Standard' CS8265 style plug (Three-phase 250V; 50A; 3P4W)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall represent a plug that matches the 'California Standard' CS8265 style plug (Single-phase 250V; 50A; 2P3W)."/>
</Member>
<Member Name="California_CS8365">
<Annotation Term="OData.Description" String="California Standard CS8365 (Three-phase 250V; 50A; 3P4W)."/>
@@ -583,13 +583,13 @@
</Property>
<NavigationProperty Name="Voltage" Type="Sensor.Sensor">
<Annotation Term="Redfish.ExcerptCopy" String="Voltage"/>
- <Annotation Term="OData.Description" String="The voltage (V) for this single-phase circuit."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the voltage, in volt units, for this single-phase circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not appear in resource instances representing poly-phase circuits."/>
+ <Annotation Term="OData.Description" String="The voltage (V) for this circuit."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the voltage, in volt units, for this circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."/>
</NavigationProperty>
<NavigationProperty Name="CurrentAmps" Type="Sensor.Sensor">
<Annotation Term="Redfish.ExcerptCopy" String="Current"/>
- <Annotation Term="OData.Description" String="The current (A) for this single-phase circuit."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the current, in ampere units, for this single-phase circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not appear in resource instances representing poly-phase circuits."/>
+ <Annotation Term="OData.Description" String="The current (A) for this circuit."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the current, in ampere units, for this circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."/>
</NavigationProperty>
<NavigationProperty Name="PowerWatts" Type="Sensor.Sensor">
<Annotation Term="Redfish.ExcerptCopy" String="Power"/>
@@ -608,19 +608,19 @@
</NavigationProperty>
<Property Name="PolyPhaseVoltage" Type="Circuit.v1_0_0.VoltageSensors">
<Annotation Term="OData.Description" String="The voltage readings for this circuit."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the voltage sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For poly-phase circuits, this property should contain multiple voltage sensor readings used to fully describe the circuit."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the voltage sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For other circuits, this property should contain multiple voltage sensor readings used to fully describe the circuit."/>
</Property>
<Property Name="PolyPhaseCurrentAmps" Type="Circuit.v1_0_0.CurrentSensors">
<Annotation Term="OData.Description" String="The current readings for this circuit."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the current sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For poly-phase circuits, this property should contain multiple current sensor readings used to fully describe the circuit."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the current sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For other circuits, this property should contain multiple current sensor readings used to fully describe the circuit."/>
</Property>
<Property Name="PolyPhasePowerWatts" Type="Circuit.v1_0_0.PowerSensors">
<Annotation Term="OData.Description" String="The power readings for this circuit."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the power sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the power sensor referenced in the `PowerWatts` property, if present. For poly-phase circuits, this property should contain multiple power sensor readings used to fully describe the circuit."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the power sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the power sensor referenced in the `PowerWatts` property, if present. For other circuits, this property should contain multiple power sensor readings used to fully describe the circuit."/>
</Property>
<Property Name="PolyPhaseEnergykWh" Type="Circuit.v1_0_0.EnergySensors">
<Annotation Term="OData.Description" String="The energy readings for this circuit."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the energy sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the energy sensor referenced in the `EnergykWh` property, if present. For poly-phase circuits, this property should contain multiple energy sensor readings used to fully describe the circuit."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the energy sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the energy sensor referenced in the `EnergykWh` property, if present. For other circuits, this property should contain multiple energy sensor readings used to fully describe the circuit."/>
</Property>
<Property Name="Links" Type="Circuit.v1_0_0.Links" Nullable="false">
<Annotation Term="OData.Description" String="The links to other resources that are related to this resource."/>
@@ -865,6 +865,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_0_4.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_0_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_0_5.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -903,6 +909,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_1_3.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_1_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_1_4.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -929,6 +941,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_2_2.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_2_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_2_3.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -960,6 +978,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_3_2.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_3_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_3_3.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.3"/>
@@ -1028,6 +1052,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_4_2.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_4_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_4_3.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -1074,6 +1104,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_5_1.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_5_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_5_2.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -1094,6 +1130,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_6_1.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_6_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_6_2.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -1114,6 +1156,12 @@
<EntityType Name="Circuit" BaseType="Circuit.v1_7_1.Circuit"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_7_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_7_2.Circuit"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -1127,5 +1175,11 @@
</EntityType>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Circuit.v1_8_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Circuit" BaseType="Circuit.v1_8_0.Circuit"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/ComponentIntegrity_v1.xml b/redfish-core/schema/dmtf/csdl/ComponentIntegrity_v1.xml
index f8a96d4335..14d7068c76 100644
--- a/redfish-core/schema/dmtf/csdl/ComponentIntegrity_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/ComponentIntegrity_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: ComponentIntegrity v1.2.3 -->
+<!--# Redfish Schema: ComponentIntegrity v1.3.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -194,6 +194,30 @@
<Annotation Term="OData.Description" String="Trusted Platform Module (TPM)."/>
<Annotation Term="OData.LongDescription" String="This value shall indicate the integrity information is related to a Trusted Platform Module (TPM) as defined by the Trusted Computing Group (TCG)."/>
</Member>
+ <Member Name="TCM">
+ <Annotation Term="OData.Description" String="Trusted Cryptography Module (TCM)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the integrity information is related to a Trusted Cryptography Module (TCM) as defined by the China TCM Union (TCMU)."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_3_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
+ <Member Name="TPCM">
+ <Annotation Term="OData.Description" String="Trusted Platform Control Module (TPCM)."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the integrity information is related to a Trusted Platform Control Module (TPCM) as defined by the Zhongguancun Trusted Computing Industry Alliance (ZTCIA)."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_3_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
<Member Name="OEM">
<Annotation Term="OData.Description" String="OEM-specific."/>
<Annotation Term="OData.LongDescription" String="This value shall indicate the integrity information is OEM-specific and the OEM section may include additional information."/>
@@ -659,5 +683,13 @@
<EntityType Name="ComponentIntegrity" BaseType="ComponentIntegrity.v1_2_2.ComponentIntegrity"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComponentIntegrity.v1_3_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+ <Annotation Term="OData.Description" String="This version was created to add `TCM` and `TPCM` to `ComponentIntegrityType`."/>
+
+ <EntityType Name="ComponentIntegrity" BaseType="ComponentIntegrity.v1_2_3.ComponentIntegrity"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/ComputerSystem_v1.xml b/redfish-core/schema/dmtf/csdl/ComputerSystem_v1.xml
index c8431bd715..ec9bd25095 100644
--- a/redfish-core/schema/dmtf/csdl/ComputerSystem_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/ComputerSystem_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: ComputerSystem v1.22.1 -->
+<!--# Redfish Schema: ComputerSystem v1.23.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -399,7 +399,7 @@
<Property Name="UUID" Type="Resource.UUID">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The UUID for this system."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the universally unique identifier number for this system. RFC4122 describes methods to create this value. The value should be considered to be opaque. Client software should only treat the overall value as a UUID and should not interpret any subfields within the UUID. If the system supports SMBIOS, the property value should follow the SMBIOS 2.6 and later recommendation for converting the SMBIOS 16-byte UUID structure into the Redfish canonical `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` string format, so that the property value matches the byte order presented by current OS APIs, such as WMI and dmidecode."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the universally unique identifier number for this system. RFC4122 describes methods to create this value. The value should be considered to be opaque. Client software should only treat the overall value as a UUID and should not interpret any subfields within the UUID. If the system supports SMBIOS, the property value should follow the SMBIOS 2.6 and later recommendation for converting the SMBIOS 16-byte UUID structure into the Redfish canonical `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` string format, so that the property value matches the byte order presented by current OS APIs, such as WMI and dmidecode. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
<Property Name="HostName" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -827,6 +827,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_0_21.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_0_23">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_0_22.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_0_24">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_0_23.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.1"/>
@@ -1068,6 +1080,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_1_19.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_1_21">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_1_20.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_1_22">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_1_21.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.2"/>
@@ -1299,6 +1323,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_2_18.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_2_20">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_2_19.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_2_21">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_2_20.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.3"/>
@@ -1451,6 +1487,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_3_17.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_3_19">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_3_18.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_3_20">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_3_19.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.1"/>
@@ -1579,6 +1627,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_4_16.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_4_18">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_4_17.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_4_19">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_4_18.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.3"/>
@@ -1813,6 +1873,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_5_15.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_5_17">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_5_16.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_5_18">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_5_17.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.3"/>
@@ -1946,6 +2018,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_6_13.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_6_15">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_6_14.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_6_16">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_6_15.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.1"/>
@@ -2048,6 +2132,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_7_12.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_7_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_7_13.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_7_15">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_7_14.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.2"/>
@@ -2135,6 +2231,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_8_11.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_8_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_8_12.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_8_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_8_13.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.3"/>
@@ -2223,6 +2331,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_9_11.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_9_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_9_12.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_9_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_9_13.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -2304,6 +2424,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_10_10.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_10_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_10_11.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_10_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_10_12.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.1"/>
@@ -2406,10 +2538,21 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_11_9.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_11_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_11_10.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_11_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_11_11.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.2"/>
- <Annotation Term="OData.Description" String="This version was created to add LastResetTime."/>
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_11_1.ComputerSystem">
<Property Name="LastResetTime" Type="Edm.DateTimeOffset" Nullable="false">
@@ -2474,6 +2617,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_12_8.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_12_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_12_9.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_12_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_12_10.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -2763,6 +2918,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_13_7.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_13_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_13_8.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_13_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_13_9.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -2860,6 +3027,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_14_6.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_14_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_14_7.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_14_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_14_8.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_15_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -3000,6 +3179,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_15_5.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_15_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_15_6.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_15_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_15_7.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -3140,6 +3331,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_16_6.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_16_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_16_7.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_16_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_16_8.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_17_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -3193,6 +3396,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_17_5.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_17_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_17_6.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_17_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_17_7.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_18_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -3269,6 +3484,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_18_4.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_18_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_18_5.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_18_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_18_6.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_19_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -3316,6 +3543,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_19_4.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_19_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_19_5.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_19_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_19_6.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_20_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -3369,6 +3608,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_20_3.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_20_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_20_4.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_20_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_20_5.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_21_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -3442,6 +3693,18 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_21_1.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_21_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_21_2.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_21_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_21_3.ComputerSystem"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_22_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -3456,5 +3719,73 @@
<EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_22_0.ComputerSystem"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_22_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_22_1.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_22_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_22_2.ComputerSystem"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ComputerSystem.v1_23_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="ComputerSystem" BaseType="ComputerSystem.v1_22_3.ComputerSystem">
+ <Property Name="LastResetCause" Type="ComputerSystem.v1_23_0.LastResetCauses" Nullable="false">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The last reset cause of the system."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the cause when the system last came out of a reset or was rebooted."/>
+ </Property>
+ </EntityType>
+
+ <EnumType Name="LastResetCauses">
+ <Member Name="PowerButtonPress">
+ <Annotation Term="OData.Description" String="System start or restart via a power button press."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart was due to a power button press."/>
+ </Member>
+ <Member Name="ManagementCommand">
+ <Annotation Term="OData.Description" String="System start or restart via an external command to the management controller or BMC."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart was due to an external command to the management controller or BMC. Examples include the Redfish `Reset` action for the `ComputerSystem` resource or the IPMI 'Chassis Control' command."/>
+ </Member>
+ <Member Name="PowerRestorePolicy">
+ <Annotation Term="OData.Description" String="System start or restart due to the power restore policy."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system automatically powered-up on AC being applied due the `PowerRestorePolicy` property containing `AlwaysOn` or `LastState`."/>
+ </Member>
+ <Member Name="RTCWakeup">
+ <Annotation Term="OData.Description" String="System power-up via an RTC (system real time clock) wakeup."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system powered-up via an RTC (system real time clock) wakeup."/>
+ </Member>
+ <Member Name="WatchdogExpiration">
+ <Annotation Term="OData.Description" String="System start or restart caused by a watchdog expiration."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart was caused by a watchdog expiration."/>
+ </Member>
+ <Member Name="OSSoftRestart">
+ <Annotation Term="OData.Description" String="System start or restart via an OS soft restart."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart was due to an OS soft restart. Examples include 'CTRL-ALT-DEL', 'init 6', or 'reboot'."/>
+ </Member>
+ <Member Name="SystemCrash">
+ <Annotation Term="OData.Description" String="System start or restart caused by a system crash."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart was caused by a system crash. Examples include an OS panic, hardware fault, or firmware fault."/>
+ </Member>
+ <Member Name="ThermalEvent">
+ <Annotation Term="OData.Description" String="System start or restart caused by a thermal event triggering a system shutdown."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart was caused by a thermal event triggering a system shutdown."/>
+ </Member>
+ <Member Name="PowerEvent">
+ <Annotation Term="OData.Description" String="System start or restart caused by a power event triggering a system shutdown."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart was caused by a power event triggering a system shutdown."/>
+ </Member>
+ <Member Name="Unknown">
+ <Annotation Term="OData.Description" String="System start or restart detected, but the cause is unknown."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate the system start or restart cause is unknown."/>
+ </Member>
+ </EnumType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Control_v1.xml b/redfish-core/schema/dmtf/csdl/Control_v1.xml
index 9aa881836d..0d98d48bc3 100644
--- a/redfish-core/schema/dmtf/csdl/Control_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Control_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Control v1.5.1 -->
+<!--# Redfish Schema: Control v1.5.2 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -142,8 +142,8 @@
</Property>
<Property Name="SetPointUnits" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
- <Annotation Term="OData.Description" String="The units of the set point."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the units of the control's set point."/>
+ <Annotation Term="OData.Description" String="The units of the set point and related properties in UCUM c/s format."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the units of the control's set point and related properties. The value shall follow the case-sensitive symbol format defined by the Unified Code for Units of Measure (UCUM), as specified by the 'Units of measure annotation' clause of the Redfish Specification."/>
</Property>
<Property Name="DeadBand" Type="Edm.Decimal">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -449,6 +449,12 @@
<EntityType Name="Control" BaseType="Control.v1_0_2.Control"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_0_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `SetPointUnits`."/>
+ <EntityType Name="Control" BaseType="Control.v1_0_3.Control"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -469,6 +475,12 @@
<EntityType Name="Control" BaseType="Control.v1_1_1.Control"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_1_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `SetPointUnits`."/>
+ <EntityType Name="Control" BaseType="Control.v1_1_2.Control"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -489,6 +501,12 @@
<EntityType Name="Control" BaseType="Control.v1_2_1.Control"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_2_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `SetPointUnits`."/>
+ <EntityType Name="Control" BaseType="Control.v1_2_2.Control"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -516,6 +534,12 @@
<EntityType Name="Control" BaseType="Control.v1_3_1.Control"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_3_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `SetPointUnits`."/>
+ <EntityType Name="Control" BaseType="Control.v1_3_2.Control"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -542,6 +566,12 @@
<EntityType Name="Control" BaseType="Control.v1_4_1.Control"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_4_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `SetPointUnits`."/>
+ <EntityType Name="Control" BaseType="Control.v1_4_2.Control"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -556,5 +586,11 @@
<EntityType Name="Control" BaseType="Control.v1_5_0.Control"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Control.v1_5_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `SetPointUnits`."/>
+ <EntityType Name="Control" BaseType="Control.v1_5_1.Control"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Drive_v1.xml b/redfish-core/schema/dmtf/csdl/Drive_v1.xml
index b5dbd9b201..c5770568ae 100644
--- a/redfish-core/schema/dmtf/csdl/Drive_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Drive_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Drive v1.19.0 -->
+<!--# Redfish Schema: Drive v1.20.1 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -37,7 +37,7 @@
<edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Chassis_v1.xml">
<edmx:Include Namespace="Chassis"/>
</edmx:Reference>
- <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Assembly_v1.xml">
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Assembly_v1.xml">
<edmx:Include Namespace="Assembly"/>
</edmx:Reference>
<edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Protocol_v1.xml">
@@ -568,6 +568,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_0_17.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_0_19">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_0_18.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.2"/>
@@ -724,6 +730,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_1_16.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_1_18">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_1_17.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.1"/>
@@ -830,6 +842,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_2_14.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_2_16">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_2_15.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.3"/>
@@ -928,6 +946,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_3_13.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_3_15">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_3_14.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.1"/>
@@ -1024,6 +1048,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_4_13.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_4_15">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_4_14.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.2"/>
@@ -1124,6 +1154,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_5_12.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_5_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_5_13.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.1"/>
@@ -1205,6 +1241,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_6_10.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_6_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_6_11.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.2"/>
@@ -1279,6 +1321,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_7_9.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_7_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_7_10.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.3"/>
@@ -1355,6 +1403,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_8_9.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_8_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_8_10.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -1428,6 +1482,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_9_9.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_9_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_9_10.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.2"/>
@@ -1489,6 +1549,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_10_7.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_10_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_10_8.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -1551,6 +1617,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_11_7.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_11_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_11_8.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -1626,6 +1698,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_12_6.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_12_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_12_7.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1672,6 +1750,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_13_4.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_13_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_13_5.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -1713,6 +1797,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_14_3.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_14_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_14_4.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_15_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -1760,6 +1850,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_15_3.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_15_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_15_4.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -1913,6 +2009,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_16_3.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_16_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_16_4.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_17_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -1958,6 +2060,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_17_2.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_17_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_17_3.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_18_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -1972,6 +2080,12 @@
<EntityType Name="Drive" BaseType="Drive.v1_18_0.Drive"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_18_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_18_1.Drive"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_19_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -1984,15 +2098,15 @@
</Property>
<Property Name="ConfigurationLock" Type="Drive.v1_19_0.ConfigurationLock">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
- <Annotation Term="OData.Description" String="Indicates whether in-band configuration requests to the drive are locked."/>
+ <Annotation Term="OData.Description" String="Indicates whether in-band configuration requests to the drive are locked. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock."/>
<Annotation Term="OData.LongDescription" String="This property shall indicate whether configuration requests to the drive are locked. Services shall reject modification requests that contain the value `Partial`."/>
</Property>
</EntityType>
<EnumType Name="ConfigurationLock">
<Member Name="Enabled">
- <Annotation Term="OData.Description" String="In-band configuration requests are locked. Configuration requests include applying firmware, updating security keys, and other hardware settings. It does not include managing the volumes or data on the drive."/>
- <Annotation Term="OData.LongDescription" String="This value shall indicate in-band configuration requests are locked."/>
+ <Annotation Term="OData.Description" String="In-band configuration requests are locked as specified by `TargetConfigurationLockLevel`."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate in-band configuration requests are locked as specified by `TargetConfigurationLockLevel`."/>
</Member>
<Member Name="Disabled">
<Annotation Term="OData.Description" String="In-band configuration requests are not locked."/>
@@ -2005,5 +2119,107 @@
</EnumType>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_19_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions for `ConfigurationLock` to align with the new `TargetConfigurationLockLevel` property."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_19_0.Drive"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_19_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_19_1.Drive"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_20_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.2"/>
+
+ <EntityType Name="Drive" BaseType="Drive.v1_19_1.Drive">
+ <Property Name="BlockSecurityIDEnabled" Type="Edm.Boolean">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="Indicates if establishment of a TCG-defined security ID (SID) on the drive is blocked."/>
+ <Annotation Term="OData.LongDescription" String="This property shall indicate if establishment of a TCG-defined security ID (SID) on the drive is blocked. The value `true` shall indicate the TCG-defined 'Block SID' command is sent to the drive during each drive boot sequence."/>
+ </Property>
+ <Property Name="TargetConfigurationLockLevel" Type="Drive.v1_20_0.TargetConfigurationLockLevel">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="Indicates the target configuration lock level for the drive based upon the state of the `ConfigurationLock` property. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the target configuration lock level for the drive. For NVMe drives, services shall implement the locking requirements specified by SNIA's Swordfish NVMe Model Overview and Mapping Guide."/>
+ </Property>
+ <Property Name="NVMe" Type="Drive.v1_20_0.NVMe">
+ <Annotation Term="OData.Description" String="NVMe properties for this drive."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain NVMe-specific properties of this drive."/>
+ </Property>
+ </EntityType>
+
+ <EnumType Name="TargetConfigurationLockLevel">
+ <Member Name="Baseline">
+ <Annotation Term="OData.Description" String="The standard configuration lock level, corresponding to applying firmware, updating security keys, and modifying other hardware settings. It does not include managing the volumes or data on the drive."/>
+ </Member>
+ </EnumType>
+
+ <EnumType Name="ConfigLockOptions">
+ <Member Name="Unlocked">
+ <Annotation Term="OData.Description" String="The command is supported, able to be locked, and is currently unlocked."/>
+ </Member>
+ <Member Name="Locked">
+ <Annotation Term="OData.Description" String="The command is supported and is currently locked."/>
+ </Member>
+ <Member Name="LockdownUnsupported">
+ <Annotation Term="OData.Description" String="The command is supported but is not able to be locked."/>
+ </Member>
+ <Member Name="CommandUnsupported">
+ <Annotation Term="OData.Description" String="The command is not supported, therefore lockdown does not apply."/>
+ </Member>
+ </EnumType>
+
+ <ComplexType Name="NVMe">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="NVMe properties for a drive."/>
+ <Annotation Term="OData.LongDescription" String="This type shall contain NVMe-specific properties of a drive."/>
+ <Property Name="ConfigurationLockState" Type="Drive.v1_20_0.NVMeConfigurationLockState">
+ <Annotation Term="OData.Description" String="The configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state."/>
+ </Property>
+ </ComplexType>
+
+ <ComplexType Name="NVMeConfigurationLockState">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="The configurable features that are able to be locked on an NVMe subsystem and their current lock state."/>
+ <Annotation Term="OData.LongDescription" String="This type shall contain the configurable features that are able to be locked on an NVMe subsystem and their current lock state."/>
+ <Property Name="FirmwareCommit" Type="Drive.v1_20_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Firmware Commit command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Firmware Commit command."/>
+ </Property>
+ <Property Name="Lockdown" Type="Drive.v1_20_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Lockdown command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Lockdown command."/>
+ </Property>
+ <Property Name="SecuritySend" Type="Drive.v1_20_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Security Send command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Security Send command."/>
+ </Property>
+ <Property Name="FirmwareImageDownload" Type="Drive.v1_20_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Firmware Image Download command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Firmware Image Download command."/>
+ </Property>
+ <Property Name="VPDWrite" Type="Drive.v1_20_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-MI-defined VPD Write command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-MI-defined VPD Write command."/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Drive.v1_20_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Drive" BaseType="Drive.v1_20_0.Drive"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/EthernetInterface_v1.xml b/redfish-core/schema/dmtf/csdl/EthernetInterface_v1.xml
index 5a67a25a63..706416e0d3 100644
--- a/redfish-core/schema/dmtf/csdl/EthernetInterface_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/EthernetInterface_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: EthernetInterface v1.12.1 -->
+<!--# Redfish Schema: EthernetInterface v1.12.2 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -148,7 +148,7 @@
<Property Name="HostName" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
<Annotation Term="OData.Description" String="The DNS host name, without any domain information."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the DNS host name for this interface. Modifying this property may modify the `HostName` in one or more `EthernetInterface` resources that belong to the same system, manager, or other device. If this interface is subordinate to a `ComputerSystem` resource, modifying this property may modify the `HostName` of the `ComputerSystem` resource that contains this interface. If this interface is subordinate to a `Manager` resource, modifying this property may modify the `HostName` of the `ManagerNetworkProtocol` resource of the `Manager` resource that contains this interface."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the DNS host name for this interface. Modifying this property may modify the `HostName` in one or more `EthernetInterface` resources that belong to the same system, manager, or other device. If this interface is subordinate to a `ComputerSystem` resource, modifying this property may modify the `HostName` of the `ComputerSystem` resource that contains this interface. If this interface is subordinate to a `Manager` resource, modifying this property may modify the `HostName` of the `ManagerNetworkProtocol` resource of the `Manager` resource that contains this interface. Services should ignore this property in modification requests if `FQDN` is also provided in the same request."/>
</Property>
<Property Name="FQDN" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -329,6 +329,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_0_15.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_0_17">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_0_16.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.2"/>
@@ -454,6 +460,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_1_13.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_1_15">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_1_14.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.3"/>
@@ -548,6 +560,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_2_12.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_2_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_2_13.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.1"/>
@@ -657,6 +675,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_3_11.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_3_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_3_12.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.3"/>
@@ -884,6 +908,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_4_10.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_4_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_4_11.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.1"/>
@@ -968,6 +998,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_5_8.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_5_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_5_9.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.1"/>
@@ -1052,6 +1088,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_6_6.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_6_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_6_7.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1087,6 +1129,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_7_2.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_7_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_7_3.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1113,6 +1161,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_8_2.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_8_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_8_3.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -1187,6 +1241,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_9_2.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_9_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_9_3.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -1215,6 +1275,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_10_1.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_10_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_10_2.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -1259,6 +1325,12 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_11_1.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_11_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_11_2.EthernetInterface"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -1278,5 +1350,11 @@
<EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_12_0.EthernetInterface"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EthernetInterface.v1_12_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to recommend ignoring `HostName` in modification requests if `FQDN` is also in the same modification request."/>
+ <EntityType Name="EthernetInterface" BaseType="EthernetInterface.v1_12_1.EthernetInterface"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/EventDestination_v1.xml b/redfish-core/schema/dmtf/csdl/EventDestination_v1.xml
index ecdcdad5c4..f31bdb06b0 100644
--- a/redfish-core/schema/dmtf/csdl/EventDestination_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/EventDestination_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: EventDestination v1.14.1 -->
+<!--# Redfish Schema: EventDestination v1.15.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -959,8 +959,8 @@
<Property Name="AuthenticationKey" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Write"/>
<Annotation Term="OData.Description" String="The secret authentication key for SNMPv3."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark."/>
- <Annotation Term="Validation.Pattern" String="(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\*+$)"/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414."/>
+ <Annotation Term="Validation.Pattern" String="(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{24,96}$)|(^\*+$)"/>
</Property>
<Property Name="AuthenticationProtocol" Type="EventDestination.v1_7_0.SNMPAuthenticationProtocols">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -970,8 +970,8 @@
<Property Name="EncryptionKey" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Write"/>
<Annotation Term="OData.Description" String="The secret authentication key for SNMPv3."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark."/>
- <Annotation Term="Validation.Pattern" String="(^[A-Za-z0-9]+$)|(^\*+$)"/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414."/>
+ <Annotation Term="Validation.Pattern" String="(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{16,64}$)|(^\*+$)"/>
</Property>
<Property Name="EncryptionProtocol" Type="EventDestination.v1_7_0.SNMPEncryptionProtocols">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -1141,6 +1141,12 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_7_8.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_7_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_7_9.EventDestination"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.1"/>
@@ -1208,6 +1214,12 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_8_8.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_8_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_8_9.EventDestination"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -1426,6 +1438,12 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_9_9.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_9_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_9_10.EventDestination"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="OData.Description" String="This version was created to add additional SNMP authentication protocols and to provide better description for the authentication and encryption keys. It also added `RetryForeverWithBackoff` to `DeliveryRetryPolicy` and long description details to the `DeliveryRetryPolicy` values."/>
@@ -1501,6 +1519,12 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_10_8.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_10_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_10_9.EventDestination"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1569,6 +1593,12 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_11_6.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_11_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_11_7.EventDestination"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -1618,6 +1648,12 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_12_4.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_12_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_12_5.EventDestination"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -1656,6 +1692,12 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_13_3.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_13_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_13_4.EventDestination"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -1670,5 +1712,25 @@
<EntityType Name="EventDestination" BaseType="EventDestination.v1_14_0.EventDestination"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_14_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` property."/>
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_14_1.EventDestination"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="EventDestination.v1_15_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="EventDestination" BaseType="EventDestination.v1_14_2.EventDestination">
+ <Property Name="BackupDestinations" Type="Collection(Edm.String)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="The backup destination URIs for this event receiver. Events are sent to these URIs, in array order, when the destination URI is unreachable or returns an error."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain an array of URIs to destination where events are sent if the event receiver specified by `Destination` is unreachable or returns an error. Events are sent to each of the backup destinations, in array order, until a destination has been reached. An empty array shall indicate that the service supports backup event receivers, but none have been specified by the user."/>
+ <Annotation Term="OData.IsURL"/>
+ </Property>
+ </EntityType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Event_v1.xml b/redfish-core/schema/dmtf/csdl/Event_v1.xml
index 4e38140770..8ffc01ad0c 100644
--- a/redfish-core/schema/dmtf/csdl/Event_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Event_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Event v1.10.1 -->
+<!--# Redfish Schema: Event v1.11.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -977,5 +977,25 @@
<EntityType Name="EventRecord" BaseType="Event.v1_10_0.EventRecord"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Event.v1_11_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="Event" BaseType="Event.v1_10_1.Event"/>
+
+ <EntityType Name="EventRecord" BaseType="Event.v1_10_1.EventRecord">
+ <Property Name="Username" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The username of the account associated with the event record."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the username of the account associated with the event record. This should be used for events that result from a user action."/>
+ </Property>
+ <Property Name="UserAuthenticationSource" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The source of authentication for the username property associated with the event record."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the URL to the authentication service that is associated with the username property. This should be used for events that result from a user action."/>
+ </Property>
+ </EntityType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/ExternalAccountProvider_v1.xml b/redfish-core/schema/dmtf/csdl/ExternalAccountProvider_v1.xml
index 9142449a1b..ee3ba0afda 100644
--- a/redfish-core/schema/dmtf/csdl/ExternalAccountProvider_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/ExternalAccountProvider_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: ExternalAccountProvider v1.7.2 -->
+<!--# Redfish Schema: ExternalAccountProvider v1.8.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -31,6 +31,9 @@
<edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/AccountService_v1.xml">
<edmx:Include Namespace="AccountService"/>
</edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerAccount_v1.xml">
+ <edmx:Include Namespace="ManagerAccount"/>
+ </edmx:Reference>
<edmx:DataServices>
@@ -735,5 +738,25 @@
<EntityType Name="ExternalAccountProvider" BaseType="ExternalAccountProvider.v1_7_1.ExternalAccountProvider"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ExternalAccountProvider.v1_8_0">
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+
+ <EntityType Name="ExternalAccountProvider" BaseType="ExternalAccountProvider.v1_7_2.ExternalAccountProvider"/>
+
+ <ComplexType Name="RoleMapping" BaseType="ExternalAccountProvider.v1_5_0.RoleMapping">
+ <Property Name="LocalAccountTypes" Type="Collection(ManagerAccount.AccountTypes)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="The list of local services in the manager that the remote user or group is allowed to access."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain an array of the various local manager services that the remote user or group is allowed to access. This shall not include functionality for receiving events or other notifications. If this property is not supported, the value shall be assumed to be an array that contains the value `Redfish`."/>
+ </Property>
+ <Property Name="LocalOEMAccountTypes" Type="Collection(Edm.String)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="The OEM account types for the remote user or group."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain an array of the OEM account types for the remote user or group when `LocalAccountTypes` contains `OEM`."/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/LeakDetection_v1.xml b/redfish-core/schema/dmtf/csdl/LeakDetection_v1.xml
index c3757636cf..97284a1f02 100644
--- a/redfish-core/schema/dmtf/csdl/LeakDetection_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/LeakDetection_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: LeakDetection v1.0.1 -->
+<!--# Redfish Schema: LeakDetection v1.1.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -137,5 +137,20 @@
<EntityType Name="LeakDetection" BaseType="LeakDetection.v1_0_0.LeakDetection"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LeakDetection.v1_1_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="LeakDetection" BaseType="LeakDetection.v1_0_1.LeakDetection"/>
+
+ <ComplexType Name="LeakDetectorGroup" BaseType="LeakDetection.v1_0_0.LeakDetectorGroup">
+ <Property Name="Status" Type="Resource.Status" Nullable="false">
+ <Annotation Term="OData.Description" String="The status and health of the resource and its subordinate or dependent resources."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain any status or health properties of the resource."/>
+ <Annotation Term="Redfish.Required"/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/LeakDetector_v1.xml b/redfish-core/schema/dmtf/csdl/LeakDetector_v1.xml
index 6ef9f502a9..2b258021a5 100644
--- a/redfish-core/schema/dmtf/csdl/LeakDetector_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/LeakDetector_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: LeakDetector v1.1.0 -->
+<!--# Redfish Schema: LeakDetector v1.2.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -97,7 +97,7 @@
<Property Name="DetectorState" Type="Resource.Health">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The state of the leak detector."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the state of the leak detector."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the state of the leak detector. The value of this property should equate the value of `Health` in `Status`, and was created primarily for use in excerpts of this resource."/>
<Annotation Term="Redfish.Excerpt"/>
</Property>
<Property Name="PhysicalContext" Type="PhysicalContext.PhysicalContext">
@@ -195,6 +195,12 @@
<EntityType Name="LeakDetector" BaseType="LeakDetector.v1_0_1.LeakDetector"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LeakDetector.v1_0_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify that the value of `DetectorState` should reflect the `Health` of the detector."/>
+ <EntityType Name="LeakDetector" BaseType="LeakDetector.v1_0_2.LeakDetector"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LeakDetector.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -208,5 +214,26 @@
</EntityType>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LeakDetector.v1_1_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify that the value of `DetectorState` should reflect the `Health` of the detector."/>
+ <EntityType Name="LeakDetector" BaseType="LeakDetector.v1_0_3.LeakDetector"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LeakDetector.v1_2_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="LeakDetector" BaseType="LeakDetector.v1_1_1.LeakDetector">
+ <Property Name="DeviceName" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The name of the device."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the name of the device associated with this leak detector. If the device is represented by a resource, the value shall contain the value of the `Name` property of the associated resource."/>
+ <Annotation Term="Redfish.Excerpt" String="Array"/>
+ <Annotation Term="Redfish.ExcerptCopyOnly"/>
+ </Property>
+ </EntityType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/LogEntry_v1.xml b/redfish-core/schema/dmtf/csdl/LogEntry_v1.xml
index 90b2cae6b9..d65e3a8122 100644
--- a/redfish-core/schema/dmtf/csdl/LogEntry_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/LogEntry_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: LogEntry v1.16.1 -->
+<!--# Redfish Schema: LogEntry v1.17.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -1710,7 +1710,7 @@
<NavigationProperty Name="RelatedLogEntries" Type="Collection(LogEntry.LogEntry)">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="An array of links to other log entries that are related to this log entry."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain an array of links to resources of type `LogEntry` in this or other log services that are related to this log entry."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain an array of links to resources of type `LogEntry` in this or other log services that are related to this log entry. This property should be used to link a log entry indicating the resolution of a condition with a log entry for the initial condition."/>
<Annotation Term="OData.AutoExpandReferences"/>
</NavigationProperty>
</ComplexType>
@@ -1746,6 +1746,12 @@
<EntityType Name="LogEntry" BaseType="LogEntry.v1_12_4.LogEntry"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_12_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify that `RelatedLogEntries` should be used to link log entries that describe the initial condition from the log entry that describes the resolved condition."/>
+ <EntityType Name="LogEntry" BaseType="LogEntry.v1_12_5.LogEntry"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -1789,6 +1795,12 @@
<EntityType Name="LogEntry" BaseType="LogEntry.v1_13_4.LogEntry"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_13_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify that `RelatedLogEntries` should be used to link log entries that describe the initial condition from the log entry that describes the resolved condition."/>
+ <EntityType Name="LogEntry" BaseType="LogEntry.v1_13_5.LogEntry"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -1865,6 +1877,12 @@
<EntityType Name="LogEntry" BaseType="LogEntry.v1_14_3.LogEntry"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_14_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify that `RelatedLogEntries` should be used to link log entries that describe the initial condition from the log entry that describes the resolved condition."/>
+ <EntityType Name="LogEntry" BaseType="LogEntry.v1_14_4.LogEntry"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_15_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -1920,6 +1938,12 @@
<EntityType Name="LogEntry" BaseType="LogEntry.v1_15_2.LogEntry"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_15_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify that `RelatedLogEntries` should be used to link log entries that describe the initial condition from the log entry that describes the resolved condition."/>
+ <EntityType Name="LogEntry" BaseType="LogEntry.v1_15_3.LogEntry"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -1938,5 +1962,29 @@
<EntityType Name="LogEntry" BaseType="LogEntry.v1_16_0.LogEntry"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_16_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify that `RelatedLogEntries` should be used to link log entries that describe the initial condition from the log entry that describes the resolved condition."/>
+ <EntityType Name="LogEntry" BaseType="LogEntry.v1_16_1.LogEntry"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="LogEntry.v1_17_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="LogEntry" BaseType="LogEntry.v1_16_2.LogEntry">
+ <Property Name="Username" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The username of the account associated with the log entry."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the username of the account associated with the log entry. This should be used for audit logs that result from a user action."/>
+ </Property>
+ <Property Name="UserAuthenticationSource" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The source of authentication for the username property associated with the log entry."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the URL to the authentication service that is associated with the username property. This should be used for audit logs that result from a user action."/>
+ </Property>
+ </EntityType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/ManagerAccount_v1.xml b/redfish-core/schema/dmtf/csdl/ManagerAccount_v1.xml
index e61094b2df..0baf4bfa78 100644
--- a/redfish-core/schema/dmtf/csdl/ManagerAccount_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/ManagerAccount_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: ManagerAccount v1.12.1 -->
+<!--# Redfish Schema: ManagerAccount v1.13.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -94,6 +94,53 @@
</Parameter>
</Action>
+ <Action Name="GenerateSecretKey" IsBound="true">
+ <Annotation Term="OData.Description" String="This action randomly generates a new secret key for Time-based One-Time Password (TOTP) multi-factor authentication for this account."/>
+ <Annotation Term="OData.LongDescription" String="This action shall randomly generate a new secret key for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication for this account."/>
+ <Parameter Name="ManagerAccount" Type="ManagerAccount.v1_1_0.Actions"/>
+ <ReturnType Type="ManagerAccount.v1_13_0.GenerateSecretKeyResponse" Nullable="false"/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_13_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Action>
+
+ <Action Name="ClearSecretKey" IsBound="true">
+ <Annotation Term="OData.Description" String="This action clears the secret key for Time-based One-Time Password (TOTP) multi-factor authentication for this account."/>
+ <Annotation Term="OData.LongDescription" String="This action shall clear the secret key for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication for this account."/>
+ <Parameter Name="ManagerAccount" Type="ManagerAccount.v1_1_0.Actions"/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_13_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Action>
+
+ <Action Name="VerifyTimeBasedOneTimePassword" IsBound="true">
+ <Annotation Term="OData.Description" String="This action verifies a user-provided Time-based One-Time Password (TOTP). This is to ensure the client's copy of the secret key is aligned with the secret key stored by the service."/>
+ <Annotation Term="OData.LongDescription" String="This action shall verify a user-provided RFC6238-defined Time-based One-Time Password (TOTP)."/>
+ <Parameter Name="ManagerAccount" Type="ManagerAccount.v1_1_0.Actions"/>
+ <Parameter Name="TimeBasedOneTimePassword" Type="Edm.String" Nullable="false">
+ <Annotation Term="OData.Description" String="The Time-based One-Time Password (TOTP) to verify."/>
+ <Annotation Term="OData.LongDescription" String="This parameter shall contain the Time-based One-Time Password (TOTP) to verify. If the Time-based One-Time Password (TOTP) is not valid, the service shall return the HTTP `400 Bad Request` status code."/>
+ </Parameter>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_13_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Action>
+
<EnumType Name="AccountTypes">
<Annotation Term="Redfish.Revisions">
<Collection>
@@ -559,8 +606,8 @@
<Property Name="AuthenticationKey" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Write"/>
<Annotation Term="OData.Description" String="The secret authentication key for SNMPv3."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark."/>
- <Annotation Term="Validation.Pattern" String="(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\*+$)"/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414."/>
+ <Annotation Term="Validation.Pattern" String="(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\*+$)"/>
</Property>
<Property Name="AuthenticationProtocol" Type="ManagerAccount.v1_4_0.SNMPAuthenticationProtocols">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -570,8 +617,8 @@
<Property Name="EncryptionKey" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Write"/>
<Annotation Term="OData.Description" String="The secret encryption key used in SNMPv3."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark."/>
- <Annotation Term="Validation.Pattern" String="(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{32})|(^\*+$)"/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414."/>
+ <Annotation Term="Validation.Pattern" String="(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{16,64}$)|(^\*+$)"/>
</Property>
<Property Name="EncryptionProtocol" Type="ManagerAccount.v1_4_0.SNMPEncryptionProtocols">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
@@ -737,6 +784,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_4_8.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_4_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_4_9.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -805,6 +858,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_5_7.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_5_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_5_8.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.1"/>
@@ -860,6 +919,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_6_6.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_6_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_6_7.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -904,6 +969,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_7_4.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_7_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_7_5.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -946,6 +1017,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_8_3.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_8_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_8_4.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -977,6 +1054,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_9_2.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_9_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_9_3.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -1001,6 +1084,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_10_1.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_10_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_10_2.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -1037,6 +1126,12 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_11_1.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_11_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_11_2.ManagerAccount"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -1051,5 +1146,36 @@
<EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_12_0.ManagerAccount"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_12_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the regular expression pattern for the SNMP `AuthenticationKey` and `EncryptionKey` properties."/>
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_12_1.ManagerAccount"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ManagerAccount.v1_13_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+ <Annotation Term="OData.Description" String="This version was created to add the `GenerateSecretKey`, `ClearSecretKey`, and `VerifyTimeBasedOneTimePassword` actions."/>
+
+ <EntityType Name="ManagerAccount" BaseType="ManagerAccount.v1_12_2.ManagerAccount">
+ <Property Name="SecretKeySet" Type="Edm.Boolean" Nullable="false">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="Indicates if the secret key for Time-based One-Time Password (TOTP) multi-factor authentication is set."/>
+ <Annotation Term="OData.LongDescription" String="This property shall indicate if the secret key for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication is set."/>
+ </Property>
+ </EntityType>
+
+ <ComplexType Name="GenerateSecretKeyResponse">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="The response body for the `GenerateSecretKey` action."/>
+ <Annotation Term="OData.LongDescription" String="This type shall contain the properties found in the response body for the `GenerateSecretKey` action."/>
+ <Property Name="SecretKey" Type="Edm.String" Nullable="false">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The secret key generated for Time-based One-Time Password (TOTP) multi-factor authentication."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain secret key generated for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication. Clients shall retain the value of this property to generate tokens for future session creation requests."/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Manager_v1.xml b/redfish-core/schema/dmtf/csdl/Manager_v1.xml
index 128b8bc4f1..7aa3241322 100644
--- a/redfish-core/schema/dmtf/csdl/Manager_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Manager_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Manager v1.19.1 -->
+<!--# Redfish Schema: Manager v1.19.2 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -260,12 +260,12 @@
</Annotation>
</Property>
<Property Name="CommandShell" Type="Manager.v1_0_0.CommandShell" Nullable="false">
- <Annotation Term="OData.Description" String="The command shell service that this manager provides."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain information about the command shell service of this manager."/>
+ <Annotation Term="OData.Description" String="The manager's command line user interface or command shell service."/>
+ <Annotation Term="OData.LongDescription" String="This property shall describe a command line user interface or command shell service provided by this manager. The command shell refers to an interface used to interact with the manager itself, not a dedicated console session redirected from a host operating system. For redirected serial or host operating system consoles, see the `SerialConsole` property in the `ComputerSystem` resource."/>
</Property>
<Property Name="GraphicalConsole" Type="Manager.v1_0_0.GraphicalConsole" Nullable="false">
- <Annotation Term="OData.Description" String="The information about the graphical console service of this manager."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the information about the graphical console (KVM-IP) service of this manager. This property should be used to describe a service for the manager's console or operating system, not a service provided on behalf of a host operating system. Implementations representing host OS consoles, known generally as a KVM-IP feature, should use the `GraphicalConsole` property in ComputerSystem."/>
+ <Annotation Term="OData.Description" String="The manager's graphical console service."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the information about the graphical console (KVM-IP) service of this manager. This property should be used to describe a service for the manager's console or operating system, not a service provided on behalf of a host operating system. Implementations representing host OS consoles, known generally as a KVM-IP feature, should use the `GraphicalConsole` property in the `ComputerSystem` resource."/>
</Property>
<Property Name="Actions" Type="Manager.v1_0_0.Actions" Nullable="false">
<Annotation Term="OData.Description" String="The available actions for this resource."/>
@@ -541,6 +541,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_0_17.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_0_19">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_0_18.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.1"/>
@@ -653,6 +659,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_1_15.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_1_17">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_1_16.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.2"/>
@@ -762,6 +774,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_2_15.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_2_17">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_2_16.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.3"/>
@@ -866,6 +884,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_3_14.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_3_16">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_3_15.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.1"/>
@@ -960,6 +984,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_4_11.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_4_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_4_12.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.2"/>
@@ -1046,6 +1076,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_5_10.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_5_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_5_11.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.2"/>
@@ -1116,6 +1152,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_6_7.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_6_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_6_8.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -1187,6 +1229,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_7_7.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_7_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_7_8.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.1"/>
@@ -1249,6 +1297,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_8_6.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_8_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_8_7.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.2"/>
@@ -1313,6 +1367,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_9_5.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_9_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_9_6.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -1357,6 +1417,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_10_4.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_10_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_10_5.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -1403,6 +1469,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_11_3.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_11_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_11_4.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -1433,6 +1505,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_12_2.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_12_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_12_3.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1472,6 +1550,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_13_1.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_13_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_13_2.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -1498,6 +1582,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_14_1.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_14_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_14_2.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_15_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -1527,6 +1617,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_15_1.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_15_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_15_2.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -1560,6 +1656,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_16_1.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_16_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_16_2.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_17_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -1585,6 +1687,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_17_1.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_17_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_17_2.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_18_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -1612,6 +1720,12 @@
<EntityType Name="Manager" BaseType="Manager.v1_18_1.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_18_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_18_2.Manager"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_19_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -1656,5 +1770,11 @@
<EntityType Name="Manager" BaseType="Manager.v1_19_0.Manager"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Manager.v1_19_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the description of the `CommandShell` property. It was also was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Manager" BaseType="Manager.v1_19_1.Manager"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/MemoryRegion_v1.xml b/redfish-core/schema/dmtf/csdl/MemoryRegion_v1.xml
index 769214d46b..e0373dc6d4 100644
--- a/redfish-core/schema/dmtf/csdl/MemoryRegion_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/MemoryRegion_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: MemoryRegion v1.0.2 -->
+<!--# Redfish Schema: MemoryRegion v1.0.3 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -159,7 +159,7 @@
</Property>
<Property Name="Tag" Type="Edm.String" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
- <Annotation Term="OData.Description" String="The user-assigned tag of this memory extent."/>
+ <Annotation Term="OData.Description" String="The tag of this memory extent."/>
<Annotation Term="OData.LongDescription" String="This property shall contain an opaque context attached to each extent to track usage of each extent or map extent to specific processes, transactions, or workloads on the host."/>
</Property>
<Property Name="SequenceNumber" Type="Edm.Int64">
@@ -224,5 +224,11 @@
<EntityType Name="MemoryRegion" BaseType="MemoryRegion.v1_0_1.MemoryRegion"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MemoryRegion.v1_0_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the definition of the `Tag` property."/>
+ <EntityType Name="MemoryRegion" BaseType="MemoryRegion.v1_0_2.MemoryRegion"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Message_v1.xml b/redfish-core/schema/dmtf/csdl/Message_v1.xml
index ed42f02805..0bcd23c683 100644
--- a/redfish-core/schema/dmtf/csdl/Message_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Message_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Message v1.2.1 -->
+<!--# Redfish Schema: Message v1.3.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -215,5 +215,23 @@
<ComplexType Name="Message" BaseType="Message.v1_2_0.Message"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Message.v1_3_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <ComplexType Name="Message" BaseType="Message.v1_2_1.Message">
+ <Property Name="Username" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The username of the account associated with the message."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the username of the account associated with the message. This should be used for messages that result from a user action."/>
+ </Property>
+ <Property Name="UserAuthenticationSource" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The source of authentication for the username property associated with the message."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the URL to the authentication service that is associated with the username property. This should be used for messages that result from a user action."/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/MetricReport_v1.xml b/redfish-core/schema/dmtf/csdl/MetricReport_v1.xml
index 5120e1ab07..985e10887f 100644
--- a/redfish-core/schema/dmtf/csdl/MetricReport_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/MetricReport_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: MetricReport v1.5.1 -->
+<!--# Redfish Schema: MetricReport v1.5.2 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -111,7 +111,7 @@
<Property Name="MetricValue" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The metric value, as a string."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the metric value, as a string."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the metric value, as a string. For numeric metrics, the service shall convert the number to a string representation of the number. For array metrics, the service shall convert the array to an RFC8259-defined JSON string. For boolean metrics, this property shall contain the strings `true` or `false`. If the metric value is `null`, this property shall contain `null`."/>
</Property>
<Property Name="Timestamp" Type="Edm.DateTimeOffset">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
@@ -212,6 +212,12 @@
<EntityType Name="MetricReport" BaseType="MetricReport.v1_0_8.MetricReport"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_0_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the `MetricValue` property to describe encoding behaviors for non-string metrics."/>
+ <EntityType Name="MetricReport" BaseType="MetricReport.v1_0_9.MetricReport"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.3"/>
@@ -273,6 +279,12 @@
<EntityType Name="MetricReport" BaseType="MetricReport.v1_1_7.MetricReport"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_1_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the `MetricValue` property to describe encoding behaviors for non-string metrics."/>
+ <EntityType Name="MetricReport" BaseType="MetricReport.v1_1_8.MetricReport"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.2"/>
@@ -323,6 +335,12 @@
<EntityType Name="MetricReport" BaseType="MetricReport.v1_2_5.MetricReport"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_2_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the `MetricValue` property to describe encoding behaviors for non-string metrics."/>
+ <EntityType Name="MetricReport" BaseType="MetricReport.v1_2_6.MetricReport"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -361,6 +379,12 @@
<EntityType Name="MetricReport" BaseType="MetricReport.v1_3_5.MetricReport"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_3_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the `MetricValue` property to describe encoding behaviors for non-string metrics."/>
+ <EntityType Name="MetricReport" BaseType="MetricReport.v1_3_6.MetricReport"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.2"/>
@@ -398,6 +422,12 @@
<EntityType Name="MetricReport" BaseType="MetricReport.v1_4_3.MetricReport"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_4_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the `MetricValue` property to describe encoding behaviors for non-string metrics."/>
+ <EntityType Name="MetricReport" BaseType="MetricReport.v1_4_4.MetricReport"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -412,5 +442,11 @@
<EntityType Name="MetricReport" BaseType="MetricReport.v1_5_0.MetricReport"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="MetricReport.v1_5_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to clarify the `MetricValue` property to describe encoding behaviors for non-string metrics."/>
+ <EntityType Name="MetricReport" BaseType="MetricReport.v1_5_1.MetricReport"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Outlet_v1.xml b/redfish-core/schema/dmtf/csdl/Outlet_v1.xml
index cfb7562978..f67dd6ae6f 100644
--- a/redfish-core/schema/dmtf/csdl/Outlet_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Outlet_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Outlet v1.4.3 -->
+<!--# Redfish Schema: Outlet v1.4.4 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -274,13 +274,13 @@
</Property>
<NavigationProperty Name="Voltage" Type="Sensor.Sensor">
<Annotation Term="Redfish.ExcerptCopy" String="Voltage"/>
- <Annotation Term="OData.Description" String="The voltage (V) for this single-phase outlet."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the voltage, in volt units, for this single-phase outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not appear in resource instances representing poly-phase outlets."/>
+ <Annotation Term="OData.Description" String="The voltage (V) for this outlet."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the voltage, in volt units, for this outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."/>
</NavigationProperty>
<NavigationProperty Name="CurrentAmps" Type="Sensor.Sensor">
<Annotation Term="Redfish.ExcerptCopy" String="Current"/>
- <Annotation Term="OData.Description" String="The current (A) for this single-phase outlet."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the current, in ampere units, for this single-phase outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not appear in resource instances representing poly-phase outlets."/>
+ <Annotation Term="OData.Description" String="The current (A) for this outlet."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the current, in ampere units, for this outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."/>
</NavigationProperty>
<NavigationProperty Name="PowerWatts" Type="Sensor.Sensor">
<Annotation Term="Redfish.ExcerptCopy" String="Power"/>
@@ -300,11 +300,11 @@
<Property Name="PolyPhaseVoltage" Type="Outlet.v1_0_0.VoltageSensors">
<Annotation Term="OData.Description" String="The voltage readings for this outlet."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the voltage readings for this outlet. For single-phase outlets, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For poly-phase outlets, this property should contain multiple voltage sensor readings used to fully describe the outlet."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the voltage readings for this outlet. For 3-wire outlets, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For other outlets, this property should contain multiple voltage sensor readings used to fully describe the outlet."/>
</Property>
<Property Name="PolyPhaseCurrentAmps" Type="Outlet.v1_0_0.CurrentSensors">
<Annotation Term="OData.Description" String="The current readings for this outlet."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the current readings for this outlet. For single-phase outlets, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For poly-phase outlets, this property should contain multiple current sensor readings used to fully describe the outlet."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the current readings for this outlet. For 3-wire outlets, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For other outlets, this property should contain multiple current sensor readings used to fully describe the outlet."/>
</Property>
<Property Name="Links" Type="Outlet.v1_0_0.Links" Nullable="false">
@@ -452,6 +452,12 @@
<EntityType Name="Outlet" BaseType="Outlet.v1_0_5.Outlet"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_0_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Outlet" BaseType="Outlet.v1_0_6.Outlet"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -496,6 +502,12 @@
<EntityType Name="Outlet" BaseType="Outlet.v1_1_4.Outlet"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_1_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Outlet" BaseType="Outlet.v1_1_5.Outlet"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -533,6 +545,12 @@
<EntityType Name="Outlet" BaseType="Outlet.v1_2_3.Outlet"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_2_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Outlet" BaseType="Outlet.v1_2_4.Outlet"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.3"/>
@@ -596,6 +614,12 @@
<EntityType Name="Outlet" BaseType="Outlet.v1_3_3.Outlet"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_3_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Outlet" BaseType="Outlet.v1_3_4.Outlet"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -638,5 +662,11 @@
<EntityType Name="Outlet" BaseType="Outlet.v1_4_2.Outlet"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Outlet.v1_4_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions to explain voltage and current sensor properties in terms of the `PhaseWiringType`. It was also created to correct various typographic errors and for consistent style."/>
+ <EntityType Name="Outlet" BaseType="Outlet.v1_4_3.Outlet"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/PCIeDevice_v1.xml b/redfish-core/schema/dmtf/csdl/PCIeDevice_v1.xml
index bcc1a54072..e545483bbe 100644
--- a/redfish-core/schema/dmtf/csdl/PCIeDevice_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/PCIeDevice_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: PCIeDevice v1.14.0 -->
+<!--# Redfish Schema: PCIeDevice v1.16.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -124,6 +124,17 @@
<Member Name="Gen5">
<Annotation Term="OData.Description" String="A PCIe v5.0 slot."/>
</Member>
+ <Member Name="Gen6">
+ <Annotation Term="OData.Description" String="A PCIe v6.0 slot."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_16_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
</EnumType>
</Schema>
@@ -1122,5 +1133,32 @@
</ComplexType>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="PCIeDevice.v1_15_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.2"/>
+
+ <EntityType Name="PCIeDevice" BaseType="PCIeDevice.v1_14_0.PCIeDevice"/>
+
+ <ComplexType Name="PCIeErrors" BaseType="PCIeDevice.v1_13_0.PCIeErrors">
+ <Property Name="BadTLPCount" Type="Edm.Int64">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The total number of Bad TLPs issued on the PCIe link by the receiver."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the total number of Bad TLPs issued on the PCIe link by the receiver. A Bad TLP in the context of PCIe communication is a packet that cannot be properly processed due to errors at the transaction layer. These errors could include corrupted data, incorrect packet formatting, invalid header information, or a mismatched checksum."/>
+ </Property>
+ <Property Name="BadDLLPCount" Type="Edm.Int64">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The total number of Bad DLLPs issued on the PCIe link by the receiver."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the total number of Bad DLLPs issued on the PCIe link by the receiver. A Bad DLLP in the context of PCIe communication is a packet that has encountered errors at the data link layer. When a DLLP is considered bad, it means it has been corrupted or is incorrectly formatted, potentially due to transmission errors, hardware failures, or other issues that affect its integrity."/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="PCIeDevice.v1_16_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="PCIeDevice" BaseType="PCIeDevice.v1_15_0.PCIeDevice"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/PhysicalContext_v1.xml b/redfish-core/schema/dmtf/csdl/PhysicalContext_v1.xml
index f29eae76a1..84e1521cca 100644
--- a/redfish-core/schema/dmtf/csdl/PhysicalContext_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/PhysicalContext_v1.xml
@@ -167,23 +167,51 @@
<Member Name="StorageDevice">
<Annotation Term="OData.Description" String="A storage device."/>
</Member>
+ <Member Name="StorageSubsystem">
+ <Annotation Term="OData.Description" String="A storage subsystem."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate a storage subsystem, which may consist of one or more storage controllers, storage devices, or related components."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="2024.3"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
<Member Name="NetworkingDevice">
<Annotation Term="OData.Description" String="A networking device."/>
</Member>
+ <Member Name="ExpansionSubsystem">
+ <Annotation Term="OData.Description" String="A group of expansion bays."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate a group of expansion bays and the devices installed in those bays."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="2024.3"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
<Member Name="ComputeBay">
- <Annotation Term="OData.Description" String="Within a compute bay."/>
+ <Annotation Term="OData.Description" String="A compute bay."/>
</Member>
<Member Name="StorageBay">
- <Annotation Term="OData.Description" String="Within a storage bay."/>
+ <Annotation Term="OData.Description" String="A storage bay."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate a location that provides for the expansion of storage functionality of a system, by the addition of storage devices."/>
</Member>
<Member Name="NetworkBay">
- <Annotation Term="OData.Description" String="Within a networking bay."/>
+ <Annotation Term="OData.Description" String="A networking bay."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate a location that provides for the expansion of networking functionality of a system, by the addition of networking devices."/>
</Member>
<Member Name="ExpansionBay">
- <Annotation Term="OData.Description" String="Within an expansion bay."/>
+ <Annotation Term="OData.Description" String="An expansion bay."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate a location that provides for the expansion of functionality of a system, such as a PCIe slot that can accept an option card."/>
</Member>
<Member Name="PowerSupplyBay">
- <Annotation Term="OData.Description" String="Within a power supply bay."/>
+ <Annotation Term="OData.Description" String="A power supply bay."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate a location that provides for the installation of a power supply or similar devices."/>
</Member>
<Member Name="Memory">
<Annotation Term="OData.Description" String="A memory device."/>
@@ -263,7 +291,8 @@
</Annotation>
</Member>
<Member Name="ACUtilityInput">
- <Annotation Term="OData.Description" String="An AC utility input."/>
+ <Annotation Term="OData.Description" String="An AC electrical utility input."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an electrical input, where the source is an electrical utility as opposed to a backup or locally-generated power source. This value is intended to differentiate multiple electrical inputs between utility, maintenance bypass, or static bypass values. For general purpose usage, the value of `ACInput` is preferred."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -274,7 +303,7 @@
</Annotation>
</Member>
<Member Name="ACStaticBypassInput">
- <Annotation Term="OData.Description" String="An AC static bypass input."/>
+ <Annotation Term="OData.Description" String="An AC electrical static bypass input."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -285,7 +314,7 @@
</Annotation>
</Member>
<Member Name="ACMaintenanceBypassInput">
- <Annotation Term="OData.Description" String="An AC maintenance bypass input."/>
+ <Annotation Term="OData.Description" String="An AC electrical maintenance bypass input."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -296,7 +325,7 @@
</Annotation>
</Member>
<Member Name="DCBus">
- <Annotation Term="OData.Description" String="A DC bus."/>
+ <Annotation Term="OData.Description" String="A DC electrical bus."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -307,7 +336,8 @@
</Annotation>
</Member>
<Member Name="ACOutput">
- <Annotation Term="OData.Description" String="An AC output."/>
+ <Annotation Term="OData.Description" String="An AC electrical output or output-related circuit."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an electrical output or an output-related circuit, such as a branch output, which is not terminated as a power outlet."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -318,7 +348,7 @@
</Annotation>
</Member>
<Member Name="ACInput">
- <Annotation Term="OData.Description" String="An AC input."/>
+ <Annotation Term="OData.Description" String="An AC electrical input or input-related circuit."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -328,6 +358,18 @@
</Collection>
</Annotation>
</Member>
+ <Member Name="PowerOutlet">
+ <Annotation Term="OData.Description" String="An electrical outlet."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate an electrical outlet or receptacle."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="2024.3"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
<Member Name="TrustedModule">
<Annotation Term="OData.Description" String="A trusted module."/>
<Annotation Term="Redfish.Revisions">
@@ -385,6 +427,50 @@
</Collection>
</Annotation>
</Member>
+ <Member Name="Filter">
+ <Annotation Term="OData.Description" String="A filter."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="2024.2"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
+ <Member Name="Reservoir">
+ <Annotation Term="OData.Description" String="A reservoir."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="2024.2"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
+ <Member Name="Switch">
+ <Annotation Term="OData.Description" String="A switch device."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="2024.2"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
+ <Member Name="Manager">
+ <Annotation Term="OData.Description" String="A management controller, such as a BMC (baseboard management controller)."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="2024.2"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
</EnumType>
<EnumType Name="PhysicalSubContext">
diff --git a/redfish-core/schema/dmtf/csdl/PortMetrics_v1.xml b/redfish-core/schema/dmtf/csdl/PortMetrics_v1.xml
index be39a4270c..9b7084bd9f 100644
--- a/redfish-core/schema/dmtf/csdl/PortMetrics_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/PortMetrics_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: PortMetrics v1.6.0 -->
+<!--# Redfish Schema: PortMetrics v1.7.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -731,5 +731,21 @@
<EntityType Name="PortMetrics" BaseType="PortMetrics.v1_6_0.PortMetrics"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="PortMetrics.v1_7_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="PortMetrics" BaseType="PortMetrics.v1_6_1.PortMetrics"/>
+
+ <ComplexType Name="Transceiver" BaseType="PortMetrics.v1_1_0.Transceiver">
+ <Property Name="WavelengthNanometers" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The laser wavelength, in nanometers, for a small form-factor pluggable (SFP) transceiver."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the laser wavelength, in nanometers, for a small form-factor pluggable (SFP) transceiver. This property shall not be present for non-optic SFP mediums."/>
+ <Annotation Term="Measures.Unit" String="nm"/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Port_v1.xml b/redfish-core/schema/dmtf/csdl/Port_v1.xml
index 396620a729..f234731e0b 100644
--- a/redfish-core/schema/dmtf/csdl/Port_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Port_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Port v1.12.0 -->
+<!--# Redfish Schema: Port v1.14.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -1189,6 +1189,7 @@
</EnumType>
<ComplexType Name="SFP">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
<Annotation Term="OData.Description" String="A small form-factor pluggable (SFP) device attached to a port."/>
<Annotation Term="OData.LongDescription" String="This type shall describe a small form-factor pluggable (SFP) device attached to a port."/>
<Property Name="Status" Type="Resource.Status" Nullable="false">
@@ -1909,5 +1910,41 @@
<EntityType Name="Port" BaseType="Port.v1_11_1.Port"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Port.v1_13_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.2"/>
+
+ <EntityType Name="Port" BaseType="Port.v1_12_0.Port"/>
+
+ <ComplexType Name="SFP" BaseType="Port.v1_4_0.SFP">
+ <Property Name="Version" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The hardware version of this SFP."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the hardware version of this SFP as determined by the vendor or supplier."/>
+ </Property>
+ <Property Name="VendorOUI" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The IEEE OUI of the vendor of this SFP."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the IEEE organizationally unique identifier (OUI) of the vendor of this SFP."/>
+ <Annotation Term="Validation.Pattern" String="^([0-9A-Fa-f]{2}-){2}([0-9A-Fa-f]{2})$"/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Port.v1_14_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="Port" BaseType="Port.v1_13_0.Port"/>
+
+ <ComplexType Name="SFP" BaseType="Port.v1_13_0.SFP">
+ <Property Name="DateCode" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The manufacturing date code for this SFP."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the manufacturing date code for this SFP as determined by the vendor or supplier."/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Processor_v1.xml b/redfish-core/schema/dmtf/csdl/Processor_v1.xml
index 758810773c..6d2541c7e4 100644
--- a/redfish-core/schema/dmtf/csdl/Processor_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Processor_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Processor v1.20.0 -->
+<!--# Redfish Schema: Processor v1.20.1 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -208,7 +208,7 @@
</Property>
<Property Name="ProcessorId" Type="Processor.v1_0_0.ProcessorId" Nullable="false">
<Annotation Term="OData.Description" String="The identification information for this processor."/>
- <Annotation Term="OData.LongDescription" String="This object shall contain identification information for this processor."/>
+ <Annotation Term="OData.LongDescription" String="This object shall contain identification information for this processor. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
<Property Name="Status" Type="Resource.Status" Nullable="false">
<Annotation Term="OData.Description" String="The status and health of the resource and its subordinate or dependent resources."/>
@@ -249,33 +249,33 @@
<Property Name="VendorId" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The vendor identification for this processor."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the vendor identification information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the vendor identification information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
<Property Name="IdentificationRegisters" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The raw manufacturer-provided processor identification registers for this processor."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the raw manufacturer-provided processor-specific identification registers of this processor's features."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the raw manufacturer-provided processor-specific identification registers of this processor's features. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
<Annotation Term="Validation.Pattern" String="^0x[0-9A-Fa-f]+$"/>
</Property>
<Property Name="EffectiveFamily" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The effective family for this processor."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the effective family information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the effective family information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
<Property Name="EffectiveModel" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The effective model for this processor."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the effective model information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the effective model information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
<Property Name="Step" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The step value for this processor."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the step or revision information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the step or revision information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
<Property Name="MicrocodeInfo" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The microcode information for this processor."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the microcode information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the microcode information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
</ComplexType>
@@ -545,6 +545,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_0_14.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_0_16">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_0_15.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.1"/>
@@ -654,6 +660,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_1_10.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_1_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_1_11.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.3"/>
@@ -738,6 +750,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_2_10.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_2_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_2_11.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.1"/>
@@ -824,6 +842,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_3_11.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_3_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_3_12.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.3"/>
@@ -1302,6 +1326,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_4_11.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_4_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_4_12.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.1"/>
@@ -1382,6 +1412,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_5_10.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_5_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_5_11.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.3"/>
@@ -1444,6 +1480,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_6_8.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_6_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_6_9.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -1520,6 +1562,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_7_7.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_7_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_7_8.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.1"/>
@@ -1587,6 +1635,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_8_6.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_8_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_8_7.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.2"/>
@@ -1677,6 +1731,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_9_5.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_9_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_9_6.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -1753,6 +1813,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_10_5.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_10_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_10_6.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -1864,6 +1930,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_11_5.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_11_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_11_6.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -1916,6 +1988,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_12_4.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_12_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_12_5.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1989,6 +2067,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_13_5.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_13_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_13_6.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -2027,6 +2111,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_14_4.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_14_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_14_5.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_15_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -2063,6 +2153,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_15_3.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_15_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_15_4.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -2150,6 +2246,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_16_3.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_16_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_16_4.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_17_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -2191,6 +2293,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_17_2.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_17_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_17_3.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_18_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -2211,6 +2319,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_18_1.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_18_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_18_2.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_19_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -2225,6 +2339,12 @@
<EntityType Name="Processor" BaseType="Processor.v1_19_0.Processor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_19_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_19_1.Processor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_20_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -2239,5 +2359,11 @@
</EntityType>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Processor.v1_20_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ <EntityType Name="Processor" BaseType="Processor.v1_20_0.Processor"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/RedfishExtensions_v1.xml b/redfish-core/schema/dmtf/csdl/RedfishExtensions_v1.xml
index 9547029aa5..98f8465e57 100644
--- a/redfish-core/schema/dmtf/csdl/RedfishExtensions_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/RedfishExtensions_v1.xml
@@ -37,10 +37,10 @@
<Annotation Term="OData.Description" String="The set of allowable values for an action parameter or read-write property."/>
</Term>
<Term Name="AllowableNumbers" Type="Collection(Edm.String)" Nullable="false">
- <Annotation Term="OData.Description" String="The term specifies the numeric values or duration values, inclusive ranges of values, and incremental step values for a read-write property that are supported by the service, as defined in the 'Allowable values for numbers and durations' clause of the Redfish Specification."/>
+ <Annotation Term="OData.Description" String="The term specifies the numeric values or duration values, inclusive ranges of values, and incremental step values for an action parameter or a read-write property that are supported by the service, as defined in the 'Allowable values for numbers and durations' clause of the Redfish Specification."/>
</Term>
<Term Name="AllowablePattern" Type="Edm.String" Nullable="false">
- <Annotation Term="OData.Description" String="The term specifies a regular expression that describes the allowable values for a read-write property as supported by the service."/>
+ <Annotation Term="OData.Description" String="The term specifies a regular expression that describes the allowable values for an action parameter or a read-write property as supported by the service."/>
</Term>
<Term Name="WriteableProperties" Type="Collection(Edm.String)" Nullable="false">
<Annotation Term="OData.Description" String="The term specifies the properties supported as read-write. The values contained are the names of the writable properties as defined in the Redfish schema that are available as read-write given the implementation, current configuration, and state of the resource. This term might appear at the root level of a resource, or within an object. For arrays of objects, the term might only appear in the first element of the array to indicate identical capabilities for every element in the array."/>
diff --git a/redfish-core/schema/dmtf/csdl/Resource_v1.xml b/redfish-core/schema/dmtf/csdl/Resource_v1.xml
index 6369ad6e54..e4c3781384 100644
--- a/redfish-core/schema/dmtf/csdl/Resource_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Resource_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Resource v1.19.0 -->
+<!--# Redfish Schema: Resource v1.20.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -109,7 +109,7 @@
<Property Name="HealthRollup" Type="Resource.Health">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The overall health state from the view of this resource."/>
- <Annotation Term="OData.LongDescription" String="This property shall represent the health state of the resource and its dependent resources. The values shall conform to those defined in the Redfish Specification."/>
+ <Annotation Term="OData.LongDescription" String="This property shall represent the health state of the resource and its dependent resources. The values shall conform to those defined in the Redfish Specification. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."/>
</Property>
<Property Name="Health" Type="Resource.Health">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
@@ -202,6 +202,32 @@
</Collection>
</Annotation>
</Property>
+ <Property Name="Username" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The username of the account associated with the condition."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the username of the account associated with the condition. This should be used for conditions that result from a user action."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_20_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Property>
+ <Property Name="UserAuthenticationSource" Type="Edm.String">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The source of authentication for the username property associated with the condition."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the URL to the authentication service that is associated with the username property. This should be used for conditions that result from a user action."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_20_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Property>
</ComplexType>
<EnumType Name="State">
@@ -585,6 +611,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_0_16">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.1"/>
@@ -811,6 +842,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_1_18">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.2"/>
@@ -897,6 +933,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_2_17">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.3"/>
@@ -1220,6 +1261,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_3_16">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.1"/>
@@ -1296,6 +1342,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_4_15">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.2"/>
@@ -1511,6 +1562,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_5_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.3"/>
@@ -1603,6 +1659,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_6_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.2"/>
@@ -1712,6 +1773,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_7_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.3"/>
@@ -1778,6 +1844,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_8_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -1834,6 +1905,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_9_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -1875,6 +1951,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_10_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -1911,6 +1992,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_11_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -1942,6 +2028,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_12_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1968,6 +2059,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_13_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -1989,6 +2085,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_14_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_15_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -2005,6 +2106,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_15_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -2028,6 +2134,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_16_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_17_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -2093,6 +2204,11 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_17_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_18_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -2104,11 +2220,27 @@
<Annotation Term="OData.Description" String="This version was created to add long descriptions to the values of `State` in `Status`. It was also created to note that the array order of conditions may change as new conditions occur or are resolved by the service. It was also created to force the regeneration of OpenAPI schemas to properly express nullable properties with external references. It was also created to correct various typographical errors."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_18_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_19_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
<Annotation Term="OData.Description" String="This version was created to deprecate `Qualified` in `State` in favor of `StandbySpare`. It was also created to add `Degraded` to `State`."/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_19_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references in property long descriptions to the Redfish Data Model Specification where additional requirements or details are provided."/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Resource.v1_20_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+ <Annotation Term="OData.Description" String="This version was created to add `Username` and `UserAuthenticationSource` to the `Condition` property in `Status`."/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Sensor_v1.xml b/redfish-core/schema/dmtf/csdl/Sensor_v1.xml
index fc1e079c23..13c76b1740 100644
--- a/redfish-core/schema/dmtf/csdl/Sensor_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Sensor_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Sensor v1.9.0 -->
+<!--# Redfish Schema: Sensor v1.10.1 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -211,13 +211,13 @@
<Property Name="Reading" Type="Edm.Decimal">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The sensor value."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the sensor value."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`."/>
<Annotation Term="Redfish.Excerpt"/>
</Property>
<Property Name="ReadingUnits" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
- <Annotation Term="OData.Description" String="The units of the reading and thresholds."/>
- <Annotation Term="OData.LongDescription" String="This property shall contain the units of the sensor's reading and thresholds."/>
+ <Annotation Term="OData.Description" String="The units of the reading, thresholds, and other reading-related properties in UCUM c/s format."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the units of the sensor's reading, thresholds, and other reading-related properties. The value shall follow the case-sensitive symbol format defined by the Unified Code for Units of Measure (UCUM), as specified by the 'Units of measure annotation' clause of the Redfish Specification."/>
</Property>
<Property Name="PhysicalContext" Type="PhysicalContext.PhysicalContext">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
@@ -737,6 +737,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_0_10.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_0_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_0_11.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -835,6 +841,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_1_6.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_1_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_1_7.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -913,6 +925,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_2_4.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_2_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_2_5.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -960,6 +978,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_3_4.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_3_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_3_5.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1040,6 +1064,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_4_3.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_4_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_4_4.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -1089,6 +1119,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_5_2.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_5_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_5_3.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.2"/>
@@ -1115,6 +1151,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_6_2.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_6_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_6_3.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -1169,6 +1211,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_7_1.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_7_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_7_2.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -1195,6 +1243,12 @@
<EntityType Name="Sensor" BaseType="Sensor.v1_8_1.Sensor"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_8_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_8_2.Sensor"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -1243,5 +1297,30 @@
</EntityType>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_9_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_9_0.Sensor"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_10_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.2"/>
+
+ <EntityType Name="Sensor" BaseType="Sensor.v1_9_0.Sensor">
+ <Property Name="Enabled" Type="Edm.Boolean">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="Indicates whether the sensor is enabled and provides a reading."/>
+ <Annotation Term="OData.LongDescription" String="This property shall indicate whether the sensor is enabled and provides a `Reading`. The value `true` shall indicate the sensor is enabled and returns the `Reading` property with a valid value. The value `false` shall indicate the sensor is disabled, shall not return the `Reading` property, and shall not trigger events, logging, or other functionality. This property allows a user to disable a faulty sensor or to otherwise remove it from use."/>
+ </Property>
+ </EntityType>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Sensor.v1_10_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to add references to formats defined by the UCUM specification in the description of `ReadingUnits`. It was also created to improve the description of the `Enabled` property."/>
+ <EntityType Name="Sensor" BaseType="Sensor.v1_10_0.Sensor"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/StorageController_v1.xml b/redfish-core/schema/dmtf/csdl/StorageController_v1.xml
index 9200ef0fec..b552021dd5 100644
--- a/redfish-core/schema/dmtf/csdl/StorageController_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/StorageController_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: StorageController v1.7.3 -->
+<!--# Redfish Schema: StorageController v1.8.0 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -890,5 +890,27 @@
<EntityType Name="StorageController" BaseType="StorageController.v1_7_2.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="StorageController.v1_7_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="StorageController" BaseType="StorageController.v1_7_3.StorageController"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="StorageController.v1_8_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.3"/>
+
+ <EntityType Name="StorageController" BaseType="StorageController.v1_7_4.StorageController"/>
+
+ <ComplexType Name="NVMeControllerProperties" BaseType="StorageController.v1_4_0.NVMeControllerProperties">
+ <Property Name="MaxAttachedNamespaces" Type="Edm.Int64">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The maximum number of attached namespaces allowed by this NVMe I/O controller."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the maximum number of attached namespaces allowed by this NVMe I/O controller."/>
+ <Annotation Term="Validation.Minimum" Int="0"/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/Storage_v1.xml b/redfish-core/schema/dmtf/csdl/Storage_v1.xml
index 5a71f24d06..90501cd92c 100644
--- a/redfish-core/schema/dmtf/csdl/Storage_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Storage_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: Storage v1.16.0 -->
+<!--# Redfish Schema: Storage v1.17.1 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -161,8 +161,8 @@
</Annotation>
</Parameter>
<Parameter Name="CurrentEncryptionKey" Type="Edm.String">
- <Annotation Term="OData.Description" String="The current local encryption key on the storage subsystem."/>
- <Annotation Term="OData.LongDescription" String="This parameter shall contain the current local encryption key on the storage subsystem. Services may reject the action request if this parameter is not provided."/>
+ <Annotation Term="OData.Description" String="The current local encryption key on the storage subsystem. This parameter is not needed if the controller does not currently have an encryption key."/>
+ <Annotation Term="OData.LongDescription" String="This parameter shall contain the current local encryption key on the storage subsystem. Services may reject the action request if this parameter is not provided or the value supplied does not match the current encryption key."/>
<Annotation Term="Redfish.Revisions">
<Collection>
<Record>
@@ -205,6 +205,32 @@
</Collection>
</Annotation>
</Action>
+
+ <Action Name="SetControllerPassword" IsBound="true">
+ <Annotation Term="OData.Description" String="This action sets the controller boot password for a host-based storage controller."/>
+ <Annotation Term="OData.LongDescription" String="This action shall set the controller boot password for a host-based storage controller."/>
+ <Parameter Name="Storage" Type="Storage.v1_0_0.Actions"/>
+ <Parameter Name="CurrentPassword" Type="Edm.String">
+ <Annotation Term="OData.Description" String="The current controller password. This parameter is not needed if the controller does not currently have a password."/>
+ <Annotation Term="OData.LongDescription" String="This parameter shall contain the current controller password. Services may reject the action request if this parameter is not provided or the value supplied does not match the current password."/>
+ </Parameter>
+ <Parameter Name="NewPassword" Type="Edm.String" Nullable="false">
+ <Annotation Term="OData.Description" String="The new password to set for the controller."/>
+ <Annotation Term="OData.LongDescription" String="This parameter shall contain the new password to set for the controller."/>
+ </Parameter>
+ <Parameter Name="SecurityKey" Type="Edm.String">
+ <Annotation Term="OData.Description" String="The security key for the controller. This parameter is not needed if the controller does not have a security key."/>
+ <Annotation Term="OData.LongDescription" String="This parameter shall contain the controller security key. Services may reject the action request if this parameter is not provided or the value provided does not match the security key for the controller."/>
+ </Parameter>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_17_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Action>
</Schema>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_0_0">
@@ -440,6 +466,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_0_12.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_0_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_0_13.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_0_13.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.2"/>
@@ -548,6 +581,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_1_11.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_1_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_1_12.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_1_12.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.1"/>
@@ -648,6 +688,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_2_9.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_2_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_2_10.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_2_10.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.2"/>
@@ -733,6 +780,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_3_9.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_3_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_3_10.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_3_10.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.3"/>
@@ -833,6 +887,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_4_9.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_4_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_4_10.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_4_10.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.2"/>
@@ -932,6 +993,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_5_7.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_5_9">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_5_8.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_5_8.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.3"/>
@@ -996,6 +1064,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_6_6.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_6_8">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_6_7.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_6_7.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.1"/>
@@ -1092,6 +1167,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_7_5.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_7_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_7_6.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_7_6.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.3"/>
@@ -1176,6 +1258,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_8_4.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_8_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_8_5.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_8_5.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.3"/>
@@ -1239,6 +1328,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_9_3.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_9_5">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_9_4.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_9_4.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2020.4"/>
@@ -1289,6 +1385,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_10_2.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_10_4">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_10_3.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_10_3.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1331,6 +1434,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_11_1.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_11_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_11_2.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_11_2.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -1354,6 +1464,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_12_1.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_12_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_12_2.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_12_2.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.1"/>
@@ -1377,6 +1494,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_13_1.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_13_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_13_2.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_13_2.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2022.3"/>
@@ -1421,6 +1545,39 @@
<Member Name="UseLocalKey">
<Annotation Term="OData.Description" String="The storage subsystem uses a local key for encryption."/>
</Member>
+ <Member Name="PasswordOnly">
+ <Annotation Term="OData.Description" String="The storage subsystem uses a password, but no keys for encryption."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_17_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
+ <Member Name="PasswordWithExternalKey">
+ <Annotation Term="OData.Description" String="The storage subsystem uses a password and one or more external keys for encryption."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_17_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
+ <Member Name="PasswordWithLocalKey">
+ <Annotation Term="OData.Description" String="The storage subsystem uses a password and a local key for encryption."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Added"/>
+ <PropertyValue Property="Version" String="v1_17_0"/>
+ </Record>
+ </Collection>
+ </Annotation>
+ </Member>
</EnumType>
<EntityType Name="StorageController" BaseType="Storage.v1_13_0.StorageController"/>
@@ -1440,6 +1597,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_14_1.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_14_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_14_2.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_14_2.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_15_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.1"/>
@@ -1498,6 +1662,13 @@
<EntityType Name="StorageController" BaseType="Storage.v1_15_1.StorageController"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_15_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_15_2.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_15_2.StorageController"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_16_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -1510,7 +1681,7 @@
</Property>
<Property Name="ConfigurationLock" Type="Storage.v1_16_0.ConfigurationLock">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
- <Annotation Term="OData.Description" String="Indicates whether in-band configuration requests to the storage subsystem are locked."/>
+ <Annotation Term="OData.Description" String="Indicates whether in-band configuration requests to the storage subsystem are locked. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock."/>
<Annotation Term="OData.LongDescription" String="This property shall indicate whether configuration requests to the storage subsystem are locked. Services shall reject modification requests that contain the value `Partial`. Modifying the value of this property may affect the `ConfigurationLock` property in `Drive` resources referenced by the `Drives` property."/>
</Property>
</EntityType>
@@ -1534,8 +1705,8 @@
<EnumType Name="ConfigurationLock">
<Member Name="Enabled">
- <Annotation Term="OData.Description" String="In-band configuration requests are locked. Configuration requests include applying firmware, updating security keys, and other hardware settings. It does not include managing the volumes or data within the storage subsystem."/>
- <Annotation Term="OData.LongDescription" String="This value shall indicate in-band configuration requests are locked."/>
+ <Annotation Term="OData.Description" String="In-band configuration requests are locked as specified by `TargetConfigurationLockLevel`."/>
+ <Annotation Term="OData.LongDescription" String="This value shall indicate in-band configuration requests are locked as specified by `TargetConfigurationLockLevel`."/>
</Member>
<Member Name="Disabled">
<Annotation Term="OData.Description" String="In-band configuration requests are not locked."/>
@@ -1548,5 +1719,101 @@
</EnumType>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_16_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to update the descriptions for `ConfigurationLock` to align with the new `TargetConfigurationLockLevel` property."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_16_0.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_16_0.StorageController"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_16_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_16_1.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_16_1.StorageController"/>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_17_0">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="Redfish.Release" String="2024.2"/>
+ <Annotation Term="OData.Description" String="This version was created to add the `SetControllerPassword` action. It was also created to add `PasswordOnly`, `PasswordWithExternalKey`, and `PasswordWithLocalKey` to `EncryptionMode`."/>
+
+ <EntityType Name="Storage" BaseType="Storage.v1_16_1.Storage">
+ <Property Name="TargetConfigurationLockLevel" Type="Storage.v1_17_0.TargetConfigurationLockLevel">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ <Annotation Term="OData.Description" String="Indicates the target configuration lock level for the drive based upon the state of the `ConfigurationLock` property. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the target configuration lock level for the drive. For NVMe subsystems, services shall implement the locking requirements specified by SNIA's Swordfish NVMe Model Overview and Mapping Guide."/>
+ </Property>
+ </EntityType>
+
+ <EntityType Name="StorageController" BaseType="Storage.v1_16_1.StorageController"/>
+
+ <EnumType Name="TargetConfigurationLockLevel">
+ <Member Name="Baseline">
+ <Annotation Term="OData.Description" String="The standard configuration lock level, corresponding to applying firmware, updating security keys, and modifying other hardware settings. It does not include managing the volumes or data within the storage subsystem."/>
+ </Member>
+ </EnumType>
+
+ <EnumType Name="ConfigLockOptions">
+ <Member Name="Unlocked">
+ <Annotation Term="OData.Description" String="The command is supported, able to be locked, and is currently unlocked."/>
+ </Member>
+ <Member Name="Locked">
+ <Annotation Term="OData.Description" String="The command is supported and is currently locked."/>
+ </Member>
+ <Member Name="LockdownUnsupported">
+ <Annotation Term="OData.Description" String="The command is supported but is not able to be locked."/>
+ </Member>
+ <Member Name="CommandUnsupported">
+ <Annotation Term="OData.Description" String="The command is not supported, therefore lockdown does not apply."/>
+ </Member>
+ </EnumType>
+
+ <ComplexType Name="NVMeConfigurationLockState">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="The configurable features that are able to be locked on an NVMe subsystem and their current lock state."/>
+ <Annotation Term="OData.LongDescription" String="This type shall contain the configurable features that are able to be locked on an NVMe subsystem and their current lock state."/>
+ <Property Name="FirmwareCommit" Type="Storage.v1_17_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Firmware Commit command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Firmware Commit command."/>
+ </Property>
+ <Property Name="Lockdown" Type="Storage.v1_17_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Lockdown command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Lockdown command."/>
+ </Property>
+ <Property Name="SecuritySend" Type="Storage.v1_17_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Security Send command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Security Send command."/>
+ </Property>
+ <Property Name="FirmwareImageDownload" Type="Storage.v1_17_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-defined Firmware Image Download command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-defined Firmware Image Download command."/>
+ </Property>
+ <Property Name="VPDWrite" Type="Storage.v1_17_0.ConfigLockOptions">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The lock state of the NVMe-MI-defined VPD Write command."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the lock state of the NVMe-MI-defined VPD Write command."/>
+ </Property>
+ </ComplexType>
+
+ <ComplexType Name="NVMeSubsystemProperties" BaseType="Storage.v1_16_0.NVMeSubsystemProperties">
+ <Property Name="ConfigurationLockState" Type="Storage.v1_17_0.NVMeConfigurationLockState">
+ <Annotation Term="OData.Description" String="The configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state."/>
+ <Annotation Term="OData.LongDescription" String="This property shall contain the configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state."/>
+ </Property>
+ </ComplexType>
+ </Schema>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Storage.v1_17_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="Storage" BaseType="Storage.v1_17_0.Storage"/>
+ <EntityType Name="StorageController" BaseType="Storage.v1_17_0.StorageController"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/UpdateService_v1.xml b/redfish-core/schema/dmtf/csdl/UpdateService_v1.xml
index eddc8ea924..7c2a5ddde7 100644
--- a/redfish-core/schema/dmtf/csdl/UpdateService_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/UpdateService_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
<!--################################################################################ -->
-<!--# Redfish Schema: UpdateService v1.14.0 -->
+<!--# Redfish Schema: UpdateService v1.14.1 -->
<!--# -->
<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, -->
<!--# available at http://www.dmtf.org/standards/redfish -->
@@ -367,6 +367,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_0_10.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_0_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_0_11.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_1_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2016.3"/>
@@ -453,6 +459,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_1_11.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_1_13">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_1_12.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_2_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2017.1"/>
@@ -550,6 +562,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_2_12.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_2_14">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_2_13.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_3_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.2"/>
@@ -624,6 +642,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_3_10.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_3_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_3_11.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_4_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2018.3"/>
@@ -784,6 +808,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_4_10.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_4_12">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_4_11.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_5_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.1"/>
@@ -858,6 +888,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_5_9.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_5_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_5_10.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_6_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.2"/>
@@ -938,6 +974,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_6_9.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_6_11">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_6_10.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_7_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.3"/>
@@ -1000,6 +1042,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_7_8.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_7_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_7_9.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_8_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2019.4"/>
@@ -1068,6 +1116,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_8_8.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_8_10">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_8_9.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_9_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.1"/>
@@ -1123,6 +1177,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_9_5.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_9_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_9_6.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.2"/>
@@ -1173,6 +1233,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_10_5.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_10_7">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_10_6.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_11_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2021.4"/>
@@ -1227,6 +1293,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_11_4.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_11_6">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_11_5.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_12_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.2"/>
@@ -1258,6 +1330,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_12_1.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_12_3">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_12_2.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_13_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2023.3"/>
@@ -1309,6 +1387,12 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_13_0.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_13_2">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_13_1.UpdateService"/>
+ </Schema>
+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_14_0">
<Annotation Term="Redfish.OwningEntity" String="DMTF"/>
<Annotation Term="Redfish.Release" String="2024.1"/>
@@ -1317,5 +1401,11 @@
<EntityType Name="UpdateService" BaseType="UpdateService.v1_13_1.UpdateService"/>
</Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="UpdateService.v1_14_1">
+ <Annotation Term="Redfish.OwningEntity" String="DMTF"/>
+ <Annotation Term="OData.Description" String="This version was created to correct the OpenAPI usage of payload annotations in action request bodies."/>
+ <EntityType Name="UpdateService" BaseType="UpdateService.v1_14_0.UpdateService"/>
+ </Schema>
+
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/csdl/VolumeCollection_v1.xml b/redfish-core/schema/dmtf/csdl/VolumeCollection_v1.xml
index 1f92a236dd..74889080cf 100644
--- a/redfish-core/schema/dmtf/csdl/VolumeCollection_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/VolumeCollection_v1.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
-<!-- Copyright 2015-2023 Storage Networking Industry Association (SNIA), USA. All rights reserved.-->
+<!-- Copyright 2015-2024 Storage Networking Industry Association (SNIA), USA. All rights reserved.-->
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml">
diff --git a/redfish-core/schema/dmtf/csdl/Volume_v1.xml b/redfish-core/schema/dmtf/csdl/Volume_v1.xml
index 843979e315..8ae23da2bc 100644
--- a/redfish-core/schema/dmtf/csdl/Volume_v1.xml
+++ b/redfish-core/schema/dmtf/csdl/Volume_v1.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!---->
-<!-- Copyright 2015-2023 Storage Networking Industry Association (SNIA), USA. All rights reserved.-->
+<!-- Copyright 2015-2024 Storage Networking Industry Association (SNIA), USA. All rights reserved.-->
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
@@ -81,6 +81,9 @@
<edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Connection_v1.xml">
<edmx:Include Namespace="Connection"/>
</edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/swordfish/v1/StoragePool_v1.xml">
+ <edmx:Include Namespace="StoragePool"/>
+ </edmx:Reference>
<edmx:DataServices>
@@ -1037,12 +1040,22 @@
<Property Name="IOStatistics" Type="IOStatistics.v1_0_1.IOStatistics" Nullable="false">
<Annotation Term="OData.Description" String="Statistics for this volume."/>
<Annotation Term="OData.LongDescription" String="The value shall represent IO statistics for this volume."/>
+ <Annotation Term="Redfish.Revisions">
+ <Collection>
+ <Record>
+ <PropertyValue Property="Kind" EnumMember="Redfish.RevisionKind/Deprecated"/>
+ <PropertyValue Property="Version" String="v1_10_0"/>
+ <PropertyValue Property="Description" String="This property is deprecated in favor of the IOStatistics property in VolumeMetrics."/>
+ </Record>
+ </Collection>
+ </Annotation>
</Property>
<Property Name="RemainingCapacityPercent" Type="Edm.Int64">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The percentage of the capacity remaining in the Volume."/>
<Annotation Term="OData.LongDescription" String="If present, this value shall return {[(SUM(AllocatedBytes) - SUM(ConsumedBytes)]/SUM(AllocatedBytes)}*100 represented as an integer value."/>
</Property>
+
</EntityType>
<ComplexType Name="Links" BaseType="Volume.v1_1_0.Links">
@@ -1577,12 +1590,49 @@
</ComplexType>
</Schema>
- <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Volume.v1_10_0">
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Volume.v1_10_0">
<Annotation Term="Redfish.OwningEntity" String="SNIA"/>
- <Annotation Term="OData.Description" String="This version was created to add ChangeStripSize to the OperationType enum."/>
+ <Annotation Term="OData.Description" String="This version was created to add ChangeStripSize to the OperationType enum, add the ALUA property for Reservations, and add ProvidingStoragePool to Links. It adds SupportsMultipleNamespaceAttachments and SupportsIOPerformanceHints to NVMeNamespaceProperties. It also deprecates IOStatistics in favor of IOStatistics in VolumeMetrics."/>
<Annotation Term="Redfish.Release" String="1.2.6"/>
<EntityType Name="Volume" BaseType="Volume.v1_9_0.Volume">
+ <Property Name="ALUA" Type="Volume.v1_10_0.ALUA">
+ <Annotation Term="OData.Description" String="ALUA properties for this volume."/>
+ <Annotation Term="OData.LongDescription" String="This shall identify the ALUA properties for this volume."/>
+ </Property>
</EntityType>
+
+ <ComplexType Name="ALUA">
+ <Property Name="ANAGroupId" Type="Edm.Decimal">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="The ANA group id for this volume."/>
+ <Annotation Term="OData.LongDescription" String="This shall contain the ANA group id for this volume."/>
+ </Property>
+ </ComplexType>
+
+ <ComplexType Name="NVMeNamespaceProperties" BaseType="Volume.v1_9_0.NVMeNamespaceProperties">
+ <Annotation Term="OData.Description" String="Add the SupportsMultipathandSharing, and ReservationCapabilities properties."/>
+ <Property Name="SupportsMultipleNamespaceAttachments" Type="Edm.Boolean">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="Indicates whether the namespace may be attached to two or more controllers."/>
+ <Annotation Term="OData.LongDescription" String="This property shall indicate whether the namespace may be attached to two or more controllers."/>
+ </Property>
+ <Property Name="SupportsIOPerformanceHints" Type="Edm.Boolean">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="Indicates whether the namespace supports IO performance hints."/>
+ <Annotation Term="OData.LongDescription" String="This property shall indicate whether the namespace supports IO performance hints."/>
+ </Property>
+ </ComplexType>
+
+ <ComplexType Name="Links" BaseType="Volume.v1_9_0.Links">
+ <Annotation Term="OData.Description" String="Add the ProvidingStoragePool property."/>
+ <NavigationProperty Name="ProvidingStoragePool" Type="StoragePool.StoragePool">
+ <Annotation Term="OData.Description" String="The StoragePool resource that provides this volume resource."/>
+ <Annotation
+ Term="OData.LongDescription"
+ String="This property shall contain a pointer to the StoragePool resource that provides this volume resource."/>
+ </NavigationProperty>
+ </ComplexType>
+
</Schema>
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/dmtf/installed/AccountService_v1.xml b/redfish-core/schema/dmtf/installed/AccountService_v1.xml
new file mode 120000
index 0000000000..9849ebc11d
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/AccountService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/AccountService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ActionInfo_v1.xml b/redfish-core/schema/dmtf/installed/ActionInfo_v1.xml
new file mode 120000
index 0000000000..508724795a
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ActionInfo_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ActionInfo_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/AggregationService_v1.xml b/redfish-core/schema/dmtf/installed/AggregationService_v1.xml
new file mode 120000
index 0000000000..239ddc17bd
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/AggregationService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/AggregationService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/AggregationSourceCollection_v1.xml b/redfish-core/schema/dmtf/installed/AggregationSourceCollection_v1.xml
new file mode 120000
index 0000000000..8cd3c01e7b
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/AggregationSourceCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/AggregationSourceCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/AggregationSource_v1.xml b/redfish-core/schema/dmtf/installed/AggregationSource_v1.xml
new file mode 120000
index 0000000000..e23b9913e1
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/AggregationSource_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/AggregationSource_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Assembly_v1.xml b/redfish-core/schema/dmtf/installed/Assembly_v1.xml
new file mode 120000
index 0000000000..8f4d70aba9
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Assembly_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Assembly_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/AttributeRegistry_v1.xml b/redfish-core/schema/dmtf/installed/AttributeRegistry_v1.xml
new file mode 120000
index 0000000000..401dfa9fcf
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/AttributeRegistry_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/AttributeRegistry_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Bios_v1.xml b/redfish-core/schema/dmtf/installed/Bios_v1.xml
new file mode 120000
index 0000000000..584c785bfd
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Bios_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Bios_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/CableCollection_v1.xml b/redfish-core/schema/dmtf/installed/CableCollection_v1.xml
new file mode 120000
index 0000000000..2a81943310
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/CableCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/CableCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Cable_v1.xml b/redfish-core/schema/dmtf/installed/Cable_v1.xml
new file mode 120000
index 0000000000..6ea3721ad4
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Cable_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Cable_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/CertificateCollection_v1.xml b/redfish-core/schema/dmtf/installed/CertificateCollection_v1.xml
new file mode 120000
index 0000000000..d85147a30a
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/CertificateCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/CertificateCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/CertificateLocations_v1.xml b/redfish-core/schema/dmtf/installed/CertificateLocations_v1.xml
new file mode 120000
index 0000000000..0f686dba6e
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/CertificateLocations_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/CertificateLocations_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/CertificateService_v1.xml b/redfish-core/schema/dmtf/installed/CertificateService_v1.xml
new file mode 120000
index 0000000000..6462ef0687
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/CertificateService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/CertificateService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Certificate_v1.xml b/redfish-core/schema/dmtf/installed/Certificate_v1.xml
new file mode 120000
index 0000000000..d883b3c863
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Certificate_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Certificate_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ChassisCollection_v1.xml b/redfish-core/schema/dmtf/installed/ChassisCollection_v1.xml
new file mode 120000
index 0000000000..3521863c93
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ChassisCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ChassisCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Chassis_v1.xml b/redfish-core/schema/dmtf/installed/Chassis_v1.xml
new file mode 120000
index 0000000000..73af0874f9
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Chassis_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Chassis_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ComponentIntegrityCollection_v1.xml b/redfish-core/schema/dmtf/installed/ComponentIntegrityCollection_v1.xml
new file mode 120000
index 0000000000..11af9e5c76
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ComponentIntegrityCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ComponentIntegrityCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ComponentIntegrity_v1.xml b/redfish-core/schema/dmtf/installed/ComponentIntegrity_v1.xml
new file mode 120000
index 0000000000..7817086da2
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ComponentIntegrity_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ComponentIntegrity_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ComputerSystemCollection_v1.xml b/redfish-core/schema/dmtf/installed/ComputerSystemCollection_v1.xml
new file mode 120000
index 0000000000..7d88c794d3
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ComputerSystemCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ComputerSystemCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ComputerSystem_v1.xml b/redfish-core/schema/dmtf/installed/ComputerSystem_v1.xml
new file mode 120000
index 0000000000..f65b130961
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ComputerSystem_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ComputerSystem_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/DriveCollection_v1.xml b/redfish-core/schema/dmtf/installed/DriveCollection_v1.xml
new file mode 120000
index 0000000000..6bd9d4eada
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/DriveCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/DriveCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Drive_v1.xml b/redfish-core/schema/dmtf/installed/Drive_v1.xml
new file mode 120000
index 0000000000..8148becf45
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Drive_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Drive_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/EnvironmentMetrics_v1.xml b/redfish-core/schema/dmtf/installed/EnvironmentMetrics_v1.xml
new file mode 120000
index 0000000000..a4c82dfc0c
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/EnvironmentMetrics_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/EnvironmentMetrics_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/EthernetInterfaceCollection_v1.xml b/redfish-core/schema/dmtf/installed/EthernetInterfaceCollection_v1.xml
new file mode 120000
index 0000000000..7f03e6815f
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/EthernetInterfaceCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/EthernetInterfaceCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/EthernetInterface_v1.xml b/redfish-core/schema/dmtf/installed/EthernetInterface_v1.xml
new file mode 120000
index 0000000000..ce6e53e5bc
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/EthernetInterface_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/EthernetInterface_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/EventDestinationCollection_v1.xml b/redfish-core/schema/dmtf/installed/EventDestinationCollection_v1.xml
new file mode 120000
index 0000000000..455dcd814b
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/EventDestinationCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/EventDestinationCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/EventDestination_v1.xml b/redfish-core/schema/dmtf/installed/EventDestination_v1.xml
new file mode 120000
index 0000000000..6a6857ecfe
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/EventDestination_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/EventDestination_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/EventService_v1.xml b/redfish-core/schema/dmtf/installed/EventService_v1.xml
new file mode 120000
index 0000000000..d4e1f3ac4e
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/EventService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/EventService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Event_v1.xml b/redfish-core/schema/dmtf/installed/Event_v1.xml
new file mode 120000
index 0000000000..735dd9b121
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Event_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Event_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/FabricAdapterCollection_v1.xml b/redfish-core/schema/dmtf/installed/FabricAdapterCollection_v1.xml
new file mode 120000
index 0000000000..0b90e155b7
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/FabricAdapterCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/FabricAdapterCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/FabricAdapter_v1.xml b/redfish-core/schema/dmtf/installed/FabricAdapter_v1.xml
new file mode 120000
index 0000000000..7369fcb962
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/FabricAdapter_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/FabricAdapter_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/FanCollection_v1.xml b/redfish-core/schema/dmtf/installed/FanCollection_v1.xml
new file mode 120000
index 0000000000..37e4262bca
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/FanCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/FanCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Fan_v1.xml b/redfish-core/schema/dmtf/installed/Fan_v1.xml
new file mode 120000
index 0000000000..6ebfe2bc9e
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Fan_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Fan_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/IPAddresses_v1.xml b/redfish-core/schema/dmtf/installed/IPAddresses_v1.xml
new file mode 120000
index 0000000000..a6e00e18a5
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/IPAddresses_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/IPAddresses_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/JsonSchemaFileCollection_v1.xml b/redfish-core/schema/dmtf/installed/JsonSchemaFileCollection_v1.xml
new file mode 120000
index 0000000000..e41380190b
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/JsonSchemaFileCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/JsonSchemaFileCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/JsonSchemaFile_v1.xml b/redfish-core/schema/dmtf/installed/JsonSchemaFile_v1.xml
new file mode 120000
index 0000000000..da937f5614
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/JsonSchemaFile_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/JsonSchemaFile_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/LogEntryCollection_v1.xml b/redfish-core/schema/dmtf/installed/LogEntryCollection_v1.xml
new file mode 120000
index 0000000000..58cc333da0
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/LogEntryCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/LogEntryCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/LogEntry_v1.xml b/redfish-core/schema/dmtf/installed/LogEntry_v1.xml
new file mode 120000
index 0000000000..c8975d94a3
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/LogEntry_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/LogEntry_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/LogServiceCollection_v1.xml b/redfish-core/schema/dmtf/installed/LogServiceCollection_v1.xml
new file mode 120000
index 0000000000..26acc18b23
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/LogServiceCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/LogServiceCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/LogService_v1.xml b/redfish-core/schema/dmtf/installed/LogService_v1.xml
new file mode 120000
index 0000000000..6f198f9a6c
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/LogService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/LogService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ManagerAccountCollection_v1.xml b/redfish-core/schema/dmtf/installed/ManagerAccountCollection_v1.xml
new file mode 120000
index 0000000000..b2a92d8df7
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ManagerAccountCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ManagerAccountCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ManagerAccount_v1.xml b/redfish-core/schema/dmtf/installed/ManagerAccount_v1.xml
new file mode 120000
index 0000000000..bcc93baaa9
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ManagerAccount_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ManagerAccount_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ManagerCollection_v1.xml b/redfish-core/schema/dmtf/installed/ManagerCollection_v1.xml
new file mode 120000
index 0000000000..4dc7bad511
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ManagerCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ManagerCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ManagerDiagnosticData_v1.xml b/redfish-core/schema/dmtf/installed/ManagerDiagnosticData_v1.xml
new file mode 120000
index 0000000000..c4c1bd5bfb
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ManagerDiagnosticData_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ManagerDiagnosticData_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ManagerNetworkProtocol_v1.xml b/redfish-core/schema/dmtf/installed/ManagerNetworkProtocol_v1.xml
new file mode 120000
index 0000000000..e52500a24e
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ManagerNetworkProtocol_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ManagerNetworkProtocol_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Manager_v1.xml b/redfish-core/schema/dmtf/installed/Manager_v1.xml
new file mode 120000
index 0000000000..0cf2141696
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Manager_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Manager_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MemoryCollection_v1.xml b/redfish-core/schema/dmtf/installed/MemoryCollection_v1.xml
new file mode 120000
index 0000000000..2f60544739
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MemoryCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MemoryCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Memory_v1.xml b/redfish-core/schema/dmtf/installed/Memory_v1.xml
new file mode 120000
index 0000000000..ec2e23887c
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Memory_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Memory_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MessageRegistryCollection_v1.xml b/redfish-core/schema/dmtf/installed/MessageRegistryCollection_v1.xml
new file mode 120000
index 0000000000..c3b47431b0
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MessageRegistryCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MessageRegistryCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MessageRegistryFileCollection_v1.xml b/redfish-core/schema/dmtf/installed/MessageRegistryFileCollection_v1.xml
new file mode 120000
index 0000000000..bc584a371b
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MessageRegistryFileCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MessageRegistryFileCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MessageRegistryFile_v1.xml b/redfish-core/schema/dmtf/installed/MessageRegistryFile_v1.xml
new file mode 120000
index 0000000000..d50967d659
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MessageRegistryFile_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MessageRegistryFile_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MessageRegistry_v1.xml b/redfish-core/schema/dmtf/installed/MessageRegistry_v1.xml
new file mode 120000
index 0000000000..2da80eab3b
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MessageRegistry_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MessageRegistry_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Message_v1.xml b/redfish-core/schema/dmtf/installed/Message_v1.xml
new file mode 120000
index 0000000000..c0e6905bfd
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Message_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Message_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MetricDefinitionCollection_v1.xml b/redfish-core/schema/dmtf/installed/MetricDefinitionCollection_v1.xml
new file mode 120000
index 0000000000..ae8b26569f
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MetricDefinitionCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MetricDefinitionCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MetricDefinition_v1.xml b/redfish-core/schema/dmtf/installed/MetricDefinition_v1.xml
new file mode 120000
index 0000000000..7afb0d492e
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MetricDefinition_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MetricDefinition_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MetricReportCollection_v1.xml b/redfish-core/schema/dmtf/installed/MetricReportCollection_v1.xml
new file mode 120000
index 0000000000..f185252055
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MetricReportCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MetricReportCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MetricReportDefinitionCollection_v1.xml b/redfish-core/schema/dmtf/installed/MetricReportDefinitionCollection_v1.xml
new file mode 120000
index 0000000000..08fd092245
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MetricReportDefinitionCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MetricReportDefinitionCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MetricReportDefinition_v1.xml b/redfish-core/schema/dmtf/installed/MetricReportDefinition_v1.xml
new file mode 120000
index 0000000000..9edff1fce9
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MetricReportDefinition_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MetricReportDefinition_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/MetricReport_v1.xml b/redfish-core/schema/dmtf/installed/MetricReport_v1.xml
new file mode 120000
index 0000000000..2468470894
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/MetricReport_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/MetricReport_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/OperatingConfigCollection_v1.xml b/redfish-core/schema/dmtf/installed/OperatingConfigCollection_v1.xml
new file mode 120000
index 0000000000..ecf294fe65
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/OperatingConfigCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/OperatingConfigCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/OperatingConfig_v1.xml b/redfish-core/schema/dmtf/installed/OperatingConfig_v1.xml
new file mode 120000
index 0000000000..4436e16850
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/OperatingConfig_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/OperatingConfig_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PCIeDeviceCollection_v1.xml b/redfish-core/schema/dmtf/installed/PCIeDeviceCollection_v1.xml
new file mode 120000
index 0000000000..a396f8df4c
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PCIeDeviceCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PCIeDeviceCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PCIeDevice_v1.xml b/redfish-core/schema/dmtf/installed/PCIeDevice_v1.xml
new file mode 120000
index 0000000000..63138e7ec5
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PCIeDevice_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PCIeDevice_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PCIeFunctionCollection_v1.xml b/redfish-core/schema/dmtf/installed/PCIeFunctionCollection_v1.xml
new file mode 120000
index 0000000000..f0f3867784
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PCIeFunctionCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PCIeFunctionCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PCIeFunction_v1.xml b/redfish-core/schema/dmtf/installed/PCIeFunction_v1.xml
new file mode 120000
index 0000000000..ac95c174f3
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PCIeFunction_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PCIeFunction_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PCIeSlots_v1.xml b/redfish-core/schema/dmtf/installed/PCIeSlots_v1.xml
new file mode 120000
index 0000000000..a54245dc5d
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PCIeSlots_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PCIeSlots_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PhysicalContext_v1.xml b/redfish-core/schema/dmtf/installed/PhysicalContext_v1.xml
new file mode 120000
index 0000000000..9ba0aa4e33
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PhysicalContext_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PhysicalContext_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PortCollection_v1.xml b/redfish-core/schema/dmtf/installed/PortCollection_v1.xml
new file mode 120000
index 0000000000..db505e1316
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PortCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PortCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Port_v1.xml b/redfish-core/schema/dmtf/installed/Port_v1.xml
new file mode 120000
index 0000000000..682c035dd9
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Port_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Port_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PowerSubsystem_v1.xml b/redfish-core/schema/dmtf/installed/PowerSubsystem_v1.xml
new file mode 120000
index 0000000000..a9f85f74c0
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PowerSubsystem_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PowerSubsystem_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PowerSupplyCollection_v1.xml b/redfish-core/schema/dmtf/installed/PowerSupplyCollection_v1.xml
new file mode 120000
index 0000000000..7a0bd988c6
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PowerSupplyCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PowerSupplyCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/PowerSupply_v1.xml b/redfish-core/schema/dmtf/installed/PowerSupply_v1.xml
new file mode 120000
index 0000000000..e3fa05fb31
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/PowerSupply_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/PowerSupply_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Power_v1.xml b/redfish-core/schema/dmtf/installed/Power_v1.xml
new file mode 120000
index 0000000000..d42d5b91cf
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Power_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Power_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Privileges_v1.xml b/redfish-core/schema/dmtf/installed/Privileges_v1.xml
new file mode 120000
index 0000000000..58ed09818b
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Privileges_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Privileges_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ProcessorCollection_v1.xml b/redfish-core/schema/dmtf/installed/ProcessorCollection_v1.xml
new file mode 120000
index 0000000000..076c193235
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ProcessorCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ProcessorCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Processor_v1.xml b/redfish-core/schema/dmtf/installed/Processor_v1.xml
new file mode 120000
index 0000000000..847e83779b
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Processor_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Processor_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Protocol_v1.xml b/redfish-core/schema/dmtf/installed/Protocol_v1.xml
new file mode 120000
index 0000000000..4f2dabdc30
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Protocol_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Protocol_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/RedfishError_v1.xml b/redfish-core/schema/dmtf/installed/RedfishError_v1.xml
new file mode 120000
index 0000000000..b86dbf879a
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/RedfishError_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/RedfishError_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/RedfishExtensions_v1.xml b/redfish-core/schema/dmtf/installed/RedfishExtensions_v1.xml
new file mode 120000
index 0000000000..02915aceda
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/RedfishExtensions_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/RedfishExtensions_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Redundancy_v1.xml b/redfish-core/schema/dmtf/installed/Redundancy_v1.xml
new file mode 120000
index 0000000000..791d9e3195
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Redundancy_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Redundancy_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Resource_v1.xml b/redfish-core/schema/dmtf/installed/Resource_v1.xml
new file mode 120000
index 0000000000..6a084de561
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Resource_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Resource_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/RoleCollection_v1.xml b/redfish-core/schema/dmtf/installed/RoleCollection_v1.xml
new file mode 120000
index 0000000000..a549edd82e
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/RoleCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/RoleCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Role_v1.xml b/redfish-core/schema/dmtf/installed/Role_v1.xml
new file mode 120000
index 0000000000..a3c1af165d
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Role_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Role_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/SensorCollection_v1.xml b/redfish-core/schema/dmtf/installed/SensorCollection_v1.xml
new file mode 120000
index 0000000000..a91309ffd7
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/SensorCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/SensorCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Sensor_v1.xml b/redfish-core/schema/dmtf/installed/Sensor_v1.xml
new file mode 120000
index 0000000000..1bca82b7d3
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Sensor_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Sensor_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ServiceRoot_v1.xml b/redfish-core/schema/dmtf/installed/ServiceRoot_v1.xml
new file mode 120000
index 0000000000..8b830024d7
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ServiceRoot_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ServiceRoot_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/SessionCollection_v1.xml b/redfish-core/schema/dmtf/installed/SessionCollection_v1.xml
new file mode 120000
index 0000000000..5a5583ecc2
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/SessionCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/SessionCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/SessionService_v1.xml b/redfish-core/schema/dmtf/installed/SessionService_v1.xml
new file mode 120000
index 0000000000..12de5b2c64
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/SessionService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/SessionService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Session_v1.xml b/redfish-core/schema/dmtf/installed/Session_v1.xml
new file mode 120000
index 0000000000..7978348008
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Session_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Session_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Settings_v1.xml b/redfish-core/schema/dmtf/installed/Settings_v1.xml
new file mode 120000
index 0000000000..ce8c8c9c74
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Settings_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Settings_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/SoftwareInventoryCollection_v1.xml b/redfish-core/schema/dmtf/installed/SoftwareInventoryCollection_v1.xml
new file mode 120000
index 0000000000..0fa131241a
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/SoftwareInventoryCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/SoftwareInventoryCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/SoftwareInventory_v1.xml b/redfish-core/schema/dmtf/installed/SoftwareInventory_v1.xml
new file mode 120000
index 0000000000..0b6c50d256
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/SoftwareInventory_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/SoftwareInventory_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/StorageCollection_v1.xml b/redfish-core/schema/dmtf/installed/StorageCollection_v1.xml
new file mode 120000
index 0000000000..0a745fd25c
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/StorageCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/StorageCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/StorageControllerCollection_v1.xml b/redfish-core/schema/dmtf/installed/StorageControllerCollection_v1.xml
new file mode 120000
index 0000000000..74c6836826
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/StorageControllerCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/StorageControllerCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/StorageController_v1.xml b/redfish-core/schema/dmtf/installed/StorageController_v1.xml
new file mode 120000
index 0000000000..867e0add81
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/StorageController_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/StorageController_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Storage_v1.xml b/redfish-core/schema/dmtf/installed/Storage_v1.xml
new file mode 120000
index 0000000000..0413b80612
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Storage_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Storage_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/TaskCollection_v1.xml b/redfish-core/schema/dmtf/installed/TaskCollection_v1.xml
new file mode 120000
index 0000000000..3fd7faa5b0
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/TaskCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/TaskCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/TaskService_v1.xml b/redfish-core/schema/dmtf/installed/TaskService_v1.xml
new file mode 120000
index 0000000000..5bc812117d
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/TaskService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/TaskService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Task_v1.xml b/redfish-core/schema/dmtf/installed/Task_v1.xml
new file mode 120000
index 0000000000..f0e3a8fda7
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Task_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Task_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/TelemetryService_v1.xml b/redfish-core/schema/dmtf/installed/TelemetryService_v1.xml
new file mode 120000
index 0000000000..72e2fc81d8
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/TelemetryService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/TelemetryService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ThermalMetrics_v1.xml b/redfish-core/schema/dmtf/installed/ThermalMetrics_v1.xml
new file mode 120000
index 0000000000..80e17b9ca4
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ThermalMetrics_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ThermalMetrics_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/ThermalSubsystem_v1.xml b/redfish-core/schema/dmtf/installed/ThermalSubsystem_v1.xml
new file mode 120000
index 0000000000..e5c54bcb67
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/ThermalSubsystem_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/ThermalSubsystem_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Thermal_v1.xml b/redfish-core/schema/dmtf/installed/Thermal_v1.xml
new file mode 120000
index 0000000000..3da8640a84
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Thermal_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Thermal_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/TriggersCollection_v1.xml b/redfish-core/schema/dmtf/installed/TriggersCollection_v1.xml
new file mode 120000
index 0000000000..4a870f8208
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/TriggersCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/TriggersCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/Triggers_v1.xml b/redfish-core/schema/dmtf/installed/Triggers_v1.xml
new file mode 120000
index 0000000000..af50645621
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/Triggers_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/Triggers_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/UpdateService_v1.xml b/redfish-core/schema/dmtf/installed/UpdateService_v1.xml
new file mode 120000
index 0000000000..73f4bdebee
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/UpdateService_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/UpdateService_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/VirtualMediaCollection_v1.xml b/redfish-core/schema/dmtf/installed/VirtualMediaCollection_v1.xml
new file mode 120000
index 0000000000..e06b8374e4
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/VirtualMediaCollection_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/VirtualMediaCollection_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/installed/VirtualMedia_v1.xml b/redfish-core/schema/dmtf/installed/VirtualMedia_v1.xml
new file mode 120000
index 0000000000..6fe497a5c1
--- /dev/null
+++ b/redfish-core/schema/dmtf/installed/VirtualMedia_v1.xml
@@ -0,0 +1 @@
+../../../../redfish-core/schema/dmtf/csdl/VirtualMedia_v1.xml \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/AccountService.v1_16_0.json b/redfish-core/schema/dmtf/json-schema-installed/AccountService.v1_16_0.json
new file mode 120000
index 0000000000..1f5349b1d9
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/AccountService.v1_16_0.json
@@ -0,0 +1 @@
+../json-schema/AccountService.v1_16_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ActionInfo.v1_4_2.json b/redfish-core/schema/dmtf/json-schema-installed/ActionInfo.v1_4_2.json
new file mode 120000
index 0000000000..f139348c2f
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ActionInfo.v1_4_2.json
@@ -0,0 +1 @@
+../json-schema/ActionInfo.v1_4_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/AggregationService.v1_0_3.json b/redfish-core/schema/dmtf/json-schema-installed/AggregationService.v1_0_3.json
new file mode 120000
index 0000000000..f683467e23
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/AggregationService.v1_0_3.json
@@ -0,0 +1 @@
+../json-schema/AggregationService.v1_0_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/AggregationSource.v1_4_3.json b/redfish-core/schema/dmtf/json-schema-installed/AggregationSource.v1_4_3.json
new file mode 120000
index 0000000000..ac153926c8
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/AggregationSource.v1_4_3.json
@@ -0,0 +1 @@
+../json-schema/AggregationSource.v1_4_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/AggregationSourceCollection.json b/redfish-core/schema/dmtf/json-schema-installed/AggregationSourceCollection.json
new file mode 120000
index 0000000000..33d6bbb3e8
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/AggregationSourceCollection.json
@@ -0,0 +1 @@
+../json-schema/AggregationSourceCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Assembly.v1_5_1.json b/redfish-core/schema/dmtf/json-schema-installed/Assembly.v1_5_1.json
new file mode 120000
index 0000000000..0b09680fde
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Assembly.v1_5_1.json
@@ -0,0 +1 @@
+../json-schema/Assembly.v1_5_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/AttributeRegistry.v1_3_9.json b/redfish-core/schema/dmtf/json-schema-installed/AttributeRegistry.v1_3_9.json
new file mode 120000
index 0000000000..4ab154df25
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/AttributeRegistry.v1_3_9.json
@@ -0,0 +1 @@
+../json-schema/AttributeRegistry.v1_3_9.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Bios.v1_2_3.json b/redfish-core/schema/dmtf/json-schema-installed/Bios.v1_2_3.json
new file mode 120000
index 0000000000..339a1504a5
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Bios.v1_2_3.json
@@ -0,0 +1 @@
+../json-schema/Bios.v1_2_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Cable.v1_2_3.json b/redfish-core/schema/dmtf/json-schema-installed/Cable.v1_2_3.json
new file mode 120000
index 0000000000..7f22b35349
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Cable.v1_2_3.json
@@ -0,0 +1 @@
+../json-schema/Cable.v1_2_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/CableCollection.json b/redfish-core/schema/dmtf/json-schema-installed/CableCollection.json
new file mode 120000
index 0000000000..479292703e
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/CableCollection.json
@@ -0,0 +1 @@
+../json-schema/CableCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Certificate.v1_9_0.json b/redfish-core/schema/dmtf/json-schema-installed/Certificate.v1_9_0.json
new file mode 120000
index 0000000000..d5f7a318b3
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Certificate.v1_9_0.json
@@ -0,0 +1 @@
+../json-schema/Certificate.v1_9_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/CertificateCollection.json b/redfish-core/schema/dmtf/json-schema-installed/CertificateCollection.json
new file mode 120000
index 0000000000..725795a08c
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/CertificateCollection.json
@@ -0,0 +1 @@
+../json-schema/CertificateCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/CertificateLocations.v1_0_4.json b/redfish-core/schema/dmtf/json-schema-installed/CertificateLocations.v1_0_4.json
new file mode 120000
index 0000000000..8aae28c48d
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/CertificateLocations.v1_0_4.json
@@ -0,0 +1 @@
+../json-schema/CertificateLocations.v1_0_4.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/CertificateService.v1_0_5.json b/redfish-core/schema/dmtf/json-schema-installed/CertificateService.v1_0_5.json
new file mode 120000
index 0000000000..764f3004f1
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/CertificateService.v1_0_5.json
@@ -0,0 +1 @@
+../json-schema/CertificateService.v1_0_5.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Chassis.v1_25_2.json b/redfish-core/schema/dmtf/json-schema-installed/Chassis.v1_25_2.json
new file mode 120000
index 0000000000..d2ecd1d445
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Chassis.v1_25_2.json
@@ -0,0 +1 @@
+../json-schema/Chassis.v1_25_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ChassisCollection.json b/redfish-core/schema/dmtf/json-schema-installed/ChassisCollection.json
new file mode 120000
index 0000000000..2bffa17168
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ChassisCollection.json
@@ -0,0 +1 @@
+../json-schema/ChassisCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrity.v1_3_0.json b/redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrity.v1_3_0.json
new file mode 120000
index 0000000000..2fc75c5893
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrity.v1_3_0.json
@@ -0,0 +1 @@
+../json-schema/ComponentIntegrity.v1_3_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrityCollection.json b/redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrityCollection.json
new file mode 120000
index 0000000000..56b0a68c18
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ComponentIntegrityCollection.json
@@ -0,0 +1 @@
+../json-schema/ComponentIntegrityCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ComputerSystem.v1_23_0.json b/redfish-core/schema/dmtf/json-schema-installed/ComputerSystem.v1_23_0.json
new file mode 120000
index 0000000000..d04a109af9
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ComputerSystem.v1_23_0.json
@@ -0,0 +1 @@
+../json-schema/ComputerSystem.v1_23_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ComputerSystemCollection.json b/redfish-core/schema/dmtf/json-schema-installed/ComputerSystemCollection.json
new file mode 120000
index 0000000000..d8ceb57d6e
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ComputerSystemCollection.json
@@ -0,0 +1 @@
+../json-schema/ComputerSystemCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Drive.v1_20_1.json b/redfish-core/schema/dmtf/json-schema-installed/Drive.v1_20_1.json
new file mode 120000
index 0000000000..50e58c26a6
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Drive.v1_20_1.json
@@ -0,0 +1 @@
+../json-schema/Drive.v1_20_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/DriveCollection.json b/redfish-core/schema/dmtf/json-schema-installed/DriveCollection.json
new file mode 120000
index 0000000000..ae1058fb16
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/DriveCollection.json
@@ -0,0 +1 @@
+../json-schema/DriveCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/EnvironmentMetrics.v1_3_2.json b/redfish-core/schema/dmtf/json-schema-installed/EnvironmentMetrics.v1_3_2.json
new file mode 120000
index 0000000000..91a315b438
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/EnvironmentMetrics.v1_3_2.json
@@ -0,0 +1 @@
+../json-schema/EnvironmentMetrics.v1_3_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/EthernetInterface.v1_12_2.json b/redfish-core/schema/dmtf/json-schema-installed/EthernetInterface.v1_12_2.json
new file mode 120000
index 0000000000..e872ece78b
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/EthernetInterface.v1_12_2.json
@@ -0,0 +1 @@
+../json-schema/EthernetInterface.v1_12_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/EthernetInterfaceCollection.json b/redfish-core/schema/dmtf/json-schema-installed/EthernetInterfaceCollection.json
new file mode 120000
index 0000000000..9f9a1e0b6c
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/EthernetInterfaceCollection.json
@@ -0,0 +1 @@
+../json-schema/EthernetInterfaceCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Event.v1_11_0.json b/redfish-core/schema/dmtf/json-schema-installed/Event.v1_11_0.json
new file mode 120000
index 0000000000..8ee1a1228c
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Event.v1_11_0.json
@@ -0,0 +1 @@
+../json-schema/Event.v1_11_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/EventDestination.v1_15_0.json b/redfish-core/schema/dmtf/json-schema-installed/EventDestination.v1_15_0.json
new file mode 120000
index 0000000000..72bb075840
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/EventDestination.v1_15_0.json
@@ -0,0 +1 @@
+../json-schema/EventDestination.v1_15_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/EventDestinationCollection.json b/redfish-core/schema/dmtf/json-schema-installed/EventDestinationCollection.json
new file mode 120000
index 0000000000..33372ae10f
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/EventDestinationCollection.json
@@ -0,0 +1 @@
+../json-schema/EventDestinationCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/EventService.v1_10_2.json b/redfish-core/schema/dmtf/json-schema-installed/EventService.v1_10_2.json
new file mode 120000
index 0000000000..9d0f23117e
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/EventService.v1_10_2.json
@@ -0,0 +1 @@
+../json-schema/EventService.v1_10_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/FabricAdapter.v1_5_3.json b/redfish-core/schema/dmtf/json-schema-installed/FabricAdapter.v1_5_3.json
new file mode 120000
index 0000000000..41001946b1
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/FabricAdapter.v1_5_3.json
@@ -0,0 +1 @@
+../json-schema/FabricAdapter.v1_5_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/FabricAdapterCollection.json b/redfish-core/schema/dmtf/json-schema-installed/FabricAdapterCollection.json
new file mode 120000
index 0000000000..74c868a5c5
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/FabricAdapterCollection.json
@@ -0,0 +1 @@
+../json-schema/FabricAdapterCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Fan.v1_5_2.json b/redfish-core/schema/dmtf/json-schema-installed/Fan.v1_5_2.json
new file mode 120000
index 0000000000..dabed56730
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Fan.v1_5_2.json
@@ -0,0 +1 @@
+../json-schema/Fan.v1_5_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/FanCollection.json b/redfish-core/schema/dmtf/json-schema-installed/FanCollection.json
new file mode 120000
index 0000000000..74c0c7def5
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/FanCollection.json
@@ -0,0 +1 @@
+../json-schema/FanCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/IPAddresses.v1_1_5.json b/redfish-core/schema/dmtf/json-schema-installed/IPAddresses.v1_1_5.json
new file mode 120000
index 0000000000..9c919c8bb2
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/IPAddresses.v1_1_5.json
@@ -0,0 +1 @@
+../json-schema/IPAddresses.v1_1_5.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFile.v1_1_5.json b/redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFile.v1_1_5.json
new file mode 120000
index 0000000000..89134f4ad7
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFile.v1_1_5.json
@@ -0,0 +1 @@
+../json-schema/JsonSchemaFile.v1_1_5.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFileCollection.json b/redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFileCollection.json
new file mode 120000
index 0000000000..1f6852cd9d
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/JsonSchemaFileCollection.json
@@ -0,0 +1 @@
+../json-schema/JsonSchemaFileCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/LogEntry.v1_17_0.json b/redfish-core/schema/dmtf/json-schema-installed/LogEntry.v1_17_0.json
new file mode 120000
index 0000000000..a6a36cf507
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/LogEntry.v1_17_0.json
@@ -0,0 +1 @@
+../json-schema/LogEntry.v1_17_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/LogEntryCollection.json b/redfish-core/schema/dmtf/json-schema-installed/LogEntryCollection.json
new file mode 120000
index 0000000000..f3b2617d60
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/LogEntryCollection.json
@@ -0,0 +1 @@
+../json-schema/LogEntryCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/LogService.v1_7_0.json b/redfish-core/schema/dmtf/json-schema-installed/LogService.v1_7_0.json
new file mode 120000
index 0000000000..a4cdd0daf2
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/LogService.v1_7_0.json
@@ -0,0 +1 @@
+../json-schema/LogService.v1_7_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/LogServiceCollection.json b/redfish-core/schema/dmtf/json-schema-installed/LogServiceCollection.json
new file mode 120000
index 0000000000..44c68567b6
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/LogServiceCollection.json
@@ -0,0 +1 @@
+../json-schema/LogServiceCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Manager.v1_19_2.json b/redfish-core/schema/dmtf/json-schema-installed/Manager.v1_19_2.json
new file mode 120000
index 0000000000..1a7077db5c
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Manager.v1_19_2.json
@@ -0,0 +1 @@
+../json-schema/Manager.v1_19_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ManagerAccount.v1_13_0.json b/redfish-core/schema/dmtf/json-schema-installed/ManagerAccount.v1_13_0.json
new file mode 120000
index 0000000000..941aeb7a18
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ManagerAccount.v1_13_0.json
@@ -0,0 +1 @@
+../json-schema/ManagerAccount.v1_13_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ManagerAccountCollection.json b/redfish-core/schema/dmtf/json-schema-installed/ManagerAccountCollection.json
new file mode 120000
index 0000000000..54df2616c1
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ManagerAccountCollection.json
@@ -0,0 +1 @@
+../json-schema/ManagerAccountCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ManagerCollection.json b/redfish-core/schema/dmtf/json-schema-installed/ManagerCollection.json
new file mode 120000
index 0000000000..3bdc7d70a6
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ManagerCollection.json
@@ -0,0 +1 @@
+../json-schema/ManagerCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ManagerDiagnosticData.v1_2_3.json b/redfish-core/schema/dmtf/json-schema-installed/ManagerDiagnosticData.v1_2_3.json
new file mode 120000
index 0000000000..720a958e5e
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ManagerDiagnosticData.v1_2_3.json
@@ -0,0 +1 @@
+../json-schema/ManagerDiagnosticData.v1_2_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ManagerNetworkProtocol.v1_10_1.json b/redfish-core/schema/dmtf/json-schema-installed/ManagerNetworkProtocol.v1_10_1.json
new file mode 120000
index 0000000000..d50f4183e6
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ManagerNetworkProtocol.v1_10_1.json
@@ -0,0 +1 @@
+../json-schema/ManagerNetworkProtocol.v1_10_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Memory.v1_20_0.json b/redfish-core/schema/dmtf/json-schema-installed/Memory.v1_20_0.json
new file mode 120000
index 0000000000..7664900c50
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Memory.v1_20_0.json
@@ -0,0 +1 @@
+../json-schema/Memory.v1_20_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MemoryCollection.json b/redfish-core/schema/dmtf/json-schema-installed/MemoryCollection.json
new file mode 120000
index 0000000000..e2181fc495
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MemoryCollection.json
@@ -0,0 +1 @@
+../json-schema/MemoryCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Message.v1_3_0.json b/redfish-core/schema/dmtf/json-schema-installed/Message.v1_3_0.json
new file mode 120000
index 0000000000..48801a77c6
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Message.v1_3_0.json
@@ -0,0 +1 @@
+../json-schema/Message.v1_3_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MessageRegistry.v1_6_3.json b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistry.v1_6_3.json
new file mode 120000
index 0000000000..f567b49026
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistry.v1_6_3.json
@@ -0,0 +1 @@
+../json-schema/MessageRegistry.v1_6_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryCollection.json b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryCollection.json
new file mode 120000
index 0000000000..216c60dc8a
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryCollection.json
@@ -0,0 +1 @@
+../json-schema/MessageRegistryCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFile.v1_1_5.json b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFile.v1_1_5.json
new file mode 120000
index 0000000000..646824ec00
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFile.v1_1_5.json
@@ -0,0 +1 @@
+../json-schema/MessageRegistryFile.v1_1_5.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFileCollection.json b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFileCollection.json
new file mode 120000
index 0000000000..c9ae434a22
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MessageRegistryFileCollection.json
@@ -0,0 +1 @@
+../json-schema/MessageRegistryFileCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MetricDefinition.v1_3_4.json b/redfish-core/schema/dmtf/json-schema-installed/MetricDefinition.v1_3_4.json
new file mode 120000
index 0000000000..cd4567cc87
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MetricDefinition.v1_3_4.json
@@ -0,0 +1 @@
+../json-schema/MetricDefinition.v1_3_4.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MetricDefinitionCollection.json b/redfish-core/schema/dmtf/json-schema-installed/MetricDefinitionCollection.json
new file mode 120000
index 0000000000..b60e963734
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MetricDefinitionCollection.json
@@ -0,0 +1 @@
+../json-schema/MetricDefinitionCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MetricReport.v1_5_2.json b/redfish-core/schema/dmtf/json-schema-installed/MetricReport.v1_5_2.json
new file mode 120000
index 0000000000..6dc28aa5f7
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MetricReport.v1_5_2.json
@@ -0,0 +1 @@
+../json-schema/MetricReport.v1_5_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MetricReportCollection.json b/redfish-core/schema/dmtf/json-schema-installed/MetricReportCollection.json
new file mode 120000
index 0000000000..30f0e19527
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MetricReportCollection.json
@@ -0,0 +1 @@
+../json-schema/MetricReportCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinition.v1_4_6.json b/redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinition.v1_4_6.json
new file mode 120000
index 0000000000..f95c542bbc
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinition.v1_4_6.json
@@ -0,0 +1 @@
+../json-schema/MetricReportDefinition.v1_4_6.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinitionCollection.json b/redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinitionCollection.json
new file mode 120000
index 0000000000..90e6d720a1
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/MetricReportDefinitionCollection.json
@@ -0,0 +1 @@
+../json-schema/MetricReportDefinitionCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/OperatingConfig.v1_0_4.json b/redfish-core/schema/dmtf/json-schema-installed/OperatingConfig.v1_0_4.json
new file mode 120000
index 0000000000..188a31b239
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/OperatingConfig.v1_0_4.json
@@ -0,0 +1 @@
+../json-schema/OperatingConfig.v1_0_4.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/OperatingConfigCollection.json b/redfish-core/schema/dmtf/json-schema-installed/OperatingConfigCollection.json
new file mode 120000
index 0000000000..520c1de7f3
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/OperatingConfigCollection.json
@@ -0,0 +1 @@
+../json-schema/OperatingConfigCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PCIeDevice.v1_16_0.json b/redfish-core/schema/dmtf/json-schema-installed/PCIeDevice.v1_16_0.json
new file mode 120000
index 0000000000..1d18d93152
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PCIeDevice.v1_16_0.json
@@ -0,0 +1 @@
+../json-schema/PCIeDevice.v1_16_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PCIeDeviceCollection.json b/redfish-core/schema/dmtf/json-schema-installed/PCIeDeviceCollection.json
new file mode 120000
index 0000000000..03238f4b8d
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PCIeDeviceCollection.json
@@ -0,0 +1 @@
+../json-schema/PCIeDeviceCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PCIeFunction.v1_6_0.json b/redfish-core/schema/dmtf/json-schema-installed/PCIeFunction.v1_6_0.json
new file mode 120000
index 0000000000..011b554920
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PCIeFunction.v1_6_0.json
@@ -0,0 +1 @@
+../json-schema/PCIeFunction.v1_6_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PCIeFunctionCollection.json b/redfish-core/schema/dmtf/json-schema-installed/PCIeFunctionCollection.json
new file mode 120000
index 0000000000..c4089cb6df
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PCIeFunctionCollection.json
@@ -0,0 +1 @@
+../json-schema/PCIeFunctionCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PCIeSlots.v1_6_1.json b/redfish-core/schema/dmtf/json-schema-installed/PCIeSlots.v1_6_1.json
new file mode 120000
index 0000000000..185e0ab0ce
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PCIeSlots.v1_6_1.json
@@ -0,0 +1 @@
+../json-schema/PCIeSlots.v1_6_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PhysicalContext.json b/redfish-core/schema/dmtf/json-schema-installed/PhysicalContext.json
new file mode 120000
index 0000000000..6a8842394e
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PhysicalContext.json
@@ -0,0 +1 @@
+../json-schema/PhysicalContext.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Port.v1_14_0.json b/redfish-core/schema/dmtf/json-schema-installed/Port.v1_14_0.json
new file mode 120000
index 0000000000..23cee15785
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Port.v1_14_0.json
@@ -0,0 +1 @@
+../json-schema/Port.v1_14_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PortCollection.json b/redfish-core/schema/dmtf/json-schema-installed/PortCollection.json
new file mode 120000
index 0000000000..53c76df0bf
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PortCollection.json
@@ -0,0 +1 @@
+../json-schema/PortCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Power.v1_7_3.json b/redfish-core/schema/dmtf/json-schema-installed/Power.v1_7_3.json
new file mode 120000
index 0000000000..392e70e660
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Power.v1_7_3.json
@@ -0,0 +1 @@
+../json-schema/Power.v1_7_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PowerSubsystem.v1_1_2.json b/redfish-core/schema/dmtf/json-schema-installed/PowerSubsystem.v1_1_2.json
new file mode 120000
index 0000000000..192e77f8ad
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PowerSubsystem.v1_1_2.json
@@ -0,0 +1 @@
+../json-schema/PowerSubsystem.v1_1_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PowerSupply.v1_6_0.json b/redfish-core/schema/dmtf/json-schema-installed/PowerSupply.v1_6_0.json
new file mode 120000
index 0000000000..0f30446058
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PowerSupply.v1_6_0.json
@@ -0,0 +1 @@
+../json-schema/PowerSupply.v1_6_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/PowerSupplyCollection.json b/redfish-core/schema/dmtf/json-schema-installed/PowerSupplyCollection.json
new file mode 120000
index 0000000000..becf5d4128
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/PowerSupplyCollection.json
@@ -0,0 +1 @@
+../json-schema/PowerSupplyCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Privileges.v1_0_6.json b/redfish-core/schema/dmtf/json-schema-installed/Privileges.v1_0_6.json
new file mode 120000
index 0000000000..50717baed0
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Privileges.v1_0_6.json
@@ -0,0 +1 @@
+../json-schema/Privileges.v1_0_6.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Processor.v1_20_1.json b/redfish-core/schema/dmtf/json-schema-installed/Processor.v1_20_1.json
new file mode 120000
index 0000000000..5df4e28dc1
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Processor.v1_20_1.json
@@ -0,0 +1 @@
+../json-schema/Processor.v1_20_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ProcessorCollection.json b/redfish-core/schema/dmtf/json-schema-installed/ProcessorCollection.json
new file mode 120000
index 0000000000..31fde443f6
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ProcessorCollection.json
@@ -0,0 +1 @@
+../json-schema/ProcessorCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Protocol.json b/redfish-core/schema/dmtf/json-schema-installed/Protocol.json
new file mode 120000
index 0000000000..dc91202d83
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Protocol.json
@@ -0,0 +1 @@
+../json-schema/Protocol.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Redundancy.v1_4_2.json b/redfish-core/schema/dmtf/json-schema-installed/Redundancy.v1_4_2.json
new file mode 120000
index 0000000000..8021dbad3f
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Redundancy.v1_4_2.json
@@ -0,0 +1 @@
+../json-schema/Redundancy.v1_4_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Resource.v1_20_0.json b/redfish-core/schema/dmtf/json-schema-installed/Resource.v1_20_0.json
new file mode 120000
index 0000000000..f0217ef197
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Resource.v1_20_0.json
@@ -0,0 +1 @@
+../json-schema/Resource.v1_20_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Role.v1_3_2.json b/redfish-core/schema/dmtf/json-schema-installed/Role.v1_3_2.json
new file mode 120000
index 0000000000..7087dc481f
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Role.v1_3_2.json
@@ -0,0 +1 @@
+../json-schema/Role.v1_3_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/RoleCollection.json b/redfish-core/schema/dmtf/json-schema-installed/RoleCollection.json
new file mode 120000
index 0000000000..3f677e55bd
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/RoleCollection.json
@@ -0,0 +1 @@
+../json-schema/RoleCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Sensor.v1_10_1.json b/redfish-core/schema/dmtf/json-schema-installed/Sensor.v1_10_1.json
new file mode 120000
index 0000000000..e8c9891714
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Sensor.v1_10_1.json
@@ -0,0 +1 @@
+../json-schema/Sensor.v1_10_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/SensorCollection.json b/redfish-core/schema/dmtf/json-schema-installed/SensorCollection.json
new file mode 120000
index 0000000000..9588c8dce3
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/SensorCollection.json
@@ -0,0 +1 @@
+../json-schema/SensorCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ServiceRoot.v1_17_0.json b/redfish-core/schema/dmtf/json-schema-installed/ServiceRoot.v1_17_0.json
new file mode 120000
index 0000000000..70647b8264
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ServiceRoot.v1_17_0.json
@@ -0,0 +1 @@
+../json-schema/ServiceRoot.v1_17_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Session.v1_7_2.json b/redfish-core/schema/dmtf/json-schema-installed/Session.v1_7_2.json
new file mode 120000
index 0000000000..9db71ce092
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Session.v1_7_2.json
@@ -0,0 +1 @@
+../json-schema/Session.v1_7_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/SessionCollection.json b/redfish-core/schema/dmtf/json-schema-installed/SessionCollection.json
new file mode 120000
index 0000000000..482be729d0
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/SessionCollection.json
@@ -0,0 +1 @@
+../json-schema/SessionCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/SessionService.v1_1_9.json b/redfish-core/schema/dmtf/json-schema-installed/SessionService.v1_1_9.json
new file mode 120000
index 0000000000..b7ecdb18d0
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/SessionService.v1_1_9.json
@@ -0,0 +1 @@
+../json-schema/SessionService.v1_1_9.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Settings.v1_4_0.json b/redfish-core/schema/dmtf/json-schema-installed/Settings.v1_4_0.json
new file mode 120000
index 0000000000..61800c6a38
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Settings.v1_4_0.json
@@ -0,0 +1 @@
+../json-schema/Settings.v1_4_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/SoftwareInventory.v1_10_2.json b/redfish-core/schema/dmtf/json-schema-installed/SoftwareInventory.v1_10_2.json
new file mode 120000
index 0000000000..63482ec1b4
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/SoftwareInventory.v1_10_2.json
@@ -0,0 +1 @@
+../json-schema/SoftwareInventory.v1_10_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/SoftwareInventoryCollection.json b/redfish-core/schema/dmtf/json-schema-installed/SoftwareInventoryCollection.json
new file mode 120000
index 0000000000..558b123646
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/SoftwareInventoryCollection.json
@@ -0,0 +1 @@
+../json-schema/SoftwareInventoryCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Storage.v1_17_1.json b/redfish-core/schema/dmtf/json-schema-installed/Storage.v1_17_1.json
new file mode 120000
index 0000000000..2aa6ef71e1
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Storage.v1_17_1.json
@@ -0,0 +1 @@
+../json-schema/Storage.v1_17_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/StorageCollection.json b/redfish-core/schema/dmtf/json-schema-installed/StorageCollection.json
new file mode 120000
index 0000000000..fc3b30a52c
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/StorageCollection.json
@@ -0,0 +1 @@
+../json-schema/StorageCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/StorageController.v1_8_0.json b/redfish-core/schema/dmtf/json-schema-installed/StorageController.v1_8_0.json
new file mode 120000
index 0000000000..91d59fc408
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/StorageController.v1_8_0.json
@@ -0,0 +1 @@
+../json-schema/StorageController.v1_8_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/StorageControllerCollection.json b/redfish-core/schema/dmtf/json-schema-installed/StorageControllerCollection.json
new file mode 120000
index 0000000000..0bb5dbb244
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/StorageControllerCollection.json
@@ -0,0 +1 @@
+../json-schema/StorageControllerCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Task.v1_7_4.json b/redfish-core/schema/dmtf/json-schema-installed/Task.v1_7_4.json
new file mode 120000
index 0000000000..09806fa1e9
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Task.v1_7_4.json
@@ -0,0 +1 @@
+../json-schema/Task.v1_7_4.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/TaskCollection.json b/redfish-core/schema/dmtf/json-schema-installed/TaskCollection.json
new file mode 120000
index 0000000000..d4c4263ba7
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/TaskCollection.json
@@ -0,0 +1 @@
+../json-schema/TaskCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/TaskService.v1_2_1.json b/redfish-core/schema/dmtf/json-schema-installed/TaskService.v1_2_1.json
new file mode 120000
index 0000000000..a154afd22f
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/TaskService.v1_2_1.json
@@ -0,0 +1 @@
+../json-schema/TaskService.v1_2_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/TelemetryService.v1_3_4.json b/redfish-core/schema/dmtf/json-schema-installed/TelemetryService.v1_3_4.json
new file mode 120000
index 0000000000..529a2d410c
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/TelemetryService.v1_3_4.json
@@ -0,0 +1 @@
+../json-schema/TelemetryService.v1_3_4.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Thermal.v1_7_3.json b/redfish-core/schema/dmtf/json-schema-installed/Thermal.v1_7_3.json
new file mode 120000
index 0000000000..89282135c1
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Thermal.v1_7_3.json
@@ -0,0 +1 @@
+../json-schema/Thermal.v1_7_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ThermalMetrics.v1_3_2.json b/redfish-core/schema/dmtf/json-schema-installed/ThermalMetrics.v1_3_2.json
new file mode 120000
index 0000000000..e900949077
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ThermalMetrics.v1_3_2.json
@@ -0,0 +1 @@
+../json-schema/ThermalMetrics.v1_3_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/ThermalSubsystem.v1_3_2.json b/redfish-core/schema/dmtf/json-schema-installed/ThermalSubsystem.v1_3_2.json
new file mode 120000
index 0000000000..5f7396342d
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/ThermalSubsystem.v1_3_2.json
@@ -0,0 +1 @@
+../json-schema/ThermalSubsystem.v1_3_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/Triggers.v1_4_0.json b/redfish-core/schema/dmtf/json-schema-installed/Triggers.v1_4_0.json
new file mode 120000
index 0000000000..44f626f554
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/Triggers.v1_4_0.json
@@ -0,0 +1 @@
+../json-schema/Triggers.v1_4_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/TriggersCollection.json b/redfish-core/schema/dmtf/json-schema-installed/TriggersCollection.json
new file mode 120000
index 0000000000..5e6bbba9ac
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/TriggersCollection.json
@@ -0,0 +1 @@
+../json-schema/TriggersCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/UpdateService.v1_14_1.json b/redfish-core/schema/dmtf/json-schema-installed/UpdateService.v1_14_1.json
new file mode 120000
index 0000000000..ac104c4451
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/UpdateService.v1_14_1.json
@@ -0,0 +1 @@
+../json-schema/UpdateService.v1_14_1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/VirtualMedia.v1_6_4.json b/redfish-core/schema/dmtf/json-schema-installed/VirtualMedia.v1_6_4.json
new file mode 120000
index 0000000000..8b7032e0a8
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/VirtualMedia.v1_6_4.json
@@ -0,0 +1 @@
+../json-schema/VirtualMedia.v1_6_4.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/VirtualMediaCollection.json b/redfish-core/schema/dmtf/json-schema-installed/VirtualMediaCollection.json
new file mode 120000
index 0000000000..76ca0ef7e3
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/VirtualMediaCollection.json
@@ -0,0 +1 @@
+../json-schema/VirtualMediaCollection.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/odata-v4.json b/redfish-core/schema/dmtf/json-schema-installed/odata-v4.json
new file mode 120000
index 0000000000..63af96e359
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/odata-v4.json
@@ -0,0 +1 @@
+../json-schema/odata-v4.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/odata.v4_0_5.json b/redfish-core/schema/dmtf/json-schema-installed/odata.v4_0_5.json
new file mode 120000
index 0000000000..e25f354569
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/odata.v4_0_5.json
@@ -0,0 +1 @@
+../json-schema/odata.v4_0_5.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/redfish-error.v1_0_2.json b/redfish-core/schema/dmtf/json-schema-installed/redfish-error.v1_0_2.json
new file mode 120000
index 0000000000..df50b05c56
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/redfish-error.v1_0_2.json
@@ -0,0 +1 @@
+../json-schema/redfish-error.v1_0_2.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/redfish-payload-annotations.v1_2_3.json b/redfish-core/schema/dmtf/json-schema-installed/redfish-payload-annotations.v1_2_3.json
new file mode 120000
index 0000000000..2ff1e8f5e5
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/redfish-payload-annotations.v1_2_3.json
@@ -0,0 +1 @@
+../json-schema/redfish-payload-annotations.v1_2_3.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/redfish-schema-v1.json b/redfish-core/schema/dmtf/json-schema-installed/redfish-schema-v1.json
new file mode 120000
index 0000000000..d80643cf27
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/redfish-schema-v1.json
@@ -0,0 +1 @@
+../json-schema/redfish-schema-v1.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema-installed/redfish-schema.v1_10_0.json b/redfish-core/schema/dmtf/json-schema-installed/redfish-schema.v1_10_0.json
new file mode 120000
index 0000000000..56d4f75476
--- /dev/null
+++ b/redfish-core/schema/dmtf/json-schema-installed/redfish-schema.v1_10_0.json
@@ -0,0 +1 @@
+../json-schema/redfish-schema.v1_10_0.json \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/AccountService.v1_15_1.json b/redfish-core/schema/dmtf/json-schema/AccountService.v1_16_0.json
index f168806321..fbb79f8db2 100644
--- a/redfish-core/schema/dmtf/json-schema/AccountService.v1_15_1.json
+++ b/redfish-core/schema/dmtf/json-schema/AccountService.v1_16_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/AccountService.v1_15_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/AccountService.v1_16_0.json",
"$ref": "#/definitions/AccountService",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -1074,7 +1074,7 @@
"type": "null"
}
],
- "description": "The settings related to Google Authenticator multi-factor authentication.",
+ "description": "The settings related to Google Authenticator multi-factor authentication. For generic Time-Based One-Time Password (TOTP) multi-factor authentication, use the `TimeBasedOneTimePassword` property.",
"longDescription": "This property shall contain the settings related to Google Authenticator multi-factor authentication.",
"versionAdded": "v1_12_0"
},
@@ -1087,7 +1087,7 @@
"type": "null"
}
],
- "description": "The settings related to Microsoft Authenticator multi-factor authentication.",
+ "description": "The settings related to Microsoft Authenticator multi-factor authentication. For generic Time-Based One-Time Password (TOTP) multi-factor authentication, use the `TimeBasedOneTimePassword` property.",
"longDescription": "This property shall contain the settings related to Microsoft Authenticator multi-factor authentication.",
"versionAdded": "v1_12_0"
},
@@ -1116,6 +1116,19 @@
"description": "The settings related to RSA SecurID multi-factor authentication.",
"longDescription": "This property shall contain the settings related to RSA SecurID multi-factor authentication.",
"versionAdded": "v1_12_0"
+ },
+ "TimeBasedOneTimePassword": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/TimeBasedOneTimePassword"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The settings related to Time-based One-Time Password (TOTP) multi-factor authentication.",
+ "longDescription": "This property shall contain the settings related to RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication.",
+ "versionAdded": "v1_16_0"
}
},
"type": "object"
@@ -1272,6 +1285,36 @@
}
},
"properties": {
+ "LocalAccountTypes": {
+ "description": "The list of local services in the manager that the remote user or group is allowed to access.",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "http://redfish.dmtf.org/schemas/v1/ManagerAccount.json#/definitions/AccountTypes"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "longDescription": "This property shall contain an array of the various local manager services that the remote user or group is allowed to access. This shall not include functionality for receiving events or other notifications. If this property is not supported, the value shall be assumed to be an array that contains the value `Redfish`.",
+ "readonly": false,
+ "type": "array",
+ "versionAdded": "v1_16_0"
+ },
+ "LocalOEMAccountTypes": {
+ "description": "The OEM account types for the remote user or group.",
+ "items": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "longDescription": "This property shall contain an array of the OEM account types for the remote user or group when `LocalAccountTypes` contains `OEM`.",
+ "readonly": false,
+ "type": "array",
+ "versionAdded": "v1_16_0"
+ },
"LocalRole": {
"description": "The name of the local Redfish role to which to map the remote user or group.",
"longDescription": "This property shall contain the `RoleId` property value within a role resource on this Redfish service to which to map the remote user or group.",
@@ -1486,10 +1529,53 @@
}
},
"type": "object"
+ },
+ "TimeBasedOneTimePassword": {
+ "additionalProperties": false,
+ "description": "Various settings for Time-based One-Time Password (TOTP) multi-factor authentication.",
+ "longDescription": "This type shall contain settings for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication.",
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "Enabled": {
+ "description": "An indication of whether multi-factor authentication with a Time-based One-Time Password (TOTP) is enabled.",
+ "longDescription": "This property shall indicate whether multi-factor authentication with an RFC6238-defined Time-based One-Time Password (TOTP) is enabled.",
+ "readonly": false,
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "versionAdded": "v1_16_0"
+ },
+ "TimeStepSeconds": {
+ "description": "The time step, in seconds, for calculating the one-time password.",
+ "longDescription": "This property shall contain the RFC6238-defined time step, in seconds, for calculating the one-time password. If this property is not supported by the service, it shall be assumed to be `30`.",
+ "minimum": 1,
+ "readonly": false,
+ "type": [
+ "integer",
+ "null"
+ ],
+ "versionAdded": "v1_16_0"
+ }
+ },
+ "type": "object"
}
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.3",
- "title": "#AccountService.v1_15_1.AccountService"
+ "release": "2024.3",
+ "title": "#AccountService.v1_16_0.AccountService"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/AggregationSource.v1_4_1.json b/redfish-core/schema/dmtf/json-schema/AggregationSource.v1_4_3.json
index 9afec896d8..b7b697b915 100644
--- a/redfish-core/schema/dmtf/json-schema/AggregationSource.v1_4_1.json
+++ b/redfish-core/schema/dmtf/json-schema/AggregationSource.v1_4_3.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/AggregationSource.v1_4_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/AggregationSource.v1_4_3.json",
"$ref": "#/definitions/AggregationSource",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -251,8 +251,8 @@
"properties": {
"ConnectionMethod": {
"$ref": "http://redfish.dmtf.org/schemas/v1/ConnectionMethod.json#/definitions/ConnectionMethod",
- "description": "An array of links to the connection methods used to contact this aggregation source.",
- "longDescription": "This property shall contain an array of links to resources of type `ConnectionMethod` that are used to connect to the aggregation source.",
+ "description": "A link to the connection method used to contact this aggregation source.",
+ "longDescription": "This property shall a link to a resource of type `ConnectionMethod` that represents the method used to connect to the aggregation source.",
"readonly": true
},
"Oem": {
@@ -411,8 +411,8 @@
"properties": {
"AuthenticationKey": {
"description": "The secret authentication key for SNMPv3.",
- "longDescription": "This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark.",
- "pattern": "(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\\*+$)",
+ "longDescription": "This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414.",
+ "pattern": "(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{24,96}$)|(^\\*+$)",
"readonly": false,
"type": [
"string",
@@ -444,8 +444,8 @@
},
"EncryptionKey": {
"description": "The secret authentication key for SNMPv3.",
- "longDescription": "This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark.",
- "pattern": "(^[A-Za-z0-9]+$)|(^\\*+$)",
+ "longDescription": "This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414.",
+ "pattern": "(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{16,64}$)|(^\\*+$)",
"readonly": false,
"type": [
"string",
@@ -576,5 +576,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2023.3",
- "title": "#AggregationSource.v1_4_1.AggregationSource"
+ "title": "#AggregationSource.v1_4_3.AggregationSource"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/CXLLogicalDevice.v1_2_0.json b/redfish-core/schema/dmtf/json-schema/CXLLogicalDevice.v1_2_1.json
index 26807b4b2d..4f4e69c10c 100644
--- a/redfish-core/schema/dmtf/json-schema/CXLLogicalDevice.v1_2_0.json
+++ b/redfish-core/schema/dmtf/json-schema/CXLLogicalDevice.v1_2_1.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/CXLLogicalDevice.v1_2_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/CXLLogicalDevice.v1_2_1.json",
"$ref": "#/definitions/CXLLogicalDevice",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -109,8 +109,8 @@
"versionAdded": "v1_1_0"
},
"MemorySizeMiB": {
- "description": "The memory region size defined in this CXL logical device.",
- "longDescription": "This property shall contain the memory region size defined in this CXL logical device in mebibytes (MiB).",
+ "description": "The total memory capacity currently available in this CXL logical device.",
+ "longDescription": "This property shall contain the total memory capacity currently available in this CXL logical device in mebibytes (MiB). This value shall equate to the sum of the dynamic capacity extents and the static capacity assigned to this logical device.",
"readonly": true,
"type": "integer",
"units": "MiBy"
@@ -363,5 +363,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2024.1",
- "title": "#CXLLogicalDevice.v1_2_0.CXLLogicalDevice"
+ "title": "#CXLLogicalDevice.v1_2_1.CXLLogicalDevice"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Certificate.v1_8_2.json b/redfish-core/schema/dmtf/json-schema/Certificate.v1_9_0.json
index 79f75950a5..5ddf3f2733 100644
--- a/redfish-core/schema/dmtf/json-schema/Certificate.v1_8_2.json
+++ b/redfish-core/schema/dmtf/json-schema/Certificate.v1_9_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Certificate.v1_8_2.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Certificate.v1_9_0.json",
"$ref": "#/definitions/Certificate",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -75,7 +75,7 @@
},
"CertificateString": {
"description": "The string for the certificate.",
- "longDescription": "This property shall contain the certificate, and the format shall follow the requirements specified by the `CertificateType` property value. If the certificate contains any private keys, they shall be removed from the string in responses. If the service does not know the private key for the certificate and is needed to use the certificate, the client shall provide the private key as part of the string in the `POST` request.",
+ "longDescription": "This property shall contain the certificate, and the format shall follow the requirements specified by the `CertificateType` property value. If the certificate contains any private keys, they shall be removed from the string in responses. If the service does not know the private key for the certificate and is needed to use the certificate, the client shall provide the private key as part of the string in the `POST` request. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true,
"type": [
"string",
@@ -92,7 +92,7 @@
}
],
"description": "The format of the certificate.",
- "longDescription": "This property shall contain the format type for the certificate.",
+ "longDescription": "This property shall contain the format type for the certificate. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true
},
"CertificateUsageTypes": {
@@ -253,11 +253,13 @@
"IDevID",
"LDevID",
"IAK",
- "LAK"
+ "LAK",
+ "EK"
],
"enumDescriptions": {
"BIOS": "This certificate is a BIOS certificate like those associated with UEFI.",
"Device": "This certificate is a device type certificate like those associated with SPDM and other standards.",
+ "EK": "This certificate is an EK certificate like those associated with TCG TPMs.",
"IAK": "This certificate is an IAK certificate like those associated with TCG TPMs.",
"IDevID": "This certificate is an IDevID certificate like those associated with TCG TPMs.",
"LAK": "This certificate is an LAK certificate like those associated with TCG TPMs.",
@@ -268,6 +270,7 @@
"Web": "This certificate is a web or HTTPS certificate like those used for event destinations."
},
"enumVersionAdded": {
+ "EK": "v1_9_0",
"IAK": "v1_8_0",
"IDevID": "v1_8_0",
"LAK": "v1_8_0",
@@ -693,6 +696,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.2",
- "title": "#Certificate.v1_8_2.Certificate"
+ "release": "2024.3",
+ "title": "#Certificate.v1_9_0.Certificate"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Chassis.v1_25_1.json b/redfish-core/schema/dmtf/json-schema/Chassis.v1_25_2.json
index bdfe1db5d4..6c7ca8393f 100644
--- a/redfish-core/schema/dmtf/json-schema/Chassis.v1_25_1.json
+++ b/redfish-core/schema/dmtf/json-schema/Chassis.v1_25_2.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Chassis.v1_25_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Chassis.v1_25_2.json",
"$ref": "#/definitions/Chassis",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -171,7 +171,7 @@
"EnvironmentMetrics": {
"$ref": "http://redfish.dmtf.org/schemas/v1/EnvironmentMetrics.json#/definitions/EnvironmentMetrics",
"description": "The link to the environment metrics for this chassis.",
- "longDescription": "This property shall contain a link to a resource of type `EnvironmentMetrics` that specifies the environment metrics for this chassis.",
+ "longDescription": "This property shall contain a link to a resource of type `EnvironmentMetrics` that specifies the environment metrics for this chassis, all containing chassis, and devices contained by any of these chassis instances. When determining power and energy readings, care should be taken to ensure any reported values do not overlap or result in double-counting.",
"readonly": true,
"versionAdded": "v1_15_0"
},
@@ -1302,5 +1302,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2023.3",
- "title": "#Chassis.v1_25_1.Chassis"
+ "title": "#Chassis.v1_25_2.Chassis"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Circuit.v1_8_0.json b/redfish-core/schema/dmtf/json-schema/Circuit.v1_8_1.json
index fb5d58b256..67654d3cc0 100644
--- a/redfish-core/schema/dmtf/json-schema/Circuit.v1_8_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Circuit.v1_8_1.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Circuit.v1_8_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Circuit.v1_8_1.json",
"$ref": "#/definitions/Circuit",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -165,9 +165,9 @@
"type": "null"
}
],
- "description": "The current (A) for this single-phase circuit.",
+ "description": "The current (A) for this circuit.",
"excerptCopy": "SensorCurrentExcerpt",
- "longDescription": "This property shall contain the current, in ampere units, for this single-phase circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not appear in resource instances representing poly-phase circuits."
+ "longDescription": "This property shall contain the current, in ampere units, for this circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."
},
"Description": {
"anyOf": [
@@ -349,7 +349,7 @@
}
],
"description": "The current readings for this circuit.",
- "longDescription": "This property shall contain the current sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For poly-phase circuits, this property should contain multiple current sensor readings used to fully describe the circuit."
+ "longDescription": "This property shall contain the current sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For other circuits, this property should contain multiple current sensor readings used to fully describe the circuit."
},
"PolyPhaseEnergykWh": {
"anyOf": [
@@ -361,7 +361,7 @@
}
],
"description": "The energy readings for this circuit.",
- "longDescription": "This property shall contain the energy sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the energy sensor referenced in the `EnergykWh` property, if present. For poly-phase circuits, this property should contain multiple energy sensor readings used to fully describe the circuit."
+ "longDescription": "This property shall contain the energy sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the energy sensor referenced in the `EnergykWh` property, if present. For other circuits, this property should contain multiple energy sensor readings used to fully describe the circuit."
},
"PolyPhasePowerWatts": {
"anyOf": [
@@ -373,7 +373,7 @@
}
],
"description": "The power readings for this circuit.",
- "longDescription": "This property shall contain the power sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the power sensor referenced in the `PowerWatts` property, if present. For poly-phase circuits, this property should contain multiple power sensor readings used to fully describe the circuit."
+ "longDescription": "This property shall contain the power sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the power sensor referenced in the `PowerWatts` property, if present. For other circuits, this property should contain multiple power sensor readings used to fully describe the circuit."
},
"PolyPhaseVoltage": {
"anyOf": [
@@ -385,7 +385,7 @@
}
],
"description": "The voltage readings for this circuit.",
- "longDescription": "This property shall contain the voltage sensors for this circuit. For single-phase circuits, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For poly-phase circuits, this property should contain multiple voltage sensor readings used to fully describe the circuit."
+ "longDescription": "This property shall contain the voltage sensors for this circuit. For 3-wire circuits, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For other circuits, this property should contain multiple voltage sensor readings used to fully describe the circuit."
},
"PowerControlLocked": {
"description": "Indicates whether power control requests are locked.",
@@ -552,9 +552,9 @@
"type": "null"
}
],
- "description": "The voltage (V) for this single-phase circuit.",
+ "description": "The voltage (V) for this circuit.",
"excerptCopy": "SensorVoltageExcerpt",
- "longDescription": "This property shall contain the voltage, in volt units, for this single-phase circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not appear in resource instances representing poly-phase circuits."
+ "longDescription": "This property shall contain the voltage, in volt units, for this circuit. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."
},
"VoltageType": {
"anyOf": [
@@ -1171,5 +1171,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2024.1",
- "title": "#Circuit.v1_8_0.Circuit"
+ "title": "#Circuit.v1_8_1.Circuit"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/ComponentIntegrity.v1_2_3.json b/redfish-core/schema/dmtf/json-schema/ComponentIntegrity.v1_3_0.json
index 5c0d78148c..8c1b5ede4d 100644
--- a/redfish-core/schema/dmtf/json-schema/ComponentIntegrity.v1_2_3.json
+++ b/redfish-core/schema/dmtf/json-schema/ComponentIntegrity.v1_3_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/ComponentIntegrity.v1_2_3.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/ComponentIntegrity.v1_3_0.json",
"$ref": "#/definitions/ComponentIntegrity",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -246,18 +246,28 @@
"enum": [
"SPDM",
"TPM",
+ "TCM",
+ "TPCM",
"OEM"
],
"enumDescriptions": {
"OEM": "OEM-specific.",
"SPDM": "Security Protocol and Data Model (SPDM) protocol.",
+ "TCM": "Trusted Cryptography Module (TCM).",
+ "TPCM": "Trusted Platform Control Module (TPCM).",
"TPM": "Trusted Platform Module (TPM)."
},
"enumLongDescriptions": {
"OEM": "This value shall indicate the integrity information is OEM-specific and the OEM section may include additional information.",
"SPDM": "This value shall indicate the integrity information is obtained through the Security Protocol and Data Model (SPDM) protocol as defined in DMTF DSP0274.",
+ "TCM": "This value shall indicate the integrity information is related to a Trusted Cryptography Module (TCM) as defined by the China TCM Union (TCMU).",
+ "TPCM": "This value shall indicate the integrity information is related to a Trusted Platform Control Module (TPCM) as defined by the Zhongguancun Trusted Computing Industry Alliance (ZTCIA).",
"TPM": "This value shall indicate the integrity information is related to a Trusted Platform Module (TPM) as defined by the Trusted Computing Group (TCG)."
},
+ "enumVersionAdded": {
+ "TCM": "v1_3_0",
+ "TPCM": "v1_3_0"
+ },
"type": "string"
},
"DMTFmeasurementTypes": {
@@ -1306,6 +1316,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2022.2",
- "title": "#ComponentIntegrity.v1_2_3.ComponentIntegrity"
+ "release": "2024.3",
+ "title": "#ComponentIntegrity.v1_3_0.ComponentIntegrity"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/ComputerSystem.v1_22_1.json b/redfish-core/schema/dmtf/json-schema/ComputerSystem.v1_23_0.json
index 82f2fcaa00..1b5ed97e09 100644
--- a/redfish-core/schema/dmtf/json-schema/ComputerSystem.v1_22_1.json
+++ b/redfish-core/schema/dmtf/json-schema/ComputerSystem.v1_23_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/ComputerSystem.v1_22_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/ComputerSystem.v1_23_0.json",
"$ref": "#/definitions/ComputerSystem",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -748,6 +748,13 @@
"longDescription": "This property shall contain the key management settings of the computer system.",
"versionAdded": "v1_16_0"
},
+ "LastResetCause": {
+ "$ref": "#/definitions/LastResetCauses",
+ "description": "The last reset cause of the system.",
+ "longDescription": "This property shall contain the cause when the system last came out of a reset or was rebooted.",
+ "readonly": true,
+ "versionAdded": "v1_23_0"
+ },
"LastResetTime": {
"description": "The date and time when the system was last reset or rebooted.",
"format": "date-time",
@@ -1075,7 +1082,7 @@
}
],
"description": "The UUID for this system.",
- "longDescription": "This property shall contain the universally unique identifier number for this system. RFC4122 describes methods to create this value. The value should be considered to be opaque. Client software should only treat the overall value as a UUID and should not interpret any subfields within the UUID. If the system supports SMBIOS, the property value should follow the SMBIOS 2.6 and later recommendation for converting the SMBIOS 16-byte UUID structure into the Redfish canonical `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` string format, so that the property value matches the byte order presented by current OS APIs, such as WMI and dmidecode.",
+ "longDescription": "This property shall contain the universally unique identifier number for this system. RFC4122 describes methods to create this value. The value should be considered to be opaque. Client software should only treat the overall value as a UUID and should not interpret any subfields within the UUID. If the system supports SMBIOS, the property value should follow the SMBIOS 2.6 and later recommendation for converting the SMBIOS 16-byte UUID structure into the Redfish canonical `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` string format, so that the property value matches the byte order presented by current OS APIs, such as WMI and dmidecode. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true
},
"VirtualMedia": {
@@ -1648,6 +1655,45 @@
},
"type": "object"
},
+ "LastResetCauses": {
+ "enum": [
+ "PowerButtonPress",
+ "ManagementCommand",
+ "PowerRestorePolicy",
+ "RTCWakeup",
+ "WatchdogExpiration",
+ "OSSoftRestart",
+ "SystemCrash",
+ "ThermalEvent",
+ "PowerEvent",
+ "Unknown"
+ ],
+ "enumDescriptions": {
+ "ManagementCommand": "System start or restart via an external command to the management controller or BMC.",
+ "OSSoftRestart": "System start or restart via an OS soft restart.",
+ "PowerButtonPress": "System start or restart via a power button press.",
+ "PowerEvent": "System start or restart caused by a power event triggering a system shutdown.",
+ "PowerRestorePolicy": "System start or restart due to the power restore policy.",
+ "RTCWakeup": "System power-up via an RTC (system real time clock) wakeup.",
+ "SystemCrash": "System start or restart caused by a system crash.",
+ "ThermalEvent": "System start or restart caused by a thermal event triggering a system shutdown.",
+ "Unknown": "System start or restart detected, but the cause is unknown.",
+ "WatchdogExpiration": "System start or restart caused by a watchdog expiration."
+ },
+ "enumLongDescriptions": {
+ "ManagementCommand": "This value shall indicate the system start or restart was due to an external command to the management controller or BMC. Examples include the Redfish `Reset` action for the `ComputerSystem` resource or the IPMI 'Chassis Control' command.",
+ "OSSoftRestart": "This value shall indicate the system start or restart was due to an OS soft restart. Examples include 'CTRL-ALT-DEL', 'init 6', or 'reboot'.",
+ "PowerButtonPress": "This value shall indicate the system start or restart was due to a power button press.",
+ "PowerEvent": "This value shall indicate the system start or restart was caused by a power event triggering a system shutdown.",
+ "PowerRestorePolicy": "This value shall indicate the system automatically powered-up on AC being applied due the `PowerRestorePolicy` property containing `AlwaysOn` or `LastState`.",
+ "RTCWakeup": "This value shall indicate the system powered-up via an RTC (system real time clock) wakeup.",
+ "SystemCrash": "This value shall indicate the system start or restart was caused by a system crash. Examples include an OS panic, hardware fault, or firmware fault.",
+ "ThermalEvent": "This value shall indicate the system start or restart was caused by a thermal event triggering a system shutdown.",
+ "Unknown": "This value shall indicate the system start or restart cause is unknown.",
+ "WatchdogExpiration": "This value shall indicate the system start or restart was caused by a watchdog expiration."
+ },
+ "type": "string"
+ },
"Links": {
"additionalProperties": false,
"description": "The links to other resources that are related to this resource.",
@@ -2569,6 +2615,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.3",
- "title": "#ComputerSystem.v1_22_1.ComputerSystem"
+ "release": "2024.3",
+ "title": "#ComputerSystem.v1_23_0.ComputerSystem"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Control.v1_5_1.json b/redfish-core/schema/dmtf/json-schema/Control.v1_5_2.json
index b8732976b2..d5731c3d44 100644
--- a/redfish-core/schema/dmtf/json-schema/Control.v1_5_1.json
+++ b/redfish-core/schema/dmtf/json-schema/Control.v1_5_2.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Control.v1_5_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Control.v1_5_2.json",
"$ref": "#/definitions/Control",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -325,8 +325,8 @@
"readonly": true
},
"SetPointUnits": {
- "description": "The units of the set point.",
- "longDescription": "This property shall contain the units of the control's set point.",
+ "description": "The units of the set point and related properties in UCUM c/s format.",
+ "longDescription": "This property shall contain the units of the control's set point and related properties. The value shall follow the case-sensitive symbol format defined by the Unified Code for Units of Measure (UCUM), as specified by the 'Units of measure annotation' clause of the Redfish Specification.",
"readonly": true,
"type": [
"string",
@@ -1012,5 +1012,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2023.3",
- "title": "#Control.v1_5_1.Control"
+ "title": "#Control.v1_5_2.Control"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Drive.v1_19_0.json b/redfish-core/schema/dmtf/json-schema/Drive.v1_20_1.json
index 67a62e53ef..a8c880784d 100644
--- a/redfish-core/schema/dmtf/json-schema/Drive.v1_19_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Drive.v1_20_1.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Drive.v1_19_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Drive.v1_20_1.json",
"$ref": "#/definitions/Drive",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -40,6 +40,21 @@
},
"type": "object"
},
+ "ConfigLockOptions": {
+ "enum": [
+ "Unlocked",
+ "Locked",
+ "LockdownUnsupported",
+ "CommandUnsupported"
+ ],
+ "enumDescriptions": {
+ "CommandUnsupported": "The command is not supported, therefore lockdown does not apply.",
+ "LockdownUnsupported": "The command is supported but is not able to be locked.",
+ "Locked": "The command is supported and is currently locked.",
+ "Unlocked": "The command is supported, able to be locked, and is currently unlocked."
+ },
+ "type": "string"
+ },
"ConfigurationLock": {
"enum": [
"Enabled",
@@ -48,12 +63,12 @@
],
"enumDescriptions": {
"Disabled": "In-band configuration requests are not locked.",
- "Enabled": "In-band configuration requests are locked. Configuration requests include applying firmware, updating security keys, and other hardware settings. It does not include managing the volumes or data on the drive.",
+ "Enabled": "In-band configuration requests are locked as specified by `TargetConfigurationLockLevel`.",
"Partial": "Some in-band configuration requests are not locked while others are locked. This value is used for status reporting to indicate that the drive is partially locked and client action is recommended."
},
"enumLongDescriptions": {
"Disabled": "This value shall indicate in-band configuration requests are not locked.",
- "Enabled": "This value shall indicate in-band configuration requests are locked.",
+ "Enabled": "This value shall indicate in-band configuration requests are locked as specified by `TargetConfigurationLockLevel`.",
"Partial": "This value shall indicate some in-band configuration requests are not locked while others are locked."
},
"type": "string"
@@ -128,6 +143,16 @@
"null"
]
},
+ "BlockSecurityIDEnabled": {
+ "description": "Indicates if establishment of a TCG-defined security ID (SID) on the drive is blocked.",
+ "longDescription": "This property shall indicate if establishment of a TCG-defined security ID (SID) on the drive is blocked. The value `true` shall indicate the TCG-defined 'Block SID' command is sent to the drive during each drive boot sequence.",
+ "readonly": false,
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "versionAdded": "v1_20_0"
+ },
"BlockSizeBytes": {
"description": "The size, in bytes, of the smallest addressable unit, or block.",
"longDescription": "This property shall contain the size of the smallest addressable unit of the associated drive.",
@@ -174,7 +199,7 @@
"type": "null"
}
],
- "description": "Indicates whether in-band configuration requests to the drive are locked.",
+ "description": "Indicates whether in-band configuration requests to the drive are locked. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock.",
"longDescription": "This property shall indicate whether configuration requests to the drive are locked. Services shall reject modification requests that contain the value `Partial`.",
"readonly": false,
"versionAdded": "v1_19_0"
@@ -401,6 +426,19 @@
],
"versionAdded": "v1_9_0"
},
+ "NVMe": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/NVMe"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "NVMe properties for this drive.",
+ "longDescription": "This property shall contain NVMe-specific properties of this drive.",
+ "versionAdded": "v1_20_0"
+ },
"Name": {
"$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Name",
"readonly": true
@@ -574,6 +612,20 @@
"longDescription": "This property shall contain the status indicator state for the status indicator associated with this drive. The `@Redfish.AllowableValues` annotation specifies the valid values for this property.",
"readonly": false
},
+ "TargetConfigurationLockLevel": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/TargetConfigurationLockLevel"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Indicates the target configuration lock level for the drive based upon the state of the `ConfigurationLock` property. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock.",
+ "longDescription": "This property shall contain the target configuration lock level for the drive. For NVMe drives, services shall implement the locking requirements specified by SNIA's Swordfish NVMe Model Overview and Mapping Guide.",
+ "readonly": false,
+ "versionAdded": "v1_20_0"
+ },
"WriteCacheEnabled": {
"description": "An indication of whether the drive write cache is enabled.",
"longDescription": "This property shall indicate whether the drive write cache is enabled.",
@@ -862,6 +914,133 @@
},
"type": "string"
},
+ "NVMe": {
+ "additionalProperties": false,
+ "description": "NVMe properties for a drive.",
+ "longDescription": "This type shall contain NVMe-specific properties of a drive.",
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "ConfigurationLockState": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/NVMeConfigurationLockState"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state.",
+ "longDescription": "This property shall contain the configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state.",
+ "versionAdded": "v1_20_0"
+ }
+ },
+ "type": "object"
+ },
+ "NVMeConfigurationLockState": {
+ "additionalProperties": false,
+ "description": "The configurable features that are able to be locked on an NVMe subsystem and their current lock state.",
+ "longDescription": "This type shall contain the configurable features that are able to be locked on an NVMe subsystem and their current lock state.",
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "FirmwareCommit": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Firmware Commit command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Firmware Commit command.",
+ "readonly": true,
+ "versionAdded": "v1_20_0"
+ },
+ "FirmwareImageDownload": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Firmware Image Download command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Firmware Image Download command.",
+ "readonly": true,
+ "versionAdded": "v1_20_0"
+ },
+ "Lockdown": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Lockdown command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Lockdown command.",
+ "readonly": true,
+ "versionAdded": "v1_20_0"
+ },
+ "SecuritySend": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Security Send command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Security Send command.",
+ "readonly": true,
+ "versionAdded": "v1_20_0"
+ },
+ "VPDWrite": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-MI-defined VPD Write command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-MI-defined VPD Write command.",
+ "readonly": true,
+ "versionAdded": "v1_20_0"
+ }
+ },
+ "type": "object"
+ },
"OemActions": {
"additionalProperties": true,
"description": "The available OEM-specific actions for this resource.",
@@ -1094,10 +1273,19 @@
"Rebuild": "The drive is being rebuilt."
},
"type": "string"
+ },
+ "TargetConfigurationLockLevel": {
+ "enum": [
+ "Baseline"
+ ],
+ "enumDescriptions": {
+ "Baseline": "The standard configuration lock level, corresponding to applying firmware, updating security keys, and modifying other hardware settings. It does not include managing the volumes or data on the drive."
+ },
+ "type": "string"
}
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#Drive.v1_19_0.Drive"
+ "release": "2024.2",
+ "title": "#Drive.v1_20_1.Drive"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/EthernetInterface.v1_12_1.json b/redfish-core/schema/dmtf/json-schema/EthernetInterface.v1_12_2.json
index 9893b2d67b..ea65bcc115 100644
--- a/redfish-core/schema/dmtf/json-schema/EthernetInterface.v1_12_1.json
+++ b/redfish-core/schema/dmtf/json-schema/EthernetInterface.v1_12_2.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/EthernetInterface.v1_12_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/EthernetInterface.v1_12_2.json",
"$ref": "#/definitions/EthernetInterface",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -372,7 +372,7 @@
},
"HostName": {
"description": "The DNS host name, without any domain information.",
- "longDescription": "This property shall contain the DNS host name for this interface. Modifying this property may modify the `HostName` in one or more `EthernetInterface` resources that belong to the same system, manager, or other device. If this interface is subordinate to a `ComputerSystem` resource, modifying this property may modify the `HostName` of the `ComputerSystem` resource that contains this interface. If this interface is subordinate to a `Manager` resource, modifying this property may modify the `HostName` of the `ManagerNetworkProtocol` resource of the `Manager` resource that contains this interface.",
+ "longDescription": "This property shall contain the DNS host name for this interface. Modifying this property may modify the `HostName` in one or more `EthernetInterface` resources that belong to the same system, manager, or other device. If this interface is subordinate to a `ComputerSystem` resource, modifying this property may modify the `HostName` of the `ComputerSystem` resource that contains this interface. If this interface is subordinate to a `Manager` resource, modifying this property may modify the `HostName` of the `ManagerNetworkProtocol` resource of the `Manager` resource that contains this interface. Services should ignore this property in modification requests if `FQDN` is also provided in the same request.",
"readonly": false,
"type": [
"string",
@@ -973,5 +973,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2023.3",
- "title": "#EthernetInterface.v1_12_1.EthernetInterface"
+ "title": "#EthernetInterface.v1_12_2.EthernetInterface"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Event.v1_10_1.json b/redfish-core/schema/dmtf/json-schema/Event.v1_11_0.json
index 3b352781aa..1aa04547f0 100644
--- a/redfish-core/schema/dmtf/json-schema/Event.v1_10_1.json
+++ b/redfish-core/schema/dmtf/json-schema/Event.v1_11_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Event.v1_10_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Event.v1_11_0.json",
"$ref": "#/definitions/Event",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -392,6 +392,26 @@
"readonly": true,
"type": "boolean",
"versionAdded": "v1_6_0"
+ },
+ "UserAuthenticationSource": {
+ "description": "The source of authentication for the username property associated with the event record.",
+ "longDescription": "This property shall contain the URL to the authentication service that is associated with the username property. This should be used for events that result from a user action.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_11_0"
+ },
+ "Username": {
+ "description": "The username of the account associated with the event record.",
+ "longDescription": "This property shall contain the username of the account associated with the event record. This should be used for events that result from a user action.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_11_0"
}
},
"required": [
@@ -474,6 +494,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.3",
- "title": "#Event.v1_10_1.Event"
+ "release": "2024.3",
+ "title": "#Event.v1_11_0.Event"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/EventDestination.v1_14_1.json b/redfish-core/schema/dmtf/json-schema/EventDestination.v1_15_0.json
index 5e4707b03b..d261e7f80b 100644
--- a/redfish-core/schema/dmtf/json-schema/EventDestination.v1_14_1.json
+++ b/redfish-core/schema/dmtf/json-schema/EventDestination.v1_15_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/EventDestination.v1_14_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/EventDestination.v1_15_0.json",
"$ref": "#/definitions/EventDestination",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -99,6 +99,20 @@
"longDescription": "This property shall contain the available actions for this resource.",
"versionAdded": "v1_2_0"
},
+ "BackupDestinations": {
+ "description": "The backup destination URIs for this event receiver. Events are sent to these URIs, in array order, when the destination URI is unreachable or returns an error.",
+ "format": "uri-reference",
+ "items": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "longDescription": "This property shall contain an array of URIs to destination where events are sent if the event receiver specified by `Destination` is unreachable or returns an error. Events are sent to each of the backup destinations, in array order, until a destination has been reached. An empty array shall indicate that the service supports backup event receivers, but none have been specified by the user.",
+ "readonly": false,
+ "type": "array",
+ "versionAdded": "v1_15_0"
+ },
"Certificates": {
"$ref": "http://redfish.dmtf.org/schemas/v1/CertificateCollection.json#/definitions/CertificateCollection",
"description": "The link to a collection of server certificates for the server referenced by the `Destination` property.",
@@ -664,8 +678,8 @@
"properties": {
"AuthenticationKey": {
"description": "The secret authentication key for SNMPv3.",
- "longDescription": "This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark.",
- "pattern": "(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\\*+$)",
+ "longDescription": "This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414.",
+ "pattern": "(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{24,96}$)|(^\\*+$)",
"readonly": false,
"type": [
"string",
@@ -697,8 +711,8 @@
},
"EncryptionKey": {
"description": "The secret authentication key for SNMPv3.",
- "longDescription": "This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark.",
- "pattern": "(^[A-Za-z0-9]+$)|(^\\*+$)",
+ "longDescription": "This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414.",
+ "pattern": "(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{16,64}$)|(^\\*+$)",
"readonly": false,
"type": [
"string",
@@ -946,6 +960,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.3",
- "title": "#EventDestination.v1_14_1.EventDestination"
+ "release": "2024.3",
+ "title": "#EventDestination.v1_15_0.EventDestination"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/ExternalAccountProvider.v1_7_2.json b/redfish-core/schema/dmtf/json-schema/ExternalAccountProvider.v1_8_0.json
index bf571aa3c1..65210cee0d 100644
--- a/redfish-core/schema/dmtf/json-schema/ExternalAccountProvider.v1_7_2.json
+++ b/redfish-core/schema/dmtf/json-schema/ExternalAccountProvider.v1_8_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/ExternalAccountProvider.v1_7_2.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/ExternalAccountProvider.v1_8_0.json",
"$ref": "#/definitions/ExternalAccountProvider",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -634,6 +634,36 @@
}
},
"properties": {
+ "LocalAccountTypes": {
+ "description": "The list of local services in the manager that the remote user or group is allowed to access.",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "http://redfish.dmtf.org/schemas/v1/ManagerAccount.json#/definitions/AccountTypes"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "longDescription": "This property shall contain an array of the various local manager services that the remote user or group is allowed to access. This shall not include functionality for receiving events or other notifications. If this property is not supported, the value shall be assumed to be an array that contains the value `Redfish`.",
+ "readonly": false,
+ "type": "array",
+ "versionAdded": "v1_8_0"
+ },
+ "LocalOEMAccountTypes": {
+ "description": "The OEM account types for the remote user or group.",
+ "items": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "longDescription": "This property shall contain an array of the OEM account types for the remote user or group when `LocalAccountTypes` contains `OEM`.",
+ "readonly": false,
+ "type": "array",
+ "versionAdded": "v1_8_0"
+ },
"LocalRole": {
"description": "The name of the local Redfish role to which to map the remote user or group.",
"longDescription": "This property shall contain the `RoleId` property value within a role resource on this Redfish service to which to map the remote user or group.",
@@ -771,6 +801,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.2",
- "title": "#ExternalAccountProvider.v1_7_2.ExternalAccountProvider"
+ "release": "2024.3",
+ "title": "#ExternalAccountProvider.v1_8_0.ExternalAccountProvider"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/LeakDetection.v1_0_1.json b/redfish-core/schema/dmtf/json-schema/LeakDetection.v1_1_0.json
index 50b3d98641..1402282374 100644
--- a/redfish-core/schema/dmtf/json-schema/LeakDetection.v1_0_1.json
+++ b/redfish-core/schema/dmtf/json-schema/LeakDetection.v1_1_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/LeakDetection.v1_0_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/LeakDetection.v1_1_0.json",
"$ref": "#/definitions/LeakDetection",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -168,8 +168,17 @@
"description": "Humidity (percent).",
"excerptCopy": "SensorExcerpt",
"longDescription": "This property shall contain the humidity, in percent units, for this resource. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Humidity`."
+ },
+ "Status": {
+ "$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Status",
+ "description": "The status and health of the resource and its subordinate or dependent resources.",
+ "longDescription": "This property shall contain any status or health properties of the resource.",
+ "versionAdded": "v1_1_0"
}
},
+ "required": [
+ "Status"
+ ],
"type": "object"
},
"OemActions": {
@@ -196,6 +205,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.1",
- "title": "#LeakDetection.v1_0_1.LeakDetection"
+ "release": "2024.3",
+ "title": "#LeakDetection.v1_1_0.LeakDetection"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/LeakDetector.v1_1_0.json b/redfish-core/schema/dmtf/json-schema/LeakDetector.v1_2_0.json
index e4c6741d37..beb38514a4 100644
--- a/redfish-core/schema/dmtf/json-schema/LeakDetector.v1_1_0.json
+++ b/redfish-core/schema/dmtf/json-schema/LeakDetector.v1_2_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/LeakDetector.v1_1_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/LeakDetector.v1_2_0.json",
"$ref": "#/definitions/LeakDetector",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -89,7 +89,7 @@
],
"description": "The state of the leak detector.",
"excerpt": "LeakDetector",
- "longDescription": "This property shall contain the state of the leak detector.",
+ "longDescription": "This property shall contain the state of the leak detector. The value of this property should equate the value of `Health` in `Status`, and was created primarily for use in excerpts of this resource.",
"readonly": true
},
"Id": {
@@ -277,9 +277,21 @@
],
"description": "The state of the leak detector.",
"excerpt": "LeakDetector",
- "longDescription": "This property shall contain the state of the leak detector.",
+ "longDescription": "This property shall contain the state of the leak detector. The value of this property should equate the value of `Health` in `Status`, and was created primarily for use in excerpts of this resource.",
"readonly": true
},
+ "DeviceName": {
+ "description": "The name of the device.",
+ "excerpt": "LeakDetectorArray",
+ "excerptCopyOnly": true,
+ "longDescription": "This property shall contain the name of the device associated with this leak detector. If the device is represented by a resource, the value shall contain the value of the `Name` property of the associated resource.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_2_0"
+ },
"PhysicalContext": {
"anyOf": [
{
@@ -353,7 +365,7 @@
],
"description": "The state of the leak detector.",
"excerpt": "LeakDetector",
- "longDescription": "This property shall contain the state of the leak detector.",
+ "longDescription": "This property shall contain the state of the leak detector. The value of this property should equate the value of `Health` in `Status`, and was created primarily for use in excerpts of this resource.",
"readonly": true
}
},
@@ -394,6 +406,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#LeakDetector.v1_1_0.LeakDetector"
+ "release": "2024.3",
+ "title": "#LeakDetector.v1_2_0.LeakDetector"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/LogEntry.v1_16_1.json b/redfish-core/schema/dmtf/json-schema/LogEntry.v1_17_0.json
index d0e064a93f..33e2d7fd63 100644
--- a/redfish-core/schema/dmtf/json-schema/LogEntry.v1_16_1.json
+++ b/redfish-core/schema/dmtf/json-schema/LogEntry.v1_17_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/LogEntry.v1_16_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/LogEntry.v1_17_0.json",
"$ref": "#/definitions/LogEntry",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -160,7 +160,7 @@
"items": {
"$ref": "http://redfish.dmtf.org/schemas/v1/LogEntry.json#/definitions/LogEntry"
},
- "longDescription": "This property shall contain an array of links to resources of type `LogEntry` in this or other log services that are related to this log entry.",
+ "longDescription": "This property shall contain an array of links to resources of type `LogEntry` in this or other log services that are related to this log entry. This property should be used to link a log entry indicating the resolution of a condition with a log entry for the initial condition.",
"readonly": true,
"type": "array",
"versionAdded": "v1_12_0"
@@ -586,6 +586,26 @@
"readonly": true,
"type": "boolean",
"versionAdded": "v1_13_0"
+ },
+ "UserAuthenticationSource": {
+ "description": "The source of authentication for the username property associated with the log entry.",
+ "longDescription": "This property shall contain the URL to the authentication service that is associated with the username property. This should be used for audit logs that result from a user action.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_17_0"
+ },
+ "Username": {
+ "description": "The username of the account associated with the log entry.",
+ "longDescription": "This property shall contain the username of the account associated with the log entry. This should be used for audit logs that result from a user action.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_17_0"
}
},
"required": [
@@ -883,6 +903,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.3",
- "title": "#LogEntry.v1_16_1.LogEntry"
+ "release": "2024.3",
+ "title": "#LogEntry.v1_17_0.LogEntry"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Manager.v1_19_1.json b/redfish-core/schema/dmtf/json-schema/Manager.v1_19_2.json
index d44e64b147..f75c896437 100644
--- a/redfish-core/schema/dmtf/json-schema/Manager.v1_19_1.json
+++ b/redfish-core/schema/dmtf/json-schema/Manager.v1_19_2.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Manager.v1_19_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Manager.v1_19_2.json",
"$ref": "#/definitions/Manager",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -437,8 +437,8 @@
},
"CommandShell": {
"$ref": "#/definitions/CommandShell",
- "description": "The command shell service that this manager provides.",
- "longDescription": "This property shall contain information about the command shell service of this manager."
+ "description": "The manager's command line user interface or command shell service.",
+ "longDescription": "This property shall describe a command line user interface or command shell service provided by this manager. The command shell refers to an interface used to interact with the manager itself, not a dedicated console session redirected from a host operating system. For redirected serial or host operating system consoles, see the `SerialConsole` property in the `ComputerSystem` resource."
},
"DateTime": {
"description": "The current date and time with UTC offset of the manager.",
@@ -500,8 +500,8 @@
},
"GraphicalConsole": {
"$ref": "#/definitions/GraphicalConsole",
- "description": "The information about the graphical console service of this manager.",
- "longDescription": "This property shall contain the information about the graphical console (KVM-IP) service of this manager. This property should be used to describe a service for the manager's console or operating system, not a service provided on behalf of a host operating system. Implementations representing host OS consoles, known generally as a KVM-IP feature, should use the `GraphicalConsole` property in ComputerSystem."
+ "description": "The manager's graphical console service.",
+ "longDescription": "This property shall contain the information about the graphical console (KVM-IP) service of this manager. This property should be used to describe a service for the manager's console or operating system, not a service provided on behalf of a host operating system. Implementations representing host OS consoles, known generally as a KVM-IP feature, should use the `GraphicalConsole` property in the `ComputerSystem` resource."
},
"HostInterfaces": {
"$ref": "http://redfish.dmtf.org/schemas/v1/HostInterfaceCollection.json#/definitions/HostInterfaceCollection",
@@ -1082,5 +1082,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2023.3",
- "title": "#Manager.v1_19_1.Manager"
+ "title": "#Manager.v1_19_2.Manager"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/ManagerAccount.v1_12_1.json b/redfish-core/schema/dmtf/json-schema/ManagerAccount.v1_13_0.json
index 8d876e99a4..9a363a6ed5 100644
--- a/redfish-core/schema/dmtf/json-schema/ManagerAccount.v1_12_1.json
+++ b/redfish-core/schema/dmtf/json-schema/ManagerAccount.v1_13_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/ManagerAccount.v1_12_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/ManagerAccount.v1_13_0.json",
"$ref": "#/definitions/ManagerAccount",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -26,6 +26,15 @@
"#ManagerAccount.ChangePassword": {
"$ref": "#/definitions/ChangePassword"
},
+ "#ManagerAccount.ClearSecretKey": {
+ "$ref": "#/definitions/ClearSecretKey"
+ },
+ "#ManagerAccount.GenerateSecretKey": {
+ "$ref": "#/definitions/GenerateSecretKey"
+ },
+ "#ManagerAccount.VerifyTimeBasedOneTimePassword": {
+ "$ref": "#/definitions/VerifyTimeBasedOneTimePassword"
+ },
"Oem": {
"$ref": "#/definitions/OemActions",
"description": "The available OEM-specific actions for this resource.",
@@ -81,6 +90,104 @@
"type": "object",
"versionAdded": "v1_11_0"
},
+ "ClearSecretKey": {
+ "additionalProperties": false,
+ "description": "This action clears the secret key for Time-based One-Time Password (TOTP) multi-factor authentication for this account.",
+ "longDescription": "This action shall clear the secret key for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication for this account.",
+ "parameters": {},
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "target": {
+ "description": "Link to invoke action",
+ "format": "uri-reference",
+ "type": "string"
+ },
+ "title": {
+ "description": "Friendly action name",
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "versionAdded": "v1_13_0"
+ },
+ "GenerateSecretKey": {
+ "actionResponse": {
+ "$ref": "#/definitions/GenerateSecretKeyResponse"
+ },
+ "additionalProperties": false,
+ "description": "This action randomly generates a new secret key for Time-based One-Time Password (TOTP) multi-factor authentication for this account.",
+ "longDescription": "This action shall randomly generate a new secret key for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication for this account.",
+ "parameters": {},
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "target": {
+ "description": "Link to invoke action",
+ "format": "uri-reference",
+ "type": "string"
+ },
+ "title": {
+ "description": "Friendly action name",
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "versionAdded": "v1_13_0"
+ },
+ "GenerateSecretKeyResponse": {
+ "additionalProperties": false,
+ "description": "The response body for the `GenerateSecretKey` action.",
+ "longDescription": "This type shall contain the properties found in the response body for the `GenerateSecretKey` action.",
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "SecretKey": {
+ "description": "The secret key generated for Time-based One-Time Password (TOTP) multi-factor authentication.",
+ "longDescription": "This property shall contain secret key generated for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication. Clients shall retain the value of this property to generate tokens for future session creation requests.",
+ "readonly": true,
+ "type": "string",
+ "versionAdded": "v1_13_0"
+ }
+ },
+ "type": "object"
+ },
"Links": {
"additionalProperties": false,
"description": "The links to other resources that are related to this resource.",
@@ -347,6 +454,13 @@
"longDescription": "This property shall contain the SNMP settings for this account when `AccountTypes` contains `SNMP`.",
"versionAdded": "v1_4_0"
},
+ "SecretKeySet": {
+ "description": "Indicates if the secret key for Time-based One-Time Password (TOTP) multi-factor authentication is set.",
+ "longDescription": "This property shall indicate if the secret key for RFC6238-defined Time-based One-Time Password (TOTP) multi-factor authentication is set.",
+ "readonly": true,
+ "type": "boolean",
+ "versionAdded": "v1_13_0"
+ },
"StrictAccountTypes": {
"description": "Indicates if the service needs to use the account types exactly as specified when the account is created or updated.",
"longDescription": "This property shall indicate if the service needs to use the value of `AccountTypes` and `OEMAccountTypes` values exactly as specified. A `true` value shall indicate the service needs to either accept the value without changes or reject the request. A `false` value shall indicate the service may add additional `AccountTypes` and `OEMAccountTypes` values as needed to support limitations it has in separately controlling access to individual services. If this property is not present, the value shall be assumed to be `false`. An update of the service can cause account types to be added to or removed from the `AccountTypes` and `OEMAccountTypes` properties, regardless of the value of this property. After a service update, clients should inspect all accounts where the value of this property is `true` and perform maintenance as needed.",
@@ -484,8 +598,8 @@
"properties": {
"AuthenticationKey": {
"description": "The secret authentication key for SNMPv3.",
- "longDescription": "This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark.",
- "pattern": "(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\\*+$)",
+ "longDescription": "This property shall contain the key for SNMPv3 authentication. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414.",
+ "pattern": "(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{24,96})|(^\\*+$)",
"readonly": false,
"type": [
"string",
@@ -517,8 +631,8 @@
},
"EncryptionKey": {
"description": "The secret encryption key used in SNMPv3.",
- "longDescription": "This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. The passphrase can contain any printable characters except for the double quotation mark.",
- "pattern": "(^[ !#-~]+$)|(^Passphrase:[ ^[ !#-~]+$)|(^Hex:[0-9A-Fa-f]{32})|(^\\*+$)",
+ "longDescription": "This property shall contain the key for SNMPv3 encryption. The value shall be `null` in responses. This property accepts a passphrase or a hex-encoded key. If the string starts with `Passphrase:`, the remainder of the string shall be the passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414. If the string starts with `Hex:`, then the remainder of the string shall be the key encoded in hexadecimal notation. If the string starts with neither, the full string shall be a passphrase and shall be converted to the key as described in the 'Password to Key Algorithm' section of RFC3414.",
+ "pattern": "(^[ -~]+$)|(^Passphrase:[ -~]+$)|(^Hex:[0-9A-Fa-f]{16,64}$)|(^\\*+$)",
"readonly": false,
"type": [
"string",
@@ -550,10 +664,50 @@
}
},
"type": "object"
+ },
+ "VerifyTimeBasedOneTimePassword": {
+ "additionalProperties": false,
+ "description": "This action verifies a user-provided Time-based One-Time Password (TOTP). This is to ensure the client's copy of the secret key is aligned with the secret key stored by the service.",
+ "longDescription": "This action shall verify a user-provided RFC6238-defined Time-based One-Time Password (TOTP).",
+ "parameters": {
+ "TimeBasedOneTimePassword": {
+ "description": "The Time-based One-Time Password (TOTP) to verify.",
+ "longDescription": "This parameter shall contain the Time-based One-Time Password (TOTP) to verify. If the Time-based One-Time Password (TOTP) is not valid, the service shall return the HTTP `400 Bad Request` status code.",
+ "requiredParameter": true,
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "target": {
+ "description": "Link to invoke action",
+ "format": "uri-reference",
+ "type": "string"
+ },
+ "title": {
+ "description": "Friendly action name",
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "versionAdded": "v1_13_0"
}
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.3",
- "title": "#ManagerAccount.v1_12_1.ManagerAccount"
+ "release": "2024.3",
+ "title": "#ManagerAccount.v1_13_0.ManagerAccount"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/MemoryRegion.v1_0_2.json b/redfish-core/schema/dmtf/json-schema/MemoryRegion.v1_0_3.json
index 8bfd7ef44e..124e92a0b4 100644
--- a/redfish-core/schema/dmtf/json-schema/MemoryRegion.v1_0_2.json
+++ b/redfish-core/schema/dmtf/json-schema/MemoryRegion.v1_0_3.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/MemoryRegion.v1_0_2.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/MemoryRegion.v1_0_3.json",
"$ref": "#/definitions/MemoryRegion",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -109,7 +109,7 @@
]
},
"Tag": {
- "description": "The user-assigned tag of this memory extent.",
+ "description": "The tag of this memory extent.",
"longDescription": "This property shall contain an opaque context attached to each extent to track usage of each extent or map extent to specific processes, transactions, or workloads on the host.",
"readonly": true,
"type": "string"
@@ -336,5 +336,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2023.2",
- "title": "#MemoryRegion.v1_0_2.MemoryRegion"
+ "title": "#MemoryRegion.v1_0_3.MemoryRegion"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Message.v1_2_1.json b/redfish-core/schema/dmtf/json-schema/Message.v1_3_0.json
index f10945157e..b27a8fe946 100644
--- a/redfish-core/schema/dmtf/json-schema/Message.v1_2_1.json
+++ b/redfish-core/schema/dmtf/json-schema/Message.v1_3_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Message.v1_2_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Message.v1_3_0.json",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
"definitions": {
@@ -86,6 +86,26 @@
"readonly": true,
"type": "string",
"versionDeprecated": "v1_1_0"
+ },
+ "UserAuthenticationSource": {
+ "description": "The source of authentication for the username property associated with the message.",
+ "longDescription": "This property shall contain the URL to the authentication service that is associated with the username property. This should be used for messages that result from a user action.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_3_0"
+ },
+ "Username": {
+ "description": "The username of the account associated with the message.",
+ "longDescription": "This property shall contain the username of the account associated with the message. This should be used for messages that result from a user action.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_3_0"
}
},
"required": [
@@ -96,6 +116,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.3",
- "title": "#Message.v1_2_1"
+ "release": "2024.3",
+ "title": "#Message.v1_3_0"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/MetricReport.v1_5_1.json b/redfish-core/schema/dmtf/json-schema/MetricReport.v1_5_2.json
index 4b884cdded..85983ae28b 100644
--- a/redfish-core/schema/dmtf/json-schema/MetricReport.v1_5_1.json
+++ b/redfish-core/schema/dmtf/json-schema/MetricReport.v1_5_2.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/MetricReport.v1_5_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/MetricReport.v1_5_2.json",
"$ref": "#/definitions/MetricReport",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -188,7 +188,7 @@
},
"MetricValue": {
"description": "The metric value, as a string.",
- "longDescription": "This property shall contain the metric value, as a string.",
+ "longDescription": "This property shall contain the metric value, as a string. For numeric metrics, the service shall convert the number to a string representation of the number. For array metrics, the service shall convert the array to an RFC8259-defined JSON string. For boolean metrics, this property shall contain the strings `true` or `false`. If the metric value is `null`, this property shall contain `null`.",
"readonly": true,
"type": [
"string",
@@ -239,5 +239,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2022.2",
- "title": "#MetricReport.v1_5_1.MetricReport"
+ "title": "#MetricReport.v1_5_2.MetricReport"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Outlet.v1_4_3.json b/redfish-core/schema/dmtf/json-schema/Outlet.v1_4_4.json
index 0d7f75237a..05f86e001d 100644
--- a/redfish-core/schema/dmtf/json-schema/Outlet.v1_4_3.json
+++ b/redfish-core/schema/dmtf/json-schema/Outlet.v1_4_4.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Outlet.v1_4_3.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Outlet.v1_4_4.json",
"$ref": "#/definitions/Outlet",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -263,9 +263,9 @@
"type": "null"
}
],
- "description": "The current (A) for this single-phase outlet.",
+ "description": "The current (A) for this outlet.",
"excerptCopy": "SensorCurrentExcerpt",
- "longDescription": "This property shall contain the current, in ampere units, for this single-phase outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not appear in resource instances representing poly-phase outlets."
+ "longDescription": "This property shall contain the current, in ampere units, for this outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Current`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."
},
"Description": {
"anyOf": [
@@ -422,7 +422,7 @@
}
],
"description": "The current readings for this outlet.",
- "longDescription": "This property shall contain the current readings for this outlet. For single-phase outlets, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For poly-phase outlets, this property should contain multiple current sensor readings used to fully describe the outlet."
+ "longDescription": "This property shall contain the current readings for this outlet. For 3-wire outlets, this property shall contain a duplicate copy of the current sensor referenced in the `CurrentAmps` property, if present. For other outlets, this property should contain multiple current sensor readings used to fully describe the outlet."
},
"PolyPhaseVoltage": {
"anyOf": [
@@ -434,7 +434,7 @@
}
],
"description": "The voltage readings for this outlet.",
- "longDescription": "This property shall contain the voltage readings for this outlet. For single-phase outlets, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For poly-phase outlets, this property should contain multiple voltage sensor readings used to fully describe the outlet."
+ "longDescription": "This property shall contain the voltage readings for this outlet. For 3-wire outlets, this property shall contain a duplicate copy of the voltage sensor referenced in the `Voltage` property, if present. For other outlets, this property should contain multiple voltage sensor readings used to fully describe the outlet."
},
"PowerControlLocked": {
"description": "Indicates whether power control requests are locked.",
@@ -573,9 +573,9 @@
"type": "null"
}
],
- "description": "The voltage (V) for this single-phase outlet.",
+ "description": "The voltage (V) for this outlet.",
"excerptCopy": "SensorVoltageExcerpt",
- "longDescription": "This property shall contain the voltage, in volt units, for this single-phase outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not appear in resource instances representing poly-phase outlets."
+ "longDescription": "This property shall contain the voltage, in volt units, for this outlet. The value of the `DataSourceUri` property, if present, shall reference a resource of type `Sensor` with the `ReadingType` property containing the value `Voltage`. This property shall not be present if `PhaseWiringType` contains a value that indicates a 4-wire or greater configuration, such as `TwoPhase4Wire`."
},
"VoltageType": {
"anyOf": [
@@ -784,5 +784,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2021.4",
- "title": "#Outlet.v1_4_3.Outlet"
+ "title": "#Outlet.v1_4_4.Outlet"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/PCIeDevice.v1_14_0.json b/redfish-core/schema/dmtf/json-schema/PCIeDevice.v1_16_0.json
index 2f61de9264..441dfea502 100644
--- a/redfish-core/schema/dmtf/json-schema/PCIeDevice.v1_14_0.json
+++ b/redfish-core/schema/dmtf/json-schema/PCIeDevice.v1_16_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/PCIeDevice.v1_14_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/PCIeDevice.v1_16_0.json",
"$ref": "#/definitions/PCIeDevice",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -798,6 +798,26 @@
}
},
"properties": {
+ "BadDLLPCount": {
+ "description": "The total number of Bad DLLPs issued on the PCIe link by the receiver.",
+ "longDescription": "This property shall contain the total number of Bad DLLPs issued on the PCIe link by the receiver. A Bad DLLP in the context of PCIe communication is a packet that has encountered errors at the data link layer. When a DLLP is considered bad, it means it has been corrupted or is incorrectly formatted, potentially due to transmission errors, hardware failures, or other issues that affect its integrity.",
+ "readonly": true,
+ "type": [
+ "integer",
+ "null"
+ ],
+ "versionAdded": "v1_15_0"
+ },
+ "BadTLPCount": {
+ "description": "The total number of Bad TLPs issued on the PCIe link by the receiver.",
+ "longDescription": "This property shall contain the total number of Bad TLPs issued on the PCIe link by the receiver. A Bad TLP in the context of PCIe communication is a packet that cannot be properly processed due to errors at the transaction layer. These errors could include corrupted data, incorrect packet formatting, invalid header information, or a mismatched checksum.",
+ "readonly": true,
+ "type": [
+ "integer",
+ "null"
+ ],
+ "versionAdded": "v1_15_0"
+ },
"CorrectableErrorCount": {
"description": "The total number of PCIe correctable errors for this device.",
"longDescription": "This property shall contain the total number of PCIe correctable errors for this device.",
@@ -1088,6 +1108,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#PCIeDevice.v1_14_0.PCIeDevice"
+ "release": "2024.3",
+ "title": "#PCIeDevice.v1_16_0.PCIeDevice"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/PhysicalContext.json b/redfish-core/schema/dmtf/json-schema/PhysicalContext.json
index a1267cfbb1..25893504bc 100644
--- a/redfish-core/schema/dmtf/json-schema/PhysicalContext.json
+++ b/redfish-core/schema/dmtf/json-schema/PhysicalContext.json
@@ -48,7 +48,9 @@
"VoltageRegulator",
"Rectifier",
"StorageDevice",
+ "StorageSubsystem",
"NetworkingDevice",
+ "ExpansionSubsystem",
"ComputeBay",
"StorageBay",
"NetworkBay",
@@ -67,18 +69,23 @@
"DCBus",
"ACOutput",
"ACInput",
+ "PowerOutlet",
"TrustedModule",
"Board",
"Transceiver",
"Battery",
- "Pump"
+ "Pump",
+ "Filter",
+ "Reservoir",
+ "Switch",
+ "Manager"
],
"enumDescriptions": {
- "ACInput": "An AC input.",
- "ACMaintenanceBypassInput": "An AC maintenance bypass input.",
- "ACOutput": "An AC output.",
- "ACStaticBypassInput": "An AC static bypass input.",
- "ACUtilityInput": "An AC utility input.",
+ "ACInput": "An AC electrical input or input-related circuit.",
+ "ACMaintenanceBypassInput": "An AC electrical maintenance bypass input.",
+ "ACOutput": "An AC electrical output or output-related circuit.",
+ "ACStaticBypassInput": "An AC electrical static bypass input.",
+ "ACUtilityInput": "An AC electrical utility input.",
"ASIC": "An ASIC device, such as a networking chip or chipset component.",
"Accelerator": "An accelerator.",
"Back": "The back of the chassis.",
@@ -88,13 +95,15 @@
"CPU": "A processor (CPU).",
"CPUSubsystem": "The entire processor (CPU) subsystem.",
"Chassis": "The entire chassis.",
- "ComputeBay": "Within a compute bay.",
+ "ComputeBay": "A compute bay.",
"CoolingSubsystem": "The entire cooling, or air and liquid, subsystem.",
- "DCBus": "A DC bus.",
+ "DCBus": "A DC electrical bus.",
"Exhaust": "The air exhaust point or points or region of the chassis.",
- "ExpansionBay": "Within an expansion bay.",
+ "ExpansionBay": "An expansion bay.",
+ "ExpansionSubsystem": "A group of expansion bays.",
"FPGA": "An FPGA.",
"Fan": "A fan.",
+ "Filter": "A filter.",
"Front": "The front of the chassis.",
"GPU": "A graphics processor (GPU).",
"GPUSubsystem": "The entire graphics processor (GPU) subsystem.",
@@ -102,19 +111,24 @@
"LiquidInlet": "The liquid inlet point of the chassis.",
"LiquidOutlet": "The liquid outlet point of the chassis.",
"Lower": "The lower portion of the chassis.",
+ "Manager": "A management controller, such as a BMC (baseboard management controller).",
"Memory": "A memory device.",
"MemorySubsystem": "The entire memory subsystem.",
"Motor": "A motor.",
- "NetworkBay": "Within a networking bay.",
+ "NetworkBay": "A networking bay.",
"NetworkingDevice": "A networking device.",
+ "PowerOutlet": "An electrical outlet.",
"PowerSubsystem": "The entire power subsystem.",
"PowerSupply": "A power supply.",
- "PowerSupplyBay": "Within a power supply bay.",
+ "PowerSupplyBay": "A power supply bay.",
"Pump": "A pump.",
"Rectifier": "A rectifier device.",
+ "Reservoir": "A reservoir.",
"Room": "The room.",
- "StorageBay": "Within a storage bay.",
+ "StorageBay": "A storage bay.",
"StorageDevice": "A storage device.",
+ "StorageSubsystem": "A storage subsystem.",
+ "Switch": "A switch device.",
"SystemBoard": "The system board (PCB).",
"Transceiver": "A transceiver.",
"Transformer": "A transformer.",
@@ -123,7 +137,16 @@
"VoltageRegulator": "A voltage regulator device."
},
"enumLongDescriptions": {
+ "ACOutput": "This value shall indicate an electrical output or an output-related circuit, such as a branch output, which is not terminated as a power outlet.",
+ "ACUtilityInput": "This value shall indicate an electrical input, where the source is an electrical utility as opposed to a backup or locally-generated power source. This value is intended to differentiate multiple electrical inputs between utility, maintenance bypass, or static bypass values. For general purpose usage, the value of `ACInput` is preferred.",
"Board": "This value shall indicate a circuit board that is not the primary or system board within a context that cannot be described by other defined values.",
+ "ExpansionBay": "This value shall indicate a location that provides for the expansion of functionality of a system, such as a PCIe slot that can accept an option card.",
+ "ExpansionSubsystem": "This value shall indicate a group of expansion bays and the devices installed in those bays.",
+ "NetworkBay": "This value shall indicate a location that provides for the expansion of networking functionality of a system, by the addition of networking devices.",
+ "PowerOutlet": "This value shall indicate an electrical outlet or receptacle.",
+ "PowerSupplyBay": "This value shall indicate a location that provides for the installation of a power supply or similar devices.",
+ "StorageBay": "This value shall indicate a location that provides for the expansion of storage functionality of a system, by the addition of storage devices.",
+ "StorageSubsystem": "This value shall indicate a storage subsystem, which may consist of one or more storage controllers, storage devices, or related components.",
"Transceiver": "This value shall indicate a transceiver attached to a device."
},
"enumVersionAdded": {
@@ -140,17 +163,24 @@
"Chassis": "2017.2",
"CoolingSubsystem": "2018.3",
"DCBus": "2018.3",
+ "ExpansionSubsystem": "2024.3",
"FPGA": "2018.3",
"Fan": "2017.2",
+ "Filter": "2024.2",
"GPUSubsystem": "2018.3",
"LiquidInlet": "2017.3",
"LiquidOutlet": "2017.3",
+ "Manager": "2024.2",
"Memory": "2017.1",
"MemorySubsystem": "2018.3",
"Motor": "2018.3",
+ "PowerOutlet": "2024.3",
"PowerSubsystem": "2019.1",
"Pump": "2021.3",
"Rectifier": "2019.1",
+ "Reservoir": "2024.2",
+ "StorageSubsystem": "2024.3",
+ "Switch": "2024.2",
"Transceiver": "2021.1",
"Transformer": "2018.3",
"TrustedModule": "2020.4"
diff --git a/redfish-core/schema/dmtf/json-schema/Port.v1_12_0.json b/redfish-core/schema/dmtf/json-schema/Port.v1_14_0.json
index 75b8152384..e3ff58e353 100644
--- a/redfish-core/schema/dmtf/json-schema/Port.v1_12_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Port.v1_14_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Port.v1_12_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Port.v1_14_0.json",
"$ref": "#/definitions/Port",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -2062,6 +2062,16 @@
}
},
"properties": {
+ "DateCode": {
+ "description": "The manufacturing date code for this SFP.",
+ "longDescription": "This property shall contain the manufacturing date code for this SFP as determined by the vendor or supplier.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_14_0"
+ },
"FiberConnectionType": {
"anyOf": [
{
@@ -2156,6 +2166,27 @@
"longDescription": "This property shall contain the SFP device type currently attached to this port.",
"readonly": true,
"versionAdded": "v1_4_0"
+ },
+ "VendorOUI": {
+ "description": "The IEEE OUI of the vendor of this SFP.",
+ "longDescription": "This property shall contain the IEEE organizationally unique identifier (OUI) of the vendor of this SFP.",
+ "pattern": "^([0-9A-Fa-f]{2}-){2}([0-9A-Fa-f]{2})$",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_13_0"
+ },
+ "Version": {
+ "description": "The hardware version of this SFP.",
+ "longDescription": "This property shall contain the hardware version of this SFP as determined by the vendor or supplier.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "versionAdded": "v1_13_0"
}
},
"type": "object"
@@ -2211,6 +2242,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#Port.v1_12_0.Port"
+ "release": "2024.3",
+ "title": "#Port.v1_14_0.Port"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/PortMetrics.v1_6_1.json b/redfish-core/schema/dmtf/json-schema/PortMetrics.v1_7_0.json
index 7ed542ad55..1144fe9a31 100644
--- a/redfish-core/schema/dmtf/json-schema/PortMetrics.v1_6_1.json
+++ b/redfish-core/schema/dmtf/json-schema/PortMetrics.v1_7_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/PortMetrics.v1_6_1.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/PortMetrics.v1_7_0.json",
"$ref": "#/definitions/PortMetrics",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -1059,6 +1059,17 @@
],
"units": "mW",
"versionAdded": "v1_1_0"
+ },
+ "WavelengthNanometers": {
+ "description": "The laser wavelength, in nanometers, for a small form-factor pluggable (SFP) transceiver.",
+ "longDescription": "This property shall contain the laser wavelength, in nanometers, for a small form-factor pluggable (SFP) transceiver. This property shall not be present for non-optic SFP mediums.",
+ "readonly": true,
+ "type": [
+ "string",
+ "null"
+ ],
+ "units": "nm",
+ "versionAdded": "v1_7_0"
}
},
"type": "object"
@@ -1066,6 +1077,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#PortMetrics.v1_6_1.PortMetrics"
+ "release": "2024.3",
+ "title": "#PortMetrics.v1_7_0.PortMetrics"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Processor.v1_20_0.json b/redfish-core/schema/dmtf/json-schema/Processor.v1_20_1.json
index 1da995bb15..8cdfe16e05 100644
--- a/redfish-core/schema/dmtf/json-schema/Processor.v1_20_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Processor.v1_20_1.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Processor.v1_20_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Processor.v1_20_1.json",
"$ref": "#/definitions/Processor",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -898,7 +898,7 @@
"ProcessorId": {
"$ref": "#/definitions/ProcessorId",
"description": "The identification information for this processor.",
- "longDescription": "This object shall contain identification information for this processor."
+ "longDescription": "This object shall contain identification information for this processor. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification."
},
"ProcessorIndex": {
"description": "The logical index of this processor within the system.",
@@ -1170,7 +1170,7 @@
"properties": {
"EffectiveFamily": {
"description": "The effective family for this processor.",
- "longDescription": "This property shall contain the effective family information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`.",
+ "longDescription": "This property shall contain the effective family information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true,
"type": [
"string",
@@ -1179,7 +1179,7 @@
},
"EffectiveModel": {
"description": "The effective model for this processor.",
- "longDescription": "This property shall contain the effective model information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`.",
+ "longDescription": "This property shall contain the effective model information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true,
"type": [
"string",
@@ -1188,7 +1188,7 @@
},
"IdentificationRegisters": {
"description": "The raw manufacturer-provided processor identification registers for this processor.",
- "longDescription": "This property shall contain the raw manufacturer-provided processor-specific identification registers of this processor's features.",
+ "longDescription": "This property shall contain the raw manufacturer-provided processor-specific identification registers of this processor's features. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"pattern": "^0x[0-9A-Fa-f]+$",
"readonly": true,
"type": [
@@ -1198,7 +1198,7 @@
},
"MicrocodeInfo": {
"description": "The microcode information for this processor.",
- "longDescription": "This property shall contain the microcode information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`.",
+ "longDescription": "This property shall contain the microcode information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true,
"type": [
"string",
@@ -1217,7 +1217,7 @@
},
"Step": {
"description": "The step value for this processor.",
- "longDescription": "This property shall contain the step or revision information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`.",
+ "longDescription": "This property shall contain the step or revision information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true,
"type": [
"string",
@@ -1226,7 +1226,7 @@
},
"VendorId": {
"description": "The vendor identification for this processor.",
- "longDescription": "This property shall contain the vendor identification information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`.",
+ "longDescription": "This property shall contain the vendor identification information as provided by the manufacturer of this processor. If this property represents raw register data, as determined by the value of the `ProcessorArchitecture` property, the service shall encode the value as a hex-encoded string following the regular expression pattern `^0x[0-9A-Fa-f]+$` or a decimal-encoded string following the regular expression pattern `^\\d+$`. For additional property requirements, see the corresponding definition in the Redfish Data Model Specification.",
"readonly": true,
"type": [
"string",
@@ -1590,5 +1590,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2024.1",
- "title": "#Processor.v1_20_0.Processor"
+ "title": "#Processor.v1_20_1.Processor"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Resource.v1_19_0.json b/redfish-core/schema/dmtf/json-schema/Resource.v1_20_0.json
index 1468893fe4..7cbdc9abb6 100644
--- a/redfish-core/schema/dmtf/json-schema/Resource.v1_19_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Resource.v1_20_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Resource.v1_19_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Resource.v1_20_0.json",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
"definitions": {
@@ -1174,6 +1174,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#Resource.v1_19_0"
+ "release": "2024.3",
+ "title": "#Resource.v1_20_0"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Sensor.v1_9_0.json b/redfish-core/schema/dmtf/json-schema/Sensor.v1_10_1.json
index b826282871..2bc28682ae 100644
--- a/redfish-core/schema/dmtf/json-schema/Sensor.v1_9_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Sensor.v1_10_1.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Sensor.v1_9_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Sensor.v1_10_1.json",
"$ref": "#/definitions/Sensor",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -472,6 +472,16 @@
"longDescription": "This property shall represent the combination of current-carrying conductors that distribute power.",
"readonly": true
},
+ "Enabled": {
+ "description": "Indicates whether the sensor is enabled and provides a reading.",
+ "longDescription": "This property shall indicate whether the sensor is enabled and provides a `Reading`. The value `true` shall indicate the sensor is enabled and returns the `Reading` property with a valid value. The value `false` shall indicate the sensor is disabled, shall not return the `Reading` property, and shall not trigger events, logging, or other functionality. This property allows a user to disable a faulty sensor or to otherwise remove it from use.",
+ "readonly": false,
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "versionAdded": "v1_10_0"
+ },
"Id": {
"$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Id",
"readonly": true
@@ -720,7 +730,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -794,8 +804,8 @@
"readonly": true
},
"ReadingUnits": {
- "description": "The units of the reading and thresholds.",
- "longDescription": "This property shall contain the units of the sensor's reading and thresholds.",
+ "description": "The units of the reading, thresholds, and other reading-related properties in UCUM c/s format.",
+ "longDescription": "This property shall contain the units of the sensor's reading, thresholds, and other reading-related properties. The value shall follow the case-sensitive symbol format defined by the Unified Code for Units of Measure (UCUM), as specified by the 'Units of measure annotation' clause of the Redfish Specification.",
"readonly": true,
"type": [
"string",
@@ -1022,7 +1032,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1077,7 +1087,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1169,7 +1179,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1224,7 +1234,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1308,7 +1318,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1364,7 +1374,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1495,7 +1505,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1586,7 +1596,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1630,7 +1640,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1697,7 +1707,7 @@
"Reading": {
"description": "The sensor value.",
"excerpt": "Sensor",
- "longDescription": "This property shall contain the sensor value.",
+ "longDescription": "This property shall contain the sensor value. This property shall not be returned if the `Enabled` property is supported and contains `false`.",
"readonly": true,
"type": [
"number",
@@ -1898,6 +1908,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#Sensor.v1_9_0.Sensor"
+ "release": "2024.2",
+ "title": "#Sensor.v1_10_1.Sensor"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Storage.v1_16_0.json b/redfish-core/schema/dmtf/json-schema/Storage.v1_17_1.json
index 12e5eeb260..a512bba35e 100644
--- a/redfish-core/schema/dmtf/json-schema/Storage.v1_16_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Storage.v1_17_1.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/Storage.v1_16_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/Storage.v1_17_1.json",
"$ref": "#/definitions/Storage",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -29,6 +29,9 @@
"#Storage.ResetToDefaults": {
"$ref": "#/definitions/ResetToDefaults"
},
+ "#Storage.SetControllerPassword": {
+ "$ref": "#/definitions/SetControllerPassword"
+ },
"#Storage.SetEncryptionKey": {
"$ref": "#/definitions/SetEncryptionKey"
},
@@ -110,6 +113,21 @@
],
"type": "object"
},
+ "ConfigLockOptions": {
+ "enum": [
+ "Unlocked",
+ "Locked",
+ "LockdownUnsupported",
+ "CommandUnsupported"
+ ],
+ "enumDescriptions": {
+ "CommandUnsupported": "The command is not supported, therefore lockdown does not apply.",
+ "LockdownUnsupported": "The command is supported but is not able to be locked.",
+ "Locked": "The command is supported and is currently locked.",
+ "Unlocked": "The command is supported, able to be locked, and is currently unlocked."
+ },
+ "type": "string"
+ },
"ConfigurationLock": {
"enum": [
"Enabled",
@@ -118,12 +136,12 @@
],
"enumDescriptions": {
"Disabled": "In-band configuration requests are not locked.",
- "Enabled": "In-band configuration requests are locked. Configuration requests include applying firmware, updating security keys, and other hardware settings. It does not include managing the volumes or data within the storage subsystem.",
+ "Enabled": "In-band configuration requests are locked as specified by `TargetConfigurationLockLevel`.",
"Partial": "Some in-band configuration requests are not locked while others are locked. This value is used for status reporting to indicate that the storage subsystem is partially locked and client action is recommended."
},
"enumLongDescriptions": {
"Disabled": "This value shall indicate in-band configuration requests are not locked.",
- "Enabled": "This value shall indicate in-band configuration requests are locked.",
+ "Enabled": "This value shall indicate in-band configuration requests are locked as specified by `TargetConfigurationLockLevel`.",
"Partial": "This value shall indicate some in-band configuration requests are not locked while others are locked."
},
"type": "string"
@@ -132,13 +150,24 @@
"enum": [
"Disabled",
"UseExternalKey",
- "UseLocalKey"
+ "UseLocalKey",
+ "PasswordOnly",
+ "PasswordWithExternalKey",
+ "PasswordWithLocalKey"
],
"enumDescriptions": {
"Disabled": "Encryption is disabled on the storage subsystem.",
+ "PasswordOnly": "The storage subsystem uses a password, but no keys for encryption.",
+ "PasswordWithExternalKey": "The storage subsystem uses a password and one or more external keys for encryption.",
+ "PasswordWithLocalKey": "The storage subsystem uses a password and a local key for encryption.",
"UseExternalKey": "The storage subsystem uses one or more external keys for encryption.",
"UseLocalKey": "The storage subsystem uses a local key for encryption."
},
+ "enumVersionAdded": {
+ "PasswordOnly": "v1_17_0",
+ "PasswordWithExternalKey": "v1_17_0",
+ "PasswordWithLocalKey": "v1_17_0"
+ },
"type": "string"
},
"HotspareActivationPolicy": {
@@ -239,6 +268,98 @@
},
"type": "object"
},
+ "NVMeConfigurationLockState": {
+ "additionalProperties": false,
+ "description": "The configurable features that are able to be locked on an NVMe subsystem and their current lock state.",
+ "longDescription": "This type shall contain the configurable features that are able to be locked on an NVMe subsystem and their current lock state.",
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "FirmwareCommit": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Firmware Commit command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Firmware Commit command.",
+ "readonly": true,
+ "versionAdded": "v1_17_0"
+ },
+ "FirmwareImageDownload": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Firmware Image Download command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Firmware Image Download command.",
+ "readonly": true,
+ "versionAdded": "v1_17_0"
+ },
+ "Lockdown": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Lockdown command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Lockdown command.",
+ "readonly": true,
+ "versionAdded": "v1_17_0"
+ },
+ "SecuritySend": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-defined Security Send command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-defined Security Send command.",
+ "readonly": true,
+ "versionAdded": "v1_17_0"
+ },
+ "VPDWrite": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ConfigLockOptions"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The lock state of the NVMe-MI-defined VPD Write command.",
+ "longDescription": "This property shall contain the lock state of the NVMe-MI-defined VPD Write command.",
+ "readonly": true,
+ "versionAdded": "v1_17_0"
+ }
+ },
+ "type": "object"
+ },
"NVMeSubsystemProperties": {
"additionalProperties": false,
"description": "Information specific to NVMe Subsystems.",
@@ -258,6 +379,19 @@
}
},
"properties": {
+ "ConfigurationLockState": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/NVMeConfigurationLockState"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state.",
+ "longDescription": "This property shall contain the configurable features that are able to be locked from in-band usage on an NVMe subsystem and their current lock state.",
+ "versionAdded": "v1_17_0"
+ },
"MaxNamespacesSupported": {
"description": "The maximum number of namespace attachments supported by this NVMe Subsystem.",
"longDescription": "This property shall contain the maximum number of namespace attachments supported by this NVMe Subsystem. If no maximum is specified, this property should not be implemented.",
@@ -444,14 +578,64 @@
},
"type": "string"
},
+ "SetControllerPassword": {
+ "additionalProperties": false,
+ "description": "This action sets the controller boot password for a host-based storage controller.",
+ "longDescription": "This action shall set the controller boot password for a host-based storage controller.",
+ "parameters": {
+ "CurrentPassword": {
+ "description": "The current controller password. This parameter is not needed if the controller does not currently have a password.",
+ "longDescription": "This parameter shall contain the current controller password. Services may reject the action request if this parameter is not provided or the value supplied does not match the current password.",
+ "type": "string"
+ },
+ "NewPassword": {
+ "description": "The new password to set for the controller.",
+ "longDescription": "This parameter shall contain the new password to set for the controller.",
+ "requiredParameter": true,
+ "type": "string"
+ },
+ "SecurityKey": {
+ "description": "The security key for the controller. This parameter is not needed if the controller does not have a security key.",
+ "longDescription": "This parameter shall contain the controller security key. Services may reject the action request if this parameter is not provided or the value provided does not match the security key for the controller.",
+ "type": "string"
+ }
+ },
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "target": {
+ "description": "Link to invoke action",
+ "format": "uri-reference",
+ "type": "string"
+ },
+ "title": {
+ "description": "Friendly action name",
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "versionAdded": "v1_17_0"
+ },
"SetEncryptionKey": {
"additionalProperties": false,
"description": "This action sets the local encryption key for the storage subsystem.",
"longDescription": "This action shall set the local encryption key for the storage subsystem.",
"parameters": {
"CurrentEncryptionKey": {
- "description": "The current local encryption key on the storage subsystem.",
- "longDescription": "This parameter shall contain the current local encryption key on the storage subsystem. Services may reject the action request if this parameter is not provided.",
+ "description": "The current local encryption key on the storage subsystem. This parameter is not needed if the controller does not currently have an encryption key.",
+ "longDescription": "This parameter shall contain the current local encryption key on the storage subsystem. Services may reject the action request if this parameter is not provided or the value supplied does not match the current encryption key.",
"type": "string",
"versionAdded": "v1_14_0"
},
@@ -554,7 +738,7 @@
"type": "null"
}
],
- "description": "Indicates whether in-band configuration requests to the storage subsystem are locked.",
+ "description": "Indicates whether in-band configuration requests to the storage subsystem are locked. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock.",
"longDescription": "This property shall indicate whether configuration requests to the storage subsystem are locked. Services shall reject modification requests that contain the value `Partial`. Modifying the value of this property may affect the `ConfigurationLock` property in `Drive` resources referenced by the `Drives` property.",
"readonly": false,
"versionAdded": "v1_16_0"
@@ -743,6 +927,20 @@
"readonly": true,
"versionAdded": "v1_8_0"
},
+ "TargetConfigurationLockLevel": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/TargetConfigurationLockLevel"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Indicates the target configuration lock level for the drive based upon the state of the `ConfigurationLock` property. Other properties, such as `ConfigurationLockState`, contain additional information regarding the status of the configuration lock.",
+ "longDescription": "This property shall contain the target configuration lock level for the drive. For NVMe subsystems, services shall implement the locking requirements specified by SNIA's Swordfish NVMe Model Overview and Mapping Guide.",
+ "readonly": false,
+ "versionAdded": "v1_17_0"
+ },
"Volumes": {
"$ref": "http://redfish.dmtf.org/schemas/swordfish/v1/VolumeCollection.json#/definitions/VolumeCollection",
"description": "The set of volumes that the storage controllers produce.",
@@ -1111,10 +1309,19 @@
},
"properties": {},
"type": "object"
+ },
+ "TargetConfigurationLockLevel": {
+ "enum": [
+ "Baseline"
+ ],
+ "enumDescriptions": {
+ "Baseline": "The standard configuration lock level, corresponding to applying firmware, updating security keys, and modifying other hardware settings. It does not include managing the volumes or data within the storage subsystem."
+ },
+ "type": "string"
}
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2024.1",
- "title": "#Storage.v1_16_0.Storage"
+ "release": "2024.2",
+ "title": "#Storage.v1_17_1.Storage"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/StorageController.v1_7_3.json b/redfish-core/schema/dmtf/json-schema/StorageController.v1_8_0.json
index f5df7e2011..f8166712e6 100644
--- a/redfish-core/schema/dmtf/json-schema/StorageController.v1_7_3.json
+++ b/redfish-core/schema/dmtf/json-schema/StorageController.v1_8_0.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/StorageController.v1_7_3.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/StorageController.v1_8_0.json",
"$ref": "#/definitions/StorageController",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -572,6 +572,17 @@
"longDescription": "This property shall contain the type of NVMe controller.",
"readonly": true
},
+ "MaxAttachedNamespaces": {
+ "description": "The maximum number of attached namespaces allowed by this NVMe I/O controller.",
+ "longDescription": "This property shall contain the maximum number of attached namespaces allowed by this NVMe I/O controller.",
+ "minimum": 0,
+ "readonly": true,
+ "type": [
+ "integer",
+ "null"
+ ],
+ "versionAdded": "v1_8_0"
+ },
"MaxQueueSize": {
"description": "The maximum individual queue size that an NVMe I/O controller supports.",
"longDescription": "This property shall contain the maximum individual queue entry size supported per queue. This is a zero-based value, where the minimum value is one, indicating two entries. For PCIe, this applies to both submission and completion queues. For NVMe-oF, this applies only to submission queues.",
@@ -1186,6 +1197,6 @@
},
"language": "en",
"owningEntity": "DMTF",
- "release": "2023.1",
- "title": "#StorageController.v1_7_3.StorageController"
+ "release": "2024.3",
+ "title": "#StorageController.v1_8_0.StorageController"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/UpdateService.v1_14_0.json b/redfish-core/schema/dmtf/json-schema/UpdateService.v1_14_1.json
index 98e64f43d6..69aa80a099 100644
--- a/redfish-core/schema/dmtf/json-schema/UpdateService.v1_14_0.json
+++ b/redfish-core/schema/dmtf/json-schema/UpdateService.v1_14_1.json
@@ -1,5 +1,5 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/UpdateService.v1_14_0.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/UpdateService.v1_14_1.json",
"$ref": "#/definitions/UpdateService",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
"copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
@@ -709,5 +709,5 @@
"language": "en",
"owningEntity": "DMTF",
"release": "2024.1",
- "title": "#UpdateService.v1_14_0.UpdateService"
+ "title": "#UpdateService.v1_14_1.UpdateService"
} \ No newline at end of file
diff --git a/redfish-core/schema/dmtf/json-schema/Volume.v1_10_0.json b/redfish-core/schema/dmtf/json-schema/Volume.v1_10_0.json
index 32b1b177df..9803ce70d3 100644
--- a/redfish-core/schema/dmtf/json-schema/Volume.v1_10_0.json
+++ b/redfish-core/schema/dmtf/json-schema/Volume.v1_10_0.json
@@ -2,8 +2,38 @@
"$id": "http://redfish.dmtf.org/schemas/swordfish/v1/Volume.v1_10_0.json",
"$ref": "#/definitions/Volume",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
- "copyright": "Copyright 2015-2023 Storage Networking Industry Association (SNIA), USA. All rights reserved.",
+ "copyright": "Copyright 2015-2024 Storage Networking Industry Association (SNIA), USA. All rights reserved.",
"definitions": {
+ "ALUA": {
+ "additionalProperties": false,
+ "patternProperties": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
+ "description": "This property shall specify a valid odata or Redfish property.",
+ "type": [
+ "array",
+ "boolean",
+ "integer",
+ "number",
+ "null",
+ "object",
+ "string"
+ ]
+ }
+ },
+ "properties": {
+ "ANAGroupId": {
+ "description": "The ANA group id for this volume.",
+ "longDescription": "This shall contain the ANA group id for this volume.",
+ "readonly": true,
+ "type": [
+ "number",
+ "null"
+ ],
+ "versionAdded": "v1_10_0"
+ }
+ },
+ "type": "object"
+ },
"Actions": {
"additionalProperties": false,
"patternProperties": {
@@ -552,6 +582,19 @@
"readonly": true,
"versionAdded": "v1_4_0"
},
+ "ProvidingStoragePool": {
+ "anyOf": [
+ {
+ "$ref": "http://redfish.dmtf.org/schemas/swordfish/v1/StoragePool.json#/definitions/StoragePool"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "The StoragePool resource that provides this volume resource.",
+ "longDescription": "This property shall contain a pointer to the StoragePool resource that provides this volume resource.",
+ "versionAdded": "v1_10_0"
+ },
"ServerEndpoints": {
"description": "An array of references to the server Endpoints associated with this volume.",
"items": {
@@ -749,6 +792,26 @@
"units": "By",
"versionAdded": "v1_5_0"
},
+ "SupportsIOPerformanceHints": {
+ "description": "Indicates whether the namespace supports IO performance hints.",
+ "longDescription": "This property shall indicate whether the namespace supports IO performance hints.",
+ "readonly": true,
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "versionAdded": "v1_10_0"
+ },
+ "SupportsMultipleNamespaceAttachments": {
+ "description": "Indicates whether the namespace may be attached to two or more controllers.",
+ "longDescription": "This property shall indicate whether the namespace may be attached to two or more controllers.",
+ "readonly": true,
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "versionAdded": "v1_10_0"
+ },
"Type": {
"anyOf": [
{
@@ -1148,6 +1211,19 @@
"@odata.type": {
"$ref": "http://redfish.dmtf.org/schemas/v1/odata-v4.json#/definitions/type"
},
+ "ALUA": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/ALUA"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "ALUA properties for this volume.",
+ "longDescription": "This shall identify the ALUA properties for this volume.",
+ "versionAdded": "v1_10_0"
+ },
"AccessCapabilities": {
"description": "Supported IO access capabilities.",
"items": {
@@ -1301,9 +1377,11 @@
},
"IOStatistics": {
"$ref": "http://redfish.dmtf.org/schemas/swordfish/v1/IOStatistics.v1_0_1.json#/definitions/IOStatistics",
+ "deprecated": "This property is deprecated in favor of the IOStatistics property in VolumeMetrics.",
"description": "Statistics for this volume.",
"longDescription": "The value shall represent IO statistics for this volume.",
- "versionAdded": "v1_2_0"
+ "versionAdded": "v1_2_0",
+ "versionDeprecated": "v1_10_0"
},
"Id": {
"$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Id",
diff --git a/redfish-core/schema/dmtf/json-schema/VolumeCollection.json b/redfish-core/schema/dmtf/json-schema/VolumeCollection.json
index 9ee0661a7e..5bebf3d393 100644
--- a/redfish-core/schema/dmtf/json-schema/VolumeCollection.json
+++ b/redfish-core/schema/dmtf/json-schema/VolumeCollection.json
@@ -2,7 +2,7 @@
"$id": "http://redfish.dmtf.org/schemas/swordfish/v1/VolumeCollection.json",
"$ref": "#/definitions/VolumeCollection",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
- "copyright": "Copyright 2015-2023 Storage Networking Industry Association (SNIA), USA. All rights reserved.",
+ "copyright": "Copyright 2015-2024 Storage Networking Industry Association (SNIA), USA. All rights reserved.",
"definitions": {
"VolumeCollection": {
"anyOf": [
diff --git a/redfish-core/schema/dmtf/json-schema/info.json b/redfish-core/schema/dmtf/json-schema/info.json
deleted file mode 100644
index 236471aa2f..0000000000
--- a/redfish-core/schema/dmtf/json-schema/info.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "version": "2024.1",
- "date": "05-16-2024"
-}
diff --git a/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations-v1.json b/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations-v1.json
index 18c7245ced..a93ea798b7 100644
--- a/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations-v1.json
+++ b/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations-v1.json
@@ -1,7 +1,7 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/redfish-payload-annotations.v1_2_2.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/redfish-payload-annotations.v1_2_3.json",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
- "copyright": "Copyright 2014-2023 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
+ "copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
"properties": {
"@Redfish.ActionInfo": {
"description": "The term can be applied to an action to specify a URI to an ActionInfo resource that describes the parameters supported by this instance of the action.",
@@ -134,7 +134,7 @@
"readonly": true
},
"^([a-zA-Z_][a-zA-Z0-9_]*)?@Redfish.AllowableNumbers$": {
- "description": "The term specifies the numeric values or duration values, inclusive ranges of values, and incremental step values for a read-write property that are supported by the service, as defined in the 'Allowable values for numbers and durations' clause of the Redfish Specification.",
+ "description": "The term specifies the numeric values or duration values, inclusive ranges of values, and incremental step values for an action parameter or a read-write property that are supported by the service, as defined in the 'Allowable values for numbers and durations' clause of the Redfish Specification.",
"type": "array",
"items": {
"type": "string"
@@ -142,7 +142,7 @@
"readonly": true
},
"^([a-zA-Z_][a-zA-Z0-9_]*)?@Redfish.AllowablePattern$": {
- "description": "The term specifies a regular expression that describes the allowable values for a read-write property as supported by the service.",
+ "description": "The term specifies a regular expression that describes the allowable values for an action parameter or a read-write property as supported by the service.",
"type": "string",
"readonly": true
},
diff --git a/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations.v1_2_2.json b/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations.v1_2_3.json
index 18c7245ced..a93ea798b7 100644
--- a/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations.v1_2_2.json
+++ b/redfish-core/schema/dmtf/json-schema/redfish-payload-annotations.v1_2_3.json
@@ -1,7 +1,7 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/redfish-payload-annotations.v1_2_2.json",
+ "$id": "http://redfish.dmtf.org/schemas/v1/redfish-payload-annotations.v1_2_3.json",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
- "copyright": "Copyright 2014-2023 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
+ "copyright": "Copyright 2014-2024 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
"properties": {
"@Redfish.ActionInfo": {
"description": "The term can be applied to an action to specify a URI to an ActionInfo resource that describes the parameters supported by this instance of the action.",
@@ -134,7 +134,7 @@
"readonly": true
},
"^([a-zA-Z_][a-zA-Z0-9_]*)?@Redfish.AllowableNumbers$": {
- "description": "The term specifies the numeric values or duration values, inclusive ranges of values, and incremental step values for a read-write property that are supported by the service, as defined in the 'Allowable values for numbers and durations' clause of the Redfish Specification.",
+ "description": "The term specifies the numeric values or duration values, inclusive ranges of values, and incremental step values for an action parameter or a read-write property that are supported by the service, as defined in the 'Allowable values for numbers and durations' clause of the Redfish Specification.",
"type": "array",
"items": {
"type": "string"
@@ -142,7 +142,7 @@
"readonly": true
},
"^([a-zA-Z_][a-zA-Z0-9_]*)?@Redfish.AllowablePattern$": {
- "description": "The term specifies a regular expression that describes the allowable values for a read-write property as supported by the service.",
+ "description": "The term specifies a regular expression that describes the allowable values for an action parameter or a read-write property as supported by the service.",
"type": "string",
"readonly": true
},
diff --git a/redfish-core/schema/dmtf/meson.build b/redfish-core/schema/dmtf/meson.build
new file mode 100644
index 0000000000..c28d224436
--- /dev/null
+++ b/redfish-core/schema/dmtf/meson.build
@@ -0,0 +1,13 @@
+install_subdir(
+ 'installed',
+ install_dir: 'share/www/redfish/v1/schema',
+ strip_directory: true,
+ follow_symlinks: true,
+)
+
+install_subdir(
+ 'json-schema-installed',
+ install_dir: 'share/www/redfish/v1/JsonSchemas',
+ strip_directory: true,
+ follow_symlinks: true,
+)
diff --git a/redfish-core/schema/meson.build b/redfish-core/schema/meson.build
new file mode 100644
index 0000000000..0ea7a4b785
--- /dev/null
+++ b/redfish-core/schema/meson.build
@@ -0,0 +1,2 @@
+subdir('dmtf')
+subdir('oem')
diff --git a/redfish-core/schema/oem/meson.build b/redfish-core/schema/oem/meson.build
new file mode 100644
index 0000000000..12bd975077
--- /dev/null
+++ b/redfish-core/schema/oem/meson.build
@@ -0,0 +1 @@
+subdir('openbmc')
diff --git a/redfish-core/schema/oem/openbmc/csdl/OemComputerSystem_v1.xml b/redfish-core/schema/oem/openbmc/csdl/OemComputerSystem_v1.xml
deleted file mode 100644
index 6588f0ac54..0000000000
--- a/redfish-core/schema/oem/openbmc/csdl/OemComputerSystem_v1.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
- <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml">
- <edmx:Include Namespace="Org.OData.Core.V1" Alias="OData" />
- </edmx:Reference>
- <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RedfishExtensions_v1.xml">
- <edmx:Include Namespace="Validation.v1_0_0" Alias="Validation"/>
- <edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish"/>
- </edmx:Reference>
- <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ComputerSystem_v1.xml">
- <edmx:Include Namespace="ComputerSystem"/>
- <edmx:Include Namespace="ComputerSystem.v1_4_0"/>
- </edmx:Reference>
- <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Resource_v1.xml">
- <edmx:Include Namespace="Resource"/>
- <edmx:Include Namespace="Resource.v1_0_0"/>
- </edmx:Reference>
-
- <edmx:DataServices>
- <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OemComputerSystem">
- <ComplexType Name="Oem" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="OemComputerSystem Oem properties." />
- <Annotation Term="OData.AutoExpand"/>
- <Property Name="OpenBmc" Type="OemComputerSystem.OpenBmc"/>
- </ComplexType>
-
- <ComplexType Name="OpenBmc" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="Oem properties for OpenBmc." />
- <Annotation Term="Redfish.DynamicPropertyPatterns">
- <Collection>
- <NavigationProperty Type="OemComputerSystem.FirmwareProvisioning">
- <Annotation Term="OData.AutoExpand"/>
- <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+" />
- <PropertyValue Property="Type" String="OemComputerSystem.FirmwareProvisioning" />
- </NavigationProperty>
- </Collection>
- </Annotation>
- </ComplexType>
-
- <ComplexType Name="FirmwareProvisioning" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="false" />
- <Annotation Term="OData.Description" String="Configuration data for platform firmware provisioning." />
- <Property Name="ProvisioningStatus" Type="OemComputerSystem.FirmwareProvisioningStatus">
- <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
- <Annotation Term="OData.Description" String="This indicates platform firmware provisioning state."/>
- <Annotation Term="OData.LongDescription" String="The value of this property indicating provisioning status of platform firmware."/>
- </Property>
- </ComplexType>
-
- <EnumType Name="FirmwareProvisioningStatus">
- <Member Name="NotProvisioned">
- <Annotation Term="OData.Description" String="Platform firmware is not provisioned."/>
- <Annotation Term="OData.LongDescription" String="Platform firmware is not provisioned."/>
- </Member>
- <Member Name="ProvisionedButNotLocked">
- <Annotation Term="OData.Description" String="Platform firmware is provisioned but not locked."/>
- <Annotation Term="OData.LongDescription" String="Platform firmware is provisioned but not locked. So re-provisioning is allowed in this state."/>
- </Member>
- <Member Name="ProvisionedAndLocked">
- <Annotation Term="OData.Description" String="Platform firmware is provisioned and locked."/>
- <Annotation Term="OData.LongDescription" String="Platform firmware is provisioned and locked. So re-provisioning is not allowed in this state."/>
- </Member>
- </EnumType>
- </Schema>
- </edmx:DataServices>
-</edmx:Edmx>
diff --git a/redfish-core/schema/oem/openbmc/csdl/OpenBMCAccountService_v1.xml b/redfish-core/schema/oem/openbmc/csdl/OpenBMCAccountService_v1.xml
index 66b00bbc32..977206d54e 100644
--- a/redfish-core/schema/oem/openbmc/csdl/OpenBMCAccountService_v1.xml
+++ b/redfish-core/schema/oem/openbmc/csdl/OpenBMCAccountService_v1.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
-
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml">
<edmx:Include Namespace="Org.OData.Core.V1" Alias="OData"/>
</edmx:Reference>
@@ -14,9 +13,7 @@
<edmx:Include Namespace="Resource"/>
<edmx:Include Namespace="Resource.v1_0_0"/>
</edmx:Reference>
-
<edmx:DataServices>
-
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCAccountService">
<Annotation Term="Redfish.OwningEntity" String="OpenBMC"/>
<Annotation Term="OData.Description" String="OpenBMC extensions to the standard account service."/>
@@ -26,58 +23,46 @@
</Collection>
</Annotation>
</Schema>
-
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCAccountService.v1_0_0">
<Annotation Term="Redfish.OwningEntity" String="OpenBMC"/>
-
<ComplexType Name="AccountService" BaseType="Resource.OemObject">
<Annotation Term="OData.Description" String="OpenBMC OEM Extension for AccountService."/>
<Annotation Term="OData.LongDescription" String="OpenBMC OEM Extension for AccountService providing info about authentication methods."/>
-
<Property Name="AuthMethods" Type="OpenBMCAccountService.v1_0_0.AuthMethodsConfig">
<Annotation Term="OData.Description" String="Authorization Methods configuration."/>
<Annotation Term="OData.LongDescription" String="Configuration describing which auth methods are enabled."/>
</Property>
</ComplexType>
-
<ComplexType Name="AuthMethodsConfig">
<Annotation Term="OData.AdditionalProperties" Bool="false"/>
<Annotation Term="OData.Description" String="Authorization Methods configuration."/>
<Annotation Term="OData.LongDescription" String="Configuration describing which auth methods are enabled."/>
-
<Property Name="BasicAuth" Type="Edm.Boolean">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
<Annotation Term="OData.Description" String="Indicates whether BasicAuth authorization is enabled."/>
<Annotation Term="OData.LongDescription" String="The value of this property shall be a boolean indicating whether BasicAuth authorization is enabled."/>
</Property>
-
<Property Name="Cookie" Type="Edm.Boolean">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
<Annotation Term="OData.Description" String="Indicates whether Cookie authorization is enabled."/>
<Annotation Term="OData.LongDescription" String="The value of this property shall be a boolean indicating whether Cookie authorization is enabled."/>
</Property>
-
<Property Name="SessionToken" Type="Edm.Boolean">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
<Annotation Term="OData.Description" String="Indicates whether SessionToken authorization is enabled."/>
<Annotation Term="OData.LongDescription" String="The value of this property shall be a boolean indicating whether SessionToken authorization is enabled."/>
</Property>
-
<Property Name="XToken" Type="Edm.Boolean">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
<Annotation Term="OData.Description" String="Indicates whether XToken authorization is enabled."/>
<Annotation Term="OData.LongDescription" String="The value of this property shall be a boolean indicating whether XToken authorization is enabled."/>
</Property>
-
<Property Name="TLS" Type="Edm.Boolean">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
<Annotation Term="OData.Description" String="Indicates whether TLS authorization is enabled."/>
<Annotation Term="OData.LongDescription" String="The value of this property shall be a boolean indicating whether TLS authorization is enabled."/>
</Property>
</ComplexType>
-
</Schema>
-
</edmx:DataServices>
</edmx:Edmx>
-
diff --git a/redfish-core/schema/oem/openbmc/csdl/OpenBMCComputerSystem_v1.xml b/redfish-core/schema/oem/openbmc/csdl/OpenBMCComputerSystem_v1.xml
new file mode 100644
index 0000000000..7c8fb9566b
--- /dev/null
+++ b/redfish-core/schema/oem/openbmc/csdl/OpenBMCComputerSystem_v1.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+ <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml">
+ <edmx:Include Namespace="Org.OData.Core.V1" Alias="OData"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RedfishExtensions_v1.xml">
+ <edmx:Include Namespace="Validation.v1_0_0" Alias="Validation"/>
+ <edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ComputerSystem_v1.xml">
+ <edmx:Include Namespace="ComputerSystem"/>
+ <edmx:Include Namespace="ComputerSystem.v1_4_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Resource_v1.xml">
+ <edmx:Include Namespace="Resource"/>
+ <edmx:Include Namespace="Resource.v1_0_0"/>
+ </edmx:Reference>
+ <edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCComputerSystem">
+ <Annotation Term="Redfish.OwningEntity" String="OpenBMC"/>
+ <Annotation Term="OData.Description" String="OpenBMC extensions to the standard account service."/>
+ <Annotation Term="Redfish.Uris">
+ <Collection>
+ <String>/redfish/v1/Systems/{SystemId}#/Oem/OpenBMC/OpenBMCComputerSystem</String>
+ </Collection>
+ </Annotation>
+ </Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCComputerSystem.v1_0_0">
+ <ComplexType Name="Oem" BaseType="Resource.OemObject">
+ <Annotation Term="OData.AdditionalProperties" Bool="true"/>
+ <Annotation Term="OData.Description" String="OpenBMCComputerSystem Oem properties."/>
+ <Annotation Term="OData.AutoExpand"/>
+ <Property Name="OpenBmc" Type="OpenBMCComputerSystem.OpenBmc"/>
+ </ComplexType>
+ <ComplexType Name="OpenBmc" BaseType="Resource.OemObject">
+ <Annotation Term="OData.AdditionalProperties" Bool="true"/>
+ <Annotation Term="OData.Description" String="Oem properties for OpenBmc."/>
+ <Annotation Term="Redfish.DynamicPropertyPatterns">
+ <Collection>
+ <NavigationProperty Type="OpenBMCComputerSystem.FirmwareProvisioning">
+ <Annotation Term="OData.AutoExpand"/>
+ <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+"/>
+ <PropertyValue Property="Type" String="OpenBMCComputerSystem.FirmwareProvisioning"/>
+ </NavigationProperty>
+ </Collection>
+ </Annotation>
+ </ComplexType>
+ <ComplexType Name="FirmwareProvisioning" BaseType="Resource.OemObject">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="Configuration data for platform firmware provisioning."/>
+ <Property Name="ProvisioningStatus" Type="OpenBMCComputerSystem.FirmwareProvisioningStatus">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="This indicates platform firmware provisioning state."/>
+ <Annotation Term="OData.LongDescription" String="The value of this property indicating provisioning status of platform firmware."/>
+ </Property>
+ </ComplexType>
+ <EnumType Name="FirmwareProvisioningStatus">
+ <Member Name="NotProvisioned">
+ <Annotation Term="OData.Description" String="Platform firmware is not provisioned."/>
+ <Annotation Term="OData.LongDescription" String="Platform firmware is not provisioned."/>
+ </Member>
+ <Member Name="ProvisionedButNotLocked">
+ <Annotation Term="OData.Description" String="Platform firmware is provisioned but not locked."/>
+ <Annotation Term="OData.LongDescription" String="Platform firmware is provisioned but not locked. So re-provisioning is allowed in this state."/>
+ </Member>
+ <Member Name="ProvisionedAndLocked">
+ <Annotation Term="OData.Description" String="Platform firmware is provisioned and locked."/>
+ <Annotation Term="OData.LongDescription" String="Platform firmware is provisioned and locked. So re-provisioning is not allowed in this state."/>
+ </Member>
+ </EnumType>
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx>
diff --git a/redfish-core/schema/oem/openbmc/csdl/OemManager_v1.xml b/redfish-core/schema/oem/openbmc/csdl/OpenBMCManager_v1.xml
index eb2bf34a8c..b96a2918bc 100644
--- a/redfish-core/schema/oem/openbmc/csdl/OemManager_v1.xml
+++ b/redfish-core/schema/oem/openbmc/csdl/OpenBMCManager_v1.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml">
- <edmx:Include Namespace="Org.OData.Core.V1" Alias="OData" />
+ <edmx:Include Namespace="Org.OData.Core.V1" Alias="OData"/>
</edmx:Reference>
<edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RedfishExtensions_v1.xml">
<edmx:Include Namespace="Validation.v1_0_0" Alias="Validation"/>
@@ -18,291 +18,343 @@
<edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Chassis_v1.xml">
<edmx:Include Namespace="Chassis"/>
</edmx:Reference>
-
<edmx:DataServices>
- <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OemManager">
- <ComplexType Name="Oem" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="OemManager Oem properties." />
- <Annotation Term="OData.AutoExpand"/>
- <Property Name="OpenBmc" Type="OemManager.OpenBmc"/>
- </ComplexType>
-
- <ComplexType Name="OpenBmc" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="Oem properties for OpenBmc." />
- <Annotation Term="OData.AutoExpand"/>
- <Property Name="Fan" Type="OemManager.Fan"/>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCManager">
+ <Annotation Term="Redfish.OwningEntity" String="OpenBMC"/>
+ <Annotation Term="OData.Description" String="OpenBMC extensions to the standard manager."/>
+ <Annotation Term="OData.LongDescription" String="OpenBMC extensions to that standard manager."/>
+ <Annotation Term="Redfish.Uris">
+ <Collection>
+ <String>/redfish/v1/Managers#/OpenBMC</String>
+ </Collection>
+ </Annotation>
+ </Schema>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCManager.v1_0_0">
+ <Annotation Term="Redfish.OwningEntity" String="OpenBMC"/>
+ <ComplexType Name="Manager" BaseType="Resource.OemObject">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="OpenBMCManager Oem properties."/>
+ <Property Name="Fan" Type="OpenBMCManager.v1_0_0.Fan">
+ <Annotation Term="OData.Description" String="OpenBMC fan configuration."/>
+ <Annotation Term="OData.LongDescription" String="OpenBMC fan configuration."/>
+ </Property>
</ComplexType>
-
- <ComplexType Name="Fan" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="OpenBmc oem fan properties." />
+ <ComplexType Name="Fan">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="OpenBmc oem fan properties."/>
+ <Annotation Term="OData.LongDescription" String="OpenBMC oem fan properties."/>
<Annotation Term="OData.AutoExpand"/>
- <Property Name="FanControllers" Type="OemManager.FanControllers"/>
- <Property Name="PidControllers" Type="OemManager.PidControllers"/>
- <Property Name="StepwiseControllers" Type="OemManager.StepwiseControllers"/>
- <Property Name="FanZones" Type="OemManager.FanZones"/>
+ <Property Name="FanControllers" Type="OpenBMCManager.v1_0_0.FanControllers">
+ <Annotation Term="OData.Description" String="Current OpenBMC fan controllers."/>
+ <Annotation Term="OData.LongDescription" String="Current OpenBMC fan controllers."/>
+ </Property>
+ <Property Name="PidControllers" Type="OpenBMCManager.v1_0_0.PidControllers">
+ <Annotation Term="OData.Description" String="Current OpenBMC pid controllers."/>
+ <Annotation Term="OData.LongDescription" String="Current OpenBMC pid controllers."/>
+ </Property>
+ <Property Name="StepwiseControllers" Type="OpenBMCManager.v1_0_0.StepwiseControllers">
+ <Annotation Term="OData.Description" String="Current OpenBMC stepwise controllers."/>
+ <Annotation Term="OData.LongDescription" String="Current OpenBMC stepwise controllers."/>
+ </Property>
+ <Property Name="FanZones" Type="OpenBMCManager.v1_0_0.FanZones">
+ <Annotation Term="OData.Description" String="Current OpenBMC fan zones."/>
+ <Annotation Term="OData.LongDescription" String="Current OpenBMC fan zones."/>
+ </Property>
<Property Name="Profile" Type="Edm.String">
<Annotation Term="OData.Description" String="Current thermal profile."/>
<Annotation Term="OData.LongDescription" String="Current thermal profile."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
-
</ComplexType>
-
- <ComplexType Name="FanControllers" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="OpenBmc FanControllers." />
- <Annotation Term="OData.LongDescription" String="Container for OpenBmc fan controllers." />
+ <ComplexType Name="FanControllers">
+ <Annotation Term="OData.AdditionalProperties" Bool="true"/>
+ <Annotation Term="OData.Description" String="OpenBmc FanControllers."/>
+ <Annotation Term="OData.LongDescription" String="Container for OpenBmc fan controllers."/>
<Annotation Term="Redfish.DynamicPropertyPatterns">
<Collection>
- <NavigationProperty Type="OemManager.FanController">
- <Annotation Term="OData.AutoExpand"/>
- <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+" />
- <PropertyValue Property="Type" String="OemManager.FanController" />
- </NavigationProperty>
+ <Record>
+ <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+"/>
+ <PropertyValue Property="Type" String="OpenBMCManager.v1_0_0.FanController"/>
+ </Record>
</Collection>
</Annotation>
</ComplexType>
-
- <ComplexType Name="PidControllers" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="OpenBmc PidControllers." />
- <Annotation Term="OData.LongDescription" String="Container for OpenBmc pid controllers." />
+ <ComplexType Name="PidControllers">
+ <Annotation Term="OData.AdditionalProperties" Bool="true"/>
+ <Annotation Term="OData.Description" String="OpenBmc PidControllers."/>
+ <Annotation Term="OData.LongDescription" String="Container for OpenBmc pid controllers."/>
<Annotation Term="Redfish.DynamicPropertyPatterns">
<Collection>
- <NavigationProperty>
- <Annotation Term="OData.AutoExpand"/>
- <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+" />
- <PropertyValue Property="Type" String="OemManager.PidController" />
- </NavigationProperty>
+ <Record>
+ <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+"/>
+ <PropertyValue Property="Type" String="OpenBMCManager.v1_0_0.PidController"/>
+ </Record>
</Collection>
</Annotation>
</ComplexType>
-
- <ComplexType Name="StepwiseControllers" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="OpenBmc StepwiseControllers." />
- <Annotation Term="OData.LongDescription" String="Container for OpenBmc Stepwise controllers." />
+ <ComplexType Name="StepwiseControllers">
+ <Annotation Term="OData.AdditionalProperties" Bool="true"/>
+ <Annotation Term="OData.Description" String="OpenBmc StepwiseControllers."/>
+ <Annotation Term="OData.LongDescription" String="Container for OpenBmc Stepwise controllers."/>
<Annotation Term="Redfish.DynamicPropertyPatterns">
<Collection>
- <NavigationProperty>
- <Annotation Term="OData.AutoExpand"/>
- <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+" />
- <PropertyValue Property="Type" String="OemManager.StepwiseController" />
- </NavigationProperty>
+ <Record>
+ <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+"/>
+ <PropertyValue Property="Type" String="OpenBMCManager.v1_0_0.StepwiseController"/>
+ </Record>
</Collection>
</Annotation>
</ComplexType>
-
- <ComplexType Name="FanZones" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="true" />
- <Annotation Term="OData.Description" String="OpenBmc FanZones." />
- <Annotation Term="OData.LongDescription" String="Container for OpenBmc fan zones." />
+ <ComplexType Name="FanZones">
+ <Annotation Term="OData.AdditionalProperties" Bool="true"/>
+ <Annotation Term="OData.Description" String="OpenBmc FanZones."/>
+ <Annotation Term="OData.LongDescription" String="Container for OpenBmc fan zones."/>
<Annotation Term="Redfish.DynamicPropertyPatterns">
<Collection>
- <NavigationProperty>
- <Annotation Term="OData.AutoExpand"/>
- <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+" />
- <PropertyValue Property="Type" String="OemManager.FanZone" />
- </NavigationProperty>
+ <Record>
+ <PropertyValue Property="Pattern" String="[A-Za-z0-9_.:]+"/>
+ <PropertyValue Property="Type" String="OpenBMCManager.v1_0_0.FanZone"/>
+ </Record>
</Collection>
</Annotation>
</ComplexType>
-
- <ComplexType Name="FanController" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="false" />
- <Annotation Term="OData.Description" String="Configuration data for Fan Controllers." />
+ <ComplexType Name="FanController">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="Configuration data for Fan Controllers."/>
+ <Annotation Term="OData.LongDescription" String="Configuration data for Fan Controllers."/>
<Property Name="FFGainCoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Feed forward gain coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Feed forward gain coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Feed forward gain coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Feed forward gain coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="FFOffCoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Feed forward offset coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Feed forward offset coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Feed forward offset coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Feed forward offset coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="ICoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Integral Coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Integral Coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Integral Coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Integral Coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="ILimitMax" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Integral limit maximum for the PID." />
- <Annotation Term="OData.LongDescription" String="Integral limit maximum for the PID." />
+ <Annotation Term="OData.Description" String="Integral limit maximum for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Integral limit maximum for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="ILimitMin" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Integral limit minimum for the PID." />
- <Annotation Term="OData.LongDescription" String="Integral limit minimum for the PID." />
+ <Annotation Term="OData.Description" String="Integral limit minimum for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Integral limit minimum for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="Inputs" Type="Collection(Edm.String)">
<Annotation Term="OData.Description" String="Input sensors to the PID controller."/>
<Annotation Term="OData.LongDescription" String="Input sensors to the PID controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="OutLimitMax" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Output limit maximum for the pwm." />
- <Annotation Term="OData.LongDescription" String="Output limit maximum for the pwm." />
+ <Annotation Term="OData.Description" String="Output limit maximum for the pwm."/>
+ <Annotation Term="OData.LongDescription" String="Output limit maximum for the pwm."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="OutLimitMin" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Output limit minimum for the pwm." />
- <Annotation Term="OData.LongDescription" String="Output limit minimum for the pwm." />
+ <Annotation Term="OData.Description" String="Output limit minimum for the pwm."/>
+ <Annotation Term="OData.LongDescription" String="Output limit minimum for the pwm."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="NegativeHysteresis" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Negative hysteresis for the controller." />
- <Annotation Term="OData.LongDescription" String="Negative hysteresis for the controller." />
- </Property>
+ <Annotation Term="OData.Description" String="Negative hysteresis for the controller."/>
+ <Annotation Term="OData.LongDescription" String="Negative hysteresis for the controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ </Property>
<Property Name="PositiveHysteresis" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Positive hysteresis for the controller." />
- <Annotation Term="OData.LongDescription" String="Positive hysteresis for the controller." />
- </Property>
+ <Annotation Term="OData.Description" String="Positive hysteresis for the controller."/>
+ <Annotation Term="OData.LongDescription" String="Positive hysteresis for the controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ </Property>
<Property Name="Outputs" Type="Collection(Edm.String)">
<Annotation Term="OData.Description" String="Output sensors to the PID controller."/>
<Annotation Term="OData.LongDescription" String="Output sensors to the PID controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="PCoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Polynomial coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Polynomial coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Polynomial coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Polynomial coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="SlewNeg" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Negative slew rate for the PID." />
- <Annotation Term="OData.LongDescription" String="Negative slew rate for the PID." />
+ <Annotation Term="OData.Description" String="Negative slew rate for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Negative slew rate for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="SlewPos" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Positive slew rate for the PID." />
- <Annotation Term="OData.LongDescription" String="Positive slew rate for the PID." />
+ <Annotation Term="OData.Description" String="Positive slew rate for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Positive slew rate for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
- <NavigationProperty Name="Zones" Type="Collection(OemManager.FanZone)">
- <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
- <Annotation Term="OData.Description" String="Contains the Zones that this PID contributes to." />
+ <NavigationProperty Name="Zones" Type="Collection(OpenBMCManager.v1_0_0.FanZone)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="Contains the Zones that this PID contributes to."/>
+ <Annotation Term="OData.LongDescription" String="Contains the Zones that this PID contributes to."/>
<Annotation Term="OData.AutoExpandReferences"/>
</NavigationProperty>
</ComplexType>
-
- <ComplexType Name="FanZone" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="false" />
- <Annotation Term="OData.Description" String="Configuration data for Fan Controllers." />
+ <ComplexType Name="FanZone">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="Configuration data for Fan Controllers."/>
+ <Annotation Term="OData.LongDescription" String="Configuration data for Fan Controllers."/>
<Property Name="FailSafePercent" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="If the sensors are in fail-safe mode, this is the percentage to use." />
- <Annotation Term="OData.LongDescription" String="If the sensors are in fail-safe mode, this is the percentage to use." />
+ <Annotation Term="OData.Description" String="If the sensors are in fail-safe mode, this is the percentage to use."/>
+ <Annotation Term="OData.LongDescription" String="If the sensors are in fail-safe mode, this is the percentage to use."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="MinThermalOutput" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Minimum thermal RPM that can be set in this Zone." />
- <Annotation Term="OData.LongDescription" String="Minimum thermal RPM that can be set in this Zone." />
+ <Annotation Term="OData.Description" String="Minimum thermal RPM that can be set in this Zone."/>
+ <Annotation Term="OData.LongDescription" String="Minimum thermal RPM that can be set in this Zone."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<NavigationProperty Name="Chassis" Type="Chassis.Chassis">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="The Chassis that enables this Zone."/>
+ <Annotation Term="OData.LongDescription" String="The Chassis that enables this Zone."/>
<Annotation Term="OData.AutoExpandReferences"/>
</NavigationProperty>
</ComplexType>
-
- <ComplexType Name="PidController" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="false" />
- <Annotation Term="OData.Description" String="Configuration data for Fan Controllers." />
+ <ComplexType Name="PidController">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="Configuration data for Fan Controllers."/>
+ <Annotation Term="OData.LongDescription" String="Configuration data for Fan Controllers."/>
<Property Name="FFGainCoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Feed forward gain coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Feed forward gain coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Feed forward gain coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Feed forward gain coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="FFOffCoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Feed forward offset coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Feed forward offset coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Feed forward offset coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Feed forward offset coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="ICoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Integral Coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Integral Coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Integral Coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Integral Coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="ILimitMax" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Integral limit maximum for the PID." />
- <Annotation Term="OData.LongDescription" String="Integral limit maximum for the PID." />
+ <Annotation Term="OData.Description" String="Integral limit maximum for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Integral limit maximum for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="ILimitMin" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Integral limit minimum for the PID." />
- <Annotation Term="OData.LongDescription" String="Integral limit minimum for the PID." />
+ <Annotation Term="OData.Description" String="Integral limit minimum for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Integral limit minimum for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="Inputs" Type="Collection(Edm.String)">
<Annotation Term="OData.Description" String="Input sensors to the PID controller."/>
<Annotation Term="OData.LongDescription" String="Input sensors to the PID controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="OutLimitMax" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Output limit maximum for the pwm." />
- <Annotation Term="OData.LongDescription" String="Output limit maximum for the pwm." />
+ <Annotation Term="OData.Description" String="Output limit maximum for the pwm."/>
+ <Annotation Term="OData.LongDescription" String="Output limit maximum for the pwm."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="OutLimitMin" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Output limit minimum for the pwm." />
- <Annotation Term="OData.LongDescription" String="Output limit minimum for the pwm." />
+ <Annotation Term="OData.Description" String="Output limit minimum for the pwm."/>
+ <Annotation Term="OData.LongDescription" String="Output limit minimum for the pwm."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="NegativeHysteresis" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Negative hysteresis for the controller." />
- <Annotation Term="OData.LongDescription" String="Negative hysteresis for the controller." />
- </Property>
+ <Annotation Term="OData.Description" String="Negative hysteresis for the controller."/>
+ <Annotation Term="OData.LongDescription" String="Negative hysteresis for the controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ </Property>
<Property Name="PositiveHysteresis" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Positive hysteresis for the controller." />
- <Annotation Term="OData.LongDescription" String="Positive hysteresis for the controller." />
- </Property>
+ <Annotation Term="OData.Description" String="Positive hysteresis for the controller."/>
+ <Annotation Term="OData.LongDescription" String="Positive hysteresis for the controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
+ </Property>
<Property Name="PCoefficient" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Polynomial coefficient for the PID." />
- <Annotation Term="OData.LongDescription" String="Polynomial coefficient for the PID." />
+ <Annotation Term="OData.Description" String="Polynomial coefficient for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Polynomial coefficient for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
- <Property Name="SetPoint" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Setpoint for the PID." />
- <Annotation Term="OData.LongDescription" String="Setpoint for the PID." />
+ <Property Name="SetPoint" Type="Edm.Decimal" Nullable="false">
+ <Annotation Term="OData.Description" String="Setpoint for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Setpoint for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="SetPointOffset" Type="Edm.String" Nullable="false">
- <Annotation Term="OData.Description" String="Threshold to take value from and apply to setpoint." />
- <Annotation Term="OData.LongDescription" String="Threshold to take value from and apply to setpoint. Valid threshold names are supported." />
+ <Annotation Term="OData.Description" String="Threshold to take value from and apply to setpoint."/>
+ <Annotation Term="OData.LongDescription" String="Threshold to take value from and apply to setpoint. Valid threshold names are supported."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="SlewNeg" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Negative slew rate for the PID." />
- <Annotation Term="OData.LongDescription" String="Negative slew rate for the PID." />
+ <Annotation Term="OData.Description" String="Negative slew rate for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Negative slew rate for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="SlewPos" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Positive slew rate for the PID." />
- <Annotation Term="OData.LongDescription" String="Positive slew rate for the PID." />
+ <Annotation Term="OData.Description" String="Positive slew rate for the PID."/>
+ <Annotation Term="OData.LongDescription" String="Positive slew rate for the PID."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
- <NavigationProperty Name="Zones" Type="Collection(OemManager.FanZone)">
- <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
- <Annotation Term="OData.Description" String="Contains the Zones that this PID contributes to." />
+ <NavigationProperty Name="Zones" Type="Collection(OpenBMCManager.v1_0_0.FanZone)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="Contains the Zones that this PID contributes to."/>
+ <Annotation Term="OData.LongDescription" String="Contains the Zones that this PID contributes to."/>
<Annotation Term="OData.AutoExpandReferences"/>
</NavigationProperty>
</ComplexType>
-
- <ComplexType Name="StepwiseController" BaseType="Resource.OemObject">
- <Annotation Term="OData.AdditionalProperties" Bool="false" />
- <Annotation Term="OData.Description" String="Configuration data for Stepwise Controllers." />
+ <ComplexType Name="StepwiseController">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="Configuration data for Stepwise Controllers."/>
+ <Annotation Term="OData.LongDescription" String="Configuration data for Stepwise Controllers."/>
<Property Name="Inputs" Type="Collection(Edm.String)">
<Annotation Term="OData.Description" String="Input sensors to the Stepwise controller."/>
<Annotation Term="OData.LongDescription" String="Input sensors to the Stepwise controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="NegativeHysteresis" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Negative Hysteresis for the stepwise controller." />
- <Annotation Term="OData.LongDescription" String="Negative Hysteresis for the stepwise controller." />
+ <Annotation Term="OData.Description" String="Negative Hysteresis for the stepwise controller."/>
+ <Annotation Term="OData.LongDescription" String="Negative Hysteresis for the stepwise controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="PositiveHysteresis" Type="Edm.Decimal" Nullable="false">
- <Annotation Term="OData.Description" String="Positive Hysteresis for the stepwise controller." />
- <Annotation Term="OData.LongDescription" String="Positive Hysteresis for the stepwise controller." />
+ <Annotation Term="OData.Description" String="Positive Hysteresis for the stepwise controller."/>
+ <Annotation Term="OData.LongDescription" String="Positive Hysteresis for the stepwise controller."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
- <Property Name="Steps" Type="Collection(OemManager.StepwiseSteps)">
- <Annotation Term="OData.Description" String="Temperature vs RPM steps for the stepwise controller." />
- <Annotation Term="OData.LongDescription" String="Temperature vs RPM steps for the stepwise controller." />
+ <Property Name="Steps" Type="Collection(OpenBMCManager.v1_0_0.StepwiseSteps)">
+ <Annotation Term="OData.Description" String="Temperature vs RPM steps for the stepwise controller."/>
+ <Annotation Term="OData.LongDescription" String="Temperature vs RPM steps for the stepwise controller."/>
<Annotation Term="OData.AutoExpand"/>
</Property>
<Property Name="Direction" Type="Edm.String">
<Annotation Term="OData.Description" String="Direction that the stepwise controller applies."/>
<Annotation Term="OData.LongDescription" String="Direction that the stepwise controller applies. Options include Ceiling and Floor."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
- <NavigationProperty Name="Zones" Type="Collection(OemManager.FanZone)">
- <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
- <Annotation Term="OData.Description" String="Contains the Zones that this controller contributes to." />
+ <NavigationProperty Name="Zones" Type="Collection(OpenBMCManager.v1_0_0.FanZone)">
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
+ <Annotation Term="OData.Description" String="Contains the Zones that this controller contributes to."/>
+ <Annotation Term="OData.LongDescription" String="Contains the Zones that this controller contributes to."/>
<Annotation Term="OData.AutoExpandReferences"/>
</NavigationProperty>
</ComplexType>
-
- <ComplexType Name="StepwiseSteps" BaseType="Resource.OemObject">
+ <ComplexType Name="StepwiseSteps">
+ <Annotation Term="OData.AdditionalProperties" Bool="false"/>
+ <Annotation Term="OData.Description" String="Single stepwise step pair."/>
+ <Annotation Term="OData.LongDescription" String="Single stepwise step pair."/>
<Property Name="Target" Type="Edm.Decimal" Nullable="false">
<Annotation Term="OData.Description" String="Input sensor reading for step."/>
<Annotation Term="OData.LongDescription" String="Input sensor reading for step."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
<Property Name="Output" Type="Edm.Decimal" Nullable="false">
<Annotation Term="OData.Description" String="Fan speed setting for step."/>
<Annotation Term="OData.LongDescription" String="Fan speed setting for step."/>
+ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/ReadWrite"/>
</Property>
</ComplexType>
</Schema>
diff --git a/redfish-core/schema/oem/openbmc/csdl/OemVirtualMedia_v1.xml b/redfish-core/schema/oem/openbmc/csdl/OpenBMCVirtualMedia_v1.xml
index 8bc62241a1..d7f778ef17 100644
--- a/redfish-core/schema/oem/openbmc/csdl/OemVirtualMedia_v1.xml
+++ b/redfish-core/schema/oem/openbmc/csdl/OpenBMCVirtualMedia_v1.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
-
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml">
<edmx:Include Namespace="Org.OData.Core.V1" Alias="OData"/>
</edmx:Reference>
@@ -14,23 +13,18 @@
<edmx:Include Namespace="Resource"/>
<edmx:Include Namespace="Resource.v1_0_0"/>
</edmx:Reference>
-
<edmx:DataServices>
-
- <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OemVirtualMedia">
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCVirtualMedia">
<Annotation Term="Redfish.OwningEntity" String="OpenBMC"/>
</Schema>
-
- <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OemVirtualMedia.v1_0_0">
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="OpenBMCVirtualMedia.v1_0_0">
<Annotation Term="Redfish.OwningEntity" String="OpenBMC"/>
<Annotation Term="Redfish.Release" String="1.0"/>
-
<Property Name="WebSocketEndpoint" Type="Edm.String">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/>
<Annotation Term="OData.Description" String="Indicates endpoint socket name and location."/>
<Annotation Term="OData.LongDescription" String="The value of this property shall be a structure ring indicating location and name of the socket used to communicate with nbd server."/>
</Property>
-
<EntityType Name="VirtualMedia" BaseType="Resource.OemObject" Abstract="true">
<Annotation Term="OData.Description" String="OEM Extension for VirtualMedia"/>
<Annotation Term="OData.LongDescription" String="OEM Extension for VirtualMedia to support Proxy mode."/>
@@ -41,6 +35,5 @@
</Property>
</EntityType>
</Schema>
-
</edmx:DataServices>
</edmx:Edmx>
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.json
new file mode 100644
index 0000000000..d3530f2337
--- /dev/null
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.json
@@ -0,0 +1,8 @@
+{
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.json",
+ "$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
+ "copyright": "Copyright 2024 OpenBMC.",
+ "definitions": {},
+ "owningEntity": "OpenBMC",
+ "title": "#OpenBMCAccountService"
+}
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OemAccountService.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.v1_0_0.json
index 7b25a42bf9..68a27795c1 100644
--- a/redfish-core/schema/oem/openbmc/json-schema/OemAccountService.json
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.v1_0_0.json
@@ -1,12 +1,12 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/OemAccountService.v1_0_0.json",
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCAccountService.v1_0_0.json",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
- "copyright": "Copyright 2014-2019 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
+ "copyright": "Copyright 2024 OpenBMC.",
"definitions": {
"AccountService": {
"additionalProperties": false,
- "description": "OEM Extension for AccountService",
- "longDescription": "OEM Extension for AccountService providing info about TLS Auth.",
+ "description": "OpenBMC OEM Extension for AccountService.",
+ "longDescription": "OpenBMC OEM Extension for AccountService providing info about authentication methods.",
"patternProperties": {
"^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
@@ -91,6 +91,5 @@
}
},
"owningEntity": "OpenBMC",
- "release": "1.0",
- "title": "#OemAccountService.v1_0_0"
+ "title": "#OpenBMCAccountService.v1_0_0"
}
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.json
new file mode 100644
index 0000000000..fe0491ad19
--- /dev/null
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.json
@@ -0,0 +1,8 @@
+{
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.json",
+ "$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
+ "copyright": "Copyright 2024 OpenBMC.",
+ "definitions": {},
+ "owningEntity": "OpenBMC",
+ "title": "#OpenBMCComputerSystem"
+}
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OemComputerSystem.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.v1_0_0.json
index 1423af5e89..9c005aa9f5 100644
--- a/redfish-core/schema/oem/openbmc/json-schema/OemComputerSystem.json
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.v1_0_0.json
@@ -1,7 +1,7 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/OemComputerSystem.json",
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.v1_0_0.json",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
- "copyright": "Copyright 2014-2019 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
+ "copyright": "Copyright 2024 OpenBMC.",
"definitions": {
"FirmwareProvisioning": {
"additionalProperties": false,
@@ -24,7 +24,7 @@
"ProvisioningStatus": {
"anyOf": [
{
- "$ref": "#/definitions/FirmwareProvisioningStatus"
+ "$ref": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.json#/definitions/FirmwareProvisioningStatus"
},
{
"type": "null"
@@ -57,7 +57,7 @@
},
"Oem": {
"additionalProperties": true,
- "description": "OemComputerSystem Oem properties.",
+ "description": "OpenBMCComputerSystem Oem properties.",
"patternProperties": {
"^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
@@ -76,7 +76,7 @@
"OpenBmc": {
"anyOf": [
{
- "$ref": "#/definitions/OpenBmc"
+ "$ref": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCComputerSystem.json#/definitions/OpenBmc"
},
{
"type": "null"
@@ -107,5 +107,6 @@
"type": "object"
}
},
- "title": "#OemComputerSystem"
+ "owningEntity": "OpenBMC",
+ "title": "#OpenBMCComputerSystem.v1_0_0"
}
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.json
new file mode 100644
index 0000000000..85140e6e7a
--- /dev/null
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.json
@@ -0,0 +1,8 @@
+{
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.json",
+ "$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
+ "copyright": "Copyright 2024 OpenBMC.",
+ "definitions": {},
+ "owningEntity": "OpenBMC",
+ "title": "#OpenBMCManager"
+}
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OemManager.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.v1_0_0.json
index 6771a3cbe2..7f11a98e75 100644
--- a/redfish-core/schema/oem/openbmc/json-schema/OemManager.json
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.v1_0_0.json
@@ -1,16 +1,19 @@
{
- "$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema.v1_4_0.json",
- "copyright": "Copyright 2014-2018 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCManager.v1_0_0.json",
+ "$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
+ "copyright": "Copyright 2024 OpenBMC.",
"definitions": {
"Fan": {
- "additionalProperties": true,
+ "additionalProperties": false,
"description": "OpenBmc oem fan properties.",
+ "longDescription": "OpenBMC oem fan properties.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -27,7 +30,9 @@
{
"type": "null"
}
- ]
+ ],
+ "description": "Current OpenBMC fan controllers.",
+ "longDescription": "Current OpenBMC fan controllers."
},
"FanZones": {
"anyOf": [
@@ -37,7 +42,9 @@
{
"type": "null"
}
- ]
+ ],
+ "description": "Current OpenBMC fan zones.",
+ "longDescription": "Current OpenBMC fan zones."
},
"PidControllers": {
"anyOf": [
@@ -47,11 +54,14 @@
{
"type": "null"
}
- ]
+ ],
+ "description": "Current OpenBMC pid controllers.",
+ "longDescription": "Current OpenBMC pid controllers."
},
"Profile": {
"description": "Current thermal profile.",
"longDescription": "Current thermal profile.",
+ "readonly": false,
"type": ["string", "null"]
},
"StepwiseControllers": {
@@ -62,7 +72,9 @@
{
"type": "null"
}
- ]
+ ],
+ "description": "Current OpenBMC stepwise controllers.",
+ "longDescription": "Current OpenBMC stepwise controllers."
}
},
"type": "object"
@@ -70,12 +82,14 @@
"FanController": {
"additionalProperties": false,
"description": "Configuration data for Fan Controllers.",
+ "longDescription": "Configuration data for Fan Controllers.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -87,26 +101,31 @@
"FFGainCoefficient": {
"description": "Feed forward gain coefficient for the PID.",
"longDescription": "Feed forward gain coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"FFOffCoefficient": {
"description": "Feed forward offset coefficient for the PID.",
"longDescription": "Feed forward offset coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"ICoefficient": {
"description": "Integral Coefficient for the PID.",
"longDescription": "Integral Coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"ILimitMax": {
"description": "Integral limit maximum for the PID.",
"longDescription": "Integral limit maximum for the PID.",
+ "readonly": false,
"type": "number"
},
"ILimitMin": {
"description": "Integral limit minimum for the PID.",
"longDescription": "Integral limit minimum for the PID.",
+ "readonly": false,
"type": "number"
},
"Inputs": {
@@ -115,21 +134,25 @@
"type": ["string", "null"]
},
"longDescription": "Input sensors to the PID controller.",
+ "readonly": false,
"type": "array"
},
"NegativeHysteresis": {
"description": "Negative hysteresis for the controller.",
"longDescription": "Negative hysteresis for the controller.",
+ "readonly": false,
"type": "number"
},
"OutLimitMax": {
"description": "Output limit maximum for the pwm.",
"longDescription": "Output limit maximum for the pwm.",
+ "readonly": false,
"type": "number"
},
"OutLimitMin": {
"description": "Output limit minimum for the pwm.",
"longDescription": "Output limit minimum for the pwm.",
+ "readonly": false,
"type": "number"
},
"Outputs": {
@@ -138,26 +161,31 @@
"type": ["string", "null"]
},
"longDescription": "Output sensors to the PID controller.",
+ "readonly": false,
"type": "array"
},
"PCoefficient": {
"description": "Polynomial coefficient for the PID.",
"longDescription": "Polynomial coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"PositiveHysteresis": {
"description": "Positive hysteresis for the controller.",
"longDescription": "Positive hysteresis for the controller.",
+ "readonly": false,
"type": "number"
},
"SlewNeg": {
"description": "Negative slew rate for the PID.",
"longDescription": "Negative slew rate for the PID.",
+ "readonly": false,
"type": "number"
},
"SlewPos": {
"description": "Positive slew rate for the PID.",
"longDescription": "Positive slew rate for the PID.",
+ "readonly": false,
"type": "number"
},
"Zones": {
@@ -165,11 +193,12 @@
"items": {
"$ref": "#/definitions/FanZone"
},
+ "longDescription": "Contains the Zones that this PID contributes to.",
"readonly": true,
"type": "array"
},
"Zones@odata.count": {
- "$ref": "http://redfish.dmtf.org/schemas/v1/odata.v4_0_2.json#/definitions/count"
+ "$ref": "http://redfish.dmtf.org/schemas/v1/odata-v4.json#/definitions/count"
}
},
"type": "object"
@@ -179,11 +208,15 @@
"description": "OpenBmc FanControllers.",
"longDescription": "Container for OpenBmc fan controllers.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "[A-Za-z0-9_.:]+": {
+ "$ref": "#/definitions/FanController"
+ },
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -197,12 +230,14 @@
"FanZone": {
"additionalProperties": false,
"description": "Configuration data for Fan Controllers.",
+ "longDescription": "Configuration data for Fan Controllers.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -221,16 +256,19 @@
}
],
"description": "The Chassis that enables this Zone.",
+ "longDescription": "The Chassis that enables this Zone.",
"readonly": true
},
"FailSafePercent": {
"description": "If the sensors are in fail-safe mode, this is the percentage to use.",
"longDescription": "If the sensors are in fail-safe mode, this is the percentage to use.",
+ "readonly": false,
"type": "number"
},
"MinThermalOutput": {
"description": "Minimum thermal RPM that can be set in this Zone.",
"longDescription": "Minimum thermal RPM that can be set in this Zone.",
+ "readonly": false,
"type": "number"
}
},
@@ -241,11 +279,15 @@
"description": "OpenBmc FanZones.",
"longDescription": "Container for OpenBmc fan zones.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "[A-Za-z0-9_.:]+": {
+ "$ref": "#/definitions/FanZone"
+ },
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -256,45 +298,16 @@
"properties": {},
"type": "object"
},
- "Oem": {
- "additionalProperties": true,
- "description": "OemManager Oem properties.",
- "patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
- "description": "This property shall specify a valid odata or Redfish property.",
- "type": [
- "array",
- "boolean",
- "number",
- "null",
- "object",
- "string"
- ]
- }
- },
- "properties": {
- "OpenBmc": {
- "anyOf": [
- {
- "$ref": "#/definitions/OpenBmc"
- },
- {
- "type": "null"
- }
- ]
- }
- },
- "type": "object"
- },
- "OpenBmc": {
- "additionalProperties": true,
- "description": "Oem properties for OpenBmc.",
+ "Manager": {
+ "additionalProperties": false,
+ "description": "OpenBMCManager Oem properties.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -311,7 +324,9 @@
{
"type": "null"
}
- ]
+ ],
+ "description": "OpenBMC fan configuration.",
+ "longDescription": "OpenBMC fan configuration."
}
},
"type": "object"
@@ -319,12 +334,14 @@
"PidController": {
"additionalProperties": false,
"description": "Configuration data for Fan Controllers.",
+ "longDescription": "Configuration data for Fan Controllers.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -336,26 +353,31 @@
"FFGainCoefficient": {
"description": "Feed forward gain coefficient for the PID.",
"longDescription": "Feed forward gain coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"FFOffCoefficient": {
"description": "Feed forward offset coefficient for the PID.",
"longDescription": "Feed forward offset coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"ICoefficient": {
"description": "Integral Coefficient for the PID.",
"longDescription": "Integral Coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"ILimitMax": {
"description": "Integral limit maximum for the PID.",
"longDescription": "Integral limit maximum for the PID.",
+ "readonly": false,
"type": "number"
},
"ILimitMin": {
"description": "Integral limit minimum for the PID.",
"longDescription": "Integral limit minimum for the PID.",
+ "readonly": false,
"type": "number"
},
"Inputs": {
@@ -364,51 +386,61 @@
"type": ["string", "null"]
},
"longDescription": "Input sensors to the PID controller.",
+ "readonly": false,
"type": "array"
},
"NegativeHysteresis": {
"description": "Negative hysteresis for the controller.",
"longDescription": "Negative hysteresis for the controller.",
+ "readonly": false,
"type": "number"
},
"OutLimitMax": {
"description": "Output limit maximum for the pwm.",
"longDescription": "Output limit maximum for the pwm.",
+ "readonly": false,
"type": "number"
},
"OutLimitMin": {
"description": "Output limit minimum for the pwm.",
"longDescription": "Output limit minimum for the pwm.",
+ "readonly": false,
"type": "number"
},
"PCoefficient": {
"description": "Polynomial coefficient for the PID.",
"longDescription": "Polynomial coefficient for the PID.",
+ "readonly": false,
"type": "number"
},
"PositiveHysteresis": {
"description": "Positive hysteresis for the controller.",
"longDescription": "Positive hysteresis for the controller.",
+ "readonly": false,
"type": "number"
},
"SetPoint": {
"description": "Setpoint for the PID.",
"longDescription": "Setpoint for the PID.",
+ "readonly": false,
"type": "number"
},
"SetPointOffset": {
"description": "Threshold to take value from and apply to setpoint.",
"longDescription": "Threshold to take value from and apply to setpoint. Valid threshold names are supported.",
+ "readonly": false,
"type": "string"
},
"SlewNeg": {
"description": "Negative slew rate for the PID.",
"longDescription": "Negative slew rate for the PID.",
+ "readonly": false,
"type": "number"
},
"SlewPos": {
"description": "Positive slew rate for the PID.",
"longDescription": "Positive slew rate for the PID.",
+ "readonly": false,
"type": "number"
},
"Zones": {
@@ -416,11 +448,12 @@
"items": {
"$ref": "#/definitions/FanZone"
},
+ "longDescription": "Contains the Zones that this PID contributes to.",
"readonly": true,
"type": "array"
},
"Zones@odata.count": {
- "$ref": "http://redfish.dmtf.org/schemas/v1/odata.v4_0_2.json#/definitions/count"
+ "$ref": "http://redfish.dmtf.org/schemas/v1/odata-v4.json#/definitions/count"
}
},
"type": "object"
@@ -430,11 +463,15 @@
"description": "OpenBmc PidControllers.",
"longDescription": "Container for OpenBmc pid controllers.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "[A-Za-z0-9_.:]+": {
+ "$ref": "#/definitions/PidController"
+ },
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -448,12 +485,14 @@
"StepwiseController": {
"additionalProperties": false,
"description": "Configuration data for Stepwise Controllers.",
+ "longDescription": "Configuration data for Stepwise Controllers.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -465,6 +504,7 @@
"Direction": {
"description": "Direction that the stepwise controller applies.",
"longDescription": "Direction that the stepwise controller applies. Options include Ceiling and Floor.",
+ "readonly": false,
"type": ["string", "null"]
},
"Inputs": {
@@ -473,19 +513,23 @@
"type": ["string", "null"]
},
"longDescription": "Input sensors to the Stepwise controller.",
+ "readonly": false,
"type": "array"
},
"NegativeHysteresis": {
"description": "Negative Hysteresis for the stepwise controller.",
"longDescription": "Negative Hysteresis for the stepwise controller.",
+ "readonly": false,
"type": "number"
},
"PositiveHysteresis": {
"description": "Positive Hysteresis for the stepwise controller.",
"longDescription": "Positive Hysteresis for the stepwise controller.",
+ "readonly": false,
"type": "number"
},
"Steps": {
+ "autoExpand": true,
"description": "Temperature vs RPM steps for the stepwise controller.",
"items": {
"anyOf": [
@@ -505,11 +549,12 @@
"items": {
"$ref": "#/definitions/FanZone"
},
+ "longDescription": "Contains the Zones that this controller contributes to.",
"readonly": true,
"type": "array"
},
"Zones@odata.count": {
- "$ref": "http://redfish.dmtf.org/schemas/v1/odata.v4_0_2.json#/definitions/count"
+ "$ref": "http://redfish.dmtf.org/schemas/v1/odata-v4.json#/definitions/count"
}
},
"type": "object"
@@ -519,11 +564,15 @@
"description": "OpenBmc StepwiseControllers.",
"longDescription": "Container for OpenBmc Stepwise controllers.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "[A-Za-z0-9_.:]+": {
+ "$ref": "#/definitions/StepwiseController"
+ },
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -536,12 +585,15 @@
},
"StepwiseSteps": {
"additionalProperties": false,
+ "description": "Single stepwise step pair.",
+ "longDescription": "Single stepwise step pair.",
"patternProperties": {
- "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
+ "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message)\\.[a-zA-Z_][a-zA-Z0-9_]*$": {
"description": "This property shall specify a valid odata or Redfish property.",
"type": [
"array",
"boolean",
+ "integer",
"number",
"null",
"object",
@@ -553,16 +605,19 @@
"Output": {
"description": "Fan speed setting for step.",
"longDescription": "Fan speed setting for step.",
+ "readonly": false,
"type": "number"
},
"Target": {
"description": "Input sensor reading for step.",
"longDescription": "Input sensor reading for step.",
+ "readonly": false,
"type": "number"
}
},
"type": "object"
}
},
- "title": "#OemManager"
+ "owningEntity": "OpenBMC",
+ "title": "#OpenBMCManager.v1_0_0"
}
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.json
new file mode 100644
index 0000000000..60a881677b
--- /dev/null
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.json
@@ -0,0 +1,8 @@
+{
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.json",
+ "$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
+ "copyright": "Copyright 2024 OpenBMC.",
+ "definitions": {},
+ "owningEntity": "OpenBMC",
+ "title": "#OpenBMCVirtualMedia"
+}
diff --git a/redfish-core/schema/oem/openbmc/json-schema/OemVirtualMedia.json b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.v1_0_0.json
index 9f30ad0f74..4710e61dae 100644
--- a/redfish-core/schema/oem/openbmc/json-schema/OemVirtualMedia.json
+++ b/redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.v1_0_0.json
@@ -1,7 +1,7 @@
{
- "$id": "http://redfish.dmtf.org/schemas/v1/OemVirtualMedia.v1_0_0.json",
+ "$id": "https://github.com/openbmc/bmcweb/tree/master/redfish-core/schema/oem/openbmc/json-schema/OpenBMCVirtualMedia.v1_0_0.json",
"$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema-v1.json",
- "copyright": "Copyright 2014-2019 DMTF. For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright",
+ "copyright": "Copyright 2024 OpenBMC.",
"definitions": {
"VirtualMedia": {
"additionalProperties": false,
@@ -34,5 +34,5 @@
},
"owningEntity": "OpenBMC",
"release": "1.0",
- "title": "#OemVirtualMedia.v1_0_0"
+ "title": "#OpenBMCVirtualMedia.v1_0_0"
}
diff --git a/redfish-core/schema/oem/openbmc/meson.build b/redfish-core/schema/oem/openbmc/meson.build
new file mode 100644
index 0000000000..95702ce792
--- /dev/null
+++ b/redfish-core/schema/oem/openbmc/meson.build
@@ -0,0 +1,23 @@
+# Mapping from option key name to schemas that should be installed if that option is enabled
+schemas = {
+ 'insecure-disable-auth': 'OpenBMCAccountService',
+ 'redfish-oem-manager-fan-data': 'OpenBMCManager',
+ 'redfish-provisioning-feature': 'OpenBMCComputerSystem',
+ #'vm-nbdproxy': 'OpenBMCVirtualMedia',
+}
+
+foreach option_key, schema : schemas
+ if get_option(option_key).allowed()
+ install_data(
+ 'csdl/@0@_v1.xml'.format(schema),
+ install_dir: 'share/www/redfish/v1/schema',
+ follow_symlinks: true,
+ )
+
+ install_data(
+ 'json-schema/@0@.v1_0_0.json'.format(schema),
+ install_dir: 'share/www/redfish/v1/JsonSchemas',
+ follow_symlinks: true,
+ )
+ endif
+endforeach
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 205da9668c..0253f10e55 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#include "error_messages.hpp"
@@ -34,8 +34,6 @@
#include <string_view>
#include <utility>
-// IWYU pragma: no_include <stddef.h>
-
namespace redfish
{
@@ -226,21 +224,19 @@ void resourceMissingAtURI(crow::Response& res,
* See header file for more information
* @endinternal
*/
-nlohmann::json actionParameterValueFormatError(const nlohmann::json& arg1,
- std::string_view arg2,
- std::string_view arg3)
+nlohmann::json actionParameterValueFormatError(
+ const nlohmann::json& arg1, std::string_view arg2, std::string_view arg3)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(
redfish::registries::base::Index::actionParameterValueFormatError,
std::to_array<std::string_view>({arg1Str, arg2, arg3}));
}
-void actionParameterValueFormatError(crow::Response& res,
- const nlohmann::json& arg1,
- std::string_view arg2,
- std::string_view arg3)
+void actionParameterValueFormatError(
+ crow::Response& res, const nlohmann::json& arg1, std::string_view arg2,
+ std::string_view arg3)
{
res.result(boost::beast::http::status::bad_request);
addMessageToErrorJson(res.jsonValue,
@@ -254,9 +250,8 @@ void actionParameterValueFormatError(crow::Response& res,
* See header file for more information
* @endinternal
*/
-nlohmann::json actionParameterValueNotInList(std::string_view arg1,
- std::string_view arg2,
- std::string_view arg3)
+nlohmann::json actionParameterValueNotInList(
+ std::string_view arg1, std::string_view arg2, std::string_view arg3)
{
return getLog(
redfish::registries::base::Index::actionParameterValueNotInList,
@@ -420,9 +415,8 @@ void serviceTemporarilyUnavailable(crow::Response& res, std::string_view arg1)
* See header file for more information
* @endinternal
*/
-nlohmann::json resourceAlreadyExists(std::string_view arg1,
- std::string_view arg2,
- std::string_view arg3)
+nlohmann::json resourceAlreadyExists(
+ std::string_view arg1, std::string_view arg2, std::string_view arg3)
{
return getLog(redfish::registries::base::Index::resourceAlreadyExists,
std::to_array({arg1, arg2, arg3}));
@@ -488,8 +482,8 @@ void createFailedMissingReqProperties(crow::Response& res,
nlohmann::json propertyValueFormatError(const nlohmann::json& arg1,
std::string_view arg2)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(redfish::registries::base::Index::propertyValueFormatError,
std::to_array<std::string_view>({arg1Str, arg2}));
}
@@ -513,8 +507,8 @@ void propertyValueFormatError(crow::Response& res, const nlohmann::json& arg1,
nlohmann::json propertyValueNotInList(const nlohmann::json& arg1,
std::string_view arg2)
{
- std::string arg1Str = arg1.dump(-1, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(redfish::registries::base::Index::propertyValueNotInList,
std::to_array<std::string_view>({arg1Str, arg2}));
}
@@ -536,8 +530,8 @@ void propertyValueNotInList(crow::Response& res, const nlohmann::json& arg1,
nlohmann::json propertyValueOutOfRange(const nlohmann::json& arg1,
std::string_view arg2)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(redfish::registries::base::Index::propertyValueOutOfRange,
std::to_array<std::string_view>({arg1Str, arg2}));
}
@@ -813,13 +807,12 @@ void propertyValueConflict(crow::Response& res, std::string_view arg1,
* See header file for more information
* @endinternal
*/
-nlohmann::json
- propertyValueResourceConflict(std::string_view arg1,
- const nlohmann::json& arg2,
- const boost::urls::url_view_base& arg3)
+nlohmann::json propertyValueResourceConflict(
+ std::string_view arg1, const nlohmann::json& arg2,
+ const boost::urls::url_view_base& arg3)
{
- std::string arg2Str = arg2.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg2Str =
+ arg2.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(
redfish::registries::base::Index::propertyValueResourceConflict,
@@ -845,8 +838,8 @@ void propertyValueResourceConflict(crow::Response& res, std::string_view arg1,
nlohmann::json propertyValueExternalConflict(std::string_view arg1,
const nlohmann::json& arg2)
{
- std::string arg2Str = arg2.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg2Str =
+ arg2.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(
redfish::registries::base::Index::propertyValueExternalConflict,
@@ -871,8 +864,8 @@ void propertyValueExternalConflict(crow::Response& res, std::string_view arg1,
nlohmann::json propertyValueIncorrect(std::string_view arg1,
const nlohmann::json& arg2)
{
- std::string arg2Str = arg2.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg2Str =
+ arg2.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(redfish::registries::base::Index::propertyValueIncorrect,
std::to_array<std::string_view>({arg1, arg2Str}));
}
@@ -1005,8 +998,8 @@ void operationTimeout(crow::Response& res)
nlohmann::json propertyValueTypeError(const nlohmann::json& arg1,
std::string_view arg2)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(redfish::registries::base::Index::propertyValueTypeError,
std::to_array<std::string_view>({arg1Str, arg2}));
}
@@ -1020,6 +1013,26 @@ void propertyValueTypeError(crow::Response& res, const nlohmann::json& arg1,
/**
* @internal
+ * @brief Formats PropertyValueError message into JSON for the specified
+ * property
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyValueError(std::string_view arg1)
+{
+ return getLog(redfish::registries::base::Index::propertyValueError,
+ std::to_array<std::string_view>({arg1}));
+}
+
+void propertyValueError(crow::Response& res, std::string_view arg1)
+{
+ res.result(boost::beast::http::status::bad_request);
+ addMessageToJson(res.jsonValue, propertyValueError(arg1), arg1);
+}
+
+/**
+ * @internal
* @brief Formats ResourceNotFound message into JSONd
*
* See header file for more information
@@ -1089,16 +1102,15 @@ void propertyNotWritable(crow::Response& res, std::string_view arg1)
nlohmann::json queryParameterValueTypeError(const nlohmann::json& arg1,
std::string_view arg2)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(
redfish::registries::base::Index::queryParameterValueTypeError,
std::to_array<std::string_view>({arg1Str, arg2}));
}
-void queryParameterValueTypeError(crow::Response& res,
- const nlohmann::json& arg1,
- std::string_view arg2)
+void queryParameterValueTypeError(
+ crow::Response& res, const nlohmann::json& arg1, std::string_view arg2)
{
res.result(boost::beast::http::status::bad_request);
addMessageToErrorJson(res.jsonValue,
@@ -1173,9 +1185,8 @@ void actionParameterNotSupported(crow::Response& res, std::string_view arg1,
* See header file for more information
* @endinternal
*/
-nlohmann::json
- sourceDoesNotSupportProtocol(const boost::urls::url_view_base& arg1,
- std::string_view arg2)
+nlohmann::json sourceDoesNotSupportProtocol(
+ const boost::urls::url_view_base& arg1, std::string_view arg2)
{
return getLog(
redfish::registries::base::Index::sourceDoesNotSupportProtocol,
@@ -1439,12 +1450,11 @@ void resourceInStandby(crow::Response& res)
* See header file for more information
* @endinternal
*/
-nlohmann::json actionParameterValueTypeError(const nlohmann::json& arg1,
- std::string_view arg2,
- std::string_view arg3)
+nlohmann::json actionParameterValueTypeError(
+ const nlohmann::json& arg1, std::string_view arg2, std::string_view arg3)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(
redfish::registries::base::Index::actionParameterValueTypeError,
std::to_array<std::string_view>({arg1Str, arg2, arg3}));
@@ -1469,8 +1479,8 @@ void actionParameterValueTypeError(crow::Response& res,
nlohmann::json actionParameterValueError(const nlohmann::json& arg1,
std::string_view arg2)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(redfish::registries::base::Index::actionParameterValueError,
std::to_array<std::string_view>({arg1Str, arg2}));
}
@@ -1660,8 +1670,8 @@ void insufficientPrivilege(crow::Response& res)
nlohmann::json propertyValueModified(std::string_view arg1,
const nlohmann::json& arg2)
{
- std::string arg2Str = arg2.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg2Str =
+ arg2.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(redfish::registries::base::Index::propertyValueModified,
std::to_array<std::string_view>({arg1, arg2Str}));
}
@@ -1701,16 +1711,15 @@ void accountNotModified(crow::Response& res)
nlohmann::json queryParameterValueFormatError(const nlohmann::json& arg1,
std::string_view arg2)
{
- std::string arg1Str = arg1.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
+ std::string arg1Str =
+ arg1.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
return getLog(
redfish::registries::base::Index::queryParameterValueFormatError,
std::to_array<std::string_view>({arg1Str, arg2}));
}
-void queryParameterValueFormatError(crow::Response& res,
- const nlohmann::json& arg1,
- std::string_view arg2)
+void queryParameterValueFormatError(
+ crow::Response& res, const nlohmann::json& arg1, std::string_view arg2)
{
res.result(boost::beast::http::status::bad_request);
addMessageToErrorJson(res.jsonValue,
@@ -1781,9 +1790,8 @@ void accountModified(crow::Response& res)
* See header file for more information
* @endinternal
*/
-nlohmann::json queryParameterOutOfRange(std::string_view arg1,
- std::string_view arg2,
- std::string_view arg3)
+nlohmann::json queryParameterOutOfRange(
+ std::string_view arg1, std::string_view arg2, std::string_view arg3)
{
return getLog(redfish::registries::base::Index::queryParameterOutOfRange,
std::to_array({arg1, arg2, arg3}));
diff --git a/redfish-core/src/filter_expr_executor.cpp b/redfish-core/src/filter_expr_executor.cpp
index 70046f0e2b..441b4bb9a4 100644
--- a/redfish-core/src/filter_expr_executor.cpp
+++ b/redfish-core/src/filter_expr_executor.cpp
@@ -5,6 +5,17 @@
#include "logging.hpp"
#include "utils/time_utils.hpp"
+#include <algorithm>
+#include <array>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <variant>
+
namespace redfish
{
@@ -19,46 +30,46 @@ struct DateTimeString
// The following is created by dumping all key names of type
// Edm.DateTimeOffset. While imperfect that it's a hardcoded list, these
// keys don't change that often
- static constexpr auto timeKeys =
- std::to_array<std::string_view>({"AccountExpiration",
- "CalibrationTime",
- "CoefficientUpdateTime",
- "Created",
- "CreatedDate",
- "CreatedTime",
- "CreateTime",
- "DateTime",
- "EndDateTime",
- "EndTime",
- "EventTimestamp",
- "ExpirationDate",
- "FirstOverflowTimestamp",
- "InitialStartTime",
- "InstallDate",
- "LastOverflowTimestamp",
- "LastResetTime",
- "LastStateTime",
- "LastUpdated",
- "LifetimeStartDateTime",
- "LowestReadingTime",
- "MaintenanceWindowStartTime",
- "Modified",
- "PasswordExpiration",
- "PeakReadingTime",
- "PresentedPublicHostKeyTimestamp",
- "ProductionDate",
- "ReadingTime",
- "ReleaseDate",
- "ReservationTime",
- "SensorResetTime",
- "ServicedDate",
- "SetPointUpdateTime",
- "StartDateTime",
- "StartTime",
- "Time",
- "Timestamp",
- "ValidNotAfter",
- "ValidNotBefore"});
+ static constexpr auto timeKeys = std::to_array<std::string_view>(
+ {"AccountExpiration",
+ "CalibrationTime",
+ "CoefficientUpdateTime",
+ "Created",
+ "CreatedDate",
+ "CreatedTime",
+ "CreateTime",
+ "DateTime",
+ "EndDateTime",
+ "EndTime",
+ "EventTimestamp",
+ "ExpirationDate",
+ "FirstOverflowTimestamp",
+ "InitialStartTime",
+ "InstallDate",
+ "LastOverflowTimestamp",
+ "LastResetTime",
+ "LastStateTime",
+ "LastUpdated",
+ "LifetimeStartDateTime",
+ "LowestReadingTime",
+ "MaintenanceWindowStartTime",
+ "Modified",
+ "PasswordExpiration",
+ "PeakReadingTime",
+ "PresentedPublicHostKeyTimestamp",
+ "ProductionDate",
+ "ReadingTime",
+ "ReleaseDate",
+ "ReservationTime",
+ "SensorResetTime",
+ "ServicedDate",
+ "SetPointUpdateTime",
+ "StartDateTime",
+ "StartTime",
+ "Time",
+ "Timestamp",
+ "ValidNotAfter",
+ "ValidNotBefore"});
explicit DateTimeString(std::string_view strvalue)
{
@@ -88,7 +99,7 @@ struct ValueVisitor
{
using result_type = std::variant<std::monostate, double, int64_t,
std::string, DateTimeString>;
- nlohmann::json& body;
+ const nlohmann::json& body;
result_type operator()(double n);
result_type operator()(int64_t x);
result_type operator()(const filter_ast::UnquotedString& x);
@@ -151,7 +162,7 @@ ValueVisitor::result_type
struct ApplyFilter
{
- nlohmann::json& body;
+ const nlohmann::json& body;
const filter_ast::LogicalAnd& filter;
using result_type = bool;
bool operator()(const filter_ast::LogicalNot& x);
@@ -370,9 +381,16 @@ bool ApplyFilter::matches()
} // namespace
+bool memberMatches(const nlohmann::json& member,
+ const filter_ast::LogicalAnd& filterParam)
+{
+ ApplyFilter filterApplier(member, filterParam);
+ return filterApplier.matches();
+}
+
// Applies a filter expression to a member array
-bool applyFilter(nlohmann::json& body,
- const filter_ast::LogicalAnd& filterParam)
+bool applyFilterToCollection(nlohmann::json& body,
+ const filter_ast::LogicalAnd& filterParam)
{
using nlohmann::json;
@@ -399,8 +417,7 @@ bool applyFilter(nlohmann::json& body,
size_t index = 0;
while (it != memberArr->end())
{
- ApplyFilter filterApplier(*it, filterParam);
- if (!filterApplier.matches())
+ if (!memberMatches(*it, filterParam))
{
BMCWEB_LOG_DEBUG("Removing item at index {}", index);
it = memberArr->erase(it);
diff --git a/redfish-core/src/filter_expr_printer.cpp b/redfish-core/src/filter_expr_printer.cpp
index 946f17ca9e..32b4e6f927 100644
--- a/redfish-core/src/filter_expr_printer.cpp
+++ b/redfish-core/src/filter_expr_printer.cpp
@@ -4,11 +4,16 @@
#include "filter_expr_parser_grammar.hpp"
#include "logging.hpp"
-#include <iostream>
+#include <boost/spirit/home/x3/char/char_class.hpp>
+#include <boost/spirit/home/x3/core/parse.hpp>
+
+#include <cstdint>
+#include <format>
#include <list>
-#include <numeric>
#include <optional>
#include <string>
+#include <string_view>
+#include <utility>
namespace redfish
{
diff --git a/redfish-core/src/redfish.cpp b/redfish-core/src/redfish.cpp
index 63d5b9d480..61f2762281 100644
--- a/redfish-core/src/redfish.cpp
+++ b/redfish-core/src/redfish.cpp
@@ -18,6 +18,7 @@
#include "hypervisor_system.hpp"
#include "log_services.hpp"
#include "manager_diagnostic_data.hpp"
+#include "manager_logservices_journal.hpp"
#include "managers.hpp"
#include "memory.hpp"
#include "message_registries.hpp"
@@ -25,6 +26,7 @@
#include "metric_report.hpp"
#include "metric_report_definition.hpp"
#include "network_protocol.hpp"
+#include "odata.hpp"
#include "pcie.hpp"
#include "power.hpp"
#include "power_subsystem.hpp"
@@ -37,6 +39,8 @@
#include "service_root.hpp"
#include "storage.hpp"
#include "systems.hpp"
+#include "systems_logservices_hostlogger.hpp"
+#include "systems_logservices_postcodes.hpp"
#include "task.hpp"
#include "telemetry_service.hpp"
#include "thermal.hpp"
@@ -52,6 +56,7 @@ namespace redfish
RedfishService::RedfishService(App& app)
{
requestRoutesMetadata(app);
+ requestRoutesOdata(app);
requestAccountServiceRoutes(app);
if constexpr (BMCWEB_REDFISH_AGGREGATION)
@@ -105,12 +110,8 @@ RedfishService::RedfishService(App& app)
requestRoutesSystemLogServiceCollection(app);
requestRoutesEventLogService(app);
- requestRoutesPostCodesEntryAdditionalData(app);
- requestRoutesPostCodesLogService(app);
- requestRoutesPostCodesClear(app);
- requestRoutesPostCodesEntry(app);
- requestRoutesPostCodesEntryCollection(app);
+ requestRoutesSystemsLogServicesPostCode(app);
if constexpr (BMCWEB_REDFISH_DUMP_LOG)
{
@@ -133,19 +134,11 @@ RedfishService::RedfishService(App& app)
requestRoutesFaultLogDumpClear(app);
}
- if constexpr (!BMCWEB_REDFISH_DBUS_LOG)
- {
- requestRoutesJournalEventLogEntryCollection(app);
- requestRoutesJournalEventLogEntry(app);
- requestRoutesJournalEventLogClear(app);
- }
-
requestRoutesBMCLogServiceCollection(app);
+
if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
{
requestRoutesBMCJournalLogService(app);
- requestRoutesBMCJournalLogEntryCollection(app);
- requestRoutesBMCJournalLogEntry(app);
}
if constexpr (BMCWEB_REDFISH_CPU_LOG)
@@ -182,12 +175,16 @@ RedfishService::RedfishService(App& app)
requestRoutesDBusEventLogEntry(app);
requestRoutesDBusEventLogEntryDownload(app);
}
+ else
+ {
+ requestRoutesJournalEventLogEntryCollection(app);
+ requestRoutesJournalEventLogEntry(app);
+ requestRoutesJournalEventLogClear(app);
+ }
if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
{
- requestRoutesSystemHostLogger(app);
- requestRoutesSystemHostLoggerCollection(app);
- requestRoutesSystemHostLoggerLogEntry(app);
+ requestRoutesSystemsLogServiceHostlogger(app);
}
requestRoutesMessageRegistryFileCollection(app);
@@ -219,7 +216,10 @@ RedfishService::RedfishService(App& app)
requestRoutesFabricAdapterCollection(app);
requestRoutesSubmitTestEvent(app);
- requestRoutesHypervisorSystems(app);
+ if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
+ {
+ requestRoutesHypervisorSystems(app);
+ }
requestRoutesTelemetryService(app);
requestRoutesMetricReportDefinitionCollection(app);
diff --git a/redfish-core/src/registries.cpp b/redfish-core/src/registries.cpp
index 61b27b57b4..a852f2497c 100644
--- a/redfish-core/src/registries.cpp
+++ b/redfish-core/src/registries.cpp
@@ -21,8 +21,8 @@ const Message* getMessageFromRegistry(const std::string& messageKey,
{
std::span<const MessageEntry>::iterator messageIt = std::ranges::find_if(
registry, [&messageKey](const MessageEntry& messageEntry) {
- return std::strcmp(messageEntry.first, messageKey.c_str()) == 0;
- });
+ return std::strcmp(messageEntry.first, messageKey.c_str()) == 0;
+ });
if (messageIt != registry.end())
{
return &messageIt->second;
diff --git a/redfish-core/src/utils/dbus_utils.cpp b/redfish-core/src/utils/dbus_utils.cpp
index f30e6ed46a..3fe2fb43ae 100644
--- a/redfish-core/src/utils/dbus_utils.cpp
+++ b/redfish-core/src/utils/dbus_utils.cpp
@@ -21,11 +21,10 @@ namespace redfish
namespace details
{
-void afterSetProperty(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& redfishPropertyName,
- const nlohmann::json& propertyValue,
- const boost::system::error_code& ec,
- const sdbusplus::message_t& msg)
+void afterSetProperty(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& redfishPropertyName, const nlohmann::json& propertyValue,
+ const boost::system::error_code& ec, const sdbusplus::message_t& msg)
{
if (ec)
{
@@ -130,10 +129,10 @@ void afterSetPropertyAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
messages::internalError(asyncResp->res);
return;
}
- // Only set 204 if another error hasn't already happened.
+ // Only set success if another error hasn't already happened.
if (asyncResp->res.result() == boost::beast::http::status::ok)
{
- asyncResp->res.result(boost::beast::http::status::no_content);
+ messages::success(asyncResp->res);
}
};
} // namespace details
diff --git a/redfish-core/src/utils/json_utils.cpp b/redfish-core/src/utils/json_utils.cpp
index 8017b36258..76c5912479 100644
--- a/redfish-core/src/utils/json_utils.cpp
+++ b/redfish-core/src/utils/json_utils.cpp
@@ -1,17 +1,17 @@
/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2018 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#include "utils/json_utils.hpp"
diff --git a/redfish-core/src/utils/time_utils.cpp b/redfish-core/src/utils/time_utils.cpp
index fa49657324..2d5e0cc808 100644
--- a/redfish-core/src/utils/time_utils.cpp
+++ b/redfish-core/src/utils/time_utils.cpp
@@ -14,7 +14,8 @@ namespace redfish::time_utils
std::optional<usSinceEpoch> dateStringToEpoch(std::string_view datetime)
{
- for (const char* format : std::to_array({"%FT%T%Ez", "%FT%TZ", "%FT%T"}))
+ for (const char* format : std::to_array(
+ {"%FT%T%Ez", "%FT%TZ", "%FT%T", "%Y%m%d", "%Y%m%dT%H%M%SZ"}))
{
// Parse using signed so we can detect negative dates
std::chrono::sys_time<usSinceEpoch> date;