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 { 671e1e598dSJonathan Doman 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 { 961e1e598dSJonathan Doman 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 { 126cf0e004cSNinad Palsule 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 { 14703fbed92SAli Ahmed BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties."; 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 { 196382d6475SAli Ahmed 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 { 215382d6475SAli Ahmed 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 { 23603fbed92SAli Ahmed 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 { 260cf0e004cSNinad Palsule BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties."; 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 { 275cf0e004cSNinad Palsule 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"]; 300*dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 301cf0e004cSNinad Palsule if (preValue == nullptr) 302cf0e004cSNinad Palsule { 303ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 304*dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 305cf0e004cSNinad Palsule } 306cf0e004cSNinad Palsule else 307cf0e004cSNinad Palsule { 308ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 309*dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 310*dfb2b408SPriyanga 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 { 341cf0e004cSNinad Palsule 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 { 36155c7b7a2SEd 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 { 37655c7b7a2SEd 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; 38755c7b7a2SEd 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 { 4221abe55efSEd Tanous BMCWEB_LOG_DEBUG 42304a258f4SEd Tanous << "Found Dimm, now get its properties."; 4249d3ae10eSAlpana Kumari 425ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4265bc2dc8eSJames Feist 4275fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4285fd0aafbSNinad Palsule { 4295bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 4301abe55efSEd Tanous } 4315fd0aafbSNinad Palsule } 43204a258f4SEd Tanous else if (interfaceName == 43304a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4341abe55efSEd Tanous { 4351abe55efSEd Tanous BMCWEB_LOG_DEBUG 43604a258f4SEd Tanous << "Found Cpu, now get its properties."; 43757e8c9beSAlpana Kumari 438ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4395bc2dc8eSJames Feist 4405fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4415fd0aafbSNinad Palsule { 4425bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4431abe55efSEd Tanous } 4445fd0aafbSNinad Palsule } 445002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4461abe55efSEd Tanous { 4471abe55efSEd Tanous BMCWEB_LOG_DEBUG 44804a258f4SEd Tanous << "Found UUID, now get its properties."; 449bc1d29deSKrzysztof Grobelny 450bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 451bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 452bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Common.UUID", 453ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 454b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4551214b7e7SGunnar Mills properties) { 456cb13a392SEd Tanous if (ec3) 4571abe55efSEd Tanous { 458002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " 459002d39b4SEd Tanous << ec3; 460ac106bf6SEd Tanous messages::internalError(asyncResp->res); 461c5b2abe0SLewanczyk, Dawid return; 462c5b2abe0SLewanczyk, Dawid } 463002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 464c5b2abe0SLewanczyk, Dawid << " UUID properties."; 46504a258f4SEd Tanous 466bc1d29deSKrzysztof Grobelny const std::string* uUID = nullptr; 467bc1d29deSKrzysztof Grobelny 468bc1d29deSKrzysztof Grobelny const bool success = 469bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 470bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 471bc1d29deSKrzysztof Grobelny properties, "UUID", uUID); 472bc1d29deSKrzysztof Grobelny 473bc1d29deSKrzysztof Grobelny if (!success) 4741abe55efSEd Tanous { 475ac106bf6SEd Tanous messages::internalError(asyncResp->res); 476bc1d29deSKrzysztof Grobelny return; 477bc1d29deSKrzysztof Grobelny } 478bc1d29deSKrzysztof Grobelny 479bc1d29deSKrzysztof Grobelny if (uUID != nullptr) 480bc1d29deSKrzysztof Grobelny { 481bc1d29deSKrzysztof Grobelny std::string valueStr = *uUID; 48204a258f4SEd Tanous if (valueStr.size() == 32) 4831abe55efSEd Tanous { 484029573d4SEd Tanous valueStr.insert(8, 1, '-'); 485029573d4SEd Tanous valueStr.insert(13, 1, '-'); 486029573d4SEd Tanous valueStr.insert(18, 1, '-'); 487029573d4SEd Tanous valueStr.insert(23, 1, '-'); 48804a258f4SEd Tanous } 489bc1d29deSKrzysztof Grobelny BMCWEB_LOG_DEBUG << "UUID = " << valueStr; 490ac106bf6SEd Tanous asyncResp->res.jsonValue["UUID"] = valueStr; 491c5b2abe0SLewanczyk, Dawid } 492bc1d29deSKrzysztof Grobelny }); 493c5b2abe0SLewanczyk, Dawid } 494029573d4SEd Tanous else if (interfaceName == 495029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4961abe55efSEd Tanous { 497bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 498bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 499bc1d29deSKrzysztof Grobelny path, 500bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 501ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 502b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 5031214b7e7SGunnar Mills propertiesList) { 504cb13a392SEd Tanous if (ec2) 505029573d4SEd Tanous { 506e4a4b9a9SJames Feist // doesn't have to include this 507e4a4b9a9SJames Feist // interface 508029573d4SEd Tanous return; 509029573d4SEd Tanous } 510002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 511029573d4SEd Tanous << " properties for system"; 512bc1d29deSKrzysztof Grobelny 513bc1d29deSKrzysztof Grobelny const std::string* partNumber = nullptr; 514bc1d29deSKrzysztof Grobelny const std::string* serialNumber = nullptr; 515bc1d29deSKrzysztof Grobelny const std::string* manufacturer = nullptr; 516bc1d29deSKrzysztof Grobelny const std::string* model = nullptr; 517bc1d29deSKrzysztof Grobelny const std::string* subModel = nullptr; 518bc1d29deSKrzysztof Grobelny 519bc1d29deSKrzysztof Grobelny const bool success = 520bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 521bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 522bc1d29deSKrzysztof Grobelny propertiesList, "PartNumber", partNumber, 523bc1d29deSKrzysztof Grobelny "SerialNumber", serialNumber, 524bc1d29deSKrzysztof Grobelny "Manufacturer", manufacturer, "Model", 525bc1d29deSKrzysztof Grobelny model, "SubModel", subModel); 526bc1d29deSKrzysztof Grobelny 527bc1d29deSKrzysztof Grobelny if (!success) 528029573d4SEd Tanous { 529ac106bf6SEd Tanous messages::internalError(asyncResp->res); 530bc1d29deSKrzysztof Grobelny return; 531029573d4SEd Tanous } 532bc1d29deSKrzysztof Grobelny 533bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 534bc1d29deSKrzysztof Grobelny { 535ac106bf6SEd Tanous asyncResp->res.jsonValue["PartNumber"] = 536bc1d29deSKrzysztof Grobelny *partNumber; 537029573d4SEd Tanous } 538bc1d29deSKrzysztof Grobelny 539bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 540bc1d29deSKrzysztof Grobelny { 541ac106bf6SEd Tanous asyncResp->res.jsonValue["SerialNumber"] = 542bc1d29deSKrzysztof Grobelny *serialNumber; 543bc1d29deSKrzysztof Grobelny } 544bc1d29deSKrzysztof Grobelny 545bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 546bc1d29deSKrzysztof Grobelny { 547ac106bf6SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = 548bc1d29deSKrzysztof Grobelny *manufacturer; 549bc1d29deSKrzysztof Grobelny } 550bc1d29deSKrzysztof Grobelny 551bc1d29deSKrzysztof Grobelny if (model != nullptr) 552bc1d29deSKrzysztof Grobelny { 553ac106bf6SEd Tanous asyncResp->res.jsonValue["Model"] = *model; 554bc1d29deSKrzysztof Grobelny } 555bc1d29deSKrzysztof Grobelny 556bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 557bc1d29deSKrzysztof Grobelny { 558ac106bf6SEd Tanous asyncResp->res.jsonValue["SubModel"] = 559ac106bf6SEd Tanous *subModel; 560fc5afcf9Sbeccabroek } 561c1e236a6SGunnar Mills 562cb7e1e7bSAndrew Geissler // Grab the bios version 563eee0013eSWilly Tu sw_util::populateSoftwareInformation( 564ac106bf6SEd Tanous asyncResp, sw_util::biosPurpose, "BiosVersion", 565002d39b4SEd Tanous false); 566bc1d29deSKrzysztof Grobelny }); 567e4a4b9a9SJames Feist 5681e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5691e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5701e1e598dSJonathan Doman path, 5711e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5721e1e598dSJonathan Doman "AssetTag", 5731e1e598dSJonathan Doman "AssetTag", 574ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 5751e1e598dSJonathan Doman const std::string& value) { 576cb13a392SEd Tanous if (ec2) 577e4a4b9a9SJames Feist { 578e4a4b9a9SJames Feist // doesn't have to include this 579e4a4b9a9SJames Feist // interface 580e4a4b9a9SJames Feist return; 581e4a4b9a9SJames Feist } 582e4a4b9a9SJames Feist 583ac106bf6SEd Tanous asyncResp->res.jsonValue["AssetTag"] = value; 5841e1e598dSJonathan Doman }); 585029573d4SEd Tanous } 586029573d4SEd Tanous } 587029573d4SEd Tanous } 588c5b2abe0SLewanczyk, Dawid } 5896617338dSEd Tanous }); 590c5b2abe0SLewanczyk, Dawid } 591c5b2abe0SLewanczyk, Dawid 592c5b2abe0SLewanczyk, Dawid /** 593c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 594c5b2abe0SLewanczyk, Dawid * 595ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 596c5b2abe0SLewanczyk, Dawid * 597c5b2abe0SLewanczyk, Dawid * @return None. 598c5b2abe0SLewanczyk, Dawid */ 599ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 6001abe55efSEd Tanous { 60155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 6021e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 6031e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 6041e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 6051e1e598dSJonathan Doman "CurrentHostState", 606ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 6071e1e598dSJonathan Doman const std::string& hostState) { 6081abe55efSEd Tanous if (ec) 6091abe55efSEd Tanous { 61022228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 61122228c28SAndrew Geissler { 61222228c28SAndrew Geissler // Service not available, no error, just don't return 61322228c28SAndrew Geissler // host state info 61422228c28SAndrew Geissler BMCWEB_LOG_DEBUG << "Service not available " << ec; 61522228c28SAndrew Geissler return; 61622228c28SAndrew Geissler } 61722228c28SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 618ac106bf6SEd Tanous messages::internalError(asyncResp->res); 619c5b2abe0SLewanczyk, Dawid return; 620c5b2abe0SLewanczyk, Dawid } 6216617338dSEd Tanous 6221e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Host state: " << hostState; 623c5b2abe0SLewanczyk, Dawid // Verify Host State 6241e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 6251abe55efSEd Tanous { 626ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 627ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 6281abe55efSEd Tanous } 6291e1e598dSJonathan Doman else if (hostState == 6300fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 6318c888608SGunnar Mills { 632ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 633ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6348c888608SGunnar Mills } 6351e1e598dSJonathan Doman else if (hostState == 6360fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 63783935af9SAndrew Geissler { 638ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 639ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 64083935af9SAndrew Geissler } 6410fda0f12SGeorge Liu else if ( 6421e1e598dSJonathan Doman hostState == 6430fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6441a2a1437SAndrew Geissler { 645ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 646ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 6471a2a1437SAndrew Geissler } 648002d39b4SEd Tanous else if (hostState == 6490fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6501a2a1437SAndrew Geissler { 651ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 652ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 6531a2a1437SAndrew Geissler } 6541abe55efSEd Tanous else 6551abe55efSEd Tanous { 656ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 657ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 658c5b2abe0SLewanczyk, Dawid } 6591e1e598dSJonathan Doman }); 660c5b2abe0SLewanczyk, Dawid } 661c5b2abe0SLewanczyk, Dawid 662c5b2abe0SLewanczyk, Dawid /** 663786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 664491d8ee7SSantosh Puranik * 665491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 666491d8ee7SSantosh Puranik * 667491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 668491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 669491d8ee7SSantosh Puranik */ 67023a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 671491d8ee7SSantosh Puranik { 672491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 673491d8ee7SSantosh Puranik { 674491d8ee7SSantosh Puranik return "None"; 675491d8ee7SSantosh Puranik } 6763174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 677491d8ee7SSantosh Puranik { 678491d8ee7SSantosh Puranik return "Hdd"; 679491d8ee7SSantosh Puranik } 6803174e4dfSEd Tanous if (dbusSource == 681a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 682491d8ee7SSantosh Puranik { 683491d8ee7SSantosh Puranik return "Cd"; 684491d8ee7SSantosh Puranik } 6853174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 686491d8ee7SSantosh Puranik { 687491d8ee7SSantosh Puranik return "Pxe"; 688491d8ee7SSantosh Puranik } 6893174e4dfSEd Tanous if (dbusSource == 690944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6919f16b2c1SJennifer Lee { 6929f16b2c1SJennifer Lee return "Usb"; 6939f16b2c1SJennifer Lee } 694491d8ee7SSantosh Puranik return ""; 695491d8ee7SSantosh Puranik } 696491d8ee7SSantosh Puranik 697491d8ee7SSantosh Puranik /** 698cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 699cd9a4666SKonstantin Aladyshev * 700cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 701cd9a4666SKonstantin Aladyshev * 702cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 703cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 704cd9a4666SKonstantin Aladyshev */ 705cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 706cd9a4666SKonstantin Aladyshev { 707cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 708cd9a4666SKonstantin Aladyshev { 709cd9a4666SKonstantin Aladyshev return "Legacy"; 710cd9a4666SKonstantin Aladyshev } 711cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 712cd9a4666SKonstantin Aladyshev { 713cd9a4666SKonstantin Aladyshev return "UEFI"; 714cd9a4666SKonstantin Aladyshev } 715cd9a4666SKonstantin Aladyshev return ""; 716cd9a4666SKonstantin Aladyshev } 717cd9a4666SKonstantin Aladyshev 718cd9a4666SKonstantin Aladyshev /** 719786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 720491d8ee7SSantosh Puranik * 721491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 722491d8ee7SSantosh Puranik * 723491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 724491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 725491d8ee7SSantosh Puranik */ 72623a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 727491d8ee7SSantosh Puranik { 728491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 729491d8ee7SSantosh Puranik { 730491d8ee7SSantosh Puranik return "None"; 731491d8ee7SSantosh Puranik } 7323174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 733491d8ee7SSantosh Puranik { 734491d8ee7SSantosh Puranik return "Diags"; 735491d8ee7SSantosh Puranik } 7363174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 737491d8ee7SSantosh Puranik { 738491d8ee7SSantosh Puranik return "BiosSetup"; 739491d8ee7SSantosh Puranik } 740491d8ee7SSantosh Puranik return ""; 741491d8ee7SSantosh Puranik } 742491d8ee7SSantosh Puranik 743491d8ee7SSantosh Puranik /** 744e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 745e43914b3SAndrew Geissler * 746e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 747e43914b3SAndrew Geissler * 748e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 749e43914b3SAndrew Geissler * translation cannot be done, returns "None". 750e43914b3SAndrew Geissler */ 751e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 752e43914b3SAndrew Geissler { 753e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 754e43914b3SAndrew Geissler // enum 755e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 756e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 757e43914b3SAndrew Geissler "ProgressStages.Unspecified") 758e43914b3SAndrew Geissler { 759e43914b3SAndrew Geissler rfBpLastState = "None"; 760e43914b3SAndrew Geissler } 761e43914b3SAndrew Geissler else if (dbusBootProgress == 762e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 763e43914b3SAndrew Geissler "PrimaryProcInit") 764e43914b3SAndrew Geissler { 765e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 766e43914b3SAndrew Geissler } 767e43914b3SAndrew Geissler else if (dbusBootProgress == 768e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 769e43914b3SAndrew Geissler "BusInit") 770e43914b3SAndrew Geissler { 771e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 772e43914b3SAndrew Geissler } 773e43914b3SAndrew Geissler else if (dbusBootProgress == 774e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 775e43914b3SAndrew Geissler "MemoryInit") 776e43914b3SAndrew Geissler { 777e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 778e43914b3SAndrew Geissler } 779e43914b3SAndrew Geissler else if (dbusBootProgress == 780e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 781e43914b3SAndrew Geissler "SecondaryProcInit") 782e43914b3SAndrew Geissler { 783e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 784e43914b3SAndrew Geissler } 785e43914b3SAndrew Geissler else if (dbusBootProgress == 786e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 787e43914b3SAndrew Geissler "PCIInit") 788e43914b3SAndrew Geissler { 789e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 790e43914b3SAndrew Geissler } 791e43914b3SAndrew Geissler else if (dbusBootProgress == 792e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 793e43914b3SAndrew Geissler "SystemSetup") 794e43914b3SAndrew Geissler { 795e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 796e43914b3SAndrew Geissler } 797e43914b3SAndrew Geissler else if (dbusBootProgress == 798e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 799e43914b3SAndrew Geissler "SystemInitComplete") 800e43914b3SAndrew Geissler { 801e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 802e43914b3SAndrew Geissler } 803e43914b3SAndrew Geissler else if (dbusBootProgress == 804e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 805e43914b3SAndrew Geissler "OSStart") 806e43914b3SAndrew Geissler { 807e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 808e43914b3SAndrew Geissler } 809e43914b3SAndrew Geissler else if (dbusBootProgress == 810e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 811e43914b3SAndrew Geissler "OSRunning") 812e43914b3SAndrew Geissler { 813e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 814e43914b3SAndrew Geissler } 815e43914b3SAndrew Geissler else 816e43914b3SAndrew Geissler { 817e43914b3SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 818e43914b3SAndrew Geissler << dbusBootProgress; 819e43914b3SAndrew Geissler // Just return the default 820e43914b3SAndrew Geissler } 821e43914b3SAndrew Geissler return rfBpLastState; 822e43914b3SAndrew Geissler } 823e43914b3SAndrew Geissler 824e43914b3SAndrew Geissler /** 825786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 826491d8ee7SSantosh Puranik * 827491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 828944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 829944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 830491d8ee7SSantosh Puranik * 831944ffaf9SJohnathan Mantey * @return Integer error code. 832491d8ee7SSantosh Puranik */ 833ac106bf6SEd Tanous inline int 834ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 835ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 836ac106bf6SEd Tanous std::string& bootMode) 837491d8ee7SSantosh Puranik { 838c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 839c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 840944ffaf9SJohnathan Mantey 841491d8ee7SSantosh Puranik if (rfSource == "None") 842491d8ee7SSantosh Puranik { 843944ffaf9SJohnathan Mantey return 0; 844491d8ee7SSantosh Puranik } 8453174e4dfSEd Tanous if (rfSource == "Pxe") 846491d8ee7SSantosh Puranik { 847944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 848944ffaf9SJohnathan Mantey } 849944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 850944ffaf9SJohnathan Mantey { 851944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 852944ffaf9SJohnathan Mantey } 853944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 854944ffaf9SJohnathan Mantey { 855944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 856944ffaf9SJohnathan Mantey } 857944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 858944ffaf9SJohnathan Mantey { 859944ffaf9SJohnathan Mantey bootSource = 860944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 861944ffaf9SJohnathan Mantey } 862944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 863944ffaf9SJohnathan Mantey { 864944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 865491d8ee7SSantosh Puranik } 8669f16b2c1SJennifer Lee else if (rfSource == "Usb") 8679f16b2c1SJennifer Lee { 868944ffaf9SJohnathan Mantey bootSource = 869944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8709f16b2c1SJennifer Lee } 871491d8ee7SSantosh Puranik else 872491d8ee7SSantosh Puranik { 8730fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 8740fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideTarget: " 875944ffaf9SJohnathan Mantey << bootSource; 876ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 877944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 878944ffaf9SJohnathan Mantey return -1; 879491d8ee7SSantosh Puranik } 880944ffaf9SJohnathan Mantey return 0; 881491d8ee7SSantosh Puranik } 8821981771bSAli Ahmed 883978b8803SAndrew Geissler /** 884978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 885978b8803SAndrew Geissler * 886ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 887978b8803SAndrew Geissler * 888978b8803SAndrew Geissler * @return None. 889978b8803SAndrew Geissler */ 890ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 891978b8803SAndrew Geissler { 8921e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8931e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8941e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8951e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 896ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8971e1e598dSJonathan Doman const std::string& bootProgressStr) { 898978b8803SAndrew Geissler if (ec) 899978b8803SAndrew Geissler { 900978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 901978b8803SAndrew Geissler // not found 902978b8803SAndrew Geissler return; 903978b8803SAndrew Geissler } 904978b8803SAndrew Geissler 9051e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr; 906978b8803SAndrew Geissler 907ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 908e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 9091e1e598dSJonathan Doman }); 910978b8803SAndrew Geissler } 911491d8ee7SSantosh Puranik 912491d8ee7SSantosh Puranik /** 913b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 914b6d5d45cSHieu Huynh * 915ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 916b6d5d45cSHieu Huynh * 917b6d5d45cSHieu Huynh * @return None. 918b6d5d45cSHieu Huynh */ 919b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 920ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 921b6d5d45cSHieu Huynh { 922b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 923b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 924b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 925b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 926ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 927b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 928b6d5d45cSHieu Huynh if (ec) 929b6d5d45cSHieu Huynh { 930b6d5d45cSHieu Huynh BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 931b6d5d45cSHieu Huynh return; 932b6d5d45cSHieu Huynh } 933b6d5d45cSHieu Huynh 934b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 935b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 936b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 937b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 938b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 939b6d5d45cSHieu Huynh 940b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 941ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 942b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 943b6d5d45cSHieu Huynh }); 944b6d5d45cSHieu Huynh } 945b6d5d45cSHieu Huynh 946b6d5d45cSHieu Huynh /** 947c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 948cd9a4666SKonstantin Aladyshev * 949ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 950cd9a4666SKonstantin Aladyshev * 951cd9a4666SKonstantin Aladyshev * @return None. 952cd9a4666SKonstantin Aladyshev */ 953cd9a4666SKonstantin Aladyshev 954ac106bf6SEd Tanous inline void 955ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 956cd9a4666SKonstantin Aladyshev { 9571e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9581e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9591e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9601e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 961ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9621e1e598dSJonathan Doman const std::string& bootType) { 963cd9a4666SKonstantin Aladyshev if (ec) 964cd9a4666SKonstantin Aladyshev { 965cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 966cd9a4666SKonstantin Aladyshev return; 967cd9a4666SKonstantin Aladyshev } 968cd9a4666SKonstantin Aladyshev 9691e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot type: " << bootType; 970cd9a4666SKonstantin Aladyshev 971ac106bf6SEd Tanous asyncResp->res 972ac106bf6SEd Tanous .jsonValue["Boot"] 973002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 974613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 975cd9a4666SKonstantin Aladyshev 9761e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 977cd9a4666SKonstantin Aladyshev if (rfType.empty()) 978cd9a4666SKonstantin Aladyshev { 979ac106bf6SEd Tanous messages::internalError(asyncResp->res); 980cd9a4666SKonstantin Aladyshev return; 981cd9a4666SKonstantin Aladyshev } 982cd9a4666SKonstantin Aladyshev 983ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9841e1e598dSJonathan Doman }); 985cd9a4666SKonstantin Aladyshev } 986cd9a4666SKonstantin Aladyshev 987cd9a4666SKonstantin Aladyshev /** 988c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 989491d8ee7SSantosh Puranik * 990ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 991491d8ee7SSantosh Puranik * 992491d8ee7SSantosh Puranik * @return None. 993491d8ee7SSantosh Puranik */ 994c21865c4SKonstantin Aladyshev 995ac106bf6SEd Tanous inline void 996ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 997491d8ee7SSantosh Puranik { 9981e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9991e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10001e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10011e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1002ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10031e1e598dSJonathan Doman const std::string& bootModeStr) { 1004491d8ee7SSantosh Puranik if (ec) 1005491d8ee7SSantosh Puranik { 1006491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1007ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1008491d8ee7SSantosh Puranik return; 1009491d8ee7SSantosh Puranik } 1010491d8ee7SSantosh Puranik 10111e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 1012491d8ee7SSantosh Puranik 1013ac106bf6SEd Tanous asyncResp->res 10140fda0f12SGeorge Liu .jsonValue["Boot"] 1015002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 1016002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1017491d8ee7SSantosh Puranik 10181e1e598dSJonathan Doman if (bootModeStr != 1019491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1020491d8ee7SSantosh Puranik { 10211e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 1022491d8ee7SSantosh Puranik if (!rfMode.empty()) 1023491d8ee7SSantosh Puranik { 1024ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1025491d8ee7SSantosh Puranik rfMode; 1026491d8ee7SSantosh Puranik } 1027491d8ee7SSantosh Puranik } 10281e1e598dSJonathan Doman }); 1029491d8ee7SSantosh Puranik } 1030491d8ee7SSantosh Puranik 1031491d8ee7SSantosh Puranik /** 1032c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1033491d8ee7SSantosh Puranik * 1034ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1035491d8ee7SSantosh Puranik * 1036491d8ee7SSantosh Puranik * @return None. 1037491d8ee7SSantosh Puranik */ 1038c21865c4SKonstantin Aladyshev 1039c21865c4SKonstantin Aladyshev inline void 1040ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1041491d8ee7SSantosh Puranik { 10421e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10431e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10441e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10451e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1046ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10471e1e598dSJonathan Doman const std::string& bootSourceStr) { 1048491d8ee7SSantosh Puranik if (ec) 1049491d8ee7SSantosh Puranik { 1050491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 10515ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10525ef735c8SNan Zhou { 10535ef735c8SNan Zhou return; 10545ef735c8SNan Zhou } 1055ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1056491d8ee7SSantosh Puranik return; 1057491d8ee7SSantosh Puranik } 1058491d8ee7SSantosh Puranik 10591e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr; 1060491d8ee7SSantosh Puranik 10611e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1062491d8ee7SSantosh Puranik if (!rfSource.empty()) 1063491d8ee7SSantosh Puranik { 1064ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1065ac106bf6SEd Tanous rfSource; 1066491d8ee7SSantosh Puranik } 1067cd9a4666SKonstantin Aladyshev 1068cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1069cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1070ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10711e1e598dSJonathan Doman }); 1072491d8ee7SSantosh Puranik } 1073491d8ee7SSantosh Puranik 1074491d8ee7SSantosh Puranik /** 1075c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1076c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1077c21865c4SKonstantin Aladyshev * state 1078491d8ee7SSantosh Puranik * 1079ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1080491d8ee7SSantosh Puranik * 1081491d8ee7SSantosh Puranik * @return None. 1082491d8ee7SSantosh Puranik */ 1083491d8ee7SSantosh Puranik 1084ac106bf6SEd Tanous inline void processBootOverrideEnable( 1085ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1086c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1087c21865c4SKonstantin Aladyshev { 1088c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1089c21865c4SKonstantin Aladyshev { 1090ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1091ac106bf6SEd Tanous "Disabled"; 1092c21865c4SKonstantin Aladyshev return; 1093c21865c4SKonstantin Aladyshev } 1094c21865c4SKonstantin Aladyshev 1095c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1096c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10971e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10981e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10991e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 11001e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1101ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1102491d8ee7SSantosh Puranik if (ec) 1103491d8ee7SSantosh Puranik { 1104491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1105ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1106491d8ee7SSantosh Puranik return; 1107491d8ee7SSantosh Puranik } 1108491d8ee7SSantosh Puranik 1109c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1110c21865c4SKonstantin Aladyshev { 1111ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1112ac106bf6SEd Tanous "Once"; 1113c21865c4SKonstantin Aladyshev } 1114c21865c4SKonstantin Aladyshev else 1115c21865c4SKonstantin Aladyshev { 1116ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1117c21865c4SKonstantin Aladyshev "Continuous"; 1118c21865c4SKonstantin Aladyshev } 11191e1e598dSJonathan Doman }); 1120491d8ee7SSantosh Puranik } 1121491d8ee7SSantosh Puranik 1122491d8ee7SSantosh Puranik /** 1123c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1124c21865c4SKonstantin Aladyshev * 1125ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1126c21865c4SKonstantin Aladyshev * 1127c21865c4SKonstantin Aladyshev * @return None. 1128c21865c4SKonstantin Aladyshev */ 1129c21865c4SKonstantin Aladyshev 1130c21865c4SKonstantin Aladyshev inline void 1131ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1132c21865c4SKonstantin Aladyshev { 11331e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11341e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11351e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 11361e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1137ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 11381e1e598dSJonathan Doman const bool bootOverrideEnable) { 1139c21865c4SKonstantin Aladyshev if (ec) 1140c21865c4SKonstantin Aladyshev { 1141c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 11425ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11435ef735c8SNan Zhou { 11445ef735c8SNan Zhou return; 11455ef735c8SNan Zhou } 1146ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1147c21865c4SKonstantin Aladyshev return; 1148c21865c4SKonstantin Aladyshev } 1149c21865c4SKonstantin Aladyshev 1150ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11511e1e598dSJonathan Doman }); 1152c21865c4SKonstantin Aladyshev } 1153c21865c4SKonstantin Aladyshev 1154c21865c4SKonstantin Aladyshev /** 1155c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1156c21865c4SKonstantin Aladyshev * 1157ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1158c21865c4SKonstantin Aladyshev * 1159c21865c4SKonstantin Aladyshev * @return None. 1160c21865c4SKonstantin Aladyshev */ 1161ac106bf6SEd Tanous inline void 1162ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1163c21865c4SKonstantin Aladyshev { 1164c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1165c21865c4SKonstantin Aladyshev 1166ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1167ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1168ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1169c21865c4SKonstantin Aladyshev } 1170c21865c4SKonstantin Aladyshev 1171c21865c4SKonstantin Aladyshev /** 1172c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1173c0557e1aSGunnar Mills * 1174c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1175c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1176c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1177c0557e1aSGunnar Mills * last power operation time. 1178c0557e1aSGunnar Mills * 1179ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1180c0557e1aSGunnar Mills * 1181c0557e1aSGunnar Mills * @return None. 1182c0557e1aSGunnar Mills */ 1183ac106bf6SEd Tanous inline void 1184ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1185c0557e1aSGunnar Mills { 1186c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1187c0557e1aSGunnar Mills 11881e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11891e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11901e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11911e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1192ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1193ac106bf6SEd Tanous uint64_t lastResetTime) { 1194c0557e1aSGunnar Mills if (ec) 1195c0557e1aSGunnar Mills { 1196c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1197c0557e1aSGunnar Mills return; 1198c0557e1aSGunnar Mills } 1199c0557e1aSGunnar Mills 1200c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1201c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 12021e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1203c0557e1aSGunnar Mills 1204c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1205ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 12062b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 12071e1e598dSJonathan Doman }); 1208c0557e1aSGunnar Mills } 1209c0557e1aSGunnar Mills 1210c0557e1aSGunnar Mills /** 1211797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1212797d5daeSCorey Hardesty * 1213797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1214797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1215797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1216797d5daeSCorey Hardesty * dbus. 1217797d5daeSCorey Hardesty * 1218ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1219797d5daeSCorey Hardesty * 1220797d5daeSCorey Hardesty * @return None. 1221797d5daeSCorey Hardesty */ 1222ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1223ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1224797d5daeSCorey Hardesty { 1225797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 1226797d5daeSCorey Hardesty 1227797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1228797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1229797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1230797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1231ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1232ac106bf6SEd Tanous const boost::system::error_code& ec, 1233797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1234797d5daeSCorey Hardesty if (ec) 1235797d5daeSCorey Hardesty { 1236797d5daeSCorey Hardesty if (ec.value() != EBADR) 1237797d5daeSCorey Hardesty { 1238797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1239ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1240797d5daeSCorey Hardesty } 1241797d5daeSCorey Hardesty return; 1242797d5daeSCorey Hardesty } 1243797d5daeSCorey Hardesty 1244797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1245797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1246797d5daeSCorey Hardesty 1247797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1248797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1249797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1250797d5daeSCorey Hardesty 1251797d5daeSCorey Hardesty if (!success) 1252797d5daeSCorey Hardesty { 1253ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1254797d5daeSCorey Hardesty return; 1255797d5daeSCorey Hardesty } 1256797d5daeSCorey Hardesty 1257797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1258797d5daeSCorey Hardesty { 1259ac106bf6SEd Tanous asyncResp->res 1260ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1261797d5daeSCorey Hardesty *attemptsLeft; 1262797d5daeSCorey Hardesty } 1263797d5daeSCorey Hardesty 1264797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1265797d5daeSCorey Hardesty { 1266ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1267797d5daeSCorey Hardesty *retryAttempts; 1268797d5daeSCorey Hardesty } 1269797d5daeSCorey Hardesty }); 1270797d5daeSCorey Hardesty } 1271797d5daeSCorey Hardesty 1272797d5daeSCorey Hardesty /** 12736bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12746bd5a8d2SGunnar Mills * 1275ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12766bd5a8d2SGunnar Mills * 12776bd5a8d2SGunnar Mills * @return None. 12786bd5a8d2SGunnar Mills */ 1279797d5daeSCorey Hardesty inline void 1280ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12816bd5a8d2SGunnar Mills { 12826bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 12836bd5a8d2SGunnar Mills 12841e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12851e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12861e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12871e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1288ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1289ac106bf6SEd Tanous bool autoRebootEnabled) { 12906bd5a8d2SGunnar Mills if (ec) 12916bd5a8d2SGunnar Mills { 1292797d5daeSCorey Hardesty if (ec.value() != EBADR) 1293797d5daeSCorey Hardesty { 1294797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1295ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1296797d5daeSCorey Hardesty } 12976bd5a8d2SGunnar Mills return; 12986bd5a8d2SGunnar Mills } 12996bd5a8d2SGunnar Mills 13001e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled; 1301e05aec50SEd Tanous if (autoRebootEnabled) 13026bd5a8d2SGunnar Mills { 1303ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 13046bd5a8d2SGunnar Mills "RetryAttempts"; 13056bd5a8d2SGunnar Mills } 13066bd5a8d2SGunnar Mills else 13076bd5a8d2SGunnar Mills { 1308ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1309ac106bf6SEd Tanous "Disabled"; 13106bd5a8d2SGunnar Mills } 1311ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 131269f35306SGunnar Mills 131369f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 131469f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 131569f35306SGunnar Mills // RetryAttempts. 1316ac106bf6SEd Tanous asyncResp->res 1317ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1318ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 13191e1e598dSJonathan Doman }); 13206bd5a8d2SGunnar Mills } 13216bd5a8d2SGunnar Mills 13226bd5a8d2SGunnar Mills /** 1323797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1324797d5daeSCorey Hardesty * 1325ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1326797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1327797d5daeSCorey Hardesty * 1328797d5daeSCorey Hardesty *@return None. 1329797d5daeSCorey Hardesty */ 1330797d5daeSCorey Hardesty 1331ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1332ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1333797d5daeSCorey Hardesty const uint32_t retryAttempts) 1334797d5daeSCorey Hardesty { 1335797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts."; 13369ae226faSGeorge Liu sdbusplus::asio::setProperty( 13379ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 13389ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 13399ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 13409ae226faSGeorge Liu retryAttempts, [asyncResp](const boost::system::error_code& ec) { 1341797d5daeSCorey Hardesty if (ec) 1342797d5daeSCorey Hardesty { 1343797d5daeSCorey Hardesty BMCWEB_LOG_ERROR 13449ae226faSGeorge Liu << "DBUS response error: Set setAutomaticRetryAttempts" 13459ae226faSGeorge Liu << ec; 1346ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1347797d5daeSCorey Hardesty return; 1348797d5daeSCorey Hardesty } 13499ae226faSGeorge Liu }); 1350797d5daeSCorey Hardesty } 1351797d5daeSCorey Hardesty 13528d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 13538d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 13548d69c668SEd Tanous { 13558d69c668SEd Tanous if (value == 13568d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 13578d69c668SEd Tanous { 13588d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 13598d69c668SEd Tanous } 13608d69c668SEd Tanous if (value == 13618d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 13628d69c668SEd Tanous { 13638d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13648d69c668SEd Tanous } 13658d69c668SEd Tanous if (value == 13668d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore") 13678d69c668SEd Tanous { 13688d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13698d69c668SEd Tanous } 13708d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13718d69c668SEd Tanous { 13728d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13738d69c668SEd Tanous } 13748d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13758d69c668SEd Tanous } 1376797d5daeSCorey Hardesty /** 1377c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1378c6a620f2SGeorge Liu * 1379ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1380c6a620f2SGeorge Liu * 1381c6a620f2SGeorge Liu * @return None. 1382c6a620f2SGeorge Liu */ 13838d1b46d7Szhanghch05 inline void 1384ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1385c6a620f2SGeorge Liu { 1386c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1387c6a620f2SGeorge Liu 13881e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13891e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13901e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13911e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1392ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13935e7e2dc5SEd Tanous const std::string& policy) { 1394c6a620f2SGeorge Liu if (ec) 1395c6a620f2SGeorge Liu { 1396c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1397c6a620f2SGeorge Liu return; 1398c6a620f2SGeorge Liu } 13998d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 14008d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 14018d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1402c6a620f2SGeorge Liu { 1403ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1404c6a620f2SGeorge Liu return; 1405c6a620f2SGeorge Liu } 1406c6a620f2SGeorge Liu 14078d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 14081e1e598dSJonathan Doman }); 1409c6a620f2SGeorge Liu } 1410c6a620f2SGeorge Liu 1411c6a620f2SGeorge Liu /** 14129dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 14139dcfe8c1SAlbert Zhang * 14149dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 14159dcfe8c1SAlbert Zhang * 14169dcfe8c1SAlbert Zhang * @return None. 14179dcfe8c1SAlbert Zhang */ 14189dcfe8c1SAlbert Zhang inline void 14199dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14209dcfe8c1SAlbert Zhang { 14219dcfe8c1SAlbert Zhang BMCWEB_LOG_DEBUG << "Get Stop Boot On Fault"; 14229dcfe8c1SAlbert Zhang 14239dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 14249dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 14259dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 14269dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 14279dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 14289dcfe8c1SAlbert Zhang if (ec) 14299dcfe8c1SAlbert Zhang { 14309dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 14319dcfe8c1SAlbert Zhang { 14329dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 14339dcfe8c1SAlbert Zhang } 14349dcfe8c1SAlbert Zhang return; 14359dcfe8c1SAlbert Zhang } 14369dcfe8c1SAlbert Zhang 14379dcfe8c1SAlbert Zhang if (value) 14389dcfe8c1SAlbert Zhang { 14399dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault"; 14409dcfe8c1SAlbert Zhang } 14419dcfe8c1SAlbert Zhang else 14429dcfe8c1SAlbert Zhang { 14439dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never"; 14449dcfe8c1SAlbert Zhang } 14459dcfe8c1SAlbert Zhang }); 14469dcfe8c1SAlbert Zhang } 14479dcfe8c1SAlbert Zhang 14489dcfe8c1SAlbert Zhang /** 14491981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 14501981771bSAli Ahmed * TPM is required for booting the host. 14511981771bSAli Ahmed * 1452ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14531981771bSAli Ahmed * 14541981771bSAli Ahmed * @return None. 14551981771bSAli Ahmed */ 14561981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1457ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14581981771bSAli Ahmed { 14591981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 1460e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1461e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1462e99073f5SGeorge Liu dbus::utility::getSubTree( 1463e99073f5SGeorge Liu "/", 0, interfaces, 1464ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1465b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14661981771bSAli Ahmed if (ec) 14671981771bSAli Ahmed { 1468002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1469002d39b4SEd Tanous << ec; 14701981771bSAli Ahmed // This is an optional D-Bus object so just return if 14711981771bSAli Ahmed // error occurs 14721981771bSAli Ahmed return; 14731981771bSAli Ahmed } 147426f6976fSEd Tanous if (subtree.empty()) 14751981771bSAli Ahmed { 14761981771bSAli Ahmed // As noted above, this is an optional interface so just return 14771981771bSAli Ahmed // if there is no instance found 14781981771bSAli Ahmed return; 14791981771bSAli Ahmed } 14801981771bSAli Ahmed 14811981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14821981771bSAli Ahmed if (subtree.size() > 1) 14831981771bSAli Ahmed { 14841981771bSAli Ahmed BMCWEB_LOG_DEBUG 14851981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 14861981771bSAli Ahmed << subtree.size(); 14871981771bSAli Ahmed // Throw an internal Error and return 1488ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14891981771bSAli Ahmed return; 14901981771bSAli Ahmed } 14911981771bSAli Ahmed 14921981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14931981771bSAli Ahmed // field 14941981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14951981771bSAli Ahmed { 14961981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 1497ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14981981771bSAli Ahmed return; 14991981771bSAli Ahmed } 15001981771bSAli Ahmed 15011981771bSAli Ahmed const std::string& path = subtree[0].first; 15021981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15031981771bSAli Ahmed 15041981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 15051e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 15061e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 15071e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1508ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1509ac106bf6SEd Tanous bool tpmRequired) { 15108a592810SEd Tanous if (ec2) 15111981771bSAli Ahmed { 1512002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get" 15138a592810SEd Tanous << ec2; 1514ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15151981771bSAli Ahmed return; 15161981771bSAli Ahmed } 15171981771bSAli Ahmed 15181e1e598dSJonathan Doman if (tpmRequired) 15191981771bSAli Ahmed { 1520ac106bf6SEd Tanous asyncResp->res 1521ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15221981771bSAli Ahmed "Required"; 15231981771bSAli Ahmed } 15241981771bSAli Ahmed else 15251981771bSAli Ahmed { 1526ac106bf6SEd Tanous asyncResp->res 1527ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15281981771bSAli Ahmed "Disabled"; 15291981771bSAli Ahmed } 15301e1e598dSJonathan Doman }); 1531e99073f5SGeorge Liu }); 15321981771bSAli Ahmed } 15331981771bSAli Ahmed 15341981771bSAli Ahmed /** 15351c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 15361c05dae3SAli Ahmed * TPM is required for booting the host. 15371c05dae3SAli Ahmed * 1538ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 15391c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 15401c05dae3SAli Ahmed * 15411c05dae3SAli Ahmed * @return None. 15421c05dae3SAli Ahmed */ 15431c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1544ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 15451c05dae3SAli Ahmed { 15461c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 1547e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1548e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1549e99073f5SGeorge Liu dbus::utility::getSubTree( 1550e99073f5SGeorge Liu "/", 0, interfaces, 1551ac106bf6SEd Tanous [asyncResp, 1552e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1553e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15541c05dae3SAli Ahmed if (ec) 15551c05dae3SAli Ahmed { 1556002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1557002d39b4SEd Tanous << ec; 1558ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15591c05dae3SAli Ahmed return; 15601c05dae3SAli Ahmed } 156126f6976fSEd Tanous if (subtree.empty()) 15621c05dae3SAli Ahmed { 1563ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 15641c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15651c05dae3SAli Ahmed return; 15661c05dae3SAli Ahmed } 15671c05dae3SAli Ahmed 15681c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15691c05dae3SAli Ahmed if (subtree.size() > 1) 15701c05dae3SAli Ahmed { 15711c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 15721c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 15731c05dae3SAli Ahmed << subtree.size(); 15741c05dae3SAli Ahmed // Throw an internal Error and return 1575ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15761c05dae3SAli Ahmed return; 15771c05dae3SAli Ahmed } 15781c05dae3SAli Ahmed 15791c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15801c05dae3SAli Ahmed // field 15811c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15821c05dae3SAli Ahmed { 15831c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 1584ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15851c05dae3SAli Ahmed return; 15861c05dae3SAli Ahmed } 15871c05dae3SAli Ahmed 15881c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15891c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15901c05dae3SAli Ahmed 15911c05dae3SAli Ahmed if (serv.empty()) 15921c05dae3SAli Ahmed { 15931c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 1594ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15951c05dae3SAli Ahmed return; 15961c05dae3SAli Ahmed } 15971c05dae3SAli Ahmed 15981c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 15999ae226faSGeorge Liu sdbusplus::asio::setProperty( 16009ae226faSGeorge Liu *crow::connections::systemBus, serv, path, 16019ae226faSGeorge Liu "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired, 1602ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 16038a592810SEd Tanous if (ec2) 16041c05dae3SAli Ahmed { 16050fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 16060fda0f12SGeorge Liu << "DBUS response error: Set TrustedModuleRequiredToBoot" 16078a592810SEd Tanous << ec2; 1608ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16091c05dae3SAli Ahmed return; 16101c05dae3SAli Ahmed } 16111c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 16129ae226faSGeorge Liu }); 1613e99073f5SGeorge Liu }); 16141c05dae3SAli Ahmed } 16151c05dae3SAli Ahmed 16161c05dae3SAli Ahmed /** 1617491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1618491d8ee7SSantosh Puranik * 1619ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1620cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1621cd9a4666SKonstantin Aladyshev * @return Integer error code. 1622cd9a4666SKonstantin Aladyshev */ 1623ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1624cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1625cd9a4666SKonstantin Aladyshev { 1626c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1627cd9a4666SKonstantin Aladyshev 1628c21865c4SKonstantin Aladyshev if (!bootType) 1629cd9a4666SKonstantin Aladyshev { 1630c21865c4SKonstantin Aladyshev return; 1631c21865c4SKonstantin Aladyshev } 1632c21865c4SKonstantin Aladyshev 1633cd9a4666SKonstantin Aladyshev // Source target specified 1634cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1635cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1636cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1637cd9a4666SKonstantin Aladyshev { 1638cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1639cd9a4666SKonstantin Aladyshev } 1640cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1641cd9a4666SKonstantin Aladyshev { 1642cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1643cd9a4666SKonstantin Aladyshev } 1644cd9a4666SKonstantin Aladyshev else 1645cd9a4666SKonstantin Aladyshev { 1646cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1647cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1648cd9a4666SKonstantin Aladyshev << *bootType; 1649ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1650cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1651cd9a4666SKonstantin Aladyshev return; 1652cd9a4666SKonstantin Aladyshev } 1653cd9a4666SKonstantin Aladyshev 1654cd9a4666SKonstantin Aladyshev // Act on validated parameters 1655cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1656cd9a4666SKonstantin Aladyshev 16579ae226faSGeorge Liu sdbusplus::asio::setProperty( 16589ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 16599ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 16609ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr, 1661ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1662cd9a4666SKonstantin Aladyshev if (ec) 1663cd9a4666SKonstantin Aladyshev { 1664cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1665cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1666cd9a4666SKonstantin Aladyshev { 1667ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1668cd9a4666SKonstantin Aladyshev return; 1669cd9a4666SKonstantin Aladyshev } 1670ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1671cd9a4666SKonstantin Aladyshev return; 1672cd9a4666SKonstantin Aladyshev } 1673cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 16749ae226faSGeorge Liu }); 1675cd9a4666SKonstantin Aladyshev } 1676cd9a4666SKonstantin Aladyshev 1677cd9a4666SKonstantin Aladyshev /** 1678cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1679cd9a4666SKonstantin Aladyshev * 1680ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1681ac106bf6SEd Tanous * message. 1682c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1683c21865c4SKonstantin Aladyshev * @return Integer error code. 1684c21865c4SKonstantin Aladyshev */ 1685ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1686c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1687c21865c4SKonstantin Aladyshev { 1688c21865c4SKonstantin Aladyshev if (!bootEnable) 1689c21865c4SKonstantin Aladyshev { 1690c21865c4SKonstantin Aladyshev return; 1691c21865c4SKonstantin Aladyshev } 1692c21865c4SKonstantin Aladyshev // Source target specified 1693c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1694c21865c4SKonstantin Aladyshev 1695c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1696c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1697c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1698c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1699c21865c4SKonstantin Aladyshev { 1700c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1701c21865c4SKonstantin Aladyshev } 1702c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1703c21865c4SKonstantin Aladyshev { 1704c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1705c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1706c21865c4SKonstantin Aladyshev } 1707c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1708c21865c4SKonstantin Aladyshev { 1709c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1710c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1711c21865c4SKonstantin Aladyshev } 1712c21865c4SKonstantin Aladyshev else 1713c21865c4SKonstantin Aladyshev { 17140fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 17150fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideEnabled: " 1716c21865c4SKonstantin Aladyshev << *bootEnable; 1717ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1718c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1719c21865c4SKonstantin Aladyshev return; 1720c21865c4SKonstantin Aladyshev } 1721c21865c4SKonstantin Aladyshev 1722c21865c4SKonstantin Aladyshev // Act on validated parameters 1723c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1724c21865c4SKonstantin Aladyshev 17259ae226faSGeorge Liu sdbusplus::asio::setProperty( 17269ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17279ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 17289ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable, 1729ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 17308a592810SEd Tanous if (ec2) 1731c21865c4SKonstantin Aladyshev { 17328a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1733ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1734c21865c4SKonstantin Aladyshev return; 1735c21865c4SKonstantin Aladyshev } 1736c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 17379ae226faSGeorge Liu }); 1738c21865c4SKonstantin Aladyshev 1739c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1740c21865c4SKonstantin Aladyshev { 1741c21865c4SKonstantin Aladyshev return; 1742c21865c4SKonstantin Aladyshev } 1743c21865c4SKonstantin Aladyshev 1744c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1745c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1746c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1747c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1748c21865c4SKonstantin Aladyshev 17499ae226faSGeorge Liu sdbusplus::asio::setProperty( 17509ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17519ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot/one_time", 17529ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent, 1753ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1754c21865c4SKonstantin Aladyshev if (ec) 1755c21865c4SKonstantin Aladyshev { 1756c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1757ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1758c21865c4SKonstantin Aladyshev return; 1759c21865c4SKonstantin Aladyshev } 1760c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 17619ae226faSGeorge Liu }); 1762c21865c4SKonstantin Aladyshev } 1763c21865c4SKonstantin Aladyshev 1764c21865c4SKonstantin Aladyshev /** 1765c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1766c21865c4SKonstantin Aladyshev * 1767ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1768491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1769491d8ee7SSantosh Puranik * 1770265c1602SJohnathan Mantey * @return Integer error code. 1771491d8ee7SSantosh Puranik */ 1772ac106bf6SEd Tanous inline void 1773ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1774cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1775491d8ee7SSantosh Puranik { 1776c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1777c21865c4SKonstantin Aladyshev std::string bootModeStr; 1778944ffaf9SJohnathan Mantey 1779c21865c4SKonstantin Aladyshev if (!bootSource) 1780491d8ee7SSantosh Puranik { 1781c21865c4SKonstantin Aladyshev return; 1782c21865c4SKonstantin Aladyshev } 1783c21865c4SKonstantin Aladyshev 1784491d8ee7SSantosh Puranik // Source target specified 1785491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1786491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1787ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1788ac106bf6SEd Tanous bootModeStr) != 0) 1789491d8ee7SSantosh Puranik { 1790944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1791944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1792491d8ee7SSantosh Puranik << *bootSource; 1793ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1794491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1795491d8ee7SSantosh Puranik return; 1796491d8ee7SSantosh Puranik } 1797491d8ee7SSantosh Puranik 1798944ffaf9SJohnathan Mantey // Act on validated parameters 1799944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1800944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1801944ffaf9SJohnathan Mantey 18029ae226faSGeorge Liu sdbusplus::asio::setProperty( 18039ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 18049ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 18059ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr, 1806ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1807491d8ee7SSantosh Puranik if (ec) 1808491d8ee7SSantosh Puranik { 1809491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1810ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1811491d8ee7SSantosh Puranik return; 1812491d8ee7SSantosh Puranik } 1813491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 18149ae226faSGeorge Liu }); 1815944ffaf9SJohnathan Mantey 18169ae226faSGeorge Liu sdbusplus::asio::setProperty( 18179ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 18189ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 18199ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr, 1820ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1821491d8ee7SSantosh Puranik if (ec) 1822491d8ee7SSantosh Puranik { 1823491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1824ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1825491d8ee7SSantosh Puranik return; 1826491d8ee7SSantosh Puranik } 1827491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 18289ae226faSGeorge Liu }); 1829cd9a4666SKonstantin Aladyshev } 1830944ffaf9SJohnathan Mantey 1831cd9a4666SKonstantin Aladyshev /** 1832c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1833491d8ee7SSantosh Puranik * 1834ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1835491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1836cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1837491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1838491d8ee7SSantosh Puranik * 1839265c1602SJohnathan Mantey * @return Integer error code. 1840491d8ee7SSantosh Puranik */ 1841c21865c4SKonstantin Aladyshev 1842ac106bf6SEd Tanous inline void 1843ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1844c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1845c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1846c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1847491d8ee7SSantosh Puranik { 1848491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1849491d8ee7SSantosh Puranik 1850ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1851ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1852ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1853491d8ee7SSantosh Puranik } 1854491d8ee7SSantosh Puranik 1855c6a620f2SGeorge Liu /** 185698e386ecSGunnar Mills * @brief Sets AssetTag 185798e386ecSGunnar Mills * 1858ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 185998e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 186098e386ecSGunnar Mills * 186198e386ecSGunnar Mills * @return None. 186298e386ecSGunnar Mills */ 1863ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 186498e386ecSGunnar Mills const std::string& assetTag) 186598e386ecSGunnar Mills { 1866e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1867e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1868e99073f5SGeorge Liu dbus::utility::getSubTree( 1869e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1870ac106bf6SEd Tanous [asyncResp, 1871e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1872b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 187398e386ecSGunnar Mills if (ec) 187498e386ecSGunnar Mills { 187598e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 1876ac106bf6SEd Tanous messages::internalError(asyncResp->res); 187798e386ecSGunnar Mills return; 187898e386ecSGunnar Mills } 187926f6976fSEd Tanous if (subtree.empty()) 188098e386ecSGunnar Mills { 188198e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 1882ac106bf6SEd Tanous messages::internalError(asyncResp->res); 188398e386ecSGunnar Mills return; 188498e386ecSGunnar Mills } 188598e386ecSGunnar Mills // Assume only 1 system D-Bus object 188698e386ecSGunnar Mills // Throw an error if there is more than 1 188798e386ecSGunnar Mills if (subtree.size() > 1) 188898e386ecSGunnar Mills { 188998e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 1890ac106bf6SEd Tanous messages::internalError(asyncResp->res); 189198e386ecSGunnar Mills return; 189298e386ecSGunnar Mills } 189398e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 189498e386ecSGunnar Mills { 189598e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 1896ac106bf6SEd Tanous messages::internalError(asyncResp->res); 189798e386ecSGunnar Mills return; 189898e386ecSGunnar Mills } 189998e386ecSGunnar Mills 190098e386ecSGunnar Mills const std::string& path = subtree[0].first; 190198e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 190298e386ecSGunnar Mills 190398e386ecSGunnar Mills if (service.empty()) 190498e386ecSGunnar Mills { 190598e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 1906ac106bf6SEd Tanous messages::internalError(asyncResp->res); 190798e386ecSGunnar Mills return; 190898e386ecSGunnar Mills } 190998e386ecSGunnar Mills 19109ae226faSGeorge Liu sdbusplus::asio::setProperty( 19119ae226faSGeorge Liu *crow::connections::systemBus, service, path, 19129ae226faSGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 19139ae226faSGeorge Liu assetTag, [asyncResp](const boost::system::error_code& ec2) { 191498e386ecSGunnar Mills if (ec2) 191598e386ecSGunnar Mills { 1916002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set " 1917002d39b4SEd Tanous << ec2; 1918ac106bf6SEd Tanous messages::internalError(asyncResp->res); 191998e386ecSGunnar Mills return; 192098e386ecSGunnar Mills } 19219ae226faSGeorge Liu }); 1922e99073f5SGeorge Liu }); 192398e386ecSGunnar Mills } 192498e386ecSGunnar Mills 192598e386ecSGunnar Mills /** 19269dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 19279dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 19289dcfe8c1SAlbert Zhang * 19299dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 19309dcfe8c1SAlbert Zhang * stopBootOnFault 19319dcfe8c1SAlbert Zhang * 19329dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 19339dcfe8c1SAlbert Zhang */ 19349dcfe8c1SAlbert Zhang inline std::optional<bool> 19359dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 19369dcfe8c1SAlbert Zhang { 19379dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 19389dcfe8c1SAlbert Zhang { 19399dcfe8c1SAlbert Zhang return true; 19409dcfe8c1SAlbert Zhang } 19419dcfe8c1SAlbert Zhang 19429dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 19439dcfe8c1SAlbert Zhang { 19449dcfe8c1SAlbert Zhang return false; 19459dcfe8c1SAlbert Zhang } 19469dcfe8c1SAlbert Zhang 19479dcfe8c1SAlbert Zhang return std::nullopt; 19489dcfe8c1SAlbert Zhang } 19499dcfe8c1SAlbert Zhang 19509dcfe8c1SAlbert Zhang /** 19519dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 19529dcfe8c1SAlbert Zhang * 19539dcfe8c1SAlbert Zhang * @param[in] aResp Shared pointer for generating response message. 19549dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 19559dcfe8c1SAlbert Zhang * 19569dcfe8c1SAlbert Zhang * @return None. 19579dcfe8c1SAlbert Zhang */ 19589dcfe8c1SAlbert Zhang inline void setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 19599dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 19609dcfe8c1SAlbert Zhang { 19619dcfe8c1SAlbert Zhang BMCWEB_LOG_DEBUG << "Set Stop Boot On Fault."; 19629dcfe8c1SAlbert Zhang 19639dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 19649dcfe8c1SAlbert Zhang if (!stopBootEnabled) 19659dcfe8c1SAlbert Zhang { 19669dcfe8c1SAlbert Zhang BMCWEB_LOG_DEBUG << "Invalid property value for StopBootOnFault: " 19679dcfe8c1SAlbert Zhang << stopBootOnFault; 19689dcfe8c1SAlbert Zhang messages::propertyValueNotInList(aResp->res, stopBootOnFault, 19699dcfe8c1SAlbert Zhang "StopBootOnFault"); 19709dcfe8c1SAlbert Zhang return; 19719dcfe8c1SAlbert Zhang } 19729dcfe8c1SAlbert Zhang 19739dcfe8c1SAlbert Zhang sdbusplus::asio::setProperty(*crow::connections::systemBus, 19749dcfe8c1SAlbert Zhang "xyz.openbmc_project.Settings", 19759dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 19769dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", 19779dcfe8c1SAlbert Zhang "QuiesceOnHwError", *stopBootEnabled, 19789dcfe8c1SAlbert Zhang [aResp](const boost::system::error_code& ec) { 19799dcfe8c1SAlbert Zhang if (ec) 19809dcfe8c1SAlbert Zhang { 19819dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 19829dcfe8c1SAlbert Zhang { 19839dcfe8c1SAlbert Zhang messages::internalError(aResp->res); 19849dcfe8c1SAlbert Zhang } 19859dcfe8c1SAlbert Zhang return; 19869dcfe8c1SAlbert Zhang } 19879dcfe8c1SAlbert Zhang }); 19889dcfe8c1SAlbert Zhang } 19899dcfe8c1SAlbert Zhang 19909dcfe8c1SAlbert Zhang /** 199169f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 199269f35306SGunnar Mills * 1993ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 199469f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 199569f35306SGunnar Mills * 199669f35306SGunnar Mills * @return None. 199769f35306SGunnar Mills */ 1998ac106bf6SEd Tanous inline void 1999ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2000f23b7296SEd Tanous const std::string& automaticRetryConfig) 200169f35306SGunnar Mills { 200269f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 200369f35306SGunnar Mills 200469f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 2005543f4400SEd Tanous bool autoRebootEnabled = false; 200669f35306SGunnar Mills 200769f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 200869f35306SGunnar Mills { 200969f35306SGunnar Mills autoRebootEnabled = false; 201069f35306SGunnar Mills } 201169f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 201269f35306SGunnar Mills { 201369f35306SGunnar Mills autoRebootEnabled = true; 201469f35306SGunnar Mills } 201569f35306SGunnar Mills else 201669f35306SGunnar Mills { 20170fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: " 201869f35306SGunnar Mills << automaticRetryConfig; 2019ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 202069f35306SGunnar Mills "AutomaticRetryConfig"); 202169f35306SGunnar Mills return; 202269f35306SGunnar Mills } 202369f35306SGunnar Mills 20249ae226faSGeorge Liu sdbusplus::asio::setProperty( 20259ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20269ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/auto_reboot", 20279ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 20289ae226faSGeorge Liu autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) { 202969f35306SGunnar Mills if (ec) 203069f35306SGunnar Mills { 2031ac106bf6SEd Tanous messages::internalError(asyncResp->res); 203269f35306SGunnar Mills return; 203369f35306SGunnar Mills } 20349ae226faSGeorge Liu }); 203569f35306SGunnar Mills } 203669f35306SGunnar Mills 20378d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 20388d69c668SEd Tanous { 20398d69c668SEd Tanous if (policy == "AlwaysOn") 20408d69c668SEd Tanous { 20418d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 20428d69c668SEd Tanous } 20438d69c668SEd Tanous if (policy == "AlwaysOff") 20448d69c668SEd Tanous { 20458d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 20468d69c668SEd Tanous } 20478d69c668SEd Tanous if (policy == "LastState") 20488d69c668SEd Tanous { 20498d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 20508d69c668SEd Tanous } 20518d69c668SEd Tanous return ""; 20528d69c668SEd Tanous } 20538d69c668SEd Tanous 205469f35306SGunnar Mills /** 2055c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 2056c6a620f2SGeorge Liu * 2057ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2058c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 2059c6a620f2SGeorge Liu * 2060c6a620f2SGeorge Liu * @return None. 2061c6a620f2SGeorge Liu */ 20628d1b46d7Szhanghch05 inline void 2063ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20648d69c668SEd Tanous std::string_view policy) 2065c6a620f2SGeorge Liu { 2066c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 2067c6a620f2SGeorge Liu 20688d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 2069c6a620f2SGeorge Liu 20708d69c668SEd Tanous if (powerRestorePolicy.empty()) 2071c6a620f2SGeorge Liu { 2072ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 20734e69c904SGunnar Mills "PowerRestorePolicy"); 2074c6a620f2SGeorge Liu return; 2075c6a620f2SGeorge Liu } 2076c6a620f2SGeorge Liu 20779ae226faSGeorge Liu sdbusplus::asio::setProperty( 20789ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20799ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 20809ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 20819ae226faSGeorge Liu powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) { 2082c6a620f2SGeorge Liu if (ec) 2083c6a620f2SGeorge Liu { 2084ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2085c6a620f2SGeorge Liu return; 2086c6a620f2SGeorge Liu } 20879ae226faSGeorge Liu }); 2088c6a620f2SGeorge Liu } 2089c6a620f2SGeorge Liu 2090a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 2091a6349918SAppaRao Puli /** 2092a6349918SAppaRao Puli * @brief Retrieves provisioning status 2093a6349918SAppaRao Puli * 2094ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 2095a6349918SAppaRao Puli * 2096a6349918SAppaRao Puli * @return None. 2097a6349918SAppaRao Puli */ 2098ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 2099a6349918SAppaRao Puli { 2100a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 2101bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2102bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 2103bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 2104ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2105b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 2106b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2107ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2108ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 210950626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 211050626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 211150626f4fSJames Feist 2112a6349918SAppaRao Puli if (ec) 2113a6349918SAppaRao Puli { 2114a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2115b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2116b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2117a6349918SAppaRao Puli return; 2118a6349918SAppaRao Puli } 2119a6349918SAppaRao Puli 2120a6349918SAppaRao Puli const bool* provState = nullptr; 2121a6349918SAppaRao Puli const bool* lockState = nullptr; 2122bc1d29deSKrzysztof Grobelny 2123bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 21240d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 21250d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 2126bc1d29deSKrzysztof Grobelny 2127bc1d29deSKrzysztof Grobelny if (!success) 2128a6349918SAppaRao Puli { 2129ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2130bc1d29deSKrzysztof Grobelny return; 2131a6349918SAppaRao Puli } 2132a6349918SAppaRao Puli 2133a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2134a6349918SAppaRao Puli { 2135a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 2136ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2137a6349918SAppaRao Puli return; 2138a6349918SAppaRao Puli } 2139a6349918SAppaRao Puli 2140a6349918SAppaRao Puli if (*provState == true) 2141a6349918SAppaRao Puli { 2142a6349918SAppaRao Puli if (*lockState == true) 2143a6349918SAppaRao Puli { 2144a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2145a6349918SAppaRao Puli } 2146a6349918SAppaRao Puli else 2147a6349918SAppaRao Puli { 2148a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2149a6349918SAppaRao Puli } 2150a6349918SAppaRao Puli } 2151a6349918SAppaRao Puli else 2152a6349918SAppaRao Puli { 2153a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2154a6349918SAppaRao Puli } 2155bc1d29deSKrzysztof Grobelny }); 2156a6349918SAppaRao Puli } 2157a6349918SAppaRao Puli #endif 2158a6349918SAppaRao Puli 2159491d8ee7SSantosh Puranik /** 21603a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 21613a2d0424SChris Cain * 2162ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21633a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 21643a2d0424SChris Cain * 21653a2d0424SChris Cain * @return None. 21663a2d0424SChris Cain */ 2167ac106bf6SEd Tanous inline void 2168ac106bf6SEd Tanous translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 21693a2d0424SChris Cain const std::string& modeValue) 21703a2d0424SChris Cain { 21710fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 21723a2d0424SChris Cain { 2173ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "Static"; 21743a2d0424SChris Cain } 21750fda0f12SGeorge Liu else if ( 21760fda0f12SGeorge Liu modeValue == 21770fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 21783a2d0424SChris Cain { 2179ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 21803a2d0424SChris Cain } 21810fda0f12SGeorge Liu else if (modeValue == 21820fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 21833a2d0424SChris Cain { 2184ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "PowerSaving"; 21853a2d0424SChris Cain } 21860fda0f12SGeorge Liu else if (modeValue == 21870fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 21883a2d0424SChris Cain { 2189ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "OEM"; 21903a2d0424SChris Cain } 21913a2d0424SChris Cain else 21923a2d0424SChris Cain { 21933a2d0424SChris Cain // Any other values would be invalid 21943a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 2195ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21963a2d0424SChris Cain } 21973a2d0424SChris Cain } 21983a2d0424SChris Cain 21993a2d0424SChris Cain /** 22003a2d0424SChris Cain * @brief Retrieves system power mode 22013a2d0424SChris Cain * 2202ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22033a2d0424SChris Cain * 22043a2d0424SChris Cain * @return None. 22053a2d0424SChris Cain */ 2206ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 22073a2d0424SChris Cain { 22083a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 22093a2d0424SChris Cain 22103a2d0424SChris Cain // Get Power Mode object path: 2211e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2212e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2213e99073f5SGeorge Liu dbus::utility::getSubTree( 2214e99073f5SGeorge Liu "/", 0, interfaces, 2215ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2216b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22173a2d0424SChris Cain if (ec) 22183a2d0424SChris Cain { 2219002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2220002d39b4SEd Tanous << ec; 22213a2d0424SChris Cain // This is an optional D-Bus object so just return if 22223a2d0424SChris Cain // error occurs 22233a2d0424SChris Cain return; 22243a2d0424SChris Cain } 22253a2d0424SChris Cain if (subtree.empty()) 22263a2d0424SChris Cain { 22273a2d0424SChris Cain // As noted above, this is an optional interface so just return 22283a2d0424SChris Cain // if there is no instance found 22293a2d0424SChris Cain return; 22303a2d0424SChris Cain } 22313a2d0424SChris Cain if (subtree.size() > 1) 22323a2d0424SChris Cain { 22333a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22343a2d0424SChris Cain // error 22353a2d0424SChris Cain BMCWEB_LOG_DEBUG 22363a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 22373a2d0424SChris Cain << subtree.size(); 2238ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22393a2d0424SChris Cain return; 22403a2d0424SChris Cain } 22413a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22423a2d0424SChris Cain { 22433a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 2244ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22453a2d0424SChris Cain return; 22463a2d0424SChris Cain } 22473a2d0424SChris Cain const std::string& path = subtree[0].first; 22483a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22493a2d0424SChris Cain if (service.empty()) 22503a2d0424SChris Cain { 22513a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 2252ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22533a2d0424SChris Cain return; 22543a2d0424SChris Cain } 22553a2d0424SChris Cain // Valid Power Mode object found, now read the current value 22561e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 22571e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 22581e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2259ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 22601e1e598dSJonathan Doman const std::string& pmode) { 22618a592810SEd Tanous if (ec2) 22623a2d0424SChris Cain { 2263002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: " 22648a592810SEd Tanous << ec2; 2265ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22663a2d0424SChris Cain return; 22673a2d0424SChris Cain } 22683a2d0424SChris Cain 2269ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2270002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 22713a2d0424SChris Cain 22721e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 2273ac106bf6SEd Tanous translatePowerMode(asyncResp, pmode); 22741e1e598dSJonathan Doman }); 2275e99073f5SGeorge Liu }); 22763a2d0424SChris Cain } 22773a2d0424SChris Cain 22783a2d0424SChris Cain /** 22793a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 22803a2d0424SChris Cain * name associated with that string 22813a2d0424SChris Cain * 2282ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22833a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 22843a2d0424SChris Cain * 22853a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22863a2d0424SChris Cain */ 22873a2d0424SChris Cain inline std::string 2288ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22893a2d0424SChris Cain const std::string& modeString) 22903a2d0424SChris Cain { 22913a2d0424SChris Cain std::string mode; 22923a2d0424SChris Cain 22933a2d0424SChris Cain if (modeString == "Static") 22943a2d0424SChris Cain { 22953a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22963a2d0424SChris Cain } 22973a2d0424SChris Cain else if (modeString == "MaximumPerformance") 22983a2d0424SChris Cain { 22990fda0f12SGeorge Liu mode = 23000fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 23013a2d0424SChris Cain } 23023a2d0424SChris Cain else if (modeString == "PowerSaving") 23033a2d0424SChris Cain { 23043a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 23053a2d0424SChris Cain } 23063a2d0424SChris Cain else 23073a2d0424SChris Cain { 2308ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, modeString, 2309ac106bf6SEd Tanous "PowerMode"); 23103a2d0424SChris Cain } 23113a2d0424SChris Cain return mode; 23123a2d0424SChris Cain } 23133a2d0424SChris Cain 23143a2d0424SChris Cain /** 23153a2d0424SChris Cain * @brief Sets system power mode. 23163a2d0424SChris Cain * 2317ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 23183a2d0424SChris Cain * @param[in] pmode System power mode from request. 23193a2d0424SChris Cain * 23203a2d0424SChris Cain * @return None. 23213a2d0424SChris Cain */ 2322ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 23233a2d0424SChris Cain const std::string& pmode) 23243a2d0424SChris Cain { 23253a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 23263a2d0424SChris Cain 2327ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 23283a2d0424SChris Cain if (powerMode.empty()) 23293a2d0424SChris Cain { 23303a2d0424SChris Cain return; 23313a2d0424SChris Cain } 23323a2d0424SChris Cain 23333a2d0424SChris Cain // Get Power Mode object path: 2334e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2335e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2336e99073f5SGeorge Liu dbus::utility::getSubTree( 2337e99073f5SGeorge Liu "/", 0, interfaces, 2338ac106bf6SEd Tanous [asyncResp, 2339e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2340b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23413a2d0424SChris Cain if (ec) 23423a2d0424SChris Cain { 2343002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2344002d39b4SEd Tanous << ec; 23453a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2346ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23473a2d0424SChris Cain return; 23483a2d0424SChris Cain } 23493a2d0424SChris Cain if (subtree.empty()) 23503a2d0424SChris Cain { 23513a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2352ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 23533a2d0424SChris Cain "PowerMode"); 23543a2d0424SChris Cain return; 23553a2d0424SChris Cain } 23563a2d0424SChris Cain if (subtree.size() > 1) 23573a2d0424SChris Cain { 23583a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23593a2d0424SChris Cain // error 23603a2d0424SChris Cain BMCWEB_LOG_DEBUG 23613a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 23623a2d0424SChris Cain << subtree.size(); 2363ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23643a2d0424SChris Cain return; 23653a2d0424SChris Cain } 23663a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23673a2d0424SChris Cain { 23683a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 2369ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23703a2d0424SChris Cain return; 23713a2d0424SChris Cain } 23723a2d0424SChris Cain const std::string& path = subtree[0].first; 23733a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23743a2d0424SChris Cain if (service.empty()) 23753a2d0424SChris Cain { 23763a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 2377ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23783a2d0424SChris Cain return; 23793a2d0424SChris Cain } 23803a2d0424SChris Cain 23813a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 23823a2d0424SChris Cain << path; 23833a2d0424SChris Cain 23843a2d0424SChris Cain // Set the Power Mode property 23859ae226faSGeorge Liu sdbusplus::asio::setProperty( 23869ae226faSGeorge Liu *crow::connections::systemBus, service, path, 23879ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode, 2388ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 23898a592810SEd Tanous if (ec2) 23903a2d0424SChris Cain { 2391ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23923a2d0424SChris Cain return; 23933a2d0424SChris Cain } 23949ae226faSGeorge Liu }); 2395e99073f5SGeorge Liu }); 23963a2d0424SChris Cain } 23973a2d0424SChris Cain 23983a2d0424SChris Cain /** 239951709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 240051709ffdSYong Li * 240151709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 240251709ffdSYong Li * 240351709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 240451709ffdSYong Li * translation cannot be done, returns an empty string. 240551709ffdSYong Li */ 240623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 240751709ffdSYong Li { 240851709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 240951709ffdSYong Li { 241051709ffdSYong Li return "None"; 241151709ffdSYong Li } 24123174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 241351709ffdSYong Li { 241451709ffdSYong Li return "ResetSystem"; 241551709ffdSYong Li } 24163174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 241751709ffdSYong Li { 241851709ffdSYong Li return "PowerDown"; 241951709ffdSYong Li } 24203174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 242151709ffdSYong Li { 242251709ffdSYong Li return "PowerCycle"; 242351709ffdSYong Li } 242451709ffdSYong Li 242551709ffdSYong Li return ""; 242651709ffdSYong Li } 242751709ffdSYong Li 242851709ffdSYong Li /** 2429c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2430c45f0082SYong Li * 2431c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2432c45f0082SYong Li * 2433c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2434c45f0082SYong Li *If translation cannot be done, returns an empty string. 2435c45f0082SYong Li */ 2436c45f0082SYong Li 243723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2438c45f0082SYong Li { 2439c45f0082SYong Li if (rfAction == "None") 2440c45f0082SYong Li { 2441c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2442c45f0082SYong Li } 24433174e4dfSEd Tanous if (rfAction == "PowerCycle") 2444c45f0082SYong Li { 2445c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2446c45f0082SYong Li } 24473174e4dfSEd Tanous if (rfAction == "PowerDown") 2448c45f0082SYong Li { 2449c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2450c45f0082SYong Li } 24513174e4dfSEd Tanous if (rfAction == "ResetSystem") 2452c45f0082SYong Li { 2453c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2454c45f0082SYong Li } 2455c45f0082SYong Li 2456c45f0082SYong Li return ""; 2457c45f0082SYong Li } 2458c45f0082SYong Li 2459c45f0082SYong Li /** 246051709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 246151709ffdSYong Li * 2462ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 246351709ffdSYong Li * 246451709ffdSYong Li * @return None. 246551709ffdSYong Li */ 24668d1b46d7Szhanghch05 inline void 2467ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 246851709ffdSYong Li { 246951709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 2470bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2471bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2472bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2473bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2474ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2475b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 247651709ffdSYong Li if (ec) 247751709ffdSYong Li { 247851709ffdSYong Li // watchdog service is stopped 247951709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 248051709ffdSYong Li return; 248151709ffdSYong Li } 248251709ffdSYong Li 248351709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 248451709ffdSYong Li 248551709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2486ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 248751709ffdSYong Li 248851709ffdSYong Li // watchdog service is running/enabled 248951709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 249051709ffdSYong Li 2491bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2492bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 249351709ffdSYong Li 2494bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2495bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2496bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2497bc1d29deSKrzysztof Grobelny 2498bc1d29deSKrzysztof Grobelny if (!success) 249951709ffdSYong Li { 2500ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2501601af5edSChicago Duan return; 250251709ffdSYong Li } 250351709ffdSYong Li 2504bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 250551709ffdSYong Li { 2506bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 250751709ffdSYong Li } 250851709ffdSYong Li 2509bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2510bc1d29deSKrzysztof Grobelny { 2511bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 251251709ffdSYong Li if (action.empty()) 251351709ffdSYong Li { 2514ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2515601af5edSChicago Duan return; 251651709ffdSYong Li } 251751709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 251851709ffdSYong Li } 2519bc1d29deSKrzysztof Grobelny }); 252051709ffdSYong Li } 252151709ffdSYong Li 252251709ffdSYong Li /** 2523c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2524c45f0082SYong Li * 2525ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2526c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2527c45f0082SYong Li * RF request. 2528c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2529c45f0082SYong Li * 2530c45f0082SYong Li * @return None. 2531c45f0082SYong Li */ 2532ac106bf6SEd Tanous inline void 2533ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2534c45f0082SYong Li const std::optional<bool> wdtEnable, 2535c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2536c45f0082SYong Li { 2537c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2538c45f0082SYong Li 2539c45f0082SYong Li if (wdtTimeOutAction) 2540c45f0082SYong Li { 2541c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2542c45f0082SYong Li // check if TimeOut Action is Valid 2543c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2544c45f0082SYong Li { 2545c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2546c45f0082SYong Li << *wdtTimeOutAction; 2547ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2548c45f0082SYong Li "TimeoutAction"); 2549c45f0082SYong Li return; 2550c45f0082SYong Li } 2551c45f0082SYong Li 25529ae226faSGeorge Liu sdbusplus::asio::setProperty( 25539ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25549ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25559ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 25569ae226faSGeorge Liu wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) { 2557c45f0082SYong Li if (ec) 2558c45f0082SYong Li { 2559c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2560ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2561c45f0082SYong Li return; 2562c45f0082SYong Li } 25639ae226faSGeorge Liu }); 2564c45f0082SYong Li } 2565c45f0082SYong Li 2566c45f0082SYong Li if (wdtEnable) 2567c45f0082SYong Li { 25689ae226faSGeorge Liu sdbusplus::asio::setProperty( 25699ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25709ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25719ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable, 2572ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2573c45f0082SYong Li if (ec) 2574c45f0082SYong Li { 2575c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2576ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2577c45f0082SYong Li return; 2578c45f0082SYong Li } 25799ae226faSGeorge Liu }); 2580c45f0082SYong Li } 2581c45f0082SYong Li } 2582c45f0082SYong Li 258337bbf98cSChris Cain /** 258437bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 258537bbf98cSChris Cain * 2586ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 258737bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 258837bbf98cSChris Cain * 258937bbf98cSChris Cain * @return true if successful 259037bbf98cSChris Cain */ 25911e5b7c88SJiaqing Zhao inline bool 2592ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25931e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 259437bbf98cSChris Cain { 2595bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2596bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2597bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2598bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2599bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2600bc1d29deSKrzysztof Grobelny 2601bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2602bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 26032661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 26042661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 26052661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2606bc1d29deSKrzysztof Grobelny 2607bc1d29deSKrzysztof Grobelny if (!success) 260837bbf98cSChris Cain { 260937bbf98cSChris Cain return false; 261037bbf98cSChris Cain } 2611bc1d29deSKrzysztof Grobelny 2612bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 261337bbf98cSChris Cain { 2614ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 261537bbf98cSChris Cain } 2616bc1d29deSKrzysztof Grobelny 2617bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 261837bbf98cSChris Cain { 2619ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2620bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 262137bbf98cSChris Cain } 2622bc1d29deSKrzysztof Grobelny 2623bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2624bc1d29deSKrzysztof Grobelny { 2625bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2626ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 262737bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 262837bbf98cSChris Cain .count(); 262937bbf98cSChris Cain } 2630bc1d29deSKrzysztof Grobelny 2631bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 263237bbf98cSChris Cain { 2633ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2634bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 263537bbf98cSChris Cain } 2636bc1d29deSKrzysztof Grobelny 2637bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 263837bbf98cSChris Cain { 2639bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2640ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 264137bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 264237bbf98cSChris Cain .count(); 264337bbf98cSChris Cain } 264437bbf98cSChris Cain 264537bbf98cSChris Cain return true; 264637bbf98cSChris Cain } 264737bbf98cSChris Cain 264837bbf98cSChris Cain /** 264937bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 265037bbf98cSChris Cain * 2651ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 265237bbf98cSChris Cain * 265337bbf98cSChris Cain * @return None. 265437bbf98cSChris Cain */ 2655ac106bf6SEd Tanous inline void 2656ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 265737bbf98cSChris Cain { 265837bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 265937bbf98cSChris Cain 266037bbf98cSChris Cain // Get IdlePowerSaver object path: 2661e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2662e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2663e99073f5SGeorge Liu dbus::utility::getSubTree( 2664e99073f5SGeorge Liu "/", 0, interfaces, 2665ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2666b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 266737bbf98cSChris Cain if (ec) 266837bbf98cSChris Cain { 266937bbf98cSChris Cain BMCWEB_LOG_DEBUG 267037bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 267137bbf98cSChris Cain << ec; 2672ac106bf6SEd Tanous messages::internalError(asyncResp->res); 267337bbf98cSChris Cain return; 267437bbf98cSChris Cain } 267537bbf98cSChris Cain if (subtree.empty()) 267637bbf98cSChris Cain { 267737bbf98cSChris Cain // This is an optional interface so just return 267837bbf98cSChris Cain // if there is no instance found 267937bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 268037bbf98cSChris Cain return; 268137bbf98cSChris Cain } 268237bbf98cSChris Cain if (subtree.size() > 1) 268337bbf98cSChris Cain { 268437bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 268537bbf98cSChris Cain // is an error 268637bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 268737bbf98cSChris Cain "Power.IdlePowerSaver objects: " 268837bbf98cSChris Cain << subtree.size(); 2689ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269037bbf98cSChris Cain return; 269137bbf98cSChris Cain } 269237bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 269337bbf98cSChris Cain { 269437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 2695ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269637bbf98cSChris Cain return; 269737bbf98cSChris Cain } 269837bbf98cSChris Cain const std::string& path = subtree[0].first; 269937bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 270037bbf98cSChris Cain if (service.empty()) 270137bbf98cSChris Cain { 2702002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 2703ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270437bbf98cSChris Cain return; 270537bbf98cSChris Cain } 270637bbf98cSChris Cain 270737bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2708bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2709bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2710bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2711ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 27121e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 27138a592810SEd Tanous if (ec2) 271437bbf98cSChris Cain { 271537bbf98cSChris Cain BMCWEB_LOG_ERROR 27168a592810SEd Tanous << "DBUS response error on IdlePowerSaver GetAll: " << ec2; 2717ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271837bbf98cSChris Cain return; 271937bbf98cSChris Cain } 272037bbf98cSChris Cain 2721ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 272237bbf98cSChris Cain { 2723ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272437bbf98cSChris Cain return; 272537bbf98cSChris Cain } 2726bc1d29deSKrzysztof Grobelny }); 2727e99073f5SGeorge Liu }); 272837bbf98cSChris Cain 272937bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 273037bbf98cSChris Cain } 273137bbf98cSChris Cain 273237bbf98cSChris Cain /** 273337bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 273437bbf98cSChris Cain * 2735ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 273637bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 273737bbf98cSChris Cain * RF request. 273837bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 273937bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 274037bbf98cSChris Cain * before entering idle state. 274137bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 274237bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 274337bbf98cSChris Cain * before exiting idle state 274437bbf98cSChris Cain * 274537bbf98cSChris Cain * @return None. 274637bbf98cSChris Cain */ 2747ac106bf6SEd Tanous inline void 2748ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 274937bbf98cSChris Cain const std::optional<bool> ipsEnable, 275037bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 275137bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 275237bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 275337bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 275437bbf98cSChris Cain { 275537bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 275637bbf98cSChris Cain 275737bbf98cSChris Cain // Get IdlePowerSaver object path: 2758e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2759e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2760e99073f5SGeorge Liu dbus::utility::getSubTree( 2761e99073f5SGeorge Liu "/", 0, interfaces, 2762ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2763e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2764b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 276537bbf98cSChris Cain if (ec) 276637bbf98cSChris Cain { 276737bbf98cSChris Cain BMCWEB_LOG_DEBUG 276837bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 276937bbf98cSChris Cain << ec; 2770ac106bf6SEd Tanous messages::internalError(asyncResp->res); 277137bbf98cSChris Cain return; 277237bbf98cSChris Cain } 277337bbf98cSChris Cain if (subtree.empty()) 277437bbf98cSChris Cain { 277537bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2776ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 277737bbf98cSChris Cain "IdlePowerSaver"); 277837bbf98cSChris Cain return; 277937bbf98cSChris Cain } 278037bbf98cSChris Cain if (subtree.size() > 1) 278137bbf98cSChris Cain { 278237bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 278337bbf98cSChris Cain // is an error 27840fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 27850fda0f12SGeorge Liu << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: " 278637bbf98cSChris Cain << subtree.size(); 2787ac106bf6SEd Tanous messages::internalError(asyncResp->res); 278837bbf98cSChris Cain return; 278937bbf98cSChris Cain } 279037bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 279137bbf98cSChris Cain { 279237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 2793ac106bf6SEd Tanous messages::internalError(asyncResp->res); 279437bbf98cSChris Cain return; 279537bbf98cSChris Cain } 279637bbf98cSChris Cain const std::string& path = subtree[0].first; 279737bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 279837bbf98cSChris Cain if (service.empty()) 279937bbf98cSChris Cain { 2800002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 2801ac106bf6SEd Tanous messages::internalError(asyncResp->res); 280237bbf98cSChris Cain return; 280337bbf98cSChris Cain } 280437bbf98cSChris Cain 280537bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 280637bbf98cSChris Cain // need to be updated 280737bbf98cSChris Cain 280837bbf98cSChris Cain if (ipsEnable) 280937bbf98cSChris Cain { 28109ae226faSGeorge Liu sdbusplus::asio::setProperty( 28119ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28129ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 28139ae226faSGeorge Liu *ipsEnable, [asyncResp](const boost::system::error_code& ec2) { 28148a592810SEd Tanous if (ec2) 281537bbf98cSChris Cain { 28168a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2817ac106bf6SEd Tanous messages::internalError(asyncResp->res); 281837bbf98cSChris Cain return; 281937bbf98cSChris Cain } 28209ae226faSGeorge Liu }); 282137bbf98cSChris Cain } 282237bbf98cSChris Cain if (ipsEnterUtil) 282337bbf98cSChris Cain { 28249ae226faSGeorge Liu sdbusplus::asio::setProperty( 28259ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28269ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28279ae226faSGeorge Liu "EnterUtilizationPercent", *ipsEnterUtil, 2828ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28298a592810SEd Tanous if (ec2) 283037bbf98cSChris Cain { 28318a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2832ac106bf6SEd Tanous messages::internalError(asyncResp->res); 283337bbf98cSChris Cain return; 283437bbf98cSChris Cain } 28359ae226faSGeorge Liu }); 283637bbf98cSChris Cain } 283737bbf98cSChris Cain if (ipsEnterTime) 283837bbf98cSChris Cain { 283937bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 284037bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 28419ae226faSGeorge Liu sdbusplus::asio::setProperty( 28429ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28439ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28449ae226faSGeorge Liu "EnterDwellTime", timeMilliseconds, 2845ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28468a592810SEd Tanous if (ec2) 284737bbf98cSChris Cain { 28488a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2849ac106bf6SEd Tanous messages::internalError(asyncResp->res); 285037bbf98cSChris Cain return; 285137bbf98cSChris Cain } 28529ae226faSGeorge Liu }); 285337bbf98cSChris Cain } 285437bbf98cSChris Cain if (ipsExitUtil) 285537bbf98cSChris Cain { 28569ae226faSGeorge Liu sdbusplus::asio::setProperty( 28579ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28589ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28599ae226faSGeorge Liu "ExitUtilizationPercent", *ipsExitUtil, 2860ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28618a592810SEd Tanous if (ec2) 286237bbf98cSChris Cain { 28638a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2864ac106bf6SEd Tanous messages::internalError(asyncResp->res); 286537bbf98cSChris Cain return; 286637bbf98cSChris Cain } 28679ae226faSGeorge Liu }); 286837bbf98cSChris Cain } 286937bbf98cSChris Cain if (ipsExitTime) 287037bbf98cSChris Cain { 287137bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 287237bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 28739ae226faSGeorge Liu sdbusplus::asio::setProperty( 28749ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28759ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28769ae226faSGeorge Liu "ExitDwellTime", timeMilliseconds, 2877ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28788a592810SEd Tanous if (ec2) 287937bbf98cSChris Cain { 28808a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2881ac106bf6SEd Tanous messages::internalError(asyncResp->res); 288237bbf98cSChris Cain return; 288337bbf98cSChris Cain } 28849ae226faSGeorge Liu }); 288537bbf98cSChris Cain } 2886e99073f5SGeorge Liu }); 288737bbf98cSChris Cain 288837bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 288937bbf98cSChris Cain } 289037bbf98cSChris Cain 2891c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2892dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2893dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2894dd60b9edSEd Tanous { 2895dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2896dd60b9edSEd Tanous { 2897dd60b9edSEd Tanous return; 2898dd60b9edSEd Tanous } 2899dd60b9edSEd Tanous asyncResp->res.addHeader( 2900dd60b9edSEd Tanous boost::beast::http::field::link, 2901dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2902dd60b9edSEd Tanous } 2903dd60b9edSEd Tanous 2904c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2905c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2906c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29071abe55efSEd Tanous { 29083ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2909f4c99e70SEd Tanous { 2910f4c99e70SEd Tanous return; 2911f4c99e70SEd Tanous } 2912dd60b9edSEd Tanous 2913dd60b9edSEd Tanous asyncResp->res.addHeader( 2914dd60b9edSEd Tanous boost::beast::http::field::link, 2915dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 29168d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 29170f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 29188d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 29198d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2920462023adSSunitha Harish 29217f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 29227f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 29237f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 29247f3e84a1SEd Tanous { 29257f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 29267f3e84a1SEd Tanous // Option currently returns no systems. TBD 29277f3e84a1SEd Tanous return; 29287f3e84a1SEd Tanous } 29297f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 29307f3e84a1SEd Tanous nlohmann::json::object_t system; 29317f3e84a1SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 29327f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 29331e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2934002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 29351e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2936002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 29375e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 29381e1e598dSJonathan Doman const std::string& /*hostName*/) { 29397f3e84a1SEd Tanous if (ec2) 2940462023adSSunitha Harish { 29417f3e84a1SEd Tanous return; 29427f3e84a1SEd Tanous } 29437f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 29447f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 29457f3e84a1SEd Tanous { 29467f3e84a1SEd Tanous BMCWEB_LOG_CRITICAL << "Count wasn't found??"; 29477f3e84a1SEd Tanous return; 29487f3e84a1SEd Tanous } 29497f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 29507f3e84a1SEd Tanous if (count == nullptr) 29517f3e84a1SEd Tanous { 29527f3e84a1SEd Tanous BMCWEB_LOG_CRITICAL << "Count wasn't found??"; 29537f3e84a1SEd Tanous return; 29547f3e84a1SEd Tanous } 29557f3e84a1SEd Tanous *count = *count + 1; 2956462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 29577f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 29581476687dSEd Tanous nlohmann::json::object_t hypervisor; 2959002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 29607f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 29611e1e598dSJonathan Doman }); 2962c1e219d5SEd Tanous } 2963c1e219d5SEd Tanous 2964c1e219d5SEd Tanous /** 29657e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 29667e860f15SJohn Edward Broadbent */ 29674f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29687e860f15SJohn Edward Broadbent { 296989492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 297089492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 297189492a15SPatrick Williams constexpr const char* interfaceName = 29727e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 297389492a15SPatrick Williams constexpr const char* method = "NMI"; 29747e860f15SJohn Edward Broadbent 29757e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 29765e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 29777e860f15SJohn Edward Broadbent if (ec) 29787e860f15SJohn Edward Broadbent { 29797e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 29807e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 29817e860f15SJohn Edward Broadbent return; 29827e860f15SJohn Edward Broadbent } 29837e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 29847e860f15SJohn Edward Broadbent }, 29857e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 29867e860f15SJohn Edward Broadbent } 2987c5b2abe0SLewanczyk, Dawid 2988c5b2abe0SLewanczyk, Dawid /** 2989fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 2990fc903b3dSAndrew Geissler */ 2991fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 2992fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 2993fc903b3dSAndrew Geissler std::string_view resetType, 2994fc903b3dSAndrew Geissler crow::Response& res) 2995fc903b3dSAndrew Geissler { 2996fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 2997fc903b3dSAndrew Geissler { 2998fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 2999fc903b3dSAndrew Geissler return; 3000fc903b3dSAndrew Geissler } 3001fc903b3dSAndrew Geissler 3002fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 3003fc903b3dSAndrew Geissler { 3004fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "D-Bus response error: " << ec; 3005fc903b3dSAndrew Geissler messages::internalError(res); 3006fc903b3dSAndrew Geissler return; 3007fc903b3dSAndrew Geissler } 3008fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 3009fc903b3dSAndrew Geissler 3010fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 3011fc903b3dSAndrew Geissler // user to retry in a bit 3012fc903b3dSAndrew Geissler if ((errorMessage == 3013fc903b3dSAndrew Geissler std::string_view( 3014fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 3015fc903b3dSAndrew Geissler (errorMessage == 3016fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 3017fc903b3dSAndrew Geissler { 3018fc903b3dSAndrew Geissler BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now"; 3019fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 3020fc903b3dSAndrew Geissler return; 3021fc903b3dSAndrew Geissler } 3022fc903b3dSAndrew Geissler 3023fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec 3024fc903b3dSAndrew Geissler << " sdbusplus:" << errorMessage; 3025fc903b3dSAndrew Geissler messages::internalError(res); 3026fc903b3dSAndrew Geissler } 3027fc903b3dSAndrew Geissler 3028c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 3029c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 30307f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3031c1e219d5SEd Tanous const std::string& systemName) 3032c1e219d5SEd Tanous { 30333ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 303445ca1b86SEd Tanous { 303545ca1b86SEd Tanous return; 303645ca1b86SEd Tanous } 3037c1e219d5SEd Tanous if (systemName != "system") 3038c1e219d5SEd Tanous { 3039c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3040c1e219d5SEd Tanous systemName); 3041c1e219d5SEd Tanous return; 3042c1e219d5SEd Tanous } 30437f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 30447f3e84a1SEd Tanous { 30457f3e84a1SEd Tanous // Option currently returns no systems. TBD 30467f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3047c1e219d5SEd Tanous systemName); 30487f3e84a1SEd Tanous return; 30497f3e84a1SEd Tanous } 30509712f8acSEd Tanous std::string resetType; 3051c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 3052cc340dd9SEd Tanous { 3053cc340dd9SEd Tanous return; 3054cc340dd9SEd Tanous } 3055cc340dd9SEd Tanous 3056d22c8396SJason M. Bills // Get the command and host vs. chassis 3057cc340dd9SEd Tanous std::string command; 3058543f4400SEd Tanous bool hostCommand = true; 3059d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 3060cc340dd9SEd Tanous { 3061cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 3062d22c8396SJason M. Bills hostCommand = true; 3063d22c8396SJason M. Bills } 3064d22c8396SJason M. Bills else if (resetType == "ForceOff") 3065d22c8396SJason M. Bills { 3066d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 3067d22c8396SJason M. Bills hostCommand = false; 3068d22c8396SJason M. Bills } 3069d22c8396SJason M. Bills else if (resetType == "ForceRestart") 3070d22c8396SJason M. Bills { 3071c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 307286a0851aSJason M. Bills hostCommand = true; 3073cc340dd9SEd Tanous } 30749712f8acSEd Tanous else if (resetType == "GracefulShutdown") 3075cc340dd9SEd Tanous { 3076cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 3077d22c8396SJason M. Bills hostCommand = true; 3078cc340dd9SEd Tanous } 30799712f8acSEd Tanous else if (resetType == "GracefulRestart") 3080cc340dd9SEd Tanous { 30810fda0f12SGeorge Liu command = 30820fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 3083d22c8396SJason M. Bills hostCommand = true; 3084d22c8396SJason M. Bills } 3085d22c8396SJason M. Bills else if (resetType == "PowerCycle") 3086d22c8396SJason M. Bills { 308786a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 308886a0851aSJason M. Bills hostCommand = true; 3089cc340dd9SEd Tanous } 3090bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 3091bfd5b826SLakshminarayana R. Kammath { 3092bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 3093bfd5b826SLakshminarayana R. Kammath return; 3094bfd5b826SLakshminarayana R. Kammath } 3095cc340dd9SEd Tanous else 3096cc340dd9SEd Tanous { 3097c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 3098cc340dd9SEd Tanous return; 3099cc340dd9SEd Tanous } 3100cc340dd9SEd Tanous 3101d22c8396SJason M. Bills if (hostCommand) 3102d22c8396SJason M. Bills { 31039ae226faSGeorge Liu sdbusplus::asio::setProperty( 31049ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 31059ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 31069ae226faSGeorge Liu "xyz.openbmc_project.State.Host", "RequestedHostTransition", 31079ae226faSGeorge Liu command, 3108fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3109fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3110cc340dd9SEd Tanous if (ec) 3111cc340dd9SEd Tanous { 3112fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3113fc903b3dSAndrew Geissler asyncResp->res); 3114fc903b3dSAndrew Geissler 3115cc340dd9SEd Tanous return; 3116cc340dd9SEd Tanous } 3117f12894f8SJason M. Bills messages::success(asyncResp->res); 31189ae226faSGeorge Liu }); 3119cc340dd9SEd Tanous } 3120d22c8396SJason M. Bills else 3121d22c8396SJason M. Bills { 31229ae226faSGeorge Liu sdbusplus::asio::setProperty( 31239ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 31249ae226faSGeorge Liu "/xyz/openbmc_project/state/chassis0", 31259ae226faSGeorge Liu "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 31269ae226faSGeorge Liu command, 3127fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3128fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3129d22c8396SJason M. Bills if (ec) 3130d22c8396SJason M. Bills { 3131fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3132fc903b3dSAndrew Geissler asyncResp->res); 3133d22c8396SJason M. Bills return; 3134d22c8396SJason M. Bills } 3135d22c8396SJason M. Bills messages::success(asyncResp->res); 31369ae226faSGeorge Liu }); 3137d22c8396SJason M. Bills } 3138d22c8396SJason M. Bills } 3139cc340dd9SEd Tanous 3140c1e219d5SEd Tanous inline void handleComputerSystemHead( 3141dd60b9edSEd Tanous App& app, const crow::Request& req, 31427f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31437f3e84a1SEd Tanous const std::string& /*systemName*/) 3144dd60b9edSEd Tanous { 3145dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3146dd60b9edSEd Tanous { 3147dd60b9edSEd Tanous return; 3148dd60b9edSEd Tanous } 3149dd60b9edSEd Tanous 3150dd60b9edSEd Tanous asyncResp->res.addHeader( 3151dd60b9edSEd Tanous boost::beast::http::field::link, 3152dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3153dd60b9edSEd Tanous } 3154dd60b9edSEd Tanous 31555c3e9272SAbhishek Patel inline void afterPortRequest( 31565c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31575c3e9272SAbhishek Patel const boost::system::error_code& ec, 31585c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 31595c3e9272SAbhishek Patel { 31605c3e9272SAbhishek Patel if (ec) 31615c3e9272SAbhishek Patel { 31625c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31635c3e9272SAbhishek Patel return; 31645c3e9272SAbhishek Patel } 31655c3e9272SAbhishek Patel for (const auto& data : socketData) 31665c3e9272SAbhishek Patel { 31675c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 31685c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 31695c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 31705c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 31715c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 31725c3e9272SAbhishek Patel // need to retrieve port number for 31735c3e9272SAbhishek Patel // obmc-console-ssh service 31745c3e9272SAbhishek Patel if (protocolName == "SSH") 31755c3e9272SAbhishek Patel { 31765c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 317781c4e330SEd Tanous const boost::system::error_code& ec1, 31785c3e9272SAbhishek Patel int portNumber) { 31795c3e9272SAbhishek Patel if (ec1) 31805c3e9272SAbhishek Patel { 31815c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31825c3e9272SAbhishek Patel return; 31835c3e9272SAbhishek Patel } 31845c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 31855c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 31865c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 31875c3e9272SAbhishek Patel }); 31885c3e9272SAbhishek Patel } 31895c3e9272SAbhishek Patel } 31905c3e9272SAbhishek Patel } 3191c1e219d5SEd Tanous 3192c1e219d5SEd Tanous inline void 3193c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 319422d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3195c1e219d5SEd Tanous const std::string& systemName) 3196c1e219d5SEd Tanous { 31973ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 319845ca1b86SEd Tanous { 319945ca1b86SEd Tanous return; 320045ca1b86SEd Tanous } 3201746b56f3SAsmitha Karunanithi 32027f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 32037f3e84a1SEd Tanous { 32047f3e84a1SEd Tanous // Option currently returns no systems. TBD 32057f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 32067f3e84a1SEd Tanous systemName); 32077f3e84a1SEd Tanous return; 32087f3e84a1SEd Tanous } 32097f3e84a1SEd Tanous 3210746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3211746b56f3SAsmitha Karunanithi { 3212746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3213746b56f3SAsmitha Karunanithi return; 3214746b56f3SAsmitha Karunanithi } 3215746b56f3SAsmitha Karunanithi 321622d268cbSEd Tanous if (systemName != "system") 321722d268cbSEd Tanous { 321822d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 321922d268cbSEd Tanous systemName); 322022d268cbSEd Tanous return; 322122d268cbSEd Tanous } 3222dd60b9edSEd Tanous asyncResp->res.addHeader( 3223dd60b9edSEd Tanous boost::beast::http::field::link, 3224dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 32258d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 322637bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 32278d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 32288d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 32298d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 32308d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 32318d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 32325fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 32335fd0aafbSNinad Palsule { 32348d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 32358d1b46d7Szhanghch05 "Disabled"; 32368d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 32378d1b46d7Szhanghch05 "Disabled"; 32385fd0aafbSNinad Palsule } 3239cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3240*dfb2b408SPriyanga Ramasamy double(0); 3241002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 324204a258f4SEd Tanous 32431476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 32441476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 32451476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 32461476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 32471476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 32481476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 32493179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 32503179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3251029573d4SEd Tanous 3252002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 32531476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 3254c1e219d5SEd Tanous asyncResp->res 3255c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 32561476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3257c5b2abe0SLewanczyk, Dawid 32581476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 32591476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 32601476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 32611476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3262c4bf6374SJason M. Bills 32631476687dSEd Tanous nlohmann::json::array_t managedBy; 32641476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 32651476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3266002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 32671476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 32681476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 32690e8ac5e7SGunnar Mills 32700e8ac5e7SGunnar Mills // Fill in SerialConsole info 3271002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3272c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 32731476687dSEd Tanous 3274c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 32751476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3276c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 32771476687dSEd Tanous "Press ~. to exit console"; 32785c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 32795c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 32800e8ac5e7SGunnar Mills 32810e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 32820e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3283002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3284c1e219d5SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4; 3285613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3286613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 32871476687dSEd Tanous 32880e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 328913451e39SWilly Tu 329013451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 329113451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 329213451e39SWilly Tu { 32937a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3294b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 32952ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3296e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3297e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3298b49ac873SJames Feist 32997a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 33007a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 33017a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3302914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3303b49ac873SJames Feist if (ec) 3304b49ac873SJames Feist { 3305b49ac873SJames Feist // no inventory 3306b49ac873SJames Feist return; 3307b49ac873SJames Feist } 3308b49ac873SJames Feist 3309914e2d5dSEd Tanous health->inventory = resp; 33107a1dbc48SGeorge Liu }); 3311b49ac873SJames Feist health->populate(); 331213451e39SWilly Tu } 3313b49ac873SJames Feist 3314002d39b4SEd Tanous getMainChassisId(asyncResp, 3315002d39b4SEd Tanous [](const std::string& chassisId, 33168d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3317b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3318b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3319ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3320ef4c65b7SEd Tanous chassisId); 3321002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3322c5d03ff4SJennifer Lee }); 3323a3002228SAppaRao Puli 33249f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 33259f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3326a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 33275bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 33286c34de48SEd Tanous getHostState(asyncResp); 3329491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3330978b8803SAndrew Geissler getBootProgress(asyncResp); 3331b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3332472bd202SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices"); 333351709ffdSYong Li getHostWatchdogTimer(asyncResp); 3334c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 33359dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3336797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3337c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3338a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3339a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3340a6349918SAppaRao Puli #endif 33411981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 33423a2d0424SChris Cain getPowerMode(asyncResp); 334337bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3344c1e219d5SEd Tanous } 3345550a6bf8SJiaqing Zhao 3346c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3347c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 334822d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3349c1e219d5SEd Tanous const std::string& systemName) 3350c1e219d5SEd Tanous { 33513ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 335245ca1b86SEd Tanous { 335345ca1b86SEd Tanous return; 335445ca1b86SEd Tanous } 33557f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 33567f3e84a1SEd Tanous { 33577f3e84a1SEd Tanous // Option currently returns no systems. TBD 33587f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 33597f3e84a1SEd Tanous systemName); 33607f3e84a1SEd Tanous return; 33617f3e84a1SEd Tanous } 336222d268cbSEd Tanous if (systemName != "system") 336322d268cbSEd Tanous { 336422d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 336522d268cbSEd Tanous systemName); 336622d268cbSEd Tanous return; 336722d268cbSEd Tanous } 336822d268cbSEd Tanous 3369dd60b9edSEd Tanous asyncResp->res.addHeader( 3370dd60b9edSEd Tanous boost::beast::http::field::link, 3371dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3372dd60b9edSEd Tanous 33739f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3374cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 337598e386ecSGunnar Mills std::optional<std::string> assetTag; 3376c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 33773a2d0424SChris Cain std::optional<std::string> powerMode; 3378550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3379550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3380550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3381550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3382550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3383550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3384797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3385550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 33869dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3387550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3388550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3389550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3390550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3391550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3392550a6bf8SJiaqing Zhao 3393550a6bf8SJiaqing Zhao // clang-format off 339415ed6780SWilly Tu if (!json_util::readJsonPatch( 3395550a6bf8SJiaqing Zhao req, asyncResp->res, 3396550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 33977e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3398550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3399550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3400550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3401550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3402550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3403550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3404550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3405550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3406550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3407797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3408550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 34099dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3410550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3411550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3412550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3413550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3414550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 34156617338dSEd Tanous { 34166617338dSEd Tanous return; 34176617338dSEd Tanous } 3418550a6bf8SJiaqing Zhao // clang-format on 3419491d8ee7SSantosh Puranik 34208d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3421c45f0082SYong Li 342298e386ecSGunnar Mills if (assetTag) 342398e386ecSGunnar Mills { 342498e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 342598e386ecSGunnar Mills } 342698e386ecSGunnar Mills 3427550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3428c45f0082SYong Li { 3429f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3430c45f0082SYong Li } 3431c45f0082SYong Li 3432cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 343369f35306SGunnar Mills { 3434002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3435491d8ee7SSantosh Puranik } 3436550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 343769f35306SGunnar Mills { 3438550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 343969f35306SGunnar Mills } 3440ac7e1e0bSAli Ahmed 3441797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3442797d5daeSCorey Hardesty { 3443797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3444797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3445797d5daeSCorey Hardesty } 3446797d5daeSCorey Hardesty 3447550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3448ac7e1e0bSAli Ahmed { 3449c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 345069f35306SGunnar Mills } 3451265c1602SJohnathan Mantey 34529dcfe8c1SAlbert Zhang if (stopBootOnFault) 34539dcfe8c1SAlbert Zhang { 34549dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 34559dcfe8c1SAlbert Zhang } 34569dcfe8c1SAlbert Zhang 34579f8bfa7cSGunnar Mills if (locationIndicatorActive) 34589f8bfa7cSGunnar Mills { 3459002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 34609f8bfa7cSGunnar Mills } 34619f8bfa7cSGunnar Mills 34627e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 34637e860f15SJohn Edward Broadbent // passed 34649712f8acSEd Tanous if (indicatorLed) 34656617338dSEd Tanous { 3466f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3467002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3468d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3469d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 34706617338dSEd Tanous } 3471c6a620f2SGeorge Liu 3472c6a620f2SGeorge Liu if (powerRestorePolicy) 3473c6a620f2SGeorge Liu { 34744e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3475c6a620f2SGeorge Liu } 34763a2d0424SChris Cain 34773a2d0424SChris Cain if (powerMode) 34783a2d0424SChris Cain { 34793a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 34803a2d0424SChris Cain } 348137bbf98cSChris Cain 3482c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 348337bbf98cSChris Cain { 3484002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3485002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 348637bbf98cSChris Cain } 3487c1e219d5SEd Tanous } 34881cb1a9e6SAppaRao Puli 348938c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3490dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 34917f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3492c1e219d5SEd Tanous const std::string& /*systemName*/) 3493dd60b9edSEd Tanous { 3494dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3495dd60b9edSEd Tanous { 3496dd60b9edSEd Tanous return; 3497dd60b9edSEd Tanous } 3498dd60b9edSEd Tanous asyncResp->res.addHeader( 3499dd60b9edSEd Tanous boost::beast::http::field::link, 3500dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3501dd60b9edSEd Tanous } 3502c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3503c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 350422d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3505c1e219d5SEd Tanous const std::string& systemName) 3506c1e219d5SEd Tanous { 35073ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 350845ca1b86SEd Tanous { 350945ca1b86SEd Tanous return; 351045ca1b86SEd Tanous } 35117f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 35127f3e84a1SEd Tanous { 35137f3e84a1SEd Tanous // Option currently returns no systems. TBD 35147f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 35157f3e84a1SEd Tanous systemName); 35167f3e84a1SEd Tanous return; 35177f3e84a1SEd Tanous } 3518746b56f3SAsmitha Karunanithi 3519746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3520746b56f3SAsmitha Karunanithi { 3521746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3522746b56f3SAsmitha Karunanithi return; 3523746b56f3SAsmitha Karunanithi } 3524746b56f3SAsmitha Karunanithi 352522d268cbSEd Tanous if (systemName != "system") 352622d268cbSEd Tanous { 352722d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 352822d268cbSEd Tanous systemName); 352922d268cbSEd Tanous return; 353022d268cbSEd Tanous } 353122d268cbSEd Tanous 3532dd60b9edSEd Tanous asyncResp->res.addHeader( 3533dd60b9edSEd Tanous boost::beast::http::field::link, 3534dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 35351476687dSEd Tanous 35361476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 35371476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3538c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 35391476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 35401476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 35413215e700SNan Zhou 35423215e700SNan Zhou nlohmann::json::array_t parameters; 35433215e700SNan Zhou nlohmann::json::object_t parameter; 35443215e700SNan Zhou 35453215e700SNan Zhou parameter["Name"] = "ResetType"; 35463215e700SNan Zhou parameter["Required"] = true; 35473215e700SNan Zhou parameter["DataType"] = "String"; 35483215e700SNan Zhou nlohmann::json::array_t allowableValues; 35493215e700SNan Zhou allowableValues.emplace_back("On"); 35503215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 35513215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 35523215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 35533215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 35543215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 35553215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 35563215e700SNan Zhou allowableValues.emplace_back("Nmi"); 35573215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 35583215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 35593215e700SNan Zhou 35603215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 3561c1e219d5SEd Tanous } 3562c1e219d5SEd Tanous /** 3563c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3564c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3565c1e219d5SEd Tanous */ 3566100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3567c1e219d5SEd Tanous { 3568100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3569100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3570100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3571100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3572100afe56SEd Tanous 3573100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3574100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3575100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3576100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3577100afe56SEd Tanous 3578100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3579100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3580100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3581100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3582100afe56SEd Tanous 3583100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3584100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3585100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3586100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3587100afe56SEd Tanous 3588100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3589100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3590100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3591100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3592100afe56SEd Tanous 3593100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3594100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3595100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3596100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3597100afe56SEd Tanous 3598c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3599c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3600c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3601c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3602c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3603c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3604c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3605c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 36061cb1a9e6SAppaRao Puli } 3607c5b2abe0SLewanczyk, Dawid } // namespace redfish 3608