1c5b2abe0SLewanczyk, Dawid /* 2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation 3c5b2abe0SLewanczyk, Dawid // 4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License"); 5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License. 6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at 7c5b2abe0SLewanczyk, Dawid // 8c5b2abe0SLewanczyk, Dawid // http://www.apache.org/licenses/LICENSE-2.0 9c5b2abe0SLewanczyk, Dawid // 10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software 11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS, 12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and 14c5b2abe0SLewanczyk, Dawid // limitations under the License. 15c5b2abe0SLewanczyk, Dawid */ 16c5b2abe0SLewanczyk, Dawid #pragma once 17c5b2abe0SLewanczyk, Dawid 1813451e39SWilly Tu #include "bmcweb_config.h" 1913451e39SWilly Tu 203ccb3adbSEd Tanous #include "app.hpp" 211e1e598dSJonathan Doman #include "dbus_singleton.hpp" 227a1dbc48SGeorge Liu #include "dbus_utility.hpp" 238d69c668SEd Tanous #include "generated/enums/computer_system.hpp" 24b49ac873SJames Feist #include "health.hpp" 25746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 261c8fba97SJames Feist #include "led.hpp" 27f4c99e70SEd Tanous #include "query.hpp" 28c5d03ff4SJennifer Lee #include "redfish_util.hpp" 293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 313ccb3adbSEd Tanous #include "utils/json_utils.hpp" 32472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 333ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 342b82937eSEd Tanous #include "utils/time_utils.hpp" 35c5d03ff4SJennifer Lee 36fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 379712f8acSEd Tanous #include <boost/container/flat_map.hpp> 38e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 39ef4c65b7SEd Tanous #include <boost/url/format.hpp> 401e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 41fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 42bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 431214b7e7SGunnar Mills 447a1dbc48SGeorge Liu #include <array> 457a1dbc48SGeorge Liu #include <string_view> 46abf2add6SEd Tanous #include <variant> 47c5b2abe0SLewanczyk, Dawid 481abe55efSEd Tanous namespace redfish 491abe55efSEd Tanous { 50c5b2abe0SLewanczyk, Dawid 515c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 525c3e9272SAbhishek Patel protocolToDBusForSystems{ 535c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 545c3e9272SAbhishek Patel 559d3ae10eSAlpana Kumari /** 569d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 579d3ae10eSAlpana Kumari * 58ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 599d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 609d3ae10eSAlpana Kumari * 619d3ae10eSAlpana Kumari * @return None. 629d3ae10eSAlpana Kumari */ 638d1b46d7Szhanghch05 inline void 64ac106bf6SEd Tanous updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 651e1e598dSJonathan Doman bool isDimmFunctional) 669d3ae10eSAlpana Kumari { 6762598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 689d3ae10eSAlpana Kumari 699d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 709d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 719d3ae10eSAlpana Kumari // ENABLED. 7202cad96eSEd Tanous const nlohmann::json& prevMemSummary = 73ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 749d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 759d3ae10eSAlpana Kumari { 76e05aec50SEd Tanous if (isDimmFunctional) 779d3ae10eSAlpana Kumari { 78ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 799d3ae10eSAlpana Kumari "Enabled"; 809d3ae10eSAlpana Kumari } 819d3ae10eSAlpana Kumari } 829d3ae10eSAlpana Kumari } 839d3ae10eSAlpana Kumari 8457e8c9beSAlpana Kumari /* 8557e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 8657e8c9beSAlpana Kumari * CPU Functional State 8757e8c9beSAlpana Kumari * 88ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 8957e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9057e8c9beSAlpana Kumari * 9157e8c9beSAlpana Kumari * @return None. 9257e8c9beSAlpana Kumari */ 93ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 94ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 9557e8c9beSAlpana Kumari { 9662598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 9757e8c9beSAlpana Kumari 9802cad96eSEd Tanous const nlohmann::json& prevProcState = 99ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10057e8c9beSAlpana Kumari 10157e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10257e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10357e8c9beSAlpana Kumari // Functional. 10457e8c9beSAlpana Kumari if (prevProcState == "Disabled") 10557e8c9beSAlpana Kumari { 106e05aec50SEd Tanous if (isCpuFunctional) 10757e8c9beSAlpana Kumari { 108ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 10957e8c9beSAlpana Kumari "Enabled"; 11057e8c9beSAlpana Kumari } 11157e8c9beSAlpana Kumari } 11257e8c9beSAlpana Kumari } 11357e8c9beSAlpana Kumari 114cf0e004cSNinad Palsule /* 115cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 116cf0e004cSNinad Palsule * 117ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 118cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 119cf0e004cSNinad Palsule * 120cf0e004cSNinad Palsule * @return None. 121cf0e004cSNinad Palsule */ 122cf0e004cSNinad Palsule inline void 123ac106bf6SEd Tanous modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 124cf0e004cSNinad Palsule bool isCpuPresent) 125cf0e004cSNinad Palsule { 12662598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 127cf0e004cSNinad Palsule 128cf0e004cSNinad Palsule if (isCpuPresent) 129cf0e004cSNinad Palsule { 130cf0e004cSNinad Palsule nlohmann::json& procCount = 131ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 132cf0e004cSNinad Palsule auto* procCountPtr = 133cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 134cf0e004cSNinad Palsule if (procCountPtr != nullptr) 135cf0e004cSNinad Palsule { 136cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 137cf0e004cSNinad Palsule *procCountPtr += 1; 138cf0e004cSNinad Palsule } 139cf0e004cSNinad Palsule } 140cf0e004cSNinad Palsule } 141cf0e004cSNinad Palsule 142382d6475SAli Ahmed inline void getProcessorProperties( 143ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 144382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 145382d6475SAli Ahmed properties) 14603fbed92SAli Ahmed { 14762598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 14803fbed92SAli Ahmed 14903fbed92SAli Ahmed // TODO: Get Model 15003fbed92SAli Ahmed 151bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15203fbed92SAli Ahmed 153bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 154bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 15503fbed92SAli Ahmed 156bc1d29deSKrzysztof Grobelny if (!success) 15703fbed92SAli Ahmed { 158ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15903fbed92SAli Ahmed return; 16003fbed92SAli Ahmed } 16103fbed92SAli Ahmed 162bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16303fbed92SAli Ahmed { 164bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 165ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 166bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 167bc1d29deSKrzysztof Grobelny 168bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 169bc1d29deSKrzysztof Grobelny { 170bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17103fbed92SAli Ahmed } 17203fbed92SAli Ahmed else 17303fbed92SAli Ahmed { 174bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 17503fbed92SAli Ahmed } 17603fbed92SAli Ahmed } 17703fbed92SAli Ahmed } 17803fbed92SAli Ahmed 17903fbed92SAli Ahmed /* 18003fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18103fbed92SAli Ahmed * 182ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 18303fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 18403fbed92SAli Ahmed * @param[in] path dbus path for Cpu 18503fbed92SAli Ahmed * 18603fbed92SAli Ahmed * @return None. 18703fbed92SAli Ahmed */ 188ac106bf6SEd Tanous inline void 189ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 190ac106bf6SEd Tanous const std::string& service, const std::string& path) 19103fbed92SAli Ahmed { 192ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 193382d6475SAli Ahmed const bool cpuPresenceCheck) { 194382d6475SAli Ahmed if (ec3) 195382d6475SAli Ahmed { 19662598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 197382d6475SAli Ahmed return; 198382d6475SAli Ahmed } 199ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 200382d6475SAli Ahmed }; 201382d6475SAli Ahmed 202cf0e004cSNinad Palsule // Get the Presence of CPU 203cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 204cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 205cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 206cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 207cf0e004cSNinad Palsule 2085fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2095fd0aafbSNinad Palsule { 2105fd0aafbSNinad Palsule auto getCpuFunctionalState = 211ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 212382d6475SAli Ahmed const bool cpuFunctionalCheck) { 213382d6475SAli Ahmed if (ec3) 214382d6475SAli Ahmed { 21562598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 216382d6475SAli Ahmed return; 217382d6475SAli Ahmed } 218ac106bf6SEd Tanous modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck); 219382d6475SAli Ahmed }; 220382d6475SAli Ahmed 221382d6475SAli Ahmed // Get the Functional State 222382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 223382d6475SAli Ahmed *crow::connections::systemBus, service, path, 2245fd0aafbSNinad Palsule "xyz.openbmc_project.State.Decorator.OperationalStatus", 2255fd0aafbSNinad Palsule "Functional", std::move(getCpuFunctionalState)); 2265fd0aafbSNinad Palsule } 227382d6475SAli Ahmed 228bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 229bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 230bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 231ac106bf6SEd Tanous [asyncResp, service, 2325e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 233b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 23403fbed92SAli Ahmed if (ec2) 23503fbed92SAli Ahmed { 23662598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 237ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23803fbed92SAli Ahmed return; 23903fbed92SAli Ahmed } 240ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 241bc1d29deSKrzysztof Grobelny }); 24203fbed92SAli Ahmed } 24303fbed92SAli Ahmed 24457e8c9beSAlpana Kumari /* 245cf0e004cSNinad Palsule * @brief processMemoryProperties fields 246cf0e004cSNinad Palsule * 247ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 248cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 249cf0e004cSNinad Palsule * @param[in] path dbus path for Memory 250cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 251cf0e004cSNinad Palsule * 252cf0e004cSNinad Palsule * @return None. 253cf0e004cSNinad Palsule */ 254cf0e004cSNinad Palsule inline void 255ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2565fd0aafbSNinad Palsule [[maybe_unused]] const std::string& service, 2575fd0aafbSNinad Palsule [[maybe_unused]] const std::string& path, 258cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 259cf0e004cSNinad Palsule { 26062598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 261cf0e004cSNinad Palsule 262cf0e004cSNinad Palsule if (properties.empty()) 263cf0e004cSNinad Palsule { 2645fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2655fd0aafbSNinad Palsule { 266cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 267cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 268cf0e004cSNinad Palsule "xyz.openbmc_project.State." 269cf0e004cSNinad Palsule "Decorator.OperationalStatus", 270cf0e004cSNinad Palsule "Functional", 271ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 272ac106bf6SEd Tanous bool dimmState) { 273cf0e004cSNinad Palsule if (ec3) 274cf0e004cSNinad Palsule { 27562598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 276cf0e004cSNinad Palsule return; 277cf0e004cSNinad Palsule } 278ac106bf6SEd Tanous updateDimmProperties(asyncResp, dimmState); 279cf0e004cSNinad Palsule }); 2805fd0aafbSNinad Palsule } 281cf0e004cSNinad Palsule return; 282cf0e004cSNinad Palsule } 283cf0e004cSNinad Palsule 284cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 285cf0e004cSNinad Palsule 286cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 287cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 288cf0e004cSNinad Palsule memorySizeInKB); 289cf0e004cSNinad Palsule 290cf0e004cSNinad Palsule if (!success) 291cf0e004cSNinad Palsule { 292ac106bf6SEd Tanous messages::internalError(asyncResp->res); 293cf0e004cSNinad Palsule return; 294cf0e004cSNinad Palsule } 295cf0e004cSNinad Palsule 296cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 297cf0e004cSNinad Palsule { 298cf0e004cSNinad Palsule nlohmann::json& totalMemory = 299ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 300dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 301cf0e004cSNinad Palsule if (preValue == nullptr) 302cf0e004cSNinad Palsule { 303ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 304dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 305cf0e004cSNinad Palsule } 306cf0e004cSNinad Palsule else 307cf0e004cSNinad Palsule { 308ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 309dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 310dfb2b408SPriyanga Ramasamy *preValue; 311cf0e004cSNinad Palsule } 3125fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3135fd0aafbSNinad Palsule { 314ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 3155fd0aafbSNinad Palsule "Enabled"; 3165fd0aafbSNinad Palsule } 317cf0e004cSNinad Palsule } 318cf0e004cSNinad Palsule } 319cf0e004cSNinad Palsule 320cf0e004cSNinad Palsule /* 321cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 322cf0e004cSNinad Palsule * 323ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 324cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 325cf0e004cSNinad Palsule * @param[in] path dbus path for memory 326cf0e004cSNinad Palsule * 327cf0e004cSNinad Palsule * @return None. 328cf0e004cSNinad Palsule */ 329ac106bf6SEd Tanous inline void 330ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 331ac106bf6SEd Tanous const std::string& service, const std::string& path) 332cf0e004cSNinad Palsule { 333cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 334cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 335cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 336ac106bf6SEd Tanous [asyncResp, service, 337cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 338cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 339cf0e004cSNinad Palsule if (ec2) 340cf0e004cSNinad Palsule { 34162598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 342ac106bf6SEd Tanous messages::internalError(asyncResp->res); 343cf0e004cSNinad Palsule return; 344cf0e004cSNinad Palsule } 345ac106bf6SEd Tanous processMemoryProperties(asyncResp, service, path, properties); 346cf0e004cSNinad Palsule }); 347cf0e004cSNinad Palsule } 348cf0e004cSNinad Palsule 349cf0e004cSNinad Palsule /* 350c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 351c5b2abe0SLewanczyk, Dawid * 352ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 3538f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 354c5b2abe0SLewanczyk, Dawid * 355c5b2abe0SLewanczyk, Dawid * @return None. 356c5b2abe0SLewanczyk, Dawid */ 357b5a76932SEd Tanous inline void 358ac106bf6SEd Tanous getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 359b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 3601abe55efSEd Tanous { 36162598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system components."); 362e99073f5SGeorge Liu constexpr std::array<std::string_view, 5> interfaces = { 363e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Asset", 364e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cpu", 365e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm", 366e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System", 367e99073f5SGeorge Liu "xyz.openbmc_project.Common.UUID", 368e99073f5SGeorge Liu }; 369e99073f5SGeorge Liu dbus::utility::getSubTree( 370e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 371ac106bf6SEd Tanous [asyncResp, 372e99073f5SGeorge Liu systemHealth](const boost::system::error_code& ec, 373b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 3741abe55efSEd Tanous if (ec) 3751abe55efSEd Tanous { 37662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 377ac106bf6SEd Tanous messages::internalError(asyncResp->res); 378c5b2abe0SLewanczyk, Dawid return; 379c5b2abe0SLewanczyk, Dawid } 380c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 381002d39b4SEd Tanous for (const std::pair< 382002d39b4SEd Tanous std::string, 383002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 3841214b7e7SGunnar Mills object : subtree) 3851abe55efSEd Tanous { 386c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 38762598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 388002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 3891214b7e7SGunnar Mills connectionNames = object.second; 39026f6976fSEd Tanous if (connectionNames.empty()) 3911abe55efSEd Tanous { 392c5b2abe0SLewanczyk, Dawid continue; 393c5b2abe0SLewanczyk, Dawid } 394029573d4SEd Tanous 3955fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> memoryHealth = nullptr; 3965fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> cpuHealth = nullptr; 3975bc2dc8eSJames Feist 3985fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3995fd0aafbSNinad Palsule { 4005fd0aafbSNinad Palsule memoryHealth = std::make_shared<HealthPopulate>( 401ac106bf6SEd Tanous asyncResp, "/MemorySummary/Status"_json_pointer); 4025fd0aafbSNinad Palsule systemHealth->children.emplace_back(memoryHealth); 4035bc2dc8eSJames Feist 40413451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 40513451e39SWilly Tu { 4065fd0aafbSNinad Palsule cpuHealth = std::make_shared<HealthPopulate>( 407ac106bf6SEd Tanous asyncResp, "/ProcessorSummary/Status"_json_pointer); 4085fd0aafbSNinad Palsule 4095bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 41013451e39SWilly Tu } 4115fd0aafbSNinad Palsule } 4125bc2dc8eSJames Feist 4136c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4146c34de48SEd Tanous // BiosVer 41504a258f4SEd Tanous for (const auto& connection : connectionNames) 4161abe55efSEd Tanous { 41704a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4181abe55efSEd Tanous { 41904a258f4SEd Tanous if (interfaceName == 42004a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 4211abe55efSEd Tanous { 42262598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 4239d3ae10eSAlpana Kumari 424ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4255bc2dc8eSJames Feist 4265fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4275fd0aafbSNinad Palsule { 4285bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 4291abe55efSEd Tanous } 4305fd0aafbSNinad Palsule } 43104a258f4SEd Tanous else if (interfaceName == 43204a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4331abe55efSEd Tanous { 43462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 43557e8c9beSAlpana Kumari 436ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4375bc2dc8eSJames Feist 4385fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4395fd0aafbSNinad Palsule { 4405bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4411abe55efSEd Tanous } 4425fd0aafbSNinad Palsule } 443002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4441abe55efSEd Tanous { 44562598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 446bc1d29deSKrzysztof Grobelny 447bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 448bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 449bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Common.UUID", 450ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 451b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4521214b7e7SGunnar Mills properties) { 453cb13a392SEd Tanous if (ec3) 4541abe55efSEd Tanous { 45562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec3); 456ac106bf6SEd Tanous messages::internalError(asyncResp->res); 457c5b2abe0SLewanczyk, Dawid return; 458c5b2abe0SLewanczyk, Dawid } 45962598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} UUID properties.", 46062598e31SEd Tanous properties.size()); 46104a258f4SEd Tanous 462bc1d29deSKrzysztof Grobelny const std::string* uUID = nullptr; 463bc1d29deSKrzysztof Grobelny 464bc1d29deSKrzysztof Grobelny const bool success = 465bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 466bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 467bc1d29deSKrzysztof Grobelny properties, "UUID", uUID); 468bc1d29deSKrzysztof Grobelny 469bc1d29deSKrzysztof Grobelny if (!success) 4701abe55efSEd Tanous { 471ac106bf6SEd Tanous messages::internalError(asyncResp->res); 472bc1d29deSKrzysztof Grobelny return; 473bc1d29deSKrzysztof Grobelny } 474bc1d29deSKrzysztof Grobelny 475bc1d29deSKrzysztof Grobelny if (uUID != nullptr) 476bc1d29deSKrzysztof Grobelny { 477bc1d29deSKrzysztof Grobelny std::string valueStr = *uUID; 47804a258f4SEd Tanous if (valueStr.size() == 32) 4791abe55efSEd Tanous { 480029573d4SEd Tanous valueStr.insert(8, 1, '-'); 481029573d4SEd Tanous valueStr.insert(13, 1, '-'); 482029573d4SEd Tanous valueStr.insert(18, 1, '-'); 483029573d4SEd Tanous valueStr.insert(23, 1, '-'); 48404a258f4SEd Tanous } 48562598e31SEd Tanous BMCWEB_LOG_DEBUG("UUID = {}", valueStr); 486ac106bf6SEd Tanous asyncResp->res.jsonValue["UUID"] = valueStr; 487c5b2abe0SLewanczyk, Dawid } 488bc1d29deSKrzysztof Grobelny }); 489c5b2abe0SLewanczyk, Dawid } 490029573d4SEd Tanous else if (interfaceName == 491029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4921abe55efSEd Tanous { 493bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 494bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 495bc1d29deSKrzysztof Grobelny path, 496bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 497ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 498b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4991214b7e7SGunnar Mills propertiesList) { 500cb13a392SEd Tanous if (ec2) 501029573d4SEd Tanous { 502e4a4b9a9SJames Feist // doesn't have to include this 503e4a4b9a9SJames Feist // interface 504029573d4SEd Tanous return; 505029573d4SEd Tanous } 50662598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} properties for system", 50762598e31SEd Tanous propertiesList.size()); 508bc1d29deSKrzysztof Grobelny 509bc1d29deSKrzysztof Grobelny const std::string* partNumber = nullptr; 510bc1d29deSKrzysztof Grobelny const std::string* serialNumber = nullptr; 511bc1d29deSKrzysztof Grobelny const std::string* manufacturer = nullptr; 512bc1d29deSKrzysztof Grobelny const std::string* model = nullptr; 513bc1d29deSKrzysztof Grobelny const std::string* subModel = nullptr; 514bc1d29deSKrzysztof Grobelny 515bc1d29deSKrzysztof Grobelny const bool success = 516bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 517bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 518bc1d29deSKrzysztof Grobelny propertiesList, "PartNumber", partNumber, 519bc1d29deSKrzysztof Grobelny "SerialNumber", serialNumber, 520bc1d29deSKrzysztof Grobelny "Manufacturer", manufacturer, "Model", 521bc1d29deSKrzysztof Grobelny model, "SubModel", subModel); 522bc1d29deSKrzysztof Grobelny 523bc1d29deSKrzysztof Grobelny if (!success) 524029573d4SEd Tanous { 525ac106bf6SEd Tanous messages::internalError(asyncResp->res); 526bc1d29deSKrzysztof Grobelny return; 527029573d4SEd Tanous } 528bc1d29deSKrzysztof Grobelny 529bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 530bc1d29deSKrzysztof Grobelny { 531ac106bf6SEd Tanous asyncResp->res.jsonValue["PartNumber"] = 532bc1d29deSKrzysztof Grobelny *partNumber; 533029573d4SEd Tanous } 534bc1d29deSKrzysztof Grobelny 535bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 536bc1d29deSKrzysztof Grobelny { 537ac106bf6SEd Tanous asyncResp->res.jsonValue["SerialNumber"] = 538bc1d29deSKrzysztof Grobelny *serialNumber; 539bc1d29deSKrzysztof Grobelny } 540bc1d29deSKrzysztof Grobelny 541bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 542bc1d29deSKrzysztof Grobelny { 543ac106bf6SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = 544bc1d29deSKrzysztof Grobelny *manufacturer; 545bc1d29deSKrzysztof Grobelny } 546bc1d29deSKrzysztof Grobelny 547bc1d29deSKrzysztof Grobelny if (model != nullptr) 548bc1d29deSKrzysztof Grobelny { 549ac106bf6SEd Tanous asyncResp->res.jsonValue["Model"] = *model; 550bc1d29deSKrzysztof Grobelny } 551bc1d29deSKrzysztof Grobelny 552bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 553bc1d29deSKrzysztof Grobelny { 554ac106bf6SEd Tanous asyncResp->res.jsonValue["SubModel"] = 555ac106bf6SEd Tanous *subModel; 556fc5afcf9Sbeccabroek } 557c1e236a6SGunnar Mills 558cb7e1e7bSAndrew Geissler // Grab the bios version 559eee0013eSWilly Tu sw_util::populateSoftwareInformation( 560ac106bf6SEd Tanous asyncResp, sw_util::biosPurpose, "BiosVersion", 561002d39b4SEd Tanous false); 562bc1d29deSKrzysztof Grobelny }); 563e4a4b9a9SJames Feist 5641e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5651e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5661e1e598dSJonathan Doman path, 5671e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5681e1e598dSJonathan Doman "AssetTag", 5691e1e598dSJonathan Doman "AssetTag", 570ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 5711e1e598dSJonathan Doman const std::string& value) { 572cb13a392SEd Tanous if (ec2) 573e4a4b9a9SJames Feist { 574e4a4b9a9SJames Feist // doesn't have to include this 575e4a4b9a9SJames Feist // interface 576e4a4b9a9SJames Feist return; 577e4a4b9a9SJames Feist } 578e4a4b9a9SJames Feist 579ac106bf6SEd Tanous asyncResp->res.jsonValue["AssetTag"] = value; 5801e1e598dSJonathan Doman }); 581029573d4SEd Tanous } 582029573d4SEd Tanous } 583029573d4SEd Tanous } 584c5b2abe0SLewanczyk, Dawid } 5856617338dSEd Tanous }); 586c5b2abe0SLewanczyk, Dawid } 587c5b2abe0SLewanczyk, Dawid 588c5b2abe0SLewanczyk, Dawid /** 589c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 590c5b2abe0SLewanczyk, Dawid * 591ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 592c5b2abe0SLewanczyk, Dawid * 593c5b2abe0SLewanczyk, Dawid * @return None. 594c5b2abe0SLewanczyk, Dawid */ 595ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5961abe55efSEd Tanous { 59762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 5981e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5991e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 6001e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 6011e1e598dSJonathan Doman "CurrentHostState", 602ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 6031e1e598dSJonathan Doman const std::string& hostState) { 6041abe55efSEd Tanous if (ec) 6051abe55efSEd Tanous { 60622228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 60722228c28SAndrew Geissler { 60822228c28SAndrew Geissler // Service not available, no error, just don't return 60922228c28SAndrew Geissler // host state info 61062598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 61122228c28SAndrew Geissler return; 61222228c28SAndrew Geissler } 61362598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 614ac106bf6SEd Tanous messages::internalError(asyncResp->res); 615c5b2abe0SLewanczyk, Dawid return; 616c5b2abe0SLewanczyk, Dawid } 6176617338dSEd Tanous 61862598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 619c5b2abe0SLewanczyk, Dawid // Verify Host State 6201e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 6211abe55efSEd Tanous { 622ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 623ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 6241abe55efSEd Tanous } 6251e1e598dSJonathan Doman else if (hostState == 6260fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 6278c888608SGunnar Mills { 628ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 629ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6308c888608SGunnar Mills } 6311e1e598dSJonathan Doman else if (hostState == 6320fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 63383935af9SAndrew Geissler { 634ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 635ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 63683935af9SAndrew Geissler } 6370fda0f12SGeorge Liu else if ( 6381e1e598dSJonathan Doman hostState == 6390fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6401a2a1437SAndrew Geissler { 641ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 642ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 6431a2a1437SAndrew Geissler } 644002d39b4SEd Tanous else if (hostState == 6450fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6461a2a1437SAndrew Geissler { 647ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 648ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 6491a2a1437SAndrew Geissler } 6501abe55efSEd Tanous else 6511abe55efSEd Tanous { 652ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 653ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 654c5b2abe0SLewanczyk, Dawid } 6551e1e598dSJonathan Doman }); 656c5b2abe0SLewanczyk, Dawid } 657c5b2abe0SLewanczyk, Dawid 658c5b2abe0SLewanczyk, Dawid /** 659786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 660491d8ee7SSantosh Puranik * 661491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 662491d8ee7SSantosh Puranik * 663491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 664491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 665491d8ee7SSantosh Puranik */ 66623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 667491d8ee7SSantosh Puranik { 668491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 669491d8ee7SSantosh Puranik { 670491d8ee7SSantosh Puranik return "None"; 671491d8ee7SSantosh Puranik } 6723174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 673491d8ee7SSantosh Puranik { 674491d8ee7SSantosh Puranik return "Hdd"; 675491d8ee7SSantosh Puranik } 6763174e4dfSEd Tanous if (dbusSource == 677a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 678491d8ee7SSantosh Puranik { 679491d8ee7SSantosh Puranik return "Cd"; 680491d8ee7SSantosh Puranik } 6813174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 682491d8ee7SSantosh Puranik { 683491d8ee7SSantosh Puranik return "Pxe"; 684491d8ee7SSantosh Puranik } 6853174e4dfSEd Tanous if (dbusSource == 686944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6879f16b2c1SJennifer Lee { 6889f16b2c1SJennifer Lee return "Usb"; 6899f16b2c1SJennifer Lee } 690491d8ee7SSantosh Puranik return ""; 691491d8ee7SSantosh Puranik } 692491d8ee7SSantosh Puranik 693491d8ee7SSantosh Puranik /** 694cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 695cd9a4666SKonstantin Aladyshev * 696cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 697cd9a4666SKonstantin Aladyshev * 698cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 699cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 700cd9a4666SKonstantin Aladyshev */ 701cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 702cd9a4666SKonstantin Aladyshev { 703cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 704cd9a4666SKonstantin Aladyshev { 705cd9a4666SKonstantin Aladyshev return "Legacy"; 706cd9a4666SKonstantin Aladyshev } 707cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 708cd9a4666SKonstantin Aladyshev { 709cd9a4666SKonstantin Aladyshev return "UEFI"; 710cd9a4666SKonstantin Aladyshev } 711cd9a4666SKonstantin Aladyshev return ""; 712cd9a4666SKonstantin Aladyshev } 713cd9a4666SKonstantin Aladyshev 714cd9a4666SKonstantin Aladyshev /** 715786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 716491d8ee7SSantosh Puranik * 717491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 718491d8ee7SSantosh Puranik * 719491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 720491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 721491d8ee7SSantosh Puranik */ 72223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 723491d8ee7SSantosh Puranik { 724491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 725491d8ee7SSantosh Puranik { 726491d8ee7SSantosh Puranik return "None"; 727491d8ee7SSantosh Puranik } 7283174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 729491d8ee7SSantosh Puranik { 730491d8ee7SSantosh Puranik return "Diags"; 731491d8ee7SSantosh Puranik } 7323174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 733491d8ee7SSantosh Puranik { 734491d8ee7SSantosh Puranik return "BiosSetup"; 735491d8ee7SSantosh Puranik } 736491d8ee7SSantosh Puranik return ""; 737491d8ee7SSantosh Puranik } 738491d8ee7SSantosh Puranik 739491d8ee7SSantosh Puranik /** 740e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 741e43914b3SAndrew Geissler * 742e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 743e43914b3SAndrew Geissler * 744e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 745e43914b3SAndrew Geissler * translation cannot be done, returns "None". 746e43914b3SAndrew Geissler */ 747e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 748e43914b3SAndrew Geissler { 749e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 750e43914b3SAndrew Geissler // enum 751e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 752e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 753e43914b3SAndrew Geissler "ProgressStages.Unspecified") 754e43914b3SAndrew Geissler { 755e43914b3SAndrew Geissler rfBpLastState = "None"; 756e43914b3SAndrew Geissler } 757e43914b3SAndrew Geissler else if (dbusBootProgress == 758e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 759e43914b3SAndrew Geissler "PrimaryProcInit") 760e43914b3SAndrew Geissler { 761e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 762e43914b3SAndrew Geissler } 763e43914b3SAndrew Geissler else if (dbusBootProgress == 764e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 765e43914b3SAndrew Geissler "BusInit") 766e43914b3SAndrew Geissler { 767e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 768e43914b3SAndrew Geissler } 769e43914b3SAndrew Geissler else if (dbusBootProgress == 770e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 771e43914b3SAndrew Geissler "MemoryInit") 772e43914b3SAndrew Geissler { 773e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 774e43914b3SAndrew Geissler } 775e43914b3SAndrew Geissler else if (dbusBootProgress == 776e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 777e43914b3SAndrew Geissler "SecondaryProcInit") 778e43914b3SAndrew Geissler { 779e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 780e43914b3SAndrew Geissler } 781e43914b3SAndrew Geissler else if (dbusBootProgress == 782e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 783e43914b3SAndrew Geissler "PCIInit") 784e43914b3SAndrew Geissler { 785e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 786e43914b3SAndrew Geissler } 787e43914b3SAndrew Geissler else if (dbusBootProgress == 788e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 789e43914b3SAndrew Geissler "SystemSetup") 790e43914b3SAndrew Geissler { 791e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 792e43914b3SAndrew Geissler } 793e43914b3SAndrew Geissler else if (dbusBootProgress == 794e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 795e43914b3SAndrew Geissler "SystemInitComplete") 796e43914b3SAndrew Geissler { 797e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 798e43914b3SAndrew Geissler } 799e43914b3SAndrew Geissler else if (dbusBootProgress == 800e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 801e43914b3SAndrew Geissler "OSStart") 802e43914b3SAndrew Geissler { 803e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 804e43914b3SAndrew Geissler } 805e43914b3SAndrew Geissler else if (dbusBootProgress == 806e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 807e43914b3SAndrew Geissler "OSRunning") 808e43914b3SAndrew Geissler { 809e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 810e43914b3SAndrew Geissler } 811e43914b3SAndrew Geissler else 812e43914b3SAndrew Geissler { 81362598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 814e43914b3SAndrew Geissler // Just return the default 815e43914b3SAndrew Geissler } 816e43914b3SAndrew Geissler return rfBpLastState; 817e43914b3SAndrew Geissler } 818e43914b3SAndrew Geissler 819e43914b3SAndrew Geissler /** 820786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 821491d8ee7SSantosh Puranik * 822491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 823944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 824944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 825491d8ee7SSantosh Puranik * 826944ffaf9SJohnathan Mantey * @return Integer error code. 827491d8ee7SSantosh Puranik */ 828ac106bf6SEd Tanous inline int 829ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 830ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 831ac106bf6SEd Tanous std::string& bootMode) 832491d8ee7SSantosh Puranik { 833c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 834c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 835944ffaf9SJohnathan Mantey 836491d8ee7SSantosh Puranik if (rfSource == "None") 837491d8ee7SSantosh Puranik { 838944ffaf9SJohnathan Mantey return 0; 839491d8ee7SSantosh Puranik } 8403174e4dfSEd Tanous if (rfSource == "Pxe") 841491d8ee7SSantosh Puranik { 842944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 843944ffaf9SJohnathan Mantey } 844944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 845944ffaf9SJohnathan Mantey { 846944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 847944ffaf9SJohnathan Mantey } 848944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 849944ffaf9SJohnathan Mantey { 850944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 851944ffaf9SJohnathan Mantey } 852944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 853944ffaf9SJohnathan Mantey { 854944ffaf9SJohnathan Mantey bootSource = 855944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 856944ffaf9SJohnathan Mantey } 857944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 858944ffaf9SJohnathan Mantey { 859944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 860491d8ee7SSantosh Puranik } 8619f16b2c1SJennifer Lee else if (rfSource == "Usb") 8629f16b2c1SJennifer Lee { 863944ffaf9SJohnathan Mantey bootSource = 864944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8659f16b2c1SJennifer Lee } 866491d8ee7SSantosh Puranik else 867491d8ee7SSantosh Puranik { 86862598e31SEd Tanous BMCWEB_LOG_DEBUG( 86962598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 87062598e31SEd Tanous bootSource); 871ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 872944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 873944ffaf9SJohnathan Mantey return -1; 874491d8ee7SSantosh Puranik } 875944ffaf9SJohnathan Mantey return 0; 876491d8ee7SSantosh Puranik } 8771981771bSAli Ahmed 878978b8803SAndrew Geissler /** 879978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 880978b8803SAndrew Geissler * 881ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 882978b8803SAndrew Geissler * 883978b8803SAndrew Geissler * @return None. 884978b8803SAndrew Geissler */ 885ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 886978b8803SAndrew Geissler { 8871e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8881e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8891e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8901e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 891ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8921e1e598dSJonathan Doman const std::string& bootProgressStr) { 893978b8803SAndrew Geissler if (ec) 894978b8803SAndrew Geissler { 895978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 896978b8803SAndrew Geissler // not found 897978b8803SAndrew Geissler return; 898978b8803SAndrew Geissler } 899978b8803SAndrew Geissler 90062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 901978b8803SAndrew Geissler 902ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 903e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 9041e1e598dSJonathan Doman }); 905978b8803SAndrew Geissler } 906491d8ee7SSantosh Puranik 907491d8ee7SSantosh Puranik /** 908b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 909b6d5d45cSHieu Huynh * 910ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 911b6d5d45cSHieu Huynh * 912b6d5d45cSHieu Huynh * @return None. 913b6d5d45cSHieu Huynh */ 914b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 915ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 916b6d5d45cSHieu Huynh { 917b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 918b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 919b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 920b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 921ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 922b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 923b6d5d45cSHieu Huynh if (ec) 924b6d5d45cSHieu Huynh { 92562598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 926b6d5d45cSHieu Huynh return; 927b6d5d45cSHieu Huynh } 928b6d5d45cSHieu Huynh 929b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 930b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 931b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 932b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 933b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 934b6d5d45cSHieu Huynh 935b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 936ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 937b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 938b6d5d45cSHieu Huynh }); 939b6d5d45cSHieu Huynh } 940b6d5d45cSHieu Huynh 941b6d5d45cSHieu Huynh /** 942c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 943cd9a4666SKonstantin Aladyshev * 944ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 945cd9a4666SKonstantin Aladyshev * 946cd9a4666SKonstantin Aladyshev * @return None. 947cd9a4666SKonstantin Aladyshev */ 948cd9a4666SKonstantin Aladyshev 949ac106bf6SEd Tanous inline void 950ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 951cd9a4666SKonstantin Aladyshev { 9521e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9531e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9541e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9551e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 956ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9571e1e598dSJonathan Doman const std::string& bootType) { 958cd9a4666SKonstantin Aladyshev if (ec) 959cd9a4666SKonstantin Aladyshev { 960cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 961cd9a4666SKonstantin Aladyshev return; 962cd9a4666SKonstantin Aladyshev } 963cd9a4666SKonstantin Aladyshev 96462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 965cd9a4666SKonstantin Aladyshev 966ac106bf6SEd Tanous asyncResp->res 967ac106bf6SEd Tanous .jsonValue["Boot"] 968002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 969613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 970cd9a4666SKonstantin Aladyshev 9711e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 972cd9a4666SKonstantin Aladyshev if (rfType.empty()) 973cd9a4666SKonstantin Aladyshev { 974ac106bf6SEd Tanous messages::internalError(asyncResp->res); 975cd9a4666SKonstantin Aladyshev return; 976cd9a4666SKonstantin Aladyshev } 977cd9a4666SKonstantin Aladyshev 978ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9791e1e598dSJonathan Doman }); 980cd9a4666SKonstantin Aladyshev } 981cd9a4666SKonstantin Aladyshev 982cd9a4666SKonstantin Aladyshev /** 983c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 984491d8ee7SSantosh Puranik * 985ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 986491d8ee7SSantosh Puranik * 987491d8ee7SSantosh Puranik * @return None. 988491d8ee7SSantosh Puranik */ 989c21865c4SKonstantin Aladyshev 990ac106bf6SEd Tanous inline void 991ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 992491d8ee7SSantosh Puranik { 9931e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9941e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9951e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9961e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 997ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9981e1e598dSJonathan Doman const std::string& bootModeStr) { 999491d8ee7SSantosh Puranik if (ec) 1000491d8ee7SSantosh Puranik { 100162598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1002ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1003491d8ee7SSantosh Puranik return; 1004491d8ee7SSantosh Puranik } 1005491d8ee7SSantosh Puranik 100662598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 1007491d8ee7SSantosh Puranik 1008ac106bf6SEd Tanous asyncResp->res 10090fda0f12SGeorge Liu .jsonValue["Boot"] 1010002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 1011002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1012491d8ee7SSantosh Puranik 10131e1e598dSJonathan Doman if (bootModeStr != 1014491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1015491d8ee7SSantosh Puranik { 10161e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 1017491d8ee7SSantosh Puranik if (!rfMode.empty()) 1018491d8ee7SSantosh Puranik { 1019ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1020491d8ee7SSantosh Puranik rfMode; 1021491d8ee7SSantosh Puranik } 1022491d8ee7SSantosh Puranik } 10231e1e598dSJonathan Doman }); 1024491d8ee7SSantosh Puranik } 1025491d8ee7SSantosh Puranik 1026491d8ee7SSantosh Puranik /** 1027c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1028491d8ee7SSantosh Puranik * 1029ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1030491d8ee7SSantosh Puranik * 1031491d8ee7SSantosh Puranik * @return None. 1032491d8ee7SSantosh Puranik */ 1033c21865c4SKonstantin Aladyshev 1034c21865c4SKonstantin Aladyshev inline void 1035ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1036491d8ee7SSantosh Puranik { 10371e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10381e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10391e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10401e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1041ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10421e1e598dSJonathan Doman const std::string& bootSourceStr) { 1043491d8ee7SSantosh Puranik if (ec) 1044491d8ee7SSantosh Puranik { 104562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 10465ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10475ef735c8SNan Zhou { 10485ef735c8SNan Zhou return; 10495ef735c8SNan Zhou } 1050ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1051491d8ee7SSantosh Puranik return; 1052491d8ee7SSantosh Puranik } 1053491d8ee7SSantosh Puranik 105462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 1055491d8ee7SSantosh Puranik 10561e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1057491d8ee7SSantosh Puranik if (!rfSource.empty()) 1058491d8ee7SSantosh Puranik { 1059ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1060ac106bf6SEd Tanous rfSource; 1061491d8ee7SSantosh Puranik } 1062cd9a4666SKonstantin Aladyshev 1063cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1064cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1065ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10661e1e598dSJonathan Doman }); 1067491d8ee7SSantosh Puranik } 1068491d8ee7SSantosh Puranik 1069491d8ee7SSantosh Puranik /** 1070c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1071c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1072c21865c4SKonstantin Aladyshev * state 1073491d8ee7SSantosh Puranik * 1074ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1075491d8ee7SSantosh Puranik * 1076491d8ee7SSantosh Puranik * @return None. 1077491d8ee7SSantosh Puranik */ 1078491d8ee7SSantosh Puranik 1079ac106bf6SEd Tanous inline void processBootOverrideEnable( 1080ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1081c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1082c21865c4SKonstantin Aladyshev { 1083c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1084c21865c4SKonstantin Aladyshev { 1085ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1086ac106bf6SEd Tanous "Disabled"; 1087c21865c4SKonstantin Aladyshev return; 1088c21865c4SKonstantin Aladyshev } 1089c21865c4SKonstantin Aladyshev 1090c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1091c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10921e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10931e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10941e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10951e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1096ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1097491d8ee7SSantosh Puranik if (ec) 1098491d8ee7SSantosh Puranik { 109962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1100ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1101491d8ee7SSantosh Puranik return; 1102491d8ee7SSantosh Puranik } 1103491d8ee7SSantosh Puranik 1104c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1105c21865c4SKonstantin Aladyshev { 1106ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1107ac106bf6SEd Tanous "Once"; 1108c21865c4SKonstantin Aladyshev } 1109c21865c4SKonstantin Aladyshev else 1110c21865c4SKonstantin Aladyshev { 1111ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1112c21865c4SKonstantin Aladyshev "Continuous"; 1113c21865c4SKonstantin Aladyshev } 11141e1e598dSJonathan Doman }); 1115491d8ee7SSantosh Puranik } 1116491d8ee7SSantosh Puranik 1117491d8ee7SSantosh Puranik /** 1118c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1119c21865c4SKonstantin Aladyshev * 1120ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1121c21865c4SKonstantin Aladyshev * 1122c21865c4SKonstantin Aladyshev * @return None. 1123c21865c4SKonstantin Aladyshev */ 1124c21865c4SKonstantin Aladyshev 1125c21865c4SKonstantin Aladyshev inline void 1126ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1127c21865c4SKonstantin Aladyshev { 11281e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11291e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11301e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 11311e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1132ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 11331e1e598dSJonathan Doman const bool bootOverrideEnable) { 1134c21865c4SKonstantin Aladyshev if (ec) 1135c21865c4SKonstantin Aladyshev { 113662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 11375ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11385ef735c8SNan Zhou { 11395ef735c8SNan Zhou return; 11405ef735c8SNan Zhou } 1141ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1142c21865c4SKonstantin Aladyshev return; 1143c21865c4SKonstantin Aladyshev } 1144c21865c4SKonstantin Aladyshev 1145ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11461e1e598dSJonathan Doman }); 1147c21865c4SKonstantin Aladyshev } 1148c21865c4SKonstantin Aladyshev 1149c21865c4SKonstantin Aladyshev /** 1150c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1151c21865c4SKonstantin Aladyshev * 1152ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1153c21865c4SKonstantin Aladyshev * 1154c21865c4SKonstantin Aladyshev * @return None. 1155c21865c4SKonstantin Aladyshev */ 1156ac106bf6SEd Tanous inline void 1157ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1158c21865c4SKonstantin Aladyshev { 115962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1160c21865c4SKonstantin Aladyshev 1161ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1162ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1163ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1164c21865c4SKonstantin Aladyshev } 1165c21865c4SKonstantin Aladyshev 1166c21865c4SKonstantin Aladyshev /** 1167c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1168c0557e1aSGunnar Mills * 1169c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1170c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1171c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1172c0557e1aSGunnar Mills * last power operation time. 1173c0557e1aSGunnar Mills * 1174ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1175c0557e1aSGunnar Mills * 1176c0557e1aSGunnar Mills * @return None. 1177c0557e1aSGunnar Mills */ 1178ac106bf6SEd Tanous inline void 1179ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1180c0557e1aSGunnar Mills { 118162598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1182c0557e1aSGunnar Mills 11831e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11841e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11851e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11861e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1187ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1188ac106bf6SEd Tanous uint64_t lastResetTime) { 1189c0557e1aSGunnar Mills if (ec) 1190c0557e1aSGunnar Mills { 119162598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1192c0557e1aSGunnar Mills return; 1193c0557e1aSGunnar Mills } 1194c0557e1aSGunnar Mills 1195c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1196c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11971e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1198c0557e1aSGunnar Mills 1199c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1200ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 12012b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 12021e1e598dSJonathan Doman }); 1203c0557e1aSGunnar Mills } 1204c0557e1aSGunnar Mills 1205c0557e1aSGunnar Mills /** 1206797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1207797d5daeSCorey Hardesty * 1208797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1209797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1210797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1211797d5daeSCorey Hardesty * dbus. 1212797d5daeSCorey Hardesty * 1213ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1214797d5daeSCorey Hardesty * 1215797d5daeSCorey Hardesty * @return None. 1216797d5daeSCorey Hardesty */ 1217ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1218ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1219797d5daeSCorey Hardesty { 122062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1221797d5daeSCorey Hardesty 1222797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1223797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1224797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1225797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1226ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1227ac106bf6SEd Tanous const boost::system::error_code& ec, 1228797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1229797d5daeSCorey Hardesty if (ec) 1230797d5daeSCorey Hardesty { 1231797d5daeSCorey Hardesty if (ec.value() != EBADR) 1232797d5daeSCorey Hardesty { 123362598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1234ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1235797d5daeSCorey Hardesty } 1236797d5daeSCorey Hardesty return; 1237797d5daeSCorey Hardesty } 1238797d5daeSCorey Hardesty 1239797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1240797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1241797d5daeSCorey Hardesty 1242797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1243797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1244797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1245797d5daeSCorey Hardesty 1246797d5daeSCorey Hardesty if (!success) 1247797d5daeSCorey Hardesty { 1248ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1249797d5daeSCorey Hardesty return; 1250797d5daeSCorey Hardesty } 1251797d5daeSCorey Hardesty 1252797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1253797d5daeSCorey Hardesty { 1254ac106bf6SEd Tanous asyncResp->res 1255ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1256797d5daeSCorey Hardesty *attemptsLeft; 1257797d5daeSCorey Hardesty } 1258797d5daeSCorey Hardesty 1259797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1260797d5daeSCorey Hardesty { 1261ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1262797d5daeSCorey Hardesty *retryAttempts; 1263797d5daeSCorey Hardesty } 1264797d5daeSCorey Hardesty }); 1265797d5daeSCorey Hardesty } 1266797d5daeSCorey Hardesty 1267797d5daeSCorey Hardesty /** 12686bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12696bd5a8d2SGunnar Mills * 1270ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12716bd5a8d2SGunnar Mills * 12726bd5a8d2SGunnar Mills * @return None. 12736bd5a8d2SGunnar Mills */ 1274797d5daeSCorey Hardesty inline void 1275ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12766bd5a8d2SGunnar Mills { 127762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12786bd5a8d2SGunnar Mills 12791e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12801e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12811e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12821e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1283ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1284ac106bf6SEd Tanous bool autoRebootEnabled) { 12856bd5a8d2SGunnar Mills if (ec) 12866bd5a8d2SGunnar Mills { 1287797d5daeSCorey Hardesty if (ec.value() != EBADR) 1288797d5daeSCorey Hardesty { 128962598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1290ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1291797d5daeSCorey Hardesty } 12926bd5a8d2SGunnar Mills return; 12936bd5a8d2SGunnar Mills } 12946bd5a8d2SGunnar Mills 129562598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1296e05aec50SEd Tanous if (autoRebootEnabled) 12976bd5a8d2SGunnar Mills { 1298ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12996bd5a8d2SGunnar Mills "RetryAttempts"; 13006bd5a8d2SGunnar Mills } 13016bd5a8d2SGunnar Mills else 13026bd5a8d2SGunnar Mills { 1303ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1304ac106bf6SEd Tanous "Disabled"; 13056bd5a8d2SGunnar Mills } 1306ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 130769f35306SGunnar Mills 130869f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 130969f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 131069f35306SGunnar Mills // RetryAttempts. 1311ac106bf6SEd Tanous asyncResp->res 1312ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1313ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 13141e1e598dSJonathan Doman }); 13156bd5a8d2SGunnar Mills } 13166bd5a8d2SGunnar Mills 13176bd5a8d2SGunnar Mills /** 1318797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1319797d5daeSCorey Hardesty * 1320ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1321797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1322797d5daeSCorey Hardesty * 1323797d5daeSCorey Hardesty *@return None. 1324797d5daeSCorey Hardesty */ 1325797d5daeSCorey Hardesty 1326ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1327ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1328797d5daeSCorey Hardesty const uint32_t retryAttempts) 1329797d5daeSCorey Hardesty { 133062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 13319ae226faSGeorge Liu sdbusplus::asio::setProperty( 13329ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 13339ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 13349ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 13359ae226faSGeorge Liu retryAttempts, [asyncResp](const boost::system::error_code& ec) { 1336797d5daeSCorey Hardesty if (ec) 1337797d5daeSCorey Hardesty { 133862598e31SEd Tanous BMCWEB_LOG_ERROR( 133962598e31SEd Tanous "DBUS response error: Set setAutomaticRetryAttempts{}", ec); 1340ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1341797d5daeSCorey Hardesty return; 1342797d5daeSCorey Hardesty } 13439ae226faSGeorge Liu }); 1344797d5daeSCorey Hardesty } 1345797d5daeSCorey Hardesty 13468d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 13478d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 13488d69c668SEd Tanous { 13498d69c668SEd Tanous if (value == 13508d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 13518d69c668SEd Tanous { 13528d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 13538d69c668SEd Tanous } 13548d69c668SEd Tanous if (value == 13558d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 13568d69c668SEd Tanous { 13578d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13588d69c668SEd Tanous } 13598d69c668SEd Tanous if (value == 13608d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore") 13618d69c668SEd Tanous { 13628d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13638d69c668SEd Tanous } 13648d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13658d69c668SEd Tanous { 13668d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13678d69c668SEd Tanous } 13688d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13698d69c668SEd Tanous } 1370797d5daeSCorey Hardesty /** 1371c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1372c6a620f2SGeorge Liu * 1373ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1374c6a620f2SGeorge Liu * 1375c6a620f2SGeorge Liu * @return None. 1376c6a620f2SGeorge Liu */ 13778d1b46d7Szhanghch05 inline void 1378ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1379c6a620f2SGeorge Liu { 138062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1381c6a620f2SGeorge Liu 13821e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13831e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13841e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13851e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1386ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13875e7e2dc5SEd Tanous const std::string& policy) { 1388c6a620f2SGeorge Liu if (ec) 1389c6a620f2SGeorge Liu { 139062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1391c6a620f2SGeorge Liu return; 1392c6a620f2SGeorge Liu } 13938d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 13948d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 13958d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1396c6a620f2SGeorge Liu { 1397ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1398c6a620f2SGeorge Liu return; 1399c6a620f2SGeorge Liu } 1400c6a620f2SGeorge Liu 14018d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 14021e1e598dSJonathan Doman }); 1403c6a620f2SGeorge Liu } 1404c6a620f2SGeorge Liu 1405c6a620f2SGeorge Liu /** 14069dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 14079dcfe8c1SAlbert Zhang * 14089dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 14099dcfe8c1SAlbert Zhang * 14109dcfe8c1SAlbert Zhang * @return None. 14119dcfe8c1SAlbert Zhang */ 14129dcfe8c1SAlbert Zhang inline void 14139dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14149dcfe8c1SAlbert Zhang { 141562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 14169dcfe8c1SAlbert Zhang 14179dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 14189dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 14199dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 14209dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 14219dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 14229dcfe8c1SAlbert Zhang if (ec) 14239dcfe8c1SAlbert Zhang { 14249dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 14259dcfe8c1SAlbert Zhang { 14269dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 14279dcfe8c1SAlbert Zhang } 14289dcfe8c1SAlbert Zhang return; 14299dcfe8c1SAlbert Zhang } 14309dcfe8c1SAlbert Zhang 14319dcfe8c1SAlbert Zhang if (value) 14329dcfe8c1SAlbert Zhang { 14339dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault"; 14349dcfe8c1SAlbert Zhang } 14359dcfe8c1SAlbert Zhang else 14369dcfe8c1SAlbert Zhang { 14379dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never"; 14389dcfe8c1SAlbert Zhang } 14399dcfe8c1SAlbert Zhang }); 14409dcfe8c1SAlbert Zhang } 14419dcfe8c1SAlbert Zhang 14429dcfe8c1SAlbert Zhang /** 14431981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 14441981771bSAli Ahmed * TPM is required for booting the host. 14451981771bSAli Ahmed * 1446ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14471981771bSAli Ahmed * 14481981771bSAli Ahmed * @return None. 14491981771bSAli Ahmed */ 14501981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1451ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14521981771bSAli Ahmed { 145362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1454e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1455e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1456e99073f5SGeorge Liu dbus::utility::getSubTree( 1457e99073f5SGeorge Liu "/", 0, interfaces, 1458ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1459b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14601981771bSAli Ahmed if (ec) 14611981771bSAli Ahmed { 146262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", 146362598e31SEd Tanous ec); 14641981771bSAli Ahmed // This is an optional D-Bus object so just return if 14651981771bSAli Ahmed // error occurs 14661981771bSAli Ahmed return; 14671981771bSAli Ahmed } 146826f6976fSEd Tanous if (subtree.empty()) 14691981771bSAli Ahmed { 14701981771bSAli Ahmed // As noted above, this is an optional interface so just return 14711981771bSAli Ahmed // if there is no instance found 14721981771bSAli Ahmed return; 14731981771bSAli Ahmed } 14741981771bSAli Ahmed 14751981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14761981771bSAli Ahmed if (subtree.size() > 1) 14771981771bSAli Ahmed { 147862598e31SEd Tanous BMCWEB_LOG_DEBUG( 147962598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 148062598e31SEd Tanous subtree.size()); 14811981771bSAli Ahmed // Throw an internal Error and return 1482ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14831981771bSAli Ahmed return; 14841981771bSAli Ahmed } 14851981771bSAli Ahmed 14861981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14871981771bSAli Ahmed // field 14881981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14891981771bSAli Ahmed { 149062598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1491ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14921981771bSAli Ahmed return; 14931981771bSAli Ahmed } 14941981771bSAli Ahmed 14951981771bSAli Ahmed const std::string& path = subtree[0].first; 14961981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14971981771bSAli Ahmed 14981981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14991e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 15001e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 15011e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1502ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1503ac106bf6SEd Tanous bool tpmRequired) { 15048a592810SEd Tanous if (ec2) 15051981771bSAli Ahmed { 150662598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error on TPM.Policy Get{}", 150762598e31SEd Tanous ec2); 1508ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15091981771bSAli Ahmed return; 15101981771bSAli Ahmed } 15111981771bSAli Ahmed 15121e1e598dSJonathan Doman if (tpmRequired) 15131981771bSAli Ahmed { 1514ac106bf6SEd Tanous asyncResp->res 1515ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15161981771bSAli Ahmed "Required"; 15171981771bSAli Ahmed } 15181981771bSAli Ahmed else 15191981771bSAli Ahmed { 1520ac106bf6SEd Tanous asyncResp->res 1521ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15221981771bSAli Ahmed "Disabled"; 15231981771bSAli Ahmed } 15241e1e598dSJonathan Doman }); 1525e99073f5SGeorge Liu }); 15261981771bSAli Ahmed } 15271981771bSAli Ahmed 15281981771bSAli Ahmed /** 15291c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 15301c05dae3SAli Ahmed * TPM is required for booting the host. 15311c05dae3SAli Ahmed * 1532ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 15331c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 15341c05dae3SAli Ahmed * 15351c05dae3SAli Ahmed * @return None. 15361c05dae3SAli Ahmed */ 15371c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1538ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 15391c05dae3SAli Ahmed { 154062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1541e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1542e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1543e99073f5SGeorge Liu dbus::utility::getSubTree( 1544e99073f5SGeorge Liu "/", 0, interfaces, 1545ac106bf6SEd Tanous [asyncResp, 1546e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1547e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15481c05dae3SAli Ahmed if (ec) 15491c05dae3SAli Ahmed { 155062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", 155162598e31SEd Tanous ec); 1552ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15531c05dae3SAli Ahmed return; 15541c05dae3SAli Ahmed } 155526f6976fSEd Tanous if (subtree.empty()) 15561c05dae3SAli Ahmed { 1557ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 15581c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15591c05dae3SAli Ahmed return; 15601c05dae3SAli Ahmed } 15611c05dae3SAli Ahmed 15621c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15631c05dae3SAli Ahmed if (subtree.size() > 1) 15641c05dae3SAli Ahmed { 156562598e31SEd Tanous BMCWEB_LOG_DEBUG( 156662598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 156762598e31SEd Tanous subtree.size()); 15681c05dae3SAli Ahmed // Throw an internal Error and return 1569ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15701c05dae3SAli Ahmed return; 15711c05dae3SAli Ahmed } 15721c05dae3SAli Ahmed 15731c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15741c05dae3SAli Ahmed // field 15751c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15761c05dae3SAli Ahmed { 157762598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1578ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15791c05dae3SAli Ahmed return; 15801c05dae3SAli Ahmed } 15811c05dae3SAli Ahmed 15821c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15831c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15841c05dae3SAli Ahmed 15851c05dae3SAli Ahmed if (serv.empty()) 15861c05dae3SAli Ahmed { 158762598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1588ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15891c05dae3SAli Ahmed return; 15901c05dae3SAli Ahmed } 15911c05dae3SAli Ahmed 15921c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 15939ae226faSGeorge Liu sdbusplus::asio::setProperty( 15949ae226faSGeorge Liu *crow::connections::systemBus, serv, path, 15959ae226faSGeorge Liu "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired, 1596ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 15978a592810SEd Tanous if (ec2) 15981c05dae3SAli Ahmed { 159962598e31SEd Tanous BMCWEB_LOG_DEBUG( 160062598e31SEd Tanous "DBUS response error: Set TrustedModuleRequiredToBoot{}", 160162598e31SEd Tanous ec2); 1602ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16031c05dae3SAli Ahmed return; 16041c05dae3SAli Ahmed } 160562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done."); 16069ae226faSGeorge Liu }); 1607e99073f5SGeorge Liu }); 16081c05dae3SAli Ahmed } 16091c05dae3SAli Ahmed 16101c05dae3SAli Ahmed /** 1611491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1612491d8ee7SSantosh Puranik * 1613ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1614cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1615cd9a4666SKonstantin Aladyshev * @return Integer error code. 1616cd9a4666SKonstantin Aladyshev */ 1617ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1618cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1619cd9a4666SKonstantin Aladyshev { 1620c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1621cd9a4666SKonstantin Aladyshev 1622c21865c4SKonstantin Aladyshev if (!bootType) 1623cd9a4666SKonstantin Aladyshev { 1624c21865c4SKonstantin Aladyshev return; 1625c21865c4SKonstantin Aladyshev } 1626c21865c4SKonstantin Aladyshev 1627cd9a4666SKonstantin Aladyshev // Source target specified 162862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1629cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1630cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1631cd9a4666SKonstantin Aladyshev { 1632cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1633cd9a4666SKonstantin Aladyshev } 1634cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1635cd9a4666SKonstantin Aladyshev { 1636cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1637cd9a4666SKonstantin Aladyshev } 1638cd9a4666SKonstantin Aladyshev else 1639cd9a4666SKonstantin Aladyshev { 164062598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 164162598e31SEd Tanous "BootSourceOverrideMode: {}", 164262598e31SEd Tanous *bootType); 1643ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1644cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1645cd9a4666SKonstantin Aladyshev return; 1646cd9a4666SKonstantin Aladyshev } 1647cd9a4666SKonstantin Aladyshev 1648cd9a4666SKonstantin Aladyshev // Act on validated parameters 164962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1650cd9a4666SKonstantin Aladyshev 16519ae226faSGeorge Liu sdbusplus::asio::setProperty( 16529ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 16539ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 16549ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr, 1655ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1656cd9a4666SKonstantin Aladyshev if (ec) 1657cd9a4666SKonstantin Aladyshev { 165862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1659cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1660cd9a4666SKonstantin Aladyshev { 1661ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1662cd9a4666SKonstantin Aladyshev return; 1663cd9a4666SKonstantin Aladyshev } 1664ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1665cd9a4666SKonstantin Aladyshev return; 1666cd9a4666SKonstantin Aladyshev } 166762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type update done."); 16689ae226faSGeorge Liu }); 1669cd9a4666SKonstantin Aladyshev } 1670cd9a4666SKonstantin Aladyshev 1671cd9a4666SKonstantin Aladyshev /** 1672cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1673cd9a4666SKonstantin Aladyshev * 1674ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1675ac106bf6SEd Tanous * message. 1676c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1677c21865c4SKonstantin Aladyshev * @return Integer error code. 1678c21865c4SKonstantin Aladyshev */ 1679ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1680c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1681c21865c4SKonstantin Aladyshev { 1682c21865c4SKonstantin Aladyshev if (!bootEnable) 1683c21865c4SKonstantin Aladyshev { 1684c21865c4SKonstantin Aladyshev return; 1685c21865c4SKonstantin Aladyshev } 1686c21865c4SKonstantin Aladyshev // Source target specified 168762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1688c21865c4SKonstantin Aladyshev 1689c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1690c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1691c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1692c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1693c21865c4SKonstantin Aladyshev { 1694c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1695c21865c4SKonstantin Aladyshev } 1696c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1697c21865c4SKonstantin Aladyshev { 1698c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1699c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1700c21865c4SKonstantin Aladyshev } 1701c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1702c21865c4SKonstantin Aladyshev { 1703c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1704c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1705c21865c4SKonstantin Aladyshev } 1706c21865c4SKonstantin Aladyshev else 1707c21865c4SKonstantin Aladyshev { 170862598e31SEd Tanous BMCWEB_LOG_DEBUG( 170962598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 171062598e31SEd Tanous *bootEnable); 1711ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1712c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1713c21865c4SKonstantin Aladyshev return; 1714c21865c4SKonstantin Aladyshev } 1715c21865c4SKonstantin Aladyshev 1716c21865c4SKonstantin Aladyshev // Act on validated parameters 171762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1718c21865c4SKonstantin Aladyshev 17199ae226faSGeorge Liu sdbusplus::asio::setProperty( 17209ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17219ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 17229ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable, 1723ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 17248a592810SEd Tanous if (ec2) 1725c21865c4SKonstantin Aladyshev { 172662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec2); 1727ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1728c21865c4SKonstantin Aladyshev return; 1729c21865c4SKonstantin Aladyshev } 173062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot override enable update done."); 17319ae226faSGeorge Liu }); 1732c21865c4SKonstantin Aladyshev 1733c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1734c21865c4SKonstantin Aladyshev { 1735c21865c4SKonstantin Aladyshev return; 1736c21865c4SKonstantin Aladyshev } 1737c21865c4SKonstantin Aladyshev 1738c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1739c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 174062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 174162598e31SEd Tanous bootOverridePersistent); 1742c21865c4SKonstantin Aladyshev 17439ae226faSGeorge Liu sdbusplus::asio::setProperty( 17449ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17459ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot/one_time", 17469ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent, 1747ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1748c21865c4SKonstantin Aladyshev if (ec) 1749c21865c4SKonstantin Aladyshev { 175062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1751ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1752c21865c4SKonstantin Aladyshev return; 1753c21865c4SKonstantin Aladyshev } 175462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot one_time update done."); 17559ae226faSGeorge Liu }); 1756c21865c4SKonstantin Aladyshev } 1757c21865c4SKonstantin Aladyshev 1758c21865c4SKonstantin Aladyshev /** 1759c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1760c21865c4SKonstantin Aladyshev * 1761ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1762491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1763491d8ee7SSantosh Puranik * 1764265c1602SJohnathan Mantey * @return Integer error code. 1765491d8ee7SSantosh Puranik */ 1766ac106bf6SEd Tanous inline void 1767ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1768cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1769491d8ee7SSantosh Puranik { 1770c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1771c21865c4SKonstantin Aladyshev std::string bootModeStr; 1772944ffaf9SJohnathan Mantey 1773c21865c4SKonstantin Aladyshev if (!bootSource) 1774491d8ee7SSantosh Puranik { 1775c21865c4SKonstantin Aladyshev return; 1776c21865c4SKonstantin Aladyshev } 1777c21865c4SKonstantin Aladyshev 1778491d8ee7SSantosh Puranik // Source target specified 177962598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1780491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1781ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1782ac106bf6SEd Tanous bootModeStr) != 0) 1783491d8ee7SSantosh Puranik { 178462598e31SEd Tanous BMCWEB_LOG_DEBUG( 178562598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 178662598e31SEd Tanous *bootSource); 1787ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1788491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1789491d8ee7SSantosh Puranik return; 1790491d8ee7SSantosh Puranik } 1791491d8ee7SSantosh Puranik 1792944ffaf9SJohnathan Mantey // Act on validated parameters 179362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 179462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1795944ffaf9SJohnathan Mantey 17969ae226faSGeorge Liu sdbusplus::asio::setProperty( 17979ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17989ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 17999ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr, 1800ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1801491d8ee7SSantosh Puranik if (ec) 1802491d8ee7SSantosh Puranik { 180362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1804ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1805491d8ee7SSantosh Puranik return; 1806491d8ee7SSantosh Puranik } 180762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source update done."); 18089ae226faSGeorge Liu }); 1809944ffaf9SJohnathan Mantey 18109ae226faSGeorge Liu sdbusplus::asio::setProperty( 18119ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 18129ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 18139ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr, 1814ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1815491d8ee7SSantosh Puranik if (ec) 1816491d8ee7SSantosh Puranik { 181762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1818ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1819491d8ee7SSantosh Puranik return; 1820491d8ee7SSantosh Puranik } 182162598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode update done."); 18229ae226faSGeorge Liu }); 1823cd9a4666SKonstantin Aladyshev } 1824944ffaf9SJohnathan Mantey 1825cd9a4666SKonstantin Aladyshev /** 1826c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1827491d8ee7SSantosh Puranik * 1828ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1829491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1830cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1831491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1832491d8ee7SSantosh Puranik * 1833265c1602SJohnathan Mantey * @return Integer error code. 1834491d8ee7SSantosh Puranik */ 1835c21865c4SKonstantin Aladyshev 1836ac106bf6SEd Tanous inline void 1837ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1838c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1839c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1840c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1841491d8ee7SSantosh Puranik { 184262598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1843491d8ee7SSantosh Puranik 1844ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1845ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1846ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1847491d8ee7SSantosh Puranik } 1848491d8ee7SSantosh Puranik 1849c6a620f2SGeorge Liu /** 185098e386ecSGunnar Mills * @brief Sets AssetTag 185198e386ecSGunnar Mills * 1852ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 185398e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 185498e386ecSGunnar Mills * 185598e386ecSGunnar Mills * @return None. 185698e386ecSGunnar Mills */ 1857ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 185898e386ecSGunnar Mills const std::string& assetTag) 185998e386ecSGunnar Mills { 1860e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1861e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1862e99073f5SGeorge Liu dbus::utility::getSubTree( 1863e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1864ac106bf6SEd Tanous [asyncResp, 1865e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1866b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 186798e386ecSGunnar Mills if (ec) 186898e386ecSGunnar Mills { 186962598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1870ac106bf6SEd Tanous messages::internalError(asyncResp->res); 187198e386ecSGunnar Mills return; 187298e386ecSGunnar Mills } 187326f6976fSEd Tanous if (subtree.empty()) 187498e386ecSGunnar Mills { 187562598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1876ac106bf6SEd Tanous messages::internalError(asyncResp->res); 187798e386ecSGunnar Mills return; 187898e386ecSGunnar Mills } 187998e386ecSGunnar Mills // Assume only 1 system D-Bus object 188098e386ecSGunnar Mills // Throw an error if there is more than 1 188198e386ecSGunnar Mills if (subtree.size() > 1) 188298e386ecSGunnar Mills { 188362598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1884ac106bf6SEd Tanous messages::internalError(asyncResp->res); 188598e386ecSGunnar Mills return; 188698e386ecSGunnar Mills } 188798e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 188898e386ecSGunnar Mills { 188962598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1890ac106bf6SEd Tanous messages::internalError(asyncResp->res); 189198e386ecSGunnar Mills return; 189298e386ecSGunnar Mills } 189398e386ecSGunnar Mills 189498e386ecSGunnar Mills const std::string& path = subtree[0].first; 189598e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 189698e386ecSGunnar Mills 189798e386ecSGunnar Mills if (service.empty()) 189898e386ecSGunnar Mills { 189962598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1900ac106bf6SEd Tanous messages::internalError(asyncResp->res); 190198e386ecSGunnar Mills return; 190298e386ecSGunnar Mills } 190398e386ecSGunnar Mills 19049ae226faSGeorge Liu sdbusplus::asio::setProperty( 19059ae226faSGeorge Liu *crow::connections::systemBus, service, path, 19069ae226faSGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 19079ae226faSGeorge Liu assetTag, [asyncResp](const boost::system::error_code& ec2) { 190898e386ecSGunnar Mills if (ec2) 190998e386ecSGunnar Mills { 191062598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on AssetTag Set {}", 191162598e31SEd Tanous ec2); 1912ac106bf6SEd Tanous messages::internalError(asyncResp->res); 191398e386ecSGunnar Mills return; 191498e386ecSGunnar Mills } 19159ae226faSGeorge Liu }); 1916e99073f5SGeorge Liu }); 191798e386ecSGunnar Mills } 191898e386ecSGunnar Mills 191998e386ecSGunnar Mills /** 19209dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 19219dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 19229dcfe8c1SAlbert Zhang * 19239dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 19249dcfe8c1SAlbert Zhang * stopBootOnFault 19259dcfe8c1SAlbert Zhang * 19269dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 19279dcfe8c1SAlbert Zhang */ 19289dcfe8c1SAlbert Zhang inline std::optional<bool> 19299dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 19309dcfe8c1SAlbert Zhang { 19319dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 19329dcfe8c1SAlbert Zhang { 19339dcfe8c1SAlbert Zhang return true; 19349dcfe8c1SAlbert Zhang } 19359dcfe8c1SAlbert Zhang 19369dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 19379dcfe8c1SAlbert Zhang { 19389dcfe8c1SAlbert Zhang return false; 19399dcfe8c1SAlbert Zhang } 19409dcfe8c1SAlbert Zhang 19419dcfe8c1SAlbert Zhang return std::nullopt; 19429dcfe8c1SAlbert Zhang } 19439dcfe8c1SAlbert Zhang 19449dcfe8c1SAlbert Zhang /** 19459dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 19469dcfe8c1SAlbert Zhang * 1947*fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 19489dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 19499dcfe8c1SAlbert Zhang * 19509dcfe8c1SAlbert Zhang * @return None. 19519dcfe8c1SAlbert Zhang */ 1952*fc3edfddSEd Tanous inline void 1953*fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19549dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 19559dcfe8c1SAlbert Zhang { 195662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 19579dcfe8c1SAlbert Zhang 19589dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 19599dcfe8c1SAlbert Zhang if (!stopBootEnabled) 19609dcfe8c1SAlbert Zhang { 196162598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 196262598e31SEd Tanous stopBootOnFault); 1963*fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 19649dcfe8c1SAlbert Zhang "StopBootOnFault"); 19659dcfe8c1SAlbert Zhang return; 19669dcfe8c1SAlbert Zhang } 19679dcfe8c1SAlbert Zhang 1968*fc3edfddSEd Tanous sdbusplus::asio::setProperty( 1969*fc3edfddSEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 19709dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 1971*fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1972*fc3edfddSEd Tanous *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) { 19739dcfe8c1SAlbert Zhang if (ec) 19749dcfe8c1SAlbert Zhang { 19759dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 19769dcfe8c1SAlbert Zhang { 1977*fc3edfddSEd Tanous messages::internalError(asyncResp->res); 19789dcfe8c1SAlbert Zhang } 19799dcfe8c1SAlbert Zhang return; 19809dcfe8c1SAlbert Zhang } 19819dcfe8c1SAlbert Zhang }); 19829dcfe8c1SAlbert Zhang } 19839dcfe8c1SAlbert Zhang 19849dcfe8c1SAlbert Zhang /** 198569f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 198669f35306SGunnar Mills * 1987ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 198869f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 198969f35306SGunnar Mills * 199069f35306SGunnar Mills * @return None. 199169f35306SGunnar Mills */ 1992ac106bf6SEd Tanous inline void 1993ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1994f23b7296SEd Tanous const std::string& automaticRetryConfig) 199569f35306SGunnar Mills { 199662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 199769f35306SGunnar Mills 199869f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1999543f4400SEd Tanous bool autoRebootEnabled = false; 200069f35306SGunnar Mills 200169f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 200269f35306SGunnar Mills { 200369f35306SGunnar Mills autoRebootEnabled = false; 200469f35306SGunnar Mills } 200569f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 200669f35306SGunnar Mills { 200769f35306SGunnar Mills autoRebootEnabled = true; 200869f35306SGunnar Mills } 200969f35306SGunnar Mills else 201069f35306SGunnar Mills { 201162598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 201262598e31SEd Tanous automaticRetryConfig); 2013ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 201469f35306SGunnar Mills "AutomaticRetryConfig"); 201569f35306SGunnar Mills return; 201669f35306SGunnar Mills } 201769f35306SGunnar Mills 20189ae226faSGeorge Liu sdbusplus::asio::setProperty( 20199ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20209ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/auto_reboot", 20219ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 20229ae226faSGeorge Liu autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) { 202369f35306SGunnar Mills if (ec) 202469f35306SGunnar Mills { 2025ac106bf6SEd Tanous messages::internalError(asyncResp->res); 202669f35306SGunnar Mills return; 202769f35306SGunnar Mills } 20289ae226faSGeorge Liu }); 202969f35306SGunnar Mills } 203069f35306SGunnar Mills 20318d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 20328d69c668SEd Tanous { 20338d69c668SEd Tanous if (policy == "AlwaysOn") 20348d69c668SEd Tanous { 20358d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 20368d69c668SEd Tanous } 20378d69c668SEd Tanous if (policy == "AlwaysOff") 20388d69c668SEd Tanous { 20398d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 20408d69c668SEd Tanous } 20418d69c668SEd Tanous if (policy == "LastState") 20428d69c668SEd Tanous { 20438d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 20448d69c668SEd Tanous } 20458d69c668SEd Tanous return ""; 20468d69c668SEd Tanous } 20478d69c668SEd Tanous 204869f35306SGunnar Mills /** 2049c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 2050c6a620f2SGeorge Liu * 2051ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2052c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 2053c6a620f2SGeorge Liu * 2054c6a620f2SGeorge Liu * @return None. 2055c6a620f2SGeorge Liu */ 20568d1b46d7Szhanghch05 inline void 2057ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20588d69c668SEd Tanous std::string_view policy) 2059c6a620f2SGeorge Liu { 206062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 2061c6a620f2SGeorge Liu 20628d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 2063c6a620f2SGeorge Liu 20648d69c668SEd Tanous if (powerRestorePolicy.empty()) 2065c6a620f2SGeorge Liu { 2066ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 20674e69c904SGunnar Mills "PowerRestorePolicy"); 2068c6a620f2SGeorge Liu return; 2069c6a620f2SGeorge Liu } 2070c6a620f2SGeorge Liu 20719ae226faSGeorge Liu sdbusplus::asio::setProperty( 20729ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20739ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 20749ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 20759ae226faSGeorge Liu powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) { 2076c6a620f2SGeorge Liu if (ec) 2077c6a620f2SGeorge Liu { 2078ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2079c6a620f2SGeorge Liu return; 2080c6a620f2SGeorge Liu } 20819ae226faSGeorge Liu }); 2082c6a620f2SGeorge Liu } 2083c6a620f2SGeorge Liu 2084a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 2085a6349918SAppaRao Puli /** 2086a6349918SAppaRao Puli * @brief Retrieves provisioning status 2087a6349918SAppaRao Puli * 2088ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 2089a6349918SAppaRao Puli * 2090a6349918SAppaRao Puli * @return None. 2091a6349918SAppaRao Puli */ 2092ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 2093a6349918SAppaRao Puli { 209462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 2095bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2096bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 2097bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 2098ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2099b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 2100b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2101ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2102ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 210350626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 210450626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 210550626f4fSJames Feist 2106a6349918SAppaRao Puli if (ec) 2107a6349918SAppaRao Puli { 210862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 2109b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2110b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2111a6349918SAppaRao Puli return; 2112a6349918SAppaRao Puli } 2113a6349918SAppaRao Puli 2114a6349918SAppaRao Puli const bool* provState = nullptr; 2115a6349918SAppaRao Puli const bool* lockState = nullptr; 2116bc1d29deSKrzysztof Grobelny 2117bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 21180d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 21190d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 2120bc1d29deSKrzysztof Grobelny 2121bc1d29deSKrzysztof Grobelny if (!success) 2122a6349918SAppaRao Puli { 2123ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2124bc1d29deSKrzysztof Grobelny return; 2125a6349918SAppaRao Puli } 2126a6349918SAppaRao Puli 2127a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2128a6349918SAppaRao Puli { 212962598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 2130ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2131a6349918SAppaRao Puli return; 2132a6349918SAppaRao Puli } 2133a6349918SAppaRao Puli 2134a6349918SAppaRao Puli if (*provState == true) 2135a6349918SAppaRao Puli { 2136a6349918SAppaRao Puli if (*lockState == true) 2137a6349918SAppaRao Puli { 2138a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2139a6349918SAppaRao Puli } 2140a6349918SAppaRao Puli else 2141a6349918SAppaRao Puli { 2142a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2143a6349918SAppaRao Puli } 2144a6349918SAppaRao Puli } 2145a6349918SAppaRao Puli else 2146a6349918SAppaRao Puli { 2147a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2148a6349918SAppaRao Puli } 2149bc1d29deSKrzysztof Grobelny }); 2150a6349918SAppaRao Puli } 2151a6349918SAppaRao Puli #endif 2152a6349918SAppaRao Puli 2153491d8ee7SSantosh Puranik /** 21543a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 21553a2d0424SChris Cain * 2156ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21573a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 21583a2d0424SChris Cain * 21593a2d0424SChris Cain * @return None. 21603a2d0424SChris Cain */ 2161ac106bf6SEd Tanous inline void 2162ac106bf6SEd Tanous translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 21633a2d0424SChris Cain const std::string& modeValue) 21643a2d0424SChris Cain { 21650fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 21663a2d0424SChris Cain { 2167ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "Static"; 21683a2d0424SChris Cain } 21690fda0f12SGeorge Liu else if ( 21700fda0f12SGeorge Liu modeValue == 21710fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 21723a2d0424SChris Cain { 2173ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 21743a2d0424SChris Cain } 21750fda0f12SGeorge Liu else if (modeValue == 21760fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 21773a2d0424SChris Cain { 2178ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "PowerSaving"; 21793a2d0424SChris Cain } 21800fda0f12SGeorge Liu else if (modeValue == 21810fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 21823a2d0424SChris Cain { 2183ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "OEM"; 21843a2d0424SChris Cain } 21853a2d0424SChris Cain else 21863a2d0424SChris Cain { 21873a2d0424SChris Cain // Any other values would be invalid 218862598e31SEd Tanous BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue); 2189ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21903a2d0424SChris Cain } 21913a2d0424SChris Cain } 21923a2d0424SChris Cain 21933a2d0424SChris Cain /** 21943a2d0424SChris Cain * @brief Retrieves system power mode 21953a2d0424SChris Cain * 2196ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21973a2d0424SChris Cain * 21983a2d0424SChris Cain * @return None. 21993a2d0424SChris Cain */ 2200ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 22013a2d0424SChris Cain { 220262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 22033a2d0424SChris Cain 22043a2d0424SChris Cain // Get Power Mode object path: 2205e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2206e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2207e99073f5SGeorge Liu dbus::utility::getSubTree( 2208e99073f5SGeorge Liu "/", 0, interfaces, 2209ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2210b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22113a2d0424SChris Cain if (ec) 22123a2d0424SChris Cain { 221362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}", 221462598e31SEd Tanous ec); 22153a2d0424SChris Cain // This is an optional D-Bus object so just return if 22163a2d0424SChris Cain // error occurs 22173a2d0424SChris Cain return; 22183a2d0424SChris Cain } 22193a2d0424SChris Cain if (subtree.empty()) 22203a2d0424SChris Cain { 22213a2d0424SChris Cain // As noted above, this is an optional interface so just return 22223a2d0424SChris Cain // if there is no instance found 22233a2d0424SChris Cain return; 22243a2d0424SChris Cain } 22253a2d0424SChris Cain if (subtree.size() > 1) 22263a2d0424SChris Cain { 22273a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22283a2d0424SChris Cain // error 222962598e31SEd Tanous BMCWEB_LOG_DEBUG( 223062598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 223162598e31SEd Tanous subtree.size()); 2232ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22333a2d0424SChris Cain return; 22343a2d0424SChris Cain } 22353a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22363a2d0424SChris Cain { 223762598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2238ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22393a2d0424SChris Cain return; 22403a2d0424SChris Cain } 22413a2d0424SChris Cain const std::string& path = subtree[0].first; 22423a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22433a2d0424SChris Cain if (service.empty()) 22443a2d0424SChris Cain { 224562598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2246ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22473a2d0424SChris Cain return; 22483a2d0424SChris Cain } 22493a2d0424SChris Cain // Valid Power Mode object found, now read the current value 22501e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 22511e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 22521e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2253ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 22541e1e598dSJonathan Doman const std::string& pmode) { 22558a592810SEd Tanous if (ec2) 22563a2d0424SChris Cain { 225762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on PowerMode Get: {}", 225862598e31SEd Tanous ec2); 2259ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22603a2d0424SChris Cain return; 22613a2d0424SChris Cain } 22623a2d0424SChris Cain 2263ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2264002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 22653a2d0424SChris Cain 226662598e31SEd Tanous BMCWEB_LOG_DEBUG("Current power mode: {}", pmode); 2267ac106bf6SEd Tanous translatePowerMode(asyncResp, pmode); 22681e1e598dSJonathan Doman }); 2269e99073f5SGeorge Liu }); 22703a2d0424SChris Cain } 22713a2d0424SChris Cain 22723a2d0424SChris Cain /** 22733a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 22743a2d0424SChris Cain * name associated with that string 22753a2d0424SChris Cain * 2276ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22773a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 22783a2d0424SChris Cain * 22793a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22803a2d0424SChris Cain */ 22813a2d0424SChris Cain inline std::string 2282ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22833a2d0424SChris Cain const std::string& modeString) 22843a2d0424SChris Cain { 22853a2d0424SChris Cain std::string mode; 22863a2d0424SChris Cain 22873a2d0424SChris Cain if (modeString == "Static") 22883a2d0424SChris Cain { 22893a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22903a2d0424SChris Cain } 22913a2d0424SChris Cain else if (modeString == "MaximumPerformance") 22923a2d0424SChris Cain { 22930fda0f12SGeorge Liu mode = 22940fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 22953a2d0424SChris Cain } 22963a2d0424SChris Cain else if (modeString == "PowerSaving") 22973a2d0424SChris Cain { 22983a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22993a2d0424SChris Cain } 23003a2d0424SChris Cain else 23013a2d0424SChris Cain { 2302ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, modeString, 2303ac106bf6SEd Tanous "PowerMode"); 23043a2d0424SChris Cain } 23053a2d0424SChris Cain return mode; 23063a2d0424SChris Cain } 23073a2d0424SChris Cain 23083a2d0424SChris Cain /** 23093a2d0424SChris Cain * @brief Sets system power mode. 23103a2d0424SChris Cain * 2311ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 23123a2d0424SChris Cain * @param[in] pmode System power mode from request. 23133a2d0424SChris Cain * 23143a2d0424SChris Cain * @return None. 23153a2d0424SChris Cain */ 2316ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 23173a2d0424SChris Cain const std::string& pmode) 23183a2d0424SChris Cain { 231962598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 23203a2d0424SChris Cain 2321ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 23223a2d0424SChris Cain if (powerMode.empty()) 23233a2d0424SChris Cain { 23243a2d0424SChris Cain return; 23253a2d0424SChris Cain } 23263a2d0424SChris Cain 23273a2d0424SChris Cain // Get Power Mode object path: 2328e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2329e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2330e99073f5SGeorge Liu dbus::utility::getSubTree( 2331e99073f5SGeorge Liu "/", 0, interfaces, 2332ac106bf6SEd Tanous [asyncResp, 2333e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2334b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23353a2d0424SChris Cain if (ec) 23363a2d0424SChris Cain { 233762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}", 233862598e31SEd Tanous ec); 23393a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2340ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23413a2d0424SChris Cain return; 23423a2d0424SChris Cain } 23433a2d0424SChris Cain if (subtree.empty()) 23443a2d0424SChris Cain { 23453a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2346ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 23473a2d0424SChris Cain "PowerMode"); 23483a2d0424SChris Cain return; 23493a2d0424SChris Cain } 23503a2d0424SChris Cain if (subtree.size() > 1) 23513a2d0424SChris Cain { 23523a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23533a2d0424SChris Cain // error 235462598e31SEd Tanous BMCWEB_LOG_DEBUG( 235562598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 235662598e31SEd Tanous subtree.size()); 2357ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23583a2d0424SChris Cain return; 23593a2d0424SChris Cain } 23603a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23613a2d0424SChris Cain { 236262598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2363ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23643a2d0424SChris Cain return; 23653a2d0424SChris Cain } 23663a2d0424SChris Cain const std::string& path = subtree[0].first; 23673a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23683a2d0424SChris Cain if (service.empty()) 23693a2d0424SChris Cain { 237062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2371ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23723a2d0424SChris Cain return; 23733a2d0424SChris Cain } 23743a2d0424SChris Cain 237562598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 23763a2d0424SChris Cain 23773a2d0424SChris Cain // Set the Power Mode property 23789ae226faSGeorge Liu sdbusplus::asio::setProperty( 23799ae226faSGeorge Liu *crow::connections::systemBus, service, path, 23809ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode, 2381ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 23828a592810SEd Tanous if (ec2) 23833a2d0424SChris Cain { 2384ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23853a2d0424SChris Cain return; 23863a2d0424SChris Cain } 23879ae226faSGeorge Liu }); 2388e99073f5SGeorge Liu }); 23893a2d0424SChris Cain } 23903a2d0424SChris Cain 23913a2d0424SChris Cain /** 239251709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 239351709ffdSYong Li * 239451709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 239551709ffdSYong Li * 239651709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 239751709ffdSYong Li * translation cannot be done, returns an empty string. 239851709ffdSYong Li */ 239923a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 240051709ffdSYong Li { 240151709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 240251709ffdSYong Li { 240351709ffdSYong Li return "None"; 240451709ffdSYong Li } 24053174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 240651709ffdSYong Li { 240751709ffdSYong Li return "ResetSystem"; 240851709ffdSYong Li } 24093174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 241051709ffdSYong Li { 241151709ffdSYong Li return "PowerDown"; 241251709ffdSYong Li } 24133174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 241451709ffdSYong Li { 241551709ffdSYong Li return "PowerCycle"; 241651709ffdSYong Li } 241751709ffdSYong Li 241851709ffdSYong Li return ""; 241951709ffdSYong Li } 242051709ffdSYong Li 242151709ffdSYong Li /** 2422c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2423c45f0082SYong Li * 2424c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2425c45f0082SYong Li * 2426c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2427c45f0082SYong Li *If translation cannot be done, returns an empty string. 2428c45f0082SYong Li */ 2429c45f0082SYong Li 243023a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2431c45f0082SYong Li { 2432c45f0082SYong Li if (rfAction == "None") 2433c45f0082SYong Li { 2434c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2435c45f0082SYong Li } 24363174e4dfSEd Tanous if (rfAction == "PowerCycle") 2437c45f0082SYong Li { 2438c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2439c45f0082SYong Li } 24403174e4dfSEd Tanous if (rfAction == "PowerDown") 2441c45f0082SYong Li { 2442c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2443c45f0082SYong Li } 24443174e4dfSEd Tanous if (rfAction == "ResetSystem") 2445c45f0082SYong Li { 2446c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2447c45f0082SYong Li } 2448c45f0082SYong Li 2449c45f0082SYong Li return ""; 2450c45f0082SYong Li } 2451c45f0082SYong Li 2452c45f0082SYong Li /** 245351709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 245451709ffdSYong Li * 2455ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 245651709ffdSYong Li * 245751709ffdSYong Li * @return None. 245851709ffdSYong Li */ 24598d1b46d7Szhanghch05 inline void 2460ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 246151709ffdSYong Li { 246262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2463bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2464bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2465bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2466bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2467ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2468b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 246951709ffdSYong Li if (ec) 247051709ffdSYong Li { 247151709ffdSYong Li // watchdog service is stopped 247262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 247351709ffdSYong Li return; 247451709ffdSYong Li } 247551709ffdSYong Li 247662598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 247751709ffdSYong Li 247851709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2479ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 248051709ffdSYong Li 248151709ffdSYong Li // watchdog service is running/enabled 248251709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 248351709ffdSYong Li 2484bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2485bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 248651709ffdSYong Li 2487bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2488bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2489bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2490bc1d29deSKrzysztof Grobelny 2491bc1d29deSKrzysztof Grobelny if (!success) 249251709ffdSYong Li { 2493ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2494601af5edSChicago Duan return; 249551709ffdSYong Li } 249651709ffdSYong Li 2497bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 249851709ffdSYong Li { 2499bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 250051709ffdSYong Li } 250151709ffdSYong Li 2502bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2503bc1d29deSKrzysztof Grobelny { 2504bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 250551709ffdSYong Li if (action.empty()) 250651709ffdSYong Li { 2507ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2508601af5edSChicago Duan return; 250951709ffdSYong Li } 251051709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 251151709ffdSYong Li } 2512bc1d29deSKrzysztof Grobelny }); 251351709ffdSYong Li } 251451709ffdSYong Li 251551709ffdSYong Li /** 2516c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2517c45f0082SYong Li * 2518ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2519c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2520c45f0082SYong Li * RF request. 2521c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2522c45f0082SYong Li * 2523c45f0082SYong Li * @return None. 2524c45f0082SYong Li */ 2525ac106bf6SEd Tanous inline void 2526ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2527c45f0082SYong Li const std::optional<bool> wdtEnable, 2528c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2529c45f0082SYong Li { 253062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2531c45f0082SYong Li 2532c45f0082SYong Li if (wdtTimeOutAction) 2533c45f0082SYong Li { 2534c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2535c45f0082SYong Li // check if TimeOut Action is Valid 2536c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2537c45f0082SYong Li { 253862598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 253962598e31SEd Tanous *wdtTimeOutAction); 2540ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2541c45f0082SYong Li "TimeoutAction"); 2542c45f0082SYong Li return; 2543c45f0082SYong Li } 2544c45f0082SYong Li 25459ae226faSGeorge Liu sdbusplus::asio::setProperty( 25469ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25479ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25489ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 25499ae226faSGeorge Liu wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) { 2550c45f0082SYong Li if (ec) 2551c45f0082SYong Li { 255262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 2553ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2554c45f0082SYong Li return; 2555c45f0082SYong Li } 25569ae226faSGeorge Liu }); 2557c45f0082SYong Li } 2558c45f0082SYong Li 2559c45f0082SYong Li if (wdtEnable) 2560c45f0082SYong Li { 25619ae226faSGeorge Liu sdbusplus::asio::setProperty( 25629ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25639ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25649ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable, 2565ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2566c45f0082SYong Li if (ec) 2567c45f0082SYong Li { 256862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 2569ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2570c45f0082SYong Li return; 2571c45f0082SYong Li } 25729ae226faSGeorge Liu }); 2573c45f0082SYong Li } 2574c45f0082SYong Li } 2575c45f0082SYong Li 257637bbf98cSChris Cain /** 257737bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 257837bbf98cSChris Cain * 2579ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 258037bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 258137bbf98cSChris Cain * 258237bbf98cSChris Cain * @return true if successful 258337bbf98cSChris Cain */ 25841e5b7c88SJiaqing Zhao inline bool 2585ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25861e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 258737bbf98cSChris Cain { 2588bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2589bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2590bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2591bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2592bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2593bc1d29deSKrzysztof Grobelny 2594bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2595bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 25962661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 25972661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 25982661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2599bc1d29deSKrzysztof Grobelny 2600bc1d29deSKrzysztof Grobelny if (!success) 260137bbf98cSChris Cain { 260237bbf98cSChris Cain return false; 260337bbf98cSChris Cain } 2604bc1d29deSKrzysztof Grobelny 2605bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 260637bbf98cSChris Cain { 2607ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 260837bbf98cSChris Cain } 2609bc1d29deSKrzysztof Grobelny 2610bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 261137bbf98cSChris Cain { 2612ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2613bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 261437bbf98cSChris Cain } 2615bc1d29deSKrzysztof Grobelny 2616bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2617bc1d29deSKrzysztof Grobelny { 2618bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2619ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 262037bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 262137bbf98cSChris Cain .count(); 262237bbf98cSChris Cain } 2623bc1d29deSKrzysztof Grobelny 2624bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 262537bbf98cSChris Cain { 2626ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2627bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 262837bbf98cSChris Cain } 2629bc1d29deSKrzysztof Grobelny 2630bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 263137bbf98cSChris Cain { 2632bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2633ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 263437bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 263537bbf98cSChris Cain .count(); 263637bbf98cSChris Cain } 263737bbf98cSChris Cain 263837bbf98cSChris Cain return true; 263937bbf98cSChris Cain } 264037bbf98cSChris Cain 264137bbf98cSChris Cain /** 264237bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 264337bbf98cSChris Cain * 2644ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 264537bbf98cSChris Cain * 264637bbf98cSChris Cain * @return None. 264737bbf98cSChris Cain */ 2648ac106bf6SEd Tanous inline void 2649ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 265037bbf98cSChris Cain { 265162598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 265237bbf98cSChris Cain 265337bbf98cSChris Cain // Get IdlePowerSaver object path: 2654e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2655e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2656e99073f5SGeorge Liu dbus::utility::getSubTree( 2657e99073f5SGeorge Liu "/", 0, interfaces, 2658ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2659b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 266037bbf98cSChris Cain if (ec) 266137bbf98cSChris Cain { 266262598e31SEd Tanous BMCWEB_LOG_DEBUG( 266362598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 266462598e31SEd Tanous ec); 2665ac106bf6SEd Tanous messages::internalError(asyncResp->res); 266637bbf98cSChris Cain return; 266737bbf98cSChris Cain } 266837bbf98cSChris Cain if (subtree.empty()) 266937bbf98cSChris Cain { 267037bbf98cSChris Cain // This is an optional interface so just return 267137bbf98cSChris Cain // if there is no instance found 267262598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 267337bbf98cSChris Cain return; 267437bbf98cSChris Cain } 267537bbf98cSChris Cain if (subtree.size() > 1) 267637bbf98cSChris Cain { 267737bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 267837bbf98cSChris Cain // is an error 267962598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 268062598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 268162598e31SEd Tanous subtree.size()); 2682ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268337bbf98cSChris Cain return; 268437bbf98cSChris Cain } 268537bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 268637bbf98cSChris Cain { 268762598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2688ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268937bbf98cSChris Cain return; 269037bbf98cSChris Cain } 269137bbf98cSChris Cain const std::string& path = subtree[0].first; 269237bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 269337bbf98cSChris Cain if (service.empty()) 269437bbf98cSChris Cain { 269562598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2696ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269737bbf98cSChris Cain return; 269837bbf98cSChris Cain } 269937bbf98cSChris Cain 270037bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2701bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2702bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2703bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2704ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 27051e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 27068a592810SEd Tanous if (ec2) 270737bbf98cSChris Cain { 270862598e31SEd Tanous BMCWEB_LOG_ERROR( 270962598e31SEd Tanous "DBUS response error on IdlePowerSaver GetAll: {}", ec2); 2710ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271137bbf98cSChris Cain return; 271237bbf98cSChris Cain } 271337bbf98cSChris Cain 2714ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 271537bbf98cSChris Cain { 2716ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271737bbf98cSChris Cain return; 271837bbf98cSChris Cain } 2719bc1d29deSKrzysztof Grobelny }); 2720e99073f5SGeorge Liu }); 272137bbf98cSChris Cain 272262598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 272337bbf98cSChris Cain } 272437bbf98cSChris Cain 272537bbf98cSChris Cain /** 272637bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 272737bbf98cSChris Cain * 2728ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 272937bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 273037bbf98cSChris Cain * RF request. 273137bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 273237bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 273337bbf98cSChris Cain * before entering idle state. 273437bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 273537bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 273637bbf98cSChris Cain * before exiting idle state 273737bbf98cSChris Cain * 273837bbf98cSChris Cain * @return None. 273937bbf98cSChris Cain */ 2740ac106bf6SEd Tanous inline void 2741ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 274237bbf98cSChris Cain const std::optional<bool> ipsEnable, 274337bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 274437bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 274537bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 274637bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 274737bbf98cSChris Cain { 274862598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 274937bbf98cSChris Cain 275037bbf98cSChris Cain // Get IdlePowerSaver object path: 2751e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2752e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2753e99073f5SGeorge Liu dbus::utility::getSubTree( 2754e99073f5SGeorge Liu "/", 0, interfaces, 2755ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2756e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2757b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 275837bbf98cSChris Cain if (ec) 275937bbf98cSChris Cain { 276062598e31SEd Tanous BMCWEB_LOG_DEBUG( 276162598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 276262598e31SEd Tanous ec); 2763ac106bf6SEd Tanous messages::internalError(asyncResp->res); 276437bbf98cSChris Cain return; 276537bbf98cSChris Cain } 276637bbf98cSChris Cain if (subtree.empty()) 276737bbf98cSChris Cain { 276837bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2769ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 277037bbf98cSChris Cain "IdlePowerSaver"); 277137bbf98cSChris Cain return; 277237bbf98cSChris Cain } 277337bbf98cSChris Cain if (subtree.size() > 1) 277437bbf98cSChris Cain { 277537bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 277637bbf98cSChris Cain // is an error 277762598e31SEd Tanous BMCWEB_LOG_DEBUG( 277862598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 277962598e31SEd Tanous subtree.size()); 2780ac106bf6SEd Tanous messages::internalError(asyncResp->res); 278137bbf98cSChris Cain return; 278237bbf98cSChris Cain } 278337bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 278437bbf98cSChris Cain { 278562598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2786ac106bf6SEd Tanous messages::internalError(asyncResp->res); 278737bbf98cSChris Cain return; 278837bbf98cSChris Cain } 278937bbf98cSChris Cain const std::string& path = subtree[0].first; 279037bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 279137bbf98cSChris Cain if (service.empty()) 279237bbf98cSChris Cain { 279362598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2794ac106bf6SEd Tanous messages::internalError(asyncResp->res); 279537bbf98cSChris Cain return; 279637bbf98cSChris Cain } 279737bbf98cSChris Cain 279837bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 279937bbf98cSChris Cain // need to be updated 280037bbf98cSChris Cain 280137bbf98cSChris Cain if (ipsEnable) 280237bbf98cSChris Cain { 28039ae226faSGeorge Liu sdbusplus::asio::setProperty( 28049ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28059ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 28069ae226faSGeorge Liu *ipsEnable, [asyncResp](const boost::system::error_code& ec2) { 28078a592810SEd Tanous if (ec2) 280837bbf98cSChris Cain { 280962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec2); 2810ac106bf6SEd Tanous messages::internalError(asyncResp->res); 281137bbf98cSChris Cain return; 281237bbf98cSChris Cain } 28139ae226faSGeorge Liu }); 281437bbf98cSChris Cain } 281537bbf98cSChris Cain if (ipsEnterUtil) 281637bbf98cSChris Cain { 28179ae226faSGeorge Liu sdbusplus::asio::setProperty( 28189ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28199ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28209ae226faSGeorge Liu "EnterUtilizationPercent", *ipsEnterUtil, 2821ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28228a592810SEd Tanous if (ec2) 282337bbf98cSChris Cain { 282462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec2); 2825ac106bf6SEd Tanous messages::internalError(asyncResp->res); 282637bbf98cSChris Cain return; 282737bbf98cSChris Cain } 28289ae226faSGeorge Liu }); 282937bbf98cSChris Cain } 283037bbf98cSChris Cain if (ipsEnterTime) 283137bbf98cSChris Cain { 283237bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 283337bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 28349ae226faSGeorge Liu sdbusplus::asio::setProperty( 28359ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28369ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28379ae226faSGeorge Liu "EnterDwellTime", timeMilliseconds, 2838ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28398a592810SEd Tanous if (ec2) 284037bbf98cSChris Cain { 284162598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec2); 2842ac106bf6SEd Tanous messages::internalError(asyncResp->res); 284337bbf98cSChris Cain return; 284437bbf98cSChris Cain } 28459ae226faSGeorge Liu }); 284637bbf98cSChris Cain } 284737bbf98cSChris Cain if (ipsExitUtil) 284837bbf98cSChris Cain { 28499ae226faSGeorge Liu sdbusplus::asio::setProperty( 28509ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28519ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28529ae226faSGeorge Liu "ExitUtilizationPercent", *ipsExitUtil, 2853ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28548a592810SEd Tanous if (ec2) 285537bbf98cSChris Cain { 285662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec2); 2857ac106bf6SEd Tanous messages::internalError(asyncResp->res); 285837bbf98cSChris Cain return; 285937bbf98cSChris Cain } 28609ae226faSGeorge Liu }); 286137bbf98cSChris Cain } 286237bbf98cSChris Cain if (ipsExitTime) 286337bbf98cSChris Cain { 286437bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 286537bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 28669ae226faSGeorge Liu sdbusplus::asio::setProperty( 28679ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28689ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28699ae226faSGeorge Liu "ExitDwellTime", timeMilliseconds, 2870ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28718a592810SEd Tanous if (ec2) 287237bbf98cSChris Cain { 287362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec2); 2874ac106bf6SEd Tanous messages::internalError(asyncResp->res); 287537bbf98cSChris Cain return; 287637bbf98cSChris Cain } 28779ae226faSGeorge Liu }); 287837bbf98cSChris Cain } 2879e99073f5SGeorge Liu }); 288037bbf98cSChris Cain 288162598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 288237bbf98cSChris Cain } 288337bbf98cSChris Cain 2884c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2885dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2886dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2887dd60b9edSEd Tanous { 2888dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2889dd60b9edSEd Tanous { 2890dd60b9edSEd Tanous return; 2891dd60b9edSEd Tanous } 2892dd60b9edSEd Tanous asyncResp->res.addHeader( 2893dd60b9edSEd Tanous boost::beast::http::field::link, 2894dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2895dd60b9edSEd Tanous } 2896dd60b9edSEd Tanous 2897c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2898c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2899c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29001abe55efSEd Tanous { 29013ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2902f4c99e70SEd Tanous { 2903f4c99e70SEd Tanous return; 2904f4c99e70SEd Tanous } 2905dd60b9edSEd Tanous 2906dd60b9edSEd Tanous asyncResp->res.addHeader( 2907dd60b9edSEd Tanous boost::beast::http::field::link, 2908dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 29098d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 29100f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 29118d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 29128d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2913462023adSSunitha Harish 29147f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 29157f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 29167f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 29177f3e84a1SEd Tanous { 29187f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 29197f3e84a1SEd Tanous // Option currently returns no systems. TBD 29207f3e84a1SEd Tanous return; 29217f3e84a1SEd Tanous } 29227f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 29237f3e84a1SEd Tanous nlohmann::json::object_t system; 29247f3e84a1SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 29257f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 29261e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2927002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 29281e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2929002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 29305e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 29311e1e598dSJonathan Doman const std::string& /*hostName*/) { 29327f3e84a1SEd Tanous if (ec2) 2933462023adSSunitha Harish { 29347f3e84a1SEd Tanous return; 29357f3e84a1SEd Tanous } 29367f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 29377f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 29387f3e84a1SEd Tanous { 293962598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 29407f3e84a1SEd Tanous return; 29417f3e84a1SEd Tanous } 29427f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 29437f3e84a1SEd Tanous if (count == nullptr) 29447f3e84a1SEd Tanous { 294562598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 29467f3e84a1SEd Tanous return; 29477f3e84a1SEd Tanous } 29487f3e84a1SEd Tanous *count = *count + 1; 294962598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 29507f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 29511476687dSEd Tanous nlohmann::json::object_t hypervisor; 2952002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 29537f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 29541e1e598dSJonathan Doman }); 2955c1e219d5SEd Tanous } 2956c1e219d5SEd Tanous 2957c1e219d5SEd Tanous /** 29587e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 29597e860f15SJohn Edward Broadbent */ 29604f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29617e860f15SJohn Edward Broadbent { 296289492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 296389492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 296489492a15SPatrick Williams constexpr const char* interfaceName = 29657e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 296689492a15SPatrick Williams constexpr const char* method = "NMI"; 29677e860f15SJohn Edward Broadbent 29687e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 29695e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 29707e860f15SJohn Edward Broadbent if (ec) 29717e860f15SJohn Edward Broadbent { 297262598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 29737e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 29747e860f15SJohn Edward Broadbent return; 29757e860f15SJohn Edward Broadbent } 29767e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 29777e860f15SJohn Edward Broadbent }, 29787e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 29797e860f15SJohn Edward Broadbent } 2980c5b2abe0SLewanczyk, Dawid 2981c5b2abe0SLewanczyk, Dawid /** 2982fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 2983fc903b3dSAndrew Geissler */ 2984fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 2985fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 2986fc903b3dSAndrew Geissler std::string_view resetType, 2987fc903b3dSAndrew Geissler crow::Response& res) 2988fc903b3dSAndrew Geissler { 2989fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 2990fc903b3dSAndrew Geissler { 2991fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 2992fc903b3dSAndrew Geissler return; 2993fc903b3dSAndrew Geissler } 2994fc903b3dSAndrew Geissler 2995fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 2996fc903b3dSAndrew Geissler { 299762598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error: {}", ec); 2998fc903b3dSAndrew Geissler messages::internalError(res); 2999fc903b3dSAndrew Geissler return; 3000fc903b3dSAndrew Geissler } 3001fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 3002fc903b3dSAndrew Geissler 3003fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 3004fc903b3dSAndrew Geissler // user to retry in a bit 3005fc903b3dSAndrew Geissler if ((errorMessage == 3006fc903b3dSAndrew Geissler std::string_view( 3007fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 3008fc903b3dSAndrew Geissler (errorMessage == 3009fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 3010fc903b3dSAndrew Geissler { 301162598e31SEd Tanous BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now"); 3012fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 3013fc903b3dSAndrew Geissler return; 3014fc903b3dSAndrew Geissler } 3015fc903b3dSAndrew Geissler 301662598e31SEd Tanous BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec, 301762598e31SEd Tanous errorMessage); 3018fc903b3dSAndrew Geissler messages::internalError(res); 3019fc903b3dSAndrew Geissler } 3020fc903b3dSAndrew Geissler 3021c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 3022c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 30237f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3024c1e219d5SEd Tanous const std::string& systemName) 3025c1e219d5SEd Tanous { 30263ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 302745ca1b86SEd Tanous { 302845ca1b86SEd Tanous return; 302945ca1b86SEd Tanous } 3030c1e219d5SEd Tanous if (systemName != "system") 3031c1e219d5SEd Tanous { 3032c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3033c1e219d5SEd Tanous systemName); 3034c1e219d5SEd Tanous return; 3035c1e219d5SEd Tanous } 30367f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 30377f3e84a1SEd Tanous { 30387f3e84a1SEd Tanous // Option currently returns no systems. TBD 30397f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3040c1e219d5SEd Tanous systemName); 30417f3e84a1SEd Tanous return; 30427f3e84a1SEd Tanous } 30439712f8acSEd Tanous std::string resetType; 3044c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 3045cc340dd9SEd Tanous { 3046cc340dd9SEd Tanous return; 3047cc340dd9SEd Tanous } 3048cc340dd9SEd Tanous 3049d22c8396SJason M. Bills // Get the command and host vs. chassis 3050cc340dd9SEd Tanous std::string command; 3051543f4400SEd Tanous bool hostCommand = true; 3052d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 3053cc340dd9SEd Tanous { 3054cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 3055d22c8396SJason M. Bills hostCommand = true; 3056d22c8396SJason M. Bills } 3057d22c8396SJason M. Bills else if (resetType == "ForceOff") 3058d22c8396SJason M. Bills { 3059d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 3060d22c8396SJason M. Bills hostCommand = false; 3061d22c8396SJason M. Bills } 3062d22c8396SJason M. Bills else if (resetType == "ForceRestart") 3063d22c8396SJason M. Bills { 3064c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 306586a0851aSJason M. Bills hostCommand = true; 3066cc340dd9SEd Tanous } 30679712f8acSEd Tanous else if (resetType == "GracefulShutdown") 3068cc340dd9SEd Tanous { 3069cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 3070d22c8396SJason M. Bills hostCommand = true; 3071cc340dd9SEd Tanous } 30729712f8acSEd Tanous else if (resetType == "GracefulRestart") 3073cc340dd9SEd Tanous { 30740fda0f12SGeorge Liu command = 30750fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 3076d22c8396SJason M. Bills hostCommand = true; 3077d22c8396SJason M. Bills } 3078d22c8396SJason M. Bills else if (resetType == "PowerCycle") 3079d22c8396SJason M. Bills { 308086a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 308186a0851aSJason M. Bills hostCommand = true; 3082cc340dd9SEd Tanous } 3083bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 3084bfd5b826SLakshminarayana R. Kammath { 3085bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 3086bfd5b826SLakshminarayana R. Kammath return; 3087bfd5b826SLakshminarayana R. Kammath } 3088cc340dd9SEd Tanous else 3089cc340dd9SEd Tanous { 3090c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 3091cc340dd9SEd Tanous return; 3092cc340dd9SEd Tanous } 3093cc340dd9SEd Tanous 3094d22c8396SJason M. Bills if (hostCommand) 3095d22c8396SJason M. Bills { 30969ae226faSGeorge Liu sdbusplus::asio::setProperty( 30979ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 30989ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 30999ae226faSGeorge Liu "xyz.openbmc_project.State.Host", "RequestedHostTransition", 31009ae226faSGeorge Liu command, 3101fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3102fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3103cc340dd9SEd Tanous if (ec) 3104cc340dd9SEd Tanous { 3105fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3106fc903b3dSAndrew Geissler asyncResp->res); 3107fc903b3dSAndrew Geissler 3108cc340dd9SEd Tanous return; 3109cc340dd9SEd Tanous } 3110f12894f8SJason M. Bills messages::success(asyncResp->res); 31119ae226faSGeorge Liu }); 3112cc340dd9SEd Tanous } 3113d22c8396SJason M. Bills else 3114d22c8396SJason M. Bills { 31159ae226faSGeorge Liu sdbusplus::asio::setProperty( 31169ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 31179ae226faSGeorge Liu "/xyz/openbmc_project/state/chassis0", 31189ae226faSGeorge Liu "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 31199ae226faSGeorge Liu command, 3120fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3121fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3122d22c8396SJason M. Bills if (ec) 3123d22c8396SJason M. Bills { 3124fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3125fc903b3dSAndrew Geissler asyncResp->res); 3126d22c8396SJason M. Bills return; 3127d22c8396SJason M. Bills } 3128d22c8396SJason M. Bills messages::success(asyncResp->res); 31299ae226faSGeorge Liu }); 3130d22c8396SJason M. Bills } 3131d22c8396SJason M. Bills } 3132cc340dd9SEd Tanous 3133c1e219d5SEd Tanous inline void handleComputerSystemHead( 3134dd60b9edSEd Tanous App& app, const crow::Request& req, 31357f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31367f3e84a1SEd Tanous const std::string& /*systemName*/) 3137dd60b9edSEd Tanous { 3138dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3139dd60b9edSEd Tanous { 3140dd60b9edSEd Tanous return; 3141dd60b9edSEd Tanous } 3142dd60b9edSEd Tanous 3143dd60b9edSEd Tanous asyncResp->res.addHeader( 3144dd60b9edSEd Tanous boost::beast::http::field::link, 3145dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3146dd60b9edSEd Tanous } 3147dd60b9edSEd Tanous 31485c3e9272SAbhishek Patel inline void afterPortRequest( 31495c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31505c3e9272SAbhishek Patel const boost::system::error_code& ec, 31515c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 31525c3e9272SAbhishek Patel { 31535c3e9272SAbhishek Patel if (ec) 31545c3e9272SAbhishek Patel { 31555c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31565c3e9272SAbhishek Patel return; 31575c3e9272SAbhishek Patel } 31585c3e9272SAbhishek Patel for (const auto& data : socketData) 31595c3e9272SAbhishek Patel { 31605c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 31615c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 31625c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 31635c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 31645c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 31655c3e9272SAbhishek Patel // need to retrieve port number for 31665c3e9272SAbhishek Patel // obmc-console-ssh service 31675c3e9272SAbhishek Patel if (protocolName == "SSH") 31685c3e9272SAbhishek Patel { 31695c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 317081c4e330SEd Tanous const boost::system::error_code& ec1, 31715c3e9272SAbhishek Patel int portNumber) { 31725c3e9272SAbhishek Patel if (ec1) 31735c3e9272SAbhishek Patel { 31745c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31755c3e9272SAbhishek Patel return; 31765c3e9272SAbhishek Patel } 31775c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 31785c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 31795c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 31805c3e9272SAbhishek Patel }); 31815c3e9272SAbhishek Patel } 31825c3e9272SAbhishek Patel } 31835c3e9272SAbhishek Patel } 3184c1e219d5SEd Tanous 3185c1e219d5SEd Tanous inline void 3186c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 318722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3188c1e219d5SEd Tanous const std::string& systemName) 3189c1e219d5SEd Tanous { 31903ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 319145ca1b86SEd Tanous { 319245ca1b86SEd Tanous return; 319345ca1b86SEd Tanous } 3194746b56f3SAsmitha Karunanithi 31957f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 31967f3e84a1SEd Tanous { 31977f3e84a1SEd Tanous // Option currently returns no systems. TBD 31987f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31997f3e84a1SEd Tanous systemName); 32007f3e84a1SEd Tanous return; 32017f3e84a1SEd Tanous } 32027f3e84a1SEd Tanous 3203746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3204746b56f3SAsmitha Karunanithi { 3205746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3206746b56f3SAsmitha Karunanithi return; 3207746b56f3SAsmitha Karunanithi } 3208746b56f3SAsmitha Karunanithi 320922d268cbSEd Tanous if (systemName != "system") 321022d268cbSEd Tanous { 321122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 321222d268cbSEd Tanous systemName); 321322d268cbSEd Tanous return; 321422d268cbSEd Tanous } 3215dd60b9edSEd Tanous asyncResp->res.addHeader( 3216dd60b9edSEd Tanous boost::beast::http::field::link, 3217dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 32188d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 321937bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 32208d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 32218d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 32228d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 32238d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 32248d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 32255fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 32265fd0aafbSNinad Palsule { 32278d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 32288d1b46d7Szhanghch05 "Disabled"; 32298d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 32308d1b46d7Szhanghch05 "Disabled"; 32315fd0aafbSNinad Palsule } 3232cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3233dfb2b408SPriyanga Ramasamy double(0); 3234002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 323504a258f4SEd Tanous 32361476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 32371476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 32381476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 32391476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 32401476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 32411476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 32423179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 32433179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3244029573d4SEd Tanous 3245002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 32461476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 3247c1e219d5SEd Tanous asyncResp->res 3248c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 32491476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3250c5b2abe0SLewanczyk, Dawid 32511476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 32521476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 32531476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 32541476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3255c4bf6374SJason M. Bills 32561476687dSEd Tanous nlohmann::json::array_t managedBy; 32571476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 32581476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3259002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 32601476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 32611476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 32620e8ac5e7SGunnar Mills 32630e8ac5e7SGunnar Mills // Fill in SerialConsole info 3264002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3265c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 32661476687dSEd Tanous 3267c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 32681476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3269c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 32701476687dSEd Tanous "Press ~. to exit console"; 32715c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 32725c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 32730e8ac5e7SGunnar Mills 32740e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 32750e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3276002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3277c1e219d5SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4; 3278613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3279613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 32801476687dSEd Tanous 32810e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 328213451e39SWilly Tu 328313451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 328413451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 328513451e39SWilly Tu { 32867a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3287b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 32882ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3289e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3290e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3291b49ac873SJames Feist 32927a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 32937a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 32947a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3295914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3296b49ac873SJames Feist if (ec) 3297b49ac873SJames Feist { 3298b49ac873SJames Feist // no inventory 3299b49ac873SJames Feist return; 3300b49ac873SJames Feist } 3301b49ac873SJames Feist 3302914e2d5dSEd Tanous health->inventory = resp; 33037a1dbc48SGeorge Liu }); 3304b49ac873SJames Feist health->populate(); 330513451e39SWilly Tu } 3306b49ac873SJames Feist 3307002d39b4SEd Tanous getMainChassisId(asyncResp, 3308002d39b4SEd Tanous [](const std::string& chassisId, 33098d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3310b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3311b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3312ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3313ef4c65b7SEd Tanous chassisId); 3314002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3315c5d03ff4SJennifer Lee }); 3316a3002228SAppaRao Puli 33179f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 33189f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3319a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 33205bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 33216c34de48SEd Tanous getHostState(asyncResp); 3322491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3323978b8803SAndrew Geissler getBootProgress(asyncResp); 3324b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3325472bd202SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices"); 332651709ffdSYong Li getHostWatchdogTimer(asyncResp); 3327c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 33289dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3329797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3330c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3331a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3332a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3333a6349918SAppaRao Puli #endif 33341981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 33353a2d0424SChris Cain getPowerMode(asyncResp); 333637bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3337c1e219d5SEd Tanous } 3338550a6bf8SJiaqing Zhao 3339c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3340c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 334122d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3342c1e219d5SEd Tanous const std::string& systemName) 3343c1e219d5SEd Tanous { 33443ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 334545ca1b86SEd Tanous { 334645ca1b86SEd Tanous return; 334745ca1b86SEd Tanous } 33487f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 33497f3e84a1SEd Tanous { 33507f3e84a1SEd Tanous // Option currently returns no systems. TBD 33517f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 33527f3e84a1SEd Tanous systemName); 33537f3e84a1SEd Tanous return; 33547f3e84a1SEd Tanous } 335522d268cbSEd Tanous if (systemName != "system") 335622d268cbSEd Tanous { 335722d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 335822d268cbSEd Tanous systemName); 335922d268cbSEd Tanous return; 336022d268cbSEd Tanous } 336122d268cbSEd Tanous 3362dd60b9edSEd Tanous asyncResp->res.addHeader( 3363dd60b9edSEd Tanous boost::beast::http::field::link, 3364dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3365dd60b9edSEd Tanous 33669f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3367cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 336898e386ecSGunnar Mills std::optional<std::string> assetTag; 3369c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 33703a2d0424SChris Cain std::optional<std::string> powerMode; 3371550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3372550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3373550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3374550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3375550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3376550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3377797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3378550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 33799dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3380550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3381550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3382550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3383550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3384550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3385550a6bf8SJiaqing Zhao 3386550a6bf8SJiaqing Zhao // clang-format off 338715ed6780SWilly Tu if (!json_util::readJsonPatch( 3388550a6bf8SJiaqing Zhao req, asyncResp->res, 3389550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 33907e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3391550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3392550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3393550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3394550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3395550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3396550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3397550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3398550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3399550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3400797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3401550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 34029dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3403550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3404550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3405550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3406550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3407550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 34086617338dSEd Tanous { 34096617338dSEd Tanous return; 34106617338dSEd Tanous } 3411550a6bf8SJiaqing Zhao // clang-format on 3412491d8ee7SSantosh Puranik 34138d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3414c45f0082SYong Li 341598e386ecSGunnar Mills if (assetTag) 341698e386ecSGunnar Mills { 341798e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 341898e386ecSGunnar Mills } 341998e386ecSGunnar Mills 3420550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3421c45f0082SYong Li { 3422f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3423c45f0082SYong Li } 3424c45f0082SYong Li 3425cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 342669f35306SGunnar Mills { 3427002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3428491d8ee7SSantosh Puranik } 3429550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 343069f35306SGunnar Mills { 3431550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 343269f35306SGunnar Mills } 3433ac7e1e0bSAli Ahmed 3434797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3435797d5daeSCorey Hardesty { 3436797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3437797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3438797d5daeSCorey Hardesty } 3439797d5daeSCorey Hardesty 3440550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3441ac7e1e0bSAli Ahmed { 3442c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 344369f35306SGunnar Mills } 3444265c1602SJohnathan Mantey 34459dcfe8c1SAlbert Zhang if (stopBootOnFault) 34469dcfe8c1SAlbert Zhang { 34479dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 34489dcfe8c1SAlbert Zhang } 34499dcfe8c1SAlbert Zhang 34509f8bfa7cSGunnar Mills if (locationIndicatorActive) 34519f8bfa7cSGunnar Mills { 3452002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 34539f8bfa7cSGunnar Mills } 34549f8bfa7cSGunnar Mills 34557e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 34567e860f15SJohn Edward Broadbent // passed 34579712f8acSEd Tanous if (indicatorLed) 34586617338dSEd Tanous { 3459f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3460002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3461d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3462d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 34636617338dSEd Tanous } 3464c6a620f2SGeorge Liu 3465c6a620f2SGeorge Liu if (powerRestorePolicy) 3466c6a620f2SGeorge Liu { 34674e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3468c6a620f2SGeorge Liu } 34693a2d0424SChris Cain 34703a2d0424SChris Cain if (powerMode) 34713a2d0424SChris Cain { 34723a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 34733a2d0424SChris Cain } 347437bbf98cSChris Cain 3475c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 347637bbf98cSChris Cain { 3477002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3478002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 347937bbf98cSChris Cain } 3480c1e219d5SEd Tanous } 34811cb1a9e6SAppaRao Puli 348238c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3483dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 34847f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3485c1e219d5SEd Tanous const std::string& /*systemName*/) 3486dd60b9edSEd Tanous { 3487dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3488dd60b9edSEd Tanous { 3489dd60b9edSEd Tanous return; 3490dd60b9edSEd Tanous } 3491dd60b9edSEd Tanous asyncResp->res.addHeader( 3492dd60b9edSEd Tanous boost::beast::http::field::link, 3493dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3494dd60b9edSEd Tanous } 3495c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3496c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 349722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3498c1e219d5SEd Tanous const std::string& systemName) 3499c1e219d5SEd Tanous { 35003ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 350145ca1b86SEd Tanous { 350245ca1b86SEd Tanous return; 350345ca1b86SEd Tanous } 35047f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 35057f3e84a1SEd Tanous { 35067f3e84a1SEd Tanous // Option currently returns no systems. TBD 35077f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 35087f3e84a1SEd Tanous systemName); 35097f3e84a1SEd Tanous return; 35107f3e84a1SEd Tanous } 3511746b56f3SAsmitha Karunanithi 3512746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3513746b56f3SAsmitha Karunanithi { 3514746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3515746b56f3SAsmitha Karunanithi return; 3516746b56f3SAsmitha Karunanithi } 3517746b56f3SAsmitha Karunanithi 351822d268cbSEd Tanous if (systemName != "system") 351922d268cbSEd Tanous { 352022d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 352122d268cbSEd Tanous systemName); 352222d268cbSEd Tanous return; 352322d268cbSEd Tanous } 352422d268cbSEd Tanous 3525dd60b9edSEd Tanous asyncResp->res.addHeader( 3526dd60b9edSEd Tanous boost::beast::http::field::link, 3527dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 35281476687dSEd Tanous 35291476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 35301476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3531c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 35321476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 35331476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 35343215e700SNan Zhou 35353215e700SNan Zhou nlohmann::json::array_t parameters; 35363215e700SNan Zhou nlohmann::json::object_t parameter; 35373215e700SNan Zhou 35383215e700SNan Zhou parameter["Name"] = "ResetType"; 35393215e700SNan Zhou parameter["Required"] = true; 35403215e700SNan Zhou parameter["DataType"] = "String"; 35413215e700SNan Zhou nlohmann::json::array_t allowableValues; 35423215e700SNan Zhou allowableValues.emplace_back("On"); 35433215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 35443215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 35453215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 35463215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 35473215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 35483215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 35493215e700SNan Zhou allowableValues.emplace_back("Nmi"); 35503215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 35513215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 35523215e700SNan Zhou 35533215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 3554c1e219d5SEd Tanous } 3555c1e219d5SEd Tanous /** 3556c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3557c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3558c1e219d5SEd Tanous */ 3559100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3560c1e219d5SEd Tanous { 3561100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3562100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3563100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3564100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3565100afe56SEd Tanous 3566100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3567100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3568100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3569100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3570100afe56SEd Tanous 3571100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3572100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3573100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3574100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3575100afe56SEd Tanous 3576100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3577100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3578100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3579100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3580100afe56SEd Tanous 3581100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3582100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3583100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3584100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3585100afe56SEd Tanous 3586100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3587100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3588100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3589100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3590100afe56SEd Tanous 3591c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3592c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3593c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3594c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3595c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3596c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3597c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3598c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 35991cb1a9e6SAppaRao Puli } 3600c5b2abe0SLewanczyk, Dawid } // namespace redfish 3601