1c5b2abe0SLewanczyk, Dawid /* 2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation 3c5b2abe0SLewanczyk, Dawid // 4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License"); 5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License. 6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at 7c5b2abe0SLewanczyk, Dawid // 8c5b2abe0SLewanczyk, Dawid // http://www.apache.org/licenses/LICENSE-2.0 9c5b2abe0SLewanczyk, Dawid // 10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software 11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS, 12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and 14c5b2abe0SLewanczyk, Dawid // limitations under the License. 15c5b2abe0SLewanczyk, Dawid */ 16c5b2abe0SLewanczyk, Dawid #pragma once 17c5b2abe0SLewanczyk, Dawid 1813451e39SWilly Tu #include "bmcweb_config.h" 1913451e39SWilly Tu 203ccb3adbSEd Tanous #include "app.hpp" 211e1e598dSJonathan Doman #include "dbus_singleton.hpp" 227a1dbc48SGeorge Liu #include "dbus_utility.hpp" 238d69c668SEd Tanous #include "generated/enums/computer_system.hpp" 24b49ac873SJames Feist #include "health.hpp" 25746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 261c8fba97SJames Feist #include "led.hpp" 27f4c99e70SEd Tanous #include "query.hpp" 28c5d03ff4SJennifer Lee #include "redfish_util.hpp" 293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 313ccb3adbSEd Tanous #include "utils/json_utils.hpp" 32472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 333ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 342b82937eSEd Tanous #include "utils/time_utils.hpp" 35c5d03ff4SJennifer Lee 36fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 379712f8acSEd Tanous #include <boost/container/flat_map.hpp> 38e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 39ef4c65b7SEd Tanous #include <boost/url/format.hpp> 401e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 41fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 42bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 431214b7e7SGunnar Mills 447a1dbc48SGeorge Liu #include <array> 457a1dbc48SGeorge Liu #include <string_view> 46abf2add6SEd Tanous #include <variant> 47c5b2abe0SLewanczyk, Dawid 481abe55efSEd Tanous namespace redfish 491abe55efSEd Tanous { 50c5b2abe0SLewanczyk, Dawid 515c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 525c3e9272SAbhishek Patel protocolToDBusForSystems{ 535c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 545c3e9272SAbhishek Patel 559d3ae10eSAlpana Kumari /** 569d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 579d3ae10eSAlpana Kumari * 58ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 599d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 609d3ae10eSAlpana Kumari * 619d3ae10eSAlpana Kumari * @return None. 629d3ae10eSAlpana Kumari */ 638d1b46d7Szhanghch05 inline void 64ac106bf6SEd Tanous updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 651e1e598dSJonathan Doman bool isDimmFunctional) 669d3ae10eSAlpana Kumari { 6762598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 689d3ae10eSAlpana Kumari 699d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 709d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 719d3ae10eSAlpana Kumari // ENABLED. 7202cad96eSEd Tanous const nlohmann::json& prevMemSummary = 73ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 749d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 759d3ae10eSAlpana Kumari { 76e05aec50SEd Tanous if (isDimmFunctional) 779d3ae10eSAlpana Kumari { 78ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 799d3ae10eSAlpana Kumari "Enabled"; 809d3ae10eSAlpana Kumari } 819d3ae10eSAlpana Kumari } 829d3ae10eSAlpana Kumari } 839d3ae10eSAlpana Kumari 8457e8c9beSAlpana Kumari /* 8557e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 8657e8c9beSAlpana Kumari * CPU Functional State 8757e8c9beSAlpana Kumari * 88ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 8957e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9057e8c9beSAlpana Kumari * 9157e8c9beSAlpana Kumari * @return None. 9257e8c9beSAlpana Kumari */ 93ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 94ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 9557e8c9beSAlpana Kumari { 9662598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 9757e8c9beSAlpana Kumari 9802cad96eSEd Tanous const nlohmann::json& prevProcState = 99ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10057e8c9beSAlpana Kumari 10157e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10257e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10357e8c9beSAlpana Kumari // Functional. 10457e8c9beSAlpana Kumari if (prevProcState == "Disabled") 10557e8c9beSAlpana Kumari { 106e05aec50SEd Tanous if (isCpuFunctional) 10757e8c9beSAlpana Kumari { 108ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 10957e8c9beSAlpana Kumari "Enabled"; 11057e8c9beSAlpana Kumari } 11157e8c9beSAlpana Kumari } 11257e8c9beSAlpana Kumari } 11357e8c9beSAlpana Kumari 114cf0e004cSNinad Palsule /* 115cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 116cf0e004cSNinad Palsule * 117ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 118cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 119cf0e004cSNinad Palsule * 120cf0e004cSNinad Palsule * @return None. 121cf0e004cSNinad Palsule */ 122cf0e004cSNinad Palsule inline void 123ac106bf6SEd Tanous modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 124cf0e004cSNinad Palsule bool isCpuPresent) 125cf0e004cSNinad Palsule { 12662598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 127cf0e004cSNinad Palsule 128cf0e004cSNinad Palsule if (isCpuPresent) 129cf0e004cSNinad Palsule { 130cf0e004cSNinad Palsule nlohmann::json& procCount = 131ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 132cf0e004cSNinad Palsule auto* procCountPtr = 133cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 134cf0e004cSNinad Palsule if (procCountPtr != nullptr) 135cf0e004cSNinad Palsule { 136cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 137cf0e004cSNinad Palsule *procCountPtr += 1; 138cf0e004cSNinad Palsule } 139cf0e004cSNinad Palsule } 140cf0e004cSNinad Palsule } 141cf0e004cSNinad Palsule 142382d6475SAli Ahmed inline void getProcessorProperties( 143ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 144382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 145382d6475SAli Ahmed properties) 14603fbed92SAli Ahmed { 14762598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 14803fbed92SAli Ahmed 14903fbed92SAli Ahmed // TODO: Get Model 15003fbed92SAli Ahmed 151bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15203fbed92SAli Ahmed 153bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 154bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 15503fbed92SAli Ahmed 156bc1d29deSKrzysztof Grobelny if (!success) 15703fbed92SAli Ahmed { 158ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15903fbed92SAli Ahmed return; 16003fbed92SAli Ahmed } 16103fbed92SAli Ahmed 162bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16303fbed92SAli Ahmed { 164bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 165ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 166bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 167bc1d29deSKrzysztof Grobelny 168bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 169bc1d29deSKrzysztof Grobelny { 170bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17103fbed92SAli Ahmed } 17203fbed92SAli Ahmed else 17303fbed92SAli Ahmed { 174bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 17503fbed92SAli Ahmed } 17603fbed92SAli Ahmed } 17703fbed92SAli Ahmed } 17803fbed92SAli Ahmed 17903fbed92SAli Ahmed /* 18003fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18103fbed92SAli Ahmed * 182ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 18303fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 18403fbed92SAli Ahmed * @param[in] path dbus path for Cpu 18503fbed92SAli Ahmed * 18603fbed92SAli Ahmed * @return None. 18703fbed92SAli Ahmed */ 188ac106bf6SEd Tanous inline void 189ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 190ac106bf6SEd Tanous const std::string& service, const std::string& path) 19103fbed92SAli Ahmed { 192ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 193382d6475SAli Ahmed const bool cpuPresenceCheck) { 194382d6475SAli Ahmed if (ec3) 195382d6475SAli Ahmed { 19662598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 197382d6475SAli Ahmed return; 198382d6475SAli Ahmed } 199ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 200382d6475SAli Ahmed }; 201382d6475SAli Ahmed 202cf0e004cSNinad Palsule // Get the Presence of CPU 203cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 204cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 205cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 206cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 207cf0e004cSNinad Palsule 2085fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2095fd0aafbSNinad Palsule { 2105fd0aafbSNinad Palsule auto getCpuFunctionalState = 211ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 212382d6475SAli Ahmed const bool cpuFunctionalCheck) { 213382d6475SAli Ahmed if (ec3) 214382d6475SAli Ahmed { 21562598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 216382d6475SAli Ahmed return; 217382d6475SAli Ahmed } 218ac106bf6SEd Tanous modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck); 219382d6475SAli Ahmed }; 220382d6475SAli Ahmed 221382d6475SAli Ahmed // Get the Functional State 222382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 223382d6475SAli Ahmed *crow::connections::systemBus, service, path, 2245fd0aafbSNinad Palsule "xyz.openbmc_project.State.Decorator.OperationalStatus", 2255fd0aafbSNinad Palsule "Functional", std::move(getCpuFunctionalState)); 2265fd0aafbSNinad Palsule } 227382d6475SAli Ahmed 228bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 229bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 230bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 231ac106bf6SEd Tanous [asyncResp, service, 2325e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 233b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 23403fbed92SAli Ahmed if (ec2) 23503fbed92SAli Ahmed { 23662598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 237ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23803fbed92SAli Ahmed return; 23903fbed92SAli Ahmed } 240ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 241bc1d29deSKrzysztof Grobelny }); 24203fbed92SAli Ahmed } 24303fbed92SAli Ahmed 24457e8c9beSAlpana Kumari /* 245cf0e004cSNinad Palsule * @brief processMemoryProperties fields 246cf0e004cSNinad Palsule * 247ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 248cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 249cf0e004cSNinad Palsule * @param[in] path dbus path for Memory 250cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 251cf0e004cSNinad Palsule * 252cf0e004cSNinad Palsule * @return None. 253cf0e004cSNinad Palsule */ 254cf0e004cSNinad Palsule inline void 255ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2565fd0aafbSNinad Palsule [[maybe_unused]] const std::string& service, 2575fd0aafbSNinad Palsule [[maybe_unused]] const std::string& path, 258cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 259cf0e004cSNinad Palsule { 26062598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 261cf0e004cSNinad Palsule 262cf0e004cSNinad Palsule if (properties.empty()) 263cf0e004cSNinad Palsule { 2645fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2655fd0aafbSNinad Palsule { 266cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 267cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 268cf0e004cSNinad Palsule "xyz.openbmc_project.State." 269cf0e004cSNinad Palsule "Decorator.OperationalStatus", 270cf0e004cSNinad Palsule "Functional", 271ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 272ac106bf6SEd Tanous bool dimmState) { 273cf0e004cSNinad Palsule if (ec3) 274cf0e004cSNinad Palsule { 27562598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 276cf0e004cSNinad Palsule return; 277cf0e004cSNinad Palsule } 278ac106bf6SEd Tanous updateDimmProperties(asyncResp, dimmState); 279cf0e004cSNinad Palsule }); 2805fd0aafbSNinad Palsule } 281cf0e004cSNinad Palsule return; 282cf0e004cSNinad Palsule } 283cf0e004cSNinad Palsule 284cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 285cf0e004cSNinad Palsule 286cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 287cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 288cf0e004cSNinad Palsule memorySizeInKB); 289cf0e004cSNinad Palsule 290cf0e004cSNinad Palsule if (!success) 291cf0e004cSNinad Palsule { 292ac106bf6SEd Tanous messages::internalError(asyncResp->res); 293cf0e004cSNinad Palsule return; 294cf0e004cSNinad Palsule } 295cf0e004cSNinad Palsule 296cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 297cf0e004cSNinad Palsule { 298cf0e004cSNinad Palsule nlohmann::json& totalMemory = 299ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 300dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 301cf0e004cSNinad Palsule if (preValue == nullptr) 302cf0e004cSNinad Palsule { 303ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 304dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 305cf0e004cSNinad Palsule } 306cf0e004cSNinad Palsule else 307cf0e004cSNinad Palsule { 308ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 309dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 310dfb2b408SPriyanga Ramasamy *preValue; 311cf0e004cSNinad Palsule } 3125fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3135fd0aafbSNinad Palsule { 314ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 3155fd0aafbSNinad Palsule "Enabled"; 3165fd0aafbSNinad Palsule } 317cf0e004cSNinad Palsule } 318cf0e004cSNinad Palsule } 319cf0e004cSNinad Palsule 320cf0e004cSNinad Palsule /* 321cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 322cf0e004cSNinad Palsule * 323ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 324cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 325cf0e004cSNinad Palsule * @param[in] path dbus path for memory 326cf0e004cSNinad Palsule * 327cf0e004cSNinad Palsule * @return None. 328cf0e004cSNinad Palsule */ 329ac106bf6SEd Tanous inline void 330ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 331ac106bf6SEd Tanous const std::string& service, const std::string& path) 332cf0e004cSNinad Palsule { 333cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 334cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 335cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 336ac106bf6SEd Tanous [asyncResp, service, 337cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 338cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 339cf0e004cSNinad Palsule if (ec2) 340cf0e004cSNinad Palsule { 34162598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 342ac106bf6SEd Tanous messages::internalError(asyncResp->res); 343cf0e004cSNinad Palsule return; 344cf0e004cSNinad Palsule } 345ac106bf6SEd Tanous processMemoryProperties(asyncResp, service, path, properties); 346cf0e004cSNinad Palsule }); 347cf0e004cSNinad Palsule } 348cf0e004cSNinad Palsule 349a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 350a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 351a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& properties) 3521abe55efSEd Tanous { 353a974c132SLakshmi Yadlapati if (ec) 354a974c132SLakshmi Yadlapati { 355a974c132SLakshmi Yadlapati BMCWEB_LOG_ERROR("DBUS response error {}", ec); 356a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 357a974c132SLakshmi Yadlapati return; 358a974c132SLakshmi Yadlapati } 359a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size()); 360a974c132SLakshmi Yadlapati 361a974c132SLakshmi Yadlapati const std::string* uUID = nullptr; 362a974c132SLakshmi Yadlapati 363a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 364a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID); 365a974c132SLakshmi Yadlapati 366a974c132SLakshmi Yadlapati if (!success) 367a974c132SLakshmi Yadlapati { 368a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 369a974c132SLakshmi Yadlapati return; 370a974c132SLakshmi Yadlapati } 371a974c132SLakshmi Yadlapati 372a974c132SLakshmi Yadlapati if (uUID != nullptr) 373a974c132SLakshmi Yadlapati { 374a974c132SLakshmi Yadlapati std::string valueStr = *uUID; 375a974c132SLakshmi Yadlapati if (valueStr.size() == 32) 376a974c132SLakshmi Yadlapati { 377a974c132SLakshmi Yadlapati valueStr.insert(8, 1, '-'); 378a974c132SLakshmi Yadlapati valueStr.insert(13, 1, '-'); 379a974c132SLakshmi Yadlapati valueStr.insert(18, 1, '-'); 380a974c132SLakshmi Yadlapati valueStr.insert(23, 1, '-'); 381a974c132SLakshmi Yadlapati } 382a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("UUID = {}", valueStr); 383a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["UUID"] = valueStr; 384a974c132SLakshmi Yadlapati } 385a974c132SLakshmi Yadlapati } 386a974c132SLakshmi Yadlapati 387a974c132SLakshmi Yadlapati inline void 388a974c132SLakshmi Yadlapati afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 389a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 390a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& propertiesList) 391a974c132SLakshmi Yadlapati { 392a974c132SLakshmi Yadlapati if (ec) 393a974c132SLakshmi Yadlapati { 394a974c132SLakshmi Yadlapati // doesn't have to include this 395a974c132SLakshmi Yadlapati // interface 396a974c132SLakshmi Yadlapati return; 397a974c132SLakshmi Yadlapati } 398a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size()); 399a974c132SLakshmi Yadlapati 400a974c132SLakshmi Yadlapati const std::string* partNumber = nullptr; 401a974c132SLakshmi Yadlapati const std::string* serialNumber = nullptr; 402a974c132SLakshmi Yadlapati const std::string* manufacturer = nullptr; 403a974c132SLakshmi Yadlapati const std::string* model = nullptr; 404a974c132SLakshmi Yadlapati const std::string* subModel = nullptr; 405a974c132SLakshmi Yadlapati 406a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 407a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber", 408a974c132SLakshmi Yadlapati partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 409a974c132SLakshmi Yadlapati "Model", model, "SubModel", subModel); 410a974c132SLakshmi Yadlapati 411a974c132SLakshmi Yadlapati if (!success) 412a974c132SLakshmi Yadlapati { 413a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 414a974c132SLakshmi Yadlapati return; 415a974c132SLakshmi Yadlapati } 416a974c132SLakshmi Yadlapati 417a974c132SLakshmi Yadlapati if (partNumber != nullptr) 418a974c132SLakshmi Yadlapati { 419a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["PartNumber"] = *partNumber; 420a974c132SLakshmi Yadlapati } 421a974c132SLakshmi Yadlapati 422a974c132SLakshmi Yadlapati if (serialNumber != nullptr) 423a974c132SLakshmi Yadlapati { 424a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 425a974c132SLakshmi Yadlapati } 426a974c132SLakshmi Yadlapati 427a974c132SLakshmi Yadlapati if (manufacturer != nullptr) 428a974c132SLakshmi Yadlapati { 429a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 430a974c132SLakshmi Yadlapati } 431a974c132SLakshmi Yadlapati 432a974c132SLakshmi Yadlapati if (model != nullptr) 433a974c132SLakshmi Yadlapati { 434a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Model"] = *model; 435a974c132SLakshmi Yadlapati } 436a974c132SLakshmi Yadlapati 437a974c132SLakshmi Yadlapati if (subModel != nullptr) 438a974c132SLakshmi Yadlapati { 439a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SubModel"] = *subModel; 440a974c132SLakshmi Yadlapati } 441a974c132SLakshmi Yadlapati 442a974c132SLakshmi Yadlapati // Grab the bios version 443a974c132SLakshmi Yadlapati sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, 444a974c132SLakshmi Yadlapati "BiosVersion", false); 445a974c132SLakshmi Yadlapati } 446a974c132SLakshmi Yadlapati 447a974c132SLakshmi Yadlapati inline void 448a974c132SLakshmi Yadlapati afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 449a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 450a974c132SLakshmi Yadlapati const std::string& value) 451a974c132SLakshmi Yadlapati { 452a974c132SLakshmi Yadlapati if (ec) 453a974c132SLakshmi Yadlapati { 454a974c132SLakshmi Yadlapati // doesn't have to include this 455a974c132SLakshmi Yadlapati // interface 456a974c132SLakshmi Yadlapati return; 457a974c132SLakshmi Yadlapati } 458a974c132SLakshmi Yadlapati 459a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["AssetTag"] = value; 460a974c132SLakshmi Yadlapati } 461a974c132SLakshmi Yadlapati 462a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree( 463a974c132SLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 464a974c132SLakshmi Yadlapati const std::shared_ptr<HealthPopulate>& systemHealth, 465a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 466a974c132SLakshmi Yadlapati const dbus::utility::MapperGetSubTreeResponse& subtree) 467a974c132SLakshmi Yadlapati { 4681abe55efSEd Tanous if (ec) 4691abe55efSEd Tanous { 470b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 471ac106bf6SEd Tanous messages::internalError(asyncResp->res); 472c5b2abe0SLewanczyk, Dawid return; 473c5b2abe0SLewanczyk, Dawid } 474c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 475002d39b4SEd Tanous for (const std::pair< 476002d39b4SEd Tanous std::string, 477002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 4781214b7e7SGunnar Mills object : subtree) 4791abe55efSEd Tanous { 480c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 48162598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 482002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 4831214b7e7SGunnar Mills connectionNames = object.second; 48426f6976fSEd Tanous if (connectionNames.empty()) 4851abe55efSEd Tanous { 486c5b2abe0SLewanczyk, Dawid continue; 487c5b2abe0SLewanczyk, Dawid } 488029573d4SEd Tanous 4895fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> memoryHealth = nullptr; 4905fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> cpuHealth = nullptr; 4915bc2dc8eSJames Feist 4925fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4935fd0aafbSNinad Palsule { 4945fd0aafbSNinad Palsule memoryHealth = std::make_shared<HealthPopulate>( 495ac106bf6SEd Tanous asyncResp, "/MemorySummary/Status"_json_pointer); 4965fd0aafbSNinad Palsule systemHealth->children.emplace_back(memoryHealth); 4975bc2dc8eSJames Feist 49813451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 49913451e39SWilly Tu { 5005fd0aafbSNinad Palsule cpuHealth = std::make_shared<HealthPopulate>( 501ac106bf6SEd Tanous asyncResp, "/ProcessorSummary/Status"_json_pointer); 5025fd0aafbSNinad Palsule 5035bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 50413451e39SWilly Tu } 5055fd0aafbSNinad Palsule } 5065bc2dc8eSJames Feist 5076c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 5086c34de48SEd Tanous // BiosVer 50904a258f4SEd Tanous for (const auto& connection : connectionNames) 5101abe55efSEd Tanous { 51104a258f4SEd Tanous for (const auto& interfaceName : connection.second) 5121abe55efSEd Tanous { 513a974c132SLakshmi Yadlapati if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") 5141abe55efSEd Tanous { 51562598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 5169d3ae10eSAlpana Kumari 517ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 5185bc2dc8eSJames Feist 5195fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 5205fd0aafbSNinad Palsule { 5215bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 5221abe55efSEd Tanous } 5235fd0aafbSNinad Palsule } 52404a258f4SEd Tanous else if (interfaceName == 52504a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 5261abe55efSEd Tanous { 52762598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 52857e8c9beSAlpana Kumari 529ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 5305bc2dc8eSJames Feist 5315fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 5325fd0aafbSNinad Palsule { 5335bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 5341abe55efSEd Tanous } 5355fd0aafbSNinad Palsule } 536002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 5371abe55efSEd Tanous { 53862598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 539bc1d29deSKrzysztof Grobelny 540bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 541a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 542a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 543ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 544b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 5451214b7e7SGunnar Mills properties) { 546a974c132SLakshmi Yadlapati afterGetUUID(asyncResp, ec3, properties); 547bc1d29deSKrzysztof Grobelny }); 548c5b2abe0SLewanczyk, Dawid } 549029573d4SEd Tanous else if (interfaceName == 550029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 5511abe55efSEd Tanous { 552bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 553a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 554bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 555a974c132SLakshmi Yadlapati [asyncResp](const boost::system::error_code& ec3, 556b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 557a974c132SLakshmi Yadlapati properties) { 558a974c132SLakshmi Yadlapati afterGetInventory(asyncResp, ec3, properties); 559bc1d29deSKrzysztof Grobelny }); 560e4a4b9a9SJames Feist 5611e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 562a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 5631e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5641e1e598dSJonathan Doman "AssetTag", 5651e1e598dSJonathan Doman "AssetTag", 566a974c132SLakshmi Yadlapati std::bind_front(afterGetAssetTag, asyncResp)); 567a974c132SLakshmi Yadlapati } 568a974c132SLakshmi Yadlapati } 569a974c132SLakshmi Yadlapati } 570a974c132SLakshmi Yadlapati } 571a974c132SLakshmi Yadlapati } 572a974c132SLakshmi Yadlapati 573a974c132SLakshmi Yadlapati /* 574a974c132SLakshmi Yadlapati * @brief Retrieves computer system properties over dbus 575a974c132SLakshmi Yadlapati * 576a974c132SLakshmi Yadlapati * @param[in] asyncResp Shared pointer for completing asynchronous calls 577a974c132SLakshmi Yadlapati * @param[in] systemHealth Shared HealthPopulate pointer 578a974c132SLakshmi Yadlapati * 579a974c132SLakshmi Yadlapati * @return None. 580a974c132SLakshmi Yadlapati */ 581a974c132SLakshmi Yadlapati inline void 582a974c132SLakshmi Yadlapati getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 583a974c132SLakshmi Yadlapati const std::shared_ptr<HealthPopulate>& systemHealth) 584e4a4b9a9SJames Feist { 585a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get available system components."); 586a974c132SLakshmi Yadlapati constexpr std::array<std::string_view, 5> interfaces = { 587a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 588a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Cpu", 589a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Dimm", 590a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.System", 591a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 592a974c132SLakshmi Yadlapati }; 593a974c132SLakshmi Yadlapati dbus::utility::getSubTree( 594a974c132SLakshmi Yadlapati "/xyz/openbmc_project/inventory", 0, interfaces, 595a974c132SLakshmi Yadlapati std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth)); 596c5b2abe0SLewanczyk, Dawid } 597c5b2abe0SLewanczyk, Dawid 598c5b2abe0SLewanczyk, Dawid /** 599c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 600c5b2abe0SLewanczyk, Dawid * 601ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 602c5b2abe0SLewanczyk, Dawid * 603c5b2abe0SLewanczyk, Dawid * @return None. 604c5b2abe0SLewanczyk, Dawid */ 605ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 6061abe55efSEd Tanous { 60762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 6081e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 6091e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 6101e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 6111e1e598dSJonathan Doman "CurrentHostState", 612ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 6131e1e598dSJonathan Doman const std::string& hostState) { 6141abe55efSEd Tanous if (ec) 6151abe55efSEd Tanous { 61622228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 61722228c28SAndrew Geissler { 61822228c28SAndrew Geissler // Service not available, no error, just don't return 61922228c28SAndrew Geissler // host state info 62062598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 62122228c28SAndrew Geissler return; 62222228c28SAndrew Geissler } 62362598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 624ac106bf6SEd Tanous messages::internalError(asyncResp->res); 625c5b2abe0SLewanczyk, Dawid return; 626c5b2abe0SLewanczyk, Dawid } 6276617338dSEd Tanous 62862598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 629c5b2abe0SLewanczyk, Dawid // Verify Host State 6301e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 6311abe55efSEd Tanous { 632ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 633ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 6341abe55efSEd Tanous } 6351e1e598dSJonathan Doman else if (hostState == 6360fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 6378c888608SGunnar Mills { 638ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 639ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6408c888608SGunnar Mills } 6411e1e598dSJonathan Doman else if (hostState == 6420fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 64383935af9SAndrew Geissler { 644ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 645ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 64683935af9SAndrew Geissler } 6470fda0f12SGeorge Liu else if ( 6481e1e598dSJonathan Doman hostState == 6490fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6501a2a1437SAndrew Geissler { 651ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 652ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 6531a2a1437SAndrew Geissler } 654002d39b4SEd Tanous else if (hostState == 6550fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6561a2a1437SAndrew Geissler { 657ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 658ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 6591a2a1437SAndrew Geissler } 6601abe55efSEd Tanous else 6611abe55efSEd Tanous { 662ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 663ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 664c5b2abe0SLewanczyk, Dawid } 6651e1e598dSJonathan Doman }); 666c5b2abe0SLewanczyk, Dawid } 667c5b2abe0SLewanczyk, Dawid 668c5b2abe0SLewanczyk, Dawid /** 669786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 670491d8ee7SSantosh Puranik * 671491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 672491d8ee7SSantosh Puranik * 673491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 674491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 675491d8ee7SSantosh Puranik */ 67623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 677491d8ee7SSantosh Puranik { 678491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 679491d8ee7SSantosh Puranik { 680491d8ee7SSantosh Puranik return "None"; 681491d8ee7SSantosh Puranik } 6823174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 683491d8ee7SSantosh Puranik { 684491d8ee7SSantosh Puranik return "Hdd"; 685491d8ee7SSantosh Puranik } 6863174e4dfSEd Tanous if (dbusSource == 687a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 688491d8ee7SSantosh Puranik { 689491d8ee7SSantosh Puranik return "Cd"; 690491d8ee7SSantosh Puranik } 6913174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 692491d8ee7SSantosh Puranik { 693491d8ee7SSantosh Puranik return "Pxe"; 694491d8ee7SSantosh Puranik } 6953174e4dfSEd Tanous if (dbusSource == 696944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6979f16b2c1SJennifer Lee { 6989f16b2c1SJennifer Lee return "Usb"; 6999f16b2c1SJennifer Lee } 700491d8ee7SSantosh Puranik return ""; 701491d8ee7SSantosh Puranik } 702491d8ee7SSantosh Puranik 703491d8ee7SSantosh Puranik /** 704cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 705cd9a4666SKonstantin Aladyshev * 706cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 707cd9a4666SKonstantin Aladyshev * 708cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 709cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 710cd9a4666SKonstantin Aladyshev */ 711cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 712cd9a4666SKonstantin Aladyshev { 713cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 714cd9a4666SKonstantin Aladyshev { 715cd9a4666SKonstantin Aladyshev return "Legacy"; 716cd9a4666SKonstantin Aladyshev } 717cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 718cd9a4666SKonstantin Aladyshev { 719cd9a4666SKonstantin Aladyshev return "UEFI"; 720cd9a4666SKonstantin Aladyshev } 721cd9a4666SKonstantin Aladyshev return ""; 722cd9a4666SKonstantin Aladyshev } 723cd9a4666SKonstantin Aladyshev 724cd9a4666SKonstantin Aladyshev /** 725786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 726491d8ee7SSantosh Puranik * 727491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 728491d8ee7SSantosh Puranik * 729491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 730491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 731491d8ee7SSantosh Puranik */ 73223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 733491d8ee7SSantosh Puranik { 734491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 735491d8ee7SSantosh Puranik { 736491d8ee7SSantosh Puranik return "None"; 737491d8ee7SSantosh Puranik } 7383174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 739491d8ee7SSantosh Puranik { 740491d8ee7SSantosh Puranik return "Diags"; 741491d8ee7SSantosh Puranik } 7423174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 743491d8ee7SSantosh Puranik { 744491d8ee7SSantosh Puranik return "BiosSetup"; 745491d8ee7SSantosh Puranik } 746491d8ee7SSantosh Puranik return ""; 747491d8ee7SSantosh Puranik } 748491d8ee7SSantosh Puranik 749491d8ee7SSantosh Puranik /** 750e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 751e43914b3SAndrew Geissler * 752e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 753e43914b3SAndrew Geissler * 754e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 755e43914b3SAndrew Geissler * translation cannot be done, returns "None". 756e43914b3SAndrew Geissler */ 757e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 758e43914b3SAndrew Geissler { 759e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 760e43914b3SAndrew Geissler // enum 761e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 762e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 763e43914b3SAndrew Geissler "ProgressStages.Unspecified") 764e43914b3SAndrew Geissler { 765e43914b3SAndrew Geissler rfBpLastState = "None"; 766e43914b3SAndrew Geissler } 767e43914b3SAndrew Geissler else if (dbusBootProgress == 768e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 769e43914b3SAndrew Geissler "PrimaryProcInit") 770e43914b3SAndrew Geissler { 771e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 772e43914b3SAndrew Geissler } 773e43914b3SAndrew Geissler else if (dbusBootProgress == 774e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 775e43914b3SAndrew Geissler "BusInit") 776e43914b3SAndrew Geissler { 777e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 778e43914b3SAndrew Geissler } 779e43914b3SAndrew Geissler else if (dbusBootProgress == 780e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 781e43914b3SAndrew Geissler "MemoryInit") 782e43914b3SAndrew Geissler { 783e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 784e43914b3SAndrew Geissler } 785e43914b3SAndrew Geissler else if (dbusBootProgress == 786e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 787e43914b3SAndrew Geissler "SecondaryProcInit") 788e43914b3SAndrew Geissler { 789e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 790e43914b3SAndrew Geissler } 791e43914b3SAndrew Geissler else if (dbusBootProgress == 792e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 793e43914b3SAndrew Geissler "PCIInit") 794e43914b3SAndrew Geissler { 795e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 796e43914b3SAndrew Geissler } 797e43914b3SAndrew Geissler else if (dbusBootProgress == 798e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 799e43914b3SAndrew Geissler "SystemSetup") 800e43914b3SAndrew Geissler { 801e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 802e43914b3SAndrew Geissler } 803e43914b3SAndrew Geissler else if (dbusBootProgress == 804e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 805e43914b3SAndrew Geissler "SystemInitComplete") 806e43914b3SAndrew Geissler { 807e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 808e43914b3SAndrew Geissler } 809e43914b3SAndrew Geissler else if (dbusBootProgress == 810e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 811e43914b3SAndrew Geissler "OSStart") 812e43914b3SAndrew Geissler { 813e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 814e43914b3SAndrew Geissler } 815e43914b3SAndrew Geissler else if (dbusBootProgress == 816e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 817e43914b3SAndrew Geissler "OSRunning") 818e43914b3SAndrew Geissler { 819e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 820e43914b3SAndrew Geissler } 821e43914b3SAndrew Geissler else 822e43914b3SAndrew Geissler { 82362598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 824e43914b3SAndrew Geissler // Just return the default 825e43914b3SAndrew Geissler } 826e43914b3SAndrew Geissler return rfBpLastState; 827e43914b3SAndrew Geissler } 828e43914b3SAndrew Geissler 829e43914b3SAndrew Geissler /** 830786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 831491d8ee7SSantosh Puranik * 832491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 833944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 834944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 835491d8ee7SSantosh Puranik * 836944ffaf9SJohnathan Mantey * @return Integer error code. 837491d8ee7SSantosh Puranik */ 838ac106bf6SEd Tanous inline int 839ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 840ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 841ac106bf6SEd Tanous std::string& bootMode) 842491d8ee7SSantosh Puranik { 843c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 844c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 845944ffaf9SJohnathan Mantey 846491d8ee7SSantosh Puranik if (rfSource == "None") 847491d8ee7SSantosh Puranik { 848944ffaf9SJohnathan Mantey return 0; 849491d8ee7SSantosh Puranik } 8503174e4dfSEd Tanous if (rfSource == "Pxe") 851491d8ee7SSantosh Puranik { 852944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 853944ffaf9SJohnathan Mantey } 854944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 855944ffaf9SJohnathan Mantey { 856944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 857944ffaf9SJohnathan Mantey } 858944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 859944ffaf9SJohnathan Mantey { 860944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 861944ffaf9SJohnathan Mantey } 862944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 863944ffaf9SJohnathan Mantey { 864944ffaf9SJohnathan Mantey bootSource = 865944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 866944ffaf9SJohnathan Mantey } 867944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 868944ffaf9SJohnathan Mantey { 869944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 870491d8ee7SSantosh Puranik } 8719f16b2c1SJennifer Lee else if (rfSource == "Usb") 8729f16b2c1SJennifer Lee { 873944ffaf9SJohnathan Mantey bootSource = 874944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8759f16b2c1SJennifer Lee } 876491d8ee7SSantosh Puranik else 877491d8ee7SSantosh Puranik { 87862598e31SEd Tanous BMCWEB_LOG_DEBUG( 87962598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 88062598e31SEd Tanous bootSource); 881ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 882944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 883944ffaf9SJohnathan Mantey return -1; 884491d8ee7SSantosh Puranik } 885944ffaf9SJohnathan Mantey return 0; 886491d8ee7SSantosh Puranik } 8871981771bSAli Ahmed 888978b8803SAndrew Geissler /** 889978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 890978b8803SAndrew Geissler * 891ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 892978b8803SAndrew Geissler * 893978b8803SAndrew Geissler * @return None. 894978b8803SAndrew Geissler */ 895ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 896978b8803SAndrew Geissler { 8971e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8981e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8991e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 9001e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 901ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9021e1e598dSJonathan Doman const std::string& bootProgressStr) { 903978b8803SAndrew Geissler if (ec) 904978b8803SAndrew Geissler { 905978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 906978b8803SAndrew Geissler // not found 907978b8803SAndrew Geissler return; 908978b8803SAndrew Geissler } 909978b8803SAndrew Geissler 91062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 911978b8803SAndrew Geissler 912ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 913e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 9141e1e598dSJonathan Doman }); 915978b8803SAndrew Geissler } 916491d8ee7SSantosh Puranik 917491d8ee7SSantosh Puranik /** 918b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 919b6d5d45cSHieu Huynh * 920ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 921b6d5d45cSHieu Huynh * 922b6d5d45cSHieu Huynh * @return None. 923b6d5d45cSHieu Huynh */ 924b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 925ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 926b6d5d45cSHieu Huynh { 927b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 928b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 929b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 930b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 931ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 932b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 933b6d5d45cSHieu Huynh if (ec) 934b6d5d45cSHieu Huynh { 93562598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 936b6d5d45cSHieu Huynh return; 937b6d5d45cSHieu Huynh } 938b6d5d45cSHieu Huynh 939b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 940b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 941b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 942b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 943b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 944b6d5d45cSHieu Huynh 945b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 946ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 947b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 948b6d5d45cSHieu Huynh }); 949b6d5d45cSHieu Huynh } 950b6d5d45cSHieu Huynh 951b6d5d45cSHieu Huynh /** 952c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 953cd9a4666SKonstantin Aladyshev * 954ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 955cd9a4666SKonstantin Aladyshev * 956cd9a4666SKonstantin Aladyshev * @return None. 957cd9a4666SKonstantin Aladyshev */ 958cd9a4666SKonstantin Aladyshev 959ac106bf6SEd Tanous inline void 960ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 961cd9a4666SKonstantin Aladyshev { 9621e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9631e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9641e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9651e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 966ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9671e1e598dSJonathan Doman const std::string& bootType) { 968cd9a4666SKonstantin Aladyshev if (ec) 969cd9a4666SKonstantin Aladyshev { 970cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 971cd9a4666SKonstantin Aladyshev return; 972cd9a4666SKonstantin Aladyshev } 973cd9a4666SKonstantin Aladyshev 97462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 975cd9a4666SKonstantin Aladyshev 976ac106bf6SEd Tanous asyncResp->res 977ac106bf6SEd Tanous .jsonValue["Boot"] 978002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 979613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 980cd9a4666SKonstantin Aladyshev 9811e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 982cd9a4666SKonstantin Aladyshev if (rfType.empty()) 983cd9a4666SKonstantin Aladyshev { 984ac106bf6SEd Tanous messages::internalError(asyncResp->res); 985cd9a4666SKonstantin Aladyshev return; 986cd9a4666SKonstantin Aladyshev } 987cd9a4666SKonstantin Aladyshev 988ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9891e1e598dSJonathan Doman }); 990cd9a4666SKonstantin Aladyshev } 991cd9a4666SKonstantin Aladyshev 992cd9a4666SKonstantin Aladyshev /** 993c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 994491d8ee7SSantosh Puranik * 995ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 996491d8ee7SSantosh Puranik * 997491d8ee7SSantosh Puranik * @return None. 998491d8ee7SSantosh Puranik */ 999c21865c4SKonstantin Aladyshev 1000ac106bf6SEd Tanous inline void 1001ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1002491d8ee7SSantosh Puranik { 10031e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10041e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10051e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10061e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1007ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10081e1e598dSJonathan Doman const std::string& bootModeStr) { 1009491d8ee7SSantosh Puranik if (ec) 1010491d8ee7SSantosh Puranik { 1011b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1012ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1013491d8ee7SSantosh Puranik return; 1014491d8ee7SSantosh Puranik } 1015491d8ee7SSantosh Puranik 101662598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 1017491d8ee7SSantosh Puranik 1018ac106bf6SEd Tanous asyncResp->res 10190fda0f12SGeorge Liu .jsonValue["Boot"] 1020002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 1021002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1022491d8ee7SSantosh Puranik 10231e1e598dSJonathan Doman if (bootModeStr != 1024491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1025491d8ee7SSantosh Puranik { 10261e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 1027491d8ee7SSantosh Puranik if (!rfMode.empty()) 1028491d8ee7SSantosh Puranik { 1029ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1030491d8ee7SSantosh Puranik rfMode; 1031491d8ee7SSantosh Puranik } 1032491d8ee7SSantosh Puranik } 10331e1e598dSJonathan Doman }); 1034491d8ee7SSantosh Puranik } 1035491d8ee7SSantosh Puranik 1036491d8ee7SSantosh Puranik /** 1037c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1038491d8ee7SSantosh Puranik * 1039ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1040491d8ee7SSantosh Puranik * 1041491d8ee7SSantosh Puranik * @return None. 1042491d8ee7SSantosh Puranik */ 1043c21865c4SKonstantin Aladyshev 1044c21865c4SKonstantin Aladyshev inline void 1045ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1046491d8ee7SSantosh Puranik { 10471e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10481e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10491e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10501e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1051ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10521e1e598dSJonathan Doman const std::string& bootSourceStr) { 1053491d8ee7SSantosh Puranik if (ec) 1054491d8ee7SSantosh Puranik { 10555ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10565ef735c8SNan Zhou { 10575ef735c8SNan Zhou return; 10585ef735c8SNan Zhou } 1059b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1060ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1061491d8ee7SSantosh Puranik return; 1062491d8ee7SSantosh Puranik } 1063491d8ee7SSantosh Puranik 106462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 1065491d8ee7SSantosh Puranik 10661e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1067491d8ee7SSantosh Puranik if (!rfSource.empty()) 1068491d8ee7SSantosh Puranik { 1069ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1070ac106bf6SEd Tanous rfSource; 1071491d8ee7SSantosh Puranik } 1072cd9a4666SKonstantin Aladyshev 1073cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1074cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1075ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10761e1e598dSJonathan Doman }); 1077491d8ee7SSantosh Puranik } 1078491d8ee7SSantosh Puranik 1079491d8ee7SSantosh Puranik /** 1080c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1081c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1082c21865c4SKonstantin Aladyshev * state 1083491d8ee7SSantosh Puranik * 1084ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1085491d8ee7SSantosh Puranik * 1086491d8ee7SSantosh Puranik * @return None. 1087491d8ee7SSantosh Puranik */ 1088491d8ee7SSantosh Puranik 1089ac106bf6SEd Tanous inline void processBootOverrideEnable( 1090ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1091c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1092c21865c4SKonstantin Aladyshev { 1093c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1094c21865c4SKonstantin Aladyshev { 1095ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1096ac106bf6SEd Tanous "Disabled"; 1097c21865c4SKonstantin Aladyshev return; 1098c21865c4SKonstantin Aladyshev } 1099c21865c4SKonstantin Aladyshev 1100c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1101c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 11021e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11031e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11041e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 11051e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1106ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1107491d8ee7SSantosh Puranik if (ec) 1108491d8ee7SSantosh Puranik { 1109b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1110ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1111491d8ee7SSantosh Puranik return; 1112491d8ee7SSantosh Puranik } 1113491d8ee7SSantosh Puranik 1114c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1115c21865c4SKonstantin Aladyshev { 1116ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1117ac106bf6SEd Tanous "Once"; 1118c21865c4SKonstantin Aladyshev } 1119c21865c4SKonstantin Aladyshev else 1120c21865c4SKonstantin Aladyshev { 1121ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1122c21865c4SKonstantin Aladyshev "Continuous"; 1123c21865c4SKonstantin Aladyshev } 11241e1e598dSJonathan Doman }); 1125491d8ee7SSantosh Puranik } 1126491d8ee7SSantosh Puranik 1127491d8ee7SSantosh Puranik /** 1128c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1129c21865c4SKonstantin Aladyshev * 1130ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1131c21865c4SKonstantin Aladyshev * 1132c21865c4SKonstantin Aladyshev * @return None. 1133c21865c4SKonstantin Aladyshev */ 1134c21865c4SKonstantin Aladyshev 1135c21865c4SKonstantin Aladyshev inline void 1136ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1137c21865c4SKonstantin Aladyshev { 11381e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11391e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11401e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 11411e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1142ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 11431e1e598dSJonathan Doman const bool bootOverrideEnable) { 1144c21865c4SKonstantin Aladyshev if (ec) 1145c21865c4SKonstantin Aladyshev { 11465ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11475ef735c8SNan Zhou { 11485ef735c8SNan Zhou return; 11495ef735c8SNan Zhou } 1150b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1151ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1152c21865c4SKonstantin Aladyshev return; 1153c21865c4SKonstantin Aladyshev } 1154c21865c4SKonstantin Aladyshev 1155ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11561e1e598dSJonathan Doman }); 1157c21865c4SKonstantin Aladyshev } 1158c21865c4SKonstantin Aladyshev 1159c21865c4SKonstantin Aladyshev /** 1160c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1161c21865c4SKonstantin Aladyshev * 1162ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1163c21865c4SKonstantin Aladyshev * 1164c21865c4SKonstantin Aladyshev * @return None. 1165c21865c4SKonstantin Aladyshev */ 1166ac106bf6SEd Tanous inline void 1167ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1168c21865c4SKonstantin Aladyshev { 116962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1170c21865c4SKonstantin Aladyshev 1171ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1172ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1173ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1174c21865c4SKonstantin Aladyshev } 1175c21865c4SKonstantin Aladyshev 1176c21865c4SKonstantin Aladyshev /** 1177c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1178c0557e1aSGunnar Mills * 1179c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1180c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1181c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1182c0557e1aSGunnar Mills * last power operation time. 1183c0557e1aSGunnar Mills * 1184ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1185c0557e1aSGunnar Mills * 1186c0557e1aSGunnar Mills * @return None. 1187c0557e1aSGunnar Mills */ 1188ac106bf6SEd Tanous inline void 1189ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1190c0557e1aSGunnar Mills { 119162598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1192c0557e1aSGunnar Mills 11931e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11941e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11951e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11961e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1197ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1198ac106bf6SEd Tanous uint64_t lastResetTime) { 1199c0557e1aSGunnar Mills if (ec) 1200c0557e1aSGunnar Mills { 120162598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1202c0557e1aSGunnar Mills return; 1203c0557e1aSGunnar Mills } 1204c0557e1aSGunnar Mills 1205c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1206c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 12071e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1208c0557e1aSGunnar Mills 1209c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1210ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 12112b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 12121e1e598dSJonathan Doman }); 1213c0557e1aSGunnar Mills } 1214c0557e1aSGunnar Mills 1215c0557e1aSGunnar Mills /** 1216797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1217797d5daeSCorey Hardesty * 1218797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1219797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1220797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1221797d5daeSCorey Hardesty * dbus. 1222797d5daeSCorey Hardesty * 1223ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1224797d5daeSCorey Hardesty * 1225797d5daeSCorey Hardesty * @return None. 1226797d5daeSCorey Hardesty */ 1227ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1228ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1229797d5daeSCorey Hardesty { 123062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1231797d5daeSCorey Hardesty 1232797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1233797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1234797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1235797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1236ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1237ac106bf6SEd Tanous const boost::system::error_code& ec, 1238797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1239797d5daeSCorey Hardesty if (ec) 1240797d5daeSCorey Hardesty { 1241797d5daeSCorey Hardesty if (ec.value() != EBADR) 1242797d5daeSCorey Hardesty { 124362598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1244ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1245797d5daeSCorey Hardesty } 1246797d5daeSCorey Hardesty return; 1247797d5daeSCorey Hardesty } 1248797d5daeSCorey Hardesty 1249797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1250797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1251797d5daeSCorey Hardesty 1252797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1253797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1254797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1255797d5daeSCorey Hardesty 1256797d5daeSCorey Hardesty if (!success) 1257797d5daeSCorey Hardesty { 1258ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1259797d5daeSCorey Hardesty return; 1260797d5daeSCorey Hardesty } 1261797d5daeSCorey Hardesty 1262797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1263797d5daeSCorey Hardesty { 1264ac106bf6SEd Tanous asyncResp->res 1265ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1266797d5daeSCorey Hardesty *attemptsLeft; 1267797d5daeSCorey Hardesty } 1268797d5daeSCorey Hardesty 1269797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1270797d5daeSCorey Hardesty { 1271ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1272797d5daeSCorey Hardesty *retryAttempts; 1273797d5daeSCorey Hardesty } 1274797d5daeSCorey Hardesty }); 1275797d5daeSCorey Hardesty } 1276797d5daeSCorey Hardesty 1277797d5daeSCorey Hardesty /** 12786bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12796bd5a8d2SGunnar Mills * 1280ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12816bd5a8d2SGunnar Mills * 12826bd5a8d2SGunnar Mills * @return None. 12836bd5a8d2SGunnar Mills */ 1284797d5daeSCorey Hardesty inline void 1285ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12866bd5a8d2SGunnar Mills { 128762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12886bd5a8d2SGunnar Mills 12891e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12901e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12911e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12921e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1293ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1294ac106bf6SEd Tanous bool autoRebootEnabled) { 12956bd5a8d2SGunnar Mills if (ec) 12966bd5a8d2SGunnar Mills { 1297797d5daeSCorey Hardesty if (ec.value() != EBADR) 1298797d5daeSCorey Hardesty { 129962598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1300ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1301797d5daeSCorey Hardesty } 13026bd5a8d2SGunnar Mills return; 13036bd5a8d2SGunnar Mills } 13046bd5a8d2SGunnar Mills 130562598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1306e05aec50SEd Tanous if (autoRebootEnabled) 13076bd5a8d2SGunnar Mills { 1308ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 13096bd5a8d2SGunnar Mills "RetryAttempts"; 13106bd5a8d2SGunnar Mills } 13116bd5a8d2SGunnar Mills else 13126bd5a8d2SGunnar Mills { 1313ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1314ac106bf6SEd Tanous "Disabled"; 13156bd5a8d2SGunnar Mills } 1316ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 131769f35306SGunnar Mills 131869f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 131969f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 132069f35306SGunnar Mills // RetryAttempts. 1321ac106bf6SEd Tanous asyncResp->res 1322ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1323ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 13241e1e598dSJonathan Doman }); 13256bd5a8d2SGunnar Mills } 13266bd5a8d2SGunnar Mills 13276bd5a8d2SGunnar Mills /** 1328797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1329797d5daeSCorey Hardesty * 1330ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1331797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1332797d5daeSCorey Hardesty * 1333797d5daeSCorey Hardesty *@return None. 1334797d5daeSCorey Hardesty */ 1335797d5daeSCorey Hardesty 1336ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1337ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1338797d5daeSCorey Hardesty const uint32_t retryAttempts) 1339797d5daeSCorey Hardesty { 134062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 13419ae226faSGeorge Liu sdbusplus::asio::setProperty( 13429ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 13439ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 13449ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 13459ae226faSGeorge Liu retryAttempts, [asyncResp](const boost::system::error_code& ec) { 1346797d5daeSCorey Hardesty if (ec) 1347797d5daeSCorey Hardesty { 134862598e31SEd Tanous BMCWEB_LOG_ERROR( 134962598e31SEd Tanous "DBUS response error: Set setAutomaticRetryAttempts{}", ec); 1350ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1351797d5daeSCorey Hardesty return; 1352797d5daeSCorey Hardesty } 13539ae226faSGeorge Liu }); 1354797d5daeSCorey Hardesty } 1355797d5daeSCorey Hardesty 13568d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 13578d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 13588d69c668SEd Tanous { 13598d69c668SEd Tanous if (value == 13608d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 13618d69c668SEd Tanous { 13628d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 13638d69c668SEd Tanous } 13648d69c668SEd Tanous if (value == 13658d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 13668d69c668SEd Tanous { 13678d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13688d69c668SEd Tanous } 13698d69c668SEd Tanous if (value == 13703a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 13718d69c668SEd Tanous { 13728d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13738d69c668SEd Tanous } 13748d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13758d69c668SEd Tanous { 13768d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13778d69c668SEd Tanous } 13788d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13798d69c668SEd Tanous } 1380797d5daeSCorey Hardesty /** 1381c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1382c6a620f2SGeorge Liu * 1383ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1384c6a620f2SGeorge Liu * 1385c6a620f2SGeorge Liu * @return None. 1386c6a620f2SGeorge Liu */ 13878d1b46d7Szhanghch05 inline void 1388ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1389c6a620f2SGeorge Liu { 139062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1391c6a620f2SGeorge Liu 13921e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13931e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13941e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13951e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1396ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13975e7e2dc5SEd Tanous const std::string& policy) { 1398c6a620f2SGeorge Liu if (ec) 1399c6a620f2SGeorge Liu { 140062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1401c6a620f2SGeorge Liu return; 1402c6a620f2SGeorge Liu } 14038d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 14048d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 14058d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1406c6a620f2SGeorge Liu { 1407ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1408c6a620f2SGeorge Liu return; 1409c6a620f2SGeorge Liu } 1410c6a620f2SGeorge Liu 14118d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 14121e1e598dSJonathan Doman }); 1413c6a620f2SGeorge Liu } 1414c6a620f2SGeorge Liu 1415c6a620f2SGeorge Liu /** 14169dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 14179dcfe8c1SAlbert Zhang * 14189dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 14199dcfe8c1SAlbert Zhang * 14209dcfe8c1SAlbert Zhang * @return None. 14219dcfe8c1SAlbert Zhang */ 14229dcfe8c1SAlbert Zhang inline void 14239dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14249dcfe8c1SAlbert Zhang { 142562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 14269dcfe8c1SAlbert Zhang 14279dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 14289dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 14299dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 14309dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 14319dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 14329dcfe8c1SAlbert Zhang if (ec) 14339dcfe8c1SAlbert Zhang { 14349dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 14359dcfe8c1SAlbert Zhang { 1436b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 14379dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 14389dcfe8c1SAlbert Zhang } 14399dcfe8c1SAlbert Zhang return; 14409dcfe8c1SAlbert Zhang } 14419dcfe8c1SAlbert Zhang 14429dcfe8c1SAlbert Zhang if (value) 14439dcfe8c1SAlbert Zhang { 14449dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault"; 14459dcfe8c1SAlbert Zhang } 14469dcfe8c1SAlbert Zhang else 14479dcfe8c1SAlbert Zhang { 14489dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never"; 14499dcfe8c1SAlbert Zhang } 14509dcfe8c1SAlbert Zhang }); 14519dcfe8c1SAlbert Zhang } 14529dcfe8c1SAlbert Zhang 14539dcfe8c1SAlbert Zhang /** 14541981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 14551981771bSAli Ahmed * TPM is required for booting the host. 14561981771bSAli Ahmed * 1457ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14581981771bSAli Ahmed * 14591981771bSAli Ahmed * @return None. 14601981771bSAli Ahmed */ 14611981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1462ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14631981771bSAli Ahmed { 146462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1465e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1466e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1467e99073f5SGeorge Liu dbus::utility::getSubTree( 1468e99073f5SGeorge Liu "/", 0, interfaces, 1469ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1470b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14711981771bSAli Ahmed if (ec) 14721981771bSAli Ahmed { 147362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", 147462598e31SEd Tanous ec); 14751981771bSAli Ahmed // This is an optional D-Bus object so just return if 14761981771bSAli Ahmed // error occurs 14771981771bSAli Ahmed return; 14781981771bSAli Ahmed } 147926f6976fSEd Tanous if (subtree.empty()) 14801981771bSAli Ahmed { 14811981771bSAli Ahmed // As noted above, this is an optional interface so just return 14821981771bSAli Ahmed // if there is no instance found 14831981771bSAli Ahmed return; 14841981771bSAli Ahmed } 14851981771bSAli Ahmed 14861981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14871981771bSAli Ahmed if (subtree.size() > 1) 14881981771bSAli Ahmed { 148962598e31SEd Tanous BMCWEB_LOG_DEBUG( 149062598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 149162598e31SEd Tanous subtree.size()); 14921981771bSAli Ahmed // Throw an internal Error and return 1493ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14941981771bSAli Ahmed return; 14951981771bSAli Ahmed } 14961981771bSAli Ahmed 14971981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14981981771bSAli Ahmed // field 14991981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15001981771bSAli Ahmed { 150162598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1502ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15031981771bSAli Ahmed return; 15041981771bSAli Ahmed } 15051981771bSAli Ahmed 15061981771bSAli Ahmed const std::string& path = subtree[0].first; 15071981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15081981771bSAli Ahmed 15091981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 15101e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 15111e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 15121e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1513ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1514ac106bf6SEd Tanous bool tpmRequired) { 15158a592810SEd Tanous if (ec2) 15161981771bSAli Ahmed { 1517b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}", 151862598e31SEd Tanous ec2); 1519ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15201981771bSAli Ahmed return; 15211981771bSAli Ahmed } 15221981771bSAli Ahmed 15231e1e598dSJonathan Doman if (tpmRequired) 15241981771bSAli Ahmed { 1525ac106bf6SEd Tanous asyncResp->res 1526ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15271981771bSAli Ahmed "Required"; 15281981771bSAli Ahmed } 15291981771bSAli Ahmed else 15301981771bSAli Ahmed { 1531ac106bf6SEd Tanous asyncResp->res 1532ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15331981771bSAli Ahmed "Disabled"; 15341981771bSAli Ahmed } 15351e1e598dSJonathan Doman }); 1536e99073f5SGeorge Liu }); 15371981771bSAli Ahmed } 15381981771bSAli Ahmed 15391981771bSAli Ahmed /** 15401c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 15411c05dae3SAli Ahmed * TPM is required for booting the host. 15421c05dae3SAli Ahmed * 1543ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 15441c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 15451c05dae3SAli Ahmed * 15461c05dae3SAli Ahmed * @return None. 15471c05dae3SAli Ahmed */ 15481c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1549ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 15501c05dae3SAli Ahmed { 155162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1552e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1553e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1554e99073f5SGeorge Liu dbus::utility::getSubTree( 1555e99073f5SGeorge Liu "/", 0, interfaces, 1556ac106bf6SEd Tanous [asyncResp, 1557e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1558e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15591c05dae3SAli Ahmed if (ec) 15601c05dae3SAli Ahmed { 1561b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", 156262598e31SEd Tanous ec); 1563ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15641c05dae3SAli Ahmed return; 15651c05dae3SAli Ahmed } 156626f6976fSEd Tanous if (subtree.empty()) 15671c05dae3SAli Ahmed { 1568ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 15691c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15701c05dae3SAli Ahmed return; 15711c05dae3SAli Ahmed } 15721c05dae3SAli Ahmed 15731c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15741c05dae3SAli Ahmed if (subtree.size() > 1) 15751c05dae3SAli Ahmed { 157662598e31SEd Tanous BMCWEB_LOG_DEBUG( 157762598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 157862598e31SEd Tanous subtree.size()); 15791c05dae3SAli Ahmed // Throw an internal Error and return 1580ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15811c05dae3SAli Ahmed return; 15821c05dae3SAli Ahmed } 15831c05dae3SAli Ahmed 15841c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15851c05dae3SAli Ahmed // field 15861c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15871c05dae3SAli Ahmed { 158862598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1589ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15901c05dae3SAli Ahmed return; 15911c05dae3SAli Ahmed } 15921c05dae3SAli Ahmed 15931c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15941c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15951c05dae3SAli Ahmed 15961c05dae3SAli Ahmed if (serv.empty()) 15971c05dae3SAli Ahmed { 159862598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1599ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16001c05dae3SAli Ahmed return; 16011c05dae3SAli Ahmed } 16021c05dae3SAli Ahmed 16031c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 16049ae226faSGeorge Liu sdbusplus::asio::setProperty( 16059ae226faSGeorge Liu *crow::connections::systemBus, serv, path, 16069ae226faSGeorge Liu "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired, 1607ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 16088a592810SEd Tanous if (ec2) 16091c05dae3SAli Ahmed { 1610b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 161162598e31SEd Tanous "DBUS response error: Set TrustedModuleRequiredToBoot{}", 161262598e31SEd Tanous ec2); 1613ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16141c05dae3SAli Ahmed return; 16151c05dae3SAli Ahmed } 161662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done."); 16179ae226faSGeorge Liu }); 1618e99073f5SGeorge Liu }); 16191c05dae3SAli Ahmed } 16201c05dae3SAli Ahmed 16211c05dae3SAli Ahmed /** 1622491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1623491d8ee7SSantosh Puranik * 1624ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1625cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1626cd9a4666SKonstantin Aladyshev * @return Integer error code. 1627cd9a4666SKonstantin Aladyshev */ 1628ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1629cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1630cd9a4666SKonstantin Aladyshev { 1631c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1632cd9a4666SKonstantin Aladyshev 1633c21865c4SKonstantin Aladyshev if (!bootType) 1634cd9a4666SKonstantin Aladyshev { 1635c21865c4SKonstantin Aladyshev return; 1636c21865c4SKonstantin Aladyshev } 1637c21865c4SKonstantin Aladyshev 1638cd9a4666SKonstantin Aladyshev // Source target specified 163962598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1640cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1641cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1642cd9a4666SKonstantin Aladyshev { 1643cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1644cd9a4666SKonstantin Aladyshev } 1645cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1646cd9a4666SKonstantin Aladyshev { 1647cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1648cd9a4666SKonstantin Aladyshev } 1649cd9a4666SKonstantin Aladyshev else 1650cd9a4666SKonstantin Aladyshev { 165162598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 165262598e31SEd Tanous "BootSourceOverrideMode: {}", 165362598e31SEd Tanous *bootType); 1654ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1655cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1656cd9a4666SKonstantin Aladyshev return; 1657cd9a4666SKonstantin Aladyshev } 1658cd9a4666SKonstantin Aladyshev 1659cd9a4666SKonstantin Aladyshev // Act on validated parameters 166062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1661cd9a4666SKonstantin Aladyshev 16629ae226faSGeorge Liu sdbusplus::asio::setProperty( 16639ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 16649ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 16659ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr, 1666ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1667cd9a4666SKonstantin Aladyshev if (ec) 1668cd9a4666SKonstantin Aladyshev { 1669cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1670cd9a4666SKonstantin Aladyshev { 1671ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1672cd9a4666SKonstantin Aladyshev return; 1673cd9a4666SKonstantin Aladyshev } 1674b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1675ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1676cd9a4666SKonstantin Aladyshev return; 1677cd9a4666SKonstantin Aladyshev } 167862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type update done."); 16799ae226faSGeorge Liu }); 1680cd9a4666SKonstantin Aladyshev } 1681cd9a4666SKonstantin Aladyshev 1682cd9a4666SKonstantin Aladyshev /** 1683cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1684cd9a4666SKonstantin Aladyshev * 1685ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1686ac106bf6SEd Tanous * message. 1687c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1688c21865c4SKonstantin Aladyshev * @return Integer error code. 1689c21865c4SKonstantin Aladyshev */ 1690ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1691c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1692c21865c4SKonstantin Aladyshev { 1693c21865c4SKonstantin Aladyshev if (!bootEnable) 1694c21865c4SKonstantin Aladyshev { 1695c21865c4SKonstantin Aladyshev return; 1696c21865c4SKonstantin Aladyshev } 1697c21865c4SKonstantin Aladyshev // Source target specified 169862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1699c21865c4SKonstantin Aladyshev 1700c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1701c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1702c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1703c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1704c21865c4SKonstantin Aladyshev { 1705c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1706c21865c4SKonstantin Aladyshev } 1707c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1708c21865c4SKonstantin Aladyshev { 1709c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1710c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1711c21865c4SKonstantin Aladyshev } 1712c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1713c21865c4SKonstantin Aladyshev { 1714c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1715c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1716c21865c4SKonstantin Aladyshev } 1717c21865c4SKonstantin Aladyshev else 1718c21865c4SKonstantin Aladyshev { 171962598e31SEd Tanous BMCWEB_LOG_DEBUG( 172062598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 172162598e31SEd Tanous *bootEnable); 1722ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1723c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1724c21865c4SKonstantin Aladyshev return; 1725c21865c4SKonstantin Aladyshev } 1726c21865c4SKonstantin Aladyshev 1727c21865c4SKonstantin Aladyshev // Act on validated parameters 172862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1729c21865c4SKonstantin Aladyshev 17309ae226faSGeorge Liu sdbusplus::asio::setProperty( 17319ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17329ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 17339ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable, 1734ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 17358a592810SEd Tanous if (ec2) 1736c21865c4SKonstantin Aladyshev { 1737b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 1738ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1739c21865c4SKonstantin Aladyshev return; 1740c21865c4SKonstantin Aladyshev } 174162598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot override enable update done."); 17429ae226faSGeorge Liu }); 1743c21865c4SKonstantin Aladyshev 1744c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1745c21865c4SKonstantin Aladyshev { 1746c21865c4SKonstantin Aladyshev return; 1747c21865c4SKonstantin Aladyshev } 1748c21865c4SKonstantin Aladyshev 1749c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1750c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 175162598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 175262598e31SEd Tanous bootOverridePersistent); 1753c21865c4SKonstantin Aladyshev 17549ae226faSGeorge Liu sdbusplus::asio::setProperty( 17559ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17569ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot/one_time", 17579ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent, 1758ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1759c21865c4SKonstantin Aladyshev if (ec) 1760c21865c4SKonstantin Aladyshev { 1761b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1762ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1763c21865c4SKonstantin Aladyshev return; 1764c21865c4SKonstantin Aladyshev } 176562598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot one_time update done."); 17669ae226faSGeorge Liu }); 1767c21865c4SKonstantin Aladyshev } 1768c21865c4SKonstantin Aladyshev 1769c21865c4SKonstantin Aladyshev /** 1770c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1771c21865c4SKonstantin Aladyshev * 1772ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1773491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1774491d8ee7SSantosh Puranik * 1775265c1602SJohnathan Mantey * @return Integer error code. 1776491d8ee7SSantosh Puranik */ 1777ac106bf6SEd Tanous inline void 1778ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1779cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1780491d8ee7SSantosh Puranik { 1781c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1782c21865c4SKonstantin Aladyshev std::string bootModeStr; 1783944ffaf9SJohnathan Mantey 1784c21865c4SKonstantin Aladyshev if (!bootSource) 1785491d8ee7SSantosh Puranik { 1786c21865c4SKonstantin Aladyshev return; 1787c21865c4SKonstantin Aladyshev } 1788c21865c4SKonstantin Aladyshev 1789491d8ee7SSantosh Puranik // Source target specified 179062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1791491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1792ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1793ac106bf6SEd Tanous bootModeStr) != 0) 1794491d8ee7SSantosh Puranik { 179562598e31SEd Tanous BMCWEB_LOG_DEBUG( 179662598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 179762598e31SEd Tanous *bootSource); 1798ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1799491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1800491d8ee7SSantosh Puranik return; 1801491d8ee7SSantosh Puranik } 1802491d8ee7SSantosh Puranik 1803944ffaf9SJohnathan Mantey // Act on validated parameters 180462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 180562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1806944ffaf9SJohnathan Mantey 18079ae226faSGeorge Liu sdbusplus::asio::setProperty( 18089ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 18099ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 18109ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr, 1811ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1812491d8ee7SSantosh Puranik if (ec) 1813491d8ee7SSantosh Puranik { 1814b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1815ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1816491d8ee7SSantosh Puranik return; 1817491d8ee7SSantosh Puranik } 181862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source update done."); 18199ae226faSGeorge Liu }); 1820944ffaf9SJohnathan Mantey 18219ae226faSGeorge Liu sdbusplus::asio::setProperty( 18229ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 18239ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 18249ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr, 1825ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1826491d8ee7SSantosh Puranik if (ec) 1827491d8ee7SSantosh Puranik { 1828b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1829ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1830491d8ee7SSantosh Puranik return; 1831491d8ee7SSantosh Puranik } 183262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode update done."); 18339ae226faSGeorge Liu }); 1834cd9a4666SKonstantin Aladyshev } 1835944ffaf9SJohnathan Mantey 1836cd9a4666SKonstantin Aladyshev /** 1837c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1838491d8ee7SSantosh Puranik * 1839ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1840491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1841cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1842491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1843491d8ee7SSantosh Puranik * 1844265c1602SJohnathan Mantey * @return Integer error code. 1845491d8ee7SSantosh Puranik */ 1846c21865c4SKonstantin Aladyshev 1847ac106bf6SEd Tanous inline void 1848ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1849c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1850c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1851c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1852491d8ee7SSantosh Puranik { 185362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1854491d8ee7SSantosh Puranik 1855ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1856ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1857ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1858491d8ee7SSantosh Puranik } 1859491d8ee7SSantosh Puranik 1860c6a620f2SGeorge Liu /** 186198e386ecSGunnar Mills * @brief Sets AssetTag 186298e386ecSGunnar Mills * 1863ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 186498e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 186598e386ecSGunnar Mills * 186698e386ecSGunnar Mills * @return None. 186798e386ecSGunnar Mills */ 1868ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 186998e386ecSGunnar Mills const std::string& assetTag) 187098e386ecSGunnar Mills { 1871e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1872e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1873e99073f5SGeorge Liu dbus::utility::getSubTree( 1874e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1875ac106bf6SEd Tanous [asyncResp, 1876e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1877b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 187898e386ecSGunnar Mills if (ec) 187998e386ecSGunnar Mills { 188062598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1881ac106bf6SEd Tanous messages::internalError(asyncResp->res); 188298e386ecSGunnar Mills return; 188398e386ecSGunnar Mills } 188426f6976fSEd Tanous if (subtree.empty()) 188598e386ecSGunnar Mills { 188662598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1887ac106bf6SEd Tanous messages::internalError(asyncResp->res); 188898e386ecSGunnar Mills return; 188998e386ecSGunnar Mills } 189098e386ecSGunnar Mills // Assume only 1 system D-Bus object 189198e386ecSGunnar Mills // Throw an error if there is more than 1 189298e386ecSGunnar Mills if (subtree.size() > 1) 189398e386ecSGunnar Mills { 189462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1895ac106bf6SEd Tanous messages::internalError(asyncResp->res); 189698e386ecSGunnar Mills return; 189798e386ecSGunnar Mills } 189898e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 189998e386ecSGunnar Mills { 190062598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1901ac106bf6SEd Tanous messages::internalError(asyncResp->res); 190298e386ecSGunnar Mills return; 190398e386ecSGunnar Mills } 190498e386ecSGunnar Mills 190598e386ecSGunnar Mills const std::string& path = subtree[0].first; 190698e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 190798e386ecSGunnar Mills 190898e386ecSGunnar Mills if (service.empty()) 190998e386ecSGunnar Mills { 191062598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1911ac106bf6SEd Tanous messages::internalError(asyncResp->res); 191298e386ecSGunnar Mills return; 191398e386ecSGunnar Mills } 191498e386ecSGunnar Mills 19159ae226faSGeorge Liu sdbusplus::asio::setProperty( 19169ae226faSGeorge Liu *crow::connections::systemBus, service, path, 19179ae226faSGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 19189ae226faSGeorge Liu assetTag, [asyncResp](const boost::system::error_code& ec2) { 191998e386ecSGunnar Mills if (ec2) 192098e386ecSGunnar Mills { 1921b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}", 192262598e31SEd Tanous ec2); 1923ac106bf6SEd Tanous messages::internalError(asyncResp->res); 192498e386ecSGunnar Mills return; 192598e386ecSGunnar Mills } 19269ae226faSGeorge Liu }); 1927e99073f5SGeorge Liu }); 192898e386ecSGunnar Mills } 192998e386ecSGunnar Mills 193098e386ecSGunnar Mills /** 19319dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 19329dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 19339dcfe8c1SAlbert Zhang * 19349dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 19359dcfe8c1SAlbert Zhang * stopBootOnFault 19369dcfe8c1SAlbert Zhang * 19379dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 19389dcfe8c1SAlbert Zhang */ 19399dcfe8c1SAlbert Zhang inline std::optional<bool> 19409dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 19419dcfe8c1SAlbert Zhang { 19429dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 19439dcfe8c1SAlbert Zhang { 19449dcfe8c1SAlbert Zhang return true; 19459dcfe8c1SAlbert Zhang } 19469dcfe8c1SAlbert Zhang 19479dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 19489dcfe8c1SAlbert Zhang { 19499dcfe8c1SAlbert Zhang return false; 19509dcfe8c1SAlbert Zhang } 19519dcfe8c1SAlbert Zhang 19529dcfe8c1SAlbert Zhang return std::nullopt; 19539dcfe8c1SAlbert Zhang } 19549dcfe8c1SAlbert Zhang 19559dcfe8c1SAlbert Zhang /** 19569dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 19579dcfe8c1SAlbert Zhang * 1958fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 19599dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 19609dcfe8c1SAlbert Zhang * 19619dcfe8c1SAlbert Zhang * @return None. 19629dcfe8c1SAlbert Zhang */ 1963fc3edfddSEd Tanous inline void 1964fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19659dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 19669dcfe8c1SAlbert Zhang { 196762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 19689dcfe8c1SAlbert Zhang 19699dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 19709dcfe8c1SAlbert Zhang if (!stopBootEnabled) 19719dcfe8c1SAlbert Zhang { 197262598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 197362598e31SEd Tanous stopBootOnFault); 1974fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 19759dcfe8c1SAlbert Zhang "StopBootOnFault"); 19769dcfe8c1SAlbert Zhang return; 19779dcfe8c1SAlbert Zhang } 19789dcfe8c1SAlbert Zhang 1979fc3edfddSEd Tanous sdbusplus::asio::setProperty( 1980fc3edfddSEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 19819dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 1982fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1983fc3edfddSEd Tanous *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) { 19849dcfe8c1SAlbert Zhang if (ec) 19859dcfe8c1SAlbert Zhang { 19869dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 19879dcfe8c1SAlbert Zhang { 1988b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1989fc3edfddSEd Tanous messages::internalError(asyncResp->res); 19909dcfe8c1SAlbert Zhang } 19919dcfe8c1SAlbert Zhang return; 19929dcfe8c1SAlbert Zhang } 19939dcfe8c1SAlbert Zhang }); 19949dcfe8c1SAlbert Zhang } 19959dcfe8c1SAlbert Zhang 19969dcfe8c1SAlbert Zhang /** 199769f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 199869f35306SGunnar Mills * 1999ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 200069f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 200169f35306SGunnar Mills * 200269f35306SGunnar Mills * @return None. 200369f35306SGunnar Mills */ 2004ac106bf6SEd Tanous inline void 2005ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2006f23b7296SEd Tanous const std::string& automaticRetryConfig) 200769f35306SGunnar Mills { 200862598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 200969f35306SGunnar Mills 201069f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 2011543f4400SEd Tanous bool autoRebootEnabled = false; 201269f35306SGunnar Mills 201369f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 201469f35306SGunnar Mills { 201569f35306SGunnar Mills autoRebootEnabled = false; 201669f35306SGunnar Mills } 201769f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 201869f35306SGunnar Mills { 201969f35306SGunnar Mills autoRebootEnabled = true; 202069f35306SGunnar Mills } 202169f35306SGunnar Mills else 202269f35306SGunnar Mills { 202362598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 202462598e31SEd Tanous automaticRetryConfig); 2025ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 202669f35306SGunnar Mills "AutomaticRetryConfig"); 202769f35306SGunnar Mills return; 202869f35306SGunnar Mills } 202969f35306SGunnar Mills 20309ae226faSGeorge Liu sdbusplus::asio::setProperty( 20319ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20329ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/auto_reboot", 20339ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 20349ae226faSGeorge Liu autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) { 203569f35306SGunnar Mills if (ec) 203669f35306SGunnar Mills { 2037b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2038ac106bf6SEd Tanous messages::internalError(asyncResp->res); 203969f35306SGunnar Mills return; 204069f35306SGunnar Mills } 20419ae226faSGeorge Liu }); 204269f35306SGunnar Mills } 204369f35306SGunnar Mills 20448d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 20458d69c668SEd Tanous { 20468d69c668SEd Tanous if (policy == "AlwaysOn") 20478d69c668SEd Tanous { 20488d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 20498d69c668SEd Tanous } 20508d69c668SEd Tanous if (policy == "AlwaysOff") 20518d69c668SEd Tanous { 20528d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 20538d69c668SEd Tanous } 20548d69c668SEd Tanous if (policy == "LastState") 20558d69c668SEd Tanous { 20568d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 20578d69c668SEd Tanous } 20588d69c668SEd Tanous return ""; 20598d69c668SEd Tanous } 20608d69c668SEd Tanous 206169f35306SGunnar Mills /** 2062c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 2063c6a620f2SGeorge Liu * 2064ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2065c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 2066c6a620f2SGeorge Liu * 2067c6a620f2SGeorge Liu * @return None. 2068c6a620f2SGeorge Liu */ 20698d1b46d7Szhanghch05 inline void 2070ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20718d69c668SEd Tanous std::string_view policy) 2072c6a620f2SGeorge Liu { 207362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 2074c6a620f2SGeorge Liu 20758d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 2076c6a620f2SGeorge Liu 20778d69c668SEd Tanous if (powerRestorePolicy.empty()) 2078c6a620f2SGeorge Liu { 2079ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 20804e69c904SGunnar Mills "PowerRestorePolicy"); 2081c6a620f2SGeorge Liu return; 2082c6a620f2SGeorge Liu } 2083c6a620f2SGeorge Liu 20849ae226faSGeorge Liu sdbusplus::asio::setProperty( 20859ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20869ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 20879ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 20889ae226faSGeorge Liu powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) { 2089c6a620f2SGeorge Liu if (ec) 2090c6a620f2SGeorge Liu { 2091b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2092ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2093c6a620f2SGeorge Liu return; 2094c6a620f2SGeorge Liu } 20959ae226faSGeorge Liu }); 2096c6a620f2SGeorge Liu } 2097c6a620f2SGeorge Liu 2098a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 2099a6349918SAppaRao Puli /** 2100a6349918SAppaRao Puli * @brief Retrieves provisioning status 2101a6349918SAppaRao Puli * 2102ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 2103a6349918SAppaRao Puli * 2104a6349918SAppaRao Puli * @return None. 2105a6349918SAppaRao Puli */ 2106ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 2107a6349918SAppaRao Puli { 210862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 2109bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2110bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 2111bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 2112ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2113b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 2114b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2115ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2116ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 211750626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 211850626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 211950626f4fSJames Feist 2120a6349918SAppaRao Puli if (ec) 2121a6349918SAppaRao Puli { 212262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 2123b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2124b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2125a6349918SAppaRao Puli return; 2126a6349918SAppaRao Puli } 2127a6349918SAppaRao Puli 2128a6349918SAppaRao Puli const bool* provState = nullptr; 2129a6349918SAppaRao Puli const bool* lockState = nullptr; 2130bc1d29deSKrzysztof Grobelny 2131bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 21320d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 21330d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 2134bc1d29deSKrzysztof Grobelny 2135bc1d29deSKrzysztof Grobelny if (!success) 2136a6349918SAppaRao Puli { 2137ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2138bc1d29deSKrzysztof Grobelny return; 2139a6349918SAppaRao Puli } 2140a6349918SAppaRao Puli 2141a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2142a6349918SAppaRao Puli { 214362598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 2144ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2145a6349918SAppaRao Puli return; 2146a6349918SAppaRao Puli } 2147a6349918SAppaRao Puli 2148a6349918SAppaRao Puli if (*provState == true) 2149a6349918SAppaRao Puli { 2150a6349918SAppaRao Puli if (*lockState == true) 2151a6349918SAppaRao Puli { 2152a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2153a6349918SAppaRao Puli } 2154a6349918SAppaRao Puli else 2155a6349918SAppaRao Puli { 2156a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2157a6349918SAppaRao Puli } 2158a6349918SAppaRao Puli } 2159a6349918SAppaRao Puli else 2160a6349918SAppaRao Puli { 2161a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2162a6349918SAppaRao Puli } 2163bc1d29deSKrzysztof Grobelny }); 2164a6349918SAppaRao Puli } 2165a6349918SAppaRao Puli #endif 2166a6349918SAppaRao Puli 2167491d8ee7SSantosh Puranik /** 21683a2d0424SChris Cain * @brief Translate the PowerMode to a response message. 21693a2d0424SChris Cain * 2170ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21713a2d0424SChris Cain * @param[in] modeValue PowerMode value to be translated 21723a2d0424SChris Cain * 21733a2d0424SChris Cain * @return None. 21743a2d0424SChris Cain */ 2175ac106bf6SEd Tanous inline void 2176ac106bf6SEd Tanous translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 21773a2d0424SChris Cain const std::string& modeValue) 21783a2d0424SChris Cain { 21790fda0f12SGeorge Liu if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 21803a2d0424SChris Cain { 2181ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "Static"; 21823a2d0424SChris Cain } 21830fda0f12SGeorge Liu else if ( 21840fda0f12SGeorge Liu modeValue == 21850fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 21863a2d0424SChris Cain { 2187ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance"; 21883a2d0424SChris Cain } 21890fda0f12SGeorge Liu else if (modeValue == 21900fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 21913a2d0424SChris Cain { 2192ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "PowerSaving"; 21933a2d0424SChris Cain } 21940fda0f12SGeorge Liu else if (modeValue == 21950fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 21963a2d0424SChris Cain { 2197ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode"] = "OEM"; 21983a2d0424SChris Cain } 21993a2d0424SChris Cain else 22003a2d0424SChris Cain { 22013a2d0424SChris Cain // Any other values would be invalid 220262598e31SEd Tanous BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue); 2203ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22043a2d0424SChris Cain } 22053a2d0424SChris Cain } 22063a2d0424SChris Cain 22073a2d0424SChris Cain /** 22083a2d0424SChris Cain * @brief Retrieves system power mode 22093a2d0424SChris Cain * 2210ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22113a2d0424SChris Cain * 22123a2d0424SChris Cain * @return None. 22133a2d0424SChris Cain */ 2214ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 22153a2d0424SChris Cain { 221662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 22173a2d0424SChris Cain 22183a2d0424SChris Cain // Get Power Mode object path: 2219e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2220e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2221e99073f5SGeorge Liu dbus::utility::getSubTree( 2222e99073f5SGeorge Liu "/", 0, interfaces, 2223ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2224b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22253a2d0424SChris Cain if (ec) 22263a2d0424SChris Cain { 222762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}", 222862598e31SEd Tanous ec); 22293a2d0424SChris Cain // This is an optional D-Bus object so just return if 22303a2d0424SChris Cain // error occurs 22313a2d0424SChris Cain return; 22323a2d0424SChris Cain } 22333a2d0424SChris Cain if (subtree.empty()) 22343a2d0424SChris Cain { 22353a2d0424SChris Cain // As noted above, this is an optional interface so just return 22363a2d0424SChris Cain // if there is no instance found 22373a2d0424SChris Cain return; 22383a2d0424SChris Cain } 22393a2d0424SChris Cain if (subtree.size() > 1) 22403a2d0424SChris Cain { 22413a2d0424SChris Cain // More then one PowerMode object is not supported and is an 22423a2d0424SChris Cain // error 224362598e31SEd Tanous BMCWEB_LOG_DEBUG( 224462598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 224562598e31SEd Tanous subtree.size()); 2246ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22473a2d0424SChris Cain return; 22483a2d0424SChris Cain } 22493a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 22503a2d0424SChris Cain { 225162598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2252ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22533a2d0424SChris Cain return; 22543a2d0424SChris Cain } 22553a2d0424SChris Cain const std::string& path = subtree[0].first; 22563a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22573a2d0424SChris Cain if (service.empty()) 22583a2d0424SChris Cain { 225962598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2260ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22613a2d0424SChris Cain return; 22623a2d0424SChris Cain } 22633a2d0424SChris Cain // Valid Power Mode object found, now read the current value 22641e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 22651e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 22661e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2267ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 22681e1e598dSJonathan Doman const std::string& pmode) { 22698a592810SEd Tanous if (ec2) 22703a2d0424SChris Cain { 2271b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on PowerMode Get: {}", 227262598e31SEd Tanous ec2); 2273ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22743a2d0424SChris Cain return; 22753a2d0424SChris Cain } 22763a2d0424SChris Cain 2277ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = { 2278002d39b4SEd Tanous "Static", "MaximumPerformance", "PowerSaving"}; 22793a2d0424SChris Cain 228062598e31SEd Tanous BMCWEB_LOG_DEBUG("Current power mode: {}", pmode); 2281ac106bf6SEd Tanous translatePowerMode(asyncResp, pmode); 22821e1e598dSJonathan Doman }); 2283e99073f5SGeorge Liu }); 22843a2d0424SChris Cain } 22853a2d0424SChris Cain 22863a2d0424SChris Cain /** 22873a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 22883a2d0424SChris Cain * name associated with that string 22893a2d0424SChris Cain * 2290ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22913a2d0424SChris Cain * @param[in] modeString String representing the desired PowerMode 22923a2d0424SChris Cain * 22933a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22943a2d0424SChris Cain */ 22953a2d0424SChris Cain inline std::string 2296ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22973a2d0424SChris Cain const std::string& modeString) 22983a2d0424SChris Cain { 22993a2d0424SChris Cain std::string mode; 23003a2d0424SChris Cain 23013a2d0424SChris Cain if (modeString == "Static") 23023a2d0424SChris Cain { 23033a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 23043a2d0424SChris Cain } 23053a2d0424SChris Cain else if (modeString == "MaximumPerformance") 23063a2d0424SChris Cain { 23070fda0f12SGeorge Liu mode = 23080fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 23093a2d0424SChris Cain } 23103a2d0424SChris Cain else if (modeString == "PowerSaving") 23113a2d0424SChris Cain { 23123a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 23133a2d0424SChris Cain } 23143a2d0424SChris Cain else 23153a2d0424SChris Cain { 2316ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, modeString, 2317ac106bf6SEd Tanous "PowerMode"); 23183a2d0424SChris Cain } 23193a2d0424SChris Cain return mode; 23203a2d0424SChris Cain } 23213a2d0424SChris Cain 23223a2d0424SChris Cain /** 23233a2d0424SChris Cain * @brief Sets system power mode. 23243a2d0424SChris Cain * 2325ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 23263a2d0424SChris Cain * @param[in] pmode System power mode from request. 23273a2d0424SChris Cain * 23283a2d0424SChris Cain * @return None. 23293a2d0424SChris Cain */ 2330ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 23313a2d0424SChris Cain const std::string& pmode) 23323a2d0424SChris Cain { 233362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 23343a2d0424SChris Cain 2335ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 23363a2d0424SChris Cain if (powerMode.empty()) 23373a2d0424SChris Cain { 23383a2d0424SChris Cain return; 23393a2d0424SChris Cain } 23403a2d0424SChris Cain 23413a2d0424SChris Cain // Get Power Mode object path: 2342e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2343e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2344e99073f5SGeorge Liu dbus::utility::getSubTree( 2345e99073f5SGeorge Liu "/", 0, interfaces, 2346ac106bf6SEd Tanous [asyncResp, 2347e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2348b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23493a2d0424SChris Cain if (ec) 23503a2d0424SChris Cain { 2351b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}", 235262598e31SEd Tanous ec); 23533a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2354ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23553a2d0424SChris Cain return; 23563a2d0424SChris Cain } 23573a2d0424SChris Cain if (subtree.empty()) 23583a2d0424SChris Cain { 23593a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2360ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 23613a2d0424SChris Cain "PowerMode"); 23623a2d0424SChris Cain return; 23633a2d0424SChris Cain } 23643a2d0424SChris Cain if (subtree.size() > 1) 23653a2d0424SChris Cain { 23663a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23673a2d0424SChris Cain // error 236862598e31SEd Tanous BMCWEB_LOG_DEBUG( 236962598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 237062598e31SEd Tanous subtree.size()); 2371ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23723a2d0424SChris Cain return; 23733a2d0424SChris Cain } 23743a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23753a2d0424SChris Cain { 237662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2377ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23783a2d0424SChris Cain return; 23793a2d0424SChris Cain } 23803a2d0424SChris Cain const std::string& path = subtree[0].first; 23813a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23823a2d0424SChris Cain if (service.empty()) 23833a2d0424SChris Cain { 238462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2385ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23863a2d0424SChris Cain return; 23873a2d0424SChris Cain } 23883a2d0424SChris Cain 238962598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 23903a2d0424SChris Cain 23913a2d0424SChris Cain // Set the Power Mode property 23929ae226faSGeorge Liu sdbusplus::asio::setProperty( 23939ae226faSGeorge Liu *crow::connections::systemBus, service, path, 23949ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode, 2395ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 23968a592810SEd Tanous if (ec2) 23973a2d0424SChris Cain { 2398b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2399ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24003a2d0424SChris Cain return; 24013a2d0424SChris Cain } 24029ae226faSGeorge Liu }); 2403e99073f5SGeorge Liu }); 24043a2d0424SChris Cain } 24053a2d0424SChris Cain 24063a2d0424SChris Cain /** 240751709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 240851709ffdSYong Li * 240951709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 241051709ffdSYong Li * 241151709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 241251709ffdSYong Li * translation cannot be done, returns an empty string. 241351709ffdSYong Li */ 241423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 241551709ffdSYong Li { 241651709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 241751709ffdSYong Li { 241851709ffdSYong Li return "None"; 241951709ffdSYong Li } 24203174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 242151709ffdSYong Li { 242251709ffdSYong Li return "ResetSystem"; 242351709ffdSYong Li } 24243174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 242551709ffdSYong Li { 242651709ffdSYong Li return "PowerDown"; 242751709ffdSYong Li } 24283174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 242951709ffdSYong Li { 243051709ffdSYong Li return "PowerCycle"; 243151709ffdSYong Li } 243251709ffdSYong Li 243351709ffdSYong Li return ""; 243451709ffdSYong Li } 243551709ffdSYong Li 243651709ffdSYong Li /** 2437c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2438c45f0082SYong Li * 2439c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2440c45f0082SYong Li * 2441c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2442c45f0082SYong Li *If translation cannot be done, returns an empty string. 2443c45f0082SYong Li */ 2444c45f0082SYong Li 244523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2446c45f0082SYong Li { 2447c45f0082SYong Li if (rfAction == "None") 2448c45f0082SYong Li { 2449c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2450c45f0082SYong Li } 24513174e4dfSEd Tanous if (rfAction == "PowerCycle") 2452c45f0082SYong Li { 2453c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2454c45f0082SYong Li } 24553174e4dfSEd Tanous if (rfAction == "PowerDown") 2456c45f0082SYong Li { 2457c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2458c45f0082SYong Li } 24593174e4dfSEd Tanous if (rfAction == "ResetSystem") 2460c45f0082SYong Li { 2461c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2462c45f0082SYong Li } 2463c45f0082SYong Li 2464c45f0082SYong Li return ""; 2465c45f0082SYong Li } 2466c45f0082SYong Li 2467c45f0082SYong Li /** 246851709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 246951709ffdSYong Li * 2470ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 247151709ffdSYong Li * 247251709ffdSYong Li * @return None. 247351709ffdSYong Li */ 24748d1b46d7Szhanghch05 inline void 2475ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 247651709ffdSYong Li { 247762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2478bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2479bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2480bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2481bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2482ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2483b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 248451709ffdSYong Li if (ec) 248551709ffdSYong Li { 248651709ffdSYong Li // watchdog service is stopped 248762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 248851709ffdSYong Li return; 248951709ffdSYong Li } 249051709ffdSYong Li 249162598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 249251709ffdSYong Li 249351709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2494ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 249551709ffdSYong Li 249651709ffdSYong Li // watchdog service is running/enabled 249751709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 249851709ffdSYong Li 2499bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2500bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 250151709ffdSYong Li 2502bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2503bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2504bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2505bc1d29deSKrzysztof Grobelny 2506bc1d29deSKrzysztof Grobelny if (!success) 250751709ffdSYong Li { 2508ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2509601af5edSChicago Duan return; 251051709ffdSYong Li } 251151709ffdSYong Li 2512bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 251351709ffdSYong Li { 2514bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 251551709ffdSYong Li } 251651709ffdSYong Li 2517bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2518bc1d29deSKrzysztof Grobelny { 2519bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 252051709ffdSYong Li if (action.empty()) 252151709ffdSYong Li { 2522ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2523601af5edSChicago Duan return; 252451709ffdSYong Li } 252551709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 252651709ffdSYong Li } 2527bc1d29deSKrzysztof Grobelny }); 252851709ffdSYong Li } 252951709ffdSYong Li 253051709ffdSYong Li /** 2531c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2532c45f0082SYong Li * 2533ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2534c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2535c45f0082SYong Li * RF request. 2536c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2537c45f0082SYong Li * 2538c45f0082SYong Li * @return None. 2539c45f0082SYong Li */ 2540ac106bf6SEd Tanous inline void 2541ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2542c45f0082SYong Li const std::optional<bool> wdtEnable, 2543c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2544c45f0082SYong Li { 254562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2546c45f0082SYong Li 2547c45f0082SYong Li if (wdtTimeOutAction) 2548c45f0082SYong Li { 2549c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2550c45f0082SYong Li // check if TimeOut Action is Valid 2551c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2552c45f0082SYong Li { 255362598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 255462598e31SEd Tanous *wdtTimeOutAction); 2555ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2556c45f0082SYong Li "TimeoutAction"); 2557c45f0082SYong Li return; 2558c45f0082SYong Li } 2559c45f0082SYong Li 25609ae226faSGeorge Liu sdbusplus::asio::setProperty( 25619ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25629ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25639ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 25649ae226faSGeorge Liu wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) { 2565c45f0082SYong Li if (ec) 2566c45f0082SYong Li { 2567b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2568ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2569c45f0082SYong Li return; 2570c45f0082SYong Li } 25719ae226faSGeorge Liu }); 2572c45f0082SYong Li } 2573c45f0082SYong Li 2574c45f0082SYong Li if (wdtEnable) 2575c45f0082SYong Li { 25769ae226faSGeorge Liu sdbusplus::asio::setProperty( 25779ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 25789ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 25799ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable, 2580ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2581c45f0082SYong Li if (ec) 2582c45f0082SYong Li { 2583b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2584ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2585c45f0082SYong Li return; 2586c45f0082SYong Li } 25879ae226faSGeorge Liu }); 2588c45f0082SYong Li } 2589c45f0082SYong Li } 2590c45f0082SYong Li 259137bbf98cSChris Cain /** 259237bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 259337bbf98cSChris Cain * 2594ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 259537bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 259637bbf98cSChris Cain * 259737bbf98cSChris Cain * @return true if successful 259837bbf98cSChris Cain */ 25991e5b7c88SJiaqing Zhao inline bool 2600ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 26011e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 260237bbf98cSChris Cain { 2603bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2604bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2605bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2606bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2607bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2608bc1d29deSKrzysztof Grobelny 2609bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2610bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 26112661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 26122661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 26132661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2614bc1d29deSKrzysztof Grobelny 2615bc1d29deSKrzysztof Grobelny if (!success) 261637bbf98cSChris Cain { 261737bbf98cSChris Cain return false; 261837bbf98cSChris Cain } 2619bc1d29deSKrzysztof Grobelny 2620bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 262137bbf98cSChris Cain { 2622ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 262337bbf98cSChris Cain } 2624bc1d29deSKrzysztof Grobelny 2625bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 262637bbf98cSChris Cain { 2627ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2628bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 262937bbf98cSChris Cain } 2630bc1d29deSKrzysztof Grobelny 2631bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2632bc1d29deSKrzysztof Grobelny { 2633bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2634ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 263537bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 263637bbf98cSChris Cain .count(); 263737bbf98cSChris Cain } 2638bc1d29deSKrzysztof Grobelny 2639bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 264037bbf98cSChris Cain { 2641ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2642bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 264337bbf98cSChris Cain } 2644bc1d29deSKrzysztof Grobelny 2645bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 264637bbf98cSChris Cain { 2647bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2648ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 264937bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 265037bbf98cSChris Cain .count(); 265137bbf98cSChris Cain } 265237bbf98cSChris Cain 265337bbf98cSChris Cain return true; 265437bbf98cSChris Cain } 265537bbf98cSChris Cain 265637bbf98cSChris Cain /** 265737bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 265837bbf98cSChris Cain * 2659ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 266037bbf98cSChris Cain * 266137bbf98cSChris Cain * @return None. 266237bbf98cSChris Cain */ 2663ac106bf6SEd Tanous inline void 2664ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 266537bbf98cSChris Cain { 266662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 266737bbf98cSChris Cain 266837bbf98cSChris Cain // Get IdlePowerSaver object path: 2669e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2670e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2671e99073f5SGeorge Liu dbus::utility::getSubTree( 2672e99073f5SGeorge Liu "/", 0, interfaces, 2673ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2674b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 267537bbf98cSChris Cain if (ec) 267637bbf98cSChris Cain { 2677b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 267862598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 267962598e31SEd Tanous ec); 2680ac106bf6SEd Tanous messages::internalError(asyncResp->res); 268137bbf98cSChris Cain return; 268237bbf98cSChris Cain } 268337bbf98cSChris Cain if (subtree.empty()) 268437bbf98cSChris Cain { 268537bbf98cSChris Cain // This is an optional interface so just return 268637bbf98cSChris Cain // if there is no instance found 268762598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 268837bbf98cSChris Cain return; 268937bbf98cSChris Cain } 269037bbf98cSChris Cain if (subtree.size() > 1) 269137bbf98cSChris Cain { 269237bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 269337bbf98cSChris Cain // is an error 269462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 269562598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 269662598e31SEd Tanous subtree.size()); 2697ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269837bbf98cSChris Cain return; 269937bbf98cSChris Cain } 270037bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 270137bbf98cSChris Cain { 270262598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2703ac106bf6SEd Tanous messages::internalError(asyncResp->res); 270437bbf98cSChris Cain return; 270537bbf98cSChris Cain } 270637bbf98cSChris Cain const std::string& path = subtree[0].first; 270737bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 270837bbf98cSChris Cain if (service.empty()) 270937bbf98cSChris Cain { 271062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2711ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271237bbf98cSChris Cain return; 271337bbf98cSChris Cain } 271437bbf98cSChris Cain 271537bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2716bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2717bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2718bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2719ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 27201e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 27218a592810SEd Tanous if (ec2) 272237bbf98cSChris Cain { 272362598e31SEd Tanous BMCWEB_LOG_ERROR( 272462598e31SEd Tanous "DBUS response error on IdlePowerSaver GetAll: {}", ec2); 2725ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272637bbf98cSChris Cain return; 272737bbf98cSChris Cain } 272837bbf98cSChris Cain 2729ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 273037bbf98cSChris Cain { 2731ac106bf6SEd Tanous messages::internalError(asyncResp->res); 273237bbf98cSChris Cain return; 273337bbf98cSChris Cain } 2734bc1d29deSKrzysztof Grobelny }); 2735e99073f5SGeorge Liu }); 273637bbf98cSChris Cain 273762598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 273837bbf98cSChris Cain } 273937bbf98cSChris Cain 274037bbf98cSChris Cain /** 274137bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 274237bbf98cSChris Cain * 2743ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 274437bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 274537bbf98cSChris Cain * RF request. 274637bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 274737bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 274837bbf98cSChris Cain * before entering idle state. 274937bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 275037bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 275137bbf98cSChris Cain * before exiting idle state 275237bbf98cSChris Cain * 275337bbf98cSChris Cain * @return None. 275437bbf98cSChris Cain */ 2755ac106bf6SEd Tanous inline void 2756ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 275737bbf98cSChris Cain const std::optional<bool> ipsEnable, 275837bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 275937bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 276037bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 276137bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 276237bbf98cSChris Cain { 276362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 276437bbf98cSChris Cain 276537bbf98cSChris Cain // Get IdlePowerSaver object path: 2766e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2767e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2768e99073f5SGeorge Liu dbus::utility::getSubTree( 2769e99073f5SGeorge Liu "/", 0, interfaces, 2770ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2771e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2772b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 277337bbf98cSChris Cain if (ec) 277437bbf98cSChris Cain { 2775b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 277662598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 277762598e31SEd Tanous ec); 2778ac106bf6SEd Tanous messages::internalError(asyncResp->res); 277937bbf98cSChris Cain return; 278037bbf98cSChris Cain } 278137bbf98cSChris Cain if (subtree.empty()) 278237bbf98cSChris Cain { 278337bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2784ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 278537bbf98cSChris Cain "IdlePowerSaver"); 278637bbf98cSChris Cain return; 278737bbf98cSChris Cain } 278837bbf98cSChris Cain if (subtree.size() > 1) 278937bbf98cSChris Cain { 279037bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 279137bbf98cSChris Cain // is an error 279262598e31SEd Tanous BMCWEB_LOG_DEBUG( 279362598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 279462598e31SEd Tanous subtree.size()); 2795ac106bf6SEd Tanous messages::internalError(asyncResp->res); 279637bbf98cSChris Cain return; 279737bbf98cSChris Cain } 279837bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 279937bbf98cSChris Cain { 280062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2801ac106bf6SEd Tanous messages::internalError(asyncResp->res); 280237bbf98cSChris Cain return; 280337bbf98cSChris Cain } 280437bbf98cSChris Cain const std::string& path = subtree[0].first; 280537bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 280637bbf98cSChris Cain if (service.empty()) 280737bbf98cSChris Cain { 280862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2809ac106bf6SEd Tanous messages::internalError(asyncResp->res); 281037bbf98cSChris Cain return; 281137bbf98cSChris Cain } 281237bbf98cSChris Cain 281337bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 281437bbf98cSChris Cain // need to be updated 281537bbf98cSChris Cain 281637bbf98cSChris Cain if (ipsEnable) 281737bbf98cSChris Cain { 28189ae226faSGeorge Liu sdbusplus::asio::setProperty( 28199ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28209ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 28219ae226faSGeorge Liu *ipsEnable, [asyncResp](const boost::system::error_code& ec2) { 28228a592810SEd Tanous if (ec2) 282337bbf98cSChris Cain { 2824b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2825ac106bf6SEd Tanous messages::internalError(asyncResp->res); 282637bbf98cSChris Cain return; 282737bbf98cSChris Cain } 28289ae226faSGeorge Liu }); 282937bbf98cSChris Cain } 283037bbf98cSChris Cain if (ipsEnterUtil) 283137bbf98cSChris Cain { 28329ae226faSGeorge Liu sdbusplus::asio::setProperty( 28339ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28349ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28359ae226faSGeorge Liu "EnterUtilizationPercent", *ipsEnterUtil, 2836ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28378a592810SEd Tanous if (ec2) 283837bbf98cSChris Cain { 2839b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2840ac106bf6SEd Tanous messages::internalError(asyncResp->res); 284137bbf98cSChris Cain return; 284237bbf98cSChris Cain } 28439ae226faSGeorge Liu }); 284437bbf98cSChris Cain } 284537bbf98cSChris Cain if (ipsEnterTime) 284637bbf98cSChris Cain { 284737bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 284837bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 28499ae226faSGeorge Liu sdbusplus::asio::setProperty( 28509ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28519ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28529ae226faSGeorge Liu "EnterDwellTime", timeMilliseconds, 2853ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28548a592810SEd Tanous if (ec2) 285537bbf98cSChris Cain { 2856b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2857ac106bf6SEd Tanous messages::internalError(asyncResp->res); 285837bbf98cSChris Cain return; 285937bbf98cSChris Cain } 28609ae226faSGeorge Liu }); 286137bbf98cSChris Cain } 286237bbf98cSChris Cain if (ipsExitUtil) 286337bbf98cSChris Cain { 28649ae226faSGeorge Liu sdbusplus::asio::setProperty( 28659ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28669ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28679ae226faSGeorge Liu "ExitUtilizationPercent", *ipsExitUtil, 2868ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28698a592810SEd Tanous if (ec2) 287037bbf98cSChris Cain { 2871b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2872ac106bf6SEd Tanous messages::internalError(asyncResp->res); 287337bbf98cSChris Cain return; 287437bbf98cSChris Cain } 28759ae226faSGeorge Liu }); 287637bbf98cSChris Cain } 287737bbf98cSChris Cain if (ipsExitTime) 287837bbf98cSChris Cain { 287937bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 288037bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 28819ae226faSGeorge Liu sdbusplus::asio::setProperty( 28829ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28839ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 28849ae226faSGeorge Liu "ExitDwellTime", timeMilliseconds, 2885ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 28868a592810SEd Tanous if (ec2) 288737bbf98cSChris Cain { 2888b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2889ac106bf6SEd Tanous messages::internalError(asyncResp->res); 289037bbf98cSChris Cain return; 289137bbf98cSChris Cain } 28929ae226faSGeorge Liu }); 289337bbf98cSChris Cain } 2894e99073f5SGeorge Liu }); 289537bbf98cSChris Cain 289662598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 289737bbf98cSChris Cain } 289837bbf98cSChris Cain 2899c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2900dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2901dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2902dd60b9edSEd Tanous { 2903dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2904dd60b9edSEd Tanous { 2905dd60b9edSEd Tanous return; 2906dd60b9edSEd Tanous } 2907dd60b9edSEd Tanous asyncResp->res.addHeader( 2908dd60b9edSEd Tanous boost::beast::http::field::link, 2909dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2910dd60b9edSEd Tanous } 2911dd60b9edSEd Tanous 2912c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2913c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2914c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29151abe55efSEd Tanous { 29163ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2917f4c99e70SEd Tanous { 2918f4c99e70SEd Tanous return; 2919f4c99e70SEd Tanous } 2920dd60b9edSEd Tanous 2921dd60b9edSEd Tanous asyncResp->res.addHeader( 2922dd60b9edSEd Tanous boost::beast::http::field::link, 2923dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 29248d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 29250f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 29268d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 29278d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2928462023adSSunitha Harish 29297f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 29307f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 29317f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 29327f3e84a1SEd Tanous { 29337f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 29347f3e84a1SEd Tanous // Option currently returns no systems. TBD 29357f3e84a1SEd Tanous return; 29367f3e84a1SEd Tanous } 29377f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 29387f3e84a1SEd Tanous nlohmann::json::object_t system; 29397f3e84a1SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 29407f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 29411e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2942002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 29431e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2944002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 29455e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 29461e1e598dSJonathan Doman const std::string& /*hostName*/) { 29477f3e84a1SEd Tanous if (ec2) 2948462023adSSunitha Harish { 29497f3e84a1SEd Tanous return; 29507f3e84a1SEd Tanous } 29517f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 29527f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 29537f3e84a1SEd Tanous { 295462598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 29557f3e84a1SEd Tanous return; 29567f3e84a1SEd Tanous } 29577f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 29587f3e84a1SEd Tanous if (count == nullptr) 29597f3e84a1SEd Tanous { 296062598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 29617f3e84a1SEd Tanous return; 29627f3e84a1SEd Tanous } 29637f3e84a1SEd Tanous *count = *count + 1; 296462598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 29657f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 29661476687dSEd Tanous nlohmann::json::object_t hypervisor; 2967002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 29687f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 29691e1e598dSJonathan Doman }); 2970c1e219d5SEd Tanous } 2971c1e219d5SEd Tanous 2972c1e219d5SEd Tanous /** 29737e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 29747e860f15SJohn Edward Broadbent */ 29754f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29767e860f15SJohn Edward Broadbent { 297789492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 297889492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 297989492a15SPatrick Williams constexpr const char* interfaceName = 29807e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 298189492a15SPatrick Williams constexpr const char* method = "NMI"; 29827e860f15SJohn Edward Broadbent 29837e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 29845e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 29857e860f15SJohn Edward Broadbent if (ec) 29867e860f15SJohn Edward Broadbent { 298762598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 29887e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 29897e860f15SJohn Edward Broadbent return; 29907e860f15SJohn Edward Broadbent } 29917e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 29927e860f15SJohn Edward Broadbent }, 29937e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 29947e860f15SJohn Edward Broadbent } 2995c5b2abe0SLewanczyk, Dawid 2996c5b2abe0SLewanczyk, Dawid /** 2997fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 2998fc903b3dSAndrew Geissler */ 2999fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 3000fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 3001fc903b3dSAndrew Geissler std::string_view resetType, 3002fc903b3dSAndrew Geissler crow::Response& res) 3003fc903b3dSAndrew Geissler { 3004fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 3005fc903b3dSAndrew Geissler { 3006fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 3007fc903b3dSAndrew Geissler return; 3008fc903b3dSAndrew Geissler } 3009fc903b3dSAndrew Geissler 3010fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 3011fc903b3dSAndrew Geissler { 301262598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error: {}", ec); 3013fc903b3dSAndrew Geissler messages::internalError(res); 3014fc903b3dSAndrew Geissler return; 3015fc903b3dSAndrew Geissler } 3016fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 3017fc903b3dSAndrew Geissler 3018fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 3019fc903b3dSAndrew Geissler // user to retry in a bit 3020fc903b3dSAndrew Geissler if ((errorMessage == 3021fc903b3dSAndrew Geissler std::string_view( 3022fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 3023fc903b3dSAndrew Geissler (errorMessage == 3024fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 3025fc903b3dSAndrew Geissler { 302662598e31SEd Tanous BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now"); 3027fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 3028fc903b3dSAndrew Geissler return; 3029fc903b3dSAndrew Geissler } 3030fc903b3dSAndrew Geissler 303162598e31SEd Tanous BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec, 303262598e31SEd Tanous errorMessage); 3033fc903b3dSAndrew Geissler messages::internalError(res); 3034fc903b3dSAndrew Geissler } 3035fc903b3dSAndrew Geissler 3036c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 3037c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 30387f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3039c1e219d5SEd Tanous const std::string& systemName) 3040c1e219d5SEd Tanous { 30413ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 304245ca1b86SEd Tanous { 304345ca1b86SEd Tanous return; 304445ca1b86SEd Tanous } 3045c1e219d5SEd Tanous if (systemName != "system") 3046c1e219d5SEd Tanous { 3047c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3048c1e219d5SEd Tanous systemName); 3049c1e219d5SEd Tanous return; 3050c1e219d5SEd Tanous } 30517f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 30527f3e84a1SEd Tanous { 30537f3e84a1SEd Tanous // Option currently returns no systems. TBD 30547f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3055c1e219d5SEd Tanous systemName); 30567f3e84a1SEd Tanous return; 30577f3e84a1SEd Tanous } 30589712f8acSEd Tanous std::string resetType; 3059c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 3060cc340dd9SEd Tanous { 3061cc340dd9SEd Tanous return; 3062cc340dd9SEd Tanous } 3063cc340dd9SEd Tanous 3064d22c8396SJason M. Bills // Get the command and host vs. chassis 3065cc340dd9SEd Tanous std::string command; 3066543f4400SEd Tanous bool hostCommand = true; 3067d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 3068cc340dd9SEd Tanous { 3069cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 3070d22c8396SJason M. Bills hostCommand = true; 3071d22c8396SJason M. Bills } 3072d22c8396SJason M. Bills else if (resetType == "ForceOff") 3073d22c8396SJason M. Bills { 3074d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 3075d22c8396SJason M. Bills hostCommand = false; 3076d22c8396SJason M. Bills } 3077d22c8396SJason M. Bills else if (resetType == "ForceRestart") 3078d22c8396SJason M. Bills { 3079c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 308086a0851aSJason M. Bills hostCommand = true; 3081cc340dd9SEd Tanous } 30829712f8acSEd Tanous else if (resetType == "GracefulShutdown") 3083cc340dd9SEd Tanous { 3084cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 3085d22c8396SJason M. Bills hostCommand = true; 3086cc340dd9SEd Tanous } 30879712f8acSEd Tanous else if (resetType == "GracefulRestart") 3088cc340dd9SEd Tanous { 30890fda0f12SGeorge Liu command = 30900fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 3091d22c8396SJason M. Bills hostCommand = true; 3092d22c8396SJason M. Bills } 3093d22c8396SJason M. Bills else if (resetType == "PowerCycle") 3094d22c8396SJason M. Bills { 309586a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 309686a0851aSJason M. Bills hostCommand = true; 3097cc340dd9SEd Tanous } 3098bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 3099bfd5b826SLakshminarayana R. Kammath { 3100bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 3101bfd5b826SLakshminarayana R. Kammath return; 3102bfd5b826SLakshminarayana R. Kammath } 3103cc340dd9SEd Tanous else 3104cc340dd9SEd Tanous { 3105c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 3106cc340dd9SEd Tanous return; 3107cc340dd9SEd Tanous } 3108cc340dd9SEd Tanous 3109d22c8396SJason M. Bills if (hostCommand) 3110d22c8396SJason M. Bills { 31119ae226faSGeorge Liu sdbusplus::asio::setProperty( 31129ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 31139ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 31149ae226faSGeorge Liu "xyz.openbmc_project.State.Host", "RequestedHostTransition", 31159ae226faSGeorge Liu command, 3116fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3117fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3118cc340dd9SEd Tanous if (ec) 3119cc340dd9SEd Tanous { 3120fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3121fc903b3dSAndrew Geissler asyncResp->res); 3122fc903b3dSAndrew Geissler 3123cc340dd9SEd Tanous return; 3124cc340dd9SEd Tanous } 3125f12894f8SJason M. Bills messages::success(asyncResp->res); 31269ae226faSGeorge Liu }); 3127cc340dd9SEd Tanous } 3128d22c8396SJason M. Bills else 3129d22c8396SJason M. Bills { 31309ae226faSGeorge Liu sdbusplus::asio::setProperty( 31319ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 31329ae226faSGeorge Liu "/xyz/openbmc_project/state/chassis0", 31339ae226faSGeorge Liu "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 31349ae226faSGeorge Liu command, 3135fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3136fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3137d22c8396SJason M. Bills if (ec) 3138d22c8396SJason M. Bills { 3139fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3140fc903b3dSAndrew Geissler asyncResp->res); 3141d22c8396SJason M. Bills return; 3142d22c8396SJason M. Bills } 3143d22c8396SJason M. Bills messages::success(asyncResp->res); 31449ae226faSGeorge Liu }); 3145d22c8396SJason M. Bills } 3146d22c8396SJason M. Bills } 3147cc340dd9SEd Tanous 3148c1e219d5SEd Tanous inline void handleComputerSystemHead( 3149dd60b9edSEd Tanous App& app, const crow::Request& req, 31507f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31517f3e84a1SEd Tanous const std::string& /*systemName*/) 3152dd60b9edSEd Tanous { 3153dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3154dd60b9edSEd Tanous { 3155dd60b9edSEd Tanous return; 3156dd60b9edSEd Tanous } 3157dd60b9edSEd Tanous 3158dd60b9edSEd Tanous asyncResp->res.addHeader( 3159dd60b9edSEd Tanous boost::beast::http::field::link, 3160dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3161dd60b9edSEd Tanous } 3162dd60b9edSEd Tanous 31635c3e9272SAbhishek Patel inline void afterPortRequest( 31645c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31655c3e9272SAbhishek Patel const boost::system::error_code& ec, 31665c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 31675c3e9272SAbhishek Patel { 31685c3e9272SAbhishek Patel if (ec) 31695c3e9272SAbhishek Patel { 3170b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 31715c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31725c3e9272SAbhishek Patel return; 31735c3e9272SAbhishek Patel } 31745c3e9272SAbhishek Patel for (const auto& data : socketData) 31755c3e9272SAbhishek Patel { 31765c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 31775c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 31785c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 31795c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 31805c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 31815c3e9272SAbhishek Patel // need to retrieve port number for 31825c3e9272SAbhishek Patel // obmc-console-ssh service 31835c3e9272SAbhishek Patel if (protocolName == "SSH") 31845c3e9272SAbhishek Patel { 31855c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 318681c4e330SEd Tanous const boost::system::error_code& ec1, 31875c3e9272SAbhishek Patel int portNumber) { 31885c3e9272SAbhishek Patel if (ec1) 31895c3e9272SAbhishek Patel { 3190b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 31915c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 31925c3e9272SAbhishek Patel return; 31935c3e9272SAbhishek Patel } 31945c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 31955c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 31965c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 31975c3e9272SAbhishek Patel }); 31985c3e9272SAbhishek Patel } 31995c3e9272SAbhishek Patel } 32005c3e9272SAbhishek Patel } 3201c1e219d5SEd Tanous 3202c1e219d5SEd Tanous inline void 3203c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 320422d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3205c1e219d5SEd Tanous const std::string& systemName) 3206c1e219d5SEd Tanous { 32073ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 320845ca1b86SEd Tanous { 320945ca1b86SEd Tanous return; 321045ca1b86SEd Tanous } 3211746b56f3SAsmitha Karunanithi 32127f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 32137f3e84a1SEd Tanous { 32147f3e84a1SEd Tanous // Option currently returns no systems. TBD 32157f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 32167f3e84a1SEd Tanous systemName); 32177f3e84a1SEd Tanous return; 32187f3e84a1SEd Tanous } 32197f3e84a1SEd Tanous 3220746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3221746b56f3SAsmitha Karunanithi { 3222746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3223746b56f3SAsmitha Karunanithi return; 3224746b56f3SAsmitha Karunanithi } 3225746b56f3SAsmitha Karunanithi 322622d268cbSEd Tanous if (systemName != "system") 322722d268cbSEd Tanous { 322822d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 322922d268cbSEd Tanous systemName); 323022d268cbSEd Tanous return; 323122d268cbSEd Tanous } 3232dd60b9edSEd Tanous asyncResp->res.addHeader( 3233dd60b9edSEd Tanous boost::beast::http::field::link, 3234dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 32358d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 323637bbf98cSChris Cain "#ComputerSystem.v1_16_0.ComputerSystem"; 32378d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 32388d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 32398d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 32408d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 32418d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 32425fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 32435fd0aafbSNinad Palsule { 32448d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 32458d1b46d7Szhanghch05 "Disabled"; 32468d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 32478d1b46d7Szhanghch05 "Disabled"; 32485fd0aafbSNinad Palsule } 3249cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3250dfb2b408SPriyanga Ramasamy double(0); 3251002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 325204a258f4SEd Tanous 32531476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 32541476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 32551476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 32561476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 32571476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 32581476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 32593179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 32603179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3261029573d4SEd Tanous 3262002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 32631476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 3264c1e219d5SEd Tanous asyncResp->res 3265c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 32661476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3267c5b2abe0SLewanczyk, Dawid 32681476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 32691476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 32701476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 32711476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3272c4bf6374SJason M. Bills 32731476687dSEd Tanous nlohmann::json::array_t managedBy; 32741476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 32751476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3276002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 32771476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 32781476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 32790e8ac5e7SGunnar Mills 32800e8ac5e7SGunnar Mills // Fill in SerialConsole info 3281002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3282c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 32831476687dSEd Tanous 3284c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 32851476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3286c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 32871476687dSEd Tanous "Press ~. to exit console"; 32885c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 32895c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 32900e8ac5e7SGunnar Mills 32910e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 32920e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3293002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3294c1e219d5SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4; 3295613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3296613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 32971476687dSEd Tanous 32980e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 329913451e39SWilly Tu 330013451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 330113451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 330213451e39SWilly Tu { 33037a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3304b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 33052ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3306e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3307e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3308b49ac873SJames Feist 33097a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 33107a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 33117a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3312914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3313b49ac873SJames Feist if (ec) 3314b49ac873SJames Feist { 3315b49ac873SJames Feist // no inventory 3316b49ac873SJames Feist return; 3317b49ac873SJames Feist } 3318b49ac873SJames Feist 3319914e2d5dSEd Tanous health->inventory = resp; 33207a1dbc48SGeorge Liu }); 3321b49ac873SJames Feist health->populate(); 332213451e39SWilly Tu } 3323b49ac873SJames Feist 3324002d39b4SEd Tanous getMainChassisId(asyncResp, 3325002d39b4SEd Tanous [](const std::string& chassisId, 33268d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3327b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3328b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3329ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3330ef4c65b7SEd Tanous chassisId); 3331002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3332c5d03ff4SJennifer Lee }); 3333a3002228SAppaRao Puli 333459a17e4fSGeorge Liu getSystemLocationIndicatorActive(asyncResp); 33359f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3336a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 33375bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 33386c34de48SEd Tanous getHostState(asyncResp); 3339491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3340978b8803SAndrew Geissler getBootProgress(asyncResp); 3341b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 3342*70c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 3343*70c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 334451709ffdSYong Li getHostWatchdogTimer(asyncResp); 3345c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 33469dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3347797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3348c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3349a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3350a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3351a6349918SAppaRao Puli #endif 33521981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 33533a2d0424SChris Cain getPowerMode(asyncResp); 335437bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3355c1e219d5SEd Tanous } 3356550a6bf8SJiaqing Zhao 3357c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3358c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 335922d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3360c1e219d5SEd Tanous const std::string& systemName) 3361c1e219d5SEd Tanous { 33623ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 336345ca1b86SEd Tanous { 336445ca1b86SEd Tanous return; 336545ca1b86SEd Tanous } 33667f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 33677f3e84a1SEd Tanous { 33687f3e84a1SEd Tanous // Option currently returns no systems. TBD 33697f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 33707f3e84a1SEd Tanous systemName); 33717f3e84a1SEd Tanous return; 33727f3e84a1SEd Tanous } 337322d268cbSEd Tanous if (systemName != "system") 337422d268cbSEd Tanous { 337522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 337622d268cbSEd Tanous systemName); 337722d268cbSEd Tanous return; 337822d268cbSEd Tanous } 337922d268cbSEd Tanous 3380dd60b9edSEd Tanous asyncResp->res.addHeader( 3381dd60b9edSEd Tanous boost::beast::http::field::link, 3382dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3383dd60b9edSEd Tanous 33849f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3385cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 338698e386ecSGunnar Mills std::optional<std::string> assetTag; 3387c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 33883a2d0424SChris Cain std::optional<std::string> powerMode; 3389550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3390550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3391550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3392550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3393550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3394550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3395797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3396550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 33979dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3398550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3399550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3400550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3401550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3402550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3403550a6bf8SJiaqing Zhao 3404550a6bf8SJiaqing Zhao // clang-format off 340515ed6780SWilly Tu if (!json_util::readJsonPatch( 3406550a6bf8SJiaqing Zhao req, asyncResp->res, 3407550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 34087e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3409550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3410550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3411550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3412550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3413550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3414550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3415550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3416550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3417550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3418797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3419550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 34209dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3421550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3422550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3423550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3424550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3425550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 34266617338dSEd Tanous { 34276617338dSEd Tanous return; 34286617338dSEd Tanous } 3429550a6bf8SJiaqing Zhao // clang-format on 3430491d8ee7SSantosh Puranik 34318d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3432c45f0082SYong Li 343398e386ecSGunnar Mills if (assetTag) 343498e386ecSGunnar Mills { 343598e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 343698e386ecSGunnar Mills } 343798e386ecSGunnar Mills 3438550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3439c45f0082SYong Li { 3440f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3441c45f0082SYong Li } 3442c45f0082SYong Li 3443cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 344469f35306SGunnar Mills { 3445002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3446491d8ee7SSantosh Puranik } 3447550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 344869f35306SGunnar Mills { 3449550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 345069f35306SGunnar Mills } 3451ac7e1e0bSAli Ahmed 3452797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3453797d5daeSCorey Hardesty { 3454797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3455797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3456797d5daeSCorey Hardesty } 3457797d5daeSCorey Hardesty 3458550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3459ac7e1e0bSAli Ahmed { 3460c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 346169f35306SGunnar Mills } 3462265c1602SJohnathan Mantey 34639dcfe8c1SAlbert Zhang if (stopBootOnFault) 34649dcfe8c1SAlbert Zhang { 34659dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 34669dcfe8c1SAlbert Zhang } 34679dcfe8c1SAlbert Zhang 34689f8bfa7cSGunnar Mills if (locationIndicatorActive) 34699f8bfa7cSGunnar Mills { 347059a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 34719f8bfa7cSGunnar Mills } 34729f8bfa7cSGunnar Mills 34737e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 34747e860f15SJohn Edward Broadbent // passed 34759712f8acSEd Tanous if (indicatorLed) 34766617338dSEd Tanous { 3477f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3478002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3479d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3480d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 34816617338dSEd Tanous } 3482c6a620f2SGeorge Liu 3483c6a620f2SGeorge Liu if (powerRestorePolicy) 3484c6a620f2SGeorge Liu { 34854e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3486c6a620f2SGeorge Liu } 34873a2d0424SChris Cain 34883a2d0424SChris Cain if (powerMode) 34893a2d0424SChris Cain { 34903a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 34913a2d0424SChris Cain } 349237bbf98cSChris Cain 3493c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 349437bbf98cSChris Cain { 3495002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3496002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 349737bbf98cSChris Cain } 3498c1e219d5SEd Tanous } 34991cb1a9e6SAppaRao Puli 350038c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3501dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 35027f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3503c1e219d5SEd Tanous const std::string& /*systemName*/) 3504dd60b9edSEd Tanous { 3505dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3506dd60b9edSEd Tanous { 3507dd60b9edSEd Tanous return; 3508dd60b9edSEd Tanous } 3509dd60b9edSEd Tanous asyncResp->res.addHeader( 3510dd60b9edSEd Tanous boost::beast::http::field::link, 3511dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3512dd60b9edSEd Tanous } 3513c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3514c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 351522d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3516c1e219d5SEd Tanous const std::string& systemName) 3517c1e219d5SEd Tanous { 35183ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 351945ca1b86SEd Tanous { 352045ca1b86SEd Tanous return; 352145ca1b86SEd Tanous } 35227f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 35237f3e84a1SEd Tanous { 35247f3e84a1SEd Tanous // Option currently returns no systems. TBD 35257f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 35267f3e84a1SEd Tanous systemName); 35277f3e84a1SEd Tanous return; 35287f3e84a1SEd Tanous } 3529746b56f3SAsmitha Karunanithi 3530746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3531746b56f3SAsmitha Karunanithi { 3532746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3533746b56f3SAsmitha Karunanithi return; 3534746b56f3SAsmitha Karunanithi } 3535746b56f3SAsmitha Karunanithi 353622d268cbSEd Tanous if (systemName != "system") 353722d268cbSEd Tanous { 353822d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 353922d268cbSEd Tanous systemName); 354022d268cbSEd Tanous return; 354122d268cbSEd Tanous } 354222d268cbSEd Tanous 3543dd60b9edSEd Tanous asyncResp->res.addHeader( 3544dd60b9edSEd Tanous boost::beast::http::field::link, 3545dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 35461476687dSEd Tanous 35471476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 35481476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3549c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 35501476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 35511476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 35523215e700SNan Zhou 35533215e700SNan Zhou nlohmann::json::array_t parameters; 35543215e700SNan Zhou nlohmann::json::object_t parameter; 35553215e700SNan Zhou 35563215e700SNan Zhou parameter["Name"] = "ResetType"; 35573215e700SNan Zhou parameter["Required"] = true; 35583215e700SNan Zhou parameter["DataType"] = "String"; 35593215e700SNan Zhou nlohmann::json::array_t allowableValues; 35603215e700SNan Zhou allowableValues.emplace_back("On"); 35613215e700SNan Zhou allowableValues.emplace_back("ForceOff"); 35623215e700SNan Zhou allowableValues.emplace_back("ForceOn"); 35633215e700SNan Zhou allowableValues.emplace_back("ForceRestart"); 35643215e700SNan Zhou allowableValues.emplace_back("GracefulRestart"); 35653215e700SNan Zhou allowableValues.emplace_back("GracefulShutdown"); 35663215e700SNan Zhou allowableValues.emplace_back("PowerCycle"); 35673215e700SNan Zhou allowableValues.emplace_back("Nmi"); 35683215e700SNan Zhou parameter["AllowableValues"] = std::move(allowableValues); 35693215e700SNan Zhou parameters.emplace_back(std::move(parameter)); 35703215e700SNan Zhou 35713215e700SNan Zhou asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 3572c1e219d5SEd Tanous } 3573c1e219d5SEd Tanous /** 3574c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3575c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3576c1e219d5SEd Tanous */ 3577100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3578c1e219d5SEd Tanous { 3579100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3580100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3581100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3582100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3583100afe56SEd Tanous 3584100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3585100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3586100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3587100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3588100afe56SEd Tanous 3589100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3590100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3591100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3592100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3593100afe56SEd Tanous 3594100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3595100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3596100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3597100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3598100afe56SEd Tanous 3599100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3600100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3601100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3602100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3603100afe56SEd Tanous 3604100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3605100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3606100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3607100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3608100afe56SEd Tanous 3609c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3610c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3611c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3612c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3613c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3614c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3615c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3616c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 36171cb1a9e6SAppaRao Puli } 3618c5b2abe0SLewanczyk, Dawid } // namespace redfish 3619