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" 23*8d69c668SEd 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"]; 300cf0e004cSNinad Palsule const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>(); 301cf0e004cSNinad Palsule if (preValue == nullptr) 302cf0e004cSNinad Palsule { 303ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 304cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024); 305cf0e004cSNinad Palsule } 306cf0e004cSNinad Palsule else 307cf0e004cSNinad Palsule { 308ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 309cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue; 310cf0e004cSNinad Palsule } 3115fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3125fd0aafbSNinad Palsule { 313ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 3145fd0aafbSNinad Palsule "Enabled"; 3155fd0aafbSNinad Palsule } 316cf0e004cSNinad Palsule } 317cf0e004cSNinad Palsule } 318cf0e004cSNinad Palsule 319cf0e004cSNinad Palsule /* 320cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 321cf0e004cSNinad Palsule * 322ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 323cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 324cf0e004cSNinad Palsule * @param[in] path dbus path for memory 325cf0e004cSNinad Palsule * 326cf0e004cSNinad Palsule * @return None. 327cf0e004cSNinad Palsule */ 328ac106bf6SEd Tanous inline void 329ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 330ac106bf6SEd Tanous const std::string& service, const std::string& path) 331cf0e004cSNinad Palsule { 332cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 333cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 334cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 335ac106bf6SEd Tanous [asyncResp, service, 336cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 337cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 338cf0e004cSNinad Palsule if (ec2) 339cf0e004cSNinad Palsule { 340cf0e004cSNinad Palsule BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 341ac106bf6SEd Tanous messages::internalError(asyncResp->res); 342cf0e004cSNinad Palsule return; 343cf0e004cSNinad Palsule } 344ac106bf6SEd Tanous processMemoryProperties(asyncResp, service, path, properties); 345cf0e004cSNinad Palsule }); 346cf0e004cSNinad Palsule } 347cf0e004cSNinad Palsule 348cf0e004cSNinad Palsule /* 349c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 350c5b2abe0SLewanczyk, Dawid * 351ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 3528f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 353c5b2abe0SLewanczyk, Dawid * 354c5b2abe0SLewanczyk, Dawid * @return None. 355c5b2abe0SLewanczyk, Dawid */ 356b5a76932SEd Tanous inline void 357ac106bf6SEd Tanous getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 358b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 3591abe55efSEd Tanous { 36055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 361e99073f5SGeorge Liu constexpr std::array<std::string_view, 5> interfaces = { 362e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Asset", 363e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cpu", 364e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm", 365e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System", 366e99073f5SGeorge Liu "xyz.openbmc_project.Common.UUID", 367e99073f5SGeorge Liu }; 368e99073f5SGeorge Liu dbus::utility::getSubTree( 369e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 370ac106bf6SEd Tanous [asyncResp, 371e99073f5SGeorge Liu systemHealth](const boost::system::error_code& ec, 372b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 3731abe55efSEd Tanous if (ec) 3741abe55efSEd Tanous { 37555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 376ac106bf6SEd Tanous messages::internalError(asyncResp->res); 377c5b2abe0SLewanczyk, Dawid return; 378c5b2abe0SLewanczyk, Dawid } 379c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 380002d39b4SEd Tanous for (const std::pair< 381002d39b4SEd Tanous std::string, 382002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 3831214b7e7SGunnar Mills object : subtree) 3841abe55efSEd Tanous { 385c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 38655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 387002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 3881214b7e7SGunnar Mills connectionNames = object.second; 38926f6976fSEd Tanous if (connectionNames.empty()) 3901abe55efSEd Tanous { 391c5b2abe0SLewanczyk, Dawid continue; 392c5b2abe0SLewanczyk, Dawid } 393029573d4SEd Tanous 3945fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> memoryHealth = nullptr; 3955fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> cpuHealth = nullptr; 3965bc2dc8eSJames Feist 3975fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3985fd0aafbSNinad Palsule { 3995fd0aafbSNinad Palsule memoryHealth = std::make_shared<HealthPopulate>( 400ac106bf6SEd Tanous asyncResp, "/MemorySummary/Status"_json_pointer); 4015fd0aafbSNinad Palsule systemHealth->children.emplace_back(memoryHealth); 4025bc2dc8eSJames Feist 40313451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 40413451e39SWilly Tu { 4055fd0aafbSNinad Palsule cpuHealth = std::make_shared<HealthPopulate>( 406ac106bf6SEd Tanous asyncResp, "/ProcessorSummary/Status"_json_pointer); 4075fd0aafbSNinad Palsule 4085bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 40913451e39SWilly Tu } 4105fd0aafbSNinad Palsule } 4115bc2dc8eSJames Feist 4126c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4136c34de48SEd Tanous // BiosVer 41404a258f4SEd Tanous for (const auto& connection : connectionNames) 4151abe55efSEd Tanous { 41604a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4171abe55efSEd Tanous { 41804a258f4SEd Tanous if (interfaceName == 41904a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 4201abe55efSEd Tanous { 4211abe55efSEd Tanous BMCWEB_LOG_DEBUG 42204a258f4SEd Tanous << "Found Dimm, now get its properties."; 4239d3ae10eSAlpana Kumari 424ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4255bc2dc8eSJames Feist 4265fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4275fd0aafbSNinad Palsule { 4285bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 4291abe55efSEd Tanous } 4305fd0aafbSNinad Palsule } 43104a258f4SEd Tanous else if (interfaceName == 43204a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4331abe55efSEd Tanous { 4341abe55efSEd Tanous BMCWEB_LOG_DEBUG 43504a258f4SEd Tanous << "Found Cpu, now get its properties."; 43657e8c9beSAlpana Kumari 437ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4385bc2dc8eSJames Feist 4395fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4405fd0aafbSNinad Palsule { 4415bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4421abe55efSEd Tanous } 4435fd0aafbSNinad Palsule } 444002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4451abe55efSEd Tanous { 4461abe55efSEd Tanous BMCWEB_LOG_DEBUG 44704a258f4SEd Tanous << "Found UUID, now get its properties."; 448bc1d29deSKrzysztof Grobelny 449bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 450bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 451bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Common.UUID", 452ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 453b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4541214b7e7SGunnar Mills properties) { 455cb13a392SEd Tanous if (ec3) 4561abe55efSEd Tanous { 457002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " 458002d39b4SEd Tanous << ec3; 459ac106bf6SEd Tanous messages::internalError(asyncResp->res); 460c5b2abe0SLewanczyk, Dawid return; 461c5b2abe0SLewanczyk, Dawid } 462002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 463c5b2abe0SLewanczyk, Dawid << " UUID properties."; 46404a258f4SEd Tanous 465bc1d29deSKrzysztof Grobelny const std::string* uUID = nullptr; 466bc1d29deSKrzysztof Grobelny 467bc1d29deSKrzysztof Grobelny const bool success = 468bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 469bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 470bc1d29deSKrzysztof Grobelny properties, "UUID", uUID); 471bc1d29deSKrzysztof Grobelny 472bc1d29deSKrzysztof Grobelny if (!success) 4731abe55efSEd Tanous { 474ac106bf6SEd Tanous messages::internalError(asyncResp->res); 475bc1d29deSKrzysztof Grobelny return; 476bc1d29deSKrzysztof Grobelny } 477bc1d29deSKrzysztof Grobelny 478bc1d29deSKrzysztof Grobelny if (uUID != nullptr) 479bc1d29deSKrzysztof Grobelny { 480bc1d29deSKrzysztof Grobelny std::string valueStr = *uUID; 48104a258f4SEd Tanous if (valueStr.size() == 32) 4821abe55efSEd Tanous { 483029573d4SEd Tanous valueStr.insert(8, 1, '-'); 484029573d4SEd Tanous valueStr.insert(13, 1, '-'); 485029573d4SEd Tanous valueStr.insert(18, 1, '-'); 486029573d4SEd Tanous valueStr.insert(23, 1, '-'); 48704a258f4SEd Tanous } 488bc1d29deSKrzysztof Grobelny BMCWEB_LOG_DEBUG << "UUID = " << valueStr; 489ac106bf6SEd Tanous asyncResp->res.jsonValue["UUID"] = valueStr; 490c5b2abe0SLewanczyk, Dawid } 491bc1d29deSKrzysztof Grobelny }); 492c5b2abe0SLewanczyk, Dawid } 493029573d4SEd Tanous else if (interfaceName == 494029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4951abe55efSEd Tanous { 496bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 497bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 498bc1d29deSKrzysztof Grobelny path, 499bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 500ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 501b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 5021214b7e7SGunnar Mills propertiesList) { 503cb13a392SEd Tanous if (ec2) 504029573d4SEd Tanous { 505e4a4b9a9SJames Feist // doesn't have to include this 506e4a4b9a9SJames Feist // interface 507029573d4SEd Tanous return; 508029573d4SEd Tanous } 509002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 510029573d4SEd Tanous << " properties for system"; 511bc1d29deSKrzysztof Grobelny 512bc1d29deSKrzysztof Grobelny const std::string* partNumber = nullptr; 513bc1d29deSKrzysztof Grobelny const std::string* serialNumber = nullptr; 514bc1d29deSKrzysztof Grobelny const std::string* manufacturer = nullptr; 515bc1d29deSKrzysztof Grobelny const std::string* model = nullptr; 516bc1d29deSKrzysztof Grobelny const std::string* subModel = nullptr; 517bc1d29deSKrzysztof Grobelny 518bc1d29deSKrzysztof Grobelny const bool success = 519bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 520bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 521bc1d29deSKrzysztof Grobelny propertiesList, "PartNumber", partNumber, 522bc1d29deSKrzysztof Grobelny "SerialNumber", serialNumber, 523bc1d29deSKrzysztof Grobelny "Manufacturer", manufacturer, "Model", 524bc1d29deSKrzysztof Grobelny model, "SubModel", subModel); 525bc1d29deSKrzysztof Grobelny 526bc1d29deSKrzysztof Grobelny if (!success) 527029573d4SEd Tanous { 528ac106bf6SEd Tanous messages::internalError(asyncResp->res); 529bc1d29deSKrzysztof Grobelny return; 530029573d4SEd Tanous } 531bc1d29deSKrzysztof Grobelny 532bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 533bc1d29deSKrzysztof Grobelny { 534ac106bf6SEd Tanous asyncResp->res.jsonValue["PartNumber"] = 535bc1d29deSKrzysztof Grobelny *partNumber; 536029573d4SEd Tanous } 537bc1d29deSKrzysztof Grobelny 538bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 539bc1d29deSKrzysztof Grobelny { 540ac106bf6SEd Tanous asyncResp->res.jsonValue["SerialNumber"] = 541bc1d29deSKrzysztof Grobelny *serialNumber; 542bc1d29deSKrzysztof Grobelny } 543bc1d29deSKrzysztof Grobelny 544bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 545bc1d29deSKrzysztof Grobelny { 546ac106bf6SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = 547bc1d29deSKrzysztof Grobelny *manufacturer; 548bc1d29deSKrzysztof Grobelny } 549bc1d29deSKrzysztof Grobelny 550bc1d29deSKrzysztof Grobelny if (model != nullptr) 551bc1d29deSKrzysztof Grobelny { 552ac106bf6SEd Tanous asyncResp->res.jsonValue["Model"] = *model; 553bc1d29deSKrzysztof Grobelny } 554bc1d29deSKrzysztof Grobelny 555bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 556bc1d29deSKrzysztof Grobelny { 557ac106bf6SEd Tanous asyncResp->res.jsonValue["SubModel"] = 558ac106bf6SEd Tanous *subModel; 559fc5afcf9Sbeccabroek } 560c1e236a6SGunnar Mills 561cb7e1e7bSAndrew Geissler // Grab the bios version 562eee0013eSWilly Tu sw_util::populateSoftwareInformation( 563ac106bf6SEd Tanous asyncResp, sw_util::biosPurpose, "BiosVersion", 564002d39b4SEd Tanous false); 565bc1d29deSKrzysztof Grobelny }); 566e4a4b9a9SJames Feist 5671e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5681e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5691e1e598dSJonathan Doman path, 5701e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5711e1e598dSJonathan Doman "AssetTag", 5721e1e598dSJonathan Doman "AssetTag", 573ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 5741e1e598dSJonathan Doman const std::string& value) { 575cb13a392SEd Tanous if (ec2) 576e4a4b9a9SJames Feist { 577e4a4b9a9SJames Feist // doesn't have to include this 578e4a4b9a9SJames Feist // interface 579e4a4b9a9SJames Feist return; 580e4a4b9a9SJames Feist } 581e4a4b9a9SJames Feist 582ac106bf6SEd Tanous asyncResp->res.jsonValue["AssetTag"] = value; 5831e1e598dSJonathan Doman }); 584029573d4SEd Tanous } 585029573d4SEd Tanous } 586029573d4SEd Tanous } 587c5b2abe0SLewanczyk, Dawid } 5886617338dSEd Tanous }); 589c5b2abe0SLewanczyk, Dawid } 590c5b2abe0SLewanczyk, Dawid 591c5b2abe0SLewanczyk, Dawid /** 592c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 593c5b2abe0SLewanczyk, Dawid * 594ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 595c5b2abe0SLewanczyk, Dawid * 596c5b2abe0SLewanczyk, Dawid * @return None. 597c5b2abe0SLewanczyk, Dawid */ 598ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5991abe55efSEd Tanous { 60055c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 6011e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 6021e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 6031e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 6041e1e598dSJonathan Doman "CurrentHostState", 605ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 6061e1e598dSJonathan Doman const std::string& hostState) { 6071abe55efSEd Tanous if (ec) 6081abe55efSEd Tanous { 60922228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 61022228c28SAndrew Geissler { 61122228c28SAndrew Geissler // Service not available, no error, just don't return 61222228c28SAndrew Geissler // host state info 61322228c28SAndrew Geissler BMCWEB_LOG_DEBUG << "Service not available " << ec; 61422228c28SAndrew Geissler return; 61522228c28SAndrew Geissler } 61622228c28SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 617ac106bf6SEd Tanous messages::internalError(asyncResp->res); 618c5b2abe0SLewanczyk, Dawid return; 619c5b2abe0SLewanczyk, Dawid } 6206617338dSEd Tanous 6211e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Host state: " << hostState; 622c5b2abe0SLewanczyk, Dawid // Verify Host State 6231e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 6241abe55efSEd Tanous { 625ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 626ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 6271abe55efSEd Tanous } 6281e1e598dSJonathan Doman else if (hostState == 6290fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 6308c888608SGunnar Mills { 631ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 632ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6338c888608SGunnar Mills } 6341e1e598dSJonathan Doman else if (hostState == 6350fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 63683935af9SAndrew Geissler { 637ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 638ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 63983935af9SAndrew Geissler } 6400fda0f12SGeorge Liu else if ( 6411e1e598dSJonathan Doman hostState == 6420fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6431a2a1437SAndrew Geissler { 644ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 645ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 6461a2a1437SAndrew Geissler } 647002d39b4SEd Tanous else if (hostState == 6480fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6491a2a1437SAndrew Geissler { 650ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 651ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 6521a2a1437SAndrew Geissler } 6531abe55efSEd Tanous else 6541abe55efSEd Tanous { 655ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 656ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 657c5b2abe0SLewanczyk, Dawid } 6581e1e598dSJonathan Doman }); 659c5b2abe0SLewanczyk, Dawid } 660c5b2abe0SLewanczyk, Dawid 661c5b2abe0SLewanczyk, Dawid /** 662786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 663491d8ee7SSantosh Puranik * 664491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 665491d8ee7SSantosh Puranik * 666491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 667491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 668491d8ee7SSantosh Puranik */ 66923a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 670491d8ee7SSantosh Puranik { 671491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 672491d8ee7SSantosh Puranik { 673491d8ee7SSantosh Puranik return "None"; 674491d8ee7SSantosh Puranik } 6753174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 676491d8ee7SSantosh Puranik { 677491d8ee7SSantosh Puranik return "Hdd"; 678491d8ee7SSantosh Puranik } 6793174e4dfSEd Tanous if (dbusSource == 680a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 681491d8ee7SSantosh Puranik { 682491d8ee7SSantosh Puranik return "Cd"; 683491d8ee7SSantosh Puranik } 6843174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 685491d8ee7SSantosh Puranik { 686491d8ee7SSantosh Puranik return "Pxe"; 687491d8ee7SSantosh Puranik } 6883174e4dfSEd Tanous if (dbusSource == 689944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6909f16b2c1SJennifer Lee { 6919f16b2c1SJennifer Lee return "Usb"; 6929f16b2c1SJennifer Lee } 693491d8ee7SSantosh Puranik return ""; 694491d8ee7SSantosh Puranik } 695491d8ee7SSantosh Puranik 696491d8ee7SSantosh Puranik /** 697cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 698cd9a4666SKonstantin Aladyshev * 699cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 700cd9a4666SKonstantin Aladyshev * 701cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 702cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 703cd9a4666SKonstantin Aladyshev */ 704cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 705cd9a4666SKonstantin Aladyshev { 706cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 707cd9a4666SKonstantin Aladyshev { 708cd9a4666SKonstantin Aladyshev return "Legacy"; 709cd9a4666SKonstantin Aladyshev } 710cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 711cd9a4666SKonstantin Aladyshev { 712cd9a4666SKonstantin Aladyshev return "UEFI"; 713cd9a4666SKonstantin Aladyshev } 714cd9a4666SKonstantin Aladyshev return ""; 715cd9a4666SKonstantin Aladyshev } 716cd9a4666SKonstantin Aladyshev 717cd9a4666SKonstantin Aladyshev /** 718786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 719491d8ee7SSantosh Puranik * 720491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 721491d8ee7SSantosh Puranik * 722491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 723491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 724491d8ee7SSantosh Puranik */ 72523a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 726491d8ee7SSantosh Puranik { 727491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 728491d8ee7SSantosh Puranik { 729491d8ee7SSantosh Puranik return "None"; 730491d8ee7SSantosh Puranik } 7313174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 732491d8ee7SSantosh Puranik { 733491d8ee7SSantosh Puranik return "Diags"; 734491d8ee7SSantosh Puranik } 7353174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 736491d8ee7SSantosh Puranik { 737491d8ee7SSantosh Puranik return "BiosSetup"; 738491d8ee7SSantosh Puranik } 739491d8ee7SSantosh Puranik return ""; 740491d8ee7SSantosh Puranik } 741491d8ee7SSantosh Puranik 742491d8ee7SSantosh Puranik /** 743e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 744e43914b3SAndrew Geissler * 745e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 746e43914b3SAndrew Geissler * 747e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 748e43914b3SAndrew Geissler * translation cannot be done, returns "None". 749e43914b3SAndrew Geissler */ 750e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 751e43914b3SAndrew Geissler { 752e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 753e43914b3SAndrew Geissler // enum 754e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 755e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 756e43914b3SAndrew Geissler "ProgressStages.Unspecified") 757e43914b3SAndrew Geissler { 758e43914b3SAndrew Geissler rfBpLastState = "None"; 759e43914b3SAndrew Geissler } 760e43914b3SAndrew Geissler else if (dbusBootProgress == 761e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 762e43914b3SAndrew Geissler "PrimaryProcInit") 763e43914b3SAndrew Geissler { 764e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 765e43914b3SAndrew Geissler } 766e43914b3SAndrew Geissler else if (dbusBootProgress == 767e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 768e43914b3SAndrew Geissler "BusInit") 769e43914b3SAndrew Geissler { 770e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 771e43914b3SAndrew Geissler } 772e43914b3SAndrew Geissler else if (dbusBootProgress == 773e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 774e43914b3SAndrew Geissler "MemoryInit") 775e43914b3SAndrew Geissler { 776e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 777e43914b3SAndrew Geissler } 778e43914b3SAndrew Geissler else if (dbusBootProgress == 779e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 780e43914b3SAndrew Geissler "SecondaryProcInit") 781e43914b3SAndrew Geissler { 782e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 783e43914b3SAndrew Geissler } 784e43914b3SAndrew Geissler else if (dbusBootProgress == 785e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 786e43914b3SAndrew Geissler "PCIInit") 787e43914b3SAndrew Geissler { 788e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 789e43914b3SAndrew Geissler } 790e43914b3SAndrew Geissler else if (dbusBootProgress == 791e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 792e43914b3SAndrew Geissler "SystemSetup") 793e43914b3SAndrew Geissler { 794e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 795e43914b3SAndrew Geissler } 796e43914b3SAndrew Geissler else if (dbusBootProgress == 797e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 798e43914b3SAndrew Geissler "SystemInitComplete") 799e43914b3SAndrew Geissler { 800e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 801e43914b3SAndrew Geissler } 802e43914b3SAndrew Geissler else if (dbusBootProgress == 803e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 804e43914b3SAndrew Geissler "OSStart") 805e43914b3SAndrew Geissler { 806e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 807e43914b3SAndrew Geissler } 808e43914b3SAndrew Geissler else if (dbusBootProgress == 809e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 810e43914b3SAndrew Geissler "OSRunning") 811e43914b3SAndrew Geissler { 812e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 813e43914b3SAndrew Geissler } 814e43914b3SAndrew Geissler else 815e43914b3SAndrew Geissler { 816e43914b3SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 817e43914b3SAndrew Geissler << dbusBootProgress; 818e43914b3SAndrew Geissler // Just return the default 819e43914b3SAndrew Geissler } 820e43914b3SAndrew Geissler return rfBpLastState; 821e43914b3SAndrew Geissler } 822e43914b3SAndrew Geissler 823e43914b3SAndrew Geissler /** 824786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 825491d8ee7SSantosh Puranik * 826491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 827944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 828944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 829491d8ee7SSantosh Puranik * 830944ffaf9SJohnathan Mantey * @return Integer error code. 831491d8ee7SSantosh Puranik */ 832ac106bf6SEd Tanous inline int 833ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 834ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 835ac106bf6SEd Tanous std::string& bootMode) 836491d8ee7SSantosh Puranik { 837c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 838c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 839944ffaf9SJohnathan Mantey 840491d8ee7SSantosh Puranik if (rfSource == "None") 841491d8ee7SSantosh Puranik { 842944ffaf9SJohnathan Mantey return 0; 843491d8ee7SSantosh Puranik } 8443174e4dfSEd Tanous if (rfSource == "Pxe") 845491d8ee7SSantosh Puranik { 846944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 847944ffaf9SJohnathan Mantey } 848944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 849944ffaf9SJohnathan Mantey { 850944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 851944ffaf9SJohnathan Mantey } 852944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 853944ffaf9SJohnathan Mantey { 854944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 855944ffaf9SJohnathan Mantey } 856944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 857944ffaf9SJohnathan Mantey { 858944ffaf9SJohnathan Mantey bootSource = 859944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 860944ffaf9SJohnathan Mantey } 861944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 862944ffaf9SJohnathan Mantey { 863944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 864491d8ee7SSantosh Puranik } 8659f16b2c1SJennifer Lee else if (rfSource == "Usb") 8669f16b2c1SJennifer Lee { 867944ffaf9SJohnathan Mantey bootSource = 868944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8699f16b2c1SJennifer Lee } 870491d8ee7SSantosh Puranik else 871491d8ee7SSantosh Puranik { 8720fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 8730fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideTarget: " 874944ffaf9SJohnathan Mantey << bootSource; 875ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 876944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 877944ffaf9SJohnathan Mantey return -1; 878491d8ee7SSantosh Puranik } 879944ffaf9SJohnathan Mantey return 0; 880491d8ee7SSantosh Puranik } 8811981771bSAli Ahmed 882978b8803SAndrew Geissler /** 883978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 884978b8803SAndrew Geissler * 885ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 886978b8803SAndrew Geissler * 887978b8803SAndrew Geissler * @return None. 888978b8803SAndrew Geissler */ 889ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 890978b8803SAndrew Geissler { 8911e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8921e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8931e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8941e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 895ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8961e1e598dSJonathan Doman const std::string& bootProgressStr) { 897978b8803SAndrew Geissler if (ec) 898978b8803SAndrew Geissler { 899978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 900978b8803SAndrew Geissler // not found 901978b8803SAndrew Geissler return; 902978b8803SAndrew Geissler } 903978b8803SAndrew Geissler 9041e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr; 905978b8803SAndrew Geissler 906ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 907e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 9081e1e598dSJonathan Doman }); 909978b8803SAndrew Geissler } 910491d8ee7SSantosh Puranik 911491d8ee7SSantosh Puranik /** 912b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 913b6d5d45cSHieu Huynh * 914ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 915b6d5d45cSHieu Huynh * 916b6d5d45cSHieu Huynh * @return None. 917b6d5d45cSHieu Huynh */ 918b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 919ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 920b6d5d45cSHieu Huynh { 921b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 922b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 923b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 924b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 925ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 926b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 927b6d5d45cSHieu Huynh if (ec) 928b6d5d45cSHieu Huynh { 929b6d5d45cSHieu Huynh BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 930b6d5d45cSHieu Huynh return; 931b6d5d45cSHieu Huynh } 932b6d5d45cSHieu Huynh 933b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 934b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 935b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 936b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 937b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 938b6d5d45cSHieu Huynh 939b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 940ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 941b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 942b6d5d45cSHieu Huynh }); 943b6d5d45cSHieu Huynh } 944b6d5d45cSHieu Huynh 945b6d5d45cSHieu Huynh /** 946c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 947cd9a4666SKonstantin Aladyshev * 948ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 949cd9a4666SKonstantin Aladyshev * 950cd9a4666SKonstantin Aladyshev * @return None. 951cd9a4666SKonstantin Aladyshev */ 952cd9a4666SKonstantin Aladyshev 953ac106bf6SEd Tanous inline void 954ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 955cd9a4666SKonstantin Aladyshev { 9561e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9571e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9581e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9591e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 960ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9611e1e598dSJonathan Doman const std::string& bootType) { 962cd9a4666SKonstantin Aladyshev if (ec) 963cd9a4666SKonstantin Aladyshev { 964cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 965cd9a4666SKonstantin Aladyshev return; 966cd9a4666SKonstantin Aladyshev } 967cd9a4666SKonstantin Aladyshev 9681e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot type: " << bootType; 969cd9a4666SKonstantin Aladyshev 970ac106bf6SEd Tanous asyncResp->res 971ac106bf6SEd Tanous .jsonValue["Boot"] 972002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 973613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 974cd9a4666SKonstantin Aladyshev 9751e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 976cd9a4666SKonstantin Aladyshev if (rfType.empty()) 977cd9a4666SKonstantin Aladyshev { 978ac106bf6SEd Tanous messages::internalError(asyncResp->res); 979cd9a4666SKonstantin Aladyshev return; 980cd9a4666SKonstantin Aladyshev } 981cd9a4666SKonstantin Aladyshev 982ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9831e1e598dSJonathan Doman }); 984cd9a4666SKonstantin Aladyshev } 985cd9a4666SKonstantin Aladyshev 986cd9a4666SKonstantin Aladyshev /** 987c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 988491d8ee7SSantosh Puranik * 989ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 990491d8ee7SSantosh Puranik * 991491d8ee7SSantosh Puranik * @return None. 992491d8ee7SSantosh Puranik */ 993c21865c4SKonstantin Aladyshev 994ac106bf6SEd Tanous inline void 995ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 996491d8ee7SSantosh Puranik { 9971e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9981e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9991e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10001e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1001ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10021e1e598dSJonathan Doman const std::string& bootModeStr) { 1003491d8ee7SSantosh Puranik if (ec) 1004491d8ee7SSantosh Puranik { 1005491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1006ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1007491d8ee7SSantosh Puranik return; 1008491d8ee7SSantosh Puranik } 1009491d8ee7SSantosh Puranik 10101e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 1011491d8ee7SSantosh Puranik 1012ac106bf6SEd Tanous asyncResp->res 10130fda0f12SGeorge Liu .jsonValue["Boot"] 1014002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 1015002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1016491d8ee7SSantosh Puranik 10171e1e598dSJonathan Doman if (bootModeStr != 1018491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1019491d8ee7SSantosh Puranik { 10201e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 1021491d8ee7SSantosh Puranik if (!rfMode.empty()) 1022491d8ee7SSantosh Puranik { 1023ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1024491d8ee7SSantosh Puranik rfMode; 1025491d8ee7SSantosh Puranik } 1026491d8ee7SSantosh Puranik } 10271e1e598dSJonathan Doman }); 1028491d8ee7SSantosh Puranik } 1029491d8ee7SSantosh Puranik 1030491d8ee7SSantosh Puranik /** 1031c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1032491d8ee7SSantosh Puranik * 1033ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1034491d8ee7SSantosh Puranik * 1035491d8ee7SSantosh Puranik * @return None. 1036491d8ee7SSantosh Puranik */ 1037c21865c4SKonstantin Aladyshev 1038c21865c4SKonstantin Aladyshev inline void 1039ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1040491d8ee7SSantosh Puranik { 10411e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10421e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10431e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10441e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1045ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10461e1e598dSJonathan Doman const std::string& bootSourceStr) { 1047491d8ee7SSantosh Puranik if (ec) 1048491d8ee7SSantosh Puranik { 1049491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 10505ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10515ef735c8SNan Zhou { 10525ef735c8SNan Zhou return; 10535ef735c8SNan Zhou } 1054ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1055491d8ee7SSantosh Puranik return; 1056491d8ee7SSantosh Puranik } 1057491d8ee7SSantosh Puranik 10581e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr; 1059491d8ee7SSantosh Puranik 10601e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1061491d8ee7SSantosh Puranik if (!rfSource.empty()) 1062491d8ee7SSantosh Puranik { 1063ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1064ac106bf6SEd Tanous rfSource; 1065491d8ee7SSantosh Puranik } 1066cd9a4666SKonstantin Aladyshev 1067cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1068cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1069ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10701e1e598dSJonathan Doman }); 1071491d8ee7SSantosh Puranik } 1072491d8ee7SSantosh Puranik 1073491d8ee7SSantosh Puranik /** 1074c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1075c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1076c21865c4SKonstantin Aladyshev * state 1077491d8ee7SSantosh Puranik * 1078ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1079491d8ee7SSantosh Puranik * 1080491d8ee7SSantosh Puranik * @return None. 1081491d8ee7SSantosh Puranik */ 1082491d8ee7SSantosh Puranik 1083ac106bf6SEd Tanous inline void processBootOverrideEnable( 1084ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1085c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1086c21865c4SKonstantin Aladyshev { 1087c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1088c21865c4SKonstantin Aladyshev { 1089ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1090ac106bf6SEd Tanous "Disabled"; 1091c21865c4SKonstantin Aladyshev return; 1092c21865c4SKonstantin Aladyshev } 1093c21865c4SKonstantin Aladyshev 1094c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1095c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10961e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10971e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10981e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10991e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1100ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1101491d8ee7SSantosh Puranik if (ec) 1102491d8ee7SSantosh Puranik { 1103491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1104ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1105491d8ee7SSantosh Puranik return; 1106491d8ee7SSantosh Puranik } 1107491d8ee7SSantosh Puranik 1108c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1109c21865c4SKonstantin Aladyshev { 1110ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1111ac106bf6SEd Tanous "Once"; 1112c21865c4SKonstantin Aladyshev } 1113c21865c4SKonstantin Aladyshev else 1114c21865c4SKonstantin Aladyshev { 1115ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1116c21865c4SKonstantin Aladyshev "Continuous"; 1117c21865c4SKonstantin Aladyshev } 11181e1e598dSJonathan Doman }); 1119491d8ee7SSantosh Puranik } 1120491d8ee7SSantosh Puranik 1121491d8ee7SSantosh Puranik /** 1122c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1123c21865c4SKonstantin Aladyshev * 1124ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1125c21865c4SKonstantin Aladyshev * 1126c21865c4SKonstantin Aladyshev * @return None. 1127c21865c4SKonstantin Aladyshev */ 1128c21865c4SKonstantin Aladyshev 1129c21865c4SKonstantin Aladyshev inline void 1130ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1131c21865c4SKonstantin Aladyshev { 11321e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11331e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11341e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 11351e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1136ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 11371e1e598dSJonathan Doman const bool bootOverrideEnable) { 1138c21865c4SKonstantin Aladyshev if (ec) 1139c21865c4SKonstantin Aladyshev { 1140c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 11415ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11425ef735c8SNan Zhou { 11435ef735c8SNan Zhou return; 11445ef735c8SNan Zhou } 1145ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1146c21865c4SKonstantin Aladyshev return; 1147c21865c4SKonstantin Aladyshev } 1148c21865c4SKonstantin Aladyshev 1149ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11501e1e598dSJonathan Doman }); 1151c21865c4SKonstantin Aladyshev } 1152c21865c4SKonstantin Aladyshev 1153c21865c4SKonstantin Aladyshev /** 1154c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1155c21865c4SKonstantin Aladyshev * 1156ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1157c21865c4SKonstantin Aladyshev * 1158c21865c4SKonstantin Aladyshev * @return None. 1159c21865c4SKonstantin Aladyshev */ 1160ac106bf6SEd Tanous inline void 1161ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1162c21865c4SKonstantin Aladyshev { 1163c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1164c21865c4SKonstantin Aladyshev 1165ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1166ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1167ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1168c21865c4SKonstantin Aladyshev } 1169c21865c4SKonstantin Aladyshev 1170c21865c4SKonstantin Aladyshev /** 1171c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1172c0557e1aSGunnar Mills * 1173c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1174c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1175c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1176c0557e1aSGunnar Mills * last power operation time. 1177c0557e1aSGunnar Mills * 1178ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1179c0557e1aSGunnar Mills * 1180c0557e1aSGunnar Mills * @return None. 1181c0557e1aSGunnar Mills */ 1182ac106bf6SEd Tanous inline void 1183ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1184c0557e1aSGunnar Mills { 1185c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1186c0557e1aSGunnar Mills 11871e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11881e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11891e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11901e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1191ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1192ac106bf6SEd Tanous uint64_t lastResetTime) { 1193c0557e1aSGunnar Mills if (ec) 1194c0557e1aSGunnar Mills { 1195c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1196c0557e1aSGunnar Mills return; 1197c0557e1aSGunnar Mills } 1198c0557e1aSGunnar Mills 1199c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1200c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 12011e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1202c0557e1aSGunnar Mills 1203c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1204ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 12052b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 12061e1e598dSJonathan Doman }); 1207c0557e1aSGunnar Mills } 1208c0557e1aSGunnar Mills 1209c0557e1aSGunnar Mills /** 1210797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1211797d5daeSCorey Hardesty * 1212797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1213797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1214797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1215797d5daeSCorey Hardesty * dbus. 1216797d5daeSCorey Hardesty * 1217ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1218797d5daeSCorey Hardesty * 1219797d5daeSCorey Hardesty * @return None. 1220797d5daeSCorey Hardesty */ 1221ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1222ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1223797d5daeSCorey Hardesty { 1224797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 1225797d5daeSCorey Hardesty 1226797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1227797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1228797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1229797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1230ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1231ac106bf6SEd Tanous const boost::system::error_code& ec, 1232797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1233797d5daeSCorey Hardesty if (ec) 1234797d5daeSCorey Hardesty { 1235797d5daeSCorey Hardesty if (ec.value() != EBADR) 1236797d5daeSCorey Hardesty { 1237797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1238ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1239797d5daeSCorey Hardesty } 1240797d5daeSCorey Hardesty return; 1241797d5daeSCorey Hardesty } 1242797d5daeSCorey Hardesty 1243797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1244797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1245797d5daeSCorey Hardesty 1246797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1247797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1248797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1249797d5daeSCorey Hardesty 1250797d5daeSCorey Hardesty if (!success) 1251797d5daeSCorey Hardesty { 1252ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1253797d5daeSCorey Hardesty return; 1254797d5daeSCorey Hardesty } 1255797d5daeSCorey Hardesty 1256797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1257797d5daeSCorey Hardesty { 1258ac106bf6SEd Tanous asyncResp->res 1259ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1260797d5daeSCorey Hardesty *attemptsLeft; 1261797d5daeSCorey Hardesty } 1262797d5daeSCorey Hardesty 1263797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1264797d5daeSCorey Hardesty { 1265ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1266797d5daeSCorey Hardesty *retryAttempts; 1267797d5daeSCorey Hardesty } 1268797d5daeSCorey Hardesty }); 1269797d5daeSCorey Hardesty } 1270797d5daeSCorey Hardesty 1271797d5daeSCorey Hardesty /** 12726bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12736bd5a8d2SGunnar Mills * 1274ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12756bd5a8d2SGunnar Mills * 12766bd5a8d2SGunnar Mills * @return None. 12776bd5a8d2SGunnar Mills */ 1278797d5daeSCorey Hardesty inline void 1279ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12806bd5a8d2SGunnar Mills { 12816bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 12826bd5a8d2SGunnar Mills 12831e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12841e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12851e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12861e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1287ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1288ac106bf6SEd Tanous bool autoRebootEnabled) { 12896bd5a8d2SGunnar Mills if (ec) 12906bd5a8d2SGunnar Mills { 1291797d5daeSCorey Hardesty if (ec.value() != EBADR) 1292797d5daeSCorey Hardesty { 1293797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1294ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1295797d5daeSCorey Hardesty } 12966bd5a8d2SGunnar Mills return; 12976bd5a8d2SGunnar Mills } 12986bd5a8d2SGunnar Mills 12991e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled; 1300e05aec50SEd Tanous if (autoRebootEnabled) 13016bd5a8d2SGunnar Mills { 1302ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 13036bd5a8d2SGunnar Mills "RetryAttempts"; 13046bd5a8d2SGunnar Mills } 13056bd5a8d2SGunnar Mills else 13066bd5a8d2SGunnar Mills { 1307ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1308ac106bf6SEd Tanous "Disabled"; 13096bd5a8d2SGunnar Mills } 1310ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 131169f35306SGunnar Mills 131269f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 131369f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 131469f35306SGunnar Mills // RetryAttempts. 1315ac106bf6SEd Tanous asyncResp->res 1316ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1317ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 13181e1e598dSJonathan Doman }); 13196bd5a8d2SGunnar Mills } 13206bd5a8d2SGunnar Mills 13216bd5a8d2SGunnar Mills /** 1322797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1323797d5daeSCorey Hardesty * 1324ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1325797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1326797d5daeSCorey Hardesty * 1327797d5daeSCorey Hardesty *@return None. 1328797d5daeSCorey Hardesty */ 1329797d5daeSCorey Hardesty 1330ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1331ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1332797d5daeSCorey Hardesty const uint32_t retryAttempts) 1333797d5daeSCorey Hardesty { 1334797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts."; 1335797d5daeSCorey Hardesty crow::connections::systemBus->async_method_call( 1336ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1337797d5daeSCorey Hardesty if (ec) 1338797d5daeSCorey Hardesty { 1339797d5daeSCorey Hardesty BMCWEB_LOG_ERROR 1340797d5daeSCorey Hardesty << "DBUS response error: Set setAutomaticRetryAttempts" << ec; 1341ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1342797d5daeSCorey Hardesty return; 1343797d5daeSCorey Hardesty } 1344797d5daeSCorey Hardesty }, 1345797d5daeSCorey Hardesty "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 1346797d5daeSCorey Hardesty "org.freedesktop.DBus.Properties", "Set", 1347797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1348797d5daeSCorey Hardesty std::variant<uint32_t>(retryAttempts)); 1349797d5daeSCorey Hardesty } 1350797d5daeSCorey Hardesty 1351*8d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 1352*8d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 1353*8d69c668SEd Tanous { 1354*8d69c668SEd Tanous if (value == 1355*8d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 1356*8d69c668SEd Tanous { 1357*8d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 1358*8d69c668SEd Tanous } 1359*8d69c668SEd Tanous if (value == 1360*8d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 1361*8d69c668SEd Tanous { 1362*8d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 1363*8d69c668SEd Tanous } 1364*8d69c668SEd Tanous if (value == 1365*8d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore") 1366*8d69c668SEd Tanous { 1367*8d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 1368*8d69c668SEd Tanous } 1369*8d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 1370*8d69c668SEd Tanous { 1371*8d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 1372*8d69c668SEd Tanous } 1373*8d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 1374*8d69c668SEd Tanous } 1375797d5daeSCorey Hardesty /** 1376c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1377c6a620f2SGeorge Liu * 1378ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1379c6a620f2SGeorge Liu * 1380c6a620f2SGeorge Liu * @return None. 1381c6a620f2SGeorge Liu */ 13828d1b46d7Szhanghch05 inline void 1383ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1384c6a620f2SGeorge Liu { 1385c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1386c6a620f2SGeorge Liu 13871e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13881e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13891e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13901e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1391ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13925e7e2dc5SEd Tanous const std::string& policy) { 1393c6a620f2SGeorge Liu if (ec) 1394c6a620f2SGeorge Liu { 1395c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1396c6a620f2SGeorge Liu return; 1397c6a620f2SGeorge Liu } 1398*8d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 1399*8d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 1400*8d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1401c6a620f2SGeorge Liu { 1402ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1403c6a620f2SGeorge Liu return; 1404c6a620f2SGeorge Liu } 1405c6a620f2SGeorge Liu 1406*8d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 14071e1e598dSJonathan Doman }); 1408c6a620f2SGeorge Liu } 1409c6a620f2SGeorge Liu 1410c6a620f2SGeorge Liu /** 14111981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 14121981771bSAli Ahmed * TPM is required for booting the host. 14131981771bSAli Ahmed * 1414ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14151981771bSAli Ahmed * 14161981771bSAli Ahmed * @return None. 14171981771bSAli Ahmed */ 14181981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1419ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14201981771bSAli Ahmed { 14211981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 1422e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1423e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1424e99073f5SGeorge Liu dbus::utility::getSubTree( 1425e99073f5SGeorge Liu "/", 0, interfaces, 1426ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1427b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14281981771bSAli Ahmed if (ec) 14291981771bSAli Ahmed { 1430002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1431002d39b4SEd Tanous << ec; 14321981771bSAli Ahmed // This is an optional D-Bus object so just return if 14331981771bSAli Ahmed // error occurs 14341981771bSAli Ahmed return; 14351981771bSAli Ahmed } 143626f6976fSEd Tanous if (subtree.empty()) 14371981771bSAli Ahmed { 14381981771bSAli Ahmed // As noted above, this is an optional interface so just return 14391981771bSAli Ahmed // if there is no instance found 14401981771bSAli Ahmed return; 14411981771bSAli Ahmed } 14421981771bSAli Ahmed 14431981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14441981771bSAli Ahmed if (subtree.size() > 1) 14451981771bSAli Ahmed { 14461981771bSAli Ahmed BMCWEB_LOG_DEBUG 14471981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 14481981771bSAli Ahmed << subtree.size(); 14491981771bSAli Ahmed // Throw an internal Error and return 1450ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14511981771bSAli Ahmed return; 14521981771bSAli Ahmed } 14531981771bSAli Ahmed 14541981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14551981771bSAli Ahmed // field 14561981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14571981771bSAli Ahmed { 14581981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 1459ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14601981771bSAli Ahmed return; 14611981771bSAli Ahmed } 14621981771bSAli Ahmed 14631981771bSAli Ahmed const std::string& path = subtree[0].first; 14641981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14651981771bSAli Ahmed 14661981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14671e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14681e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14691e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1470ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1471ac106bf6SEd Tanous bool tpmRequired) { 14728a592810SEd Tanous if (ec2) 14731981771bSAli Ahmed { 1474002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get" 14758a592810SEd Tanous << ec2; 1476ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14771981771bSAli Ahmed return; 14781981771bSAli Ahmed } 14791981771bSAli Ahmed 14801e1e598dSJonathan Doman if (tpmRequired) 14811981771bSAli Ahmed { 1482ac106bf6SEd Tanous asyncResp->res 1483ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14841981771bSAli Ahmed "Required"; 14851981771bSAli Ahmed } 14861981771bSAli Ahmed else 14871981771bSAli Ahmed { 1488ac106bf6SEd Tanous asyncResp->res 1489ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14901981771bSAli Ahmed "Disabled"; 14911981771bSAli Ahmed } 14921e1e598dSJonathan Doman }); 1493e99073f5SGeorge Liu }); 14941981771bSAli Ahmed } 14951981771bSAli Ahmed 14961981771bSAli Ahmed /** 14971c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14981c05dae3SAli Ahmed * TPM is required for booting the host. 14991c05dae3SAli Ahmed * 1500ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 15011c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 15021c05dae3SAli Ahmed * 15031c05dae3SAli Ahmed * @return None. 15041c05dae3SAli Ahmed */ 15051c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1506ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 15071c05dae3SAli Ahmed { 15081c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 1509e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1510e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1511e99073f5SGeorge Liu dbus::utility::getSubTree( 1512e99073f5SGeorge Liu "/", 0, interfaces, 1513ac106bf6SEd Tanous [asyncResp, 1514e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1515e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15161c05dae3SAli Ahmed if (ec) 15171c05dae3SAli Ahmed { 1518002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1519002d39b4SEd Tanous << ec; 1520ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15211c05dae3SAli Ahmed return; 15221c05dae3SAli Ahmed } 152326f6976fSEd Tanous if (subtree.empty()) 15241c05dae3SAli Ahmed { 1525ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 15261c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15271c05dae3SAli Ahmed return; 15281c05dae3SAli Ahmed } 15291c05dae3SAli Ahmed 15301c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15311c05dae3SAli Ahmed if (subtree.size() > 1) 15321c05dae3SAli Ahmed { 15331c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 15341c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 15351c05dae3SAli Ahmed << subtree.size(); 15361c05dae3SAli Ahmed // Throw an internal Error and return 1537ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15381c05dae3SAli Ahmed return; 15391c05dae3SAli Ahmed } 15401c05dae3SAli Ahmed 15411c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15421c05dae3SAli Ahmed // field 15431c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15441c05dae3SAli Ahmed { 15451c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 1546ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15471c05dae3SAli Ahmed return; 15481c05dae3SAli Ahmed } 15491c05dae3SAli Ahmed 15501c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15511c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15521c05dae3SAli Ahmed 15531c05dae3SAli Ahmed if (serv.empty()) 15541c05dae3SAli Ahmed { 15551c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 1556ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15571c05dae3SAli Ahmed return; 15581c05dae3SAli Ahmed } 15591c05dae3SAli Ahmed 15601c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 15611c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 1562ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 15638a592810SEd Tanous if (ec2) 15641c05dae3SAli Ahmed { 15650fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 15660fda0f12SGeorge Liu << "DBUS response error: Set TrustedModuleRequiredToBoot" 15678a592810SEd Tanous << ec2; 1568ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15691c05dae3SAli Ahmed return; 15701c05dae3SAli Ahmed } 15711c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 15721c05dae3SAli Ahmed }, 15731c05dae3SAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Set", 15741c05dae3SAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1575168e20c1SEd Tanous dbus::utility::DbusVariantType(tpmRequired)); 1576e99073f5SGeorge Liu }); 15771c05dae3SAli Ahmed } 15781c05dae3SAli Ahmed 15791c05dae3SAli Ahmed /** 1580491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1581491d8ee7SSantosh Puranik * 1582ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1583cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1584cd9a4666SKonstantin Aladyshev * @return Integer error code. 1585cd9a4666SKonstantin Aladyshev */ 1586ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1587cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1588cd9a4666SKonstantin Aladyshev { 1589c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1590cd9a4666SKonstantin Aladyshev 1591c21865c4SKonstantin Aladyshev if (!bootType) 1592cd9a4666SKonstantin Aladyshev { 1593c21865c4SKonstantin Aladyshev return; 1594c21865c4SKonstantin Aladyshev } 1595c21865c4SKonstantin Aladyshev 1596cd9a4666SKonstantin Aladyshev // Source target specified 1597cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1598cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1599cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1600cd9a4666SKonstantin Aladyshev { 1601cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1602cd9a4666SKonstantin Aladyshev } 1603cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1604cd9a4666SKonstantin Aladyshev { 1605cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1606cd9a4666SKonstantin Aladyshev } 1607cd9a4666SKonstantin Aladyshev else 1608cd9a4666SKonstantin Aladyshev { 1609cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1610cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1611cd9a4666SKonstantin Aladyshev << *bootType; 1612ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1613cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1614cd9a4666SKonstantin Aladyshev return; 1615cd9a4666SKonstantin Aladyshev } 1616cd9a4666SKonstantin Aladyshev 1617cd9a4666SKonstantin Aladyshev // Act on validated parameters 1618cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1619cd9a4666SKonstantin Aladyshev 1620cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1621ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1622cd9a4666SKonstantin Aladyshev if (ec) 1623cd9a4666SKonstantin Aladyshev { 1624cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1625cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1626cd9a4666SKonstantin Aladyshev { 1627ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1628cd9a4666SKonstantin Aladyshev return; 1629cd9a4666SKonstantin Aladyshev } 1630ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1631cd9a4666SKonstantin Aladyshev return; 1632cd9a4666SKonstantin Aladyshev } 1633cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1634cd9a4666SKonstantin Aladyshev }, 1635c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1636c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1637cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1638cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1639168e20c1SEd Tanous dbus::utility::DbusVariantType(bootTypeStr)); 1640cd9a4666SKonstantin Aladyshev } 1641cd9a4666SKonstantin Aladyshev 1642cd9a4666SKonstantin Aladyshev /** 1643cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1644cd9a4666SKonstantin Aladyshev * 1645ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1646ac106bf6SEd Tanous * message. 1647c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1648c21865c4SKonstantin Aladyshev * @return Integer error code. 1649c21865c4SKonstantin Aladyshev */ 1650ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1651c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1652c21865c4SKonstantin Aladyshev { 1653c21865c4SKonstantin Aladyshev if (!bootEnable) 1654c21865c4SKonstantin Aladyshev { 1655c21865c4SKonstantin Aladyshev return; 1656c21865c4SKonstantin Aladyshev } 1657c21865c4SKonstantin Aladyshev // Source target specified 1658c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1659c21865c4SKonstantin Aladyshev 1660c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1661c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1662c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1663c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1664c21865c4SKonstantin Aladyshev { 1665c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1666c21865c4SKonstantin Aladyshev } 1667c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1668c21865c4SKonstantin Aladyshev { 1669c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1670c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1671c21865c4SKonstantin Aladyshev } 1672c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1673c21865c4SKonstantin Aladyshev { 1674c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1675c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1676c21865c4SKonstantin Aladyshev } 1677c21865c4SKonstantin Aladyshev else 1678c21865c4SKonstantin Aladyshev { 16790fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 16800fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideEnabled: " 1681c21865c4SKonstantin Aladyshev << *bootEnable; 1682ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1683c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1684c21865c4SKonstantin Aladyshev return; 1685c21865c4SKonstantin Aladyshev } 1686c21865c4SKonstantin Aladyshev 1687c21865c4SKonstantin Aladyshev // Act on validated parameters 1688c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1689c21865c4SKonstantin Aladyshev 1690c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1691ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 16928a592810SEd Tanous if (ec2) 1693c21865c4SKonstantin Aladyshev { 16948a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1695ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1696c21865c4SKonstantin Aladyshev return; 1697c21865c4SKonstantin Aladyshev } 1698c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1699c21865c4SKonstantin Aladyshev }, 1700c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1701c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1702c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1703c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1704168e20c1SEd Tanous dbus::utility::DbusVariantType(bootOverrideEnable)); 1705c21865c4SKonstantin Aladyshev 1706c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1707c21865c4SKonstantin Aladyshev { 1708c21865c4SKonstantin Aladyshev return; 1709c21865c4SKonstantin Aladyshev } 1710c21865c4SKonstantin Aladyshev 1711c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1712c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1713c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1714c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1715c21865c4SKonstantin Aladyshev 1716c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1717ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1718c21865c4SKonstantin Aladyshev if (ec) 1719c21865c4SKonstantin Aladyshev { 1720c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1721ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1722c21865c4SKonstantin Aladyshev return; 1723c21865c4SKonstantin Aladyshev } 1724c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1725c21865c4SKonstantin Aladyshev }, 1726c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1727c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1728c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1729c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1730168e20c1SEd Tanous dbus::utility::DbusVariantType(!bootOverridePersistent)); 1731c21865c4SKonstantin Aladyshev } 1732c21865c4SKonstantin Aladyshev 1733c21865c4SKonstantin Aladyshev /** 1734c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1735c21865c4SKonstantin Aladyshev * 1736ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1737491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1738491d8ee7SSantosh Puranik * 1739265c1602SJohnathan Mantey * @return Integer error code. 1740491d8ee7SSantosh Puranik */ 1741ac106bf6SEd Tanous inline void 1742ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1743cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1744491d8ee7SSantosh Puranik { 1745c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1746c21865c4SKonstantin Aladyshev std::string bootModeStr; 1747944ffaf9SJohnathan Mantey 1748c21865c4SKonstantin Aladyshev if (!bootSource) 1749491d8ee7SSantosh Puranik { 1750c21865c4SKonstantin Aladyshev return; 1751c21865c4SKonstantin Aladyshev } 1752c21865c4SKonstantin Aladyshev 1753491d8ee7SSantosh Puranik // Source target specified 1754491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1755491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1756ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1757ac106bf6SEd Tanous bootModeStr) != 0) 1758491d8ee7SSantosh Puranik { 1759944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1760944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1761491d8ee7SSantosh Puranik << *bootSource; 1762ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1763491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1764491d8ee7SSantosh Puranik return; 1765491d8ee7SSantosh Puranik } 1766491d8ee7SSantosh Puranik 1767944ffaf9SJohnathan Mantey // Act on validated parameters 1768944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1769944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1770944ffaf9SJohnathan Mantey 1771491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1772ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1773491d8ee7SSantosh Puranik if (ec) 1774491d8ee7SSantosh Puranik { 1775491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1776ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1777491d8ee7SSantosh Puranik return; 1778491d8ee7SSantosh Puranik } 1779491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1780491d8ee7SSantosh Puranik }, 1781c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1782c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1783491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1784491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1785168e20c1SEd Tanous dbus::utility::DbusVariantType(bootSourceStr)); 1786944ffaf9SJohnathan Mantey 1787491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1788ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1789491d8ee7SSantosh Puranik if (ec) 1790491d8ee7SSantosh Puranik { 1791491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1792ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1793491d8ee7SSantosh Puranik return; 1794491d8ee7SSantosh Puranik } 1795491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1796491d8ee7SSantosh Puranik }, 1797c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1798c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1799491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1800491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1801168e20c1SEd Tanous dbus::utility::DbusVariantType(bootModeStr)); 1802cd9a4666SKonstantin Aladyshev } 1803944ffaf9SJohnathan Mantey 1804cd9a4666SKonstantin Aladyshev /** 1805c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1806491d8ee7SSantosh Puranik * 1807ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1808491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1809cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1810491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1811491d8ee7SSantosh Puranik * 1812265c1602SJohnathan Mantey * @return Integer error code. 1813491d8ee7SSantosh Puranik */ 1814c21865c4SKonstantin Aladyshev 1815ac106bf6SEd Tanous inline void 1816ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1817c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1818c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1819c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1820491d8ee7SSantosh Puranik { 1821491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1822491d8ee7SSantosh Puranik 1823ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1824ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1825ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1826491d8ee7SSantosh Puranik } 1827491d8ee7SSantosh Puranik 1828c6a620f2SGeorge Liu /** 182998e386ecSGunnar Mills * @brief Sets AssetTag 183098e386ecSGunnar Mills * 1831ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 183298e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 183398e386ecSGunnar Mills * 183498e386ecSGunnar Mills * @return None. 183598e386ecSGunnar Mills */ 1836ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 183798e386ecSGunnar Mills const std::string& assetTag) 183898e386ecSGunnar Mills { 1839e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1840e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1841e99073f5SGeorge Liu dbus::utility::getSubTree( 1842e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1843ac106bf6SEd Tanous [asyncResp, 1844e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1845b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 184698e386ecSGunnar Mills if (ec) 184798e386ecSGunnar Mills { 184898e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 1849ac106bf6SEd Tanous messages::internalError(asyncResp->res); 185098e386ecSGunnar Mills return; 185198e386ecSGunnar Mills } 185226f6976fSEd Tanous if (subtree.empty()) 185398e386ecSGunnar Mills { 185498e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 1855ac106bf6SEd Tanous messages::internalError(asyncResp->res); 185698e386ecSGunnar Mills return; 185798e386ecSGunnar Mills } 185898e386ecSGunnar Mills // Assume only 1 system D-Bus object 185998e386ecSGunnar Mills // Throw an error if there is more than 1 186098e386ecSGunnar Mills if (subtree.size() > 1) 186198e386ecSGunnar Mills { 186298e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 1863ac106bf6SEd Tanous messages::internalError(asyncResp->res); 186498e386ecSGunnar Mills return; 186598e386ecSGunnar Mills } 186698e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 186798e386ecSGunnar Mills { 186898e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 1869ac106bf6SEd Tanous messages::internalError(asyncResp->res); 187098e386ecSGunnar Mills return; 187198e386ecSGunnar Mills } 187298e386ecSGunnar Mills 187398e386ecSGunnar Mills const std::string& path = subtree[0].first; 187498e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 187598e386ecSGunnar Mills 187698e386ecSGunnar Mills if (service.empty()) 187798e386ecSGunnar Mills { 187898e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 1879ac106bf6SEd Tanous messages::internalError(asyncResp->res); 188098e386ecSGunnar Mills return; 188198e386ecSGunnar Mills } 188298e386ecSGunnar Mills 188398e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 1884ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 188598e386ecSGunnar Mills if (ec2) 188698e386ecSGunnar Mills { 1887002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set " 1888002d39b4SEd Tanous << ec2; 1889ac106bf6SEd Tanous messages::internalError(asyncResp->res); 189098e386ecSGunnar Mills return; 189198e386ecSGunnar Mills } 189298e386ecSGunnar Mills }, 189398e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 189498e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 1895168e20c1SEd Tanous dbus::utility::DbusVariantType(assetTag)); 1896e99073f5SGeorge Liu }); 189798e386ecSGunnar Mills } 189898e386ecSGunnar Mills 189998e386ecSGunnar Mills /** 190069f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 190169f35306SGunnar Mills * 1902ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 190369f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 190469f35306SGunnar Mills * 190569f35306SGunnar Mills * @return None. 190669f35306SGunnar Mills */ 1907ac106bf6SEd Tanous inline void 1908ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1909f23b7296SEd Tanous const std::string& automaticRetryConfig) 191069f35306SGunnar Mills { 191169f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 191269f35306SGunnar Mills 191369f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1914543f4400SEd Tanous bool autoRebootEnabled = false; 191569f35306SGunnar Mills 191669f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 191769f35306SGunnar Mills { 191869f35306SGunnar Mills autoRebootEnabled = false; 191969f35306SGunnar Mills } 192069f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 192169f35306SGunnar Mills { 192269f35306SGunnar Mills autoRebootEnabled = true; 192369f35306SGunnar Mills } 192469f35306SGunnar Mills else 192569f35306SGunnar Mills { 19260fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: " 192769f35306SGunnar Mills << automaticRetryConfig; 1928ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 192969f35306SGunnar Mills "AutomaticRetryConfig"); 193069f35306SGunnar Mills return; 193169f35306SGunnar Mills } 193269f35306SGunnar Mills 193369f35306SGunnar Mills crow::connections::systemBus->async_method_call( 1934ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 193569f35306SGunnar Mills if (ec) 193669f35306SGunnar Mills { 1937ac106bf6SEd Tanous messages::internalError(asyncResp->res); 193869f35306SGunnar Mills return; 193969f35306SGunnar Mills } 194069f35306SGunnar Mills }, 194169f35306SGunnar Mills "xyz.openbmc_project.Settings", 194269f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 194369f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 194469f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1945168e20c1SEd Tanous dbus::utility::DbusVariantType(autoRebootEnabled)); 194669f35306SGunnar Mills } 194769f35306SGunnar Mills 1948*8d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 1949*8d69c668SEd Tanous { 1950*8d69c668SEd Tanous if (policy == "AlwaysOn") 1951*8d69c668SEd Tanous { 1952*8d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 1953*8d69c668SEd Tanous } 1954*8d69c668SEd Tanous if (policy == "AlwaysOff") 1955*8d69c668SEd Tanous { 1956*8d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 1957*8d69c668SEd Tanous } 1958*8d69c668SEd Tanous if (policy == "LastState") 1959*8d69c668SEd Tanous { 1960*8d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 1961*8d69c668SEd Tanous } 1962*8d69c668SEd Tanous return ""; 1963*8d69c668SEd Tanous } 1964*8d69c668SEd Tanous 196569f35306SGunnar Mills /** 1966c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1967c6a620f2SGeorge Liu * 1968ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1969c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1970c6a620f2SGeorge Liu * 1971c6a620f2SGeorge Liu * @return None. 1972c6a620f2SGeorge Liu */ 19738d1b46d7Szhanghch05 inline void 1974ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1975*8d69c668SEd Tanous std::string_view policy) 1976c6a620f2SGeorge Liu { 1977c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1978c6a620f2SGeorge Liu 1979*8d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 1980c6a620f2SGeorge Liu 1981*8d69c668SEd Tanous if (powerRestorePolicy.empty()) 1982c6a620f2SGeorge Liu { 1983ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 19844e69c904SGunnar Mills "PowerRestorePolicy"); 1985c6a620f2SGeorge Liu return; 1986c6a620f2SGeorge Liu } 1987c6a620f2SGeorge Liu 1988c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1989ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1990c6a620f2SGeorge Liu if (ec) 1991c6a620f2SGeorge Liu { 1992ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1993c6a620f2SGeorge Liu return; 1994c6a620f2SGeorge Liu } 1995c6a620f2SGeorge Liu }, 1996c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1997c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1998c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1999c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 2000*8d69c668SEd Tanous dbus::utility::DbusVariantType(powerRestorePolicy)); 2001c6a620f2SGeorge Liu } 2002c6a620f2SGeorge Liu 2003a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 2004a6349918SAppaRao Puli /** 2005a6349918SAppaRao Puli * @brief Retrieves provisioning status 2006a6349918SAppaRao Puli * 2007ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 2008a6349918SAppaRao Puli * 2009a6349918SAppaRao Puli * @return None. 2010a6349918SAppaRao Puli */ 2011ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 2012a6349918SAppaRao Puli { 2013a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 2014bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2015bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 2016bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 2017ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2018b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 2019b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2020ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2021ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 202250626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 202350626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 202450626f4fSJames Feist 2025a6349918SAppaRao Puli if (ec) 2026a6349918SAppaRao Puli { 2027a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2028b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2029b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2030a6349918SAppaRao Puli return; 2031a6349918SAppaRao Puli } 2032a6349918SAppaRao Puli 2033a6349918SAppaRao Puli const bool* provState = nullptr; 2034a6349918SAppaRao Puli const bool* lockState = nullptr; 2035bc1d29deSKrzysztof Grobelny 2036bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 20370d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 20380d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 2039bc1d29deSKrzysztof Grobelny 2040bc1d29deSKrzysztof Grobelny if (!success) 2041a6349918SAppaRao Puli { 2042ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2043bc1d29deSKrzysztof Grobelny return; 2044a6349918SAppaRao Puli } 2045a6349918SAppaRao Puli 2046a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2047a6349918SAppaRao Puli { 2048a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 2049ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2050a6349918SAppaRao Puli return; 2051a6349918SAppaRao Puli } 2052a6349918SAppaRao Puli 2053a6349918SAppaRao Puli if (*provState == true) 2054a6349918SAppaRao Puli { 2055a6349918SAppaRao Puli if (*lockState == true) 2056a6349918SAppaRao Puli { 2057a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2058a6349918SAppaRao Puli } 2059a6349918SAppaRao Puli else 2060a6349918SAppaRao Puli { 2061a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2062a6349918SAppaRao Puli } 2063a6349918SAppaRao Puli } 2064a6349918SAppaRao Puli else 2065a6349918SAppaRao Puli { 2066a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2067a6349918SAppaRao Puli } 2068bc1d29deSKrzysztof Grobelny }); 2069a6349918SAppaRao Puli } 2070a6349918SAppaRao Puli #endif 2071a6349918SAppaRao Puli 2072491d8ee7SSantosh Puranik /** 20733a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 20743a2d0424SChris Cain * 2075ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 20763a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 20773a2d0424SChris Cain * 20783a2d0424SChris Cain * @return None. 20793a2d0424SChris Cain */ 2080ac106bf6SEd Tanous inline void 2081ac106bf6SEd Tanous translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20823a2d0424SChris Cain const std::string& modeValue) 20833a2d0424SChris Cain { 20840fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20853a2d0424SChris Cain { 2086ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "Static"; 20873a2d0424SChris Cain } 20880fda0f12SGeorge Liu else if ( 20890fda0f12SGeorge Liu modeValue == 20900fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20913a2d0424SChris Cain { 2092ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 20933a2d0424SChris Cain } 20940fda0f12SGeorge Liu else if (modeValue == 20950fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20963a2d0424SChris Cain { 2097ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "PowerSaving"; 20983a2d0424SChris Cain } 20990fda0f12SGeorge Liu else if (modeValue == 21000fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 21013a2d0424SChris Cain { 2102ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "OEM"; 21033a2d0424SChris Cain } 21043a2d0424SChris Cain else 21053a2d0424SChris Cain { 21063a2d0424SChris Cain // Any other values would be invalid 21073a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 2108ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21093a2d0424SChris Cain } 21103a2d0424SChris Cain } 21113a2d0424SChris Cain 21123a2d0424SChris Cain /** 21133a2d0424SChris Cain * @brief Retrieves system power mode 21143a2d0424SChris Cain * 2115ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21163a2d0424SChris Cain * 21173a2d0424SChris Cain * @return None. 21183a2d0424SChris Cain */ 2119ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 21203a2d0424SChris Cain { 21213a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 21223a2d0424SChris Cain 21233a2d0424SChris Cain // Get Power Mode object path: 2124e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2125e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2126e99073f5SGeorge Liu dbus::utility::getSubTree( 2127e99073f5SGeorge Liu "/", 0, interfaces, 2128ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2129b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21303a2d0424SChris Cain if (ec) 21313a2d0424SChris Cain { 2132002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2133002d39b4SEd Tanous << ec; 21343a2d0424SChris Cain // This is an optional D-Bus object so just return if 21353a2d0424SChris Cain // error occurs 21363a2d0424SChris Cain return; 21373a2d0424SChris Cain } 21383a2d0424SChris Cain if (subtree.empty()) 21393a2d0424SChris Cain { 21403a2d0424SChris Cain // As noted above, this is an optional interface so just return 21413a2d0424SChris Cain // if there is no instance found 21423a2d0424SChris Cain return; 21433a2d0424SChris Cain } 21443a2d0424SChris Cain if (subtree.size() > 1) 21453a2d0424SChris Cain { 21463a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21473a2d0424SChris Cain // error 21483a2d0424SChris Cain BMCWEB_LOG_DEBUG 21493a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 21503a2d0424SChris Cain << subtree.size(); 2151ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21523a2d0424SChris Cain return; 21533a2d0424SChris Cain } 21543a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21553a2d0424SChris Cain { 21563a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 2157ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21583a2d0424SChris Cain return; 21593a2d0424SChris Cain } 21603a2d0424SChris Cain const std::string& path = subtree[0].first; 21613a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21623a2d0424SChris Cain if (service.empty()) 21633a2d0424SChris Cain { 21643a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 2165ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21663a2d0424SChris Cain return; 21673a2d0424SChris Cain } 21683a2d0424SChris Cain // Valid Power Mode object found, now read the current value 21691e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 21701e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 21711e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2172ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 21731e1e598dSJonathan Doman const std::string& pmode) { 21748a592810SEd Tanous if (ec2) 21753a2d0424SChris Cain { 2176002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: " 21778a592810SEd Tanous << ec2; 2178ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21793a2d0424SChris Cain return; 21803a2d0424SChris Cain } 21813a2d0424SChris Cain 2182ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2183002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 21843a2d0424SChris Cain 21851e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 2186ac106bf6SEd Tanous translatePowerMode(asyncResp, pmode); 21871e1e598dSJonathan Doman }); 2188e99073f5SGeorge Liu }); 21893a2d0424SChris Cain } 21903a2d0424SChris Cain 21913a2d0424SChris Cain /** 21923a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21933a2d0424SChris Cain * name associated with that string 21943a2d0424SChris Cain * 2195ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21963a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 21973a2d0424SChris Cain * 21983a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 21993a2d0424SChris Cain */ 22003a2d0424SChris Cain inline std::string 2201ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22023a2d0424SChris Cain const std::string& modeString) 22033a2d0424SChris Cain { 22043a2d0424SChris Cain std::string mode; 22053a2d0424SChris Cain 22063a2d0424SChris Cain if (modeString == "Static") 22073a2d0424SChris Cain { 22083a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22093a2d0424SChris Cain } 22103a2d0424SChris Cain else if (modeString == "MaximumPerformance") 22113a2d0424SChris Cain { 22120fda0f12SGeorge Liu mode = 22130fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 22143a2d0424SChris Cain } 22153a2d0424SChris Cain else if (modeString == "PowerSaving") 22163a2d0424SChris Cain { 22173a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22183a2d0424SChris Cain } 22193a2d0424SChris Cain else 22203a2d0424SChris Cain { 2221ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, modeString, 2222ac106bf6SEd Tanous "PowerMode"); 22233a2d0424SChris Cain } 22243a2d0424SChris Cain return mode; 22253a2d0424SChris Cain } 22263a2d0424SChris Cain 22273a2d0424SChris Cain /** 22283a2d0424SChris Cain * @brief Sets system power mode. 22293a2d0424SChris Cain * 2230ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22313a2d0424SChris Cain * @param[in] pmode System power mode from request. 22323a2d0424SChris Cain * 22333a2d0424SChris Cain * @return None. 22343a2d0424SChris Cain */ 2235ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22363a2d0424SChris Cain const std::string& pmode) 22373a2d0424SChris Cain { 22383a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 22393a2d0424SChris Cain 2240ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 22413a2d0424SChris Cain if (powerMode.empty()) 22423a2d0424SChris Cain { 22433a2d0424SChris Cain return; 22443a2d0424SChris Cain } 22453a2d0424SChris Cain 22463a2d0424SChris Cain // Get Power Mode object path: 2247e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2248e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2249e99073f5SGeorge Liu dbus::utility::getSubTree( 2250e99073f5SGeorge Liu "/", 0, interfaces, 2251ac106bf6SEd Tanous [asyncResp, 2252e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2253b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22543a2d0424SChris Cain if (ec) 22553a2d0424SChris Cain { 2256002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2257002d39b4SEd Tanous << ec; 22583a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2259ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22603a2d0424SChris Cain return; 22613a2d0424SChris Cain } 22623a2d0424SChris Cain if (subtree.empty()) 22633a2d0424SChris Cain { 22643a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2265ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 22663a2d0424SChris Cain "PowerMode"); 22673a2d0424SChris Cain return; 22683a2d0424SChris Cain } 22693a2d0424SChris Cain if (subtree.size() > 1) 22703a2d0424SChris Cain { 22713a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22723a2d0424SChris Cain // error 22733a2d0424SChris Cain BMCWEB_LOG_DEBUG 22743a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 22753a2d0424SChris Cain << subtree.size(); 2276ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22773a2d0424SChris Cain return; 22783a2d0424SChris Cain } 22793a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22803a2d0424SChris Cain { 22813a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 2282ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22833a2d0424SChris Cain return; 22843a2d0424SChris Cain } 22853a2d0424SChris Cain const std::string& path = subtree[0].first; 22863a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22873a2d0424SChris Cain if (service.empty()) 22883a2d0424SChris Cain { 22893a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 2290ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22913a2d0424SChris Cain return; 22923a2d0424SChris Cain } 22933a2d0424SChris Cain 22943a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 22953a2d0424SChris Cain << path; 22963a2d0424SChris Cain 22973a2d0424SChris Cain // Set the Power Mode property 22983a2d0424SChris Cain crow::connections::systemBus->async_method_call( 2299ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 23008a592810SEd Tanous if (ec2) 23013a2d0424SChris Cain { 2302ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23033a2d0424SChris Cain return; 23043a2d0424SChris Cain } 23053a2d0424SChris Cain }, 23063a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 23073a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2308168e20c1SEd Tanous dbus::utility::DbusVariantType(powerMode)); 2309e99073f5SGeorge Liu }); 23103a2d0424SChris Cain } 23113a2d0424SChris Cain 23123a2d0424SChris Cain /** 231351709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 231451709ffdSYong Li * 231551709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 231651709ffdSYong Li * 231751709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 231851709ffdSYong Li * translation cannot be done, returns an empty string. 231951709ffdSYong Li */ 232023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 232151709ffdSYong Li { 232251709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 232351709ffdSYong Li { 232451709ffdSYong Li return "None"; 232551709ffdSYong Li } 23263174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 232751709ffdSYong Li { 232851709ffdSYong Li return "ResetSystem"; 232951709ffdSYong Li } 23303174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 233151709ffdSYong Li { 233251709ffdSYong Li return "PowerDown"; 233351709ffdSYong Li } 23343174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 233551709ffdSYong Li { 233651709ffdSYong Li return "PowerCycle"; 233751709ffdSYong Li } 233851709ffdSYong Li 233951709ffdSYong Li return ""; 234051709ffdSYong Li } 234151709ffdSYong Li 234251709ffdSYong Li /** 2343c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2344c45f0082SYong Li * 2345c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2346c45f0082SYong Li * 2347c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2348c45f0082SYong Li *If translation cannot be done, returns an empty string. 2349c45f0082SYong Li */ 2350c45f0082SYong Li 235123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2352c45f0082SYong Li { 2353c45f0082SYong Li if (rfAction == "None") 2354c45f0082SYong Li { 2355c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2356c45f0082SYong Li } 23573174e4dfSEd Tanous if (rfAction == "PowerCycle") 2358c45f0082SYong Li { 2359c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2360c45f0082SYong Li } 23613174e4dfSEd Tanous if (rfAction == "PowerDown") 2362c45f0082SYong Li { 2363c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2364c45f0082SYong Li } 23653174e4dfSEd Tanous if (rfAction == "ResetSystem") 2366c45f0082SYong Li { 2367c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2368c45f0082SYong Li } 2369c45f0082SYong Li 2370c45f0082SYong Li return ""; 2371c45f0082SYong Li } 2372c45f0082SYong Li 2373c45f0082SYong Li /** 237451709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 237551709ffdSYong Li * 2376ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 237751709ffdSYong Li * 237851709ffdSYong Li * @return None. 237951709ffdSYong Li */ 23808d1b46d7Szhanghch05 inline void 2381ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 238251709ffdSYong Li { 238351709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 2384bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2385bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2386bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2387bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2388ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2389b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 239051709ffdSYong Li if (ec) 239151709ffdSYong Li { 239251709ffdSYong Li // watchdog service is stopped 239351709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 239451709ffdSYong Li return; 239551709ffdSYong Li } 239651709ffdSYong Li 239751709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 239851709ffdSYong Li 239951709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2400ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 240151709ffdSYong Li 240251709ffdSYong Li // watchdog service is running/enabled 240351709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 240451709ffdSYong Li 2405bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2406bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 240751709ffdSYong Li 2408bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2409bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2410bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2411bc1d29deSKrzysztof Grobelny 2412bc1d29deSKrzysztof Grobelny if (!success) 241351709ffdSYong Li { 2414ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2415601af5edSChicago Duan return; 241651709ffdSYong Li } 241751709ffdSYong Li 2418bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 241951709ffdSYong Li { 2420bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 242151709ffdSYong Li } 242251709ffdSYong Li 2423bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2424bc1d29deSKrzysztof Grobelny { 2425bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 242651709ffdSYong Li if (action.empty()) 242751709ffdSYong Li { 2428ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2429601af5edSChicago Duan return; 243051709ffdSYong Li } 243151709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 243251709ffdSYong Li } 2433bc1d29deSKrzysztof Grobelny }); 243451709ffdSYong Li } 243551709ffdSYong Li 243651709ffdSYong Li /** 2437c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2438c45f0082SYong Li * 2439ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2440c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2441c45f0082SYong Li * RF request. 2442c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2443c45f0082SYong Li * 2444c45f0082SYong Li * @return None. 2445c45f0082SYong Li */ 2446ac106bf6SEd Tanous inline void 2447ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2448c45f0082SYong Li const std::optional<bool> wdtEnable, 2449c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2450c45f0082SYong Li { 2451c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2452c45f0082SYong Li 2453c45f0082SYong Li if (wdtTimeOutAction) 2454c45f0082SYong Li { 2455c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2456c45f0082SYong Li // check if TimeOut Action is Valid 2457c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2458c45f0082SYong Li { 2459c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2460c45f0082SYong Li << *wdtTimeOutAction; 2461ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2462c45f0082SYong Li "TimeoutAction"); 2463c45f0082SYong Li return; 2464c45f0082SYong Li } 2465c45f0082SYong Li 2466c45f0082SYong Li crow::connections::systemBus->async_method_call( 2467ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2468c45f0082SYong Li if (ec) 2469c45f0082SYong Li { 2470c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2471ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2472c45f0082SYong Li return; 2473c45f0082SYong Li } 2474c45f0082SYong Li }, 2475c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2476c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2477c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2478c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2479168e20c1SEd Tanous dbus::utility::DbusVariantType(wdtTimeOutActStr)); 2480c45f0082SYong Li } 2481c45f0082SYong Li 2482c45f0082SYong Li if (wdtEnable) 2483c45f0082SYong Li { 2484c45f0082SYong Li crow::connections::systemBus->async_method_call( 2485ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2486c45f0082SYong Li if (ec) 2487c45f0082SYong Li { 2488c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2489ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2490c45f0082SYong Li return; 2491c45f0082SYong Li } 2492c45f0082SYong Li }, 2493c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2494c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2495c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2496c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2497168e20c1SEd Tanous dbus::utility::DbusVariantType(*wdtEnable)); 2498c45f0082SYong Li } 2499c45f0082SYong Li } 2500c45f0082SYong Li 250137bbf98cSChris Cain /** 250237bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 250337bbf98cSChris Cain * 2504ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 250537bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 250637bbf98cSChris Cain * 250737bbf98cSChris Cain * @return true if successful 250837bbf98cSChris Cain */ 25091e5b7c88SJiaqing Zhao inline bool 2510ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25111e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 251237bbf98cSChris Cain { 2513bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2514bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2515bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2516bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2517bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2518bc1d29deSKrzysztof Grobelny 2519bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2520bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 25212661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 25222661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 25232661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2524bc1d29deSKrzysztof Grobelny 2525bc1d29deSKrzysztof Grobelny if (!success) 252637bbf98cSChris Cain { 252737bbf98cSChris Cain return false; 252837bbf98cSChris Cain } 2529bc1d29deSKrzysztof Grobelny 2530bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 253137bbf98cSChris Cain { 2532ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 253337bbf98cSChris Cain } 2534bc1d29deSKrzysztof Grobelny 2535bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 253637bbf98cSChris Cain { 2537ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2538bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 253937bbf98cSChris Cain } 2540bc1d29deSKrzysztof Grobelny 2541bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2542bc1d29deSKrzysztof Grobelny { 2543bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2544ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 254537bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 254637bbf98cSChris Cain .count(); 254737bbf98cSChris Cain } 2548bc1d29deSKrzysztof Grobelny 2549bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 255037bbf98cSChris Cain { 2551ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2552bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 255337bbf98cSChris Cain } 2554bc1d29deSKrzysztof Grobelny 2555bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 255637bbf98cSChris Cain { 2557bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2558ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 255937bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 256037bbf98cSChris Cain .count(); 256137bbf98cSChris Cain } 256237bbf98cSChris Cain 256337bbf98cSChris Cain return true; 256437bbf98cSChris Cain } 256537bbf98cSChris Cain 256637bbf98cSChris Cain /** 256737bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 256837bbf98cSChris Cain * 2569ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 257037bbf98cSChris Cain * 257137bbf98cSChris Cain * @return None. 257237bbf98cSChris Cain */ 2573ac106bf6SEd Tanous inline void 2574ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 257537bbf98cSChris Cain { 257637bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 257737bbf98cSChris Cain 257837bbf98cSChris Cain // Get IdlePowerSaver object path: 2579e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2580e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2581e99073f5SGeorge Liu dbus::utility::getSubTree( 2582e99073f5SGeorge Liu "/", 0, interfaces, 2583ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2584b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 258537bbf98cSChris Cain if (ec) 258637bbf98cSChris Cain { 258737bbf98cSChris Cain BMCWEB_LOG_DEBUG 258837bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 258937bbf98cSChris Cain << ec; 2590ac106bf6SEd Tanous messages::internalError(asyncResp->res); 259137bbf98cSChris Cain return; 259237bbf98cSChris Cain } 259337bbf98cSChris Cain if (subtree.empty()) 259437bbf98cSChris Cain { 259537bbf98cSChris Cain // This is an optional interface so just return 259637bbf98cSChris Cain // if there is no instance found 259737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 259837bbf98cSChris Cain return; 259937bbf98cSChris Cain } 260037bbf98cSChris Cain if (subtree.size() > 1) 260137bbf98cSChris Cain { 260237bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 260337bbf98cSChris Cain // is an error 260437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 260537bbf98cSChris Cain "Power.IdlePowerSaver objects: " 260637bbf98cSChris Cain << subtree.size(); 2607ac106bf6SEd Tanous messages::internalError(asyncResp->res); 260837bbf98cSChris Cain return; 260937bbf98cSChris Cain } 261037bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 261137bbf98cSChris Cain { 261237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 2613ac106bf6SEd Tanous messages::internalError(asyncResp->res); 261437bbf98cSChris Cain return; 261537bbf98cSChris Cain } 261637bbf98cSChris Cain const std::string& path = subtree[0].first; 261737bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 261837bbf98cSChris Cain if (service.empty()) 261937bbf98cSChris Cain { 2620002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 2621ac106bf6SEd Tanous messages::internalError(asyncResp->res); 262237bbf98cSChris Cain return; 262337bbf98cSChris Cain } 262437bbf98cSChris Cain 262537bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2626bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2627bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2628bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2629ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 26301e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 26318a592810SEd Tanous if (ec2) 263237bbf98cSChris Cain { 263337bbf98cSChris Cain BMCWEB_LOG_ERROR 26348a592810SEd Tanous << "DBUS response error on IdlePowerSaver GetAll: " << ec2; 2635ac106bf6SEd Tanous messages::internalError(asyncResp->res); 263637bbf98cSChris Cain return; 263737bbf98cSChris Cain } 263837bbf98cSChris Cain 2639ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 264037bbf98cSChris Cain { 2641ac106bf6SEd Tanous messages::internalError(asyncResp->res); 264237bbf98cSChris Cain return; 264337bbf98cSChris Cain } 2644bc1d29deSKrzysztof Grobelny }); 2645e99073f5SGeorge Liu }); 264637bbf98cSChris Cain 264737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 264837bbf98cSChris Cain } 264937bbf98cSChris Cain 265037bbf98cSChris Cain /** 265137bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 265237bbf98cSChris Cain * 2653ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 265437bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 265537bbf98cSChris Cain * RF request. 265637bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 265737bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 265837bbf98cSChris Cain * before entering idle state. 265937bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 266037bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 266137bbf98cSChris Cain * before exiting idle state 266237bbf98cSChris Cain * 266337bbf98cSChris Cain * @return None. 266437bbf98cSChris Cain */ 2665ac106bf6SEd Tanous inline void 2666ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 266737bbf98cSChris Cain const std::optional<bool> ipsEnable, 266837bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 266937bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 267037bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 267137bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 267237bbf98cSChris Cain { 267337bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 267437bbf98cSChris Cain 267537bbf98cSChris Cain // Get IdlePowerSaver object path: 2676e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2677e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2678e99073f5SGeorge Liu dbus::utility::getSubTree( 2679e99073f5SGeorge Liu "/", 0, interfaces, 2680ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2681e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2682b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 268337bbf98cSChris Cain if (ec) 268437bbf98cSChris Cain { 268537bbf98cSChris Cain BMCWEB_LOG_DEBUG 268637bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 268737bbf98cSChris Cain << ec; 2688ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268937bbf98cSChris Cain return; 269037bbf98cSChris Cain } 269137bbf98cSChris Cain if (subtree.empty()) 269237bbf98cSChris Cain { 269337bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2694ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 269537bbf98cSChris Cain "IdlePowerSaver"); 269637bbf98cSChris Cain return; 269737bbf98cSChris Cain } 269837bbf98cSChris Cain if (subtree.size() > 1) 269937bbf98cSChris Cain { 270037bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 270137bbf98cSChris Cain // is an error 27020fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 27030fda0f12SGeorge Liu << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: " 270437bbf98cSChris Cain << subtree.size(); 2705ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270637bbf98cSChris Cain return; 270737bbf98cSChris Cain } 270837bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 270937bbf98cSChris Cain { 271037bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 2711ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271237bbf98cSChris Cain return; 271337bbf98cSChris Cain } 271437bbf98cSChris Cain const std::string& path = subtree[0].first; 271537bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 271637bbf98cSChris Cain if (service.empty()) 271737bbf98cSChris Cain { 2718002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 2719ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272037bbf98cSChris Cain return; 272137bbf98cSChris Cain } 272237bbf98cSChris Cain 272337bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 272437bbf98cSChris Cain // need to be updated 272537bbf98cSChris Cain 272637bbf98cSChris Cain if (ipsEnable) 272737bbf98cSChris Cain { 272837bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2729ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27308a592810SEd Tanous if (ec2) 273137bbf98cSChris Cain { 27328a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2733ac106bf6SEd Tanous messages::internalError(asyncResp->res); 273437bbf98cSChris Cain return; 273537bbf98cSChris Cain } 273637bbf98cSChris Cain }, 273737bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 2738002d39b4SEd Tanous "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 2739002d39b4SEd Tanous dbus::utility::DbusVariantType(*ipsEnable)); 274037bbf98cSChris Cain } 274137bbf98cSChris Cain if (ipsEnterUtil) 274237bbf98cSChris Cain { 274337bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2744ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27458a592810SEd Tanous if (ec2) 274637bbf98cSChris Cain { 27478a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2748ac106bf6SEd Tanous messages::internalError(asyncResp->res); 274937bbf98cSChris Cain return; 275037bbf98cSChris Cain } 275137bbf98cSChris Cain }, 275237bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 275337bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 275437bbf98cSChris Cain "EnterUtilizationPercent", 2755168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsEnterUtil)); 275637bbf98cSChris Cain } 275737bbf98cSChris Cain if (ipsEnterTime) 275837bbf98cSChris Cain { 275937bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 276037bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 276137bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2762ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27638a592810SEd Tanous if (ec2) 276437bbf98cSChris Cain { 27658a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2766ac106bf6SEd Tanous messages::internalError(asyncResp->res); 276737bbf98cSChris Cain return; 276837bbf98cSChris Cain } 276937bbf98cSChris Cain }, 277037bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 277137bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2772168e20c1SEd Tanous "EnterDwellTime", 2773168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 277437bbf98cSChris Cain } 277537bbf98cSChris Cain if (ipsExitUtil) 277637bbf98cSChris Cain { 277737bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2778ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27798a592810SEd Tanous if (ec2) 278037bbf98cSChris Cain { 27818a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2782ac106bf6SEd Tanous messages::internalError(asyncResp->res); 278337bbf98cSChris Cain return; 278437bbf98cSChris Cain } 278537bbf98cSChris Cain }, 278637bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 278737bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 278837bbf98cSChris Cain "ExitUtilizationPercent", 2789168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsExitUtil)); 279037bbf98cSChris Cain } 279137bbf98cSChris Cain if (ipsExitTime) 279237bbf98cSChris Cain { 279337bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 279437bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 279537bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2796ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27978a592810SEd Tanous if (ec2) 279837bbf98cSChris Cain { 27998a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2800ac106bf6SEd Tanous messages::internalError(asyncResp->res); 280137bbf98cSChris Cain return; 280237bbf98cSChris Cain } 280337bbf98cSChris Cain }, 280437bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 280537bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2806168e20c1SEd Tanous "ExitDwellTime", 2807168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 280837bbf98cSChris Cain } 2809e99073f5SGeorge Liu }); 281037bbf98cSChris Cain 281137bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 281237bbf98cSChris Cain } 281337bbf98cSChris Cain 2814c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2815dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2816dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2817dd60b9edSEd Tanous { 2818dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2819dd60b9edSEd Tanous { 2820dd60b9edSEd Tanous return; 2821dd60b9edSEd Tanous } 2822dd60b9edSEd Tanous asyncResp->res.addHeader( 2823dd60b9edSEd Tanous boost::beast::http::field::link, 2824dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2825dd60b9edSEd Tanous } 2826dd60b9edSEd Tanous 2827c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2828c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2829c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28301abe55efSEd Tanous { 28313ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2832f4c99e70SEd Tanous { 2833f4c99e70SEd Tanous return; 2834f4c99e70SEd Tanous } 2835dd60b9edSEd Tanous 2836dd60b9edSEd Tanous asyncResp->res.addHeader( 2837dd60b9edSEd Tanous boost::beast::http::field::link, 2838dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 28398d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28400f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28418d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28428d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2843462023adSSunitha Harish 28447f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 28457f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 28467f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 28477f3e84a1SEd Tanous { 28487f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 28497f3e84a1SEd Tanous // Option currently returns no systems. TBD 28507f3e84a1SEd Tanous return; 28517f3e84a1SEd Tanous } 28527f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 28537f3e84a1SEd Tanous nlohmann::json::object_t system; 28547f3e84a1SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 28557f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 28561e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2857002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 28581e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2859002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 28605e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 28611e1e598dSJonathan Doman const std::string& /*hostName*/) { 28627f3e84a1SEd Tanous if (ec2) 2863462023adSSunitha Harish { 28647f3e84a1SEd Tanous return; 28657f3e84a1SEd Tanous } 28667f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 28677f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 28687f3e84a1SEd Tanous { 28697f3e84a1SEd Tanous BMCWEB_LOG_CRITICAL << "Count wasn't found??"; 28707f3e84a1SEd Tanous return; 28717f3e84a1SEd Tanous } 28727f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 28737f3e84a1SEd Tanous if (count == nullptr) 28747f3e84a1SEd Tanous { 28757f3e84a1SEd Tanous BMCWEB_LOG_CRITICAL << "Count wasn't found??"; 28767f3e84a1SEd Tanous return; 28777f3e84a1SEd Tanous } 28787f3e84a1SEd Tanous *count = *count + 1; 2879462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 28807f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 28811476687dSEd Tanous nlohmann::json::object_t hypervisor; 2882002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 28837f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 28841e1e598dSJonathan Doman }); 2885c1e219d5SEd Tanous } 2886c1e219d5SEd Tanous 2887c1e219d5SEd Tanous /** 28887e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28897e860f15SJohn Edward Broadbent */ 28904f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28917e860f15SJohn Edward Broadbent { 289289492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 289389492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 289489492a15SPatrick Williams constexpr const char* interfaceName = 28957e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 289689492a15SPatrick Williams constexpr const char* method = "NMI"; 28977e860f15SJohn Edward Broadbent 28987e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28995e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 29007e860f15SJohn Edward Broadbent if (ec) 29017e860f15SJohn Edward Broadbent { 29027e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 29037e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 29047e860f15SJohn Edward Broadbent return; 29057e860f15SJohn Edward Broadbent } 29067e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 29077e860f15SJohn Edward Broadbent }, 29087e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 29097e860f15SJohn Edward Broadbent } 2910c5b2abe0SLewanczyk, Dawid 2911c5b2abe0SLewanczyk, Dawid /** 2912fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 2913fc903b3dSAndrew Geissler */ 2914fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 2915fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 2916fc903b3dSAndrew Geissler std::string_view resetType, 2917fc903b3dSAndrew Geissler crow::Response& res) 2918fc903b3dSAndrew Geissler { 2919fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 2920fc903b3dSAndrew Geissler { 2921fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 2922fc903b3dSAndrew Geissler return; 2923fc903b3dSAndrew Geissler } 2924fc903b3dSAndrew Geissler 2925fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 2926fc903b3dSAndrew Geissler { 2927fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "D-Bus response error: " << ec; 2928fc903b3dSAndrew Geissler messages::internalError(res); 2929fc903b3dSAndrew Geissler return; 2930fc903b3dSAndrew Geissler } 2931fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 2932fc903b3dSAndrew Geissler 2933fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 2934fc903b3dSAndrew Geissler // user to retry in a bit 2935fc903b3dSAndrew Geissler if ((errorMessage == 2936fc903b3dSAndrew Geissler std::string_view( 2937fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 2938fc903b3dSAndrew Geissler (errorMessage == 2939fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 2940fc903b3dSAndrew Geissler { 2941fc903b3dSAndrew Geissler BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now"; 2942fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 2943fc903b3dSAndrew Geissler return; 2944fc903b3dSAndrew Geissler } 2945fc903b3dSAndrew Geissler 2946fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec 2947fc903b3dSAndrew Geissler << " sdbusplus:" << errorMessage; 2948fc903b3dSAndrew Geissler messages::internalError(res); 2949fc903b3dSAndrew Geissler } 2950fc903b3dSAndrew Geissler 2951c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2952c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 29537f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2954c1e219d5SEd Tanous const std::string& systemName) 2955c1e219d5SEd Tanous { 29563ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 295745ca1b86SEd Tanous { 295845ca1b86SEd Tanous return; 295945ca1b86SEd Tanous } 2960c1e219d5SEd Tanous if (systemName != "system") 2961c1e219d5SEd Tanous { 2962c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2963c1e219d5SEd Tanous systemName); 2964c1e219d5SEd Tanous return; 2965c1e219d5SEd Tanous } 29667f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 29677f3e84a1SEd Tanous { 29687f3e84a1SEd Tanous // Option currently returns no systems. TBD 29697f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2970c1e219d5SEd Tanous systemName); 29717f3e84a1SEd Tanous return; 29727f3e84a1SEd Tanous } 29739712f8acSEd Tanous std::string resetType; 2974c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 2975cc340dd9SEd Tanous { 2976cc340dd9SEd Tanous return; 2977cc340dd9SEd Tanous } 2978cc340dd9SEd Tanous 2979d22c8396SJason M. Bills // Get the command and host vs. chassis 2980cc340dd9SEd Tanous std::string command; 2981543f4400SEd Tanous bool hostCommand = true; 2982d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2983cc340dd9SEd Tanous { 2984cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2985d22c8396SJason M. Bills hostCommand = true; 2986d22c8396SJason M. Bills } 2987d22c8396SJason M. Bills else if (resetType == "ForceOff") 2988d22c8396SJason M. Bills { 2989d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2990d22c8396SJason M. Bills hostCommand = false; 2991d22c8396SJason M. Bills } 2992d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2993d22c8396SJason M. Bills { 2994c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 299586a0851aSJason M. Bills hostCommand = true; 2996cc340dd9SEd Tanous } 29979712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2998cc340dd9SEd Tanous { 2999cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 3000d22c8396SJason M. Bills hostCommand = true; 3001cc340dd9SEd Tanous } 30029712f8acSEd Tanous else if (resetType == "GracefulRestart") 3003cc340dd9SEd Tanous { 30040fda0f12SGeorge Liu command = 30050fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 3006d22c8396SJason M. Bills hostCommand = true; 3007d22c8396SJason M. Bills } 3008d22c8396SJason M. Bills else if (resetType == "PowerCycle") 3009d22c8396SJason M. Bills { 301086a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 301186a0851aSJason M. Bills hostCommand = true; 3012cc340dd9SEd Tanous } 3013bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 3014bfd5b826SLakshminarayana R. Kammath { 3015bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 3016bfd5b826SLakshminarayana R. Kammath return; 3017bfd5b826SLakshminarayana R. Kammath } 3018cc340dd9SEd Tanous else 3019cc340dd9SEd Tanous { 3020c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 3021cc340dd9SEd Tanous return; 3022cc340dd9SEd Tanous } 3023cc340dd9SEd Tanous 3024d22c8396SJason M. Bills if (hostCommand) 3025d22c8396SJason M. Bills { 3026cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 3027fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3028fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3029cc340dd9SEd Tanous if (ec) 3030cc340dd9SEd Tanous { 3031fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3032fc903b3dSAndrew Geissler asyncResp->res); 3033fc903b3dSAndrew Geissler 3034cc340dd9SEd Tanous return; 3035cc340dd9SEd Tanous } 3036f12894f8SJason M. Bills messages::success(asyncResp->res); 3037cc340dd9SEd Tanous }, 3038cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 3039cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 3040cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 30419712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 3042168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 3043cc340dd9SEd Tanous } 3044d22c8396SJason M. Bills else 3045d22c8396SJason M. Bills { 3046d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 3047fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3048fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3049d22c8396SJason M. Bills if (ec) 3050d22c8396SJason M. Bills { 3051fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3052fc903b3dSAndrew Geissler asyncResp->res); 3053d22c8396SJason M. Bills return; 3054d22c8396SJason M. Bills } 3055d22c8396SJason M. Bills messages::success(asyncResp->res); 3056d22c8396SJason M. Bills }, 3057d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 3058d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 3059d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 3060002d39b4SEd Tanous "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 3061168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 3062d22c8396SJason M. Bills } 3063d22c8396SJason M. Bills } 3064cc340dd9SEd Tanous 3065c1e219d5SEd Tanous inline void handleComputerSystemHead( 3066dd60b9edSEd Tanous App& app, const crow::Request& req, 30677f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 30687f3e84a1SEd Tanous const std::string& /*systemName*/) 3069dd60b9edSEd Tanous { 3070dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3071dd60b9edSEd Tanous { 3072dd60b9edSEd Tanous return; 3073dd60b9edSEd Tanous } 3074dd60b9edSEd Tanous 3075dd60b9edSEd Tanous asyncResp->res.addHeader( 3076dd60b9edSEd Tanous boost::beast::http::field::link, 3077dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3078dd60b9edSEd Tanous } 3079dd60b9edSEd Tanous 30805c3e9272SAbhishek Patel inline void afterPortRequest( 30815c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 30825c3e9272SAbhishek Patel const boost::system::error_code& ec, 30835c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 30845c3e9272SAbhishek Patel { 30855c3e9272SAbhishek Patel if (ec) 30865c3e9272SAbhishek Patel { 30875c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 30885c3e9272SAbhishek Patel return; 30895c3e9272SAbhishek Patel } 30905c3e9272SAbhishek Patel for (const auto& data : socketData) 30915c3e9272SAbhishek Patel { 30925c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 30935c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 30945c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 30955c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 30965c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 30975c3e9272SAbhishek Patel // need to retrieve port number for 30985c3e9272SAbhishek Patel // obmc-console-ssh service 30995c3e9272SAbhishek Patel if (protocolName == "SSH") 31005c3e9272SAbhishek Patel { 31015c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 310281c4e330SEd Tanous const boost::system::error_code& ec1, 31035c3e9272SAbhishek Patel int portNumber) { 31045c3e9272SAbhishek Patel if (ec1) 31055c3e9272SAbhishek Patel { 31065c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31075c3e9272SAbhishek Patel return; 31085c3e9272SAbhishek Patel } 31095c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 31105c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 31115c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 31125c3e9272SAbhishek Patel }); 31135c3e9272SAbhishek Patel } 31145c3e9272SAbhishek Patel } 31155c3e9272SAbhishek Patel } 3116c1e219d5SEd Tanous 3117c1e219d5SEd Tanous inline void 3118c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 311922d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3120c1e219d5SEd Tanous const std::string& systemName) 3121c1e219d5SEd Tanous { 31223ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 312345ca1b86SEd Tanous { 312445ca1b86SEd Tanous return; 312545ca1b86SEd Tanous } 3126746b56f3SAsmitha Karunanithi 31277f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 31287f3e84a1SEd Tanous { 31297f3e84a1SEd Tanous // Option currently returns no systems. TBD 31307f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31317f3e84a1SEd Tanous systemName); 31327f3e84a1SEd Tanous return; 31337f3e84a1SEd Tanous } 31347f3e84a1SEd Tanous 3135746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3136746b56f3SAsmitha Karunanithi { 3137746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3138746b56f3SAsmitha Karunanithi return; 3139746b56f3SAsmitha Karunanithi } 3140746b56f3SAsmitha Karunanithi 314122d268cbSEd Tanous if (systemName != "system") 314222d268cbSEd Tanous { 314322d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 314422d268cbSEd Tanous systemName); 314522d268cbSEd Tanous return; 314622d268cbSEd Tanous } 3147dd60b9edSEd Tanous asyncResp->res.addHeader( 3148dd60b9edSEd Tanous boost::beast::http::field::link, 3149dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 31508d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 315137bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 31528d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 31538d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 31548d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 31558d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 31568d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 31575fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 31585fd0aafbSNinad Palsule { 31598d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 31608d1b46d7Szhanghch05 "Disabled"; 31618d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 31628d1b46d7Szhanghch05 "Disabled"; 31635fd0aafbSNinad Palsule } 3164cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3165cf0e004cSNinad Palsule uint64_t(0); 3166002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 316704a258f4SEd Tanous 31681476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 31691476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 31701476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 31711476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 31721476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 31731476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 31743179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 31753179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3176029573d4SEd Tanous 3177002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 31781476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 3179c1e219d5SEd Tanous asyncResp->res 3180c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 31811476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3182c5b2abe0SLewanczyk, Dawid 31831476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 31841476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 31851476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 31861476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3187c4bf6374SJason M. Bills 31881476687dSEd Tanous nlohmann::json::array_t managedBy; 31891476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 31901476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3191002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 31921476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 31931476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 31940e8ac5e7SGunnar Mills 31950e8ac5e7SGunnar Mills // Fill in SerialConsole info 3196002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3197c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 31981476687dSEd Tanous 3199c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 32001476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3201c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 32021476687dSEd Tanous "Press ~. to exit console"; 32035c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 32045c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 32050e8ac5e7SGunnar Mills 32060e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 32070e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3208002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3209c1e219d5SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4; 3210613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3211613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 32121476687dSEd Tanous 32130e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 321413451e39SWilly Tu 321513451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 321613451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 321713451e39SWilly Tu { 32187a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3219b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 32202ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3221e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3222e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3223b49ac873SJames Feist 32247a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 32257a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 32267a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3227914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3228b49ac873SJames Feist if (ec) 3229b49ac873SJames Feist { 3230b49ac873SJames Feist // no inventory 3231b49ac873SJames Feist return; 3232b49ac873SJames Feist } 3233b49ac873SJames Feist 3234914e2d5dSEd Tanous health->inventory = resp; 32357a1dbc48SGeorge Liu }); 3236b49ac873SJames Feist health->populate(); 323713451e39SWilly Tu } 3238b49ac873SJames Feist 3239002d39b4SEd Tanous getMainChassisId(asyncResp, 3240002d39b4SEd Tanous [](const std::string& chassisId, 32418d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3242b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3243b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3244ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3245ef4c65b7SEd Tanous chassisId); 3246002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3247c5d03ff4SJennifer Lee }); 3248a3002228SAppaRao Puli 32499f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 32509f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3251a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 32525bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 32536c34de48SEd Tanous getHostState(asyncResp); 3254491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3255978b8803SAndrew Geissler getBootProgress(asyncResp); 3256b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3257472bd202SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices"); 325851709ffdSYong Li getHostWatchdogTimer(asyncResp); 3259c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 3260797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3261c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3262a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3263a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3264a6349918SAppaRao Puli #endif 32651981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 32663a2d0424SChris Cain getPowerMode(asyncResp); 326737bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3268c1e219d5SEd Tanous } 3269550a6bf8SJiaqing Zhao 3270c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3271c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 327222d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3273c1e219d5SEd Tanous const std::string& systemName) 3274c1e219d5SEd Tanous { 32753ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 327645ca1b86SEd Tanous { 327745ca1b86SEd Tanous return; 327845ca1b86SEd Tanous } 32797f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 32807f3e84a1SEd Tanous { 32817f3e84a1SEd Tanous // Option currently returns no systems. TBD 32827f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 32837f3e84a1SEd Tanous systemName); 32847f3e84a1SEd Tanous return; 32857f3e84a1SEd Tanous } 328622d268cbSEd Tanous if (systemName != "system") 328722d268cbSEd Tanous { 328822d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 328922d268cbSEd Tanous systemName); 329022d268cbSEd Tanous return; 329122d268cbSEd Tanous } 329222d268cbSEd Tanous 3293dd60b9edSEd Tanous asyncResp->res.addHeader( 3294dd60b9edSEd Tanous boost::beast::http::field::link, 3295dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3296dd60b9edSEd Tanous 32979f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3298cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 329998e386ecSGunnar Mills std::optional<std::string> assetTag; 3300c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 33013a2d0424SChris Cain std::optional<std::string> powerMode; 3302550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3303550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3304550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3305550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3306550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3307550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3308797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3309550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 3310550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3311550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3312550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3313550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3314550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3315550a6bf8SJiaqing Zhao 3316550a6bf8SJiaqing Zhao // clang-format off 331715ed6780SWilly Tu if (!json_util::readJsonPatch( 3318550a6bf8SJiaqing Zhao req, asyncResp->res, 3319550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 33207e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3321550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3322550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3323550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3324550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3325550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3326550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3327550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3328550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3329550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3330797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3331550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 3332550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3333550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3334550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3335550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3336550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 33376617338dSEd Tanous { 33386617338dSEd Tanous return; 33396617338dSEd Tanous } 3340550a6bf8SJiaqing Zhao // clang-format on 3341491d8ee7SSantosh Puranik 33428d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3343c45f0082SYong Li 334498e386ecSGunnar Mills if (assetTag) 334598e386ecSGunnar Mills { 334698e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 334798e386ecSGunnar Mills } 334898e386ecSGunnar Mills 3349550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3350c45f0082SYong Li { 3351f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3352c45f0082SYong Li } 3353c45f0082SYong Li 3354cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 335569f35306SGunnar Mills { 3356002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3357491d8ee7SSantosh Puranik } 3358550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 335969f35306SGunnar Mills { 3360550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 336169f35306SGunnar Mills } 3362ac7e1e0bSAli Ahmed 3363797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3364797d5daeSCorey Hardesty { 3365797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3366797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3367797d5daeSCorey Hardesty } 3368797d5daeSCorey Hardesty 3369550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3370ac7e1e0bSAli Ahmed { 3371c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 337269f35306SGunnar Mills } 3373265c1602SJohnathan Mantey 33749f8bfa7cSGunnar Mills if (locationIndicatorActive) 33759f8bfa7cSGunnar Mills { 3376002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 33779f8bfa7cSGunnar Mills } 33789f8bfa7cSGunnar Mills 33797e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 33807e860f15SJohn Edward Broadbent // passed 33819712f8acSEd Tanous if (indicatorLed) 33826617338dSEd Tanous { 3383f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3384002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3385d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3386d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 33876617338dSEd Tanous } 3388c6a620f2SGeorge Liu 3389c6a620f2SGeorge Liu if (powerRestorePolicy) 3390c6a620f2SGeorge Liu { 33914e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3392c6a620f2SGeorge Liu } 33933a2d0424SChris Cain 33943a2d0424SChris Cain if (powerMode) 33953a2d0424SChris Cain { 33963a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 33973a2d0424SChris Cain } 339837bbf98cSChris Cain 3399c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 340037bbf98cSChris Cain { 3401002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3402002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 340337bbf98cSChris Cain } 3404c1e219d5SEd Tanous } 34051cb1a9e6SAppaRao Puli 340638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3407dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 34087f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3409c1e219d5SEd Tanous const std::string& /*systemName*/) 3410dd60b9edSEd Tanous { 3411dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3412dd60b9edSEd Tanous { 3413dd60b9edSEd Tanous return; 3414dd60b9edSEd Tanous } 3415dd60b9edSEd Tanous asyncResp->res.addHeader( 3416dd60b9edSEd Tanous boost::beast::http::field::link, 3417dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3418dd60b9edSEd Tanous } 3419c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3420c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 342122d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3422c1e219d5SEd Tanous const std::string& systemName) 3423c1e219d5SEd Tanous { 34243ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 342545ca1b86SEd Tanous { 342645ca1b86SEd Tanous return; 342745ca1b86SEd Tanous } 34287f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 34297f3e84a1SEd Tanous { 34307f3e84a1SEd Tanous // Option currently returns no systems. TBD 34317f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 34327f3e84a1SEd Tanous systemName); 34337f3e84a1SEd Tanous return; 34347f3e84a1SEd Tanous } 3435746b56f3SAsmitha Karunanithi 3436746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3437746b56f3SAsmitha Karunanithi { 3438746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3439746b56f3SAsmitha Karunanithi return; 3440746b56f3SAsmitha Karunanithi } 3441746b56f3SAsmitha Karunanithi 344222d268cbSEd Tanous if (systemName != "system") 344322d268cbSEd Tanous { 344422d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 344522d268cbSEd Tanous systemName); 344622d268cbSEd Tanous return; 344722d268cbSEd Tanous } 344822d268cbSEd Tanous 3449dd60b9edSEd Tanous asyncResp->res.addHeader( 3450dd60b9edSEd Tanous boost::beast::http::field::link, 3451dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34521476687dSEd Tanous 34531476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 34541476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3455c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34561476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34571476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34583215e700SNan Zhou 34593215e700SNan Zhou nlohmann::json::array_t parameters; 34603215e700SNan Zhou nlohmann::json::object_t parameter; 34613215e700SNan Zhou 34623215e700SNan Zhou parameter["Name"] = "ResetType"; 34633215e700SNan Zhou parameter["Required"] = true; 34643215e700SNan Zhou parameter["DataType"] = "String"; 34653215e700SNan Zhou nlohmann::json::array_t allowableValues; 34663215e700SNan Zhou allowableValues.emplace_back("On"); 34673215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 34683215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 34693215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 34703215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 34713215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 34723215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 34733215e700SNan Zhou allowableValues.emplace_back("Nmi"); 34743215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 34753215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 34763215e700SNan Zhou 34773215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 3478c1e219d5SEd Tanous } 3479c1e219d5SEd Tanous /** 3480c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3481c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3482c1e219d5SEd Tanous */ 3483100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3484c1e219d5SEd Tanous { 3485100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3486100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3487100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3488100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3489100afe56SEd Tanous 3490100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3491100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3492100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3493100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3494100afe56SEd Tanous 3495100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3496100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3497100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3498100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3499100afe56SEd Tanous 3500100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3501100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3502100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3503100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3504100afe56SEd Tanous 3505100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3506100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3507100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3508100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3509100afe56SEd Tanous 3510100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3511100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3512100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3513100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3514100afe56SEd Tanous 3515c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3516c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3517c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3518c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3519c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3520c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3521c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3522c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 35231cb1a9e6SAppaRao Puli } 3524c5b2abe0SLewanczyk, Dawid } // namespace redfish 3525