140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation 4c5b2abe0SLewanczyk, Dawid #pragma once 5c5b2abe0SLewanczyk, Dawid 613451e39SWilly Tu #include "bmcweb_config.h" 713451e39SWilly Tu 83ccb3adbSEd Tanous #include "app.hpp" 9d7857201SEd Tanous #include "async_resp.hpp" 101e1e598dSJonathan Doman #include "dbus_singleton.hpp" 117a1dbc48SGeorge Liu #include "dbus_utility.hpp" 12d7857201SEd Tanous #include "error_messages.hpp" 13539d8c6bSEd Tanous #include "generated/enums/action_info.hpp" 148d69c668SEd Tanous #include "generated/enums/computer_system.hpp" 15539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp" 1633e1f122SAndrew Geissler #include "generated/enums/resource.hpp" 17d7857201SEd Tanous #include "http_request.hpp" 18746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp" 191c8fba97SJames Feist #include "led.hpp" 20d7857201SEd Tanous #include "logging.hpp" 21f4c99e70SEd Tanous #include "query.hpp" 22c5d03ff4SJennifer Lee #include "redfish_util.hpp" 233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 243ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 253ccb3adbSEd Tanous #include "utils/json_utils.hpp" 26472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp" 273ccb3adbSEd Tanous #include "utils/sw_utils.hpp" 28fc5ae94dSOliver Brewka #include "utils/systems_utils.hpp" 292b82937eSEd Tanous #include "utils/time_utils.hpp" 30c5d03ff4SJennifer Lee 31d7857201SEd Tanous #include <asm-generic/errno.h> 32d7857201SEd Tanous 33fc903b3dSAndrew Geissler #include <boost/asio/error.hpp> 34d7857201SEd Tanous #include <boost/beast/http/field.hpp> 35d7857201SEd Tanous #include <boost/beast/http/status.hpp> 36d7857201SEd Tanous #include <boost/beast/http/verb.hpp> 37e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 3833e1f122SAndrew Geissler #include <boost/system/linux_error.hpp> 39ef4c65b7SEd Tanous #include <boost/url/format.hpp> 40d7857201SEd Tanous #include <nlohmann/json.hpp> 41d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp> 42bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 431214b7e7SGunnar Mills 447a1dbc48SGeorge Liu #include <array> 45d7857201SEd Tanous #include <chrono> 46d7857201SEd Tanous #include <cstddef> 47d7857201SEd Tanous #include <cstdint> 48d7857201SEd Tanous #include <functional> 4933e1f122SAndrew Geissler #include <memory> 50d7857201SEd Tanous #include <optional> 51d7857201SEd Tanous #include <ratio> 526b9ac4f2SChris Cain #include <string> 537a1dbc48SGeorge Liu #include <string_view> 54d7857201SEd Tanous #include <tuple> 5520fa6a2cSEd Tanous #include <utility> 566b9ac4f2SChris Cain #include <vector> 57c5b2abe0SLewanczyk, Dawid 581abe55efSEd Tanous namespace redfish 591abe55efSEd Tanous { 60c5b2abe0SLewanczyk, Dawid 615c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2> 625c3e9272SAbhishek Patel protocolToDBusForSystems{ 635c3e9272SAbhishek Patel {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}}; 645c3e9272SAbhishek Patel 659d3ae10eSAlpana Kumari /** 669d3ae10eSAlpana Kumari * @brief Updates the Functional State of DIMMs 679d3ae10eSAlpana Kumari * 68ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 699d3ae10eSAlpana Kumari * @param[in] dimmState Dimm's Functional state, true/false 709d3ae10eSAlpana Kumari * 719d3ae10eSAlpana Kumari * @return None. 729d3ae10eSAlpana Kumari */ 73bd79bce8SPatrick Williams inline void updateDimmProperties( 74bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional) 759d3ae10eSAlpana Kumari { 7662598e31SEd Tanous BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional); 779d3ae10eSAlpana Kumari 789d3ae10eSAlpana Kumari // Set it as Enabled if at least one DIMM is functional 799d3ae10eSAlpana Kumari // Update STATE only if previous State was DISABLED and current Dimm is 809d3ae10eSAlpana Kumari // ENABLED. 8102cad96eSEd Tanous const nlohmann::json& prevMemSummary = 82ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"]; 839d3ae10eSAlpana Kumari if (prevMemSummary == "Disabled") 849d3ae10eSAlpana Kumari { 85e05aec50SEd Tanous if (isDimmFunctional) 869d3ae10eSAlpana Kumari { 87ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = 889d3ae10eSAlpana Kumari "Enabled"; 899d3ae10eSAlpana Kumari } 909d3ae10eSAlpana Kumari } 919d3ae10eSAlpana Kumari } 929d3ae10eSAlpana Kumari 9357e8c9beSAlpana Kumari /* 9457e8c9beSAlpana Kumari * @brief Update "ProcessorSummary" "Status" "State" based on 9557e8c9beSAlpana Kumari * CPU Functional State 9657e8c9beSAlpana Kumari * 97ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 9857e8c9beSAlpana Kumari * @param[in] cpuFunctionalState is CPU functional true/false 9957e8c9beSAlpana Kumari * 10057e8c9beSAlpana Kumari * @return None. 10157e8c9beSAlpana Kumari */ 102ac106bf6SEd Tanous inline void modifyCpuFunctionalState( 103ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional) 10457e8c9beSAlpana Kumari { 10562598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional); 10657e8c9beSAlpana Kumari 10702cad96eSEd Tanous const nlohmann::json& prevProcState = 108ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"]; 10957e8c9beSAlpana Kumari 11057e8c9beSAlpana Kumari // Set it as Enabled if at least one CPU is functional 11157e8c9beSAlpana Kumari // Update STATE only if previous State was Non_Functional and current CPU is 11257e8c9beSAlpana Kumari // Functional. 11357e8c9beSAlpana Kumari if (prevProcState == "Disabled") 11457e8c9beSAlpana Kumari { 115e05aec50SEd Tanous if (isCpuFunctional) 11657e8c9beSAlpana Kumari { 117ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = 11857e8c9beSAlpana Kumari "Enabled"; 11957e8c9beSAlpana Kumari } 12057e8c9beSAlpana Kumari } 12157e8c9beSAlpana Kumari } 12257e8c9beSAlpana Kumari 123cf0e004cSNinad Palsule /* 124cf0e004cSNinad Palsule * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState 125cf0e004cSNinad Palsule * 126ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 127cf0e004cSNinad Palsule * @param[in] cpuPresenceState CPU present or not 128cf0e004cSNinad Palsule * 129cf0e004cSNinad Palsule * @return None. 130cf0e004cSNinad Palsule */ 131bd79bce8SPatrick Williams inline void modifyCpuPresenceState( 132bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent) 133cf0e004cSNinad Palsule { 13462598e31SEd Tanous BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent); 135cf0e004cSNinad Palsule 136cf0e004cSNinad Palsule if (isCpuPresent) 137cf0e004cSNinad Palsule { 138cf0e004cSNinad Palsule nlohmann::json& procCount = 139ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["Count"]; 140cf0e004cSNinad Palsule auto* procCountPtr = 141cf0e004cSNinad Palsule procCount.get_ptr<nlohmann::json::number_integer_t*>(); 142cf0e004cSNinad Palsule if (procCountPtr != nullptr) 143cf0e004cSNinad Palsule { 144cf0e004cSNinad Palsule // shouldn't be possible to be nullptr 145cf0e004cSNinad Palsule *procCountPtr += 1; 146cf0e004cSNinad Palsule } 147cf0e004cSNinad Palsule } 148cf0e004cSNinad Palsule } 149cf0e004cSNinad Palsule 150382d6475SAli Ahmed inline void getProcessorProperties( 151ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 152382d6475SAli Ahmed const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>& 153382d6475SAli Ahmed properties) 15403fbed92SAli Ahmed { 15562598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size()); 15603fbed92SAli Ahmed 15703fbed92SAli Ahmed // TODO: Get Model 15803fbed92SAli Ahmed 159bc1d29deSKrzysztof Grobelny const uint16_t* coreCount = nullptr; 16003fbed92SAli Ahmed 161bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 162bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount); 16303fbed92SAli Ahmed 164bc1d29deSKrzysztof Grobelny if (!success) 16503fbed92SAli Ahmed { 166ac106bf6SEd Tanous messages::internalError(asyncResp->res); 16703fbed92SAli Ahmed return; 16803fbed92SAli Ahmed } 16903fbed92SAli Ahmed 170bc1d29deSKrzysztof Grobelny if (coreCount != nullptr) 17103fbed92SAli Ahmed { 172bc1d29deSKrzysztof Grobelny nlohmann::json& coreCountJson = 173ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"]; 174bc1d29deSKrzysztof Grobelny uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>(); 175bc1d29deSKrzysztof Grobelny 176bc1d29deSKrzysztof Grobelny if (coreCountJsonPtr == nullptr) 177bc1d29deSKrzysztof Grobelny { 178bc1d29deSKrzysztof Grobelny coreCountJson = *coreCount; 17903fbed92SAli Ahmed } 18003fbed92SAli Ahmed else 18103fbed92SAli Ahmed { 182bc1d29deSKrzysztof Grobelny *coreCountJsonPtr += *coreCount; 18303fbed92SAli Ahmed } 18403fbed92SAli Ahmed } 18503fbed92SAli Ahmed } 18603fbed92SAli Ahmed 18703fbed92SAli Ahmed /* 18803fbed92SAli Ahmed * @brief Get ProcessorSummary fields 18903fbed92SAli Ahmed * 190ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 19103fbed92SAli Ahmed * @param[in] service dbus service for Cpu Information 19203fbed92SAli Ahmed * @param[in] path dbus path for Cpu 19303fbed92SAli Ahmed * 19403fbed92SAli Ahmed * @return None. 19503fbed92SAli Ahmed */ 196504af5a0SPatrick Williams inline void getProcessorSummary( 197504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 198ac106bf6SEd Tanous const std::string& service, const std::string& path) 19903fbed92SAli Ahmed { 200ac106bf6SEd Tanous auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3, 201382d6475SAli Ahmed const bool cpuPresenceCheck) { 202382d6475SAli Ahmed if (ec3) 203382d6475SAli Ahmed { 20462598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec3); 205382d6475SAli Ahmed return; 206382d6475SAli Ahmed } 207ac106bf6SEd Tanous modifyCpuPresenceState(asyncResp, cpuPresenceCheck); 208382d6475SAli Ahmed }; 209382d6475SAli Ahmed 210cf0e004cSNinad Palsule // Get the Presence of CPU 211deae6a78SEd Tanous dbus::utility::getProperty<bool>(*crow::connections::systemBus, service, 212deae6a78SEd Tanous path, "xyz.openbmc_project.Inventory.Item", 213deae6a78SEd Tanous "Present", std::move(getCpuPresenceState)); 214cf0e004cSNinad Palsule 215deae6a78SEd Tanous dbus::utility::getAllProperties( 216deae6a78SEd Tanous service, path, "xyz.openbmc_project.Inventory.Item.Cpu", 217ac106bf6SEd Tanous [asyncResp, service, 2185e7e2dc5SEd Tanous path](const boost::system::error_code& ec2, 219b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 22003fbed92SAli Ahmed if (ec2) 22103fbed92SAli Ahmed { 22262598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 223ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22403fbed92SAli Ahmed return; 22503fbed92SAli Ahmed } 226ac106bf6SEd Tanous getProcessorProperties(asyncResp, properties); 227bc1d29deSKrzysztof Grobelny }); 22803fbed92SAli Ahmed } 22903fbed92SAli Ahmed 23057e8c9beSAlpana Kumari /* 231cf0e004cSNinad Palsule * @brief processMemoryProperties fields 232cf0e004cSNinad Palsule * 233ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 234cf0e004cSNinad Palsule * @param[in] DBUS properties for memory 235cf0e004cSNinad Palsule * 236cf0e004cSNinad Palsule * @return None. 237cf0e004cSNinad Palsule */ 238504af5a0SPatrick Williams inline void processMemoryProperties( 239504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 240cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) 241cf0e004cSNinad Palsule { 24262598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size()); 243cf0e004cSNinad Palsule 244cf0e004cSNinad Palsule if (properties.empty()) 245cf0e004cSNinad Palsule { 246cf0e004cSNinad Palsule return; 247cf0e004cSNinad Palsule } 248cf0e004cSNinad Palsule 249cf0e004cSNinad Palsule const size_t* memorySizeInKB = nullptr; 250cf0e004cSNinad Palsule 251cf0e004cSNinad Palsule const bool success = sdbusplus::unpackPropertiesNoThrow( 252cf0e004cSNinad Palsule dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB", 253cf0e004cSNinad Palsule memorySizeInKB); 254cf0e004cSNinad Palsule 255cf0e004cSNinad Palsule if (!success) 256cf0e004cSNinad Palsule { 257ac106bf6SEd Tanous messages::internalError(asyncResp->res); 258cf0e004cSNinad Palsule return; 259cf0e004cSNinad Palsule } 260cf0e004cSNinad Palsule 261cf0e004cSNinad Palsule if (memorySizeInKB != nullptr) 262cf0e004cSNinad Palsule { 263cf0e004cSNinad Palsule nlohmann::json& totalMemory = 264ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"]; 265dfb2b408SPriyanga Ramasamy const double* preValue = totalMemory.get_ptr<const double*>(); 266cf0e004cSNinad Palsule if (preValue == nullptr) 267cf0e004cSNinad Palsule { 268ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 269dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024); 270cf0e004cSNinad Palsule } 271cf0e004cSNinad Palsule else 272cf0e004cSNinad Palsule { 273ac106bf6SEd Tanous asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 274dfb2b408SPriyanga Ramasamy static_cast<double>(*memorySizeInKB) / (1024 * 1024) + 275dfb2b408SPriyanga Ramasamy *preValue; 276cf0e004cSNinad Palsule } 277cf0e004cSNinad Palsule } 278cf0e004cSNinad Palsule } 279cf0e004cSNinad Palsule 280cf0e004cSNinad Palsule /* 281cf0e004cSNinad Palsule * @brief Get getMemorySummary fields 282cf0e004cSNinad Palsule * 283ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls 284cf0e004cSNinad Palsule * @param[in] service dbus service for memory Information 285cf0e004cSNinad Palsule * @param[in] path dbus path for memory 286cf0e004cSNinad Palsule * 287cf0e004cSNinad Palsule * @return None. 288cf0e004cSNinad Palsule */ 289504af5a0SPatrick Williams inline void getMemorySummary( 290504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 291ac106bf6SEd Tanous const std::string& service, const std::string& path) 292cf0e004cSNinad Palsule { 293deae6a78SEd Tanous dbus::utility::getAllProperties( 294deae6a78SEd Tanous service, path, "xyz.openbmc_project.Inventory.Item.Dimm", 295ac106bf6SEd Tanous [asyncResp, service, 296cf0e004cSNinad Palsule path](const boost::system::error_code& ec2, 297cf0e004cSNinad Palsule const dbus::utility::DBusPropertiesMap& properties) { 298cf0e004cSNinad Palsule if (ec2) 299cf0e004cSNinad Palsule { 30062598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec2); 301ac106bf6SEd Tanous messages::internalError(asyncResp->res); 302cf0e004cSNinad Palsule return; 303cf0e004cSNinad Palsule } 30451bd2d8aSGunnar Mills processMemoryProperties(asyncResp, properties); 305cf0e004cSNinad Palsule }); 306cf0e004cSNinad Palsule } 307cf0e004cSNinad Palsule 308a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 309a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 310a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& properties) 3111abe55efSEd Tanous { 312a974c132SLakshmi Yadlapati if (ec) 313a974c132SLakshmi Yadlapati { 314a974c132SLakshmi Yadlapati BMCWEB_LOG_ERROR("DBUS response error {}", ec); 315a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 316a974c132SLakshmi Yadlapati return; 317a974c132SLakshmi Yadlapati } 318a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size()); 319a974c132SLakshmi Yadlapati 320a974c132SLakshmi Yadlapati const std::string* uUID = nullptr; 321a974c132SLakshmi Yadlapati 322a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 323a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID); 324a974c132SLakshmi Yadlapati 325a974c132SLakshmi Yadlapati if (!success) 326a974c132SLakshmi Yadlapati { 327a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 328a974c132SLakshmi Yadlapati return; 329a974c132SLakshmi Yadlapati } 330a974c132SLakshmi Yadlapati 331a974c132SLakshmi Yadlapati if (uUID != nullptr) 332a974c132SLakshmi Yadlapati { 333a974c132SLakshmi Yadlapati std::string valueStr = *uUID; 334a974c132SLakshmi Yadlapati if (valueStr.size() == 32) 335a974c132SLakshmi Yadlapati { 336a974c132SLakshmi Yadlapati valueStr.insert(8, 1, '-'); 337a974c132SLakshmi Yadlapati valueStr.insert(13, 1, '-'); 338a974c132SLakshmi Yadlapati valueStr.insert(18, 1, '-'); 339a974c132SLakshmi Yadlapati valueStr.insert(23, 1, '-'); 340a974c132SLakshmi Yadlapati } 341a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("UUID = {}", valueStr); 342a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["UUID"] = valueStr; 343a974c132SLakshmi Yadlapati } 344a974c132SLakshmi Yadlapati } 345a974c132SLakshmi Yadlapati 346504af5a0SPatrick Williams inline void afterGetInventory( 347504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 348a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 349a974c132SLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& propertiesList) 350a974c132SLakshmi Yadlapati { 351a974c132SLakshmi Yadlapati if (ec) 352a974c132SLakshmi Yadlapati { 353a974c132SLakshmi Yadlapati // doesn't have to include this 354a974c132SLakshmi Yadlapati // interface 355a974c132SLakshmi Yadlapati return; 356a974c132SLakshmi Yadlapati } 357a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size()); 358a974c132SLakshmi Yadlapati 359a974c132SLakshmi Yadlapati const std::string* partNumber = nullptr; 360a974c132SLakshmi Yadlapati const std::string* serialNumber = nullptr; 361a974c132SLakshmi Yadlapati const std::string* manufacturer = nullptr; 362a974c132SLakshmi Yadlapati const std::string* model = nullptr; 363a974c132SLakshmi Yadlapati const std::string* subModel = nullptr; 364a974c132SLakshmi Yadlapati 365a974c132SLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 366a974c132SLakshmi Yadlapati dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber", 367a974c132SLakshmi Yadlapati partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 368a974c132SLakshmi Yadlapati "Model", model, "SubModel", subModel); 369a974c132SLakshmi Yadlapati 370a974c132SLakshmi Yadlapati if (!success) 371a974c132SLakshmi Yadlapati { 372a974c132SLakshmi Yadlapati messages::internalError(asyncResp->res); 373a974c132SLakshmi Yadlapati return; 374a974c132SLakshmi Yadlapati } 375a974c132SLakshmi Yadlapati 376a974c132SLakshmi Yadlapati if (partNumber != nullptr) 377a974c132SLakshmi Yadlapati { 378a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["PartNumber"] = *partNumber; 379a974c132SLakshmi Yadlapati } 380a974c132SLakshmi Yadlapati 381a974c132SLakshmi Yadlapati if (serialNumber != nullptr) 382a974c132SLakshmi Yadlapati { 383a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 384a974c132SLakshmi Yadlapati } 385a974c132SLakshmi Yadlapati 386a974c132SLakshmi Yadlapati if (manufacturer != nullptr) 387a974c132SLakshmi Yadlapati { 388a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 389a974c132SLakshmi Yadlapati } 390a974c132SLakshmi Yadlapati 391a974c132SLakshmi Yadlapati if (model != nullptr) 392a974c132SLakshmi Yadlapati { 393a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["Model"] = *model; 394a974c132SLakshmi Yadlapati } 395a974c132SLakshmi Yadlapati 396a974c132SLakshmi Yadlapati if (subModel != nullptr) 397a974c132SLakshmi Yadlapati { 398a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["SubModel"] = *subModel; 399a974c132SLakshmi Yadlapati } 400a974c132SLakshmi Yadlapati 401a974c132SLakshmi Yadlapati // Grab the bios version 402a974c132SLakshmi Yadlapati sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, 403a974c132SLakshmi Yadlapati "BiosVersion", false); 404a974c132SLakshmi Yadlapati } 405a974c132SLakshmi Yadlapati 406bd79bce8SPatrick Williams inline void afterGetAssetTag( 407bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 408bd79bce8SPatrick Williams const boost::system::error_code& ec, const std::string& value) 409a974c132SLakshmi Yadlapati { 410a974c132SLakshmi Yadlapati if (ec) 411a974c132SLakshmi Yadlapati { 412a974c132SLakshmi Yadlapati // doesn't have to include this 413a974c132SLakshmi Yadlapati // interface 414a974c132SLakshmi Yadlapati return; 415a974c132SLakshmi Yadlapati } 416a974c132SLakshmi Yadlapati 417a974c132SLakshmi Yadlapati asyncResp->res.jsonValue["AssetTag"] = value; 418a974c132SLakshmi Yadlapati } 419a974c132SLakshmi Yadlapati 420a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree( 421a974c132SLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 422a974c132SLakshmi Yadlapati const boost::system::error_code& ec, 423a974c132SLakshmi Yadlapati const dbus::utility::MapperGetSubTreeResponse& subtree) 424a974c132SLakshmi Yadlapati { 4251abe55efSEd Tanous if (ec) 4261abe55efSEd Tanous { 427b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 428ac106bf6SEd Tanous messages::internalError(asyncResp->res); 429c5b2abe0SLewanczyk, Dawid return; 430c5b2abe0SLewanczyk, Dawid } 431c5b2abe0SLewanczyk, Dawid // Iterate over all retrieved ObjectPaths. 432002d39b4SEd Tanous for (const std::pair< 433002d39b4SEd Tanous std::string, 434002d39b4SEd Tanous std::vector<std::pair<std::string, std::vector<std::string>>>>& 4351214b7e7SGunnar Mills object : subtree) 4361abe55efSEd Tanous { 437c5b2abe0SLewanczyk, Dawid const std::string& path = object.first; 43862598e31SEd Tanous BMCWEB_LOG_DEBUG("Got path: {}", path); 439002d39b4SEd Tanous const std::vector<std::pair<std::string, std::vector<std::string>>>& 4401214b7e7SGunnar Mills connectionNames = object.second; 44126f6976fSEd Tanous if (connectionNames.empty()) 4421abe55efSEd Tanous { 443c5b2abe0SLewanczyk, Dawid continue; 444c5b2abe0SLewanczyk, Dawid } 445029573d4SEd Tanous 4466c34de48SEd Tanous // This is not system, so check if it's cpu, dimm, UUID or 4476c34de48SEd Tanous // BiosVer 44804a258f4SEd Tanous for (const auto& connection : connectionNames) 4491abe55efSEd Tanous { 45004a258f4SEd Tanous for (const auto& interfaceName : connection.second) 4511abe55efSEd Tanous { 452a974c132SLakshmi Yadlapati if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") 4531abe55efSEd Tanous { 45462598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Dimm, now get its properties."); 4559d3ae10eSAlpana Kumari 456ac106bf6SEd Tanous getMemorySummary(asyncResp, connection.first, path); 4575fd0aafbSNinad Palsule } 45804a258f4SEd Tanous else if (interfaceName == 45904a258f4SEd Tanous "xyz.openbmc_project.Inventory.Item.Cpu") 4601abe55efSEd Tanous { 46162598e31SEd Tanous BMCWEB_LOG_DEBUG("Found Cpu, now get its properties."); 46257e8c9beSAlpana Kumari 463ac106bf6SEd Tanous getProcessorSummary(asyncResp, connection.first, path); 4645fd0aafbSNinad Palsule } 465002d39b4SEd Tanous else if (interfaceName == "xyz.openbmc_project.Common.UUID") 4661abe55efSEd Tanous { 46762598e31SEd Tanous BMCWEB_LOG_DEBUG("Found UUID, now get its properties."); 468bc1d29deSKrzysztof Grobelny 469deae6a78SEd Tanous dbus::utility::getAllProperties( 470a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 471a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 472ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec3, 473b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 4741214b7e7SGunnar Mills properties) { 475a974c132SLakshmi Yadlapati afterGetUUID(asyncResp, ec3, properties); 476bc1d29deSKrzysztof Grobelny }); 477c5b2abe0SLewanczyk, Dawid } 478029573d4SEd Tanous else if (interfaceName == 479029573d4SEd Tanous "xyz.openbmc_project.Inventory.Item.System") 4801abe55efSEd Tanous { 481deae6a78SEd Tanous dbus::utility::getAllProperties( 482a974c132SLakshmi Yadlapati *crow::connections::systemBus, connection.first, path, 483bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Inventory.Decorator.Asset", 484a974c132SLakshmi Yadlapati [asyncResp](const boost::system::error_code& ec3, 485b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 486a974c132SLakshmi Yadlapati properties) { 487a974c132SLakshmi Yadlapati afterGetInventory(asyncResp, ec3, properties); 488bc1d29deSKrzysztof Grobelny }); 489e4a4b9a9SJames Feist 490deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 491deae6a78SEd Tanous connection.first, path, 4921e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator." 4931e1e598dSJonathan Doman "AssetTag", 4941e1e598dSJonathan Doman "AssetTag", 495a974c132SLakshmi Yadlapati std::bind_front(afterGetAssetTag, asyncResp)); 496a974c132SLakshmi Yadlapati } 497a974c132SLakshmi Yadlapati } 498a974c132SLakshmi Yadlapati } 499a974c132SLakshmi Yadlapati } 500a974c132SLakshmi Yadlapati } 501a974c132SLakshmi Yadlapati 502a974c132SLakshmi Yadlapati /* 503a974c132SLakshmi Yadlapati * @brief Retrieves computer system properties over dbus 504a974c132SLakshmi Yadlapati * 505a974c132SLakshmi Yadlapati * @param[in] asyncResp Shared pointer for completing asynchronous calls 506a974c132SLakshmi Yadlapati * 507a974c132SLakshmi Yadlapati * @return None. 508a974c132SLakshmi Yadlapati */ 509504af5a0SPatrick Williams inline void getComputerSystem( 510504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 511e4a4b9a9SJames Feist { 512a974c132SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get available system components."); 513a974c132SLakshmi Yadlapati constexpr std::array<std::string_view, 5> interfaces = { 514a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 515a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Cpu", 516a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.Dimm", 517a974c132SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Item.System", 518a974c132SLakshmi Yadlapati "xyz.openbmc_project.Common.UUID", 519a974c132SLakshmi Yadlapati }; 520a974c132SLakshmi Yadlapati dbus::utility::getSubTree( 521a974c132SLakshmi Yadlapati "/xyz/openbmc_project/inventory", 0, interfaces, 52251bd2d8aSGunnar Mills std::bind_front(afterSystemGetSubTree, asyncResp)); 523c5b2abe0SLewanczyk, Dawid } 524c5b2abe0SLewanczyk, Dawid 525c5b2abe0SLewanczyk, Dawid /** 526c5b2abe0SLewanczyk, Dawid * @brief Retrieves host state properties over dbus 527c5b2abe0SLewanczyk, Dawid * 528ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 529c5b2abe0SLewanczyk, Dawid * 530c5b2abe0SLewanczyk, Dawid * @return None. 531c5b2abe0SLewanczyk, Dawid */ 532ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 5331abe55efSEd Tanous { 53462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host information."); 535deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 536deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 537deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "CurrentHostState", 538ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 5391e1e598dSJonathan Doman const std::string& hostState) { 5401abe55efSEd Tanous if (ec) 5411abe55efSEd Tanous { 54222228c28SAndrew Geissler if (ec == boost::system::errc::host_unreachable) 54322228c28SAndrew Geissler { 54422228c28SAndrew Geissler // Service not available, no error, just don't return 54522228c28SAndrew Geissler // host state info 54662598e31SEd Tanous BMCWEB_LOG_DEBUG("Service not available {}", ec); 54722228c28SAndrew Geissler return; 54822228c28SAndrew Geissler } 54962598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 550ac106bf6SEd Tanous messages::internalError(asyncResp->res); 551c5b2abe0SLewanczyk, Dawid return; 552c5b2abe0SLewanczyk, Dawid } 5536617338dSEd Tanous 55462598e31SEd Tanous BMCWEB_LOG_DEBUG("Host state: {}", hostState); 555c5b2abe0SLewanczyk, Dawid // Verify Host State 5561e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 5571abe55efSEd Tanous { 558bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 559bd79bce8SPatrick Williams resource::PowerState::On; 560539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 561539d8c6bSEd Tanous resource::State::Enabled; 5621abe55efSEd Tanous } 5631e1e598dSJonathan Doman else if (hostState == 5640fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.Quiesced") 5658c888608SGunnar Mills { 566bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 567bd79bce8SPatrick Williams resource::PowerState::On; 568539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 569539d8c6bSEd Tanous resource::State::Quiesced; 5708c888608SGunnar Mills } 5711e1e598dSJonathan Doman else if (hostState == 5720fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") 57383935af9SAndrew Geissler { 574bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 575bd79bce8SPatrick Williams resource::PowerState::On; 576539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 577539d8c6bSEd Tanous resource::State::InTest; 57883935af9SAndrew Geissler } 5790fda0f12SGeorge Liu else if ( 5801e1e598dSJonathan Doman hostState == 5810fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning") 5821a2a1437SAndrew Geissler { 583539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 584539d8c6bSEd Tanous resource::PowerState::PoweringOn; 585539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 586539d8c6bSEd Tanous resource::State::Starting; 5871a2a1437SAndrew Geissler } 588bd79bce8SPatrick Williams else if ( 589bd79bce8SPatrick Williams hostState == 5900fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.HostState.TransitioningToOff") 5911a2a1437SAndrew Geissler { 592539d8c6bSEd Tanous asyncResp->res.jsonValue["PowerState"] = 593539d8c6bSEd Tanous resource::PowerState::PoweringOff; 594539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 595539d8c6bSEd Tanous resource::State::Disabled; 5961a2a1437SAndrew Geissler } 5971abe55efSEd Tanous else 5981abe55efSEd Tanous { 599bd79bce8SPatrick Williams asyncResp->res.jsonValue["PowerState"] = 600bd79bce8SPatrick Williams resource::PowerState::Off; 601539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 602539d8c6bSEd Tanous resource::State::Disabled; 603c5b2abe0SLewanczyk, Dawid } 6041e1e598dSJonathan Doman }); 605c5b2abe0SLewanczyk, Dawid } 606c5b2abe0SLewanczyk, Dawid 607c5b2abe0SLewanczyk, Dawid /** 608786d0f60SGunnar Mills * @brief Translates boot source DBUS property value to redfish. 609491d8ee7SSantosh Puranik * 610491d8ee7SSantosh Puranik * @param[in] dbusSource The boot source in DBUS speak. 611491d8ee7SSantosh Puranik * 612491d8ee7SSantosh Puranik * @return Returns as a string, the boot source in Redfish terms. If translation 613491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 614491d8ee7SSantosh Puranik */ 61523a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource) 616491d8ee7SSantosh Puranik { 617491d8ee7SSantosh Puranik if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") 618491d8ee7SSantosh Puranik { 619491d8ee7SSantosh Puranik return "None"; 620491d8ee7SSantosh Puranik } 6213174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") 622491d8ee7SSantosh Puranik { 623491d8ee7SSantosh Puranik return "Hdd"; 624491d8ee7SSantosh Puranik } 6253174e4dfSEd Tanous if (dbusSource == 626a71dc0b7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") 627491d8ee7SSantosh Puranik { 628491d8ee7SSantosh Puranik return "Cd"; 629491d8ee7SSantosh Puranik } 6303174e4dfSEd Tanous if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") 631491d8ee7SSantosh Puranik { 632491d8ee7SSantosh Puranik return "Pxe"; 633491d8ee7SSantosh Puranik } 6343174e4dfSEd Tanous if (dbusSource == 635944ffaf9SJohnathan Mantey "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") 6369f16b2c1SJennifer Lee { 6379f16b2c1SJennifer Lee return "Usb"; 6389f16b2c1SJennifer Lee } 639491d8ee7SSantosh Puranik return ""; 640491d8ee7SSantosh Puranik } 641491d8ee7SSantosh Puranik 642491d8ee7SSantosh Puranik /** 643cd9a4666SKonstantin Aladyshev * @brief Translates boot type DBUS property value to redfish. 644cd9a4666SKonstantin Aladyshev * 645cd9a4666SKonstantin Aladyshev * @param[in] dbusType The boot type in DBUS speak. 646cd9a4666SKonstantin Aladyshev * 647cd9a4666SKonstantin Aladyshev * @return Returns as a string, the boot type in Redfish terms. If translation 648cd9a4666SKonstantin Aladyshev * cannot be done, returns an empty string. 649cd9a4666SKonstantin Aladyshev */ 650cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType) 651cd9a4666SKonstantin Aladyshev { 652cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") 653cd9a4666SKonstantin Aladyshev { 654cd9a4666SKonstantin Aladyshev return "Legacy"; 655cd9a4666SKonstantin Aladyshev } 656cd9a4666SKonstantin Aladyshev if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") 657cd9a4666SKonstantin Aladyshev { 658cd9a4666SKonstantin Aladyshev return "UEFI"; 659cd9a4666SKonstantin Aladyshev } 660cd9a4666SKonstantin Aladyshev return ""; 661cd9a4666SKonstantin Aladyshev } 662cd9a4666SKonstantin Aladyshev 663cd9a4666SKonstantin Aladyshev /** 664786d0f60SGunnar Mills * @brief Translates boot mode DBUS property value to redfish. 665491d8ee7SSantosh Puranik * 666491d8ee7SSantosh Puranik * @param[in] dbusMode The boot mode in DBUS speak. 667491d8ee7SSantosh Puranik * 668491d8ee7SSantosh Puranik * @return Returns as a string, the boot mode in Redfish terms. If translation 669491d8ee7SSantosh Puranik * cannot be done, returns an empty string. 670491d8ee7SSantosh Puranik */ 67123a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode) 672491d8ee7SSantosh Puranik { 673491d8ee7SSantosh Puranik if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 674491d8ee7SSantosh Puranik { 675491d8ee7SSantosh Puranik return "None"; 676491d8ee7SSantosh Puranik } 6773174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") 678491d8ee7SSantosh Puranik { 679491d8ee7SSantosh Puranik return "Diags"; 680491d8ee7SSantosh Puranik } 6813174e4dfSEd Tanous if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") 682491d8ee7SSantosh Puranik { 683491d8ee7SSantosh Puranik return "BiosSetup"; 684491d8ee7SSantosh Puranik } 685491d8ee7SSantosh Puranik return ""; 686491d8ee7SSantosh Puranik } 687491d8ee7SSantosh Puranik 688491d8ee7SSantosh Puranik /** 689e43914b3SAndrew Geissler * @brief Translates boot progress DBUS property value to redfish. 690e43914b3SAndrew Geissler * 691e43914b3SAndrew Geissler * @param[in] dbusBootProgress The boot progress in DBUS speak. 692e43914b3SAndrew Geissler * 693e43914b3SAndrew Geissler * @return Returns as a string, the boot progress in Redfish terms. If 694e43914b3SAndrew Geissler * translation cannot be done, returns "None". 695e43914b3SAndrew Geissler */ 696e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) 697e43914b3SAndrew Geissler { 698e43914b3SAndrew Geissler // Now convert the D-Bus BootProgress to the appropriate Redfish 699e43914b3SAndrew Geissler // enum 700e43914b3SAndrew Geissler std::string rfBpLastState = "None"; 701e43914b3SAndrew Geissler if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress." 702e43914b3SAndrew Geissler "ProgressStages.Unspecified") 703e43914b3SAndrew Geissler { 704e43914b3SAndrew Geissler rfBpLastState = "None"; 705e43914b3SAndrew Geissler } 706e43914b3SAndrew Geissler else if (dbusBootProgress == 707e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 708e43914b3SAndrew Geissler "PrimaryProcInit") 709e43914b3SAndrew Geissler { 710e43914b3SAndrew Geissler rfBpLastState = "PrimaryProcessorInitializationStarted"; 711e43914b3SAndrew Geissler } 712e43914b3SAndrew Geissler else if (dbusBootProgress == 713e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 714e43914b3SAndrew Geissler "BusInit") 715e43914b3SAndrew Geissler { 716e43914b3SAndrew Geissler rfBpLastState = "BusInitializationStarted"; 717e43914b3SAndrew Geissler } 718e43914b3SAndrew Geissler else if (dbusBootProgress == 719e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 720e43914b3SAndrew Geissler "MemoryInit") 721e43914b3SAndrew Geissler { 722e43914b3SAndrew Geissler rfBpLastState = "MemoryInitializationStarted"; 723e43914b3SAndrew Geissler } 724e43914b3SAndrew Geissler else if (dbusBootProgress == 725e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 726e43914b3SAndrew Geissler "SecondaryProcInit") 727e43914b3SAndrew Geissler { 728e43914b3SAndrew Geissler rfBpLastState = "SecondaryProcessorInitializationStarted"; 729e43914b3SAndrew Geissler } 730e43914b3SAndrew Geissler else if (dbusBootProgress == 731e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 732e43914b3SAndrew Geissler "PCIInit") 733e43914b3SAndrew Geissler { 734e43914b3SAndrew Geissler rfBpLastState = "PCIResourceConfigStarted"; 735e43914b3SAndrew Geissler } 736e43914b3SAndrew Geissler else if (dbusBootProgress == 737e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 738e43914b3SAndrew Geissler "SystemSetup") 739e43914b3SAndrew Geissler { 740e43914b3SAndrew Geissler rfBpLastState = "SetupEntered"; 741e43914b3SAndrew Geissler } 742e43914b3SAndrew Geissler else if (dbusBootProgress == 743e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 744e43914b3SAndrew Geissler "SystemInitComplete") 745e43914b3SAndrew Geissler { 746e43914b3SAndrew Geissler rfBpLastState = "SystemHardwareInitializationComplete"; 747e43914b3SAndrew Geissler } 748e43914b3SAndrew Geissler else if (dbusBootProgress == 749e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 750e43914b3SAndrew Geissler "OSStart") 751e43914b3SAndrew Geissler { 752e43914b3SAndrew Geissler rfBpLastState = "OSBootStarted"; 753e43914b3SAndrew Geissler } 754e43914b3SAndrew Geissler else if (dbusBootProgress == 755e43914b3SAndrew Geissler "xyz.openbmc_project.State.Boot.Progress.ProgressStages." 756e43914b3SAndrew Geissler "OSRunning") 757e43914b3SAndrew Geissler { 758e43914b3SAndrew Geissler rfBpLastState = "OSRunning"; 759e43914b3SAndrew Geissler } 760e43914b3SAndrew Geissler else 761e43914b3SAndrew Geissler { 76262598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress); 763e43914b3SAndrew Geissler // Just return the default 764e43914b3SAndrew Geissler } 765e43914b3SAndrew Geissler return rfBpLastState; 766e43914b3SAndrew Geissler } 767e43914b3SAndrew Geissler 768e43914b3SAndrew Geissler /** 769786d0f60SGunnar Mills * @brief Translates boot source from Redfish to the DBus boot paths. 770491d8ee7SSantosh Puranik * 771491d8ee7SSantosh Puranik * @param[in] rfSource The boot source in Redfish. 772944ffaf9SJohnathan Mantey * @param[out] bootSource The DBus source 773944ffaf9SJohnathan Mantey * @param[out] bootMode the DBus boot mode 774491d8ee7SSantosh Puranik * 775944ffaf9SJohnathan Mantey * @return Integer error code. 776491d8ee7SSantosh Puranik */ 777bd79bce8SPatrick Williams inline int assignBootParameters( 778bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 779bd79bce8SPatrick Williams const std::string& rfSource, std::string& bootSource, 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 { 835deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 836deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 8371e1e598dSJonathan Doman "xyz.openbmc_project.State.Boot.Progress", "BootProgress", 838ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 8391e1e598dSJonathan Doman const std::string& bootProgressStr) { 840978b8803SAndrew Geissler if (ec) 841978b8803SAndrew Geissler { 842978b8803SAndrew Geissler // BootProgress is an optional object so just do nothing if 843978b8803SAndrew Geissler // not found 844978b8803SAndrew Geissler return; 845978b8803SAndrew Geissler } 846978b8803SAndrew Geissler 84762598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr); 848978b8803SAndrew Geissler 849ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastState"] = 850e43914b3SAndrew Geissler dbusToRfBootProgress(bootProgressStr); 8511e1e598dSJonathan Doman }); 852978b8803SAndrew Geissler } 853491d8ee7SSantosh Puranik 854491d8ee7SSantosh Puranik /** 855b6d5d45cSHieu Huynh * @brief Retrieves boot progress Last Update of the system 856b6d5d45cSHieu Huynh * 857ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 858b6d5d45cSHieu Huynh * 859b6d5d45cSHieu Huynh * @return None. 860b6d5d45cSHieu Huynh */ 861b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime( 862ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 863b6d5d45cSHieu Huynh { 864deae6a78SEd Tanous dbus::utility::getProperty<uint64_t>( 865deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 866b6d5d45cSHieu Huynh "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate", 867ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 868b6d5d45cSHieu Huynh const uint64_t lastStateTime) { 869b6d5d45cSHieu Huynh if (ec) 870b6d5d45cSHieu Huynh { 87162598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 872b6d5d45cSHieu Huynh return; 873b6d5d45cSHieu Huynh } 874b6d5d45cSHieu Huynh 875b6d5d45cSHieu Huynh // BootProgressLastUpdate is the last time the BootProgress property 876b6d5d45cSHieu Huynh // was updated. The time is the Epoch time, number of microseconds 877b6d5d45cSHieu Huynh // since 1 Jan 1970 00::00::00 UTC." 878b6d5d45cSHieu Huynh // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/ 879b6d5d45cSHieu Huynh // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11 880b6d5d45cSHieu Huynh 881b6d5d45cSHieu Huynh // Convert to ISO 8601 standard 882ac106bf6SEd Tanous asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] = 883b6d5d45cSHieu Huynh redfish::time_utils::getDateTimeUintUs(lastStateTime); 884b6d5d45cSHieu Huynh }); 885b6d5d45cSHieu Huynh } 886b6d5d45cSHieu Huynh 887b6d5d45cSHieu Huynh /** 888c21865c4SKonstantin Aladyshev * @brief Retrieves boot override type over DBUS and fills out the response 889cd9a4666SKonstantin Aladyshev * 890ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 891cd9a4666SKonstantin Aladyshev * 892cd9a4666SKonstantin Aladyshev * @return None. 893cd9a4666SKonstantin Aladyshev */ 894cd9a4666SKonstantin Aladyshev 895504af5a0SPatrick Williams inline void getBootOverrideType( 896504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 897cd9a4666SKonstantin Aladyshev { 898deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 899deae6a78SEd Tanous "xyz.openbmc_project.Settings", 9001e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9011e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Type", "BootType", 902ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9031e1e598dSJonathan Doman const std::string& bootType) { 904cd9a4666SKonstantin Aladyshev if (ec) 905cd9a4666SKonstantin Aladyshev { 906cd9a4666SKonstantin Aladyshev // not an error, don't have to have the interface 907cd9a4666SKonstantin Aladyshev return; 908cd9a4666SKonstantin Aladyshev } 909cd9a4666SKonstantin Aladyshev 91062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", bootType); 911cd9a4666SKonstantin Aladyshev 912ac106bf6SEd Tanous asyncResp->res 913ac106bf6SEd Tanous .jsonValue["Boot"] 914002d39b4SEd Tanous ["BootSourceOverrideMode@Redfish.AllowableValues"] = 915613dabeaSEd Tanous nlohmann::json::array_t({"Legacy", "UEFI"}); 916cd9a4666SKonstantin Aladyshev 9171e1e598dSJonathan Doman auto rfType = dbusToRfBootType(bootType); 918cd9a4666SKonstantin Aladyshev if (rfType.empty()) 919cd9a4666SKonstantin Aladyshev { 920ac106bf6SEd Tanous messages::internalError(asyncResp->res); 921cd9a4666SKonstantin Aladyshev return; 922cd9a4666SKonstantin Aladyshev } 923cd9a4666SKonstantin Aladyshev 924ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; 9251e1e598dSJonathan Doman }); 926cd9a4666SKonstantin Aladyshev } 927cd9a4666SKonstantin Aladyshev 928cd9a4666SKonstantin Aladyshev /** 929c21865c4SKonstantin Aladyshev * @brief Retrieves boot override mode over DBUS and fills out the response 930491d8ee7SSantosh Puranik * 931ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 932491d8ee7SSantosh Puranik * 933491d8ee7SSantosh Puranik * @return None. 934491d8ee7SSantosh Puranik */ 935c21865c4SKonstantin Aladyshev 936504af5a0SPatrick Williams inline void getBootOverrideMode( 937504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 938491d8ee7SSantosh Puranik { 939deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 940deae6a78SEd Tanous "xyz.openbmc_project.Settings", 9411e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9421e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 943ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9441e1e598dSJonathan Doman const std::string& bootModeStr) { 945491d8ee7SSantosh Puranik if (ec) 946491d8ee7SSantosh Puranik { 947b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 948ac106bf6SEd Tanous messages::internalError(asyncResp->res); 949491d8ee7SSantosh Puranik return; 950491d8ee7SSantosh Puranik } 951491d8ee7SSantosh Puranik 95262598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr); 953491d8ee7SSantosh Puranik 95420fa6a2cSEd Tanous nlohmann::json::array_t allowed; 95520fa6a2cSEd Tanous allowed.emplace_back("None"); 95620fa6a2cSEd Tanous allowed.emplace_back("Pxe"); 95720fa6a2cSEd Tanous allowed.emplace_back("Hdd"); 95820fa6a2cSEd Tanous allowed.emplace_back("Cd"); 95920fa6a2cSEd Tanous allowed.emplace_back("Diags"); 96020fa6a2cSEd Tanous allowed.emplace_back("BiosSetup"); 96120fa6a2cSEd Tanous allowed.emplace_back("Usb"); 96220fa6a2cSEd Tanous 963ac106bf6SEd Tanous asyncResp->res 9640fda0f12SGeorge Liu .jsonValue["Boot"] 96520fa6a2cSEd Tanous ["BootSourceOverrideTarget@Redfish.AllowableValues"] = 96620fa6a2cSEd Tanous std::move(allowed); 9671e1e598dSJonathan Doman if (bootModeStr != 968491d8ee7SSantosh Puranik "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") 969491d8ee7SSantosh Puranik { 9701e1e598dSJonathan Doman auto rfMode = dbusToRfBootMode(bootModeStr); 971491d8ee7SSantosh Puranik if (!rfMode.empty()) 972491d8ee7SSantosh Puranik { 973bd79bce8SPatrick Williams asyncResp->res 974bd79bce8SPatrick Williams .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode; 975491d8ee7SSantosh Puranik } 976491d8ee7SSantosh Puranik } 9771e1e598dSJonathan Doman }); 978491d8ee7SSantosh Puranik } 979491d8ee7SSantosh Puranik 980491d8ee7SSantosh Puranik /** 981c21865c4SKonstantin Aladyshev * @brief Retrieves boot override source over DBUS 982491d8ee7SSantosh Puranik * 983ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 984491d8ee7SSantosh Puranik * 985491d8ee7SSantosh Puranik * @return None. 986491d8ee7SSantosh Puranik */ 987c21865c4SKonstantin Aladyshev 988504af5a0SPatrick Williams inline void getBootOverrideSource( 989504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 990491d8ee7SSantosh Puranik { 991deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 992deae6a78SEd Tanous "xyz.openbmc_project.Settings", 9931e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/boot", 9941e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.Source", "BootSource", 995ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 9961e1e598dSJonathan Doman const std::string& bootSourceStr) { 997491d8ee7SSantosh Puranik if (ec) 998491d8ee7SSantosh Puranik { 9998f1a35b9SAllen.Wang // Service not available, no error, just don't return 10008f1a35b9SAllen.Wang // Boot Override Source information 10018f1a35b9SAllen.Wang if (ec.value() != EBADR && 10028f1a35b9SAllen.Wang ec.value() != boost::asio::error::host_unreachable) 10035ef735c8SNan Zhou { 10048f1a35b9SAllen.Wang BMCWEB_LOG_ERROR("D-Bus response error: {}", ec); 1005ac106bf6SEd Tanous messages::internalError(asyncResp->res); 10068f1a35b9SAllen.Wang } 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" 1048deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1049deae6a78SEd Tanous "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 1081504af5a0SPatrick Williams inline void getBootOverrideEnable( 1082504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1083c21865c4SKonstantin Aladyshev { 1084deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1085deae6a78SEd Tanous "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 { 10928f1a35b9SAllen.Wang // Service not available, no error, just don't return 10938f1a35b9SAllen.Wang // Boot Override Enable information 10948f1a35b9SAllen.Wang if (ec.value() != EBADR && 10958f1a35b9SAllen.Wang ec.value() != boost::asio::error::host_unreachable) 10965ef735c8SNan Zhou { 10978f1a35b9SAllen.Wang BMCWEB_LOG_ERROR("D-Bus response error: {}", ec); 1098ac106bf6SEd Tanous messages::internalError(asyncResp->res); 10998f1a35b9SAllen.Wang } 1100c21865c4SKonstantin Aladyshev return; 1101c21865c4SKonstantin Aladyshev } 1102c21865c4SKonstantin Aladyshev 1103ac106bf6SEd Tanous processBootOverrideEnable(asyncResp, bootOverrideEnable); 11041e1e598dSJonathan Doman }); 1105c21865c4SKonstantin Aladyshev } 1106c21865c4SKonstantin Aladyshev 1107c21865c4SKonstantin Aladyshev /** 1108c21865c4SKonstantin Aladyshev * @brief Retrieves boot source override properties 1109c21865c4SKonstantin Aladyshev * 1110ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1111c21865c4SKonstantin Aladyshev * 1112c21865c4SKonstantin Aladyshev * @return None. 1113c21865c4SKonstantin Aladyshev */ 1114504af5a0SPatrick Williams inline void getBootProperties( 1115504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1116c21865c4SKonstantin Aladyshev { 111762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get boot information."); 1118c21865c4SKonstantin Aladyshev 1119ac106bf6SEd Tanous getBootOverrideSource(asyncResp); 1120ac106bf6SEd Tanous getBootOverrideType(asyncResp); 1121ac106bf6SEd Tanous getBootOverrideEnable(asyncResp); 1122c21865c4SKonstantin Aladyshev } 1123c21865c4SKonstantin Aladyshev 1124c21865c4SKonstantin Aladyshev /** 1125c0557e1aSGunnar Mills * @brief Retrieves the Last Reset Time 1126c0557e1aSGunnar Mills * 1127c0557e1aSGunnar Mills * "Reset" is an overloaded term in Redfish, "Reset" includes power on 1128c0557e1aSGunnar Mills * and power off. Even though this is the "system" Redfish object look at the 1129c0557e1aSGunnar Mills * chassis D-Bus interface for the LastStateChangeTime since this has the 1130c0557e1aSGunnar Mills * last power operation time. 1131c0557e1aSGunnar Mills * 1132ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1133c0557e1aSGunnar Mills * 1134c0557e1aSGunnar Mills * @return None. 1135c0557e1aSGunnar Mills */ 1136504af5a0SPatrick Williams inline void getLastResetTime( 1137504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1138c0557e1aSGunnar Mills { 113962598e31SEd Tanous BMCWEB_LOG_DEBUG("Getting System Last Reset Time"); 1140c0557e1aSGunnar Mills 1141deae6a78SEd Tanous dbus::utility::getProperty<uint64_t>( 1142deae6a78SEd Tanous "xyz.openbmc_project.State.Chassis", 11431e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 11441e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "LastStateChangeTime", 1145ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1146ac106bf6SEd Tanous uint64_t lastResetTime) { 1147c0557e1aSGunnar Mills if (ec) 1148c0557e1aSGunnar Mills { 114962598e31SEd Tanous BMCWEB_LOG_DEBUG("D-BUS response error {}", ec); 1150c0557e1aSGunnar Mills return; 1151c0557e1aSGunnar Mills } 1152c0557e1aSGunnar Mills 1153c0557e1aSGunnar Mills // LastStateChangeTime is epoch time, in milliseconds 1154c0557e1aSGunnar Mills // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19 11551e1e598dSJonathan Doman uint64_t lastResetTimeStamp = lastResetTime / 1000; 1156c0557e1aSGunnar Mills 1157c0557e1aSGunnar Mills // Convert to ISO 8601 standard 1158ac106bf6SEd Tanous asyncResp->res.jsonValue["LastResetTime"] = 11592b82937eSEd Tanous redfish::time_utils::getDateTimeUint(lastResetTimeStamp); 11601e1e598dSJonathan Doman }); 1161c0557e1aSGunnar Mills } 1162c0557e1aSGunnar Mills 1163c0557e1aSGunnar Mills /** 1164797d5daeSCorey Hardesty * @brief Retrieves the number of automatic boot Retry attempts allowed/left. 1165797d5daeSCorey Hardesty * 1166797d5daeSCorey Hardesty * The total number of automatic reboot retries allowed "RetryAttempts" and its 1167797d5daeSCorey Hardesty * corresponding property "AttemptsLeft" that keeps track of the amount of 1168797d5daeSCorey Hardesty * automatic retry attempts left are hosted in phosphor-state-manager through 1169797d5daeSCorey Hardesty * dbus. 1170797d5daeSCorey Hardesty * 1171ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1172797d5daeSCorey Hardesty * 1173797d5daeSCorey Hardesty * @return None. 1174797d5daeSCorey Hardesty */ 1175ac106bf6SEd Tanous inline void getAutomaticRebootAttempts( 1176ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1177797d5daeSCorey Hardesty { 117862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 1179797d5daeSCorey Hardesty 1180deae6a78SEd Tanous dbus::utility::getAllProperties( 1181deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 1182797d5daeSCorey Hardesty "xyz.openbmc_project.Control.Boot.RebootAttempts", 1183ac106bf6SEd Tanous [asyncResp{asyncResp}]( 1184ac106bf6SEd Tanous const boost::system::error_code& ec, 1185797d5daeSCorey Hardesty const dbus::utility::DBusPropertiesMap& propertiesList) { 1186797d5daeSCorey Hardesty if (ec) 1187797d5daeSCorey Hardesty { 1188d39a8c28SAishwary Joshi if (ec.value() != EBADR && 1189d39a8c28SAishwary Joshi ec.value() != boost::asio::error::host_unreachable) 1190797d5daeSCorey Hardesty { 1191d39a8c28SAishwary Joshi // Service not available, no error, just don't return 1192d39a8c28SAishwary Joshi // RebootAttempts information 119362598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1194ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1195797d5daeSCorey Hardesty } 1196797d5daeSCorey Hardesty return; 1197797d5daeSCorey Hardesty } 1198797d5daeSCorey Hardesty 1199797d5daeSCorey Hardesty const uint32_t* attemptsLeft = nullptr; 1200797d5daeSCorey Hardesty const uint32_t* retryAttempts = nullptr; 1201797d5daeSCorey Hardesty 1202797d5daeSCorey Hardesty const bool success = sdbusplus::unpackPropertiesNoThrow( 1203bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), propertiesList, 1204bd79bce8SPatrick Williams "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts); 1205797d5daeSCorey Hardesty 1206797d5daeSCorey Hardesty if (!success) 1207797d5daeSCorey Hardesty { 1208ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1209797d5daeSCorey Hardesty return; 1210797d5daeSCorey Hardesty } 1211797d5daeSCorey Hardesty 1212797d5daeSCorey Hardesty if (attemptsLeft != nullptr) 1213797d5daeSCorey Hardesty { 1214ac106bf6SEd Tanous asyncResp->res 1215ac106bf6SEd Tanous .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] = 1216797d5daeSCorey Hardesty *attemptsLeft; 1217797d5daeSCorey Hardesty } 1218797d5daeSCorey Hardesty 1219797d5daeSCorey Hardesty if (retryAttempts != nullptr) 1220797d5daeSCorey Hardesty { 1221ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 1222797d5daeSCorey Hardesty *retryAttempts; 1223797d5daeSCorey Hardesty } 1224797d5daeSCorey Hardesty }); 1225797d5daeSCorey Hardesty } 1226797d5daeSCorey Hardesty 1227797d5daeSCorey Hardesty /** 12286bd5a8d2SGunnar Mills * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot. 12296bd5a8d2SGunnar Mills * 1230ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 12316bd5a8d2SGunnar Mills * 12326bd5a8d2SGunnar Mills * @return None. 12336bd5a8d2SGunnar Mills */ 1234504af5a0SPatrick Williams inline void getAutomaticRetryPolicy( 1235504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12366bd5a8d2SGunnar Mills { 123762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Automatic Retry policy"); 12386bd5a8d2SGunnar Mills 1239deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1240deae6a78SEd Tanous "xyz.openbmc_project.Settings", 12411e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/auto_reboot", 12421e1e598dSJonathan Doman "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", 1243ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1244ac106bf6SEd Tanous bool autoRebootEnabled) { 12456bd5a8d2SGunnar Mills if (ec) 12466bd5a8d2SGunnar Mills { 1247d39a8c28SAishwary Joshi // Service not available, no error, just don't return 1248d39a8c28SAishwary Joshi // AutoReboot information 1249d39a8c28SAishwary Joshi if (ec.value() != EBADR && 1250d39a8c28SAishwary Joshi ec.value() != boost::asio::error::host_unreachable) 1251797d5daeSCorey Hardesty { 125262598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); 1253ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1254797d5daeSCorey Hardesty } 12556bd5a8d2SGunnar Mills return; 12566bd5a8d2SGunnar Mills } 12576bd5a8d2SGunnar Mills 125862598e31SEd Tanous BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled); 1259e05aec50SEd Tanous if (autoRebootEnabled) 12606bd5a8d2SGunnar Mills { 1261ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 12626bd5a8d2SGunnar Mills "RetryAttempts"; 12636bd5a8d2SGunnar Mills } 12646bd5a8d2SGunnar Mills else 12656bd5a8d2SGunnar Mills { 1266ac106bf6SEd Tanous asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = 1267ac106bf6SEd Tanous "Disabled"; 12686bd5a8d2SGunnar Mills } 1269ac106bf6SEd Tanous getAutomaticRebootAttempts(asyncResp); 127069f35306SGunnar Mills 127169f35306SGunnar Mills // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways, 127269f35306SGunnar Mills // and RetryAttempts. OpenBMC only supports Disabled and 127369f35306SGunnar Mills // RetryAttempts. 127420fa6a2cSEd Tanous nlohmann::json::array_t allowed; 127520fa6a2cSEd Tanous allowed.emplace_back("Disabled"); 127620fa6a2cSEd Tanous allowed.emplace_back("RetryAttempts"); 1277ac106bf6SEd Tanous asyncResp->res 1278bd79bce8SPatrick Williams .jsonValue["Boot"] 1279bd79bce8SPatrick Williams ["AutomaticRetryConfig@Redfish.AllowableValues"] = 128020fa6a2cSEd Tanous std::move(allowed); 12811e1e598dSJonathan Doman }); 12826bd5a8d2SGunnar Mills } 12836bd5a8d2SGunnar Mills 12846bd5a8d2SGunnar Mills /** 1285797d5daeSCorey Hardesty * @brief Sets RetryAttempts 1286797d5daeSCorey Hardesty * 1287ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1288797d5daeSCorey Hardesty * @param[in] retryAttempts "AutomaticRetryAttempts" from request. 1289797d5daeSCorey Hardesty * 1290797d5daeSCorey Hardesty *@return None. 1291797d5daeSCorey Hardesty */ 1292797d5daeSCorey Hardesty 1293ac106bf6SEd Tanous inline void setAutomaticRetryAttempts( 1294ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1295797d5daeSCorey Hardesty const uint32_t retryAttempts) 1296797d5daeSCorey Hardesty { 129762598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts."); 129887c44966SAsmitha Karunanithi setDbusProperty( 1299e93abac6SGinu George asyncResp, "Boot/AutomaticRetryAttempts", 1300e93abac6SGinu George "xyz.openbmc_project.State.Host", 130187c44966SAsmitha Karunanithi sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"), 13029ae226faSGeorge Liu "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts", 1303e93abac6SGinu George retryAttempts); 1304797d5daeSCorey Hardesty } 1305797d5daeSCorey Hardesty 13068d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes 13078d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(std::string_view value) 13088d69c668SEd Tanous { 13098d69c668SEd Tanous if (value == 13108d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn") 13118d69c668SEd Tanous { 13128d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOn; 13138d69c668SEd Tanous } 13148d69c668SEd Tanous if (value == 13158d69c668SEd Tanous "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff") 13168d69c668SEd Tanous { 13178d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13188d69c668SEd Tanous } 13198d69c668SEd Tanous if (value == 13203a34b742SGunnar Mills "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore") 13218d69c668SEd Tanous { 13228d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::LastState; 13238d69c668SEd Tanous } 13248d69c668SEd Tanous if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None") 13258d69c668SEd Tanous { 13268d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::AlwaysOff; 13278d69c668SEd Tanous } 13288d69c668SEd Tanous return computer_system::PowerRestorePolicyTypes::Invalid; 13298d69c668SEd Tanous } 1330797d5daeSCorey Hardesty /** 1331c6a620f2SGeorge Liu * @brief Retrieves power restore policy over DBUS. 1332c6a620f2SGeorge Liu * 1333ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1334c6a620f2SGeorge Liu * 1335c6a620f2SGeorge Liu * @return None. 1336c6a620f2SGeorge Liu */ 1337504af5a0SPatrick Williams inline void getPowerRestorePolicy( 1338504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1339c6a620f2SGeorge Liu { 134062598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power restore policy"); 1341c6a620f2SGeorge Liu 1342deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 1343deae6a78SEd Tanous "xyz.openbmc_project.Settings", 13441e1e598dSJonathan Doman "/xyz/openbmc_project/control/host0/power_restore_policy", 13451e1e598dSJonathan Doman "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1346ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 13475e7e2dc5SEd Tanous const std::string& policy) { 1348c6a620f2SGeorge Liu if (ec) 1349c6a620f2SGeorge Liu { 135062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1351c6a620f2SGeorge Liu return; 1352c6a620f2SGeorge Liu } 13538d69c668SEd Tanous computer_system::PowerRestorePolicyTypes restore = 13548d69c668SEd Tanous redfishPowerRestorePolicyFromDbus(policy); 13558d69c668SEd Tanous if (restore == computer_system::PowerRestorePolicyTypes::Invalid) 1356c6a620f2SGeorge Liu { 1357ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1358c6a620f2SGeorge Liu return; 1359c6a620f2SGeorge Liu } 1360c6a620f2SGeorge Liu 13618d69c668SEd Tanous asyncResp->res.jsonValue["PowerRestorePolicy"] = restore; 13621e1e598dSJonathan Doman }); 1363c6a620f2SGeorge Liu } 1364c6a620f2SGeorge Liu 1365c6a620f2SGeorge Liu /** 13669dcfe8c1SAlbert Zhang * @brief Stop Boot On Fault over DBUS. 13679dcfe8c1SAlbert Zhang * 13689dcfe8c1SAlbert Zhang * @param[in] asyncResp Shared pointer for generating response message. 13699dcfe8c1SAlbert Zhang * 13709dcfe8c1SAlbert Zhang * @return None. 13719dcfe8c1SAlbert Zhang */ 1372504af5a0SPatrick Williams inline void getStopBootOnFault( 1373504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 13749dcfe8c1SAlbert Zhang { 137562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Stop Boot On Fault"); 13769dcfe8c1SAlbert Zhang 1377deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1378deae6a78SEd Tanous "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings", 13799dcfe8c1SAlbert Zhang "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 13809dcfe8c1SAlbert Zhang [asyncResp](const boost::system::error_code& ec, bool value) { 13819dcfe8c1SAlbert Zhang if (ec) 13829dcfe8c1SAlbert Zhang { 1383d39a8c28SAishwary Joshi // Service not available, no error, just don't return 1384d39a8c28SAishwary Joshi // StopBootOnFault information 1385d39a8c28SAishwary Joshi if (ec.value() != EBADR || 1386d39a8c28SAishwary Joshi ec.value() != boost::asio::error::host_unreachable) 13879dcfe8c1SAlbert Zhang { 1388b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 13899dcfe8c1SAlbert Zhang messages::internalError(asyncResp->res); 13909dcfe8c1SAlbert Zhang } 13919dcfe8c1SAlbert Zhang return; 13929dcfe8c1SAlbert Zhang } 13939dcfe8c1SAlbert Zhang 13949dcfe8c1SAlbert Zhang if (value) 13959dcfe8c1SAlbert Zhang { 1396539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1397539d8c6bSEd Tanous computer_system::StopBootOnFault::AnyFault; 13989dcfe8c1SAlbert Zhang } 13999dcfe8c1SAlbert Zhang else 14009dcfe8c1SAlbert Zhang { 1401539d8c6bSEd Tanous asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = 1402539d8c6bSEd Tanous computer_system::StopBootOnFault::Never; 14039dcfe8c1SAlbert Zhang } 14049dcfe8c1SAlbert Zhang }); 14059dcfe8c1SAlbert Zhang } 14069dcfe8c1SAlbert Zhang 14079dcfe8c1SAlbert Zhang /** 14081981771bSAli Ahmed * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not 14091981771bSAli Ahmed * TPM is required for booting the host. 14101981771bSAli Ahmed * 1411ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14121981771bSAli Ahmed * 14131981771bSAli Ahmed * @return None. 14141981771bSAli Ahmed */ 14151981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot( 1416ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14171981771bSAli Ahmed { 141862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get TPM required to boot."); 1419e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1420e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1421e99073f5SGeorge Liu dbus::utility::getSubTree( 1422e99073f5SGeorge Liu "/", 0, interfaces, 1423ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1424b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 14251981771bSAli Ahmed if (ec) 14261981771bSAli Ahmed { 1427bd79bce8SPatrick Williams BMCWEB_LOG_DEBUG( 1428bd79bce8SPatrick Williams "DBUS response error on TPM.Policy GetSubTree{}", ec); 14291981771bSAli Ahmed // This is an optional D-Bus object so just return if 14301981771bSAli Ahmed // error occurs 14311981771bSAli Ahmed return; 14321981771bSAli Ahmed } 143326f6976fSEd Tanous if (subtree.empty()) 14341981771bSAli Ahmed { 14351981771bSAli Ahmed // As noted above, this is an optional interface so just return 14361981771bSAli Ahmed // if there is no instance found 14371981771bSAli Ahmed return; 14381981771bSAli Ahmed } 14391981771bSAli Ahmed 14401981771bSAli Ahmed /* When there is more than one TPMEnable object... */ 14411981771bSAli Ahmed if (subtree.size() > 1) 14421981771bSAli Ahmed { 144362598e31SEd Tanous BMCWEB_LOG_DEBUG( 144462598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 144562598e31SEd Tanous subtree.size()); 14461981771bSAli Ahmed // Throw an internal Error and return 1447ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14481981771bSAli Ahmed return; 14491981771bSAli Ahmed } 14501981771bSAli Ahmed 14511981771bSAli Ahmed // Make sure the Dbus response map has a service and objectPath 14521981771bSAli Ahmed // field 14531981771bSAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 14541981771bSAli Ahmed { 145562598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1456ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14571981771bSAli Ahmed return; 14581981771bSAli Ahmed } 14591981771bSAli Ahmed 14601981771bSAli Ahmed const std::string& path = subtree[0].first; 14611981771bSAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 14621981771bSAli Ahmed 14631981771bSAli Ahmed // Valid TPM Enable object found, now reading the current value 1464deae6a78SEd Tanous dbus::utility::getProperty<bool>( 1465deae6a78SEd Tanous serv, path, "xyz.openbmc_project.Control.TPM.Policy", 1466deae6a78SEd Tanous "TPMEnable", 1467ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec2, 1468ac106bf6SEd Tanous bool tpmRequired) { 14698a592810SEd Tanous if (ec2) 14701981771bSAli Ahmed { 1471bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 1472bd79bce8SPatrick Williams "D-BUS response error on TPM.Policy Get{}", ec2); 1473ac106bf6SEd Tanous messages::internalError(asyncResp->res); 14741981771bSAli Ahmed return; 14751981771bSAli Ahmed } 14761981771bSAli Ahmed 14771e1e598dSJonathan Doman if (tpmRequired) 14781981771bSAli Ahmed { 1479ac106bf6SEd Tanous asyncResp->res 1480ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14811981771bSAli Ahmed "Required"; 14821981771bSAli Ahmed } 14831981771bSAli Ahmed else 14841981771bSAli Ahmed { 1485ac106bf6SEd Tanous asyncResp->res 1486ac106bf6SEd Tanous .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] = 14871981771bSAli Ahmed "Disabled"; 14881981771bSAli Ahmed } 14891e1e598dSJonathan Doman }); 1490e99073f5SGeorge Liu }); 14911981771bSAli Ahmed } 14921981771bSAli Ahmed 14931981771bSAli Ahmed /** 14941c05dae3SAli Ahmed * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not 14951c05dae3SAli Ahmed * TPM is required for booting the host. 14961c05dae3SAli Ahmed * 1497ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 14981c05dae3SAli Ahmed * @param[in] tpmRequired Value to set TPM Required To Boot property to. 14991c05dae3SAli Ahmed * 15001c05dae3SAli Ahmed * @return None. 15011c05dae3SAli Ahmed */ 15021c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot( 1503ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired) 15041c05dae3SAli Ahmed { 150562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot."); 1506e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1507e99073f5SGeorge Liu "xyz.openbmc_project.Control.TPM.Policy"}; 1508e99073f5SGeorge Liu dbus::utility::getSubTree( 1509e99073f5SGeorge Liu "/", 0, interfaces, 1510ac106bf6SEd Tanous [asyncResp, 1511e99073f5SGeorge Liu tpmRequired](const boost::system::error_code& ec, 1512e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 15131c05dae3SAli Ahmed if (ec) 15141c05dae3SAli Ahmed { 1515bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 1516bd79bce8SPatrick Williams "DBUS response error on TPM.Policy GetSubTree{}", ec); 1517ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15181c05dae3SAli Ahmed return; 15191c05dae3SAli Ahmed } 152026f6976fSEd Tanous if (subtree.empty()) 15211c05dae3SAli Ahmed { 1522bd79bce8SPatrick Williams messages::propertyValueNotInList(asyncResp->res, 1523bd79bce8SPatrick Williams "ComputerSystem", 15241c05dae3SAli Ahmed "TrustedModuleRequiredToBoot"); 15251c05dae3SAli Ahmed return; 15261c05dae3SAli Ahmed } 15271c05dae3SAli Ahmed 15281c05dae3SAli Ahmed /* When there is more than one TPMEnable object... */ 15291c05dae3SAli Ahmed if (subtree.size() > 1) 15301c05dae3SAli Ahmed { 153162598e31SEd Tanous BMCWEB_LOG_DEBUG( 153262598e31SEd Tanous "DBUS response has more than 1 TPM Enable object:{}", 153362598e31SEd Tanous subtree.size()); 15341c05dae3SAli Ahmed // Throw an internal Error and return 1535ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15361c05dae3SAli Ahmed return; 15371c05dae3SAli Ahmed } 15381c05dae3SAli Ahmed 15391c05dae3SAli Ahmed // Make sure the Dbus response map has a service and objectPath 15401c05dae3SAli Ahmed // field 15411c05dae3SAli Ahmed if (subtree[0].first.empty() || subtree[0].second.size() != 1) 15421c05dae3SAli Ahmed { 154362598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy mapper error!"); 1544ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15451c05dae3SAli Ahmed return; 15461c05dae3SAli Ahmed } 15471c05dae3SAli Ahmed 15481c05dae3SAli Ahmed const std::string& path = subtree[0].first; 15491c05dae3SAli Ahmed const std::string& serv = subtree[0].second.begin()->first; 15501c05dae3SAli Ahmed 15511c05dae3SAli Ahmed if (serv.empty()) 15521c05dae3SAli Ahmed { 155362598e31SEd Tanous BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!"); 1554ac106bf6SEd Tanous messages::internalError(asyncResp->res); 15551c05dae3SAli Ahmed return; 15561c05dae3SAli Ahmed } 15571c05dae3SAli Ahmed 15581c05dae3SAli Ahmed // Valid TPM Enable object found, now setting the value 1559e93abac6SGinu George setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv, 1560e93abac6SGinu George path, "xyz.openbmc_project.Control.TPM.Policy", 1561e93abac6SGinu George "TPMEnable", tpmRequired); 1562e99073f5SGeorge Liu }); 15631c05dae3SAli Ahmed } 15641c05dae3SAli Ahmed 15651c05dae3SAli Ahmed /** 1566491d8ee7SSantosh Puranik * @brief Sets boot properties into DBUS object(s). 1567491d8ee7SSantosh Puranik * 1568ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1569cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1570cd9a4666SKonstantin Aladyshev * @return Integer error code. 1571cd9a4666SKonstantin Aladyshev */ 1572ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1573cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootType) 1574cd9a4666SKonstantin Aladyshev { 1575c21865c4SKonstantin Aladyshev std::string bootTypeStr; 1576cd9a4666SKonstantin Aladyshev 1577c21865c4SKonstantin Aladyshev if (!bootType) 1578cd9a4666SKonstantin Aladyshev { 1579c21865c4SKonstantin Aladyshev return; 1580c21865c4SKonstantin Aladyshev } 1581c21865c4SKonstantin Aladyshev 1582cd9a4666SKonstantin Aladyshev // Source target specified 158362598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot type: {}", *bootType); 1584cd9a4666SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1585cd9a4666SKonstantin Aladyshev if (*bootType == "Legacy") 1586cd9a4666SKonstantin Aladyshev { 1587cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; 1588cd9a4666SKonstantin Aladyshev } 1589cd9a4666SKonstantin Aladyshev else if (*bootType == "UEFI") 1590cd9a4666SKonstantin Aladyshev { 1591cd9a4666SKonstantin Aladyshev bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; 1592cd9a4666SKonstantin Aladyshev } 1593cd9a4666SKonstantin Aladyshev else 1594cd9a4666SKonstantin Aladyshev { 159562598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for " 159662598e31SEd Tanous "BootSourceOverrideMode: {}", 159762598e31SEd Tanous *bootType); 1598ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootType, 1599cd9a4666SKonstantin Aladyshev "BootSourceOverrideMode"); 1600cd9a4666SKonstantin Aladyshev return; 1601cd9a4666SKonstantin Aladyshev } 1602cd9a4666SKonstantin Aladyshev 1603cd9a4666SKonstantin Aladyshev // Act on validated parameters 160462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr); 1605cd9a4666SKonstantin Aladyshev 1606e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode", 1607e93abac6SGinu George "xyz.openbmc_project.Settings", 160887c44966SAsmitha Karunanithi sdbusplus::message::object_path( 160987c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 161087c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Type", "BootType", 1611e93abac6SGinu George bootTypeStr); 1612cd9a4666SKonstantin Aladyshev } 1613cd9a4666SKonstantin Aladyshev 1614cd9a4666SKonstantin Aladyshev /** 1615cd9a4666SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1616cd9a4666SKonstantin Aladyshev * 1617ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response 1618ac106bf6SEd Tanous * message. 1619c21865c4SKonstantin Aladyshev * @param[in] bootType The boot type to set. 1620c21865c4SKonstantin Aladyshev * @return Integer error code. 1621c21865c4SKonstantin Aladyshev */ 1622ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1623c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1624c21865c4SKonstantin Aladyshev { 1625c21865c4SKonstantin Aladyshev if (!bootEnable) 1626c21865c4SKonstantin Aladyshev { 1627c21865c4SKonstantin Aladyshev return; 1628c21865c4SKonstantin Aladyshev } 1629c21865c4SKonstantin Aladyshev // Source target specified 163062598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable); 1631c21865c4SKonstantin Aladyshev 1632c21865c4SKonstantin Aladyshev bool bootOverrideEnable = false; 1633c21865c4SKonstantin Aladyshev bool bootOverridePersistent = false; 1634c21865c4SKonstantin Aladyshev // Figure out which DBUS interface and property to use 1635c21865c4SKonstantin Aladyshev if (*bootEnable == "Disabled") 1636c21865c4SKonstantin Aladyshev { 1637c21865c4SKonstantin Aladyshev bootOverrideEnable = false; 1638c21865c4SKonstantin Aladyshev } 1639c21865c4SKonstantin Aladyshev else if (*bootEnable == "Once") 1640c21865c4SKonstantin Aladyshev { 1641c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1642c21865c4SKonstantin Aladyshev bootOverridePersistent = false; 1643c21865c4SKonstantin Aladyshev } 1644c21865c4SKonstantin Aladyshev else if (*bootEnable == "Continuous") 1645c21865c4SKonstantin Aladyshev { 1646c21865c4SKonstantin Aladyshev bootOverrideEnable = true; 1647c21865c4SKonstantin Aladyshev bootOverridePersistent = true; 1648c21865c4SKonstantin Aladyshev } 1649c21865c4SKonstantin Aladyshev else 1650c21865c4SKonstantin Aladyshev { 165162598e31SEd Tanous BMCWEB_LOG_DEBUG( 165262598e31SEd Tanous "Invalid property value for BootSourceOverrideEnabled: {}", 165362598e31SEd Tanous *bootEnable); 1654ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootEnable, 1655c21865c4SKonstantin Aladyshev "BootSourceOverrideEnabled"); 1656c21865c4SKonstantin Aladyshev return; 1657c21865c4SKonstantin Aladyshev } 1658c21865c4SKonstantin Aladyshev 1659c21865c4SKonstantin Aladyshev // Act on validated parameters 166062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable); 1661c21865c4SKonstantin Aladyshev 1662e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1663e93abac6SGinu George "xyz.openbmc_project.Settings", 166487c44966SAsmitha Karunanithi sdbusplus::message::object_path( 166587c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 166687c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1667e93abac6SGinu George bootOverrideEnable); 1668c21865c4SKonstantin Aladyshev 1669c21865c4SKonstantin Aladyshev if (!bootOverrideEnable) 1670c21865c4SKonstantin Aladyshev { 1671c21865c4SKonstantin Aladyshev return; 1672c21865c4SKonstantin Aladyshev } 1673c21865c4SKonstantin Aladyshev 1674c21865c4SKonstantin Aladyshev // In case boot override is enabled we need to set correct value for the 1675c21865c4SKonstantin Aladyshev // 'one_time' enable DBus interface 167662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}", 167762598e31SEd Tanous bootOverridePersistent); 1678c21865c4SKonstantin Aladyshev 1679e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled", 1680e93abac6SGinu George "xyz.openbmc_project.Settings", 168187c44966SAsmitha Karunanithi sdbusplus::message::object_path( 168287c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot/one_time"), 168387c44966SAsmitha Karunanithi "xyz.openbmc_project.Object.Enable", "Enabled", 1684e93abac6SGinu George !bootOverridePersistent); 1685c21865c4SKonstantin Aladyshev } 1686c21865c4SKonstantin Aladyshev 1687c21865c4SKonstantin Aladyshev /** 1688c21865c4SKonstantin Aladyshev * @brief Sets boot properties into DBUS object(s). 1689c21865c4SKonstantin Aladyshev * 1690ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1691491d8ee7SSantosh Puranik * @param[in] bootSource The boot source to set. 1692491d8ee7SSantosh Puranik * 1693265c1602SJohnathan Mantey * @return Integer error code. 1694491d8ee7SSantosh Puranik */ 1695504af5a0SPatrick Williams inline void setBootModeOrSource( 1696504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1697cd9a4666SKonstantin Aladyshev const std::optional<std::string>& bootSource) 1698491d8ee7SSantosh Puranik { 1699c21865c4SKonstantin Aladyshev std::string bootSourceStr; 1700c21865c4SKonstantin Aladyshev std::string bootModeStr; 1701944ffaf9SJohnathan Mantey 1702c21865c4SKonstantin Aladyshev if (!bootSource) 1703491d8ee7SSantosh Puranik { 1704c21865c4SKonstantin Aladyshev return; 1705c21865c4SKonstantin Aladyshev } 1706c21865c4SKonstantin Aladyshev 1707491d8ee7SSantosh Puranik // Source target specified 170862598e31SEd Tanous BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource); 1709491d8ee7SSantosh Puranik // Figure out which DBUS interface and property to use 1710ac106bf6SEd Tanous if (assignBootParameters(asyncResp, *bootSource, bootSourceStr, 1711ac106bf6SEd Tanous bootModeStr) != 0) 1712491d8ee7SSantosh Puranik { 171362598e31SEd Tanous BMCWEB_LOG_DEBUG( 171462598e31SEd Tanous "Invalid property value for BootSourceOverrideTarget: {}", 171562598e31SEd Tanous *bootSource); 1716ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *bootSource, 1717491d8ee7SSantosh Puranik "BootSourceTargetOverride"); 1718491d8ee7SSantosh Puranik return; 1719491d8ee7SSantosh Puranik } 1720491d8ee7SSantosh Puranik 1721944ffaf9SJohnathan Mantey // Act on validated parameters 172262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr); 172362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr); 1724944ffaf9SJohnathan Mantey 1725e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1726e93abac6SGinu George "xyz.openbmc_project.Settings", 172787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 172887c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 172987c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Source", "BootSource", 1730e93abac6SGinu George bootSourceStr); 1731e93abac6SGinu George setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget", 1732e93abac6SGinu George "xyz.openbmc_project.Settings", 173387c44966SAsmitha Karunanithi sdbusplus::message::object_path( 173487c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/boot"), 173587c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.Mode", "BootMode", 1736e93abac6SGinu George bootModeStr); 1737cd9a4666SKonstantin Aladyshev } 1738944ffaf9SJohnathan Mantey 1739cd9a4666SKonstantin Aladyshev /** 1740c21865c4SKonstantin Aladyshev * @brief Sets Boot source override properties. 1741491d8ee7SSantosh Puranik * 1742ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1743491d8ee7SSantosh Puranik * @param[in] bootSource The boot source from incoming RF request. 1744cd9a4666SKonstantin Aladyshev * @param[in] bootType The boot type from incoming RF request. 1745491d8ee7SSantosh Puranik * @param[in] bootEnable The boot override enable from incoming RF request. 1746491d8ee7SSantosh Puranik * 1747265c1602SJohnathan Mantey * @return Integer error code. 1748491d8ee7SSantosh Puranik */ 1749c21865c4SKonstantin Aladyshev 1750504af5a0SPatrick Williams inline void setBootProperties( 1751504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1752c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootSource, 1753c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootType, 1754c21865c4SKonstantin Aladyshev const std::optional<std::string>& bootEnable) 1755491d8ee7SSantosh Puranik { 175662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set boot information."); 1757491d8ee7SSantosh Puranik 1758ac106bf6SEd Tanous setBootModeOrSource(asyncResp, bootSource); 1759ac106bf6SEd Tanous setBootType(asyncResp, bootType); 1760ac106bf6SEd Tanous setBootEnable(asyncResp, bootEnable); 1761491d8ee7SSantosh Puranik } 1762491d8ee7SSantosh Puranik 1763c6a620f2SGeorge Liu /** 176498e386ecSGunnar Mills * @brief Sets AssetTag 176598e386ecSGunnar Mills * 1766ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 176798e386ecSGunnar Mills * @param[in] assetTag "AssetTag" from request. 176898e386ecSGunnar Mills * 176998e386ecSGunnar Mills * @return None. 177098e386ecSGunnar Mills */ 1771ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 177298e386ecSGunnar Mills const std::string& assetTag) 177398e386ecSGunnar Mills { 1774e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1775e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.System"}; 1776e99073f5SGeorge Liu dbus::utility::getSubTree( 1777e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1778ac106bf6SEd Tanous [asyncResp, 1779e99073f5SGeorge Liu assetTag](const boost::system::error_code& ec, 1780b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 178198e386ecSGunnar Mills if (ec) 178298e386ecSGunnar Mills { 178362598e31SEd Tanous BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec); 1784ac106bf6SEd Tanous messages::internalError(asyncResp->res); 178598e386ecSGunnar Mills return; 178698e386ecSGunnar Mills } 178726f6976fSEd Tanous if (subtree.empty()) 178898e386ecSGunnar Mills { 178962598e31SEd Tanous BMCWEB_LOG_DEBUG("Can't find system D-Bus object!"); 1790ac106bf6SEd Tanous messages::internalError(asyncResp->res); 179198e386ecSGunnar Mills return; 179298e386ecSGunnar Mills } 179398e386ecSGunnar Mills // Assume only 1 system D-Bus object 179498e386ecSGunnar Mills // Throw an error if there is more than 1 179598e386ecSGunnar Mills if (subtree.size() > 1) 179698e386ecSGunnar Mills { 179762598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!"); 1798ac106bf6SEd Tanous messages::internalError(asyncResp->res); 179998e386ecSGunnar Mills return; 180098e386ecSGunnar Mills } 180198e386ecSGunnar Mills if (subtree[0].first.empty() || subtree[0].second.size() != 1) 180298e386ecSGunnar Mills { 180362598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!"); 1804ac106bf6SEd Tanous messages::internalError(asyncResp->res); 180598e386ecSGunnar Mills return; 180698e386ecSGunnar Mills } 180798e386ecSGunnar Mills 180898e386ecSGunnar Mills const std::string& path = subtree[0].first; 180998e386ecSGunnar Mills const std::string& service = subtree[0].second.begin()->first; 181098e386ecSGunnar Mills 181198e386ecSGunnar Mills if (service.empty()) 181298e386ecSGunnar Mills { 181362598e31SEd Tanous BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!"); 1814ac106bf6SEd Tanous messages::internalError(asyncResp->res); 181598e386ecSGunnar Mills return; 181698e386ecSGunnar Mills } 181798e386ecSGunnar Mills 1818e93abac6SGinu George setDbusProperty(asyncResp, "AssetTag", service, path, 181987c44966SAsmitha Karunanithi "xyz.openbmc_project.Inventory.Decorator.AssetTag", 1820e93abac6SGinu George "AssetTag", assetTag); 1821e99073f5SGeorge Liu }); 182298e386ecSGunnar Mills } 182398e386ecSGunnar Mills 182498e386ecSGunnar Mills /** 18259dcfe8c1SAlbert Zhang * @brief Validate the specified stopBootOnFault is valid and return the 18269dcfe8c1SAlbert Zhang * stopBootOnFault name associated with that string 18279dcfe8c1SAlbert Zhang * 18289dcfe8c1SAlbert Zhang * @param[in] stopBootOnFaultString String representing the desired 18299dcfe8c1SAlbert Zhang * stopBootOnFault 18309dcfe8c1SAlbert Zhang * 18319dcfe8c1SAlbert Zhang * @return stopBootOnFault value or empty if incoming value is not valid 18329dcfe8c1SAlbert Zhang */ 1833504af5a0SPatrick Williams inline std::optional<bool> validstopBootOnFault( 1834504af5a0SPatrick Williams const std::string& stopBootOnFaultString) 18359dcfe8c1SAlbert Zhang { 18369dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "AnyFault") 18379dcfe8c1SAlbert Zhang { 18389dcfe8c1SAlbert Zhang return true; 18399dcfe8c1SAlbert Zhang } 18409dcfe8c1SAlbert Zhang 18419dcfe8c1SAlbert Zhang if (stopBootOnFaultString == "Never") 18429dcfe8c1SAlbert Zhang { 18439dcfe8c1SAlbert Zhang return false; 18449dcfe8c1SAlbert Zhang } 18459dcfe8c1SAlbert Zhang 18469dcfe8c1SAlbert Zhang return std::nullopt; 18479dcfe8c1SAlbert Zhang } 18489dcfe8c1SAlbert Zhang 18499dcfe8c1SAlbert Zhang /** 18509dcfe8c1SAlbert Zhang * @brief Sets stopBootOnFault 18519dcfe8c1SAlbert Zhang * 1852fc3edfddSEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 18539dcfe8c1SAlbert Zhang * @param[in] stopBootOnFault "StopBootOnFault" from request. 18549dcfe8c1SAlbert Zhang * 18559dcfe8c1SAlbert Zhang * @return None. 18569dcfe8c1SAlbert Zhang */ 1857504af5a0SPatrick Williams inline void setStopBootOnFault( 1858504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 18599dcfe8c1SAlbert Zhang const std::string& stopBootOnFault) 18609dcfe8c1SAlbert Zhang { 186162598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Stop Boot On Fault."); 18629dcfe8c1SAlbert Zhang 18639dcfe8c1SAlbert Zhang std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault); 18649dcfe8c1SAlbert Zhang if (!stopBootEnabled) 18659dcfe8c1SAlbert Zhang { 186662598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}", 186762598e31SEd Tanous stopBootOnFault); 1868fc3edfddSEd Tanous messages::propertyValueNotInList(asyncResp->res, stopBootOnFault, 18699dcfe8c1SAlbert Zhang "StopBootOnFault"); 18709dcfe8c1SAlbert Zhang return; 18719dcfe8c1SAlbert Zhang } 18729dcfe8c1SAlbert Zhang 1873e93abac6SGinu George setDbusProperty(asyncResp, "Boot/StopBootOnFault", 1874e93abac6SGinu George "xyz.openbmc_project.Settings", 187587c44966SAsmitha Karunanithi sdbusplus::message::object_path( 187687c44966SAsmitha Karunanithi "/xyz/openbmc_project/logging/settings"), 1877fc3edfddSEd Tanous "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError", 1878e93abac6SGinu George *stopBootEnabled); 18799dcfe8c1SAlbert Zhang } 18809dcfe8c1SAlbert Zhang 18819dcfe8c1SAlbert Zhang /** 188269f35306SGunnar Mills * @brief Sets automaticRetry (Auto Reboot) 188369f35306SGunnar Mills * 1884ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 188569f35306SGunnar Mills * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request. 188669f35306SGunnar Mills * 188769f35306SGunnar Mills * @return None. 188869f35306SGunnar Mills */ 1889504af5a0SPatrick Williams inline void setAutomaticRetry( 1890504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1891f23b7296SEd Tanous const std::string& automaticRetryConfig) 189269f35306SGunnar Mills { 189362598e31SEd Tanous BMCWEB_LOG_DEBUG("Set Automatic Retry."); 189469f35306SGunnar Mills 189569f35306SGunnar Mills // OpenBMC only supports "Disabled" and "RetryAttempts". 1896543f4400SEd Tanous bool autoRebootEnabled = false; 189769f35306SGunnar Mills 189869f35306SGunnar Mills if (automaticRetryConfig == "Disabled") 189969f35306SGunnar Mills { 190069f35306SGunnar Mills autoRebootEnabled = false; 190169f35306SGunnar Mills } 190269f35306SGunnar Mills else if (automaticRetryConfig == "RetryAttempts") 190369f35306SGunnar Mills { 190469f35306SGunnar Mills autoRebootEnabled = true; 190569f35306SGunnar Mills } 190669f35306SGunnar Mills else 190769f35306SGunnar Mills { 190862598e31SEd Tanous BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}", 190962598e31SEd Tanous automaticRetryConfig); 1910ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig, 191169f35306SGunnar Mills "AutomaticRetryConfig"); 191269f35306SGunnar Mills return; 191369f35306SGunnar Mills } 191469f35306SGunnar Mills 1915e93abac6SGinu George setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig", 1916e93abac6SGinu George "xyz.openbmc_project.Settings", 191787c44966SAsmitha Karunanithi sdbusplus::message::object_path( 191887c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/auto_reboot"), 191987c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Boot.RebootPolicy", 1920e93abac6SGinu George "AutoReboot", autoRebootEnabled); 192169f35306SGunnar Mills } 192269f35306SGunnar Mills 19238d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy) 19248d69c668SEd Tanous { 19258d69c668SEd Tanous if (policy == "AlwaysOn") 19268d69c668SEd Tanous { 19278d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"; 19288d69c668SEd Tanous } 19298d69c668SEd Tanous if (policy == "AlwaysOff") 19308d69c668SEd Tanous { 19318d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"; 19328d69c668SEd Tanous } 19338d69c668SEd Tanous if (policy == "LastState") 19348d69c668SEd Tanous { 19358d69c668SEd Tanous return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"; 19368d69c668SEd Tanous } 19378d69c668SEd Tanous return ""; 19388d69c668SEd Tanous } 19398d69c668SEd Tanous 194069f35306SGunnar Mills /** 1941c6a620f2SGeorge Liu * @brief Sets power restore policy properties. 1942c6a620f2SGeorge Liu * 1943ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 1944c6a620f2SGeorge Liu * @param[in] policy power restore policy properties from request. 1945c6a620f2SGeorge Liu * 1946c6a620f2SGeorge Liu * @return None. 1947c6a620f2SGeorge Liu */ 1948504af5a0SPatrick Williams inline void setPowerRestorePolicy( 1949504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 19508d69c668SEd Tanous std::string_view policy) 1951c6a620f2SGeorge Liu { 195262598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power restore policy."); 1953c6a620f2SGeorge Liu 19548d69c668SEd Tanous std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy); 1955c6a620f2SGeorge Liu 19568d69c668SEd Tanous if (powerRestorePolicy.empty()) 1957c6a620f2SGeorge Liu { 1958ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, policy, 19594e69c904SGunnar Mills "PowerRestorePolicy"); 1960c6a620f2SGeorge Liu return; 1961c6a620f2SGeorge Liu } 1962c6a620f2SGeorge Liu 196387c44966SAsmitha Karunanithi setDbusProperty( 1964e93abac6SGinu George asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings", 196587c44966SAsmitha Karunanithi sdbusplus::message::object_path( 196687c44966SAsmitha Karunanithi "/xyz/openbmc_project/control/host0/power_restore_policy"), 19679ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy", 1968e93abac6SGinu George powerRestorePolicy); 1969c6a620f2SGeorge Liu } 1970c6a620f2SGeorge Liu 1971a6349918SAppaRao Puli /** 1972a6349918SAppaRao Puli * @brief Retrieves provisioning status 1973a6349918SAppaRao Puli * 197425b54dbaSEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous 197525b54dbaSEd Tanous * calls. 1976a6349918SAppaRao Puli * 1977a6349918SAppaRao Puli * @return None. 1978a6349918SAppaRao Puli */ 1979504af5a0SPatrick Williams inline void getProvisioningStatus( 1980504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1981a6349918SAppaRao Puli { 198262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get OEM information."); 1983deae6a78SEd Tanous dbus::utility::getAllProperties( 1984deae6a78SEd Tanous "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr", 1985deae6a78SEd Tanous "xyz.openbmc_project.PFR.Attributes", 1986ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 1987b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& propertiesList) { 1988b99fb1a9SAppaRao Puli nlohmann::json& oemPFR = 1989bd79bce8SPatrick Williams asyncResp->res 1990bd79bce8SPatrick Williams .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"]; 1991ac106bf6SEd Tanous asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = 19921d834d49SEd Tanous "#OpenBMCComputerSystem.v1_0_0.OpenBmc"; 1993bd79bce8SPatrick Williams oemPFR["@odata.type"] = 1994bd79bce8SPatrick Williams "#OpenBMCComputerSystem.FirmwareProvisioning"; 199550626f4fSJames Feist 1996a6349918SAppaRao Puli if (ec) 1997a6349918SAppaRao Puli { 199862598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 1999b99fb1a9SAppaRao Puli // not an error, don't have to have the interface 2000539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2001539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 2002a6349918SAppaRao Puli return; 2003a6349918SAppaRao Puli } 2004a6349918SAppaRao Puli 2005a6349918SAppaRao Puli const bool* provState = nullptr; 2006a6349918SAppaRao Puli const bool* lockState = nullptr; 2007bc1d29deSKrzysztof Grobelny 2008bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2009bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), propertiesList, 2010bd79bce8SPatrick Williams "UfmProvisioned", provState, "UfmLocked", lockState); 2011bc1d29deSKrzysztof Grobelny 2012bc1d29deSKrzysztof Grobelny if (!success) 2013a6349918SAppaRao Puli { 2014ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2015bc1d29deSKrzysztof Grobelny return; 2016a6349918SAppaRao Puli } 2017a6349918SAppaRao Puli 2018a6349918SAppaRao Puli if ((provState == nullptr) || (lockState == nullptr)) 2019a6349918SAppaRao Puli { 202062598e31SEd Tanous BMCWEB_LOG_DEBUG("Unable to get PFR attributes."); 2021ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2022a6349918SAppaRao Puli return; 2023a6349918SAppaRao Puli } 2024a6349918SAppaRao Puli 202525b54dbaSEd Tanous if (*provState) 2026a6349918SAppaRao Puli { 202725b54dbaSEd Tanous if (*lockState) 2028a6349918SAppaRao Puli { 2029539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2030539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedAndLocked; 2031a6349918SAppaRao Puli } 2032a6349918SAppaRao Puli else 2033a6349918SAppaRao Puli { 2034539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2035539d8c6bSEd Tanous FirmwareProvisioningStatus::ProvisionedButNotLocked; 2036a6349918SAppaRao Puli } 2037a6349918SAppaRao Puli } 2038a6349918SAppaRao Puli else 2039a6349918SAppaRao Puli { 2040539d8c6bSEd Tanous oemPFR["ProvisioningStatus"] = open_bmc_computer_system:: 2041539d8c6bSEd Tanous FirmwareProvisioningStatus::NotProvisioned; 2042a6349918SAppaRao Puli } 2043bc1d29deSKrzysztof Grobelny }); 2044a6349918SAppaRao Puli } 2045a6349918SAppaRao Puli 2046491d8ee7SSantosh Puranik /** 20476b9ac4f2SChris Cain * @brief Translate the PowerMode string to enum value 20483a2d0424SChris Cain * 20496b9ac4f2SChris Cain * @param[in] modeString PowerMode string to be translated 20503a2d0424SChris Cain * 20516b9ac4f2SChris Cain * @return PowerMode enum 20523a2d0424SChris Cain */ 2053504af5a0SPatrick Williams inline computer_system::PowerMode translatePowerModeString( 2054504af5a0SPatrick Williams const std::string& modeString) 20553a2d0424SChris Cain { 2056b6655101SChris Cain using PowerMode = computer_system::PowerMode; 2057b6655101SChris Cain 20586b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") 20593a2d0424SChris Cain { 20606b9ac4f2SChris Cain return PowerMode::Static; 20613a2d0424SChris Cain } 20626b9ac4f2SChris Cain if (modeString == 20630fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance") 20643a2d0424SChris Cain { 20656b9ac4f2SChris Cain return PowerMode::MaximumPerformance; 20663a2d0424SChris Cain } 20676b9ac4f2SChris Cain if (modeString == 20680fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") 20693a2d0424SChris Cain { 20706b9ac4f2SChris Cain return PowerMode::PowerSaving; 2071b6655101SChris Cain } 20726b9ac4f2SChris Cain if (modeString == 2073b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance") 2074b6655101SChris Cain { 20756b9ac4f2SChris Cain return PowerMode::BalancedPerformance; 2076b6655101SChris Cain } 20776b9ac4f2SChris Cain if (modeString == 2078b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance") 2079b6655101SChris Cain { 20806b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPerformance; 2081b6655101SChris Cain } 20826b9ac4f2SChris Cain if (modeString == 2083b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower") 2084b6655101SChris Cain { 20856b9ac4f2SChris Cain return PowerMode::EfficiencyFavorPower; 20863a2d0424SChris Cain } 20876b9ac4f2SChris Cain if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") 20883a2d0424SChris Cain { 20896b9ac4f2SChris Cain return PowerMode::OEM; 20906b9ac4f2SChris Cain } 20916b9ac4f2SChris Cain // Any other values would be invalid 20926b9ac4f2SChris Cain BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString); 20936b9ac4f2SChris Cain return PowerMode::Invalid; 20946b9ac4f2SChris Cain } 20956b9ac4f2SChris Cain 2096504af5a0SPatrick Williams inline void afterGetPowerMode( 2097504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 20986b9ac4f2SChris Cain const boost::system::error_code& ec, 20996b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) 21006b9ac4f2SChris Cain { 21016b9ac4f2SChris Cain if (ec) 21026b9ac4f2SChris Cain { 21036b9ac4f2SChris Cain BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec); 21046b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21056b9ac4f2SChris Cain return; 21066b9ac4f2SChris Cain } 21076b9ac4f2SChris Cain 21086b9ac4f2SChris Cain std::string powerMode; 21096b9ac4f2SChris Cain const std::vector<std::string>* allowedModes = nullptr; 21106b9ac4f2SChris Cain const bool success = sdbusplus::unpackPropertiesNoThrow( 21116b9ac4f2SChris Cain dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode, 21126b9ac4f2SChris Cain "AllowedPowerModes", allowedModes); 21136b9ac4f2SChris Cain 21146b9ac4f2SChris Cain if (!success) 21156b9ac4f2SChris Cain { 21166b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21176b9ac4f2SChris Cain return; 21186b9ac4f2SChris Cain } 21196b9ac4f2SChris Cain 21206b9ac4f2SChris Cain nlohmann::json::array_t modeList; 21216b9ac4f2SChris Cain if (allowedModes == nullptr) 21226b9ac4f2SChris Cain { 21236b9ac4f2SChris Cain modeList.emplace_back("Static"); 21246b9ac4f2SChris Cain modeList.emplace_back("MaximumPerformance"); 21256b9ac4f2SChris Cain modeList.emplace_back("PowerSaving"); 21263a2d0424SChris Cain } 21273a2d0424SChris Cain else 21283a2d0424SChris Cain { 21296b9ac4f2SChris Cain for (const auto& aMode : *allowedModes) 21306b9ac4f2SChris Cain { 21316b9ac4f2SChris Cain computer_system::PowerMode modeValue = 21326b9ac4f2SChris Cain translatePowerModeString(aMode); 21336b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21346b9ac4f2SChris Cain { 2135ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21366b9ac4f2SChris Cain continue; 21376b9ac4f2SChris Cain } 21386b9ac4f2SChris Cain modeList.emplace_back(modeValue); 21393a2d0424SChris Cain } 21403a2d0424SChris Cain } 21416b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList; 21423a2d0424SChris Cain 21436b9ac4f2SChris Cain BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode); 21446b9ac4f2SChris Cain const computer_system::PowerMode modeValue = 21456b9ac4f2SChris Cain translatePowerModeString(powerMode); 21466b9ac4f2SChris Cain if (modeValue == computer_system::PowerMode::Invalid) 21476b9ac4f2SChris Cain { 21486b9ac4f2SChris Cain messages::internalError(asyncResp->res); 21496b9ac4f2SChris Cain return; 21506b9ac4f2SChris Cain } 21516b9ac4f2SChris Cain asyncResp->res.jsonValue["PowerMode"] = modeValue; 21526b9ac4f2SChris Cain } 21533a2d0424SChris Cain /** 21543a2d0424SChris Cain * @brief Retrieves system power mode 21553a2d0424SChris Cain * 2156ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 21573a2d0424SChris Cain * 21583a2d0424SChris Cain * @return None. 21593a2d0424SChris Cain */ 2160ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 21613a2d0424SChris Cain { 216262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get power mode."); 21633a2d0424SChris Cain 21643a2d0424SChris Cain // Get Power Mode object path: 2165e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2166e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2167e99073f5SGeorge Liu dbus::utility::getSubTree( 2168e99073f5SGeorge Liu "/", 0, interfaces, 2169ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2170b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 21713a2d0424SChris Cain if (ec) 21723a2d0424SChris Cain { 2173bd79bce8SPatrick Williams BMCWEB_LOG_DEBUG( 2174bd79bce8SPatrick Williams "DBUS response error on Power.Mode GetSubTree {}", ec); 21753a2d0424SChris Cain // This is an optional D-Bus object so just return if 21763a2d0424SChris Cain // error occurs 21773a2d0424SChris Cain return; 21783a2d0424SChris Cain } 21793a2d0424SChris Cain if (subtree.empty()) 21803a2d0424SChris Cain { 21813a2d0424SChris Cain // As noted above, this is an optional interface so just return 21823a2d0424SChris Cain // if there is no instance found 21833a2d0424SChris Cain return; 21843a2d0424SChris Cain } 21853a2d0424SChris Cain if (subtree.size() > 1) 21863a2d0424SChris Cain { 21873a2d0424SChris Cain // More then one PowerMode object is not supported and is an 21883a2d0424SChris Cain // error 218962598e31SEd Tanous BMCWEB_LOG_DEBUG( 219062598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 219162598e31SEd Tanous subtree.size()); 2192ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21933a2d0424SChris Cain return; 21943a2d0424SChris Cain } 21953a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 21963a2d0424SChris Cain { 219762598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2198ac106bf6SEd Tanous messages::internalError(asyncResp->res); 21993a2d0424SChris Cain return; 22003a2d0424SChris Cain } 22013a2d0424SChris Cain const std::string& path = subtree[0].first; 22023a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 22033a2d0424SChris Cain if (service.empty()) 22043a2d0424SChris Cain { 220562598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2206ac106bf6SEd Tanous messages::internalError(asyncResp->res); 22073a2d0424SChris Cain return; 22083a2d0424SChris Cain } 22096b9ac4f2SChris Cain 22106b9ac4f2SChris Cain // Valid Power Mode object found, now read the mode properties 2211deae6a78SEd Tanous dbus::utility::getAllProperties( 22121e1e598dSJonathan Doman *crow::connections::systemBus, service, path, 22136b9ac4f2SChris Cain "xyz.openbmc_project.Control.Power.Mode", 2214bd79bce8SPatrick Williams [asyncResp]( 2215bd79bce8SPatrick Williams const boost::system::error_code& ec2, 22166b9ac4f2SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 22176b9ac4f2SChris Cain afterGetPowerMode(asyncResp, ec2, properties); 22181e1e598dSJonathan Doman }); 2219e99073f5SGeorge Liu }); 22203a2d0424SChris Cain } 22213a2d0424SChris Cain 22223a2d0424SChris Cain /** 22233a2d0424SChris Cain * @brief Validate the specified mode is valid and return the PowerMode 22243a2d0424SChris Cain * name associated with that string 22253a2d0424SChris Cain * 2226ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2227b6655101SChris Cain * @param[in] modeValue String representing the desired PowerMode 22283a2d0424SChris Cain * 22293a2d0424SChris Cain * @return PowerMode value or empty string if mode is not valid 22303a2d0424SChris Cain */ 2231504af5a0SPatrick Williams inline std::string validatePowerMode( 2232504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2233b6655101SChris Cain const nlohmann::json& modeValue) 22343a2d0424SChris Cain { 2235b6655101SChris Cain using PowerMode = computer_system::PowerMode; 22363a2d0424SChris Cain std::string mode; 22373a2d0424SChris Cain 2238b6655101SChris Cain if (modeValue == PowerMode::Static) 22393a2d0424SChris Cain { 22403a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static"; 22413a2d0424SChris Cain } 2242b6655101SChris Cain else if (modeValue == PowerMode::MaximumPerformance) 22433a2d0424SChris Cain { 22440fda0f12SGeorge Liu mode = 22450fda0f12SGeorge Liu "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance"; 22463a2d0424SChris Cain } 2247b6655101SChris Cain else if (modeValue == PowerMode::PowerSaving) 22483a2d0424SChris Cain { 22493a2d0424SChris Cain mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"; 22503a2d0424SChris Cain } 2251b6655101SChris Cain else if (modeValue == PowerMode::BalancedPerformance) 2252b6655101SChris Cain { 2253b6655101SChris Cain mode = 2254b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance"; 2255b6655101SChris Cain } 2256b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPerformance) 2257b6655101SChris Cain { 2258b6655101SChris Cain mode = 2259b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance"; 2260b6655101SChris Cain } 2261b6655101SChris Cain else if (modeValue == PowerMode::EfficiencyFavorPower) 2262b6655101SChris Cain { 2263b6655101SChris Cain mode = 2264b6655101SChris Cain "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower"; 2265b6655101SChris Cain } 22663a2d0424SChris Cain else 22673a2d0424SChris Cain { 2268b6655101SChris Cain messages::propertyValueNotInList(asyncResp->res, modeValue.dump(), 2269ac106bf6SEd Tanous "PowerMode"); 22703a2d0424SChris Cain } 22713a2d0424SChris Cain return mode; 22723a2d0424SChris Cain } 22733a2d0424SChris Cain 22743a2d0424SChris Cain /** 22753a2d0424SChris Cain * @brief Sets system power mode. 22763a2d0424SChris Cain * 2277ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 22783a2d0424SChris Cain * @param[in] pmode System power mode from request. 22793a2d0424SChris Cain * 22803a2d0424SChris Cain * @return None. 22813a2d0424SChris Cain */ 2282ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 22833a2d0424SChris Cain const std::string& pmode) 22843a2d0424SChris Cain { 228562598e31SEd Tanous BMCWEB_LOG_DEBUG("Set power mode."); 22863a2d0424SChris Cain 2287ac106bf6SEd Tanous std::string powerMode = validatePowerMode(asyncResp, pmode); 22883a2d0424SChris Cain if (powerMode.empty()) 22893a2d0424SChris Cain { 22903a2d0424SChris Cain return; 22913a2d0424SChris Cain } 22923a2d0424SChris Cain 22933a2d0424SChris Cain // Get Power Mode object path: 2294e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2295e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.Mode"}; 2296e99073f5SGeorge Liu dbus::utility::getSubTree( 2297e99073f5SGeorge Liu "/", 0, interfaces, 2298ac106bf6SEd Tanous [asyncResp, 2299e99073f5SGeorge Liu powerMode](const boost::system::error_code& ec, 2300b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23013a2d0424SChris Cain if (ec) 23023a2d0424SChris Cain { 2303bd79bce8SPatrick Williams BMCWEB_LOG_ERROR( 2304bd79bce8SPatrick Williams "DBUS response error on Power.Mode GetSubTree {}", ec); 23053a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2306ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23073a2d0424SChris Cain return; 23083a2d0424SChris Cain } 23093a2d0424SChris Cain if (subtree.empty()) 23103a2d0424SChris Cain { 23113a2d0424SChris Cain // This is an optional D-Bus object, but user attempted to patch 2312ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 23133a2d0424SChris Cain "PowerMode"); 23143a2d0424SChris Cain return; 23153a2d0424SChris Cain } 23163a2d0424SChris Cain if (subtree.size() > 1) 23173a2d0424SChris Cain { 23183a2d0424SChris Cain // More then one PowerMode object is not supported and is an 23193a2d0424SChris Cain // error 232062598e31SEd Tanous BMCWEB_LOG_DEBUG( 232162598e31SEd Tanous "Found more than 1 system D-Bus Power.Mode objects: {}", 232262598e31SEd Tanous subtree.size()); 2323ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23243a2d0424SChris Cain return; 23253a2d0424SChris Cain } 23263a2d0424SChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 23273a2d0424SChris Cain { 232862598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode mapper error!"); 2329ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23303a2d0424SChris Cain return; 23313a2d0424SChris Cain } 23323a2d0424SChris Cain const std::string& path = subtree[0].first; 23333a2d0424SChris Cain const std::string& service = subtree[0].second.begin()->first; 23343a2d0424SChris Cain if (service.empty()) 23353a2d0424SChris Cain { 233662598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.Mode service mapper error!"); 2337ac106bf6SEd Tanous messages::internalError(asyncResp->res); 23383a2d0424SChris Cain return; 23393a2d0424SChris Cain } 23403a2d0424SChris Cain 234162598e31SEd Tanous BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path); 23423a2d0424SChris Cain 23433a2d0424SChris Cain // Set the Power Mode property 2344e93abac6SGinu George setDbusProperty(asyncResp, "PowerMode", service, path, 2345bd79bce8SPatrick Williams "xyz.openbmc_project.Control.Power.Mode", 2346bd79bce8SPatrick Williams "PowerMode", powerMode); 2347e99073f5SGeorge Liu }); 23483a2d0424SChris Cain } 23493a2d0424SChris Cain 23503a2d0424SChris Cain /** 235151709ffdSYong Li * @brief Translates watchdog timeout action DBUS property value to redfish. 235251709ffdSYong Li * 235351709ffdSYong Li * @param[in] dbusAction The watchdog timeout action in D-BUS. 235451709ffdSYong Li * 235551709ffdSYong Li * @return Returns as a string, the timeout action in Redfish terms. If 235651709ffdSYong Li * translation cannot be done, returns an empty string. 235751709ffdSYong Li */ 235823a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) 235951709ffdSYong Li { 236051709ffdSYong Li if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") 236151709ffdSYong Li { 236251709ffdSYong Li return "None"; 236351709ffdSYong Li } 23643174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") 236551709ffdSYong Li { 236651709ffdSYong Li return "ResetSystem"; 236751709ffdSYong Li } 23683174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") 236951709ffdSYong Li { 237051709ffdSYong Li return "PowerDown"; 237151709ffdSYong Li } 23723174e4dfSEd Tanous if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") 237351709ffdSYong Li { 237451709ffdSYong Li return "PowerCycle"; 237551709ffdSYong Li } 237651709ffdSYong Li 237751709ffdSYong Li return ""; 237851709ffdSYong Li } 237951709ffdSYong Li 238051709ffdSYong Li /** 2381c45f0082SYong Li *@brief Translates timeout action from Redfish to DBUS property value. 2382c45f0082SYong Li * 2383c45f0082SYong Li *@param[in] rfAction The timeout action in Redfish. 2384c45f0082SYong Li * 2385c45f0082SYong Li *@return Returns as a string, the time_out action as expected by DBUS. 2386c45f0082SYong Li *If translation cannot be done, returns an empty string. 2387c45f0082SYong Li */ 2388c45f0082SYong Li 238923a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) 2390c45f0082SYong Li { 2391c45f0082SYong Li if (rfAction == "None") 2392c45f0082SYong Li { 2393c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.None"; 2394c45f0082SYong Li } 23953174e4dfSEd Tanous if (rfAction == "PowerCycle") 2396c45f0082SYong Li { 2397c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; 2398c45f0082SYong Li } 23993174e4dfSEd Tanous if (rfAction == "PowerDown") 2400c45f0082SYong Li { 2401c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; 2402c45f0082SYong Li } 24033174e4dfSEd Tanous if (rfAction == "ResetSystem") 2404c45f0082SYong Li { 2405c45f0082SYong Li return "xyz.openbmc_project.State.Watchdog.Action.HardReset"; 2406c45f0082SYong Li } 2407c45f0082SYong Li 2408c45f0082SYong Li return ""; 2409c45f0082SYong Li } 2410c45f0082SYong Li 2411c45f0082SYong Li /** 241251709ffdSYong Li * @brief Retrieves host watchdog timer properties over DBUS 241351709ffdSYong Li * 2414ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 241551709ffdSYong Li * 241651709ffdSYong Li * @return None. 241751709ffdSYong Li */ 2418504af5a0SPatrick Williams inline void getHostWatchdogTimer( 2419504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 242051709ffdSYong Li { 242162598e31SEd Tanous BMCWEB_LOG_DEBUG("Get host watchodg"); 2422deae6a78SEd Tanous dbus::utility::getAllProperties( 2423deae6a78SEd Tanous "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0", 2424bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.State.Watchdog", 2425ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2426b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 242751709ffdSYong Li if (ec) 242851709ffdSYong Li { 242951709ffdSYong Li // watchdog service is stopped 243062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec); 243151709ffdSYong Li return; 243251709ffdSYong Li } 243351709ffdSYong Li 243462598e31SEd Tanous BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size()); 243551709ffdSYong Li 243651709ffdSYong Li nlohmann::json& hostWatchdogTimer = 2437ac106bf6SEd Tanous asyncResp->res.jsonValue["HostWatchdogTimer"]; 243851709ffdSYong Li 243951709ffdSYong Li // watchdog service is running/enabled 2440539d8c6bSEd Tanous hostWatchdogTimer["Status"]["State"] = resource::State::Enabled; 244151709ffdSYong Li 2442bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2443bc1d29deSKrzysztof Grobelny const std::string* expireAction = nullptr; 244451709ffdSYong Li 2445bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2446bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), properties, "Enabled", 2447bd79bce8SPatrick Williams enabled, "ExpireAction", expireAction); 2448bc1d29deSKrzysztof Grobelny 2449bc1d29deSKrzysztof Grobelny if (!success) 245051709ffdSYong Li { 2451ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2452601af5edSChicago Duan return; 245351709ffdSYong Li } 245451709ffdSYong Li 2455bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 245651709ffdSYong Li { 2457bc1d29deSKrzysztof Grobelny hostWatchdogTimer["FunctionEnabled"] = *enabled; 245851709ffdSYong Li } 245951709ffdSYong Li 2460bc1d29deSKrzysztof Grobelny if (expireAction != nullptr) 2461bc1d29deSKrzysztof Grobelny { 2462bc1d29deSKrzysztof Grobelny std::string action = dbusToRfWatchdogAction(*expireAction); 246351709ffdSYong Li if (action.empty()) 246451709ffdSYong Li { 2465ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2466601af5edSChicago Duan return; 246751709ffdSYong Li } 246851709ffdSYong Li hostWatchdogTimer["TimeoutAction"] = action; 246951709ffdSYong Li } 2470bc1d29deSKrzysztof Grobelny }); 247151709ffdSYong Li } 247251709ffdSYong Li 247351709ffdSYong Li /** 2474c45f0082SYong Li * @brief Sets Host WatchDog Timer properties. 2475c45f0082SYong Li * 2476ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 2477c45f0082SYong Li * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming 2478c45f0082SYong Li * RF request. 2479c45f0082SYong Li * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request. 2480c45f0082SYong Li * 2481c45f0082SYong Li * @return None. 2482c45f0082SYong Li */ 2483504af5a0SPatrick Williams inline void setWDTProperties( 2484504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2485c45f0082SYong Li const std::optional<bool> wdtEnable, 2486c45f0082SYong Li const std::optional<std::string>& wdtTimeOutAction) 2487c45f0082SYong Li { 248862598e31SEd Tanous BMCWEB_LOG_DEBUG("Set host watchdog"); 2489c45f0082SYong Li 2490c45f0082SYong Li if (wdtTimeOutAction) 2491c45f0082SYong Li { 2492c45f0082SYong Li std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction); 2493c45f0082SYong Li // check if TimeOut Action is Valid 2494c45f0082SYong Li if (wdtTimeOutActStr.empty()) 2495c45f0082SYong Li { 249662598e31SEd Tanous BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}", 249762598e31SEd Tanous *wdtTimeOutAction); 2498ac106bf6SEd Tanous messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction, 2499c45f0082SYong Li "TimeoutAction"); 2500c45f0082SYong Li return; 2501c45f0082SYong Li } 2502c45f0082SYong Li 2503e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction", 2504e93abac6SGinu George "xyz.openbmc_project.Watchdog", 250587c44966SAsmitha Karunanithi sdbusplus::message::object_path( 250687c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 25079ae226faSGeorge Liu "xyz.openbmc_project.State.Watchdog", "ExpireAction", 2508e93abac6SGinu George wdtTimeOutActStr); 2509c45f0082SYong Li } 2510c45f0082SYong Li 2511c45f0082SYong Li if (wdtEnable) 2512c45f0082SYong Li { 2513e93abac6SGinu George setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled", 2514e93abac6SGinu George "xyz.openbmc_project.Watchdog", 251587c44966SAsmitha Karunanithi sdbusplus::message::object_path( 251687c44966SAsmitha Karunanithi "/xyz/openbmc_project/watchdog/host0"), 251787c44966SAsmitha Karunanithi "xyz.openbmc_project.State.Watchdog", "Enabled", 2518e93abac6SGinu George *wdtEnable); 2519c45f0082SYong Li } 2520c45f0082SYong Li } 2521c45f0082SYong Li 252237bbf98cSChris Cain /** 252337bbf98cSChris Cain * @brief Parse the Idle Power Saver properties into json 252437bbf98cSChris Cain * 2525ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 252637bbf98cSChris Cain * @param[in] properties IPS property data from DBus. 252737bbf98cSChris Cain * 252837bbf98cSChris Cain * @return true if successful 252937bbf98cSChris Cain */ 2530504af5a0SPatrick Williams inline bool parseIpsProperties( 2531504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25321e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) 253337bbf98cSChris Cain { 2534bc1d29deSKrzysztof Grobelny const bool* enabled = nullptr; 2535bc1d29deSKrzysztof Grobelny const uint8_t* enterUtilizationPercent = nullptr; 2536bc1d29deSKrzysztof Grobelny const uint64_t* enterDwellTime = nullptr; 2537bc1d29deSKrzysztof Grobelny const uint8_t* exitUtilizationPercent = nullptr; 2538bc1d29deSKrzysztof Grobelny const uint64_t* exitDwellTime = nullptr; 2539bc1d29deSKrzysztof Grobelny 2540bc1d29deSKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 2541bc1d29deSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled, 25422661b72cSChris Cain "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime", 25432661b72cSChris Cain enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent, 25442661b72cSChris Cain "ExitDwellTime", exitDwellTime); 2545bc1d29deSKrzysztof Grobelny 2546bc1d29deSKrzysztof Grobelny if (!success) 254737bbf98cSChris Cain { 254837bbf98cSChris Cain return false; 254937bbf98cSChris Cain } 2550bc1d29deSKrzysztof Grobelny 2551bc1d29deSKrzysztof Grobelny if (enabled != nullptr) 255237bbf98cSChris Cain { 2553ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled; 255437bbf98cSChris Cain } 2555bc1d29deSKrzysztof Grobelny 2556bc1d29deSKrzysztof Grobelny if (enterUtilizationPercent != nullptr) 255737bbf98cSChris Cain { 2558ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] = 2559bc1d29deSKrzysztof Grobelny *enterUtilizationPercent; 256037bbf98cSChris Cain } 2561bc1d29deSKrzysztof Grobelny 2562bc1d29deSKrzysztof Grobelny if (enterDwellTime != nullptr) 2563bc1d29deSKrzysztof Grobelny { 2564bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime); 2565ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] = 256637bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 256737bbf98cSChris Cain .count(); 256837bbf98cSChris Cain } 2569bc1d29deSKrzysztof Grobelny 2570bc1d29deSKrzysztof Grobelny if (exitUtilizationPercent != nullptr) 257137bbf98cSChris Cain { 2572ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] = 2573bc1d29deSKrzysztof Grobelny *exitUtilizationPercent; 257437bbf98cSChris Cain } 2575bc1d29deSKrzysztof Grobelny 2576bc1d29deSKrzysztof Grobelny if (exitDwellTime != nullptr) 257737bbf98cSChris Cain { 2578bc1d29deSKrzysztof Grobelny const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime); 2579ac106bf6SEd Tanous asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] = 258037bbf98cSChris Cain std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms) 258137bbf98cSChris Cain .count(); 258237bbf98cSChris Cain } 258337bbf98cSChris Cain 258437bbf98cSChris Cain return true; 258537bbf98cSChris Cain } 258637bbf98cSChris Cain 258737bbf98cSChris Cain /** 258837bbf98cSChris Cain * @brief Retrieves host watchdog timer properties over DBUS 258937bbf98cSChris Cain * 2590ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for completing asynchronous calls. 259137bbf98cSChris Cain * 259237bbf98cSChris Cain * @return None. 259337bbf98cSChris Cain */ 2594504af5a0SPatrick Williams inline void getIdlePowerSaver( 2595504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 259637bbf98cSChris Cain { 259762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get idle power saver parameters"); 259837bbf98cSChris Cain 259937bbf98cSChris Cain // Get IdlePowerSaver object path: 2600e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2601e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2602e99073f5SGeorge Liu dbus::utility::getSubTree( 2603e99073f5SGeorge Liu "/", 0, interfaces, 2604ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 2605b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 260637bbf98cSChris Cain if (ec) 260737bbf98cSChris Cain { 2608b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 260962598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 261062598e31SEd Tanous ec); 2611ac106bf6SEd Tanous messages::internalError(asyncResp->res); 261237bbf98cSChris Cain return; 261337bbf98cSChris Cain } 261437bbf98cSChris Cain if (subtree.empty()) 261537bbf98cSChris Cain { 261637bbf98cSChris Cain // This is an optional interface so just return 261737bbf98cSChris Cain // if there is no instance found 261862598e31SEd Tanous BMCWEB_LOG_DEBUG("No instances found"); 261937bbf98cSChris Cain return; 262037bbf98cSChris Cain } 262137bbf98cSChris Cain if (subtree.size() > 1) 262237bbf98cSChris Cain { 262337bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 262437bbf98cSChris Cain // is an error 262562598e31SEd Tanous BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus " 262662598e31SEd Tanous "Power.IdlePowerSaver objects: {}", 262762598e31SEd Tanous subtree.size()); 2628ac106bf6SEd Tanous messages::internalError(asyncResp->res); 262937bbf98cSChris Cain return; 263037bbf98cSChris Cain } 263137bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 263237bbf98cSChris Cain { 263362598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2634ac106bf6SEd Tanous messages::internalError(asyncResp->res); 263537bbf98cSChris Cain return; 263637bbf98cSChris Cain } 263737bbf98cSChris Cain const std::string& path = subtree[0].first; 263837bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 263937bbf98cSChris Cain if (service.empty()) 264037bbf98cSChris Cain { 264162598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2642ac106bf6SEd Tanous messages::internalError(asyncResp->res); 264337bbf98cSChris Cain return; 264437bbf98cSChris Cain } 264537bbf98cSChris Cain 264637bbf98cSChris Cain // Valid IdlePowerSaver object found, now read the current values 2647deae6a78SEd Tanous dbus::utility::getAllProperties( 2648bc1d29deSKrzysztof Grobelny *crow::connections::systemBus, service, path, 2649bc1d29deSKrzysztof Grobelny "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2650bd79bce8SPatrick Williams [asyncResp]( 2651bd79bce8SPatrick Williams const boost::system::error_code& ec2, 26521e5b7c88SJiaqing Zhao const dbus::utility::DBusPropertiesMap& properties) { 26538a592810SEd Tanous if (ec2) 265437bbf98cSChris Cain { 265562598e31SEd Tanous BMCWEB_LOG_ERROR( 2656bd79bce8SPatrick Williams "DBUS response error on IdlePowerSaver GetAll: {}", 2657bd79bce8SPatrick Williams ec2); 2658ac106bf6SEd Tanous messages::internalError(asyncResp->res); 265937bbf98cSChris Cain return; 266037bbf98cSChris Cain } 266137bbf98cSChris Cain 2662ac106bf6SEd Tanous if (!parseIpsProperties(asyncResp, properties)) 266337bbf98cSChris Cain { 2664ac106bf6SEd Tanous messages::internalError(asyncResp->res); 266537bbf98cSChris Cain return; 266637bbf98cSChris Cain } 2667bc1d29deSKrzysztof Grobelny }); 2668e99073f5SGeorge Liu }); 266937bbf98cSChris Cain 267062598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters"); 267137bbf98cSChris Cain } 267237bbf98cSChris Cain 267337bbf98cSChris Cain /** 267437bbf98cSChris Cain * @brief Sets Idle Power Saver properties. 267537bbf98cSChris Cain * 2676ac106bf6SEd Tanous * @param[in] asyncResp Shared pointer for generating response message. 267737bbf98cSChris Cain * @param[in] ipsEnable The IPS Enable value (true/false) from incoming 267837bbf98cSChris Cain * RF request. 267937bbf98cSChris Cain * @param[in] ipsEnterUtil The utilization limit to enter idle state. 268037bbf98cSChris Cain * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil 268137bbf98cSChris Cain * before entering idle state. 268237bbf98cSChris Cain * @param[in] ipsExitUtil The utilization limit when exiting idle state. 268337bbf98cSChris Cain * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil 268437bbf98cSChris Cain * before exiting idle state 268537bbf98cSChris Cain * 268637bbf98cSChris Cain * @return None. 268737bbf98cSChris Cain */ 2688bd79bce8SPatrick Williams inline void setIdlePowerSaver( 2689bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 269037bbf98cSChris Cain const std::optional<bool> ipsEnable, 269137bbf98cSChris Cain const std::optional<uint8_t> ipsEnterUtil, 269237bbf98cSChris Cain const std::optional<uint64_t> ipsEnterTime, 269337bbf98cSChris Cain const std::optional<uint8_t> ipsExitUtil, 269437bbf98cSChris Cain const std::optional<uint64_t> ipsExitTime) 269537bbf98cSChris Cain { 269662598e31SEd Tanous BMCWEB_LOG_DEBUG("Set idle power saver properties"); 269737bbf98cSChris Cain 269837bbf98cSChris Cain // Get IdlePowerSaver object path: 2699e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 2700e99073f5SGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver"}; 2701e99073f5SGeorge Liu dbus::utility::getSubTree( 2702e99073f5SGeorge Liu "/", 0, interfaces, 2703ac106bf6SEd Tanous [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, 2704e99073f5SGeorge Liu ipsExitTime](const boost::system::error_code& ec, 2705b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 270637bbf98cSChris Cain if (ec) 270737bbf98cSChris Cain { 2708b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR( 270962598e31SEd Tanous "DBUS response error on Power.IdlePowerSaver GetSubTree {}", 271062598e31SEd Tanous ec); 2711ac106bf6SEd Tanous messages::internalError(asyncResp->res); 271237bbf98cSChris Cain return; 271337bbf98cSChris Cain } 271437bbf98cSChris Cain if (subtree.empty()) 271537bbf98cSChris Cain { 271637bbf98cSChris Cain // This is an optional D-Bus object, but user attempted to patch 2717ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 271837bbf98cSChris Cain "IdlePowerSaver"); 271937bbf98cSChris Cain return; 272037bbf98cSChris Cain } 272137bbf98cSChris Cain if (subtree.size() > 1) 272237bbf98cSChris Cain { 272337bbf98cSChris Cain // More then one PowerIdlePowerSaver object is not supported and 272437bbf98cSChris Cain // is an error 272562598e31SEd Tanous BMCWEB_LOG_DEBUG( 272662598e31SEd Tanous "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}", 272762598e31SEd Tanous subtree.size()); 2728ac106bf6SEd Tanous messages::internalError(asyncResp->res); 272937bbf98cSChris Cain return; 273037bbf98cSChris Cain } 273137bbf98cSChris Cain if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) 273237bbf98cSChris Cain { 273362598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!"); 2734ac106bf6SEd Tanous messages::internalError(asyncResp->res); 273537bbf98cSChris Cain return; 273637bbf98cSChris Cain } 273737bbf98cSChris Cain const std::string& path = subtree[0].first; 273837bbf98cSChris Cain const std::string& service = subtree[0].second.begin()->first; 273937bbf98cSChris Cain if (service.empty()) 274037bbf98cSChris Cain { 274162598e31SEd Tanous BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!"); 2742ac106bf6SEd Tanous messages::internalError(asyncResp->res); 274337bbf98cSChris Cain return; 274437bbf98cSChris Cain } 274537bbf98cSChris Cain 274637bbf98cSChris Cain // Valid Power IdlePowerSaver object found, now set any values that 274737bbf98cSChris Cain // need to be updated 274837bbf98cSChris Cain 274937bbf98cSChris Cain if (ipsEnable) 275037bbf98cSChris Cain { 2751bd79bce8SPatrick Williams setDbusProperty( 2752bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/Enabled", service, path, 275387c44966SAsmitha Karunanithi "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2754e93abac6SGinu George "Enabled", *ipsEnable); 275537bbf98cSChris Cain } 275637bbf98cSChris Cain if (ipsEnterUtil) 275737bbf98cSChris Cain { 2758bd79bce8SPatrick Williams setDbusProperty( 2759bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/EnterUtilizationPercent", 2760e93abac6SGinu George service, path, 27619ae226faSGeorge Liu "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2762e93abac6SGinu George "EnterUtilizationPercent", *ipsEnterUtil); 276337bbf98cSChris Cain } 276437bbf98cSChris Cain if (ipsEnterTime) 276537bbf98cSChris Cain { 276637bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 276737bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsEnterTime * 1000; 2768bd79bce8SPatrick Williams setDbusProperty( 2769bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service, 2770bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2771e93abac6SGinu George "EnterDwellTime", timeMilliseconds); 277237bbf98cSChris Cain } 277337bbf98cSChris Cain if (ipsExitUtil) 277437bbf98cSChris Cain { 2775bd79bce8SPatrick Williams setDbusProperty( 2776bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service, 2777bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2778e93abac6SGinu George "ExitUtilizationPercent", *ipsExitUtil); 277937bbf98cSChris Cain } 278037bbf98cSChris Cain if (ipsExitTime) 278137bbf98cSChris Cain { 278237bbf98cSChris Cain // Convert from seconds into milliseconds for DBus 278337bbf98cSChris Cain const uint64_t timeMilliseconds = *ipsExitTime * 1000; 2784bd79bce8SPatrick Williams setDbusProperty( 2785bd79bce8SPatrick Williams asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service, 2786bd79bce8SPatrick Williams path, "xyz.openbmc_project.Control.Power.IdlePowerSaver", 2787e93abac6SGinu George "ExitDwellTime", timeMilliseconds); 278837bbf98cSChris Cain } 2789e99073f5SGeorge Liu }); 279037bbf98cSChris Cain 279162598e31SEd Tanous BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters"); 279237bbf98cSChris Cain } 279337bbf98cSChris Cain 2794c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead( 2795dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 2796dd60b9edSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 2797dd60b9edSEd Tanous { 2798dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2799dd60b9edSEd Tanous { 2800dd60b9edSEd Tanous return; 2801dd60b9edSEd Tanous } 2802dd60b9edSEd Tanous asyncResp->res.addHeader( 2803dd60b9edSEd Tanous boost::beast::http::field::link, 2804dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby"); 2805dd60b9edSEd Tanous } 2806dd60b9edSEd Tanous 2807c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet( 2808c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 2809c1e219d5SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28101abe55efSEd Tanous { 28113ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2812f4c99e70SEd Tanous { 2813f4c99e70SEd Tanous return; 2814f4c99e70SEd Tanous } 2815dd60b9edSEd Tanous 2816dd60b9edSEd Tanous asyncResp->res.addHeader( 2817dd60b9edSEd Tanous boost::beast::http::field::link, 2818dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby"); 28198d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 28200f74e643SEd Tanous "#ComputerSystemCollection.ComputerSystemCollection"; 28218d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems"; 28228d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Computer System Collection"; 2823462023adSSunitha Harish 2824fc5ae94dSOliver Brewka getSystemCollectionMembers(asyncResp); 2825c1e219d5SEd Tanous } 2826c1e219d5SEd Tanous 2827c1e219d5SEd Tanous /** 28287e860f15SJohn Edward Broadbent * Function transceives data with dbus directly. 28297e860f15SJohn Edward Broadbent */ 28304f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 28317e860f15SJohn Edward Broadbent { 283289492a15SPatrick Williams constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI"; 283389492a15SPatrick Williams constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi"; 283489492a15SPatrick Williams constexpr const char* interfaceName = 28357e860f15SJohn Edward Broadbent "xyz.openbmc_project.Control.Host.NMI"; 283689492a15SPatrick Williams constexpr const char* method = "NMI"; 28377e860f15SJohn Edward Broadbent 2838177612aaSEd Tanous dbus::utility::async_method_call( 2839177612aaSEd Tanous asyncResp, 28405e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 28417e860f15SJohn Edward Broadbent if (ec) 28427e860f15SJohn Edward Broadbent { 284362598e31SEd Tanous BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec); 28447e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 28457e860f15SJohn Edward Broadbent return; 28467e860f15SJohn Edward Broadbent } 28477e860f15SJohn Edward Broadbent messages::success(asyncResp->res); 28487e860f15SJohn Edward Broadbent }, 28497e860f15SJohn Edward Broadbent serviceName, objectPath, interfaceName, method); 28507e860f15SJohn Edward Broadbent } 2851c5b2abe0SLewanczyk, Dawid 2852c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost( 2853c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 28547f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2855c1e219d5SEd Tanous const std::string& systemName) 2856c1e219d5SEd Tanous { 28573ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 285845ca1b86SEd Tanous { 285945ca1b86SEd Tanous return; 286045ca1b86SEd Tanous } 2861dd7090e6SGunnar Mills 2862dd7090e6SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 2863dd7090e6SGunnar Mills { 2864dd7090e6SGunnar Mills if (systemName == "hypervisor") 2865dd7090e6SGunnar Mills { 2866dd7090e6SGunnar Mills handleHypervisorSystemResetPost(req, asyncResp); 2867dd7090e6SGunnar Mills return; 2868dd7090e6SGunnar Mills } 2869dd7090e6SGunnar Mills } 2870dd7090e6SGunnar Mills 2871253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 2872c1e219d5SEd Tanous { 2873c1e219d5SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2874c1e219d5SEd Tanous systemName); 2875c1e219d5SEd Tanous return; 2876c1e219d5SEd Tanous } 287725b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 28787f3e84a1SEd Tanous { 28797f3e84a1SEd Tanous // Option currently returns no systems. TBD 28807f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2881c1e219d5SEd Tanous systemName); 28827f3e84a1SEd Tanous return; 28837f3e84a1SEd Tanous } 28849712f8acSEd Tanous std::string resetType; 2885c1e219d5SEd Tanous if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 2886cc340dd9SEd Tanous { 2887cc340dd9SEd Tanous return; 2888cc340dd9SEd Tanous } 2889cc340dd9SEd Tanous 2890d22c8396SJason M. Bills // Get the command and host vs. chassis 2891cc340dd9SEd Tanous std::string command; 2892543f4400SEd Tanous bool hostCommand = true; 2893d4d25793SEd Tanous if ((resetType == "On") || (resetType == "ForceOn")) 2894cc340dd9SEd Tanous { 2895cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.On"; 2896d22c8396SJason M. Bills hostCommand = true; 2897d22c8396SJason M. Bills } 2898d22c8396SJason M. Bills else if (resetType == "ForceOff") 2899d22c8396SJason M. Bills { 2900d22c8396SJason M. Bills command = "xyz.openbmc_project.State.Chassis.Transition.Off"; 2901d22c8396SJason M. Bills hostCommand = false; 2902d22c8396SJason M. Bills } 2903d22c8396SJason M. Bills else if (resetType == "ForceRestart") 2904d22c8396SJason M. Bills { 2905c1e219d5SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot"; 290686a0851aSJason M. Bills hostCommand = true; 2907cc340dd9SEd Tanous } 29089712f8acSEd Tanous else if (resetType == "GracefulShutdown") 2909cc340dd9SEd Tanous { 2910cc340dd9SEd Tanous command = "xyz.openbmc_project.State.Host.Transition.Off"; 2911d22c8396SJason M. Bills hostCommand = true; 2912cc340dd9SEd Tanous } 29139712f8acSEd Tanous else if (resetType == "GracefulRestart") 2914cc340dd9SEd Tanous { 29150fda0f12SGeorge Liu command = 29160fda0f12SGeorge Liu "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot"; 2917d22c8396SJason M. Bills hostCommand = true; 2918d22c8396SJason M. Bills } 2919d22c8396SJason M. Bills else if (resetType == "PowerCycle") 2920d22c8396SJason M. Bills { 292186a0851aSJason M. Bills command = "xyz.openbmc_project.State.Host.Transition.Reboot"; 292286a0851aSJason M. Bills hostCommand = true; 2923cc340dd9SEd Tanous } 2924bfd5b826SLakshminarayana R. Kammath else if (resetType == "Nmi") 2925bfd5b826SLakshminarayana R. Kammath { 2926bfd5b826SLakshminarayana R. Kammath doNMI(asyncResp); 2927bfd5b826SLakshminarayana R. Kammath return; 2928bfd5b826SLakshminarayana R. Kammath } 2929cc340dd9SEd Tanous else 2930cc340dd9SEd Tanous { 2931c1e219d5SEd Tanous messages::actionParameterUnknown(asyncResp->res, "Reset", resetType); 2932cc340dd9SEd Tanous return; 2933cc340dd9SEd Tanous } 2934d02aad39SEd Tanous sdbusplus::message::object_path statePath("/xyz/openbmc_project/state"); 2935cc340dd9SEd Tanous 2936d22c8396SJason M. Bills if (hostCommand) 2937d22c8396SJason M. Bills { 2938e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host", 2939d02aad39SEd Tanous statePath / "host0", "xyz.openbmc_project.State.Host", 2940e93abac6SGinu George "RequestedHostTransition", command); 2941cc340dd9SEd Tanous } 2942d22c8396SJason M. Bills else 2943d22c8396SJason M. Bills { 2944e93abac6SGinu George setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis", 2945d02aad39SEd Tanous statePath / "chassis0", 2946d02aad39SEd Tanous "xyz.openbmc_project.State.Chassis", 2947e93abac6SGinu George "RequestedPowerTransition", command); 2948d22c8396SJason M. Bills } 2949d22c8396SJason M. Bills } 2950cc340dd9SEd Tanous 2951c1e219d5SEd Tanous inline void handleComputerSystemHead( 2952dd60b9edSEd Tanous App& app, const crow::Request& req, 29537f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29547f3e84a1SEd Tanous const std::string& /*systemName*/) 2955dd60b9edSEd Tanous { 2956dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2957dd60b9edSEd Tanous { 2958dd60b9edSEd Tanous return; 2959dd60b9edSEd Tanous } 2960dd60b9edSEd Tanous 2961dd60b9edSEd Tanous asyncResp->res.addHeader( 2962dd60b9edSEd Tanous boost::beast::http::field::link, 2963dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 2964dd60b9edSEd Tanous } 2965dd60b9edSEd Tanous 29665c3e9272SAbhishek Patel inline void afterPortRequest( 29675c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29685c3e9272SAbhishek Patel const boost::system::error_code& ec, 29695c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 29705c3e9272SAbhishek Patel { 29715c3e9272SAbhishek Patel if (ec) 29725c3e9272SAbhishek Patel { 2973b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 29745c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29755c3e9272SAbhishek Patel return; 29765c3e9272SAbhishek Patel } 29775c3e9272SAbhishek Patel for (const auto& data : socketData) 29785c3e9272SAbhishek Patel { 29795c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 29805c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 29815c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 29825c3e9272SAbhishek Patel nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"]; 29835c3e9272SAbhishek Patel dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled; 29845c3e9272SAbhishek Patel // need to retrieve port number for 29855c3e9272SAbhishek Patel // obmc-console-ssh service 29865c3e9272SAbhishek Patel if (protocolName == "SSH") 29875c3e9272SAbhishek Patel { 29885c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 298981c4e330SEd Tanous const boost::system::error_code& ec1, 29905c3e9272SAbhishek Patel int portNumber) { 29915c3e9272SAbhishek Patel if (ec1) 29925c3e9272SAbhishek Patel { 2993b3e86cb0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec1); 29945c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 29955c3e9272SAbhishek Patel return; 29965c3e9272SAbhishek Patel } 29975c3e9272SAbhishek Patel nlohmann::json& dataJson1 = 29985c3e9272SAbhishek Patel asyncResp->res.jsonValue["SerialConsole"]; 29995c3e9272SAbhishek Patel dataJson1[protocolName]["Port"] = portNumber; 30005c3e9272SAbhishek Patel }); 30015c3e9272SAbhishek Patel } 30025c3e9272SAbhishek Patel } 30035c3e9272SAbhishek Patel } 3004c1e219d5SEd Tanous 3005504af5a0SPatrick Williams inline void handleComputerSystemGet( 3006504af5a0SPatrick Williams crow::App& app, const crow::Request& req, 300722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3008c1e219d5SEd Tanous const std::string& systemName) 3009c1e219d5SEd Tanous { 30103ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 301145ca1b86SEd Tanous { 301245ca1b86SEd Tanous return; 301345ca1b86SEd Tanous } 3014746b56f3SAsmitha Karunanithi 301525b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 30167f3e84a1SEd Tanous { 30177f3e84a1SEd Tanous // Option currently returns no systems. TBD 30187f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 30197f3e84a1SEd Tanous systemName); 30207f3e84a1SEd Tanous return; 30217f3e84a1SEd Tanous } 30227f3e84a1SEd Tanous 302368896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 302468896206SGunnar Mills { 3025746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3026746b56f3SAsmitha Karunanithi { 3027746b56f3SAsmitha Karunanithi handleHypervisorSystemGet(asyncResp); 3028746b56f3SAsmitha Karunanithi return; 3029746b56f3SAsmitha Karunanithi } 303068896206SGunnar Mills } 3031746b56f3SAsmitha Karunanithi 3032253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 303322d268cbSEd Tanous { 303422d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 303522d268cbSEd Tanous systemName); 303622d268cbSEd Tanous return; 303722d268cbSEd Tanous } 3038dd60b9edSEd Tanous asyncResp->res.addHeader( 3039dd60b9edSEd Tanous boost::beast::http::field::link, 3040dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 30418d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3042b6655101SChris Cain "#ComputerSystem.v1_22_0.ComputerSystem"; 3043253f11b8SEd Tanous asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3044253f11b8SEd Tanous asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME; 3045539d8c6bSEd Tanous asyncResp->res.jsonValue["SystemType"] = 3046539d8c6bSEd Tanous computer_system::SystemType::Physical; 30478d1b46d7Szhanghch05 asyncResp->res.jsonValue["Description"] = "Computer System"; 30488d1b46d7Szhanghch05 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0; 3049cf0e004cSNinad Palsule asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = 3050dfb2b408SPriyanga Ramasamy double(0); 3051253f11b8SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 3052253f11b8SEd Tanous "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME); 305304a258f4SEd Tanous 3054253f11b8SEd Tanous asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format( 3055253f11b8SEd Tanous "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3056253f11b8SEd Tanous asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format( 3057253f11b8SEd Tanous "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3058253f11b8SEd Tanous asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format( 3059253f11b8SEd Tanous "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME); 30603179105bSSunny Srivastava asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = 3061253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters", 3062253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3063029573d4SEd Tanous 3064002d39b4SEd Tanous asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = 3065253f11b8SEd Tanous boost::urls::format( 3066253f11b8SEd Tanous "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", 3067253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3068c1e219d5SEd Tanous asyncResp->res 3069c1e219d5SEd Tanous .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] = 3070253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3071253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3072c5b2abe0SLewanczyk, Dawid 3073253f11b8SEd Tanous asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format( 3074253f11b8SEd Tanous "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3075253f11b8SEd Tanous asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format( 3076253f11b8SEd Tanous "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME); 3077c4bf6374SJason M. Bills 30781476687dSEd Tanous nlohmann::json::array_t managedBy; 30791476687dSEd Tanous nlohmann::json& manager = managedBy.emplace_back(); 3080253f11b8SEd Tanous manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}", 3081253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME); 3082002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 3083539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK; 3084539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled; 30850e8ac5e7SGunnar Mills 30860e8ac5e7SGunnar Mills // Fill in SerialConsole info 3087002d39b4SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15; 3088c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true; 30891476687dSEd Tanous 3090c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true; 30911476687dSEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200; 3092c1e219d5SEd Tanous asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] = 30931476687dSEd Tanous "Press ~. to exit console"; 30945c3e9272SAbhishek Patel getPortStatusAndPath(std::span{protocolToDBusForSystems}, 30955c3e9272SAbhishek Patel std::bind_front(afterPortRequest, asyncResp)); 30960e8ac5e7SGunnar Mills 309725b54dbaSEd Tanous if constexpr (BMCWEB_KVM) 309825b54dbaSEd Tanous { 30990e8ac5e7SGunnar Mills // Fill in GraphicalConsole info 3100002d39b4SEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true; 310125b54dbaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 310225b54dbaSEd Tanous 4; 3103613dabeaSEd Tanous asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = 3104613dabeaSEd Tanous nlohmann::json::array_t({"KVMIP"}); 310525b54dbaSEd Tanous } 310613451e39SWilly Tu 3107bd79bce8SPatrick Williams getMainChassisId( 3108bd79bce8SPatrick Williams asyncResp, [](const std::string& chassisId, 31098d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 3110b2c7e208SEd Tanous nlohmann::json::array_t chassisArray; 3111b2c7e208SEd Tanous nlohmann::json& chassis = chassisArray.emplace_back(); 3112bd79bce8SPatrick Williams chassis["@odata.id"] = 3113bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Chassis/{}", chassisId); 3114002d39b4SEd Tanous aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray); 3115c5d03ff4SJennifer Lee }); 3116a3002228SAppaRao Puli 3117*2eaa9279SJanet Adkins systems_utils::getValidSystemsPath( 3118*2eaa9279SJanet Adkins asyncResp, systemName, 3119*2eaa9279SJanet Adkins [asyncResp, 3120*2eaa9279SJanet Adkins systemName](const std::optional<std::string>& validSystemsPath) { 3121*2eaa9279SJanet Adkins if (validSystemsPath) 3122*2eaa9279SJanet Adkins { 3123*2eaa9279SJanet Adkins getLocationIndicatorActive(asyncResp, *validSystemsPath); 3124*2eaa9279SJanet Adkins } 3125*2eaa9279SJanet Adkins }); 3126*2eaa9279SJanet Adkins 31279f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 3128a3002228SAppaRao Puli getIndicatorLedState(asyncResp); 312951bd2d8aSGunnar Mills getComputerSystem(asyncResp); 31306c34de48SEd Tanous getHostState(asyncResp); 3131491d8ee7SSantosh Puranik getBootProperties(asyncResp); 3132978b8803SAndrew Geissler getBootProgress(asyncResp); 3133b6d5d45cSHieu Huynh getBootProgressLastStateTime(asyncResp); 313470c4d545SLakshmi Yadlapati pcie_util::getPCIeDeviceList(asyncResp, 313570c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/PCIeDevices")); 313651709ffdSYong Li getHostWatchdogTimer(asyncResp); 3137c6a620f2SGeorge Liu getPowerRestorePolicy(asyncResp); 31389dcfe8c1SAlbert Zhang getStopBootOnFault(asyncResp); 3139797d5daeSCorey Hardesty getAutomaticRetryPolicy(asyncResp); 3140c0557e1aSGunnar Mills getLastResetTime(asyncResp); 314125b54dbaSEd Tanous if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE) 314225b54dbaSEd Tanous { 3143a6349918SAppaRao Puli getProvisioningStatus(asyncResp); 314425b54dbaSEd Tanous } 31451981771bSAli Ahmed getTrustedModuleRequiredToBoot(asyncResp); 31463a2d0424SChris Cain getPowerMode(asyncResp); 314737bbf98cSChris Cain getIdlePowerSaver(asyncResp); 3148c1e219d5SEd Tanous } 3149550a6bf8SJiaqing Zhao 3150c1e219d5SEd Tanous inline void handleComputerSystemPatch( 3151c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 315222d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3153c1e219d5SEd Tanous const std::string& systemName) 3154c1e219d5SEd Tanous { 31553ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 315645ca1b86SEd Tanous { 315745ca1b86SEd Tanous return; 315845ca1b86SEd Tanous } 315925b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 31607f3e84a1SEd Tanous { 31617f3e84a1SEd Tanous // Option currently returns no systems. TBD 31627f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 31637f3e84a1SEd Tanous systemName); 31647f3e84a1SEd Tanous return; 31657f3e84a1SEd Tanous } 3166253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 316722d268cbSEd Tanous { 316822d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 316922d268cbSEd Tanous systemName); 317022d268cbSEd Tanous return; 317122d268cbSEd Tanous } 317222d268cbSEd Tanous 3173dd60b9edSEd Tanous asyncResp->res.addHeader( 3174dd60b9edSEd Tanous boost::beast::http::field::link, 3175dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby"); 3176dd60b9edSEd Tanous 31779f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 3178cde19e5fSSantosh Puranik std::optional<std::string> indicatorLed; 317998e386ecSGunnar Mills std::optional<std::string> assetTag; 3180c6a620f2SGeorge Liu std::optional<std::string> powerRestorePolicy; 31813a2d0424SChris Cain std::optional<std::string> powerMode; 3182550a6bf8SJiaqing Zhao std::optional<bool> wdtEnable; 3183550a6bf8SJiaqing Zhao std::optional<std::string> wdtTimeOutAction; 3184550a6bf8SJiaqing Zhao std::optional<std::string> bootSource; 3185550a6bf8SJiaqing Zhao std::optional<std::string> bootType; 3186550a6bf8SJiaqing Zhao std::optional<std::string> bootEnable; 3187550a6bf8SJiaqing Zhao std::optional<std::string> bootAutomaticRetry; 3188797d5daeSCorey Hardesty std::optional<uint32_t> bootAutomaticRetryAttempts; 3189550a6bf8SJiaqing Zhao std::optional<bool> bootTrustedModuleRequired; 31909dcfe8c1SAlbert Zhang std::optional<std::string> stopBootOnFault; 3191550a6bf8SJiaqing Zhao std::optional<bool> ipsEnable; 3192550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsEnterUtil; 3193550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsEnterTime; 3194550a6bf8SJiaqing Zhao std::optional<uint8_t> ipsExitUtil; 3195550a6bf8SJiaqing Zhao std::optional<uint64_t> ipsExitTime; 3196550a6bf8SJiaqing Zhao 3197afc474aeSMyung Bae if (!json_util::readJsonPatch( // 3198afc474aeSMyung Bae req, asyncResp->res, // 3199afc474aeSMyung Bae "AssetTag", assetTag, // 3200afc474aeSMyung Bae "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, // 3201afc474aeSMyung Bae "Boot/AutomaticRetryConfig", bootAutomaticRetry, // 3202afc474aeSMyung Bae "Boot/BootSourceOverrideEnabled", bootEnable, // 3203afc474aeSMyung Bae "Boot/BootSourceOverrideMode", bootType, // 3204afc474aeSMyung Bae "Boot/BootSourceOverrideTarget", bootSource, // 3205afc474aeSMyung Bae "Boot/StopBootOnFault", stopBootOnFault, // 3206afc474aeSMyung Bae "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, // 3207afc474aeSMyung Bae "HostWatchdogTimer/FunctionEnabled", wdtEnable, // 3208afc474aeSMyung Bae "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, // 3209afc474aeSMyung Bae "IdlePowerSaver/Enabled", ipsEnable, // 3210afc474aeSMyung Bae "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, // 3211afc474aeSMyung Bae "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, // 3212afc474aeSMyung Bae "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, // 3213afc474aeSMyung Bae "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, // 3214afc474aeSMyung Bae "IndicatorLED", indicatorLed, // 3215afc474aeSMyung Bae "LocationIndicatorActive", locationIndicatorActive, // 3216afc474aeSMyung Bae "PowerMode", powerMode, // 3217afc474aeSMyung Bae "PowerRestorePolicy", powerRestorePolicy // 3218afc474aeSMyung Bae )) 32196617338dSEd Tanous { 32206617338dSEd Tanous return; 32216617338dSEd Tanous } 3222491d8ee7SSantosh Puranik 322398e386ecSGunnar Mills if (assetTag) 322498e386ecSGunnar Mills { 322598e386ecSGunnar Mills setAssetTag(asyncResp, *assetTag); 322698e386ecSGunnar Mills } 322798e386ecSGunnar Mills 3228550a6bf8SJiaqing Zhao if (wdtEnable || wdtTimeOutAction) 3229c45f0082SYong Li { 3230f23b7296SEd Tanous setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction); 3231c45f0082SYong Li } 3232c45f0082SYong Li 3233cd9a4666SKonstantin Aladyshev if (bootSource || bootType || bootEnable) 323469f35306SGunnar Mills { 3235002d39b4SEd Tanous setBootProperties(asyncResp, bootSource, bootType, bootEnable); 3236491d8ee7SSantosh Puranik } 3237550a6bf8SJiaqing Zhao if (bootAutomaticRetry) 323869f35306SGunnar Mills { 3239550a6bf8SJiaqing Zhao setAutomaticRetry(asyncResp, *bootAutomaticRetry); 324069f35306SGunnar Mills } 3241ac7e1e0bSAli Ahmed 3242797d5daeSCorey Hardesty if (bootAutomaticRetryAttempts) 3243797d5daeSCorey Hardesty { 3244797d5daeSCorey Hardesty setAutomaticRetryAttempts(asyncResp, 3245797d5daeSCorey Hardesty bootAutomaticRetryAttempts.value()); 3246797d5daeSCorey Hardesty } 3247797d5daeSCorey Hardesty 3248550a6bf8SJiaqing Zhao if (bootTrustedModuleRequired) 3249ac7e1e0bSAli Ahmed { 3250c1e219d5SEd Tanous setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired); 325169f35306SGunnar Mills } 3252265c1602SJohnathan Mantey 32539dcfe8c1SAlbert Zhang if (stopBootOnFault) 32549dcfe8c1SAlbert Zhang { 32559dcfe8c1SAlbert Zhang setStopBootOnFault(asyncResp, *stopBootOnFault); 32569dcfe8c1SAlbert Zhang } 32579dcfe8c1SAlbert Zhang 32589f8bfa7cSGunnar Mills if (locationIndicatorActive) 32599f8bfa7cSGunnar Mills { 3260*2eaa9279SJanet Adkins systems_utils::getValidSystemsPath( 3261*2eaa9279SJanet Adkins asyncResp, systemName, 3262*2eaa9279SJanet Adkins [asyncResp, systemName, 3263*2eaa9279SJanet Adkins locationIndicatorActive{*locationIndicatorActive}]( 3264*2eaa9279SJanet Adkins const std::optional<std::string>& validSystemsPath) { 3265*2eaa9279SJanet Adkins if (!validSystemsPath) 3266*2eaa9279SJanet Adkins { 3267*2eaa9279SJanet Adkins messages::resourceNotFound(asyncResp->res, "Systems", 3268*2eaa9279SJanet Adkins systemName); 3269*2eaa9279SJanet Adkins return; 3270*2eaa9279SJanet Adkins } 3271*2eaa9279SJanet Adkins setLocationIndicatorActive(asyncResp, *validSystemsPath, 3272*2eaa9279SJanet Adkins locationIndicatorActive); 3273*2eaa9279SJanet Adkins }); 32749f8bfa7cSGunnar Mills } 32759f8bfa7cSGunnar Mills 32767e860f15SJohn Edward Broadbent // TODO (Gunnar): Remove IndicatorLED after enough time has 32777e860f15SJohn Edward Broadbent // passed 32789712f8acSEd Tanous if (indicatorLed) 32796617338dSEd Tanous { 3280f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 3281002d39b4SEd Tanous asyncResp->res.addHeader(boost::beast::http::field::warning, 3282d6aa0093SGunnar Mills "299 - \"IndicatorLED is deprecated. Use " 3283d6aa0093SGunnar Mills "LocationIndicatorActive instead.\""); 32846617338dSEd Tanous } 3285c6a620f2SGeorge Liu 3286c6a620f2SGeorge Liu if (powerRestorePolicy) 3287c6a620f2SGeorge Liu { 32884e69c904SGunnar Mills setPowerRestorePolicy(asyncResp, *powerRestorePolicy); 3289c6a620f2SGeorge Liu } 32903a2d0424SChris Cain 32913a2d0424SChris Cain if (powerMode) 32923a2d0424SChris Cain { 32933a2d0424SChris Cain setPowerMode(asyncResp, *powerMode); 32943a2d0424SChris Cain } 329537bbf98cSChris Cain 3296c1e219d5SEd Tanous if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime) 329737bbf98cSChris Cain { 3298002d39b4SEd Tanous setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, 3299002d39b4SEd Tanous ipsExitUtil, ipsExitTime); 330037bbf98cSChris Cain } 3301c1e219d5SEd Tanous } 33021cb1a9e6SAppaRao Puli 330338c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead( 3304dd60b9edSEd Tanous crow::App& app, const crow::Request& req, 33057f3e84a1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3306c1e219d5SEd Tanous const std::string& /*systemName*/) 3307dd60b9edSEd Tanous { 3308dd60b9edSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3309dd60b9edSEd Tanous { 3310dd60b9edSEd Tanous return; 3311dd60b9edSEd Tanous } 3312dd60b9edSEd Tanous asyncResp->res.addHeader( 3313dd60b9edSEd Tanous boost::beast::http::field::link, 3314dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 3315dd60b9edSEd Tanous } 331633e1f122SAndrew Geissler 331733e1f122SAndrew Geissler /** 331833e1f122SAndrew Geissler * @brief Translates allowed host transitions to redfish string 331933e1f122SAndrew Geissler * 332033e1f122SAndrew Geissler * @param[in] dbusAllowedHostTran The allowed host transition on dbus 332133e1f122SAndrew Geissler * @param[out] allowableValues The translated host transition(s) 332233e1f122SAndrew Geissler * 3323efff2b5dSManojkiran Eda * @return Emplaces corresponding Redfish translated value(s) in 332433e1f122SAndrew Geissler * allowableValues. If translation not possible, does nothing to 332533e1f122SAndrew Geissler * allowableValues. 332633e1f122SAndrew Geissler */ 3327504af5a0SPatrick Williams inline void dbusToRfAllowedHostTransitions( 3328504af5a0SPatrick Williams const std::string& dbusAllowedHostTran, 332933e1f122SAndrew Geissler nlohmann::json::array_t& allowableValues) 333033e1f122SAndrew Geissler { 333133e1f122SAndrew Geissler if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On") 333233e1f122SAndrew Geissler { 333333e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 333433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 333533e1f122SAndrew Geissler } 333633e1f122SAndrew Geissler else if (dbusAllowedHostTran == 333733e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.Off") 333833e1f122SAndrew Geissler { 333933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 334033e1f122SAndrew Geissler } 334133e1f122SAndrew Geissler else if (dbusAllowedHostTran == 334233e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot") 334333e1f122SAndrew Geissler { 334433e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 334533e1f122SAndrew Geissler } 334633e1f122SAndrew Geissler else if (dbusAllowedHostTran == 334733e1f122SAndrew Geissler "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot") 334833e1f122SAndrew Geissler { 334933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 335033e1f122SAndrew Geissler } 335133e1f122SAndrew Geissler else 335233e1f122SAndrew Geissler { 335333e1f122SAndrew Geissler BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran); 335433e1f122SAndrew Geissler } 335533e1f122SAndrew Geissler } 335633e1f122SAndrew Geissler 335733e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions( 335833e1f122SAndrew Geissler const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 335933e1f122SAndrew Geissler const boost::system::error_code& ec, 336033e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) 336133e1f122SAndrew Geissler { 336233e1f122SAndrew Geissler nlohmann::json::array_t allowableValues; 336333e1f122SAndrew Geissler 336433e1f122SAndrew Geissler // Supported on all systems currently 336533e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOff); 336633e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::PowerCycle); 336733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::Nmi); 336833e1f122SAndrew Geissler 336933e1f122SAndrew Geissler if (ec) 337033e1f122SAndrew Geissler { 3371e715d14bSEd Tanous if ((ec.value() == 3372e715d14bSEd Tanous boost::system::linux_error::bad_request_descriptor) || 3373e715d14bSEd Tanous (ec.value() == boost::asio::error::basic_errors::host_unreachable)) 337433e1f122SAndrew Geissler { 337533e1f122SAndrew Geissler // Property not implemented so just return defaults 337633e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Property not available {}", ec); 337733e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::On); 337833e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceOn); 337933e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::ForceRestart); 338033e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulRestart); 338133e1f122SAndrew Geissler allowableValues.emplace_back(resource::ResetType::GracefulShutdown); 338233e1f122SAndrew Geissler } 338333e1f122SAndrew Geissler else 338433e1f122SAndrew Geissler { 338533e1f122SAndrew Geissler BMCWEB_LOG_ERROR("DBUS response error {}", ec); 338633e1f122SAndrew Geissler messages::internalError(asyncResp->res); 338733e1f122SAndrew Geissler return; 338833e1f122SAndrew Geissler } 338933e1f122SAndrew Geissler } 339033e1f122SAndrew Geissler else 339133e1f122SAndrew Geissler { 339233e1f122SAndrew Geissler for (const std::string& transition : allowedHostTransitions) 339333e1f122SAndrew Geissler { 339433e1f122SAndrew Geissler BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition); 339533e1f122SAndrew Geissler dbusToRfAllowedHostTransitions(transition, allowableValues); 339633e1f122SAndrew Geissler } 339733e1f122SAndrew Geissler } 339833e1f122SAndrew Geissler 339933e1f122SAndrew Geissler nlohmann::json::object_t parameter; 340033e1f122SAndrew Geissler parameter["Name"] = "ResetType"; 340133e1f122SAndrew Geissler parameter["Required"] = true; 3402539d8c6bSEd Tanous parameter["DataType"] = action_info::ParameterTypes::String; 340333e1f122SAndrew Geissler parameter["AllowableValues"] = std::move(allowableValues); 340433e1f122SAndrew Geissler nlohmann::json::array_t parameters; 340533e1f122SAndrew Geissler parameters.emplace_back(std::move(parameter)); 340633e1f122SAndrew Geissler asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 340733e1f122SAndrew Geissler } 340833e1f122SAndrew Geissler 3409c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet( 3410c1e219d5SEd Tanous crow::App& app, const crow::Request& req, 341122d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3412c1e219d5SEd Tanous const std::string& systemName) 3413c1e219d5SEd Tanous { 34143ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 341545ca1b86SEd Tanous { 341645ca1b86SEd Tanous return; 341745ca1b86SEd Tanous } 341825b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 34197f3e84a1SEd Tanous { 34207f3e84a1SEd Tanous // Option currently returns no systems. TBD 34217f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 34227f3e84a1SEd Tanous systemName); 34237f3e84a1SEd Tanous return; 34247f3e84a1SEd Tanous } 3425746b56f3SAsmitha Karunanithi 342668896206SGunnar Mills if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM) 342768896206SGunnar Mills { 3428746b56f3SAsmitha Karunanithi if (systemName == "hypervisor") 3429746b56f3SAsmitha Karunanithi { 3430746b56f3SAsmitha Karunanithi handleHypervisorResetActionGet(asyncResp); 3431746b56f3SAsmitha Karunanithi return; 3432746b56f3SAsmitha Karunanithi } 343368896206SGunnar Mills } 3434746b56f3SAsmitha Karunanithi 3435253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 343622d268cbSEd Tanous { 343722d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 343822d268cbSEd Tanous systemName); 343922d268cbSEd Tanous return; 344022d268cbSEd Tanous } 344122d268cbSEd Tanous 3442dd60b9edSEd Tanous asyncResp->res.addHeader( 3443dd60b9edSEd Tanous boost::beast::http::field::link, 3444dd60b9edSEd Tanous "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby"); 34451476687dSEd Tanous 34461476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 3447253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo", 3448253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME); 3449c1e219d5SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo"; 34501476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 34511476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 34523215e700SNan Zhou 345333e1f122SAndrew Geissler // Look to see if system defines AllowedHostTransitions 3454deae6a78SEd Tanous dbus::utility::getProperty<std::vector<std::string>>( 3455deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0", 3456deae6a78SEd Tanous "xyz.openbmc_project.State.Host", "AllowedHostTransitions", 345733e1f122SAndrew Geissler [asyncResp](const boost::system::error_code& ec, 345833e1f122SAndrew Geissler const std::vector<std::string>& allowedHostTransitions) { 3459bd79bce8SPatrick Williams afterGetAllowedHostTransitions(asyncResp, ec, 3460bd79bce8SPatrick Williams allowedHostTransitions); 346133e1f122SAndrew Geissler }); 3462c1e219d5SEd Tanous } 3463c1e219d5SEd Tanous /** 3464c1e219d5SEd Tanous * SystemResetActionInfo derived class for delivering Computer Systems 3465c1e219d5SEd Tanous * ResetType AllowableValues using ResetInfo schema. 3466c1e219d5SEd Tanous */ 3467100afe56SEd Tanous inline void requestRoutesSystems(App& app) 3468c1e219d5SEd Tanous { 3469100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3470100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystemCollection) 3471100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3472100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionHead, std::ref(app))); 3473100afe56SEd Tanous 3474100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/") 3475100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystemCollection) 3476100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3477100afe56SEd Tanous std::bind_front(handleComputerSystemCollectionGet, std::ref(app))); 3478100afe56SEd Tanous 3479100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3480100afe56SEd Tanous .privileges(redfish::privileges::headComputerSystem) 3481100afe56SEd Tanous .methods(boost::beast::http::verb::head)( 3482100afe56SEd Tanous std::bind_front(handleComputerSystemHead, std::ref(app))); 3483100afe56SEd Tanous 3484100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3485100afe56SEd Tanous .privileges(redfish::privileges::getComputerSystem) 3486100afe56SEd Tanous .methods(boost::beast::http::verb::get)( 3487100afe56SEd Tanous std::bind_front(handleComputerSystemGet, std::ref(app))); 3488100afe56SEd Tanous 3489100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/") 3490100afe56SEd Tanous .privileges(redfish::privileges::patchComputerSystem) 3491100afe56SEd Tanous .methods(boost::beast::http::verb::patch)( 3492100afe56SEd Tanous std::bind_front(handleComputerSystemPatch, std::ref(app))); 3493100afe56SEd Tanous 3494100afe56SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/") 3495100afe56SEd Tanous .privileges(redfish::privileges::postComputerSystem) 3496100afe56SEd Tanous .methods(boost::beast::http::verb::post)(std::bind_front( 3497100afe56SEd Tanous handleComputerSystemResetActionPost, std::ref(app))); 3498100afe56SEd Tanous 3499c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3500c1e219d5SEd Tanous .privileges(redfish::privileges::headActionInfo) 3501c1e219d5SEd Tanous .methods(boost::beast::http::verb::head)(std::bind_front( 3502c1e219d5SEd Tanous handleSystemCollectionResetActionHead, std::ref(app))); 3503c1e219d5SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/") 3504c1e219d5SEd Tanous .privileges(redfish::privileges::getActionInfo) 3505c1e219d5SEd Tanous .methods(boost::beast::http::verb::get)(std::bind_front( 3506c1e219d5SEd Tanous handleSystemCollectionResetActionGet, std::ref(app))); 35071cb1a9e6SAppaRao Puli } 3508c5b2abe0SLewanczyk, Dawid } // namespace redfish 3509