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 183ccb3adbSEd Tanous #include "app.hpp" 191e1e598dSJonathan Doman #include "dbus_singleton.hpp" 207a1dbc48SGeorge Liu #include "dbus_utility.hpp" 21b49ac873SJames Feist #include "health.hpp" 22746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 231c8fba97SJames Feist #include "led.hpp" 24f5c9f8bdSJason M. Bills #include "pcie.hpp" 25f4c99e70SEd Tanous #include "query.hpp" 26c5d03ff4SJennifer Lee #include "redfish_util.hpp" 273ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 283ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 293ccb3adbSEd Tanous #include "utils/json_utils.hpp" 303ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 312b82937eSEd Tanous #include "utils/time_utils.hpp" 32c5d03ff4SJennifer Lee 339712f8acSEd Tanous #include <boost/container/flat_map.hpp> 34e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 35ef4c65b7SEd Tanous #include <boost/url/format.hpp> 361e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 37bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 381214b7e7SGunnar Mills 397a1dbc48SGeorge Liu #include <array> 407a1dbc48SGeorge Liu #include <string_view> 41abf2add6SEd Tanous #include <variant> 42c5b2abe0SLewanczyk, Dawid 431abe55efSEd Tanous namespace redfish 441abe55efSEd Tanous { 45c5b2abe0SLewanczyk, Dawid 465c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 475c3e9272SAbhishek Patel protocolToDBusForSystems{ 485c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 495c3e9272SAbhishek Patel 509d3ae10eSAlpana Kumari /** 519d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 529d3ae10eSAlpana Kumari * 539d3ae10eSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 549d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 559d3ae10eSAlpana Kumari * 569d3ae10eSAlpana Kumari * @return None. 579d3ae10eSAlpana Kumari */ 588d1b46d7Szhanghch05 inline void 598d1b46d7Szhanghch05 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 601e1e598dSJonathan Doman bool isDimmFunctional) 619d3ae10eSAlpana Kumari { 621e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional; 639d3ae10eSAlpana Kumari 649d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 659d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 669d3ae10eSAlpana Kumari // ENABLED. 6702cad96eSEd Tanous const nlohmann::json& prevMemSummary = 689d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 699d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 709d3ae10eSAlpana Kumari { 71e05aec50SEd Tanous if (isDimmFunctional) 729d3ae10eSAlpana Kumari { 739d3ae10eSAlpana Kumari aResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 749d3ae10eSAlpana Kumari "Enabled"; 759d3ae10eSAlpana Kumari } 769d3ae10eSAlpana Kumari } 779d3ae10eSAlpana Kumari } 789d3ae10eSAlpana Kumari 7957e8c9beSAlpana Kumari /* 8057e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 8157e8c9beSAlpana Kumari * CPU Functional State 8257e8c9beSAlpana Kumari * 8357e8c9beSAlpana Kumari * @param[in] aResp Shared pointer for completing asynchronous calls 8457e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 8557e8c9beSAlpana Kumari * 8657e8c9beSAlpana Kumari * @return None. 8757e8c9beSAlpana Kumari */ 881e1e598dSJonathan Doman inline void 891e1e598dSJonathan Doman modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 901e1e598dSJonathan Doman bool isCpuFunctional) 9157e8c9beSAlpana Kumari { 921e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional; 9357e8c9beSAlpana Kumari 9402cad96eSEd Tanous const nlohmann::json& prevProcState = 9557e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 9657e8c9beSAlpana Kumari 9757e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 9857e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 9957e8c9beSAlpana Kumari // Functional. 10057e8c9beSAlpana Kumari if (prevProcState == "Disabled") 10157e8c9beSAlpana Kumari { 102e05aec50SEd Tanous if (isCpuFunctional) 10357e8c9beSAlpana Kumari { 10457e8c9beSAlpana Kumari aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 10557e8c9beSAlpana Kumari "Enabled"; 10657e8c9beSAlpana Kumari } 10757e8c9beSAlpana Kumari } 10857e8c9beSAlpana Kumari } 10957e8c9beSAlpana Kumari 110*cf0e004cSNinad Palsule /* 111*cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 112*cf0e004cSNinad Palsule * 113*cf0e004cSNinad Palsule * @param[in] aResp Shared pointer for completing asynchronous calls 114*cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 115*cf0e004cSNinad Palsule * 116*cf0e004cSNinad Palsule * @return None. 117*cf0e004cSNinad Palsule */ 118*cf0e004cSNinad Palsule inline void 119*cf0e004cSNinad Palsule modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 120*cf0e004cSNinad Palsule bool isCpuPresent) 121*cf0e004cSNinad Palsule { 122*cf0e004cSNinad Palsule BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent; 123*cf0e004cSNinad Palsule 124*cf0e004cSNinad Palsule if (isCpuPresent) 125*cf0e004cSNinad Palsule { 126*cf0e004cSNinad Palsule nlohmann::json& procCount = 127*cf0e004cSNinad Palsule aResp->res.jsonValue["ProcessorSummary"]["Count"]; 128*cf0e004cSNinad Palsule auto* procCountPtr = 129*cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 130*cf0e004cSNinad Palsule if (procCountPtr != nullptr) 131*cf0e004cSNinad Palsule { 132*cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 133*cf0e004cSNinad Palsule *procCountPtr += 1; 134*cf0e004cSNinad Palsule } 135*cf0e004cSNinad Palsule } 136*cf0e004cSNinad Palsule } 137*cf0e004cSNinad Palsule 138382d6475SAli Ahmed inline void getProcessorProperties( 139382d6475SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, 140382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 141382d6475SAli Ahmed properties) 14203fbed92SAli Ahmed { 14303fbed92SAli Ahmed BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties."; 14403fbed92SAli Ahmed 14503fbed92SAli Ahmed // TODO: Get Model 14603fbed92SAli Ahmed 147bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 14803fbed92SAli Ahmed 149bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 150bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 15103fbed92SAli Ahmed 152bc1d29deSKrzysztof Grobelny if (!success) 15303fbed92SAli Ahmed { 15403fbed92SAli Ahmed messages::internalError(aResp->res); 15503fbed92SAli Ahmed return; 15603fbed92SAli Ahmed } 15703fbed92SAli Ahmed 158bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 15903fbed92SAli Ahmed { 160bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 161bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 162bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 163bc1d29deSKrzysztof Grobelny 164bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 165bc1d29deSKrzysztof Grobelny { 166bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 16703fbed92SAli Ahmed } 16803fbed92SAli Ahmed else 16903fbed92SAli Ahmed { 170bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 17103fbed92SAli Ahmed } 17203fbed92SAli Ahmed } 17303fbed92SAli Ahmed } 17403fbed92SAli Ahmed 17503fbed92SAli Ahmed /* 17603fbed92SAli Ahmed * @brief Get ProcessorSummary fields 17703fbed92SAli Ahmed * 17803fbed92SAli Ahmed * @param[in] aResp Shared pointer for completing asynchronous calls 17903fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 18003fbed92SAli Ahmed * @param[in] path dbus path for Cpu 18103fbed92SAli Ahmed * 18203fbed92SAli Ahmed * @return None. 18303fbed92SAli Ahmed */ 18403fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 18503fbed92SAli Ahmed const std::string& service, 18603fbed92SAli Ahmed const std::string& path) 18703fbed92SAli Ahmed { 1885e7e2dc5SEd Tanous auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3, 189382d6475SAli Ahmed const bool cpuPresenceCheck) { 190382d6475SAli Ahmed if (ec3) 191382d6475SAli Ahmed { 192382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 193382d6475SAli Ahmed return; 194382d6475SAli Ahmed } 195382d6475SAli Ahmed modifyCpuPresenceState(aResp, cpuPresenceCheck); 196382d6475SAli Ahmed }; 197382d6475SAli Ahmed 198*cf0e004cSNinad Palsule // Get the Presence of CPU 199*cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 200*cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 201*cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 202*cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 203*cf0e004cSNinad Palsule 2045e7e2dc5SEd Tanous auto getCpuFunctionalState = [aResp](const boost::system::error_code& ec3, 205382d6475SAli Ahmed const bool cpuFunctionalCheck) { 206382d6475SAli Ahmed if (ec3) 207382d6475SAli Ahmed { 208382d6475SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 209382d6475SAli Ahmed return; 210382d6475SAli Ahmed } 211382d6475SAli Ahmed modifyCpuFunctionalState(aResp, cpuFunctionalCheck); 212382d6475SAli Ahmed }; 213382d6475SAli Ahmed 214382d6475SAli Ahmed // Get the Functional State 215382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 216382d6475SAli Ahmed *crow::connections::systemBus, service, path, 217382d6475SAli Ahmed "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional", 218382d6475SAli Ahmed std::move(getCpuFunctionalState)); 219382d6475SAli Ahmed 220bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 221bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 222bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 22303fbed92SAli Ahmed [aResp, service, 2245e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 225b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 22603fbed92SAli Ahmed if (ec2) 22703fbed92SAli Ahmed { 22803fbed92SAli Ahmed BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 22903fbed92SAli Ahmed messages::internalError(aResp->res); 23003fbed92SAli Ahmed return; 23103fbed92SAli Ahmed } 232382d6475SAli Ahmed getProcessorProperties(aResp, properties); 233bc1d29deSKrzysztof Grobelny }); 23403fbed92SAli Ahmed } 23503fbed92SAli Ahmed 23657e8c9beSAlpana Kumari /* 237*cf0e004cSNinad Palsule * @brief processMemoryProperties fields 238*cf0e004cSNinad Palsule * 239*cf0e004cSNinad Palsule * @param[in] aResp Shared pointer for completing asynchronous calls 240*cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 241*cf0e004cSNinad Palsule * @param[in] path dbus path for Memory 242*cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 243*cf0e004cSNinad Palsule * 244*cf0e004cSNinad Palsule * @return None. 245*cf0e004cSNinad Palsule */ 246*cf0e004cSNinad Palsule inline void 247*cf0e004cSNinad Palsule processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 248*cf0e004cSNinad Palsule const std::string& service, const std::string& path, 249*cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 250*cf0e004cSNinad Palsule { 251*cf0e004cSNinad Palsule BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties."; 252*cf0e004cSNinad Palsule 253*cf0e004cSNinad Palsule if (properties.empty()) 254*cf0e004cSNinad Palsule { 255*cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 256*cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 257*cf0e004cSNinad Palsule "xyz.openbmc_project.State." 258*cf0e004cSNinad Palsule "Decorator.OperationalStatus", 259*cf0e004cSNinad Palsule "Functional", 260*cf0e004cSNinad Palsule [aResp](const boost::system::error_code& ec3, bool dimmState) { 261*cf0e004cSNinad Palsule if (ec3) 262*cf0e004cSNinad Palsule { 263*cf0e004cSNinad Palsule BMCWEB_LOG_ERROR << "DBUS response error " << ec3; 264*cf0e004cSNinad Palsule return; 265*cf0e004cSNinad Palsule } 266*cf0e004cSNinad Palsule updateDimmProperties(aResp, dimmState); 267*cf0e004cSNinad Palsule }); 268*cf0e004cSNinad Palsule return; 269*cf0e004cSNinad Palsule } 270*cf0e004cSNinad Palsule 271*cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 272*cf0e004cSNinad Palsule 273*cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 274*cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 275*cf0e004cSNinad Palsule memorySizeInKB); 276*cf0e004cSNinad Palsule 277*cf0e004cSNinad Palsule if (!success) 278*cf0e004cSNinad Palsule { 279*cf0e004cSNinad Palsule messages::internalError(aResp->res); 280*cf0e004cSNinad Palsule return; 281*cf0e004cSNinad Palsule } 282*cf0e004cSNinad Palsule 283*cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 284*cf0e004cSNinad Palsule { 285*cf0e004cSNinad Palsule nlohmann::json& totalMemory = 286*cf0e004cSNinad Palsule aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 287*cf0e004cSNinad Palsule const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>(); 288*cf0e004cSNinad Palsule if (preValue == nullptr) 289*cf0e004cSNinad Palsule { 290*cf0e004cSNinad Palsule aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 291*cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024); 292*cf0e004cSNinad Palsule } 293*cf0e004cSNinad Palsule else 294*cf0e004cSNinad Palsule { 295*cf0e004cSNinad Palsule aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 296*cf0e004cSNinad Palsule *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue; 297*cf0e004cSNinad Palsule } 298*cf0e004cSNinad Palsule aResp->res.jsonValue["MemorySummary"]["Status"]["State"] = "Enabled"; 299*cf0e004cSNinad Palsule } 300*cf0e004cSNinad Palsule } 301*cf0e004cSNinad Palsule 302*cf0e004cSNinad Palsule /* 303*cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 304*cf0e004cSNinad Palsule * 305*cf0e004cSNinad Palsule * @param[in] aResp Shared pointer for completing asynchronous calls 306*cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 307*cf0e004cSNinad Palsule * @param[in] path dbus path for memory 308*cf0e004cSNinad Palsule * 309*cf0e004cSNinad Palsule * @return None. 310*cf0e004cSNinad Palsule */ 311*cf0e004cSNinad Palsule inline void getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 312*cf0e004cSNinad Palsule const std::string& service, 313*cf0e004cSNinad Palsule const std::string& path) 314*cf0e004cSNinad Palsule { 315*cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 316*cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 317*cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 318*cf0e004cSNinad Palsule [aResp, service, 319*cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 320*cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 321*cf0e004cSNinad Palsule if (ec2) 322*cf0e004cSNinad Palsule { 323*cf0e004cSNinad Palsule BMCWEB_LOG_ERROR << "DBUS response error " << ec2; 324*cf0e004cSNinad Palsule messages::internalError(aResp->res); 325*cf0e004cSNinad Palsule return; 326*cf0e004cSNinad Palsule } 327*cf0e004cSNinad Palsule processMemoryProperties(aResp, service, path, properties); 328*cf0e004cSNinad Palsule }); 329*cf0e004cSNinad Palsule } 330*cf0e004cSNinad Palsule 331*cf0e004cSNinad Palsule /* 332c5b2abe0SLewanczyk, Dawid * @brief Retrieves computer system properties over dbus 333c5b2abe0SLewanczyk, Dawid * 334c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls 3358f9ee3cdSGunnar Mills * @param[in] systemHealth Shared HealthPopulate pointer 336c5b2abe0SLewanczyk, Dawid * 337c5b2abe0SLewanczyk, Dawid * @return None. 338c5b2abe0SLewanczyk, Dawid */ 339b5a76932SEd Tanous inline void 3408d1b46d7Szhanghch05 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 341b5a76932SEd Tanous const std::shared_ptr<HealthPopulate>& systemHealth) 3421abe55efSEd Tanous { 34355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get available system components."; 344e99073f5SGeorge Liu constexpr std::array<std::string_view, 5> interfaces = { 345e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Asset", 346e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cpu", 347e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm", 348e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System", 349e99073f5SGeorge Liu "xyz.openbmc_project.Common.UUID", 350e99073f5SGeorge Liu }; 351e99073f5SGeorge Liu dbus::utility::getSubTree( 352e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 353b9d36b47SEd Tanous [aResp, 354e99073f5SGeorge Liu systemHealth](const boost::system::error_code& ec, 355b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 3561abe55efSEd Tanous if (ec) 3571abe55efSEd Tanous { 35855c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error"; 359f12894f8SJason M. Bills messages::internalError(aResp->res); 360c5b2abe0SLewanczyk, Dawid return; 361c5b2abe0SLewanczyk, Dawid } 362c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 363002d39b4SEd Tanous for (const std::pair< 364002d39b4SEd Tanous std::string, 365002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 3661214b7e7SGunnar Mills object : subtree) 3671abe55efSEd Tanous { 368c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 36955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Got path: " << path; 370002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 3711214b7e7SGunnar Mills connectionNames = object.second; 37226f6976fSEd Tanous if (connectionNames.empty()) 3731abe55efSEd Tanous { 374c5b2abe0SLewanczyk, Dawid continue; 375c5b2abe0SLewanczyk, Dawid } 376029573d4SEd Tanous 3775bc2dc8eSJames Feist auto memoryHealth = std::make_shared<HealthPopulate>( 378dfababfcSNan Zhou aResp, "/MemorySummary/Status"_json_pointer); 3795bc2dc8eSJames Feist 3805bc2dc8eSJames Feist auto cpuHealth = std::make_shared<HealthPopulate>( 381dfababfcSNan Zhou aResp, "/ProcessorSummary/Status"_json_pointer); 3825bc2dc8eSJames Feist 3835bc2dc8eSJames Feist systemHealth->children.emplace_back(memoryHealth); 3845bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 3855bc2dc8eSJames Feist 3866c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 3876c34de48SEd Tanous // BiosVer 38804a258f4SEd Tanous for (const auto& connection : connectionNames) 3891abe55efSEd Tanous { 39004a258f4SEd Tanous for (const auto& interfaceName : connection.second) 3911abe55efSEd Tanous { 39204a258f4SEd Tanous if (interfaceName == 39304a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 3941abe55efSEd Tanous { 3951abe55efSEd Tanous BMCWEB_LOG_DEBUG 39604a258f4SEd Tanous << "Found Dimm, now get its properties."; 3979d3ae10eSAlpana Kumari 398*cf0e004cSNinad Palsule getMemorySummary(aResp, connection.first, path); 3995bc2dc8eSJames Feist 4005bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 4011abe55efSEd Tanous } 40204a258f4SEd Tanous else if (interfaceName == 40304a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4041abe55efSEd Tanous { 4051abe55efSEd Tanous BMCWEB_LOG_DEBUG 40604a258f4SEd Tanous << "Found Cpu, now get its properties."; 40757e8c9beSAlpana Kumari 40803fbed92SAli Ahmed getProcessorSummary(aResp, connection.first, path); 4095bc2dc8eSJames Feist 4105bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 4111abe55efSEd Tanous } 412002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4131abe55efSEd Tanous { 4141abe55efSEd Tanous BMCWEB_LOG_DEBUG 41504a258f4SEd Tanous << "Found UUID, now get its properties."; 416bc1d29deSKrzysztof Grobelny 417bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 418bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 419bc1d29deSKrzysztof Grobelny path, "xyz.openbmc_project.Common.UUID", 4205e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec3, 421b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4221214b7e7SGunnar Mills properties) { 423cb13a392SEd Tanous if (ec3) 4241abe55efSEd Tanous { 425002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " 426002d39b4SEd Tanous << ec3; 427f12894f8SJason M. Bills messages::internalError(aResp->res); 428c5b2abe0SLewanczyk, Dawid return; 429c5b2abe0SLewanczyk, Dawid } 430002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << properties.size() 431c5b2abe0SLewanczyk, Dawid << " UUID properties."; 43204a258f4SEd Tanous 433bc1d29deSKrzysztof Grobelny const std::string* uUID = nullptr; 434bc1d29deSKrzysztof Grobelny 435bc1d29deSKrzysztof Grobelny const bool success = 436bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 437bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 438bc1d29deSKrzysztof Grobelny properties, "UUID", uUID); 439bc1d29deSKrzysztof Grobelny 440bc1d29deSKrzysztof Grobelny if (!success) 4411abe55efSEd Tanous { 442bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 443bc1d29deSKrzysztof Grobelny return; 444bc1d29deSKrzysztof Grobelny } 445bc1d29deSKrzysztof Grobelny 446bc1d29deSKrzysztof Grobelny if (uUID != nullptr) 447bc1d29deSKrzysztof Grobelny { 448bc1d29deSKrzysztof Grobelny std::string valueStr = *uUID; 44904a258f4SEd Tanous if (valueStr.size() == 32) 4501abe55efSEd Tanous { 451029573d4SEd Tanous valueStr.insert(8, 1, '-'); 452029573d4SEd Tanous valueStr.insert(13, 1, '-'); 453029573d4SEd Tanous valueStr.insert(18, 1, '-'); 454029573d4SEd Tanous valueStr.insert(23, 1, '-'); 45504a258f4SEd Tanous } 456bc1d29deSKrzysztof Grobelny BMCWEB_LOG_DEBUG << "UUID = " << valueStr; 457002d39b4SEd Tanous aResp->res.jsonValue["UUID"] = valueStr; 458c5b2abe0SLewanczyk, Dawid } 459bc1d29deSKrzysztof Grobelny }); 460c5b2abe0SLewanczyk, Dawid } 461029573d4SEd Tanous else if (interfaceName == 462029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4631abe55efSEd Tanous { 464bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 465bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, connection.first, 466bc1d29deSKrzysztof Grobelny path, 467bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 4685e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, 469b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4701214b7e7SGunnar Mills propertiesList) { 471cb13a392SEd Tanous if (ec2) 472029573d4SEd Tanous { 473e4a4b9a9SJames Feist // doesn't have to include this 474e4a4b9a9SJames Feist // interface 475029573d4SEd Tanous return; 476029573d4SEd Tanous } 477002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Got " << propertiesList.size() 478029573d4SEd Tanous << " properties for system"; 479bc1d29deSKrzysztof Grobelny 480bc1d29deSKrzysztof Grobelny const std::string* partNumber = nullptr; 481bc1d29deSKrzysztof Grobelny const std::string* serialNumber = nullptr; 482bc1d29deSKrzysztof Grobelny const std::string* manufacturer = nullptr; 483bc1d29deSKrzysztof Grobelny const std::string* model = nullptr; 484bc1d29deSKrzysztof Grobelny const std::string* subModel = nullptr; 485bc1d29deSKrzysztof Grobelny 486bc1d29deSKrzysztof Grobelny const bool success = 487bc1d29deSKrzysztof Grobelny sdbusplus::unpackPropertiesNoThrow( 488bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), 489bc1d29deSKrzysztof Grobelny propertiesList, "PartNumber", partNumber, 490bc1d29deSKrzysztof Grobelny "SerialNumber", serialNumber, 491bc1d29deSKrzysztof Grobelny "Manufacturer", manufacturer, "Model", 492bc1d29deSKrzysztof Grobelny model, "SubModel", subModel); 493bc1d29deSKrzysztof Grobelny 494bc1d29deSKrzysztof Grobelny if (!success) 495029573d4SEd Tanous { 496bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 497bc1d29deSKrzysztof Grobelny return; 498029573d4SEd Tanous } 499bc1d29deSKrzysztof Grobelny 500bc1d29deSKrzysztof Grobelny if (partNumber != nullptr) 501bc1d29deSKrzysztof Grobelny { 502bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["PartNumber"] = 503bc1d29deSKrzysztof Grobelny *partNumber; 504029573d4SEd Tanous } 505bc1d29deSKrzysztof Grobelny 506bc1d29deSKrzysztof Grobelny if (serialNumber != nullptr) 507bc1d29deSKrzysztof Grobelny { 508bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SerialNumber"] = 509bc1d29deSKrzysztof Grobelny *serialNumber; 510bc1d29deSKrzysztof Grobelny } 511bc1d29deSKrzysztof Grobelny 512bc1d29deSKrzysztof Grobelny if (manufacturer != nullptr) 513bc1d29deSKrzysztof Grobelny { 514bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Manufacturer"] = 515bc1d29deSKrzysztof Grobelny *manufacturer; 516bc1d29deSKrzysztof Grobelny } 517bc1d29deSKrzysztof Grobelny 518bc1d29deSKrzysztof Grobelny if (model != nullptr) 519bc1d29deSKrzysztof Grobelny { 520bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["Model"] = *model; 521bc1d29deSKrzysztof Grobelny } 522bc1d29deSKrzysztof Grobelny 523bc1d29deSKrzysztof Grobelny if (subModel != nullptr) 524bc1d29deSKrzysztof Grobelny { 525bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["SubModel"] = *subModel; 526fc5afcf9Sbeccabroek } 527c1e236a6SGunnar Mills 528cb7e1e7bSAndrew Geissler // Grab the bios version 529eee0013eSWilly Tu sw_util::populateSoftwareInformation( 530eee0013eSWilly Tu aResp, sw_util::biosPurpose, "BiosVersion", 531002d39b4SEd Tanous false); 532bc1d29deSKrzysztof Grobelny }); 533e4a4b9a9SJames Feist 5341e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5351e1e598dSJonathan Doman *crow::connections::systemBus, connection.first, 5361e1e598dSJonathan Doman path, 5371e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5381e1e598dSJonathan Doman "AssetTag", 5391e1e598dSJonathan Doman "AssetTag", 5405e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, 5411e1e598dSJonathan Doman const std::string& value) { 542cb13a392SEd Tanous if (ec2) 543e4a4b9a9SJames Feist { 544e4a4b9a9SJames Feist // doesn't have to include this 545e4a4b9a9SJames Feist // interface 546e4a4b9a9SJames Feist return; 547e4a4b9a9SJames Feist } 548e4a4b9a9SJames Feist 5491e1e598dSJonathan Doman aResp->res.jsonValue["AssetTag"] = value; 5501e1e598dSJonathan Doman }); 551029573d4SEd Tanous } 552029573d4SEd Tanous } 553029573d4SEd Tanous } 554c5b2abe0SLewanczyk, Dawid } 5556617338dSEd Tanous }); 556c5b2abe0SLewanczyk, Dawid } 557c5b2abe0SLewanczyk, Dawid 558c5b2abe0SLewanczyk, Dawid /** 559c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 560c5b2abe0SLewanczyk, Dawid * 561c5b2abe0SLewanczyk, Dawid * @param[in] aResp Shared pointer for completing asynchronous calls. 562c5b2abe0SLewanczyk, Dawid * 563c5b2abe0SLewanczyk, Dawid * @return None. 564c5b2abe0SLewanczyk, Dawid */ 5658d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 5661abe55efSEd Tanous { 56755c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "Get host information."; 5681e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5691e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 5701e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 5711e1e598dSJonathan Doman "CurrentHostState", 5725e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 5731e1e598dSJonathan Doman const std::string& hostState) { 5741abe55efSEd Tanous if (ec) 5751abe55efSEd Tanous { 57622228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 57722228c28SAndrew Geissler { 57822228c28SAndrew Geissler // Service not available, no error, just don't return 57922228c28SAndrew Geissler // host state info 58022228c28SAndrew Geissler BMCWEB_LOG_DEBUG << "Service not available " << ec; 58122228c28SAndrew Geissler return; 58222228c28SAndrew Geissler } 58322228c28SAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 584f12894f8SJason M. Bills messages::internalError(aResp->res); 585c5b2abe0SLewanczyk, Dawid return; 586c5b2abe0SLewanczyk, Dawid } 5876617338dSEd Tanous 5881e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Host state: " << hostState; 589c5b2abe0SLewanczyk, Dawid // Verify Host State 5901e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5911abe55efSEd Tanous { 59255c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "On"; 5936617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Enabled"; 5941abe55efSEd Tanous } 5951e1e598dSJonathan Doman else if (hostState == 5960fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5978c888608SGunnar Mills { 5988c888608SGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 5998c888608SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6008c888608SGunnar Mills } 6011e1e598dSJonathan Doman else if (hostState == 6020fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 60383935af9SAndrew Geissler { 60483935af9SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 60583935af9SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "InTest"; 60683935af9SAndrew Geissler } 6070fda0f12SGeorge Liu else if ( 6081e1e598dSJonathan Doman hostState == 6090fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6101a2a1437SAndrew Geissler { 6111a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOn"; 61215c27bf8SNoah Brewer aResp->res.jsonValue["Status"]["State"] = "Starting"; 6131a2a1437SAndrew Geissler } 614002d39b4SEd Tanous else if (hostState == 6150fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6161a2a1437SAndrew Geissler { 6171a2a1437SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOff"; 6181a2a1437SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Disabled"; 6191a2a1437SAndrew Geissler } 6201abe55efSEd Tanous else 6211abe55efSEd Tanous { 62255c7b7a2SEd Tanous aResp->res.jsonValue["PowerState"] = "Off"; 6236617338dSEd Tanous aResp->res.jsonValue["Status"]["State"] = "Disabled"; 624c5b2abe0SLewanczyk, Dawid } 6251e1e598dSJonathan Doman }); 626c5b2abe0SLewanczyk, Dawid } 627c5b2abe0SLewanczyk, Dawid 628c5b2abe0SLewanczyk, Dawid /** 629786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 630491d8ee7SSantosh Puranik * 631491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 632491d8ee7SSantosh Puranik * 633491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 634491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 635491d8ee7SSantosh Puranik */ 63623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 637491d8ee7SSantosh Puranik { 638491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 639491d8ee7SSantosh Puranik { 640491d8ee7SSantosh Puranik return "None"; 641491d8ee7SSantosh Puranik } 6423174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 643491d8ee7SSantosh Puranik { 644491d8ee7SSantosh Puranik return "Hdd"; 645491d8ee7SSantosh Puranik } 6463174e4dfSEd Tanous if (dbusSource == 647a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 648491d8ee7SSantosh Puranik { 649491d8ee7SSantosh Puranik return "Cd"; 650491d8ee7SSantosh Puranik } 6513174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 652491d8ee7SSantosh Puranik { 653491d8ee7SSantosh Puranik return "Pxe"; 654491d8ee7SSantosh Puranik } 6553174e4dfSEd Tanous if (dbusSource == 656944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6579f16b2c1SJennifer Lee { 6589f16b2c1SJennifer Lee return "Usb"; 6599f16b2c1SJennifer Lee } 660491d8ee7SSantosh Puranik return ""; 661491d8ee7SSantosh Puranik } 662491d8ee7SSantosh Puranik 663491d8ee7SSantosh Puranik /** 664cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 665cd9a4666SKonstantin Aladyshev * 666cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 667cd9a4666SKonstantin Aladyshev * 668cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 669cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 670cd9a4666SKonstantin Aladyshev */ 671cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 672cd9a4666SKonstantin Aladyshev { 673cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 674cd9a4666SKonstantin Aladyshev { 675cd9a4666SKonstantin Aladyshev return "Legacy"; 676cd9a4666SKonstantin Aladyshev } 677cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 678cd9a4666SKonstantin Aladyshev { 679cd9a4666SKonstantin Aladyshev return "UEFI"; 680cd9a4666SKonstantin Aladyshev } 681cd9a4666SKonstantin Aladyshev return ""; 682cd9a4666SKonstantin Aladyshev } 683cd9a4666SKonstantin Aladyshev 684cd9a4666SKonstantin Aladyshev /** 685786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 686491d8ee7SSantosh Puranik * 687491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 688491d8ee7SSantosh Puranik * 689491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 690491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 691491d8ee7SSantosh Puranik */ 69223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 693491d8ee7SSantosh Puranik { 694491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 695491d8ee7SSantosh Puranik { 696491d8ee7SSantosh Puranik return "None"; 697491d8ee7SSantosh Puranik } 6983174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 699491d8ee7SSantosh Puranik { 700491d8ee7SSantosh Puranik return "Diags"; 701491d8ee7SSantosh Puranik } 7023174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 703491d8ee7SSantosh Puranik { 704491d8ee7SSantosh Puranik return "BiosSetup"; 705491d8ee7SSantosh Puranik } 706491d8ee7SSantosh Puranik return ""; 707491d8ee7SSantosh Puranik } 708491d8ee7SSantosh Puranik 709491d8ee7SSantosh Puranik /** 710e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 711e43914b3SAndrew Geissler * 712e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 713e43914b3SAndrew Geissler * 714e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 715e43914b3SAndrew Geissler * translation cannot be done, returns "None". 716e43914b3SAndrew Geissler */ 717e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 718e43914b3SAndrew Geissler { 719e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 720e43914b3SAndrew Geissler // enum 721e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 722e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 723e43914b3SAndrew Geissler "ProgressStages.Unspecified") 724e43914b3SAndrew Geissler { 725e43914b3SAndrew Geissler rfBpLastState = "None"; 726e43914b3SAndrew Geissler } 727e43914b3SAndrew Geissler else if (dbusBootProgress == 728e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 729e43914b3SAndrew Geissler "PrimaryProcInit") 730e43914b3SAndrew Geissler { 731e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 732e43914b3SAndrew Geissler } 733e43914b3SAndrew Geissler else if (dbusBootProgress == 734e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 735e43914b3SAndrew Geissler "BusInit") 736e43914b3SAndrew Geissler { 737e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 738e43914b3SAndrew Geissler } 739e43914b3SAndrew Geissler else if (dbusBootProgress == 740e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 741e43914b3SAndrew Geissler "MemoryInit") 742e43914b3SAndrew Geissler { 743e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 744e43914b3SAndrew Geissler } 745e43914b3SAndrew Geissler else if (dbusBootProgress == 746e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 747e43914b3SAndrew Geissler "SecondaryProcInit") 748e43914b3SAndrew Geissler { 749e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 750e43914b3SAndrew Geissler } 751e43914b3SAndrew Geissler else if (dbusBootProgress == 752e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 753e43914b3SAndrew Geissler "PCIInit") 754e43914b3SAndrew Geissler { 755e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 756e43914b3SAndrew Geissler } 757e43914b3SAndrew Geissler else if (dbusBootProgress == 758e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 759e43914b3SAndrew Geissler "SystemSetup") 760e43914b3SAndrew Geissler { 761e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 762e43914b3SAndrew Geissler } 763e43914b3SAndrew Geissler else if (dbusBootProgress == 764e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 765e43914b3SAndrew Geissler "SystemInitComplete") 766e43914b3SAndrew Geissler { 767e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 768e43914b3SAndrew Geissler } 769e43914b3SAndrew Geissler else if (dbusBootProgress == 770e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 771e43914b3SAndrew Geissler "OSStart") 772e43914b3SAndrew Geissler { 773e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 774e43914b3SAndrew Geissler } 775e43914b3SAndrew Geissler else if (dbusBootProgress == 776e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 777e43914b3SAndrew Geissler "OSRunning") 778e43914b3SAndrew Geissler { 779e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 780e43914b3SAndrew Geissler } 781e43914b3SAndrew Geissler else 782e43914b3SAndrew Geissler { 783e43914b3SAndrew Geissler BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " 784e43914b3SAndrew Geissler << dbusBootProgress; 785e43914b3SAndrew Geissler // Just return the default 786e43914b3SAndrew Geissler } 787e43914b3SAndrew Geissler return rfBpLastState; 788e43914b3SAndrew Geissler } 789e43914b3SAndrew Geissler 790e43914b3SAndrew Geissler /** 791786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 792491d8ee7SSantosh Puranik * 793491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 794944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 795944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 796491d8ee7SSantosh Puranik * 797944ffaf9SJohnathan Mantey * @return Integer error code. 798491d8ee7SSantosh Puranik */ 7998d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 800944ffaf9SJohnathan Mantey const std::string& rfSource, 801944ffaf9SJohnathan Mantey std::string& bootSource, std::string& bootMode) 802491d8ee7SSantosh Puranik { 803c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 804c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 805944ffaf9SJohnathan Mantey 806491d8ee7SSantosh Puranik if (rfSource == "None") 807491d8ee7SSantosh Puranik { 808944ffaf9SJohnathan Mantey return 0; 809491d8ee7SSantosh Puranik } 8103174e4dfSEd Tanous if (rfSource == "Pxe") 811491d8ee7SSantosh Puranik { 812944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 813944ffaf9SJohnathan Mantey } 814944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 815944ffaf9SJohnathan Mantey { 816944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 817944ffaf9SJohnathan Mantey } 818944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 819944ffaf9SJohnathan Mantey { 820944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 821944ffaf9SJohnathan Mantey } 822944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 823944ffaf9SJohnathan Mantey { 824944ffaf9SJohnathan Mantey bootSource = 825944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 826944ffaf9SJohnathan Mantey } 827944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 828944ffaf9SJohnathan Mantey { 829944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 830491d8ee7SSantosh Puranik } 8319f16b2c1SJennifer Lee else if (rfSource == "Usb") 8329f16b2c1SJennifer Lee { 833944ffaf9SJohnathan Mantey bootSource = 834944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8359f16b2c1SJennifer Lee } 836491d8ee7SSantosh Puranik else 837491d8ee7SSantosh Puranik { 8380fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 8390fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideTarget: " 840944ffaf9SJohnathan Mantey << bootSource; 841944ffaf9SJohnathan Mantey messages::propertyValueNotInList(aResp->res, rfSource, 842944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 843944ffaf9SJohnathan Mantey return -1; 844491d8ee7SSantosh Puranik } 845944ffaf9SJohnathan Mantey return 0; 846491d8ee7SSantosh Puranik } 8471981771bSAli Ahmed 848978b8803SAndrew Geissler /** 849978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 850978b8803SAndrew Geissler * 851978b8803SAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 852978b8803SAndrew Geissler * 853978b8803SAndrew Geissler * @return None. 854978b8803SAndrew Geissler */ 8558d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 856978b8803SAndrew Geissler { 8571e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8581e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8591e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8601e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 8615e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 8621e1e598dSJonathan Doman const std::string& bootProgressStr) { 863978b8803SAndrew Geissler if (ec) 864978b8803SAndrew Geissler { 865978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 866978b8803SAndrew Geissler // not found 867978b8803SAndrew Geissler return; 868978b8803SAndrew Geissler } 869978b8803SAndrew Geissler 8701e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr; 871978b8803SAndrew Geissler 872e43914b3SAndrew Geissler aResp->res.jsonValue["BootProgress"]["LastState"] = 873e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8741e1e598dSJonathan Doman }); 875978b8803SAndrew Geissler } 876491d8ee7SSantosh Puranik 877491d8ee7SSantosh Puranik /** 878b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 879b6d5d45cSHieu Huynh * 880b6d5d45cSHieu Huynh * @param[in] aResp Shared pointer for generating response message. 881b6d5d45cSHieu Huynh * 882b6d5d45cSHieu Huynh * @return None. 883b6d5d45cSHieu Huynh */ 884b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 885b6d5d45cSHieu Huynh const std::shared_ptr<bmcweb::AsyncResp>& aResp) 886b6d5d45cSHieu Huynh { 887b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 888b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 889b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 890b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 8915e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 892b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 893b6d5d45cSHieu Huynh if (ec) 894b6d5d45cSHieu Huynh { 895b6d5d45cSHieu Huynh BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 896b6d5d45cSHieu Huynh return; 897b6d5d45cSHieu Huynh } 898b6d5d45cSHieu Huynh 899b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 900b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 901b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 902b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 903b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 904b6d5d45cSHieu Huynh 905b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 906b6d5d45cSHieu Huynh aResp->res.jsonValue["BootProgress"]["LastStateTime"] = 907b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 908b6d5d45cSHieu Huynh }); 909b6d5d45cSHieu Huynh } 910b6d5d45cSHieu Huynh 911b6d5d45cSHieu Huynh /** 912c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 913cd9a4666SKonstantin Aladyshev * 914cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 915cd9a4666SKonstantin Aladyshev * 916cd9a4666SKonstantin Aladyshev * @return None. 917cd9a4666SKonstantin Aladyshev */ 918cd9a4666SKonstantin Aladyshev 919c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 920cd9a4666SKonstantin Aladyshev { 9211e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9221e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9231e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9241e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 9255e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 9261e1e598dSJonathan Doman const std::string& bootType) { 927cd9a4666SKonstantin Aladyshev if (ec) 928cd9a4666SKonstantin Aladyshev { 929cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 930cd9a4666SKonstantin Aladyshev return; 931cd9a4666SKonstantin Aladyshev } 932cd9a4666SKonstantin Aladyshev 9331e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot type: " << bootType; 934cd9a4666SKonstantin Aladyshev 935002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 936002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 937613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 938cd9a4666SKonstantin Aladyshev 9391e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 940cd9a4666SKonstantin Aladyshev if (rfType.empty()) 941cd9a4666SKonstantin Aladyshev { 942cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 943cd9a4666SKonstantin Aladyshev return; 944cd9a4666SKonstantin Aladyshev } 945cd9a4666SKonstantin Aladyshev 946cd9a4666SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9471e1e598dSJonathan Doman }); 948cd9a4666SKonstantin Aladyshev } 949cd9a4666SKonstantin Aladyshev 950cd9a4666SKonstantin Aladyshev /** 951c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 952491d8ee7SSantosh Puranik * 953491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 954491d8ee7SSantosh Puranik * 955491d8ee7SSantosh Puranik * @return None. 956491d8ee7SSantosh Puranik */ 957c21865c4SKonstantin Aladyshev 958c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 959491d8ee7SSantosh Puranik { 9601e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9611e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9621e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9631e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 9645e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 9651e1e598dSJonathan Doman const std::string& bootModeStr) { 966491d8ee7SSantosh Puranik if (ec) 967491d8ee7SSantosh Puranik { 968491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 969491d8ee7SSantosh Puranik messages::internalError(aResp->res); 970491d8ee7SSantosh Puranik return; 971491d8ee7SSantosh Puranik } 972491d8ee7SSantosh Puranik 9731e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr; 974491d8ee7SSantosh Puranik 9750fda0f12SGeorge Liu aResp->res 9760fda0f12SGeorge Liu .jsonValue["Boot"] 977002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 978002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 979491d8ee7SSantosh Puranik 9801e1e598dSJonathan Doman if (bootModeStr != 981491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 982491d8ee7SSantosh Puranik { 9831e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 984491d8ee7SSantosh Puranik if (!rfMode.empty()) 985491d8ee7SSantosh Puranik { 986491d8ee7SSantosh Puranik aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 987491d8ee7SSantosh Puranik rfMode; 988491d8ee7SSantosh Puranik } 989491d8ee7SSantosh Puranik } 9901e1e598dSJonathan Doman }); 991491d8ee7SSantosh Puranik } 992491d8ee7SSantosh Puranik 993491d8ee7SSantosh Puranik /** 994c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 995491d8ee7SSantosh Puranik * 996491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 997491d8ee7SSantosh Puranik * 998491d8ee7SSantosh Puranik * @return None. 999491d8ee7SSantosh Puranik */ 1000c21865c4SKonstantin Aladyshev 1001c21865c4SKonstantin Aladyshev inline void 1002c21865c4SKonstantin Aladyshev getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1003491d8ee7SSantosh Puranik { 10041e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10051e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10061e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10071e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 10085e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 10091e1e598dSJonathan Doman const std::string& bootSourceStr) { 1010491d8ee7SSantosh Puranik if (ec) 1011491d8ee7SSantosh Puranik { 1012491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 10135ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10145ef735c8SNan Zhou { 10155ef735c8SNan Zhou return; 10165ef735c8SNan Zhou } 1017491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1018491d8ee7SSantosh Puranik return; 1019491d8ee7SSantosh Puranik } 1020491d8ee7SSantosh Puranik 10211e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr; 1022491d8ee7SSantosh Puranik 10231e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1024491d8ee7SSantosh Puranik if (!rfSource.empty()) 1025491d8ee7SSantosh Puranik { 1026002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource; 1027491d8ee7SSantosh Puranik } 1028cd9a4666SKonstantin Aladyshev 1029cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1030cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1031c21865c4SKonstantin Aladyshev getBootOverrideMode(aResp); 10321e1e598dSJonathan Doman }); 1033491d8ee7SSantosh Puranik } 1034491d8ee7SSantosh Puranik 1035491d8ee7SSantosh Puranik /** 1036c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1037c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1038c21865c4SKonstantin Aladyshev * state 1039491d8ee7SSantosh Puranik * 1040491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1041491d8ee7SSantosh Puranik * 1042491d8ee7SSantosh Puranik * @return None. 1043491d8ee7SSantosh Puranik */ 1044491d8ee7SSantosh Puranik 1045c21865c4SKonstantin Aladyshev inline void 1046c21865c4SKonstantin Aladyshev processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1047c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1048c21865c4SKonstantin Aladyshev { 1049c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1050c21865c4SKonstantin Aladyshev { 1051c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; 1052c21865c4SKonstantin Aladyshev return; 1053c21865c4SKonstantin Aladyshev } 1054c21865c4SKonstantin Aladyshev 1055c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1056c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10571e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10581e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10591e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10601e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 10615e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1062491d8ee7SSantosh Puranik if (ec) 1063491d8ee7SSantosh Puranik { 1064491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1065c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1066491d8ee7SSantosh Puranik return; 1067491d8ee7SSantosh Puranik } 1068491d8ee7SSantosh Puranik 1069c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1070c21865c4SKonstantin Aladyshev { 1071002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once"; 1072c21865c4SKonstantin Aladyshev } 1073c21865c4SKonstantin Aladyshev else 1074c21865c4SKonstantin Aladyshev { 1075c21865c4SKonstantin Aladyshev aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1076c21865c4SKonstantin Aladyshev "Continuous"; 1077c21865c4SKonstantin Aladyshev } 10781e1e598dSJonathan Doman }); 1079491d8ee7SSantosh Puranik } 1080491d8ee7SSantosh Puranik 1081491d8ee7SSantosh Puranik /** 1082c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1083c21865c4SKonstantin Aladyshev * 1084c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1085c21865c4SKonstantin Aladyshev * 1086c21865c4SKonstantin Aladyshev * @return None. 1087c21865c4SKonstantin Aladyshev */ 1088c21865c4SKonstantin Aladyshev 1089c21865c4SKonstantin Aladyshev inline void 1090c21865c4SKonstantin Aladyshev getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1091c21865c4SKonstantin Aladyshev { 10921e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10931e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10941e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10951e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 10965e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 10971e1e598dSJonathan Doman const bool bootOverrideEnable) { 1098c21865c4SKonstantin Aladyshev if (ec) 1099c21865c4SKonstantin Aladyshev { 1100c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 11015ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11025ef735c8SNan Zhou { 11035ef735c8SNan Zhou return; 11045ef735c8SNan Zhou } 1105c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1106c21865c4SKonstantin Aladyshev return; 1107c21865c4SKonstantin Aladyshev } 1108c21865c4SKonstantin Aladyshev 11091e1e598dSJonathan Doman processBootOverrideEnable(aResp, bootOverrideEnable); 11101e1e598dSJonathan Doman }); 1111c21865c4SKonstantin Aladyshev } 1112c21865c4SKonstantin Aladyshev 1113c21865c4SKonstantin Aladyshev /** 1114c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1115c21865c4SKonstantin Aladyshev * 1116c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1117c21865c4SKonstantin Aladyshev * 1118c21865c4SKonstantin Aladyshev * @return None. 1119c21865c4SKonstantin Aladyshev */ 1120c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1121c21865c4SKonstantin Aladyshev { 1122c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Get boot information."; 1123c21865c4SKonstantin Aladyshev 1124c21865c4SKonstantin Aladyshev getBootOverrideSource(aResp); 1125c21865c4SKonstantin Aladyshev getBootOverrideType(aResp); 1126c21865c4SKonstantin Aladyshev getBootOverrideEnable(aResp); 1127c21865c4SKonstantin Aladyshev } 1128c21865c4SKonstantin Aladyshev 1129c21865c4SKonstantin Aladyshev /** 1130c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1131c0557e1aSGunnar Mills * 1132c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1133c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1134c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1135c0557e1aSGunnar Mills * last power operation time. 1136c0557e1aSGunnar Mills * 1137c0557e1aSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 1138c0557e1aSGunnar Mills * 1139c0557e1aSGunnar Mills * @return None. 1140c0557e1aSGunnar Mills */ 11418d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1142c0557e1aSGunnar Mills { 1143c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "Getting System Last Reset Time"; 1144c0557e1aSGunnar Mills 11451e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11461e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11471e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11481e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 11495e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) { 1150c0557e1aSGunnar Mills if (ec) 1151c0557e1aSGunnar Mills { 1152c0557e1aSGunnar Mills BMCWEB_LOG_DEBUG << "D-BUS response error " << ec; 1153c0557e1aSGunnar Mills return; 1154c0557e1aSGunnar Mills } 1155c0557e1aSGunnar Mills 1156c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1157c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11581e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1159c0557e1aSGunnar Mills 1160c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1161c0557e1aSGunnar Mills aResp->res.jsonValue["LastResetTime"] = 11622b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11631e1e598dSJonathan Doman }); 1164c0557e1aSGunnar Mills } 1165c0557e1aSGunnar Mills 1166c0557e1aSGunnar Mills /** 1167797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1168797d5daeSCorey Hardesty * 1169797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1170797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1171797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1172797d5daeSCorey Hardesty * dbus. 1173797d5daeSCorey Hardesty * 1174797d5daeSCorey Hardesty * @param[in] aResp Shared pointer for generating response message. 1175797d5daeSCorey Hardesty * 1176797d5daeSCorey Hardesty * @return None. 1177797d5daeSCorey Hardesty */ 1178797d5daeSCorey Hardesty inline void 1179797d5daeSCorey Hardesty getAutomaticRebootAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1180797d5daeSCorey Hardesty { 1181797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 1182797d5daeSCorey Hardesty 1183797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1184797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1185797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1186797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1187797d5daeSCorey Hardesty [aResp{aResp}](const boost::system::error_code& ec, 1188797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1189797d5daeSCorey Hardesty if (ec) 1190797d5daeSCorey Hardesty { 1191797d5daeSCorey Hardesty if (ec.value() != EBADR) 1192797d5daeSCorey Hardesty { 1193797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1194797d5daeSCorey Hardesty messages::internalError(aResp->res); 1195797d5daeSCorey Hardesty } 1196797d5daeSCorey Hardesty return; 1197797d5daeSCorey Hardesty } 1198797d5daeSCorey Hardesty 1199797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1200797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1201797d5daeSCorey Hardesty 1202797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1203797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1204797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1205797d5daeSCorey Hardesty 1206797d5daeSCorey Hardesty if (!success) 1207797d5daeSCorey Hardesty { 1208797d5daeSCorey Hardesty messages::internalError(aResp->res); 1209797d5daeSCorey Hardesty return; 1210797d5daeSCorey Hardesty } 1211797d5daeSCorey Hardesty 1212797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1213797d5daeSCorey Hardesty { 1214797d5daeSCorey Hardesty aResp->res.jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1215797d5daeSCorey Hardesty *attemptsLeft; 1216797d5daeSCorey Hardesty } 1217797d5daeSCorey Hardesty 1218797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1219797d5daeSCorey Hardesty { 1220797d5daeSCorey Hardesty aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1221797d5daeSCorey Hardesty *retryAttempts; 1222797d5daeSCorey Hardesty } 1223797d5daeSCorey Hardesty }); 1224797d5daeSCorey Hardesty } 1225797d5daeSCorey Hardesty 1226797d5daeSCorey Hardesty /** 12276bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12286bd5a8d2SGunnar Mills * 12296bd5a8d2SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 12306bd5a8d2SGunnar Mills * 12316bd5a8d2SGunnar Mills * @return None. 12326bd5a8d2SGunnar Mills */ 1233797d5daeSCorey Hardesty inline void 1234797d5daeSCorey Hardesty getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 12356bd5a8d2SGunnar Mills { 12366bd5a8d2SGunnar Mills BMCWEB_LOG_DEBUG << "Get Automatic Retry policy"; 12376bd5a8d2SGunnar Mills 12381e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12391e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12401e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12411e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 12425e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) { 12436bd5a8d2SGunnar Mills if (ec) 12446bd5a8d2SGunnar Mills { 1245797d5daeSCorey Hardesty if (ec.value() != EBADR) 1246797d5daeSCorey Hardesty { 1247797d5daeSCorey Hardesty BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1248797d5daeSCorey Hardesty messages::internalError(aResp->res); 1249797d5daeSCorey Hardesty } 12506bd5a8d2SGunnar Mills return; 12516bd5a8d2SGunnar Mills } 12526bd5a8d2SGunnar Mills 12531e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled; 1254e05aec50SEd Tanous if (autoRebootEnabled) 12556bd5a8d2SGunnar Mills { 12566bd5a8d2SGunnar Mills aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12576bd5a8d2SGunnar Mills "RetryAttempts"; 12586bd5a8d2SGunnar Mills } 12596bd5a8d2SGunnar Mills else 12606bd5a8d2SGunnar Mills { 1261002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled"; 12626bd5a8d2SGunnar Mills } 1263797d5daeSCorey Hardesty getAutomaticRebootAttempts(aResp); 126469f35306SGunnar Mills 126569f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 126669f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 126769f35306SGunnar Mills // RetryAttempts. 1268002d39b4SEd Tanous aResp->res.jsonValue["Boot"] 12690fda0f12SGeorge Liu ["AutomaticRetryConfig@Redfish.AllowableValues"] = { 12700fda0f12SGeorge Liu "Disabled", "RetryAttempts"}; 12711e1e598dSJonathan Doman }); 12726bd5a8d2SGunnar Mills } 12736bd5a8d2SGunnar Mills 12746bd5a8d2SGunnar Mills /** 1275797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1276797d5daeSCorey Hardesty * 1277797d5daeSCorey Hardesty * @param[in] aResp Shared pointer for generating response message. 1278797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1279797d5daeSCorey Hardesty * 1280797d5daeSCorey Hardesty *@return None. 1281797d5daeSCorey Hardesty */ 1282797d5daeSCorey Hardesty 1283797d5daeSCorey Hardesty inline void 1284797d5daeSCorey Hardesty setAutomaticRetryAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1285797d5daeSCorey Hardesty const uint32_t retryAttempts) 1286797d5daeSCorey Hardesty { 1287797d5daeSCorey Hardesty BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts."; 1288797d5daeSCorey Hardesty crow::connections::systemBus->async_method_call( 1289797d5daeSCorey Hardesty [aResp](const boost::system::error_code& ec) { 1290797d5daeSCorey Hardesty if (ec) 1291797d5daeSCorey Hardesty { 1292797d5daeSCorey Hardesty BMCWEB_LOG_ERROR 1293797d5daeSCorey Hardesty << "DBUS response error: Set setAutomaticRetryAttempts" << ec; 1294797d5daeSCorey Hardesty messages::internalError(aResp->res); 1295797d5daeSCorey Hardesty return; 1296797d5daeSCorey Hardesty } 1297797d5daeSCorey Hardesty }, 1298797d5daeSCorey Hardesty "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 1299797d5daeSCorey Hardesty "org.freedesktop.DBus.Properties", "Set", 1300797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1301797d5daeSCorey Hardesty std::variant<uint32_t>(retryAttempts)); 1302797d5daeSCorey Hardesty } 1303797d5daeSCorey Hardesty 1304797d5daeSCorey Hardesty /** 1305c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1306c6a620f2SGeorge Liu * 1307c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1308c6a620f2SGeorge Liu * 1309c6a620f2SGeorge Liu * @return None. 1310c6a620f2SGeorge Liu */ 13118d1b46d7Szhanghch05 inline void 13128d1b46d7Szhanghch05 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1313c6a620f2SGeorge Liu { 1314c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Get power restore policy"; 1315c6a620f2SGeorge Liu 13161e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13171e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13181e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13191e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 13205e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 13215e7e2dc5SEd Tanous const std::string& policy) { 1322c6a620f2SGeorge Liu if (ec) 1323c6a620f2SGeorge Liu { 1324c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1325c6a620f2SGeorge Liu return; 1326c6a620f2SGeorge Liu } 1327c6a620f2SGeorge Liu 13280fda0f12SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 13290fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn", 1330c6a620f2SGeorge Liu "AlwaysOn"}, 13310fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff", 1332c6a620f2SGeorge Liu "AlwaysOff"}, 13330fda0f12SGeorge Liu {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore", 13344ed47cb8SMatthew Barth "LastState"}, 13354ed47cb8SMatthew Barth // Return `AlwaysOff` when power restore policy set to "None" 13364ed47cb8SMatthew Barth {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None", 13374ed47cb8SMatthew Barth "AlwaysOff"}}; 1338c6a620f2SGeorge Liu 13391e1e598dSJonathan Doman auto policyMapsIt = policyMaps.find(policy); 1340c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1341c6a620f2SGeorge Liu { 1342c6a620f2SGeorge Liu messages::internalError(aResp->res); 1343c6a620f2SGeorge Liu return; 1344c6a620f2SGeorge Liu } 1345c6a620f2SGeorge Liu 1346c6a620f2SGeorge Liu aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second; 13471e1e598dSJonathan Doman }); 1348c6a620f2SGeorge Liu } 1349c6a620f2SGeorge Liu 1350c6a620f2SGeorge Liu /** 13511981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13521981771bSAli Ahmed * TPM is required for booting the host. 13531981771bSAli Ahmed * 13541981771bSAli Ahmed * @param[in] aResp Shared pointer for generating response message. 13551981771bSAli Ahmed * 13561981771bSAli Ahmed * @return None. 13571981771bSAli Ahmed */ 13581981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 13591981771bSAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp) 13601981771bSAli Ahmed { 13611981771bSAli Ahmed BMCWEB_LOG_DEBUG << "Get TPM required to boot."; 1362e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1363e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1364e99073f5SGeorge Liu dbus::utility::getSubTree( 1365e99073f5SGeorge Liu "/", 0, interfaces, 1366e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 1367b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 13681981771bSAli Ahmed if (ec) 13691981771bSAli Ahmed { 1370002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1371002d39b4SEd Tanous << ec; 13721981771bSAli Ahmed // This is an optional D-Bus object so just return if 13731981771bSAli Ahmed // error occurs 13741981771bSAli Ahmed return; 13751981771bSAli Ahmed } 137626f6976fSEd Tanous if (subtree.empty()) 13771981771bSAli Ahmed { 13781981771bSAli Ahmed // As noted above, this is an optional interface so just return 13791981771bSAli Ahmed // if there is no instance found 13801981771bSAli Ahmed return; 13811981771bSAli Ahmed } 13821981771bSAli Ahmed 13831981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 13841981771bSAli Ahmed if (subtree.size() > 1) 13851981771bSAli Ahmed { 13861981771bSAli Ahmed BMCWEB_LOG_DEBUG 13871981771bSAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 13881981771bSAli Ahmed << subtree.size(); 13891981771bSAli Ahmed // Throw an internal Error and return 13901981771bSAli Ahmed messages::internalError(aResp->res); 13911981771bSAli Ahmed return; 13921981771bSAli Ahmed } 13931981771bSAli Ahmed 13941981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 13951981771bSAli Ahmed // field 13961981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 13971981771bSAli Ahmed { 13981981771bSAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 13991981771bSAli Ahmed messages::internalError(aResp->res); 14001981771bSAli Ahmed return; 14011981771bSAli Ahmed } 14021981771bSAli Ahmed 14031981771bSAli Ahmed const std::string& path = subtree[0].first; 14041981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14051981771bSAli Ahmed 14061981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14071e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14081e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14091e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 14105e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, bool tpmRequired) { 14118a592810SEd Tanous if (ec2) 14121981771bSAli Ahmed { 1413002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get" 14148a592810SEd Tanous << ec2; 14151981771bSAli Ahmed messages::internalError(aResp->res); 14161981771bSAli Ahmed return; 14171981771bSAli Ahmed } 14181981771bSAli Ahmed 14191e1e598dSJonathan Doman if (tpmRequired) 14201981771bSAli Ahmed { 1421002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14221981771bSAli Ahmed "Required"; 14231981771bSAli Ahmed } 14241981771bSAli Ahmed else 14251981771bSAli Ahmed { 1426002d39b4SEd Tanous aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14271981771bSAli Ahmed "Disabled"; 14281981771bSAli Ahmed } 14291e1e598dSJonathan Doman }); 1430e99073f5SGeorge Liu }); 14311981771bSAli Ahmed } 14321981771bSAli Ahmed 14331981771bSAli Ahmed /** 14341c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14351c05dae3SAli Ahmed * TPM is required for booting the host. 14361c05dae3SAli Ahmed * 14371c05dae3SAli Ahmed * @param[in] aResp Shared pointer for generating response message. 14381c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14391c05dae3SAli Ahmed * 14401c05dae3SAli Ahmed * @return None. 14411c05dae3SAli Ahmed */ 14421c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 14431c05dae3SAli Ahmed const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired) 14441c05dae3SAli Ahmed { 14451c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot."; 1446e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1447e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1448e99073f5SGeorge Liu dbus::utility::getSubTree( 1449e99073f5SGeorge Liu "/", 0, interfaces, 1450e99073f5SGeorge Liu [aResp, 1451e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1452e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 14531c05dae3SAli Ahmed if (ec) 14541c05dae3SAli Ahmed { 1455002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree" 1456002d39b4SEd Tanous << ec; 14571c05dae3SAli Ahmed messages::internalError(aResp->res); 14581c05dae3SAli Ahmed return; 14591c05dae3SAli Ahmed } 146026f6976fSEd Tanous if (subtree.empty()) 14611c05dae3SAli Ahmed { 14621c05dae3SAli Ahmed messages::propertyValueNotInList(aResp->res, "ComputerSystem", 14631c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 14641c05dae3SAli Ahmed return; 14651c05dae3SAli Ahmed } 14661c05dae3SAli Ahmed 14671c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 14681c05dae3SAli Ahmed if (subtree.size() > 1) 14691c05dae3SAli Ahmed { 14701c05dae3SAli Ahmed BMCWEB_LOG_DEBUG 14711c05dae3SAli Ahmed << "DBUS response has more than 1 TPM Enable object:" 14721c05dae3SAli Ahmed << subtree.size(); 14731c05dae3SAli Ahmed // Throw an internal Error and return 14741c05dae3SAli Ahmed messages::internalError(aResp->res); 14751c05dae3SAli Ahmed return; 14761c05dae3SAli Ahmed } 14771c05dae3SAli Ahmed 14781c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 14791c05dae3SAli Ahmed // field 14801c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14811c05dae3SAli Ahmed { 14821c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!"; 14831c05dae3SAli Ahmed messages::internalError(aResp->res); 14841c05dae3SAli Ahmed return; 14851c05dae3SAli Ahmed } 14861c05dae3SAli Ahmed 14871c05dae3SAli Ahmed const std::string& path = subtree[0].first; 14881c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14891c05dae3SAli Ahmed 14901c05dae3SAli Ahmed if (serv.empty()) 14911c05dae3SAli Ahmed { 14921c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!"; 14931c05dae3SAli Ahmed messages::internalError(aResp->res); 14941c05dae3SAli Ahmed return; 14951c05dae3SAli Ahmed } 14961c05dae3SAli Ahmed 14971c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 14981c05dae3SAli Ahmed crow::connections::systemBus->async_method_call( 14995e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 15008a592810SEd Tanous if (ec2) 15011c05dae3SAli Ahmed { 15020fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 15030fda0f12SGeorge Liu << "DBUS response error: Set TrustedModuleRequiredToBoot" 15048a592810SEd Tanous << ec2; 15051c05dae3SAli Ahmed messages::internalError(aResp->res); 15061c05dae3SAli Ahmed return; 15071c05dae3SAli Ahmed } 15081c05dae3SAli Ahmed BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done."; 15091c05dae3SAli Ahmed }, 15101c05dae3SAli Ahmed serv, path, "org.freedesktop.DBus.Properties", "Set", 15111c05dae3SAli Ahmed "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1512168e20c1SEd Tanous dbus::utility::DbusVariantType(tpmRequired)); 1513e99073f5SGeorge Liu }); 15141c05dae3SAli Ahmed } 15151c05dae3SAli Ahmed 15161c05dae3SAli Ahmed /** 1517491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1518491d8ee7SSantosh Puranik * 1519491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1520cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1521cd9a4666SKonstantin Aladyshev * @return Integer error code. 1522cd9a4666SKonstantin Aladyshev */ 1523cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1524cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1525cd9a4666SKonstantin Aladyshev { 1526c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1527cd9a4666SKonstantin Aladyshev 1528c21865c4SKonstantin Aladyshev if (!bootType) 1529cd9a4666SKonstantin Aladyshev { 1530c21865c4SKonstantin Aladyshev return; 1531c21865c4SKonstantin Aladyshev } 1532c21865c4SKonstantin Aladyshev 1533cd9a4666SKonstantin Aladyshev // Source target specified 1534cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; 1535cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1536cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1537cd9a4666SKonstantin Aladyshev { 1538cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1539cd9a4666SKonstantin Aladyshev } 1540cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1541cd9a4666SKonstantin Aladyshev { 1542cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1543cd9a4666SKonstantin Aladyshev } 1544cd9a4666SKonstantin Aladyshev else 1545cd9a4666SKonstantin Aladyshev { 1546cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Invalid property value for " 1547cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode: " 1548cd9a4666SKonstantin Aladyshev << *bootType; 1549cd9a4666SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootType, 1550cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1551cd9a4666SKonstantin Aladyshev return; 1552cd9a4666SKonstantin Aladyshev } 1553cd9a4666SKonstantin Aladyshev 1554cd9a4666SKonstantin Aladyshev // Act on validated parameters 1555cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; 1556cd9a4666SKonstantin Aladyshev 1557cd9a4666SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 15585e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1559cd9a4666SKonstantin Aladyshev if (ec) 1560cd9a4666SKonstantin Aladyshev { 1561cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1562cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1563cd9a4666SKonstantin Aladyshev { 1564cd9a4666SKonstantin Aladyshev messages::resourceNotFound(aResp->res, "Set", "BootType"); 1565cd9a4666SKonstantin Aladyshev return; 1566cd9a4666SKonstantin Aladyshev } 1567cd9a4666SKonstantin Aladyshev messages::internalError(aResp->res); 1568cd9a4666SKonstantin Aladyshev return; 1569cd9a4666SKonstantin Aladyshev } 1570cd9a4666SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot type update done."; 1571cd9a4666SKonstantin Aladyshev }, 1572c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1573c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1574cd9a4666SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1575cd9a4666SKonstantin Aladyshev "xyz.openbmc_project.Control.Boot.Type", "BootType", 1576168e20c1SEd Tanous dbus::utility::DbusVariantType(bootTypeStr)); 1577cd9a4666SKonstantin Aladyshev } 1578cd9a4666SKonstantin Aladyshev 1579cd9a4666SKonstantin Aladyshev /** 1580cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1581cd9a4666SKonstantin Aladyshev * 1582cd9a4666SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1583c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1584c21865c4SKonstantin Aladyshev * @return Integer error code. 1585c21865c4SKonstantin Aladyshev */ 1586c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1587c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1588c21865c4SKonstantin Aladyshev { 1589c21865c4SKonstantin Aladyshev if (!bootEnable) 1590c21865c4SKonstantin Aladyshev { 1591c21865c4SKonstantin Aladyshev return; 1592c21865c4SKonstantin Aladyshev } 1593c21865c4SKonstantin Aladyshev // Source target specified 1594c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; 1595c21865c4SKonstantin Aladyshev 1596c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1597c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1598c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1599c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1600c21865c4SKonstantin Aladyshev { 1601c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1602c21865c4SKonstantin Aladyshev } 1603c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1604c21865c4SKonstantin Aladyshev { 1605c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1606c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1607c21865c4SKonstantin Aladyshev } 1608c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1609c21865c4SKonstantin Aladyshev { 1610c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1611c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1612c21865c4SKonstantin Aladyshev } 1613c21865c4SKonstantin Aladyshev else 1614c21865c4SKonstantin Aladyshev { 16150fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 16160fda0f12SGeorge Liu << "Invalid property value for BootSourceOverrideEnabled: " 1617c21865c4SKonstantin Aladyshev << *bootEnable; 1618c21865c4SKonstantin Aladyshev messages::propertyValueNotInList(aResp->res, *bootEnable, 1619c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1620c21865c4SKonstantin Aladyshev return; 1621c21865c4SKonstantin Aladyshev } 1622c21865c4SKonstantin Aladyshev 1623c21865c4SKonstantin Aladyshev // Act on validated parameters 1624c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; 1625c21865c4SKonstantin Aladyshev 1626c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 16275e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 16288a592810SEd Tanous if (ec2) 1629c21865c4SKonstantin Aladyshev { 16308a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 1631c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1632c21865c4SKonstantin Aladyshev return; 1633c21865c4SKonstantin Aladyshev } 1634c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot override enable update done."; 1635c21865c4SKonstantin Aladyshev }, 1636c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1637c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1638c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1639c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1640168e20c1SEd Tanous dbus::utility::DbusVariantType(bootOverrideEnable)); 1641c21865c4SKonstantin Aladyshev 1642c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1643c21865c4SKonstantin Aladyshev { 1644c21865c4SKonstantin Aladyshev return; 1645c21865c4SKonstantin Aladyshev } 1646c21865c4SKonstantin Aladyshev 1647c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1648c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 1649c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " 1650c21865c4SKonstantin Aladyshev << bootOverridePersistent; 1651c21865c4SKonstantin Aladyshev 1652c21865c4SKonstantin Aladyshev crow::connections::systemBus->async_method_call( 16535e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1654c21865c4SKonstantin Aladyshev if (ec) 1655c21865c4SKonstantin Aladyshev { 1656c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1657c21865c4SKonstantin Aladyshev messages::internalError(aResp->res); 1658c21865c4SKonstantin Aladyshev return; 1659c21865c4SKonstantin Aladyshev } 1660c21865c4SKonstantin Aladyshev BMCWEB_LOG_DEBUG << "Boot one_time update done."; 1661c21865c4SKonstantin Aladyshev }, 1662c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1663c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot/one_time", 1664c21865c4SKonstantin Aladyshev "org.freedesktop.DBus.Properties", "Set", 1665c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Object.Enable", "Enabled", 1666168e20c1SEd Tanous dbus::utility::DbusVariantType(!bootOverridePersistent)); 1667c21865c4SKonstantin Aladyshev } 1668c21865c4SKonstantin Aladyshev 1669c21865c4SKonstantin Aladyshev /** 1670c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1671c21865c4SKonstantin Aladyshev * 1672c21865c4SKonstantin Aladyshev * @param[in] aResp Shared pointer for generating response message. 1673491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1674491d8ee7SSantosh Puranik * 1675265c1602SJohnathan Mantey * @return Integer error code. 1676491d8ee7SSantosh Puranik */ 1677cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1678cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1679491d8ee7SSantosh Puranik { 1680c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1681c21865c4SKonstantin Aladyshev std::string bootModeStr; 1682944ffaf9SJohnathan Mantey 1683c21865c4SKonstantin Aladyshev if (!bootSource) 1684491d8ee7SSantosh Puranik { 1685c21865c4SKonstantin Aladyshev return; 1686c21865c4SKonstantin Aladyshev } 1687c21865c4SKonstantin Aladyshev 1688491d8ee7SSantosh Puranik // Source target specified 1689491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; 1690491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1691e662eae8SEd Tanous if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) != 1692e662eae8SEd Tanous 0) 1693491d8ee7SSantosh Puranik { 1694944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG 1695944ffaf9SJohnathan Mantey << "Invalid property value for BootSourceOverrideTarget: " 1696491d8ee7SSantosh Puranik << *bootSource; 1697491d8ee7SSantosh Puranik messages::propertyValueNotInList(aResp->res, *bootSource, 1698491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1699491d8ee7SSantosh Puranik return; 1700491d8ee7SSantosh Puranik } 1701491d8ee7SSantosh Puranik 1702944ffaf9SJohnathan Mantey // Act on validated parameters 1703944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; 1704944ffaf9SJohnathan Mantey BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; 1705944ffaf9SJohnathan Mantey 1706491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 17075e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1708491d8ee7SSantosh Puranik if (ec) 1709491d8ee7SSantosh Puranik { 1710491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1711491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1712491d8ee7SSantosh Puranik return; 1713491d8ee7SSantosh Puranik } 1714491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot source update done."; 1715491d8ee7SSantosh Puranik }, 1716c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1717c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1718491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1719491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1720168e20c1SEd Tanous dbus::utility::DbusVariantType(bootSourceStr)); 1721944ffaf9SJohnathan Mantey 1722491d8ee7SSantosh Puranik crow::connections::systemBus->async_method_call( 17235e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1724491d8ee7SSantosh Puranik if (ec) 1725491d8ee7SSantosh Puranik { 1726491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1727491d8ee7SSantosh Puranik messages::internalError(aResp->res); 1728491d8ee7SSantosh Puranik return; 1729491d8ee7SSantosh Puranik } 1730491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Boot mode update done."; 1731491d8ee7SSantosh Puranik }, 1732c21865c4SKonstantin Aladyshev "xyz.openbmc_project.Settings", 1733c21865c4SKonstantin Aladyshev "/xyz/openbmc_project/control/host0/boot", 1734491d8ee7SSantosh Puranik "org.freedesktop.DBus.Properties", "Set", 1735491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1736168e20c1SEd Tanous dbus::utility::DbusVariantType(bootModeStr)); 1737cd9a4666SKonstantin Aladyshev } 1738944ffaf9SJohnathan Mantey 1739cd9a4666SKonstantin Aladyshev /** 1740c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1741491d8ee7SSantosh Puranik * 1742491d8ee7SSantosh Puranik * @param[in] aResp Shared pointer for generating response message. 1743491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1744cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1745491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1746491d8ee7SSantosh Puranik * 1747265c1602SJohnathan Mantey * @return Integer error code. 1748491d8ee7SSantosh Puranik */ 1749c21865c4SKonstantin Aladyshev 1750c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1751c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1752c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1753c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1754491d8ee7SSantosh Puranik { 1755491d8ee7SSantosh Puranik BMCWEB_LOG_DEBUG << "Set boot information."; 1756491d8ee7SSantosh Puranik 1757c21865c4SKonstantin Aladyshev setBootModeOrSource(aResp, bootSource); 1758c21865c4SKonstantin Aladyshev setBootType(aResp, bootType); 1759c21865c4SKonstantin Aladyshev setBootEnable(aResp, bootEnable); 1760491d8ee7SSantosh Puranik } 1761491d8ee7SSantosh Puranik 1762c6a620f2SGeorge Liu /** 176398e386ecSGunnar Mills * @brief Sets AssetTag 176498e386ecSGunnar Mills * 176598e386ecSGunnar Mills * @param[in] aResp Shared pointer for generating response message. 176698e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 176798e386ecSGunnar Mills * 176898e386ecSGunnar Mills * @return None. 176998e386ecSGunnar Mills */ 17708d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 177198e386ecSGunnar Mills const std::string& assetTag) 177298e386ecSGunnar Mills { 1773e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1774e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1775e99073f5SGeorge Liu dbus::utility::getSubTree( 1776e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1777b9d36b47SEd Tanous [aResp, 1778e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1779b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 178098e386ecSGunnar Mills if (ec) 178198e386ecSGunnar Mills { 178298e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec; 178398e386ecSGunnar Mills messages::internalError(aResp->res); 178498e386ecSGunnar Mills return; 178598e386ecSGunnar Mills } 178626f6976fSEd Tanous if (subtree.empty()) 178798e386ecSGunnar Mills { 178898e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!"; 178998e386ecSGunnar Mills messages::internalError(aResp->res); 179098e386ecSGunnar Mills return; 179198e386ecSGunnar Mills } 179298e386ecSGunnar Mills // Assume only 1 system D-Bus object 179398e386ecSGunnar Mills // Throw an error if there is more than 1 179498e386ecSGunnar Mills if (subtree.size() > 1) 179598e386ecSGunnar Mills { 179698e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!"; 179798e386ecSGunnar Mills messages::internalError(aResp->res); 179898e386ecSGunnar Mills return; 179998e386ecSGunnar Mills } 180098e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 180198e386ecSGunnar Mills { 180298e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!"; 180398e386ecSGunnar Mills messages::internalError(aResp->res); 180498e386ecSGunnar Mills return; 180598e386ecSGunnar Mills } 180698e386ecSGunnar Mills 180798e386ecSGunnar Mills const std::string& path = subtree[0].first; 180898e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 180998e386ecSGunnar Mills 181098e386ecSGunnar Mills if (service.empty()) 181198e386ecSGunnar Mills { 181298e386ecSGunnar Mills BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!"; 181398e386ecSGunnar Mills messages::internalError(aResp->res); 181498e386ecSGunnar Mills return; 181598e386ecSGunnar Mills } 181698e386ecSGunnar Mills 181798e386ecSGunnar Mills crow::connections::systemBus->async_method_call( 18185e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 181998e386ecSGunnar Mills if (ec2) 182098e386ecSGunnar Mills { 1821002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set " 1822002d39b4SEd Tanous << ec2; 182398e386ecSGunnar Mills messages::internalError(aResp->res); 182498e386ecSGunnar Mills return; 182598e386ecSGunnar Mills } 182698e386ecSGunnar Mills }, 182798e386ecSGunnar Mills service, path, "org.freedesktop.DBus.Properties", "Set", 182898e386ecSGunnar Mills "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 1829168e20c1SEd Tanous dbus::utility::DbusVariantType(assetTag)); 1830e99073f5SGeorge Liu }); 183198e386ecSGunnar Mills } 183298e386ecSGunnar Mills 183398e386ecSGunnar Mills /** 183469f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 183569f35306SGunnar Mills * 183669f35306SGunnar Mills * @param[in] aResp Shared pointer for generating response message. 183769f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 183869f35306SGunnar Mills * 183969f35306SGunnar Mills * @return None. 184069f35306SGunnar Mills */ 18418d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1842f23b7296SEd Tanous const std::string& automaticRetryConfig) 184369f35306SGunnar Mills { 184469f35306SGunnar Mills BMCWEB_LOG_DEBUG << "Set Automatic Retry."; 184569f35306SGunnar Mills 184669f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1847543f4400SEd Tanous bool autoRebootEnabled = false; 184869f35306SGunnar Mills 184969f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 185069f35306SGunnar Mills { 185169f35306SGunnar Mills autoRebootEnabled = false; 185269f35306SGunnar Mills } 185369f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 185469f35306SGunnar Mills { 185569f35306SGunnar Mills autoRebootEnabled = true; 185669f35306SGunnar Mills } 185769f35306SGunnar Mills else 185869f35306SGunnar Mills { 18590fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: " 186069f35306SGunnar Mills << automaticRetryConfig; 186169f35306SGunnar Mills messages::propertyValueNotInList(aResp->res, automaticRetryConfig, 186269f35306SGunnar Mills "AutomaticRetryConfig"); 186369f35306SGunnar Mills return; 186469f35306SGunnar Mills } 186569f35306SGunnar Mills 186669f35306SGunnar Mills crow::connections::systemBus->async_method_call( 18675e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 186869f35306SGunnar Mills if (ec) 186969f35306SGunnar Mills { 187069f35306SGunnar Mills messages::internalError(aResp->res); 187169f35306SGunnar Mills return; 187269f35306SGunnar Mills } 187369f35306SGunnar Mills }, 187469f35306SGunnar Mills "xyz.openbmc_project.Settings", 187569f35306SGunnar Mills "/xyz/openbmc_project/control/host0/auto_reboot", 187669f35306SGunnar Mills "org.freedesktop.DBus.Properties", "Set", 187769f35306SGunnar Mills "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1878168e20c1SEd Tanous dbus::utility::DbusVariantType(autoRebootEnabled)); 187969f35306SGunnar Mills } 188069f35306SGunnar Mills 188169f35306SGunnar Mills /** 1882c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1883c6a620f2SGeorge Liu * 1884c6a620f2SGeorge Liu * @param[in] aResp Shared pointer for generating response message. 1885c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1886c6a620f2SGeorge Liu * 1887c6a620f2SGeorge Liu * @return None. 1888c6a620f2SGeorge Liu */ 18898d1b46d7Szhanghch05 inline void 18908d1b46d7Szhanghch05 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 18914e69c904SGunnar Mills const std::string& policy) 1892c6a620f2SGeorge Liu { 1893c6a620f2SGeorge Liu BMCWEB_LOG_DEBUG << "Set power restore policy."; 1894c6a620f2SGeorge Liu 1895c6a620f2SGeorge Liu const boost::container::flat_map<std::string, std::string> policyMaps = { 18960fda0f12SGeorge Liu {"AlwaysOn", 18970fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"}, 18980fda0f12SGeorge Liu {"AlwaysOff", 18990fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"}, 19000fda0f12SGeorge Liu {"LastState", 19010fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}}; 1902c6a620f2SGeorge Liu 1903c6a620f2SGeorge Liu std::string powerRestorPolicy; 1904c6a620f2SGeorge Liu 19054e69c904SGunnar Mills auto policyMapsIt = policyMaps.find(policy); 1906c6a620f2SGeorge Liu if (policyMapsIt == policyMaps.end()) 1907c6a620f2SGeorge Liu { 19084e69c904SGunnar Mills messages::propertyValueNotInList(aResp->res, policy, 19094e69c904SGunnar Mills "PowerRestorePolicy"); 1910c6a620f2SGeorge Liu return; 1911c6a620f2SGeorge Liu } 1912c6a620f2SGeorge Liu 1913c6a620f2SGeorge Liu powerRestorPolicy = policyMapsIt->second; 1914c6a620f2SGeorge Liu 1915c6a620f2SGeorge Liu crow::connections::systemBus->async_method_call( 19165e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 1917c6a620f2SGeorge Liu if (ec) 1918c6a620f2SGeorge Liu { 1919c6a620f2SGeorge Liu messages::internalError(aResp->res); 1920c6a620f2SGeorge Liu return; 1921c6a620f2SGeorge Liu } 1922c6a620f2SGeorge Liu }, 1923c6a620f2SGeorge Liu "xyz.openbmc_project.Settings", 1924c6a620f2SGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 1925c6a620f2SGeorge Liu "org.freedesktop.DBus.Properties", "Set", 1926c6a620f2SGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1927168e20c1SEd Tanous dbus::utility::DbusVariantType(powerRestorPolicy)); 1928c6a620f2SGeorge Liu } 1929c6a620f2SGeorge Liu 1930a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 1931a6349918SAppaRao Puli /** 1932a6349918SAppaRao Puli * @brief Retrieves provisioning status 1933a6349918SAppaRao Puli * 1934a6349918SAppaRao Puli * @param[in] aResp Shared pointer for completing asynchronous calls. 1935a6349918SAppaRao Puli * 1936a6349918SAppaRao Puli * @return None. 1937a6349918SAppaRao Puli */ 19388d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp) 1939a6349918SAppaRao Puli { 1940a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Get OEM information."; 1941bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1942bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1943bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 19445e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 1945b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1946b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1947b99fb1a9SAppaRao Puli aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 194850626f4fSJames Feist aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 194950626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 195050626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 195150626f4fSJames Feist 1952a6349918SAppaRao Puli if (ec) 1953a6349918SAppaRao Puli { 1954a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1955b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1956b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1957a6349918SAppaRao Puli return; 1958a6349918SAppaRao Puli } 1959a6349918SAppaRao Puli 1960a6349918SAppaRao Puli const bool* provState = nullptr; 1961a6349918SAppaRao Puli const bool* lockState = nullptr; 1962bc1d29deSKrzysztof Grobelny 1963bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 19640d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 19650d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 1966bc1d29deSKrzysztof Grobelny 1967bc1d29deSKrzysztof Grobelny if (!success) 1968a6349918SAppaRao Puli { 1969bc1d29deSKrzysztof Grobelny messages::internalError(aResp->res); 1970bc1d29deSKrzysztof Grobelny return; 1971a6349918SAppaRao Puli } 1972a6349918SAppaRao Puli 1973a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 1974a6349918SAppaRao Puli { 1975a6349918SAppaRao Puli BMCWEB_LOG_DEBUG << "Unable to get PFR attributes."; 1976a6349918SAppaRao Puli messages::internalError(aResp->res); 1977a6349918SAppaRao Puli return; 1978a6349918SAppaRao Puli } 1979a6349918SAppaRao Puli 1980a6349918SAppaRao Puli if (*provState == true) 1981a6349918SAppaRao Puli { 1982a6349918SAppaRao Puli if (*lockState == true) 1983a6349918SAppaRao Puli { 1984a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 1985a6349918SAppaRao Puli } 1986a6349918SAppaRao Puli else 1987a6349918SAppaRao Puli { 1988a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 1989a6349918SAppaRao Puli } 1990a6349918SAppaRao Puli } 1991a6349918SAppaRao Puli else 1992a6349918SAppaRao Puli { 1993a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 1994a6349918SAppaRao Puli } 1995bc1d29deSKrzysztof Grobelny }); 1996a6349918SAppaRao Puli } 1997a6349918SAppaRao Puli #endif 1998a6349918SAppaRao Puli 1999491d8ee7SSantosh Puranik /** 20003a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 20013a2d0424SChris Cain * 20023a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20033a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 20043a2d0424SChris Cain * 20053a2d0424SChris Cain * @return None. 20063a2d0424SChris Cain */ 20073a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 20083a2d0424SChris Cain const std::string& modeValue) 20093a2d0424SChris Cain { 20100fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20113a2d0424SChris Cain { 20123a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "Static"; 20133a2d0424SChris Cain } 20140fda0f12SGeorge Liu else if ( 20150fda0f12SGeorge Liu modeValue == 20160fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20173a2d0424SChris Cain { 20183a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 20193a2d0424SChris Cain } 20200fda0f12SGeorge Liu else if (modeValue == 20210fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20223a2d0424SChris Cain { 20233a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "PowerSaving"; 20243a2d0424SChris Cain } 20250fda0f12SGeorge Liu else if (modeValue == 20260fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20273a2d0424SChris Cain { 20283a2d0424SChris Cain aResp->res.jsonValue["PowerMode"] = "OEM"; 20293a2d0424SChris Cain } 20303a2d0424SChris Cain else 20313a2d0424SChris Cain { 20323a2d0424SChris Cain // Any other values would be invalid 20333a2d0424SChris Cain BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue; 20343a2d0424SChris Cain messages::internalError(aResp->res); 20353a2d0424SChris Cain } 20363a2d0424SChris Cain } 20373a2d0424SChris Cain 20383a2d0424SChris Cain /** 20393a2d0424SChris Cain * @brief Retrieves system power mode 20403a2d0424SChris Cain * 20413a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 20423a2d0424SChris Cain * 20433a2d0424SChris Cain * @return None. 20443a2d0424SChris Cain */ 20453a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 20463a2d0424SChris Cain { 20473a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Get power mode."; 20483a2d0424SChris Cain 20493a2d0424SChris Cain // Get Power Mode object path: 2050e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2051e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2052e99073f5SGeorge Liu dbus::utility::getSubTree( 2053e99073f5SGeorge Liu "/", 0, interfaces, 2054e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 2055b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 20563a2d0424SChris Cain if (ec) 20573a2d0424SChris Cain { 2058002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2059002d39b4SEd Tanous << ec; 20603a2d0424SChris Cain // This is an optional D-Bus object so just return if 20613a2d0424SChris Cain // error occurs 20623a2d0424SChris Cain return; 20633a2d0424SChris Cain } 20643a2d0424SChris Cain if (subtree.empty()) 20653a2d0424SChris Cain { 20663a2d0424SChris Cain // As noted above, this is an optional interface so just return 20673a2d0424SChris Cain // if there is no instance found 20683a2d0424SChris Cain return; 20693a2d0424SChris Cain } 20703a2d0424SChris Cain if (subtree.size() > 1) 20713a2d0424SChris Cain { 20723a2d0424SChris Cain // More then one PowerMode object is not supported and is an 20733a2d0424SChris Cain // error 20743a2d0424SChris Cain BMCWEB_LOG_DEBUG 20753a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 20763a2d0424SChris Cain << subtree.size(); 20773a2d0424SChris Cain messages::internalError(aResp->res); 20783a2d0424SChris Cain return; 20793a2d0424SChris Cain } 20803a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 20813a2d0424SChris Cain { 20823a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 20833a2d0424SChris Cain messages::internalError(aResp->res); 20843a2d0424SChris Cain return; 20853a2d0424SChris Cain } 20863a2d0424SChris Cain const std::string& path = subtree[0].first; 20873a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 20883a2d0424SChris Cain if (service.empty()) 20893a2d0424SChris Cain { 20903a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 20913a2d0424SChris Cain messages::internalError(aResp->res); 20923a2d0424SChris Cain return; 20933a2d0424SChris Cain } 20943a2d0424SChris Cain // Valid Power Mode object found, now read the current value 20951e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 20961e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 20971e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 20985e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, 20991e1e598dSJonathan Doman const std::string& pmode) { 21008a592810SEd Tanous if (ec2) 21013a2d0424SChris Cain { 2102002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: " 21038a592810SEd Tanous << ec2; 21043a2d0424SChris Cain messages::internalError(aResp->res); 21053a2d0424SChris Cain return; 21063a2d0424SChris Cain } 21073a2d0424SChris Cain 2108002d39b4SEd Tanous aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2109002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 21103a2d0424SChris Cain 21111e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Current power mode: " << pmode; 21121e1e598dSJonathan Doman translatePowerMode(aResp, pmode); 21131e1e598dSJonathan Doman }); 2114e99073f5SGeorge Liu }); 21153a2d0424SChris Cain } 21163a2d0424SChris Cain 21173a2d0424SChris Cain /** 21183a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 21193a2d0424SChris Cain * name associated with that string 21203a2d0424SChris Cain * 21213a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21223a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 21233a2d0424SChris Cain * 21243a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 21253a2d0424SChris Cain */ 21263a2d0424SChris Cain inline std::string 21273a2d0424SChris Cain validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21283a2d0424SChris Cain const std::string& modeString) 21293a2d0424SChris Cain { 21303a2d0424SChris Cain std::string mode; 21313a2d0424SChris Cain 21323a2d0424SChris Cain if (modeString == "Static") 21333a2d0424SChris Cain { 21343a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 21353a2d0424SChris Cain } 21363a2d0424SChris Cain else if (modeString == "MaximumPerformance") 21373a2d0424SChris Cain { 21380fda0f12SGeorge Liu mode = 21390fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 21403a2d0424SChris Cain } 21413a2d0424SChris Cain else if (modeString == "PowerSaving") 21423a2d0424SChris Cain { 21433a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 21443a2d0424SChris Cain } 21453a2d0424SChris Cain else 21463a2d0424SChris Cain { 21473a2d0424SChris Cain messages::propertyValueNotInList(aResp->res, modeString, "PowerMode"); 21483a2d0424SChris Cain } 21493a2d0424SChris Cain return mode; 21503a2d0424SChris Cain } 21513a2d0424SChris Cain 21523a2d0424SChris Cain /** 21533a2d0424SChris Cain * @brief Sets system power mode. 21543a2d0424SChris Cain * 21553a2d0424SChris Cain * @param[in] aResp Shared pointer for generating response message. 21563a2d0424SChris Cain * @param[in] pmode System power mode from request. 21573a2d0424SChris Cain * 21583a2d0424SChris Cain * @return None. 21593a2d0424SChris Cain */ 21603a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 21613a2d0424SChris Cain const std::string& pmode) 21623a2d0424SChris Cain { 21633a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Set power mode."; 21643a2d0424SChris Cain 21653a2d0424SChris Cain std::string powerMode = validatePowerMode(aResp, pmode); 21663a2d0424SChris Cain if (powerMode.empty()) 21673a2d0424SChris Cain { 21683a2d0424SChris Cain return; 21693a2d0424SChris Cain } 21703a2d0424SChris Cain 21713a2d0424SChris Cain // Get Power Mode object path: 2172e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2173e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2174e99073f5SGeorge Liu dbus::utility::getSubTree( 2175e99073f5SGeorge Liu "/", 0, interfaces, 2176b9d36b47SEd Tanous [aResp, 2177e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2178b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21793a2d0424SChris Cain if (ec) 21803a2d0424SChris Cain { 2181002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree " 2182002d39b4SEd Tanous << ec; 21833a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 21843a2d0424SChris Cain messages::internalError(aResp->res); 21853a2d0424SChris Cain return; 21863a2d0424SChris Cain } 21873a2d0424SChris Cain if (subtree.empty()) 21883a2d0424SChris Cain { 21893a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 21903a2d0424SChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 21913a2d0424SChris Cain "PowerMode"); 21923a2d0424SChris Cain return; 21933a2d0424SChris Cain } 21943a2d0424SChris Cain if (subtree.size() > 1) 21953a2d0424SChris Cain { 21963a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21973a2d0424SChris Cain // error 21983a2d0424SChris Cain BMCWEB_LOG_DEBUG 21993a2d0424SChris Cain << "Found more than 1 system D-Bus Power.Mode objects: " 22003a2d0424SChris Cain << subtree.size(); 22013a2d0424SChris Cain messages::internalError(aResp->res); 22023a2d0424SChris Cain return; 22033a2d0424SChris Cain } 22043a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22053a2d0424SChris Cain { 22063a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode mapper error!"; 22073a2d0424SChris Cain messages::internalError(aResp->res); 22083a2d0424SChris Cain return; 22093a2d0424SChris Cain } 22103a2d0424SChris Cain const std::string& path = subtree[0].first; 22113a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22123a2d0424SChris Cain if (service.empty()) 22133a2d0424SChris Cain { 22143a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!"; 22153a2d0424SChris Cain messages::internalError(aResp->res); 22163a2d0424SChris Cain return; 22173a2d0424SChris Cain } 22183a2d0424SChris Cain 22193a2d0424SChris Cain BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> " 22203a2d0424SChris Cain << path; 22213a2d0424SChris Cain 22223a2d0424SChris Cain // Set the Power Mode property 22233a2d0424SChris Cain crow::connections::systemBus->async_method_call( 22245e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 22258a592810SEd Tanous if (ec2) 22263a2d0424SChris Cain { 22273a2d0424SChris Cain messages::internalError(aResp->res); 22283a2d0424SChris Cain return; 22293a2d0424SChris Cain } 22303a2d0424SChris Cain }, 22313a2d0424SChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 22323a2d0424SChris Cain "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2233168e20c1SEd Tanous dbus::utility::DbusVariantType(powerMode)); 2234e99073f5SGeorge Liu }); 22353a2d0424SChris Cain } 22363a2d0424SChris Cain 22373a2d0424SChris Cain /** 223851709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 223951709ffdSYong Li * 224051709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 224151709ffdSYong Li * 224251709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 224351709ffdSYong Li * translation cannot be done, returns an empty string. 224451709ffdSYong Li */ 224523a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 224651709ffdSYong Li { 224751709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 224851709ffdSYong Li { 224951709ffdSYong Li return "None"; 225051709ffdSYong Li } 22513174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 225251709ffdSYong Li { 225351709ffdSYong Li return "ResetSystem"; 225451709ffdSYong Li } 22553174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 225651709ffdSYong Li { 225751709ffdSYong Li return "PowerDown"; 225851709ffdSYong Li } 22593174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 226051709ffdSYong Li { 226151709ffdSYong Li return "PowerCycle"; 226251709ffdSYong Li } 226351709ffdSYong Li 226451709ffdSYong Li return ""; 226551709ffdSYong Li } 226651709ffdSYong Li 226751709ffdSYong Li /** 2268c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2269c45f0082SYong Li * 2270c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2271c45f0082SYong Li * 2272c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2273c45f0082SYong Li *If translation cannot be done, returns an empty string. 2274c45f0082SYong Li */ 2275c45f0082SYong Li 227623a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2277c45f0082SYong Li { 2278c45f0082SYong Li if (rfAction == "None") 2279c45f0082SYong Li { 2280c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2281c45f0082SYong Li } 22823174e4dfSEd Tanous if (rfAction == "PowerCycle") 2283c45f0082SYong Li { 2284c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2285c45f0082SYong Li } 22863174e4dfSEd Tanous if (rfAction == "PowerDown") 2287c45f0082SYong Li { 2288c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2289c45f0082SYong Li } 22903174e4dfSEd Tanous if (rfAction == "ResetSystem") 2291c45f0082SYong Li { 2292c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2293c45f0082SYong Li } 2294c45f0082SYong Li 2295c45f0082SYong Li return ""; 2296c45f0082SYong Li } 2297c45f0082SYong Li 2298c45f0082SYong Li /** 229951709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 230051709ffdSYong Li * 230151709ffdSYong Li * @param[in] aResp Shared pointer for completing asynchronous calls. 230251709ffdSYong Li * 230351709ffdSYong Li * @return None. 230451709ffdSYong Li */ 23058d1b46d7Szhanghch05 inline void 23068d1b46d7Szhanghch05 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 230751709ffdSYong Li { 230851709ffdSYong Li BMCWEB_LOG_DEBUG << "Get host watchodg"; 2309bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2310bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2311bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2312bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 23135e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 2314b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 231551709ffdSYong Li if (ec) 231651709ffdSYong Li { 231751709ffdSYong Li // watchdog service is stopped 231851709ffdSYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 231951709ffdSYong Li return; 232051709ffdSYong Li } 232151709ffdSYong Li 232251709ffdSYong Li BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop."; 232351709ffdSYong Li 232451709ffdSYong Li nlohmann::json& hostWatchdogTimer = 232551709ffdSYong Li aResp->res.jsonValue["HostWatchdogTimer"]; 232651709ffdSYong Li 232751709ffdSYong Li // watchdog service is running/enabled 232851709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 232951709ffdSYong Li 2330bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2331bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 233251709ffdSYong Li 2333bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2334bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2335bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2336bc1d29deSKrzysztof Grobelny 2337bc1d29deSKrzysztof Grobelny if (!success) 233851709ffdSYong Li { 233951709ffdSYong Li messages::internalError(aResp->res); 2340601af5edSChicago Duan return; 234151709ffdSYong Li } 234251709ffdSYong Li 2343bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 234451709ffdSYong Li { 2345bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 234651709ffdSYong Li } 234751709ffdSYong Li 2348bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2349bc1d29deSKrzysztof Grobelny { 2350bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 235151709ffdSYong Li if (action.empty()) 235251709ffdSYong Li { 235351709ffdSYong Li messages::internalError(aResp->res); 2354601af5edSChicago Duan return; 235551709ffdSYong Li } 235651709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 235751709ffdSYong Li } 2358bc1d29deSKrzysztof Grobelny }); 235951709ffdSYong Li } 236051709ffdSYong Li 236151709ffdSYong Li /** 2362c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2363c45f0082SYong Li * 2364c45f0082SYong Li * @param[in] aResp Shared pointer for generating response message. 2365c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2366c45f0082SYong Li * RF request. 2367c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2368c45f0082SYong Li * 2369c45f0082SYong Li * @return None. 2370c45f0082SYong Li */ 23718d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 2372c45f0082SYong Li const std::optional<bool> wdtEnable, 2373c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2374c45f0082SYong Li { 2375c45f0082SYong Li BMCWEB_LOG_DEBUG << "Set host watchdog"; 2376c45f0082SYong Li 2377c45f0082SYong Li if (wdtTimeOutAction) 2378c45f0082SYong Li { 2379c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2380c45f0082SYong Li // check if TimeOut Action is Valid 2381c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2382c45f0082SYong Li { 2383c45f0082SYong Li BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: " 2384c45f0082SYong Li << *wdtTimeOutAction; 2385c45f0082SYong Li messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction, 2386c45f0082SYong Li "TimeoutAction"); 2387c45f0082SYong Li return; 2388c45f0082SYong Li } 2389c45f0082SYong Li 2390c45f0082SYong Li crow::connections::systemBus->async_method_call( 23915e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 2392c45f0082SYong Li if (ec) 2393c45f0082SYong Li { 2394c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2395c45f0082SYong Li messages::internalError(aResp->res); 2396c45f0082SYong Li return; 2397c45f0082SYong Li } 2398c45f0082SYong Li }, 2399c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2400c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2401c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2402c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2403168e20c1SEd Tanous dbus::utility::DbusVariantType(wdtTimeOutActStr)); 2404c45f0082SYong Li } 2405c45f0082SYong Li 2406c45f0082SYong Li if (wdtEnable) 2407c45f0082SYong Li { 2408c45f0082SYong Li crow::connections::systemBus->async_method_call( 24095e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 2410c45f0082SYong Li if (ec) 2411c45f0082SYong Li { 2412c45f0082SYong Li BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 2413c45f0082SYong Li messages::internalError(aResp->res); 2414c45f0082SYong Li return; 2415c45f0082SYong Li } 2416c45f0082SYong Li }, 2417c45f0082SYong Li "xyz.openbmc_project.Watchdog", 2418c45f0082SYong Li "/xyz/openbmc_project/watchdog/host0", 2419c45f0082SYong Li "org.freedesktop.DBus.Properties", "Set", 2420c45f0082SYong Li "xyz.openbmc_project.State.Watchdog", "Enabled", 2421168e20c1SEd Tanous dbus::utility::DbusVariantType(*wdtEnable)); 2422c45f0082SYong Li } 2423c45f0082SYong Li } 2424c45f0082SYong Li 242537bbf98cSChris Cain /** 242637bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 242737bbf98cSChris Cain * 242837bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 242937bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 243037bbf98cSChris Cain * 243137bbf98cSChris Cain * @return true if successful 243237bbf98cSChris Cain */ 24331e5b7c88SJiaqing Zhao inline bool 24341e5b7c88SJiaqing Zhao parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 24351e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 243637bbf98cSChris Cain { 2437bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2438bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2439bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2440bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2441bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2442bc1d29deSKrzysztof Grobelny 2443bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2444bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 24452661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 24462661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 24472661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2448bc1d29deSKrzysztof Grobelny 2449bc1d29deSKrzysztof Grobelny if (!success) 245037bbf98cSChris Cain { 245137bbf98cSChris Cain return false; 245237bbf98cSChris Cain } 2453bc1d29deSKrzysztof Grobelny 2454bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 245537bbf98cSChris Cain { 2456bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 245737bbf98cSChris Cain } 2458bc1d29deSKrzysztof Grobelny 2459bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 246037bbf98cSChris Cain { 2461bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2462bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 246337bbf98cSChris Cain } 2464bc1d29deSKrzysztof Grobelny 2465bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2466bc1d29deSKrzysztof Grobelny { 2467bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 246837bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 246937bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 247037bbf98cSChris Cain .count(); 247137bbf98cSChris Cain } 2472bc1d29deSKrzysztof Grobelny 2473bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 247437bbf98cSChris Cain { 2475bc1d29deSKrzysztof Grobelny aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2476bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 247737bbf98cSChris Cain } 2478bc1d29deSKrzysztof Grobelny 2479bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 248037bbf98cSChris Cain { 2481bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 248237bbf98cSChris Cain aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 248337bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 248437bbf98cSChris Cain .count(); 248537bbf98cSChris Cain } 248637bbf98cSChris Cain 248737bbf98cSChris Cain return true; 248837bbf98cSChris Cain } 248937bbf98cSChris Cain 249037bbf98cSChris Cain /** 249137bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 249237bbf98cSChris Cain * 249337bbf98cSChris Cain * @param[in] aResp Shared pointer for completing asynchronous calls. 249437bbf98cSChris Cain * 249537bbf98cSChris Cain * @return None. 249637bbf98cSChris Cain */ 249737bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 249837bbf98cSChris Cain { 249937bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Get idle power saver parameters"; 250037bbf98cSChris Cain 250137bbf98cSChris Cain // Get IdlePowerSaver object path: 2502e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2503e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2504e99073f5SGeorge Liu dbus::utility::getSubTree( 2505e99073f5SGeorge Liu "/", 0, interfaces, 2506e99073f5SGeorge Liu [aResp](const boost::system::error_code& ec, 2507b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 250837bbf98cSChris Cain if (ec) 250937bbf98cSChris Cain { 251037bbf98cSChris Cain BMCWEB_LOG_DEBUG 251137bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 251237bbf98cSChris Cain << ec; 251337bbf98cSChris Cain messages::internalError(aResp->res); 251437bbf98cSChris Cain return; 251537bbf98cSChris Cain } 251637bbf98cSChris Cain if (subtree.empty()) 251737bbf98cSChris Cain { 251837bbf98cSChris Cain // This is an optional interface so just return 251937bbf98cSChris Cain // if there is no instance found 252037bbf98cSChris Cain BMCWEB_LOG_DEBUG << "No instances found"; 252137bbf98cSChris Cain return; 252237bbf98cSChris Cain } 252337bbf98cSChris Cain if (subtree.size() > 1) 252437bbf98cSChris Cain { 252537bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 252637bbf98cSChris Cain // is an error 252737bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus " 252837bbf98cSChris Cain "Power.IdlePowerSaver objects: " 252937bbf98cSChris Cain << subtree.size(); 253037bbf98cSChris Cain messages::internalError(aResp->res); 253137bbf98cSChris Cain return; 253237bbf98cSChris Cain } 253337bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 253437bbf98cSChris Cain { 253537bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 253637bbf98cSChris Cain messages::internalError(aResp->res); 253737bbf98cSChris Cain return; 253837bbf98cSChris Cain } 253937bbf98cSChris Cain const std::string& path = subtree[0].first; 254037bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 254137bbf98cSChris Cain if (service.empty()) 254237bbf98cSChris Cain { 2543002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 254437bbf98cSChris Cain messages::internalError(aResp->res); 254537bbf98cSChris Cain return; 254637bbf98cSChris Cain } 254737bbf98cSChris Cain 254837bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2549bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2550bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2551bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 25525e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2, 25531e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 25548a592810SEd Tanous if (ec2) 255537bbf98cSChris Cain { 255637bbf98cSChris Cain BMCWEB_LOG_ERROR 25578a592810SEd Tanous << "DBUS response error on IdlePowerSaver GetAll: " << ec2; 255837bbf98cSChris Cain messages::internalError(aResp->res); 255937bbf98cSChris Cain return; 256037bbf98cSChris Cain } 256137bbf98cSChris Cain 2562e05aec50SEd Tanous if (!parseIpsProperties(aResp, properties)) 256337bbf98cSChris Cain { 256437bbf98cSChris Cain messages::internalError(aResp->res); 256537bbf98cSChris Cain return; 256637bbf98cSChris Cain } 2567bc1d29deSKrzysztof Grobelny }); 2568e99073f5SGeorge Liu }); 256937bbf98cSChris Cain 257037bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters"; 257137bbf98cSChris Cain } 257237bbf98cSChris Cain 257337bbf98cSChris Cain /** 257437bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 257537bbf98cSChris Cain * 257637bbf98cSChris Cain * @param[in] aResp Shared pointer for generating response message. 257737bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 257837bbf98cSChris Cain * RF request. 257937bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 258037bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 258137bbf98cSChris Cain * before entering idle state. 258237bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 258337bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 258437bbf98cSChris Cain * before exiting idle state 258537bbf98cSChris Cain * 258637bbf98cSChris Cain * @return None. 258737bbf98cSChris Cain */ 258837bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 258937bbf98cSChris Cain const std::optional<bool> ipsEnable, 259037bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 259137bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 259237bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 259337bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 259437bbf98cSChris Cain { 259537bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Set idle power saver properties"; 259637bbf98cSChris Cain 259737bbf98cSChris Cain // Get IdlePowerSaver object path: 2598e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2599e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2600e99073f5SGeorge Liu dbus::utility::getSubTree( 2601e99073f5SGeorge Liu "/", 0, interfaces, 260237bbf98cSChris Cain [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2603e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2604b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 260537bbf98cSChris Cain if (ec) 260637bbf98cSChris Cain { 260737bbf98cSChris Cain BMCWEB_LOG_DEBUG 260837bbf98cSChris Cain << "DBUS response error on Power.IdlePowerSaver GetSubTree " 260937bbf98cSChris Cain << ec; 261037bbf98cSChris Cain messages::internalError(aResp->res); 261137bbf98cSChris Cain return; 261237bbf98cSChris Cain } 261337bbf98cSChris Cain if (subtree.empty()) 261437bbf98cSChris Cain { 261537bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 261637bbf98cSChris Cain messages::resourceNotFound(aResp->res, "ComputerSystem", 261737bbf98cSChris Cain "IdlePowerSaver"); 261837bbf98cSChris Cain return; 261937bbf98cSChris Cain } 262037bbf98cSChris Cain if (subtree.size() > 1) 262137bbf98cSChris Cain { 262237bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 262337bbf98cSChris Cain // is an error 26240fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 26250fda0f12SGeorge Liu << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: " 262637bbf98cSChris Cain << subtree.size(); 262737bbf98cSChris Cain messages::internalError(aResp->res); 262837bbf98cSChris Cain return; 262937bbf98cSChris Cain } 263037bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 263137bbf98cSChris Cain { 263237bbf98cSChris Cain BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!"; 263337bbf98cSChris Cain messages::internalError(aResp->res); 263437bbf98cSChris Cain return; 263537bbf98cSChris Cain } 263637bbf98cSChris Cain const std::string& path = subtree[0].first; 263737bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 263837bbf98cSChris Cain if (service.empty()) 263937bbf98cSChris Cain { 2640002d39b4SEd Tanous BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!"; 264137bbf98cSChris Cain messages::internalError(aResp->res); 264237bbf98cSChris Cain return; 264337bbf98cSChris Cain } 264437bbf98cSChris Cain 264537bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 264637bbf98cSChris Cain // need to be updated 264737bbf98cSChris Cain 264837bbf98cSChris Cain if (ipsEnable) 264937bbf98cSChris Cain { 265037bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26515e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 26528a592810SEd Tanous if (ec2) 265337bbf98cSChris Cain { 26548a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 265537bbf98cSChris Cain messages::internalError(aResp->res); 265637bbf98cSChris Cain return; 265737bbf98cSChris Cain } 265837bbf98cSChris Cain }, 265937bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 2660002d39b4SEd Tanous "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 2661002d39b4SEd Tanous dbus::utility::DbusVariantType(*ipsEnable)); 266237bbf98cSChris Cain } 266337bbf98cSChris Cain if (ipsEnterUtil) 266437bbf98cSChris Cain { 266537bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26665e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 26678a592810SEd Tanous if (ec2) 266837bbf98cSChris Cain { 26698a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 267037bbf98cSChris Cain messages::internalError(aResp->res); 267137bbf98cSChris Cain return; 267237bbf98cSChris Cain } 267337bbf98cSChris Cain }, 267437bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 267537bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 267637bbf98cSChris Cain "EnterUtilizationPercent", 2677168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsEnterUtil)); 267837bbf98cSChris Cain } 267937bbf98cSChris Cain if (ipsEnterTime) 268037bbf98cSChris Cain { 268137bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 268237bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 268337bbf98cSChris Cain crow::connections::systemBus->async_method_call( 26845e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 26858a592810SEd Tanous if (ec2) 268637bbf98cSChris Cain { 26878a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 268837bbf98cSChris Cain messages::internalError(aResp->res); 268937bbf98cSChris Cain return; 269037bbf98cSChris Cain } 269137bbf98cSChris Cain }, 269237bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 269337bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2694168e20c1SEd Tanous "EnterDwellTime", 2695168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 269637bbf98cSChris Cain } 269737bbf98cSChris Cain if (ipsExitUtil) 269837bbf98cSChris Cain { 269937bbf98cSChris Cain crow::connections::systemBus->async_method_call( 27005e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 27018a592810SEd Tanous if (ec2) 270237bbf98cSChris Cain { 27038a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 270437bbf98cSChris Cain messages::internalError(aResp->res); 270537bbf98cSChris Cain return; 270637bbf98cSChris Cain } 270737bbf98cSChris Cain }, 270837bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 270937bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 271037bbf98cSChris Cain "ExitUtilizationPercent", 2711168e20c1SEd Tanous dbus::utility::DbusVariantType(*ipsExitUtil)); 271237bbf98cSChris Cain } 271337bbf98cSChris Cain if (ipsExitTime) 271437bbf98cSChris Cain { 271537bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 271637bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 271737bbf98cSChris Cain crow::connections::systemBus->async_method_call( 27185e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec2) { 27198a592810SEd Tanous if (ec2) 272037bbf98cSChris Cain { 27218a592810SEd Tanous BMCWEB_LOG_DEBUG << "DBUS response error " << ec2; 272237bbf98cSChris Cain messages::internalError(aResp->res); 272337bbf98cSChris Cain return; 272437bbf98cSChris Cain } 272537bbf98cSChris Cain }, 272637bbf98cSChris Cain service, path, "org.freedesktop.DBus.Properties", "Set", 272737bbf98cSChris Cain "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2728168e20c1SEd Tanous "ExitDwellTime", 2729168e20c1SEd Tanous dbus::utility::DbusVariantType(timeMilliseconds)); 273037bbf98cSChris Cain } 2731e99073f5SGeorge Liu }); 273237bbf98cSChris Cain 273337bbf98cSChris Cain BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters"; 273437bbf98cSChris Cain } 273537bbf98cSChris Cain 2736dd60b9edSEd Tanous inline void handleComputerSystemHead( 2737dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2738dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2739dd60b9edSEd Tanous { 2740dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2741dd60b9edSEd Tanous { 2742dd60b9edSEd Tanous return; 2743dd60b9edSEd Tanous } 2744dd60b9edSEd Tanous asyncResp->res.addHeader( 2745dd60b9edSEd Tanous boost::beast::http::field::link, 2746dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2747dd60b9edSEd Tanous } 2748dd60b9edSEd Tanous 2749c45f0082SYong Li /** 2750c5b2abe0SLewanczyk, Dawid * SystemsCollection derived class for delivering ComputerSystems Collection 2751c5b2abe0SLewanczyk, Dawid * Schema 2752c5b2abe0SLewanczyk, Dawid */ 27537e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app) 27541abe55efSEd Tanous { 27557e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2756dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 2757dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 2758dd60b9edSEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 2759dd60b9edSEd Tanous 2760dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 2761ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 27627e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 2763f4c99e70SEd Tanous [&app](const crow::Request& req, 27647e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 27653ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2766f4c99e70SEd Tanous { 2767f4c99e70SEd Tanous return; 2768f4c99e70SEd Tanous } 2769dd60b9edSEd Tanous 2770dd60b9edSEd Tanous asyncResp->res.addHeader( 2771dd60b9edSEd Tanous boost::beast::http::field::link, 2772dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 27738d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 27740f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 27758d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 27768d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2777462023adSSunitha Harish 27781e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2779002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 27801e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2781002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 27825e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 27831e1e598dSJonathan Doman const std::string& /*hostName*/) { 2784002d39b4SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 27852c70f800SEd Tanous ifaceArray = nlohmann::json::array(); 2786002d39b4SEd Tanous auto& count = asyncResp->res.jsonValue["Members@odata.count"]; 27871476687dSEd Tanous 27881476687dSEd Tanous nlohmann::json::object_t system; 27891476687dSEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 2790b2ba3072SPatrick Williams ifaceArray.emplace_back(std::move(system)); 279194bda602STim Lee count = ifaceArray.size(); 27928a592810SEd Tanous if (!ec2) 2793462023adSSunitha Harish { 2794462023adSSunitha Harish BMCWEB_LOG_DEBUG << "Hypervisor is available"; 27951476687dSEd Tanous nlohmann::json::object_t hypervisor; 2796002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 2797b2ba3072SPatrick Williams ifaceArray.emplace_back(std::move(hypervisor)); 27982c70f800SEd Tanous count = ifaceArray.size(); 2799cb13a392SEd Tanous } 28001e1e598dSJonathan Doman }); 28017e860f15SJohn Edward Broadbent }); 2802c5b2abe0SLewanczyk, Dawid } 28037e860f15SJohn Edward Broadbent 28047e860f15SJohn Edward Broadbent /** 28057e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28067e860f15SJohn Edward Broadbent */ 28074f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28087e860f15SJohn Edward Broadbent { 280989492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 281089492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 281189492a15SPatrick Williams constexpr const char* interfaceName = 28127e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 281389492a15SPatrick Williams constexpr const char* method = "NMI"; 28147e860f15SJohn Edward Broadbent 28157e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28165e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28177e860f15SJohn Edward Broadbent if (ec) 28187e860f15SJohn Edward Broadbent { 28197e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec; 28207e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28217e860f15SJohn Edward Broadbent return; 28227e860f15SJohn Edward Broadbent } 28237e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28247e860f15SJohn Edward Broadbent }, 28257e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28267e860f15SJohn Edward Broadbent } 2827c5b2abe0SLewanczyk, Dawid 2828c5b2abe0SLewanczyk, Dawid /** 2829cc340dd9SEd Tanous * SystemActionsReset class supports handle POST method for Reset action. 2830cc340dd9SEd Tanous * The class retrieves and sends data directly to D-Bus. 2831cc340dd9SEd Tanous */ 28327e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app) 2833cc340dd9SEd Tanous { 2834cc340dd9SEd Tanous /** 2835cc340dd9SEd Tanous * Function handles POST method request. 2836cc340dd9SEd Tanous * Analyzes POST body message before sends Reset request data to D-Bus. 2837cc340dd9SEd Tanous */ 28387e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 28397e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/") 2840ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 2841002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 2842002d39b4SEd Tanous [&app](const crow::Request& req, 28437e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 28443ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 284545ca1b86SEd Tanous { 284645ca1b86SEd Tanous return; 284745ca1b86SEd Tanous } 28489712f8acSEd Tanous std::string resetType; 284915ed6780SWilly Tu if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", 28507e860f15SJohn Edward Broadbent resetType)) 2851cc340dd9SEd Tanous { 2852cc340dd9SEd Tanous return; 2853cc340dd9SEd Tanous } 2854cc340dd9SEd Tanous 2855d22c8396SJason M. Bills // Get the command and host vs. chassis 2856cc340dd9SEd Tanous std::string command; 2857543f4400SEd Tanous bool hostCommand = true; 2858d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2859cc340dd9SEd Tanous { 2860cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2861d22c8396SJason M. Bills hostCommand = true; 2862d22c8396SJason M. Bills } 2863d22c8396SJason M. Bills else if (resetType == "ForceOff") 2864d22c8396SJason M. Bills { 2865d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2866d22c8396SJason M. Bills hostCommand = false; 2867d22c8396SJason M. Bills } 2868d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2869d22c8396SJason M. Bills { 287086a0851aSJason M. Bills command = 287186a0851aSJason M. Bills "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 287286a0851aSJason M. Bills hostCommand = true; 2873cc340dd9SEd Tanous } 28749712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2875cc340dd9SEd Tanous { 2876cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2877d22c8396SJason M. Bills hostCommand = true; 2878cc340dd9SEd Tanous } 28799712f8acSEd Tanous else if (resetType == "GracefulRestart") 2880cc340dd9SEd Tanous { 28810fda0f12SGeorge Liu command = 28820fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2883d22c8396SJason M. Bills hostCommand = true; 2884d22c8396SJason M. Bills } 2885d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2886d22c8396SJason M. Bills { 288786a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 288886a0851aSJason M. Bills hostCommand = true; 2889cc340dd9SEd Tanous } 2890bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2891bfd5b826SLakshminarayana R. Kammath { 2892bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2893bfd5b826SLakshminarayana R. Kammath return; 2894bfd5b826SLakshminarayana R. Kammath } 2895cc340dd9SEd Tanous else 2896cc340dd9SEd Tanous { 28978d1b46d7Szhanghch05 messages::actionParameterUnknown(asyncResp->res, "Reset", 28988d1b46d7Szhanghch05 resetType); 2899cc340dd9SEd Tanous return; 2900cc340dd9SEd Tanous } 2901cc340dd9SEd Tanous 2902d22c8396SJason M. Bills if (hostCommand) 2903d22c8396SJason M. Bills { 2904cc340dd9SEd Tanous crow::connections::systemBus->async_method_call( 29055e7e2dc5SEd Tanous [asyncResp, resetType](const boost::system::error_code& ec) { 2906cc340dd9SEd Tanous if (ec) 2907cc340dd9SEd Tanous { 2908cc340dd9SEd Tanous BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 2909002d39b4SEd Tanous if (ec.value() == boost::asio::error::invalid_argument) 2910d22c8396SJason M. Bills { 2911d22c8396SJason M. Bills messages::actionParameterNotSupported( 2912d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2913d22c8396SJason M. Bills } 2914d22c8396SJason M. Bills else 2915d22c8396SJason M. Bills { 2916f12894f8SJason M. Bills messages::internalError(asyncResp->res); 2917d22c8396SJason M. Bills } 2918cc340dd9SEd Tanous return; 2919cc340dd9SEd Tanous } 2920f12894f8SJason M. Bills messages::success(asyncResp->res); 2921cc340dd9SEd Tanous }, 2922cc340dd9SEd Tanous "xyz.openbmc_project.State.Host", 2923cc340dd9SEd Tanous "/xyz/openbmc_project/state/host0", 2924cc340dd9SEd Tanous "org.freedesktop.DBus.Properties", "Set", 29259712f8acSEd Tanous "xyz.openbmc_project.State.Host", "RequestedHostTransition", 2926168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 2927cc340dd9SEd Tanous } 2928d22c8396SJason M. Bills else 2929d22c8396SJason M. Bills { 2930d22c8396SJason M. Bills crow::connections::systemBus->async_method_call( 29315e7e2dc5SEd Tanous [asyncResp, resetType](const boost::system::error_code& ec) { 2932d22c8396SJason M. Bills if (ec) 2933d22c8396SJason M. Bills { 2934d22c8396SJason M. Bills BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 2935002d39b4SEd Tanous if (ec.value() == boost::asio::error::invalid_argument) 2936d22c8396SJason M. Bills { 2937d22c8396SJason M. Bills messages::actionParameterNotSupported( 2938d22c8396SJason M. Bills asyncResp->res, resetType, "Reset"); 2939d22c8396SJason M. Bills } 2940d22c8396SJason M. Bills else 2941d22c8396SJason M. Bills { 2942d22c8396SJason M. Bills messages::internalError(asyncResp->res); 2943d22c8396SJason M. Bills } 2944d22c8396SJason M. Bills return; 2945d22c8396SJason M. Bills } 2946d22c8396SJason M. Bills messages::success(asyncResp->res); 2947d22c8396SJason M. Bills }, 2948d22c8396SJason M. Bills "xyz.openbmc_project.State.Chassis", 2949d22c8396SJason M. Bills "/xyz/openbmc_project/state/chassis0", 2950d22c8396SJason M. Bills "org.freedesktop.DBus.Properties", "Set", 2951002d39b4SEd Tanous "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 2952168e20c1SEd Tanous dbus::utility::DbusVariantType{command}); 2953d22c8396SJason M. Bills } 29547e860f15SJohn Edward Broadbent }); 2955d22c8396SJason M. Bills } 2956cc340dd9SEd Tanous 295738c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead( 2958dd60b9edSEd Tanous App& app, const crow::Request& req, 2959dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2960dd60b9edSEd Tanous { 2961dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2962dd60b9edSEd Tanous { 2963dd60b9edSEd Tanous return; 2964dd60b9edSEd Tanous } 2965dd60b9edSEd Tanous 2966dd60b9edSEd Tanous asyncResp->res.addHeader( 2967dd60b9edSEd Tanous boost::beast::http::field::link, 2968dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2969dd60b9edSEd Tanous } 2970dd60b9edSEd Tanous 29715c3e9272SAbhishek Patel inline void afterPortRequest( 29725c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29735c3e9272SAbhishek Patel const boost::system::error_code& ec, 29745c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 29755c3e9272SAbhishek Patel { 29765c3e9272SAbhishek Patel if (ec) 29775c3e9272SAbhishek Patel { 29785c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29795c3e9272SAbhishek Patel return; 29805c3e9272SAbhishek Patel } 29815c3e9272SAbhishek Patel for (const auto& data : socketData) 29825c3e9272SAbhishek Patel { 29835c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 29845c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 29855c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 29865c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 29875c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 29885c3e9272SAbhishek Patel // need to retrieve port number for 29895c3e9272SAbhishek Patel // obmc-console-ssh service 29905c3e9272SAbhishek Patel if (protocolName == "SSH") 29915c3e9272SAbhishek Patel { 29925c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 299381c4e330SEd Tanous const boost::system::error_code& ec1, 29945c3e9272SAbhishek Patel int portNumber) { 29955c3e9272SAbhishek Patel if (ec1) 29965c3e9272SAbhishek Patel { 29975c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29985c3e9272SAbhishek Patel return; 29995c3e9272SAbhishek Patel } 30005c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 30015c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 30025c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 30035c3e9272SAbhishek Patel }); 30045c3e9272SAbhishek Patel } 30055c3e9272SAbhishek Patel } 30065c3e9272SAbhishek Patel } 3007cc340dd9SEd Tanous /** 30086617338dSEd Tanous * Systems derived class for delivering Computer Systems Schema. 3009c5b2abe0SLewanczyk, Dawid */ 30107e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app) 30111abe55efSEd Tanous { 3012dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/") 3013dd60b9edSEd Tanous .privileges(redfish::privileges::headComputerSystem) 3014dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)( 3015dd60b9edSEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3016c5b2abe0SLewanczyk, Dawid /** 3017c5b2abe0SLewanczyk, Dawid * Functions triggers appropriate requests on DBus 3018c5b2abe0SLewanczyk, Dawid */ 301922d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3020ed398213SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3021002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 3022002d39b4SEd Tanous [&app](const crow::Request& req, 302322d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 302422d268cbSEd Tanous const std::string& systemName) { 30253ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 302645ca1b86SEd Tanous { 302745ca1b86SEd Tanous return; 302845ca1b86SEd Tanous } 3029746b56f3SAsmitha Karunanithi 3030746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3031746b56f3SAsmitha Karunanithi { 3032746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3033746b56f3SAsmitha Karunanithi return; 3034746b56f3SAsmitha Karunanithi } 3035746b56f3SAsmitha Karunanithi 303622d268cbSEd Tanous if (systemName != "system") 303722d268cbSEd Tanous { 303822d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 303922d268cbSEd Tanous systemName); 304022d268cbSEd Tanous return; 304122d268cbSEd Tanous } 3042dd60b9edSEd Tanous asyncResp->res.addHeader( 3043dd60b9edSEd Tanous boost::beast::http::field::link, 3044dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 30458d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 304637bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 30478d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 30488d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 30498d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 30508d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 30518d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 30528d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 30538d1b46d7Szhanghch05 "Disabled"; 30548d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 30558d1b46d7Szhanghch05 "Disabled"; 3056*cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3057*cf0e004cSNinad Palsule uint64_t(0); 3058002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 305904a258f4SEd Tanous 30601476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 30611476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 30621476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 30631476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 30641476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 30651476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 30663179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 30673179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3068029573d4SEd Tanous 3069002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 30701476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 30711476687dSEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] 30721476687dSEd Tanous ["@Redfish.ActionInfo"] = 30731476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3074c5b2abe0SLewanczyk, Dawid 30751476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 30761476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 30771476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 30781476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3079c4bf6374SJason M. Bills 30801476687dSEd Tanous nlohmann::json::array_t managedBy; 30811476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 30821476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3083002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 30841476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 30851476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 30860e8ac5e7SGunnar Mills 30870e8ac5e7SGunnar Mills // Fill in SerialConsole info 3088002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3089002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = 3090002d39b4SEd Tanous true; 30911476687dSEd Tanous 30921476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = 30931476687dSEd Tanous true; 30941476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 30951476687dSEd Tanous asyncResp->res 30961476687dSEd Tanous .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 30971476687dSEd Tanous "Press ~. to exit console"; 30985c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 30995c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 31000e8ac5e7SGunnar Mills 31010e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 31020e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3103002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3104002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 3105002d39b4SEd Tanous 4; 3106613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3107613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 31081476687dSEd Tanous 31090e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 31107a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3111b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 31122ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3113e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3114e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3115b49ac873SJames Feist 3116b49ac873SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 31177a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 31187a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 31197a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3120914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3121b49ac873SJames Feist if (ec) 3122b49ac873SJames Feist { 3123b49ac873SJames Feist // no inventory 3124b49ac873SJames Feist return; 3125b49ac873SJames Feist } 3126b49ac873SJames Feist 3127914e2d5dSEd Tanous health->inventory = resp; 31287a1dbc48SGeorge Liu }); 3129b49ac873SJames Feist 3130b49ac873SJames Feist health->populate(); 3131b49ac873SJames Feist 3132002d39b4SEd Tanous getMainChassisId(asyncResp, 3133002d39b4SEd Tanous [](const std::string& chassisId, 31348d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3135b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3136b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3137ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3138ef4c65b7SEd Tanous chassisId); 3139002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3140c5d03ff4SJennifer Lee }); 3141a3002228SAppaRao Puli 31429f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 31439f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3144a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 31455bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 31466c34de48SEd Tanous getHostState(asyncResp); 3147491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3148978b8803SAndrew Geissler getBootProgress(asyncResp); 3149b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3150adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "PCIeDevices"); 315151709ffdSYong Li getHostWatchdogTimer(asyncResp); 3152c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 3153797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3154c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3155a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3156a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3157a6349918SAppaRao Puli #endif 31581981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 31593a2d0424SChris Cain getPowerMode(asyncResp); 316037bbf98cSChris Cain getIdlePowerSaver(asyncResp); 31617e860f15SJohn Edward Broadbent }); 3162550a6bf8SJiaqing Zhao 316322d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3164ed398213SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 31657e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 316645ca1b86SEd Tanous [&app](const crow::Request& req, 316722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 316822d268cbSEd Tanous const std::string& systemName) { 31693ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 317045ca1b86SEd Tanous { 317145ca1b86SEd Tanous return; 317245ca1b86SEd Tanous } 317322d268cbSEd Tanous if (systemName != "system") 317422d268cbSEd Tanous { 317522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 317622d268cbSEd Tanous systemName); 317722d268cbSEd Tanous return; 317822d268cbSEd Tanous } 317922d268cbSEd Tanous 3180dd60b9edSEd Tanous asyncResp->res.addHeader( 3181dd60b9edSEd Tanous boost::beast::http::field::link, 3182dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3183dd60b9edSEd Tanous 31849f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3185cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 318698e386ecSGunnar Mills std::optional<std::string> assetTag; 3187c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 31883a2d0424SChris Cain std::optional<std::string> powerMode; 3189550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3190550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3191550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3192550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3193550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3194550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3195797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3196550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 3197550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3198550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3199550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3200550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3201550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3202550a6bf8SJiaqing Zhao 3203550a6bf8SJiaqing Zhao // clang-format off 320415ed6780SWilly Tu if (!json_util::readJsonPatch( 3205550a6bf8SJiaqing Zhao req, asyncResp->res, 3206550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 32077e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3208550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3209550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3210550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3211550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3212550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3213550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3214550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3215550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3216550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3217797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3218550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 3219550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3220550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3221550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3222550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3223550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 32246617338dSEd Tanous { 32256617338dSEd Tanous return; 32266617338dSEd Tanous } 3227550a6bf8SJiaqing Zhao // clang-format on 3228491d8ee7SSantosh Puranik 32298d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3230c45f0082SYong Li 323198e386ecSGunnar Mills if (assetTag) 323298e386ecSGunnar Mills { 323398e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 323498e386ecSGunnar Mills } 323598e386ecSGunnar Mills 3236550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3237c45f0082SYong Li { 3238f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3239c45f0082SYong Li } 3240c45f0082SYong Li 3241cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 324269f35306SGunnar Mills { 3243002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3244491d8ee7SSantosh Puranik } 3245550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 324669f35306SGunnar Mills { 3247550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 324869f35306SGunnar Mills } 3249ac7e1e0bSAli Ahmed 3250797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3251797d5daeSCorey Hardesty { 3252797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3253797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3254797d5daeSCorey Hardesty } 3255797d5daeSCorey Hardesty 3256550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3257ac7e1e0bSAli Ahmed { 3258550a6bf8SJiaqing Zhao setTrustedModuleRequiredToBoot(asyncResp, 3259550a6bf8SJiaqing Zhao *bootTrustedModuleRequired); 326069f35306SGunnar Mills } 3261265c1602SJohnathan Mantey 32629f8bfa7cSGunnar Mills if (locationIndicatorActive) 32639f8bfa7cSGunnar Mills { 3264002d39b4SEd Tanous setLocationIndicatorActive(asyncResp, *locationIndicatorActive); 32659f8bfa7cSGunnar Mills } 32669f8bfa7cSGunnar Mills 32677e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32687e860f15SJohn Edward Broadbent // passed 32699712f8acSEd Tanous if (indicatorLed) 32706617338dSEd Tanous { 3271f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3272002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3273d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3274d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32756617338dSEd Tanous } 3276c6a620f2SGeorge Liu 3277c6a620f2SGeorge Liu if (powerRestorePolicy) 3278c6a620f2SGeorge Liu { 32794e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3280c6a620f2SGeorge Liu } 32813a2d0424SChris Cain 32823a2d0424SChris Cain if (powerMode) 32833a2d0424SChris Cain { 32843a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32853a2d0424SChris Cain } 328637bbf98cSChris Cain 3287550a6bf8SJiaqing Zhao if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || 3288550a6bf8SJiaqing Zhao ipsExitTime) 328937bbf98cSChris Cain { 3290002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3291002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 329237bbf98cSChris Cain } 32937e860f15SJohn Edward Broadbent }); 3294c5b2abe0SLewanczyk, Dawid } 32951cb1a9e6SAppaRao Puli 329638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3297dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 3298dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 3299dd60b9edSEd Tanous { 3300dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3301dd60b9edSEd Tanous { 3302dd60b9edSEd Tanous return; 3303dd60b9edSEd Tanous } 3304dd60b9edSEd Tanous asyncResp->res.addHeader( 3305dd60b9edSEd Tanous boost::beast::http::field::link, 3306dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3307dd60b9edSEd Tanous } 3308dd60b9edSEd Tanous 33091cb1a9e6SAppaRao Puli /** 33101cb1a9e6SAppaRao Puli * SystemResetActionInfo derived class for delivering Computer Systems 33111cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 33121cb1a9e6SAppaRao Puli */ 33137e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app) 33141cb1a9e6SAppaRao Puli { 3315dd60b9edSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/") 3316dd60b9edSEd Tanous .privileges(redfish::privileges::headActionInfo) 3317dd60b9edSEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3318dd60b9edSEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 33191cb1a9e6SAppaRao Puli /** 33201cb1a9e6SAppaRao Puli * Functions triggers appropriate requests on DBus 33211cb1a9e6SAppaRao Puli */ 332222d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3323ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 33247e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 332545ca1b86SEd Tanous [&app](const crow::Request& req, 332622d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 332722d268cbSEd Tanous const std::string& systemName) { 33283ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 332945ca1b86SEd Tanous { 333045ca1b86SEd Tanous return; 333145ca1b86SEd Tanous } 3332746b56f3SAsmitha Karunanithi 3333746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3334746b56f3SAsmitha Karunanithi { 3335746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3336746b56f3SAsmitha Karunanithi return; 3337746b56f3SAsmitha Karunanithi } 3338746b56f3SAsmitha Karunanithi 333922d268cbSEd Tanous if (systemName != "system") 334022d268cbSEd Tanous { 334122d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 334222d268cbSEd Tanous systemName); 334322d268cbSEd Tanous return; 334422d268cbSEd Tanous } 334522d268cbSEd Tanous 3346dd60b9edSEd Tanous asyncResp->res.addHeader( 3347dd60b9edSEd Tanous boost::beast::http::field::link, 3348dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 33491476687dSEd Tanous 33501476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 33511476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 33521476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 33531476687dSEd Tanous "#ActionInfo.v1_1_2.ActionInfo"; 33541476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 33551476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 33563215e700SNan Zhou 33573215e700SNan Zhou nlohmann::json::array_t parameters; 33583215e700SNan Zhou nlohmann::json::object_t parameter; 33593215e700SNan Zhou 33603215e700SNan Zhou parameter["Name"] = "ResetType"; 33613215e700SNan Zhou parameter["Required"] = true; 33623215e700SNan Zhou parameter["DataType"] = "String"; 33633215e700SNan Zhou nlohmann::json::array_t allowableValues; 33643215e700SNan Zhou allowableValues.emplace_back("On"); 33653215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 33663215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 33673215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 33683215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 33693215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 33703215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 33713215e700SNan Zhou allowableValues.emplace_back("Nmi"); 33723215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 33733215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 33743215e700SNan Zhou 33753215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 33767e860f15SJohn Edward Broadbent }); 33771cb1a9e6SAppaRao Puli } 3378c5b2abe0SLewanczyk, Dawid } // namespace redfish 3379