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" 2433e1f122SAndrew Geissler #include "generated/enums/resource.hpp" 25b49ac873SJames Feist #include "health.hpp" 26746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 271c8fba97SJames Feist #include "led.hpp" 28f4c99e70SEd Tanous #include "query.hpp" 29c5d03ff4SJennifer Lee #include "redfish_util.hpp" 303ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 313ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 323ccb3adbSEd Tanous #include "utils/json_utils.hpp" 33472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 343ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 352b82937eSEd Tanous #include "utils/time_utils.hpp" 36c5d03ff4SJennifer Lee 37fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 389712f8acSEd Tanous #include <boost/container/flat_map.hpp> 39e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 4033e1f122SAndrew Geissler #include <boost/system/linux_error.hpp> 41ef4c65b7SEd Tanous #include <boost/url/format.hpp> 42b6655101SChris Cain #include <generated/enums/computer_system.hpp> 431e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 44fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp> 45bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 461214b7e7SGunnar Mills 477a1dbc48SGeorge Liu #include <array> 4833e1f122SAndrew Geissler #include <memory> 496b9ac4f2SChris Cain #include <string> 507a1dbc48SGeorge Liu #include <string_view> 51abf2add6SEd Tanous #include <variant> 526b9ac4f2SChris Cain #include <vector> 53c5b2abe0SLewanczyk, Dawid 541abe55efSEd Tanous namespace redfish 551abe55efSEd Tanous { 56c5b2abe0SLewanczyk, Dawid 575c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 585c3e9272SAbhishek Patel protocolToDBusForSystems{ 595c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 605c3e9272SAbhishek Patel 619d3ae10eSAlpana Kumari /** 629d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 639d3ae10eSAlpana Kumari * 64ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 659d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 669d3ae10eSAlpana Kumari * 679d3ae10eSAlpana Kumari * @return None. 689d3ae10eSAlpana Kumari */ 698d1b46d7Szhanghch05 inline void 70ac106bf6SEd Tanous updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 711e1e598dSJonathan Doman bool isDimmFunctional) 729d3ae10eSAlpana Kumari { 7362598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 749d3ae10eSAlpana Kumari 759d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 769d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 779d3ae10eSAlpana Kumari // ENABLED. 7802cad96eSEd Tanous const nlohmann::json& prevMemSummary = 79ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 809d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 819d3ae10eSAlpana Kumari { 82e05aec50SEd Tanous if (isDimmFunctional) 839d3ae10eSAlpana Kumari { 84ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 859d3ae10eSAlpana Kumari "Enabled"; 869d3ae10eSAlpana Kumari } 879d3ae10eSAlpana Kumari } 889d3ae10eSAlpana Kumari } 899d3ae10eSAlpana Kumari 9057e8c9beSAlpana Kumari /* 9157e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 9257e8c9beSAlpana Kumari * CPU Functional State 9357e8c9beSAlpana Kumari * 94ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 9557e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9657e8c9beSAlpana Kumari * 9757e8c9beSAlpana Kumari * @return None. 9857e8c9beSAlpana Kumari */ 99ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 100ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 10157e8c9beSAlpana Kumari { 10262598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 10357e8c9beSAlpana Kumari 10402cad96eSEd Tanous const nlohmann::json& prevProcState = 105ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10657e8c9beSAlpana Kumari 10757e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10857e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 10957e8c9beSAlpana Kumari // Functional. 11057e8c9beSAlpana Kumari if (prevProcState == "Disabled") 11157e8c9beSAlpana Kumari { 112e05aec50SEd Tanous if (isCpuFunctional) 11357e8c9beSAlpana Kumari { 114ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 11557e8c9beSAlpana Kumari "Enabled"; 11657e8c9beSAlpana Kumari } 11757e8c9beSAlpana Kumari } 11857e8c9beSAlpana Kumari } 11957e8c9beSAlpana Kumari 120cf0e004cSNinad Palsule /* 121cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 122cf0e004cSNinad Palsule * 123ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 124cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 125cf0e004cSNinad Palsule * 126cf0e004cSNinad Palsule * @return None. 127cf0e004cSNinad Palsule */ 128cf0e004cSNinad Palsule inline void 129ac106bf6SEd Tanous modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 130cf0e004cSNinad Palsule bool isCpuPresent) 131cf0e004cSNinad Palsule { 13262598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 133cf0e004cSNinad Palsule 134cf0e004cSNinad Palsule if (isCpuPresent) 135cf0e004cSNinad Palsule { 136cf0e004cSNinad Palsule nlohmann::json& procCount = 137ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 138cf0e004cSNinad Palsule auto* procCountPtr = 139cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 140cf0e004cSNinad Palsule if (procCountPtr != nullptr) 141cf0e004cSNinad Palsule { 142cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 143cf0e004cSNinad Palsule *procCountPtr += 1; 144cf0e004cSNinad Palsule } 145cf0e004cSNinad Palsule } 146cf0e004cSNinad Palsule } 147cf0e004cSNinad Palsule 148382d6475SAli Ahmed inline void getProcessorProperties( 149ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 150382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 151382d6475SAli Ahmed properties) 15203fbed92SAli Ahmed { 15362598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 15403fbed92SAli Ahmed 15503fbed92SAli Ahmed // TODO: Get Model 15603fbed92SAli Ahmed 157bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15803fbed92SAli Ahmed 159bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 160bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 16103fbed92SAli Ahmed 162bc1d29deSKrzysztof Grobelny if (!success) 16303fbed92SAli Ahmed { 164ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16503fbed92SAli Ahmed return; 16603fbed92SAli Ahmed } 16703fbed92SAli Ahmed 168bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 16903fbed92SAli Ahmed { 170bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 171ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 172bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 173bc1d29deSKrzysztof Grobelny 174bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 175bc1d29deSKrzysztof Grobelny { 176bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17703fbed92SAli Ahmed } 17803fbed92SAli Ahmed else 17903fbed92SAli Ahmed { 180bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 18103fbed92SAli Ahmed } 18203fbed92SAli Ahmed } 18303fbed92SAli Ahmed } 18403fbed92SAli Ahmed 18503fbed92SAli Ahmed /* 18603fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18703fbed92SAli Ahmed * 188ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 18903fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 19003fbed92SAli Ahmed * @param[in] path dbus path for Cpu 19103fbed92SAli Ahmed * 19203fbed92SAli Ahmed * @return None. 19303fbed92SAli Ahmed */ 194ac106bf6SEd Tanous inline void 195ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 196ac106bf6SEd Tanous const std::string& service, const std::string& path) 19703fbed92SAli Ahmed { 198ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 199382d6475SAli Ahmed const bool cpuPresenceCheck) { 200382d6475SAli Ahmed if (ec3) 201382d6475SAli Ahmed { 20262598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 203382d6475SAli Ahmed return; 204382d6475SAli Ahmed } 205ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 206382d6475SAli Ahmed }; 207382d6475SAli Ahmed 208cf0e004cSNinad Palsule // Get the Presence of CPU 209cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 210cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 211cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 212cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 213cf0e004cSNinad Palsule 2145fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2155fd0aafbSNinad Palsule { 2165fd0aafbSNinad Palsule auto getCpuFunctionalState = 217ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 218382d6475SAli Ahmed const bool cpuFunctionalCheck) { 219382d6475SAli Ahmed if (ec3) 220382d6475SAli Ahmed { 22162598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 222382d6475SAli Ahmed return; 223382d6475SAli Ahmed } 224ac106bf6SEd Tanous modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck); 225382d6475SAli Ahmed }; 226382d6475SAli Ahmed 227382d6475SAli Ahmed // Get the Functional State 228382d6475SAli Ahmed sdbusplus::asio::getProperty<bool>( 229382d6475SAli Ahmed *crow::connections::systemBus, service, path, 2305fd0aafbSNinad Palsule "xyz.openbmc_project.State.Decorator.OperationalStatus", 2315fd0aafbSNinad Palsule "Functional", std::move(getCpuFunctionalState)); 2325fd0aafbSNinad Palsule } 233382d6475SAli Ahmed 234bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 235bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 236bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 237ac106bf6SEd Tanous [asyncResp, service, 2385e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 239b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 24003fbed92SAli Ahmed if (ec2) 24103fbed92SAli Ahmed { 24262598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 243ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24403fbed92SAli Ahmed return; 24503fbed92SAli Ahmed } 246ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 247bc1d29deSKrzysztof Grobelny }); 24803fbed92SAli Ahmed } 24903fbed92SAli Ahmed 25057e8c9beSAlpana Kumari /* 251cf0e004cSNinad Palsule * @brief processMemoryProperties fields 252cf0e004cSNinad Palsule * 253ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 254cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 255cf0e004cSNinad Palsule * @param[in] path dbus path for Memory 256cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 257cf0e004cSNinad Palsule * 258cf0e004cSNinad Palsule * @return None. 259cf0e004cSNinad Palsule */ 260cf0e004cSNinad Palsule inline void 261ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2625fd0aafbSNinad Palsule [[maybe_unused]] const std::string& service, 2635fd0aafbSNinad Palsule [[maybe_unused]] const std::string& path, 264cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 265cf0e004cSNinad Palsule { 26662598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 267cf0e004cSNinad Palsule 268cf0e004cSNinad Palsule if (properties.empty()) 269cf0e004cSNinad Palsule { 2705fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 2715fd0aafbSNinad Palsule { 272cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 273cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 274cf0e004cSNinad Palsule "xyz.openbmc_project.State." 275cf0e004cSNinad Palsule "Decorator.OperationalStatus", 276cf0e004cSNinad Palsule "Functional", 277ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 278ac106bf6SEd Tanous bool dimmState) { 279cf0e004cSNinad Palsule if (ec3) 280cf0e004cSNinad Palsule { 28162598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 282cf0e004cSNinad Palsule return; 283cf0e004cSNinad Palsule } 284ac106bf6SEd Tanous updateDimmProperties(asyncResp, dimmState); 285cf0e004cSNinad Palsule }); 2865fd0aafbSNinad Palsule } 287cf0e004cSNinad Palsule return; 288cf0e004cSNinad Palsule } 289cf0e004cSNinad Palsule 290cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 291cf0e004cSNinad Palsule 292cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 293cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 294cf0e004cSNinad Palsule memorySizeInKB); 295cf0e004cSNinad Palsule 296cf0e004cSNinad Palsule if (!success) 297cf0e004cSNinad Palsule { 298ac106bf6SEd Tanous messages::internalError(asyncResp->res); 299cf0e004cSNinad Palsule return; 300cf0e004cSNinad Palsule } 301cf0e004cSNinad Palsule 302cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 303cf0e004cSNinad Palsule { 304cf0e004cSNinad Palsule nlohmann::json& totalMemory = 305ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 306dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 307cf0e004cSNinad Palsule if (preValue == nullptr) 308cf0e004cSNinad Palsule { 309ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 310dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 311cf0e004cSNinad Palsule } 312cf0e004cSNinad Palsule else 313cf0e004cSNinad Palsule { 314ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 315dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 316dfb2b408SPriyanga Ramasamy *preValue; 317cf0e004cSNinad Palsule } 3185fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 3195fd0aafbSNinad Palsule { 320ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 3215fd0aafbSNinad Palsule "Enabled"; 3225fd0aafbSNinad Palsule } 323cf0e004cSNinad Palsule } 324cf0e004cSNinad Palsule } 325cf0e004cSNinad Palsule 326cf0e004cSNinad Palsule /* 327cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 328cf0e004cSNinad Palsule * 329ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 330cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 331cf0e004cSNinad Palsule * @param[in] path dbus path for memory 332cf0e004cSNinad Palsule * 333cf0e004cSNinad Palsule * @return None. 334cf0e004cSNinad Palsule */ 335ac106bf6SEd Tanous inline void 336ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 337ac106bf6SEd Tanous const std::string& service, const std::string& path) 338cf0e004cSNinad Palsule { 339cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 340cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 341cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 342ac106bf6SEd Tanous [asyncResp, service, 343cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 344cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 345cf0e004cSNinad Palsule if (ec2) 346cf0e004cSNinad Palsule { 34762598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 348ac106bf6SEd Tanous messages::internalError(asyncResp->res); 349cf0e004cSNinad Palsule return; 350cf0e004cSNinad Palsule } 351ac106bf6SEd Tanous processMemoryProperties(asyncResp, service, path, properties); 352cf0e004cSNinad Palsule }); 353cf0e004cSNinad Palsule } 354cf0e004cSNinad Palsule 355a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 356a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 357a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& properties) 3581abe55efSEd Tanous { 359a974c132SLakshmi Yadlapati if (ec) 360a974c132SLakshmi Yadlapati { 361a974c132SLakshmi Yadlapati BMCWEB_LOG_ERROR("DBUS response error {}", ec); 362a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 363a974c132SLakshmi Yadlapati return; 364a974c132SLakshmi Yadlapati } 365a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size()); 366a974c132SLakshmi Yadlapati 367a974c132SLakshmi Yadlapati const std::string* uUID = nullptr; 368a974c132SLakshmi Yadlapati 369a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 370a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID); 371a974c132SLakshmi Yadlapati 372a974c132SLakshmi Yadlapati if (!success) 373a974c132SLakshmi Yadlapati { 374a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 375a974c132SLakshmi Yadlapati return; 376a974c132SLakshmi Yadlapati } 377a974c132SLakshmi Yadlapati 378a974c132SLakshmi Yadlapati if (uUID != nullptr) 379a974c132SLakshmi Yadlapati { 380a974c132SLakshmi Yadlapati std::string valueStr = *uUID; 381a974c132SLakshmi Yadlapati if (valueStr.size() == 32) 382a974c132SLakshmi Yadlapati { 383a974c132SLakshmi Yadlapati valueStr.insert(8, 1, '-'); 384a974c132SLakshmi Yadlapati valueStr.insert(13, 1, '-'); 385a974c132SLakshmi Yadlapati valueStr.insert(18, 1, '-'); 386a974c132SLakshmi Yadlapati valueStr.insert(23, 1, '-'); 387a974c132SLakshmi Yadlapati } 388a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("UUID = {}", valueStr); 389a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["UUID"] = valueStr; 390a974c132SLakshmi Yadlapati } 391a974c132SLakshmi Yadlapati } 392a974c132SLakshmi Yadlapati 393a974c132SLakshmi Yadlapati inline void 394a974c132SLakshmi Yadlapati afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 395a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 396a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& propertiesList) 397a974c132SLakshmi Yadlapati { 398a974c132SLakshmi Yadlapati if (ec) 399a974c132SLakshmi Yadlapati { 400a974c132SLakshmi Yadlapati // doesn't have to include this 401a974c132SLakshmi Yadlapati // interface 402a974c132SLakshmi Yadlapati return; 403a974c132SLakshmi Yadlapati } 404a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size()); 405a974c132SLakshmi Yadlapati 406a974c132SLakshmi Yadlapati const std::string* partNumber = nullptr; 407a974c132SLakshmi Yadlapati const std::string* serialNumber = nullptr; 408a974c132SLakshmi Yadlapati const std::string* manufacturer = nullptr; 409a974c132SLakshmi Yadlapati const std::string* model = nullptr; 410a974c132SLakshmi Yadlapati const std::string* subModel = nullptr; 411a974c132SLakshmi Yadlapati 412a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 413a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber", 414a974c132SLakshmi Yadlapati partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 415a974c132SLakshmi Yadlapati "Model", model, "SubModel", subModel); 416a974c132SLakshmi Yadlapati 417a974c132SLakshmi Yadlapati if (!success) 418a974c132SLakshmi Yadlapati { 419a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 420a974c132SLakshmi Yadlapati return; 421a974c132SLakshmi Yadlapati } 422a974c132SLakshmi Yadlapati 423a974c132SLakshmi Yadlapati if (partNumber != nullptr) 424a974c132SLakshmi Yadlapati { 425a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["PartNumber"] = *partNumber; 426a974c132SLakshmi Yadlapati } 427a974c132SLakshmi Yadlapati 428a974c132SLakshmi Yadlapati if (serialNumber != nullptr) 429a974c132SLakshmi Yadlapati { 430a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 431a974c132SLakshmi Yadlapati } 432a974c132SLakshmi Yadlapati 433a974c132SLakshmi Yadlapati if (manufacturer != nullptr) 434a974c132SLakshmi Yadlapati { 435a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 436a974c132SLakshmi Yadlapati } 437a974c132SLakshmi Yadlapati 438a974c132SLakshmi Yadlapati if (model != nullptr) 439a974c132SLakshmi Yadlapati { 440a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Model"] = *model; 441a974c132SLakshmi Yadlapati } 442a974c132SLakshmi Yadlapati 443a974c132SLakshmi Yadlapati if (subModel != nullptr) 444a974c132SLakshmi Yadlapati { 445a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SubModel"] = *subModel; 446a974c132SLakshmi Yadlapati } 447a974c132SLakshmi Yadlapati 448a974c132SLakshmi Yadlapati // Grab the bios version 449a974c132SLakshmi Yadlapati sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, 450a974c132SLakshmi Yadlapati "BiosVersion", false); 451a974c132SLakshmi Yadlapati } 452a974c132SLakshmi Yadlapati 453a974c132SLakshmi Yadlapati inline void 454a974c132SLakshmi Yadlapati afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 455a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 456a974c132SLakshmi Yadlapati const std::string& value) 457a974c132SLakshmi Yadlapati { 458a974c132SLakshmi Yadlapati if (ec) 459a974c132SLakshmi Yadlapati { 460a974c132SLakshmi Yadlapati // doesn't have to include this 461a974c132SLakshmi Yadlapati // interface 462a974c132SLakshmi Yadlapati return; 463a974c132SLakshmi Yadlapati } 464a974c132SLakshmi Yadlapati 465a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["AssetTag"] = value; 466a974c132SLakshmi Yadlapati } 467a974c132SLakshmi Yadlapati 468a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree( 469a974c132SLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 470a974c132SLakshmi Yadlapati const std::shared_ptr<HealthPopulate>& systemHealth, 471a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 472a974c132SLakshmi Yadlapati const dbus::utility::MapperGetSubTreeResponse& subtree) 473a974c132SLakshmi Yadlapati { 4741abe55efSEd Tanous if (ec) 4751abe55efSEd Tanous { 476b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 477ac106bf6SEd Tanous messages::internalError(asyncResp->res); 478c5b2abe0SLewanczyk, Dawid return; 479c5b2abe0SLewanczyk, Dawid } 480c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 481002d39b4SEd Tanous for (const std::pair< 482002d39b4SEd Tanous std::string, 483002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 4841214b7e7SGunnar Mills object : subtree) 4851abe55efSEd Tanous { 486c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 48762598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 488002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 4891214b7e7SGunnar Mills connectionNames = object.second; 49026f6976fSEd Tanous if (connectionNames.empty()) 4911abe55efSEd Tanous { 492c5b2abe0SLewanczyk, Dawid continue; 493c5b2abe0SLewanczyk, Dawid } 494029573d4SEd Tanous 4955fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> memoryHealth = nullptr; 4965fd0aafbSNinad Palsule std::shared_ptr<HealthPopulate> cpuHealth = nullptr; 4975bc2dc8eSJames Feist 4985fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 4995fd0aafbSNinad Palsule { 5005fd0aafbSNinad Palsule memoryHealth = std::make_shared<HealthPopulate>( 501ac106bf6SEd Tanous asyncResp, "/MemorySummary/Status"_json_pointer); 5025fd0aafbSNinad Palsule systemHealth->children.emplace_back(memoryHealth); 5035bc2dc8eSJames Feist 50413451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 50513451e39SWilly Tu { 5065fd0aafbSNinad Palsule cpuHealth = std::make_shared<HealthPopulate>( 507ac106bf6SEd Tanous asyncResp, "/ProcessorSummary/Status"_json_pointer); 5085fd0aafbSNinad Palsule 5095bc2dc8eSJames Feist systemHealth->children.emplace_back(cpuHealth); 51013451e39SWilly Tu } 5115fd0aafbSNinad Palsule } 5125bc2dc8eSJames Feist 5136c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 5146c34de48SEd Tanous // BiosVer 51504a258f4SEd Tanous for (const auto& connection : connectionNames) 5161abe55efSEd Tanous { 51704a258f4SEd Tanous for (const auto& interfaceName : connection.second) 5181abe55efSEd Tanous { 519a974c132SLakshmi Yadlapati if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") 5201abe55efSEd Tanous { 52162598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 5229d3ae10eSAlpana Kumari 523ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 5245bc2dc8eSJames Feist 5255fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 5265fd0aafbSNinad Palsule { 5275bc2dc8eSJames Feist memoryHealth->inventory.emplace_back(path); 5281abe55efSEd Tanous } 5295fd0aafbSNinad Palsule } 53004a258f4SEd Tanous else if (interfaceName == 53104a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 5321abe55efSEd Tanous { 53362598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 53457e8c9beSAlpana Kumari 535ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 5365bc2dc8eSJames Feist 5375fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 5385fd0aafbSNinad Palsule { 5395bc2dc8eSJames Feist cpuHealth->inventory.emplace_back(path); 5401abe55efSEd Tanous } 5415fd0aafbSNinad Palsule } 542002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 5431abe55efSEd Tanous { 54462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 545bc1d29deSKrzysztof Grobelny 546bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 547a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 548a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 549ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 550b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 5511214b7e7SGunnar Mills properties) { 552a974c132SLakshmi Yadlapati afterGetUUID(asyncResp, ec3, properties); 553bc1d29deSKrzysztof Grobelny }); 554c5b2abe0SLewanczyk, Dawid } 555029573d4SEd Tanous else if (interfaceName == 556029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 5571abe55efSEd Tanous { 558bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 559a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 560bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 561a974c132SLakshmi Yadlapati [asyncResp](const boost::system::error_code& ec3, 562b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 563a974c132SLakshmi Yadlapati properties) { 564a974c132SLakshmi Yadlapati afterGetInventory(asyncResp, ec3, properties); 565bc1d29deSKrzysztof Grobelny }); 566e4a4b9a9SJames Feist 5671e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 568a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 5691e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 5701e1e598dSJonathan Doman "AssetTag", 5711e1e598dSJonathan Doman "AssetTag", 572a974c132SLakshmi Yadlapati std::bind_front(afterGetAssetTag, asyncResp)); 573a974c132SLakshmi Yadlapati } 574a974c132SLakshmi Yadlapati } 575a974c132SLakshmi Yadlapati } 576a974c132SLakshmi Yadlapati } 577a974c132SLakshmi Yadlapati } 578a974c132SLakshmi Yadlapati 579a974c132SLakshmi Yadlapati /* 580a974c132SLakshmi Yadlapati * @brief Retrieves computer system properties over dbus 581a974c132SLakshmi Yadlapati * 582a974c132SLakshmi Yadlapati * @param[in] asyncResp Shared pointer for completing asynchronous calls 583a974c132SLakshmi Yadlapati * @param[in] systemHealth Shared HealthPopulate pointer 584a974c132SLakshmi Yadlapati * 585a974c132SLakshmi Yadlapati * @return None. 586a974c132SLakshmi Yadlapati */ 587a974c132SLakshmi Yadlapati inline void 588a974c132SLakshmi Yadlapati getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 589a974c132SLakshmi Yadlapati const std::shared_ptr<HealthPopulate>& systemHealth) 590e4a4b9a9SJames Feist { 591a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get available system components."); 592a974c132SLakshmi Yadlapati constexpr std::array<std::string_view, 5> interfaces = { 593a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 594a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Cpu", 595a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Dimm", 596a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.System", 597a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 598a974c132SLakshmi Yadlapati }; 599a974c132SLakshmi Yadlapati dbus::utility::getSubTree( 600a974c132SLakshmi Yadlapati "/xyz/openbmc_project/inventory", 0, interfaces, 601a974c132SLakshmi Yadlapati std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth)); 602c5b2abe0SLewanczyk, Dawid } 603c5b2abe0SLewanczyk, Dawid 604c5b2abe0SLewanczyk, Dawid /** 605c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 606c5b2abe0SLewanczyk, Dawid * 607ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 608c5b2abe0SLewanczyk, Dawid * 609c5b2abe0SLewanczyk, Dawid * @return None. 610c5b2abe0SLewanczyk, Dawid */ 611ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 6121abe55efSEd Tanous { 61362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 6141e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 6151e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 6161e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 6171e1e598dSJonathan Doman "CurrentHostState", 618ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 6191e1e598dSJonathan Doman const std::string& hostState) { 6201abe55efSEd Tanous if (ec) 6211abe55efSEd Tanous { 62222228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 62322228c28SAndrew Geissler { 62422228c28SAndrew Geissler // Service not available, no error, just don't return 62522228c28SAndrew Geissler // host state info 62662598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 62722228c28SAndrew Geissler return; 62822228c28SAndrew Geissler } 62962598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 630ac106bf6SEd Tanous messages::internalError(asyncResp->res); 631c5b2abe0SLewanczyk, Dawid return; 632c5b2abe0SLewanczyk, Dawid } 6336617338dSEd Tanous 63462598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 635c5b2abe0SLewanczyk, Dawid // Verify Host State 6361e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 6371abe55efSEd Tanous { 638ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 639ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 6401abe55efSEd Tanous } 6411e1e598dSJonathan Doman else if (hostState == 6420fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 6438c888608SGunnar Mills { 644ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 645ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Quiesced"; 6468c888608SGunnar Mills } 6471e1e598dSJonathan Doman else if (hostState == 6480fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 64983935af9SAndrew Geissler { 650ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "On"; 651ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "InTest"; 65283935af9SAndrew Geissler } 6530fda0f12SGeorge Liu else if ( 6541e1e598dSJonathan Doman hostState == 6550fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 6561a2a1437SAndrew Geissler { 657ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOn"; 658ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Starting"; 6591a2a1437SAndrew Geissler } 660002d39b4SEd Tanous else if (hostState == 6610fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 6621a2a1437SAndrew Geissler { 663ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "PoweringOff"; 664ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 6651a2a1437SAndrew Geissler } 6661abe55efSEd Tanous else 6671abe55efSEd Tanous { 668ac106bf6SEd Tanous asyncResp->res.jsonValue["PowerState"] = "Off"; 669ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 670c5b2abe0SLewanczyk, Dawid } 6711e1e598dSJonathan Doman }); 672c5b2abe0SLewanczyk, Dawid } 673c5b2abe0SLewanczyk, Dawid 674c5b2abe0SLewanczyk, Dawid /** 675786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 676491d8ee7SSantosh Puranik * 677491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 678491d8ee7SSantosh Puranik * 679491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 680491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 681491d8ee7SSantosh Puranik */ 68223a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 683491d8ee7SSantosh Puranik { 684491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 685491d8ee7SSantosh Puranik { 686491d8ee7SSantosh Puranik return "None"; 687491d8ee7SSantosh Puranik } 6883174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 689491d8ee7SSantosh Puranik { 690491d8ee7SSantosh Puranik return "Hdd"; 691491d8ee7SSantosh Puranik } 6923174e4dfSEd Tanous if (dbusSource == 693a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 694491d8ee7SSantosh Puranik { 695491d8ee7SSantosh Puranik return "Cd"; 696491d8ee7SSantosh Puranik } 6973174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 698491d8ee7SSantosh Puranik { 699491d8ee7SSantosh Puranik return "Pxe"; 700491d8ee7SSantosh Puranik } 7013174e4dfSEd Tanous if (dbusSource == 702944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 7039f16b2c1SJennifer Lee { 7049f16b2c1SJennifer Lee return "Usb"; 7059f16b2c1SJennifer Lee } 706491d8ee7SSantosh Puranik return ""; 707491d8ee7SSantosh Puranik } 708491d8ee7SSantosh Puranik 709491d8ee7SSantosh Puranik /** 710cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 711cd9a4666SKonstantin Aladyshev * 712cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 713cd9a4666SKonstantin Aladyshev * 714cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 715cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 716cd9a4666SKonstantin Aladyshev */ 717cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 718cd9a4666SKonstantin Aladyshev { 719cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 720cd9a4666SKonstantin Aladyshev { 721cd9a4666SKonstantin Aladyshev return "Legacy"; 722cd9a4666SKonstantin Aladyshev } 723cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 724cd9a4666SKonstantin Aladyshev { 725cd9a4666SKonstantin Aladyshev return "UEFI"; 726cd9a4666SKonstantin Aladyshev } 727cd9a4666SKonstantin Aladyshev return ""; 728cd9a4666SKonstantin Aladyshev } 729cd9a4666SKonstantin Aladyshev 730cd9a4666SKonstantin Aladyshev /** 731786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 732491d8ee7SSantosh Puranik * 733491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 734491d8ee7SSantosh Puranik * 735491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 736491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 737491d8ee7SSantosh Puranik */ 73823a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 739491d8ee7SSantosh Puranik { 740491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 741491d8ee7SSantosh Puranik { 742491d8ee7SSantosh Puranik return "None"; 743491d8ee7SSantosh Puranik } 7443174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 745491d8ee7SSantosh Puranik { 746491d8ee7SSantosh Puranik return "Diags"; 747491d8ee7SSantosh Puranik } 7483174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 749491d8ee7SSantosh Puranik { 750491d8ee7SSantosh Puranik return "BiosSetup"; 751491d8ee7SSantosh Puranik } 752491d8ee7SSantosh Puranik return ""; 753491d8ee7SSantosh Puranik } 754491d8ee7SSantosh Puranik 755491d8ee7SSantosh Puranik /** 756e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 757e43914b3SAndrew Geissler * 758e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 759e43914b3SAndrew Geissler * 760e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 761e43914b3SAndrew Geissler * translation cannot be done, returns "None". 762e43914b3SAndrew Geissler */ 763e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 764e43914b3SAndrew Geissler { 765e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 766e43914b3SAndrew Geissler // enum 767e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 768e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 769e43914b3SAndrew Geissler "ProgressStages.Unspecified") 770e43914b3SAndrew Geissler { 771e43914b3SAndrew Geissler rfBpLastState = "None"; 772e43914b3SAndrew Geissler } 773e43914b3SAndrew Geissler else if (dbusBootProgress == 774e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 775e43914b3SAndrew Geissler "PrimaryProcInit") 776e43914b3SAndrew Geissler { 777e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 778e43914b3SAndrew Geissler } 779e43914b3SAndrew Geissler else if (dbusBootProgress == 780e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 781e43914b3SAndrew Geissler "BusInit") 782e43914b3SAndrew Geissler { 783e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 784e43914b3SAndrew Geissler } 785e43914b3SAndrew Geissler else if (dbusBootProgress == 786e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 787e43914b3SAndrew Geissler "MemoryInit") 788e43914b3SAndrew Geissler { 789e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 790e43914b3SAndrew Geissler } 791e43914b3SAndrew Geissler else if (dbusBootProgress == 792e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 793e43914b3SAndrew Geissler "SecondaryProcInit") 794e43914b3SAndrew Geissler { 795e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 796e43914b3SAndrew Geissler } 797e43914b3SAndrew Geissler else if (dbusBootProgress == 798e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 799e43914b3SAndrew Geissler "PCIInit") 800e43914b3SAndrew Geissler { 801e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 802e43914b3SAndrew Geissler } 803e43914b3SAndrew Geissler else if (dbusBootProgress == 804e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 805e43914b3SAndrew Geissler "SystemSetup") 806e43914b3SAndrew Geissler { 807e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 808e43914b3SAndrew Geissler } 809e43914b3SAndrew Geissler else if (dbusBootProgress == 810e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 811e43914b3SAndrew Geissler "SystemInitComplete") 812e43914b3SAndrew Geissler { 813e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 814e43914b3SAndrew Geissler } 815e43914b3SAndrew Geissler else if (dbusBootProgress == 816e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 817e43914b3SAndrew Geissler "OSStart") 818e43914b3SAndrew Geissler { 819e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 820e43914b3SAndrew Geissler } 821e43914b3SAndrew Geissler else if (dbusBootProgress == 822e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 823e43914b3SAndrew Geissler "OSRunning") 824e43914b3SAndrew Geissler { 825e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 826e43914b3SAndrew Geissler } 827e43914b3SAndrew Geissler else 828e43914b3SAndrew Geissler { 82962598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 830e43914b3SAndrew Geissler // Just return the default 831e43914b3SAndrew Geissler } 832e43914b3SAndrew Geissler return rfBpLastState; 833e43914b3SAndrew Geissler } 834e43914b3SAndrew Geissler 835e43914b3SAndrew Geissler /** 836786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 837491d8ee7SSantosh Puranik * 838491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 839944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 840944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 841491d8ee7SSantosh Puranik * 842944ffaf9SJohnathan Mantey * @return Integer error code. 843491d8ee7SSantosh Puranik */ 844ac106bf6SEd Tanous inline int 845ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 846ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 847ac106bf6SEd Tanous std::string& bootMode) 848491d8ee7SSantosh Puranik { 849c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 850c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 851944ffaf9SJohnathan Mantey 852491d8ee7SSantosh Puranik if (rfSource == "None") 853491d8ee7SSantosh Puranik { 854944ffaf9SJohnathan Mantey return 0; 855491d8ee7SSantosh Puranik } 8563174e4dfSEd Tanous if (rfSource == "Pxe") 857491d8ee7SSantosh Puranik { 858944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 859944ffaf9SJohnathan Mantey } 860944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 861944ffaf9SJohnathan Mantey { 862944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 863944ffaf9SJohnathan Mantey } 864944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 865944ffaf9SJohnathan Mantey { 866944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 867944ffaf9SJohnathan Mantey } 868944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 869944ffaf9SJohnathan Mantey { 870944ffaf9SJohnathan Mantey bootSource = 871944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 872944ffaf9SJohnathan Mantey } 873944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 874944ffaf9SJohnathan Mantey { 875944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 876491d8ee7SSantosh Puranik } 8779f16b2c1SJennifer Lee else if (rfSource == "Usb") 8789f16b2c1SJennifer Lee { 879944ffaf9SJohnathan Mantey bootSource = 880944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8819f16b2c1SJennifer Lee } 882491d8ee7SSantosh Puranik else 883491d8ee7SSantosh Puranik { 88462598e31SEd Tanous BMCWEB_LOG_DEBUG( 88562598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 88662598e31SEd Tanous bootSource); 887ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 888944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 889944ffaf9SJohnathan Mantey return -1; 890491d8ee7SSantosh Puranik } 891944ffaf9SJohnathan Mantey return 0; 892491d8ee7SSantosh Puranik } 8931981771bSAli Ahmed 894978b8803SAndrew Geissler /** 895978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 896978b8803SAndrew Geissler * 897ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 898978b8803SAndrew Geissler * 899978b8803SAndrew Geissler * @return None. 900978b8803SAndrew Geissler */ 901ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 902978b8803SAndrew Geissler { 9031e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9041e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 9051e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 9061e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 907ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9081e1e598dSJonathan Doman const std::string& bootProgressStr) { 909978b8803SAndrew Geissler if (ec) 910978b8803SAndrew Geissler { 911978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 912978b8803SAndrew Geissler // not found 913978b8803SAndrew Geissler return; 914978b8803SAndrew Geissler } 915978b8803SAndrew Geissler 91662598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 917978b8803SAndrew Geissler 918ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 919e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 9201e1e598dSJonathan Doman }); 921978b8803SAndrew Geissler } 922491d8ee7SSantosh Puranik 923491d8ee7SSantosh Puranik /** 924b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 925b6d5d45cSHieu Huynh * 926ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 927b6d5d45cSHieu Huynh * 928b6d5d45cSHieu Huynh * @return None. 929b6d5d45cSHieu Huynh */ 930b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 931ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 932b6d5d45cSHieu Huynh { 933b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 934b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 935b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 936b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 937ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 938b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 939b6d5d45cSHieu Huynh if (ec) 940b6d5d45cSHieu Huynh { 94162598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 942b6d5d45cSHieu Huynh return; 943b6d5d45cSHieu Huynh } 944b6d5d45cSHieu Huynh 945b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 946b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 947b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 948b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 949b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 950b6d5d45cSHieu Huynh 951b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 952ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 953b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 954b6d5d45cSHieu Huynh }); 955b6d5d45cSHieu Huynh } 956b6d5d45cSHieu Huynh 957b6d5d45cSHieu Huynh /** 958c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 959cd9a4666SKonstantin Aladyshev * 960ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 961cd9a4666SKonstantin Aladyshev * 962cd9a4666SKonstantin Aladyshev * @return None. 963cd9a4666SKonstantin Aladyshev */ 964cd9a4666SKonstantin Aladyshev 965ac106bf6SEd Tanous inline void 966ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 967cd9a4666SKonstantin Aladyshev { 9681e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9691e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9701e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9711e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 972ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9731e1e598dSJonathan Doman const std::string& bootType) { 974cd9a4666SKonstantin Aladyshev if (ec) 975cd9a4666SKonstantin Aladyshev { 976cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 977cd9a4666SKonstantin Aladyshev return; 978cd9a4666SKonstantin Aladyshev } 979cd9a4666SKonstantin Aladyshev 98062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 981cd9a4666SKonstantin Aladyshev 982ac106bf6SEd Tanous asyncResp->res 983ac106bf6SEd Tanous .jsonValue["Boot"] 984002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 985613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 986cd9a4666SKonstantin Aladyshev 9871e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 988cd9a4666SKonstantin Aladyshev if (rfType.empty()) 989cd9a4666SKonstantin Aladyshev { 990ac106bf6SEd Tanous messages::internalError(asyncResp->res); 991cd9a4666SKonstantin Aladyshev return; 992cd9a4666SKonstantin Aladyshev } 993cd9a4666SKonstantin Aladyshev 994ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9951e1e598dSJonathan Doman }); 996cd9a4666SKonstantin Aladyshev } 997cd9a4666SKonstantin Aladyshev 998cd9a4666SKonstantin Aladyshev /** 999c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 1000491d8ee7SSantosh Puranik * 1001ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1002491d8ee7SSantosh Puranik * 1003491d8ee7SSantosh Puranik * @return None. 1004491d8ee7SSantosh Puranik */ 1005c21865c4SKonstantin Aladyshev 1006ac106bf6SEd Tanous inline void 1007ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1008491d8ee7SSantosh Puranik { 10091e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10101e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10111e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10121e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1013ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10141e1e598dSJonathan Doman const std::string& bootModeStr) { 1015491d8ee7SSantosh Puranik if (ec) 1016491d8ee7SSantosh Puranik { 1017b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1018ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1019491d8ee7SSantosh Puranik return; 1020491d8ee7SSantosh Puranik } 1021491d8ee7SSantosh Puranik 102262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 1023491d8ee7SSantosh Puranik 1024ac106bf6SEd Tanous asyncResp->res 10250fda0f12SGeorge Liu .jsonValue["Boot"] 1026002d39b4SEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = { 1027002d39b4SEd Tanous "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"}; 1028491d8ee7SSantosh Puranik 10291e1e598dSJonathan Doman if (bootModeStr != 1030491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 1031491d8ee7SSantosh Puranik { 10321e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 1033491d8ee7SSantosh Puranik if (!rfMode.empty()) 1034491d8ee7SSantosh Puranik { 1035ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1036491d8ee7SSantosh Puranik rfMode; 1037491d8ee7SSantosh Puranik } 1038491d8ee7SSantosh Puranik } 10391e1e598dSJonathan Doman }); 1040491d8ee7SSantosh Puranik } 1041491d8ee7SSantosh Puranik 1042491d8ee7SSantosh Puranik /** 1043c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 1044491d8ee7SSantosh Puranik * 1045ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1046491d8ee7SSantosh Puranik * 1047491d8ee7SSantosh Puranik * @return None. 1048491d8ee7SSantosh Puranik */ 1049c21865c4SKonstantin Aladyshev 1050c21865c4SKonstantin Aladyshev inline void 1051ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1052491d8ee7SSantosh Puranik { 10531e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 10541e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10551e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10561e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1057ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10581e1e598dSJonathan Doman const std::string& bootSourceStr) { 1059491d8ee7SSantosh Puranik if (ec) 1060491d8ee7SSantosh Puranik { 10615ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10625ef735c8SNan Zhou { 10635ef735c8SNan Zhou return; 10645ef735c8SNan Zhou } 1065b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1066ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1067491d8ee7SSantosh Puranik return; 1068491d8ee7SSantosh Puranik } 1069491d8ee7SSantosh Puranik 107062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 1071491d8ee7SSantosh Puranik 10721e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1073491d8ee7SSantosh Puranik if (!rfSource.empty()) 1074491d8ee7SSantosh Puranik { 1075ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1076ac106bf6SEd Tanous rfSource; 1077491d8ee7SSantosh Puranik } 1078cd9a4666SKonstantin Aladyshev 1079cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1080cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1081ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10821e1e598dSJonathan Doman }); 1083491d8ee7SSantosh Puranik } 1084491d8ee7SSantosh Puranik 1085491d8ee7SSantosh Puranik /** 1086c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1087c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1088c21865c4SKonstantin Aladyshev * state 1089491d8ee7SSantosh Puranik * 1090ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1091491d8ee7SSantosh Puranik * 1092491d8ee7SSantosh Puranik * @return None. 1093491d8ee7SSantosh Puranik */ 1094491d8ee7SSantosh Puranik 1095ac106bf6SEd Tanous inline void processBootOverrideEnable( 1096ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1097c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1098c21865c4SKonstantin Aladyshev { 1099c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1100c21865c4SKonstantin Aladyshev { 1101ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1102ac106bf6SEd Tanous "Disabled"; 1103c21865c4SKonstantin Aladyshev return; 1104c21865c4SKonstantin Aladyshev } 1105c21865c4SKonstantin Aladyshev 1106c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1107c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 11081e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11091e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11101e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 11111e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1112ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1113491d8ee7SSantosh Puranik if (ec) 1114491d8ee7SSantosh Puranik { 1115b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1116ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1117491d8ee7SSantosh Puranik return; 1118491d8ee7SSantosh Puranik } 1119491d8ee7SSantosh Puranik 1120c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1121c21865c4SKonstantin Aladyshev { 1122ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1123ac106bf6SEd Tanous "Once"; 1124c21865c4SKonstantin Aladyshev } 1125c21865c4SKonstantin Aladyshev else 1126c21865c4SKonstantin Aladyshev { 1127ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1128c21865c4SKonstantin Aladyshev "Continuous"; 1129c21865c4SKonstantin Aladyshev } 11301e1e598dSJonathan Doman }); 1131491d8ee7SSantosh Puranik } 1132491d8ee7SSantosh Puranik 1133491d8ee7SSantosh Puranik /** 1134c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1135c21865c4SKonstantin Aladyshev * 1136ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1137c21865c4SKonstantin Aladyshev * 1138c21865c4SKonstantin Aladyshev * @return None. 1139c21865c4SKonstantin Aladyshev */ 1140c21865c4SKonstantin Aladyshev 1141c21865c4SKonstantin Aladyshev inline void 1142ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1143c21865c4SKonstantin Aladyshev { 11441e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 11451e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 11461e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 11471e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1148ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 11491e1e598dSJonathan Doman const bool bootOverrideEnable) { 1150c21865c4SKonstantin Aladyshev if (ec) 1151c21865c4SKonstantin Aladyshev { 11525ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 11535ef735c8SNan Zhou { 11545ef735c8SNan Zhou return; 11555ef735c8SNan Zhou } 1156b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1157ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1158c21865c4SKonstantin Aladyshev return; 1159c21865c4SKonstantin Aladyshev } 1160c21865c4SKonstantin Aladyshev 1161ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11621e1e598dSJonathan Doman }); 1163c21865c4SKonstantin Aladyshev } 1164c21865c4SKonstantin Aladyshev 1165c21865c4SKonstantin Aladyshev /** 1166c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1167c21865c4SKonstantin Aladyshev * 1168ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1169c21865c4SKonstantin Aladyshev * 1170c21865c4SKonstantin Aladyshev * @return None. 1171c21865c4SKonstantin Aladyshev */ 1172ac106bf6SEd Tanous inline void 1173ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1174c21865c4SKonstantin Aladyshev { 117562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1176c21865c4SKonstantin Aladyshev 1177ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1178ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1179ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1180c21865c4SKonstantin Aladyshev } 1181c21865c4SKonstantin Aladyshev 1182c21865c4SKonstantin Aladyshev /** 1183c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1184c0557e1aSGunnar Mills * 1185c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1186c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1187c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1188c0557e1aSGunnar Mills * last power operation time. 1189c0557e1aSGunnar Mills * 1190ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1191c0557e1aSGunnar Mills * 1192c0557e1aSGunnar Mills * @return None. 1193c0557e1aSGunnar Mills */ 1194ac106bf6SEd Tanous inline void 1195ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1196c0557e1aSGunnar Mills { 119762598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1198c0557e1aSGunnar Mills 11991e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 12001e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 12011e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 12021e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1203ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1204ac106bf6SEd Tanous uint64_t lastResetTime) { 1205c0557e1aSGunnar Mills if (ec) 1206c0557e1aSGunnar Mills { 120762598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1208c0557e1aSGunnar Mills return; 1209c0557e1aSGunnar Mills } 1210c0557e1aSGunnar Mills 1211c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1212c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 12131e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1214c0557e1aSGunnar Mills 1215c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1216ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 12172b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 12181e1e598dSJonathan Doman }); 1219c0557e1aSGunnar Mills } 1220c0557e1aSGunnar Mills 1221c0557e1aSGunnar Mills /** 1222797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1223797d5daeSCorey Hardesty * 1224797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1225797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1226797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1227797d5daeSCorey Hardesty * dbus. 1228797d5daeSCorey Hardesty * 1229ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1230797d5daeSCorey Hardesty * 1231797d5daeSCorey Hardesty * @return None. 1232797d5daeSCorey Hardesty */ 1233ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1234ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1235797d5daeSCorey Hardesty { 123662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1237797d5daeSCorey Hardesty 1238797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1239797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1240797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1241797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1242ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1243ac106bf6SEd Tanous const boost::system::error_code& ec, 1244797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1245797d5daeSCorey Hardesty if (ec) 1246797d5daeSCorey Hardesty { 1247797d5daeSCorey Hardesty if (ec.value() != EBADR) 1248797d5daeSCorey Hardesty { 124962598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1250ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1251797d5daeSCorey Hardesty } 1252797d5daeSCorey Hardesty return; 1253797d5daeSCorey Hardesty } 1254797d5daeSCorey Hardesty 1255797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1256797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1257797d5daeSCorey Hardesty 1258797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1259797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1260797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1261797d5daeSCorey Hardesty 1262797d5daeSCorey Hardesty if (!success) 1263797d5daeSCorey Hardesty { 1264ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1265797d5daeSCorey Hardesty return; 1266797d5daeSCorey Hardesty } 1267797d5daeSCorey Hardesty 1268797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1269797d5daeSCorey Hardesty { 1270ac106bf6SEd Tanous asyncResp->res 1271ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1272797d5daeSCorey Hardesty *attemptsLeft; 1273797d5daeSCorey Hardesty } 1274797d5daeSCorey Hardesty 1275797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1276797d5daeSCorey Hardesty { 1277ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1278797d5daeSCorey Hardesty *retryAttempts; 1279797d5daeSCorey Hardesty } 1280797d5daeSCorey Hardesty }); 1281797d5daeSCorey Hardesty } 1282797d5daeSCorey Hardesty 1283797d5daeSCorey Hardesty /** 12846bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12856bd5a8d2SGunnar Mills * 1286ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12876bd5a8d2SGunnar Mills * 12886bd5a8d2SGunnar Mills * @return None. 12896bd5a8d2SGunnar Mills */ 1290797d5daeSCorey Hardesty inline void 1291ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12926bd5a8d2SGunnar Mills { 129362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12946bd5a8d2SGunnar Mills 12951e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12961e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12971e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12981e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1299ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1300ac106bf6SEd Tanous bool autoRebootEnabled) { 13016bd5a8d2SGunnar Mills if (ec) 13026bd5a8d2SGunnar Mills { 1303797d5daeSCorey Hardesty if (ec.value() != EBADR) 1304797d5daeSCorey Hardesty { 130562598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1306ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1307797d5daeSCorey Hardesty } 13086bd5a8d2SGunnar Mills return; 13096bd5a8d2SGunnar Mills } 13106bd5a8d2SGunnar Mills 131162598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1312e05aec50SEd Tanous if (autoRebootEnabled) 13136bd5a8d2SGunnar Mills { 1314ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 13156bd5a8d2SGunnar Mills "RetryAttempts"; 13166bd5a8d2SGunnar Mills } 13176bd5a8d2SGunnar Mills else 13186bd5a8d2SGunnar Mills { 1319ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1320ac106bf6SEd Tanous "Disabled"; 13216bd5a8d2SGunnar Mills } 1322ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 132369f35306SGunnar Mills 132469f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 132569f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 132669f35306SGunnar Mills // RetryAttempts. 1327ac106bf6SEd Tanous asyncResp->res 1328ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 1329ac106bf6SEd Tanous {"Disabled", "RetryAttempts"}; 13301e1e598dSJonathan Doman }); 13316bd5a8d2SGunnar Mills } 13326bd5a8d2SGunnar Mills 13336bd5a8d2SGunnar Mills /** 1334797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1335797d5daeSCorey Hardesty * 1336ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1337797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1338797d5daeSCorey Hardesty * 1339797d5daeSCorey Hardesty *@return None. 1340797d5daeSCorey Hardesty */ 1341797d5daeSCorey Hardesty 1342ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1343ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1344797d5daeSCorey Hardesty const uint32_t retryAttempts) 1345797d5daeSCorey Hardesty { 134662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 13479ae226faSGeorge Liu sdbusplus::asio::setProperty( 13489ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 13499ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 13509ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 13519ae226faSGeorge Liu retryAttempts, [asyncResp](const boost::system::error_code& ec) { 1352797d5daeSCorey Hardesty if (ec) 1353797d5daeSCorey Hardesty { 135462598e31SEd Tanous BMCWEB_LOG_ERROR( 135562598e31SEd Tanous "DBUS response error: Set setAutomaticRetryAttempts{}", ec); 1356ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1357797d5daeSCorey Hardesty return; 1358797d5daeSCorey Hardesty } 13599ae226faSGeorge Liu }); 1360797d5daeSCorey Hardesty } 1361797d5daeSCorey Hardesty 13628d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 13638d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 13648d69c668SEd Tanous { 13658d69c668SEd Tanous if (value == 13668d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 13678d69c668SEd Tanous { 13688d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 13698d69c668SEd Tanous } 13708d69c668SEd Tanous if (value == 13718d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 13728d69c668SEd Tanous { 13738d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13748d69c668SEd Tanous } 13758d69c668SEd Tanous if (value == 13763a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 13778d69c668SEd Tanous { 13788d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13798d69c668SEd Tanous } 13808d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13818d69c668SEd Tanous { 13828d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13838d69c668SEd Tanous } 13848d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13858d69c668SEd Tanous } 1386797d5daeSCorey Hardesty /** 1387c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1388c6a620f2SGeorge Liu * 1389ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1390c6a620f2SGeorge Liu * 1391c6a620f2SGeorge Liu * @return None. 1392c6a620f2SGeorge Liu */ 13938d1b46d7Szhanghch05 inline void 1394ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1395c6a620f2SGeorge Liu { 139662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1397c6a620f2SGeorge Liu 13981e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13991e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 14001e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 14011e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1402ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 14035e7e2dc5SEd Tanous const std::string& policy) { 1404c6a620f2SGeorge Liu if (ec) 1405c6a620f2SGeorge Liu { 140662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1407c6a620f2SGeorge Liu return; 1408c6a620f2SGeorge Liu } 14098d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 14108d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 14118d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1412c6a620f2SGeorge Liu { 1413ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1414c6a620f2SGeorge Liu return; 1415c6a620f2SGeorge Liu } 1416c6a620f2SGeorge Liu 14178d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 14181e1e598dSJonathan Doman }); 1419c6a620f2SGeorge Liu } 1420c6a620f2SGeorge Liu 1421c6a620f2SGeorge Liu /** 14229dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 14239dcfe8c1SAlbert Zhang * 14249dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 14259dcfe8c1SAlbert Zhang * 14269dcfe8c1SAlbert Zhang * @return None. 14279dcfe8c1SAlbert Zhang */ 14289dcfe8c1SAlbert Zhang inline void 14299dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14309dcfe8c1SAlbert Zhang { 143162598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 14329dcfe8c1SAlbert Zhang 14339dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 14349dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 14359dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 14369dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 14379dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 14389dcfe8c1SAlbert Zhang if (ec) 14399dcfe8c1SAlbert Zhang { 14409dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 14419dcfe8c1SAlbert Zhang { 1442b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 14439dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 14449dcfe8c1SAlbert Zhang } 14459dcfe8c1SAlbert Zhang return; 14469dcfe8c1SAlbert Zhang } 14479dcfe8c1SAlbert Zhang 14489dcfe8c1SAlbert Zhang if (value) 14499dcfe8c1SAlbert Zhang { 14509dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault"; 14519dcfe8c1SAlbert Zhang } 14529dcfe8c1SAlbert Zhang else 14539dcfe8c1SAlbert Zhang { 14549dcfe8c1SAlbert Zhang asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never"; 14559dcfe8c1SAlbert Zhang } 14569dcfe8c1SAlbert Zhang }); 14579dcfe8c1SAlbert Zhang } 14589dcfe8c1SAlbert Zhang 14599dcfe8c1SAlbert Zhang /** 14601981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 14611981771bSAli Ahmed * TPM is required for booting the host. 14621981771bSAli Ahmed * 1463ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14641981771bSAli Ahmed * 14651981771bSAli Ahmed * @return None. 14661981771bSAli Ahmed */ 14671981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1468ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14691981771bSAli Ahmed { 147062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1471e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1472e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1473e99073f5SGeorge Liu dbus::utility::getSubTree( 1474e99073f5SGeorge Liu "/", 0, interfaces, 1475ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1476b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14771981771bSAli Ahmed if (ec) 14781981771bSAli Ahmed { 147962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", 148062598e31SEd Tanous ec); 14811981771bSAli Ahmed // This is an optional D-Bus object so just return if 14821981771bSAli Ahmed // error occurs 14831981771bSAli Ahmed return; 14841981771bSAli Ahmed } 148526f6976fSEd Tanous if (subtree.empty()) 14861981771bSAli Ahmed { 14871981771bSAli Ahmed // As noted above, this is an optional interface so just return 14881981771bSAli Ahmed // if there is no instance found 14891981771bSAli Ahmed return; 14901981771bSAli Ahmed } 14911981771bSAli Ahmed 14921981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14931981771bSAli Ahmed if (subtree.size() > 1) 14941981771bSAli Ahmed { 149562598e31SEd Tanous BMCWEB_LOG_DEBUG( 149662598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 149762598e31SEd Tanous subtree.size()); 14981981771bSAli Ahmed // Throw an internal Error and return 1499ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15001981771bSAli Ahmed return; 15011981771bSAli Ahmed } 15021981771bSAli Ahmed 15031981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 15041981771bSAli Ahmed // field 15051981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15061981771bSAli Ahmed { 150762598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1508ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15091981771bSAli Ahmed return; 15101981771bSAli Ahmed } 15111981771bSAli Ahmed 15121981771bSAli Ahmed const std::string& path = subtree[0].first; 15131981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15141981771bSAli Ahmed 15151981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 15161e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 15171e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 15181e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1519ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1520ac106bf6SEd Tanous bool tpmRequired) { 15218a592810SEd Tanous if (ec2) 15221981771bSAli Ahmed { 1523b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}", 152462598e31SEd Tanous ec2); 1525ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15261981771bSAli Ahmed return; 15271981771bSAli Ahmed } 15281981771bSAli Ahmed 15291e1e598dSJonathan Doman if (tpmRequired) 15301981771bSAli Ahmed { 1531ac106bf6SEd Tanous asyncResp->res 1532ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15331981771bSAli Ahmed "Required"; 15341981771bSAli Ahmed } 15351981771bSAli Ahmed else 15361981771bSAli Ahmed { 1537ac106bf6SEd Tanous asyncResp->res 1538ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 15391981771bSAli Ahmed "Disabled"; 15401981771bSAli Ahmed } 15411e1e598dSJonathan Doman }); 1542e99073f5SGeorge Liu }); 15431981771bSAli Ahmed } 15441981771bSAli Ahmed 15451981771bSAli Ahmed /** 15461c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 15471c05dae3SAli Ahmed * TPM is required for booting the host. 15481c05dae3SAli Ahmed * 1549ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 15501c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 15511c05dae3SAli Ahmed * 15521c05dae3SAli Ahmed * @return None. 15531c05dae3SAli Ahmed */ 15541c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1555ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 15561c05dae3SAli Ahmed { 155762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1558e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1559e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1560e99073f5SGeorge Liu dbus::utility::getSubTree( 1561e99073f5SGeorge Liu "/", 0, interfaces, 1562ac106bf6SEd Tanous [asyncResp, 1563e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1564e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15651c05dae3SAli Ahmed if (ec) 15661c05dae3SAli Ahmed { 1567b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", 156862598e31SEd Tanous ec); 1569ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15701c05dae3SAli Ahmed return; 15711c05dae3SAli Ahmed } 157226f6976fSEd Tanous if (subtree.empty()) 15731c05dae3SAli Ahmed { 1574ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 15751c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15761c05dae3SAli Ahmed return; 15771c05dae3SAli Ahmed } 15781c05dae3SAli Ahmed 15791c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15801c05dae3SAli Ahmed if (subtree.size() > 1) 15811c05dae3SAli Ahmed { 158262598e31SEd Tanous BMCWEB_LOG_DEBUG( 158362598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 158462598e31SEd Tanous subtree.size()); 15851c05dae3SAli Ahmed // Throw an internal Error and return 1586ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15871c05dae3SAli Ahmed return; 15881c05dae3SAli Ahmed } 15891c05dae3SAli Ahmed 15901c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15911c05dae3SAli Ahmed // field 15921c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15931c05dae3SAli Ahmed { 159462598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1595ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15961c05dae3SAli Ahmed return; 15971c05dae3SAli Ahmed } 15981c05dae3SAli Ahmed 15991c05dae3SAli Ahmed const std::string& path = subtree[0].first; 16001c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 16011c05dae3SAli Ahmed 16021c05dae3SAli Ahmed if (serv.empty()) 16031c05dae3SAli Ahmed { 160462598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1605ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16061c05dae3SAli Ahmed return; 16071c05dae3SAli Ahmed } 16081c05dae3SAli Ahmed 16091c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 16109ae226faSGeorge Liu sdbusplus::asio::setProperty( 16119ae226faSGeorge Liu *crow::connections::systemBus, serv, path, 16129ae226faSGeorge Liu "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired, 1613ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 16148a592810SEd Tanous if (ec2) 16151c05dae3SAli Ahmed { 1616b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 161762598e31SEd Tanous "DBUS response error: Set TrustedModuleRequiredToBoot{}", 161862598e31SEd Tanous ec2); 1619ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16201c05dae3SAli Ahmed return; 16211c05dae3SAli Ahmed } 162262598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done."); 16239ae226faSGeorge Liu }); 1624e99073f5SGeorge Liu }); 16251c05dae3SAli Ahmed } 16261c05dae3SAli Ahmed 16271c05dae3SAli Ahmed /** 1628491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1629491d8ee7SSantosh Puranik * 1630ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1631cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1632cd9a4666SKonstantin Aladyshev * @return Integer error code. 1633cd9a4666SKonstantin Aladyshev */ 1634ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1635cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1636cd9a4666SKonstantin Aladyshev { 1637c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1638cd9a4666SKonstantin Aladyshev 1639c21865c4SKonstantin Aladyshev if (!bootType) 1640cd9a4666SKonstantin Aladyshev { 1641c21865c4SKonstantin Aladyshev return; 1642c21865c4SKonstantin Aladyshev } 1643c21865c4SKonstantin Aladyshev 1644cd9a4666SKonstantin Aladyshev // Source target specified 164562598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1646cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1647cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1648cd9a4666SKonstantin Aladyshev { 1649cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1650cd9a4666SKonstantin Aladyshev } 1651cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1652cd9a4666SKonstantin Aladyshev { 1653cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1654cd9a4666SKonstantin Aladyshev } 1655cd9a4666SKonstantin Aladyshev else 1656cd9a4666SKonstantin Aladyshev { 165762598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 165862598e31SEd Tanous "BootSourceOverrideMode: {}", 165962598e31SEd Tanous *bootType); 1660ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1661cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1662cd9a4666SKonstantin Aladyshev return; 1663cd9a4666SKonstantin Aladyshev } 1664cd9a4666SKonstantin Aladyshev 1665cd9a4666SKonstantin Aladyshev // Act on validated parameters 166662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1667cd9a4666SKonstantin Aladyshev 16689ae226faSGeorge Liu sdbusplus::asio::setProperty( 16699ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 16709ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 16719ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr, 1672ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1673cd9a4666SKonstantin Aladyshev if (ec) 1674cd9a4666SKonstantin Aladyshev { 1675cd9a4666SKonstantin Aladyshev if (ec.value() == boost::asio::error::host_unreachable) 1676cd9a4666SKonstantin Aladyshev { 1677ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Set", "BootType"); 1678cd9a4666SKonstantin Aladyshev return; 1679cd9a4666SKonstantin Aladyshev } 1680b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1681ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1682cd9a4666SKonstantin Aladyshev return; 1683cd9a4666SKonstantin Aladyshev } 168462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type update done."); 16859ae226faSGeorge Liu }); 1686cd9a4666SKonstantin Aladyshev } 1687cd9a4666SKonstantin Aladyshev 1688cd9a4666SKonstantin Aladyshev /** 1689cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1690cd9a4666SKonstantin Aladyshev * 1691ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1692ac106bf6SEd Tanous * message. 1693c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1694c21865c4SKonstantin Aladyshev * @return Integer error code. 1695c21865c4SKonstantin Aladyshev */ 1696ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1697c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1698c21865c4SKonstantin Aladyshev { 1699c21865c4SKonstantin Aladyshev if (!bootEnable) 1700c21865c4SKonstantin Aladyshev { 1701c21865c4SKonstantin Aladyshev return; 1702c21865c4SKonstantin Aladyshev } 1703c21865c4SKonstantin Aladyshev // Source target specified 170462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1705c21865c4SKonstantin Aladyshev 1706c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1707c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1708c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1709c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1710c21865c4SKonstantin Aladyshev { 1711c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1712c21865c4SKonstantin Aladyshev } 1713c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1714c21865c4SKonstantin Aladyshev { 1715c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1716c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1717c21865c4SKonstantin Aladyshev } 1718c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1719c21865c4SKonstantin Aladyshev { 1720c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1721c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1722c21865c4SKonstantin Aladyshev } 1723c21865c4SKonstantin Aladyshev else 1724c21865c4SKonstantin Aladyshev { 172562598e31SEd Tanous BMCWEB_LOG_DEBUG( 172662598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 172762598e31SEd Tanous *bootEnable); 1728ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1729c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1730c21865c4SKonstantin Aladyshev return; 1731c21865c4SKonstantin Aladyshev } 1732c21865c4SKonstantin Aladyshev 1733c21865c4SKonstantin Aladyshev // Act on validated parameters 173462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1735c21865c4SKonstantin Aladyshev 17369ae226faSGeorge Liu sdbusplus::asio::setProperty( 17379ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17389ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 17399ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable, 1740ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 17418a592810SEd Tanous if (ec2) 1742c21865c4SKonstantin Aladyshev { 1743b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 1744ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1745c21865c4SKonstantin Aladyshev return; 1746c21865c4SKonstantin Aladyshev } 174762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot override enable update done."); 17489ae226faSGeorge Liu }); 1749c21865c4SKonstantin Aladyshev 1750c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1751c21865c4SKonstantin Aladyshev { 1752c21865c4SKonstantin Aladyshev return; 1753c21865c4SKonstantin Aladyshev } 1754c21865c4SKonstantin Aladyshev 1755c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1756c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 175762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 175862598e31SEd Tanous bootOverridePersistent); 1759c21865c4SKonstantin Aladyshev 17609ae226faSGeorge Liu sdbusplus::asio::setProperty( 17619ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 17629ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot/one_time", 17639ae226faSGeorge Liu "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent, 1764ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1765c21865c4SKonstantin Aladyshev if (ec) 1766c21865c4SKonstantin Aladyshev { 1767b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1768ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1769c21865c4SKonstantin Aladyshev return; 1770c21865c4SKonstantin Aladyshev } 177162598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot one_time update done."); 17729ae226faSGeorge Liu }); 1773c21865c4SKonstantin Aladyshev } 1774c21865c4SKonstantin Aladyshev 1775c21865c4SKonstantin Aladyshev /** 1776c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1777c21865c4SKonstantin Aladyshev * 1778ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1779491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1780491d8ee7SSantosh Puranik * 1781265c1602SJohnathan Mantey * @return Integer error code. 1782491d8ee7SSantosh Puranik */ 1783ac106bf6SEd Tanous inline void 1784ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1785cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1786491d8ee7SSantosh Puranik { 1787c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1788c21865c4SKonstantin Aladyshev std::string bootModeStr; 1789944ffaf9SJohnathan Mantey 1790c21865c4SKonstantin Aladyshev if (!bootSource) 1791491d8ee7SSantosh Puranik { 1792c21865c4SKonstantin Aladyshev return; 1793c21865c4SKonstantin Aladyshev } 1794c21865c4SKonstantin Aladyshev 1795491d8ee7SSantosh Puranik // Source target specified 179662598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1797491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1798ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1799ac106bf6SEd Tanous bootModeStr) != 0) 1800491d8ee7SSantosh Puranik { 180162598e31SEd Tanous BMCWEB_LOG_DEBUG( 180262598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 180362598e31SEd Tanous *bootSource); 1804ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1805491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1806491d8ee7SSantosh Puranik return; 1807491d8ee7SSantosh Puranik } 1808491d8ee7SSantosh Puranik 1809944ffaf9SJohnathan Mantey // Act on validated parameters 181062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 181162598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1812944ffaf9SJohnathan Mantey 18139ae226faSGeorge Liu sdbusplus::asio::setProperty( 18149ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 18159ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 18169ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr, 1817ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1818491d8ee7SSantosh Puranik if (ec) 1819491d8ee7SSantosh Puranik { 1820b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1821ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1822491d8ee7SSantosh Puranik return; 1823491d8ee7SSantosh Puranik } 182462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source update done."); 18259ae226faSGeorge Liu }); 1826944ffaf9SJohnathan Mantey 18279ae226faSGeorge Liu sdbusplus::asio::setProperty( 18289ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 18299ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/boot", 18309ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr, 1831ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 1832491d8ee7SSantosh Puranik if (ec) 1833491d8ee7SSantosh Puranik { 1834b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1835ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1836491d8ee7SSantosh Puranik return; 1837491d8ee7SSantosh Puranik } 183862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode update done."); 18399ae226faSGeorge Liu }); 1840cd9a4666SKonstantin Aladyshev } 1841944ffaf9SJohnathan Mantey 1842cd9a4666SKonstantin Aladyshev /** 1843c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1844491d8ee7SSantosh Puranik * 1845ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1846491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1847cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1848491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1849491d8ee7SSantosh Puranik * 1850265c1602SJohnathan Mantey * @return Integer error code. 1851491d8ee7SSantosh Puranik */ 1852c21865c4SKonstantin Aladyshev 1853ac106bf6SEd Tanous inline void 1854ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1855c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1856c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1857c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1858491d8ee7SSantosh Puranik { 185962598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1860491d8ee7SSantosh Puranik 1861ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1862ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1863ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1864491d8ee7SSantosh Puranik } 1865491d8ee7SSantosh Puranik 1866c6a620f2SGeorge Liu /** 186798e386ecSGunnar Mills * @brief Sets AssetTag 186898e386ecSGunnar Mills * 1869ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 187098e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 187198e386ecSGunnar Mills * 187298e386ecSGunnar Mills * @return None. 187398e386ecSGunnar Mills */ 1874ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 187598e386ecSGunnar Mills const std::string& assetTag) 187698e386ecSGunnar Mills { 1877e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1878e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1879e99073f5SGeorge Liu dbus::utility::getSubTree( 1880e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1881ac106bf6SEd Tanous [asyncResp, 1882e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1883b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 188498e386ecSGunnar Mills if (ec) 188598e386ecSGunnar Mills { 188662598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1887ac106bf6SEd Tanous messages::internalError(asyncResp->res); 188898e386ecSGunnar Mills return; 188998e386ecSGunnar Mills } 189026f6976fSEd Tanous if (subtree.empty()) 189198e386ecSGunnar Mills { 189262598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1893ac106bf6SEd Tanous messages::internalError(asyncResp->res); 189498e386ecSGunnar Mills return; 189598e386ecSGunnar Mills } 189698e386ecSGunnar Mills // Assume only 1 system D-Bus object 189798e386ecSGunnar Mills // Throw an error if there is more than 1 189898e386ecSGunnar Mills if (subtree.size() > 1) 189998e386ecSGunnar Mills { 190062598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1901ac106bf6SEd Tanous messages::internalError(asyncResp->res); 190298e386ecSGunnar Mills return; 190398e386ecSGunnar Mills } 190498e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 190598e386ecSGunnar Mills { 190662598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1907ac106bf6SEd Tanous messages::internalError(asyncResp->res); 190898e386ecSGunnar Mills return; 190998e386ecSGunnar Mills } 191098e386ecSGunnar Mills 191198e386ecSGunnar Mills const std::string& path = subtree[0].first; 191298e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 191398e386ecSGunnar Mills 191498e386ecSGunnar Mills if (service.empty()) 191598e386ecSGunnar Mills { 191662598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1917ac106bf6SEd Tanous messages::internalError(asyncResp->res); 191898e386ecSGunnar Mills return; 191998e386ecSGunnar Mills } 192098e386ecSGunnar Mills 19219ae226faSGeorge Liu sdbusplus::asio::setProperty( 19229ae226faSGeorge Liu *crow::connections::systemBus, service, path, 19239ae226faSGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag", 19249ae226faSGeorge Liu assetTag, [asyncResp](const boost::system::error_code& ec2) { 192598e386ecSGunnar Mills if (ec2) 192698e386ecSGunnar Mills { 1927b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}", 192862598e31SEd Tanous ec2); 1929ac106bf6SEd Tanous messages::internalError(asyncResp->res); 193098e386ecSGunnar Mills return; 193198e386ecSGunnar Mills } 19329ae226faSGeorge Liu }); 1933e99073f5SGeorge Liu }); 193498e386ecSGunnar Mills } 193598e386ecSGunnar Mills 193698e386ecSGunnar Mills /** 19379dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 19389dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 19399dcfe8c1SAlbert Zhang * 19409dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 19419dcfe8c1SAlbert Zhang * stopBootOnFault 19429dcfe8c1SAlbert Zhang * 19439dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 19449dcfe8c1SAlbert Zhang */ 19459dcfe8c1SAlbert Zhang inline std::optional<bool> 19469dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 19479dcfe8c1SAlbert Zhang { 19489dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 19499dcfe8c1SAlbert Zhang { 19509dcfe8c1SAlbert Zhang return true; 19519dcfe8c1SAlbert Zhang } 19529dcfe8c1SAlbert Zhang 19539dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 19549dcfe8c1SAlbert Zhang { 19559dcfe8c1SAlbert Zhang return false; 19569dcfe8c1SAlbert Zhang } 19579dcfe8c1SAlbert Zhang 19589dcfe8c1SAlbert Zhang return std::nullopt; 19599dcfe8c1SAlbert Zhang } 19609dcfe8c1SAlbert Zhang 19619dcfe8c1SAlbert Zhang /** 19629dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 19639dcfe8c1SAlbert Zhang * 1964fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 19659dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 19669dcfe8c1SAlbert Zhang * 19679dcfe8c1SAlbert Zhang * @return None. 19689dcfe8c1SAlbert Zhang */ 1969fc3edfddSEd Tanous inline void 1970fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19719dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 19729dcfe8c1SAlbert Zhang { 197362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 19749dcfe8c1SAlbert Zhang 19759dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 19769dcfe8c1SAlbert Zhang if (!stopBootEnabled) 19779dcfe8c1SAlbert Zhang { 197862598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 197962598e31SEd Tanous stopBootOnFault); 1980fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 19819dcfe8c1SAlbert Zhang "StopBootOnFault"); 19829dcfe8c1SAlbert Zhang return; 19839dcfe8c1SAlbert Zhang } 19849dcfe8c1SAlbert Zhang 1985fc3edfddSEd Tanous sdbusplus::asio::setProperty( 1986fc3edfddSEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 19879dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 1988fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1989fc3edfddSEd Tanous *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) { 19909dcfe8c1SAlbert Zhang if (ec) 19919dcfe8c1SAlbert Zhang { 19929dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 19939dcfe8c1SAlbert Zhang { 1994b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1995fc3edfddSEd Tanous messages::internalError(asyncResp->res); 19969dcfe8c1SAlbert Zhang } 19979dcfe8c1SAlbert Zhang return; 19989dcfe8c1SAlbert Zhang } 19999dcfe8c1SAlbert Zhang }); 20009dcfe8c1SAlbert Zhang } 20019dcfe8c1SAlbert Zhang 20029dcfe8c1SAlbert Zhang /** 200369f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 200469f35306SGunnar Mills * 2005ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 200669f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 200769f35306SGunnar Mills * 200869f35306SGunnar Mills * @return None. 200969f35306SGunnar Mills */ 2010ac106bf6SEd Tanous inline void 2011ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2012f23b7296SEd Tanous const std::string& automaticRetryConfig) 201369f35306SGunnar Mills { 201462598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 201569f35306SGunnar Mills 201669f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 2017543f4400SEd Tanous bool autoRebootEnabled = false; 201869f35306SGunnar Mills 201969f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 202069f35306SGunnar Mills { 202169f35306SGunnar Mills autoRebootEnabled = false; 202269f35306SGunnar Mills } 202369f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 202469f35306SGunnar Mills { 202569f35306SGunnar Mills autoRebootEnabled = true; 202669f35306SGunnar Mills } 202769f35306SGunnar Mills else 202869f35306SGunnar Mills { 202962598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 203062598e31SEd Tanous automaticRetryConfig); 2031ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 203269f35306SGunnar Mills "AutomaticRetryConfig"); 203369f35306SGunnar Mills return; 203469f35306SGunnar Mills } 203569f35306SGunnar Mills 20369ae226faSGeorge Liu sdbusplus::asio::setProperty( 20379ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20389ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/auto_reboot", 20399ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 20409ae226faSGeorge Liu autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) { 204169f35306SGunnar Mills if (ec) 204269f35306SGunnar Mills { 2043b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2044ac106bf6SEd Tanous messages::internalError(asyncResp->res); 204569f35306SGunnar Mills return; 204669f35306SGunnar Mills } 20479ae226faSGeorge Liu }); 204869f35306SGunnar Mills } 204969f35306SGunnar Mills 20508d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 20518d69c668SEd Tanous { 20528d69c668SEd Tanous if (policy == "AlwaysOn") 20538d69c668SEd Tanous { 20548d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 20558d69c668SEd Tanous } 20568d69c668SEd Tanous if (policy == "AlwaysOff") 20578d69c668SEd Tanous { 20588d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 20598d69c668SEd Tanous } 20608d69c668SEd Tanous if (policy == "LastState") 20618d69c668SEd Tanous { 20628d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 20638d69c668SEd Tanous } 20648d69c668SEd Tanous return ""; 20658d69c668SEd Tanous } 20668d69c668SEd Tanous 206769f35306SGunnar Mills /** 2068c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 2069c6a620f2SGeorge Liu * 2070ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2071c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 2072c6a620f2SGeorge Liu * 2073c6a620f2SGeorge Liu * @return None. 2074c6a620f2SGeorge Liu */ 20758d1b46d7Szhanghch05 inline void 2076ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20778d69c668SEd Tanous std::string_view policy) 2078c6a620f2SGeorge Liu { 207962598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 2080c6a620f2SGeorge Liu 20818d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 2082c6a620f2SGeorge Liu 20838d69c668SEd Tanous if (powerRestorePolicy.empty()) 2084c6a620f2SGeorge Liu { 2085ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 20864e69c904SGunnar Mills "PowerRestorePolicy"); 2087c6a620f2SGeorge Liu return; 2088c6a620f2SGeorge Liu } 2089c6a620f2SGeorge Liu 20909ae226faSGeorge Liu sdbusplus::asio::setProperty( 20919ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Settings", 20929ae226faSGeorge Liu "/xyz/openbmc_project/control/host0/power_restore_policy", 20939ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 20949ae226faSGeorge Liu powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) { 2095c6a620f2SGeorge Liu if (ec) 2096c6a620f2SGeorge Liu { 2097b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2098ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2099c6a620f2SGeorge Liu return; 2100c6a620f2SGeorge Liu } 21019ae226faSGeorge Liu }); 2102c6a620f2SGeorge Liu } 2103c6a620f2SGeorge Liu 2104a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 2105a6349918SAppaRao Puli /** 2106a6349918SAppaRao Puli * @brief Retrieves provisioning status 2107a6349918SAppaRao Puli * 2108ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 2109a6349918SAppaRao Puli * 2110a6349918SAppaRao Puli * @return None. 2111a6349918SAppaRao Puli */ 2112ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp) 2113a6349918SAppaRao Puli { 211462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 2115bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2116bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 2117bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 2118ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2119b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 2120b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 2121ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 2122ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 212350626f4fSJames Feist "#OemComputerSystem.OpenBmc"; 212450626f4fSJames Feist oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning"; 212550626f4fSJames Feist 2126a6349918SAppaRao Puli if (ec) 2127a6349918SAppaRao Puli { 212862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 2129b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2130b99fb1a9SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2131a6349918SAppaRao Puli return; 2132a6349918SAppaRao Puli } 2133a6349918SAppaRao Puli 2134a6349918SAppaRao Puli const bool* provState = nullptr; 2135a6349918SAppaRao Puli const bool* lockState = nullptr; 2136bc1d29deSKrzysztof Grobelny 2137bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 21380d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 21390d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 2140bc1d29deSKrzysztof Grobelny 2141bc1d29deSKrzysztof Grobelny if (!success) 2142a6349918SAppaRao Puli { 2143ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2144bc1d29deSKrzysztof Grobelny return; 2145a6349918SAppaRao Puli } 2146a6349918SAppaRao Puli 2147a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2148a6349918SAppaRao Puli { 214962598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 2150ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2151a6349918SAppaRao Puli return; 2152a6349918SAppaRao Puli } 2153a6349918SAppaRao Puli 2154a6349918SAppaRao Puli if (*provState == true) 2155a6349918SAppaRao Puli { 2156a6349918SAppaRao Puli if (*lockState == true) 2157a6349918SAppaRao Puli { 2158a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked"; 2159a6349918SAppaRao Puli } 2160a6349918SAppaRao Puli else 2161a6349918SAppaRao Puli { 2162a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked"; 2163a6349918SAppaRao Puli } 2164a6349918SAppaRao Puli } 2165a6349918SAppaRao Puli else 2166a6349918SAppaRao Puli { 2167a6349918SAppaRao Puli oemPFR["ProvisioningStatus"] = "NotProvisioned"; 2168a6349918SAppaRao Puli } 2169bc1d29deSKrzysztof Grobelny }); 2170a6349918SAppaRao Puli } 2171a6349918SAppaRao Puli #endif 2172a6349918SAppaRao Puli 2173491d8ee7SSantosh Puranik /** 21746b9ac4f2SChris Cain * @brief Translate the PowerMode string to enum value 21753a2d0424SChris Cain * 21766b9ac4f2SChris Cain * @param[in] modeString PowerMode string to be translated 21773a2d0424SChris Cain * 21786b9ac4f2SChris Cain * @return PowerMode enum 21793a2d0424SChris Cain */ 21806b9ac4f2SChris Cain inline computer_system::PowerMode 21816b9ac4f2SChris Cain translatePowerModeString(const std::string& modeString) 21823a2d0424SChris Cain { 2183b6655101SChris Cain using PowerMode = computer_system::PowerMode; 2184b6655101SChris Cain 21856b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 21863a2d0424SChris Cain { 21876b9ac4f2SChris Cain return PowerMode::Static; 21883a2d0424SChris Cain } 21896b9ac4f2SChris Cain if (modeString == 21900fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 21913a2d0424SChris Cain { 21926b9ac4f2SChris Cain return PowerMode::MaximumPerformance; 21933a2d0424SChris Cain } 21946b9ac4f2SChris Cain if (modeString == 21950fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 21963a2d0424SChris Cain { 21976b9ac4f2SChris Cain return PowerMode::PowerSaving; 2198b6655101SChris Cain } 21996b9ac4f2SChris Cain if (modeString == 2200b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance") 2201b6655101SChris Cain { 22026b9ac4f2SChris Cain return PowerMode::BalancedPerformance; 2203b6655101SChris Cain } 22046b9ac4f2SChris Cain if (modeString == 2205b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance") 2206b6655101SChris Cain { 22076b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPerformance; 2208b6655101SChris Cain } 22096b9ac4f2SChris Cain if (modeString == 2210b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower") 2211b6655101SChris Cain { 22126b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPower; 22133a2d0424SChris Cain } 22146b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 22153a2d0424SChris Cain { 22166b9ac4f2SChris Cain return PowerMode::OEM; 22176b9ac4f2SChris Cain } 22186b9ac4f2SChris Cain // Any other values would be invalid 22196b9ac4f2SChris Cain BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString); 22206b9ac4f2SChris Cain return PowerMode::Invalid; 22216b9ac4f2SChris Cain } 22226b9ac4f2SChris Cain 22236b9ac4f2SChris Cain inline void 22246b9ac4f2SChris Cain afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22256b9ac4f2SChris Cain const boost::system::error_code& ec, 22266b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) 22276b9ac4f2SChris Cain { 22286b9ac4f2SChris Cain if (ec) 22296b9ac4f2SChris Cain { 22306b9ac4f2SChris Cain BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec); 22316b9ac4f2SChris Cain messages::internalError(asyncResp->res); 22326b9ac4f2SChris Cain return; 22336b9ac4f2SChris Cain } 22346b9ac4f2SChris Cain 22356b9ac4f2SChris Cain std::string powerMode; 22366b9ac4f2SChris Cain const std::vector<std::string>* allowedModes = nullptr; 22376b9ac4f2SChris Cain const bool success = sdbusplus::unpackPropertiesNoThrow( 22386b9ac4f2SChris Cain dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode, 22396b9ac4f2SChris Cain "AllowedPowerModes", allowedModes); 22406b9ac4f2SChris Cain 22416b9ac4f2SChris Cain if (!success) 22426b9ac4f2SChris Cain { 22436b9ac4f2SChris Cain messages::internalError(asyncResp->res); 22446b9ac4f2SChris Cain return; 22456b9ac4f2SChris Cain } 22466b9ac4f2SChris Cain 22476b9ac4f2SChris Cain nlohmann::json::array_t modeList; 22486b9ac4f2SChris Cain if (allowedModes == nullptr) 22496b9ac4f2SChris Cain { 22506b9ac4f2SChris Cain modeList.emplace_back("Static"); 22516b9ac4f2SChris Cain modeList.emplace_back("MaximumPerformance"); 22526b9ac4f2SChris Cain modeList.emplace_back("PowerSaving"); 22533a2d0424SChris Cain } 22543a2d0424SChris Cain else 22553a2d0424SChris Cain { 22566b9ac4f2SChris Cain for (const auto& aMode : *allowedModes) 22576b9ac4f2SChris Cain { 22586b9ac4f2SChris Cain computer_system::PowerMode modeValue = 22596b9ac4f2SChris Cain translatePowerModeString(aMode); 22606b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 22616b9ac4f2SChris Cain { 2262ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22636b9ac4f2SChris Cain continue; 22646b9ac4f2SChris Cain } 22656b9ac4f2SChris Cain modeList.emplace_back(modeValue); 22663a2d0424SChris Cain } 22673a2d0424SChris Cain } 22686b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList; 22693a2d0424SChris Cain 22706b9ac4f2SChris Cain BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode); 22716b9ac4f2SChris Cain const computer_system::PowerMode modeValue = 22726b9ac4f2SChris Cain translatePowerModeString(powerMode); 22736b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 22746b9ac4f2SChris Cain { 22756b9ac4f2SChris Cain messages::internalError(asyncResp->res); 22766b9ac4f2SChris Cain return; 22776b9ac4f2SChris Cain } 22786b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode"] = modeValue; 22796b9ac4f2SChris Cain } 22803a2d0424SChris Cain /** 22813a2d0424SChris Cain * @brief Retrieves system power mode 22823a2d0424SChris Cain * 2283ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22843a2d0424SChris Cain * 22853a2d0424SChris Cain * @return None. 22863a2d0424SChris Cain */ 2287ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 22883a2d0424SChris Cain { 228962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 22903a2d0424SChris Cain 22913a2d0424SChris Cain // Get Power Mode object path: 2292e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2293e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2294e99073f5SGeorge Liu dbus::utility::getSubTree( 2295e99073f5SGeorge Liu "/", 0, interfaces, 2296ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2297b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22983a2d0424SChris Cain if (ec) 22993a2d0424SChris Cain { 230062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}", 230162598e31SEd Tanous ec); 23023a2d0424SChris Cain // This is an optional D-Bus object so just return if 23033a2d0424SChris Cain // error occurs 23043a2d0424SChris Cain return; 23053a2d0424SChris Cain } 23063a2d0424SChris Cain if (subtree.empty()) 23073a2d0424SChris Cain { 23083a2d0424SChris Cain // As noted above, this is an optional interface so just return 23093a2d0424SChris Cain // if there is no instance found 23103a2d0424SChris Cain return; 23113a2d0424SChris Cain } 23123a2d0424SChris Cain if (subtree.size() > 1) 23133a2d0424SChris Cain { 23143a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23153a2d0424SChris Cain // error 231662598e31SEd Tanous BMCWEB_LOG_DEBUG( 231762598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 231862598e31SEd Tanous subtree.size()); 2319ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23203a2d0424SChris Cain return; 23213a2d0424SChris Cain } 23223a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23233a2d0424SChris Cain { 232462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2325ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23263a2d0424SChris Cain return; 23273a2d0424SChris Cain } 23283a2d0424SChris Cain const std::string& path = subtree[0].first; 23293a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23303a2d0424SChris Cain if (service.empty()) 23313a2d0424SChris Cain { 233262598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2333ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23343a2d0424SChris Cain return; 23353a2d0424SChris Cain } 23366b9ac4f2SChris Cain 23376b9ac4f2SChris Cain // Valid Power Mode object found, now read the mode properties 23386b9ac4f2SChris Cain sdbusplus::asio::getAllProperties( 23391e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 23406b9ac4f2SChris Cain "xyz.openbmc_project.Control.Power.Mode", 2341ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 23426b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 23436b9ac4f2SChris Cain afterGetPowerMode(asyncResp, ec2, properties); 23441e1e598dSJonathan Doman }); 2345e99073f5SGeorge Liu }); 23463a2d0424SChris Cain } 23473a2d0424SChris Cain 23483a2d0424SChris Cain /** 23493a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 23503a2d0424SChris Cain * name associated with that string 23513a2d0424SChris Cain * 2352ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2353b6655101SChris Cain * @param[in] modeValue String representing the desired PowerMode 23543a2d0424SChris Cain * 23553a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 23563a2d0424SChris Cain */ 23573a2d0424SChris Cain inline std::string 2358ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2359b6655101SChris Cain const nlohmann::json& modeValue) 23603a2d0424SChris Cain { 2361b6655101SChris Cain using PowerMode = computer_system::PowerMode; 23623a2d0424SChris Cain std::string mode; 23633a2d0424SChris Cain 2364b6655101SChris Cain if (modeValue == PowerMode::Static) 23653a2d0424SChris Cain { 23663a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 23673a2d0424SChris Cain } 2368b6655101SChris Cain else if (modeValue == PowerMode::MaximumPerformance) 23693a2d0424SChris Cain { 23700fda0f12SGeorge Liu mode = 23710fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 23723a2d0424SChris Cain } 2373b6655101SChris Cain else if (modeValue == PowerMode::PowerSaving) 23743a2d0424SChris Cain { 23753a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 23763a2d0424SChris Cain } 2377b6655101SChris Cain else if (modeValue == PowerMode::BalancedPerformance) 2378b6655101SChris Cain { 2379b6655101SChris Cain mode = 2380b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance"; 2381b6655101SChris Cain } 2382b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPerformance) 2383b6655101SChris Cain { 2384b6655101SChris Cain mode = 2385b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance"; 2386b6655101SChris Cain } 2387b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPower) 2388b6655101SChris Cain { 2389b6655101SChris Cain mode = 2390b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower"; 2391b6655101SChris Cain } 23923a2d0424SChris Cain else 23933a2d0424SChris Cain { 2394b6655101SChris Cain messages::propertyValueNotInList(asyncResp->res, modeValue.dump(), 2395ac106bf6SEd Tanous "PowerMode"); 23963a2d0424SChris Cain } 23973a2d0424SChris Cain return mode; 23983a2d0424SChris Cain } 23993a2d0424SChris Cain 24003a2d0424SChris Cain /** 24013a2d0424SChris Cain * @brief Sets system power mode. 24023a2d0424SChris Cain * 2403ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 24043a2d0424SChris Cain * @param[in] pmode System power mode from request. 24053a2d0424SChris Cain * 24063a2d0424SChris Cain * @return None. 24073a2d0424SChris Cain */ 2408ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 24093a2d0424SChris Cain const std::string& pmode) 24103a2d0424SChris Cain { 241162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 24123a2d0424SChris Cain 2413ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 24143a2d0424SChris Cain if (powerMode.empty()) 24153a2d0424SChris Cain { 24163a2d0424SChris Cain return; 24173a2d0424SChris Cain } 24183a2d0424SChris Cain 24193a2d0424SChris Cain // Get Power Mode object path: 2420e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2421e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2422e99073f5SGeorge Liu dbus::utility::getSubTree( 2423e99073f5SGeorge Liu "/", 0, interfaces, 2424ac106bf6SEd Tanous [asyncResp, 2425e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2426b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 24273a2d0424SChris Cain if (ec) 24283a2d0424SChris Cain { 2429b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}", 243062598e31SEd Tanous ec); 24313a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2432ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24333a2d0424SChris Cain return; 24343a2d0424SChris Cain } 24353a2d0424SChris Cain if (subtree.empty()) 24363a2d0424SChris Cain { 24373a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2438ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 24393a2d0424SChris Cain "PowerMode"); 24403a2d0424SChris Cain return; 24413a2d0424SChris Cain } 24423a2d0424SChris Cain if (subtree.size() > 1) 24433a2d0424SChris Cain { 24443a2d0424SChris Cain // More then one PowerMode object is not supported and is an 24453a2d0424SChris Cain // error 244662598e31SEd Tanous BMCWEB_LOG_DEBUG( 244762598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 244862598e31SEd Tanous subtree.size()); 2449ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24503a2d0424SChris Cain return; 24513a2d0424SChris Cain } 24523a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 24533a2d0424SChris Cain { 245462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2455ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24563a2d0424SChris Cain return; 24573a2d0424SChris Cain } 24583a2d0424SChris Cain const std::string& path = subtree[0].first; 24593a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 24603a2d0424SChris Cain if (service.empty()) 24613a2d0424SChris Cain { 246262598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2463ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24643a2d0424SChris Cain return; 24653a2d0424SChris Cain } 24663a2d0424SChris Cain 246762598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 24683a2d0424SChris Cain 24693a2d0424SChris Cain // Set the Power Mode property 24709ae226faSGeorge Liu sdbusplus::asio::setProperty( 24719ae226faSGeorge Liu *crow::connections::systemBus, service, path, 24729ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode, 2473ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 24748a592810SEd Tanous if (ec2) 24753a2d0424SChris Cain { 2476b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2477ac106bf6SEd Tanous messages::internalError(asyncResp->res); 24783a2d0424SChris Cain return; 24793a2d0424SChris Cain } 24809ae226faSGeorge Liu }); 2481e99073f5SGeorge Liu }); 24823a2d0424SChris Cain } 24833a2d0424SChris Cain 24843a2d0424SChris Cain /** 248551709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 248651709ffdSYong Li * 248751709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 248851709ffdSYong Li * 248951709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 249051709ffdSYong Li * translation cannot be done, returns an empty string. 249151709ffdSYong Li */ 249223a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 249351709ffdSYong Li { 249451709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 249551709ffdSYong Li { 249651709ffdSYong Li return "None"; 249751709ffdSYong Li } 24983174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 249951709ffdSYong Li { 250051709ffdSYong Li return "ResetSystem"; 250151709ffdSYong Li } 25023174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 250351709ffdSYong Li { 250451709ffdSYong Li return "PowerDown"; 250551709ffdSYong Li } 25063174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 250751709ffdSYong Li { 250851709ffdSYong Li return "PowerCycle"; 250951709ffdSYong Li } 251051709ffdSYong Li 251151709ffdSYong Li return ""; 251251709ffdSYong Li } 251351709ffdSYong Li 251451709ffdSYong Li /** 2515c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2516c45f0082SYong Li * 2517c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2518c45f0082SYong Li * 2519c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2520c45f0082SYong Li *If translation cannot be done, returns an empty string. 2521c45f0082SYong Li */ 2522c45f0082SYong Li 252323a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2524c45f0082SYong Li { 2525c45f0082SYong Li if (rfAction == "None") 2526c45f0082SYong Li { 2527c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2528c45f0082SYong Li } 25293174e4dfSEd Tanous if (rfAction == "PowerCycle") 2530c45f0082SYong Li { 2531c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2532c45f0082SYong Li } 25333174e4dfSEd Tanous if (rfAction == "PowerDown") 2534c45f0082SYong Li { 2535c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2536c45f0082SYong Li } 25373174e4dfSEd Tanous if (rfAction == "ResetSystem") 2538c45f0082SYong Li { 2539c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2540c45f0082SYong Li } 2541c45f0082SYong Li 2542c45f0082SYong Li return ""; 2543c45f0082SYong Li } 2544c45f0082SYong Li 2545c45f0082SYong Li /** 254651709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 254751709ffdSYong Li * 2548ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 254951709ffdSYong Li * 255051709ffdSYong Li * @return None. 255151709ffdSYong Li */ 25528d1b46d7Szhanghch05 inline void 2553ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 255451709ffdSYong Li { 255562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2556bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2557bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2558bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2559bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2560ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2561b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 256251709ffdSYong Li if (ec) 256351709ffdSYong Li { 256451709ffdSYong Li // watchdog service is stopped 256562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 256651709ffdSYong Li return; 256751709ffdSYong Li } 256851709ffdSYong Li 256962598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 257051709ffdSYong Li 257151709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2572ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 257351709ffdSYong Li 257451709ffdSYong Li // watchdog service is running/enabled 257551709ffdSYong Li hostWatchdogTimer["Status"]["State"] = "Enabled"; 257651709ffdSYong Li 2577bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2578bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 257951709ffdSYong Li 2580bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2581bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2582bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2583bc1d29deSKrzysztof Grobelny 2584bc1d29deSKrzysztof Grobelny if (!success) 258551709ffdSYong Li { 2586ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2587601af5edSChicago Duan return; 258851709ffdSYong Li } 258951709ffdSYong Li 2590bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 259151709ffdSYong Li { 2592bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 259351709ffdSYong Li } 259451709ffdSYong Li 2595bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2596bc1d29deSKrzysztof Grobelny { 2597bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 259851709ffdSYong Li if (action.empty()) 259951709ffdSYong Li { 2600ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2601601af5edSChicago Duan return; 260251709ffdSYong Li } 260351709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 260451709ffdSYong Li } 2605bc1d29deSKrzysztof Grobelny }); 260651709ffdSYong Li } 260751709ffdSYong Li 260851709ffdSYong Li /** 2609c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2610c45f0082SYong Li * 2611ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2612c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2613c45f0082SYong Li * RF request. 2614c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2615c45f0082SYong Li * 2616c45f0082SYong Li * @return None. 2617c45f0082SYong Li */ 2618ac106bf6SEd Tanous inline void 2619ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2620c45f0082SYong Li const std::optional<bool> wdtEnable, 2621c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2622c45f0082SYong Li { 262362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2624c45f0082SYong Li 2625c45f0082SYong Li if (wdtTimeOutAction) 2626c45f0082SYong Li { 2627c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2628c45f0082SYong Li // check if TimeOut Action is Valid 2629c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2630c45f0082SYong Li { 263162598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 263262598e31SEd Tanous *wdtTimeOutAction); 2633ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2634c45f0082SYong Li "TimeoutAction"); 2635c45f0082SYong Li return; 2636c45f0082SYong Li } 2637c45f0082SYong Li 26389ae226faSGeorge Liu sdbusplus::asio::setProperty( 26399ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 26409ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 26419ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 26429ae226faSGeorge Liu wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) { 2643c45f0082SYong Li if (ec) 2644c45f0082SYong Li { 2645b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2646ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2647c45f0082SYong Li return; 2648c45f0082SYong Li } 26499ae226faSGeorge Liu }); 2650c45f0082SYong Li } 2651c45f0082SYong Li 2652c45f0082SYong Li if (wdtEnable) 2653c45f0082SYong Li { 26549ae226faSGeorge Liu sdbusplus::asio::setProperty( 26559ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 26569ae226faSGeorge Liu "/xyz/openbmc_project/watchdog/host0", 26579ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable, 2658ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec) { 2659c45f0082SYong Li if (ec) 2660c45f0082SYong Li { 2661b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 2662ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2663c45f0082SYong Li return; 2664c45f0082SYong Li } 26659ae226faSGeorge Liu }); 2666c45f0082SYong Li } 2667c45f0082SYong Li } 2668c45f0082SYong Li 266937bbf98cSChris Cain /** 267037bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 267137bbf98cSChris Cain * 2672ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 267337bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 267437bbf98cSChris Cain * 267537bbf98cSChris Cain * @return true if successful 267637bbf98cSChris Cain */ 26771e5b7c88SJiaqing Zhao inline bool 2678ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 26791e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 268037bbf98cSChris Cain { 2681bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2682bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2683bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2684bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2685bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2686bc1d29deSKrzysztof Grobelny 2687bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2688bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 26892661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 26902661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 26912661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2692bc1d29deSKrzysztof Grobelny 2693bc1d29deSKrzysztof Grobelny if (!success) 269437bbf98cSChris Cain { 269537bbf98cSChris Cain return false; 269637bbf98cSChris Cain } 2697bc1d29deSKrzysztof Grobelny 2698bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 269937bbf98cSChris Cain { 2700ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 270137bbf98cSChris Cain } 2702bc1d29deSKrzysztof Grobelny 2703bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 270437bbf98cSChris Cain { 2705ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2706bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 270737bbf98cSChris Cain } 2708bc1d29deSKrzysztof Grobelny 2709bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2710bc1d29deSKrzysztof Grobelny { 2711bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2712ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 271337bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 271437bbf98cSChris Cain .count(); 271537bbf98cSChris Cain } 2716bc1d29deSKrzysztof Grobelny 2717bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 271837bbf98cSChris Cain { 2719ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2720bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 272137bbf98cSChris Cain } 2722bc1d29deSKrzysztof Grobelny 2723bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 272437bbf98cSChris Cain { 2725bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2726ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 272737bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 272837bbf98cSChris Cain .count(); 272937bbf98cSChris Cain } 273037bbf98cSChris Cain 273137bbf98cSChris Cain return true; 273237bbf98cSChris Cain } 273337bbf98cSChris Cain 273437bbf98cSChris Cain /** 273537bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 273637bbf98cSChris Cain * 2737ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 273837bbf98cSChris Cain * 273937bbf98cSChris Cain * @return None. 274037bbf98cSChris Cain */ 2741ac106bf6SEd Tanous inline void 2742ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 274337bbf98cSChris Cain { 274462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 274537bbf98cSChris Cain 274637bbf98cSChris Cain // Get IdlePowerSaver object path: 2747e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2748e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2749e99073f5SGeorge Liu dbus::utility::getSubTree( 2750e99073f5SGeorge Liu "/", 0, interfaces, 2751ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2752b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 275337bbf98cSChris Cain if (ec) 275437bbf98cSChris Cain { 2755b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 275662598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 275762598e31SEd Tanous ec); 2758ac106bf6SEd Tanous messages::internalError(asyncResp->res); 275937bbf98cSChris Cain return; 276037bbf98cSChris Cain } 276137bbf98cSChris Cain if (subtree.empty()) 276237bbf98cSChris Cain { 276337bbf98cSChris Cain // This is an optional interface so just return 276437bbf98cSChris Cain // if there is no instance found 276562598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 276637bbf98cSChris Cain return; 276737bbf98cSChris Cain } 276837bbf98cSChris Cain if (subtree.size() > 1) 276937bbf98cSChris Cain { 277037bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 277137bbf98cSChris Cain // is an error 277262598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 277362598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 277462598e31SEd Tanous subtree.size()); 2775ac106bf6SEd Tanous messages::internalError(asyncResp->res); 277637bbf98cSChris Cain return; 277737bbf98cSChris Cain } 277837bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 277937bbf98cSChris Cain { 278062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2781ac106bf6SEd Tanous messages::internalError(asyncResp->res); 278237bbf98cSChris Cain return; 278337bbf98cSChris Cain } 278437bbf98cSChris Cain const std::string& path = subtree[0].first; 278537bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 278637bbf98cSChris Cain if (service.empty()) 278737bbf98cSChris Cain { 278862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2789ac106bf6SEd Tanous messages::internalError(asyncResp->res); 279037bbf98cSChris Cain return; 279137bbf98cSChris Cain } 279237bbf98cSChris Cain 279337bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2794bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2795bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2796bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2797ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 27981e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 27998a592810SEd Tanous if (ec2) 280037bbf98cSChris Cain { 280162598e31SEd Tanous BMCWEB_LOG_ERROR( 280262598e31SEd Tanous "DBUS response error on IdlePowerSaver GetAll: {}", ec2); 2803ac106bf6SEd Tanous messages::internalError(asyncResp->res); 280437bbf98cSChris Cain return; 280537bbf98cSChris Cain } 280637bbf98cSChris Cain 2807ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 280837bbf98cSChris Cain { 2809ac106bf6SEd Tanous messages::internalError(asyncResp->res); 281037bbf98cSChris Cain return; 281137bbf98cSChris Cain } 2812bc1d29deSKrzysztof Grobelny }); 2813e99073f5SGeorge Liu }); 281437bbf98cSChris Cain 281562598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 281637bbf98cSChris Cain } 281737bbf98cSChris Cain 281837bbf98cSChris Cain /** 281937bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 282037bbf98cSChris Cain * 2821ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 282237bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 282337bbf98cSChris Cain * RF request. 282437bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 282537bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 282637bbf98cSChris Cain * before entering idle state. 282737bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 282837bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 282937bbf98cSChris Cain * before exiting idle state 283037bbf98cSChris Cain * 283137bbf98cSChris Cain * @return None. 283237bbf98cSChris Cain */ 2833ac106bf6SEd Tanous inline void 2834ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 283537bbf98cSChris Cain const std::optional<bool> ipsEnable, 283637bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 283737bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 283837bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 283937bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 284037bbf98cSChris Cain { 284162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 284237bbf98cSChris Cain 284337bbf98cSChris Cain // Get IdlePowerSaver object path: 2844e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2845e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2846e99073f5SGeorge Liu dbus::utility::getSubTree( 2847e99073f5SGeorge Liu "/", 0, interfaces, 2848ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2849e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2850b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 285137bbf98cSChris Cain if (ec) 285237bbf98cSChris Cain { 2853b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 285462598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 285562598e31SEd Tanous ec); 2856ac106bf6SEd Tanous messages::internalError(asyncResp->res); 285737bbf98cSChris Cain return; 285837bbf98cSChris Cain } 285937bbf98cSChris Cain if (subtree.empty()) 286037bbf98cSChris Cain { 286137bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2862ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 286337bbf98cSChris Cain "IdlePowerSaver"); 286437bbf98cSChris Cain return; 286537bbf98cSChris Cain } 286637bbf98cSChris Cain if (subtree.size() > 1) 286737bbf98cSChris Cain { 286837bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 286937bbf98cSChris Cain // is an error 287062598e31SEd Tanous BMCWEB_LOG_DEBUG( 287162598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 287262598e31SEd Tanous subtree.size()); 2873ac106bf6SEd Tanous messages::internalError(asyncResp->res); 287437bbf98cSChris Cain return; 287537bbf98cSChris Cain } 287637bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 287737bbf98cSChris Cain { 287862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2879ac106bf6SEd Tanous messages::internalError(asyncResp->res); 288037bbf98cSChris Cain return; 288137bbf98cSChris Cain } 288237bbf98cSChris Cain const std::string& path = subtree[0].first; 288337bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 288437bbf98cSChris Cain if (service.empty()) 288537bbf98cSChris Cain { 288662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2887ac106bf6SEd Tanous messages::internalError(asyncResp->res); 288837bbf98cSChris Cain return; 288937bbf98cSChris Cain } 289037bbf98cSChris Cain 289137bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 289237bbf98cSChris Cain // need to be updated 289337bbf98cSChris Cain 289437bbf98cSChris Cain if (ipsEnable) 289537bbf98cSChris Cain { 28969ae226faSGeorge Liu sdbusplus::asio::setProperty( 28979ae226faSGeorge Liu *crow::connections::systemBus, service, path, 28989ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled", 28999ae226faSGeorge Liu *ipsEnable, [asyncResp](const boost::system::error_code& ec2) { 29008a592810SEd Tanous if (ec2) 290137bbf98cSChris Cain { 2902b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2903ac106bf6SEd Tanous messages::internalError(asyncResp->res); 290437bbf98cSChris Cain return; 290537bbf98cSChris Cain } 29069ae226faSGeorge Liu }); 290737bbf98cSChris Cain } 290837bbf98cSChris Cain if (ipsEnterUtil) 290937bbf98cSChris Cain { 29109ae226faSGeorge Liu sdbusplus::asio::setProperty( 29119ae226faSGeorge Liu *crow::connections::systemBus, service, path, 29129ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 29139ae226faSGeorge Liu "EnterUtilizationPercent", *ipsEnterUtil, 2914ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 29158a592810SEd Tanous if (ec2) 291637bbf98cSChris Cain { 2917b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2918ac106bf6SEd Tanous messages::internalError(asyncResp->res); 291937bbf98cSChris Cain return; 292037bbf98cSChris Cain } 29219ae226faSGeorge Liu }); 292237bbf98cSChris Cain } 292337bbf98cSChris Cain if (ipsEnterTime) 292437bbf98cSChris Cain { 292537bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 292637bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 29279ae226faSGeorge Liu sdbusplus::asio::setProperty( 29289ae226faSGeorge Liu *crow::connections::systemBus, service, path, 29299ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 29309ae226faSGeorge Liu "EnterDwellTime", timeMilliseconds, 2931ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 29328a592810SEd Tanous if (ec2) 293337bbf98cSChris Cain { 2934b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2935ac106bf6SEd Tanous messages::internalError(asyncResp->res); 293637bbf98cSChris Cain return; 293737bbf98cSChris Cain } 29389ae226faSGeorge Liu }); 293937bbf98cSChris Cain } 294037bbf98cSChris Cain if (ipsExitUtil) 294137bbf98cSChris Cain { 29429ae226faSGeorge Liu sdbusplus::asio::setProperty( 29439ae226faSGeorge Liu *crow::connections::systemBus, service, path, 29449ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 29459ae226faSGeorge Liu "ExitUtilizationPercent", *ipsExitUtil, 2946ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 29478a592810SEd Tanous if (ec2) 294837bbf98cSChris Cain { 2949b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2950ac106bf6SEd Tanous messages::internalError(asyncResp->res); 295137bbf98cSChris Cain return; 295237bbf98cSChris Cain } 29539ae226faSGeorge Liu }); 295437bbf98cSChris Cain } 295537bbf98cSChris Cain if (ipsExitTime) 295637bbf98cSChris Cain { 295737bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 295837bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 29599ae226faSGeorge Liu sdbusplus::asio::setProperty( 29609ae226faSGeorge Liu *crow::connections::systemBus, service, path, 29619ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 29629ae226faSGeorge Liu "ExitDwellTime", timeMilliseconds, 2963ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 29648a592810SEd Tanous if (ec2) 296537bbf98cSChris Cain { 2966b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 2967ac106bf6SEd Tanous messages::internalError(asyncResp->res); 296837bbf98cSChris Cain return; 296937bbf98cSChris Cain } 29709ae226faSGeorge Liu }); 297137bbf98cSChris Cain } 2972e99073f5SGeorge Liu }); 297337bbf98cSChris Cain 297462598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 297537bbf98cSChris Cain } 297637bbf98cSChris Cain 2977c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2978dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2979dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2980dd60b9edSEd Tanous { 2981dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2982dd60b9edSEd Tanous { 2983dd60b9edSEd Tanous return; 2984dd60b9edSEd Tanous } 2985dd60b9edSEd Tanous asyncResp->res.addHeader( 2986dd60b9edSEd Tanous boost::beast::http::field::link, 2987dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2988dd60b9edSEd Tanous } 2989dd60b9edSEd Tanous 2990c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2991c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2992c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 29931abe55efSEd Tanous { 29943ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2995f4c99e70SEd Tanous { 2996f4c99e70SEd Tanous return; 2997f4c99e70SEd Tanous } 2998dd60b9edSEd Tanous 2999dd60b9edSEd Tanous asyncResp->res.addHeader( 3000dd60b9edSEd Tanous boost::beast::http::field::link, 3001dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 30028d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 30030f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 30048d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 30058d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 3006462023adSSunitha Harish 30077f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 30087f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 30097f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 30107f3e84a1SEd Tanous { 30117f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 30127f3e84a1SEd Tanous // Option currently returns no systems. TBD 30137f3e84a1SEd Tanous return; 30147f3e84a1SEd Tanous } 30157f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 30167f3e84a1SEd Tanous nlohmann::json::object_t system; 30177f3e84a1SEd Tanous system["@odata.id"] = "/redfish/v1/Systems/system"; 30187f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 30191e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 3020002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 30211e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 3022002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 30235e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 30241e1e598dSJonathan Doman const std::string& /*hostName*/) { 30257f3e84a1SEd Tanous if (ec2) 3026462023adSSunitha Harish { 30277f3e84a1SEd Tanous return; 30287f3e84a1SEd Tanous } 30297f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 30307f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 30317f3e84a1SEd Tanous { 303262598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 30337f3e84a1SEd Tanous return; 30347f3e84a1SEd Tanous } 30357f3e84a1SEd Tanous uint64_t* count = val->get_ptr<uint64_t*>(); 30367f3e84a1SEd Tanous if (count == nullptr) 30377f3e84a1SEd Tanous { 303862598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 30397f3e84a1SEd Tanous return; 30407f3e84a1SEd Tanous } 30417f3e84a1SEd Tanous *count = *count + 1; 304262598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 30437f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 30441476687dSEd Tanous nlohmann::json::object_t hypervisor; 3045002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 30467f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 30471e1e598dSJonathan Doman }); 3048c1e219d5SEd Tanous } 3049c1e219d5SEd Tanous 3050c1e219d5SEd Tanous /** 30517e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 30527e860f15SJohn Edward Broadbent */ 30534f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 30547e860f15SJohn Edward Broadbent { 305589492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 305689492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 305789492a15SPatrick Williams constexpr const char* interfaceName = 30587e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 305989492a15SPatrick Williams constexpr const char* method = "NMI"; 30607e860f15SJohn Edward Broadbent 30617e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 30625e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 30637e860f15SJohn Edward Broadbent if (ec) 30647e860f15SJohn Edward Broadbent { 306562598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 30667e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 30677e860f15SJohn Edward Broadbent return; 30687e860f15SJohn Edward Broadbent } 30697e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 30707e860f15SJohn Edward Broadbent }, 30717e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 30727e860f15SJohn Edward Broadbent } 3073c5b2abe0SLewanczyk, Dawid 3074c5b2abe0SLewanczyk, Dawid /** 3075fc903b3dSAndrew Geissler * Handle error responses from d-bus for system power requests 3076fc903b3dSAndrew Geissler */ 3077fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec, 3078fc903b3dSAndrew Geissler const sdbusplus::message_t& eMsg, 3079fc903b3dSAndrew Geissler std::string_view resetType, 3080fc903b3dSAndrew Geissler crow::Response& res) 3081fc903b3dSAndrew Geissler { 3082fc903b3dSAndrew Geissler if (ec.value() == boost::asio::error::invalid_argument) 3083fc903b3dSAndrew Geissler { 3084fc903b3dSAndrew Geissler messages::actionParameterNotSupported(res, resetType, "Reset"); 3085fc903b3dSAndrew Geissler return; 3086fc903b3dSAndrew Geissler } 3087fc903b3dSAndrew Geissler 3088fc903b3dSAndrew Geissler if (eMsg.get_error() == nullptr) 3089fc903b3dSAndrew Geissler { 309062598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error: {}", ec); 3091fc903b3dSAndrew Geissler messages::internalError(res); 3092fc903b3dSAndrew Geissler return; 3093fc903b3dSAndrew Geissler } 3094fc903b3dSAndrew Geissler std::string_view errorMessage = eMsg.get_error()->name; 3095fc903b3dSAndrew Geissler 3096fc903b3dSAndrew Geissler // If operation failed due to BMC not being in Ready state, tell 3097fc903b3dSAndrew Geissler // user to retry in a bit 3098fc903b3dSAndrew Geissler if ((errorMessage == 3099fc903b3dSAndrew Geissler std::string_view( 3100fc903b3dSAndrew Geissler "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) || 3101fc903b3dSAndrew Geissler (errorMessage == 3102fc903b3dSAndrew Geissler std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady"))) 3103fc903b3dSAndrew Geissler { 310462598e31SEd Tanous BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now"); 3105fc903b3dSAndrew Geissler messages::serviceTemporarilyUnavailable(res, "10"); 3106fc903b3dSAndrew Geissler return; 3107fc903b3dSAndrew Geissler } 3108fc903b3dSAndrew Geissler 310962598e31SEd Tanous BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec, 311062598e31SEd Tanous errorMessage); 3111fc903b3dSAndrew Geissler messages::internalError(res); 3112fc903b3dSAndrew Geissler } 3113fc903b3dSAndrew Geissler 3114c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 3115c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 31167f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3117c1e219d5SEd Tanous const std::string& systemName) 3118c1e219d5SEd Tanous { 31193ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 312045ca1b86SEd Tanous { 312145ca1b86SEd Tanous return; 312245ca1b86SEd Tanous } 3123c1e219d5SEd Tanous if (systemName != "system") 3124c1e219d5SEd Tanous { 3125c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3126c1e219d5SEd Tanous systemName); 3127c1e219d5SEd Tanous return; 3128c1e219d5SEd Tanous } 31297f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 31307f3e84a1SEd Tanous { 31317f3e84a1SEd Tanous // Option currently returns no systems. TBD 31327f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3133c1e219d5SEd Tanous systemName); 31347f3e84a1SEd Tanous return; 31357f3e84a1SEd Tanous } 31369712f8acSEd Tanous std::string resetType; 3137c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 3138cc340dd9SEd Tanous { 3139cc340dd9SEd Tanous return; 3140cc340dd9SEd Tanous } 3141cc340dd9SEd Tanous 3142d22c8396SJason M. Bills // Get the command and host vs. chassis 3143cc340dd9SEd Tanous std::string command; 3144543f4400SEd Tanous bool hostCommand = true; 3145d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 3146cc340dd9SEd Tanous { 3147cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 3148d22c8396SJason M. Bills hostCommand = true; 3149d22c8396SJason M. Bills } 3150d22c8396SJason M. Bills else if (resetType == "ForceOff") 3151d22c8396SJason M. Bills { 3152d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 3153d22c8396SJason M. Bills hostCommand = false; 3154d22c8396SJason M. Bills } 3155d22c8396SJason M. Bills else if (resetType == "ForceRestart") 3156d22c8396SJason M. Bills { 3157c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 315886a0851aSJason M. Bills hostCommand = true; 3159cc340dd9SEd Tanous } 31609712f8acSEd Tanous else if (resetType == "GracefulShutdown") 3161cc340dd9SEd Tanous { 3162cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 3163d22c8396SJason M. Bills hostCommand = true; 3164cc340dd9SEd Tanous } 31659712f8acSEd Tanous else if (resetType == "GracefulRestart") 3166cc340dd9SEd Tanous { 31670fda0f12SGeorge Liu command = 31680fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 3169d22c8396SJason M. Bills hostCommand = true; 3170d22c8396SJason M. Bills } 3171d22c8396SJason M. Bills else if (resetType == "PowerCycle") 3172d22c8396SJason M. Bills { 317386a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 317486a0851aSJason M. Bills hostCommand = true; 3175cc340dd9SEd Tanous } 3176bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 3177bfd5b826SLakshminarayana R. Kammath { 3178bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 3179bfd5b826SLakshminarayana R. Kammath return; 3180bfd5b826SLakshminarayana R. Kammath } 3181cc340dd9SEd Tanous else 3182cc340dd9SEd Tanous { 3183c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 3184cc340dd9SEd Tanous return; 3185cc340dd9SEd Tanous } 3186cc340dd9SEd Tanous 3187d22c8396SJason M. Bills if (hostCommand) 3188d22c8396SJason M. Bills { 31899ae226faSGeorge Liu sdbusplus::asio::setProperty( 31909ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 31919ae226faSGeorge Liu "/xyz/openbmc_project/state/host0", 31929ae226faSGeorge Liu "xyz.openbmc_project.State.Host", "RequestedHostTransition", 31939ae226faSGeorge Liu command, 3194fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3195fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3196cc340dd9SEd Tanous if (ec) 3197cc340dd9SEd Tanous { 3198fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3199fc903b3dSAndrew Geissler asyncResp->res); 3200fc903b3dSAndrew Geissler 3201cc340dd9SEd Tanous return; 3202cc340dd9SEd Tanous } 3203f12894f8SJason M. Bills messages::success(asyncResp->res); 32049ae226faSGeorge Liu }); 3205cc340dd9SEd Tanous } 3206d22c8396SJason M. Bills else 3207d22c8396SJason M. Bills { 32089ae226faSGeorge Liu sdbusplus::asio::setProperty( 32099ae226faSGeorge Liu *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 32109ae226faSGeorge Liu "/xyz/openbmc_project/state/chassis0", 32119ae226faSGeorge Liu "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", 32129ae226faSGeorge Liu command, 3213fc903b3dSAndrew Geissler [asyncResp, resetType](const boost::system::error_code& ec, 3214fc903b3dSAndrew Geissler sdbusplus::message_t& sdbusErrMsg) { 3215d22c8396SJason M. Bills if (ec) 3216d22c8396SJason M. Bills { 3217fc903b3dSAndrew Geissler handleSystemActionResetError(ec, sdbusErrMsg, resetType, 3218fc903b3dSAndrew Geissler asyncResp->res); 3219d22c8396SJason M. Bills return; 3220d22c8396SJason M. Bills } 3221d22c8396SJason M. Bills messages::success(asyncResp->res); 32229ae226faSGeorge Liu }); 3223d22c8396SJason M. Bills } 3224d22c8396SJason M. Bills } 3225cc340dd9SEd Tanous 3226c1e219d5SEd Tanous inline void handleComputerSystemHead( 3227dd60b9edSEd Tanous App& app, const crow::Request& req, 32287f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 32297f3e84a1SEd Tanous const std::string& /*systemName*/) 3230dd60b9edSEd Tanous { 3231dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3232dd60b9edSEd Tanous { 3233dd60b9edSEd Tanous return; 3234dd60b9edSEd Tanous } 3235dd60b9edSEd Tanous 3236dd60b9edSEd Tanous asyncResp->res.addHeader( 3237dd60b9edSEd Tanous boost::beast::http::field::link, 3238dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3239dd60b9edSEd Tanous } 3240dd60b9edSEd Tanous 32415c3e9272SAbhishek Patel inline void afterPortRequest( 32425c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 32435c3e9272SAbhishek Patel const boost::system::error_code& ec, 32445c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 32455c3e9272SAbhishek Patel { 32465c3e9272SAbhishek Patel if (ec) 32475c3e9272SAbhishek Patel { 3248b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 32495c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 32505c3e9272SAbhishek Patel return; 32515c3e9272SAbhishek Patel } 32525c3e9272SAbhishek Patel for (const auto& data : socketData) 32535c3e9272SAbhishek Patel { 32545c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 32555c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 32565c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 32575c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 32585c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 32595c3e9272SAbhishek Patel // need to retrieve port number for 32605c3e9272SAbhishek Patel // obmc-console-ssh service 32615c3e9272SAbhishek Patel if (protocolName == "SSH") 32625c3e9272SAbhishek Patel { 32635c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 326481c4e330SEd Tanous const boost::system::error_code& ec1, 32655c3e9272SAbhishek Patel int portNumber) { 32665c3e9272SAbhishek Patel if (ec1) 32675c3e9272SAbhishek Patel { 3268b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 32695c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 32705c3e9272SAbhishek Patel return; 32715c3e9272SAbhishek Patel } 32725c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 32735c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 32745c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 32755c3e9272SAbhishek Patel }); 32765c3e9272SAbhishek Patel } 32775c3e9272SAbhishek Patel } 32785c3e9272SAbhishek Patel } 3279c1e219d5SEd Tanous 3280c1e219d5SEd Tanous inline void 3281c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 328222d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3283c1e219d5SEd Tanous const std::string& systemName) 3284c1e219d5SEd Tanous { 32853ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 328645ca1b86SEd Tanous { 328745ca1b86SEd Tanous return; 328845ca1b86SEd Tanous } 3289746b56f3SAsmitha Karunanithi 32907f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 32917f3e84a1SEd Tanous { 32927f3e84a1SEd Tanous // Option currently returns no systems. TBD 32937f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 32947f3e84a1SEd Tanous systemName); 32957f3e84a1SEd Tanous return; 32967f3e84a1SEd Tanous } 32977f3e84a1SEd Tanous 3298746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3299746b56f3SAsmitha Karunanithi { 3300746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3301746b56f3SAsmitha Karunanithi return; 3302746b56f3SAsmitha Karunanithi } 3303746b56f3SAsmitha Karunanithi 330422d268cbSEd Tanous if (systemName != "system") 330522d268cbSEd Tanous { 330622d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 330722d268cbSEd Tanous systemName); 330822d268cbSEd Tanous return; 330922d268cbSEd Tanous } 3310dd60b9edSEd Tanous asyncResp->res.addHeader( 3311dd60b9edSEd Tanous boost::beast::http::field::link, 3312dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 33138d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3314b6655101SChris Cain "#ComputerSystem.v1_22_0.ComputerSystem"; 33158d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "system"; 33168d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "system"; 33178d1b46d7Szhanghch05 asyncResp->res.jsonValue["SystemType"] = "Physical"; 33188d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 33198d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 33205fd0aafbSNinad Palsule if constexpr (bmcwebEnableProcMemStatus) 33215fd0aafbSNinad Palsule { 33228d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 33238d1b46d7Szhanghch05 "Disabled"; 33248d1b46d7Szhanghch05 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 33258d1b46d7Szhanghch05 "Disabled"; 33265fd0aafbSNinad Palsule } 3327cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3328dfb2b408SPriyanga Ramasamy double(0); 3329002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system"; 333004a258f4SEd Tanous 33311476687dSEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = 33321476687dSEd Tanous "/redfish/v1/Systems/system/Processors"; 33331476687dSEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = 33341476687dSEd Tanous "/redfish/v1/Systems/system/Memory"; 33351476687dSEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = 33361476687dSEd Tanous "/redfish/v1/Systems/system/Storage"; 33373179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 33383179105bSSunny Srivastava "/redfish/v1/Systems/system/FabricAdapters"; 3339029573d4SEd Tanous 3340002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 33411476687dSEd Tanous "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; 3342c1e219d5SEd Tanous asyncResp->res 3343c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 33441476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3345c5b2abe0SLewanczyk, Dawid 33461476687dSEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = 33471476687dSEd Tanous "/redfish/v1/Systems/system/LogServices"; 33481476687dSEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = 33491476687dSEd Tanous "/redfish/v1/Systems/system/Bios"; 3350c4bf6374SJason M. Bills 33511476687dSEd Tanous nlohmann::json::array_t managedBy; 33521476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 33531476687dSEd Tanous manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 3354002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 33551476687dSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 33561476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 33570e8ac5e7SGunnar Mills 33580e8ac5e7SGunnar Mills // Fill in SerialConsole info 3359002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3360c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 33611476687dSEd Tanous 3362c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 33631476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3364c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 33651476687dSEd Tanous "Press ~. to exit console"; 33665c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 33675c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 33680e8ac5e7SGunnar Mills 33690e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM 33700e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3371002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 3372c1e219d5SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4; 3373613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3374613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 33751476687dSEd Tanous 33760e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM 337713451e39SWilly Tu 337813451e39SWilly Tu auto health = std::make_shared<HealthPopulate>(asyncResp); 337913451e39SWilly Tu if constexpr (bmcwebEnableHealthPopulate) 338013451e39SWilly Tu { 33817a1dbc48SGeorge Liu constexpr std::array<std::string_view, 4> inventoryForSystems{ 3382b49ac873SJames Feist "xyz.openbmc_project.Inventory.Item.Dimm", 33832ad9c2f6SJames Feist "xyz.openbmc_project.Inventory.Item.Cpu", 3384e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.Drive", 3385e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}; 3386b49ac873SJames Feist 33877a1dbc48SGeorge Liu dbus::utility::getSubTreePaths( 33887a1dbc48SGeorge Liu "/", 0, inventoryForSystems, 33897a1dbc48SGeorge Liu [health](const boost::system::error_code& ec, 3390914e2d5dSEd Tanous const std::vector<std::string>& resp) { 3391b49ac873SJames Feist if (ec) 3392b49ac873SJames Feist { 3393b49ac873SJames Feist // no inventory 3394b49ac873SJames Feist return; 3395b49ac873SJames Feist } 3396b49ac873SJames Feist 3397914e2d5dSEd Tanous health->inventory = resp; 33987a1dbc48SGeorge Liu }); 3399b49ac873SJames Feist health->populate(); 340013451e39SWilly Tu } 3401b49ac873SJames Feist 3402002d39b4SEd Tanous getMainChassisId(asyncResp, 3403002d39b4SEd Tanous [](const std::string& chassisId, 34048d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3405b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3406b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3407ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3408ef4c65b7SEd Tanous chassisId); 3409002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3410c5d03ff4SJennifer Lee }); 3411a3002228SAppaRao Puli 341259a17e4fSGeorge Liu getSystemLocationIndicatorActive(asyncResp); 34139f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3414a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 34155bc2dc8eSJames Feist getComputerSystem(asyncResp, health); 34166c34de48SEd Tanous getHostState(asyncResp); 3417491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3418978b8803SAndrew Geissler getBootProgress(asyncResp); 3419b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 342070c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 342170c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 342251709ffdSYong Li getHostWatchdogTimer(asyncResp); 3423c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 34249dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3425797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3426c0557e1aSGunnar Mills getLastResetTime(asyncResp); 3427a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE 3428a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 3429a6349918SAppaRao Puli #endif 34301981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 34313a2d0424SChris Cain getPowerMode(asyncResp); 343237bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3433c1e219d5SEd Tanous } 3434550a6bf8SJiaqing Zhao 3435c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3436c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 343722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3438c1e219d5SEd Tanous const std::string& systemName) 3439c1e219d5SEd Tanous { 34403ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 344145ca1b86SEd Tanous { 344245ca1b86SEd Tanous return; 344345ca1b86SEd Tanous } 34447f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 34457f3e84a1SEd Tanous { 34467f3e84a1SEd Tanous // Option currently returns no systems. TBD 34477f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 34487f3e84a1SEd Tanous systemName); 34497f3e84a1SEd Tanous return; 34507f3e84a1SEd Tanous } 345122d268cbSEd Tanous if (systemName != "system") 345222d268cbSEd Tanous { 345322d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 345422d268cbSEd Tanous systemName); 345522d268cbSEd Tanous return; 345622d268cbSEd Tanous } 345722d268cbSEd Tanous 3458dd60b9edSEd Tanous asyncResp->res.addHeader( 3459dd60b9edSEd Tanous boost::beast::http::field::link, 3460dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3461dd60b9edSEd Tanous 34629f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3463cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 346498e386ecSGunnar Mills std::optional<std::string> assetTag; 3465c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 34663a2d0424SChris Cain std::optional<std::string> powerMode; 3467550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3468550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3469550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3470550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3471550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3472550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3473797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3474550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 34759dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3476550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3477550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3478550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3479550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3480550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3481550a6bf8SJiaqing Zhao 3482550a6bf8SJiaqing Zhao // clang-format off 348315ed6780SWilly Tu if (!json_util::readJsonPatch( 3484550a6bf8SJiaqing Zhao req, asyncResp->res, 3485550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 34867e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3487550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3488550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3489550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3490550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3491550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3492550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3493550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3494550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3495550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3496797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3497550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 34989dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3499550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3500550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3501550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3502550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3503550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 35046617338dSEd Tanous { 35056617338dSEd Tanous return; 35066617338dSEd Tanous } 3507550a6bf8SJiaqing Zhao // clang-format on 3508491d8ee7SSantosh Puranik 35098d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3510c45f0082SYong Li 351198e386ecSGunnar Mills if (assetTag) 351298e386ecSGunnar Mills { 351398e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 351498e386ecSGunnar Mills } 351598e386ecSGunnar Mills 3516550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3517c45f0082SYong Li { 3518f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3519c45f0082SYong Li } 3520c45f0082SYong Li 3521cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 352269f35306SGunnar Mills { 3523002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3524491d8ee7SSantosh Puranik } 3525550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 352669f35306SGunnar Mills { 3527550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 352869f35306SGunnar Mills } 3529ac7e1e0bSAli Ahmed 3530797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3531797d5daeSCorey Hardesty { 3532797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3533797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3534797d5daeSCorey Hardesty } 3535797d5daeSCorey Hardesty 3536550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3537ac7e1e0bSAli Ahmed { 3538c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 353969f35306SGunnar Mills } 3540265c1602SJohnathan Mantey 35419dcfe8c1SAlbert Zhang if (stopBootOnFault) 35429dcfe8c1SAlbert Zhang { 35439dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 35449dcfe8c1SAlbert Zhang } 35459dcfe8c1SAlbert Zhang 35469f8bfa7cSGunnar Mills if (locationIndicatorActive) 35479f8bfa7cSGunnar Mills { 354859a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 35499f8bfa7cSGunnar Mills } 35509f8bfa7cSGunnar Mills 35517e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 35527e860f15SJohn Edward Broadbent // passed 35539712f8acSEd Tanous if (indicatorLed) 35546617338dSEd Tanous { 3555f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3556002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3557d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3558d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 35596617338dSEd Tanous } 3560c6a620f2SGeorge Liu 3561c6a620f2SGeorge Liu if (powerRestorePolicy) 3562c6a620f2SGeorge Liu { 35634e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3564c6a620f2SGeorge Liu } 35653a2d0424SChris Cain 35663a2d0424SChris Cain if (powerMode) 35673a2d0424SChris Cain { 35683a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 35693a2d0424SChris Cain } 357037bbf98cSChris Cain 3571c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 357237bbf98cSChris Cain { 3573002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3574002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 357537bbf98cSChris Cain } 3576c1e219d5SEd Tanous } 35771cb1a9e6SAppaRao Puli 357838c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3579dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 35807f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3581c1e219d5SEd Tanous const std::string& /*systemName*/) 3582dd60b9edSEd Tanous { 3583dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3584dd60b9edSEd Tanous { 3585dd60b9edSEd Tanous return; 3586dd60b9edSEd Tanous } 3587dd60b9edSEd Tanous asyncResp->res.addHeader( 3588dd60b9edSEd Tanous boost::beast::http::field::link, 3589dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3590dd60b9edSEd Tanous } 359133e1f122SAndrew Geissler 359233e1f122SAndrew Geissler /** 359333e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 359433e1f122SAndrew Geissler * 359533e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 359633e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 359733e1f122SAndrew Geissler * 359833e1f122SAndrew Geissler * @return Emplaces correpsonding Redfish translated value(s) in 359933e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 360033e1f122SAndrew Geissler * allowableValues. 360133e1f122SAndrew Geissler */ 360233e1f122SAndrew Geissler inline void 360333e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran, 360433e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 360533e1f122SAndrew Geissler { 360633e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 360733e1f122SAndrew Geissler { 360833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 360933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 361033e1f122SAndrew Geissler } 361133e1f122SAndrew Geissler else if (dbusAllowedHostTran == 361233e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 361333e1f122SAndrew Geissler { 361433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 361533e1f122SAndrew Geissler } 361633e1f122SAndrew Geissler else if (dbusAllowedHostTran == 361733e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 361833e1f122SAndrew Geissler { 361933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 362033e1f122SAndrew Geissler } 362133e1f122SAndrew Geissler else if (dbusAllowedHostTran == 362233e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 362333e1f122SAndrew Geissler { 362433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 362533e1f122SAndrew Geissler } 362633e1f122SAndrew Geissler else 362733e1f122SAndrew Geissler { 362833e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 362933e1f122SAndrew Geissler } 363033e1f122SAndrew Geissler } 363133e1f122SAndrew Geissler 363233e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 363333e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 363433e1f122SAndrew Geissler const boost::system::error_code& ec, 363533e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 363633e1f122SAndrew Geissler { 363733e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 363833e1f122SAndrew Geissler 363933e1f122SAndrew Geissler // Supported on all systems currently 364033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 364133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 364233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 364333e1f122SAndrew Geissler 364433e1f122SAndrew Geissler if (ec) 364533e1f122SAndrew Geissler { 3646*e715d14bSEd Tanous if ((ec.value() == 3647*e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3648*e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 364933e1f122SAndrew Geissler { 365033e1f122SAndrew Geissler // Property not implemented so just return defaults 365133e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 365233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 365333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 365433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 365533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 365633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 365733e1f122SAndrew Geissler } 365833e1f122SAndrew Geissler else 365933e1f122SAndrew Geissler { 366033e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 366133e1f122SAndrew Geissler messages::internalError(asyncResp->res); 366233e1f122SAndrew Geissler return; 366333e1f122SAndrew Geissler } 366433e1f122SAndrew Geissler } 366533e1f122SAndrew Geissler else 366633e1f122SAndrew Geissler { 366733e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 366833e1f122SAndrew Geissler { 366933e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 367033e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 367133e1f122SAndrew Geissler } 367233e1f122SAndrew Geissler } 367333e1f122SAndrew Geissler 367433e1f122SAndrew Geissler nlohmann::json::object_t parameter; 367533e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 367633e1f122SAndrew Geissler parameter["Required"] = true; 367733e1f122SAndrew Geissler parameter["DataType"] = "String"; 367833e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 367933e1f122SAndrew Geissler nlohmann::json::array_t parameters; 368033e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 368133e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 368233e1f122SAndrew Geissler } 368333e1f122SAndrew Geissler 3684c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3685c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 368622d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3687c1e219d5SEd Tanous const std::string& systemName) 3688c1e219d5SEd Tanous { 36893ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 369045ca1b86SEd Tanous { 369145ca1b86SEd Tanous return; 369245ca1b86SEd Tanous } 36937f3e84a1SEd Tanous if constexpr (bmcwebEnableMultiHost) 36947f3e84a1SEd Tanous { 36957f3e84a1SEd Tanous // Option currently returns no systems. TBD 36967f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 36977f3e84a1SEd Tanous systemName); 36987f3e84a1SEd Tanous return; 36997f3e84a1SEd Tanous } 3700746b56f3SAsmitha Karunanithi 3701746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3702746b56f3SAsmitha Karunanithi { 3703746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3704746b56f3SAsmitha Karunanithi return; 3705746b56f3SAsmitha Karunanithi } 3706746b56f3SAsmitha Karunanithi 370722d268cbSEd Tanous if (systemName != "system") 370822d268cbSEd Tanous { 370922d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 371022d268cbSEd Tanous systemName); 371122d268cbSEd Tanous return; 371222d268cbSEd Tanous } 371322d268cbSEd Tanous 3714dd60b9edSEd Tanous asyncResp->res.addHeader( 3715dd60b9edSEd Tanous boost::beast::http::field::link, 3716dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 37171476687dSEd Tanous 37181476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 37191476687dSEd Tanous "/redfish/v1/Systems/system/ResetActionInfo"; 3720c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 37211476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 37221476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 37233215e700SNan Zhou 372433e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 372533e1f122SAndrew Geissler sdbusplus::asio::getProperty<std::vector<std::string>>( 372633e1f122SAndrew Geissler *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 372733e1f122SAndrew Geissler "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 372833e1f122SAndrew Geissler "AllowedHostTransitions", 372933e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 373033e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 373133e1f122SAndrew Geissler afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions); 373233e1f122SAndrew Geissler }); 3733c1e219d5SEd Tanous } 3734c1e219d5SEd Tanous /** 3735c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3736c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3737c1e219d5SEd Tanous */ 3738100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3739c1e219d5SEd Tanous { 3740100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3741100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3742100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3743100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3744100afe56SEd Tanous 3745100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3746100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3747100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3748100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3749100afe56SEd Tanous 3750100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3751100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3752100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3753100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3754100afe56SEd Tanous 3755100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3756100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3757100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3758100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3759100afe56SEd Tanous 3760100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3761100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3762100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3763100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3764100afe56SEd Tanous 3765100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3766100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3767100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3768100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3769100afe56SEd Tanous 3770c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3771c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3772c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3773c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3774c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3775c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3776c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3777c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 37781cb1a9e6SAppaRao Puli } 3779c5b2abe0SLewanczyk, Dawid } // namespace redfish 3780