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" 23*539d8c6bSEd Tanous #include "generated/enums/action_info.hpp" 248d69c668SEd Tanous #include "generated/enums/computer_system.hpp" 25*539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp" 2633e1f122SAndrew Geissler #include "generated/enums/resource.hpp" 27746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 281c8fba97SJames Feist #include "led.hpp" 29f4c99e70SEd Tanous #include "query.hpp" 30c5d03ff4SJennifer Lee #include "redfish_util.hpp" 313ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 323ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 333ccb3adbSEd Tanous #include "utils/json_utils.hpp" 34472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 353ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 362b82937eSEd Tanous #include "utils/time_utils.hpp" 37c5d03ff4SJennifer Lee 38fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 399712f8acSEd Tanous #include <boost/container/flat_map.hpp> 40e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 4133e1f122SAndrew Geissler #include <boost/system/linux_error.hpp> 42ef4c65b7SEd Tanous #include <boost/url/format.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> 5120fa6a2cSEd Tanous #include <utility> 52abf2add6SEd Tanous #include <variant> 536b9ac4f2SChris Cain #include <vector> 54c5b2abe0SLewanczyk, Dawid 551abe55efSEd Tanous namespace redfish 561abe55efSEd Tanous { 57c5b2abe0SLewanczyk, Dawid 585c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 595c3e9272SAbhishek Patel protocolToDBusForSystems{ 605c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 615c3e9272SAbhishek Patel 629d3ae10eSAlpana Kumari /** 639d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 649d3ae10eSAlpana Kumari * 65ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 669d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 679d3ae10eSAlpana Kumari * 689d3ae10eSAlpana Kumari * @return None. 699d3ae10eSAlpana Kumari */ 708d1b46d7Szhanghch05 inline void 71ac106bf6SEd Tanous updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 721e1e598dSJonathan Doman bool isDimmFunctional) 739d3ae10eSAlpana Kumari { 7462598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 759d3ae10eSAlpana Kumari 769d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 779d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 789d3ae10eSAlpana Kumari // ENABLED. 7902cad96eSEd Tanous const nlohmann::json& prevMemSummary = 80ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 819d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 829d3ae10eSAlpana Kumari { 83e05aec50SEd Tanous if (isDimmFunctional) 849d3ae10eSAlpana Kumari { 85ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 869d3ae10eSAlpana Kumari "Enabled"; 879d3ae10eSAlpana Kumari } 889d3ae10eSAlpana Kumari } 899d3ae10eSAlpana Kumari } 909d3ae10eSAlpana Kumari 9157e8c9beSAlpana Kumari /* 9257e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 9357e8c9beSAlpana Kumari * CPU Functional State 9457e8c9beSAlpana Kumari * 95ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 9657e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9757e8c9beSAlpana Kumari * 9857e8c9beSAlpana Kumari * @return None. 9957e8c9beSAlpana Kumari */ 100ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 101ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 10257e8c9beSAlpana Kumari { 10362598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 10457e8c9beSAlpana Kumari 10502cad96eSEd Tanous const nlohmann::json& prevProcState = 106ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10757e8c9beSAlpana Kumari 10857e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 10957e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 11057e8c9beSAlpana Kumari // Functional. 11157e8c9beSAlpana Kumari if (prevProcState == "Disabled") 11257e8c9beSAlpana Kumari { 113e05aec50SEd Tanous if (isCpuFunctional) 11457e8c9beSAlpana Kumari { 115ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 11657e8c9beSAlpana Kumari "Enabled"; 11757e8c9beSAlpana Kumari } 11857e8c9beSAlpana Kumari } 11957e8c9beSAlpana Kumari } 12057e8c9beSAlpana Kumari 121cf0e004cSNinad Palsule /* 122cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 123cf0e004cSNinad Palsule * 124ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 125cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 126cf0e004cSNinad Palsule * 127cf0e004cSNinad Palsule * @return None. 128cf0e004cSNinad Palsule */ 129cf0e004cSNinad Palsule inline void 130ac106bf6SEd Tanous modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 131cf0e004cSNinad Palsule bool isCpuPresent) 132cf0e004cSNinad Palsule { 13362598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 134cf0e004cSNinad Palsule 135cf0e004cSNinad Palsule if (isCpuPresent) 136cf0e004cSNinad Palsule { 137cf0e004cSNinad Palsule nlohmann::json& procCount = 138ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 139cf0e004cSNinad Palsule auto* procCountPtr = 140cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 141cf0e004cSNinad Palsule if (procCountPtr != nullptr) 142cf0e004cSNinad Palsule { 143cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 144cf0e004cSNinad Palsule *procCountPtr += 1; 145cf0e004cSNinad Palsule } 146cf0e004cSNinad Palsule } 147cf0e004cSNinad Palsule } 148cf0e004cSNinad Palsule 149382d6475SAli Ahmed inline void getProcessorProperties( 150ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 151382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 152382d6475SAli Ahmed properties) 15303fbed92SAli Ahmed { 15462598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 15503fbed92SAli Ahmed 15603fbed92SAli Ahmed // TODO: Get Model 15703fbed92SAli Ahmed 158bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 15903fbed92SAli Ahmed 160bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 161bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 16203fbed92SAli Ahmed 163bc1d29deSKrzysztof Grobelny if (!success) 16403fbed92SAli Ahmed { 165ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16603fbed92SAli Ahmed return; 16703fbed92SAli Ahmed } 16803fbed92SAli Ahmed 169bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 17003fbed92SAli Ahmed { 171bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 172ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 173bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 174bc1d29deSKrzysztof Grobelny 175bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 176bc1d29deSKrzysztof Grobelny { 177bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17803fbed92SAli Ahmed } 17903fbed92SAli Ahmed else 18003fbed92SAli Ahmed { 181bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 18203fbed92SAli Ahmed } 18303fbed92SAli Ahmed } 18403fbed92SAli Ahmed } 18503fbed92SAli Ahmed 18603fbed92SAli Ahmed /* 18703fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18803fbed92SAli Ahmed * 189ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 19003fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 19103fbed92SAli Ahmed * @param[in] path dbus path for Cpu 19203fbed92SAli Ahmed * 19303fbed92SAli Ahmed * @return None. 19403fbed92SAli Ahmed */ 195ac106bf6SEd Tanous inline void 196ac106bf6SEd Tanous getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 197ac106bf6SEd Tanous const std::string& service, const std::string& path) 19803fbed92SAli Ahmed { 199ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 200382d6475SAli Ahmed const bool cpuPresenceCheck) { 201382d6475SAli Ahmed if (ec3) 202382d6475SAli Ahmed { 20362598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 204382d6475SAli Ahmed return; 205382d6475SAli Ahmed } 206ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 207382d6475SAli Ahmed }; 208382d6475SAli Ahmed 209cf0e004cSNinad Palsule // Get the Presence of CPU 210cf0e004cSNinad Palsule sdbusplus::asio::getProperty<bool>( 211cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 212cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item", "Present", 213cf0e004cSNinad Palsule std::move(getCpuPresenceState)); 214cf0e004cSNinad Palsule 215bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 216bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 217bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.Cpu", 218ac106bf6SEd Tanous [asyncResp, service, 2195e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 220b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 22103fbed92SAli Ahmed if (ec2) 22203fbed92SAli Ahmed { 22362598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 224ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22503fbed92SAli Ahmed return; 22603fbed92SAli Ahmed } 227ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 228bc1d29deSKrzysztof Grobelny }); 22903fbed92SAli Ahmed } 23003fbed92SAli Ahmed 23157e8c9beSAlpana Kumari /* 232cf0e004cSNinad Palsule * @brief processMemoryProperties fields 233cf0e004cSNinad Palsule * 234ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 235cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 236cf0e004cSNinad Palsule * 237cf0e004cSNinad Palsule * @return None. 238cf0e004cSNinad Palsule */ 239cf0e004cSNinad Palsule inline void 240ac106bf6SEd Tanous processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 241cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 242cf0e004cSNinad Palsule { 24362598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 244cf0e004cSNinad Palsule 245cf0e004cSNinad Palsule if (properties.empty()) 246cf0e004cSNinad Palsule { 247cf0e004cSNinad Palsule return; 248cf0e004cSNinad Palsule } 249cf0e004cSNinad Palsule 250cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 251cf0e004cSNinad Palsule 252cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 253cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 254cf0e004cSNinad Palsule memorySizeInKB); 255cf0e004cSNinad Palsule 256cf0e004cSNinad Palsule if (!success) 257cf0e004cSNinad Palsule { 258ac106bf6SEd Tanous messages::internalError(asyncResp->res); 259cf0e004cSNinad Palsule return; 260cf0e004cSNinad Palsule } 261cf0e004cSNinad Palsule 262cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 263cf0e004cSNinad Palsule { 264cf0e004cSNinad Palsule nlohmann::json& totalMemory = 265ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 266dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 267cf0e004cSNinad Palsule if (preValue == nullptr) 268cf0e004cSNinad Palsule { 269ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 270dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 271cf0e004cSNinad Palsule } 272cf0e004cSNinad Palsule else 273cf0e004cSNinad Palsule { 274ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 275dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 276dfb2b408SPriyanga Ramasamy *preValue; 277cf0e004cSNinad Palsule } 278cf0e004cSNinad Palsule } 279cf0e004cSNinad Palsule } 280cf0e004cSNinad Palsule 281cf0e004cSNinad Palsule /* 282cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 283cf0e004cSNinad Palsule * 284ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 285cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 286cf0e004cSNinad Palsule * @param[in] path dbus path for memory 287cf0e004cSNinad Palsule * 288cf0e004cSNinad Palsule * @return None. 289cf0e004cSNinad Palsule */ 290ac106bf6SEd Tanous inline void 291ac106bf6SEd Tanous getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 292ac106bf6SEd Tanous const std::string& service, const std::string& path) 293cf0e004cSNinad Palsule { 294cf0e004cSNinad Palsule sdbusplus::asio::getAllProperties( 295cf0e004cSNinad Palsule *crow::connections::systemBus, service, path, 296cf0e004cSNinad Palsule "xyz.openbmc_project.Inventory.Item.Dimm", 297ac106bf6SEd Tanous [asyncResp, service, 298cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 299cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 300cf0e004cSNinad Palsule if (ec2) 301cf0e004cSNinad Palsule { 30262598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 303ac106bf6SEd Tanous messages::internalError(asyncResp->res); 304cf0e004cSNinad Palsule return; 305cf0e004cSNinad Palsule } 30651bd2d8aSGunnar Mills processMemoryProperties(asyncResp, properties); 307cf0e004cSNinad Palsule }); 308cf0e004cSNinad Palsule } 309cf0e004cSNinad Palsule 310a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 311a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 312a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& properties) 3131abe55efSEd Tanous { 314a974c132SLakshmi Yadlapati if (ec) 315a974c132SLakshmi Yadlapati { 316a974c132SLakshmi Yadlapati BMCWEB_LOG_ERROR("DBUS response error {}", ec); 317a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 318a974c132SLakshmi Yadlapati return; 319a974c132SLakshmi Yadlapati } 320a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size()); 321a974c132SLakshmi Yadlapati 322a974c132SLakshmi Yadlapati const std::string* uUID = nullptr; 323a974c132SLakshmi Yadlapati 324a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 325a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID); 326a974c132SLakshmi Yadlapati 327a974c132SLakshmi Yadlapati if (!success) 328a974c132SLakshmi Yadlapati { 329a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 330a974c132SLakshmi Yadlapati return; 331a974c132SLakshmi Yadlapati } 332a974c132SLakshmi Yadlapati 333a974c132SLakshmi Yadlapati if (uUID != nullptr) 334a974c132SLakshmi Yadlapati { 335a974c132SLakshmi Yadlapati std::string valueStr = *uUID; 336a974c132SLakshmi Yadlapati if (valueStr.size() == 32) 337a974c132SLakshmi Yadlapati { 338a974c132SLakshmi Yadlapati valueStr.insert(8, 1, '-'); 339a974c132SLakshmi Yadlapati valueStr.insert(13, 1, '-'); 340a974c132SLakshmi Yadlapati valueStr.insert(18, 1, '-'); 341a974c132SLakshmi Yadlapati valueStr.insert(23, 1, '-'); 342a974c132SLakshmi Yadlapati } 343a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("UUID = {}", valueStr); 344a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["UUID"] = valueStr; 345a974c132SLakshmi Yadlapati } 346a974c132SLakshmi Yadlapati } 347a974c132SLakshmi Yadlapati 348a974c132SLakshmi Yadlapati inline void 349a974c132SLakshmi Yadlapati afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 350a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 351a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& propertiesList) 352a974c132SLakshmi Yadlapati { 353a974c132SLakshmi Yadlapati if (ec) 354a974c132SLakshmi Yadlapati { 355a974c132SLakshmi Yadlapati // doesn't have to include this 356a974c132SLakshmi Yadlapati // interface 357a974c132SLakshmi Yadlapati return; 358a974c132SLakshmi Yadlapati } 359a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size()); 360a974c132SLakshmi Yadlapati 361a974c132SLakshmi Yadlapati const std::string* partNumber = nullptr; 362a974c132SLakshmi Yadlapati const std::string* serialNumber = nullptr; 363a974c132SLakshmi Yadlapati const std::string* manufacturer = nullptr; 364a974c132SLakshmi Yadlapati const std::string* model = nullptr; 365a974c132SLakshmi Yadlapati const std::string* subModel = nullptr; 366a974c132SLakshmi Yadlapati 367a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 368a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber", 369a974c132SLakshmi Yadlapati partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 370a974c132SLakshmi Yadlapati "Model", model, "SubModel", subModel); 371a974c132SLakshmi Yadlapati 372a974c132SLakshmi Yadlapati if (!success) 373a974c132SLakshmi Yadlapati { 374a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 375a974c132SLakshmi Yadlapati return; 376a974c132SLakshmi Yadlapati } 377a974c132SLakshmi Yadlapati 378a974c132SLakshmi Yadlapati if (partNumber != nullptr) 379a974c132SLakshmi Yadlapati { 380a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["PartNumber"] = *partNumber; 381a974c132SLakshmi Yadlapati } 382a974c132SLakshmi Yadlapati 383a974c132SLakshmi Yadlapati if (serialNumber != nullptr) 384a974c132SLakshmi Yadlapati { 385a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 386a974c132SLakshmi Yadlapati } 387a974c132SLakshmi Yadlapati 388a974c132SLakshmi Yadlapati if (manufacturer != nullptr) 389a974c132SLakshmi Yadlapati { 390a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 391a974c132SLakshmi Yadlapati } 392a974c132SLakshmi Yadlapati 393a974c132SLakshmi Yadlapati if (model != nullptr) 394a974c132SLakshmi Yadlapati { 395a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Model"] = *model; 396a974c132SLakshmi Yadlapati } 397a974c132SLakshmi Yadlapati 398a974c132SLakshmi Yadlapati if (subModel != nullptr) 399a974c132SLakshmi Yadlapati { 400a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SubModel"] = *subModel; 401a974c132SLakshmi Yadlapati } 402a974c132SLakshmi Yadlapati 403a974c132SLakshmi Yadlapati // Grab the bios version 404a974c132SLakshmi Yadlapati sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, 405a974c132SLakshmi Yadlapati "BiosVersion", false); 406a974c132SLakshmi Yadlapati } 407a974c132SLakshmi Yadlapati 408a974c132SLakshmi Yadlapati inline void 409a974c132SLakshmi Yadlapati afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 410a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 411a974c132SLakshmi Yadlapati const std::string& value) 412a974c132SLakshmi Yadlapati { 413a974c132SLakshmi Yadlapati if (ec) 414a974c132SLakshmi Yadlapati { 415a974c132SLakshmi Yadlapati // doesn't have to include this 416a974c132SLakshmi Yadlapati // interface 417a974c132SLakshmi Yadlapati return; 418a974c132SLakshmi Yadlapati } 419a974c132SLakshmi Yadlapati 420a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["AssetTag"] = value; 421a974c132SLakshmi Yadlapati } 422a974c132SLakshmi Yadlapati 423a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree( 424a974c132SLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 425a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 426a974c132SLakshmi Yadlapati const dbus::utility::MapperGetSubTreeResponse& subtree) 427a974c132SLakshmi Yadlapati { 4281abe55efSEd Tanous if (ec) 4291abe55efSEd Tanous { 430b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 431ac106bf6SEd Tanous messages::internalError(asyncResp->res); 432c5b2abe0SLewanczyk, Dawid return; 433c5b2abe0SLewanczyk, Dawid } 434c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 435002d39b4SEd Tanous for (const std::pair< 436002d39b4SEd Tanous std::string, 437002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 4381214b7e7SGunnar Mills object : subtree) 4391abe55efSEd Tanous { 440c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 44162598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 442002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 4431214b7e7SGunnar Mills connectionNames = object.second; 44426f6976fSEd Tanous if (connectionNames.empty()) 4451abe55efSEd Tanous { 446c5b2abe0SLewanczyk, Dawid continue; 447c5b2abe0SLewanczyk, Dawid } 448029573d4SEd Tanous 4496c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4506c34de48SEd Tanous // BiosVer 45104a258f4SEd Tanous for (const auto& connection : connectionNames) 4521abe55efSEd Tanous { 45304a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4541abe55efSEd Tanous { 455a974c132SLakshmi Yadlapati if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") 4561abe55efSEd Tanous { 45762598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 4589d3ae10eSAlpana Kumari 459ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4605fd0aafbSNinad Palsule } 46104a258f4SEd Tanous else if (interfaceName == 46204a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4631abe55efSEd Tanous { 46462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 46557e8c9beSAlpana Kumari 466ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4675fd0aafbSNinad Palsule } 468002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4691abe55efSEd Tanous { 47062598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 471bc1d29deSKrzysztof Grobelny 472bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 473a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 474a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 475ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 476b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4771214b7e7SGunnar Mills properties) { 478a974c132SLakshmi Yadlapati afterGetUUID(asyncResp, ec3, properties); 479bc1d29deSKrzysztof Grobelny }); 480c5b2abe0SLewanczyk, Dawid } 481029573d4SEd Tanous else if (interfaceName == 482029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4831abe55efSEd Tanous { 484bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 485a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 486bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 487a974c132SLakshmi Yadlapati [asyncResp](const boost::system::error_code& ec3, 488b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 489a974c132SLakshmi Yadlapati properties) { 490a974c132SLakshmi Yadlapati afterGetInventory(asyncResp, ec3, properties); 491bc1d29deSKrzysztof Grobelny }); 492e4a4b9a9SJames Feist 4931e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 494a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 4951e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 4961e1e598dSJonathan Doman "AssetTag", 4971e1e598dSJonathan Doman "AssetTag", 498a974c132SLakshmi Yadlapati std::bind_front(afterGetAssetTag, asyncResp)); 499a974c132SLakshmi Yadlapati } 500a974c132SLakshmi Yadlapati } 501a974c132SLakshmi Yadlapati } 502a974c132SLakshmi Yadlapati } 503a974c132SLakshmi Yadlapati } 504a974c132SLakshmi Yadlapati 505a974c132SLakshmi Yadlapati /* 506a974c132SLakshmi Yadlapati * @brief Retrieves computer system properties over dbus 507a974c132SLakshmi Yadlapati * 508a974c132SLakshmi Yadlapati * @param[in] asyncResp Shared pointer for completing asynchronous calls 509a974c132SLakshmi Yadlapati * 510a974c132SLakshmi Yadlapati * @return None. 511a974c132SLakshmi Yadlapati */ 512a974c132SLakshmi Yadlapati inline void 51351bd2d8aSGunnar Mills getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 514e4a4b9a9SJames Feist { 515a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get available system components."); 516a974c132SLakshmi Yadlapati constexpr std::array<std::string_view, 5> interfaces = { 517a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 518a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Cpu", 519a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Dimm", 520a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.System", 521a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 522a974c132SLakshmi Yadlapati }; 523a974c132SLakshmi Yadlapati dbus::utility::getSubTree( 524a974c132SLakshmi Yadlapati "/xyz/openbmc_project/inventory", 0, interfaces, 52551bd2d8aSGunnar Mills std::bind_front(afterSystemGetSubTree, asyncResp)); 526c5b2abe0SLewanczyk, Dawid } 527c5b2abe0SLewanczyk, Dawid 528c5b2abe0SLewanczyk, Dawid /** 529c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 530c5b2abe0SLewanczyk, Dawid * 531ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 532c5b2abe0SLewanczyk, Dawid * 533c5b2abe0SLewanczyk, Dawid * @return None. 534c5b2abe0SLewanczyk, Dawid */ 535ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5361abe55efSEd Tanous { 53762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 5381e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 5391e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 5401e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 5411e1e598dSJonathan Doman "CurrentHostState", 542ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 5431e1e598dSJonathan Doman const std::string& hostState) { 5441abe55efSEd Tanous if (ec) 5451abe55efSEd Tanous { 54622228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 54722228c28SAndrew Geissler { 54822228c28SAndrew Geissler // Service not available, no error, just don't return 54922228c28SAndrew Geissler // host state info 55062598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 55122228c28SAndrew Geissler return; 55222228c28SAndrew Geissler } 55362598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 554ac106bf6SEd Tanous messages::internalError(asyncResp->res); 555c5b2abe0SLewanczyk, Dawid return; 556c5b2abe0SLewanczyk, Dawid } 5576617338dSEd Tanous 55862598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 559c5b2abe0SLewanczyk, Dawid // Verify Host State 5601e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5611abe55efSEd Tanous { 562*539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On; 563*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 564*539d8c6bSEd Tanous resource::State::Enabled; 5651abe55efSEd Tanous } 5661e1e598dSJonathan Doman else if (hostState == 5670fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5688c888608SGunnar Mills { 569*539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On; 570*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 571*539d8c6bSEd Tanous resource::State::Quiesced; 5728c888608SGunnar Mills } 5731e1e598dSJonathan Doman else if (hostState == 5740fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 57583935af9SAndrew Geissler { 576*539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On; 577*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 578*539d8c6bSEd Tanous resource::State::InTest; 57983935af9SAndrew Geissler } 5800fda0f12SGeorge Liu else if ( 5811e1e598dSJonathan Doman hostState == 5820fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5831a2a1437SAndrew Geissler { 584*539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 585*539d8c6bSEd Tanous resource::PowerState::PoweringOn; 586*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 587*539d8c6bSEd Tanous resource::State::Starting; 5881a2a1437SAndrew Geissler } 589002d39b4SEd Tanous else if (hostState == 5900fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5911a2a1437SAndrew Geissler { 592*539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 593*539d8c6bSEd Tanous resource::PowerState::PoweringOff; 594*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 595*539d8c6bSEd Tanous resource::State::Disabled; 5961a2a1437SAndrew Geissler } 5971abe55efSEd Tanous else 5981abe55efSEd Tanous { 599*539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = resource::PowerState::Off; 600*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 601*539d8c6bSEd Tanous resource::State::Disabled; 602c5b2abe0SLewanczyk, Dawid } 6031e1e598dSJonathan Doman }); 604c5b2abe0SLewanczyk, Dawid } 605c5b2abe0SLewanczyk, Dawid 606c5b2abe0SLewanczyk, Dawid /** 607786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 608491d8ee7SSantosh Puranik * 609491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 610491d8ee7SSantosh Puranik * 611491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 612491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 613491d8ee7SSantosh Puranik */ 61423a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 615491d8ee7SSantosh Puranik { 616491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 617491d8ee7SSantosh Puranik { 618491d8ee7SSantosh Puranik return "None"; 619491d8ee7SSantosh Puranik } 6203174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 621491d8ee7SSantosh Puranik { 622491d8ee7SSantosh Puranik return "Hdd"; 623491d8ee7SSantosh Puranik } 6243174e4dfSEd Tanous if (dbusSource == 625a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 626491d8ee7SSantosh Puranik { 627491d8ee7SSantosh Puranik return "Cd"; 628491d8ee7SSantosh Puranik } 6293174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 630491d8ee7SSantosh Puranik { 631491d8ee7SSantosh Puranik return "Pxe"; 632491d8ee7SSantosh Puranik } 6333174e4dfSEd Tanous if (dbusSource == 634944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6359f16b2c1SJennifer Lee { 6369f16b2c1SJennifer Lee return "Usb"; 6379f16b2c1SJennifer Lee } 638491d8ee7SSantosh Puranik return ""; 639491d8ee7SSantosh Puranik } 640491d8ee7SSantosh Puranik 641491d8ee7SSantosh Puranik /** 642cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 643cd9a4666SKonstantin Aladyshev * 644cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 645cd9a4666SKonstantin Aladyshev * 646cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 647cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 648cd9a4666SKonstantin Aladyshev */ 649cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 650cd9a4666SKonstantin Aladyshev { 651cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 652cd9a4666SKonstantin Aladyshev { 653cd9a4666SKonstantin Aladyshev return "Legacy"; 654cd9a4666SKonstantin Aladyshev } 655cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 656cd9a4666SKonstantin Aladyshev { 657cd9a4666SKonstantin Aladyshev return "UEFI"; 658cd9a4666SKonstantin Aladyshev } 659cd9a4666SKonstantin Aladyshev return ""; 660cd9a4666SKonstantin Aladyshev } 661cd9a4666SKonstantin Aladyshev 662cd9a4666SKonstantin Aladyshev /** 663786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 664491d8ee7SSantosh Puranik * 665491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 666491d8ee7SSantosh Puranik * 667491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 668491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 669491d8ee7SSantosh Puranik */ 67023a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 671491d8ee7SSantosh Puranik { 672491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 673491d8ee7SSantosh Puranik { 674491d8ee7SSantosh Puranik return "None"; 675491d8ee7SSantosh Puranik } 6763174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 677491d8ee7SSantosh Puranik { 678491d8ee7SSantosh Puranik return "Diags"; 679491d8ee7SSantosh Puranik } 6803174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 681491d8ee7SSantosh Puranik { 682491d8ee7SSantosh Puranik return "BiosSetup"; 683491d8ee7SSantosh Puranik } 684491d8ee7SSantosh Puranik return ""; 685491d8ee7SSantosh Puranik } 686491d8ee7SSantosh Puranik 687491d8ee7SSantosh Puranik /** 688e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 689e43914b3SAndrew Geissler * 690e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 691e43914b3SAndrew Geissler * 692e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 693e43914b3SAndrew Geissler * translation cannot be done, returns "None". 694e43914b3SAndrew Geissler */ 695e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 696e43914b3SAndrew Geissler { 697e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 698e43914b3SAndrew Geissler // enum 699e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 700e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 701e43914b3SAndrew Geissler "ProgressStages.Unspecified") 702e43914b3SAndrew Geissler { 703e43914b3SAndrew Geissler rfBpLastState = "None"; 704e43914b3SAndrew Geissler } 705e43914b3SAndrew Geissler else if (dbusBootProgress == 706e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 707e43914b3SAndrew Geissler "PrimaryProcInit") 708e43914b3SAndrew Geissler { 709e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 710e43914b3SAndrew Geissler } 711e43914b3SAndrew Geissler else if (dbusBootProgress == 712e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 713e43914b3SAndrew Geissler "BusInit") 714e43914b3SAndrew Geissler { 715e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 716e43914b3SAndrew Geissler } 717e43914b3SAndrew Geissler else if (dbusBootProgress == 718e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 719e43914b3SAndrew Geissler "MemoryInit") 720e43914b3SAndrew Geissler { 721e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 722e43914b3SAndrew Geissler } 723e43914b3SAndrew Geissler else if (dbusBootProgress == 724e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 725e43914b3SAndrew Geissler "SecondaryProcInit") 726e43914b3SAndrew Geissler { 727e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 728e43914b3SAndrew Geissler } 729e43914b3SAndrew Geissler else if (dbusBootProgress == 730e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 731e43914b3SAndrew Geissler "PCIInit") 732e43914b3SAndrew Geissler { 733e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 734e43914b3SAndrew Geissler } 735e43914b3SAndrew Geissler else if (dbusBootProgress == 736e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 737e43914b3SAndrew Geissler "SystemSetup") 738e43914b3SAndrew Geissler { 739e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 740e43914b3SAndrew Geissler } 741e43914b3SAndrew Geissler else if (dbusBootProgress == 742e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 743e43914b3SAndrew Geissler "SystemInitComplete") 744e43914b3SAndrew Geissler { 745e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 746e43914b3SAndrew Geissler } 747e43914b3SAndrew Geissler else if (dbusBootProgress == 748e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 749e43914b3SAndrew Geissler "OSStart") 750e43914b3SAndrew Geissler { 751e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 752e43914b3SAndrew Geissler } 753e43914b3SAndrew Geissler else if (dbusBootProgress == 754e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 755e43914b3SAndrew Geissler "OSRunning") 756e43914b3SAndrew Geissler { 757e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 758e43914b3SAndrew Geissler } 759e43914b3SAndrew Geissler else 760e43914b3SAndrew Geissler { 76162598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 762e43914b3SAndrew Geissler // Just return the default 763e43914b3SAndrew Geissler } 764e43914b3SAndrew Geissler return rfBpLastState; 765e43914b3SAndrew Geissler } 766e43914b3SAndrew Geissler 767e43914b3SAndrew Geissler /** 768786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 769491d8ee7SSantosh Puranik * 770491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 771944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 772944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 773491d8ee7SSantosh Puranik * 774944ffaf9SJohnathan Mantey * @return Integer error code. 775491d8ee7SSantosh Puranik */ 776ac106bf6SEd Tanous inline int 777ac106bf6SEd Tanous assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 778ac106bf6SEd Tanous const std::string& rfSource, std::string& bootSource, 779ac106bf6SEd Tanous std::string& bootMode) 780491d8ee7SSantosh Puranik { 781c21865c4SKonstantin Aladyshev bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; 782c21865c4SKonstantin Aladyshev bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; 783944ffaf9SJohnathan Mantey 784491d8ee7SSantosh Puranik if (rfSource == "None") 785491d8ee7SSantosh Puranik { 786944ffaf9SJohnathan Mantey return 0; 787491d8ee7SSantosh Puranik } 7883174e4dfSEd Tanous if (rfSource == "Pxe") 789491d8ee7SSantosh Puranik { 790944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network"; 791944ffaf9SJohnathan Mantey } 792944ffaf9SJohnathan Mantey else if (rfSource == "Hdd") 793944ffaf9SJohnathan Mantey { 794944ffaf9SJohnathan Mantey bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk"; 795944ffaf9SJohnathan Mantey } 796944ffaf9SJohnathan Mantey else if (rfSource == "Diags") 797944ffaf9SJohnathan Mantey { 798944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe"; 799944ffaf9SJohnathan Mantey } 800944ffaf9SJohnathan Mantey else if (rfSource == "Cd") 801944ffaf9SJohnathan Mantey { 802944ffaf9SJohnathan Mantey bootSource = 803944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia"; 804944ffaf9SJohnathan Mantey } 805944ffaf9SJohnathan Mantey else if (rfSource == "BiosSetup") 806944ffaf9SJohnathan Mantey { 807944ffaf9SJohnathan Mantey bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup"; 808491d8ee7SSantosh Puranik } 8099f16b2c1SJennifer Lee else if (rfSource == "Usb") 8109f16b2c1SJennifer Lee { 811944ffaf9SJohnathan Mantey bootSource = 812944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia"; 8139f16b2c1SJennifer Lee } 814491d8ee7SSantosh Puranik else 815491d8ee7SSantosh Puranik { 81662598e31SEd Tanous BMCWEB_LOG_DEBUG( 81762598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 81862598e31SEd Tanous bootSource); 819ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, rfSource, 820944ffaf9SJohnathan Mantey "BootSourceTargetOverride"); 821944ffaf9SJohnathan Mantey return -1; 822491d8ee7SSantosh Puranik } 823944ffaf9SJohnathan Mantey return 0; 824491d8ee7SSantosh Puranik } 8251981771bSAli Ahmed 826978b8803SAndrew Geissler /** 827978b8803SAndrew Geissler * @brief Retrieves boot progress of the system 828978b8803SAndrew Geissler * 829ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 830978b8803SAndrew Geissler * 831978b8803SAndrew Geissler * @return None. 832978b8803SAndrew Geissler */ 833ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 834978b8803SAndrew Geissler { 8351e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 8361e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 8371e1e598dSJonathan Doman "/xyz/openbmc_project/state/host0", 8381e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 839ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8401e1e598dSJonathan Doman const std::string& bootProgressStr) { 841978b8803SAndrew Geissler if (ec) 842978b8803SAndrew Geissler { 843978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 844978b8803SAndrew Geissler // not found 845978b8803SAndrew Geissler return; 846978b8803SAndrew Geissler } 847978b8803SAndrew Geissler 84862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 849978b8803SAndrew Geissler 850ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 851e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8521e1e598dSJonathan Doman }); 853978b8803SAndrew Geissler } 854491d8ee7SSantosh Puranik 855491d8ee7SSantosh Puranik /** 856b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 857b6d5d45cSHieu Huynh * 858ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 859b6d5d45cSHieu Huynh * 860b6d5d45cSHieu Huynh * @return None. 861b6d5d45cSHieu Huynh */ 862b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 863ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 864b6d5d45cSHieu Huynh { 865b6d5d45cSHieu Huynh sdbusplus::asio::getProperty<uint64_t>( 866b6d5d45cSHieu Huynh *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 867b6d5d45cSHieu Huynh "/xyz/openbmc_project/state/host0", 868b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 869ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 870b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 871b6d5d45cSHieu Huynh if (ec) 872b6d5d45cSHieu Huynh { 87362598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 874b6d5d45cSHieu Huynh return; 875b6d5d45cSHieu Huynh } 876b6d5d45cSHieu Huynh 877b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 878b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 879b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 880b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 881b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 882b6d5d45cSHieu Huynh 883b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 884ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 885b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 886b6d5d45cSHieu Huynh }); 887b6d5d45cSHieu Huynh } 888b6d5d45cSHieu Huynh 889b6d5d45cSHieu Huynh /** 890c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 891cd9a4666SKonstantin Aladyshev * 892ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 893cd9a4666SKonstantin Aladyshev * 894cd9a4666SKonstantin Aladyshev * @return None. 895cd9a4666SKonstantin Aladyshev */ 896cd9a4666SKonstantin Aladyshev 897ac106bf6SEd Tanous inline void 898ac106bf6SEd Tanous getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 899cd9a4666SKonstantin Aladyshev { 9001e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9011e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9021e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9031e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 904ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9051e1e598dSJonathan Doman const std::string& bootType) { 906cd9a4666SKonstantin Aladyshev if (ec) 907cd9a4666SKonstantin Aladyshev { 908cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 909cd9a4666SKonstantin Aladyshev return; 910cd9a4666SKonstantin Aladyshev } 911cd9a4666SKonstantin Aladyshev 91262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 913cd9a4666SKonstantin Aladyshev 914ac106bf6SEd Tanous asyncResp->res 915ac106bf6SEd Tanous .jsonValue["Boot"] 916002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 917613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 918cd9a4666SKonstantin Aladyshev 9191e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 920cd9a4666SKonstantin Aladyshev if (rfType.empty()) 921cd9a4666SKonstantin Aladyshev { 922ac106bf6SEd Tanous messages::internalError(asyncResp->res); 923cd9a4666SKonstantin Aladyshev return; 924cd9a4666SKonstantin Aladyshev } 925cd9a4666SKonstantin Aladyshev 926ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9271e1e598dSJonathan Doman }); 928cd9a4666SKonstantin Aladyshev } 929cd9a4666SKonstantin Aladyshev 930cd9a4666SKonstantin Aladyshev /** 931c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 932491d8ee7SSantosh Puranik * 933ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 934491d8ee7SSantosh Puranik * 935491d8ee7SSantosh Puranik * @return None. 936491d8ee7SSantosh Puranik */ 937c21865c4SKonstantin Aladyshev 938ac106bf6SEd Tanous inline void 939ac106bf6SEd Tanous getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 940491d8ee7SSantosh Puranik { 9411e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9421e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9431e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9441e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 945ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9461e1e598dSJonathan Doman const std::string& bootModeStr) { 947491d8ee7SSantosh Puranik if (ec) 948491d8ee7SSantosh Puranik { 949b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 950ac106bf6SEd Tanous messages::internalError(asyncResp->res); 951491d8ee7SSantosh Puranik return; 952491d8ee7SSantosh Puranik } 953491d8ee7SSantosh Puranik 95462598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 955491d8ee7SSantosh Puranik 95620fa6a2cSEd Tanous nlohmann::json::array_t allowed; 95720fa6a2cSEd Tanous allowed.emplace_back("None"); 95820fa6a2cSEd Tanous allowed.emplace_back("Pxe"); 95920fa6a2cSEd Tanous allowed.emplace_back("Hdd"); 96020fa6a2cSEd Tanous allowed.emplace_back("Cd"); 96120fa6a2cSEd Tanous allowed.emplace_back("Diags"); 96220fa6a2cSEd Tanous allowed.emplace_back("BiosSetup"); 96320fa6a2cSEd Tanous allowed.emplace_back("Usb"); 96420fa6a2cSEd Tanous 965ac106bf6SEd Tanous asyncResp->res 9660fda0f12SGeorge Liu .jsonValue["Boot"] 96720fa6a2cSEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = 96820fa6a2cSEd Tanous std::move(allowed); 9691e1e598dSJonathan Doman if (bootModeStr != 970491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 971491d8ee7SSantosh Puranik { 9721e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 973491d8ee7SSantosh Puranik if (!rfMode.empty()) 974491d8ee7SSantosh Puranik { 975ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 976491d8ee7SSantosh Puranik rfMode; 977491d8ee7SSantosh Puranik } 978491d8ee7SSantosh Puranik } 9791e1e598dSJonathan Doman }); 980491d8ee7SSantosh Puranik } 981491d8ee7SSantosh Puranik 982491d8ee7SSantosh Puranik /** 983c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 984491d8ee7SSantosh Puranik * 985ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 986491d8ee7SSantosh Puranik * 987491d8ee7SSantosh Puranik * @return None. 988491d8ee7SSantosh Puranik */ 989c21865c4SKonstantin Aladyshev 990c21865c4SKonstantin Aladyshev inline void 991ac106bf6SEd Tanous getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 992491d8ee7SSantosh Puranik { 9931e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 9941e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 9951e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9961e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 997ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9981e1e598dSJonathan Doman const std::string& bootSourceStr) { 999491d8ee7SSantosh Puranik if (ec) 1000491d8ee7SSantosh Puranik { 10015ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10025ef735c8SNan Zhou { 10035ef735c8SNan Zhou return; 10045ef735c8SNan Zhou } 1005b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1006ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1007491d8ee7SSantosh Puranik return; 1008491d8ee7SSantosh Puranik } 1009491d8ee7SSantosh Puranik 101062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr); 1011491d8ee7SSantosh Puranik 10121e1e598dSJonathan Doman auto rfSource = dbusToRfBootSource(bootSourceStr); 1013491d8ee7SSantosh Puranik if (!rfSource.empty()) 1014491d8ee7SSantosh Puranik { 1015ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = 1016ac106bf6SEd Tanous rfSource; 1017491d8ee7SSantosh Puranik } 1018cd9a4666SKonstantin Aladyshev 1019cd9a4666SKonstantin Aladyshev // Get BootMode as BootSourceOverrideTarget is constructed 1020cd9a4666SKonstantin Aladyshev // from both BootSource and BootMode 1021ac106bf6SEd Tanous getBootOverrideMode(asyncResp); 10221e1e598dSJonathan Doman }); 1023491d8ee7SSantosh Puranik } 1024491d8ee7SSantosh Puranik 1025491d8ee7SSantosh Puranik /** 1026c21865c4SKonstantin Aladyshev * @brief This functions abstracts all the logic behind getting a 1027c21865c4SKonstantin Aladyshev * "BootSourceOverrideEnabled" property from an overall boot override enable 1028c21865c4SKonstantin Aladyshev * state 1029491d8ee7SSantosh Puranik * 1030ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1031491d8ee7SSantosh Puranik * 1032491d8ee7SSantosh Puranik * @return None. 1033491d8ee7SSantosh Puranik */ 1034491d8ee7SSantosh Puranik 1035ac106bf6SEd Tanous inline void processBootOverrideEnable( 1036ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1037c21865c4SKonstantin Aladyshev const bool bootOverrideEnableSetting) 1038c21865c4SKonstantin Aladyshev { 1039c21865c4SKonstantin Aladyshev if (!bootOverrideEnableSetting) 1040c21865c4SKonstantin Aladyshev { 1041ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1042ac106bf6SEd Tanous "Disabled"; 1043c21865c4SKonstantin Aladyshev return; 1044c21865c4SKonstantin Aladyshev } 1045c21865c4SKonstantin Aladyshev 1046c21865c4SKonstantin Aladyshev // If boot source override is enabled, we need to check 'one_time' 1047c21865c4SKonstantin Aladyshev // property to set a correct value for the "BootSourceOverrideEnabled" 10481e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10491e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10501e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot/one_time", 10511e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1052ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) { 1053491d8ee7SSantosh Puranik if (ec) 1054491d8ee7SSantosh Puranik { 1055b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1056ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1057491d8ee7SSantosh Puranik return; 1058491d8ee7SSantosh Puranik } 1059491d8ee7SSantosh Puranik 1060c21865c4SKonstantin Aladyshev if (oneTimeSetting) 1061c21865c4SKonstantin Aladyshev { 1062ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1063ac106bf6SEd Tanous "Once"; 1064c21865c4SKonstantin Aladyshev } 1065c21865c4SKonstantin Aladyshev else 1066c21865c4SKonstantin Aladyshev { 1067ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = 1068c21865c4SKonstantin Aladyshev "Continuous"; 1069c21865c4SKonstantin Aladyshev } 10701e1e598dSJonathan Doman }); 1071491d8ee7SSantosh Puranik } 1072491d8ee7SSantosh Puranik 1073491d8ee7SSantosh Puranik /** 1074c21865c4SKonstantin Aladyshev * @brief Retrieves boot override enable over DBUS 1075c21865c4SKonstantin Aladyshev * 1076ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1077c21865c4SKonstantin Aladyshev * 1078c21865c4SKonstantin Aladyshev * @return None. 1079c21865c4SKonstantin Aladyshev */ 1080c21865c4SKonstantin Aladyshev 1081c21865c4SKonstantin Aladyshev inline void 1082ac106bf6SEd Tanous getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1083c21865c4SKonstantin Aladyshev { 10841e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 10851e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 10861e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 10871e1e598dSJonathan Doman "xyz.openbmc_project.Object.Enable", "Enabled", 1088ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 10891e1e598dSJonathan Doman const bool bootOverrideEnable) { 1090c21865c4SKonstantin Aladyshev if (ec) 1091c21865c4SKonstantin Aladyshev { 10925ef735c8SNan Zhou if (ec.value() == boost::asio::error::host_unreachable) 10935ef735c8SNan Zhou { 10945ef735c8SNan Zhou return; 10955ef735c8SNan Zhou } 1096b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1097ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1098c21865c4SKonstantin Aladyshev return; 1099c21865c4SKonstantin Aladyshev } 1100c21865c4SKonstantin Aladyshev 1101ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11021e1e598dSJonathan Doman }); 1103c21865c4SKonstantin Aladyshev } 1104c21865c4SKonstantin Aladyshev 1105c21865c4SKonstantin Aladyshev /** 1106c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1107c21865c4SKonstantin Aladyshev * 1108ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1109c21865c4SKonstantin Aladyshev * 1110c21865c4SKonstantin Aladyshev * @return None. 1111c21865c4SKonstantin Aladyshev */ 1112ac106bf6SEd Tanous inline void 1113ac106bf6SEd Tanous getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1114c21865c4SKonstantin Aladyshev { 111562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1116c21865c4SKonstantin Aladyshev 1117ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1118ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1119ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1120c21865c4SKonstantin Aladyshev } 1121c21865c4SKonstantin Aladyshev 1122c21865c4SKonstantin Aladyshev /** 1123c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1124c0557e1aSGunnar Mills * 1125c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1126c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1127c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1128c0557e1aSGunnar Mills * last power operation time. 1129c0557e1aSGunnar Mills * 1130ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1131c0557e1aSGunnar Mills * 1132c0557e1aSGunnar Mills * @return None. 1133c0557e1aSGunnar Mills */ 1134ac106bf6SEd Tanous inline void 1135ac106bf6SEd Tanous getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1136c0557e1aSGunnar Mills { 113762598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1138c0557e1aSGunnar Mills 11391e1e598dSJonathan Doman sdbusplus::asio::getProperty<uint64_t>( 11401e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 11411e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11421e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1143ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1144ac106bf6SEd Tanous uint64_t lastResetTime) { 1145c0557e1aSGunnar Mills if (ec) 1146c0557e1aSGunnar Mills { 114762598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1148c0557e1aSGunnar Mills return; 1149c0557e1aSGunnar Mills } 1150c0557e1aSGunnar Mills 1151c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1152c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11531e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1154c0557e1aSGunnar Mills 1155c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1156ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 11572b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11581e1e598dSJonathan Doman }); 1159c0557e1aSGunnar Mills } 1160c0557e1aSGunnar Mills 1161c0557e1aSGunnar Mills /** 1162797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1163797d5daeSCorey Hardesty * 1164797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1165797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1166797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1167797d5daeSCorey Hardesty * dbus. 1168797d5daeSCorey Hardesty * 1169ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1170797d5daeSCorey Hardesty * 1171797d5daeSCorey Hardesty * @return None. 1172797d5daeSCorey Hardesty */ 1173ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1174ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1175797d5daeSCorey Hardesty { 117662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1177797d5daeSCorey Hardesty 1178797d5daeSCorey Hardesty sdbusplus::asio::getAllProperties( 1179797d5daeSCorey Hardesty *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 1180797d5daeSCorey Hardesty "/xyz/openbmc_project/state/host0", 1181797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1182ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1183ac106bf6SEd Tanous const boost::system::error_code& ec, 1184797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1185797d5daeSCorey Hardesty if (ec) 1186797d5daeSCorey Hardesty { 1187797d5daeSCorey Hardesty if (ec.value() != EBADR) 1188797d5daeSCorey Hardesty { 118962598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1190ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1191797d5daeSCorey Hardesty } 1192797d5daeSCorey Hardesty return; 1193797d5daeSCorey Hardesty } 1194797d5daeSCorey Hardesty 1195797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1196797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1197797d5daeSCorey Hardesty 1198797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1199797d5daeSCorey Hardesty dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft", 1200797d5daeSCorey Hardesty attemptsLeft, "RetryAttempts", retryAttempts); 1201797d5daeSCorey Hardesty 1202797d5daeSCorey Hardesty if (!success) 1203797d5daeSCorey Hardesty { 1204ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1205797d5daeSCorey Hardesty return; 1206797d5daeSCorey Hardesty } 1207797d5daeSCorey Hardesty 1208797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1209797d5daeSCorey Hardesty { 1210ac106bf6SEd Tanous asyncResp->res 1211ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1212797d5daeSCorey Hardesty *attemptsLeft; 1213797d5daeSCorey Hardesty } 1214797d5daeSCorey Hardesty 1215797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1216797d5daeSCorey Hardesty { 1217ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1218797d5daeSCorey Hardesty *retryAttempts; 1219797d5daeSCorey Hardesty } 1220797d5daeSCorey Hardesty }); 1221797d5daeSCorey Hardesty } 1222797d5daeSCorey Hardesty 1223797d5daeSCorey Hardesty /** 12246bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12256bd5a8d2SGunnar Mills * 1226ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12276bd5a8d2SGunnar Mills * 12286bd5a8d2SGunnar Mills * @return None. 12296bd5a8d2SGunnar Mills */ 1230797d5daeSCorey Hardesty inline void 1231ac106bf6SEd Tanous getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12326bd5a8d2SGunnar Mills { 123362598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12346bd5a8d2SGunnar Mills 12351e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 12361e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 12371e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12381e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1239ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1240ac106bf6SEd Tanous bool autoRebootEnabled) { 12416bd5a8d2SGunnar Mills if (ec) 12426bd5a8d2SGunnar Mills { 1243797d5daeSCorey Hardesty if (ec.value() != EBADR) 1244797d5daeSCorey Hardesty { 124562598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1246ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1247797d5daeSCorey Hardesty } 12486bd5a8d2SGunnar Mills return; 12496bd5a8d2SGunnar Mills } 12506bd5a8d2SGunnar Mills 125162598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1252e05aec50SEd Tanous if (autoRebootEnabled) 12536bd5a8d2SGunnar Mills { 1254ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12556bd5a8d2SGunnar Mills "RetryAttempts"; 12566bd5a8d2SGunnar Mills } 12576bd5a8d2SGunnar Mills else 12586bd5a8d2SGunnar Mills { 1259ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1260ac106bf6SEd Tanous "Disabled"; 12616bd5a8d2SGunnar Mills } 1262ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 126369f35306SGunnar Mills 126469f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 126569f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 126669f35306SGunnar Mills // RetryAttempts. 126720fa6a2cSEd Tanous nlohmann::json::array_t allowed; 126820fa6a2cSEd Tanous allowed.emplace_back("Disabled"); 126920fa6a2cSEd Tanous allowed.emplace_back("RetryAttempts"); 1270ac106bf6SEd Tanous asyncResp->res 1271ac106bf6SEd Tanous .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] = 127220fa6a2cSEd Tanous std::move(allowed); 12731e1e598dSJonathan Doman }); 12746bd5a8d2SGunnar Mills } 12756bd5a8d2SGunnar Mills 12766bd5a8d2SGunnar Mills /** 1277797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1278797d5daeSCorey Hardesty * 1279ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1280797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1281797d5daeSCorey Hardesty * 1282797d5daeSCorey Hardesty *@return None. 1283797d5daeSCorey Hardesty */ 1284797d5daeSCorey Hardesty 1285ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1286ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1287797d5daeSCorey Hardesty const uint32_t retryAttempts) 1288797d5daeSCorey Hardesty { 128962598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 129087c44966SAsmitha Karunanithi setDbusProperty( 1291e93abac6SGinu George asyncResp, "Boot/AutomaticRetryAttempts", 1292e93abac6SGinu George "xyz.openbmc_project.State.Host", 129387c44966SAsmitha Karunanithi sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"), 12949ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1295e93abac6SGinu George retryAttempts); 1296797d5daeSCorey Hardesty } 1297797d5daeSCorey Hardesty 12988d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 12998d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 13008d69c668SEd Tanous { 13018d69c668SEd Tanous if (value == 13028d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 13038d69c668SEd Tanous { 13048d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 13058d69c668SEd Tanous } 13068d69c668SEd Tanous if (value == 13078d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 13088d69c668SEd Tanous { 13098d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13108d69c668SEd Tanous } 13118d69c668SEd Tanous if (value == 13123a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 13138d69c668SEd Tanous { 13148d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13158d69c668SEd Tanous } 13168d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13178d69c668SEd Tanous { 13188d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13198d69c668SEd Tanous } 13208d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13218d69c668SEd Tanous } 1322797d5daeSCorey Hardesty /** 1323c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1324c6a620f2SGeorge Liu * 1325ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1326c6a620f2SGeorge Liu * 1327c6a620f2SGeorge Liu * @return None. 1328c6a620f2SGeorge Liu */ 13298d1b46d7Szhanghch05 inline void 1330ac106bf6SEd Tanous getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1331c6a620f2SGeorge Liu { 133262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1333c6a620f2SGeorge Liu 13341e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 13351e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13361e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13371e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1338ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13395e7e2dc5SEd Tanous const std::string& policy) { 1340c6a620f2SGeorge Liu if (ec) 1341c6a620f2SGeorge Liu { 134262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1343c6a620f2SGeorge Liu return; 1344c6a620f2SGeorge Liu } 13458d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 13468d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 13478d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1348c6a620f2SGeorge Liu { 1349ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1350c6a620f2SGeorge Liu return; 1351c6a620f2SGeorge Liu } 1352c6a620f2SGeorge Liu 13538d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 13541e1e598dSJonathan Doman }); 1355c6a620f2SGeorge Liu } 1356c6a620f2SGeorge Liu 1357c6a620f2SGeorge Liu /** 13589dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 13599dcfe8c1SAlbert Zhang * 13609dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 13619dcfe8c1SAlbert Zhang * 13629dcfe8c1SAlbert Zhang * @return None. 13639dcfe8c1SAlbert Zhang */ 13649dcfe8c1SAlbert Zhang inline void 13659dcfe8c1SAlbert Zhang getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13669dcfe8c1SAlbert Zhang { 136762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 13689dcfe8c1SAlbert Zhang 13699dcfe8c1SAlbert Zhang sdbusplus::asio::getProperty<bool>( 13709dcfe8c1SAlbert Zhang *crow::connections::systemBus, "xyz.openbmc_project.Settings", 13719dcfe8c1SAlbert Zhang "/xyz/openbmc_project/logging/settings", 13729dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 13739dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 13749dcfe8c1SAlbert Zhang if (ec) 13759dcfe8c1SAlbert Zhang { 13769dcfe8c1SAlbert Zhang if (ec.value() != EBADR) 13779dcfe8c1SAlbert Zhang { 1378b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 13799dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 13809dcfe8c1SAlbert Zhang } 13819dcfe8c1SAlbert Zhang return; 13829dcfe8c1SAlbert Zhang } 13839dcfe8c1SAlbert Zhang 13849dcfe8c1SAlbert Zhang if (value) 13859dcfe8c1SAlbert Zhang { 1386*539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1387*539d8c6bSEd Tanous computer_system::StopBootOnFault::AnyFault; 13889dcfe8c1SAlbert Zhang } 13899dcfe8c1SAlbert Zhang else 13909dcfe8c1SAlbert Zhang { 1391*539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1392*539d8c6bSEd Tanous computer_system::StopBootOnFault::Never; 13939dcfe8c1SAlbert Zhang } 13949dcfe8c1SAlbert Zhang }); 13959dcfe8c1SAlbert Zhang } 13969dcfe8c1SAlbert Zhang 13979dcfe8c1SAlbert Zhang /** 13981981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 13991981771bSAli Ahmed * TPM is required for booting the host. 14001981771bSAli Ahmed * 1401ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14021981771bSAli Ahmed * 14031981771bSAli Ahmed * @return None. 14041981771bSAli Ahmed */ 14051981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1406ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14071981771bSAli Ahmed { 140862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1409e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1410e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1411e99073f5SGeorge Liu dbus::utility::getSubTree( 1412e99073f5SGeorge Liu "/", 0, interfaces, 1413ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1414b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14151981771bSAli Ahmed if (ec) 14161981771bSAli Ahmed { 141762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", 141862598e31SEd Tanous ec); 14191981771bSAli Ahmed // This is an optional D-Bus object so just return if 14201981771bSAli Ahmed // error occurs 14211981771bSAli Ahmed return; 14221981771bSAli Ahmed } 142326f6976fSEd Tanous if (subtree.empty()) 14241981771bSAli Ahmed { 14251981771bSAli Ahmed // As noted above, this is an optional interface so just return 14261981771bSAli Ahmed // if there is no instance found 14271981771bSAli Ahmed return; 14281981771bSAli Ahmed } 14291981771bSAli Ahmed 14301981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14311981771bSAli Ahmed if (subtree.size() > 1) 14321981771bSAli Ahmed { 143362598e31SEd Tanous BMCWEB_LOG_DEBUG( 143462598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 143562598e31SEd Tanous subtree.size()); 14361981771bSAli Ahmed // Throw an internal Error and return 1437ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14381981771bSAli Ahmed return; 14391981771bSAli Ahmed } 14401981771bSAli Ahmed 14411981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14421981771bSAli Ahmed // field 14431981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14441981771bSAli Ahmed { 144562598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1446ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14471981771bSAli Ahmed return; 14481981771bSAli Ahmed } 14491981771bSAli Ahmed 14501981771bSAli Ahmed const std::string& path = subtree[0].first; 14511981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14521981771bSAli Ahmed 14531981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 14541e1e598dSJonathan Doman sdbusplus::asio::getProperty<bool>( 14551e1e598dSJonathan Doman *crow::connections::systemBus, serv, path, 14561e1e598dSJonathan Doman "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", 1457ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1458ac106bf6SEd Tanous bool tpmRequired) { 14598a592810SEd Tanous if (ec2) 14601981771bSAli Ahmed { 1461b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}", 146262598e31SEd Tanous ec2); 1463ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14641981771bSAli Ahmed return; 14651981771bSAli Ahmed } 14661981771bSAli Ahmed 14671e1e598dSJonathan Doman if (tpmRequired) 14681981771bSAli Ahmed { 1469ac106bf6SEd Tanous asyncResp->res 1470ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14711981771bSAli Ahmed "Required"; 14721981771bSAli Ahmed } 14731981771bSAli Ahmed else 14741981771bSAli Ahmed { 1475ac106bf6SEd Tanous asyncResp->res 1476ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14771981771bSAli Ahmed "Disabled"; 14781981771bSAli Ahmed } 14791e1e598dSJonathan Doman }); 1480e99073f5SGeorge Liu }); 14811981771bSAli Ahmed } 14821981771bSAli Ahmed 14831981771bSAli Ahmed /** 14841c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14851c05dae3SAli Ahmed * TPM is required for booting the host. 14861c05dae3SAli Ahmed * 1487ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14881c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14891c05dae3SAli Ahmed * 14901c05dae3SAli Ahmed * @return None. 14911c05dae3SAli Ahmed */ 14921c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1493ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 14941c05dae3SAli Ahmed { 149562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1496e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1497e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1498e99073f5SGeorge Liu dbus::utility::getSubTree( 1499e99073f5SGeorge Liu "/", 0, interfaces, 1500ac106bf6SEd Tanous [asyncResp, 1501e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1502e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15031c05dae3SAli Ahmed if (ec) 15041c05dae3SAli Ahmed { 1505b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", 150662598e31SEd Tanous ec); 1507ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15081c05dae3SAli Ahmed return; 15091c05dae3SAli Ahmed } 151026f6976fSEd Tanous if (subtree.empty()) 15111c05dae3SAli Ahmed { 1512ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, "ComputerSystem", 15131c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15141c05dae3SAli Ahmed return; 15151c05dae3SAli Ahmed } 15161c05dae3SAli Ahmed 15171c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15181c05dae3SAli Ahmed if (subtree.size() > 1) 15191c05dae3SAli Ahmed { 152062598e31SEd Tanous BMCWEB_LOG_DEBUG( 152162598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 152262598e31SEd Tanous subtree.size()); 15231c05dae3SAli Ahmed // Throw an internal Error and return 1524ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15251c05dae3SAli Ahmed return; 15261c05dae3SAli Ahmed } 15271c05dae3SAli Ahmed 15281c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15291c05dae3SAli Ahmed // field 15301c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15311c05dae3SAli Ahmed { 153262598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1533ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15341c05dae3SAli Ahmed return; 15351c05dae3SAli Ahmed } 15361c05dae3SAli Ahmed 15371c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15381c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15391c05dae3SAli Ahmed 15401c05dae3SAli Ahmed if (serv.empty()) 15411c05dae3SAli Ahmed { 154262598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1543ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15441c05dae3SAli Ahmed return; 15451c05dae3SAli Ahmed } 15461c05dae3SAli Ahmed 15471c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 1548e93abac6SGinu George setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv, 1549e93abac6SGinu George path, "xyz.openbmc_project.Control.TPM.Policy", 1550e93abac6SGinu George "TPMEnable", tpmRequired); 1551e99073f5SGeorge Liu }); 15521c05dae3SAli Ahmed } 15531c05dae3SAli Ahmed 15541c05dae3SAli Ahmed /** 1555491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1556491d8ee7SSantosh Puranik * 1557ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1558cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1559cd9a4666SKonstantin Aladyshev * @return Integer error code. 1560cd9a4666SKonstantin Aladyshev */ 1561ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1562cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1563cd9a4666SKonstantin Aladyshev { 1564c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1565cd9a4666SKonstantin Aladyshev 1566c21865c4SKonstantin Aladyshev if (!bootType) 1567cd9a4666SKonstantin Aladyshev { 1568c21865c4SKonstantin Aladyshev return; 1569c21865c4SKonstantin Aladyshev } 1570c21865c4SKonstantin Aladyshev 1571cd9a4666SKonstantin Aladyshev // Source target specified 157262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1573cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1574cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1575cd9a4666SKonstantin Aladyshev { 1576cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1577cd9a4666SKonstantin Aladyshev } 1578cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1579cd9a4666SKonstantin Aladyshev { 1580cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1581cd9a4666SKonstantin Aladyshev } 1582cd9a4666SKonstantin Aladyshev else 1583cd9a4666SKonstantin Aladyshev { 158462598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 158562598e31SEd Tanous "BootSourceOverrideMode: {}", 158662598e31SEd Tanous *bootType); 1587ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1588cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1589cd9a4666SKonstantin Aladyshev return; 1590cd9a4666SKonstantin Aladyshev } 1591cd9a4666SKonstantin Aladyshev 1592cd9a4666SKonstantin Aladyshev // Act on validated parameters 159362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1594cd9a4666SKonstantin Aladyshev 1595e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode", 1596e93abac6SGinu George "xyz.openbmc_project.Settings", 159787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 159887c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 159987c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Type", "BootType", 1600e93abac6SGinu George bootTypeStr); 1601cd9a4666SKonstantin Aladyshev } 1602cd9a4666SKonstantin Aladyshev 1603cd9a4666SKonstantin Aladyshev /** 1604cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1605cd9a4666SKonstantin Aladyshev * 1606ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1607ac106bf6SEd Tanous * message. 1608c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1609c21865c4SKonstantin Aladyshev * @return Integer error code. 1610c21865c4SKonstantin Aladyshev */ 1611ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1612c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1613c21865c4SKonstantin Aladyshev { 1614c21865c4SKonstantin Aladyshev if (!bootEnable) 1615c21865c4SKonstantin Aladyshev { 1616c21865c4SKonstantin Aladyshev return; 1617c21865c4SKonstantin Aladyshev } 1618c21865c4SKonstantin Aladyshev // Source target specified 161962598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1620c21865c4SKonstantin Aladyshev 1621c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1622c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1623c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1624c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1625c21865c4SKonstantin Aladyshev { 1626c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1627c21865c4SKonstantin Aladyshev } 1628c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1629c21865c4SKonstantin Aladyshev { 1630c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1631c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1632c21865c4SKonstantin Aladyshev } 1633c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1634c21865c4SKonstantin Aladyshev { 1635c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1636c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1637c21865c4SKonstantin Aladyshev } 1638c21865c4SKonstantin Aladyshev else 1639c21865c4SKonstantin Aladyshev { 164062598e31SEd Tanous BMCWEB_LOG_DEBUG( 164162598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 164262598e31SEd Tanous *bootEnable); 1643ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1644c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1645c21865c4SKonstantin Aladyshev return; 1646c21865c4SKonstantin Aladyshev } 1647c21865c4SKonstantin Aladyshev 1648c21865c4SKonstantin Aladyshev // Act on validated parameters 164962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1650c21865c4SKonstantin Aladyshev 1651e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1652e93abac6SGinu George "xyz.openbmc_project.Settings", 165387c44966SAsmitha Karunanithi sdbusplus::message::object_path( 165487c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 165587c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1656e93abac6SGinu George bootOverrideEnable); 1657c21865c4SKonstantin Aladyshev 1658c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1659c21865c4SKonstantin Aladyshev { 1660c21865c4SKonstantin Aladyshev return; 1661c21865c4SKonstantin Aladyshev } 1662c21865c4SKonstantin Aladyshev 1663c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1664c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 166562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 166662598e31SEd Tanous bootOverridePersistent); 1667c21865c4SKonstantin Aladyshev 1668e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1669e93abac6SGinu George "xyz.openbmc_project.Settings", 167087c44966SAsmitha Karunanithi sdbusplus::message::object_path( 167187c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot/one_time"), 167287c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1673e93abac6SGinu George !bootOverridePersistent); 1674c21865c4SKonstantin Aladyshev } 1675c21865c4SKonstantin Aladyshev 1676c21865c4SKonstantin Aladyshev /** 1677c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1678c21865c4SKonstantin Aladyshev * 1679ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1680491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1681491d8ee7SSantosh Puranik * 1682265c1602SJohnathan Mantey * @return Integer error code. 1683491d8ee7SSantosh Puranik */ 1684ac106bf6SEd Tanous inline void 1685ac106bf6SEd Tanous setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1686cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1687491d8ee7SSantosh Puranik { 1688c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1689c21865c4SKonstantin Aladyshev std::string bootModeStr; 1690944ffaf9SJohnathan Mantey 1691c21865c4SKonstantin Aladyshev if (!bootSource) 1692491d8ee7SSantosh Puranik { 1693c21865c4SKonstantin Aladyshev return; 1694c21865c4SKonstantin Aladyshev } 1695c21865c4SKonstantin Aladyshev 1696491d8ee7SSantosh Puranik // Source target specified 169762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1698491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1699ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1700ac106bf6SEd Tanous bootModeStr) != 0) 1701491d8ee7SSantosh Puranik { 170262598e31SEd Tanous BMCWEB_LOG_DEBUG( 170362598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 170462598e31SEd Tanous *bootSource); 1705ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1706491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1707491d8ee7SSantosh Puranik return; 1708491d8ee7SSantosh Puranik } 1709491d8ee7SSantosh Puranik 1710944ffaf9SJohnathan Mantey // Act on validated parameters 171162598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 171262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1713944ffaf9SJohnathan Mantey 1714e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1715e93abac6SGinu George "xyz.openbmc_project.Settings", 171687c44966SAsmitha Karunanithi sdbusplus::message::object_path( 171787c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 171887c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1719e93abac6SGinu George bootSourceStr); 1720e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1721e93abac6SGinu George "xyz.openbmc_project.Settings", 172287c44966SAsmitha Karunanithi sdbusplus::message::object_path( 172387c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 172487c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1725e93abac6SGinu George bootModeStr); 1726cd9a4666SKonstantin Aladyshev } 1727944ffaf9SJohnathan Mantey 1728cd9a4666SKonstantin Aladyshev /** 1729c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1730491d8ee7SSantosh Puranik * 1731ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1732491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1733cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1734491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1735491d8ee7SSantosh Puranik * 1736265c1602SJohnathan Mantey * @return Integer error code. 1737491d8ee7SSantosh Puranik */ 1738c21865c4SKonstantin Aladyshev 1739ac106bf6SEd Tanous inline void 1740ac106bf6SEd Tanous setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1741c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1742c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1743c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1744491d8ee7SSantosh Puranik { 174562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1746491d8ee7SSantosh Puranik 1747ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1748ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1749ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1750491d8ee7SSantosh Puranik } 1751491d8ee7SSantosh Puranik 1752c6a620f2SGeorge Liu /** 175398e386ecSGunnar Mills * @brief Sets AssetTag 175498e386ecSGunnar Mills * 1755ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 175698e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 175798e386ecSGunnar Mills * 175898e386ecSGunnar Mills * @return None. 175998e386ecSGunnar Mills */ 1760ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 176198e386ecSGunnar Mills const std::string& assetTag) 176298e386ecSGunnar Mills { 1763e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1764e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1765e99073f5SGeorge Liu dbus::utility::getSubTree( 1766e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1767ac106bf6SEd Tanous [asyncResp, 1768e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1769b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 177098e386ecSGunnar Mills if (ec) 177198e386ecSGunnar Mills { 177262598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1773ac106bf6SEd Tanous messages::internalError(asyncResp->res); 177498e386ecSGunnar Mills return; 177598e386ecSGunnar Mills } 177626f6976fSEd Tanous if (subtree.empty()) 177798e386ecSGunnar Mills { 177862598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1779ac106bf6SEd Tanous messages::internalError(asyncResp->res); 178098e386ecSGunnar Mills return; 178198e386ecSGunnar Mills } 178298e386ecSGunnar Mills // Assume only 1 system D-Bus object 178398e386ecSGunnar Mills // Throw an error if there is more than 1 178498e386ecSGunnar Mills if (subtree.size() > 1) 178598e386ecSGunnar Mills { 178662598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1787ac106bf6SEd Tanous messages::internalError(asyncResp->res); 178898e386ecSGunnar Mills return; 178998e386ecSGunnar Mills } 179098e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 179198e386ecSGunnar Mills { 179262598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1793ac106bf6SEd Tanous messages::internalError(asyncResp->res); 179498e386ecSGunnar Mills return; 179598e386ecSGunnar Mills } 179698e386ecSGunnar Mills 179798e386ecSGunnar Mills const std::string& path = subtree[0].first; 179898e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 179998e386ecSGunnar Mills 180098e386ecSGunnar Mills if (service.empty()) 180198e386ecSGunnar Mills { 180262598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1803ac106bf6SEd Tanous messages::internalError(asyncResp->res); 180498e386ecSGunnar Mills return; 180598e386ecSGunnar Mills } 180698e386ecSGunnar Mills 1807e93abac6SGinu George setDbusProperty(asyncResp, "AssetTag", service, path, 180887c44966SAsmitha Karunanithi "xyz.openbmc_project.Inventory.Decorator.AssetTag", 1809e93abac6SGinu George "AssetTag", assetTag); 1810e99073f5SGeorge Liu }); 181198e386ecSGunnar Mills } 181298e386ecSGunnar Mills 181398e386ecSGunnar Mills /** 18149dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 18159dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 18169dcfe8c1SAlbert Zhang * 18179dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 18189dcfe8c1SAlbert Zhang * stopBootOnFault 18199dcfe8c1SAlbert Zhang * 18209dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 18219dcfe8c1SAlbert Zhang */ 18229dcfe8c1SAlbert Zhang inline std::optional<bool> 18239dcfe8c1SAlbert Zhang validstopBootOnFault(const std::string& stopBootOnFaultString) 18249dcfe8c1SAlbert Zhang { 18259dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 18269dcfe8c1SAlbert Zhang { 18279dcfe8c1SAlbert Zhang return true; 18289dcfe8c1SAlbert Zhang } 18299dcfe8c1SAlbert Zhang 18309dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 18319dcfe8c1SAlbert Zhang { 18329dcfe8c1SAlbert Zhang return false; 18339dcfe8c1SAlbert Zhang } 18349dcfe8c1SAlbert Zhang 18359dcfe8c1SAlbert Zhang return std::nullopt; 18369dcfe8c1SAlbert Zhang } 18379dcfe8c1SAlbert Zhang 18389dcfe8c1SAlbert Zhang /** 18399dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 18409dcfe8c1SAlbert Zhang * 1841fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 18429dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 18439dcfe8c1SAlbert Zhang * 18449dcfe8c1SAlbert Zhang * @return None. 18459dcfe8c1SAlbert Zhang */ 1846fc3edfddSEd Tanous inline void 1847fc3edfddSEd Tanous setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 18489dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 18499dcfe8c1SAlbert Zhang { 185062598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 18519dcfe8c1SAlbert Zhang 18529dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 18539dcfe8c1SAlbert Zhang if (!stopBootEnabled) 18549dcfe8c1SAlbert Zhang { 185562598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 185662598e31SEd Tanous stopBootOnFault); 1857fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 18589dcfe8c1SAlbert Zhang "StopBootOnFault"); 18599dcfe8c1SAlbert Zhang return; 18609dcfe8c1SAlbert Zhang } 18619dcfe8c1SAlbert Zhang 1862e93abac6SGinu George setDbusProperty(asyncResp, "Boot/StopBootOnFault", 1863e93abac6SGinu George "xyz.openbmc_project.Settings", 186487c44966SAsmitha Karunanithi sdbusplus::message::object_path( 186587c44966SAsmitha Karunanithi "/xyz/openbmc_project/logging/settings"), 1866fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1867e93abac6SGinu George *stopBootEnabled); 18689dcfe8c1SAlbert Zhang } 18699dcfe8c1SAlbert Zhang 18709dcfe8c1SAlbert Zhang /** 187169f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 187269f35306SGunnar Mills * 1873ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 187469f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 187569f35306SGunnar Mills * 187669f35306SGunnar Mills * @return None. 187769f35306SGunnar Mills */ 1878ac106bf6SEd Tanous inline void 1879ac106bf6SEd Tanous setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1880f23b7296SEd Tanous const std::string& automaticRetryConfig) 188169f35306SGunnar Mills { 188262598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 188369f35306SGunnar Mills 188469f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1885543f4400SEd Tanous bool autoRebootEnabled = false; 188669f35306SGunnar Mills 188769f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 188869f35306SGunnar Mills { 188969f35306SGunnar Mills autoRebootEnabled = false; 189069f35306SGunnar Mills } 189169f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 189269f35306SGunnar Mills { 189369f35306SGunnar Mills autoRebootEnabled = true; 189469f35306SGunnar Mills } 189569f35306SGunnar Mills else 189669f35306SGunnar Mills { 189762598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 189862598e31SEd Tanous automaticRetryConfig); 1899ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 190069f35306SGunnar Mills "AutomaticRetryConfig"); 190169f35306SGunnar Mills return; 190269f35306SGunnar Mills } 190369f35306SGunnar Mills 1904e93abac6SGinu George setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig", 1905e93abac6SGinu George "xyz.openbmc_project.Settings", 190687c44966SAsmitha Karunanithi sdbusplus::message::object_path( 190787c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/auto_reboot"), 190887c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.RebootPolicy", 1909e93abac6SGinu George "AutoReboot", autoRebootEnabled); 191069f35306SGunnar Mills } 191169f35306SGunnar Mills 19128d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 19138d69c668SEd Tanous { 19148d69c668SEd Tanous if (policy == "AlwaysOn") 19158d69c668SEd Tanous { 19168d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 19178d69c668SEd Tanous } 19188d69c668SEd Tanous if (policy == "AlwaysOff") 19198d69c668SEd Tanous { 19208d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 19218d69c668SEd Tanous } 19228d69c668SEd Tanous if (policy == "LastState") 19238d69c668SEd Tanous { 19248d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 19258d69c668SEd Tanous } 19268d69c668SEd Tanous return ""; 19278d69c668SEd Tanous } 19288d69c668SEd Tanous 192969f35306SGunnar Mills /** 1930c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1931c6a620f2SGeorge Liu * 1932ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1933c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1934c6a620f2SGeorge Liu * 1935c6a620f2SGeorge Liu * @return None. 1936c6a620f2SGeorge Liu */ 19378d1b46d7Szhanghch05 inline void 1938ac106bf6SEd Tanous setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19398d69c668SEd Tanous std::string_view policy) 1940c6a620f2SGeorge Liu { 194162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 1942c6a620f2SGeorge Liu 19438d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 1944c6a620f2SGeorge Liu 19458d69c668SEd Tanous if (powerRestorePolicy.empty()) 1946c6a620f2SGeorge Liu { 1947ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 19484e69c904SGunnar Mills "PowerRestorePolicy"); 1949c6a620f2SGeorge Liu return; 1950c6a620f2SGeorge Liu } 1951c6a620f2SGeorge Liu 195287c44966SAsmitha Karunanithi setDbusProperty( 1953e93abac6SGinu George asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings", 195487c44966SAsmitha Karunanithi sdbusplus::message::object_path( 195587c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/power_restore_policy"), 19569ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1957e93abac6SGinu George powerRestorePolicy); 1958c6a620f2SGeorge Liu } 1959c6a620f2SGeorge Liu 1960a6349918SAppaRao Puli /** 1961a6349918SAppaRao Puli * @brief Retrieves provisioning status 1962a6349918SAppaRao Puli * 196325b54dbaSEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous 196425b54dbaSEd Tanous * calls. 1965a6349918SAppaRao Puli * 1966a6349918SAppaRao Puli * @return None. 1967a6349918SAppaRao Puli */ 196825b54dbaSEd Tanous inline void 196925b54dbaSEd Tanous getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1970a6349918SAppaRao Puli { 197162598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 1972bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 1973bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager", 1974bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes", 1975ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1976b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1977b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1978ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 1979ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 19801d834d49SEd Tanous "#OpenBMCComputerSystem.v1_0_0.OpenBmc"; 19811d834d49SEd Tanous oemPFR["@odata.type"] = "#OpenBMCComputerSystem.FirmwareProvisioning"; 198250626f4fSJames Feist 1983a6349918SAppaRao Puli if (ec) 1984a6349918SAppaRao Puli { 198562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1986b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 1987*539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 1988*539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 1989a6349918SAppaRao Puli return; 1990a6349918SAppaRao Puli } 1991a6349918SAppaRao Puli 1992a6349918SAppaRao Puli const bool* provState = nullptr; 1993a6349918SAppaRao Puli const bool* lockState = nullptr; 1994bc1d29deSKrzysztof Grobelny 1995bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 19960d4befa8SJiaqing Zhao dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned", 19970d4befa8SJiaqing Zhao provState, "UfmLocked", lockState); 1998bc1d29deSKrzysztof Grobelny 1999bc1d29deSKrzysztof Grobelny if (!success) 2000a6349918SAppaRao Puli { 2001ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2002bc1d29deSKrzysztof Grobelny return; 2003a6349918SAppaRao Puli } 2004a6349918SAppaRao Puli 2005a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2006a6349918SAppaRao Puli { 200762598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 2008ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2009a6349918SAppaRao Puli return; 2010a6349918SAppaRao Puli } 2011a6349918SAppaRao Puli 201225b54dbaSEd Tanous if (*provState) 2013a6349918SAppaRao Puli { 201425b54dbaSEd Tanous if (*lockState) 2015a6349918SAppaRao Puli { 2016*539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2017*539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedAndLocked; 2018a6349918SAppaRao Puli } 2019a6349918SAppaRao Puli else 2020a6349918SAppaRao Puli { 2021*539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2022*539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedButNotLocked; 2023a6349918SAppaRao Puli } 2024a6349918SAppaRao Puli } 2025a6349918SAppaRao Puli else 2026a6349918SAppaRao Puli { 2027*539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2028*539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 2029a6349918SAppaRao Puli } 2030bc1d29deSKrzysztof Grobelny }); 2031a6349918SAppaRao Puli } 2032a6349918SAppaRao Puli 2033491d8ee7SSantosh Puranik /** 20346b9ac4f2SChris Cain * @brief Translate the PowerMode string to enum value 20353a2d0424SChris Cain * 20366b9ac4f2SChris Cain * @param[in] modeString PowerMode string to be translated 20373a2d0424SChris Cain * 20386b9ac4f2SChris Cain * @return PowerMode enum 20393a2d0424SChris Cain */ 20406b9ac4f2SChris Cain inline computer_system::PowerMode 20416b9ac4f2SChris Cain translatePowerModeString(const std::string& modeString) 20423a2d0424SChris Cain { 2043b6655101SChris Cain using PowerMode = computer_system::PowerMode; 2044b6655101SChris Cain 20456b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20463a2d0424SChris Cain { 20476b9ac4f2SChris Cain return PowerMode::Static; 20483a2d0424SChris Cain } 20496b9ac4f2SChris Cain if (modeString == 20500fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20513a2d0424SChris Cain { 20526b9ac4f2SChris Cain return PowerMode::MaximumPerformance; 20533a2d0424SChris Cain } 20546b9ac4f2SChris Cain if (modeString == 20550fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20563a2d0424SChris Cain { 20576b9ac4f2SChris Cain return PowerMode::PowerSaving; 2058b6655101SChris Cain } 20596b9ac4f2SChris Cain if (modeString == 2060b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance") 2061b6655101SChris Cain { 20626b9ac4f2SChris Cain return PowerMode::BalancedPerformance; 2063b6655101SChris Cain } 20646b9ac4f2SChris Cain if (modeString == 2065b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance") 2066b6655101SChris Cain { 20676b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPerformance; 2068b6655101SChris Cain } 20696b9ac4f2SChris Cain if (modeString == 2070b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower") 2071b6655101SChris Cain { 20726b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPower; 20733a2d0424SChris Cain } 20746b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20753a2d0424SChris Cain { 20766b9ac4f2SChris Cain return PowerMode::OEM; 20776b9ac4f2SChris Cain } 20786b9ac4f2SChris Cain // Any other values would be invalid 20796b9ac4f2SChris Cain BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString); 20806b9ac4f2SChris Cain return PowerMode::Invalid; 20816b9ac4f2SChris Cain } 20826b9ac4f2SChris Cain 20836b9ac4f2SChris Cain inline void 20846b9ac4f2SChris Cain afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20856b9ac4f2SChris Cain const boost::system::error_code& ec, 20866b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) 20876b9ac4f2SChris Cain { 20886b9ac4f2SChris Cain if (ec) 20896b9ac4f2SChris Cain { 20906b9ac4f2SChris Cain BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec); 20916b9ac4f2SChris Cain messages::internalError(asyncResp->res); 20926b9ac4f2SChris Cain return; 20936b9ac4f2SChris Cain } 20946b9ac4f2SChris Cain 20956b9ac4f2SChris Cain std::string powerMode; 20966b9ac4f2SChris Cain const std::vector<std::string>* allowedModes = nullptr; 20976b9ac4f2SChris Cain const bool success = sdbusplus::unpackPropertiesNoThrow( 20986b9ac4f2SChris Cain dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode, 20996b9ac4f2SChris Cain "AllowedPowerModes", allowedModes); 21006b9ac4f2SChris Cain 21016b9ac4f2SChris Cain if (!success) 21026b9ac4f2SChris Cain { 21036b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21046b9ac4f2SChris Cain return; 21056b9ac4f2SChris Cain } 21066b9ac4f2SChris Cain 21076b9ac4f2SChris Cain nlohmann::json::array_t modeList; 21086b9ac4f2SChris Cain if (allowedModes == nullptr) 21096b9ac4f2SChris Cain { 21106b9ac4f2SChris Cain modeList.emplace_back("Static"); 21116b9ac4f2SChris Cain modeList.emplace_back("MaximumPerformance"); 21126b9ac4f2SChris Cain modeList.emplace_back("PowerSaving"); 21133a2d0424SChris Cain } 21143a2d0424SChris Cain else 21153a2d0424SChris Cain { 21166b9ac4f2SChris Cain for (const auto& aMode : *allowedModes) 21176b9ac4f2SChris Cain { 21186b9ac4f2SChris Cain computer_system::PowerMode modeValue = 21196b9ac4f2SChris Cain translatePowerModeString(aMode); 21206b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21216b9ac4f2SChris Cain { 2122ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21236b9ac4f2SChris Cain continue; 21246b9ac4f2SChris Cain } 21256b9ac4f2SChris Cain modeList.emplace_back(modeValue); 21263a2d0424SChris Cain } 21273a2d0424SChris Cain } 21286b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList; 21293a2d0424SChris Cain 21306b9ac4f2SChris Cain BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode); 21316b9ac4f2SChris Cain const computer_system::PowerMode modeValue = 21326b9ac4f2SChris Cain translatePowerModeString(powerMode); 21336b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21346b9ac4f2SChris Cain { 21356b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21366b9ac4f2SChris Cain return; 21376b9ac4f2SChris Cain } 21386b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode"] = modeValue; 21396b9ac4f2SChris Cain } 21403a2d0424SChris Cain /** 21413a2d0424SChris Cain * @brief Retrieves system power mode 21423a2d0424SChris Cain * 2143ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21443a2d0424SChris Cain * 21453a2d0424SChris Cain * @return None. 21463a2d0424SChris Cain */ 2147ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 21483a2d0424SChris Cain { 214962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 21503a2d0424SChris Cain 21513a2d0424SChris Cain // Get Power Mode object path: 2152e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2153e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2154e99073f5SGeorge Liu dbus::utility::getSubTree( 2155e99073f5SGeorge Liu "/", 0, interfaces, 2156ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2157b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21583a2d0424SChris Cain if (ec) 21593a2d0424SChris Cain { 216062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}", 216162598e31SEd Tanous ec); 21623a2d0424SChris Cain // This is an optional D-Bus object so just return if 21633a2d0424SChris Cain // error occurs 21643a2d0424SChris Cain return; 21653a2d0424SChris Cain } 21663a2d0424SChris Cain if (subtree.empty()) 21673a2d0424SChris Cain { 21683a2d0424SChris Cain // As noted above, this is an optional interface so just return 21693a2d0424SChris Cain // if there is no instance found 21703a2d0424SChris Cain return; 21713a2d0424SChris Cain } 21723a2d0424SChris Cain if (subtree.size() > 1) 21733a2d0424SChris Cain { 21743a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21753a2d0424SChris Cain // error 217662598e31SEd Tanous BMCWEB_LOG_DEBUG( 217762598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 217862598e31SEd Tanous subtree.size()); 2179ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21803a2d0424SChris Cain return; 21813a2d0424SChris Cain } 21823a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21833a2d0424SChris Cain { 218462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2185ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21863a2d0424SChris Cain return; 21873a2d0424SChris Cain } 21883a2d0424SChris Cain const std::string& path = subtree[0].first; 21893a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 21903a2d0424SChris Cain if (service.empty()) 21913a2d0424SChris Cain { 219262598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2193ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21943a2d0424SChris Cain return; 21953a2d0424SChris Cain } 21966b9ac4f2SChris Cain 21976b9ac4f2SChris Cain // Valid Power Mode object found, now read the mode properties 21986b9ac4f2SChris Cain sdbusplus::asio::getAllProperties( 21991e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 22006b9ac4f2SChris Cain "xyz.openbmc_project.Control.Power.Mode", 2201ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 22026b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 22036b9ac4f2SChris Cain afterGetPowerMode(asyncResp, ec2, properties); 22041e1e598dSJonathan Doman }); 2205e99073f5SGeorge Liu }); 22063a2d0424SChris Cain } 22073a2d0424SChris Cain 22083a2d0424SChris Cain /** 22093a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 22103a2d0424SChris Cain * name associated with that string 22113a2d0424SChris Cain * 2212ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2213b6655101SChris Cain * @param[in] modeValue String representing the desired PowerMode 22143a2d0424SChris Cain * 22153a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22163a2d0424SChris Cain */ 22173a2d0424SChris Cain inline std::string 2218ac106bf6SEd Tanous validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2219b6655101SChris Cain const nlohmann::json& modeValue) 22203a2d0424SChris Cain { 2221b6655101SChris Cain using PowerMode = computer_system::PowerMode; 22223a2d0424SChris Cain std::string mode; 22233a2d0424SChris Cain 2224b6655101SChris Cain if (modeValue == PowerMode::Static) 22253a2d0424SChris Cain { 22263a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22273a2d0424SChris Cain } 2228b6655101SChris Cain else if (modeValue == PowerMode::MaximumPerformance) 22293a2d0424SChris Cain { 22300fda0f12SGeorge Liu mode = 22310fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 22323a2d0424SChris Cain } 2233b6655101SChris Cain else if (modeValue == PowerMode::PowerSaving) 22343a2d0424SChris Cain { 22353a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22363a2d0424SChris Cain } 2237b6655101SChris Cain else if (modeValue == PowerMode::BalancedPerformance) 2238b6655101SChris Cain { 2239b6655101SChris Cain mode = 2240b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance"; 2241b6655101SChris Cain } 2242b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPerformance) 2243b6655101SChris Cain { 2244b6655101SChris Cain mode = 2245b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance"; 2246b6655101SChris Cain } 2247b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPower) 2248b6655101SChris Cain { 2249b6655101SChris Cain mode = 2250b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower"; 2251b6655101SChris Cain } 22523a2d0424SChris Cain else 22533a2d0424SChris Cain { 2254b6655101SChris Cain messages::propertyValueNotInList(asyncResp->res, modeValue.dump(), 2255ac106bf6SEd Tanous "PowerMode"); 22563a2d0424SChris Cain } 22573a2d0424SChris Cain return mode; 22583a2d0424SChris Cain } 22593a2d0424SChris Cain 22603a2d0424SChris Cain /** 22613a2d0424SChris Cain * @brief Sets system power mode. 22623a2d0424SChris Cain * 2263ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22643a2d0424SChris Cain * @param[in] pmode System power mode from request. 22653a2d0424SChris Cain * 22663a2d0424SChris Cain * @return None. 22673a2d0424SChris Cain */ 2268ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22693a2d0424SChris Cain const std::string& pmode) 22703a2d0424SChris Cain { 227162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 22723a2d0424SChris Cain 2273ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 22743a2d0424SChris Cain if (powerMode.empty()) 22753a2d0424SChris Cain { 22763a2d0424SChris Cain return; 22773a2d0424SChris Cain } 22783a2d0424SChris Cain 22793a2d0424SChris Cain // Get Power Mode object path: 2280e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2281e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2282e99073f5SGeorge Liu dbus::utility::getSubTree( 2283e99073f5SGeorge Liu "/", 0, interfaces, 2284ac106bf6SEd Tanous [asyncResp, 2285e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2286b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22873a2d0424SChris Cain if (ec) 22883a2d0424SChris Cain { 2289b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}", 229062598e31SEd Tanous ec); 22913a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2292ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22933a2d0424SChris Cain return; 22943a2d0424SChris Cain } 22953a2d0424SChris Cain if (subtree.empty()) 22963a2d0424SChris Cain { 22973a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2298ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 22993a2d0424SChris Cain "PowerMode"); 23003a2d0424SChris Cain return; 23013a2d0424SChris Cain } 23023a2d0424SChris Cain if (subtree.size() > 1) 23033a2d0424SChris Cain { 23043a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23053a2d0424SChris Cain // error 230662598e31SEd Tanous BMCWEB_LOG_DEBUG( 230762598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 230862598e31SEd Tanous subtree.size()); 2309ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23103a2d0424SChris Cain return; 23113a2d0424SChris Cain } 23123a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23133a2d0424SChris Cain { 231462598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2315ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23163a2d0424SChris Cain return; 23173a2d0424SChris Cain } 23183a2d0424SChris Cain const std::string& path = subtree[0].first; 23193a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23203a2d0424SChris Cain if (service.empty()) 23213a2d0424SChris Cain { 232262598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2323ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23243a2d0424SChris Cain return; 23253a2d0424SChris Cain } 23263a2d0424SChris Cain 232762598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 23283a2d0424SChris Cain 23293a2d0424SChris Cain // Set the Power Mode property 2330e93abac6SGinu George setDbusProperty(asyncResp, "PowerMode", service, path, 233187c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Power.Mode", "PowerMode", 2332e93abac6SGinu George powerMode); 2333e99073f5SGeorge Liu }); 23343a2d0424SChris Cain } 23353a2d0424SChris Cain 23363a2d0424SChris Cain /** 233751709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 233851709ffdSYong Li * 233951709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 234051709ffdSYong Li * 234151709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 234251709ffdSYong Li * translation cannot be done, returns an empty string. 234351709ffdSYong Li */ 234423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 234551709ffdSYong Li { 234651709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 234751709ffdSYong Li { 234851709ffdSYong Li return "None"; 234951709ffdSYong Li } 23503174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 235151709ffdSYong Li { 235251709ffdSYong Li return "ResetSystem"; 235351709ffdSYong Li } 23543174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 235551709ffdSYong Li { 235651709ffdSYong Li return "PowerDown"; 235751709ffdSYong Li } 23583174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 235951709ffdSYong Li { 236051709ffdSYong Li return "PowerCycle"; 236151709ffdSYong Li } 236251709ffdSYong Li 236351709ffdSYong Li return ""; 236451709ffdSYong Li } 236551709ffdSYong Li 236651709ffdSYong Li /** 2367c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2368c45f0082SYong Li * 2369c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2370c45f0082SYong Li * 2371c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2372c45f0082SYong Li *If translation cannot be done, returns an empty string. 2373c45f0082SYong Li */ 2374c45f0082SYong Li 237523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2376c45f0082SYong Li { 2377c45f0082SYong Li if (rfAction == "None") 2378c45f0082SYong Li { 2379c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2380c45f0082SYong Li } 23813174e4dfSEd Tanous if (rfAction == "PowerCycle") 2382c45f0082SYong Li { 2383c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2384c45f0082SYong Li } 23853174e4dfSEd Tanous if (rfAction == "PowerDown") 2386c45f0082SYong Li { 2387c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2388c45f0082SYong Li } 23893174e4dfSEd Tanous if (rfAction == "ResetSystem") 2390c45f0082SYong Li { 2391c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2392c45f0082SYong Li } 2393c45f0082SYong Li 2394c45f0082SYong Li return ""; 2395c45f0082SYong Li } 2396c45f0082SYong Li 2397c45f0082SYong Li /** 239851709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 239951709ffdSYong Li * 2400ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 240151709ffdSYong Li * 240251709ffdSYong Li * @return None. 240351709ffdSYong Li */ 24048d1b46d7Szhanghch05 inline void 2405ac106bf6SEd Tanous getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 240651709ffdSYong Li { 240762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2408bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2409bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, "xyz.openbmc_project.Watchdog", 2410bc1d29deSKrzysztof Grobelny "/xyz/openbmc_project/watchdog/host0", 2411bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2412ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2413b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 241451709ffdSYong Li if (ec) 241551709ffdSYong Li { 241651709ffdSYong Li // watchdog service is stopped 241762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 241851709ffdSYong Li return; 241951709ffdSYong Li } 242051709ffdSYong Li 242162598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 242251709ffdSYong Li 242351709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2424ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 242551709ffdSYong Li 242651709ffdSYong Li // watchdog service is running/enabled 2427*539d8c6bSEd Tanous hostWatchdogTimer["Status"]["State"] = resource::State::Enabled; 242851709ffdSYong Li 2429bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2430bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 243151709ffdSYong Li 2432bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2433bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 2434bc1d29deSKrzysztof Grobelny "ExpireAction", expireAction); 2435bc1d29deSKrzysztof Grobelny 2436bc1d29deSKrzysztof Grobelny if (!success) 243751709ffdSYong Li { 2438ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2439601af5edSChicago Duan return; 244051709ffdSYong Li } 244151709ffdSYong Li 2442bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 244351709ffdSYong Li { 2444bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 244551709ffdSYong Li } 244651709ffdSYong Li 2447bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2448bc1d29deSKrzysztof Grobelny { 2449bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 245051709ffdSYong Li if (action.empty()) 245151709ffdSYong Li { 2452ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2453601af5edSChicago Duan return; 245451709ffdSYong Li } 245551709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 245651709ffdSYong Li } 2457bc1d29deSKrzysztof Grobelny }); 245851709ffdSYong Li } 245951709ffdSYong Li 246051709ffdSYong Li /** 2461c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2462c45f0082SYong Li * 2463ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2464c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2465c45f0082SYong Li * RF request. 2466c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2467c45f0082SYong Li * 2468c45f0082SYong Li * @return None. 2469c45f0082SYong Li */ 2470ac106bf6SEd Tanous inline void 2471ac106bf6SEd Tanous setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2472c45f0082SYong Li const std::optional<bool> wdtEnable, 2473c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2474c45f0082SYong Li { 247562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2476c45f0082SYong Li 2477c45f0082SYong Li if (wdtTimeOutAction) 2478c45f0082SYong Li { 2479c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2480c45f0082SYong Li // check if TimeOut Action is Valid 2481c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2482c45f0082SYong Li { 248362598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 248462598e31SEd Tanous *wdtTimeOutAction); 2485ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2486c45f0082SYong Li "TimeoutAction"); 2487c45f0082SYong Li return; 2488c45f0082SYong Li } 2489c45f0082SYong Li 2490e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction", 2491e93abac6SGinu George "xyz.openbmc_project.Watchdog", 249287c44966SAsmitha Karunanithi sdbusplus::message::object_path( 249387c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 24949ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2495e93abac6SGinu George wdtTimeOutActStr); 2496c45f0082SYong Li } 2497c45f0082SYong Li 2498c45f0082SYong Li if (wdtEnable) 2499c45f0082SYong Li { 2500e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled", 2501e93abac6SGinu George "xyz.openbmc_project.Watchdog", 250287c44966SAsmitha Karunanithi sdbusplus::message::object_path( 250387c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 250487c44966SAsmitha Karunanithi "xyz.openbmc_project.State.Watchdog", "Enabled", 2505e93abac6SGinu George *wdtEnable); 2506c45f0082SYong Li } 2507c45f0082SYong Li } 2508c45f0082SYong Li 250937bbf98cSChris Cain /** 251037bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 251137bbf98cSChris Cain * 2512ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 251337bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 251437bbf98cSChris Cain * 251537bbf98cSChris Cain * @return true if successful 251637bbf98cSChris Cain */ 25171e5b7c88SJiaqing Zhao inline bool 2518ac106bf6SEd Tanous parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25191e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 252037bbf98cSChris Cain { 2521bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2522bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2523bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2524bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2525bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2526bc1d29deSKrzysztof Grobelny 2527bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2528bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 25292661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 25302661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 25312661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2532bc1d29deSKrzysztof Grobelny 2533bc1d29deSKrzysztof Grobelny if (!success) 253437bbf98cSChris Cain { 253537bbf98cSChris Cain return false; 253637bbf98cSChris Cain } 2537bc1d29deSKrzysztof Grobelny 2538bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 253937bbf98cSChris Cain { 2540ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 254137bbf98cSChris Cain } 2542bc1d29deSKrzysztof Grobelny 2543bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 254437bbf98cSChris Cain { 2545ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2546bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 254737bbf98cSChris Cain } 2548bc1d29deSKrzysztof Grobelny 2549bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2550bc1d29deSKrzysztof Grobelny { 2551bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2552ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 255337bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 255437bbf98cSChris Cain .count(); 255537bbf98cSChris Cain } 2556bc1d29deSKrzysztof Grobelny 2557bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 255837bbf98cSChris Cain { 2559ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2560bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 256137bbf98cSChris Cain } 2562bc1d29deSKrzysztof Grobelny 2563bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 256437bbf98cSChris Cain { 2565bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2566ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 256737bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 256837bbf98cSChris Cain .count(); 256937bbf98cSChris Cain } 257037bbf98cSChris Cain 257137bbf98cSChris Cain return true; 257237bbf98cSChris Cain } 257337bbf98cSChris Cain 257437bbf98cSChris Cain /** 257537bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 257637bbf98cSChris Cain * 2577ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 257837bbf98cSChris Cain * 257937bbf98cSChris Cain * @return None. 258037bbf98cSChris Cain */ 2581ac106bf6SEd Tanous inline void 2582ac106bf6SEd Tanous getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 258337bbf98cSChris Cain { 258462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 258537bbf98cSChris Cain 258637bbf98cSChris Cain // Get IdlePowerSaver object path: 2587e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2588e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2589e99073f5SGeorge Liu dbus::utility::getSubTree( 2590e99073f5SGeorge Liu "/", 0, interfaces, 2591ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2592b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 259337bbf98cSChris Cain if (ec) 259437bbf98cSChris Cain { 2595b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 259662598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 259762598e31SEd Tanous ec); 2598ac106bf6SEd Tanous messages::internalError(asyncResp->res); 259937bbf98cSChris Cain return; 260037bbf98cSChris Cain } 260137bbf98cSChris Cain if (subtree.empty()) 260237bbf98cSChris Cain { 260337bbf98cSChris Cain // This is an optional interface so just return 260437bbf98cSChris Cain // if there is no instance found 260562598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 260637bbf98cSChris Cain return; 260737bbf98cSChris Cain } 260837bbf98cSChris Cain if (subtree.size() > 1) 260937bbf98cSChris Cain { 261037bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 261137bbf98cSChris Cain // is an error 261262598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 261362598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 261462598e31SEd Tanous subtree.size()); 2615ac106bf6SEd Tanous messages::internalError(asyncResp->res); 261637bbf98cSChris Cain return; 261737bbf98cSChris Cain } 261837bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 261937bbf98cSChris Cain { 262062598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2621ac106bf6SEd Tanous messages::internalError(asyncResp->res); 262237bbf98cSChris Cain return; 262337bbf98cSChris Cain } 262437bbf98cSChris Cain const std::string& path = subtree[0].first; 262537bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 262637bbf98cSChris Cain if (service.empty()) 262737bbf98cSChris Cain { 262862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2629ac106bf6SEd Tanous messages::internalError(asyncResp->res); 263037bbf98cSChris Cain return; 263137bbf98cSChris Cain } 263237bbf98cSChris Cain 263337bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2634bc1d29deSKrzysztof Grobelny sdbusplus::asio::getAllProperties( 2635bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2636bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2637ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 26381e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 26398a592810SEd Tanous if (ec2) 264037bbf98cSChris Cain { 264162598e31SEd Tanous BMCWEB_LOG_ERROR( 264262598e31SEd Tanous "DBUS response error on IdlePowerSaver GetAll: {}", ec2); 2643ac106bf6SEd Tanous messages::internalError(asyncResp->res); 264437bbf98cSChris Cain return; 264537bbf98cSChris Cain } 264637bbf98cSChris Cain 2647ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 264837bbf98cSChris Cain { 2649ac106bf6SEd Tanous messages::internalError(asyncResp->res); 265037bbf98cSChris Cain return; 265137bbf98cSChris Cain } 2652bc1d29deSKrzysztof Grobelny }); 2653e99073f5SGeorge Liu }); 265437bbf98cSChris Cain 265562598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 265637bbf98cSChris Cain } 265737bbf98cSChris Cain 265837bbf98cSChris Cain /** 265937bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 266037bbf98cSChris Cain * 2661ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 266237bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 266337bbf98cSChris Cain * RF request. 266437bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 266537bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 266637bbf98cSChris Cain * before entering idle state. 266737bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 266837bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 266937bbf98cSChris Cain * before exiting idle state 267037bbf98cSChris Cain * 267137bbf98cSChris Cain * @return None. 267237bbf98cSChris Cain */ 2673ac106bf6SEd Tanous inline void 2674ac106bf6SEd Tanous setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 267537bbf98cSChris Cain const std::optional<bool> ipsEnable, 267637bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 267737bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 267837bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 267937bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 268037bbf98cSChris Cain { 268162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 268237bbf98cSChris Cain 268337bbf98cSChris Cain // Get IdlePowerSaver object path: 2684e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2685e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2686e99073f5SGeorge Liu dbus::utility::getSubTree( 2687e99073f5SGeorge Liu "/", 0, interfaces, 2688ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2689e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2690b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 269137bbf98cSChris Cain if (ec) 269237bbf98cSChris Cain { 2693b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 269462598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 269562598e31SEd Tanous ec); 2696ac106bf6SEd Tanous messages::internalError(asyncResp->res); 269737bbf98cSChris Cain return; 269837bbf98cSChris Cain } 269937bbf98cSChris Cain if (subtree.empty()) 270037bbf98cSChris Cain { 270137bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2702ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 270337bbf98cSChris Cain "IdlePowerSaver"); 270437bbf98cSChris Cain return; 270537bbf98cSChris Cain } 270637bbf98cSChris Cain if (subtree.size() > 1) 270737bbf98cSChris Cain { 270837bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 270937bbf98cSChris Cain // is an error 271062598e31SEd Tanous BMCWEB_LOG_DEBUG( 271162598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 271262598e31SEd Tanous subtree.size()); 2713ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271437bbf98cSChris Cain return; 271537bbf98cSChris Cain } 271637bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 271737bbf98cSChris Cain { 271862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2719ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272037bbf98cSChris Cain return; 272137bbf98cSChris Cain } 272237bbf98cSChris Cain const std::string& path = subtree[0].first; 272337bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 272437bbf98cSChris Cain if (service.empty()) 272537bbf98cSChris Cain { 272662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2727ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272837bbf98cSChris Cain return; 272937bbf98cSChris Cain } 273037bbf98cSChris Cain 273137bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 273237bbf98cSChris Cain // need to be updated 273337bbf98cSChris Cain 273437bbf98cSChris Cain if (ipsEnable) 273537bbf98cSChris Cain { 2736e93abac6SGinu George setDbusProperty(asyncResp, "IdlePowerSaver/Enabled", service, path, 273787c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2738e93abac6SGinu George "Enabled", *ipsEnable); 273937bbf98cSChris Cain } 274037bbf98cSChris Cain if (ipsEnterUtil) 274137bbf98cSChris Cain { 2742e93abac6SGinu George setDbusProperty(asyncResp, "IdlePowerSaver/EnterUtilizationPercent", 2743e93abac6SGinu George service, path, 27449ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2745e93abac6SGinu George "EnterUtilizationPercent", *ipsEnterUtil); 274637bbf98cSChris Cain } 274737bbf98cSChris Cain if (ipsEnterTime) 274837bbf98cSChris Cain { 274937bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 275037bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 2751e93abac6SGinu George setDbusProperty(asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", 2752e93abac6SGinu George service, path, 27539ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2754e93abac6SGinu George "EnterDwellTime", timeMilliseconds); 275537bbf98cSChris Cain } 275637bbf98cSChris Cain if (ipsExitUtil) 275737bbf98cSChris Cain { 2758e93abac6SGinu George setDbusProperty(asyncResp, "IdlePowerSaver/ExitUtilizationPercent", 2759e93abac6SGinu George service, path, 27609ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2761e93abac6SGinu George "ExitUtilizationPercent", *ipsExitUtil); 276237bbf98cSChris Cain } 276337bbf98cSChris Cain if (ipsExitTime) 276437bbf98cSChris Cain { 276537bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 276637bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 2767e93abac6SGinu George setDbusProperty(asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", 2768e93abac6SGinu George service, path, 27699ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2770e93abac6SGinu George "ExitDwellTime", timeMilliseconds); 277137bbf98cSChris Cain } 2772e99073f5SGeorge Liu }); 277337bbf98cSChris Cain 277462598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 277537bbf98cSChris Cain } 277637bbf98cSChris Cain 2777c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2778dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2779dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2780dd60b9edSEd Tanous { 2781dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2782dd60b9edSEd Tanous { 2783dd60b9edSEd Tanous return; 2784dd60b9edSEd Tanous } 2785dd60b9edSEd Tanous asyncResp->res.addHeader( 2786dd60b9edSEd Tanous boost::beast::http::field::link, 2787dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2788dd60b9edSEd Tanous } 2789dd60b9edSEd Tanous 2790c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2791c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2792c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 27931abe55efSEd Tanous { 27943ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2795f4c99e70SEd Tanous { 2796f4c99e70SEd Tanous return; 2797f4c99e70SEd Tanous } 2798dd60b9edSEd Tanous 2799dd60b9edSEd Tanous asyncResp->res.addHeader( 2800dd60b9edSEd Tanous boost::beast::http::field::link, 2801dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 28028d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28030f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28048d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28058d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2806462023adSSunitha Harish 28077f3e84a1SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 28087f3e84a1SEd Tanous ifaceArray = nlohmann::json::array(); 280925b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 28107f3e84a1SEd Tanous { 28117f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 28127f3e84a1SEd Tanous // Option currently returns no systems. TBD 28137f3e84a1SEd Tanous return; 28147f3e84a1SEd Tanous } 28157f3e84a1SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 1; 28167f3e84a1SEd Tanous nlohmann::json::object_t system; 2817253f11b8SEd Tanous system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}", 2818253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 28197f3e84a1SEd Tanous ifaceArray.emplace_back(std::move(system)); 28201e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 2821002d39b4SEd Tanous *crow::connections::systemBus, "xyz.openbmc_project.Settings", 28221e1e598dSJonathan Doman "/xyz/openbmc_project/network/hypervisor", 2823002d39b4SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 28245e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2, 28251e1e598dSJonathan Doman const std::string& /*hostName*/) { 28267f3e84a1SEd Tanous if (ec2) 2827462023adSSunitha Harish { 28287f3e84a1SEd Tanous return; 28297f3e84a1SEd Tanous } 28307f3e84a1SEd Tanous auto val = asyncResp->res.jsonValue.find("Members@odata.count"); 28317f3e84a1SEd Tanous if (val == asyncResp->res.jsonValue.end()) 28327f3e84a1SEd Tanous { 283362598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 28347f3e84a1SEd Tanous return; 28357f3e84a1SEd Tanous } 283667b15903SAsmitha Karunanithi int64_t* count = val->get_ptr<int64_t*>(); 28377f3e84a1SEd Tanous if (count == nullptr) 28387f3e84a1SEd Tanous { 283962598e31SEd Tanous BMCWEB_LOG_CRITICAL("Count wasn't found??"); 28407f3e84a1SEd Tanous return; 28417f3e84a1SEd Tanous } 28427f3e84a1SEd Tanous *count = *count + 1; 284362598e31SEd Tanous BMCWEB_LOG_DEBUG("Hypervisor is available"); 28447f3e84a1SEd Tanous nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"]; 28451476687dSEd Tanous nlohmann::json::object_t hypervisor; 2846002d39b4SEd Tanous hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor"; 28477f3e84a1SEd Tanous ifaceArray2.emplace_back(std::move(hypervisor)); 28481e1e598dSJonathan Doman }); 2849c1e219d5SEd Tanous } 2850c1e219d5SEd Tanous 2851c1e219d5SEd Tanous /** 28527e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28537e860f15SJohn Edward Broadbent */ 28544f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28557e860f15SJohn Edward Broadbent { 285689492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 285789492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 285889492a15SPatrick Williams constexpr const char* interfaceName = 28597e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 286089492a15SPatrick Williams constexpr const char* method = "NMI"; 28617e860f15SJohn Edward Broadbent 28627e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 28635e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28647e860f15SJohn Edward Broadbent if (ec) 28657e860f15SJohn Edward Broadbent { 286662598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 28677e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28687e860f15SJohn Edward Broadbent return; 28697e860f15SJohn Edward Broadbent } 28707e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28717e860f15SJohn Edward Broadbent }, 28727e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28737e860f15SJohn Edward Broadbent } 2874c5b2abe0SLewanczyk, Dawid 2875c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2876c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 28777f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2878c1e219d5SEd Tanous const std::string& systemName) 2879c1e219d5SEd Tanous { 28803ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 288145ca1b86SEd Tanous { 288245ca1b86SEd Tanous return; 288345ca1b86SEd Tanous } 2884253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 2885c1e219d5SEd Tanous { 2886c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2887c1e219d5SEd Tanous systemName); 2888c1e219d5SEd Tanous return; 2889c1e219d5SEd Tanous } 289025b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 28917f3e84a1SEd Tanous { 28927f3e84a1SEd Tanous // Option currently returns no systems. TBD 28937f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2894c1e219d5SEd Tanous systemName); 28957f3e84a1SEd Tanous return; 28967f3e84a1SEd Tanous } 28979712f8acSEd Tanous std::string resetType; 2898c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 2899cc340dd9SEd Tanous { 2900cc340dd9SEd Tanous return; 2901cc340dd9SEd Tanous } 2902cc340dd9SEd Tanous 2903d22c8396SJason M. Bills // Get the command and host vs. chassis 2904cc340dd9SEd Tanous std::string command; 2905543f4400SEd Tanous bool hostCommand = true; 2906d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2907cc340dd9SEd Tanous { 2908cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2909d22c8396SJason M. Bills hostCommand = true; 2910d22c8396SJason M. Bills } 2911d22c8396SJason M. Bills else if (resetType == "ForceOff") 2912d22c8396SJason M. Bills { 2913d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2914d22c8396SJason M. Bills hostCommand = false; 2915d22c8396SJason M. Bills } 2916d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2917d22c8396SJason M. Bills { 2918c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 291986a0851aSJason M. Bills hostCommand = true; 2920cc340dd9SEd Tanous } 29219712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2922cc340dd9SEd Tanous { 2923cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2924d22c8396SJason M. Bills hostCommand = true; 2925cc340dd9SEd Tanous } 29269712f8acSEd Tanous else if (resetType == "GracefulRestart") 2927cc340dd9SEd Tanous { 29280fda0f12SGeorge Liu command = 29290fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2930d22c8396SJason M. Bills hostCommand = true; 2931d22c8396SJason M. Bills } 2932d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2933d22c8396SJason M. Bills { 293486a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 293586a0851aSJason M. Bills hostCommand = true; 2936cc340dd9SEd Tanous } 2937bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2938bfd5b826SLakshminarayana R. Kammath { 2939bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2940bfd5b826SLakshminarayana R. Kammath return; 2941bfd5b826SLakshminarayana R. Kammath } 2942cc340dd9SEd Tanous else 2943cc340dd9SEd Tanous { 2944c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 2945cc340dd9SEd Tanous return; 2946cc340dd9SEd Tanous } 2947d02aad39SEd Tanous sdbusplus::message::object_path statePath("/xyz/openbmc_project/state"); 2948cc340dd9SEd Tanous 2949d22c8396SJason M. Bills if (hostCommand) 2950d22c8396SJason M. Bills { 2951e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host", 2952d02aad39SEd Tanous statePath / "host0", "xyz.openbmc_project.State.Host", 2953e93abac6SGinu George "RequestedHostTransition", command); 2954cc340dd9SEd Tanous } 2955d22c8396SJason M. Bills else 2956d22c8396SJason M. Bills { 2957e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis", 2958d02aad39SEd Tanous statePath / "chassis0", 2959d02aad39SEd Tanous "xyz.openbmc_project.State.Chassis", 2960e93abac6SGinu George "RequestedPowerTransition", command); 2961d22c8396SJason M. Bills } 2962d22c8396SJason M. Bills } 2963cc340dd9SEd Tanous 2964c1e219d5SEd Tanous inline void handleComputerSystemHead( 2965dd60b9edSEd Tanous App& app, const crow::Request& req, 29667f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29677f3e84a1SEd Tanous const std::string& /*systemName*/) 2968dd60b9edSEd Tanous { 2969dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2970dd60b9edSEd Tanous { 2971dd60b9edSEd Tanous return; 2972dd60b9edSEd Tanous } 2973dd60b9edSEd Tanous 2974dd60b9edSEd Tanous asyncResp->res.addHeader( 2975dd60b9edSEd Tanous boost::beast::http::field::link, 2976dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2977dd60b9edSEd Tanous } 2978dd60b9edSEd Tanous 29795c3e9272SAbhishek Patel inline void afterPortRequest( 29805c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29815c3e9272SAbhishek Patel const boost::system::error_code& ec, 29825c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 29835c3e9272SAbhishek Patel { 29845c3e9272SAbhishek Patel if (ec) 29855c3e9272SAbhishek Patel { 2986b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 29875c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29885c3e9272SAbhishek Patel return; 29895c3e9272SAbhishek Patel } 29905c3e9272SAbhishek Patel for (const auto& data : socketData) 29915c3e9272SAbhishek Patel { 29925c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 29935c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 29945c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 29955c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 29965c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 29975c3e9272SAbhishek Patel // need to retrieve port number for 29985c3e9272SAbhishek Patel // obmc-console-ssh service 29995c3e9272SAbhishek Patel if (protocolName == "SSH") 30005c3e9272SAbhishek Patel { 30015c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 300281c4e330SEd Tanous const boost::system::error_code& ec1, 30035c3e9272SAbhishek Patel int portNumber) { 30045c3e9272SAbhishek Patel if (ec1) 30055c3e9272SAbhishek Patel { 3006b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 30075c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 30085c3e9272SAbhishek Patel return; 30095c3e9272SAbhishek Patel } 30105c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 30115c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 30125c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 30135c3e9272SAbhishek Patel }); 30145c3e9272SAbhishek Patel } 30155c3e9272SAbhishek Patel } 30165c3e9272SAbhishek Patel } 3017c1e219d5SEd Tanous 3018c1e219d5SEd Tanous inline void 3019c1e219d5SEd Tanous handleComputerSystemGet(crow::App& app, const crow::Request& req, 302022d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3021c1e219d5SEd Tanous const std::string& systemName) 3022c1e219d5SEd Tanous { 30233ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 302445ca1b86SEd Tanous { 302545ca1b86SEd Tanous return; 302645ca1b86SEd Tanous } 3027746b56f3SAsmitha Karunanithi 302825b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 30297f3e84a1SEd Tanous { 30307f3e84a1SEd Tanous // Option currently returns no systems. TBD 30317f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 30327f3e84a1SEd Tanous systemName); 30337f3e84a1SEd Tanous return; 30347f3e84a1SEd Tanous } 30357f3e84a1SEd Tanous 3036746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3037746b56f3SAsmitha Karunanithi { 3038746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3039746b56f3SAsmitha Karunanithi return; 3040746b56f3SAsmitha Karunanithi } 3041746b56f3SAsmitha Karunanithi 3042253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 304322d268cbSEd Tanous { 304422d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 304522d268cbSEd Tanous systemName); 304622d268cbSEd Tanous return; 304722d268cbSEd Tanous } 3048dd60b9edSEd Tanous asyncResp->res.addHeader( 3049dd60b9edSEd Tanous boost::beast::http::field::link, 3050dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 30518d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3052b6655101SChris Cain "#ComputerSystem.v1_22_0.ComputerSystem"; 3053253f11b8SEd Tanous asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3054253f11b8SEd Tanous asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3055*539d8c6bSEd Tanous asyncResp->res.jsonValue["SystemType"] = 3056*539d8c6bSEd Tanous computer_system::SystemType::Physical; 30578d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 30588d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 3059cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3060dfb2b408SPriyanga Ramasamy double(0); 3061253f11b8SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 3062253f11b8SEd Tanous "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME); 306304a258f4SEd Tanous 3064253f11b8SEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format( 3065253f11b8SEd Tanous "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3066253f11b8SEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format( 3067253f11b8SEd Tanous "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3068253f11b8SEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format( 3069253f11b8SEd Tanous "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME); 30703179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 3071253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters", 3072253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3073029573d4SEd Tanous 3074002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 3075253f11b8SEd Tanous boost::urls::format( 3076253f11b8SEd Tanous "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", 3077253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3078c1e219d5SEd Tanous asyncResp->res 3079c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 3080253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3081253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3082c5b2abe0SLewanczyk, Dawid 3083253f11b8SEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format( 3084253f11b8SEd Tanous "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3085253f11b8SEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format( 3086253f11b8SEd Tanous "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3087c4bf6374SJason M. Bills 30881476687dSEd Tanous nlohmann::json::array_t managedBy; 30891476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 3090253f11b8SEd Tanous manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}", 3091253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME); 3092002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 3093*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK; 3094*539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled; 30950e8ac5e7SGunnar Mills 30960e8ac5e7SGunnar Mills // Fill in SerialConsole info 3097002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3098c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 30991476687dSEd Tanous 3100c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 31011476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3102c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 31031476687dSEd Tanous "Press ~. to exit console"; 31045c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 31055c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 31060e8ac5e7SGunnar Mills 310725b54dbaSEd Tanous if constexpr (BMCWEB_KVM) 310825b54dbaSEd Tanous { 31090e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3110002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 311125b54dbaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 311225b54dbaSEd Tanous 4; 3113613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3114613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 311525b54dbaSEd Tanous } 311613451e39SWilly Tu 3117002d39b4SEd Tanous getMainChassisId(asyncResp, 3118002d39b4SEd Tanous [](const std::string& chassisId, 31198d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3120b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3121b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3122ef4c65b7SEd Tanous chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}", 3123ef4c65b7SEd Tanous chassisId); 3124002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3125c5d03ff4SJennifer Lee }); 3126a3002228SAppaRao Puli 312759a17e4fSGeorge Liu getSystemLocationIndicatorActive(asyncResp); 31289f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3129a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 313051bd2d8aSGunnar Mills getComputerSystem(asyncResp); 31316c34de48SEd Tanous getHostState(asyncResp); 3132491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3133978b8803SAndrew Geissler getBootProgress(asyncResp); 3134b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 313570c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 313670c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 313751709ffdSYong Li getHostWatchdogTimer(asyncResp); 3138c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 31399dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3140797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3141c0557e1aSGunnar Mills getLastResetTime(asyncResp); 314225b54dbaSEd Tanous if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE) 314325b54dbaSEd Tanous { 3144a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 314525b54dbaSEd Tanous } 31461981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 31473a2d0424SChris Cain getPowerMode(asyncResp); 314837bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3149c1e219d5SEd Tanous } 3150550a6bf8SJiaqing Zhao 3151c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3152c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 315322d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3154c1e219d5SEd Tanous const std::string& systemName) 3155c1e219d5SEd Tanous { 31563ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 315745ca1b86SEd Tanous { 315845ca1b86SEd Tanous return; 315945ca1b86SEd Tanous } 316025b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 31617f3e84a1SEd Tanous { 31627f3e84a1SEd Tanous // Option currently returns no systems. TBD 31637f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31647f3e84a1SEd Tanous systemName); 31657f3e84a1SEd Tanous return; 31667f3e84a1SEd Tanous } 3167253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 316822d268cbSEd Tanous { 316922d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 317022d268cbSEd Tanous systemName); 317122d268cbSEd Tanous return; 317222d268cbSEd Tanous } 317322d268cbSEd Tanous 3174dd60b9edSEd Tanous asyncResp->res.addHeader( 3175dd60b9edSEd Tanous boost::beast::http::field::link, 3176dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3177dd60b9edSEd Tanous 31789f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3179cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 318098e386ecSGunnar Mills std::optional<std::string> assetTag; 3181c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 31823a2d0424SChris Cain std::optional<std::string> powerMode; 3183550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3184550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3185550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3186550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3187550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3188550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3189797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3190550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 31919dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3192550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3193550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3194550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3195550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3196550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3197550a6bf8SJiaqing Zhao 3198550a6bf8SJiaqing Zhao // clang-format off 319915ed6780SWilly Tu if (!json_util::readJsonPatch( 3200550a6bf8SJiaqing Zhao req, asyncResp->res, 3201550a6bf8SJiaqing Zhao "IndicatorLED", indicatorLed, 32027e860f15SJohn Edward Broadbent "LocationIndicatorActive", locationIndicatorActive, 3203550a6bf8SJiaqing Zhao "AssetTag", assetTag, 3204550a6bf8SJiaqing Zhao "PowerRestorePolicy", powerRestorePolicy, 3205550a6bf8SJiaqing Zhao "PowerMode", powerMode, 3206550a6bf8SJiaqing Zhao "HostWatchdogTimer/FunctionEnabled", wdtEnable, 3207550a6bf8SJiaqing Zhao "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, 3208550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideTarget", bootSource, 3209550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideMode", bootType, 3210550a6bf8SJiaqing Zhao "Boot/BootSourceOverrideEnabled", bootEnable, 3211550a6bf8SJiaqing Zhao "Boot/AutomaticRetryConfig", bootAutomaticRetry, 3212797d5daeSCorey Hardesty "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, 3213550a6bf8SJiaqing Zhao "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, 32149dcfe8c1SAlbert Zhang "Boot/StopBootOnFault", stopBootOnFault, 3215550a6bf8SJiaqing Zhao "IdlePowerSaver/Enabled", ipsEnable, 3216550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, 3217550a6bf8SJiaqing Zhao "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, 3218550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, 3219550a6bf8SJiaqing Zhao "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime)) 32206617338dSEd Tanous { 32216617338dSEd Tanous return; 32226617338dSEd Tanous } 3223550a6bf8SJiaqing Zhao // clang-format on 3224491d8ee7SSantosh Puranik 32258d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 3226c45f0082SYong Li 322798e386ecSGunnar Mills if (assetTag) 322898e386ecSGunnar Mills { 322998e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 323098e386ecSGunnar Mills } 323198e386ecSGunnar Mills 3232550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3233c45f0082SYong Li { 3234f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3235c45f0082SYong Li } 3236c45f0082SYong Li 3237cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 323869f35306SGunnar Mills { 3239002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3240491d8ee7SSantosh Puranik } 3241550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 324269f35306SGunnar Mills { 3243550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 324469f35306SGunnar Mills } 3245ac7e1e0bSAli Ahmed 3246797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3247797d5daeSCorey Hardesty { 3248797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3249797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3250797d5daeSCorey Hardesty } 3251797d5daeSCorey Hardesty 3252550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3253ac7e1e0bSAli Ahmed { 3254c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 325569f35306SGunnar Mills } 3256265c1602SJohnathan Mantey 32579dcfe8c1SAlbert Zhang if (stopBootOnFault) 32589dcfe8c1SAlbert Zhang { 32599dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 32609dcfe8c1SAlbert Zhang } 32619dcfe8c1SAlbert Zhang 32629f8bfa7cSGunnar Mills if (locationIndicatorActive) 32639f8bfa7cSGunnar Mills { 326459a17e4fSGeorge Liu setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive); 32659f8bfa7cSGunnar Mills } 32669f8bfa7cSGunnar Mills 32677e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32687e860f15SJohn Edward Broadbent // passed 32699712f8acSEd Tanous if (indicatorLed) 32706617338dSEd Tanous { 3271f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3272002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3273d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3274d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32756617338dSEd Tanous } 3276c6a620f2SGeorge Liu 3277c6a620f2SGeorge Liu if (powerRestorePolicy) 3278c6a620f2SGeorge Liu { 32794e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3280c6a620f2SGeorge Liu } 32813a2d0424SChris Cain 32823a2d0424SChris Cain if (powerMode) 32833a2d0424SChris Cain { 32843a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32853a2d0424SChris Cain } 328637bbf98cSChris Cain 3287c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 328837bbf98cSChris Cain { 3289002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3290002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 329137bbf98cSChris Cain } 3292c1e219d5SEd Tanous } 32931cb1a9e6SAppaRao Puli 329438c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3295dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 32967f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3297c1e219d5SEd Tanous const std::string& /*systemName*/) 3298dd60b9edSEd Tanous { 3299dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3300dd60b9edSEd Tanous { 3301dd60b9edSEd Tanous return; 3302dd60b9edSEd Tanous } 3303dd60b9edSEd Tanous asyncResp->res.addHeader( 3304dd60b9edSEd Tanous boost::beast::http::field::link, 3305dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3306dd60b9edSEd Tanous } 330733e1f122SAndrew Geissler 330833e1f122SAndrew Geissler /** 330933e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 331033e1f122SAndrew Geissler * 331133e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 331233e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 331333e1f122SAndrew Geissler * 3314efff2b5dSManojkiran Eda * @return Emplaces corresponding Redfish translated value(s) in 331533e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 331633e1f122SAndrew Geissler * allowableValues. 331733e1f122SAndrew Geissler */ 331833e1f122SAndrew Geissler inline void 331933e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran, 332033e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 332133e1f122SAndrew Geissler { 332233e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 332333e1f122SAndrew Geissler { 332433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 332533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 332633e1f122SAndrew Geissler } 332733e1f122SAndrew Geissler else if (dbusAllowedHostTran == 332833e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 332933e1f122SAndrew Geissler { 333033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 333133e1f122SAndrew Geissler } 333233e1f122SAndrew Geissler else if (dbusAllowedHostTran == 333333e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 333433e1f122SAndrew Geissler { 333533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 333633e1f122SAndrew Geissler } 333733e1f122SAndrew Geissler else if (dbusAllowedHostTran == 333833e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 333933e1f122SAndrew Geissler { 334033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 334133e1f122SAndrew Geissler } 334233e1f122SAndrew Geissler else 334333e1f122SAndrew Geissler { 334433e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 334533e1f122SAndrew Geissler } 334633e1f122SAndrew Geissler } 334733e1f122SAndrew Geissler 334833e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 334933e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 335033e1f122SAndrew Geissler const boost::system::error_code& ec, 335133e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 335233e1f122SAndrew Geissler { 335333e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 335433e1f122SAndrew Geissler 335533e1f122SAndrew Geissler // Supported on all systems currently 335633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 335733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 335833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 335933e1f122SAndrew Geissler 336033e1f122SAndrew Geissler if (ec) 336133e1f122SAndrew Geissler { 3362e715d14bSEd Tanous if ((ec.value() == 3363e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3364e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 336533e1f122SAndrew Geissler { 336633e1f122SAndrew Geissler // Property not implemented so just return defaults 336733e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 336833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 336933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 337033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 337133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 337233e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 337333e1f122SAndrew Geissler } 337433e1f122SAndrew Geissler else 337533e1f122SAndrew Geissler { 337633e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 337733e1f122SAndrew Geissler messages::internalError(asyncResp->res); 337833e1f122SAndrew Geissler return; 337933e1f122SAndrew Geissler } 338033e1f122SAndrew Geissler } 338133e1f122SAndrew Geissler else 338233e1f122SAndrew Geissler { 338333e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 338433e1f122SAndrew Geissler { 338533e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 338633e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 338733e1f122SAndrew Geissler } 338833e1f122SAndrew Geissler } 338933e1f122SAndrew Geissler 339033e1f122SAndrew Geissler nlohmann::json::object_t parameter; 339133e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 339233e1f122SAndrew Geissler parameter["Required"] = true; 3393*539d8c6bSEd Tanous parameter["DataType"] = action_info::ParameterTypes::String; 339433e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 339533e1f122SAndrew Geissler nlohmann::json::array_t parameters; 339633e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 339733e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 339833e1f122SAndrew Geissler } 339933e1f122SAndrew Geissler 3400c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3401c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 340222d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3403c1e219d5SEd Tanous const std::string& systemName) 3404c1e219d5SEd Tanous { 34053ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 340645ca1b86SEd Tanous { 340745ca1b86SEd Tanous return; 340845ca1b86SEd Tanous } 340925b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 34107f3e84a1SEd Tanous { 34117f3e84a1SEd Tanous // Option currently returns no systems. TBD 34127f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 34137f3e84a1SEd Tanous systemName); 34147f3e84a1SEd Tanous return; 34157f3e84a1SEd Tanous } 3416746b56f3SAsmitha Karunanithi 3417746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3418746b56f3SAsmitha Karunanithi { 3419746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3420746b56f3SAsmitha Karunanithi return; 3421746b56f3SAsmitha Karunanithi } 3422746b56f3SAsmitha Karunanithi 3423253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 342422d268cbSEd Tanous { 342522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 342622d268cbSEd Tanous systemName); 342722d268cbSEd Tanous return; 342822d268cbSEd Tanous } 342922d268cbSEd Tanous 3430dd60b9edSEd Tanous asyncResp->res.addHeader( 3431dd60b9edSEd Tanous boost::beast::http::field::link, 3432dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34331476687dSEd Tanous 34341476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 3435253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3436253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3437c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34381476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34391476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34403215e700SNan Zhou 344133e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 344233e1f122SAndrew Geissler sdbusplus::asio::getProperty<std::vector<std::string>>( 344333e1f122SAndrew Geissler *crow::connections::systemBus, "xyz.openbmc_project.State.Host", 344433e1f122SAndrew Geissler "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host", 344533e1f122SAndrew Geissler "AllowedHostTransitions", 344633e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 344733e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 344833e1f122SAndrew Geissler afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions); 344933e1f122SAndrew Geissler }); 3450c1e219d5SEd Tanous } 3451c1e219d5SEd Tanous /** 3452c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3453c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3454c1e219d5SEd Tanous */ 3455100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3456c1e219d5SEd Tanous { 3457100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3458100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3459100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3460100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3461100afe56SEd Tanous 3462100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3463100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3464100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3465100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3466100afe56SEd Tanous 3467100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3468100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3469100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3470100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3471100afe56SEd Tanous 3472100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3473100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3474100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3475100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3476100afe56SEd Tanous 3477100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3478100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3479100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3480100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3481100afe56SEd Tanous 3482100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3483100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3484100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3485100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3486100afe56SEd Tanous 3487c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3488c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3489c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3490c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3491c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3492c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3493c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3494c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 34951cb1a9e6SAppaRao Puli } 3496c5b2abe0SLewanczyk, Dawid } // namespace redfish 3497