1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation 4c5b2abe0SLewanczyk, Dawid #pragma once 5c5b2abe0SLewanczyk, Dawid 613451e39SWilly Tu #include "bmcweb_config.h" 713451e39SWilly Tu 83ccb3adbSEd Tanous #include "app.hpp" 91e1e598dSJonathan Doman #include "dbus_singleton.hpp" 107a1dbc48SGeorge Liu #include "dbus_utility.hpp" 11539d8c6bSEd Tanous #include "generated/enums/action_info.hpp" 128d69c668SEd Tanous #include "generated/enums/computer_system.hpp" 13539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp" 1433e1f122SAndrew Geissler #include "generated/enums/resource.hpp" 15746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 161c8fba97SJames Feist #include "led.hpp" 17f4c99e70SEd Tanous #include "query.hpp" 18c5d03ff4SJennifer Lee #include "redfish_util.hpp" 193ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 203ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 213ccb3adbSEd Tanous #include "utils/json_utils.hpp" 22472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 233ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 242b82937eSEd Tanous #include "utils/time_utils.hpp" 25c5d03ff4SJennifer Lee 26fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 279712f8acSEd Tanous #include <boost/container/flat_map.hpp> 28e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 2933e1f122SAndrew Geissler #include <boost/system/linux_error.hpp> 30ef4c65b7SEd Tanous #include <boost/url/format.hpp> 311e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 32fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 33bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 341214b7e7SGunnar Mills 357a1dbc48SGeorge Liu #include <array> 3633e1f122SAndrew Geissler #include <memory> 376b9ac4f2SChris Cain #include <string> 387a1dbc48SGeorge Liu #include <string_view> 3920fa6a2cSEd Tanous #include <utility> 40abf2add6SEd Tanous #include <variant> 416b9ac4f2SChris Cain #include <vector> 42c5b2abe0SLewanczyk, Dawid 431abe55efSEd Tanous namespace redfish 441abe55efSEd Tanous { 45c5b2abe0SLewanczyk, Dawid 465c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 475c3e9272SAbhishek Patel protocolToDBusForSystems{ 485c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 495c3e9272SAbhishek Patel 509d3ae10eSAlpana Kumari /** 519d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 529d3ae10eSAlpana Kumari * 53ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 549d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 559d3ae10eSAlpana Kumari * 569d3ae10eSAlpana Kumari * @return None. 579d3ae10eSAlpana Kumari */ 58bd79bce8SPatrick Williams inline void updateDimmProperties( 59bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional) 609d3ae10eSAlpana Kumari { 6162598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 629d3ae10eSAlpana Kumari 639d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 649d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 659d3ae10eSAlpana Kumari // ENABLED. 6602cad96eSEd Tanous const nlohmann::json& prevMemSummary = 67ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 689d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 699d3ae10eSAlpana Kumari { 70e05aec50SEd Tanous if (isDimmFunctional) 719d3ae10eSAlpana Kumari { 72ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 739d3ae10eSAlpana Kumari "Enabled"; 749d3ae10eSAlpana Kumari } 759d3ae10eSAlpana Kumari } 769d3ae10eSAlpana Kumari } 779d3ae10eSAlpana Kumari 7857e8c9beSAlpana Kumari /* 7957e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 8057e8c9beSAlpana Kumari * CPU Functional State 8157e8c9beSAlpana Kumari * 82ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 8357e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 8457e8c9beSAlpana Kumari * 8557e8c9beSAlpana Kumari * @return None. 8657e8c9beSAlpana Kumari */ 87ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 88ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 8957e8c9beSAlpana Kumari { 9062598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 9157e8c9beSAlpana Kumari 9202cad96eSEd Tanous const nlohmann::json& prevProcState = 93ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 9457e8c9beSAlpana Kumari 9557e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 9657e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 9757e8c9beSAlpana Kumari // Functional. 9857e8c9beSAlpana Kumari if (prevProcState == "Disabled") 9957e8c9beSAlpana Kumari { 100e05aec50SEd Tanous if (isCpuFunctional) 10157e8c9beSAlpana Kumari { 102ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 10357e8c9beSAlpana Kumari "Enabled"; 10457e8c9beSAlpana Kumari } 10557e8c9beSAlpana Kumari } 10657e8c9beSAlpana Kumari } 10757e8c9beSAlpana Kumari 108cf0e004cSNinad Palsule /* 109cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 110cf0e004cSNinad Palsule * 111ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 112cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 113cf0e004cSNinad Palsule * 114cf0e004cSNinad Palsule * @return None. 115cf0e004cSNinad Palsule */ 116bd79bce8SPatrick Williams inline void modifyCpuPresenceState( 117bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent) 118cf0e004cSNinad Palsule { 11962598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 120cf0e004cSNinad Palsule 121cf0e004cSNinad Palsule if (isCpuPresent) 122cf0e004cSNinad Palsule { 123cf0e004cSNinad Palsule nlohmann::json& procCount = 124ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 125cf0e004cSNinad Palsule auto* procCountPtr = 126cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 127cf0e004cSNinad Palsule if (procCountPtr != nullptr) 128cf0e004cSNinad Palsule { 129cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 130cf0e004cSNinad Palsule *procCountPtr += 1; 131cf0e004cSNinad Palsule } 132cf0e004cSNinad Palsule } 133cf0e004cSNinad Palsule } 134cf0e004cSNinad Palsule 135382d6475SAli Ahmed inline void getProcessorProperties( 136ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 137382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 138382d6475SAli Ahmed properties) 13903fbed92SAli Ahmed { 14062598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 14103fbed92SAli Ahmed 14203fbed92SAli Ahmed // TODO: Get Model 14303fbed92SAli Ahmed 144bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 14503fbed92SAli Ahmed 146bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 147bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 14803fbed92SAli Ahmed 149bc1d29deSKrzysztof Grobelny if (!success) 15003fbed92SAli Ahmed { 151ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15203fbed92SAli Ahmed return; 15303fbed92SAli Ahmed } 15403fbed92SAli Ahmed 155bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 15603fbed92SAli Ahmed { 157bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 158ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 159bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 160bc1d29deSKrzysztof Grobelny 161bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 162bc1d29deSKrzysztof Grobelny { 163bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 16403fbed92SAli Ahmed } 16503fbed92SAli Ahmed else 16603fbed92SAli Ahmed { 167bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 16803fbed92SAli Ahmed } 16903fbed92SAli Ahmed } 17003fbed92SAli Ahmed } 17103fbed92SAli Ahmed 17203fbed92SAli Ahmed /* 17303fbed92SAli Ahmed * @brief Get ProcessorSummary fields 17403fbed92SAli Ahmed * 175ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 17603fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 17703fbed92SAli Ahmed * @param[in] path dbus path for Cpu 17803fbed92SAli Ahmed * 17903fbed92SAli Ahmed * @return None. 18003fbed92SAli Ahmed */ 181ac106bf6SEd Tanous inline void 182ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 183ac106bf6SEd Tanous const std::string& service, const std::string& path) 18403fbed92SAli Ahmed { 185ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 186382d6475SAli Ahmed const bool cpuPresenceCheck) { 187382d6475SAli Ahmed if (ec3) 188382d6475SAli Ahmed { 18962598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 190382d6475SAli Ahmed return; 191382d6475SAli Ahmed } 192ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 193382d6475SAli Ahmed }; 194382d6475SAli Ahmed 195cf0e004cSNinad Palsule // Get the Presence of CPU 196deae6a78SEd Tanous dbus::utility::getProperty<bool>(*crow::connections::systemBus, service, 197deae6a78SEd Tanous path, "xyz.openbmc_project.Inventory.Item", 198deae6a78SEd Tanous "Present", std::move(getCpuPresenceState)); 199cf0e004cSNinad Palsule 200deae6a78SEd Tanous dbus::utility::getAllProperties( 201deae6a78SEd Tanous service, path, "xyz.openbmc_project.Inventory.Item.Cpu", 202ac106bf6SEd Tanous [asyncResp, service, 2035e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 204b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 20503fbed92SAli Ahmed if (ec2) 20603fbed92SAli Ahmed { 20762598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 208ac106bf6SEd Tanous messages::internalError(asyncResp->res); 20903fbed92SAli Ahmed return; 21003fbed92SAli Ahmed } 211ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 212bc1d29deSKrzysztof Grobelny }); 21303fbed92SAli Ahmed } 21403fbed92SAli Ahmed 21557e8c9beSAlpana Kumari /* 216cf0e004cSNinad Palsule * @brief processMemoryProperties fields 217cf0e004cSNinad Palsule * 218ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 219cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 220cf0e004cSNinad Palsule * 221cf0e004cSNinad Palsule * @return None. 222cf0e004cSNinad Palsule */ 223cf0e004cSNinad Palsule inline void 224ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 225cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 226cf0e004cSNinad Palsule { 22762598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 228cf0e004cSNinad Palsule 229cf0e004cSNinad Palsule if (properties.empty()) 230cf0e004cSNinad Palsule { 231cf0e004cSNinad Palsule return; 232cf0e004cSNinad Palsule } 233cf0e004cSNinad Palsule 234cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 235cf0e004cSNinad Palsule 236cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 237cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 238cf0e004cSNinad Palsule memorySizeInKB); 239cf0e004cSNinad Palsule 240cf0e004cSNinad Palsule if (!success) 241cf0e004cSNinad Palsule { 242ac106bf6SEd Tanous messages::internalError(asyncResp->res); 243cf0e004cSNinad Palsule return; 244cf0e004cSNinad Palsule } 245cf0e004cSNinad Palsule 246cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 247cf0e004cSNinad Palsule { 248cf0e004cSNinad Palsule nlohmann::json& totalMemory = 249ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 250dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 251cf0e004cSNinad Palsule if (preValue == nullptr) 252cf0e004cSNinad Palsule { 253ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 254dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 255cf0e004cSNinad Palsule } 256cf0e004cSNinad Palsule else 257cf0e004cSNinad Palsule { 258ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 259dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 260dfb2b408SPriyanga Ramasamy *preValue; 261cf0e004cSNinad Palsule } 262cf0e004cSNinad Palsule } 263cf0e004cSNinad Palsule } 264cf0e004cSNinad Palsule 265cf0e004cSNinad Palsule /* 266cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 267cf0e004cSNinad Palsule * 268ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 269cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 270cf0e004cSNinad Palsule * @param[in] path dbus path for memory 271cf0e004cSNinad Palsule * 272cf0e004cSNinad Palsule * @return None. 273cf0e004cSNinad Palsule */ 274ac106bf6SEd Tanous inline void 275ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 276ac106bf6SEd Tanous const std::string& service, const std::string& path) 277cf0e004cSNinad Palsule { 278deae6a78SEd Tanous dbus::utility::getAllProperties( 279deae6a78SEd Tanous service, path, "xyz.openbmc_project.Inventory.Item.Dimm", 280ac106bf6SEd Tanous [asyncResp, service, 281cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 282cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 283cf0e004cSNinad Palsule if (ec2) 284cf0e004cSNinad Palsule { 28562598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 286ac106bf6SEd Tanous messages::internalError(asyncResp->res); 287cf0e004cSNinad Palsule return; 288cf0e004cSNinad Palsule } 28951bd2d8aSGunnar Mills processMemoryProperties(asyncResp, properties); 290cf0e004cSNinad Palsule }); 291cf0e004cSNinad Palsule } 292cf0e004cSNinad Palsule 293a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 294a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 295a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& properties) 2961abe55efSEd Tanous { 297a974c132SLakshmi Yadlapati if (ec) 298a974c132SLakshmi Yadlapati { 299a974c132SLakshmi Yadlapati BMCWEB_LOG_ERROR("DBUS response error {}", ec); 300a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 301a974c132SLakshmi Yadlapati return; 302a974c132SLakshmi Yadlapati } 303a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size()); 304a974c132SLakshmi Yadlapati 305a974c132SLakshmi Yadlapati const std::string* uUID = nullptr; 306a974c132SLakshmi Yadlapati 307a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 308a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID); 309a974c132SLakshmi Yadlapati 310a974c132SLakshmi Yadlapati if (!success) 311a974c132SLakshmi Yadlapati { 312a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 313a974c132SLakshmi Yadlapati return; 314a974c132SLakshmi Yadlapati } 315a974c132SLakshmi Yadlapati 316a974c132SLakshmi Yadlapati if (uUID != nullptr) 317a974c132SLakshmi Yadlapati { 318a974c132SLakshmi Yadlapati std::string valueStr = *uUID; 319a974c132SLakshmi Yadlapati if (valueStr.size() == 32) 320a974c132SLakshmi Yadlapati { 321a974c132SLakshmi Yadlapati valueStr.insert(8, 1, '-'); 322a974c132SLakshmi Yadlapati valueStr.insert(13, 1, '-'); 323a974c132SLakshmi Yadlapati valueStr.insert(18, 1, '-'); 324a974c132SLakshmi Yadlapati valueStr.insert(23, 1, '-'); 325a974c132SLakshmi Yadlapati } 326a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("UUID = {}", valueStr); 327a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["UUID"] = valueStr; 328a974c132SLakshmi Yadlapati } 329a974c132SLakshmi Yadlapati } 330a974c132SLakshmi Yadlapati 331a974c132SLakshmi Yadlapati inline void 332a974c132SLakshmi Yadlapati afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 333a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 334a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& propertiesList) 335a974c132SLakshmi Yadlapati { 336a974c132SLakshmi Yadlapati if (ec) 337a974c132SLakshmi Yadlapati { 338a974c132SLakshmi Yadlapati // doesn't have to include this 339a974c132SLakshmi Yadlapati // interface 340a974c132SLakshmi Yadlapati return; 341a974c132SLakshmi Yadlapati } 342a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size()); 343a974c132SLakshmi Yadlapati 344a974c132SLakshmi Yadlapati const std::string* partNumber = nullptr; 345a974c132SLakshmi Yadlapati const std::string* serialNumber = nullptr; 346a974c132SLakshmi Yadlapati const std::string* manufacturer = nullptr; 347a974c132SLakshmi Yadlapati const std::string* model = nullptr; 348a974c132SLakshmi Yadlapati const std::string* subModel = nullptr; 349a974c132SLakshmi Yadlapati 350a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 351a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber", 352a974c132SLakshmi Yadlapati partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 353a974c132SLakshmi Yadlapati "Model", model, "SubModel", subModel); 354a974c132SLakshmi Yadlapati 355a974c132SLakshmi Yadlapati if (!success) 356a974c132SLakshmi Yadlapati { 357a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 358a974c132SLakshmi Yadlapati return; 359a974c132SLakshmi Yadlapati } 360a974c132SLakshmi Yadlapati 361a974c132SLakshmi Yadlapati if (partNumber != nullptr) 362a974c132SLakshmi Yadlapati { 363a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["PartNumber"] = *partNumber; 364a974c132SLakshmi Yadlapati } 365a974c132SLakshmi Yadlapati 366a974c132SLakshmi Yadlapati if (serialNumber != nullptr) 367a974c132SLakshmi Yadlapati { 368a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 369a974c132SLakshmi Yadlapati } 370a974c132SLakshmi Yadlapati 371a974c132SLakshmi Yadlapati if (manufacturer != nullptr) 372a974c132SLakshmi Yadlapati { 373a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 374a974c132SLakshmi Yadlapati } 375a974c132SLakshmi Yadlapati 376a974c132SLakshmi Yadlapati if (model != nullptr) 377a974c132SLakshmi Yadlapati { 378a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Model"] = *model; 379a974c132SLakshmi Yadlapati } 380a974c132SLakshmi Yadlapati 381a974c132SLakshmi Yadlapati if (subModel != nullptr) 382a974c132SLakshmi Yadlapati { 383a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SubModel"] = *subModel; 384a974c132SLakshmi Yadlapati } 385a974c132SLakshmi Yadlapati 386a974c132SLakshmi Yadlapati // Grab the bios version 387a974c132SLakshmi Yadlapati sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, 388a974c132SLakshmi Yadlapati "BiosVersion", false); 389a974c132SLakshmi Yadlapati } 390a974c132SLakshmi Yadlapati 391bd79bce8SPatrick Williams inline void afterGetAssetTag( 392bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 393bd79bce8SPatrick Williams const boost::system::error_code& ec, const std::string& value) 394a974c132SLakshmi Yadlapati { 395a974c132SLakshmi Yadlapati if (ec) 396a974c132SLakshmi Yadlapati { 397a974c132SLakshmi Yadlapati // doesn't have to include this 398a974c132SLakshmi Yadlapati // interface 399a974c132SLakshmi Yadlapati return; 400a974c132SLakshmi Yadlapati } 401a974c132SLakshmi Yadlapati 402a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["AssetTag"] = value; 403a974c132SLakshmi Yadlapati } 404a974c132SLakshmi Yadlapati 405a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree( 406a974c132SLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 407a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 408a974c132SLakshmi Yadlapati const dbus::utility::MapperGetSubTreeResponse& subtree) 409a974c132SLakshmi Yadlapati { 4101abe55efSEd Tanous if (ec) 4111abe55efSEd Tanous { 412b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 413ac106bf6SEd Tanous messages::internalError(asyncResp->res); 414c5b2abe0SLewanczyk, Dawid return; 415c5b2abe0SLewanczyk, Dawid } 416c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 417002d39b4SEd Tanous for (const std::pair< 418002d39b4SEd Tanous std::string, 419002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 4201214b7e7SGunnar Mills object : subtree) 4211abe55efSEd Tanous { 422c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 42362598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 424002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 4251214b7e7SGunnar Mills connectionNames = object.second; 42626f6976fSEd Tanous if (connectionNames.empty()) 4271abe55efSEd Tanous { 428c5b2abe0SLewanczyk, Dawid continue; 429c5b2abe0SLewanczyk, Dawid } 430029573d4SEd Tanous 4316c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4326c34de48SEd Tanous // BiosVer 43304a258f4SEd Tanous for (const auto& connection : connectionNames) 4341abe55efSEd Tanous { 43504a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4361abe55efSEd Tanous { 437a974c132SLakshmi Yadlapati if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") 4381abe55efSEd Tanous { 43962598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 4409d3ae10eSAlpana Kumari 441ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4425fd0aafbSNinad Palsule } 44304a258f4SEd Tanous else if (interfaceName == 44404a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4451abe55efSEd Tanous { 44662598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 44757e8c9beSAlpana Kumari 448ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4495fd0aafbSNinad Palsule } 450002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4511abe55efSEd Tanous { 45262598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 453bc1d29deSKrzysztof Grobelny 454deae6a78SEd Tanous dbus::utility::getAllProperties( 455a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 456a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 457ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 458b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4591214b7e7SGunnar Mills properties) { 460a974c132SLakshmi Yadlapati afterGetUUID(asyncResp, ec3, properties); 461bc1d29deSKrzysztof Grobelny }); 462c5b2abe0SLewanczyk, Dawid } 463029573d4SEd Tanous else if (interfaceName == 464029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4651abe55efSEd Tanous { 466deae6a78SEd Tanous dbus::utility::getAllProperties( 467a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 468bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 469a974c132SLakshmi Yadlapati [asyncResp](const boost::system::error_code& ec3, 470b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 471a974c132SLakshmi Yadlapati properties) { 472a974c132SLakshmi Yadlapati afterGetInventory(asyncResp, ec3, properties); 473bc1d29deSKrzysztof Grobelny }); 474e4a4b9a9SJames Feist 475deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 476deae6a78SEd Tanous connection.first, path, 4771e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 4781e1e598dSJonathan Doman "AssetTag", 4791e1e598dSJonathan Doman "AssetTag", 480a974c132SLakshmi Yadlapati std::bind_front(afterGetAssetTag, asyncResp)); 481a974c132SLakshmi Yadlapati } 482a974c132SLakshmi Yadlapati } 483a974c132SLakshmi Yadlapati } 484a974c132SLakshmi Yadlapati } 485a974c132SLakshmi Yadlapati } 486a974c132SLakshmi Yadlapati 487a974c132SLakshmi Yadlapati /* 488a974c132SLakshmi Yadlapati * @brief Retrieves computer system properties over dbus 489a974c132SLakshmi Yadlapati * 490a974c132SLakshmi Yadlapati * @param[in] asyncResp Shared pointer for completing asynchronous calls 491a974c132SLakshmi Yadlapati * 492a974c132SLakshmi Yadlapati * @return None. 493a974c132SLakshmi Yadlapati */ 494a974c132SLakshmi Yadlapati inline void 49551bd2d8aSGunnar Mills getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 496e4a4b9a9SJames Feist { 497a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get available system components."); 498a974c132SLakshmi Yadlapati constexpr std::array<std::string_view, 5> interfaces = { 499a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 500a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Cpu", 501a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Dimm", 502a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.System", 503a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 504a974c132SLakshmi Yadlapati }; 505a974c132SLakshmi Yadlapati dbus::utility::getSubTree( 506a974c132SLakshmi Yadlapati "/xyz/openbmc_project/inventory", 0, interfaces, 50751bd2d8aSGunnar Mills std::bind_front(afterSystemGetSubTree, asyncResp)); 508c5b2abe0SLewanczyk, Dawid } 509c5b2abe0SLewanczyk, Dawid 510c5b2abe0SLewanczyk, Dawid /** 511c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 512c5b2abe0SLewanczyk, Dawid * 513ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 514c5b2abe0SLewanczyk, Dawid * 515c5b2abe0SLewanczyk, Dawid * @return None. 516c5b2abe0SLewanczyk, Dawid */ 517ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5181abe55efSEd Tanous { 51962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 520deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 521deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 522deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "CurrentHostState", 523ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 5241e1e598dSJonathan Doman const std::string& hostState) { 5251abe55efSEd Tanous if (ec) 5261abe55efSEd Tanous { 52722228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 52822228c28SAndrew Geissler { 52922228c28SAndrew Geissler // Service not available, no error, just don't return 53022228c28SAndrew Geissler // host state info 53162598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 53222228c28SAndrew Geissler return; 53322228c28SAndrew Geissler } 53462598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 535ac106bf6SEd Tanous messages::internalError(asyncResp->res); 536c5b2abe0SLewanczyk, Dawid return; 537c5b2abe0SLewanczyk, Dawid } 5386617338dSEd Tanous 53962598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 540c5b2abe0SLewanczyk, Dawid // Verify Host State 5411e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5421abe55efSEd Tanous { 543bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 544bd79bce8SPatrick Williams resource::PowerState::On; 545539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 546539d8c6bSEd Tanous resource::State::Enabled; 5471abe55efSEd Tanous } 5481e1e598dSJonathan Doman else if (hostState == 5490fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5508c888608SGunnar Mills { 551bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 552bd79bce8SPatrick Williams resource::PowerState::On; 553539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 554539d8c6bSEd Tanous resource::State::Quiesced; 5558c888608SGunnar Mills } 5561e1e598dSJonathan Doman else if (hostState == 5570fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 55883935af9SAndrew Geissler { 559bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 560bd79bce8SPatrick Williams resource::PowerState::On; 561539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 562539d8c6bSEd Tanous resource::State::InTest; 56383935af9SAndrew Geissler } 5640fda0f12SGeorge Liu else if ( 5651e1e598dSJonathan Doman hostState == 5660fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5671a2a1437SAndrew Geissler { 568539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 569539d8c6bSEd Tanous resource::PowerState::PoweringOn; 570539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 571539d8c6bSEd Tanous resource::State::Starting; 5721a2a1437SAndrew Geissler } 573bd79bce8SPatrick Williams else if ( 574bd79bce8SPatrick Williams hostState == 5750fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5761a2a1437SAndrew Geissler { 577539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 578539d8c6bSEd Tanous resource::PowerState::PoweringOff; 579539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 580539d8c6bSEd Tanous resource::State::Disabled; 5811a2a1437SAndrew Geissler } 5821abe55efSEd Tanous else 5831abe55efSEd Tanous { 584bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 585bd79bce8SPatrick Williams resource::PowerState::Off; 586539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 587539d8c6bSEd Tanous resource::State::Disabled; 588c5b2abe0SLewanczyk, Dawid } 5891e1e598dSJonathan Doman }); 590c5b2abe0SLewanczyk, Dawid } 591c5b2abe0SLewanczyk, Dawid 592c5b2abe0SLewanczyk, Dawid /** 593786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 594491d8ee7SSantosh Puranik * 595491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 596491d8ee7SSantosh Puranik * 597491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 598491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 599491d8ee7SSantosh Puranik */ 60023a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 601491d8ee7SSantosh Puranik { 602491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 603491d8ee7SSantosh Puranik { 604491d8ee7SSantosh Puranik return "None"; 605491d8ee7SSantosh Puranik } 6063174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 607491d8ee7SSantosh Puranik { 608491d8ee7SSantosh Puranik return "Hdd"; 609491d8ee7SSantosh Puranik } 6103174e4dfSEd Tanous if (dbusSource == 611a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 612491d8ee7SSantosh Puranik { 613491d8ee7SSantosh Puranik return "Cd"; 614491d8ee7SSantosh Puranik } 6153174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 616491d8ee7SSantosh Puranik { 617491d8ee7SSantosh Puranik return "Pxe"; 618491d8ee7SSantosh Puranik } 6193174e4dfSEd Tanous if (dbusSource == 620944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6219f16b2c1SJennifer Lee { 6229f16b2c1SJennifer Lee return "Usb"; 6239f16b2c1SJennifer Lee } 624491d8ee7SSantosh Puranik return ""; 625491d8ee7SSantosh Puranik } 626491d8ee7SSantosh Puranik 627491d8ee7SSantosh Puranik /** 628cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 629cd9a4666SKonstantin Aladyshev * 630cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 631cd9a4666SKonstantin Aladyshev * 632cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 633cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 634cd9a4666SKonstantin Aladyshev */ 635cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 636cd9a4666SKonstantin Aladyshev { 637cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 638cd9a4666SKonstantin Aladyshev { 639cd9a4666SKonstantin Aladyshev return "Legacy"; 640cd9a4666SKonstantin Aladyshev } 641cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 642cd9a4666SKonstantin Aladyshev { 643cd9a4666SKonstantin Aladyshev return "UEFI"; 644cd9a4666SKonstantin Aladyshev } 645cd9a4666SKonstantin Aladyshev return ""; 646cd9a4666SKonstantin Aladyshev } 647cd9a4666SKonstantin Aladyshev 648cd9a4666SKonstantin Aladyshev /** 649786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 650491d8ee7SSantosh Puranik * 651491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 652491d8ee7SSantosh Puranik * 653491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 654491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 655491d8ee7SSantosh Puranik */ 65623a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 657491d8ee7SSantosh Puranik { 658491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 659491d8ee7SSantosh Puranik { 660491d8ee7SSantosh Puranik return "None"; 661491d8ee7SSantosh Puranik } 6623174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 663491d8ee7SSantosh Puranik { 664491d8ee7SSantosh Puranik return "Diags"; 665491d8ee7SSantosh Puranik } 6663174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 667491d8ee7SSantosh Puranik { 668491d8ee7SSantosh Puranik return "BiosSetup"; 669491d8ee7SSantosh Puranik } 670491d8ee7SSantosh Puranik return ""; 671491d8ee7SSantosh Puranik } 672491d8ee7SSantosh Puranik 673491d8ee7SSantosh Puranik /** 674e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 675e43914b3SAndrew Geissler * 676e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 677e43914b3SAndrew Geissler * 678e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 679e43914b3SAndrew Geissler * translation cannot be done, returns "None". 680e43914b3SAndrew Geissler */ 681e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 682e43914b3SAndrew Geissler { 683e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 684e43914b3SAndrew Geissler // enum 685e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 686e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 687e43914b3SAndrew Geissler "ProgressStages.Unspecified") 688e43914b3SAndrew Geissler { 689e43914b3SAndrew Geissler rfBpLastState = "None"; 690e43914b3SAndrew Geissler } 691e43914b3SAndrew Geissler else if (dbusBootProgress == 692e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 693e43914b3SAndrew Geissler "PrimaryProcInit") 694e43914b3SAndrew Geissler { 695e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 696e43914b3SAndrew Geissler } 697e43914b3SAndrew Geissler else if (dbusBootProgress == 698e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 699e43914b3SAndrew Geissler "BusInit") 700e43914b3SAndrew Geissler { 701e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 702e43914b3SAndrew Geissler } 703e43914b3SAndrew Geissler else if (dbusBootProgress == 704e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 705e43914b3SAndrew Geissler "MemoryInit") 706e43914b3SAndrew Geissler { 707e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 708e43914b3SAndrew Geissler } 709e43914b3SAndrew Geissler else if (dbusBootProgress == 710e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 711e43914b3SAndrew Geissler "SecondaryProcInit") 712e43914b3SAndrew Geissler { 713e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 714e43914b3SAndrew Geissler } 715e43914b3SAndrew Geissler else if (dbusBootProgress == 716e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 717e43914b3SAndrew Geissler "PCIInit") 718e43914b3SAndrew Geissler { 719e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 720e43914b3SAndrew Geissler } 721e43914b3SAndrew Geissler else if (dbusBootProgress == 722e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 723e43914b3SAndrew Geissler "SystemSetup") 724e43914b3SAndrew Geissler { 725e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 726e43914b3SAndrew Geissler } 727e43914b3SAndrew Geissler else if (dbusBootProgress == 728e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 729e43914b3SAndrew Geissler "SystemInitComplete") 730e43914b3SAndrew Geissler { 731e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 732e43914b3SAndrew Geissler } 733e43914b3SAndrew Geissler else if (dbusBootProgress == 734e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 735e43914b3SAndrew Geissler "OSStart") 736e43914b3SAndrew Geissler { 737e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 738e43914b3SAndrew Geissler } 739e43914b3SAndrew Geissler else if (dbusBootProgress == 740e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 741e43914b3SAndrew Geissler "OSRunning") 742e43914b3SAndrew Geissler { 743e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 744e43914b3SAndrew Geissler } 745e43914b3SAndrew Geissler else 746e43914b3SAndrew Geissler { 74762598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 748e43914b3SAndrew Geissler // Just return the default 749e43914b3SAndrew Geissler } 750e43914b3SAndrew Geissler return rfBpLastState; 751e43914b3SAndrew Geissler } 752e43914b3SAndrew Geissler 753e43914b3SAndrew Geissler /** 754786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 755491d8ee7SSantosh Puranik * 756491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 757944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 758944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 759491d8ee7SSantosh Puranik * 760944ffaf9SJohnathan Mantey * @return Integer error code. 761491d8ee7SSantosh Puranik */ 762bd79bce8SPatrick Williams inline int assignBootParameters( 763bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 764bd79bce8SPatrick Williams const std::string& rfSource, std::string& bootSource, std::string& bootMode) 765491d8ee7SSantosh Puranik { 766c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 767c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 768944ffaf9SJohnathan Mantey 769491d8ee7SSantosh Puranik if (rfSource == "None") 770491d8ee7SSantosh Puranik { 771944ffaf9SJohnathan Mantey return 0; 772491d8ee7SSantosh Puranik } 7733174e4dfSEd Tanous if (rfSource == "Pxe") 774491d8ee7SSantosh Puranik { 775944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 776944ffaf9SJohnathan Mantey } 777944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 778944ffaf9SJohnathan Mantey { 779944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 780944ffaf9SJohnathan Mantey } 781944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 782944ffaf9SJohnathan Mantey { 783944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 784944ffaf9SJohnathan Mantey } 785944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 786944ffaf9SJohnathan Mantey { 787944ffaf9SJohnathan Mantey bootSource = 788944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 789944ffaf9SJohnathan Mantey } 790944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 791944ffaf9SJohnathan Mantey { 792944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 793491d8ee7SSantosh Puranik } 7949f16b2c1SJennifer Lee else if (rfSource == "Usb") 7959f16b2c1SJennifer Lee { 796944ffaf9SJohnathan Mantey bootSource = 797944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 7989f16b2c1SJennifer Lee } 799491d8ee7SSantosh Puranik else 800491d8ee7SSantosh Puranik { 80162598e31SEd Tanous BMCWEB_LOG_DEBUG( 80262598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 80362598e31SEd Tanous bootSource); 804ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 805944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 806944ffaf9SJohnathan Mantey return -1; 807491d8ee7SSantosh Puranik } 808944ffaf9SJohnathan Mantey return 0; 809491d8ee7SSantosh Puranik } 8101981771bSAli Ahmed 811978b8803SAndrew Geissler /** 812978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 813978b8803SAndrew Geissler * 814ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 815978b8803SAndrew Geissler * 816978b8803SAndrew Geissler * @return None. 817978b8803SAndrew Geissler */ 818ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 819978b8803SAndrew Geissler { 820deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 821deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 8221e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 823ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8241e1e598dSJonathan Doman const std::string& bootProgressStr) { 825978b8803SAndrew Geissler if (ec) 826978b8803SAndrew Geissler { 827978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 828978b8803SAndrew Geissler // not found 829978b8803SAndrew Geissler return; 830978b8803SAndrew Geissler } 831978b8803SAndrew Geissler 83262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 833978b8803SAndrew Geissler 834ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 835e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8361e1e598dSJonathan Doman }); 837978b8803SAndrew Geissler } 838491d8ee7SSantosh Puranik 839491d8ee7SSantosh Puranik /** 840b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 841b6d5d45cSHieu Huynh * 842ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 843b6d5d45cSHieu Huynh * 844b6d5d45cSHieu Huynh * @return None. 845b6d5d45cSHieu Huynh */ 846b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 847ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 848b6d5d45cSHieu Huynh { 849deae6a78SEd Tanous dbus::utility::getProperty<uint64_t>( 850deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 851b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 852ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 853b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 854b6d5d45cSHieu Huynh if (ec) 855b6d5d45cSHieu Huynh { 85662598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 857b6d5d45cSHieu Huynh return; 858b6d5d45cSHieu Huynh } 859b6d5d45cSHieu Huynh 860b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 861b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 862b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 863b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 864b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 865b6d5d45cSHieu Huynh 866b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 867ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 868b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 869b6d5d45cSHieu Huynh }); 870b6d5d45cSHieu Huynh } 871b6d5d45cSHieu Huynh 872b6d5d45cSHieu Huynh /** 873c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 874cd9a4666SKonstantin Aladyshev * 875ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 876cd9a4666SKonstantin Aladyshev * 877cd9a4666SKonstantin Aladyshev * @return None. 878cd9a4666SKonstantin Aladyshev */ 879cd9a4666SKonstantin Aladyshev 880ac106bf6SEd Tanous inline void 881ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 882cd9a4666SKonstantin Aladyshev { 883deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 884deae6a78SEd Tanous "xyz.openbmc_project.Settings", 8851e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 8861e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 887ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8881e1e598dSJonathan Doman const std::string& bootType) { 889cd9a4666SKonstantin Aladyshev if (ec) 890cd9a4666SKonstantin Aladyshev { 891cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 892cd9a4666SKonstantin Aladyshev return; 893cd9a4666SKonstantin Aladyshev } 894cd9a4666SKonstantin Aladyshev 89562598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 896cd9a4666SKonstantin Aladyshev 897ac106bf6SEd Tanous asyncResp->res 898ac106bf6SEd Tanous .jsonValue["Boot"] 899002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 900613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 901cd9a4666SKonstantin Aladyshev 9021e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 903cd9a4666SKonstantin Aladyshev if (rfType.empty()) 904cd9a4666SKonstantin Aladyshev { 905ac106bf6SEd Tanous messages::internalError(asyncResp->res); 906cd9a4666SKonstantin Aladyshev return; 907cd9a4666SKonstantin Aladyshev } 908cd9a4666SKonstantin Aladyshev 909ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9101e1e598dSJonathan Doman }); 911cd9a4666SKonstantin Aladyshev } 912cd9a4666SKonstantin Aladyshev 913cd9a4666SKonstantin Aladyshev /** 914c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 915491d8ee7SSantosh Puranik * 916ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 917491d8ee7SSantosh Puranik * 918491d8ee7SSantosh Puranik * @return None. 919491d8ee7SSantosh Puranik */ 920c21865c4SKonstantin Aladyshev 921ac106bf6SEd Tanous inline void 922ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 923491d8ee7SSantosh Puranik { 924deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 925deae6a78SEd Tanous "xyz.openbmc_project.Settings", 9261e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9271e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 928ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9291e1e598dSJonathan Doman const std::string& bootModeStr) { 930491d8ee7SSantosh Puranik if (ec) 931491d8ee7SSantosh Puranik { 932b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 933ac106bf6SEd Tanous messages::internalError(asyncResp->res); 934491d8ee7SSantosh Puranik return; 935491d8ee7SSantosh Puranik } 936491d8ee7SSantosh Puranik 93762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 938491d8ee7SSantosh Puranik 93920fa6a2cSEd Tanous nlohmann::json::array_t allowed; 94020fa6a2cSEd Tanous allowed.emplace_back("None"); 94120fa6a2cSEd Tanous allowed.emplace_back("Pxe"); 94220fa6a2cSEd Tanous allowed.emplace_back("Hdd"); 94320fa6a2cSEd Tanous allowed.emplace_back("Cd"); 94420fa6a2cSEd Tanous allowed.emplace_back("Diags"); 94520fa6a2cSEd Tanous allowed.emplace_back("BiosSetup"); 94620fa6a2cSEd Tanous allowed.emplace_back("Usb"); 94720fa6a2cSEd Tanous 948ac106bf6SEd Tanous asyncResp->res 9490fda0f12SGeorge Liu .jsonValue["Boot"] 95020fa6a2cSEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = 95120fa6a2cSEd Tanous std::move(allowed); 9521e1e598dSJonathan Doman if (bootModeStr != 953491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 954491d8ee7SSantosh Puranik { 9551e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 956491d8ee7SSantosh Puranik if (!rfMode.empty()) 957491d8ee7SSantosh Puranik { 958bd79bce8SPatrick Williams asyncResp->res 959bd79bce8SPatrick Williams .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode; 960491d8ee7SSantosh Puranik } 961491d8ee7SSantosh Puranik } 9621e1e598dSJonathan Doman }); 963491d8ee7SSantosh Puranik } 964491d8ee7SSantosh Puranik 965491d8ee7SSantosh Puranik /** 966c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 967491d8ee7SSantosh Puranik * 968ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 969491d8ee7SSantosh Puranik * 970491d8ee7SSantosh Puranik * @return None. 971491d8ee7SSantosh Puranik */ 972c21865c4SKonstantin Aladyshev 973c21865c4SKonstantin Aladyshev inline void 974ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 975491d8ee7SSantosh Puranik { 976deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 977deae6a78SEd Tanous "xyz.openbmc_project.Settings", 9781e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9791e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 980ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9811e1e598dSJonathan Doman const std::string& bootSourceStr) { 982491d8ee7SSantosh Puranik if (ec) 983491d8ee7SSantosh Puranik { 9845ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 9855ef735c8SNan Zhou { 9865ef735c8SNan Zhou return; 9875ef735c8SNan Zhou } 988b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 989ac106bf6SEd Tanous messages::internalError(asyncResp->res); 990491d8ee7SSantosh Puranik return; 991491d8ee7SSantosh Puranik } 992491d8ee7SSantosh Puranik 99362598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 994491d8ee7SSantosh Puranik 9951e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 996491d8ee7SSantosh Puranik if (!rfSource.empty()) 997491d8ee7SSantosh Puranik { 998ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 999ac106bf6SEd Tanous rfSource; 1000491d8ee7SSantosh Puranik } 1001cd9a4666SKonstantin Aladyshev 1002cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1003cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1004ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10051e1e598dSJonathan Doman }); 1006491d8ee7SSantosh Puranik } 1007491d8ee7SSantosh Puranik 1008491d8ee7SSantosh Puranik /** 1009c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1010c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1011c21865c4SKonstantin Aladyshev * state 1012491d8ee7SSantosh Puranik * 1013ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1014491d8ee7SSantosh Puranik * 1015491d8ee7SSantosh Puranik * @return None. 1016491d8ee7SSantosh Puranik */ 1017491d8ee7SSantosh Puranik 1018ac106bf6SEd Tanous inline void processBootOverrideEnable( 1019ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1020c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1021c21865c4SKonstantin Aladyshev { 1022c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1023c21865c4SKonstantin Aladyshev { 1024ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1025ac106bf6SEd Tanous "Disabled"; 1026c21865c4SKonstantin Aladyshev return; 1027c21865c4SKonstantin Aladyshev } 1028c21865c4SKonstantin Aladyshev 1029c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1030c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 1031deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1032deae6a78SEd Tanous "xyz.openbmc_project.Settings", 10331e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10341e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1035ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1036491d8ee7SSantosh Puranik if (ec) 1037491d8ee7SSantosh Puranik { 1038b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1039ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1040491d8ee7SSantosh Puranik return; 1041491d8ee7SSantosh Puranik } 1042491d8ee7SSantosh Puranik 1043c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1044c21865c4SKonstantin Aladyshev { 1045ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1046ac106bf6SEd Tanous "Once"; 1047c21865c4SKonstantin Aladyshev } 1048c21865c4SKonstantin Aladyshev else 1049c21865c4SKonstantin Aladyshev { 1050ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1051c21865c4SKonstantin Aladyshev "Continuous"; 1052c21865c4SKonstantin Aladyshev } 10531e1e598dSJonathan Doman }); 1054491d8ee7SSantosh Puranik } 1055491d8ee7SSantosh Puranik 1056491d8ee7SSantosh Puranik /** 1057c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1058c21865c4SKonstantin Aladyshev * 1059ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1060c21865c4SKonstantin Aladyshev * 1061c21865c4SKonstantin Aladyshev * @return None. 1062c21865c4SKonstantin Aladyshev */ 1063c21865c4SKonstantin Aladyshev 1064c21865c4SKonstantin Aladyshev inline void 1065ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1066c21865c4SKonstantin Aladyshev { 1067deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1068deae6a78SEd Tanous "xyz.openbmc_project.Settings", 10691e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10701e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1071ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10721e1e598dSJonathan Doman const bool bootOverrideEnable) { 1073c21865c4SKonstantin Aladyshev if (ec) 1074c21865c4SKonstantin Aladyshev { 10755ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10765ef735c8SNan Zhou { 10775ef735c8SNan Zhou return; 10785ef735c8SNan Zhou } 1079b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1080ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1081c21865c4SKonstantin Aladyshev return; 1082c21865c4SKonstantin Aladyshev } 1083c21865c4SKonstantin Aladyshev 1084ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 10851e1e598dSJonathan Doman }); 1086c21865c4SKonstantin Aladyshev } 1087c21865c4SKonstantin Aladyshev 1088c21865c4SKonstantin Aladyshev /** 1089c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1090c21865c4SKonstantin Aladyshev * 1091ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1092c21865c4SKonstantin Aladyshev * 1093c21865c4SKonstantin Aladyshev * @return None. 1094c21865c4SKonstantin Aladyshev */ 1095ac106bf6SEd Tanous inline void 1096ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1097c21865c4SKonstantin Aladyshev { 109862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1099c21865c4SKonstantin Aladyshev 1100ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1101ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1102ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1103c21865c4SKonstantin Aladyshev } 1104c21865c4SKonstantin Aladyshev 1105c21865c4SKonstantin Aladyshev /** 1106c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1107c0557e1aSGunnar Mills * 1108c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1109c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1110c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1111c0557e1aSGunnar Mills * last power operation time. 1112c0557e1aSGunnar Mills * 1113ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1114c0557e1aSGunnar Mills * 1115c0557e1aSGunnar Mills * @return None. 1116c0557e1aSGunnar Mills */ 1117ac106bf6SEd Tanous inline void 1118ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1119c0557e1aSGunnar Mills { 112062598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1121c0557e1aSGunnar Mills 1122deae6a78SEd Tanous dbus::utility::getProperty<uint64_t>( 1123deae6a78SEd Tanous "xyz.openbmc_project.State.Chassis", 11241e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11251e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1126ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1127ac106bf6SEd Tanous uint64_t lastResetTime) { 1128c0557e1aSGunnar Mills if (ec) 1129c0557e1aSGunnar Mills { 113062598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1131c0557e1aSGunnar Mills return; 1132c0557e1aSGunnar Mills } 1133c0557e1aSGunnar Mills 1134c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1135c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11361e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1137c0557e1aSGunnar Mills 1138c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1139ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 11402b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11411e1e598dSJonathan Doman }); 1142c0557e1aSGunnar Mills } 1143c0557e1aSGunnar Mills 1144c0557e1aSGunnar Mills /** 1145797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1146797d5daeSCorey Hardesty * 1147797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1148797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1149797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1150797d5daeSCorey Hardesty * dbus. 1151797d5daeSCorey Hardesty * 1152ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1153797d5daeSCorey Hardesty * 1154797d5daeSCorey Hardesty * @return None. 1155797d5daeSCorey Hardesty */ 1156ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1157ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1158797d5daeSCorey Hardesty { 115962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1160797d5daeSCorey Hardesty 1161deae6a78SEd Tanous dbus::utility::getAllProperties( 1162deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 1163797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1164ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1165ac106bf6SEd Tanous const boost::system::error_code& ec, 1166797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1167797d5daeSCorey Hardesty if (ec) 1168797d5daeSCorey Hardesty { 1169797d5daeSCorey Hardesty if (ec.value() != EBADR) 1170797d5daeSCorey Hardesty { 117162598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1172ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1173797d5daeSCorey Hardesty } 1174797d5daeSCorey Hardesty return; 1175797d5daeSCorey Hardesty } 1176797d5daeSCorey Hardesty 1177797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1178797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1179797d5daeSCorey Hardesty 1180797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1181bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), propertiesList, 1182bd79bce8SPatrick Williams "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts); 1183797d5daeSCorey Hardesty 1184797d5daeSCorey Hardesty if (!success) 1185797d5daeSCorey Hardesty { 1186ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1187797d5daeSCorey Hardesty return; 1188797d5daeSCorey Hardesty } 1189797d5daeSCorey Hardesty 1190797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1191797d5daeSCorey Hardesty { 1192ac106bf6SEd Tanous asyncResp->res 1193ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1194797d5daeSCorey Hardesty *attemptsLeft; 1195797d5daeSCorey Hardesty } 1196797d5daeSCorey Hardesty 1197797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1198797d5daeSCorey Hardesty { 1199ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1200797d5daeSCorey Hardesty *retryAttempts; 1201797d5daeSCorey Hardesty } 1202797d5daeSCorey Hardesty }); 1203797d5daeSCorey Hardesty } 1204797d5daeSCorey Hardesty 1205797d5daeSCorey Hardesty /** 12066bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12076bd5a8d2SGunnar Mills * 1208ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12096bd5a8d2SGunnar Mills * 12106bd5a8d2SGunnar Mills * @return None. 12116bd5a8d2SGunnar Mills */ 1212797d5daeSCorey Hardesty inline void 1213ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12146bd5a8d2SGunnar Mills { 121562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12166bd5a8d2SGunnar Mills 1217deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1218deae6a78SEd Tanous "xyz.openbmc_project.Settings", 12191e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12201e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1221ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1222ac106bf6SEd Tanous bool autoRebootEnabled) { 12236bd5a8d2SGunnar Mills if (ec) 12246bd5a8d2SGunnar Mills { 1225797d5daeSCorey Hardesty if (ec.value() != EBADR) 1226797d5daeSCorey Hardesty { 122762598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1228ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1229797d5daeSCorey Hardesty } 12306bd5a8d2SGunnar Mills return; 12316bd5a8d2SGunnar Mills } 12326bd5a8d2SGunnar Mills 123362598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1234e05aec50SEd Tanous if (autoRebootEnabled) 12356bd5a8d2SGunnar Mills { 1236ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12376bd5a8d2SGunnar Mills "RetryAttempts"; 12386bd5a8d2SGunnar Mills } 12396bd5a8d2SGunnar Mills else 12406bd5a8d2SGunnar Mills { 1241ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1242ac106bf6SEd Tanous "Disabled"; 12436bd5a8d2SGunnar Mills } 1244ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 124569f35306SGunnar Mills 124669f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 124769f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 124869f35306SGunnar Mills // RetryAttempts. 124920fa6a2cSEd Tanous nlohmann::json::array_t allowed; 125020fa6a2cSEd Tanous allowed.emplace_back("Disabled"); 125120fa6a2cSEd Tanous allowed.emplace_back("RetryAttempts"); 1252ac106bf6SEd Tanous asyncResp->res 1253bd79bce8SPatrick Williams .jsonValue["Boot"] 1254bd79bce8SPatrick Williams ["AutomaticRetryConfig@Redfish.AllowableValues"] = 125520fa6a2cSEd Tanous std::move(allowed); 12561e1e598dSJonathan Doman }); 12576bd5a8d2SGunnar Mills } 12586bd5a8d2SGunnar Mills 12596bd5a8d2SGunnar Mills /** 1260797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1261797d5daeSCorey Hardesty * 1262ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1263797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1264797d5daeSCorey Hardesty * 1265797d5daeSCorey Hardesty *@return None. 1266797d5daeSCorey Hardesty */ 1267797d5daeSCorey Hardesty 1268ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1269ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1270797d5daeSCorey Hardesty const uint32_t retryAttempts) 1271797d5daeSCorey Hardesty { 127262598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 127387c44966SAsmitha Karunanithi setDbusProperty( 1274e93abac6SGinu George asyncResp, "Boot/AutomaticRetryAttempts", 1275e93abac6SGinu George "xyz.openbmc_project.State.Host", 127687c44966SAsmitha Karunanithi sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"), 12779ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1278e93abac6SGinu George retryAttempts); 1279797d5daeSCorey Hardesty } 1280797d5daeSCorey Hardesty 12818d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 12828d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 12838d69c668SEd Tanous { 12848d69c668SEd Tanous if (value == 12858d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 12868d69c668SEd Tanous { 12878d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 12888d69c668SEd Tanous } 12898d69c668SEd Tanous if (value == 12908d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 12918d69c668SEd Tanous { 12928d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 12938d69c668SEd Tanous } 12948d69c668SEd Tanous if (value == 12953a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 12968d69c668SEd Tanous { 12978d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 12988d69c668SEd Tanous } 12998d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13008d69c668SEd Tanous { 13018d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13028d69c668SEd Tanous } 13038d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13048d69c668SEd Tanous } 1305797d5daeSCorey Hardesty /** 1306c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1307c6a620f2SGeorge Liu * 1308ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1309c6a620f2SGeorge Liu * 1310c6a620f2SGeorge Liu * @return None. 1311c6a620f2SGeorge Liu */ 13128d1b46d7Szhanghch05 inline void 1313ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1314c6a620f2SGeorge Liu { 131562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1316c6a620f2SGeorge Liu 1317deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 1318deae6a78SEd Tanous "xyz.openbmc_project.Settings", 13191e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13201e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1321ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13225e7e2dc5SEd Tanous const std::string& policy) { 1323c6a620f2SGeorge Liu if (ec) 1324c6a620f2SGeorge Liu { 132562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1326c6a620f2SGeorge Liu return; 1327c6a620f2SGeorge Liu } 13288d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 13298d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 13308d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1331c6a620f2SGeorge Liu { 1332ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1333c6a620f2SGeorge Liu return; 1334c6a620f2SGeorge Liu } 1335c6a620f2SGeorge Liu 13368d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 13371e1e598dSJonathan Doman }); 1338c6a620f2SGeorge Liu } 1339c6a620f2SGeorge Liu 1340c6a620f2SGeorge Liu /** 13419dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 13429dcfe8c1SAlbert Zhang * 13439dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 13449dcfe8c1SAlbert Zhang * 13459dcfe8c1SAlbert Zhang * @return None. 13469dcfe8c1SAlbert Zhang */ 13479dcfe8c1SAlbert Zhang inline void 13489dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13499dcfe8c1SAlbert Zhang { 135062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 13519dcfe8c1SAlbert Zhang 1352deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1353deae6a78SEd Tanous "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings", 13549dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 13559dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 13569dcfe8c1SAlbert Zhang if (ec) 13579dcfe8c1SAlbert Zhang { 13589dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 13599dcfe8c1SAlbert Zhang { 1360b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 13619dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 13629dcfe8c1SAlbert Zhang } 13639dcfe8c1SAlbert Zhang return; 13649dcfe8c1SAlbert Zhang } 13659dcfe8c1SAlbert Zhang 13669dcfe8c1SAlbert Zhang if (value) 13679dcfe8c1SAlbert Zhang { 1368539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1369539d8c6bSEd Tanous computer_system::StopBootOnFault::AnyFault; 13709dcfe8c1SAlbert Zhang } 13719dcfe8c1SAlbert Zhang else 13729dcfe8c1SAlbert Zhang { 1373539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1374539d8c6bSEd Tanous computer_system::StopBootOnFault::Never; 13759dcfe8c1SAlbert Zhang } 13769dcfe8c1SAlbert Zhang }); 13779dcfe8c1SAlbert Zhang } 13789dcfe8c1SAlbert Zhang 13799dcfe8c1SAlbert Zhang /** 13801981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13811981771bSAli Ahmed * TPM is required for booting the host. 13821981771bSAli Ahmed * 1383ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 13841981771bSAli Ahmed * 13851981771bSAli Ahmed * @return None. 13861981771bSAli Ahmed */ 13871981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1388ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13891981771bSAli Ahmed { 139062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1391e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1392e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1393e99073f5SGeorge Liu dbus::utility::getSubTree( 1394e99073f5SGeorge Liu "/", 0, interfaces, 1395ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1396b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 13971981771bSAli Ahmed if (ec) 13981981771bSAli Ahmed { 1399bd79bce8SPatrick Williams BMCWEB_LOG_DEBUG( 1400bd79bce8SPatrick Williams "DBUS response error on TPM.Policy GetSubTree{}", ec); 14011981771bSAli Ahmed // This is an optional D-Bus object so just return if 14021981771bSAli Ahmed // error occurs 14031981771bSAli Ahmed return; 14041981771bSAli Ahmed } 140526f6976fSEd Tanous if (subtree.empty()) 14061981771bSAli Ahmed { 14071981771bSAli Ahmed // As noted above, this is an optional interface so just return 14081981771bSAli Ahmed // if there is no instance found 14091981771bSAli Ahmed return; 14101981771bSAli Ahmed } 14111981771bSAli Ahmed 14121981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14131981771bSAli Ahmed if (subtree.size() > 1) 14141981771bSAli Ahmed { 141562598e31SEd Tanous BMCWEB_LOG_DEBUG( 141662598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 141762598e31SEd Tanous subtree.size()); 14181981771bSAli Ahmed // Throw an internal Error and return 1419ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14201981771bSAli Ahmed return; 14211981771bSAli Ahmed } 14221981771bSAli Ahmed 14231981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14241981771bSAli Ahmed // field 14251981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14261981771bSAli Ahmed { 142762598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1428ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14291981771bSAli Ahmed return; 14301981771bSAli Ahmed } 14311981771bSAli Ahmed 14321981771bSAli Ahmed const std::string& path = subtree[0].first; 14331981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14341981771bSAli Ahmed 14351981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 1436deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1437deae6a78SEd Tanous serv, path, "xyz.openbmc_project.Control.TPM.Policy", 1438deae6a78SEd Tanous "TPMEnable", 1439ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1440ac106bf6SEd Tanous bool tpmRequired) { 14418a592810SEd Tanous if (ec2) 14421981771bSAli Ahmed { 1443bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 1444bd79bce8SPatrick Williams "D-BUS response error on TPM.Policy Get{}", ec2); 1445ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14461981771bSAli Ahmed return; 14471981771bSAli Ahmed } 14481981771bSAli Ahmed 14491e1e598dSJonathan Doman if (tpmRequired) 14501981771bSAli Ahmed { 1451ac106bf6SEd Tanous asyncResp->res 1452ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14531981771bSAli Ahmed "Required"; 14541981771bSAli Ahmed } 14551981771bSAli Ahmed else 14561981771bSAli Ahmed { 1457ac106bf6SEd Tanous asyncResp->res 1458ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14591981771bSAli Ahmed "Disabled"; 14601981771bSAli Ahmed } 14611e1e598dSJonathan Doman }); 1462e99073f5SGeorge Liu }); 14631981771bSAli Ahmed } 14641981771bSAli Ahmed 14651981771bSAli Ahmed /** 14661c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14671c05dae3SAli Ahmed * TPM is required for booting the host. 14681c05dae3SAli Ahmed * 1469ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14701c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14711c05dae3SAli Ahmed * 14721c05dae3SAli Ahmed * @return None. 14731c05dae3SAli Ahmed */ 14741c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1475ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 14761c05dae3SAli Ahmed { 147762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1478e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1479e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1480e99073f5SGeorge Liu dbus::utility::getSubTree( 1481e99073f5SGeorge Liu "/", 0, interfaces, 1482ac106bf6SEd Tanous [asyncResp, 1483e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1484e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 14851c05dae3SAli Ahmed if (ec) 14861c05dae3SAli Ahmed { 1487bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 1488bd79bce8SPatrick Williams "DBUS response error on TPM.Policy GetSubTree{}", ec); 1489ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14901c05dae3SAli Ahmed return; 14911c05dae3SAli Ahmed } 149226f6976fSEd Tanous if (subtree.empty()) 14931c05dae3SAli Ahmed { 1494bd79bce8SPatrick Williams messages::propertyValueNotInList(asyncResp->res, 1495bd79bce8SPatrick Williams "ComputerSystem", 14961c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 14971c05dae3SAli Ahmed return; 14981c05dae3SAli Ahmed } 14991c05dae3SAli Ahmed 15001c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15011c05dae3SAli Ahmed if (subtree.size() > 1) 15021c05dae3SAli Ahmed { 150362598e31SEd Tanous BMCWEB_LOG_DEBUG( 150462598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 150562598e31SEd Tanous subtree.size()); 15061c05dae3SAli Ahmed // Throw an internal Error and return 1507ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15081c05dae3SAli Ahmed return; 15091c05dae3SAli Ahmed } 15101c05dae3SAli Ahmed 15111c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15121c05dae3SAli Ahmed // field 15131c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15141c05dae3SAli Ahmed { 151562598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1516ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15171c05dae3SAli Ahmed return; 15181c05dae3SAli Ahmed } 15191c05dae3SAli Ahmed 15201c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15211c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15221c05dae3SAli Ahmed 15231c05dae3SAli Ahmed if (serv.empty()) 15241c05dae3SAli Ahmed { 152562598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1526ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15271c05dae3SAli Ahmed return; 15281c05dae3SAli Ahmed } 15291c05dae3SAli Ahmed 15301c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 1531e93abac6SGinu George setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv, 1532e93abac6SGinu George path, "xyz.openbmc_project.Control.TPM.Policy", 1533e93abac6SGinu George "TPMEnable", tpmRequired); 1534e99073f5SGeorge Liu }); 15351c05dae3SAli Ahmed } 15361c05dae3SAli Ahmed 15371c05dae3SAli Ahmed /** 1538491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1539491d8ee7SSantosh Puranik * 1540ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1541cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1542cd9a4666SKonstantin Aladyshev * @return Integer error code. 1543cd9a4666SKonstantin Aladyshev */ 1544ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1545cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1546cd9a4666SKonstantin Aladyshev { 1547c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1548cd9a4666SKonstantin Aladyshev 1549c21865c4SKonstantin Aladyshev if (!bootType) 1550cd9a4666SKonstantin Aladyshev { 1551c21865c4SKonstantin Aladyshev return; 1552c21865c4SKonstantin Aladyshev } 1553c21865c4SKonstantin Aladyshev 1554cd9a4666SKonstantin Aladyshev // Source target specified 155562598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1556cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1557cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1558cd9a4666SKonstantin Aladyshev { 1559cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1560cd9a4666SKonstantin Aladyshev } 1561cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1562cd9a4666SKonstantin Aladyshev { 1563cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1564cd9a4666SKonstantin Aladyshev } 1565cd9a4666SKonstantin Aladyshev else 1566cd9a4666SKonstantin Aladyshev { 156762598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 156862598e31SEd Tanous "BootSourceOverrideMode: {}", 156962598e31SEd Tanous *bootType); 1570ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1571cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1572cd9a4666SKonstantin Aladyshev return; 1573cd9a4666SKonstantin Aladyshev } 1574cd9a4666SKonstantin Aladyshev 1575cd9a4666SKonstantin Aladyshev // Act on validated parameters 157662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1577cd9a4666SKonstantin Aladyshev 1578e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode", 1579e93abac6SGinu George "xyz.openbmc_project.Settings", 158087c44966SAsmitha Karunanithi sdbusplus::message::object_path( 158187c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 158287c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Type", "BootType", 1583e93abac6SGinu George bootTypeStr); 1584cd9a4666SKonstantin Aladyshev } 1585cd9a4666SKonstantin Aladyshev 1586cd9a4666SKonstantin Aladyshev /** 1587cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1588cd9a4666SKonstantin Aladyshev * 1589ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1590ac106bf6SEd Tanous * message. 1591c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1592c21865c4SKonstantin Aladyshev * @return Integer error code. 1593c21865c4SKonstantin Aladyshev */ 1594ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1595c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1596c21865c4SKonstantin Aladyshev { 1597c21865c4SKonstantin Aladyshev if (!bootEnable) 1598c21865c4SKonstantin Aladyshev { 1599c21865c4SKonstantin Aladyshev return; 1600c21865c4SKonstantin Aladyshev } 1601c21865c4SKonstantin Aladyshev // Source target specified 160262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1603c21865c4SKonstantin Aladyshev 1604c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1605c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1606c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1607c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1608c21865c4SKonstantin Aladyshev { 1609c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1610c21865c4SKonstantin Aladyshev } 1611c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1612c21865c4SKonstantin Aladyshev { 1613c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1614c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1615c21865c4SKonstantin Aladyshev } 1616c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1617c21865c4SKonstantin Aladyshev { 1618c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1619c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1620c21865c4SKonstantin Aladyshev } 1621c21865c4SKonstantin Aladyshev else 1622c21865c4SKonstantin Aladyshev { 162362598e31SEd Tanous BMCWEB_LOG_DEBUG( 162462598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 162562598e31SEd Tanous *bootEnable); 1626ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1627c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1628c21865c4SKonstantin Aladyshev return; 1629c21865c4SKonstantin Aladyshev } 1630c21865c4SKonstantin Aladyshev 1631c21865c4SKonstantin Aladyshev // Act on validated parameters 163262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1633c21865c4SKonstantin Aladyshev 1634e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1635e93abac6SGinu George "xyz.openbmc_project.Settings", 163687c44966SAsmitha Karunanithi sdbusplus::message::object_path( 163787c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 163887c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1639e93abac6SGinu George bootOverrideEnable); 1640c21865c4SKonstantin Aladyshev 1641c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1642c21865c4SKonstantin Aladyshev { 1643c21865c4SKonstantin Aladyshev return; 1644c21865c4SKonstantin Aladyshev } 1645c21865c4SKonstantin Aladyshev 1646c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1647c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 164862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 164962598e31SEd Tanous bootOverridePersistent); 1650c21865c4SKonstantin Aladyshev 1651e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1652e93abac6SGinu George "xyz.openbmc_project.Settings", 165387c44966SAsmitha Karunanithi sdbusplus::message::object_path( 165487c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot/one_time"), 165587c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1656e93abac6SGinu George !bootOverridePersistent); 1657c21865c4SKonstantin Aladyshev } 1658c21865c4SKonstantin Aladyshev 1659c21865c4SKonstantin Aladyshev /** 1660c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1661c21865c4SKonstantin Aladyshev * 1662ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1663491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1664491d8ee7SSantosh Puranik * 1665265c1602SJohnathan Mantey * @return Integer error code. 1666491d8ee7SSantosh Puranik */ 1667ac106bf6SEd Tanous inline void 1668ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1669cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1670491d8ee7SSantosh Puranik { 1671c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1672c21865c4SKonstantin Aladyshev std::string bootModeStr; 1673944ffaf9SJohnathan Mantey 1674c21865c4SKonstantin Aladyshev if (!bootSource) 1675491d8ee7SSantosh Puranik { 1676c21865c4SKonstantin Aladyshev return; 1677c21865c4SKonstantin Aladyshev } 1678c21865c4SKonstantin Aladyshev 1679491d8ee7SSantosh Puranik // Source target specified 168062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1681491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1682ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1683ac106bf6SEd Tanous bootModeStr) != 0) 1684491d8ee7SSantosh Puranik { 168562598e31SEd Tanous BMCWEB_LOG_DEBUG( 168662598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 168762598e31SEd Tanous *bootSource); 1688ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1689491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1690491d8ee7SSantosh Puranik return; 1691491d8ee7SSantosh Puranik } 1692491d8ee7SSantosh Puranik 1693944ffaf9SJohnathan Mantey // Act on validated parameters 169462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 169562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1696944ffaf9SJohnathan Mantey 1697e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1698e93abac6SGinu George "xyz.openbmc_project.Settings", 169987c44966SAsmitha Karunanithi sdbusplus::message::object_path( 170087c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 170187c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1702e93abac6SGinu George bootSourceStr); 1703e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1704e93abac6SGinu George "xyz.openbmc_project.Settings", 170587c44966SAsmitha Karunanithi sdbusplus::message::object_path( 170687c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 170787c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1708e93abac6SGinu George bootModeStr); 1709cd9a4666SKonstantin Aladyshev } 1710944ffaf9SJohnathan Mantey 1711cd9a4666SKonstantin Aladyshev /** 1712c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1713491d8ee7SSantosh Puranik * 1714ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1715491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1716cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1717491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1718491d8ee7SSantosh Puranik * 1719265c1602SJohnathan Mantey * @return Integer error code. 1720491d8ee7SSantosh Puranik */ 1721c21865c4SKonstantin Aladyshev 1722ac106bf6SEd Tanous inline void 1723ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1724c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1725c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1726c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1727491d8ee7SSantosh Puranik { 172862598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1729491d8ee7SSantosh Puranik 1730ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1731ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1732ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1733491d8ee7SSantosh Puranik } 1734491d8ee7SSantosh Puranik 1735c6a620f2SGeorge Liu /** 173698e386ecSGunnar Mills * @brief Sets AssetTag 173798e386ecSGunnar Mills * 1738ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 173998e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 174098e386ecSGunnar Mills * 174198e386ecSGunnar Mills * @return None. 174298e386ecSGunnar Mills */ 1743ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 174498e386ecSGunnar Mills const std::string& assetTag) 174598e386ecSGunnar Mills { 1746e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1747e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1748e99073f5SGeorge Liu dbus::utility::getSubTree( 1749e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1750ac106bf6SEd Tanous [asyncResp, 1751e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1752b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 175398e386ecSGunnar Mills if (ec) 175498e386ecSGunnar Mills { 175562598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1756ac106bf6SEd Tanous messages::internalError(asyncResp->res); 175798e386ecSGunnar Mills return; 175898e386ecSGunnar Mills } 175926f6976fSEd Tanous if (subtree.empty()) 176098e386ecSGunnar Mills { 176162598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1762ac106bf6SEd Tanous messages::internalError(asyncResp->res); 176398e386ecSGunnar Mills return; 176498e386ecSGunnar Mills } 176598e386ecSGunnar Mills // Assume only 1 system D-Bus object 176698e386ecSGunnar Mills // Throw an error if there is more than 1 176798e386ecSGunnar Mills if (subtree.size() > 1) 176898e386ecSGunnar Mills { 176962598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1770ac106bf6SEd Tanous messages::internalError(asyncResp->res); 177198e386ecSGunnar Mills return; 177298e386ecSGunnar Mills } 177398e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 177498e386ecSGunnar Mills { 177562598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1776ac106bf6SEd Tanous messages::internalError(asyncResp->res); 177798e386ecSGunnar Mills return; 177898e386ecSGunnar Mills } 177998e386ecSGunnar Mills 178098e386ecSGunnar Mills const std::string& path = subtree[0].first; 178198e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 178298e386ecSGunnar Mills 178398e386ecSGunnar Mills if (service.empty()) 178498e386ecSGunnar Mills { 178562598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1786ac106bf6SEd Tanous messages::internalError(asyncResp->res); 178798e386ecSGunnar Mills return; 178898e386ecSGunnar Mills } 178998e386ecSGunnar Mills 1790e93abac6SGinu George setDbusProperty(asyncResp, "AssetTag", service, path, 179187c44966SAsmitha Karunanithi "xyz.openbmc_project.Inventory.Decorator.AssetTag", 1792e93abac6SGinu George "AssetTag", assetTag); 1793e99073f5SGeorge Liu }); 179498e386ecSGunnar Mills } 179598e386ecSGunnar Mills 179698e386ecSGunnar Mills /** 17979dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 17989dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 17999dcfe8c1SAlbert Zhang * 18009dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 18019dcfe8c1SAlbert Zhang * stopBootOnFault 18029dcfe8c1SAlbert Zhang * 18039dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 18049dcfe8c1SAlbert Zhang */ 18059dcfe8c1SAlbert Zhang inline std::optional<bool> 18069dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 18079dcfe8c1SAlbert Zhang { 18089dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 18099dcfe8c1SAlbert Zhang { 18109dcfe8c1SAlbert Zhang return true; 18119dcfe8c1SAlbert Zhang } 18129dcfe8c1SAlbert Zhang 18139dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 18149dcfe8c1SAlbert Zhang { 18159dcfe8c1SAlbert Zhang return false; 18169dcfe8c1SAlbert Zhang } 18179dcfe8c1SAlbert Zhang 18189dcfe8c1SAlbert Zhang return std::nullopt; 18199dcfe8c1SAlbert Zhang } 18209dcfe8c1SAlbert Zhang 18219dcfe8c1SAlbert Zhang /** 18229dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 18239dcfe8c1SAlbert Zhang * 1824fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 18259dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 18269dcfe8c1SAlbert Zhang * 18279dcfe8c1SAlbert Zhang * @return None. 18289dcfe8c1SAlbert Zhang */ 1829fc3edfddSEd Tanous inline void 1830fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 18319dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 18329dcfe8c1SAlbert Zhang { 183362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 18349dcfe8c1SAlbert Zhang 18359dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 18369dcfe8c1SAlbert Zhang if (!stopBootEnabled) 18379dcfe8c1SAlbert Zhang { 183862598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 183962598e31SEd Tanous stopBootOnFault); 1840fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 18419dcfe8c1SAlbert Zhang "StopBootOnFault"); 18429dcfe8c1SAlbert Zhang return; 18439dcfe8c1SAlbert Zhang } 18449dcfe8c1SAlbert Zhang 1845e93abac6SGinu George setDbusProperty(asyncResp, "Boot/StopBootOnFault", 1846e93abac6SGinu George "xyz.openbmc_project.Settings", 184787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 184887c44966SAsmitha Karunanithi "/xyz/openbmc_project/logging/settings"), 1849fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1850e93abac6SGinu George *stopBootEnabled); 18519dcfe8c1SAlbert Zhang } 18529dcfe8c1SAlbert Zhang 18539dcfe8c1SAlbert Zhang /** 185469f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 185569f35306SGunnar Mills * 1856ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 185769f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 185869f35306SGunnar Mills * 185969f35306SGunnar Mills * @return None. 186069f35306SGunnar Mills */ 1861ac106bf6SEd Tanous inline void 1862ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1863f23b7296SEd Tanous const std::string& automaticRetryConfig) 186469f35306SGunnar Mills { 186562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 186669f35306SGunnar Mills 186769f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1868543f4400SEd Tanous bool autoRebootEnabled = false; 186969f35306SGunnar Mills 187069f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 187169f35306SGunnar Mills { 187269f35306SGunnar Mills autoRebootEnabled = false; 187369f35306SGunnar Mills } 187469f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 187569f35306SGunnar Mills { 187669f35306SGunnar Mills autoRebootEnabled = true; 187769f35306SGunnar Mills } 187869f35306SGunnar Mills else 187969f35306SGunnar Mills { 188062598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 188162598e31SEd Tanous automaticRetryConfig); 1882ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 188369f35306SGunnar Mills "AutomaticRetryConfig"); 188469f35306SGunnar Mills return; 188569f35306SGunnar Mills } 188669f35306SGunnar Mills 1887e93abac6SGinu George setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig", 1888e93abac6SGinu George "xyz.openbmc_project.Settings", 188987c44966SAsmitha Karunanithi sdbusplus::message::object_path( 189087c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/auto_reboot"), 189187c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.RebootPolicy", 1892e93abac6SGinu George "AutoReboot", autoRebootEnabled); 189369f35306SGunnar Mills } 189469f35306SGunnar Mills 18958d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 18968d69c668SEd Tanous { 18978d69c668SEd Tanous if (policy == "AlwaysOn") 18988d69c668SEd Tanous { 18998d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 19008d69c668SEd Tanous } 19018d69c668SEd Tanous if (policy == "AlwaysOff") 19028d69c668SEd Tanous { 19038d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 19048d69c668SEd Tanous } 19058d69c668SEd Tanous if (policy == "LastState") 19068d69c668SEd Tanous { 19078d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 19088d69c668SEd Tanous } 19098d69c668SEd Tanous return ""; 19108d69c668SEd Tanous } 19118d69c668SEd Tanous 191269f35306SGunnar Mills /** 1913c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1914c6a620f2SGeorge Liu * 1915ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1916c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1917c6a620f2SGeorge Liu * 1918c6a620f2SGeorge Liu * @return None. 1919c6a620f2SGeorge Liu */ 19208d1b46d7Szhanghch05 inline void 1921ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19228d69c668SEd Tanous std::string_view policy) 1923c6a620f2SGeorge Liu { 192462598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 1925c6a620f2SGeorge Liu 19268d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 1927c6a620f2SGeorge Liu 19288d69c668SEd Tanous if (powerRestorePolicy.empty()) 1929c6a620f2SGeorge Liu { 1930ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 19314e69c904SGunnar Mills "PowerRestorePolicy"); 1932c6a620f2SGeorge Liu return; 1933c6a620f2SGeorge Liu } 1934c6a620f2SGeorge Liu 193587c44966SAsmitha Karunanithi setDbusProperty( 1936e93abac6SGinu George asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings", 193787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 193887c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/power_restore_policy"), 19399ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1940e93abac6SGinu George powerRestorePolicy); 1941c6a620f2SGeorge Liu } 1942c6a620f2SGeorge Liu 1943a6349918SAppaRao Puli /** 1944a6349918SAppaRao Puli * @brief Retrieves provisioning status 1945a6349918SAppaRao Puli * 194625b54dbaSEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous 194725b54dbaSEd Tanous * calls. 1948a6349918SAppaRao Puli * 1949a6349918SAppaRao Puli * @return None. 1950a6349918SAppaRao Puli */ 195125b54dbaSEd Tanous inline void 195225b54dbaSEd Tanous getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1953a6349918SAppaRao Puli { 195462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 1955deae6a78SEd Tanous dbus::utility::getAllProperties( 1956deae6a78SEd Tanous "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr", 1957deae6a78SEd Tanous "xyz.openbmc_project.PFR.Attributes", 1958ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1959b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1960b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1961bd79bce8SPatrick Williams asyncResp->res 1962bd79bce8SPatrick Williams .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 1963ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 19641d834d49SEd Tanous "#OpenBMCComputerSystem.v1_0_0.OpenBmc"; 1965bd79bce8SPatrick Williams oemPFR["@odata.type"] = 1966bd79bce8SPatrick Williams "#OpenBMCComputerSystem.FirmwareProvisioning"; 196750626f4fSJames Feist 1968a6349918SAppaRao Puli if (ec) 1969a6349918SAppaRao Puli { 197062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1971b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1972539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 1973539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 1974a6349918SAppaRao Puli return; 1975a6349918SAppaRao Puli } 1976a6349918SAppaRao Puli 1977a6349918SAppaRao Puli const bool* provState = nullptr; 1978a6349918SAppaRao Puli const bool* lockState = nullptr; 1979bc1d29deSKrzysztof Grobelny 1980bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 1981bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), propertiesList, 1982bd79bce8SPatrick Williams "UfmProvisioned", provState, "UfmLocked", lockState); 1983bc1d29deSKrzysztof Grobelny 1984bc1d29deSKrzysztof Grobelny if (!success) 1985a6349918SAppaRao Puli { 1986ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1987bc1d29deSKrzysztof Grobelny return; 1988a6349918SAppaRao Puli } 1989a6349918SAppaRao Puli 1990a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 1991a6349918SAppaRao Puli { 199262598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 1993ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1994a6349918SAppaRao Puli return; 1995a6349918SAppaRao Puli } 1996a6349918SAppaRao Puli 199725b54dbaSEd Tanous if (*provState) 1998a6349918SAppaRao Puli { 199925b54dbaSEd Tanous if (*lockState) 2000a6349918SAppaRao Puli { 2001539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2002539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedAndLocked; 2003a6349918SAppaRao Puli } 2004a6349918SAppaRao Puli else 2005a6349918SAppaRao Puli { 2006539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2007539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedButNotLocked; 2008a6349918SAppaRao Puli } 2009a6349918SAppaRao Puli } 2010a6349918SAppaRao Puli else 2011a6349918SAppaRao Puli { 2012539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2013539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 2014a6349918SAppaRao Puli } 2015bc1d29deSKrzysztof Grobelny }); 2016a6349918SAppaRao Puli } 2017a6349918SAppaRao Puli 2018491d8ee7SSantosh Puranik /** 20196b9ac4f2SChris Cain * @brief Translate the PowerMode string to enum value 20203a2d0424SChris Cain * 20216b9ac4f2SChris Cain * @param[in] modeString PowerMode string to be translated 20223a2d0424SChris Cain * 20236b9ac4f2SChris Cain * @return PowerMode enum 20243a2d0424SChris Cain */ 20256b9ac4f2SChris Cain inline computer_system::PowerMode 20266b9ac4f2SChris Cain translatePowerModeString(const std::string& modeString) 20273a2d0424SChris Cain { 2028b6655101SChris Cain using PowerMode = computer_system::PowerMode; 2029b6655101SChris Cain 20306b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20313a2d0424SChris Cain { 20326b9ac4f2SChris Cain return PowerMode::Static; 20333a2d0424SChris Cain } 20346b9ac4f2SChris Cain if (modeString == 20350fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20363a2d0424SChris Cain { 20376b9ac4f2SChris Cain return PowerMode::MaximumPerformance; 20383a2d0424SChris Cain } 20396b9ac4f2SChris Cain if (modeString == 20400fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20413a2d0424SChris Cain { 20426b9ac4f2SChris Cain return PowerMode::PowerSaving; 2043b6655101SChris Cain } 20446b9ac4f2SChris Cain if (modeString == 2045b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance") 2046b6655101SChris Cain { 20476b9ac4f2SChris Cain return PowerMode::BalancedPerformance; 2048b6655101SChris Cain } 20496b9ac4f2SChris Cain if (modeString == 2050b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance") 2051b6655101SChris Cain { 20526b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPerformance; 2053b6655101SChris Cain } 20546b9ac4f2SChris Cain if (modeString == 2055b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower") 2056b6655101SChris Cain { 20576b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPower; 20583a2d0424SChris Cain } 20596b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20603a2d0424SChris Cain { 20616b9ac4f2SChris Cain return PowerMode::OEM; 20626b9ac4f2SChris Cain } 20636b9ac4f2SChris Cain // Any other values would be invalid 20646b9ac4f2SChris Cain BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString); 20656b9ac4f2SChris Cain return PowerMode::Invalid; 20666b9ac4f2SChris Cain } 20676b9ac4f2SChris Cain 20686b9ac4f2SChris Cain inline void 20696b9ac4f2SChris Cain afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20706b9ac4f2SChris Cain const boost::system::error_code& ec, 20716b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) 20726b9ac4f2SChris Cain { 20736b9ac4f2SChris Cain if (ec) 20746b9ac4f2SChris Cain { 20756b9ac4f2SChris Cain BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec); 20766b9ac4f2SChris Cain messages::internalError(asyncResp->res); 20776b9ac4f2SChris Cain return; 20786b9ac4f2SChris Cain } 20796b9ac4f2SChris Cain 20806b9ac4f2SChris Cain std::string powerMode; 20816b9ac4f2SChris Cain const std::vector<std::string>* allowedModes = nullptr; 20826b9ac4f2SChris Cain const bool success = sdbusplus::unpackPropertiesNoThrow( 20836b9ac4f2SChris Cain dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode, 20846b9ac4f2SChris Cain "AllowedPowerModes", allowedModes); 20856b9ac4f2SChris Cain 20866b9ac4f2SChris Cain if (!success) 20876b9ac4f2SChris Cain { 20886b9ac4f2SChris Cain messages::internalError(asyncResp->res); 20896b9ac4f2SChris Cain return; 20906b9ac4f2SChris Cain } 20916b9ac4f2SChris Cain 20926b9ac4f2SChris Cain nlohmann::json::array_t modeList; 20936b9ac4f2SChris Cain if (allowedModes == nullptr) 20946b9ac4f2SChris Cain { 20956b9ac4f2SChris Cain modeList.emplace_back("Static"); 20966b9ac4f2SChris Cain modeList.emplace_back("MaximumPerformance"); 20976b9ac4f2SChris Cain modeList.emplace_back("PowerSaving"); 20983a2d0424SChris Cain } 20993a2d0424SChris Cain else 21003a2d0424SChris Cain { 21016b9ac4f2SChris Cain for (const auto& aMode : *allowedModes) 21026b9ac4f2SChris Cain { 21036b9ac4f2SChris Cain computer_system::PowerMode modeValue = 21046b9ac4f2SChris Cain translatePowerModeString(aMode); 21056b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21066b9ac4f2SChris Cain { 2107ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21086b9ac4f2SChris Cain continue; 21096b9ac4f2SChris Cain } 21106b9ac4f2SChris Cain modeList.emplace_back(modeValue); 21113a2d0424SChris Cain } 21123a2d0424SChris Cain } 21136b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList; 21143a2d0424SChris Cain 21156b9ac4f2SChris Cain BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode); 21166b9ac4f2SChris Cain const computer_system::PowerMode modeValue = 21176b9ac4f2SChris Cain translatePowerModeString(powerMode); 21186b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21196b9ac4f2SChris Cain { 21206b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21216b9ac4f2SChris Cain return; 21226b9ac4f2SChris Cain } 21236b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode"] = modeValue; 21246b9ac4f2SChris Cain } 21253a2d0424SChris Cain /** 21263a2d0424SChris Cain * @brief Retrieves system power mode 21273a2d0424SChris Cain * 2128ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21293a2d0424SChris Cain * 21303a2d0424SChris Cain * @return None. 21313a2d0424SChris Cain */ 2132ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 21333a2d0424SChris Cain { 213462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 21353a2d0424SChris Cain 21363a2d0424SChris Cain // Get Power Mode object path: 2137e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2138e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2139e99073f5SGeorge Liu dbus::utility::getSubTree( 2140e99073f5SGeorge Liu "/", 0, interfaces, 2141ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2142b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21433a2d0424SChris Cain if (ec) 21443a2d0424SChris Cain { 2145bd79bce8SPatrick Williams BMCWEB_LOG_DEBUG( 2146bd79bce8SPatrick Williams "DBUS response error on Power.Mode GetSubTree {}", ec); 21473a2d0424SChris Cain // This is an optional D-Bus object so just return if 21483a2d0424SChris Cain // error occurs 21493a2d0424SChris Cain return; 21503a2d0424SChris Cain } 21513a2d0424SChris Cain if (subtree.empty()) 21523a2d0424SChris Cain { 21533a2d0424SChris Cain // As noted above, this is an optional interface so just return 21543a2d0424SChris Cain // if there is no instance found 21553a2d0424SChris Cain return; 21563a2d0424SChris Cain } 21573a2d0424SChris Cain if (subtree.size() > 1) 21583a2d0424SChris Cain { 21593a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21603a2d0424SChris Cain // error 216162598e31SEd Tanous BMCWEB_LOG_DEBUG( 216262598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 216362598e31SEd Tanous subtree.size()); 2164ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21653a2d0424SChris Cain return; 21663a2d0424SChris Cain } 21673a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21683a2d0424SChris Cain { 216962598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2170ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21713a2d0424SChris Cain return; 21723a2d0424SChris Cain } 21733a2d0424SChris Cain const std::string& path = subtree[0].first; 21743a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21753a2d0424SChris Cain if (service.empty()) 21763a2d0424SChris Cain { 217762598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2178ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21793a2d0424SChris Cain return; 21803a2d0424SChris Cain } 21816b9ac4f2SChris Cain 21826b9ac4f2SChris Cain // Valid Power Mode object found, now read the mode properties 2183deae6a78SEd Tanous dbus::utility::getAllProperties( 21841e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 21856b9ac4f2SChris Cain "xyz.openbmc_project.Control.Power.Mode", 2186bd79bce8SPatrick Williams [asyncResp]( 2187bd79bce8SPatrick Williams const boost::system::error_code& ec2, 21886b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 21896b9ac4f2SChris Cain afterGetPowerMode(asyncResp, ec2, properties); 21901e1e598dSJonathan Doman }); 2191e99073f5SGeorge Liu }); 21923a2d0424SChris Cain } 21933a2d0424SChris Cain 21943a2d0424SChris Cain /** 21953a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21963a2d0424SChris Cain * name associated with that string 21973a2d0424SChris Cain * 2198ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2199b6655101SChris Cain * @param[in] modeValue String representing the desired PowerMode 22003a2d0424SChris Cain * 22013a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22023a2d0424SChris Cain */ 22033a2d0424SChris Cain inline std::string 2204ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2205b6655101SChris Cain const nlohmann::json& modeValue) 22063a2d0424SChris Cain { 2207b6655101SChris Cain using PowerMode = computer_system::PowerMode; 22083a2d0424SChris Cain std::string mode; 22093a2d0424SChris Cain 2210b6655101SChris Cain if (modeValue == PowerMode::Static) 22113a2d0424SChris Cain { 22123a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22133a2d0424SChris Cain } 2214b6655101SChris Cain else if (modeValue == PowerMode::MaximumPerformance) 22153a2d0424SChris Cain { 22160fda0f12SGeorge Liu mode = 22170fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 22183a2d0424SChris Cain } 2219b6655101SChris Cain else if (modeValue == PowerMode::PowerSaving) 22203a2d0424SChris Cain { 22213a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22223a2d0424SChris Cain } 2223b6655101SChris Cain else if (modeValue == PowerMode::BalancedPerformance) 2224b6655101SChris Cain { 2225b6655101SChris Cain mode = 2226b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance"; 2227b6655101SChris Cain } 2228b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPerformance) 2229b6655101SChris Cain { 2230b6655101SChris Cain mode = 2231b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance"; 2232b6655101SChris Cain } 2233b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPower) 2234b6655101SChris Cain { 2235b6655101SChris Cain mode = 2236b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower"; 2237b6655101SChris Cain } 22383a2d0424SChris Cain else 22393a2d0424SChris Cain { 2240b6655101SChris Cain messages::propertyValueNotInList(asyncResp->res, modeValue.dump(), 2241ac106bf6SEd Tanous "PowerMode"); 22423a2d0424SChris Cain } 22433a2d0424SChris Cain return mode; 22443a2d0424SChris Cain } 22453a2d0424SChris Cain 22463a2d0424SChris Cain /** 22473a2d0424SChris Cain * @brief Sets system power mode. 22483a2d0424SChris Cain * 2249ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22503a2d0424SChris Cain * @param[in] pmode System power mode from request. 22513a2d0424SChris Cain * 22523a2d0424SChris Cain * @return None. 22533a2d0424SChris Cain */ 2254ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22553a2d0424SChris Cain const std::string& pmode) 22563a2d0424SChris Cain { 225762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 22583a2d0424SChris Cain 2259ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 22603a2d0424SChris Cain if (powerMode.empty()) 22613a2d0424SChris Cain { 22623a2d0424SChris Cain return; 22633a2d0424SChris Cain } 22643a2d0424SChris Cain 22653a2d0424SChris Cain // Get Power Mode object path: 2266e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2267e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2268e99073f5SGeorge Liu dbus::utility::getSubTree( 2269e99073f5SGeorge Liu "/", 0, interfaces, 2270ac106bf6SEd Tanous [asyncResp, 2271e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2272b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22733a2d0424SChris Cain if (ec) 22743a2d0424SChris Cain { 2275bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 2276bd79bce8SPatrick Williams "DBUS response error on Power.Mode GetSubTree {}", ec); 22773a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2278ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22793a2d0424SChris Cain return; 22803a2d0424SChris Cain } 22813a2d0424SChris Cain if (subtree.empty()) 22823a2d0424SChris Cain { 22833a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2284ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 22853a2d0424SChris Cain "PowerMode"); 22863a2d0424SChris Cain return; 22873a2d0424SChris Cain } 22883a2d0424SChris Cain if (subtree.size() > 1) 22893a2d0424SChris Cain { 22903a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22913a2d0424SChris Cain // error 229262598e31SEd Tanous BMCWEB_LOG_DEBUG( 229362598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 229462598e31SEd Tanous subtree.size()); 2295ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22963a2d0424SChris Cain return; 22973a2d0424SChris Cain } 22983a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22993a2d0424SChris Cain { 230062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2301ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23023a2d0424SChris Cain return; 23033a2d0424SChris Cain } 23043a2d0424SChris Cain const std::string& path = subtree[0].first; 23053a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23063a2d0424SChris Cain if (service.empty()) 23073a2d0424SChris Cain { 230862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2309ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23103a2d0424SChris Cain return; 23113a2d0424SChris Cain } 23123a2d0424SChris Cain 231362598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 23143a2d0424SChris Cain 23153a2d0424SChris Cain // Set the Power Mode property 2316e93abac6SGinu George setDbusProperty(asyncResp, "PowerMode", service, path, 2317bd79bce8SPatrick Williams "xyz.openbmc_project.Control.Power.Mode", 2318bd79bce8SPatrick Williams "PowerMode", powerMode); 2319e99073f5SGeorge Liu }); 23203a2d0424SChris Cain } 23213a2d0424SChris Cain 23223a2d0424SChris Cain /** 232351709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 232451709ffdSYong Li * 232551709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 232651709ffdSYong Li * 232751709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 232851709ffdSYong Li * translation cannot be done, returns an empty string. 232951709ffdSYong Li */ 233023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 233151709ffdSYong Li { 233251709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 233351709ffdSYong Li { 233451709ffdSYong Li return "None"; 233551709ffdSYong Li } 23363174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 233751709ffdSYong Li { 233851709ffdSYong Li return "ResetSystem"; 233951709ffdSYong Li } 23403174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 234151709ffdSYong Li { 234251709ffdSYong Li return "PowerDown"; 234351709ffdSYong Li } 23443174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 234551709ffdSYong Li { 234651709ffdSYong Li return "PowerCycle"; 234751709ffdSYong Li } 234851709ffdSYong Li 234951709ffdSYong Li return ""; 235051709ffdSYong Li } 235151709ffdSYong Li 235251709ffdSYong Li /** 2353c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2354c45f0082SYong Li * 2355c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2356c45f0082SYong Li * 2357c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2358c45f0082SYong Li *If translation cannot be done, returns an empty string. 2359c45f0082SYong Li */ 2360c45f0082SYong Li 236123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2362c45f0082SYong Li { 2363c45f0082SYong Li if (rfAction == "None") 2364c45f0082SYong Li { 2365c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2366c45f0082SYong Li } 23673174e4dfSEd Tanous if (rfAction == "PowerCycle") 2368c45f0082SYong Li { 2369c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2370c45f0082SYong Li } 23713174e4dfSEd Tanous if (rfAction == "PowerDown") 2372c45f0082SYong Li { 2373c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2374c45f0082SYong Li } 23753174e4dfSEd Tanous if (rfAction == "ResetSystem") 2376c45f0082SYong Li { 2377c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2378c45f0082SYong Li } 2379c45f0082SYong Li 2380c45f0082SYong Li return ""; 2381c45f0082SYong Li } 2382c45f0082SYong Li 2383c45f0082SYong Li /** 238451709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 238551709ffdSYong Li * 2386ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 238751709ffdSYong Li * 238851709ffdSYong Li * @return None. 238951709ffdSYong Li */ 23908d1b46d7Szhanghch05 inline void 2391ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 239251709ffdSYong Li { 239362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2394deae6a78SEd Tanous dbus::utility::getAllProperties( 2395deae6a78SEd Tanous "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0", 2396bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2397ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2398b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 239951709ffdSYong Li if (ec) 240051709ffdSYong Li { 240151709ffdSYong Li // watchdog service is stopped 240262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 240351709ffdSYong Li return; 240451709ffdSYong Li } 240551709ffdSYong Li 240662598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 240751709ffdSYong Li 240851709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2409ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 241051709ffdSYong Li 241151709ffdSYong Li // watchdog service is running/enabled 2412539d8c6bSEd Tanous hostWatchdogTimer["Status"]["State"] = resource::State::Enabled; 241351709ffdSYong Li 2414bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2415bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 241651709ffdSYong Li 2417bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2418bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), properties, "Enabled", 2419bd79bce8SPatrick Williams enabled, "ExpireAction", expireAction); 2420bc1d29deSKrzysztof Grobelny 2421bc1d29deSKrzysztof Grobelny if (!success) 242251709ffdSYong Li { 2423ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2424601af5edSChicago Duan return; 242551709ffdSYong Li } 242651709ffdSYong Li 2427bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 242851709ffdSYong Li { 2429bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 243051709ffdSYong Li } 243151709ffdSYong Li 2432bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2433bc1d29deSKrzysztof Grobelny { 2434bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 243551709ffdSYong Li if (action.empty()) 243651709ffdSYong Li { 2437ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2438601af5edSChicago Duan return; 243951709ffdSYong Li } 244051709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 244151709ffdSYong Li } 2442bc1d29deSKrzysztof Grobelny }); 244351709ffdSYong Li } 244451709ffdSYong Li 244551709ffdSYong Li /** 2446c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2447c45f0082SYong Li * 2448ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2449c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2450c45f0082SYong Li * RF request. 2451c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2452c45f0082SYong Li * 2453c45f0082SYong Li * @return None. 2454c45f0082SYong Li */ 2455ac106bf6SEd Tanous inline void 2456ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2457c45f0082SYong Li const std::optional<bool> wdtEnable, 2458c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2459c45f0082SYong Li { 246062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2461c45f0082SYong Li 2462c45f0082SYong Li if (wdtTimeOutAction) 2463c45f0082SYong Li { 2464c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2465c45f0082SYong Li // check if TimeOut Action is Valid 2466c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2467c45f0082SYong Li { 246862598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 246962598e31SEd Tanous *wdtTimeOutAction); 2470ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2471c45f0082SYong Li "TimeoutAction"); 2472c45f0082SYong Li return; 2473c45f0082SYong Li } 2474c45f0082SYong Li 2475e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction", 2476e93abac6SGinu George "xyz.openbmc_project.Watchdog", 247787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 247887c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 24799ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2480e93abac6SGinu George wdtTimeOutActStr); 2481c45f0082SYong Li } 2482c45f0082SYong Li 2483c45f0082SYong Li if (wdtEnable) 2484c45f0082SYong Li { 2485e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled", 2486e93abac6SGinu George "xyz.openbmc_project.Watchdog", 248787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 248887c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 248987c44966SAsmitha Karunanithi "xyz.openbmc_project.State.Watchdog", "Enabled", 2490e93abac6SGinu George *wdtEnable); 2491c45f0082SYong Li } 2492c45f0082SYong Li } 2493c45f0082SYong Li 249437bbf98cSChris Cain /** 249537bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 249637bbf98cSChris Cain * 2497ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 249837bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 249937bbf98cSChris Cain * 250037bbf98cSChris Cain * @return true if successful 250137bbf98cSChris Cain */ 25021e5b7c88SJiaqing Zhao inline bool 2503ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25041e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 250537bbf98cSChris Cain { 2506bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2507bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2508bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2509bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2510bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2511bc1d29deSKrzysztof Grobelny 2512bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2513bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 25142661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 25152661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 25162661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2517bc1d29deSKrzysztof Grobelny 2518bc1d29deSKrzysztof Grobelny if (!success) 251937bbf98cSChris Cain { 252037bbf98cSChris Cain return false; 252137bbf98cSChris Cain } 2522bc1d29deSKrzysztof Grobelny 2523bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 252437bbf98cSChris Cain { 2525ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 252637bbf98cSChris Cain } 2527bc1d29deSKrzysztof Grobelny 2528bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 252937bbf98cSChris Cain { 2530ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2531bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 253237bbf98cSChris Cain } 2533bc1d29deSKrzysztof Grobelny 2534bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2535bc1d29deSKrzysztof Grobelny { 2536bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2537ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 253837bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 253937bbf98cSChris Cain .count(); 254037bbf98cSChris Cain } 2541bc1d29deSKrzysztof Grobelny 2542bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 254337bbf98cSChris Cain { 2544ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2545bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 254637bbf98cSChris Cain } 2547bc1d29deSKrzysztof Grobelny 2548bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 254937bbf98cSChris Cain { 2550bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2551ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 255237bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 255337bbf98cSChris Cain .count(); 255437bbf98cSChris Cain } 255537bbf98cSChris Cain 255637bbf98cSChris Cain return true; 255737bbf98cSChris Cain } 255837bbf98cSChris Cain 255937bbf98cSChris Cain /** 256037bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 256137bbf98cSChris Cain * 2562ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 256337bbf98cSChris Cain * 256437bbf98cSChris Cain * @return None. 256537bbf98cSChris Cain */ 2566ac106bf6SEd Tanous inline void 2567ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 256837bbf98cSChris Cain { 256962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 257037bbf98cSChris Cain 257137bbf98cSChris Cain // Get IdlePowerSaver object path: 2572e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2573e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2574e99073f5SGeorge Liu dbus::utility::getSubTree( 2575e99073f5SGeorge Liu "/", 0, interfaces, 2576ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2577b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 257837bbf98cSChris Cain if (ec) 257937bbf98cSChris Cain { 2580b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 258162598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 258262598e31SEd Tanous ec); 2583ac106bf6SEd Tanous messages::internalError(asyncResp->res); 258437bbf98cSChris Cain return; 258537bbf98cSChris Cain } 258637bbf98cSChris Cain if (subtree.empty()) 258737bbf98cSChris Cain { 258837bbf98cSChris Cain // This is an optional interface so just return 258937bbf98cSChris Cain // if there is no instance found 259062598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 259137bbf98cSChris Cain return; 259237bbf98cSChris Cain } 259337bbf98cSChris Cain if (subtree.size() > 1) 259437bbf98cSChris Cain { 259537bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 259637bbf98cSChris Cain // is an error 259762598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 259862598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 259962598e31SEd Tanous subtree.size()); 2600ac106bf6SEd Tanous messages::internalError(asyncResp->res); 260137bbf98cSChris Cain return; 260237bbf98cSChris Cain } 260337bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 260437bbf98cSChris Cain { 260562598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2606ac106bf6SEd Tanous messages::internalError(asyncResp->res); 260737bbf98cSChris Cain return; 260837bbf98cSChris Cain } 260937bbf98cSChris Cain const std::string& path = subtree[0].first; 261037bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 261137bbf98cSChris Cain if (service.empty()) 261237bbf98cSChris Cain { 261362598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2614ac106bf6SEd Tanous messages::internalError(asyncResp->res); 261537bbf98cSChris Cain return; 261637bbf98cSChris Cain } 261737bbf98cSChris Cain 261837bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2619deae6a78SEd Tanous dbus::utility::getAllProperties( 2620bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2621bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2622bd79bce8SPatrick Williams [asyncResp]( 2623bd79bce8SPatrick Williams const boost::system::error_code& ec2, 26241e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 26258a592810SEd Tanous if (ec2) 262637bbf98cSChris Cain { 262762598e31SEd Tanous BMCWEB_LOG_ERROR( 2628bd79bce8SPatrick Williams "DBUS response error on IdlePowerSaver GetAll: {}", 2629bd79bce8SPatrick Williams ec2); 2630ac106bf6SEd Tanous messages::internalError(asyncResp->res); 263137bbf98cSChris Cain return; 263237bbf98cSChris Cain } 263337bbf98cSChris Cain 2634ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 263537bbf98cSChris Cain { 2636ac106bf6SEd Tanous messages::internalError(asyncResp->res); 263737bbf98cSChris Cain return; 263837bbf98cSChris Cain } 2639bc1d29deSKrzysztof Grobelny }); 2640e99073f5SGeorge Liu }); 264137bbf98cSChris Cain 264262598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 264337bbf98cSChris Cain } 264437bbf98cSChris Cain 264537bbf98cSChris Cain /** 264637bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 264737bbf98cSChris Cain * 2648ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 264937bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 265037bbf98cSChris Cain * RF request. 265137bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 265237bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 265337bbf98cSChris Cain * before entering idle state. 265437bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 265537bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 265637bbf98cSChris Cain * before exiting idle state 265737bbf98cSChris Cain * 265837bbf98cSChris Cain * @return None. 265937bbf98cSChris Cain */ 2660bd79bce8SPatrick Williams inline void setIdlePowerSaver( 2661bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 266237bbf98cSChris Cain const std::optional<bool> ipsEnable, 266337bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 266437bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 266537bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 266637bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 266737bbf98cSChris Cain { 266862598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 266937bbf98cSChris Cain 267037bbf98cSChris Cain // Get IdlePowerSaver object path: 2671e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2672e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2673e99073f5SGeorge Liu dbus::utility::getSubTree( 2674e99073f5SGeorge Liu "/", 0, interfaces, 2675ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2676e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2677b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 267837bbf98cSChris Cain if (ec) 267937bbf98cSChris Cain { 2680b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 268162598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 268262598e31SEd Tanous ec); 2683ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268437bbf98cSChris Cain return; 268537bbf98cSChris Cain } 268637bbf98cSChris Cain if (subtree.empty()) 268737bbf98cSChris Cain { 268837bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2689ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 269037bbf98cSChris Cain "IdlePowerSaver"); 269137bbf98cSChris Cain return; 269237bbf98cSChris Cain } 269337bbf98cSChris Cain if (subtree.size() > 1) 269437bbf98cSChris Cain { 269537bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 269637bbf98cSChris Cain // is an error 269762598e31SEd Tanous BMCWEB_LOG_DEBUG( 269862598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 269962598e31SEd Tanous subtree.size()); 2700ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270137bbf98cSChris Cain return; 270237bbf98cSChris Cain } 270337bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 270437bbf98cSChris Cain { 270562598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2706ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270737bbf98cSChris Cain return; 270837bbf98cSChris Cain } 270937bbf98cSChris Cain const std::string& path = subtree[0].first; 271037bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 271137bbf98cSChris Cain if (service.empty()) 271237bbf98cSChris Cain { 271362598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2714ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271537bbf98cSChris Cain return; 271637bbf98cSChris Cain } 271737bbf98cSChris Cain 271837bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 271937bbf98cSChris Cain // need to be updated 272037bbf98cSChris Cain 272137bbf98cSChris Cain if (ipsEnable) 272237bbf98cSChris Cain { 2723bd79bce8SPatrick Williams setDbusProperty( 2724bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/Enabled", service, path, 272587c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2726e93abac6SGinu George "Enabled", *ipsEnable); 272737bbf98cSChris Cain } 272837bbf98cSChris Cain if (ipsEnterUtil) 272937bbf98cSChris Cain { 2730bd79bce8SPatrick Williams setDbusProperty( 2731bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/EnterUtilizationPercent", 2732e93abac6SGinu George service, path, 27339ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2734e93abac6SGinu George "EnterUtilizationPercent", *ipsEnterUtil); 273537bbf98cSChris Cain } 273637bbf98cSChris Cain if (ipsEnterTime) 273737bbf98cSChris Cain { 273837bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 273937bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 2740bd79bce8SPatrick Williams setDbusProperty( 2741bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service, 2742bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2743e93abac6SGinu George "EnterDwellTime", timeMilliseconds); 274437bbf98cSChris Cain } 274537bbf98cSChris Cain if (ipsExitUtil) 274637bbf98cSChris Cain { 2747bd79bce8SPatrick Williams setDbusProperty( 2748bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service, 2749bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2750e93abac6SGinu George "ExitUtilizationPercent", *ipsExitUtil); 275137bbf98cSChris Cain } 275237bbf98cSChris Cain if (ipsExitTime) 275337bbf98cSChris Cain { 275437bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 275537bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 2756bd79bce8SPatrick Williams setDbusProperty( 2757bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service, 2758bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2759e93abac6SGinu George "ExitDwellTime", timeMilliseconds); 276037bbf98cSChris Cain } 2761e99073f5SGeorge Liu }); 276237bbf98cSChris Cain 276362598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 276437bbf98cSChris Cain } 276537bbf98cSChris Cain 2766c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2767dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2768dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2769dd60b9edSEd Tanous { 2770dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2771dd60b9edSEd Tanous { 2772dd60b9edSEd Tanous return; 2773dd60b9edSEd Tanous } 2774dd60b9edSEd Tanous asyncResp->res.addHeader( 2775dd60b9edSEd Tanous boost::beast::http::field::link, 2776dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2777dd60b9edSEd Tanous } 2778dd60b9edSEd Tanous 2779c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2780c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2781c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 27821abe55efSEd Tanous { 27833ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2784f4c99e70SEd Tanous { 2785f4c99e70SEd Tanous return; 2786f4c99e70SEd Tanous } 2787dd60b9edSEd Tanous 2788dd60b9edSEd Tanous asyncResp->res.addHeader( 2789dd60b9edSEd Tanous boost::beast::http::field::link, 2790dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 27918d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 27920f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 27938d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 27948d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2795462023adSSunitha Harish 27967f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 27977f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 279825b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 27997f3e84a1SEd Tanous { 28007f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 28017f3e84a1SEd Tanous // Option currently returns no systems. TBD 28027f3e84a1SEd Tanous return; 28037f3e84a1SEd Tanous } 28047f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 28057f3e84a1SEd Tanous nlohmann::json::object_t system; 2806253f11b8SEd Tanous system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}", 2807253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 28087f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 280968896206SGunnar Mills 281068896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 2811462023adSSunitha Harish { 281262598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 281368896206SGunnar Mills asyncResp->res.jsonValue["Members@odata.count"] = 2; 281468896206SGunnar Mills 28151476687dSEd Tanous nlohmann::json::object_t hypervisor; 2816002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 281768896206SGunnar Mills ifaceArray.emplace_back(std::move(hypervisor)); 281868896206SGunnar Mills } 2819c1e219d5SEd Tanous } 2820c1e219d5SEd Tanous 2821c1e219d5SEd Tanous /** 28227e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28237e860f15SJohn Edward Broadbent */ 28244f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28257e860f15SJohn Edward Broadbent { 282689492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 282789492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 282889492a15SPatrick Williams constexpr const char* interfaceName = 28297e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 283089492a15SPatrick Williams constexpr const char* method = "NMI"; 28317e860f15SJohn Edward Broadbent 28327e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28335e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28347e860f15SJohn Edward Broadbent if (ec) 28357e860f15SJohn Edward Broadbent { 283662598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 28377e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28387e860f15SJohn Edward Broadbent return; 28397e860f15SJohn Edward Broadbent } 28407e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28417e860f15SJohn Edward Broadbent }, 28427e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28437e860f15SJohn Edward Broadbent } 2844c5b2abe0SLewanczyk, Dawid 2845c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2846c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 28477f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2848c1e219d5SEd Tanous const std::string& systemName) 2849c1e219d5SEd Tanous { 28503ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 285145ca1b86SEd Tanous { 285245ca1b86SEd Tanous return; 285345ca1b86SEd Tanous } 2854dd7090e6SGunnar Mills 2855dd7090e6SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 2856dd7090e6SGunnar Mills { 2857dd7090e6SGunnar Mills if (systemName == "hypervisor") 2858dd7090e6SGunnar Mills { 2859dd7090e6SGunnar Mills handleHypervisorSystemResetPost(req, asyncResp); 2860dd7090e6SGunnar Mills return; 2861dd7090e6SGunnar Mills } 2862dd7090e6SGunnar Mills } 2863dd7090e6SGunnar Mills 2864253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 2865c1e219d5SEd Tanous { 2866c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2867c1e219d5SEd Tanous systemName); 2868c1e219d5SEd Tanous return; 2869c1e219d5SEd Tanous } 287025b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 28717f3e84a1SEd Tanous { 28727f3e84a1SEd Tanous // Option currently returns no systems. TBD 28737f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2874c1e219d5SEd Tanous systemName); 28757f3e84a1SEd Tanous return; 28767f3e84a1SEd Tanous } 28779712f8acSEd Tanous std::string resetType; 2878c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 2879cc340dd9SEd Tanous { 2880cc340dd9SEd Tanous return; 2881cc340dd9SEd Tanous } 2882cc340dd9SEd Tanous 2883d22c8396SJason M. Bills // Get the command and host vs. chassis 2884cc340dd9SEd Tanous std::string command; 2885543f4400SEd Tanous bool hostCommand = true; 2886d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2887cc340dd9SEd Tanous { 2888cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2889d22c8396SJason M. Bills hostCommand = true; 2890d22c8396SJason M. Bills } 2891d22c8396SJason M. Bills else if (resetType == "ForceOff") 2892d22c8396SJason M. Bills { 2893d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2894d22c8396SJason M. Bills hostCommand = false; 2895d22c8396SJason M. Bills } 2896d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2897d22c8396SJason M. Bills { 2898c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 289986a0851aSJason M. Bills hostCommand = true; 2900cc340dd9SEd Tanous } 29019712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2902cc340dd9SEd Tanous { 2903cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2904d22c8396SJason M. Bills hostCommand = true; 2905cc340dd9SEd Tanous } 29069712f8acSEd Tanous else if (resetType == "GracefulRestart") 2907cc340dd9SEd Tanous { 29080fda0f12SGeorge Liu command = 29090fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2910d22c8396SJason M. Bills hostCommand = true; 2911d22c8396SJason M. Bills } 2912d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2913d22c8396SJason M. Bills { 291486a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 291586a0851aSJason M. Bills hostCommand = true; 2916cc340dd9SEd Tanous } 2917bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2918bfd5b826SLakshminarayana R. Kammath { 2919bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2920bfd5b826SLakshminarayana R. Kammath return; 2921bfd5b826SLakshminarayana R. Kammath } 2922cc340dd9SEd Tanous else 2923cc340dd9SEd Tanous { 2924c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 2925cc340dd9SEd Tanous return; 2926cc340dd9SEd Tanous } 2927d02aad39SEd Tanous sdbusplus::message::object_path statePath("/xyz/openbmc_project/state"); 2928cc340dd9SEd Tanous 2929d22c8396SJason M. Bills if (hostCommand) 2930d22c8396SJason M. Bills { 2931e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host", 2932d02aad39SEd Tanous statePath / "host0", "xyz.openbmc_project.State.Host", 2933e93abac6SGinu George "RequestedHostTransition", command); 2934cc340dd9SEd Tanous } 2935d22c8396SJason M. Bills else 2936d22c8396SJason M. Bills { 2937e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis", 2938d02aad39SEd Tanous statePath / "chassis0", 2939d02aad39SEd Tanous "xyz.openbmc_project.State.Chassis", 2940e93abac6SGinu George "RequestedPowerTransition", command); 2941d22c8396SJason M. Bills } 2942d22c8396SJason M. Bills } 2943cc340dd9SEd Tanous 2944c1e219d5SEd Tanous inline void handleComputerSystemHead( 2945dd60b9edSEd Tanous App& app, const crow::Request& req, 29467f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29477f3e84a1SEd Tanous const std::string& /*systemName*/) 2948dd60b9edSEd Tanous { 2949dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2950dd60b9edSEd Tanous { 2951dd60b9edSEd Tanous return; 2952dd60b9edSEd Tanous } 2953dd60b9edSEd Tanous 2954dd60b9edSEd Tanous asyncResp->res.addHeader( 2955dd60b9edSEd Tanous boost::beast::http::field::link, 2956dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2957dd60b9edSEd Tanous } 2958dd60b9edSEd Tanous 29595c3e9272SAbhishek Patel inline void afterPortRequest( 29605c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29615c3e9272SAbhishek Patel const boost::system::error_code& ec, 29625c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 29635c3e9272SAbhishek Patel { 29645c3e9272SAbhishek Patel if (ec) 29655c3e9272SAbhishek Patel { 2966b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 29675c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29685c3e9272SAbhishek Patel return; 29695c3e9272SAbhishek Patel } 29705c3e9272SAbhishek Patel for (const auto& data : socketData) 29715c3e9272SAbhishek Patel { 29725c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 29735c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 29745c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 29755c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 29765c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 29775c3e9272SAbhishek Patel // need to retrieve port number for 29785c3e9272SAbhishek Patel // obmc-console-ssh service 29795c3e9272SAbhishek Patel if (protocolName == "SSH") 29805c3e9272SAbhishek Patel { 29815c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 298281c4e330SEd Tanous const boost::system::error_code& ec1, 29835c3e9272SAbhishek Patel int portNumber) { 29845c3e9272SAbhishek Patel if (ec1) 29855c3e9272SAbhishek Patel { 2986b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 29875c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29885c3e9272SAbhishek Patel return; 29895c3e9272SAbhishek Patel } 29905c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 29915c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 29925c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 29935c3e9272SAbhishek Patel }); 29945c3e9272SAbhishek Patel } 29955c3e9272SAbhishek Patel } 29965c3e9272SAbhishek Patel } 2997c1e219d5SEd Tanous 2998c1e219d5SEd Tanous inline void 2999c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 300022d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3001c1e219d5SEd Tanous const std::string& systemName) 3002c1e219d5SEd Tanous { 30033ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 300445ca1b86SEd Tanous { 300545ca1b86SEd Tanous return; 300645ca1b86SEd Tanous } 3007746b56f3SAsmitha Karunanithi 300825b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 30097f3e84a1SEd Tanous { 30107f3e84a1SEd Tanous // Option currently returns no systems. TBD 30117f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 30127f3e84a1SEd Tanous systemName); 30137f3e84a1SEd Tanous return; 30147f3e84a1SEd Tanous } 30157f3e84a1SEd Tanous 301668896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 301768896206SGunnar Mills { 3018746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3019746b56f3SAsmitha Karunanithi { 3020746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3021746b56f3SAsmitha Karunanithi return; 3022746b56f3SAsmitha Karunanithi } 302368896206SGunnar Mills } 3024746b56f3SAsmitha Karunanithi 3025253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 302622d268cbSEd Tanous { 302722d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 302822d268cbSEd Tanous systemName); 302922d268cbSEd Tanous return; 303022d268cbSEd Tanous } 3031dd60b9edSEd Tanous asyncResp->res.addHeader( 3032dd60b9edSEd Tanous boost::beast::http::field::link, 3033dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 30348d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3035b6655101SChris Cain "#ComputerSystem.v1_22_0.ComputerSystem"; 3036253f11b8SEd Tanous asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3037253f11b8SEd Tanous asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3038539d8c6bSEd Tanous asyncResp->res.jsonValue["SystemType"] = 3039539d8c6bSEd Tanous computer_system::SystemType::Physical; 30408d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 30418d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 3042cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3043dfb2b408SPriyanga Ramasamy double(0); 3044253f11b8SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 3045253f11b8SEd Tanous "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME); 304604a258f4SEd Tanous 3047253f11b8SEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format( 3048253f11b8SEd Tanous "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3049253f11b8SEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format( 3050253f11b8SEd Tanous "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3051253f11b8SEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format( 3052253f11b8SEd Tanous "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME); 30533179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 3054253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters", 3055253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3056029573d4SEd Tanous 3057002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 3058253f11b8SEd Tanous boost::urls::format( 3059253f11b8SEd Tanous "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", 3060253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3061c1e219d5SEd Tanous asyncResp->res 3062c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 3063253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3064253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3065c5b2abe0SLewanczyk, Dawid 3066253f11b8SEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format( 3067253f11b8SEd Tanous "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3068253f11b8SEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format( 3069253f11b8SEd Tanous "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3070c4bf6374SJason M. Bills 30711476687dSEd Tanous nlohmann::json::array_t managedBy; 30721476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 3073253f11b8SEd Tanous manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}", 3074253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME); 3075002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 3076539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK; 3077539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled; 30780e8ac5e7SGunnar Mills 30790e8ac5e7SGunnar Mills // Fill in SerialConsole info 3080002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3081c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 30821476687dSEd Tanous 3083c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 30841476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3085c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 30861476687dSEd Tanous "Press ~. to exit console"; 30875c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 30885c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 30890e8ac5e7SGunnar Mills 309025b54dbaSEd Tanous if constexpr (BMCWEB_KVM) 309125b54dbaSEd Tanous { 30920e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3093002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 309425b54dbaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 309525b54dbaSEd Tanous 4; 3096613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3097613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 309825b54dbaSEd Tanous } 309913451e39SWilly Tu 3100bd79bce8SPatrick Williams getMainChassisId( 3101bd79bce8SPatrick Williams asyncResp, [](const std::string& chassisId, 31028d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3103b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3104b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3105bd79bce8SPatrick Williams chassis["@odata.id"] = 3106bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Chassis/{}", chassisId); 3107002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3108c5d03ff4SJennifer Lee }); 3109a3002228SAppaRao Puli 311059a17e4fSGeorge Liu getSystemLocationIndicatorActive(asyncResp); 31119f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3112a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 311351bd2d8aSGunnar Mills getComputerSystem(asyncResp); 31146c34de48SEd Tanous getHostState(asyncResp); 3115491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3116978b8803SAndrew Geissler getBootProgress(asyncResp); 3117b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 311870c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 311970c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 312051709ffdSYong Li getHostWatchdogTimer(asyncResp); 3121c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 31229dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3123797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3124c0557e1aSGunnar Mills getLastResetTime(asyncResp); 312525b54dbaSEd Tanous if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE) 312625b54dbaSEd Tanous { 3127a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 312825b54dbaSEd Tanous } 31291981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 31303a2d0424SChris Cain getPowerMode(asyncResp); 313137bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3132c1e219d5SEd Tanous } 3133550a6bf8SJiaqing Zhao 3134c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3135c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 313622d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3137c1e219d5SEd Tanous const std::string& systemName) 3138c1e219d5SEd Tanous { 31393ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 314045ca1b86SEd Tanous { 314145ca1b86SEd Tanous return; 314245ca1b86SEd Tanous } 314325b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 31447f3e84a1SEd Tanous { 31457f3e84a1SEd Tanous // Option currently returns no systems. TBD 31467f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31477f3e84a1SEd Tanous systemName); 31487f3e84a1SEd Tanous return; 31497f3e84a1SEd Tanous } 3150253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 315122d268cbSEd Tanous { 315222d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 315322d268cbSEd Tanous systemName); 315422d268cbSEd Tanous return; 315522d268cbSEd Tanous } 315622d268cbSEd Tanous 3157dd60b9edSEd Tanous asyncResp->res.addHeader( 3158dd60b9edSEd Tanous boost::beast::http::field::link, 3159dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3160dd60b9edSEd Tanous 31619f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3162cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 316398e386ecSGunnar Mills std::optional<std::string> assetTag; 3164c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 31653a2d0424SChris Cain std::optional<std::string> powerMode; 3166550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3167550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3168550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3169550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3170550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3171550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3172797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3173550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 31749dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3175550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3176550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3177550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3178550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3179550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3180550a6bf8SJiaqing Zhao 3181afc474aeSMyung Bae if (!json_util::readJsonPatch( // 3182afc474aeSMyung Bae req, asyncResp->res, // 3183afc474aeSMyung Bae "AssetTag", assetTag, // 3184afc474aeSMyung Bae "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, // 3185afc474aeSMyung Bae "Boot/AutomaticRetryConfig", bootAutomaticRetry, // 3186afc474aeSMyung Bae "Boot/BootSourceOverrideEnabled", bootEnable, // 3187afc474aeSMyung Bae "Boot/BootSourceOverrideMode", bootType, // 3188afc474aeSMyung Bae "Boot/BootSourceOverrideTarget", bootSource, // 3189afc474aeSMyung Bae "Boot/StopBootOnFault", stopBootOnFault, // 3190afc474aeSMyung Bae "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, // 3191afc474aeSMyung Bae "HostWatchdogTimer/FunctionEnabled", wdtEnable, // 3192afc474aeSMyung Bae "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, // 3193afc474aeSMyung Bae "IdlePowerSaver/Enabled", ipsEnable, // 3194afc474aeSMyung Bae "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, // 3195afc474aeSMyung Bae "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, // 3196afc474aeSMyung Bae "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, // 3197afc474aeSMyung Bae "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, // 3198afc474aeSMyung Bae "IndicatorLED", indicatorLed, // 3199afc474aeSMyung Bae "LocationIndicatorActive", locationIndicatorActive, // 3200afc474aeSMyung Bae "PowerMode", powerMode, // 3201afc474aeSMyung Bae "PowerRestorePolicy", powerRestorePolicy // 3202afc474aeSMyung Bae )) 32036617338dSEd Tanous { 32046617338dSEd Tanous return; 32056617338dSEd Tanous } 3206491d8ee7SSantosh Puranik 32078d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3208c45f0082SYong Li 320998e386ecSGunnar Mills if (assetTag) 321098e386ecSGunnar Mills { 321198e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 321298e386ecSGunnar Mills } 321398e386ecSGunnar Mills 3214550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3215c45f0082SYong Li { 3216f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3217c45f0082SYong Li } 3218c45f0082SYong Li 3219cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 322069f35306SGunnar Mills { 3221002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3222491d8ee7SSantosh Puranik } 3223550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 322469f35306SGunnar Mills { 3225550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 322669f35306SGunnar Mills } 3227ac7e1e0bSAli Ahmed 3228797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3229797d5daeSCorey Hardesty { 3230797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3231797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3232797d5daeSCorey Hardesty } 3233797d5daeSCorey Hardesty 3234550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3235ac7e1e0bSAli Ahmed { 3236c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 323769f35306SGunnar Mills } 3238265c1602SJohnathan Mantey 32399dcfe8c1SAlbert Zhang if (stopBootOnFault) 32409dcfe8c1SAlbert Zhang { 32419dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 32429dcfe8c1SAlbert Zhang } 32439dcfe8c1SAlbert Zhang 32449f8bfa7cSGunnar Mills if (locationIndicatorActive) 32459f8bfa7cSGunnar Mills { 324659a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 32479f8bfa7cSGunnar Mills } 32489f8bfa7cSGunnar Mills 32497e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32507e860f15SJohn Edward Broadbent // passed 32519712f8acSEd Tanous if (indicatorLed) 32526617338dSEd Tanous { 3253f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3254002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3255d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3256d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32576617338dSEd Tanous } 3258c6a620f2SGeorge Liu 3259c6a620f2SGeorge Liu if (powerRestorePolicy) 3260c6a620f2SGeorge Liu { 32614e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3262c6a620f2SGeorge Liu } 32633a2d0424SChris Cain 32643a2d0424SChris Cain if (powerMode) 32653a2d0424SChris Cain { 32663a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32673a2d0424SChris Cain } 326837bbf98cSChris Cain 3269c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 327037bbf98cSChris Cain { 3271002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3272002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 327337bbf98cSChris Cain } 3274c1e219d5SEd Tanous } 32751cb1a9e6SAppaRao Puli 327638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3277dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 32787f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3279c1e219d5SEd Tanous const std::string& /*systemName*/) 3280dd60b9edSEd Tanous { 3281dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3282dd60b9edSEd Tanous { 3283dd60b9edSEd Tanous return; 3284dd60b9edSEd Tanous } 3285dd60b9edSEd Tanous asyncResp->res.addHeader( 3286dd60b9edSEd Tanous boost::beast::http::field::link, 3287dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3288dd60b9edSEd Tanous } 328933e1f122SAndrew Geissler 329033e1f122SAndrew Geissler /** 329133e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 329233e1f122SAndrew Geissler * 329333e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 329433e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 329533e1f122SAndrew Geissler * 3296efff2b5dSManojkiran Eda * @return Emplaces corresponding Redfish translated value(s) in 329733e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 329833e1f122SAndrew Geissler * allowableValues. 329933e1f122SAndrew Geissler */ 330033e1f122SAndrew Geissler inline void 330133e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran, 330233e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 330333e1f122SAndrew Geissler { 330433e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 330533e1f122SAndrew Geissler { 330633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 330733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 330833e1f122SAndrew Geissler } 330933e1f122SAndrew Geissler else if (dbusAllowedHostTran == 331033e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 331133e1f122SAndrew Geissler { 331233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 331333e1f122SAndrew Geissler } 331433e1f122SAndrew Geissler else if (dbusAllowedHostTran == 331533e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 331633e1f122SAndrew Geissler { 331733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 331833e1f122SAndrew Geissler } 331933e1f122SAndrew Geissler else if (dbusAllowedHostTran == 332033e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 332133e1f122SAndrew Geissler { 332233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 332333e1f122SAndrew Geissler } 332433e1f122SAndrew Geissler else 332533e1f122SAndrew Geissler { 332633e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 332733e1f122SAndrew Geissler } 332833e1f122SAndrew Geissler } 332933e1f122SAndrew Geissler 333033e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 333133e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 333233e1f122SAndrew Geissler const boost::system::error_code& ec, 333333e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 333433e1f122SAndrew Geissler { 333533e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 333633e1f122SAndrew Geissler 333733e1f122SAndrew Geissler // Supported on all systems currently 333833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 333933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 334033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 334133e1f122SAndrew Geissler 334233e1f122SAndrew Geissler if (ec) 334333e1f122SAndrew Geissler { 3344e715d14bSEd Tanous if ((ec.value() == 3345e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3346e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 334733e1f122SAndrew Geissler { 334833e1f122SAndrew Geissler // Property not implemented so just return defaults 334933e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 335033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 335133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 335233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 335333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 335433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 335533e1f122SAndrew Geissler } 335633e1f122SAndrew Geissler else 335733e1f122SAndrew Geissler { 335833e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 335933e1f122SAndrew Geissler messages::internalError(asyncResp->res); 336033e1f122SAndrew Geissler return; 336133e1f122SAndrew Geissler } 336233e1f122SAndrew Geissler } 336333e1f122SAndrew Geissler else 336433e1f122SAndrew Geissler { 336533e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 336633e1f122SAndrew Geissler { 336733e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 336833e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 336933e1f122SAndrew Geissler } 337033e1f122SAndrew Geissler } 337133e1f122SAndrew Geissler 337233e1f122SAndrew Geissler nlohmann::json::object_t parameter; 337333e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 337433e1f122SAndrew Geissler parameter["Required"] = true; 3375539d8c6bSEd Tanous parameter["DataType"] = action_info::ParameterTypes::String; 337633e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 337733e1f122SAndrew Geissler nlohmann::json::array_t parameters; 337833e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 337933e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 338033e1f122SAndrew Geissler } 338133e1f122SAndrew Geissler 3382c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3383c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 338422d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3385c1e219d5SEd Tanous const std::string& systemName) 3386c1e219d5SEd Tanous { 33873ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 338845ca1b86SEd Tanous { 338945ca1b86SEd Tanous return; 339045ca1b86SEd Tanous } 339125b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 33927f3e84a1SEd Tanous { 33937f3e84a1SEd Tanous // Option currently returns no systems. TBD 33947f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 33957f3e84a1SEd Tanous systemName); 33967f3e84a1SEd Tanous return; 33977f3e84a1SEd Tanous } 3398746b56f3SAsmitha Karunanithi 339968896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 340068896206SGunnar Mills { 3401746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3402746b56f3SAsmitha Karunanithi { 3403746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3404746b56f3SAsmitha Karunanithi return; 3405746b56f3SAsmitha Karunanithi } 340668896206SGunnar Mills } 3407746b56f3SAsmitha Karunanithi 3408253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 340922d268cbSEd Tanous { 341022d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 341122d268cbSEd Tanous systemName); 341222d268cbSEd Tanous return; 341322d268cbSEd Tanous } 341422d268cbSEd Tanous 3415dd60b9edSEd Tanous asyncResp->res.addHeader( 3416dd60b9edSEd Tanous boost::beast::http::field::link, 3417dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34181476687dSEd Tanous 34191476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 3420253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3421253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3422c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34231476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34241476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34253215e700SNan Zhou 342633e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 3427deae6a78SEd Tanous dbus::utility::getProperty<std::vector<std::string>>( 3428deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 3429deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "AllowedHostTransitions", 343033e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 343133e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 3432bd79bce8SPatrick Williams afterGetAllowedHostTransitions(asyncResp, ec, 3433bd79bce8SPatrick Williams allowedHostTransitions); 343433e1f122SAndrew Geissler }); 3435c1e219d5SEd Tanous } 3436c1e219d5SEd Tanous /** 3437c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3438c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3439c1e219d5SEd Tanous */ 3440100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3441c1e219d5SEd Tanous { 3442100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3443100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3444100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3445100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3446100afe56SEd Tanous 3447100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3448100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3449100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3450100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3451100afe56SEd Tanous 3452100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3453100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3454100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3455100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3456100afe56SEd Tanous 3457100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3458100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3459100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3460100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3461100afe56SEd Tanous 3462100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3463100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3464100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3465100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3466100afe56SEd Tanous 3467100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3468100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3469100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3470100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3471100afe56SEd Tanous 3472c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3473c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3474c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3475c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3476c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3477c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3478c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3479c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 34801cb1a9e6SAppaRao Puli } 3481c5b2abe0SLewanczyk, Dawid } // namespace redfish 3482