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 35*fc903b3dSAndrew 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> 40*fc903b3dSAndrew 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 * 579d3ae10eSAlpana Kumari * @param[in] aResp 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 638d1b46d7Szhanghch05 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 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 = 729d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 739d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 749d3ae10eSAlpana Kumari { 75e05aec50SEd Tanous if (isDimmFunctional) 769d3ae10eSAlpana Kumari { 779d3ae10eSAlpana Kumari aResp->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 * 8757e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 8857e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 8957e8c9beSAlpana Kumari * 9057e8c9beSAlpana Kumari * @return None. 9157e8c9beSAlpana Kumari */ 921e1e598dSJonathan Doman inline void 931e1e598dSJonathan Doman modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 941e1e598dSJonathan Doman bool isCpuFunctional) 9557e8c9beSAlpana Kumari { 961e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional; 9757e8c9beSAlpana Kumari 9802cad96eSEd Tanous const nlohmann::json& prevProcState = 9957e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10057e8c9beSAlpana Kumari 10157e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10257e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10357e8c9beSAlpana Kumari // Functional. 10457e8c9beSAlpana Kumari if (prevProcState == "Disabled") 10557e8c9beSAlpana Kumari { 106e05aec50SEd Tanous if (isCpuFunctional) 10757e8c9beSAlpana Kumari { 10857e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 10957e8c9beSAlpana Kumari "Enabled"; 11057e8c9beSAlpana Kumari } 11157e8c9beSAlpana Kumari } 11257e8c9beSAlpana Kumari } 11357e8c9beSAlpana Kumari 114cf0e004cSNinad Palsule /* 115cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 116cf0e004cSNinad Palsule * 117cf0e004cSNinad Palsule * @param[in] aResp Shared pointer for completing asynchronous calls 118cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 119cf0e004cSNinad Palsule * 120cf0e004cSNinad Palsule * @return None. 121cf0e004cSNinad Palsule */ 122cf0e004cSNinad Palsule inline void 123cf0e004cSNinad Palsule modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 124cf0e004cSNinad Palsule bool isCpuPresent) 125cf0e004cSNinad Palsule { 126cf0e004cSNinad Palsule BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent; 127cf0e004cSNinad Palsule 128cf0e004cSNinad Palsule if (isCpuPresent) 129cf0e004cSNinad Palsule { 130cf0e004cSNinad Palsule nlohmann::json& procCount = 131cf0e004cSNinad Palsule aResp->res.jsonValue["ProcessorSummary"]["Count"]; 132cf0e004cSNinad Palsule auto* procCountPtr = 133cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 134cf0e004cSNinad Palsule if (procCountPtr != nullptr) 135cf0e004cSNinad Palsule { 136cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 137cf0e004cSNinad Palsule *procCountPtr += 1; 138cf0e004cSNinad Palsule } 139cf0e004cSNinad Palsule } 140cf0e004cSNinad Palsule } 141cf0e004cSNinad Palsule 142382d6475SAli Ahmed inline void getProcessorProperties( 143382d6475SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, 144382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 145382d6475SAli Ahmed properties) 14603fbed92SAli Ahmed { 14703fbed92SAli Ahmed BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties."; 14803fbed92SAli Ahmed 14903fbed92SAli Ahmed // TODO: Get Model 15003fbed92SAli Ahmed 151bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15203fbed92SAli Ahmed 153bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 154bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 15503fbed92SAli Ahmed 156bc1d29deSKrzysztof Grobelny if (!success) 15703fbed92SAli Ahmed { 15803fbed92SAli Ahmed messages::internalError(aResp->res); 15903fbed92SAli Ahmed return; 16003fbed92SAli Ahmed } 16103fbed92SAli Ahmed 162bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16303fbed92SAli Ahmed { 164bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 165bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 166bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 167bc1d29deSKrzysztof Grobelny 168bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 169bc1d29deSKrzysztof Grobelny { 170bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17103fbed92SAli Ahmed } 17203fbed92SAli Ahmed else 17303fbed92SAli Ahmed { 174bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 17503fbed92SAli Ahmed } 17603fbed92SAli Ahmed } 17703fbed92SAli Ahmed } 17803fbed92SAli Ahmed 17903fbed92SAli Ahmed /* 18003fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18103fbed92SAli Ahmed * 18203fbed92SAli Ahmed * @param[in] aResp Shared pointer for completing asynchronous calls 18303fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 18403fbed92SAli Ahmed * @param[in] path dbus path for Cpu 18503fbed92SAli Ahmed * 18603fbed92SAli Ahmed * @return None. 18703fbed92SAli Ahmed */ 18803fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 18903fbed92SAli Ahmed const std::string& service, 19003fbed92SAli Ahmed const std::string& path) 19103fbed92SAli Ahmed { 1925e7e2dc5SEd Tanous auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3, 193382d6475SAli Ahmed const bool cpuPresenceCheck) { 194382d6475SAli Ahmed if (ec3) 195382d6475SAli Ahmed { 196382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 197382d6475SAli Ahmed return; 198382d6475SAli Ahmed } 199382d6475SAli Ahmed modifyCpuPresenceState(aResp, cpuPresenceCheck); 200382d6475SAli Ahmed }; 201382d6475SAli Ahmed 202cf0e004cSNinad Palsule // Get the Presence of CPU 203cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 204cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 205cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 206cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 207cf0e004cSNinad Palsule 2085fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2095fd0aafbSNinad Palsule { 2105fd0aafbSNinad Palsule auto getCpuFunctionalState = 2115fd0aafbSNinad Palsule [aResp](const boost::system::error_code& ec3, 212382d6475SAli Ahmed const bool cpuFunctionalCheck) { 213382d6475SAli Ahmed if (ec3) 214382d6475SAli Ahmed { 215382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 216382d6475SAli Ahmed return; 217382d6475SAli Ahmed } 218382d6475SAli Ahmed modifyCpuFunctionalState(aResp, cpuFunctionalCheck); 219382d6475SAli Ahmed }; 220382d6475SAli Ahmed 221382d6475SAli Ahmed // Get the Functional State 222382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 223382d6475SAli Ahmed *crow::connections::systemBus, service, path, 2245fd0aafbSNinad Palsule "xyz.openbmc_project.State.Decorator.OperationalStatus", 2255fd0aafbSNinad Palsule "Functional", std::move(getCpuFunctionalState)); 2265fd0aafbSNinad Palsule } 227382d6475SAli Ahmed 228bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 229bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 230bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 23103fbed92SAli Ahmed [aResp, service, 2325e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 233b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 23403fbed92SAli Ahmed if (ec2) 23503fbed92SAli Ahmed { 23603fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 23703fbed92SAli Ahmed messages::internalError(aResp->res); 23803fbed92SAli Ahmed return; 23903fbed92SAli Ahmed } 240382d6475SAli Ahmed getProcessorProperties(aResp, properties); 241bc1d29deSKrzysztof Grobelny }); 24203fbed92SAli Ahmed } 24303fbed92SAli Ahmed 24457e8c9beSAlpana Kumari /* 245cf0e004cSNinad Palsule * @brief processMemoryProperties fields 246cf0e004cSNinad Palsule * 247cf0e004cSNinad Palsule * @param[in] aResp Shared pointer for completing asynchronous calls 248cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 249cf0e004cSNinad Palsule * @param[in] path dbus path for Memory 250cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 251cf0e004cSNinad Palsule * 252cf0e004cSNinad Palsule * @return None. 253cf0e004cSNinad Palsule */ 254cf0e004cSNinad Palsule inline void 255cf0e004cSNinad Palsule processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 2565fd0aafbSNinad Palsule [[maybe_unused]] const std::string& service, 2575fd0aafbSNinad Palsule [[maybe_unused]] const std::string& path, 258cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 259cf0e004cSNinad Palsule { 260cf0e004cSNinad Palsule BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties."; 261cf0e004cSNinad Palsule 262cf0e004cSNinad Palsule if (properties.empty()) 263cf0e004cSNinad Palsule { 2645fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2655fd0aafbSNinad Palsule { 266cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 267cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 268cf0e004cSNinad Palsule "xyz.openbmc_project.State." 269cf0e004cSNinad Palsule "Decorator.OperationalStatus", 270cf0e004cSNinad Palsule "Functional", 271cf0e004cSNinad Palsule [aResp](const boost::system::error_code& ec3, bool dimmState) { 272cf0e004cSNinad Palsule if (ec3) 273cf0e004cSNinad Palsule { 274cf0e004cSNinad Palsule BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 275cf0e004cSNinad Palsule return; 276cf0e004cSNinad Palsule } 277cf0e004cSNinad Palsule updateDimmProperties(aResp, 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 { 291cf0e004cSNinad Palsule messages::internalError(aResp->res); 292cf0e004cSNinad Palsule return; 293cf0e004cSNinad Palsule } 294cf0e004cSNinad Palsule 295cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 296cf0e004cSNinad Palsule { 297cf0e004cSNinad Palsule nlohmann::json& totalMemory = 298cf0e004cSNinad Palsule aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 299cf0e004cSNinad Palsule const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>(); 300cf0e004cSNinad Palsule if (preValue == nullptr) 301cf0e004cSNinad Palsule { 302cf0e004cSNinad Palsule aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 303cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024); 304cf0e004cSNinad Palsule } 305cf0e004cSNinad Palsule else 306cf0e004cSNinad Palsule { 307cf0e004cSNinad Palsule aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 308cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue; 309cf0e004cSNinad Palsule } 3105fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3115fd0aafbSNinad Palsule { 3125fd0aafbSNinad Palsule aResp->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 * 321cf0e004cSNinad Palsule * @param[in] aResp 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 */ 327cf0e004cSNinad Palsule inline void getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 328cf0e004cSNinad Palsule const std::string& service, 329cf0e004cSNinad Palsule 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", 334cf0e004cSNinad Palsule [aResp, 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; 340cf0e004cSNinad Palsule messages::internalError(aResp->res); 341cf0e004cSNinad Palsule return; 342cf0e004cSNinad Palsule } 343cf0e004cSNinad Palsule processMemoryProperties(aResp, service, path, properties); 344cf0e004cSNinad Palsule }); 345cf0e004cSNinad Palsule } 346cf0e004cSNinad Palsule 347cf0e004cSNinad Palsule /* 348c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 349c5b2abe0SLewanczyk, Dawid * 350c5b2abe0SLewanczyk, Dawid * @param[in] aResp 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 3568d1b46d7Szhanghch05 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 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, 369b9d36b47SEd Tanous [aResp, 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"; 375f12894f8SJason M. Bills messages::internalError(aResp->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>( 3995fd0aafbSNinad Palsule aResp, "/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>( 4055fd0aafbSNinad Palsule aResp, "/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 423cf0e004cSNinad Palsule getMemorySummary(aResp, 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 43603fbed92SAli Ahmed getProcessorSummary(aResp, 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", 4515e7e2dc5SEd Tanous [aResp](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; 458f12894f8SJason M. Bills messages::internalError(aResp->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 { 473bc1d29deSKrzysztof Grobelny messages::internalError(aResp->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; 488002d39b4SEd Tanous aResp->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", 4995e7e2dc5SEd Tanous [aResp](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 { 527bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 528bc1d29deSKrzysztof Grobelny return; 529029573d4SEd Tanous } 530bc1d29deSKrzysztof Grobelny 531bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 532bc1d29deSKrzysztof Grobelny { 533bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["PartNumber"] = 534bc1d29deSKrzysztof Grobelny *partNumber; 535029573d4SEd Tanous } 536bc1d29deSKrzysztof Grobelny 537bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 538bc1d29deSKrzysztof Grobelny { 539bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SerialNumber"] = 540bc1d29deSKrzysztof Grobelny *serialNumber; 541bc1d29deSKrzysztof Grobelny } 542bc1d29deSKrzysztof Grobelny 543bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 544bc1d29deSKrzysztof Grobelny { 545bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Manufacturer"] = 546bc1d29deSKrzysztof Grobelny *manufacturer; 547bc1d29deSKrzysztof Grobelny } 548bc1d29deSKrzysztof Grobelny 549bc1d29deSKrzysztof Grobelny if (model != nullptr) 550bc1d29deSKrzysztof Grobelny { 551bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Model"] = *model; 552bc1d29deSKrzysztof Grobelny } 553bc1d29deSKrzysztof Grobelny 554bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 555bc1d29deSKrzysztof Grobelny { 556bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SubModel"] = *subModel; 557fc5afcf9Sbeccabroek } 558c1e236a6SGunnar Mills 559cb7e1e7bSAndrew Geissler // Grab the bios version 560eee0013eSWilly Tu sw_util::populateSoftwareInformation( 561eee0013eSWilly Tu aResp, sw_util::biosPurpose, "BiosVersion", 562002d39b4SEd Tanous false); 563bc1d29deSKrzysztof Grobelny }); 564e4a4b9a9SJames Feist 5651e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5661e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5671e1e598dSJonathan Doman path, 5681e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5691e1e598dSJonathan Doman "AssetTag", 5701e1e598dSJonathan Doman "AssetTag", 5715e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, 5721e1e598dSJonathan Doman const std::string& value) { 573cb13a392SEd Tanous if (ec2) 574e4a4b9a9SJames Feist { 575e4a4b9a9SJames Feist // doesn't have to include this 576e4a4b9a9SJames Feist // interface 577e4a4b9a9SJames Feist return; 578e4a4b9a9SJames Feist } 579e4a4b9a9SJames Feist 5801e1e598dSJonathan Doman aResp->res.jsonValue["AssetTag"] = value; 5811e1e598dSJonathan Doman }); 582029573d4SEd Tanous } 583029573d4SEd Tanous } 584029573d4SEd Tanous } 585c5b2abe0SLewanczyk, Dawid } 5866617338dSEd Tanous }); 587c5b2abe0SLewanczyk, Dawid } 588c5b2abe0SLewanczyk, Dawid 589c5b2abe0SLewanczyk, Dawid /** 590c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 591c5b2abe0SLewanczyk, Dawid * 592c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 593c5b2abe0SLewanczyk, Dawid * 594c5b2abe0SLewanczyk, Dawid * @return None. 595c5b2abe0SLewanczyk, Dawid */ 5968d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 5971abe55efSEd Tanous { 59855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 5991e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 6001e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 6011e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 6021e1e598dSJonathan Doman "CurrentHostState", 6035e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 6041e1e598dSJonathan Doman const std::string& hostState) { 6051abe55efSEd Tanous if (ec) 6061abe55efSEd Tanous { 60722228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 60822228c28SAndrew Geissler { 60922228c28SAndrew Geissler // Service not available, no error, just don't return 61022228c28SAndrew Geissler // host state info 61122228c28SAndrew Geissler BMCWEB_LOG_DEBUG << "Service not available " << ec; 61222228c28SAndrew Geissler return; 61322228c28SAndrew Geissler } 61422228c28SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 615f12894f8SJason M. Bills messages::internalError(aResp->res); 616c5b2abe0SLewanczyk, Dawid return; 617c5b2abe0SLewanczyk, Dawid } 6186617338dSEd Tanous 6191e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Host state: " << hostState; 620c5b2abe0SLewanczyk, Dawid // Verify Host State 6211e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 6221abe55efSEd Tanous { 62355c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 6246617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 6251abe55efSEd Tanous } 6261e1e598dSJonathan Doman else if (hostState == 6270fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 6288c888608SGunnar Mills { 6298c888608SGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 6308c888608SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6318c888608SGunnar Mills } 6321e1e598dSJonathan Doman else if (hostState == 6330fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 63483935af9SAndrew Geissler { 63583935af9SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 63683935af9SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "InTest"; 63783935af9SAndrew Geissler } 6380fda0f12SGeorge Liu else if ( 6391e1e598dSJonathan Doman hostState == 6400fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6411a2a1437SAndrew Geissler { 6421a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOn"; 64315c27bf8SNoah Brewer aResp->res.jsonValue["Status"]["State"] = "Starting"; 6441a2a1437SAndrew Geissler } 645002d39b4SEd Tanous else if (hostState == 6460fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6471a2a1437SAndrew Geissler { 6481a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOff"; 6491a2a1437SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Disabled"; 6501a2a1437SAndrew Geissler } 6511abe55efSEd Tanous else 6521abe55efSEd Tanous { 65355c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 6546617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 655c5b2abe0SLewanczyk, Dawid } 6561e1e598dSJonathan Doman }); 657c5b2abe0SLewanczyk, Dawid } 658c5b2abe0SLewanczyk, Dawid 659c5b2abe0SLewanczyk, Dawid /** 660786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 661491d8ee7SSantosh Puranik * 662491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 663491d8ee7SSantosh Puranik * 664491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 665491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 666491d8ee7SSantosh Puranik */ 66723a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 668491d8ee7SSantosh Puranik { 669491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 670491d8ee7SSantosh Puranik { 671491d8ee7SSantosh Puranik return "None"; 672491d8ee7SSantosh Puranik } 6733174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 674491d8ee7SSantosh Puranik { 675491d8ee7SSantosh Puranik return "Hdd"; 676491d8ee7SSantosh Puranik } 6773174e4dfSEd Tanous if (dbusSource == 678a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 679491d8ee7SSantosh Puranik { 680491d8ee7SSantosh Puranik return "Cd"; 681491d8ee7SSantosh Puranik } 6823174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 683491d8ee7SSantosh Puranik { 684491d8ee7SSantosh Puranik return "Pxe"; 685491d8ee7SSantosh Puranik } 6863174e4dfSEd Tanous if (dbusSource == 687944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6889f16b2c1SJennifer Lee { 6899f16b2c1SJennifer Lee return "Usb"; 6909f16b2c1SJennifer Lee } 691491d8ee7SSantosh Puranik return ""; 692491d8ee7SSantosh Puranik } 693491d8ee7SSantosh Puranik 694491d8ee7SSantosh Puranik /** 695cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 696cd9a4666SKonstantin Aladyshev * 697cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 698cd9a4666SKonstantin Aladyshev * 699cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 700cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 701cd9a4666SKonstantin Aladyshev */ 702cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 703cd9a4666SKonstantin Aladyshev { 704cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 705cd9a4666SKonstantin Aladyshev { 706cd9a4666SKonstantin Aladyshev return "Legacy"; 707cd9a4666SKonstantin Aladyshev } 708cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 709cd9a4666SKonstantin Aladyshev { 710cd9a4666SKonstantin Aladyshev return "UEFI"; 711cd9a4666SKonstantin Aladyshev } 712cd9a4666SKonstantin Aladyshev return ""; 713cd9a4666SKonstantin Aladyshev } 714cd9a4666SKonstantin Aladyshev 715cd9a4666SKonstantin Aladyshev /** 716786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 717491d8ee7SSantosh Puranik * 718491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 719491d8ee7SSantosh Puranik * 720491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 721491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 722491d8ee7SSantosh Puranik */ 72323a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 724491d8ee7SSantosh Puranik { 725491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 726491d8ee7SSantosh Puranik { 727491d8ee7SSantosh Puranik return "None"; 728491d8ee7SSantosh Puranik } 7293174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 730491d8ee7SSantosh Puranik { 731491d8ee7SSantosh Puranik return "Diags"; 732491d8ee7SSantosh Puranik } 7333174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 734491d8ee7SSantosh Puranik { 735491d8ee7SSantosh Puranik return "BiosSetup"; 736491d8ee7SSantosh Puranik } 737491d8ee7SSantosh Puranik return ""; 738491d8ee7SSantosh Puranik } 739491d8ee7SSantosh Puranik 740491d8ee7SSantosh Puranik /** 741e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 742e43914b3SAndrew Geissler * 743e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 744e43914b3SAndrew Geissler * 745e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 746e43914b3SAndrew Geissler * translation cannot be done, returns "None". 747e43914b3SAndrew Geissler */ 748e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 749e43914b3SAndrew Geissler { 750e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 751e43914b3SAndrew Geissler // enum 752e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 753e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 754e43914b3SAndrew Geissler "ProgressStages.Unspecified") 755e43914b3SAndrew Geissler { 756e43914b3SAndrew Geissler rfBpLastState = "None"; 757e43914b3SAndrew Geissler } 758e43914b3SAndrew Geissler else if (dbusBootProgress == 759e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 760e43914b3SAndrew Geissler "PrimaryProcInit") 761e43914b3SAndrew Geissler { 762e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 763e43914b3SAndrew Geissler } 764e43914b3SAndrew Geissler else if (dbusBootProgress == 765e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 766e43914b3SAndrew Geissler "BusInit") 767e43914b3SAndrew Geissler { 768e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 769e43914b3SAndrew Geissler } 770e43914b3SAndrew Geissler else if (dbusBootProgress == 771e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 772e43914b3SAndrew Geissler "MemoryInit") 773e43914b3SAndrew Geissler { 774e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 775e43914b3SAndrew Geissler } 776e43914b3SAndrew Geissler else if (dbusBootProgress == 777e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 778e43914b3SAndrew Geissler "SecondaryProcInit") 779e43914b3SAndrew Geissler { 780e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 781e43914b3SAndrew Geissler } 782e43914b3SAndrew Geissler else if (dbusBootProgress == 783e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 784e43914b3SAndrew Geissler "PCIInit") 785e43914b3SAndrew Geissler { 786e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 787e43914b3SAndrew Geissler } 788e43914b3SAndrew Geissler else if (dbusBootProgress == 789e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 790e43914b3SAndrew Geissler "SystemSetup") 791e43914b3SAndrew Geissler { 792e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 793e43914b3SAndrew Geissler } 794e43914b3SAndrew Geissler else if (dbusBootProgress == 795e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 796e43914b3SAndrew Geissler "SystemInitComplete") 797e43914b3SAndrew Geissler { 798e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 799e43914b3SAndrew Geissler } 800e43914b3SAndrew Geissler else if (dbusBootProgress == 801e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 802e43914b3SAndrew Geissler "OSStart") 803e43914b3SAndrew Geissler { 804e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 805e43914b3SAndrew Geissler } 806e43914b3SAndrew Geissler else if (dbusBootProgress == 807e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 808e43914b3SAndrew Geissler "OSRunning") 809e43914b3SAndrew Geissler { 810e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 811e43914b3SAndrew Geissler } 812e43914b3SAndrew Geissler else 813e43914b3SAndrew Geissler { 814e43914b3SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 815e43914b3SAndrew Geissler << dbusBootProgress; 816e43914b3SAndrew Geissler // Just return the default 817e43914b3SAndrew Geissler } 818e43914b3SAndrew Geissler return rfBpLastState; 819e43914b3SAndrew Geissler } 820e43914b3SAndrew Geissler 821e43914b3SAndrew Geissler /** 822786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 823491d8ee7SSantosh Puranik * 824491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 825944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 826944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 827491d8ee7SSantosh Puranik * 828944ffaf9SJohnathan Mantey * @return Integer error code. 829491d8ee7SSantosh Puranik */ 8308d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 831944ffaf9SJohnathan Mantey const std::string& rfSource, 832944ffaf9SJohnathan Mantey std::string& bootSource, std::string& bootMode) 833491d8ee7SSantosh Puranik { 834c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 835c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 836944ffaf9SJohnathan Mantey 837491d8ee7SSantosh Puranik if (rfSource == "None") 838491d8ee7SSantosh Puranik { 839944ffaf9SJohnathan Mantey return 0; 840491d8ee7SSantosh Puranik } 8413174e4dfSEd Tanous if (rfSource == "Pxe") 842491d8ee7SSantosh Puranik { 843944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 844944ffaf9SJohnathan Mantey } 845944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 846944ffaf9SJohnathan Mantey { 847944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 848944ffaf9SJohnathan Mantey } 849944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 850944ffaf9SJohnathan Mantey { 851944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 852944ffaf9SJohnathan Mantey } 853944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 854944ffaf9SJohnathan Mantey { 855944ffaf9SJohnathan Mantey bootSource = 856944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 857944ffaf9SJohnathan Mantey } 858944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 859944ffaf9SJohnathan Mantey { 860944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 861491d8ee7SSantosh Puranik } 8629f16b2c1SJennifer Lee else if (rfSource == "Usb") 8639f16b2c1SJennifer Lee { 864944ffaf9SJohnathan Mantey bootSource = 865944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8669f16b2c1SJennifer Lee } 867491d8ee7SSantosh Puranik else 868491d8ee7SSantosh Puranik { 8690fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 8700fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideTarget: " 871944ffaf9SJohnathan Mantey << bootSource; 872944ffaf9SJohnathan Mantey messages::propertyValueNotInList(aResp->res, rfSource, 873944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 874944ffaf9SJohnathan Mantey return -1; 875491d8ee7SSantosh Puranik } 876944ffaf9SJohnathan Mantey return 0; 877491d8ee7SSantosh Puranik } 8781981771bSAli Ahmed 879978b8803SAndrew Geissler /** 880978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 881978b8803SAndrew Geissler * 882978b8803SAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 883978b8803SAndrew Geissler * 884978b8803SAndrew Geissler * @return None. 885978b8803SAndrew Geissler */ 8868d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 887978b8803SAndrew Geissler { 8881e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8891e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8901e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8911e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 8925e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 8931e1e598dSJonathan Doman const std::string& bootProgressStr) { 894978b8803SAndrew Geissler if (ec) 895978b8803SAndrew Geissler { 896978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 897978b8803SAndrew Geissler // not found 898978b8803SAndrew Geissler return; 899978b8803SAndrew Geissler } 900978b8803SAndrew Geissler 9011e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr; 902978b8803SAndrew Geissler 903e43914b3SAndrew Geissler aResp->res.jsonValue["BootProgress"]["LastState"] = 904e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 9051e1e598dSJonathan Doman }); 906978b8803SAndrew Geissler } 907491d8ee7SSantosh Puranik 908491d8ee7SSantosh Puranik /** 909b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 910b6d5d45cSHieu Huynh * 911b6d5d45cSHieu Huynh * @param[in] aResp Shared pointer for generating response message. 912b6d5d45cSHieu Huynh * 913b6d5d45cSHieu Huynh * @return None. 914b6d5d45cSHieu Huynh */ 915b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 916b6d5d45cSHieu Huynh const std::shared_ptr<bmcweb::AsyncResp>& aResp) 917b6d5d45cSHieu Huynh { 918b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 919b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 920b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 921b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 9225e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 923b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 924b6d5d45cSHieu Huynh if (ec) 925b6d5d45cSHieu Huynh { 926b6d5d45cSHieu Huynh BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 927b6d5d45cSHieu Huynh return; 928b6d5d45cSHieu Huynh } 929b6d5d45cSHieu Huynh 930b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 931b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 932b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 933b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 934b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 935b6d5d45cSHieu Huynh 936b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 937b6d5d45cSHieu Huynh aResp->res.jsonValue["BootProgress"]["LastStateTime"] = 938b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 939b6d5d45cSHieu Huynh }); 940b6d5d45cSHieu Huynh } 941b6d5d45cSHieu Huynh 942b6d5d45cSHieu Huynh /** 943c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 944cd9a4666SKonstantin Aladyshev * 945cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 946cd9a4666SKonstantin Aladyshev * 947cd9a4666SKonstantin Aladyshev * @return None. 948cd9a4666SKonstantin Aladyshev */ 949cd9a4666SKonstantin Aladyshev 950c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 951cd9a4666SKonstantin Aladyshev { 9521e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9531e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9541e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9551e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 9565e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 9571e1e598dSJonathan Doman const std::string& bootType) { 958cd9a4666SKonstantin Aladyshev if (ec) 959cd9a4666SKonstantin Aladyshev { 960cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 961cd9a4666SKonstantin Aladyshev return; 962cd9a4666SKonstantin Aladyshev } 963cd9a4666SKonstantin Aladyshev 9641e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot type: " << bootType; 965cd9a4666SKonstantin Aladyshev 966002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 967002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 968613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 969cd9a4666SKonstantin Aladyshev 9701e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 971cd9a4666SKonstantin Aladyshev if (rfType.empty()) 972cd9a4666SKonstantin Aladyshev { 973cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 974cd9a4666SKonstantin Aladyshev return; 975cd9a4666SKonstantin Aladyshev } 976cd9a4666SKonstantin Aladyshev 977cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9781e1e598dSJonathan Doman }); 979cd9a4666SKonstantin Aladyshev } 980cd9a4666SKonstantin Aladyshev 981cd9a4666SKonstantin Aladyshev /** 982c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 983491d8ee7SSantosh Puranik * 984491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 985491d8ee7SSantosh Puranik * 986491d8ee7SSantosh Puranik * @return None. 987491d8ee7SSantosh Puranik */ 988c21865c4SKonstantin Aladyshev 989c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 990491d8ee7SSantosh Puranik { 9911e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9921e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9931e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9941e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 9955e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 9961e1e598dSJonathan Doman const std::string& bootModeStr) { 997491d8ee7SSantosh Puranik if (ec) 998491d8ee7SSantosh Puranik { 999491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1000491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1001491d8ee7SSantosh Puranik return; 1002491d8ee7SSantosh Puranik } 1003491d8ee7SSantosh Puranik 10041e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 1005491d8ee7SSantosh Puranik 10060fda0f12SGeorge Liu aResp->res 10070fda0f12SGeorge Liu .jsonValue["Boot"] 1008002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 1009002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1010491d8ee7SSantosh Puranik 10111e1e598dSJonathan Doman if (bootModeStr != 1012491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1013491d8ee7SSantosh Puranik { 10141e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 1015491d8ee7SSantosh Puranik if (!rfMode.empty()) 1016491d8ee7SSantosh Puranik { 1017491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1018491d8ee7SSantosh Puranik rfMode; 1019491d8ee7SSantosh Puranik } 1020491d8ee7SSantosh Puranik } 10211e1e598dSJonathan Doman }); 1022491d8ee7SSantosh Puranik } 1023491d8ee7SSantosh Puranik 1024491d8ee7SSantosh Puranik /** 1025c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1026491d8ee7SSantosh Puranik * 1027491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1028491d8ee7SSantosh Puranik * 1029491d8ee7SSantosh Puranik * @return None. 1030491d8ee7SSantosh Puranik */ 1031c21865c4SKonstantin Aladyshev 1032c21865c4SKonstantin Aladyshev inline void 1033c21865c4SKonstantin Aladyshev getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1034491d8ee7SSantosh Puranik { 10351e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10361e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10371e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10381e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 10395e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 10401e1e598dSJonathan Doman const std::string& bootSourceStr) { 1041491d8ee7SSantosh Puranik if (ec) 1042491d8ee7SSantosh Puranik { 1043491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 10445ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10455ef735c8SNan Zhou { 10465ef735c8SNan Zhou return; 10475ef735c8SNan Zhou } 1048491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1049491d8ee7SSantosh Puranik return; 1050491d8ee7SSantosh Puranik } 1051491d8ee7SSantosh Puranik 10521e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr; 1053491d8ee7SSantosh Puranik 10541e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1055491d8ee7SSantosh Puranik if (!rfSource.empty()) 1056491d8ee7SSantosh Puranik { 1057002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource; 1058491d8ee7SSantosh Puranik } 1059cd9a4666SKonstantin Aladyshev 1060cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1061cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1062c21865c4SKonstantin Aladyshev getBootOverrideMode(aResp); 10631e1e598dSJonathan Doman }); 1064491d8ee7SSantosh Puranik } 1065491d8ee7SSantosh Puranik 1066491d8ee7SSantosh Puranik /** 1067c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1068c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1069c21865c4SKonstantin Aladyshev * state 1070491d8ee7SSantosh Puranik * 1071491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1072491d8ee7SSantosh Puranik * 1073491d8ee7SSantosh Puranik * @return None. 1074491d8ee7SSantosh Puranik */ 1075491d8ee7SSantosh Puranik 1076c21865c4SKonstantin Aladyshev inline void 1077c21865c4SKonstantin Aladyshev processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1078c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1079c21865c4SKonstantin Aladyshev { 1080c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1081c21865c4SKonstantin Aladyshev { 1082c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; 1083c21865c4SKonstantin Aladyshev return; 1084c21865c4SKonstantin Aladyshev } 1085c21865c4SKonstantin Aladyshev 1086c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1087c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10881e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10891e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10901e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10911e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 10925e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1093491d8ee7SSantosh Puranik if (ec) 1094491d8ee7SSantosh Puranik { 1095491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1096c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1097491d8ee7SSantosh Puranik return; 1098491d8ee7SSantosh Puranik } 1099491d8ee7SSantosh Puranik 1100c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1101c21865c4SKonstantin Aladyshev { 1102002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once"; 1103c21865c4SKonstantin Aladyshev } 1104c21865c4SKonstantin Aladyshev else 1105c21865c4SKonstantin Aladyshev { 1106c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1107c21865c4SKonstantin Aladyshev "Continuous"; 1108c21865c4SKonstantin Aladyshev } 11091e1e598dSJonathan Doman }); 1110491d8ee7SSantosh Puranik } 1111491d8ee7SSantosh Puranik 1112491d8ee7SSantosh Puranik /** 1113c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1114c21865c4SKonstantin Aladyshev * 1115c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1116c21865c4SKonstantin Aladyshev * 1117c21865c4SKonstantin Aladyshev * @return None. 1118c21865c4SKonstantin Aladyshev */ 1119c21865c4SKonstantin Aladyshev 1120c21865c4SKonstantin Aladyshev inline void 1121c21865c4SKonstantin Aladyshev getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1122c21865c4SKonstantin Aladyshev { 11231e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11241e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11251e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 11261e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 11275e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 11281e1e598dSJonathan Doman const bool bootOverrideEnable) { 1129c21865c4SKonstantin Aladyshev if (ec) 1130c21865c4SKonstantin Aladyshev { 1131c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 11325ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11335ef735c8SNan Zhou { 11345ef735c8SNan Zhou return; 11355ef735c8SNan Zhou } 1136c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1137c21865c4SKonstantin Aladyshev return; 1138c21865c4SKonstantin Aladyshev } 1139c21865c4SKonstantin Aladyshev 11401e1e598dSJonathan Doman processBootOverrideEnable(aResp, bootOverrideEnable); 11411e1e598dSJonathan Doman }); 1142c21865c4SKonstantin Aladyshev } 1143c21865c4SKonstantin Aladyshev 1144c21865c4SKonstantin Aladyshev /** 1145c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1146c21865c4SKonstantin Aladyshev * 1147c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1148c21865c4SKonstantin Aladyshev * 1149c21865c4SKonstantin Aladyshev * @return None. 1150c21865c4SKonstantin Aladyshev */ 1151c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1152c21865c4SKonstantin Aladyshev { 1153c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1154c21865c4SKonstantin Aladyshev 1155c21865c4SKonstantin Aladyshev getBootOverrideSource(aResp); 1156c21865c4SKonstantin Aladyshev getBootOverrideType(aResp); 1157c21865c4SKonstantin Aladyshev getBootOverrideEnable(aResp); 1158c21865c4SKonstantin Aladyshev } 1159c21865c4SKonstantin Aladyshev 1160c21865c4SKonstantin Aladyshev /** 1161c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1162c0557e1aSGunnar Mills * 1163c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1164c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1165c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1166c0557e1aSGunnar Mills * last power operation time. 1167c0557e1aSGunnar Mills * 1168c0557e1aSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 1169c0557e1aSGunnar Mills * 1170c0557e1aSGunnar Mills * @return None. 1171c0557e1aSGunnar Mills */ 11728d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1173c0557e1aSGunnar Mills { 1174c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1175c0557e1aSGunnar Mills 11761e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11771e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11781e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11791e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 11805e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) { 1181c0557e1aSGunnar Mills if (ec) 1182c0557e1aSGunnar Mills { 1183c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1184c0557e1aSGunnar Mills return; 1185c0557e1aSGunnar Mills } 1186c0557e1aSGunnar Mills 1187c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1188c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11891e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1190c0557e1aSGunnar Mills 1191c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1192c0557e1aSGunnar Mills aResp->res.jsonValue["LastResetTime"] = 11932b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11941e1e598dSJonathan Doman }); 1195c0557e1aSGunnar Mills } 1196c0557e1aSGunnar Mills 1197c0557e1aSGunnar Mills /** 1198797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1199797d5daeSCorey Hardesty * 1200797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1201797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1202797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1203797d5daeSCorey Hardesty * dbus. 1204797d5daeSCorey Hardesty * 1205797d5daeSCorey Hardesty * @param[in] aResp Shared pointer for generating response message. 1206797d5daeSCorey Hardesty * 1207797d5daeSCorey Hardesty * @return None. 1208797d5daeSCorey Hardesty */ 1209797d5daeSCorey Hardesty inline void 1210797d5daeSCorey Hardesty getAutomaticRebootAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1211797d5daeSCorey Hardesty { 1212797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 1213797d5daeSCorey Hardesty 1214797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1215797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1216797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1217797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1218797d5daeSCorey Hardesty [aResp{aResp}](const boost::system::error_code& ec, 1219797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1220797d5daeSCorey Hardesty if (ec) 1221797d5daeSCorey Hardesty { 1222797d5daeSCorey Hardesty if (ec.value() != EBADR) 1223797d5daeSCorey Hardesty { 1224797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1225797d5daeSCorey Hardesty messages::internalError(aResp->res); 1226797d5daeSCorey Hardesty } 1227797d5daeSCorey Hardesty return; 1228797d5daeSCorey Hardesty } 1229797d5daeSCorey Hardesty 1230797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1231797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1232797d5daeSCorey Hardesty 1233797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1234797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1235797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1236797d5daeSCorey Hardesty 1237797d5daeSCorey Hardesty if (!success) 1238797d5daeSCorey Hardesty { 1239797d5daeSCorey Hardesty messages::internalError(aResp->res); 1240797d5daeSCorey Hardesty return; 1241797d5daeSCorey Hardesty } 1242797d5daeSCorey Hardesty 1243797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1244797d5daeSCorey Hardesty { 1245797d5daeSCorey Hardesty aResp->res.jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1246797d5daeSCorey Hardesty *attemptsLeft; 1247797d5daeSCorey Hardesty } 1248797d5daeSCorey Hardesty 1249797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1250797d5daeSCorey Hardesty { 1251797d5daeSCorey Hardesty aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1252797d5daeSCorey Hardesty *retryAttempts; 1253797d5daeSCorey Hardesty } 1254797d5daeSCorey Hardesty }); 1255797d5daeSCorey Hardesty } 1256797d5daeSCorey Hardesty 1257797d5daeSCorey Hardesty /** 12586bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12596bd5a8d2SGunnar Mills * 12606bd5a8d2SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 12616bd5a8d2SGunnar Mills * 12626bd5a8d2SGunnar Mills * @return None. 12636bd5a8d2SGunnar Mills */ 1264797d5daeSCorey Hardesty inline void 1265797d5daeSCorey Hardesty getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 12666bd5a8d2SGunnar Mills { 12676bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 12686bd5a8d2SGunnar Mills 12691e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12701e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12711e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12721e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 12735e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) { 12746bd5a8d2SGunnar Mills if (ec) 12756bd5a8d2SGunnar Mills { 1276797d5daeSCorey Hardesty if (ec.value() != EBADR) 1277797d5daeSCorey Hardesty { 1278797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1279797d5daeSCorey Hardesty messages::internalError(aResp->res); 1280797d5daeSCorey Hardesty } 12816bd5a8d2SGunnar Mills return; 12826bd5a8d2SGunnar Mills } 12836bd5a8d2SGunnar Mills 12841e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled; 1285e05aec50SEd Tanous if (autoRebootEnabled) 12866bd5a8d2SGunnar Mills { 12876bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12886bd5a8d2SGunnar Mills "RetryAttempts"; 12896bd5a8d2SGunnar Mills } 12906bd5a8d2SGunnar Mills else 12916bd5a8d2SGunnar Mills { 1292002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled"; 12936bd5a8d2SGunnar Mills } 1294797d5daeSCorey Hardesty getAutomaticRebootAttempts(aResp); 129569f35306SGunnar Mills 129669f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 129769f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 129869f35306SGunnar Mills // RetryAttempts. 1299002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 13000fda0f12SGeorge Liu ["AutomaticRetryConfig@Redfish.AllowableValues"] = { 13010fda0f12SGeorge Liu "Disabled", "RetryAttempts"}; 13021e1e598dSJonathan Doman }); 13036bd5a8d2SGunnar Mills } 13046bd5a8d2SGunnar Mills 13056bd5a8d2SGunnar Mills /** 1306797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1307797d5daeSCorey Hardesty * 1308797d5daeSCorey Hardesty * @param[in] aResp Shared pointer for generating response message. 1309797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1310797d5daeSCorey Hardesty * 1311797d5daeSCorey Hardesty *@return None. 1312797d5daeSCorey Hardesty */ 1313797d5daeSCorey Hardesty 1314797d5daeSCorey Hardesty inline void 1315797d5daeSCorey Hardesty setAutomaticRetryAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1316797d5daeSCorey Hardesty const uint32_t retryAttempts) 1317797d5daeSCorey Hardesty { 1318797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts."; 1319797d5daeSCorey Hardesty crow::connections::systemBus->async_method_call( 1320797d5daeSCorey Hardesty [aResp](const boost::system::error_code& ec) { 1321797d5daeSCorey Hardesty if (ec) 1322797d5daeSCorey Hardesty { 1323797d5daeSCorey Hardesty BMCWEB_LOG_ERROR 1324797d5daeSCorey Hardesty << "DBUS response error: Set setAutomaticRetryAttempts" << ec; 1325797d5daeSCorey Hardesty messages::internalError(aResp->res); 1326797d5daeSCorey Hardesty return; 1327797d5daeSCorey Hardesty } 1328797d5daeSCorey Hardesty }, 1329797d5daeSCorey Hardesty "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 1330797d5daeSCorey Hardesty "org.freedesktop.DBus.Properties", "Set", 1331797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1332797d5daeSCorey Hardesty std::variant<uint32_t>(retryAttempts)); 1333797d5daeSCorey Hardesty } 1334797d5daeSCorey Hardesty 1335797d5daeSCorey Hardesty /** 1336c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1337c6a620f2SGeorge Liu * 1338c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1339c6a620f2SGeorge Liu * 1340c6a620f2SGeorge Liu * @return None. 1341c6a620f2SGeorge Liu */ 13428d1b46d7Szhanghch05 inline void 13438d1b46d7Szhanghch05 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1344c6a620f2SGeorge Liu { 1345c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1346c6a620f2SGeorge Liu 13471e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13481e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13491e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13501e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 13515e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 13525e7e2dc5SEd Tanous const std::string& policy) { 1353c6a620f2SGeorge Liu if (ec) 1354c6a620f2SGeorge Liu { 1355c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1356c6a620f2SGeorge Liu return; 1357c6a620f2SGeorge Liu } 1358c6a620f2SGeorge Liu 13590fda0f12SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 13600fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn", 1361c6a620f2SGeorge Liu "AlwaysOn"}, 13620fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff", 1363c6a620f2SGeorge Liu "AlwaysOff"}, 13640fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore", 13654ed47cb8SMatthew Barth "LastState"}, 13664ed47cb8SMatthew Barth // Return `AlwaysOff` when power restore policy set to "None" 13674ed47cb8SMatthew Barth {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None", 13684ed47cb8SMatthew Barth "AlwaysOff"}}; 1369c6a620f2SGeorge Liu 13701e1e598dSJonathan Doman auto policyMapsIt = policyMaps.find(policy); 1371c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1372c6a620f2SGeorge Liu { 1373c6a620f2SGeorge Liu messages::internalError(aResp->res); 1374c6a620f2SGeorge Liu return; 1375c6a620f2SGeorge Liu } 1376c6a620f2SGeorge Liu 1377c6a620f2SGeorge Liu aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second; 13781e1e598dSJonathan Doman }); 1379c6a620f2SGeorge Liu } 1380c6a620f2SGeorge Liu 1381c6a620f2SGeorge Liu /** 13821981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13831981771bSAli Ahmed * TPM is required for booting the host. 13841981771bSAli Ahmed * 13851981771bSAli Ahmed * @param[in] aResp Shared pointer for generating response message. 13861981771bSAli Ahmed * 13871981771bSAli Ahmed * @return None. 13881981771bSAli Ahmed */ 13891981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 13901981771bSAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp) 13911981771bSAli Ahmed { 13921981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 1393e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1394e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1395e99073f5SGeorge Liu dbus::utility::getSubTree( 1396e99073f5SGeorge Liu "/", 0, interfaces, 1397e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 1398b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 13991981771bSAli Ahmed if (ec) 14001981771bSAli Ahmed { 1401002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1402002d39b4SEd Tanous << ec; 14031981771bSAli Ahmed // This is an optional D-Bus object so just return if 14041981771bSAli Ahmed // error occurs 14051981771bSAli Ahmed return; 14061981771bSAli Ahmed } 140726f6976fSEd Tanous if (subtree.empty()) 14081981771bSAli Ahmed { 14091981771bSAli Ahmed // As noted above, this is an optional interface so just return 14101981771bSAli Ahmed // if there is no instance found 14111981771bSAli Ahmed return; 14121981771bSAli Ahmed } 14131981771bSAli Ahmed 14141981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14151981771bSAli Ahmed if (subtree.size() > 1) 14161981771bSAli Ahmed { 14171981771bSAli Ahmed BMCWEB_LOG_DEBUG 14181981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 14191981771bSAli Ahmed << subtree.size(); 14201981771bSAli Ahmed // Throw an internal Error and return 14211981771bSAli Ahmed messages::internalError(aResp->res); 14221981771bSAli Ahmed return; 14231981771bSAli Ahmed } 14241981771bSAli Ahmed 14251981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14261981771bSAli Ahmed // field 14271981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14281981771bSAli Ahmed { 14291981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 14301981771bSAli Ahmed messages::internalError(aResp->res); 14311981771bSAli Ahmed return; 14321981771bSAli Ahmed } 14331981771bSAli Ahmed 14341981771bSAli Ahmed const std::string& path = subtree[0].first; 14351981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14361981771bSAli Ahmed 14371981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14381e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14391e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14401e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 14415e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, bool tpmRequired) { 14428a592810SEd Tanous if (ec2) 14431981771bSAli Ahmed { 1444002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get" 14458a592810SEd Tanous << ec2; 14461981771bSAli Ahmed messages::internalError(aResp->res); 14471981771bSAli Ahmed return; 14481981771bSAli Ahmed } 14491981771bSAli Ahmed 14501e1e598dSJonathan Doman if (tpmRequired) 14511981771bSAli Ahmed { 1452002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14531981771bSAli Ahmed "Required"; 14541981771bSAli Ahmed } 14551981771bSAli Ahmed else 14561981771bSAli Ahmed { 1457002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14581981771bSAli Ahmed "Disabled"; 14591981771bSAli Ahmed } 14601e1e598dSJonathan Doman }); 1461e99073f5SGeorge Liu }); 14621981771bSAli Ahmed } 14631981771bSAli Ahmed 14641981771bSAli Ahmed /** 14651c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14661c05dae3SAli Ahmed * TPM is required for booting the host. 14671c05dae3SAli Ahmed * 14681c05dae3SAli Ahmed * @param[in] aResp Shared pointer for generating response message. 14691c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14701c05dae3SAli Ahmed * 14711c05dae3SAli Ahmed * @return None. 14721c05dae3SAli Ahmed */ 14731c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 14741c05dae3SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired) 14751c05dae3SAli Ahmed { 14761c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 1477e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1478e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1479e99073f5SGeorge Liu dbus::utility::getSubTree( 1480e99073f5SGeorge Liu "/", 0, interfaces, 1481e99073f5SGeorge Liu [aResp, 1482e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1483e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 14841c05dae3SAli Ahmed if (ec) 14851c05dae3SAli Ahmed { 1486002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1487002d39b4SEd Tanous << ec; 14881c05dae3SAli Ahmed messages::internalError(aResp->res); 14891c05dae3SAli Ahmed return; 14901c05dae3SAli Ahmed } 149126f6976fSEd Tanous if (subtree.empty()) 14921c05dae3SAli Ahmed { 14931c05dae3SAli Ahmed messages::propertyValueNotInList(aResp->res, "ComputerSystem", 14941c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 14951c05dae3SAli Ahmed return; 14961c05dae3SAli Ahmed } 14971c05dae3SAli Ahmed 14981c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 14991c05dae3SAli Ahmed if (subtree.size() > 1) 15001c05dae3SAli Ahmed { 15011c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 15021c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 15031c05dae3SAli Ahmed << subtree.size(); 15041c05dae3SAli Ahmed // Throw an internal Error and return 15051c05dae3SAli Ahmed messages::internalError(aResp->res); 15061c05dae3SAli Ahmed return; 15071c05dae3SAli Ahmed } 15081c05dae3SAli Ahmed 15091c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15101c05dae3SAli Ahmed // field 15111c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15121c05dae3SAli Ahmed { 15131c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 15141c05dae3SAli Ahmed messages::internalError(aResp->res); 15151c05dae3SAli Ahmed return; 15161c05dae3SAli Ahmed } 15171c05dae3SAli Ahmed 15181c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15191c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15201c05dae3SAli Ahmed 15211c05dae3SAli Ahmed if (serv.empty()) 15221c05dae3SAli Ahmed { 15231c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 15241c05dae3SAli Ahmed messages::internalError(aResp->res); 15251c05dae3SAli Ahmed return; 15261c05dae3SAli Ahmed } 15271c05dae3SAli Ahmed 15281c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 15291c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 15305e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 15318a592810SEd Tanous if (ec2) 15321c05dae3SAli Ahmed { 15330fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 15340fda0f12SGeorge Liu << "DBUS response error: Set TrustedModuleRequiredToBoot" 15358a592810SEd Tanous << ec2; 15361c05dae3SAli Ahmed messages::internalError(aResp->res); 15371c05dae3SAli Ahmed return; 15381c05dae3SAli Ahmed } 15391c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 15401c05dae3SAli Ahmed }, 15411c05dae3SAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Set", 15421c05dae3SAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1543168e20c1SEd Tanous dbus::utility::DbusVariantType(tpmRequired)); 1544e99073f5SGeorge Liu }); 15451c05dae3SAli Ahmed } 15461c05dae3SAli Ahmed 15471c05dae3SAli Ahmed /** 1548491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1549491d8ee7SSantosh Puranik * 1550491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1551cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1552cd9a4666SKonstantin Aladyshev * @return Integer error code. 1553cd9a4666SKonstantin Aladyshev */ 1554cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1555cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1556cd9a4666SKonstantin Aladyshev { 1557c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1558cd9a4666SKonstantin Aladyshev 1559c21865c4SKonstantin Aladyshev if (!bootType) 1560cd9a4666SKonstantin Aladyshev { 1561c21865c4SKonstantin Aladyshev return; 1562c21865c4SKonstantin Aladyshev } 1563c21865c4SKonstantin Aladyshev 1564cd9a4666SKonstantin Aladyshev // Source target specified 1565cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1566cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1567cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1568cd9a4666SKonstantin Aladyshev { 1569cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1570cd9a4666SKonstantin Aladyshev } 1571cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1572cd9a4666SKonstantin Aladyshev { 1573cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1574cd9a4666SKonstantin Aladyshev } 1575cd9a4666SKonstantin Aladyshev else 1576cd9a4666SKonstantin Aladyshev { 1577cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1578cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1579cd9a4666SKonstantin Aladyshev << *bootType; 1580cd9a4666SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootType, 1581cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1582cd9a4666SKonstantin Aladyshev return; 1583cd9a4666SKonstantin Aladyshev } 1584cd9a4666SKonstantin Aladyshev 1585cd9a4666SKonstantin Aladyshev // Act on validated parameters 1586cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1587cd9a4666SKonstantin Aladyshev 1588cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 15895e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1590cd9a4666SKonstantin Aladyshev if (ec) 1591cd9a4666SKonstantin Aladyshev { 1592cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1593cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1594cd9a4666SKonstantin Aladyshev { 1595cd9a4666SKonstantin Aladyshev messages::resourceNotFound(aResp->res, "Set", "BootType"); 1596cd9a4666SKonstantin Aladyshev return; 1597cd9a4666SKonstantin Aladyshev } 1598cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 1599cd9a4666SKonstantin Aladyshev return; 1600cd9a4666SKonstantin Aladyshev } 1601cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1602cd9a4666SKonstantin Aladyshev }, 1603c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1604c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1605cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1606cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1607168e20c1SEd Tanous dbus::utility::DbusVariantType(bootTypeStr)); 1608cd9a4666SKonstantin Aladyshev } 1609cd9a4666SKonstantin Aladyshev 1610cd9a4666SKonstantin Aladyshev /** 1611cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1612cd9a4666SKonstantin Aladyshev * 1613cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1614c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1615c21865c4SKonstantin Aladyshev * @return Integer error code. 1616c21865c4SKonstantin Aladyshev */ 1617c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1618c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1619c21865c4SKonstantin Aladyshev { 1620c21865c4SKonstantin Aladyshev if (!bootEnable) 1621c21865c4SKonstantin Aladyshev { 1622c21865c4SKonstantin Aladyshev return; 1623c21865c4SKonstantin Aladyshev } 1624c21865c4SKonstantin Aladyshev // Source target specified 1625c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1626c21865c4SKonstantin Aladyshev 1627c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1628c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1629c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1630c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1631c21865c4SKonstantin Aladyshev { 1632c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1633c21865c4SKonstantin Aladyshev } 1634c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1635c21865c4SKonstantin Aladyshev { 1636c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1637c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1638c21865c4SKonstantin Aladyshev } 1639c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1640c21865c4SKonstantin Aladyshev { 1641c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1642c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1643c21865c4SKonstantin Aladyshev } 1644c21865c4SKonstantin Aladyshev else 1645c21865c4SKonstantin Aladyshev { 16460fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 16470fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideEnabled: " 1648c21865c4SKonstantin Aladyshev << *bootEnable; 1649c21865c4SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootEnable, 1650c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1651c21865c4SKonstantin Aladyshev return; 1652c21865c4SKonstantin Aladyshev } 1653c21865c4SKonstantin Aladyshev 1654c21865c4SKonstantin Aladyshev // Act on validated parameters 1655c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1656c21865c4SKonstantin Aladyshev 1657c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 16585e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 16598a592810SEd Tanous if (ec2) 1660c21865c4SKonstantin Aladyshev { 16618a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1662c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1663c21865c4SKonstantin Aladyshev return; 1664c21865c4SKonstantin Aladyshev } 1665c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1666c21865c4SKonstantin Aladyshev }, 1667c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1668c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1669c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1670c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1671168e20c1SEd Tanous dbus::utility::DbusVariantType(bootOverrideEnable)); 1672c21865c4SKonstantin Aladyshev 1673c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1674c21865c4SKonstantin Aladyshev { 1675c21865c4SKonstantin Aladyshev return; 1676c21865c4SKonstantin Aladyshev } 1677c21865c4SKonstantin Aladyshev 1678c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1679c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1680c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1681c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1682c21865c4SKonstantin Aladyshev 1683c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 16845e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1685c21865c4SKonstantin Aladyshev if (ec) 1686c21865c4SKonstantin Aladyshev { 1687c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1688c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1689c21865c4SKonstantin Aladyshev return; 1690c21865c4SKonstantin Aladyshev } 1691c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1692c21865c4SKonstantin Aladyshev }, 1693c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1694c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1695c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1696c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1697168e20c1SEd Tanous dbus::utility::DbusVariantType(!bootOverridePersistent)); 1698c21865c4SKonstantin Aladyshev } 1699c21865c4SKonstantin Aladyshev 1700c21865c4SKonstantin Aladyshev /** 1701c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1702c21865c4SKonstantin Aladyshev * 1703c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1704491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1705491d8ee7SSantosh Puranik * 1706265c1602SJohnathan Mantey * @return Integer error code. 1707491d8ee7SSantosh Puranik */ 1708cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1709cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1710491d8ee7SSantosh Puranik { 1711c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1712c21865c4SKonstantin Aladyshev std::string bootModeStr; 1713944ffaf9SJohnathan Mantey 1714c21865c4SKonstantin Aladyshev if (!bootSource) 1715491d8ee7SSantosh Puranik { 1716c21865c4SKonstantin Aladyshev return; 1717c21865c4SKonstantin Aladyshev } 1718c21865c4SKonstantin Aladyshev 1719491d8ee7SSantosh Puranik // Source target specified 1720491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1721491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1722e662eae8SEd Tanous if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) != 1723e662eae8SEd Tanous 0) 1724491d8ee7SSantosh Puranik { 1725944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1726944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1727491d8ee7SSantosh Puranik << *bootSource; 1728491d8ee7SSantosh Puranik messages::propertyValueNotInList(aResp->res, *bootSource, 1729491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1730491d8ee7SSantosh Puranik return; 1731491d8ee7SSantosh Puranik } 1732491d8ee7SSantosh Puranik 1733944ffaf9SJohnathan Mantey // Act on validated parameters 1734944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1735944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1736944ffaf9SJohnathan Mantey 1737491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 17385e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1739491d8ee7SSantosh Puranik if (ec) 1740491d8ee7SSantosh Puranik { 1741491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1742491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1743491d8ee7SSantosh Puranik return; 1744491d8ee7SSantosh Puranik } 1745491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1746491d8ee7SSantosh Puranik }, 1747c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1748c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1749491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1750491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1751168e20c1SEd Tanous dbus::utility::DbusVariantType(bootSourceStr)); 1752944ffaf9SJohnathan Mantey 1753491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 17545e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1755491d8ee7SSantosh Puranik if (ec) 1756491d8ee7SSantosh Puranik { 1757491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1758491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1759491d8ee7SSantosh Puranik return; 1760491d8ee7SSantosh Puranik } 1761491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1762491d8ee7SSantosh Puranik }, 1763c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1764c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1765491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1766491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1767168e20c1SEd Tanous dbus::utility::DbusVariantType(bootModeStr)); 1768cd9a4666SKonstantin Aladyshev } 1769944ffaf9SJohnathan Mantey 1770cd9a4666SKonstantin Aladyshev /** 1771c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1772491d8ee7SSantosh Puranik * 1773491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1774491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1775cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1776491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1777491d8ee7SSantosh Puranik * 1778265c1602SJohnathan Mantey * @return Integer error code. 1779491d8ee7SSantosh Puranik */ 1780c21865c4SKonstantin Aladyshev 1781c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1782c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1783c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1784c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1785491d8ee7SSantosh Puranik { 1786491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1787491d8ee7SSantosh Puranik 1788c21865c4SKonstantin Aladyshev setBootModeOrSource(aResp, bootSource); 1789c21865c4SKonstantin Aladyshev setBootType(aResp, bootType); 1790c21865c4SKonstantin Aladyshev setBootEnable(aResp, bootEnable); 1791491d8ee7SSantosh Puranik } 1792491d8ee7SSantosh Puranik 1793c6a620f2SGeorge Liu /** 179498e386ecSGunnar Mills * @brief Sets AssetTag 179598e386ecSGunnar Mills * 179698e386ecSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 179798e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 179898e386ecSGunnar Mills * 179998e386ecSGunnar Mills * @return None. 180098e386ecSGunnar Mills */ 18018d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 180298e386ecSGunnar Mills const std::string& assetTag) 180398e386ecSGunnar Mills { 1804e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1805e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1806e99073f5SGeorge Liu dbus::utility::getSubTree( 1807e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1808b9d36b47SEd Tanous [aResp, 1809e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1810b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 181198e386ecSGunnar Mills if (ec) 181298e386ecSGunnar Mills { 181398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 181498e386ecSGunnar Mills messages::internalError(aResp->res); 181598e386ecSGunnar Mills return; 181698e386ecSGunnar Mills } 181726f6976fSEd Tanous if (subtree.empty()) 181898e386ecSGunnar Mills { 181998e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 182098e386ecSGunnar Mills messages::internalError(aResp->res); 182198e386ecSGunnar Mills return; 182298e386ecSGunnar Mills } 182398e386ecSGunnar Mills // Assume only 1 system D-Bus object 182498e386ecSGunnar Mills // Throw an error if there is more than 1 182598e386ecSGunnar Mills if (subtree.size() > 1) 182698e386ecSGunnar Mills { 182798e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 182898e386ecSGunnar Mills messages::internalError(aResp->res); 182998e386ecSGunnar Mills return; 183098e386ecSGunnar Mills } 183198e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 183298e386ecSGunnar Mills { 183398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 183498e386ecSGunnar Mills messages::internalError(aResp->res); 183598e386ecSGunnar Mills return; 183698e386ecSGunnar Mills } 183798e386ecSGunnar Mills 183898e386ecSGunnar Mills const std::string& path = subtree[0].first; 183998e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 184098e386ecSGunnar Mills 184198e386ecSGunnar Mills if (service.empty()) 184298e386ecSGunnar Mills { 184398e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 184498e386ecSGunnar Mills messages::internalError(aResp->res); 184598e386ecSGunnar Mills return; 184698e386ecSGunnar Mills } 184798e386ecSGunnar Mills 184898e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 18495e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 185098e386ecSGunnar Mills if (ec2) 185198e386ecSGunnar Mills { 1852002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set " 1853002d39b4SEd Tanous << ec2; 185498e386ecSGunnar Mills messages::internalError(aResp->res); 185598e386ecSGunnar Mills return; 185698e386ecSGunnar Mills } 185798e386ecSGunnar Mills }, 185898e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 185998e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 1860168e20c1SEd Tanous dbus::utility::DbusVariantType(assetTag)); 1861e99073f5SGeorge Liu }); 186298e386ecSGunnar Mills } 186398e386ecSGunnar Mills 186498e386ecSGunnar Mills /** 186569f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 186669f35306SGunnar Mills * 186769f35306SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 186869f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 186969f35306SGunnar Mills * 187069f35306SGunnar Mills * @return None. 187169f35306SGunnar Mills */ 18728d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1873f23b7296SEd Tanous const std::string& automaticRetryConfig) 187469f35306SGunnar Mills { 187569f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 187669f35306SGunnar Mills 187769f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1878543f4400SEd Tanous bool autoRebootEnabled = false; 187969f35306SGunnar Mills 188069f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 188169f35306SGunnar Mills { 188269f35306SGunnar Mills autoRebootEnabled = false; 188369f35306SGunnar Mills } 188469f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 188569f35306SGunnar Mills { 188669f35306SGunnar Mills autoRebootEnabled = true; 188769f35306SGunnar Mills } 188869f35306SGunnar Mills else 188969f35306SGunnar Mills { 18900fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: " 189169f35306SGunnar Mills << automaticRetryConfig; 189269f35306SGunnar Mills messages::propertyValueNotInList(aResp->res, automaticRetryConfig, 189369f35306SGunnar Mills "AutomaticRetryConfig"); 189469f35306SGunnar Mills return; 189569f35306SGunnar Mills } 189669f35306SGunnar Mills 189769f35306SGunnar Mills crow::connections::systemBus->async_method_call( 18985e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 189969f35306SGunnar Mills if (ec) 190069f35306SGunnar Mills { 190169f35306SGunnar Mills messages::internalError(aResp->res); 190269f35306SGunnar Mills return; 190369f35306SGunnar Mills } 190469f35306SGunnar Mills }, 190569f35306SGunnar Mills "xyz.openbmc_project.Settings", 190669f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 190769f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 190869f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1909168e20c1SEd Tanous dbus::utility::DbusVariantType(autoRebootEnabled)); 191069f35306SGunnar Mills } 191169f35306SGunnar Mills 191269f35306SGunnar Mills /** 1913c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1914c6a620f2SGeorge Liu * 1915c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1916c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1917c6a620f2SGeorge Liu * 1918c6a620f2SGeorge Liu * @return None. 1919c6a620f2SGeorge Liu */ 19208d1b46d7Szhanghch05 inline void 19218d1b46d7Szhanghch05 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 19224e69c904SGunnar Mills const std::string& policy) 1923c6a620f2SGeorge Liu { 1924c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1925c6a620f2SGeorge Liu 1926c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 19270fda0f12SGeorge Liu {"AlwaysOn", 19280fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"}, 19290fda0f12SGeorge Liu {"AlwaysOff", 19300fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"}, 19310fda0f12SGeorge Liu {"LastState", 19320fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}}; 1933c6a620f2SGeorge Liu 1934c6a620f2SGeorge Liu std::string powerRestorPolicy; 1935c6a620f2SGeorge Liu 19364e69c904SGunnar Mills auto policyMapsIt = policyMaps.find(policy); 1937c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1938c6a620f2SGeorge Liu { 19394e69c904SGunnar Mills messages::propertyValueNotInList(aResp->res, policy, 19404e69c904SGunnar Mills "PowerRestorePolicy"); 1941c6a620f2SGeorge Liu return; 1942c6a620f2SGeorge Liu } 1943c6a620f2SGeorge Liu 1944c6a620f2SGeorge Liu powerRestorPolicy = policyMapsIt->second; 1945c6a620f2SGeorge Liu 1946c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 19475e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1948c6a620f2SGeorge Liu if (ec) 1949c6a620f2SGeorge Liu { 1950c6a620f2SGeorge Liu messages::internalError(aResp->res); 1951c6a620f2SGeorge Liu return; 1952c6a620f2SGeorge Liu } 1953c6a620f2SGeorge Liu }, 1954c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1955c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1956c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1957c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1958168e20c1SEd Tanous dbus::utility::DbusVariantType(powerRestorPolicy)); 1959c6a620f2SGeorge Liu } 1960c6a620f2SGeorge Liu 1961a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 1962a6349918SAppaRao Puli /** 1963a6349918SAppaRao Puli * @brief Retrieves provisioning status 1964a6349918SAppaRao Puli * 1965a6349918SAppaRao Puli * @param[in] aResp Shared pointer for completing asynchronous calls. 1966a6349918SAppaRao Puli * 1967a6349918SAppaRao Puli * @return None. 1968a6349918SAppaRao Puli */ 19698d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp) 1970a6349918SAppaRao Puli { 1971a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 1972bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1973bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1974bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 19755e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 1976b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1977b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1978b99fb1a9SAppaRao Puli aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 197950626f4fSJames Feist aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 198050626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 198150626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 198250626f4fSJames Feist 1983a6349918SAppaRao Puli if (ec) 1984a6349918SAppaRao Puli { 1985a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1986b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1987b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1988a6349918SAppaRao Puli return; 1989a6349918SAppaRao Puli } 1990a6349918SAppaRao Puli 1991a6349918SAppaRao Puli const bool* provState = nullptr; 1992a6349918SAppaRao Puli const bool* lockState = nullptr; 1993bc1d29deSKrzysztof Grobelny 1994bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 19950d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 19960d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 1997bc1d29deSKrzysztof Grobelny 1998bc1d29deSKrzysztof Grobelny if (!success) 1999a6349918SAppaRao Puli { 2000bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 2001bc1d29deSKrzysztof Grobelny return; 2002a6349918SAppaRao Puli } 2003a6349918SAppaRao Puli 2004a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2005a6349918SAppaRao Puli { 2006a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 2007a6349918SAppaRao Puli messages::internalError(aResp->res); 2008a6349918SAppaRao Puli return; 2009a6349918SAppaRao Puli } 2010a6349918SAppaRao Puli 2011a6349918SAppaRao Puli if (*provState == true) 2012a6349918SAppaRao Puli { 2013a6349918SAppaRao Puli if (*lockState == true) 2014a6349918SAppaRao Puli { 2015a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2016a6349918SAppaRao Puli } 2017a6349918SAppaRao Puli else 2018a6349918SAppaRao Puli { 2019a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2020a6349918SAppaRao Puli } 2021a6349918SAppaRao Puli } 2022a6349918SAppaRao Puli else 2023a6349918SAppaRao Puli { 2024a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2025a6349918SAppaRao Puli } 2026bc1d29deSKrzysztof Grobelny }); 2027a6349918SAppaRao Puli } 2028a6349918SAppaRao Puli #endif 2029a6349918SAppaRao Puli 2030491d8ee7SSantosh Puranik /** 20313a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 20323a2d0424SChris Cain * 20333a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20343a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 20353a2d0424SChris Cain * 20363a2d0424SChris Cain * @return None. 20373a2d0424SChris Cain */ 20383a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 20393a2d0424SChris Cain const std::string& modeValue) 20403a2d0424SChris Cain { 20410fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20423a2d0424SChris Cain { 20433a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "Static"; 20443a2d0424SChris Cain } 20450fda0f12SGeorge Liu else if ( 20460fda0f12SGeorge Liu modeValue == 20470fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20483a2d0424SChris Cain { 20493a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 20503a2d0424SChris Cain } 20510fda0f12SGeorge Liu else if (modeValue == 20520fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20533a2d0424SChris Cain { 20543a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "PowerSaving"; 20553a2d0424SChris Cain } 20560fda0f12SGeorge Liu else if (modeValue == 20570fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20583a2d0424SChris Cain { 20593a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "OEM"; 20603a2d0424SChris Cain } 20613a2d0424SChris Cain else 20623a2d0424SChris Cain { 20633a2d0424SChris Cain // Any other values would be invalid 20643a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 20653a2d0424SChris Cain messages::internalError(aResp->res); 20663a2d0424SChris Cain } 20673a2d0424SChris Cain } 20683a2d0424SChris Cain 20693a2d0424SChris Cain /** 20703a2d0424SChris Cain * @brief Retrieves system power mode 20713a2d0424SChris Cain * 20723a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20733a2d0424SChris Cain * 20743a2d0424SChris Cain * @return None. 20753a2d0424SChris Cain */ 20763a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 20773a2d0424SChris Cain { 20783a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 20793a2d0424SChris Cain 20803a2d0424SChris Cain // Get Power Mode object path: 2081e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2082e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2083e99073f5SGeorge Liu dbus::utility::getSubTree( 2084e99073f5SGeorge Liu "/", 0, interfaces, 2085e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 2086b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 20873a2d0424SChris Cain if (ec) 20883a2d0424SChris Cain { 2089002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2090002d39b4SEd Tanous << ec; 20913a2d0424SChris Cain // This is an optional D-Bus object so just return if 20923a2d0424SChris Cain // error occurs 20933a2d0424SChris Cain return; 20943a2d0424SChris Cain } 20953a2d0424SChris Cain if (subtree.empty()) 20963a2d0424SChris Cain { 20973a2d0424SChris Cain // As noted above, this is an optional interface so just return 20983a2d0424SChris Cain // if there is no instance found 20993a2d0424SChris Cain return; 21003a2d0424SChris Cain } 21013a2d0424SChris Cain if (subtree.size() > 1) 21023a2d0424SChris Cain { 21033a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21043a2d0424SChris Cain // error 21053a2d0424SChris Cain BMCWEB_LOG_DEBUG 21063a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 21073a2d0424SChris Cain << subtree.size(); 21083a2d0424SChris Cain messages::internalError(aResp->res); 21093a2d0424SChris Cain return; 21103a2d0424SChris Cain } 21113a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21123a2d0424SChris Cain { 21133a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 21143a2d0424SChris Cain messages::internalError(aResp->res); 21153a2d0424SChris Cain return; 21163a2d0424SChris Cain } 21173a2d0424SChris Cain const std::string& path = subtree[0].first; 21183a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21193a2d0424SChris Cain if (service.empty()) 21203a2d0424SChris Cain { 21213a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 21223a2d0424SChris Cain messages::internalError(aResp->res); 21233a2d0424SChris Cain return; 21243a2d0424SChris Cain } 21253a2d0424SChris Cain // Valid Power Mode object found, now read the current value 21261e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 21271e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 21281e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 21295e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, 21301e1e598dSJonathan Doman const std::string& pmode) { 21318a592810SEd Tanous if (ec2) 21323a2d0424SChris Cain { 2133002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: " 21348a592810SEd Tanous << ec2; 21353a2d0424SChris Cain messages::internalError(aResp->res); 21363a2d0424SChris Cain return; 21373a2d0424SChris Cain } 21383a2d0424SChris Cain 2139002d39b4SEd Tanous aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2140002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 21413a2d0424SChris Cain 21421e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 21431e1e598dSJonathan Doman translatePowerMode(aResp, pmode); 21441e1e598dSJonathan Doman }); 2145e99073f5SGeorge Liu }); 21463a2d0424SChris Cain } 21473a2d0424SChris Cain 21483a2d0424SChris Cain /** 21493a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21503a2d0424SChris Cain * name associated with that string 21513a2d0424SChris Cain * 21523a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21533a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 21543a2d0424SChris Cain * 21553a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 21563a2d0424SChris Cain */ 21573a2d0424SChris Cain inline std::string 21583a2d0424SChris Cain validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21593a2d0424SChris Cain const std::string& modeString) 21603a2d0424SChris Cain { 21613a2d0424SChris Cain std::string mode; 21623a2d0424SChris Cain 21633a2d0424SChris Cain if (modeString == "Static") 21643a2d0424SChris Cain { 21653a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 21663a2d0424SChris Cain } 21673a2d0424SChris Cain else if (modeString == "MaximumPerformance") 21683a2d0424SChris Cain { 21690fda0f12SGeorge Liu mode = 21700fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 21713a2d0424SChris Cain } 21723a2d0424SChris Cain else if (modeString == "PowerSaving") 21733a2d0424SChris Cain { 21743a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 21753a2d0424SChris Cain } 21763a2d0424SChris Cain else 21773a2d0424SChris Cain { 21783a2d0424SChris Cain messages::propertyValueNotInList(aResp->res, modeString, "PowerMode"); 21793a2d0424SChris Cain } 21803a2d0424SChris Cain return mode; 21813a2d0424SChris Cain } 21823a2d0424SChris Cain 21833a2d0424SChris Cain /** 21843a2d0424SChris Cain * @brief Sets system power mode. 21853a2d0424SChris Cain * 21863a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21873a2d0424SChris Cain * @param[in] pmode System power mode from request. 21883a2d0424SChris Cain * 21893a2d0424SChris Cain * @return None. 21903a2d0424SChris Cain */ 21913a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21923a2d0424SChris Cain const std::string& pmode) 21933a2d0424SChris Cain { 21943a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 21953a2d0424SChris Cain 21963a2d0424SChris Cain std::string powerMode = validatePowerMode(aResp, pmode); 21973a2d0424SChris Cain if (powerMode.empty()) 21983a2d0424SChris Cain { 21993a2d0424SChris Cain return; 22003a2d0424SChris Cain } 22013a2d0424SChris Cain 22023a2d0424SChris Cain // Get Power Mode object path: 2203e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2204e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2205e99073f5SGeorge Liu dbus::utility::getSubTree( 2206e99073f5SGeorge Liu "/", 0, interfaces, 2207b9d36b47SEd Tanous [aResp, 2208e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2209b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22103a2d0424SChris Cain if (ec) 22113a2d0424SChris Cain { 2212002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2213002d39b4SEd Tanous << ec; 22143a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 22153a2d0424SChris Cain messages::internalError(aResp->res); 22163a2d0424SChris Cain return; 22173a2d0424SChris Cain } 22183a2d0424SChris Cain if (subtree.empty()) 22193a2d0424SChris Cain { 22203a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 22213a2d0424SChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 22223a2d0424SChris Cain "PowerMode"); 22233a2d0424SChris Cain return; 22243a2d0424SChris Cain } 22253a2d0424SChris Cain if (subtree.size() > 1) 22263a2d0424SChris Cain { 22273a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22283a2d0424SChris Cain // error 22293a2d0424SChris Cain BMCWEB_LOG_DEBUG 22303a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 22313a2d0424SChris Cain << subtree.size(); 22323a2d0424SChris Cain messages::internalError(aResp->res); 22333a2d0424SChris Cain return; 22343a2d0424SChris Cain } 22353a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22363a2d0424SChris Cain { 22373a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 22383a2d0424SChris Cain messages::internalError(aResp->res); 22393a2d0424SChris Cain return; 22403a2d0424SChris Cain } 22413a2d0424SChris Cain const std::string& path = subtree[0].first; 22423a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22433a2d0424SChris Cain if (service.empty()) 22443a2d0424SChris Cain { 22453a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 22463a2d0424SChris Cain messages::internalError(aResp->res); 22473a2d0424SChris Cain return; 22483a2d0424SChris Cain } 22493a2d0424SChris Cain 22503a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 22513a2d0424SChris Cain << path; 22523a2d0424SChris Cain 22533a2d0424SChris Cain // Set the Power Mode property 22543a2d0424SChris Cain crow::connections::systemBus->async_method_call( 22555e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 22568a592810SEd Tanous if (ec2) 22573a2d0424SChris Cain { 22583a2d0424SChris Cain messages::internalError(aResp->res); 22593a2d0424SChris Cain return; 22603a2d0424SChris Cain } 22613a2d0424SChris Cain }, 22623a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 22633a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2264168e20c1SEd Tanous dbus::utility::DbusVariantType(powerMode)); 2265e99073f5SGeorge Liu }); 22663a2d0424SChris Cain } 22673a2d0424SChris Cain 22683a2d0424SChris Cain /** 226951709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 227051709ffdSYong Li * 227151709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 227251709ffdSYong Li * 227351709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 227451709ffdSYong Li * translation cannot be done, returns an empty string. 227551709ffdSYong Li */ 227623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 227751709ffdSYong Li { 227851709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 227951709ffdSYong Li { 228051709ffdSYong Li return "None"; 228151709ffdSYong Li } 22823174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 228351709ffdSYong Li { 228451709ffdSYong Li return "ResetSystem"; 228551709ffdSYong Li } 22863174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 228751709ffdSYong Li { 228851709ffdSYong Li return "PowerDown"; 228951709ffdSYong Li } 22903174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 229151709ffdSYong Li { 229251709ffdSYong Li return "PowerCycle"; 229351709ffdSYong Li } 229451709ffdSYong Li 229551709ffdSYong Li return ""; 229651709ffdSYong Li } 229751709ffdSYong Li 229851709ffdSYong Li /** 2299c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2300c45f0082SYong Li * 2301c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2302c45f0082SYong Li * 2303c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2304c45f0082SYong Li *If translation cannot be done, returns an empty string. 2305c45f0082SYong Li */ 2306c45f0082SYong Li 230723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2308c45f0082SYong Li { 2309c45f0082SYong Li if (rfAction == "None") 2310c45f0082SYong Li { 2311c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2312c45f0082SYong Li } 23133174e4dfSEd Tanous if (rfAction == "PowerCycle") 2314c45f0082SYong Li { 2315c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2316c45f0082SYong Li } 23173174e4dfSEd Tanous if (rfAction == "PowerDown") 2318c45f0082SYong Li { 2319c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2320c45f0082SYong Li } 23213174e4dfSEd Tanous if (rfAction == "ResetSystem") 2322c45f0082SYong Li { 2323c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2324c45f0082SYong Li } 2325c45f0082SYong Li 2326c45f0082SYong Li return ""; 2327c45f0082SYong Li } 2328c45f0082SYong Li 2329c45f0082SYong Li /** 233051709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 233151709ffdSYong Li * 233251709ffdSYong Li * @param[in] aResp Shared pointer for completing asynchronous calls. 233351709ffdSYong Li * 233451709ffdSYong Li * @return None. 233551709ffdSYong Li */ 23368d1b46d7Szhanghch05 inline void 23378d1b46d7Szhanghch05 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 233851709ffdSYong Li { 233951709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 2340bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2341bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2342bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2343bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 23445e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 2345b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 234651709ffdSYong Li if (ec) 234751709ffdSYong Li { 234851709ffdSYong Li // watchdog service is stopped 234951709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 235051709ffdSYong Li return; 235151709ffdSYong Li } 235251709ffdSYong Li 235351709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 235451709ffdSYong Li 235551709ffdSYong Li nlohmann::json& hostWatchdogTimer = 235651709ffdSYong Li aResp->res.jsonValue["HostWatchdogTimer"]; 235751709ffdSYong Li 235851709ffdSYong Li // watchdog service is running/enabled 235951709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 236051709ffdSYong Li 2361bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2362bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 236351709ffdSYong Li 2364bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2365bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2366bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2367bc1d29deSKrzysztof Grobelny 2368bc1d29deSKrzysztof Grobelny if (!success) 236951709ffdSYong Li { 237051709ffdSYong Li messages::internalError(aResp->res); 2371601af5edSChicago Duan return; 237251709ffdSYong Li } 237351709ffdSYong Li 2374bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 237551709ffdSYong Li { 2376bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 237751709ffdSYong Li } 237851709ffdSYong Li 2379bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2380bc1d29deSKrzysztof Grobelny { 2381bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 238251709ffdSYong Li if (action.empty()) 238351709ffdSYong Li { 238451709ffdSYong Li messages::internalError(aResp->res); 2385601af5edSChicago Duan return; 238651709ffdSYong Li } 238751709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 238851709ffdSYong Li } 2389bc1d29deSKrzysztof Grobelny }); 239051709ffdSYong Li } 239151709ffdSYong Li 239251709ffdSYong Li /** 2393c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2394c45f0082SYong Li * 2395c45f0082SYong Li * @param[in] aResp Shared pointer for generating response message. 2396c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2397c45f0082SYong Li * RF request. 2398c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2399c45f0082SYong Li * 2400c45f0082SYong Li * @return None. 2401c45f0082SYong Li */ 24028d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 2403c45f0082SYong Li const std::optional<bool> wdtEnable, 2404c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2405c45f0082SYong Li { 2406c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2407c45f0082SYong Li 2408c45f0082SYong Li if (wdtTimeOutAction) 2409c45f0082SYong Li { 2410c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2411c45f0082SYong Li // check if TimeOut Action is Valid 2412c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2413c45f0082SYong Li { 2414c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2415c45f0082SYong Li << *wdtTimeOutAction; 2416c45f0082SYong Li messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction, 2417c45f0082SYong Li "TimeoutAction"); 2418c45f0082SYong Li return; 2419c45f0082SYong Li } 2420c45f0082SYong Li 2421c45f0082SYong Li crow::connections::systemBus->async_method_call( 24225e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 2423c45f0082SYong Li if (ec) 2424c45f0082SYong Li { 2425c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2426c45f0082SYong Li messages::internalError(aResp->res); 2427c45f0082SYong Li return; 2428c45f0082SYong Li } 2429c45f0082SYong Li }, 2430c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2431c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2432c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2433c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2434168e20c1SEd Tanous dbus::utility::DbusVariantType(wdtTimeOutActStr)); 2435c45f0082SYong Li } 2436c45f0082SYong Li 2437c45f0082SYong Li if (wdtEnable) 2438c45f0082SYong Li { 2439c45f0082SYong Li crow::connections::systemBus->async_method_call( 24405e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 2441c45f0082SYong Li if (ec) 2442c45f0082SYong Li { 2443c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2444c45f0082SYong Li messages::internalError(aResp->res); 2445c45f0082SYong Li return; 2446c45f0082SYong Li } 2447c45f0082SYong Li }, 2448c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2449c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2450c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2451c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2452168e20c1SEd Tanous dbus::utility::DbusVariantType(*wdtEnable)); 2453c45f0082SYong Li } 2454c45f0082SYong Li } 2455c45f0082SYong Li 245637bbf98cSChris Cain /** 245737bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 245837bbf98cSChris Cain * 245937bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 246037bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 246137bbf98cSChris Cain * 246237bbf98cSChris Cain * @return true if successful 246337bbf98cSChris Cain */ 24641e5b7c88SJiaqing Zhao inline bool 24651e5b7c88SJiaqing Zhao parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 24661e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 246737bbf98cSChris Cain { 2468bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2469bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2470bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2471bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2472bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2473bc1d29deSKrzysztof Grobelny 2474bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2475bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 24762661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 24772661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 24782661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2479bc1d29deSKrzysztof Grobelny 2480bc1d29deSKrzysztof Grobelny if (!success) 248137bbf98cSChris Cain { 248237bbf98cSChris Cain return false; 248337bbf98cSChris Cain } 2484bc1d29deSKrzysztof Grobelny 2485bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 248637bbf98cSChris Cain { 2487bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 248837bbf98cSChris Cain } 2489bc1d29deSKrzysztof Grobelny 2490bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 249137bbf98cSChris Cain { 2492bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2493bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 249437bbf98cSChris Cain } 2495bc1d29deSKrzysztof Grobelny 2496bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2497bc1d29deSKrzysztof Grobelny { 2498bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 249937bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 250037bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 250137bbf98cSChris Cain .count(); 250237bbf98cSChris Cain } 2503bc1d29deSKrzysztof Grobelny 2504bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 250537bbf98cSChris Cain { 2506bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2507bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 250837bbf98cSChris Cain } 2509bc1d29deSKrzysztof Grobelny 2510bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 251137bbf98cSChris Cain { 2512bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 251337bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 251437bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 251537bbf98cSChris Cain .count(); 251637bbf98cSChris Cain } 251737bbf98cSChris Cain 251837bbf98cSChris Cain return true; 251937bbf98cSChris Cain } 252037bbf98cSChris Cain 252137bbf98cSChris Cain /** 252237bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 252337bbf98cSChris Cain * 252437bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 252537bbf98cSChris Cain * 252637bbf98cSChris Cain * @return None. 252737bbf98cSChris Cain */ 252837bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 252937bbf98cSChris Cain { 253037bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 253137bbf98cSChris Cain 253237bbf98cSChris Cain // Get IdlePowerSaver object path: 2533e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2534e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2535e99073f5SGeorge Liu dbus::utility::getSubTree( 2536e99073f5SGeorge Liu "/", 0, interfaces, 2537e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 2538b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 253937bbf98cSChris Cain if (ec) 254037bbf98cSChris Cain { 254137bbf98cSChris Cain BMCWEB_LOG_DEBUG 254237bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 254337bbf98cSChris Cain << ec; 254437bbf98cSChris Cain messages::internalError(aResp->res); 254537bbf98cSChris Cain return; 254637bbf98cSChris Cain } 254737bbf98cSChris Cain if (subtree.empty()) 254837bbf98cSChris Cain { 254937bbf98cSChris Cain // This is an optional interface so just return 255037bbf98cSChris Cain // if there is no instance found 255137bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 255237bbf98cSChris Cain return; 255337bbf98cSChris Cain } 255437bbf98cSChris Cain if (subtree.size() > 1) 255537bbf98cSChris Cain { 255637bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 255737bbf98cSChris Cain // is an error 255837bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 255937bbf98cSChris Cain "Power.IdlePowerSaver objects: " 256037bbf98cSChris Cain << subtree.size(); 256137bbf98cSChris Cain messages::internalError(aResp->res); 256237bbf98cSChris Cain return; 256337bbf98cSChris Cain } 256437bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 256537bbf98cSChris Cain { 256637bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 256737bbf98cSChris Cain messages::internalError(aResp->res); 256837bbf98cSChris Cain return; 256937bbf98cSChris Cain } 257037bbf98cSChris Cain const std::string& path = subtree[0].first; 257137bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 257237bbf98cSChris Cain if (service.empty()) 257337bbf98cSChris Cain { 2574002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 257537bbf98cSChris Cain messages::internalError(aResp->res); 257637bbf98cSChris Cain return; 257737bbf98cSChris Cain } 257837bbf98cSChris Cain 257937bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2580bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2581bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2582bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 25835e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, 25841e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 25858a592810SEd Tanous if (ec2) 258637bbf98cSChris Cain { 258737bbf98cSChris Cain BMCWEB_LOG_ERROR 25888a592810SEd Tanous << "DBUS response error on IdlePowerSaver GetAll: " << ec2; 258937bbf98cSChris Cain messages::internalError(aResp->res); 259037bbf98cSChris Cain return; 259137bbf98cSChris Cain } 259237bbf98cSChris Cain 2593e05aec50SEd Tanous if (!parseIpsProperties(aResp, properties)) 259437bbf98cSChris Cain { 259537bbf98cSChris Cain messages::internalError(aResp->res); 259637bbf98cSChris Cain return; 259737bbf98cSChris Cain } 2598bc1d29deSKrzysztof Grobelny }); 2599e99073f5SGeorge Liu }); 260037bbf98cSChris Cain 260137bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 260237bbf98cSChris Cain } 260337bbf98cSChris Cain 260437bbf98cSChris Cain /** 260537bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 260637bbf98cSChris Cain * 260737bbf98cSChris Cain * @param[in] aResp Shared pointer for generating response message. 260837bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 260937bbf98cSChris Cain * RF request. 261037bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 261137bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 261237bbf98cSChris Cain * before entering idle state. 261337bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 261437bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 261537bbf98cSChris Cain * before exiting idle state 261637bbf98cSChris Cain * 261737bbf98cSChris Cain * @return None. 261837bbf98cSChris Cain */ 261937bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 262037bbf98cSChris Cain const std::optional<bool> ipsEnable, 262137bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 262237bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 262337bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 262437bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 262537bbf98cSChris Cain { 262637bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 262737bbf98cSChris Cain 262837bbf98cSChris Cain // Get IdlePowerSaver object path: 2629e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2630e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2631e99073f5SGeorge Liu dbus::utility::getSubTree( 2632e99073f5SGeorge Liu "/", 0, interfaces, 263337bbf98cSChris Cain [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2634e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2635b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 263637bbf98cSChris Cain if (ec) 263737bbf98cSChris Cain { 263837bbf98cSChris Cain BMCWEB_LOG_DEBUG 263937bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 264037bbf98cSChris Cain << ec; 264137bbf98cSChris Cain messages::internalError(aResp->res); 264237bbf98cSChris Cain return; 264337bbf98cSChris Cain } 264437bbf98cSChris Cain if (subtree.empty()) 264537bbf98cSChris Cain { 264637bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 264737bbf98cSChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 264837bbf98cSChris Cain "IdlePowerSaver"); 264937bbf98cSChris Cain return; 265037bbf98cSChris Cain } 265137bbf98cSChris Cain if (subtree.size() > 1) 265237bbf98cSChris Cain { 265337bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 265437bbf98cSChris Cain // is an error 26550fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 26560fda0f12SGeorge Liu << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: " 265737bbf98cSChris Cain << subtree.size(); 265837bbf98cSChris Cain messages::internalError(aResp->res); 265937bbf98cSChris Cain return; 266037bbf98cSChris Cain } 266137bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 266237bbf98cSChris Cain { 266337bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 266437bbf98cSChris Cain messages::internalError(aResp->res); 266537bbf98cSChris Cain return; 266637bbf98cSChris Cain } 266737bbf98cSChris Cain const std::string& path = subtree[0].first; 266837bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 266937bbf98cSChris Cain if (service.empty()) 267037bbf98cSChris Cain { 2671002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 267237bbf98cSChris Cain messages::internalError(aResp->res); 267337bbf98cSChris Cain return; 267437bbf98cSChris Cain } 267537bbf98cSChris Cain 267637bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 267737bbf98cSChris Cain // need to be updated 267837bbf98cSChris Cain 267937bbf98cSChris Cain if (ipsEnable) 268037bbf98cSChris Cain { 268137bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26825e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 26838a592810SEd Tanous if (ec2) 268437bbf98cSChris Cain { 26858a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 268637bbf98cSChris Cain messages::internalError(aResp->res); 268737bbf98cSChris Cain return; 268837bbf98cSChris Cain } 268937bbf98cSChris Cain }, 269037bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 2691002d39b4SEd Tanous "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 2692002d39b4SEd Tanous dbus::utility::DbusVariantType(*ipsEnable)); 269337bbf98cSChris Cain } 269437bbf98cSChris Cain if (ipsEnterUtil) 269537bbf98cSChris Cain { 269637bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26975e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 26988a592810SEd Tanous if (ec2) 269937bbf98cSChris Cain { 27008a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 270137bbf98cSChris Cain messages::internalError(aResp->res); 270237bbf98cSChris Cain return; 270337bbf98cSChris Cain } 270437bbf98cSChris Cain }, 270537bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 270637bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 270737bbf98cSChris Cain "EnterUtilizationPercent", 2708168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsEnterUtil)); 270937bbf98cSChris Cain } 271037bbf98cSChris Cain if (ipsEnterTime) 271137bbf98cSChris Cain { 271237bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 271337bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 271437bbf98cSChris Cain crow::connections::systemBus->async_method_call( 27155e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 27168a592810SEd Tanous if (ec2) 271737bbf98cSChris Cain { 27188a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 271937bbf98cSChris Cain messages::internalError(aResp->res); 272037bbf98cSChris Cain return; 272137bbf98cSChris Cain } 272237bbf98cSChris Cain }, 272337bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 272437bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2725168e20c1SEd Tanous "EnterDwellTime", 2726168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 272737bbf98cSChris Cain } 272837bbf98cSChris Cain if (ipsExitUtil) 272937bbf98cSChris Cain { 273037bbf98cSChris Cain crow::connections::systemBus->async_method_call( 27315e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 27328a592810SEd Tanous if (ec2) 273337bbf98cSChris Cain { 27348a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 273537bbf98cSChris Cain messages::internalError(aResp->res); 273637bbf98cSChris Cain return; 273737bbf98cSChris Cain } 273837bbf98cSChris Cain }, 273937bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 274037bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 274137bbf98cSChris Cain "ExitUtilizationPercent", 2742168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsExitUtil)); 274337bbf98cSChris Cain } 274437bbf98cSChris Cain if (ipsExitTime) 274537bbf98cSChris Cain { 274637bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 274737bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 274837bbf98cSChris Cain crow::connections::systemBus->async_method_call( 27495e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 27508a592810SEd Tanous if (ec2) 275137bbf98cSChris Cain { 27528a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 275337bbf98cSChris Cain messages::internalError(aResp->res); 275437bbf98cSChris Cain return; 275537bbf98cSChris Cain } 275637bbf98cSChris Cain }, 275737bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 275837bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2759168e20c1SEd Tanous "ExitDwellTime", 2760168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 276137bbf98cSChris Cain } 2762e99073f5SGeorge Liu }); 276337bbf98cSChris Cain 276437bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 276537bbf98cSChris Cain } 276637bbf98cSChris Cain 2767dd60b9edSEd Tanous inline void handleComputerSystemHead( 2768dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2769dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2770dd60b9edSEd Tanous { 2771dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2772dd60b9edSEd Tanous { 2773dd60b9edSEd Tanous return; 2774dd60b9edSEd Tanous } 2775dd60b9edSEd Tanous asyncResp->res.addHeader( 2776dd60b9edSEd Tanous boost::beast::http::field::link, 2777dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2778dd60b9edSEd Tanous } 2779dd60b9edSEd Tanous 2780c45f0082SYong Li /** 2781c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 2782c5b2abe0SLewanczyk, Dawid * Schema 2783c5b2abe0SLewanczyk, Dawid */ 27847e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app) 27851abe55efSEd Tanous { 27867e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2787dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 2788dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 2789dd60b9edSEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 2790dd60b9edSEd Tanous 2791dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2792ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 27937e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 2794f4c99e70SEd Tanous [&app](const crow::Request& req, 27957e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 27963ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2797f4c99e70SEd Tanous { 2798f4c99e70SEd Tanous return; 2799f4c99e70SEd Tanous } 2800dd60b9edSEd Tanous 2801dd60b9edSEd Tanous asyncResp->res.addHeader( 2802dd60b9edSEd Tanous boost::beast::http::field::link, 2803dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 28048d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28050f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28068d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28078d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2808462023adSSunitha Harish 28091e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2810002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 28111e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2812002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 28135e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 28141e1e598dSJonathan Doman const std::string& /*hostName*/) { 2815002d39b4SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 28162c70f800SEd Tanous ifaceArray = nlohmann::json::array(); 2817002d39b4SEd Tanous auto& count = asyncResp->res.jsonValue["Members@odata.count"]; 28181476687dSEd Tanous 28191476687dSEd Tanous nlohmann::json::object_t system; 28201476687dSEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 2821b2ba3072SPatrick Williams ifaceArray.emplace_back(std::move(system)); 282294bda602STim Lee count = ifaceArray.size(); 28238a592810SEd Tanous if (!ec2) 2824462023adSSunitha Harish { 2825462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 28261476687dSEd Tanous nlohmann::json::object_t hypervisor; 2827002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 2828b2ba3072SPatrick Williams ifaceArray.emplace_back(std::move(hypervisor)); 28292c70f800SEd Tanous count = ifaceArray.size(); 2830cb13a392SEd Tanous } 28311e1e598dSJonathan Doman }); 28327e860f15SJohn Edward Broadbent }); 2833c5b2abe0SLewanczyk, Dawid } 28347e860f15SJohn Edward Broadbent 28357e860f15SJohn Edward Broadbent /** 28367e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28377e860f15SJohn Edward Broadbent */ 28384f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28397e860f15SJohn Edward Broadbent { 284089492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 284189492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 284289492a15SPatrick Williams constexpr const char* interfaceName = 28437e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 284489492a15SPatrick Williams constexpr const char* method = "NMI"; 28457e860f15SJohn Edward Broadbent 28467e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28475e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28487e860f15SJohn Edward Broadbent if (ec) 28497e860f15SJohn Edward Broadbent { 28507e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 28517e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28527e860f15SJohn Edward Broadbent return; 28537e860f15SJohn Edward Broadbent } 28547e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28557e860f15SJohn Edward Broadbent }, 28567e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28577e860f15SJohn Edward Broadbent } 2858c5b2abe0SLewanczyk, Dawid 2859c5b2abe0SLewanczyk, Dawid /** 2860*fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 2861*fc903b3dSAndrew Geissler */ 2862*fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 2863*fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 2864*fc903b3dSAndrew Geissler std::string_view resetType, 2865*fc903b3dSAndrew Geissler crow::Response& res) 2866*fc903b3dSAndrew Geissler { 2867*fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 2868*fc903b3dSAndrew Geissler { 2869*fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 2870*fc903b3dSAndrew Geissler return; 2871*fc903b3dSAndrew Geissler } 2872*fc903b3dSAndrew Geissler 2873*fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 2874*fc903b3dSAndrew Geissler { 2875*fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "D-Bus response error: " << ec; 2876*fc903b3dSAndrew Geissler messages::internalError(res); 2877*fc903b3dSAndrew Geissler return; 2878*fc903b3dSAndrew Geissler } 2879*fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 2880*fc903b3dSAndrew Geissler 2881*fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 2882*fc903b3dSAndrew Geissler // user to retry in a bit 2883*fc903b3dSAndrew Geissler if ((errorMessage == 2884*fc903b3dSAndrew Geissler std::string_view( 2885*fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 2886*fc903b3dSAndrew Geissler (errorMessage == 2887*fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 2888*fc903b3dSAndrew Geissler { 2889*fc903b3dSAndrew Geissler BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now"; 2890*fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 2891*fc903b3dSAndrew Geissler return; 2892*fc903b3dSAndrew Geissler } 2893*fc903b3dSAndrew Geissler 2894*fc903b3dSAndrew Geissler BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec 2895*fc903b3dSAndrew Geissler << " sdbusplus:" << errorMessage; 2896*fc903b3dSAndrew Geissler messages::internalError(res); 2897*fc903b3dSAndrew Geissler } 2898*fc903b3dSAndrew Geissler 2899*fc903b3dSAndrew Geissler /** 2900cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 2901cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 2902cc340dd9SEd Tanous */ 29037e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app) 2904cc340dd9SEd Tanous { 2905cc340dd9SEd Tanous /** 2906cc340dd9SEd Tanous * Function handles POST method request. 2907cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 2908cc340dd9SEd Tanous */ 29097e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 29107e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/") 2911ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 2912002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 2913002d39b4SEd Tanous [&app](const crow::Request& req, 29147e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 29153ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 291645ca1b86SEd Tanous { 291745ca1b86SEd Tanous return; 291845ca1b86SEd Tanous } 29199712f8acSEd Tanous std::string resetType; 292015ed6780SWilly Tu if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", 29217e860f15SJohn Edward Broadbent resetType)) 2922cc340dd9SEd Tanous { 2923cc340dd9SEd Tanous return; 2924cc340dd9SEd Tanous } 2925cc340dd9SEd Tanous 2926d22c8396SJason M. Bills // Get the command and host vs. chassis 2927cc340dd9SEd Tanous std::string command; 2928543f4400SEd Tanous bool hostCommand = true; 2929d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2930cc340dd9SEd Tanous { 2931cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2932d22c8396SJason M. Bills hostCommand = true; 2933d22c8396SJason M. Bills } 2934d22c8396SJason M. Bills else if (resetType == "ForceOff") 2935d22c8396SJason M. Bills { 2936d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2937d22c8396SJason M. Bills hostCommand = false; 2938d22c8396SJason M. Bills } 2939d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2940d22c8396SJason M. Bills { 294186a0851aSJason M. Bills command = 294286a0851aSJason M. Bills "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 294386a0851aSJason M. Bills hostCommand = true; 2944cc340dd9SEd Tanous } 29459712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2946cc340dd9SEd Tanous { 2947cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2948d22c8396SJason M. Bills hostCommand = true; 2949cc340dd9SEd Tanous } 29509712f8acSEd Tanous else if (resetType == "GracefulRestart") 2951cc340dd9SEd Tanous { 29520fda0f12SGeorge Liu command = 29530fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2954d22c8396SJason M. Bills hostCommand = true; 2955d22c8396SJason M. Bills } 2956d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2957d22c8396SJason M. Bills { 295886a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 295986a0851aSJason M. Bills hostCommand = true; 2960cc340dd9SEd Tanous } 2961bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2962bfd5b826SLakshminarayana R. Kammath { 2963bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2964bfd5b826SLakshminarayana R. Kammath return; 2965bfd5b826SLakshminarayana R. Kammath } 2966cc340dd9SEd Tanous else 2967cc340dd9SEd Tanous { 29688d1b46d7Szhanghch05 messages::actionParameterUnknown(asyncResp->res, "Reset", 29698d1b46d7Szhanghch05 resetType); 2970cc340dd9SEd Tanous return; 2971cc340dd9SEd Tanous } 2972cc340dd9SEd Tanous 2973d22c8396SJason M. Bills if (hostCommand) 2974d22c8396SJason M. Bills { 2975cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 2976*fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 2977*fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 2978cc340dd9SEd Tanous if (ec) 2979cc340dd9SEd Tanous { 2980*fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 2981*fc903b3dSAndrew Geissler asyncResp->res); 2982*fc903b3dSAndrew Geissler 2983cc340dd9SEd Tanous return; 2984cc340dd9SEd Tanous } 2985f12894f8SJason M. Bills messages::success(asyncResp->res); 2986cc340dd9SEd Tanous }, 2987cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 2988cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 2989cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 29909712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 2991168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 2992cc340dd9SEd Tanous } 2993d22c8396SJason M. Bills else 2994d22c8396SJason M. Bills { 2995d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 2996*fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 2997*fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 2998d22c8396SJason M. Bills if (ec) 2999d22c8396SJason M. Bills { 3000*fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3001*fc903b3dSAndrew Geissler asyncResp->res); 3002d22c8396SJason M. Bills return; 3003d22c8396SJason M. Bills } 3004d22c8396SJason M. Bills messages::success(asyncResp->res); 3005d22c8396SJason M. Bills }, 3006d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 3007d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 3008d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 3009002d39b4SEd Tanous "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 3010168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 3011d22c8396SJason M. Bills } 30127e860f15SJohn Edward Broadbent }); 3013d22c8396SJason M. Bills } 3014cc340dd9SEd Tanous 301538c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead( 3016dd60b9edSEd Tanous App& app, const crow::Request& req, 3017dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3018dd60b9edSEd Tanous { 3019dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3020dd60b9edSEd Tanous { 3021dd60b9edSEd Tanous return; 3022dd60b9edSEd Tanous } 3023dd60b9edSEd Tanous 3024dd60b9edSEd Tanous asyncResp->res.addHeader( 3025dd60b9edSEd Tanous boost::beast::http::field::link, 3026dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3027dd60b9edSEd Tanous } 3028dd60b9edSEd Tanous 30295c3e9272SAbhishek Patel inline void afterPortRequest( 30305c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 30315c3e9272SAbhishek Patel const boost::system::error_code& ec, 30325c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 30335c3e9272SAbhishek Patel { 30345c3e9272SAbhishek Patel if (ec) 30355c3e9272SAbhishek Patel { 30365c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 30375c3e9272SAbhishek Patel return; 30385c3e9272SAbhishek Patel } 30395c3e9272SAbhishek Patel for (const auto& data : socketData) 30405c3e9272SAbhishek Patel { 30415c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 30425c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 30435c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 30445c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 30455c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 30465c3e9272SAbhishek Patel // need to retrieve port number for 30475c3e9272SAbhishek Patel // obmc-console-ssh service 30485c3e9272SAbhishek Patel if (protocolName == "SSH") 30495c3e9272SAbhishek Patel { 30505c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 305181c4e330SEd Tanous const boost::system::error_code& ec1, 30525c3e9272SAbhishek Patel int portNumber) { 30535c3e9272SAbhishek Patel if (ec1) 30545c3e9272SAbhishek Patel { 30555c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 30565c3e9272SAbhishek Patel return; 30575c3e9272SAbhishek Patel } 30585c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 30595c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 30605c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 30615c3e9272SAbhishek Patel }); 30625c3e9272SAbhishek Patel } 30635c3e9272SAbhishek Patel } 30645c3e9272SAbhishek Patel } 3065cc340dd9SEd Tanous /** 30666617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 3067c5b2abe0SLewanczyk, Dawid */ 30687e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app) 30691abe55efSEd Tanous { 3070dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 3071dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystem) 3072dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 3073dd60b9edSEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3074c5b2abe0SLewanczyk, Dawid /** 3075c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 3076c5b2abe0SLewanczyk, Dawid */ 307722d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3078ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3079002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 3080002d39b4SEd Tanous [&app](const crow::Request& req, 308122d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 308222d268cbSEd Tanous const std::string& systemName) { 30833ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 308445ca1b86SEd Tanous { 308545ca1b86SEd Tanous return; 308645ca1b86SEd Tanous } 3087746b56f3SAsmitha Karunanithi 3088746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3089746b56f3SAsmitha Karunanithi { 3090746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3091746b56f3SAsmitha Karunanithi return; 3092746b56f3SAsmitha Karunanithi } 3093746b56f3SAsmitha Karunanithi 309422d268cbSEd Tanous if (systemName != "system") 309522d268cbSEd Tanous { 309622d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 309722d268cbSEd Tanous systemName); 309822d268cbSEd Tanous return; 309922d268cbSEd Tanous } 3100dd60b9edSEd Tanous asyncResp->res.addHeader( 3101dd60b9edSEd Tanous boost::beast::http::field::link, 3102dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 31038d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 310437bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 31058d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 31068d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 31078d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 31088d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 31098d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 31105fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 31115fd0aafbSNinad Palsule { 31128d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 31138d1b46d7Szhanghch05 "Disabled"; 31148d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 31158d1b46d7Szhanghch05 "Disabled"; 31165fd0aafbSNinad Palsule } 3117cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3118cf0e004cSNinad Palsule uint64_t(0); 3119002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 312004a258f4SEd Tanous 31211476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 31221476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 31231476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 31241476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 31251476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 31261476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 31273179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 31283179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3129029573d4SEd Tanous 3130002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 31311476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 31321476687dSEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] 31331476687dSEd Tanous ["@Redfish.ActionInfo"] = 31341476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3135c5b2abe0SLewanczyk, Dawid 31361476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 31371476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 31381476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 31391476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3140c4bf6374SJason M. Bills 31411476687dSEd Tanous nlohmann::json::array_t managedBy; 31421476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 31431476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3144002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 31451476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 31461476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 31470e8ac5e7SGunnar Mills 31480e8ac5e7SGunnar Mills // Fill in SerialConsole info 3149002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3150002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = 3151002d39b4SEd Tanous true; 31521476687dSEd Tanous 31531476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = 31541476687dSEd Tanous true; 31551476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 31561476687dSEd Tanous asyncResp->res 31571476687dSEd Tanous .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 31581476687dSEd Tanous "Press ~. to exit console"; 31595c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 31605c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 31610e8ac5e7SGunnar Mills 31620e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 31630e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3164002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3165002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 3166002d39b4SEd Tanous 4; 3167613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3168613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 31691476687dSEd Tanous 31700e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 317113451e39SWilly Tu 317213451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 317313451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 317413451e39SWilly Tu { 31757a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3176b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 31772ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3178e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3179e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3180b49ac873SJames Feist 31817a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 31827a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 31837a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3184914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3185b49ac873SJames Feist if (ec) 3186b49ac873SJames Feist { 3187b49ac873SJames Feist // no inventory 3188b49ac873SJames Feist return; 3189b49ac873SJames Feist } 3190b49ac873SJames Feist 3191914e2d5dSEd Tanous health->inventory = resp; 31927a1dbc48SGeorge Liu }); 3193b49ac873SJames Feist health->populate(); 319413451e39SWilly Tu } 3195b49ac873SJames Feist 3196002d39b4SEd Tanous getMainChassisId(asyncResp, 3197002d39b4SEd Tanous [](const std::string& chassisId, 31988d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3199b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3200b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3201ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3202ef4c65b7SEd Tanous chassisId); 3203002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3204c5d03ff4SJennifer Lee }); 3205a3002228SAppaRao Puli 32069f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 32079f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3208a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 32095bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 32106c34de48SEd Tanous getHostState(asyncResp); 3211491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3212978b8803SAndrew Geissler getBootProgress(asyncResp); 3213b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3214472bd202SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices"); 321551709ffdSYong Li getHostWatchdogTimer(asyncResp); 3216c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 3217797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3218c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3219a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3220a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3221a6349918SAppaRao Puli #endif 32221981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 32233a2d0424SChris Cain getPowerMode(asyncResp); 322437bbf98cSChris Cain getIdlePowerSaver(asyncResp); 32257e860f15SJohn Edward Broadbent }); 3226550a6bf8SJiaqing Zhao 322722d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3228ed398213SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 32297e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 323045ca1b86SEd Tanous [&app](const crow::Request& req, 323122d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 323222d268cbSEd Tanous const std::string& systemName) { 32333ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 323445ca1b86SEd Tanous { 323545ca1b86SEd Tanous return; 323645ca1b86SEd Tanous } 323722d268cbSEd Tanous if (systemName != "system") 323822d268cbSEd Tanous { 323922d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 324022d268cbSEd Tanous systemName); 324122d268cbSEd Tanous return; 324222d268cbSEd Tanous } 324322d268cbSEd Tanous 3244dd60b9edSEd Tanous asyncResp->res.addHeader( 3245dd60b9edSEd Tanous boost::beast::http::field::link, 3246dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3247dd60b9edSEd Tanous 32489f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3249cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 325098e386ecSGunnar Mills std::optional<std::string> assetTag; 3251c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 32523a2d0424SChris Cain std::optional<std::string> powerMode; 3253550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3254550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3255550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3256550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3257550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3258550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3259797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3260550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 3261550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3262550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3263550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3264550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3265550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3266550a6bf8SJiaqing Zhao 3267550a6bf8SJiaqing Zhao // clang-format off 326815ed6780SWilly Tu if (!json_util::readJsonPatch( 3269550a6bf8SJiaqing Zhao req, asyncResp->res, 3270550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 32717e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3272550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3273550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3274550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3275550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3276550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3277550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3278550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3279550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3280550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3281797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3282550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 3283550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3284550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3285550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3286550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3287550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 32886617338dSEd Tanous { 32896617338dSEd Tanous return; 32906617338dSEd Tanous } 3291550a6bf8SJiaqing Zhao // clang-format on 3292491d8ee7SSantosh Puranik 32938d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3294c45f0082SYong Li 329598e386ecSGunnar Mills if (assetTag) 329698e386ecSGunnar Mills { 329798e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 329898e386ecSGunnar Mills } 329998e386ecSGunnar Mills 3300550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3301c45f0082SYong Li { 3302f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3303c45f0082SYong Li } 3304c45f0082SYong Li 3305cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 330669f35306SGunnar Mills { 3307002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3308491d8ee7SSantosh Puranik } 3309550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 331069f35306SGunnar Mills { 3311550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 331269f35306SGunnar Mills } 3313ac7e1e0bSAli Ahmed 3314797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3315797d5daeSCorey Hardesty { 3316797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3317797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3318797d5daeSCorey Hardesty } 3319797d5daeSCorey Hardesty 3320550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3321ac7e1e0bSAli Ahmed { 3322550a6bf8SJiaqing Zhao setTrustedModuleRequiredToBoot(asyncResp, 3323550a6bf8SJiaqing Zhao *bootTrustedModuleRequired); 332469f35306SGunnar Mills } 3325265c1602SJohnathan Mantey 33269f8bfa7cSGunnar Mills if (locationIndicatorActive) 33279f8bfa7cSGunnar Mills { 3328002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 33299f8bfa7cSGunnar Mills } 33309f8bfa7cSGunnar Mills 33317e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 33327e860f15SJohn Edward Broadbent // passed 33339712f8acSEd Tanous if (indicatorLed) 33346617338dSEd Tanous { 3335f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3336002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3337d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3338d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 33396617338dSEd Tanous } 3340c6a620f2SGeorge Liu 3341c6a620f2SGeorge Liu if (powerRestorePolicy) 3342c6a620f2SGeorge Liu { 33434e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3344c6a620f2SGeorge Liu } 33453a2d0424SChris Cain 33463a2d0424SChris Cain if (powerMode) 33473a2d0424SChris Cain { 33483a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 33493a2d0424SChris Cain } 335037bbf98cSChris Cain 3351550a6bf8SJiaqing Zhao if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || 3352550a6bf8SJiaqing Zhao ipsExitTime) 335337bbf98cSChris Cain { 3354002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3355002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 335637bbf98cSChris Cain } 33577e860f15SJohn Edward Broadbent }); 3358c5b2abe0SLewanczyk, Dawid } 33591cb1a9e6SAppaRao Puli 336038c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3361dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 3362dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3363dd60b9edSEd Tanous { 3364dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3365dd60b9edSEd Tanous { 3366dd60b9edSEd Tanous return; 3367dd60b9edSEd Tanous } 3368dd60b9edSEd Tanous asyncResp->res.addHeader( 3369dd60b9edSEd Tanous boost::beast::http::field::link, 3370dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3371dd60b9edSEd Tanous } 3372dd60b9edSEd Tanous 33731cb1a9e6SAppaRao Puli /** 33741cb1a9e6SAppaRao Puli * SystemResetActionInfo derived class for delivering Computer Systems 33751cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 33761cb1a9e6SAppaRao Puli */ 33777e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app) 33781cb1a9e6SAppaRao Puli { 3379dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/") 3380dd60b9edSEd Tanous .privileges(redfish::privileges::headActionInfo) 3381dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3382dd60b9edSEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 33831cb1a9e6SAppaRao Puli /** 33841cb1a9e6SAppaRao Puli * Functions triggers appropriate requests on DBus 33851cb1a9e6SAppaRao Puli */ 338622d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3387ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 33887e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 338945ca1b86SEd Tanous [&app](const crow::Request& req, 339022d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 339122d268cbSEd Tanous const std::string& systemName) { 33923ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 339345ca1b86SEd Tanous { 339445ca1b86SEd Tanous return; 339545ca1b86SEd Tanous } 3396746b56f3SAsmitha Karunanithi 3397746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3398746b56f3SAsmitha Karunanithi { 3399746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3400746b56f3SAsmitha Karunanithi return; 3401746b56f3SAsmitha Karunanithi } 3402746b56f3SAsmitha Karunanithi 340322d268cbSEd Tanous if (systemName != "system") 340422d268cbSEd Tanous { 340522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 340622d268cbSEd Tanous systemName); 340722d268cbSEd Tanous return; 340822d268cbSEd Tanous } 340922d268cbSEd Tanous 3410dd60b9edSEd Tanous asyncResp->res.addHeader( 3411dd60b9edSEd Tanous boost::beast::http::field::link, 3412dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34131476687dSEd Tanous 34141476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 34151476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 34161476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 34171476687dSEd Tanous "#ActionInfo.v1_1_2.ActionInfo"; 34181476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34191476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34203215e700SNan Zhou 34213215e700SNan Zhou nlohmann::json::array_t parameters; 34223215e700SNan Zhou nlohmann::json::object_t parameter; 34233215e700SNan Zhou 34243215e700SNan Zhou parameter["Name"] = "ResetType"; 34253215e700SNan Zhou parameter["Required"] = true; 34263215e700SNan Zhou parameter["DataType"] = "String"; 34273215e700SNan Zhou nlohmann::json::array_t allowableValues; 34283215e700SNan Zhou allowableValues.emplace_back("On"); 34293215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 34303215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 34313215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 34323215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 34333215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 34343215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 34353215e700SNan Zhou allowableValues.emplace_back("Nmi"); 34363215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 34373215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 34383215e700SNan Zhou 34393215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 34407e860f15SJohn Edward Broadbent }); 34411cb1a9e6SAppaRao Puli } 3442c5b2abe0SLewanczyk, Dawid } // namespace redfish 3443