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" 23b49ac873SJames Feist #include "health.hpp" 24746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 251c8fba97SJames Feist #include "led.hpp" 26f4c99e70SEd Tanous #include "query.hpp" 27c5d03ff4SJennifer Lee #include "redfish_util.hpp" 283ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 293ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 303ccb3adbSEd Tanous #include "utils/json_utils.hpp" 31472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 323ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 332b82937eSEd Tanous #include "utils/time_utils.hpp" 34c5d03ff4SJennifer Lee 35fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 369712f8acSEd Tanous #include <boost/container/flat_map.hpp> 37e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 38ef4c65b7SEd Tanous #include <boost/url/format.hpp> 391e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 40fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 41bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 421214b7e7SGunnar Mills 437a1dbc48SGeorge Liu #include <array> 447a1dbc48SGeorge Liu #include <string_view> 45abf2add6SEd Tanous #include <variant> 46c5b2abe0SLewanczyk, Dawid 471abe55efSEd Tanous namespace redfish 481abe55efSEd Tanous { 49c5b2abe0SLewanczyk, Dawid 505c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 515c3e9272SAbhishek Patel protocolToDBusForSystems{ 525c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 535c3e9272SAbhishek Patel 549d3ae10eSAlpana Kumari /** 559d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 569d3ae10eSAlpana Kumari * 57*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 589d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 599d3ae10eSAlpana Kumari * 609d3ae10eSAlpana Kumari * @return None. 619d3ae10eSAlpana Kumari */ 628d1b46d7Szhanghch05 inline void 63*ac106bf6SEd Tanous updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 641e1e598dSJonathan Doman bool isDimmFunctional) 659d3ae10eSAlpana Kumari { 661e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional; 679d3ae10eSAlpana Kumari 689d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 699d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 709d3ae10eSAlpana Kumari // ENABLED. 7102cad96eSEd Tanous const nlohmann::json& prevMemSummary = 72*ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 739d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 749d3ae10eSAlpana Kumari { 75e05aec50SEd Tanous if (isDimmFunctional) 769d3ae10eSAlpana Kumari { 77*ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 789d3ae10eSAlpana Kumari "Enabled"; 799d3ae10eSAlpana Kumari } 809d3ae10eSAlpana Kumari } 819d3ae10eSAlpana Kumari } 829d3ae10eSAlpana Kumari 8357e8c9beSAlpana Kumari /* 8457e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 8557e8c9beSAlpana Kumari * CPU Functional State 8657e8c9beSAlpana Kumari * 87*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 8857e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 8957e8c9beSAlpana Kumari * 9057e8c9beSAlpana Kumari * @return None. 9157e8c9beSAlpana Kumari */ 92*ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 93*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 9457e8c9beSAlpana Kumari { 951e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional; 9657e8c9beSAlpana Kumari 9702cad96eSEd Tanous const nlohmann::json& prevProcState = 98*ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 9957e8c9beSAlpana Kumari 10057e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10157e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10257e8c9beSAlpana Kumari // Functional. 10357e8c9beSAlpana Kumari if (prevProcState == "Disabled") 10457e8c9beSAlpana Kumari { 105e05aec50SEd Tanous if (isCpuFunctional) 10657e8c9beSAlpana Kumari { 107*ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 10857e8c9beSAlpana Kumari "Enabled"; 10957e8c9beSAlpana Kumari } 11057e8c9beSAlpana Kumari } 11157e8c9beSAlpana Kumari } 11257e8c9beSAlpana Kumari 113cf0e004cSNinad Palsule /* 114cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 115cf0e004cSNinad Palsule * 116*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 117cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 118cf0e004cSNinad Palsule * 119cf0e004cSNinad Palsule * @return None. 120cf0e004cSNinad Palsule */ 121cf0e004cSNinad Palsule inline void 122*ac106bf6SEd Tanous modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 123cf0e004cSNinad Palsule bool isCpuPresent) 124cf0e004cSNinad Palsule { 125cf0e004cSNinad Palsule BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent; 126cf0e004cSNinad Palsule 127cf0e004cSNinad Palsule if (isCpuPresent) 128cf0e004cSNinad Palsule { 129cf0e004cSNinad Palsule nlohmann::json& procCount = 130*ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 131cf0e004cSNinad Palsule auto* procCountPtr = 132cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 133cf0e004cSNinad Palsule if (procCountPtr != nullptr) 134cf0e004cSNinad Palsule { 135cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 136cf0e004cSNinad Palsule *procCountPtr += 1; 137cf0e004cSNinad Palsule } 138cf0e004cSNinad Palsule } 139cf0e004cSNinad Palsule } 140cf0e004cSNinad Palsule 141382d6475SAli Ahmed inline void getProcessorProperties( 142*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 143382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 144382d6475SAli Ahmed properties) 14503fbed92SAli Ahmed { 14603fbed92SAli Ahmed BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties."; 14703fbed92SAli Ahmed 14803fbed92SAli Ahmed // TODO: Get Model 14903fbed92SAli Ahmed 150bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15103fbed92SAli Ahmed 152bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 153bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 15403fbed92SAli Ahmed 155bc1d29deSKrzysztof Grobelny if (!success) 15603fbed92SAli Ahmed { 157*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15803fbed92SAli Ahmed return; 15903fbed92SAli Ahmed } 16003fbed92SAli Ahmed 161bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16203fbed92SAli Ahmed { 163bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 164*ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 165bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 166bc1d29deSKrzysztof Grobelny 167bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 168bc1d29deSKrzysztof Grobelny { 169bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17003fbed92SAli Ahmed } 17103fbed92SAli Ahmed else 17203fbed92SAli Ahmed { 173bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 17403fbed92SAli Ahmed } 17503fbed92SAli Ahmed } 17603fbed92SAli Ahmed } 17703fbed92SAli Ahmed 17803fbed92SAli Ahmed /* 17903fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18003fbed92SAli Ahmed * 181*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 18203fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 18303fbed92SAli Ahmed * @param[in] path dbus path for Cpu 18403fbed92SAli Ahmed * 18503fbed92SAli Ahmed * @return None. 18603fbed92SAli Ahmed */ 187*ac106bf6SEd Tanous inline void 188*ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 189*ac106bf6SEd Tanous const std::string& service, const std::string& path) 19003fbed92SAli Ahmed { 191*ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 192382d6475SAli Ahmed const bool cpuPresenceCheck) { 193382d6475SAli Ahmed if (ec3) 194382d6475SAli Ahmed { 195382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 196382d6475SAli Ahmed return; 197382d6475SAli Ahmed } 198*ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 199382d6475SAli Ahmed }; 200382d6475SAli Ahmed 201cf0e004cSNinad Palsule // Get the Presence of CPU 202cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 203cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 204cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 205cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 206cf0e004cSNinad Palsule 2075fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2085fd0aafbSNinad Palsule { 2095fd0aafbSNinad Palsule auto getCpuFunctionalState = 210*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 211382d6475SAli Ahmed const bool cpuFunctionalCheck) { 212382d6475SAli Ahmed if (ec3) 213382d6475SAli Ahmed { 214382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 215382d6475SAli Ahmed return; 216382d6475SAli Ahmed } 217*ac106bf6SEd Tanous modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck); 218382d6475SAli Ahmed }; 219382d6475SAli Ahmed 220382d6475SAli Ahmed // Get the Functional State 221382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 222382d6475SAli Ahmed *crow::connections::systemBus, service, path, 2235fd0aafbSNinad Palsule "xyz.openbmc_project.State.Decorator.OperationalStatus", 2245fd0aafbSNinad Palsule "Functional", std::move(getCpuFunctionalState)); 2255fd0aafbSNinad Palsule } 226382d6475SAli Ahmed 227bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 228bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 229bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 230*ac106bf6SEd Tanous [asyncResp, service, 2315e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 232b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 23303fbed92SAli Ahmed if (ec2) 23403fbed92SAli Ahmed { 23503fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 236*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23703fbed92SAli Ahmed return; 23803fbed92SAli Ahmed } 239*ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 240bc1d29deSKrzysztof Grobelny }); 24103fbed92SAli Ahmed } 24203fbed92SAli Ahmed 24357e8c9beSAlpana Kumari /* 244cf0e004cSNinad Palsule * @brief processMemoryProperties fields 245cf0e004cSNinad Palsule * 246*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 247cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 248cf0e004cSNinad Palsule * @param[in] path dbus path for Memory 249cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 250cf0e004cSNinad Palsule * 251cf0e004cSNinad Palsule * @return None. 252cf0e004cSNinad Palsule */ 253cf0e004cSNinad Palsule inline void 254*ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2555fd0aafbSNinad Palsule [[maybe_unused]] const std::string& service, 2565fd0aafbSNinad Palsule [[maybe_unused]] const std::string& path, 257cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 258cf0e004cSNinad Palsule { 259cf0e004cSNinad Palsule BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties."; 260cf0e004cSNinad Palsule 261cf0e004cSNinad Palsule if (properties.empty()) 262cf0e004cSNinad Palsule { 2635fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2645fd0aafbSNinad Palsule { 265cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 266cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 267cf0e004cSNinad Palsule "xyz.openbmc_project.State." 268cf0e004cSNinad Palsule "Decorator.OperationalStatus", 269cf0e004cSNinad Palsule "Functional", 270*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 271*ac106bf6SEd Tanous bool dimmState) { 272cf0e004cSNinad Palsule if (ec3) 273cf0e004cSNinad Palsule { 274cf0e004cSNinad Palsule BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 275cf0e004cSNinad Palsule return; 276cf0e004cSNinad Palsule } 277*ac106bf6SEd Tanous updateDimmProperties(asyncResp, dimmState); 278cf0e004cSNinad Palsule }); 2795fd0aafbSNinad Palsule } 280cf0e004cSNinad Palsule return; 281cf0e004cSNinad Palsule } 282cf0e004cSNinad Palsule 283cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 284cf0e004cSNinad Palsule 285cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 286cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 287cf0e004cSNinad Palsule memorySizeInKB); 288cf0e004cSNinad Palsule 289cf0e004cSNinad Palsule if (!success) 290cf0e004cSNinad Palsule { 291*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 292cf0e004cSNinad Palsule return; 293cf0e004cSNinad Palsule } 294cf0e004cSNinad Palsule 295cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 296cf0e004cSNinad Palsule { 297cf0e004cSNinad Palsule nlohmann::json& totalMemory = 298*ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 299cf0e004cSNinad Palsule const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>(); 300cf0e004cSNinad Palsule if (preValue == nullptr) 301cf0e004cSNinad Palsule { 302*ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 303cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024); 304cf0e004cSNinad Palsule } 305cf0e004cSNinad Palsule else 306cf0e004cSNinad Palsule { 307*ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 308cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue; 309cf0e004cSNinad Palsule } 3105fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3115fd0aafbSNinad Palsule { 312*ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 3135fd0aafbSNinad Palsule "Enabled"; 3145fd0aafbSNinad Palsule } 315cf0e004cSNinad Palsule } 316cf0e004cSNinad Palsule } 317cf0e004cSNinad Palsule 318cf0e004cSNinad Palsule /* 319cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 320cf0e004cSNinad Palsule * 321*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 322cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 323cf0e004cSNinad Palsule * @param[in] path dbus path for memory 324cf0e004cSNinad Palsule * 325cf0e004cSNinad Palsule * @return None. 326cf0e004cSNinad Palsule */ 327*ac106bf6SEd Tanous inline void 328*ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 329*ac106bf6SEd Tanous const std::string& service, const std::string& path) 330cf0e004cSNinad Palsule { 331cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 332cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 333cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 334*ac106bf6SEd Tanous [asyncResp, service, 335cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 336cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 337cf0e004cSNinad Palsule if (ec2) 338cf0e004cSNinad Palsule { 339cf0e004cSNinad Palsule BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 340*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 341cf0e004cSNinad Palsule return; 342cf0e004cSNinad Palsule } 343*ac106bf6SEd Tanous processMemoryProperties(asyncResp, service, path, properties); 344cf0e004cSNinad Palsule }); 345cf0e004cSNinad Palsule } 346cf0e004cSNinad Palsule 347cf0e004cSNinad Palsule /* 348c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 349c5b2abe0SLewanczyk, Dawid * 350*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 3518f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 352c5b2abe0SLewanczyk, Dawid * 353c5b2abe0SLewanczyk, Dawid * @return None. 354c5b2abe0SLewanczyk, Dawid */ 355b5a76932SEd Tanous inline void 356*ac106bf6SEd Tanous getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 357b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 3581abe55efSEd Tanous { 35955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 360e99073f5SGeorge Liu constexpr std::array<std::string_view, 5> interfaces = { 361e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Asset", 362e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cpu", 363e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm", 364e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System", 365e99073f5SGeorge Liu "xyz.openbmc_project.Common.UUID", 366e99073f5SGeorge Liu }; 367e99073f5SGeorge Liu dbus::utility::getSubTree( 368e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 369*ac106bf6SEd Tanous [asyncResp, 370e99073f5SGeorge Liu systemHealth](const boost::system::error_code& ec, 371b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 3721abe55efSEd Tanous if (ec) 3731abe55efSEd Tanous { 37455c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 375*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 376c5b2abe0SLewanczyk, Dawid return; 377c5b2abe0SLewanczyk, Dawid } 378c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 379002d39b4SEd Tanous for (const std::pair< 380002d39b4SEd Tanous std::string, 381002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 3821214b7e7SGunnar Mills object : subtree) 3831abe55efSEd Tanous { 384c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 38555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 386002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 3871214b7e7SGunnar Mills connectionNames = object.second; 38826f6976fSEd Tanous if (connectionNames.empty()) 3891abe55efSEd Tanous { 390c5b2abe0SLewanczyk, Dawid continue; 391c5b2abe0SLewanczyk, Dawid } 392029573d4SEd Tanous 3935fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> memoryHealth = nullptr; 3945fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> cpuHealth = nullptr; 3955bc2dc8eSJames Feist 3965fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3975fd0aafbSNinad Palsule { 3985fd0aafbSNinad Palsule memoryHealth = std::make_shared<HealthPopulate>( 399*ac106bf6SEd Tanous asyncResp, "/MemorySummary/Status"_json_pointer); 4005fd0aafbSNinad Palsule systemHealth->children.emplace_back(memoryHealth); 4015bc2dc8eSJames Feist 40213451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 40313451e39SWilly Tu { 4045fd0aafbSNinad Palsule cpuHealth = std::make_shared<HealthPopulate>( 405*ac106bf6SEd Tanous asyncResp, "/ProcessorSummary/Status"_json_pointer); 4065fd0aafbSNinad Palsule 4075bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 40813451e39SWilly Tu } 4095fd0aafbSNinad Palsule } 4105bc2dc8eSJames Feist 4116c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4126c34de48SEd Tanous // BiosVer 41304a258f4SEd Tanous for (const auto& connection : connectionNames) 4141abe55efSEd Tanous { 41504a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4161abe55efSEd Tanous { 41704a258f4SEd Tanous if (interfaceName == 41804a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 4191abe55efSEd Tanous { 4201abe55efSEd Tanous BMCWEB_LOG_DEBUG 42104a258f4SEd Tanous << "Found Dimm, now get its properties."; 4229d3ae10eSAlpana Kumari 423*ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4245bc2dc8eSJames Feist 4255fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4265fd0aafbSNinad Palsule { 4275bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 4281abe55efSEd Tanous } 4295fd0aafbSNinad Palsule } 43004a258f4SEd Tanous else if (interfaceName == 43104a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4321abe55efSEd Tanous { 4331abe55efSEd Tanous BMCWEB_LOG_DEBUG 43404a258f4SEd Tanous << "Found Cpu, now get its properties."; 43557e8c9beSAlpana Kumari 436*ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4375bc2dc8eSJames Feist 4385fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4395fd0aafbSNinad Palsule { 4405bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4411abe55efSEd Tanous } 4425fd0aafbSNinad Palsule } 443002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4441abe55efSEd Tanous { 4451abe55efSEd Tanous BMCWEB_LOG_DEBUG 44604a258f4SEd Tanous << "Found UUID, now get its properties."; 447bc1d29deSKrzysztof Grobelny 448bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 449bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 450bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Common.UUID", 451*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 452b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4531214b7e7SGunnar Mills properties) { 454cb13a392SEd Tanous if (ec3) 4551abe55efSEd Tanous { 456002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " 457002d39b4SEd Tanous << ec3; 458*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 459c5b2abe0SLewanczyk, Dawid return; 460c5b2abe0SLewanczyk, Dawid } 461002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 462c5b2abe0SLewanczyk, Dawid << " UUID properties."; 46304a258f4SEd Tanous 464bc1d29deSKrzysztof Grobelny const std::string* uUID = nullptr; 465bc1d29deSKrzysztof Grobelny 466bc1d29deSKrzysztof Grobelny const bool success = 467bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 468bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 469bc1d29deSKrzysztof Grobelny properties, "UUID", uUID); 470bc1d29deSKrzysztof Grobelny 471bc1d29deSKrzysztof Grobelny if (!success) 4721abe55efSEd Tanous { 473*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 474bc1d29deSKrzysztof Grobelny return; 475bc1d29deSKrzysztof Grobelny } 476bc1d29deSKrzysztof Grobelny 477bc1d29deSKrzysztof Grobelny if (uUID != nullptr) 478bc1d29deSKrzysztof Grobelny { 479bc1d29deSKrzysztof Grobelny std::string valueStr = *uUID; 48004a258f4SEd Tanous if (valueStr.size() == 32) 4811abe55efSEd Tanous { 482029573d4SEd Tanous valueStr.insert(8, 1, '-'); 483029573d4SEd Tanous valueStr.insert(13, 1, '-'); 484029573d4SEd Tanous valueStr.insert(18, 1, '-'); 485029573d4SEd Tanous valueStr.insert(23, 1, '-'); 48604a258f4SEd Tanous } 487bc1d29deSKrzysztof Grobelny BMCWEB_LOG_DEBUG << "UUID = " << valueStr; 488*ac106bf6SEd Tanous asyncResp->res.jsonValue["UUID"] = valueStr; 489c5b2abe0SLewanczyk, Dawid } 490bc1d29deSKrzysztof Grobelny }); 491c5b2abe0SLewanczyk, Dawid } 492029573d4SEd Tanous else if (interfaceName == 493029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4941abe55efSEd Tanous { 495bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 496bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 497bc1d29deSKrzysztof Grobelny path, 498bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 499*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 500b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 5011214b7e7SGunnar Mills propertiesList) { 502cb13a392SEd Tanous if (ec2) 503029573d4SEd Tanous { 504e4a4b9a9SJames Feist // doesn't have to include this 505e4a4b9a9SJames Feist // interface 506029573d4SEd Tanous return; 507029573d4SEd Tanous } 508002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 509029573d4SEd Tanous << " properties for system"; 510bc1d29deSKrzysztof Grobelny 511bc1d29deSKrzysztof Grobelny const std::string* partNumber = nullptr; 512bc1d29deSKrzysztof Grobelny const std::string* serialNumber = nullptr; 513bc1d29deSKrzysztof Grobelny const std::string* manufacturer = nullptr; 514bc1d29deSKrzysztof Grobelny const std::string* model = nullptr; 515bc1d29deSKrzysztof Grobelny const std::string* subModel = nullptr; 516bc1d29deSKrzysztof Grobelny 517bc1d29deSKrzysztof Grobelny const bool success = 518bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 519bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 520bc1d29deSKrzysztof Grobelny propertiesList, "PartNumber", partNumber, 521bc1d29deSKrzysztof Grobelny "SerialNumber", serialNumber, 522bc1d29deSKrzysztof Grobelny "Manufacturer", manufacturer, "Model", 523bc1d29deSKrzysztof Grobelny model, "SubModel", subModel); 524bc1d29deSKrzysztof Grobelny 525bc1d29deSKrzysztof Grobelny if (!success) 526029573d4SEd Tanous { 527*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 528bc1d29deSKrzysztof Grobelny return; 529029573d4SEd Tanous } 530bc1d29deSKrzysztof Grobelny 531bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 532bc1d29deSKrzysztof Grobelny { 533*ac106bf6SEd Tanous asyncResp->res.jsonValue["PartNumber"] = 534bc1d29deSKrzysztof Grobelny *partNumber; 535029573d4SEd Tanous } 536bc1d29deSKrzysztof Grobelny 537bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 538bc1d29deSKrzysztof Grobelny { 539*ac106bf6SEd Tanous asyncResp->res.jsonValue["SerialNumber"] = 540bc1d29deSKrzysztof Grobelny *serialNumber; 541bc1d29deSKrzysztof Grobelny } 542bc1d29deSKrzysztof Grobelny 543bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 544bc1d29deSKrzysztof Grobelny { 545*ac106bf6SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = 546bc1d29deSKrzysztof Grobelny *manufacturer; 547bc1d29deSKrzysztof Grobelny } 548bc1d29deSKrzysztof Grobelny 549bc1d29deSKrzysztof Grobelny if (model != nullptr) 550bc1d29deSKrzysztof Grobelny { 551*ac106bf6SEd Tanous asyncResp->res.jsonValue["Model"] = *model; 552bc1d29deSKrzysztof Grobelny } 553bc1d29deSKrzysztof Grobelny 554bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 555bc1d29deSKrzysztof Grobelny { 556*ac106bf6SEd Tanous asyncResp->res.jsonValue["SubModel"] = 557*ac106bf6SEd Tanous *subModel; 558fc5afcf9Sbeccabroek } 559c1e236a6SGunnar Mills 560cb7e1e7bSAndrew Geissler // Grab the bios version 561eee0013eSWilly Tu sw_util::populateSoftwareInformation( 562*ac106bf6SEd Tanous asyncResp, sw_util::biosPurpose, "BiosVersion", 563002d39b4SEd Tanous false); 564bc1d29deSKrzysztof Grobelny }); 565e4a4b9a9SJames Feist 5661e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5671e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5681e1e598dSJonathan Doman path, 5691e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5701e1e598dSJonathan Doman "AssetTag", 5711e1e598dSJonathan Doman "AssetTag", 572*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 5731e1e598dSJonathan Doman const std::string& value) { 574cb13a392SEd Tanous if (ec2) 575e4a4b9a9SJames Feist { 576e4a4b9a9SJames Feist // doesn't have to include this 577e4a4b9a9SJames Feist // interface 578e4a4b9a9SJames Feist return; 579e4a4b9a9SJames Feist } 580e4a4b9a9SJames Feist 581*ac106bf6SEd Tanous asyncResp->res.jsonValue["AssetTag"] = value; 5821e1e598dSJonathan Doman }); 583029573d4SEd Tanous } 584029573d4SEd Tanous } 585029573d4SEd Tanous } 586c5b2abe0SLewanczyk, Dawid } 5876617338dSEd Tanous }); 588c5b2abe0SLewanczyk, Dawid } 589c5b2abe0SLewanczyk, Dawid 590c5b2abe0SLewanczyk, Dawid /** 591c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 592c5b2abe0SLewanczyk, Dawid * 593*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 594c5b2abe0SLewanczyk, Dawid * 595c5b2abe0SLewanczyk, Dawid * @return None. 596c5b2abe0SLewanczyk, Dawid */ 597*ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5981abe55efSEd Tanous { 59955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 6001e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 6011e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 6021e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 6031e1e598dSJonathan Doman "CurrentHostState", 604*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 6051e1e598dSJonathan Doman const std::string& hostState) { 6061abe55efSEd Tanous if (ec) 6071abe55efSEd Tanous { 60822228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 60922228c28SAndrew Geissler { 61022228c28SAndrew Geissler // Service not available, no error, just don't return 61122228c28SAndrew Geissler // host state info 61222228c28SAndrew Geissler BMCWEB_LOG_DEBUG << "Service not available " << ec; 61322228c28SAndrew Geissler return; 61422228c28SAndrew Geissler } 61522228c28SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 616*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 617c5b2abe0SLewanczyk, Dawid return; 618c5b2abe0SLewanczyk, Dawid } 6196617338dSEd Tanous 6201e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Host state: " << hostState; 621c5b2abe0SLewanczyk, Dawid // Verify Host State 6221e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 6231abe55efSEd Tanous { 624*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 625*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 6261abe55efSEd Tanous } 6271e1e598dSJonathan Doman else if (hostState == 6280fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 6298c888608SGunnar Mills { 630*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 631*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6328c888608SGunnar Mills } 6331e1e598dSJonathan Doman else if (hostState == 6340fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 63583935af9SAndrew Geissler { 636*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 637*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 63883935af9SAndrew Geissler } 6390fda0f12SGeorge Liu else if ( 6401e1e598dSJonathan Doman hostState == 6410fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6421a2a1437SAndrew Geissler { 643*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 644*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 6451a2a1437SAndrew Geissler } 646002d39b4SEd Tanous else if (hostState == 6470fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6481a2a1437SAndrew Geissler { 649*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 650*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 6511a2a1437SAndrew Geissler } 6521abe55efSEd Tanous else 6531abe55efSEd Tanous { 654*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 655*ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 656c5b2abe0SLewanczyk, Dawid } 6571e1e598dSJonathan Doman }); 658c5b2abe0SLewanczyk, Dawid } 659c5b2abe0SLewanczyk, Dawid 660c5b2abe0SLewanczyk, Dawid /** 661786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 662491d8ee7SSantosh Puranik * 663491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 664491d8ee7SSantosh Puranik * 665491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 666491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 667491d8ee7SSantosh Puranik */ 66823a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 669491d8ee7SSantosh Puranik { 670491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 671491d8ee7SSantosh Puranik { 672491d8ee7SSantosh Puranik return "None"; 673491d8ee7SSantosh Puranik } 6743174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 675491d8ee7SSantosh Puranik { 676491d8ee7SSantosh Puranik return "Hdd"; 677491d8ee7SSantosh Puranik } 6783174e4dfSEd Tanous if (dbusSource == 679a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 680491d8ee7SSantosh Puranik { 681491d8ee7SSantosh Puranik return "Cd"; 682491d8ee7SSantosh Puranik } 6833174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 684491d8ee7SSantosh Puranik { 685491d8ee7SSantosh Puranik return "Pxe"; 686491d8ee7SSantosh Puranik } 6873174e4dfSEd Tanous if (dbusSource == 688944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6899f16b2c1SJennifer Lee { 6909f16b2c1SJennifer Lee return "Usb"; 6919f16b2c1SJennifer Lee } 692491d8ee7SSantosh Puranik return ""; 693491d8ee7SSantosh Puranik } 694491d8ee7SSantosh Puranik 695491d8ee7SSantosh Puranik /** 696cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 697cd9a4666SKonstantin Aladyshev * 698cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 699cd9a4666SKonstantin Aladyshev * 700cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 701cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 702cd9a4666SKonstantin Aladyshev */ 703cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 704cd9a4666SKonstantin Aladyshev { 705cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 706cd9a4666SKonstantin Aladyshev { 707cd9a4666SKonstantin Aladyshev return "Legacy"; 708cd9a4666SKonstantin Aladyshev } 709cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 710cd9a4666SKonstantin Aladyshev { 711cd9a4666SKonstantin Aladyshev return "UEFI"; 712cd9a4666SKonstantin Aladyshev } 713cd9a4666SKonstantin Aladyshev return ""; 714cd9a4666SKonstantin Aladyshev } 715cd9a4666SKonstantin Aladyshev 716cd9a4666SKonstantin Aladyshev /** 717786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 718491d8ee7SSantosh Puranik * 719491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 720491d8ee7SSantosh Puranik * 721491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 722491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 723491d8ee7SSantosh Puranik */ 72423a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 725491d8ee7SSantosh Puranik { 726491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 727491d8ee7SSantosh Puranik { 728491d8ee7SSantosh Puranik return "None"; 729491d8ee7SSantosh Puranik } 7303174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 731491d8ee7SSantosh Puranik { 732491d8ee7SSantosh Puranik return "Diags"; 733491d8ee7SSantosh Puranik } 7343174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 735491d8ee7SSantosh Puranik { 736491d8ee7SSantosh Puranik return "BiosSetup"; 737491d8ee7SSantosh Puranik } 738491d8ee7SSantosh Puranik return ""; 739491d8ee7SSantosh Puranik } 740491d8ee7SSantosh Puranik 741491d8ee7SSantosh Puranik /** 742e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 743e43914b3SAndrew Geissler * 744e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 745e43914b3SAndrew Geissler * 746e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 747e43914b3SAndrew Geissler * translation cannot be done, returns "None". 748e43914b3SAndrew Geissler */ 749e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 750e43914b3SAndrew Geissler { 751e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 752e43914b3SAndrew Geissler // enum 753e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 754e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 755e43914b3SAndrew Geissler "ProgressStages.Unspecified") 756e43914b3SAndrew Geissler { 757e43914b3SAndrew Geissler rfBpLastState = "None"; 758e43914b3SAndrew Geissler } 759e43914b3SAndrew Geissler else if (dbusBootProgress == 760e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 761e43914b3SAndrew Geissler "PrimaryProcInit") 762e43914b3SAndrew Geissler { 763e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 764e43914b3SAndrew Geissler } 765e43914b3SAndrew Geissler else if (dbusBootProgress == 766e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 767e43914b3SAndrew Geissler "BusInit") 768e43914b3SAndrew Geissler { 769e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 770e43914b3SAndrew Geissler } 771e43914b3SAndrew Geissler else if (dbusBootProgress == 772e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 773e43914b3SAndrew Geissler "MemoryInit") 774e43914b3SAndrew Geissler { 775e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 776e43914b3SAndrew Geissler } 777e43914b3SAndrew Geissler else if (dbusBootProgress == 778e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 779e43914b3SAndrew Geissler "SecondaryProcInit") 780e43914b3SAndrew Geissler { 781e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 782e43914b3SAndrew Geissler } 783e43914b3SAndrew Geissler else if (dbusBootProgress == 784e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 785e43914b3SAndrew Geissler "PCIInit") 786e43914b3SAndrew Geissler { 787e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 788e43914b3SAndrew Geissler } 789e43914b3SAndrew Geissler else if (dbusBootProgress == 790e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 791e43914b3SAndrew Geissler "SystemSetup") 792e43914b3SAndrew Geissler { 793e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 794e43914b3SAndrew Geissler } 795e43914b3SAndrew Geissler else if (dbusBootProgress == 796e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 797e43914b3SAndrew Geissler "SystemInitComplete") 798e43914b3SAndrew Geissler { 799e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 800e43914b3SAndrew Geissler } 801e43914b3SAndrew Geissler else if (dbusBootProgress == 802e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 803e43914b3SAndrew Geissler "OSStart") 804e43914b3SAndrew Geissler { 805e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 806e43914b3SAndrew Geissler } 807e43914b3SAndrew Geissler else if (dbusBootProgress == 808e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 809e43914b3SAndrew Geissler "OSRunning") 810e43914b3SAndrew Geissler { 811e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 812e43914b3SAndrew Geissler } 813e43914b3SAndrew Geissler else 814e43914b3SAndrew Geissler { 815e43914b3SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 816e43914b3SAndrew Geissler << dbusBootProgress; 817e43914b3SAndrew Geissler // Just return the default 818e43914b3SAndrew Geissler } 819e43914b3SAndrew Geissler return rfBpLastState; 820e43914b3SAndrew Geissler } 821e43914b3SAndrew Geissler 822e43914b3SAndrew Geissler /** 823786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 824491d8ee7SSantosh Puranik * 825491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 826944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 827944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 828491d8ee7SSantosh Puranik * 829944ffaf9SJohnathan Mantey * @return Integer error code. 830491d8ee7SSantosh Puranik */ 831*ac106bf6SEd Tanous inline int 832*ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 833*ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 834*ac106bf6SEd Tanous std::string& bootMode) 835491d8ee7SSantosh Puranik { 836c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 837c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 838944ffaf9SJohnathan Mantey 839491d8ee7SSantosh Puranik if (rfSource == "None") 840491d8ee7SSantosh Puranik { 841944ffaf9SJohnathan Mantey return 0; 842491d8ee7SSantosh Puranik } 8433174e4dfSEd Tanous if (rfSource == "Pxe") 844491d8ee7SSantosh Puranik { 845944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 846944ffaf9SJohnathan Mantey } 847944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 848944ffaf9SJohnathan Mantey { 849944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 850944ffaf9SJohnathan Mantey } 851944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 852944ffaf9SJohnathan Mantey { 853944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 854944ffaf9SJohnathan Mantey } 855944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 856944ffaf9SJohnathan Mantey { 857944ffaf9SJohnathan Mantey bootSource = 858944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 859944ffaf9SJohnathan Mantey } 860944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 861944ffaf9SJohnathan Mantey { 862944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 863491d8ee7SSantosh Puranik } 8649f16b2c1SJennifer Lee else if (rfSource == "Usb") 8659f16b2c1SJennifer Lee { 866944ffaf9SJohnathan Mantey bootSource = 867944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8689f16b2c1SJennifer Lee } 869491d8ee7SSantosh Puranik else 870491d8ee7SSantosh Puranik { 8710fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 8720fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideTarget: " 873944ffaf9SJohnathan Mantey << bootSource; 874*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 875944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 876944ffaf9SJohnathan Mantey return -1; 877491d8ee7SSantosh Puranik } 878944ffaf9SJohnathan Mantey return 0; 879491d8ee7SSantosh Puranik } 8801981771bSAli Ahmed 881978b8803SAndrew Geissler /** 882978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 883978b8803SAndrew Geissler * 884*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 885978b8803SAndrew Geissler * 886978b8803SAndrew Geissler * @return None. 887978b8803SAndrew Geissler */ 888*ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 889978b8803SAndrew Geissler { 8901e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8911e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8921e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8931e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 894*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8951e1e598dSJonathan Doman const std::string& bootProgressStr) { 896978b8803SAndrew Geissler if (ec) 897978b8803SAndrew Geissler { 898978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 899978b8803SAndrew Geissler // not found 900978b8803SAndrew Geissler return; 901978b8803SAndrew Geissler } 902978b8803SAndrew Geissler 9031e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr; 904978b8803SAndrew Geissler 905*ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 906e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 9071e1e598dSJonathan Doman }); 908978b8803SAndrew Geissler } 909491d8ee7SSantosh Puranik 910491d8ee7SSantosh Puranik /** 911b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 912b6d5d45cSHieu Huynh * 913*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 914b6d5d45cSHieu Huynh * 915b6d5d45cSHieu Huynh * @return None. 916b6d5d45cSHieu Huynh */ 917b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 918*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 919b6d5d45cSHieu Huynh { 920b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 921b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 922b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 923b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 924*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 925b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 926b6d5d45cSHieu Huynh if (ec) 927b6d5d45cSHieu Huynh { 928b6d5d45cSHieu Huynh BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 929b6d5d45cSHieu Huynh return; 930b6d5d45cSHieu Huynh } 931b6d5d45cSHieu Huynh 932b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 933b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 934b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 935b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 936b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 937b6d5d45cSHieu Huynh 938b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 939*ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 940b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 941b6d5d45cSHieu Huynh }); 942b6d5d45cSHieu Huynh } 943b6d5d45cSHieu Huynh 944b6d5d45cSHieu Huynh /** 945c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 946cd9a4666SKonstantin Aladyshev * 947*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 948cd9a4666SKonstantin Aladyshev * 949cd9a4666SKonstantin Aladyshev * @return None. 950cd9a4666SKonstantin Aladyshev */ 951cd9a4666SKonstantin Aladyshev 952*ac106bf6SEd Tanous inline void 953*ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 954cd9a4666SKonstantin Aladyshev { 9551e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9561e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9571e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9581e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 959*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9601e1e598dSJonathan Doman const std::string& bootType) { 961cd9a4666SKonstantin Aladyshev if (ec) 962cd9a4666SKonstantin Aladyshev { 963cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 964cd9a4666SKonstantin Aladyshev return; 965cd9a4666SKonstantin Aladyshev } 966cd9a4666SKonstantin Aladyshev 9671e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot type: " << bootType; 968cd9a4666SKonstantin Aladyshev 969*ac106bf6SEd Tanous asyncResp->res 970*ac106bf6SEd Tanous .jsonValue["Boot"] 971002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 972613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 973cd9a4666SKonstantin Aladyshev 9741e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 975cd9a4666SKonstantin Aladyshev if (rfType.empty()) 976cd9a4666SKonstantin Aladyshev { 977*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 978cd9a4666SKonstantin Aladyshev return; 979cd9a4666SKonstantin Aladyshev } 980cd9a4666SKonstantin Aladyshev 981*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9821e1e598dSJonathan Doman }); 983cd9a4666SKonstantin Aladyshev } 984cd9a4666SKonstantin Aladyshev 985cd9a4666SKonstantin Aladyshev /** 986c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 987491d8ee7SSantosh Puranik * 988*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 989491d8ee7SSantosh Puranik * 990491d8ee7SSantosh Puranik * @return None. 991491d8ee7SSantosh Puranik */ 992c21865c4SKonstantin Aladyshev 993*ac106bf6SEd Tanous inline void 994*ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 995491d8ee7SSantosh Puranik { 9961e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9971e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9981e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9991e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1000*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10011e1e598dSJonathan Doman const std::string& bootModeStr) { 1002491d8ee7SSantosh Puranik if (ec) 1003491d8ee7SSantosh Puranik { 1004491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1005*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1006491d8ee7SSantosh Puranik return; 1007491d8ee7SSantosh Puranik } 1008491d8ee7SSantosh Puranik 10091e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 1010491d8ee7SSantosh Puranik 1011*ac106bf6SEd Tanous asyncResp->res 10120fda0f12SGeorge Liu .jsonValue["Boot"] 1013002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 1014002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1015491d8ee7SSantosh Puranik 10161e1e598dSJonathan Doman if (bootModeStr != 1017491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1018491d8ee7SSantosh Puranik { 10191e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 1020491d8ee7SSantosh Puranik if (!rfMode.empty()) 1021491d8ee7SSantosh Puranik { 1022*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1023491d8ee7SSantosh Puranik rfMode; 1024491d8ee7SSantosh Puranik } 1025491d8ee7SSantosh Puranik } 10261e1e598dSJonathan Doman }); 1027491d8ee7SSantosh Puranik } 1028491d8ee7SSantosh Puranik 1029491d8ee7SSantosh Puranik /** 1030c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1031491d8ee7SSantosh Puranik * 1032*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1033491d8ee7SSantosh Puranik * 1034491d8ee7SSantosh Puranik * @return None. 1035491d8ee7SSantosh Puranik */ 1036c21865c4SKonstantin Aladyshev 1037c21865c4SKonstantin Aladyshev inline void 1038*ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1039491d8ee7SSantosh Puranik { 10401e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10411e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10421e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10431e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1044*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10451e1e598dSJonathan Doman const std::string& bootSourceStr) { 1046491d8ee7SSantosh Puranik if (ec) 1047491d8ee7SSantosh Puranik { 1048491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 10495ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10505ef735c8SNan Zhou { 10515ef735c8SNan Zhou return; 10525ef735c8SNan Zhou } 1053*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1054491d8ee7SSantosh Puranik return; 1055491d8ee7SSantosh Puranik } 1056491d8ee7SSantosh Puranik 10571e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr; 1058491d8ee7SSantosh Puranik 10591e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1060491d8ee7SSantosh Puranik if (!rfSource.empty()) 1061491d8ee7SSantosh Puranik { 1062*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1063*ac106bf6SEd Tanous rfSource; 1064491d8ee7SSantosh Puranik } 1065cd9a4666SKonstantin Aladyshev 1066cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1067cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1068*ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10691e1e598dSJonathan Doman }); 1070491d8ee7SSantosh Puranik } 1071491d8ee7SSantosh Puranik 1072491d8ee7SSantosh Puranik /** 1073c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1074c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1075c21865c4SKonstantin Aladyshev * state 1076491d8ee7SSantosh Puranik * 1077*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1078491d8ee7SSantosh Puranik * 1079491d8ee7SSantosh Puranik * @return None. 1080491d8ee7SSantosh Puranik */ 1081491d8ee7SSantosh Puranik 1082*ac106bf6SEd Tanous inline void processBootOverrideEnable( 1083*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1084c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1085c21865c4SKonstantin Aladyshev { 1086c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1087c21865c4SKonstantin Aladyshev { 1088*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1089*ac106bf6SEd Tanous "Disabled"; 1090c21865c4SKonstantin Aladyshev return; 1091c21865c4SKonstantin Aladyshev } 1092c21865c4SKonstantin Aladyshev 1093c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1094c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10951e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10961e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10971e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10981e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1099*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1100491d8ee7SSantosh Puranik if (ec) 1101491d8ee7SSantosh Puranik { 1102491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1103*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1104491d8ee7SSantosh Puranik return; 1105491d8ee7SSantosh Puranik } 1106491d8ee7SSantosh Puranik 1107c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1108c21865c4SKonstantin Aladyshev { 1109*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1110*ac106bf6SEd Tanous "Once"; 1111c21865c4SKonstantin Aladyshev } 1112c21865c4SKonstantin Aladyshev else 1113c21865c4SKonstantin Aladyshev { 1114*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1115c21865c4SKonstantin Aladyshev "Continuous"; 1116c21865c4SKonstantin Aladyshev } 11171e1e598dSJonathan Doman }); 1118491d8ee7SSantosh Puranik } 1119491d8ee7SSantosh Puranik 1120491d8ee7SSantosh Puranik /** 1121c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1122c21865c4SKonstantin Aladyshev * 1123*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1124c21865c4SKonstantin Aladyshev * 1125c21865c4SKonstantin Aladyshev * @return None. 1126c21865c4SKonstantin Aladyshev */ 1127c21865c4SKonstantin Aladyshev 1128c21865c4SKonstantin Aladyshev inline void 1129*ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1130c21865c4SKonstantin Aladyshev { 11311e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11321e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11331e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 11341e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1135*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 11361e1e598dSJonathan Doman const bool bootOverrideEnable) { 1137c21865c4SKonstantin Aladyshev if (ec) 1138c21865c4SKonstantin Aladyshev { 1139c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 11405ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11415ef735c8SNan Zhou { 11425ef735c8SNan Zhou return; 11435ef735c8SNan Zhou } 1144*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1145c21865c4SKonstantin Aladyshev return; 1146c21865c4SKonstantin Aladyshev } 1147c21865c4SKonstantin Aladyshev 1148*ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11491e1e598dSJonathan Doman }); 1150c21865c4SKonstantin Aladyshev } 1151c21865c4SKonstantin Aladyshev 1152c21865c4SKonstantin Aladyshev /** 1153c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1154c21865c4SKonstantin Aladyshev * 1155*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1156c21865c4SKonstantin Aladyshev * 1157c21865c4SKonstantin Aladyshev * @return None. 1158c21865c4SKonstantin Aladyshev */ 1159*ac106bf6SEd Tanous inline void 1160*ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1161c21865c4SKonstantin Aladyshev { 1162c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1163c21865c4SKonstantin Aladyshev 1164*ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1165*ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1166*ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1167c21865c4SKonstantin Aladyshev } 1168c21865c4SKonstantin Aladyshev 1169c21865c4SKonstantin Aladyshev /** 1170c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1171c0557e1aSGunnar Mills * 1172c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1173c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1174c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1175c0557e1aSGunnar Mills * last power operation time. 1176c0557e1aSGunnar Mills * 1177*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1178c0557e1aSGunnar Mills * 1179c0557e1aSGunnar Mills * @return None. 1180c0557e1aSGunnar Mills */ 1181*ac106bf6SEd Tanous inline void 1182*ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1183c0557e1aSGunnar Mills { 1184c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1185c0557e1aSGunnar Mills 11861e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11871e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11881e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11891e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1190*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1191*ac106bf6SEd Tanous uint64_t lastResetTime) { 1192c0557e1aSGunnar Mills if (ec) 1193c0557e1aSGunnar Mills { 1194c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1195c0557e1aSGunnar Mills return; 1196c0557e1aSGunnar Mills } 1197c0557e1aSGunnar Mills 1198c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1199c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 12001e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1201c0557e1aSGunnar Mills 1202c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1203*ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 12042b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 12051e1e598dSJonathan Doman }); 1206c0557e1aSGunnar Mills } 1207c0557e1aSGunnar Mills 1208c0557e1aSGunnar Mills /** 1209797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1210797d5daeSCorey Hardesty * 1211797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1212797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1213797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1214797d5daeSCorey Hardesty * dbus. 1215797d5daeSCorey Hardesty * 1216*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1217797d5daeSCorey Hardesty * 1218797d5daeSCorey Hardesty * @return None. 1219797d5daeSCorey Hardesty */ 1220*ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1221*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1222797d5daeSCorey Hardesty { 1223797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 1224797d5daeSCorey Hardesty 1225797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1226797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1227797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1228797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1229*ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1230*ac106bf6SEd Tanous const boost::system::error_code& ec, 1231797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1232797d5daeSCorey Hardesty if (ec) 1233797d5daeSCorey Hardesty { 1234797d5daeSCorey Hardesty if (ec.value() != EBADR) 1235797d5daeSCorey Hardesty { 1236797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1237*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1238797d5daeSCorey Hardesty } 1239797d5daeSCorey Hardesty return; 1240797d5daeSCorey Hardesty } 1241797d5daeSCorey Hardesty 1242797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1243797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1244797d5daeSCorey Hardesty 1245797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1246797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1247797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1248797d5daeSCorey Hardesty 1249797d5daeSCorey Hardesty if (!success) 1250797d5daeSCorey Hardesty { 1251*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1252797d5daeSCorey Hardesty return; 1253797d5daeSCorey Hardesty } 1254797d5daeSCorey Hardesty 1255797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1256797d5daeSCorey Hardesty { 1257*ac106bf6SEd Tanous asyncResp->res 1258*ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1259797d5daeSCorey Hardesty *attemptsLeft; 1260797d5daeSCorey Hardesty } 1261797d5daeSCorey Hardesty 1262797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1263797d5daeSCorey Hardesty { 1264*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1265797d5daeSCorey Hardesty *retryAttempts; 1266797d5daeSCorey Hardesty } 1267797d5daeSCorey Hardesty }); 1268797d5daeSCorey Hardesty } 1269797d5daeSCorey Hardesty 1270797d5daeSCorey Hardesty /** 12716bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12726bd5a8d2SGunnar Mills * 1273*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12746bd5a8d2SGunnar Mills * 12756bd5a8d2SGunnar Mills * @return None. 12766bd5a8d2SGunnar Mills */ 1277797d5daeSCorey Hardesty inline void 1278*ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12796bd5a8d2SGunnar Mills { 12806bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 12816bd5a8d2SGunnar Mills 12821e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12831e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12841e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12851e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1286*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1287*ac106bf6SEd Tanous bool autoRebootEnabled) { 12886bd5a8d2SGunnar Mills if (ec) 12896bd5a8d2SGunnar Mills { 1290797d5daeSCorey Hardesty if (ec.value() != EBADR) 1291797d5daeSCorey Hardesty { 1292797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1293*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1294797d5daeSCorey Hardesty } 12956bd5a8d2SGunnar Mills return; 12966bd5a8d2SGunnar Mills } 12976bd5a8d2SGunnar Mills 12981e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled; 1299e05aec50SEd Tanous if (autoRebootEnabled) 13006bd5a8d2SGunnar Mills { 1301*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 13026bd5a8d2SGunnar Mills "RetryAttempts"; 13036bd5a8d2SGunnar Mills } 13046bd5a8d2SGunnar Mills else 13056bd5a8d2SGunnar Mills { 1306*ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1307*ac106bf6SEd Tanous "Disabled"; 13086bd5a8d2SGunnar Mills } 1309*ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 131069f35306SGunnar Mills 131169f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 131269f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 131369f35306SGunnar Mills // RetryAttempts. 1314*ac106bf6SEd Tanous asyncResp->res 1315*ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1316*ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 13171e1e598dSJonathan Doman }); 13186bd5a8d2SGunnar Mills } 13196bd5a8d2SGunnar Mills 13206bd5a8d2SGunnar Mills /** 1321797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1322797d5daeSCorey Hardesty * 1323*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1324797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1325797d5daeSCorey Hardesty * 1326797d5daeSCorey Hardesty *@return None. 1327797d5daeSCorey Hardesty */ 1328797d5daeSCorey Hardesty 1329*ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1330*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1331797d5daeSCorey Hardesty const uint32_t retryAttempts) 1332797d5daeSCorey Hardesty { 1333797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts."; 1334797d5daeSCorey Hardesty crow::connections::systemBus->async_method_call( 1335*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1336797d5daeSCorey Hardesty if (ec) 1337797d5daeSCorey Hardesty { 1338797d5daeSCorey Hardesty BMCWEB_LOG_ERROR 1339797d5daeSCorey Hardesty << "DBUS response error: Set setAutomaticRetryAttempts" << ec; 1340*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1341797d5daeSCorey Hardesty return; 1342797d5daeSCorey Hardesty } 1343797d5daeSCorey Hardesty }, 1344797d5daeSCorey Hardesty "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 1345797d5daeSCorey Hardesty "org.freedesktop.DBus.Properties", "Set", 1346797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1347797d5daeSCorey Hardesty std::variant<uint32_t>(retryAttempts)); 1348797d5daeSCorey Hardesty } 1349797d5daeSCorey Hardesty 1350797d5daeSCorey Hardesty /** 1351c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1352c6a620f2SGeorge Liu * 1353*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1354c6a620f2SGeorge Liu * 1355c6a620f2SGeorge Liu * @return None. 1356c6a620f2SGeorge Liu */ 13578d1b46d7Szhanghch05 inline void 1358*ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1359c6a620f2SGeorge Liu { 1360c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1361c6a620f2SGeorge Liu 13621e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13631e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13641e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13651e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1366*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13675e7e2dc5SEd Tanous const std::string& policy) { 1368c6a620f2SGeorge Liu if (ec) 1369c6a620f2SGeorge Liu { 1370c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1371c6a620f2SGeorge Liu return; 1372c6a620f2SGeorge Liu } 1373c6a620f2SGeorge Liu 13740fda0f12SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 13750fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn", 1376c6a620f2SGeorge Liu "AlwaysOn"}, 13770fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff", 1378c6a620f2SGeorge Liu "AlwaysOff"}, 13790fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore", 13804ed47cb8SMatthew Barth "LastState"}, 13814ed47cb8SMatthew Barth // Return `AlwaysOff` when power restore policy set to "None" 13824ed47cb8SMatthew Barth {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None", 13834ed47cb8SMatthew Barth "AlwaysOff"}}; 1384c6a620f2SGeorge Liu 13851e1e598dSJonathan Doman auto policyMapsIt = policyMaps.find(policy); 1386c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1387c6a620f2SGeorge Liu { 1388*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1389c6a620f2SGeorge Liu return; 1390c6a620f2SGeorge Liu } 1391c6a620f2SGeorge Liu 1392*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second; 13931e1e598dSJonathan Doman }); 1394c6a620f2SGeorge Liu } 1395c6a620f2SGeorge Liu 1396c6a620f2SGeorge Liu /** 13971981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13981981771bSAli Ahmed * TPM is required for booting the host. 13991981771bSAli Ahmed * 1400*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14011981771bSAli Ahmed * 14021981771bSAli Ahmed * @return None. 14031981771bSAli Ahmed */ 14041981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1405*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14061981771bSAli Ahmed { 14071981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 1408e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1409e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1410e99073f5SGeorge Liu dbus::utility::getSubTree( 1411e99073f5SGeorge Liu "/", 0, interfaces, 1412*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1413b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14141981771bSAli Ahmed if (ec) 14151981771bSAli Ahmed { 1416002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1417002d39b4SEd Tanous << ec; 14181981771bSAli Ahmed // This is an optional D-Bus object so just return if 14191981771bSAli Ahmed // error occurs 14201981771bSAli Ahmed return; 14211981771bSAli Ahmed } 142226f6976fSEd Tanous if (subtree.empty()) 14231981771bSAli Ahmed { 14241981771bSAli Ahmed // As noted above, this is an optional interface so just return 14251981771bSAli Ahmed // if there is no instance found 14261981771bSAli Ahmed return; 14271981771bSAli Ahmed } 14281981771bSAli Ahmed 14291981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14301981771bSAli Ahmed if (subtree.size() > 1) 14311981771bSAli Ahmed { 14321981771bSAli Ahmed BMCWEB_LOG_DEBUG 14331981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 14341981771bSAli Ahmed << subtree.size(); 14351981771bSAli Ahmed // Throw an internal Error and return 1436*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14371981771bSAli Ahmed return; 14381981771bSAli Ahmed } 14391981771bSAli Ahmed 14401981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14411981771bSAli Ahmed // field 14421981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14431981771bSAli Ahmed { 14441981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 1445*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14461981771bSAli Ahmed return; 14471981771bSAli Ahmed } 14481981771bSAli Ahmed 14491981771bSAli Ahmed const std::string& path = subtree[0].first; 14501981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14511981771bSAli Ahmed 14521981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14531e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14541e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14551e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1456*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1457*ac106bf6SEd Tanous bool tpmRequired) { 14588a592810SEd Tanous if (ec2) 14591981771bSAli Ahmed { 1460002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get" 14618a592810SEd Tanous << ec2; 1462*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14631981771bSAli Ahmed return; 14641981771bSAli Ahmed } 14651981771bSAli Ahmed 14661e1e598dSJonathan Doman if (tpmRequired) 14671981771bSAli Ahmed { 1468*ac106bf6SEd Tanous asyncResp->res 1469*ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14701981771bSAli Ahmed "Required"; 14711981771bSAli Ahmed } 14721981771bSAli Ahmed else 14731981771bSAli Ahmed { 1474*ac106bf6SEd Tanous asyncResp->res 1475*ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14761981771bSAli Ahmed "Disabled"; 14771981771bSAli Ahmed } 14781e1e598dSJonathan Doman }); 1479e99073f5SGeorge Liu }); 14801981771bSAli Ahmed } 14811981771bSAli Ahmed 14821981771bSAli Ahmed /** 14831c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14841c05dae3SAli Ahmed * TPM is required for booting the host. 14851c05dae3SAli Ahmed * 1486*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14871c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14881c05dae3SAli Ahmed * 14891c05dae3SAli Ahmed * @return None. 14901c05dae3SAli Ahmed */ 14911c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1492*ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 14931c05dae3SAli Ahmed { 14941c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 1495e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1496e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1497e99073f5SGeorge Liu dbus::utility::getSubTree( 1498e99073f5SGeorge Liu "/", 0, interfaces, 1499*ac106bf6SEd Tanous [asyncResp, 1500e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1501e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15021c05dae3SAli Ahmed if (ec) 15031c05dae3SAli Ahmed { 1504002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1505002d39b4SEd Tanous << ec; 1506*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15071c05dae3SAli Ahmed return; 15081c05dae3SAli Ahmed } 150926f6976fSEd Tanous if (subtree.empty()) 15101c05dae3SAli Ahmed { 1511*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 15121c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15131c05dae3SAli Ahmed return; 15141c05dae3SAli Ahmed } 15151c05dae3SAli Ahmed 15161c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15171c05dae3SAli Ahmed if (subtree.size() > 1) 15181c05dae3SAli Ahmed { 15191c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 15201c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 15211c05dae3SAli Ahmed << subtree.size(); 15221c05dae3SAli Ahmed // Throw an internal Error and return 1523*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15241c05dae3SAli Ahmed return; 15251c05dae3SAli Ahmed } 15261c05dae3SAli Ahmed 15271c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15281c05dae3SAli Ahmed // field 15291c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15301c05dae3SAli Ahmed { 15311c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 1532*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15331c05dae3SAli Ahmed return; 15341c05dae3SAli Ahmed } 15351c05dae3SAli Ahmed 15361c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15371c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15381c05dae3SAli Ahmed 15391c05dae3SAli Ahmed if (serv.empty()) 15401c05dae3SAli Ahmed { 15411c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 1542*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15431c05dae3SAli Ahmed return; 15441c05dae3SAli Ahmed } 15451c05dae3SAli Ahmed 15461c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 15471c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 1548*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 15498a592810SEd Tanous if (ec2) 15501c05dae3SAli Ahmed { 15510fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 15520fda0f12SGeorge Liu << "DBUS response error: Set TrustedModuleRequiredToBoot" 15538a592810SEd Tanous << ec2; 1554*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15551c05dae3SAli Ahmed return; 15561c05dae3SAli Ahmed } 15571c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 15581c05dae3SAli Ahmed }, 15591c05dae3SAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Set", 15601c05dae3SAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1561168e20c1SEd Tanous dbus::utility::DbusVariantType(tpmRequired)); 1562e99073f5SGeorge Liu }); 15631c05dae3SAli Ahmed } 15641c05dae3SAli Ahmed 15651c05dae3SAli Ahmed /** 1566491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1567491d8ee7SSantosh Puranik * 1568*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1569cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1570cd9a4666SKonstantin Aladyshev * @return Integer error code. 1571cd9a4666SKonstantin Aladyshev */ 1572*ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1573cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1574cd9a4666SKonstantin Aladyshev { 1575c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1576cd9a4666SKonstantin Aladyshev 1577c21865c4SKonstantin Aladyshev if (!bootType) 1578cd9a4666SKonstantin Aladyshev { 1579c21865c4SKonstantin Aladyshev return; 1580c21865c4SKonstantin Aladyshev } 1581c21865c4SKonstantin Aladyshev 1582cd9a4666SKonstantin Aladyshev // Source target specified 1583cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1584cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1585cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1586cd9a4666SKonstantin Aladyshev { 1587cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1588cd9a4666SKonstantin Aladyshev } 1589cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1590cd9a4666SKonstantin Aladyshev { 1591cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1592cd9a4666SKonstantin Aladyshev } 1593cd9a4666SKonstantin Aladyshev else 1594cd9a4666SKonstantin Aladyshev { 1595cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1596cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1597cd9a4666SKonstantin Aladyshev << *bootType; 1598*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1599cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1600cd9a4666SKonstantin Aladyshev return; 1601cd9a4666SKonstantin Aladyshev } 1602cd9a4666SKonstantin Aladyshev 1603cd9a4666SKonstantin Aladyshev // Act on validated parameters 1604cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1605cd9a4666SKonstantin Aladyshev 1606cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1607*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1608cd9a4666SKonstantin Aladyshev if (ec) 1609cd9a4666SKonstantin Aladyshev { 1610cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1611cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1612cd9a4666SKonstantin Aladyshev { 1613*ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1614cd9a4666SKonstantin Aladyshev return; 1615cd9a4666SKonstantin Aladyshev } 1616*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1617cd9a4666SKonstantin Aladyshev return; 1618cd9a4666SKonstantin Aladyshev } 1619cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1620cd9a4666SKonstantin Aladyshev }, 1621c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1622c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1623cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1624cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1625168e20c1SEd Tanous dbus::utility::DbusVariantType(bootTypeStr)); 1626cd9a4666SKonstantin Aladyshev } 1627cd9a4666SKonstantin Aladyshev 1628cd9a4666SKonstantin Aladyshev /** 1629cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1630cd9a4666SKonstantin Aladyshev * 1631*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1632*ac106bf6SEd Tanous * message. 1633c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1634c21865c4SKonstantin Aladyshev * @return Integer error code. 1635c21865c4SKonstantin Aladyshev */ 1636*ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1637c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1638c21865c4SKonstantin Aladyshev { 1639c21865c4SKonstantin Aladyshev if (!bootEnable) 1640c21865c4SKonstantin Aladyshev { 1641c21865c4SKonstantin Aladyshev return; 1642c21865c4SKonstantin Aladyshev } 1643c21865c4SKonstantin Aladyshev // Source target specified 1644c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1645c21865c4SKonstantin Aladyshev 1646c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1647c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1648c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1649c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1650c21865c4SKonstantin Aladyshev { 1651c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1652c21865c4SKonstantin Aladyshev } 1653c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1654c21865c4SKonstantin Aladyshev { 1655c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1656c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1657c21865c4SKonstantin Aladyshev } 1658c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1659c21865c4SKonstantin Aladyshev { 1660c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1661c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1662c21865c4SKonstantin Aladyshev } 1663c21865c4SKonstantin Aladyshev else 1664c21865c4SKonstantin Aladyshev { 16650fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 16660fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideEnabled: " 1667c21865c4SKonstantin Aladyshev << *bootEnable; 1668*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1669c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1670c21865c4SKonstantin Aladyshev return; 1671c21865c4SKonstantin Aladyshev } 1672c21865c4SKonstantin Aladyshev 1673c21865c4SKonstantin Aladyshev // Act on validated parameters 1674c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1675c21865c4SKonstantin Aladyshev 1676c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1677*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 16788a592810SEd Tanous if (ec2) 1679c21865c4SKonstantin Aladyshev { 16808a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1681*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1682c21865c4SKonstantin Aladyshev return; 1683c21865c4SKonstantin Aladyshev } 1684c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1685c21865c4SKonstantin Aladyshev }, 1686c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1687c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1688c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1689c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1690168e20c1SEd Tanous dbus::utility::DbusVariantType(bootOverrideEnable)); 1691c21865c4SKonstantin Aladyshev 1692c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1693c21865c4SKonstantin Aladyshev { 1694c21865c4SKonstantin Aladyshev return; 1695c21865c4SKonstantin Aladyshev } 1696c21865c4SKonstantin Aladyshev 1697c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1698c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1699c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1700c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1701c21865c4SKonstantin Aladyshev 1702c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 1703*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1704c21865c4SKonstantin Aladyshev if (ec) 1705c21865c4SKonstantin Aladyshev { 1706c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1707*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1708c21865c4SKonstantin Aladyshev return; 1709c21865c4SKonstantin Aladyshev } 1710c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1711c21865c4SKonstantin Aladyshev }, 1712c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1713c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1714c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1715c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1716168e20c1SEd Tanous dbus::utility::DbusVariantType(!bootOverridePersistent)); 1717c21865c4SKonstantin Aladyshev } 1718c21865c4SKonstantin Aladyshev 1719c21865c4SKonstantin Aladyshev /** 1720c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1721c21865c4SKonstantin Aladyshev * 1722*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1723491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1724491d8ee7SSantosh Puranik * 1725265c1602SJohnathan Mantey * @return Integer error code. 1726491d8ee7SSantosh Puranik */ 1727*ac106bf6SEd Tanous inline void 1728*ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1729cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1730491d8ee7SSantosh Puranik { 1731c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1732c21865c4SKonstantin Aladyshev std::string bootModeStr; 1733944ffaf9SJohnathan Mantey 1734c21865c4SKonstantin Aladyshev if (!bootSource) 1735491d8ee7SSantosh Puranik { 1736c21865c4SKonstantin Aladyshev return; 1737c21865c4SKonstantin Aladyshev } 1738c21865c4SKonstantin Aladyshev 1739491d8ee7SSantosh Puranik // Source target specified 1740491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1741491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1742*ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1743*ac106bf6SEd Tanous bootModeStr) != 0) 1744491d8ee7SSantosh Puranik { 1745944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1746944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1747491d8ee7SSantosh Puranik << *bootSource; 1748*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1749491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1750491d8ee7SSantosh Puranik return; 1751491d8ee7SSantosh Puranik } 1752491d8ee7SSantosh Puranik 1753944ffaf9SJohnathan Mantey // Act on validated parameters 1754944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1755944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1756944ffaf9SJohnathan Mantey 1757491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1758*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1759491d8ee7SSantosh Puranik if (ec) 1760491d8ee7SSantosh Puranik { 1761491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1762*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1763491d8ee7SSantosh Puranik return; 1764491d8ee7SSantosh Puranik } 1765491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1766491d8ee7SSantosh Puranik }, 1767c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1768c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1769491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1770491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1771168e20c1SEd Tanous dbus::utility::DbusVariantType(bootSourceStr)); 1772944ffaf9SJohnathan Mantey 1773491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 1774*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1775491d8ee7SSantosh Puranik if (ec) 1776491d8ee7SSantosh Puranik { 1777491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1778*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1779491d8ee7SSantosh Puranik return; 1780491d8ee7SSantosh Puranik } 1781491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1782491d8ee7SSantosh Puranik }, 1783c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1784c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1785491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1786491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1787168e20c1SEd Tanous dbus::utility::DbusVariantType(bootModeStr)); 1788cd9a4666SKonstantin Aladyshev } 1789944ffaf9SJohnathan Mantey 1790cd9a4666SKonstantin Aladyshev /** 1791c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1792491d8ee7SSantosh Puranik * 1793*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1794491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1795cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1796491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1797491d8ee7SSantosh Puranik * 1798265c1602SJohnathan Mantey * @return Integer error code. 1799491d8ee7SSantosh Puranik */ 1800c21865c4SKonstantin Aladyshev 1801*ac106bf6SEd Tanous inline void 1802*ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1803c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1804c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1805c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1806491d8ee7SSantosh Puranik { 1807491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1808491d8ee7SSantosh Puranik 1809*ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1810*ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1811*ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1812491d8ee7SSantosh Puranik } 1813491d8ee7SSantosh Puranik 1814c6a620f2SGeorge Liu /** 181598e386ecSGunnar Mills * @brief Sets AssetTag 181698e386ecSGunnar Mills * 1817*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 181898e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 181998e386ecSGunnar Mills * 182098e386ecSGunnar Mills * @return None. 182198e386ecSGunnar Mills */ 1822*ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 182398e386ecSGunnar Mills const std::string& assetTag) 182498e386ecSGunnar Mills { 1825e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1826e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1827e99073f5SGeorge Liu dbus::utility::getSubTree( 1828e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1829*ac106bf6SEd Tanous [asyncResp, 1830e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1831b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 183298e386ecSGunnar Mills if (ec) 183398e386ecSGunnar Mills { 183498e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 1835*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 183698e386ecSGunnar Mills return; 183798e386ecSGunnar Mills } 183826f6976fSEd Tanous if (subtree.empty()) 183998e386ecSGunnar Mills { 184098e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 1841*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 184298e386ecSGunnar Mills return; 184398e386ecSGunnar Mills } 184498e386ecSGunnar Mills // Assume only 1 system D-Bus object 184598e386ecSGunnar Mills // Throw an error if there is more than 1 184698e386ecSGunnar Mills if (subtree.size() > 1) 184798e386ecSGunnar Mills { 184898e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 1849*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 185098e386ecSGunnar Mills return; 185198e386ecSGunnar Mills } 185298e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 185398e386ecSGunnar Mills { 185498e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 1855*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 185698e386ecSGunnar Mills return; 185798e386ecSGunnar Mills } 185898e386ecSGunnar Mills 185998e386ecSGunnar Mills const std::string& path = subtree[0].first; 186098e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 186198e386ecSGunnar Mills 186298e386ecSGunnar Mills if (service.empty()) 186398e386ecSGunnar Mills { 186498e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 1865*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 186698e386ecSGunnar Mills return; 186798e386ecSGunnar Mills } 186898e386ecSGunnar Mills 186998e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 1870*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 187198e386ecSGunnar Mills if (ec2) 187298e386ecSGunnar Mills { 1873002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set " 1874002d39b4SEd Tanous << ec2; 1875*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 187698e386ecSGunnar Mills return; 187798e386ecSGunnar Mills } 187898e386ecSGunnar Mills }, 187998e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 188098e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 1881168e20c1SEd Tanous dbus::utility::DbusVariantType(assetTag)); 1882e99073f5SGeorge Liu }); 188398e386ecSGunnar Mills } 188498e386ecSGunnar Mills 188598e386ecSGunnar Mills /** 188669f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 188769f35306SGunnar Mills * 1888*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 188969f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 189069f35306SGunnar Mills * 189169f35306SGunnar Mills * @return None. 189269f35306SGunnar Mills */ 1893*ac106bf6SEd Tanous inline void 1894*ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1895f23b7296SEd Tanous const std::string& automaticRetryConfig) 189669f35306SGunnar Mills { 189769f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 189869f35306SGunnar Mills 189969f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1900543f4400SEd Tanous bool autoRebootEnabled = false; 190169f35306SGunnar Mills 190269f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 190369f35306SGunnar Mills { 190469f35306SGunnar Mills autoRebootEnabled = false; 190569f35306SGunnar Mills } 190669f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 190769f35306SGunnar Mills { 190869f35306SGunnar Mills autoRebootEnabled = true; 190969f35306SGunnar Mills } 191069f35306SGunnar Mills else 191169f35306SGunnar Mills { 19120fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: " 191369f35306SGunnar Mills << automaticRetryConfig; 1914*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 191569f35306SGunnar Mills "AutomaticRetryConfig"); 191669f35306SGunnar Mills return; 191769f35306SGunnar Mills } 191869f35306SGunnar Mills 191969f35306SGunnar Mills crow::connections::systemBus->async_method_call( 1920*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 192169f35306SGunnar Mills if (ec) 192269f35306SGunnar Mills { 1923*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 192469f35306SGunnar Mills return; 192569f35306SGunnar Mills } 192669f35306SGunnar Mills }, 192769f35306SGunnar Mills "xyz.openbmc_project.Settings", 192869f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 192969f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 193069f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1931168e20c1SEd Tanous dbus::utility::DbusVariantType(autoRebootEnabled)); 193269f35306SGunnar Mills } 193369f35306SGunnar Mills 193469f35306SGunnar Mills /** 1935c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1936c6a620f2SGeorge Liu * 1937*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1938c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1939c6a620f2SGeorge Liu * 1940c6a620f2SGeorge Liu * @return None. 1941c6a620f2SGeorge Liu */ 19428d1b46d7Szhanghch05 inline void 1943*ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19444e69c904SGunnar Mills const std::string& policy) 1945c6a620f2SGeorge Liu { 1946c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1947c6a620f2SGeorge Liu 1948c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 19490fda0f12SGeorge Liu {"AlwaysOn", 19500fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"}, 19510fda0f12SGeorge Liu {"AlwaysOff", 19520fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"}, 19530fda0f12SGeorge Liu {"LastState", 19540fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}}; 1955c6a620f2SGeorge Liu 1956c6a620f2SGeorge Liu std::string powerRestorPolicy; 1957c6a620f2SGeorge Liu 19584e69c904SGunnar Mills auto policyMapsIt = policyMaps.find(policy); 1959c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1960c6a620f2SGeorge Liu { 1961*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 19624e69c904SGunnar Mills "PowerRestorePolicy"); 1963c6a620f2SGeorge Liu return; 1964c6a620f2SGeorge Liu } 1965c6a620f2SGeorge Liu 1966c6a620f2SGeorge Liu powerRestorPolicy = policyMapsIt->second; 1967c6a620f2SGeorge Liu 1968c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 1969*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1970c6a620f2SGeorge Liu if (ec) 1971c6a620f2SGeorge Liu { 1972*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1973c6a620f2SGeorge Liu return; 1974c6a620f2SGeorge Liu } 1975c6a620f2SGeorge Liu }, 1976c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1977c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1978c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1979c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1980168e20c1SEd Tanous dbus::utility::DbusVariantType(powerRestorPolicy)); 1981c6a620f2SGeorge Liu } 1982c6a620f2SGeorge Liu 1983a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 1984a6349918SAppaRao Puli /** 1985a6349918SAppaRao Puli * @brief Retrieves provisioning status 1986a6349918SAppaRao Puli * 1987*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 1988a6349918SAppaRao Puli * 1989a6349918SAppaRao Puli * @return None. 1990a6349918SAppaRao Puli */ 1991*ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 1992a6349918SAppaRao Puli { 1993a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 1994bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1995bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1996bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 1997*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1998b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1999b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2000*ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2001*ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 200250626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 200350626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 200450626f4fSJames Feist 2005a6349918SAppaRao Puli if (ec) 2006a6349918SAppaRao Puli { 2007a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2008b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2009b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2010a6349918SAppaRao Puli return; 2011a6349918SAppaRao Puli } 2012a6349918SAppaRao Puli 2013a6349918SAppaRao Puli const bool* provState = nullptr; 2014a6349918SAppaRao Puli const bool* lockState = nullptr; 2015bc1d29deSKrzysztof Grobelny 2016bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 20170d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 20180d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 2019bc1d29deSKrzysztof Grobelny 2020bc1d29deSKrzysztof Grobelny if (!success) 2021a6349918SAppaRao Puli { 2022*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2023bc1d29deSKrzysztof Grobelny return; 2024a6349918SAppaRao Puli } 2025a6349918SAppaRao Puli 2026a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2027a6349918SAppaRao Puli { 2028a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 2029*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2030a6349918SAppaRao Puli return; 2031a6349918SAppaRao Puli } 2032a6349918SAppaRao Puli 2033a6349918SAppaRao Puli if (*provState == true) 2034a6349918SAppaRao Puli { 2035a6349918SAppaRao Puli if (*lockState == true) 2036a6349918SAppaRao Puli { 2037a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2038a6349918SAppaRao Puli } 2039a6349918SAppaRao Puli else 2040a6349918SAppaRao Puli { 2041a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2042a6349918SAppaRao Puli } 2043a6349918SAppaRao Puli } 2044a6349918SAppaRao Puli else 2045a6349918SAppaRao Puli { 2046a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2047a6349918SAppaRao Puli } 2048bc1d29deSKrzysztof Grobelny }); 2049a6349918SAppaRao Puli } 2050a6349918SAppaRao Puli #endif 2051a6349918SAppaRao Puli 2052491d8ee7SSantosh Puranik /** 20533a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 20543a2d0424SChris Cain * 2055*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 20563a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 20573a2d0424SChris Cain * 20583a2d0424SChris Cain * @return None. 20593a2d0424SChris Cain */ 2060*ac106bf6SEd Tanous inline void 2061*ac106bf6SEd Tanous translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20623a2d0424SChris Cain const std::string& modeValue) 20633a2d0424SChris Cain { 20640fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20653a2d0424SChris Cain { 2066*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "Static"; 20673a2d0424SChris Cain } 20680fda0f12SGeorge Liu else if ( 20690fda0f12SGeorge Liu modeValue == 20700fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20713a2d0424SChris Cain { 2072*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 20733a2d0424SChris Cain } 20740fda0f12SGeorge Liu else if (modeValue == 20750fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20763a2d0424SChris Cain { 2077*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "PowerSaving"; 20783a2d0424SChris Cain } 20790fda0f12SGeorge Liu else if (modeValue == 20800fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20813a2d0424SChris Cain { 2082*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "OEM"; 20833a2d0424SChris Cain } 20843a2d0424SChris Cain else 20853a2d0424SChris Cain { 20863a2d0424SChris Cain // Any other values would be invalid 20873a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 2088*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 20893a2d0424SChris Cain } 20903a2d0424SChris Cain } 20913a2d0424SChris Cain 20923a2d0424SChris Cain /** 20933a2d0424SChris Cain * @brief Retrieves system power mode 20943a2d0424SChris Cain * 2095*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 20963a2d0424SChris Cain * 20973a2d0424SChris Cain * @return None. 20983a2d0424SChris Cain */ 2099*ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 21003a2d0424SChris Cain { 21013a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 21023a2d0424SChris Cain 21033a2d0424SChris Cain // Get Power Mode object path: 2104e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2105e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2106e99073f5SGeorge Liu dbus::utility::getSubTree( 2107e99073f5SGeorge Liu "/", 0, interfaces, 2108*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2109b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21103a2d0424SChris Cain if (ec) 21113a2d0424SChris Cain { 2112002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2113002d39b4SEd Tanous << ec; 21143a2d0424SChris Cain // This is an optional D-Bus object so just return if 21153a2d0424SChris Cain // error occurs 21163a2d0424SChris Cain return; 21173a2d0424SChris Cain } 21183a2d0424SChris Cain if (subtree.empty()) 21193a2d0424SChris Cain { 21203a2d0424SChris Cain // As noted above, this is an optional interface so just return 21213a2d0424SChris Cain // if there is no instance found 21223a2d0424SChris Cain return; 21233a2d0424SChris Cain } 21243a2d0424SChris Cain if (subtree.size() > 1) 21253a2d0424SChris Cain { 21263a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21273a2d0424SChris Cain // error 21283a2d0424SChris Cain BMCWEB_LOG_DEBUG 21293a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 21303a2d0424SChris Cain << subtree.size(); 2131*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21323a2d0424SChris Cain return; 21333a2d0424SChris Cain } 21343a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21353a2d0424SChris Cain { 21363a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 2137*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21383a2d0424SChris Cain return; 21393a2d0424SChris Cain } 21403a2d0424SChris Cain const std::string& path = subtree[0].first; 21413a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21423a2d0424SChris Cain if (service.empty()) 21433a2d0424SChris Cain { 21443a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 2145*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21463a2d0424SChris Cain return; 21473a2d0424SChris Cain } 21483a2d0424SChris Cain // Valid Power Mode object found, now read the current value 21491e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 21501e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 21511e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2152*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 21531e1e598dSJonathan Doman const std::string& pmode) { 21548a592810SEd Tanous if (ec2) 21553a2d0424SChris Cain { 2156002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: " 21578a592810SEd Tanous << ec2; 2158*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21593a2d0424SChris Cain return; 21603a2d0424SChris Cain } 21613a2d0424SChris Cain 2162*ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2163002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 21643a2d0424SChris Cain 21651e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 2166*ac106bf6SEd Tanous translatePowerMode(asyncResp, pmode); 21671e1e598dSJonathan Doman }); 2168e99073f5SGeorge Liu }); 21693a2d0424SChris Cain } 21703a2d0424SChris Cain 21713a2d0424SChris Cain /** 21723a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21733a2d0424SChris Cain * name associated with that string 21743a2d0424SChris Cain * 2175*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21763a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 21773a2d0424SChris Cain * 21783a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 21793a2d0424SChris Cain */ 21803a2d0424SChris Cain inline std::string 2181*ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 21823a2d0424SChris Cain const std::string& modeString) 21833a2d0424SChris Cain { 21843a2d0424SChris Cain std::string mode; 21853a2d0424SChris Cain 21863a2d0424SChris Cain if (modeString == "Static") 21873a2d0424SChris Cain { 21883a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 21893a2d0424SChris Cain } 21903a2d0424SChris Cain else if (modeString == "MaximumPerformance") 21913a2d0424SChris Cain { 21920fda0f12SGeorge Liu mode = 21930fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 21943a2d0424SChris Cain } 21953a2d0424SChris Cain else if (modeString == "PowerSaving") 21963a2d0424SChris Cain { 21973a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 21983a2d0424SChris Cain } 21993a2d0424SChris Cain else 22003a2d0424SChris Cain { 2201*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, modeString, 2202*ac106bf6SEd Tanous "PowerMode"); 22033a2d0424SChris Cain } 22043a2d0424SChris Cain return mode; 22053a2d0424SChris Cain } 22063a2d0424SChris Cain 22073a2d0424SChris Cain /** 22083a2d0424SChris Cain * @brief Sets system power mode. 22093a2d0424SChris Cain * 2210*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22113a2d0424SChris Cain * @param[in] pmode System power mode from request. 22123a2d0424SChris Cain * 22133a2d0424SChris Cain * @return None. 22143a2d0424SChris Cain */ 2215*ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22163a2d0424SChris Cain const std::string& pmode) 22173a2d0424SChris Cain { 22183a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 22193a2d0424SChris Cain 2220*ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 22213a2d0424SChris Cain if (powerMode.empty()) 22223a2d0424SChris Cain { 22233a2d0424SChris Cain return; 22243a2d0424SChris Cain } 22253a2d0424SChris Cain 22263a2d0424SChris Cain // Get Power Mode object path: 2227e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2228e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2229e99073f5SGeorge Liu dbus::utility::getSubTree( 2230e99073f5SGeorge Liu "/", 0, interfaces, 2231*ac106bf6SEd Tanous [asyncResp, 2232e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2233b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22343a2d0424SChris Cain if (ec) 22353a2d0424SChris Cain { 2236002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2237002d39b4SEd Tanous << ec; 22383a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2239*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22403a2d0424SChris Cain return; 22413a2d0424SChris Cain } 22423a2d0424SChris Cain if (subtree.empty()) 22433a2d0424SChris Cain { 22443a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2245*ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 22463a2d0424SChris Cain "PowerMode"); 22473a2d0424SChris Cain return; 22483a2d0424SChris Cain } 22493a2d0424SChris Cain if (subtree.size() > 1) 22503a2d0424SChris Cain { 22513a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22523a2d0424SChris Cain // error 22533a2d0424SChris Cain BMCWEB_LOG_DEBUG 22543a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 22553a2d0424SChris Cain << subtree.size(); 2256*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22573a2d0424SChris Cain return; 22583a2d0424SChris Cain } 22593a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22603a2d0424SChris Cain { 22613a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 2262*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22633a2d0424SChris Cain return; 22643a2d0424SChris Cain } 22653a2d0424SChris Cain const std::string& path = subtree[0].first; 22663a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22673a2d0424SChris Cain if (service.empty()) 22683a2d0424SChris Cain { 22693a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 2270*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22713a2d0424SChris Cain return; 22723a2d0424SChris Cain } 22733a2d0424SChris Cain 22743a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 22753a2d0424SChris Cain << path; 22763a2d0424SChris Cain 22773a2d0424SChris Cain // Set the Power Mode property 22783a2d0424SChris Cain crow::connections::systemBus->async_method_call( 2279*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 22808a592810SEd Tanous if (ec2) 22813a2d0424SChris Cain { 2282*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22833a2d0424SChris Cain return; 22843a2d0424SChris Cain } 22853a2d0424SChris Cain }, 22863a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 22873a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2288168e20c1SEd Tanous dbus::utility::DbusVariantType(powerMode)); 2289e99073f5SGeorge Liu }); 22903a2d0424SChris Cain } 22913a2d0424SChris Cain 22923a2d0424SChris Cain /** 229351709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 229451709ffdSYong Li * 229551709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 229651709ffdSYong Li * 229751709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 229851709ffdSYong Li * translation cannot be done, returns an empty string. 229951709ffdSYong Li */ 230023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 230151709ffdSYong Li { 230251709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 230351709ffdSYong Li { 230451709ffdSYong Li return "None"; 230551709ffdSYong Li } 23063174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 230751709ffdSYong Li { 230851709ffdSYong Li return "ResetSystem"; 230951709ffdSYong Li } 23103174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 231151709ffdSYong Li { 231251709ffdSYong Li return "PowerDown"; 231351709ffdSYong Li } 23143174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 231551709ffdSYong Li { 231651709ffdSYong Li return "PowerCycle"; 231751709ffdSYong Li } 231851709ffdSYong Li 231951709ffdSYong Li return ""; 232051709ffdSYong Li } 232151709ffdSYong Li 232251709ffdSYong Li /** 2323c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2324c45f0082SYong Li * 2325c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2326c45f0082SYong Li * 2327c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2328c45f0082SYong Li *If translation cannot be done, returns an empty string. 2329c45f0082SYong Li */ 2330c45f0082SYong Li 233123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2332c45f0082SYong Li { 2333c45f0082SYong Li if (rfAction == "None") 2334c45f0082SYong Li { 2335c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2336c45f0082SYong Li } 23373174e4dfSEd Tanous if (rfAction == "PowerCycle") 2338c45f0082SYong Li { 2339c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2340c45f0082SYong Li } 23413174e4dfSEd Tanous if (rfAction == "PowerDown") 2342c45f0082SYong Li { 2343c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2344c45f0082SYong Li } 23453174e4dfSEd Tanous if (rfAction == "ResetSystem") 2346c45f0082SYong Li { 2347c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2348c45f0082SYong Li } 2349c45f0082SYong Li 2350c45f0082SYong Li return ""; 2351c45f0082SYong Li } 2352c45f0082SYong Li 2353c45f0082SYong Li /** 235451709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 235551709ffdSYong Li * 2356*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 235751709ffdSYong Li * 235851709ffdSYong Li * @return None. 235951709ffdSYong Li */ 23608d1b46d7Szhanghch05 inline void 2361*ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 236251709ffdSYong Li { 236351709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 2364bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2365bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2366bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2367bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2368*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2369b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 237051709ffdSYong Li if (ec) 237151709ffdSYong Li { 237251709ffdSYong Li // watchdog service is stopped 237351709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 237451709ffdSYong Li return; 237551709ffdSYong Li } 237651709ffdSYong Li 237751709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 237851709ffdSYong Li 237951709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2380*ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 238151709ffdSYong Li 238251709ffdSYong Li // watchdog service is running/enabled 238351709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 238451709ffdSYong Li 2385bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2386bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 238751709ffdSYong Li 2388bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2389bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2390bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2391bc1d29deSKrzysztof Grobelny 2392bc1d29deSKrzysztof Grobelny if (!success) 239351709ffdSYong Li { 2394*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2395601af5edSChicago Duan return; 239651709ffdSYong Li } 239751709ffdSYong Li 2398bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 239951709ffdSYong Li { 2400bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 240151709ffdSYong Li } 240251709ffdSYong Li 2403bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2404bc1d29deSKrzysztof Grobelny { 2405bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 240651709ffdSYong Li if (action.empty()) 240751709ffdSYong Li { 2408*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2409601af5edSChicago Duan return; 241051709ffdSYong Li } 241151709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 241251709ffdSYong Li } 2413bc1d29deSKrzysztof Grobelny }); 241451709ffdSYong Li } 241551709ffdSYong Li 241651709ffdSYong Li /** 2417c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2418c45f0082SYong Li * 2419*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2420c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2421c45f0082SYong Li * RF request. 2422c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2423c45f0082SYong Li * 2424c45f0082SYong Li * @return None. 2425c45f0082SYong Li */ 2426*ac106bf6SEd Tanous inline void 2427*ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2428c45f0082SYong Li const std::optional<bool> wdtEnable, 2429c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2430c45f0082SYong Li { 2431c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2432c45f0082SYong Li 2433c45f0082SYong Li if (wdtTimeOutAction) 2434c45f0082SYong Li { 2435c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2436c45f0082SYong Li // check if TimeOut Action is Valid 2437c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2438c45f0082SYong Li { 2439c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2440c45f0082SYong Li << *wdtTimeOutAction; 2441*ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2442c45f0082SYong Li "TimeoutAction"); 2443c45f0082SYong Li return; 2444c45f0082SYong Li } 2445c45f0082SYong Li 2446c45f0082SYong Li crow::connections::systemBus->async_method_call( 2447*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2448c45f0082SYong Li if (ec) 2449c45f0082SYong Li { 2450c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2451*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2452c45f0082SYong Li return; 2453c45f0082SYong Li } 2454c45f0082SYong Li }, 2455c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2456c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2457c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2458c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2459168e20c1SEd Tanous dbus::utility::DbusVariantType(wdtTimeOutActStr)); 2460c45f0082SYong Li } 2461c45f0082SYong Li 2462c45f0082SYong Li if (wdtEnable) 2463c45f0082SYong Li { 2464c45f0082SYong Li crow::connections::systemBus->async_method_call( 2465*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2466c45f0082SYong Li if (ec) 2467c45f0082SYong Li { 2468c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2469*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2470c45f0082SYong Li return; 2471c45f0082SYong Li } 2472c45f0082SYong Li }, 2473c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2474c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2475c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2476c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2477168e20c1SEd Tanous dbus::utility::DbusVariantType(*wdtEnable)); 2478c45f0082SYong Li } 2479c45f0082SYong Li } 2480c45f0082SYong Li 248137bbf98cSChris Cain /** 248237bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 248337bbf98cSChris Cain * 2484*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 248537bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 248637bbf98cSChris Cain * 248737bbf98cSChris Cain * @return true if successful 248837bbf98cSChris Cain */ 24891e5b7c88SJiaqing Zhao inline bool 2490*ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 24911e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 249237bbf98cSChris Cain { 2493bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2494bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2495bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2496bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2497bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2498bc1d29deSKrzysztof Grobelny 2499bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2500bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 25012661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 25022661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 25032661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2504bc1d29deSKrzysztof Grobelny 2505bc1d29deSKrzysztof Grobelny if (!success) 250637bbf98cSChris Cain { 250737bbf98cSChris Cain return false; 250837bbf98cSChris Cain } 2509bc1d29deSKrzysztof Grobelny 2510bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 251137bbf98cSChris Cain { 2512*ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 251337bbf98cSChris Cain } 2514bc1d29deSKrzysztof Grobelny 2515bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 251637bbf98cSChris Cain { 2517*ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2518bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 251937bbf98cSChris Cain } 2520bc1d29deSKrzysztof Grobelny 2521bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2522bc1d29deSKrzysztof Grobelny { 2523bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2524*ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 252537bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 252637bbf98cSChris Cain .count(); 252737bbf98cSChris Cain } 2528bc1d29deSKrzysztof Grobelny 2529bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 253037bbf98cSChris Cain { 2531*ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2532bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 253337bbf98cSChris Cain } 2534bc1d29deSKrzysztof Grobelny 2535bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 253637bbf98cSChris Cain { 2537bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2538*ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 253937bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 254037bbf98cSChris Cain .count(); 254137bbf98cSChris Cain } 254237bbf98cSChris Cain 254337bbf98cSChris Cain return true; 254437bbf98cSChris Cain } 254537bbf98cSChris Cain 254637bbf98cSChris Cain /** 254737bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 254837bbf98cSChris Cain * 2549*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 255037bbf98cSChris Cain * 255137bbf98cSChris Cain * @return None. 255237bbf98cSChris Cain */ 2553*ac106bf6SEd Tanous inline void 2554*ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 255537bbf98cSChris Cain { 255637bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 255737bbf98cSChris Cain 255837bbf98cSChris Cain // Get IdlePowerSaver object path: 2559e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2560e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2561e99073f5SGeorge Liu dbus::utility::getSubTree( 2562e99073f5SGeorge Liu "/", 0, interfaces, 2563*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2564b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 256537bbf98cSChris Cain if (ec) 256637bbf98cSChris Cain { 256737bbf98cSChris Cain BMCWEB_LOG_DEBUG 256837bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 256937bbf98cSChris Cain << ec; 2570*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 257137bbf98cSChris Cain return; 257237bbf98cSChris Cain } 257337bbf98cSChris Cain if (subtree.empty()) 257437bbf98cSChris Cain { 257537bbf98cSChris Cain // This is an optional interface so just return 257637bbf98cSChris Cain // if there is no instance found 257737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 257837bbf98cSChris Cain return; 257937bbf98cSChris Cain } 258037bbf98cSChris Cain if (subtree.size() > 1) 258137bbf98cSChris Cain { 258237bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 258337bbf98cSChris Cain // is an error 258437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 258537bbf98cSChris Cain "Power.IdlePowerSaver objects: " 258637bbf98cSChris Cain << subtree.size(); 2587*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 258837bbf98cSChris Cain return; 258937bbf98cSChris Cain } 259037bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 259137bbf98cSChris Cain { 259237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 2593*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 259437bbf98cSChris Cain return; 259537bbf98cSChris Cain } 259637bbf98cSChris Cain const std::string& path = subtree[0].first; 259737bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 259837bbf98cSChris Cain if (service.empty()) 259937bbf98cSChris Cain { 2600002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 2601*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 260237bbf98cSChris Cain return; 260337bbf98cSChris Cain } 260437bbf98cSChris Cain 260537bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2606bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2607bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2608bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2609*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 26101e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 26118a592810SEd Tanous if (ec2) 261237bbf98cSChris Cain { 261337bbf98cSChris Cain BMCWEB_LOG_ERROR 26148a592810SEd Tanous << "DBUS response error on IdlePowerSaver GetAll: " << ec2; 2615*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 261637bbf98cSChris Cain return; 261737bbf98cSChris Cain } 261837bbf98cSChris Cain 2619*ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 262037bbf98cSChris Cain { 2621*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 262237bbf98cSChris Cain return; 262337bbf98cSChris Cain } 2624bc1d29deSKrzysztof Grobelny }); 2625e99073f5SGeorge Liu }); 262637bbf98cSChris Cain 262737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 262837bbf98cSChris Cain } 262937bbf98cSChris Cain 263037bbf98cSChris Cain /** 263137bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 263237bbf98cSChris Cain * 2633*ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 263437bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 263537bbf98cSChris Cain * RF request. 263637bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 263737bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 263837bbf98cSChris Cain * before entering idle state. 263937bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 264037bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 264137bbf98cSChris Cain * before exiting idle state 264237bbf98cSChris Cain * 264337bbf98cSChris Cain * @return None. 264437bbf98cSChris Cain */ 2645*ac106bf6SEd Tanous inline void 2646*ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 264737bbf98cSChris Cain const std::optional<bool> ipsEnable, 264837bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 264937bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 265037bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 265137bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 265237bbf98cSChris Cain { 265337bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 265437bbf98cSChris Cain 265537bbf98cSChris Cain // Get IdlePowerSaver object path: 2656e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2657e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2658e99073f5SGeorge Liu dbus::utility::getSubTree( 2659e99073f5SGeorge Liu "/", 0, interfaces, 2660*ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2661e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2662b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 266337bbf98cSChris Cain if (ec) 266437bbf98cSChris Cain { 266537bbf98cSChris Cain BMCWEB_LOG_DEBUG 266637bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 266737bbf98cSChris Cain << ec; 2668*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 266937bbf98cSChris Cain return; 267037bbf98cSChris Cain } 267137bbf98cSChris Cain if (subtree.empty()) 267237bbf98cSChris Cain { 267337bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2674*ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 267537bbf98cSChris Cain "IdlePowerSaver"); 267637bbf98cSChris Cain return; 267737bbf98cSChris Cain } 267837bbf98cSChris Cain if (subtree.size() > 1) 267937bbf98cSChris Cain { 268037bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 268137bbf98cSChris Cain // is an error 26820fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 26830fda0f12SGeorge Liu << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: " 268437bbf98cSChris Cain << subtree.size(); 2685*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268637bbf98cSChris Cain return; 268737bbf98cSChris Cain } 268837bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 268937bbf98cSChris Cain { 269037bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 2691*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269237bbf98cSChris Cain return; 269337bbf98cSChris Cain } 269437bbf98cSChris Cain const std::string& path = subtree[0].first; 269537bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 269637bbf98cSChris Cain if (service.empty()) 269737bbf98cSChris Cain { 2698002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 2699*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270037bbf98cSChris Cain return; 270137bbf98cSChris Cain } 270237bbf98cSChris Cain 270337bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 270437bbf98cSChris Cain // need to be updated 270537bbf98cSChris Cain 270637bbf98cSChris Cain if (ipsEnable) 270737bbf98cSChris Cain { 270837bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2709*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27108a592810SEd Tanous if (ec2) 271137bbf98cSChris Cain { 27128a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2713*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271437bbf98cSChris Cain return; 271537bbf98cSChris Cain } 271637bbf98cSChris Cain }, 271737bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 2718002d39b4SEd Tanous "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 2719002d39b4SEd Tanous dbus::utility::DbusVariantType(*ipsEnable)); 272037bbf98cSChris Cain } 272137bbf98cSChris Cain if (ipsEnterUtil) 272237bbf98cSChris Cain { 272337bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2724*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27258a592810SEd Tanous if (ec2) 272637bbf98cSChris Cain { 27278a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2728*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272937bbf98cSChris Cain return; 273037bbf98cSChris Cain } 273137bbf98cSChris Cain }, 273237bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 273337bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 273437bbf98cSChris Cain "EnterUtilizationPercent", 2735168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsEnterUtil)); 273637bbf98cSChris Cain } 273737bbf98cSChris Cain if (ipsEnterTime) 273837bbf98cSChris Cain { 273937bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 274037bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 274137bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2742*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27438a592810SEd Tanous if (ec2) 274437bbf98cSChris Cain { 27458a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2746*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 274737bbf98cSChris Cain return; 274837bbf98cSChris Cain } 274937bbf98cSChris Cain }, 275037bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 275137bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2752168e20c1SEd Tanous "EnterDwellTime", 2753168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 275437bbf98cSChris Cain } 275537bbf98cSChris Cain if (ipsExitUtil) 275637bbf98cSChris Cain { 275737bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2758*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27598a592810SEd Tanous if (ec2) 276037bbf98cSChris Cain { 27618a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2762*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 276337bbf98cSChris Cain return; 276437bbf98cSChris Cain } 276537bbf98cSChris Cain }, 276637bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 276737bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 276837bbf98cSChris Cain "ExitUtilizationPercent", 2769168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsExitUtil)); 277037bbf98cSChris Cain } 277137bbf98cSChris Cain if (ipsExitTime) 277237bbf98cSChris Cain { 277337bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 277437bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 277537bbf98cSChris Cain crow::connections::systemBus->async_method_call( 2776*ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27778a592810SEd Tanous if (ec2) 277837bbf98cSChris Cain { 27798a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2780*ac106bf6SEd Tanous messages::internalError(asyncResp->res); 278137bbf98cSChris Cain return; 278237bbf98cSChris Cain } 278337bbf98cSChris Cain }, 278437bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 278537bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2786168e20c1SEd Tanous "ExitDwellTime", 2787168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 278837bbf98cSChris Cain } 2789e99073f5SGeorge Liu }); 279037bbf98cSChris Cain 279137bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 279237bbf98cSChris Cain } 279337bbf98cSChris Cain 2794dd60b9edSEd Tanous inline void handleComputerSystemHead( 2795dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2796dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2797dd60b9edSEd Tanous { 2798dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2799dd60b9edSEd Tanous { 2800dd60b9edSEd Tanous return; 2801dd60b9edSEd Tanous } 2802dd60b9edSEd Tanous asyncResp->res.addHeader( 2803dd60b9edSEd Tanous boost::beast::http::field::link, 2804dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2805dd60b9edSEd Tanous } 2806dd60b9edSEd Tanous 2807c45f0082SYong Li /** 2808c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 2809c5b2abe0SLewanczyk, Dawid * Schema 2810c5b2abe0SLewanczyk, Dawid */ 28117e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app) 28121abe55efSEd Tanous { 28137e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2814dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 2815dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 2816dd60b9edSEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 2817dd60b9edSEd Tanous 2818dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2819ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 28207e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 2821f4c99e70SEd Tanous [&app](const crow::Request& req, 28227e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 28233ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2824f4c99e70SEd Tanous { 2825f4c99e70SEd Tanous return; 2826f4c99e70SEd Tanous } 2827dd60b9edSEd Tanous 2828dd60b9edSEd Tanous asyncResp->res.addHeader( 2829dd60b9edSEd Tanous boost::beast::http::field::link, 2830dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 28318d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28320f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28338d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28348d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2835462023adSSunitha Harish 28361e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2837002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 28381e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2839002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 28405e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 28411e1e598dSJonathan Doman const std::string& /*hostName*/) { 2842002d39b4SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 28432c70f800SEd Tanous ifaceArray = nlohmann::json::array(); 2844002d39b4SEd Tanous auto& count = asyncResp->res.jsonValue["Members@odata.count"]; 28451476687dSEd Tanous 28461476687dSEd Tanous nlohmann::json::object_t system; 28471476687dSEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 2848b2ba3072SPatrick Williams ifaceArray.emplace_back(std::move(system)); 284994bda602STim Lee count = ifaceArray.size(); 28508a592810SEd Tanous if (!ec2) 2851462023adSSunitha Harish { 2852462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 28531476687dSEd Tanous nlohmann::json::object_t hypervisor; 2854002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 2855b2ba3072SPatrick Williams ifaceArray.emplace_back(std::move(hypervisor)); 28562c70f800SEd Tanous count = ifaceArray.size(); 2857cb13a392SEd Tanous } 28581e1e598dSJonathan Doman }); 28597e860f15SJohn Edward Broadbent }); 2860c5b2abe0SLewanczyk, Dawid } 28617e860f15SJohn Edward Broadbent 28627e860f15SJohn Edward Broadbent /** 28637e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28647e860f15SJohn Edward Broadbent */ 28654f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28667e860f15SJohn Edward Broadbent { 286789492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 286889492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 286989492a15SPatrick Williams constexpr const char* interfaceName = 28707e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 287189492a15SPatrick Williams constexpr const char* method = "NMI"; 28727e860f15SJohn Edward Broadbent 28737e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28745e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28757e860f15SJohn Edward Broadbent if (ec) 28767e860f15SJohn Edward Broadbent { 28777e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 28787e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28797e860f15SJohn Edward Broadbent return; 28807e860f15SJohn Edward Broadbent } 28817e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28827e860f15SJohn Edward Broadbent }, 28837e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28847e860f15SJohn Edward Broadbent } 2885c5b2abe0SLewanczyk, Dawid 2886c5b2abe0SLewanczyk, Dawid /** 2887fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 2888fc903b3dSAndrew Geissler */ 2889fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 2890fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 2891fc903b3dSAndrew Geissler std::string_view resetType, 2892fc903b3dSAndrew Geissler crow::Response& res) 2893fc903b3dSAndrew Geissler { 2894fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 2895fc903b3dSAndrew Geissler { 2896fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 2897fc903b3dSAndrew Geissler return; 2898fc903b3dSAndrew Geissler } 2899fc903b3dSAndrew Geissler 2900fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 2901fc903b3dSAndrew Geissler { 2902fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "D-Bus response error: " << ec; 2903fc903b3dSAndrew Geissler messages::internalError(res); 2904fc903b3dSAndrew Geissler return; 2905fc903b3dSAndrew Geissler } 2906fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 2907fc903b3dSAndrew Geissler 2908fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 2909fc903b3dSAndrew Geissler // user to retry in a bit 2910fc903b3dSAndrew Geissler if ((errorMessage == 2911fc903b3dSAndrew Geissler std::string_view( 2912fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 2913fc903b3dSAndrew Geissler (errorMessage == 2914fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 2915fc903b3dSAndrew Geissler { 2916fc903b3dSAndrew Geissler BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now"; 2917fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 2918fc903b3dSAndrew Geissler return; 2919fc903b3dSAndrew Geissler } 2920fc903b3dSAndrew Geissler 2921fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec 2922fc903b3dSAndrew Geissler << " sdbusplus:" << errorMessage; 2923fc903b3dSAndrew Geissler messages::internalError(res); 2924fc903b3dSAndrew Geissler } 2925fc903b3dSAndrew Geissler 2926fc903b3dSAndrew Geissler /** 2927cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 2928cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 2929cc340dd9SEd Tanous */ 29307e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app) 2931cc340dd9SEd Tanous { 2932cc340dd9SEd Tanous /** 2933cc340dd9SEd Tanous * Function handles POST method request. 2934cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 2935cc340dd9SEd Tanous */ 29367e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 29377e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/") 2938ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 2939002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 2940002d39b4SEd Tanous [&app](const crow::Request& req, 29417e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 29423ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 294345ca1b86SEd Tanous { 294445ca1b86SEd Tanous return; 294545ca1b86SEd Tanous } 29469712f8acSEd Tanous std::string resetType; 294715ed6780SWilly Tu if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", 29487e860f15SJohn Edward Broadbent resetType)) 2949cc340dd9SEd Tanous { 2950cc340dd9SEd Tanous return; 2951cc340dd9SEd Tanous } 2952cc340dd9SEd Tanous 2953d22c8396SJason M. Bills // Get the command and host vs. chassis 2954cc340dd9SEd Tanous std::string command; 2955543f4400SEd Tanous bool hostCommand = true; 2956d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2957cc340dd9SEd Tanous { 2958cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2959d22c8396SJason M. Bills hostCommand = true; 2960d22c8396SJason M. Bills } 2961d22c8396SJason M. Bills else if (resetType == "ForceOff") 2962d22c8396SJason M. Bills { 2963d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2964d22c8396SJason M. Bills hostCommand = false; 2965d22c8396SJason M. Bills } 2966d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2967d22c8396SJason M. Bills { 296886a0851aSJason M. Bills command = 296986a0851aSJason M. Bills "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 297086a0851aSJason M. Bills hostCommand = true; 2971cc340dd9SEd Tanous } 29729712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2973cc340dd9SEd Tanous { 2974cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2975d22c8396SJason M. Bills hostCommand = true; 2976cc340dd9SEd Tanous } 29779712f8acSEd Tanous else if (resetType == "GracefulRestart") 2978cc340dd9SEd Tanous { 29790fda0f12SGeorge Liu command = 29800fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2981d22c8396SJason M. Bills hostCommand = true; 2982d22c8396SJason M. Bills } 2983d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2984d22c8396SJason M. Bills { 298586a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 298686a0851aSJason M. Bills hostCommand = true; 2987cc340dd9SEd Tanous } 2988bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2989bfd5b826SLakshminarayana R. Kammath { 2990bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2991bfd5b826SLakshminarayana R. Kammath return; 2992bfd5b826SLakshminarayana R. Kammath } 2993cc340dd9SEd Tanous else 2994cc340dd9SEd Tanous { 29958d1b46d7Szhanghch05 messages::actionParameterUnknown(asyncResp->res, "Reset", 29968d1b46d7Szhanghch05 resetType); 2997cc340dd9SEd Tanous return; 2998cc340dd9SEd Tanous } 2999cc340dd9SEd Tanous 3000d22c8396SJason M. Bills if (hostCommand) 3001d22c8396SJason M. Bills { 3002cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 3003fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3004fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3005cc340dd9SEd Tanous if (ec) 3006cc340dd9SEd Tanous { 3007fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3008fc903b3dSAndrew Geissler asyncResp->res); 3009fc903b3dSAndrew Geissler 3010cc340dd9SEd Tanous return; 3011cc340dd9SEd Tanous } 3012f12894f8SJason M. Bills messages::success(asyncResp->res); 3013cc340dd9SEd Tanous }, 3014cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 3015cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 3016cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 30179712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 3018168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 3019cc340dd9SEd Tanous } 3020d22c8396SJason M. Bills else 3021d22c8396SJason M. Bills { 3022d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 3023fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3024fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3025d22c8396SJason M. Bills if (ec) 3026d22c8396SJason M. Bills { 3027fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3028fc903b3dSAndrew Geissler asyncResp->res); 3029d22c8396SJason M. Bills return; 3030d22c8396SJason M. Bills } 3031d22c8396SJason M. Bills messages::success(asyncResp->res); 3032d22c8396SJason M. Bills }, 3033d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 3034d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 3035d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 3036002d39b4SEd Tanous "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 3037168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 3038d22c8396SJason M. Bills } 30397e860f15SJohn Edward Broadbent }); 3040d22c8396SJason M. Bills } 3041cc340dd9SEd Tanous 304238c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead( 3043dd60b9edSEd Tanous App& app, const crow::Request& req, 3044dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3045dd60b9edSEd Tanous { 3046dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3047dd60b9edSEd Tanous { 3048dd60b9edSEd Tanous return; 3049dd60b9edSEd Tanous } 3050dd60b9edSEd Tanous 3051dd60b9edSEd Tanous asyncResp->res.addHeader( 3052dd60b9edSEd Tanous boost::beast::http::field::link, 3053dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3054dd60b9edSEd Tanous } 3055dd60b9edSEd Tanous 30565c3e9272SAbhishek Patel inline void afterPortRequest( 30575c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 30585c3e9272SAbhishek Patel const boost::system::error_code& ec, 30595c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 30605c3e9272SAbhishek Patel { 30615c3e9272SAbhishek Patel if (ec) 30625c3e9272SAbhishek Patel { 30635c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 30645c3e9272SAbhishek Patel return; 30655c3e9272SAbhishek Patel } 30665c3e9272SAbhishek Patel for (const auto& data : socketData) 30675c3e9272SAbhishek Patel { 30685c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 30695c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 30705c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 30715c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 30725c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 30735c3e9272SAbhishek Patel // need to retrieve port number for 30745c3e9272SAbhishek Patel // obmc-console-ssh service 30755c3e9272SAbhishek Patel if (protocolName == "SSH") 30765c3e9272SAbhishek Patel { 30775c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 307881c4e330SEd Tanous const boost::system::error_code& ec1, 30795c3e9272SAbhishek Patel int portNumber) { 30805c3e9272SAbhishek Patel if (ec1) 30815c3e9272SAbhishek Patel { 30825c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 30835c3e9272SAbhishek Patel return; 30845c3e9272SAbhishek Patel } 30855c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 30865c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 30875c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 30885c3e9272SAbhishek Patel }); 30895c3e9272SAbhishek Patel } 30905c3e9272SAbhishek Patel } 30915c3e9272SAbhishek Patel } 3092cc340dd9SEd Tanous /** 30936617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 3094c5b2abe0SLewanczyk, Dawid */ 30957e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app) 30961abe55efSEd Tanous { 3097dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 3098dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystem) 3099dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 3100dd60b9edSEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3101c5b2abe0SLewanczyk, Dawid /** 3102c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 3103c5b2abe0SLewanczyk, Dawid */ 310422d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3105ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3106002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 3107002d39b4SEd Tanous [&app](const crow::Request& req, 310822d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 310922d268cbSEd Tanous const std::string& systemName) { 31103ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 311145ca1b86SEd Tanous { 311245ca1b86SEd Tanous return; 311345ca1b86SEd Tanous } 3114746b56f3SAsmitha Karunanithi 3115746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3116746b56f3SAsmitha Karunanithi { 3117746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3118746b56f3SAsmitha Karunanithi return; 3119746b56f3SAsmitha Karunanithi } 3120746b56f3SAsmitha Karunanithi 312122d268cbSEd Tanous if (systemName != "system") 312222d268cbSEd Tanous { 312322d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 312422d268cbSEd Tanous systemName); 312522d268cbSEd Tanous return; 312622d268cbSEd Tanous } 3127dd60b9edSEd Tanous asyncResp->res.addHeader( 3128dd60b9edSEd Tanous boost::beast::http::field::link, 3129dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 31308d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 313137bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 31328d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 31338d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 31348d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 31358d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 31368d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 31375fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 31385fd0aafbSNinad Palsule { 31398d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 31408d1b46d7Szhanghch05 "Disabled"; 31418d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 31428d1b46d7Szhanghch05 "Disabled"; 31435fd0aafbSNinad Palsule } 3144cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3145cf0e004cSNinad Palsule uint64_t(0); 3146002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 314704a258f4SEd Tanous 31481476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 31491476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 31501476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 31511476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 31521476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 31531476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 31543179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 31553179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3156029573d4SEd Tanous 3157002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 31581476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 31591476687dSEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] 31601476687dSEd Tanous ["@Redfish.ActionInfo"] = 31611476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3162c5b2abe0SLewanczyk, Dawid 31631476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 31641476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 31651476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 31661476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3167c4bf6374SJason M. Bills 31681476687dSEd Tanous nlohmann::json::array_t managedBy; 31691476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 31701476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3171002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 31721476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 31731476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 31740e8ac5e7SGunnar Mills 31750e8ac5e7SGunnar Mills // Fill in SerialConsole info 3176002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3177002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = 3178002d39b4SEd Tanous true; 31791476687dSEd Tanous 31801476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = 31811476687dSEd Tanous true; 31821476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 31831476687dSEd Tanous asyncResp->res 31841476687dSEd Tanous .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 31851476687dSEd Tanous "Press ~. to exit console"; 31865c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 31875c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 31880e8ac5e7SGunnar Mills 31890e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 31900e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3191002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3192002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 3193002d39b4SEd Tanous 4; 3194613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3195613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 31961476687dSEd Tanous 31970e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 319813451e39SWilly Tu 319913451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 320013451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 320113451e39SWilly Tu { 32027a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3203b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 32042ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3205e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3206e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3207b49ac873SJames Feist 32087a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 32097a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 32107a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3211914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3212b49ac873SJames Feist if (ec) 3213b49ac873SJames Feist { 3214b49ac873SJames Feist // no inventory 3215b49ac873SJames Feist return; 3216b49ac873SJames Feist } 3217b49ac873SJames Feist 3218914e2d5dSEd Tanous health->inventory = resp; 32197a1dbc48SGeorge Liu }); 3220b49ac873SJames Feist health->populate(); 322113451e39SWilly Tu } 3222b49ac873SJames Feist 3223002d39b4SEd Tanous getMainChassisId(asyncResp, 3224002d39b4SEd Tanous [](const std::string& chassisId, 32258d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3226b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3227b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3228ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3229ef4c65b7SEd Tanous chassisId); 3230002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3231c5d03ff4SJennifer Lee }); 3232a3002228SAppaRao Puli 32339f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 32349f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3235a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 32365bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 32376c34de48SEd Tanous getHostState(asyncResp); 3238491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3239978b8803SAndrew Geissler getBootProgress(asyncResp); 3240b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3241472bd202SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices"); 324251709ffdSYong Li getHostWatchdogTimer(asyncResp); 3243c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 3244797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3245c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3246a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3247a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3248a6349918SAppaRao Puli #endif 32491981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 32503a2d0424SChris Cain getPowerMode(asyncResp); 325137bbf98cSChris Cain getIdlePowerSaver(asyncResp); 32527e860f15SJohn Edward Broadbent }); 3253550a6bf8SJiaqing Zhao 325422d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3255ed398213SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 32567e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 325745ca1b86SEd Tanous [&app](const crow::Request& req, 325822d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 325922d268cbSEd Tanous const std::string& systemName) { 32603ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 326145ca1b86SEd Tanous { 326245ca1b86SEd Tanous return; 326345ca1b86SEd Tanous } 326422d268cbSEd Tanous if (systemName != "system") 326522d268cbSEd Tanous { 326622d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 326722d268cbSEd Tanous systemName); 326822d268cbSEd Tanous return; 326922d268cbSEd Tanous } 327022d268cbSEd Tanous 3271dd60b9edSEd Tanous asyncResp->res.addHeader( 3272dd60b9edSEd Tanous boost::beast::http::field::link, 3273dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3274dd60b9edSEd Tanous 32759f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3276cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 327798e386ecSGunnar Mills std::optional<std::string> assetTag; 3278c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 32793a2d0424SChris Cain std::optional<std::string> powerMode; 3280550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3281550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3282550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3283550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3284550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3285550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3286797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3287550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 3288550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3289550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3290550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3291550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3292550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3293550a6bf8SJiaqing Zhao 3294550a6bf8SJiaqing Zhao // clang-format off 329515ed6780SWilly Tu if (!json_util::readJsonPatch( 3296550a6bf8SJiaqing Zhao req, asyncResp->res, 3297550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 32987e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3299550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3300550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3301550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3302550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3303550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3304550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3305550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3306550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3307550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3308797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3309550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 3310550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3311550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3312550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3313550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3314550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 33156617338dSEd Tanous { 33166617338dSEd Tanous return; 33176617338dSEd Tanous } 3318550a6bf8SJiaqing Zhao // clang-format on 3319491d8ee7SSantosh Puranik 33208d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3321c45f0082SYong Li 332298e386ecSGunnar Mills if (assetTag) 332398e386ecSGunnar Mills { 332498e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 332598e386ecSGunnar Mills } 332698e386ecSGunnar Mills 3327550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3328c45f0082SYong Li { 3329f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3330c45f0082SYong Li } 3331c45f0082SYong Li 3332cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 333369f35306SGunnar Mills { 3334002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3335491d8ee7SSantosh Puranik } 3336550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 333769f35306SGunnar Mills { 3338550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 333969f35306SGunnar Mills } 3340ac7e1e0bSAli Ahmed 3341797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3342797d5daeSCorey Hardesty { 3343797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3344797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3345797d5daeSCorey Hardesty } 3346797d5daeSCorey Hardesty 3347550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3348ac7e1e0bSAli Ahmed { 3349550a6bf8SJiaqing Zhao setTrustedModuleRequiredToBoot(asyncResp, 3350550a6bf8SJiaqing Zhao *bootTrustedModuleRequired); 335169f35306SGunnar Mills } 3352265c1602SJohnathan Mantey 33539f8bfa7cSGunnar Mills if (locationIndicatorActive) 33549f8bfa7cSGunnar Mills { 3355002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 33569f8bfa7cSGunnar Mills } 33579f8bfa7cSGunnar Mills 33587e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 33597e860f15SJohn Edward Broadbent // passed 33609712f8acSEd Tanous if (indicatorLed) 33616617338dSEd Tanous { 3362f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3363002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3364d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3365d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 33666617338dSEd Tanous } 3367c6a620f2SGeorge Liu 3368c6a620f2SGeorge Liu if (powerRestorePolicy) 3369c6a620f2SGeorge Liu { 33704e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3371c6a620f2SGeorge Liu } 33723a2d0424SChris Cain 33733a2d0424SChris Cain if (powerMode) 33743a2d0424SChris Cain { 33753a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 33763a2d0424SChris Cain } 337737bbf98cSChris Cain 3378550a6bf8SJiaqing Zhao if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || 3379550a6bf8SJiaqing Zhao ipsExitTime) 338037bbf98cSChris Cain { 3381002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3382002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 338337bbf98cSChris Cain } 33847e860f15SJohn Edward Broadbent }); 3385c5b2abe0SLewanczyk, Dawid } 33861cb1a9e6SAppaRao Puli 338738c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3388dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 3389dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3390dd60b9edSEd Tanous { 3391dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3392dd60b9edSEd Tanous { 3393dd60b9edSEd Tanous return; 3394dd60b9edSEd Tanous } 3395dd60b9edSEd Tanous asyncResp->res.addHeader( 3396dd60b9edSEd Tanous boost::beast::http::field::link, 3397dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3398dd60b9edSEd Tanous } 3399dd60b9edSEd Tanous 34001cb1a9e6SAppaRao Puli /** 34011cb1a9e6SAppaRao Puli * SystemResetActionInfo derived class for delivering Computer Systems 34021cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 34031cb1a9e6SAppaRao Puli */ 34047e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app) 34051cb1a9e6SAppaRao Puli { 3406dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/") 3407dd60b9edSEd Tanous .privileges(redfish::privileges::headActionInfo) 3408dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3409dd60b9edSEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 34101cb1a9e6SAppaRao Puli /** 34111cb1a9e6SAppaRao Puli * Functions triggers appropriate requests on DBus 34121cb1a9e6SAppaRao Puli */ 341322d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3414ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 34157e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 341645ca1b86SEd Tanous [&app](const crow::Request& req, 341722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 341822d268cbSEd Tanous const std::string& systemName) { 34193ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 342045ca1b86SEd Tanous { 342145ca1b86SEd Tanous return; 342245ca1b86SEd Tanous } 3423746b56f3SAsmitha Karunanithi 3424746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3425746b56f3SAsmitha Karunanithi { 3426746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3427746b56f3SAsmitha Karunanithi return; 3428746b56f3SAsmitha Karunanithi } 3429746b56f3SAsmitha Karunanithi 343022d268cbSEd Tanous if (systemName != "system") 343122d268cbSEd Tanous { 343222d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 343322d268cbSEd Tanous systemName); 343422d268cbSEd Tanous return; 343522d268cbSEd Tanous } 343622d268cbSEd Tanous 3437dd60b9edSEd Tanous asyncResp->res.addHeader( 3438dd60b9edSEd Tanous boost::beast::http::field::link, 3439dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34401476687dSEd Tanous 34411476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 34421476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 34431476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 34441476687dSEd Tanous "#ActionInfo.v1_1_2.ActionInfo"; 34451476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34461476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34473215e700SNan Zhou 34483215e700SNan Zhou nlohmann::json::array_t parameters; 34493215e700SNan Zhou nlohmann::json::object_t parameter; 34503215e700SNan Zhou 34513215e700SNan Zhou parameter["Name"] = "ResetType"; 34523215e700SNan Zhou parameter["Required"] = true; 34533215e700SNan Zhou parameter["DataType"] = "String"; 34543215e700SNan Zhou nlohmann::json::array_t allowableValues; 34553215e700SNan Zhou allowableValues.emplace_back("On"); 34563215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 34573215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 34583215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 34593215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 34603215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 34613215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 34623215e700SNan Zhou allowableValues.emplace_back("Nmi"); 34633215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 34643215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 34653215e700SNan Zhou 34663215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 34677e860f15SJohn Edward Broadbent }); 34681cb1a9e6SAppaRao Puli } 3469c5b2abe0SLewanczyk, Dawid } // namespace redfish 3470