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 * 57ac106bf6SEd 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 63ac106bf6SEd 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 = 72ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 739d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 749d3ae10eSAlpana Kumari { 75e05aec50SEd Tanous if (isDimmFunctional) 769d3ae10eSAlpana Kumari { 77ac106bf6SEd 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 * 87ac106bf6SEd 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 */ 92ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 93ac106bf6SEd 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 = 98ac106bf6SEd 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 { 107ac106bf6SEd 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 * 116ac106bf6SEd 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 122ac106bf6SEd 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 = 130ac106bf6SEd 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( 142ac106bf6SEd 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 { 157ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15803fbed92SAli Ahmed return; 15903fbed92SAli Ahmed } 16003fbed92SAli Ahmed 161bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16203fbed92SAli Ahmed { 163bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 164ac106bf6SEd 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 * 181ac106bf6SEd 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 */ 187ac106bf6SEd Tanous inline void 188ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 189ac106bf6SEd Tanous const std::string& service, const std::string& path) 19003fbed92SAli Ahmed { 191ac106bf6SEd 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 } 198ac106bf6SEd 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 = 210ac106bf6SEd 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 } 217ac106bf6SEd 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", 230ac106bf6SEd 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; 236ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23703fbed92SAli Ahmed return; 23803fbed92SAli Ahmed } 239ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 240bc1d29deSKrzysztof Grobelny }); 24103fbed92SAli Ahmed } 24203fbed92SAli Ahmed 24357e8c9beSAlpana Kumari /* 244cf0e004cSNinad Palsule * @brief processMemoryProperties fields 245cf0e004cSNinad Palsule * 246ac106bf6SEd 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 254ac106bf6SEd 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", 270ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 271ac106bf6SEd Tanous bool dimmState) { 272cf0e004cSNinad Palsule if (ec3) 273cf0e004cSNinad Palsule { 274cf0e004cSNinad Palsule BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 275cf0e004cSNinad Palsule return; 276cf0e004cSNinad Palsule } 277ac106bf6SEd 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 { 291ac106bf6SEd Tanous messages::internalError(asyncResp->res); 292cf0e004cSNinad Palsule return; 293cf0e004cSNinad Palsule } 294cf0e004cSNinad Palsule 295cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 296cf0e004cSNinad Palsule { 297cf0e004cSNinad Palsule nlohmann::json& totalMemory = 298ac106bf6SEd 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 { 302ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 303cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024); 304cf0e004cSNinad Palsule } 305cf0e004cSNinad Palsule else 306cf0e004cSNinad Palsule { 307ac106bf6SEd 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 { 312ac106bf6SEd 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 * 321ac106bf6SEd 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 */ 327ac106bf6SEd Tanous inline void 328ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 329ac106bf6SEd 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", 334ac106bf6SEd 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; 340ac106bf6SEd Tanous messages::internalError(asyncResp->res); 341cf0e004cSNinad Palsule return; 342cf0e004cSNinad Palsule } 343ac106bf6SEd 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 * 350ac106bf6SEd 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 356ac106bf6SEd 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, 369ac106bf6SEd 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"; 375ac106bf6SEd 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>( 399ac106bf6SEd 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>( 405ac106bf6SEd 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 423ac106bf6SEd 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 436ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4375bc2dc8eSJames Feist 4385fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4395fd0aafbSNinad Palsule { 4405bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4411abe55efSEd Tanous } 4425fd0aafbSNinad Palsule } 443002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4441abe55efSEd Tanous { 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", 451ac106bf6SEd 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; 458ac106bf6SEd 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 { 473ac106bf6SEd 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; 488ac106bf6SEd 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", 499ac106bf6SEd 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 { 527ac106bf6SEd Tanous messages::internalError(asyncResp->res); 528bc1d29deSKrzysztof Grobelny return; 529029573d4SEd Tanous } 530bc1d29deSKrzysztof Grobelny 531bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 532bc1d29deSKrzysztof Grobelny { 533ac106bf6SEd Tanous asyncResp->res.jsonValue["PartNumber"] = 534bc1d29deSKrzysztof Grobelny *partNumber; 535029573d4SEd Tanous } 536bc1d29deSKrzysztof Grobelny 537bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 538bc1d29deSKrzysztof Grobelny { 539ac106bf6SEd Tanous asyncResp->res.jsonValue["SerialNumber"] = 540bc1d29deSKrzysztof Grobelny *serialNumber; 541bc1d29deSKrzysztof Grobelny } 542bc1d29deSKrzysztof Grobelny 543bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 544bc1d29deSKrzysztof Grobelny { 545ac106bf6SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = 546bc1d29deSKrzysztof Grobelny *manufacturer; 547bc1d29deSKrzysztof Grobelny } 548bc1d29deSKrzysztof Grobelny 549bc1d29deSKrzysztof Grobelny if (model != nullptr) 550bc1d29deSKrzysztof Grobelny { 551ac106bf6SEd Tanous asyncResp->res.jsonValue["Model"] = *model; 552bc1d29deSKrzysztof Grobelny } 553bc1d29deSKrzysztof Grobelny 554bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 555bc1d29deSKrzysztof Grobelny { 556ac106bf6SEd Tanous asyncResp->res.jsonValue["SubModel"] = 557ac106bf6SEd Tanous *subModel; 558fc5afcf9Sbeccabroek } 559c1e236a6SGunnar Mills 560cb7e1e7bSAndrew Geissler // Grab the bios version 561eee0013eSWilly Tu sw_util::populateSoftwareInformation( 562ac106bf6SEd 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", 572ac106bf6SEd 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 581ac106bf6SEd 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 * 593ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 594c5b2abe0SLewanczyk, Dawid * 595c5b2abe0SLewanczyk, Dawid * @return None. 596c5b2abe0SLewanczyk, Dawid */ 597ac106bf6SEd 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", 604ac106bf6SEd 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; 616ac106bf6SEd 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 { 624ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 625ac106bf6SEd 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 { 630ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 631ac106bf6SEd 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 { 636ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 637ac106bf6SEd 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 { 643ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 644ac106bf6SEd 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 { 649ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 650ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 6511a2a1437SAndrew Geissler } 6521abe55efSEd Tanous else 6531abe55efSEd Tanous { 654ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 655ac106bf6SEd 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 */ 831ac106bf6SEd Tanous inline int 832ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 833ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 834ac106bf6SEd 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; 874ac106bf6SEd 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 * 884ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 885978b8803SAndrew Geissler * 886978b8803SAndrew Geissler * @return None. 887978b8803SAndrew Geissler */ 888ac106bf6SEd 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", 894ac106bf6SEd 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 905ac106bf6SEd 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 * 913ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 914b6d5d45cSHieu Huynh * 915b6d5d45cSHieu Huynh * @return None. 916b6d5d45cSHieu Huynh */ 917b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 918ac106bf6SEd 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", 924ac106bf6SEd 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 939ac106bf6SEd 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 * 947ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 948cd9a4666SKonstantin Aladyshev * 949cd9a4666SKonstantin Aladyshev * @return None. 950cd9a4666SKonstantin Aladyshev */ 951cd9a4666SKonstantin Aladyshev 952ac106bf6SEd Tanous inline void 953ac106bf6SEd 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", 959ac106bf6SEd 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 969ac106bf6SEd Tanous asyncResp->res 970ac106bf6SEd 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 { 977ac106bf6SEd Tanous messages::internalError(asyncResp->res); 978cd9a4666SKonstantin Aladyshev return; 979cd9a4666SKonstantin Aladyshev } 980cd9a4666SKonstantin Aladyshev 981ac106bf6SEd 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 * 988ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 989491d8ee7SSantosh Puranik * 990491d8ee7SSantosh Puranik * @return None. 991491d8ee7SSantosh Puranik */ 992c21865c4SKonstantin Aladyshev 993ac106bf6SEd Tanous inline void 994ac106bf6SEd 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", 1000ac106bf6SEd 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; 1005ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1006491d8ee7SSantosh Puranik return; 1007491d8ee7SSantosh Puranik } 1008491d8ee7SSantosh Puranik 10091e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 1010491d8ee7SSantosh Puranik 1011ac106bf6SEd 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 { 1022ac106bf6SEd 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 * 1032ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1033491d8ee7SSantosh Puranik * 1034491d8ee7SSantosh Puranik * @return None. 1035491d8ee7SSantosh Puranik */ 1036c21865c4SKonstantin Aladyshev 1037c21865c4SKonstantin Aladyshev inline void 1038ac106bf6SEd 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", 1044ac106bf6SEd 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 } 1053ac106bf6SEd 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 { 1062ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1063ac106bf6SEd Tanous rfSource; 1064491d8ee7SSantosh Puranik } 1065cd9a4666SKonstantin Aladyshev 1066cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1067cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1068ac106bf6SEd 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 * 1077ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1078491d8ee7SSantosh Puranik * 1079491d8ee7SSantosh Puranik * @return None. 1080491d8ee7SSantosh Puranik */ 1081491d8ee7SSantosh Puranik 1082ac106bf6SEd Tanous inline void processBootOverrideEnable( 1083ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1084c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1085c21865c4SKonstantin Aladyshev { 1086c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1087c21865c4SKonstantin Aladyshev { 1088ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1089ac106bf6SEd 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", 1099ac106bf6SEd 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; 1103ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1104491d8ee7SSantosh Puranik return; 1105491d8ee7SSantosh Puranik } 1106491d8ee7SSantosh Puranik 1107c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1108c21865c4SKonstantin Aladyshev { 1109ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1110ac106bf6SEd Tanous "Once"; 1111c21865c4SKonstantin Aladyshev } 1112c21865c4SKonstantin Aladyshev else 1113c21865c4SKonstantin Aladyshev { 1114ac106bf6SEd 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 * 1123ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1124c21865c4SKonstantin Aladyshev * 1125c21865c4SKonstantin Aladyshev * @return None. 1126c21865c4SKonstantin Aladyshev */ 1127c21865c4SKonstantin Aladyshev 1128c21865c4SKonstantin Aladyshev inline void 1129ac106bf6SEd 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", 1135ac106bf6SEd 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 } 1144ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1145c21865c4SKonstantin Aladyshev return; 1146c21865c4SKonstantin Aladyshev } 1147c21865c4SKonstantin Aladyshev 1148ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11491e1e598dSJonathan Doman }); 1150c21865c4SKonstantin Aladyshev } 1151c21865c4SKonstantin Aladyshev 1152c21865c4SKonstantin Aladyshev /** 1153c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1154c21865c4SKonstantin Aladyshev * 1155ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1156c21865c4SKonstantin Aladyshev * 1157c21865c4SKonstantin Aladyshev * @return None. 1158c21865c4SKonstantin Aladyshev */ 1159ac106bf6SEd Tanous inline void 1160ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1161c21865c4SKonstantin Aladyshev { 1162c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1163c21865c4SKonstantin Aladyshev 1164ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1165ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1166ac106bf6SEd 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 * 1177ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1178c0557e1aSGunnar Mills * 1179c0557e1aSGunnar Mills * @return None. 1180c0557e1aSGunnar Mills */ 1181ac106bf6SEd Tanous inline void 1182ac106bf6SEd 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", 1190ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1191ac106bf6SEd 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 1203ac106bf6SEd 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 * 1216ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1217797d5daeSCorey Hardesty * 1218797d5daeSCorey Hardesty * @return None. 1219797d5daeSCorey Hardesty */ 1220ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1221ac106bf6SEd 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", 1229ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1230ac106bf6SEd 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; 1237ac106bf6SEd 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 { 1251ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1252797d5daeSCorey Hardesty return; 1253797d5daeSCorey Hardesty } 1254797d5daeSCorey Hardesty 1255797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1256797d5daeSCorey Hardesty { 1257ac106bf6SEd Tanous asyncResp->res 1258ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1259797d5daeSCorey Hardesty *attemptsLeft; 1260797d5daeSCorey Hardesty } 1261797d5daeSCorey Hardesty 1262797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1263797d5daeSCorey Hardesty { 1264ac106bf6SEd 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 * 1273ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12746bd5a8d2SGunnar Mills * 12756bd5a8d2SGunnar Mills * @return None. 12766bd5a8d2SGunnar Mills */ 1277797d5daeSCorey Hardesty inline void 1278ac106bf6SEd 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", 1286ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1287ac106bf6SEd 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; 1293ac106bf6SEd 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 { 1301ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 13026bd5a8d2SGunnar Mills "RetryAttempts"; 13036bd5a8d2SGunnar Mills } 13046bd5a8d2SGunnar Mills else 13056bd5a8d2SGunnar Mills { 1306ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1307ac106bf6SEd Tanous "Disabled"; 13086bd5a8d2SGunnar Mills } 1309ac106bf6SEd 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. 1314ac106bf6SEd Tanous asyncResp->res 1315ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1316ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 13171e1e598dSJonathan Doman }); 13186bd5a8d2SGunnar Mills } 13196bd5a8d2SGunnar Mills 13206bd5a8d2SGunnar Mills /** 1321797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1322797d5daeSCorey Hardesty * 1323ac106bf6SEd 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 1329ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1330ac106bf6SEd 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( 1335ac106bf6SEd 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; 1340ac106bf6SEd 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 * 1353ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1354c6a620f2SGeorge Liu * 1355c6a620f2SGeorge Liu * @return None. 1356c6a620f2SGeorge Liu */ 13578d1b46d7Szhanghch05 inline void 1358ac106bf6SEd 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", 1366ac106bf6SEd 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 { 1388ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1389c6a620f2SGeorge Liu return; 1390c6a620f2SGeorge Liu } 1391c6a620f2SGeorge Liu 1392ac106bf6SEd 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 * 1400ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14011981771bSAli Ahmed * 14021981771bSAli Ahmed * @return None. 14031981771bSAli Ahmed */ 14041981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1405ac106bf6SEd 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, 1412ac106bf6SEd 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 1436ac106bf6SEd 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!"; 1445ac106bf6SEd 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", 1456ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1457ac106bf6SEd 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; 1462ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14631981771bSAli Ahmed return; 14641981771bSAli Ahmed } 14651981771bSAli Ahmed 14661e1e598dSJonathan Doman if (tpmRequired) 14671981771bSAli Ahmed { 1468ac106bf6SEd Tanous asyncResp->res 1469ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14701981771bSAli Ahmed "Required"; 14711981771bSAli Ahmed } 14721981771bSAli Ahmed else 14731981771bSAli Ahmed { 1474ac106bf6SEd Tanous asyncResp->res 1475ac106bf6SEd 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 * 1486ac106bf6SEd 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( 1492ac106bf6SEd 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, 1499ac106bf6SEd 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; 1506ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15071c05dae3SAli Ahmed return; 15081c05dae3SAli Ahmed } 150926f6976fSEd Tanous if (subtree.empty()) 15101c05dae3SAli Ahmed { 1511ac106bf6SEd 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 1523ac106bf6SEd 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!"; 1532ac106bf6SEd 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!"; 1542ac106bf6SEd 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( 1548ac106bf6SEd 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; 1554ac106bf6SEd 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 * 1568ac106bf6SEd 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 */ 1572ac106bf6SEd 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; 1598ac106bf6SEd 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( 1607ac106bf6SEd 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 { 1613ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1614cd9a4666SKonstantin Aladyshev return; 1615cd9a4666SKonstantin Aladyshev } 1616ac106bf6SEd 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 * 1631ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1632ac106bf6SEd Tanous * message. 1633c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1634c21865c4SKonstantin Aladyshev * @return Integer error code. 1635c21865c4SKonstantin Aladyshev */ 1636ac106bf6SEd 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; 1668ac106bf6SEd 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( 1677ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 16788a592810SEd Tanous if (ec2) 1679c21865c4SKonstantin Aladyshev { 16808a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1681ac106bf6SEd 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( 1703ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1704c21865c4SKonstantin Aladyshev if (ec) 1705c21865c4SKonstantin Aladyshev { 1706c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1707ac106bf6SEd 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 * 1722ac106bf6SEd 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 */ 1727ac106bf6SEd Tanous inline void 1728ac106bf6SEd 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 1742ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1743ac106bf6SEd Tanous bootModeStr) != 0) 1744491d8ee7SSantosh Puranik { 1745944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1746944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1747491d8ee7SSantosh Puranik << *bootSource; 1748ac106bf6SEd 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( 1758ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1759491d8ee7SSantosh Puranik if (ec) 1760491d8ee7SSantosh Puranik { 1761491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1762ac106bf6SEd 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( 1774ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1775491d8ee7SSantosh Puranik if (ec) 1776491d8ee7SSantosh Puranik { 1777491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1778ac106bf6SEd 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 * 1793ac106bf6SEd 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 1801ac106bf6SEd Tanous inline void 1802ac106bf6SEd 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 1809ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1810ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1811ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1812491d8ee7SSantosh Puranik } 1813491d8ee7SSantosh Puranik 1814c6a620f2SGeorge Liu /** 181598e386ecSGunnar Mills * @brief Sets AssetTag 181698e386ecSGunnar Mills * 1817ac106bf6SEd 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 */ 1822ac106bf6SEd 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, 1829ac106bf6SEd 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; 1835ac106bf6SEd 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!"; 1841ac106bf6SEd 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!"; 1849ac106bf6SEd 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!"; 1855ac106bf6SEd 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!"; 1865ac106bf6SEd Tanous messages::internalError(asyncResp->res); 186698e386ecSGunnar Mills return; 186798e386ecSGunnar Mills } 186898e386ecSGunnar Mills 186998e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 1870ac106bf6SEd 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; 1875ac106bf6SEd 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 * 1888ac106bf6SEd 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 */ 1893ac106bf6SEd Tanous inline void 1894ac106bf6SEd 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; 1914ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 191569f35306SGunnar Mills "AutomaticRetryConfig"); 191669f35306SGunnar Mills return; 191769f35306SGunnar Mills } 191869f35306SGunnar Mills 191969f35306SGunnar Mills crow::connections::systemBus->async_method_call( 1920ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 192169f35306SGunnar Mills if (ec) 192269f35306SGunnar Mills { 1923ac106bf6SEd 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 * 1937ac106bf6SEd 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 1943ac106bf6SEd 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 { 1961ac106bf6SEd 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( 1969ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1970c6a620f2SGeorge Liu if (ec) 1971c6a620f2SGeorge Liu { 1972ac106bf6SEd 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 * 1987ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 1988a6349918SAppaRao Puli * 1989a6349918SAppaRao Puli * @return None. 1990a6349918SAppaRao Puli */ 1991ac106bf6SEd 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", 1997ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1998b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1999b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2000ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2001ac106bf6SEd 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 { 2022ac106bf6SEd 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."; 2029ac106bf6SEd 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 * 2055ac106bf6SEd 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 */ 2060ac106bf6SEd Tanous inline void 2061ac106bf6SEd 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 { 2066ac106bf6SEd 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 { 2072ac106bf6SEd 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 { 2077ac106bf6SEd 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 { 2082ac106bf6SEd 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; 2088ac106bf6SEd Tanous messages::internalError(asyncResp->res); 20893a2d0424SChris Cain } 20903a2d0424SChris Cain } 20913a2d0424SChris Cain 20923a2d0424SChris Cain /** 20933a2d0424SChris Cain * @brief Retrieves system power mode 20943a2d0424SChris Cain * 2095ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 20963a2d0424SChris Cain * 20973a2d0424SChris Cain * @return None. 20983a2d0424SChris Cain */ 2099ac106bf6SEd 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, 2108ac106bf6SEd 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(); 2131ac106bf6SEd 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!"; 2137ac106bf6SEd 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!"; 2145ac106bf6SEd 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", 2152ac106bf6SEd 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; 2158ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21593a2d0424SChris Cain return; 21603a2d0424SChris Cain } 21613a2d0424SChris Cain 2162ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2163002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 21643a2d0424SChris Cain 21651e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 2166ac106bf6SEd 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 * 2175ac106bf6SEd 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 2181ac106bf6SEd 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 { 2201ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, modeString, 2202ac106bf6SEd Tanous "PowerMode"); 22033a2d0424SChris Cain } 22043a2d0424SChris Cain return mode; 22053a2d0424SChris Cain } 22063a2d0424SChris Cain 22073a2d0424SChris Cain /** 22083a2d0424SChris Cain * @brief Sets system power mode. 22093a2d0424SChris Cain * 2210ac106bf6SEd 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 */ 2215ac106bf6SEd 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 2220ac106bf6SEd 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, 2231ac106bf6SEd 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 2239ac106bf6SEd 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 2245ac106bf6SEd 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(); 2256ac106bf6SEd 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!"; 2262ac106bf6SEd 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!"; 2270ac106bf6SEd 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( 2279ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 22808a592810SEd Tanous if (ec2) 22813a2d0424SChris Cain { 2282ac106bf6SEd 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 * 2356ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 235751709ffdSYong Li * 235851709ffdSYong Li * @return None. 235951709ffdSYong Li */ 23608d1b46d7Szhanghch05 inline void 2361ac106bf6SEd 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", 2368ac106bf6SEd 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 = 2380ac106bf6SEd 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 { 2394ac106bf6SEd 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 { 2408ac106bf6SEd 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 * 2419ac106bf6SEd 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 */ 2426ac106bf6SEd Tanous inline void 2427ac106bf6SEd 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; 2441ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2442c45f0082SYong Li "TimeoutAction"); 2443c45f0082SYong Li return; 2444c45f0082SYong Li } 2445c45f0082SYong Li 2446c45f0082SYong Li crow::connections::systemBus->async_method_call( 2447ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2448c45f0082SYong Li if (ec) 2449c45f0082SYong Li { 2450c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2451ac106bf6SEd 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( 2465ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2466c45f0082SYong Li if (ec) 2467c45f0082SYong Li { 2468c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2469ac106bf6SEd 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 * 2484ac106bf6SEd 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 2490ac106bf6SEd 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 { 2512ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 251337bbf98cSChris Cain } 2514bc1d29deSKrzysztof Grobelny 2515bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 251637bbf98cSChris Cain { 2517ac106bf6SEd 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); 2524ac106bf6SEd 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 { 2531ac106bf6SEd 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); 2538ac106bf6SEd 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 * 2549ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 255037bbf98cSChris Cain * 255137bbf98cSChris Cain * @return None. 255237bbf98cSChris Cain */ 2553ac106bf6SEd Tanous inline void 2554ac106bf6SEd 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, 2563ac106bf6SEd 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; 2570ac106bf6SEd 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(); 2587ac106bf6SEd 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!"; 2593ac106bf6SEd 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!"; 2601ac106bf6SEd 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", 2609ac106bf6SEd 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; 2615ac106bf6SEd Tanous messages::internalError(asyncResp->res); 261637bbf98cSChris Cain return; 261737bbf98cSChris Cain } 261837bbf98cSChris Cain 2619ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 262037bbf98cSChris Cain { 2621ac106bf6SEd 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 * 2633ac106bf6SEd 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 */ 2645ac106bf6SEd Tanous inline void 2646ac106bf6SEd 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, 2660ac106bf6SEd 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; 2668ac106bf6SEd 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 2674ac106bf6SEd 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(); 2685ac106bf6SEd 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!"; 2691ac106bf6SEd 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!"; 2699ac106bf6SEd 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( 2709ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27108a592810SEd Tanous if (ec2) 271137bbf98cSChris Cain { 27128a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2713ac106bf6SEd 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( 2724ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27258a592810SEd Tanous if (ec2) 272637bbf98cSChris Cain { 27278a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2728ac106bf6SEd 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( 2742ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27438a592810SEd Tanous if (ec2) 274437bbf98cSChris Cain { 27458a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2746ac106bf6SEd 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( 2758ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27598a592810SEd Tanous if (ec2) 276037bbf98cSChris Cain { 27618a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2762ac106bf6SEd 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( 2776ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 27778a592810SEd Tanous if (ec2) 277837bbf98cSChris Cain { 27798a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 2780ac106bf6SEd 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 2794*c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 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 2807*c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2808*c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2809*c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28101abe55efSEd Tanous { 28113ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2812f4c99e70SEd Tanous { 2813f4c99e70SEd Tanous return; 2814f4c99e70SEd Tanous } 2815dd60b9edSEd Tanous 2816dd60b9edSEd Tanous asyncResp->res.addHeader( 2817dd60b9edSEd Tanous boost::beast::http::field::link, 2818dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 28198d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28200f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28218d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28228d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2823462023adSSunitha Harish 28247f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 28257f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 28267f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 28277f3e84a1SEd Tanous { 28287f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 28297f3e84a1SEd Tanous // Option currently returns no systems. TBD 28307f3e84a1SEd Tanous return; 28317f3e84a1SEd Tanous } 28327f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 28337f3e84a1SEd Tanous nlohmann::json::object_t system; 28347f3e84a1SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 28357f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 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*/) { 28427f3e84a1SEd Tanous if (ec2) 2843462023adSSunitha Harish { 28447f3e84a1SEd Tanous return; 28457f3e84a1SEd Tanous } 28467f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 28477f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 28487f3e84a1SEd Tanous { 28497f3e84a1SEd Tanous BMCWEB_LOG_CRITICAL << "Count wasn't found??"; 28507f3e84a1SEd Tanous return; 28517f3e84a1SEd Tanous } 28527f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 28537f3e84a1SEd Tanous if (count == nullptr) 28547f3e84a1SEd Tanous { 28557f3e84a1SEd Tanous BMCWEB_LOG_CRITICAL << "Count wasn't found??"; 28567f3e84a1SEd Tanous return; 28577f3e84a1SEd Tanous } 28587f3e84a1SEd Tanous *count = *count + 1; 2859462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 28607f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 28611476687dSEd Tanous nlohmann::json::object_t hypervisor; 2862002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 28637f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 28641e1e598dSJonathan Doman }); 2865*c1e219d5SEd Tanous } 2866*c1e219d5SEd Tanous 2867*c1e219d5SEd Tanous /** 2868*c1e219d5SEd Tanous * SystemsCollection derived class for delivering ComputerSystems Collection 2869*c1e219d5SEd Tanous * Schema 2870*c1e219d5SEd Tanous */ 2871*c1e219d5SEd Tanous inline void requestRoutesSystemsCollection(App& app) 2872*c1e219d5SEd Tanous { 2873*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2874*c1e219d5SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 2875*c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)( 2876*c1e219d5SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 2877*c1e219d5SEd Tanous 2878*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2879*c1e219d5SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 2880*c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)( 2881*c1e219d5SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 2882c5b2abe0SLewanczyk, Dawid } 28837e860f15SJohn Edward Broadbent 28847e860f15SJohn Edward Broadbent /** 28857e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28867e860f15SJohn Edward Broadbent */ 28874f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28887e860f15SJohn Edward Broadbent { 288989492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 289089492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 289189492a15SPatrick Williams constexpr const char* interfaceName = 28927e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 289389492a15SPatrick Williams constexpr const char* method = "NMI"; 28947e860f15SJohn Edward Broadbent 28957e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28965e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28977e860f15SJohn Edward Broadbent if (ec) 28987e860f15SJohn Edward Broadbent { 28997e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 29007e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 29017e860f15SJohn Edward Broadbent return; 29027e860f15SJohn Edward Broadbent } 29037e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 29047e860f15SJohn Edward Broadbent }, 29057e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 29067e860f15SJohn Edward Broadbent } 2907c5b2abe0SLewanczyk, Dawid 2908c5b2abe0SLewanczyk, Dawid /** 2909fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 2910fc903b3dSAndrew Geissler */ 2911fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 2912fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 2913fc903b3dSAndrew Geissler std::string_view resetType, 2914fc903b3dSAndrew Geissler crow::Response& res) 2915fc903b3dSAndrew Geissler { 2916fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 2917fc903b3dSAndrew Geissler { 2918fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 2919fc903b3dSAndrew Geissler return; 2920fc903b3dSAndrew Geissler } 2921fc903b3dSAndrew Geissler 2922fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 2923fc903b3dSAndrew Geissler { 2924fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "D-Bus response error: " << ec; 2925fc903b3dSAndrew Geissler messages::internalError(res); 2926fc903b3dSAndrew Geissler return; 2927fc903b3dSAndrew Geissler } 2928fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 2929fc903b3dSAndrew Geissler 2930fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 2931fc903b3dSAndrew Geissler // user to retry in a bit 2932fc903b3dSAndrew Geissler if ((errorMessage == 2933fc903b3dSAndrew Geissler std::string_view( 2934fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 2935fc903b3dSAndrew Geissler (errorMessage == 2936fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 2937fc903b3dSAndrew Geissler { 2938fc903b3dSAndrew Geissler BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now"; 2939fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 2940fc903b3dSAndrew Geissler return; 2941fc903b3dSAndrew Geissler } 2942fc903b3dSAndrew Geissler 2943fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec 2944fc903b3dSAndrew Geissler << " sdbusplus:" << errorMessage; 2945fc903b3dSAndrew Geissler messages::internalError(res); 2946fc903b3dSAndrew Geissler } 2947fc903b3dSAndrew Geissler 2948*c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2949*c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 29507f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2951*c1e219d5SEd Tanous const std::string& systemName) 2952*c1e219d5SEd Tanous { 29533ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 295445ca1b86SEd Tanous { 295545ca1b86SEd Tanous return; 295645ca1b86SEd Tanous } 2957*c1e219d5SEd Tanous if (systemName != "system") 2958*c1e219d5SEd Tanous { 2959*c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2960*c1e219d5SEd Tanous systemName); 2961*c1e219d5SEd Tanous return; 2962*c1e219d5SEd Tanous } 29637f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 29647f3e84a1SEd Tanous { 29657f3e84a1SEd Tanous // Option currently returns no systems. TBD 29667f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2967*c1e219d5SEd Tanous systemName); 29687f3e84a1SEd Tanous return; 29697f3e84a1SEd Tanous } 29709712f8acSEd Tanous std::string resetType; 2971*c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 2972cc340dd9SEd Tanous { 2973cc340dd9SEd Tanous return; 2974cc340dd9SEd Tanous } 2975cc340dd9SEd Tanous 2976d22c8396SJason M. Bills // Get the command and host vs. chassis 2977cc340dd9SEd Tanous std::string command; 2978543f4400SEd Tanous bool hostCommand = true; 2979d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2980cc340dd9SEd Tanous { 2981cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2982d22c8396SJason M. Bills hostCommand = true; 2983d22c8396SJason M. Bills } 2984d22c8396SJason M. Bills else if (resetType == "ForceOff") 2985d22c8396SJason M. Bills { 2986d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2987d22c8396SJason M. Bills hostCommand = false; 2988d22c8396SJason M. Bills } 2989d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2990d22c8396SJason M. Bills { 2991*c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 299286a0851aSJason M. Bills hostCommand = true; 2993cc340dd9SEd Tanous } 29949712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2995cc340dd9SEd Tanous { 2996cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2997d22c8396SJason M. Bills hostCommand = true; 2998cc340dd9SEd Tanous } 29999712f8acSEd Tanous else if (resetType == "GracefulRestart") 3000cc340dd9SEd Tanous { 30010fda0f12SGeorge Liu command = 30020fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 3003d22c8396SJason M. Bills hostCommand = true; 3004d22c8396SJason M. Bills } 3005d22c8396SJason M. Bills else if (resetType == "PowerCycle") 3006d22c8396SJason M. Bills { 300786a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 300886a0851aSJason M. Bills hostCommand = true; 3009cc340dd9SEd Tanous } 3010bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 3011bfd5b826SLakshminarayana R. Kammath { 3012bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 3013bfd5b826SLakshminarayana R. Kammath return; 3014bfd5b826SLakshminarayana R. Kammath } 3015cc340dd9SEd Tanous else 3016cc340dd9SEd Tanous { 3017*c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 3018cc340dd9SEd Tanous return; 3019cc340dd9SEd Tanous } 3020cc340dd9SEd Tanous 3021d22c8396SJason M. Bills if (hostCommand) 3022d22c8396SJason M. Bills { 3023cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 3024fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3025fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3026cc340dd9SEd Tanous if (ec) 3027cc340dd9SEd Tanous { 3028fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3029fc903b3dSAndrew Geissler asyncResp->res); 3030fc903b3dSAndrew Geissler 3031cc340dd9SEd Tanous return; 3032cc340dd9SEd Tanous } 3033f12894f8SJason M. Bills messages::success(asyncResp->res); 3034cc340dd9SEd Tanous }, 3035cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 3036cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 3037cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 30389712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 3039168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 3040cc340dd9SEd Tanous } 3041d22c8396SJason M. Bills else 3042d22c8396SJason M. Bills { 3043d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 3044fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3045fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3046d22c8396SJason M. Bills if (ec) 3047d22c8396SJason M. Bills { 3048fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3049fc903b3dSAndrew Geissler asyncResp->res); 3050d22c8396SJason M. Bills return; 3051d22c8396SJason M. Bills } 3052d22c8396SJason M. Bills messages::success(asyncResp->res); 3053d22c8396SJason M. Bills }, 3054d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 3055d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 3056d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 3057002d39b4SEd Tanous "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 3058168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 3059d22c8396SJason M. Bills } 3060d22c8396SJason M. Bills } 3061cc340dd9SEd Tanous 3062*c1e219d5SEd Tanous /** 3063*c1e219d5SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 3064*c1e219d5SEd Tanous * The class retrieves and sends data directly to D-Bus. 3065*c1e219d5SEd Tanous */ 3066*c1e219d5SEd Tanous inline void requestRoutesSystemActionsReset(App& app) 3067*c1e219d5SEd Tanous { 3068*c1e219d5SEd Tanous /** 3069*c1e219d5SEd Tanous * Function handles POST method request. 3070*c1e219d5SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 3071*c1e219d5SEd Tanous */ 3072*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3073*c1e219d5SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3074*c1e219d5SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3075*c1e219d5SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3076*c1e219d5SEd Tanous } 3077*c1e219d5SEd Tanous 3078*c1e219d5SEd Tanous inline void handleComputerSystemHead( 3079dd60b9edSEd Tanous App& app, const crow::Request& req, 30807f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 30817f3e84a1SEd Tanous const std::string& /*systemName*/) 3082dd60b9edSEd Tanous { 3083dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3084dd60b9edSEd Tanous { 3085dd60b9edSEd Tanous return; 3086dd60b9edSEd Tanous } 3087dd60b9edSEd Tanous 3088dd60b9edSEd Tanous asyncResp->res.addHeader( 3089dd60b9edSEd Tanous boost::beast::http::field::link, 3090dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3091dd60b9edSEd Tanous } 3092dd60b9edSEd Tanous 30935c3e9272SAbhishek Patel inline void afterPortRequest( 30945c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 30955c3e9272SAbhishek Patel const boost::system::error_code& ec, 30965c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 30975c3e9272SAbhishek Patel { 30985c3e9272SAbhishek Patel if (ec) 30995c3e9272SAbhishek Patel { 31005c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31015c3e9272SAbhishek Patel return; 31025c3e9272SAbhishek Patel } 31035c3e9272SAbhishek Patel for (const auto& data : socketData) 31045c3e9272SAbhishek Patel { 31055c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 31065c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 31075c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 31085c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 31095c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 31105c3e9272SAbhishek Patel // need to retrieve port number for 31115c3e9272SAbhishek Patel // obmc-console-ssh service 31125c3e9272SAbhishek Patel if (protocolName == "SSH") 31135c3e9272SAbhishek Patel { 31145c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 311581c4e330SEd Tanous const boost::system::error_code& ec1, 31165c3e9272SAbhishek Patel int portNumber) { 31175c3e9272SAbhishek Patel if (ec1) 31185c3e9272SAbhishek Patel { 31195c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31205c3e9272SAbhishek Patel return; 31215c3e9272SAbhishek Patel } 31225c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 31235c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 31245c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 31255c3e9272SAbhishek Patel }); 31265c3e9272SAbhishek Patel } 31275c3e9272SAbhishek Patel } 31285c3e9272SAbhishek Patel } 3129*c1e219d5SEd Tanous 3130*c1e219d5SEd Tanous inline void 3131*c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 313222d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3133*c1e219d5SEd Tanous const std::string& systemName) 3134*c1e219d5SEd Tanous { 31353ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 313645ca1b86SEd Tanous { 313745ca1b86SEd Tanous return; 313845ca1b86SEd Tanous } 3139746b56f3SAsmitha Karunanithi 31407f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 31417f3e84a1SEd Tanous { 31427f3e84a1SEd Tanous // Option currently returns no systems. TBD 31437f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31447f3e84a1SEd Tanous systemName); 31457f3e84a1SEd Tanous return; 31467f3e84a1SEd Tanous } 31477f3e84a1SEd Tanous 3148746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3149746b56f3SAsmitha Karunanithi { 3150746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3151746b56f3SAsmitha Karunanithi return; 3152746b56f3SAsmitha Karunanithi } 3153746b56f3SAsmitha Karunanithi 315422d268cbSEd Tanous if (systemName != "system") 315522d268cbSEd Tanous { 315622d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 315722d268cbSEd Tanous systemName); 315822d268cbSEd Tanous return; 315922d268cbSEd Tanous } 3160dd60b9edSEd Tanous asyncResp->res.addHeader( 3161dd60b9edSEd Tanous boost::beast::http::field::link, 3162dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 31638d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 316437bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 31658d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 31668d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 31678d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 31688d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 31698d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 31705fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 31715fd0aafbSNinad Palsule { 31728d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 31738d1b46d7Szhanghch05 "Disabled"; 31748d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 31758d1b46d7Szhanghch05 "Disabled"; 31765fd0aafbSNinad Palsule } 3177cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3178cf0e004cSNinad Palsule uint64_t(0); 3179002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 318004a258f4SEd Tanous 31811476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 31821476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 31831476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 31841476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 31851476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 31861476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 31873179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 31883179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3189029573d4SEd Tanous 3190002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 31911476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 3192*c1e219d5SEd Tanous asyncResp->res 3193*c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 31941476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3195c5b2abe0SLewanczyk, Dawid 31961476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 31971476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 31981476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 31991476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3200c4bf6374SJason M. Bills 32011476687dSEd Tanous nlohmann::json::array_t managedBy; 32021476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 32031476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3204002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 32051476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 32061476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 32070e8ac5e7SGunnar Mills 32080e8ac5e7SGunnar Mills // Fill in SerialConsole info 3209002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3210*c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 32111476687dSEd Tanous 3212*c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 32131476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3214*c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 32151476687dSEd Tanous "Press ~. to exit console"; 32165c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 32175c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 32180e8ac5e7SGunnar Mills 32190e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 32200e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3221002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3222*c1e219d5SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4; 3223613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3224613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 32251476687dSEd Tanous 32260e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 322713451e39SWilly Tu 322813451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 322913451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 323013451e39SWilly Tu { 32317a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3232b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 32332ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3234e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3235e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3236b49ac873SJames Feist 32377a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 32387a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 32397a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3240914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3241b49ac873SJames Feist if (ec) 3242b49ac873SJames Feist { 3243b49ac873SJames Feist // no inventory 3244b49ac873SJames Feist return; 3245b49ac873SJames Feist } 3246b49ac873SJames Feist 3247914e2d5dSEd Tanous health->inventory = resp; 32487a1dbc48SGeorge Liu }); 3249b49ac873SJames Feist health->populate(); 325013451e39SWilly Tu } 3251b49ac873SJames Feist 3252002d39b4SEd Tanous getMainChassisId(asyncResp, 3253002d39b4SEd Tanous [](const std::string& chassisId, 32548d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3255b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3256b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3257ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3258ef4c65b7SEd Tanous chassisId); 3259002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3260c5d03ff4SJennifer Lee }); 3261a3002228SAppaRao Puli 32629f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 32639f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3264a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 32655bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 32666c34de48SEd Tanous getHostState(asyncResp); 3267491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3268978b8803SAndrew Geissler getBootProgress(asyncResp); 3269b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3270472bd202SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices"); 327151709ffdSYong Li getHostWatchdogTimer(asyncResp); 3272c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 3273797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3274c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3275a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3276a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3277a6349918SAppaRao Puli #endif 32781981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 32793a2d0424SChris Cain getPowerMode(asyncResp); 328037bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3281*c1e219d5SEd Tanous } 3282550a6bf8SJiaqing Zhao 3283*c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3284*c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 328522d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3286*c1e219d5SEd Tanous const std::string& systemName) 3287*c1e219d5SEd Tanous { 32883ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 328945ca1b86SEd Tanous { 329045ca1b86SEd Tanous return; 329145ca1b86SEd Tanous } 32927f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 32937f3e84a1SEd Tanous { 32947f3e84a1SEd Tanous // Option currently returns no systems. TBD 32957f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 32967f3e84a1SEd Tanous systemName); 32977f3e84a1SEd Tanous return; 32987f3e84a1SEd Tanous } 329922d268cbSEd Tanous if (systemName != "system") 330022d268cbSEd Tanous { 330122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 330222d268cbSEd Tanous systemName); 330322d268cbSEd Tanous return; 330422d268cbSEd Tanous } 330522d268cbSEd Tanous 3306dd60b9edSEd Tanous asyncResp->res.addHeader( 3307dd60b9edSEd Tanous boost::beast::http::field::link, 3308dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3309dd60b9edSEd Tanous 33109f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3311cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 331298e386ecSGunnar Mills std::optional<std::string> assetTag; 3313c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 33143a2d0424SChris Cain std::optional<std::string> powerMode; 3315550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3316550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3317550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3318550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3319550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3320550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3321797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3322550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 3323550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3324550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3325550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3326550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3327550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3328550a6bf8SJiaqing Zhao 3329550a6bf8SJiaqing Zhao // clang-format off 333015ed6780SWilly Tu if (!json_util::readJsonPatch( 3331550a6bf8SJiaqing Zhao req, asyncResp->res, 3332550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 33337e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3334550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3335550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3336550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3337550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3338550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3339550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3340550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3341550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3342550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3343797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3344550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 3345550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3346550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3347550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3348550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3349550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 33506617338dSEd Tanous { 33516617338dSEd Tanous return; 33526617338dSEd Tanous } 3353550a6bf8SJiaqing Zhao // clang-format on 3354491d8ee7SSantosh Puranik 33558d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3356c45f0082SYong Li 335798e386ecSGunnar Mills if (assetTag) 335898e386ecSGunnar Mills { 335998e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 336098e386ecSGunnar Mills } 336198e386ecSGunnar Mills 3362550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3363c45f0082SYong Li { 3364f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3365c45f0082SYong Li } 3366c45f0082SYong Li 3367cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 336869f35306SGunnar Mills { 3369002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3370491d8ee7SSantosh Puranik } 3371550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 337269f35306SGunnar Mills { 3373550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 337469f35306SGunnar Mills } 3375ac7e1e0bSAli Ahmed 3376797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3377797d5daeSCorey Hardesty { 3378797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3379797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3380797d5daeSCorey Hardesty } 3381797d5daeSCorey Hardesty 3382550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3383ac7e1e0bSAli Ahmed { 3384*c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 338569f35306SGunnar Mills } 3386265c1602SJohnathan Mantey 33879f8bfa7cSGunnar Mills if (locationIndicatorActive) 33889f8bfa7cSGunnar Mills { 3389002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 33909f8bfa7cSGunnar Mills } 33919f8bfa7cSGunnar Mills 33927e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 33937e860f15SJohn Edward Broadbent // passed 33949712f8acSEd Tanous if (indicatorLed) 33956617338dSEd Tanous { 3396f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3397002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3398d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3399d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 34006617338dSEd Tanous } 3401c6a620f2SGeorge Liu 3402c6a620f2SGeorge Liu if (powerRestorePolicy) 3403c6a620f2SGeorge Liu { 34044e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3405c6a620f2SGeorge Liu } 34063a2d0424SChris Cain 34073a2d0424SChris Cain if (powerMode) 34083a2d0424SChris Cain { 34093a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 34103a2d0424SChris Cain } 341137bbf98cSChris Cain 3412*c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 341337bbf98cSChris Cain { 3414002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3415002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 341637bbf98cSChris Cain } 3417*c1e219d5SEd Tanous } 3418*c1e219d5SEd Tanous /** 3419*c1e219d5SEd Tanous * Systems derived class for delivering Computer Systems Schema. 3420*c1e219d5SEd Tanous */ 3421*c1e219d5SEd Tanous inline void requestRoutesSystems(App& app) 3422*c1e219d5SEd Tanous { 3423*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3424*c1e219d5SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3425*c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)( 3426*c1e219d5SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3427*c1e219d5SEd Tanous /** 3428*c1e219d5SEd Tanous * Functions triggers appropriate requests on DBus 3429*c1e219d5SEd Tanous */ 3430*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3431*c1e219d5SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3432*c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)( 3433*c1e219d5SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3434*c1e219d5SEd Tanous 3435*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3436*c1e219d5SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3437*c1e219d5SEd Tanous .methods(boost::beast::http::verb::patch)( 3438*c1e219d5SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3439c5b2abe0SLewanczyk, Dawid } 34401cb1a9e6SAppaRao Puli 344138c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3442dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 34437f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3444*c1e219d5SEd Tanous const std::string& /*systemName*/) 3445dd60b9edSEd Tanous { 3446dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3447dd60b9edSEd Tanous { 3448dd60b9edSEd Tanous return; 3449dd60b9edSEd Tanous } 3450dd60b9edSEd Tanous asyncResp->res.addHeader( 3451dd60b9edSEd Tanous boost::beast::http::field::link, 3452dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3453dd60b9edSEd Tanous } 3454*c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3455*c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 345622d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3457*c1e219d5SEd Tanous const std::string& systemName) 3458*c1e219d5SEd Tanous { 34593ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 346045ca1b86SEd Tanous { 346145ca1b86SEd Tanous return; 346245ca1b86SEd Tanous } 34637f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 34647f3e84a1SEd Tanous { 34657f3e84a1SEd Tanous // Option currently returns no systems. TBD 34667f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 34677f3e84a1SEd Tanous systemName); 34687f3e84a1SEd Tanous return; 34697f3e84a1SEd Tanous } 3470746b56f3SAsmitha Karunanithi 3471746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3472746b56f3SAsmitha Karunanithi { 3473746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3474746b56f3SAsmitha Karunanithi return; 3475746b56f3SAsmitha Karunanithi } 3476746b56f3SAsmitha Karunanithi 347722d268cbSEd Tanous if (systemName != "system") 347822d268cbSEd Tanous { 347922d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 348022d268cbSEd Tanous systemName); 348122d268cbSEd Tanous return; 348222d268cbSEd Tanous } 348322d268cbSEd Tanous 3484dd60b9edSEd Tanous asyncResp->res.addHeader( 3485dd60b9edSEd Tanous boost::beast::http::field::link, 3486dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34871476687dSEd Tanous 34881476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 34891476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3490*c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34911476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34921476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34933215e700SNan Zhou 34943215e700SNan Zhou nlohmann::json::array_t parameters; 34953215e700SNan Zhou nlohmann::json::object_t parameter; 34963215e700SNan Zhou 34973215e700SNan Zhou parameter["Name"] = "ResetType"; 34983215e700SNan Zhou parameter["Required"] = true; 34993215e700SNan Zhou parameter["DataType"] = "String"; 35003215e700SNan Zhou nlohmann::json::array_t allowableValues; 35013215e700SNan Zhou allowableValues.emplace_back("On"); 35023215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 35033215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 35043215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 35053215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 35063215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 35073215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 35083215e700SNan Zhou allowableValues.emplace_back("Nmi"); 35093215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 35103215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 35113215e700SNan Zhou 35123215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 3513*c1e219d5SEd Tanous } 3514*c1e219d5SEd Tanous /** 3515*c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3516*c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3517*c1e219d5SEd Tanous */ 3518*c1e219d5SEd Tanous inline void requestRoutesSystemResetActionInfo(App& app) 3519*c1e219d5SEd Tanous { 3520*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3521*c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3522*c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3523*c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3524*c1e219d5SEd Tanous /** 3525*c1e219d5SEd Tanous * Functions triggers appropriate requests on DBus 3526*c1e219d5SEd Tanous */ 3527*c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3528*c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3529*c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3530*c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 35311cb1a9e6SAppaRao Puli } 3532c5b2abe0SLewanczyk, Dawid } // namespace redfish 3533